Rerun analysis for an existing experiment ========================================= Problem ------- You want to rerun the analysis, possibly with different options, and generate a new :class:`.ExperimentData` object for an existing experiment whose jobs have finished execution successfully. Solution -------- .. note:: This guide requires :external+qiskit_ibm_runtime:doc:`qiskit-ibm-runtime ` version 0.15 and up, which can be installed with ``python -m pip install qiskit-ibm-runtime``. For how to migrate from the older ``qiskit-ibm-provider`` to :external+qiskit_ibm_runtime:doc:`qiskit-ibm-runtime `, consult the `migration guide `_.\ Once you recreate the exact experiment you ran and all of its parameters and options, you can call the :meth:`.ExperimentData.add_jobs` method with a list of :class:`Job ` objects to generate the new :class:`.ExperimentData` object. The following example retrieves jobs from a provider that has access to them via their job IDs: .. jupyter-input:: from qiskit_experiments.framework import ExperimentData from qiskit_ibm_runtime import QiskitRuntimeService # The experiment you ran experiment = Experiment(**opts) # List of job IDs for the experiment job_ids= ["job1_id", "job2_id", ...] service = QiskitRuntimeService(channel="ibm_quantum") expdata = ExperimentData(experiment = experiment) expdata.add_jobs([service.job(job_id) for job_id in job_ids]) experiment.analysis.run(expdata, replace_results=True) # Block execution of subsequent code until analysis is complete expdata.block_for_results() ``expdata`` will be the new experiment data object containing results of the rerun analysis. Note that if ``replace_results`` isn't set, running the analysis will return a new :class:`.ExperimentData` object instead of overwriting the existing one. If you have the job data in the form of a :class:`~qiskit.result.Result` object, you can invoke the :meth:`.ExperimentData.add_data` method instead of :meth:`.ExperimentData.add_jobs`: .. jupyter-input:: data.add_data([service.job(job_id).result() for job_id in job_ids]) The remaining workflow remains the same. Note that for a composite experiment, you only need to run these code snippets for the parent experiment. The child experiment data will automatically populate. Discussion ---------- This guide is helpful for cases such as a lost connection during experiment execution, where the jobs may have finished running on the remote backends but the :class:`.ExperimentData` class returned upon completion of an experiment does not contain correct results. In the case where jobs are not directly accessible from the provider but you've downloaded the jobs from the `IQS dashboard `_, you can load them from the downloaded directory into :class:`~qiskit.result.Result` objects with this code: .. jupyter-input:: import json from pathlib import Path from qiskit.result import Result result_dict = json.loads(next(Path('.').glob("*-result.txt")).read_text()) result = Result.from_dict(result_dict) Recreation of the experiment object is often done by rerunning the code that you ran previously to create it. It may sometimes be helpful instead to save an experiment and restore it later with the following lines of code: .. jupyter-input:: from qiskit_experiments.framework import ExperimentDecoder, ExperimentEncoder serialized_exp = json.dumps(Experiment.config(), cls=ExperimentEncoder) Experiment.from_config(json.loads(serialized_exp), cls=ExperimentDecoder) Rerunning with different analysis options ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ You may also want to rerun the analysis with different options of a previously-run experiment when you instantiate this new :class:`.ExperimentData` object. Here's a code snippet where we reconstruct a parallel experiment consisting of randomized benchmarking experiments, then change the gate error ratio as well as the line plot color of the first component experiment. .. jupyter-input:: pexp = ParallelExperiment([ StandardRB((i,), np.arange(1, 800, 200), num_samples=10) for i in range(2)]) pexp.analysis.component_analysis(0).options.gate_error_ratio = { "x": 10, "sx": 1, "rz": 0 } pexp.analysis.component_analysis(0).plotter.figure_options.series_params.update( { "rb_decay": {"color": "r"} } ) data = ExperimentData(experiment=pexp) data.add_jobs([service.job(job_id) for job_id in job_ids]) pexp.analysis.run(data, replace_results=True) See Also -------- * `Saving and loading experiment data with the cloud service `_