Skip to content

Commit

Permalink
Bugfix when copying the ExperiemntData object and add warning to `_…
Browse files Browse the repository at this point in the history
…retrieve_data` (#1316)

### Summary

As said in #1314 , `copy` method in `Experiment Data` class will now
copy the `provider` attribute to the copied instance and warnning if
data isn't retrieved due to `provider=None` .
### Details and comments

Some details that should be in this section include:

- Why this change was necessary
This is a bug that the provider isn't copied. In addition,
`_retrive_data()` method in the `ExperimentData` class doesn;t retirive
data if provider is not provided. Added a warning so the user will know.
  • Loading branch information
ItamarGoldman authored Nov 30, 2023
1 parent e65e1c6 commit 8b0b562
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 8 deletions.
8 changes: 8 additions & 0 deletions qiskit_experiments/framework/experiment_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -1071,6 +1071,13 @@ def _retrieve_data(self):
"""Retrieve job data if missing experiment data."""
# Get job results if missing in experiment data.
if self.provider is None:
# 'self._result_data' could be locked, so I check a copy of it.
if not self._result_data.copy():
# Adding warning so the user will have indication why the analysis may fail.
LOG.warning(
"Provider for ExperimentData object doesn't exist, resulting in a failed attempt to"
" retrieve data from the server; no stored result data exists"
)
return
retrieved_jobs = {}
jobs_to_retrieve = [] # the list of all jobs to retrieve from the server
Expand Down Expand Up @@ -2293,6 +2300,7 @@ def copy(self, copy_results: bool = True) -> "ExperimentData":
new_instance = ExperimentData(
backend=self.backend,
service=self.service,
provider=self.provider,
parent_id=self.parent_id,
job_ids=self.job_ids,
child_data=list(self._child_data.values()),
Expand Down
11 changes: 9 additions & 2 deletions qiskit_experiments/test/fake_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import uuid
from qiskit.circuit.library import Measure
from qiskit.providers.backend import BackendV2
from qiskit.providers.fake_provider import FakeProvider
from qiskit.providers.options import Options
from qiskit.transpiler import Target

Expand All @@ -27,8 +28,14 @@ class FakeBackend(BackendV2):
Fake backend for test purposes only.
"""

def __init__(self, backend_name="fake_backend", num_qubits=1, max_experiments=100):
super().__init__(name=backend_name)
def __init__(
self,
provider=FakeProvider(),
backend_name="fake_backend",
num_qubits=1,
max_experiments=100,
):
super().__init__(provider=provider, name=backend_name)
self._target = Target(num_qubits=num_qubits)
# Add a measure for each qubit so a simple measure circuit works
self.target.add_instruction(Measure())
Expand Down
5 changes: 5 additions & 0 deletions releasenotes/notes/bugfix_expdata_copy-2c73a21ad720858d.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
fixes:
- |
'copy' method under ExperimentData class now copies the provider.
8 changes: 4 additions & 4 deletions test/database_service/test_db_experiment_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

"""Test ExperimentData."""
from test.base import QiskitExperimentsTestCase
from test.fake_experiment import FakeExperiment
import os
from unittest import mock
import copy
Expand Down Expand Up @@ -46,6 +47,7 @@
ExperimentStatus,
)
from qiskit_experiments.framework.matplotlib import get_non_gui_ax
from qiskit_experiments.test.fake_backend import FakeBackend


class TestDbExperimentData(QiskitExperimentsTestCase):
Expand Down Expand Up @@ -1044,14 +1046,12 @@ def test_additional_attr(self):

def test_copy_metadata(self):
"""Test copy metadata."""
exp_data = ExperimentData(experiment_type="qiskit_test")
exp_data = FakeExperiment(experiment_type="qiskit_test").run(backend=FakeBackend())
exp_data.add_data(self._get_job_result(1))
result = mock.MagicMock()
result.result_id = str(uuid.uuid4())
exp_data.add_analysis_results(result)
copied = exp_data.copy(copy_results=False)
self.assertEqual(exp_data.data(), copied.data())
self.assertFalse(copied.analysis_results())
self.assertEqual(exp_data.provider, copied.provider)

def test_copy_metadata_pending_job(self):
"""Test copy metadata with a pending job."""
Expand Down
9 changes: 7 additions & 2 deletions test/fake_experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,16 @@ def _default_experiment_options(cls) -> Options:
options.dummyoption = None
return options

def __init__(self, physical_qubits=None):
def __init__(self, physical_qubits=None, backend=None, experiment_type=None):
"""Initialise the fake experiment."""
if physical_qubits is None:
physical_qubits = [0]
super().__init__(physical_qubits, analysis=FakeAnalysis())
super().__init__(
physical_qubits,
analysis=FakeAnalysis(),
backend=backend,
experiment_type=experiment_type,
)

def circuits(self):
"""Fake circuits."""
Expand Down

0 comments on commit 8b0b562

Please sign in to comment.