Skip to content

Commit 3c26036

Browse files
committed
update copy behavior
1 parent c4e9a52 commit 3c26036

File tree

4 files changed

+37
-4
lines changed

4 files changed

+37
-4
lines changed

qiskit_experiments/framework/analysis_result_table.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -204,16 +204,26 @@ def clear(self):
204204
with self._lock:
205205
self._data = pd.DataFrame(columns=self.DEFAULT_COLUMNS)
206206

207-
def copy(self):
207+
def copy(self, new_ids: bool = True):
208208
"""Create new thread-safe instance with the same data.
209209
210-
.. note::
211-
This returns a new object with shallow copied data frame.
210+
Args:
211+
new_ids: Whether to generate new IDs for copied entries. Defaults to True.
212+
213+
Returns:
214+
A new shallow copied DataFrame object.
212215
"""
213216
with self._lock:
214217
# Hold the lock so that no data can be added
215218
new_instance = self.__class__()
216219
new_instance._data = self._data.copy(deep=False)
220+
if new_ids:
221+
new_instance._data["result_id"] = None
222+
for idx, _ in new_instance._data.iterrows():
223+
new_instance._data.at[idx, "result_id"] = new_instance._create_unique_hash()
224+
new_instance._data.index = [
225+
result_id[:8] for result_id in new_instance._data["result_id"]
226+
]
217227
return new_instance
218228

219229
def _create_unique_hash(self) -> str:

qiskit_experiments/framework/experiment_data.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2397,7 +2397,10 @@ def copy(self, copy_results: bool = True) -> "ExperimentData":
23972397
# Copy results and figures.
23982398
# This requires analysis callbacks to finish
23992399
self._wait_for_futures(self._analysis_futures.values(), name="analysis")
2400-
new_instance._analysis_results = self._analysis_results.copy()
2400+
copied_results = self._analysis_results.copy()
2401+
# Analysis results should have experiment ID of the copied experiment
2402+
copied_results._data["experiment_id"] = new_instance.experiment_id
2403+
new_instance._analysis_results = copied_results
24012404
with self._figures.lock:
24022405
new_instance._figures = ThreadSafeOrderedDict()
24032406
new_instance.add_figures(self._figures.values())
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
fixes:
3+
- |
4+
Fixed a bug where a copied :class:`.ExperimentData` instance's analysis results didn't get
5+
new IDs and experiement ID.

test/database_service/test_db_experiment_data.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
"""Test ExperimentData."""
1616
from test.base import QiskitExperimentsTestCase
1717
from test.fake_experiment import FakeExperiment
18+
from test.extended_equality import is_equivalent
19+
1820
import os
1921
from unittest import mock
2022
import copy
@@ -1058,12 +1060,25 @@ def test_additional_attr(self):
10581060
def test_copy_metadata(self):
10591061
"""Test copy metadata."""
10601062
exp_data = FakeExperiment(experiment_type="qiskit_test").run(backend=FakeBackend())
1063+
self.assertExperimentDone(exp_data)
10611064
exp_data.add_data(self._get_job_result(1))
10621065
copied = exp_data.copy(copy_results=False)
10631066
self.assertEqual(exp_data.data(), copied.data())
10641067
self.assertFalse(copied.analysis_results())
10651068
self.assertEqual(exp_data.provider, copied.provider)
10661069

1070+
def test_copy_analysis_results(self):
1071+
"""Test copy analysis results."""
1072+
exp_data = FakeExperiment(experiment_type="qiskit_test").run(backend=FakeBackend())
1073+
self.assertExperimentDone(exp_data)
1074+
exp_data.add_data(self._get_job_result(1))
1075+
copied = exp_data.copy(copy_results=True)
1076+
for res in copied.analysis_results():
1077+
self.assertEqual(res.experiment_id, copied.experiment_id)
1078+
# copied analysis results should be identical to the original except for experiment ID
1079+
copied._analysis_results._data["experiment_id"] = exp_data.experiment_id
1080+
self.assertTrue(is_equivalent(exp_data.analysis_results(), copied.analysis_results()))
1081+
10671082
def test_copy_figure_artifacts(self):
10681083
"""Test copy expdata figures and artifacts."""
10691084
exp_data = FakeExperiment(experiment_type="qiskit_test").run(backend=FakeBackend())

0 commit comments

Comments
 (0)