From 5c8bb3c33570e1444ed06c284263394a42172dfa Mon Sep 17 00:00:00 2001 From: Yael Ben-Haim Date: Thu, 11 Nov 2021 13:36:16 +0200 Subject: [PATCH 1/8] wrote add_tags_recursive and remove_tag_recursive --- .../database_service/db_experiment_data.py | 3 ++- .../framework/composite/composite_analysis.py | 2 +- .../framework/experiment_data.py | 20 ++++++++++++++ test/test_composite.py | 27 +++++++++++++++++++ 4 files changed, 50 insertions(+), 2 deletions(-) diff --git a/qiskit_experiments/database_service/db_experiment_data.py b/qiskit_experiments/database_service/db_experiment_data.py index c6d8ab29f2..d3fba1ebdb 100644 --- a/qiskit_experiments/database_service/db_experiment_data.py +++ b/qiskit_experiments/database_service/db_experiment_data.py @@ -24,6 +24,7 @@ import contextlib from collections import deque from datetime import datetime +import numpy as np from matplotlib import pyplot from qiskit.providers import Job, BaseJob, Backend, BaseBackend, Provider @@ -1213,7 +1214,7 @@ def tags(self, new_tags: List[str]) -> None: raise DbExperimentDataError( f"The `tags` field of {type(self).__name__} must be a list." ) - self._tags = new_tags + self._tags = np.unique(new_tags).tolist() if self.auto_save: self.save_metadata() diff --git a/qiskit_experiments/framework/composite/composite_analysis.py b/qiskit_experiments/framework/composite/composite_analysis.py index 33bdf9e931..fcfa2465be 100644 --- a/qiskit_experiments/framework/composite/composite_analysis.py +++ b/qiskit_experiments/framework/composite/composite_analysis.py @@ -39,7 +39,7 @@ class CompositeAnalysis(BaseAnalysis): composite :class:`ExperimentData`. When calling :meth:`run` on experiment data already containing - initalized component experiment child data, any previously stored + initialized component experiment child data, any previously stored circuit data will be cleared and replaced with the marginalized data reconstructed from the parent composite experiment data. """ diff --git a/qiskit_experiments/framework/experiment_data.py b/qiskit_experiments/framework/experiment_data.py index 4831a8a8ce..9436ea3e3c 100644 --- a/qiskit_experiments/framework/experiment_data.py +++ b/qiskit_experiments/framework/experiment_data.py @@ -224,6 +224,26 @@ def block_for_results(self, timeout: Optional[float] = None) -> ExperimentData: _, timeout = combined_timeout(subdata.block_for_results, timeout) return self + def add_tags_recursive(self, tags2add: List[str]) -> None: + """Add tags to self and all its descendants + + Args: + tags2add - the tags that will be added to the existing tags + """ + self.tags += tags2add + for data in self._child_data.values(): + data.add_tags_recursive(tags2add) + + def remove_tags_recursive(self, tags2remove: List[str]) -> None: + """Remove tags from self and all its descendants + + Args: + tags2remove - the tags that will be removed from the existing tags + """ + self.tags = [x for x in self.tags if x not in tags2remove] + for data in self._child_data.values(): + data.remove_tags_recursive(tags2remove) + def __repr__(self): out = ( f" Date: Thu, 11 Nov 2021 13:46:44 +0200 Subject: [PATCH 2/8] docs --- .../database_service/db_experiment_data.py | 12 ++++++++---- qiskit_experiments/framework/experiment_data.py | 6 ++++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/qiskit_experiments/database_service/db_experiment_data.py b/qiskit_experiments/database_service/db_experiment_data.py index d3fba1ebdb..644e03cce9 100644 --- a/qiskit_experiments/database_service/db_experiment_data.py +++ b/qiskit_experiments/database_service/db_experiment_data.py @@ -1293,7 +1293,8 @@ def figure_names(self) -> List[str]: @property def share_level(self) -> str: - """Return the share level fo this experiment. + """Return the share level fo this experiment, + to self and all its descendants. Returns: Experiment share level. @@ -1302,7 +1303,8 @@ def share_level(self) -> str: @share_level.setter def share_level(self, new_level: str) -> None: - """Set the experiment share level. + """Set the experiment share level, + only to this experiment and not to its descendants. Args: new_level: New experiment share level. Valid share levels are provider- @@ -1344,7 +1346,8 @@ def service(self) -> Optional[DatabaseServiceV1]: @service.setter def service(self, service: DatabaseServiceV1) -> None: - """Set the service to be used for storing experiment data. + """Set the service to be used for storing experiment data, + to self and all its descendants Args: service: Service to be used. @@ -1355,7 +1358,8 @@ def service(self, service: DatabaseServiceV1) -> None: self._set_service(service) def _set_service(self, service: DatabaseServiceV1) -> None: - """Set the service to be used for storing experiment data. + """Set the service to be used for storing experiment data, + to this experiment only and not to its descendants Args: service: Service to be used. diff --git a/qiskit_experiments/framework/experiment_data.py b/qiskit_experiments/framework/experiment_data.py index 9436ea3e3c..2eabb6e074 100644 --- a/qiskit_experiments/framework/experiment_data.py +++ b/qiskit_experiments/framework/experiment_data.py @@ -180,7 +180,8 @@ def _set_child_data(self, child_data: List[ExperimentData]): self.add_child_data(data) def _set_service(self, service: DatabaseService) -> None: - """Set the service to be used for storing experiment data. + """Set the service to be used for storing experiment data, + to self and all its descendants. Args: service: Service to be used. @@ -194,7 +195,8 @@ def _set_service(self, service: DatabaseService) -> None: @DbExperimentData.share_level.setter def share_level(self, new_level: str) -> None: - """Set the experiment share level. + """Set the experiment share level, + to self and all its descendants. Args: new_level: New experiment share level. Valid share levels are provider- From ae58463b3eaea93e73c3f6db16984c066ebe02ea Mon Sep 17 00:00:00 2001 From: Yael Ben-Haim Date: Thu, 11 Nov 2021 14:35:08 +0200 Subject: [PATCH 3/8] lint --- qiskit_experiments/database_service/db_experiment_data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit_experiments/database_service/db_experiment_data.py b/qiskit_experiments/database_service/db_experiment_data.py index 644e03cce9..c66d01f672 100644 --- a/qiskit_experiments/database_service/db_experiment_data.py +++ b/qiskit_experiments/database_service/db_experiment_data.py @@ -1346,7 +1346,7 @@ def service(self) -> Optional[DatabaseServiceV1]: @service.setter def service(self, service: DatabaseServiceV1) -> None: - """Set the service to be used for storing experiment data, + """Set the service to be used for storing experiment data, to self and all its descendants Args: From 96cdeebc2fe05da634b300b3448f8245123f0389 Mon Sep 17 00:00:00 2001 From: Yael Ben-Haim Date: Tue, 16 Nov 2021 09:02:27 +0200 Subject: [PATCH 4/8] Update qiskit_experiments/database_service/db_experiment_data.py Co-authored-by: Helena Zhang --- qiskit_experiments/database_service/db_experiment_data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit_experiments/database_service/db_experiment_data.py b/qiskit_experiments/database_service/db_experiment_data.py index c66d01f672..245f077c84 100644 --- a/qiskit_experiments/database_service/db_experiment_data.py +++ b/qiskit_experiments/database_service/db_experiment_data.py @@ -1293,7 +1293,7 @@ def figure_names(self) -> List[str]: @property def share_level(self) -> str: - """Return the share level fo this experiment, + """Return the share level for this experiment, to self and all its descendants. Returns: From 2ed2f08acbe348cddcd6531469ceb129ffdd080f Mon Sep 17 00:00:00 2001 From: Yael Ben-Haim Date: Tue, 16 Nov 2021 10:20:07 +0200 Subject: [PATCH 5/8] release notes --- releasenotes/notes/add-remove-tags-9fa798ccad0f5c6a.yaml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 releasenotes/notes/add-remove-tags-9fa798ccad0f5c6a.yaml diff --git a/releasenotes/notes/add-remove-tags-9fa798ccad0f5c6a.yaml b/releasenotes/notes/add-remove-tags-9fa798ccad0f5c6a.yaml new file mode 100644 index 0000000000..b3713b84af --- /dev/null +++ b/releasenotes/notes/add-remove-tags-9fa798ccad0f5c6a.yaml @@ -0,0 +1,4 @@ +--- +features: + - | + New methods `add_tags_recursive` and `remove_tags_recursive` for adding and removing tags of an experiment data object and recursively all its descendants (if it is composite). From a3357f955e3d1caade047b5205ebcf5a010cd14a Mon Sep 17 00:00:00 2001 From: Yael Ben-Haim Date: Tue, 16 Nov 2021 10:26:48 +0200 Subject: [PATCH 6/8] fix method docs --- qiskit_experiments/database_service/db_experiment_data.py | 6 ++---- qiskit_experiments/framework/experiment_data.py | 8 ++++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/qiskit_experiments/database_service/db_experiment_data.py b/qiskit_experiments/database_service/db_experiment_data.py index 245f077c84..b94bb3a414 100644 --- a/qiskit_experiments/database_service/db_experiment_data.py +++ b/qiskit_experiments/database_service/db_experiment_data.py @@ -1293,8 +1293,7 @@ def figure_names(self) -> List[str]: @property def share_level(self) -> str: - """Return the share level for this experiment, - to self and all its descendants. + """Return the share level for this experiment Returns: Experiment share level. @@ -1346,8 +1345,7 @@ def service(self) -> Optional[DatabaseServiceV1]: @service.setter def service(self, service: DatabaseServiceV1) -> None: - """Set the service to be used for storing experiment data, - to self and all its descendants + """Set the service to be used for storing experiment data Args: service: Service to be used. diff --git a/qiskit_experiments/framework/experiment_data.py b/qiskit_experiments/framework/experiment_data.py index 2eabb6e074..be4d9e7681 100644 --- a/qiskit_experiments/framework/experiment_data.py +++ b/qiskit_experiments/framework/experiment_data.py @@ -181,7 +181,7 @@ def _set_child_data(self, child_data: List[ExperimentData]): def _set_service(self, service: DatabaseService) -> None: """Set the service to be used for storing experiment data, - to self and all its descendants. + to this experiment itself and its descendants. Args: service: Service to be used. @@ -196,7 +196,7 @@ def _set_service(self, service: DatabaseService) -> None: @DbExperimentData.share_level.setter def share_level(self, new_level: str) -> None: """Set the experiment share level, - to self and all its descendants. + to this experiment itself and its descendants. Args: new_level: New experiment share level. Valid share levels are provider- @@ -227,7 +227,7 @@ def block_for_results(self, timeout: Optional[float] = None) -> ExperimentData: return self def add_tags_recursive(self, tags2add: List[str]) -> None: - """Add tags to self and all its descendants + """Add tags to this experiment itself and its descendants Args: tags2add - the tags that will be added to the existing tags @@ -237,7 +237,7 @@ def add_tags_recursive(self, tags2add: List[str]) -> None: data.add_tags_recursive(tags2add) def remove_tags_recursive(self, tags2remove: List[str]) -> None: - """Remove tags from self and all its descendants + """Remove tags from this experiment itself and its descendants Args: tags2remove - the tags that will be removed from the existing tags From db633ee513e80b132b0ae7f688e4b470ce8d98f1 Mon Sep 17 00:00:00 2001 From: Yael Ben-Haim Date: Tue, 16 Nov 2021 10:39:32 +0200 Subject: [PATCH 7/8] fixed test --- test/test_composite.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/test/test_composite.py b/test/test_composite.py index 2ca4d1ca54..fe775b52f0 100644 --- a/test/test_composite.py +++ b/test/test_composite.py @@ -414,16 +414,17 @@ def test_composite_tags(self): expdata.tags = ["a", "c", "a"] data1.tags = ["b"] - self.assertSetEqual(set(expdata.tags), {"a", "c"}) - self.assertSetEqual(set(data1.tags), {"b"}) - self.assertSetEqual(set(data2.tags), set()) + print(expdata.tags) + self.assertEqual(sorted(expdata.tags), ["a", "c"]) + self.assertEqual(sorted(data1.tags), ["b"]) + self.assertEqual(sorted(data2.tags), []) expdata.add_tags_recursive(["d", "c"]) - self.assertSetEqual(set(expdata.tags), {"a", "c", "d"}) - self.assertSetEqual(set(data1.tags), {"b", "c", "d"}) - self.assertSetEqual(set(data2.tags), {"c", "d"}) + self.assertEqual(sorted(expdata.tags), ["a", "c", "d"]) + self.assertEqual(sorted(data1.tags), ["b", "c", "d"]) + self.assertEqual(sorted(data2.tags), ["c", "d"]) expdata.remove_tags_recursive(["a", "b"]) - self.assertSetEqual(set(expdata.tags), {"c", "d"}) - self.assertSetEqual(set(data1.tags), {"c", "d"}) - self.assertSetEqual(set(data2.tags), {"c", "d"}) + self.assertEqual(sorted(expdata.tags), ["c", "d"]) + self.assertEqual(sorted(data1.tags), ["c", "d"]) + self.assertEqual(sorted(data2.tags), ["c", "d"]) From bd5ede3872f95fbc81bcc2e9da75930b966457a6 Mon Sep 17 00:00:00 2001 From: Yael Ben-Haim Date: Wed, 17 Nov 2021 17:19:01 +0200 Subject: [PATCH 8/8] black --- test/test_composite.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/test_composite.py b/test/test_composite.py index d4fc1fe155..197377b9c7 100644 --- a/test/test_composite.py +++ b/test/test_composite.py @@ -421,4 +421,3 @@ def circuits(self): ): for circ_data, circ_counts in zip(childdata.data(), child_counts): self.assertDictEqual(circ_data["counts"], circ_counts) -