diff --git a/docs/tutorials/getting_started.rst b/docs/tutorials/getting_started.rst index 4509de94a7..3acfdaacd9 100644 --- a/docs/tutorials/getting_started.rst +++ b/docs/tutorials/getting_started.rst @@ -393,4 +393,17 @@ into one level: parallel_data = parallel_exp.run(backend, seed_simulator=101).block_for_results() for result in parallel_data.analysis_results(): - print(result) \ No newline at end of file + print(result) + +Broadcasting analysis options to child experiments +-------------------------------------------------- + +Use the `broadcast` parameter to set analysis options to each of the child experiments. + +.. jupyter-execute:: + + parallel_exp.analysis.set_options(plot=False, broadcast=True) + +If the child experiment inherits from :class:`.CompositeExperiment` (such as :class:`.ParallelExperiment` +and :class:`.BatchExperiment` classes), this process will continue to work recursively. +In this instance, the analysis will not generate a figure for the child experiment after the analysis. \ No newline at end of file diff --git a/qiskit_experiments/framework/composite/composite_analysis.py b/qiskit_experiments/framework/composite/composite_analysis.py index 85e8baf0a0..774644b247 100644 --- a/qiskit_experiments/framework/composite/composite_analysis.py +++ b/qiskit_experiments/framework/composite/composite_analysis.py @@ -96,6 +96,14 @@ def component_analysis( return self._analyses return self._analyses[index] + def set_options(self, **fields): + """Set the analysis options for the experiment. If the `broadcast` argument set to `True`, the + analysis options will cascade to the child experiments.""" + super().set_options(**fields) + if fields.get("broadcast", None): + for sub_analysis in self._analyses: + sub_analysis.set_options(**fields) + def copy(self): ret = super().copy() # Recursively copy analysis diff --git a/releasenotes/notes/broadcasting-option-8a3b72bfc1df9668.yaml b/releasenotes/notes/broadcasting-option-8a3b72bfc1df9668.yaml new file mode 100644 index 0000000000..e99e7a1b8e --- /dev/null +++ b/releasenotes/notes/broadcasting-option-8a3b72bfc1df9668.yaml @@ -0,0 +1,7 @@ +--- +features: + - | + Added a `broadcast` option to the :class:`.CompositeAnalysis`. When `broadcast=True` is passed, + this option will be applied to child experiment analyses within the class. This means it will iterate + through the child analysis classes and apply the given option to each of + them. diff --git a/test/framework/test_composite.py b/test/framework/test_composite.py index fc0d126b2f..9c2555c0c0 100644 --- a/test/framework/test_composite.py +++ b/test/framework/test_composite.py @@ -624,6 +624,49 @@ def _default_options(cls): self.assertEqual(par_exp.analysis.component_analysis(0).options.option1, opt1_val) self.assertEqual(par_exp.analysis.component_analysis(1).options.option2, opt2_val) + def test_composite_analysis_options_cascade(self): + """Test setting component analysis options""" + + class Analysis(FakeAnalysis): + """Fake analysis class with options""" + + @classmethod + def _default_options(cls): + opts = super()._default_options() + opts.option1 = None + return opts + + exp1 = FakeExperiment([0]) + exp1.analysis = Analysis() + exp2 = FakeExperiment([1]) + exp2.analysis = Analysis() + par_exp1 = ParallelExperiment([exp1, exp2], flatten_results=True) + + exp3 = FakeExperiment([0]) + exp3.analysis = Analysis() + exp4 = FakeExperiment([1]) + exp4.analysis = Analysis() + par_exp2 = ParallelExperiment([exp3, exp4], flatten_results=True) + + # Set a batch experiment + batch_exp = BatchExperiment([par_exp1, par_exp2], flatten_results=True) + + # Set new option to the experiment + exp_list = [exp1, exp2, exp3, exp4] + opt1_vals = [9000, 8000, 7000, 6000] + for exp, opt1_val in zip(exp_list, opt1_vals): + exp.analysis.set_options(option1=opt1_val) + + opt1_new_val = 1000 + batch_exp.analysis.set_options(option1=opt1_new_val, broadcast=False) + + for exp in exp_list: + self.assertNotEqual(exp.analysis.options.option1, opt1_new_val) + + batch_exp.analysis.set_options(option1=opt1_new_val, broadcast=True) + for exp in exp_list: + self.assertEqual(exp.analysis.options.option1, opt1_new_val) + @data( ["0x0", "0x2", "0x3", "0x0", "0x0", "0x1", "0x3", "0x0", "0x2", "0x3"], ["00", "10", "11", "00", "00", "01", "11", "00", "10", "11"],