diff --git a/qiskit_experiments/curve_analysis/composite_curve_analysis.py b/qiskit_experiments/curve_analysis/composite_curve_analysis.py index 680aba1829..f19807e9c8 100644 --- a/qiskit_experiments/curve_analysis/composite_curve_analysis.py +++ b/qiskit_experiments/curve_analysis/composite_curve_analysis.py @@ -282,6 +282,7 @@ def _run_analysis( fit_dataset = {} for analysis in self._analyses: analysis._initialize(experiment_data) + analysis.experiment_metadata = self.experiment_metadata metadata = analysis.options.extra.copy() metadata["group"] = analysis.name diff --git a/qiskit_experiments/curve_analysis/standard_analysis/bloch_trajectory.py b/qiskit_experiments/curve_analysis/standard_analysis/bloch_trajectory.py index f3c8909a25..2d6f7471fe 100644 --- a/qiskit_experiments/curve_analysis/standard_analysis/bloch_trajectory.py +++ b/qiskit_experiments/curve_analysis/standard_analysis/bloch_trajectory.py @@ -166,6 +166,9 @@ def _generate_fit_guesses( user_opt.bounds.set_if_empty(t_off=(0, np.inf), b=(-1, 1)) user_opt.p0.set_if_empty(b=1e-9) + if "xval_offset" in self.experiment_metadata: + user_opt.p0.set_if_empty(t_off=self.experiment_metadata["xval_offset"]) + x_data = curve_data.get_subset_of("x") y_data = curve_data.get_subset_of("y") z_data = curve_data.get_subset_of("z") diff --git a/qiskit_experiments/framework/base_analysis.py b/qiskit_experiments/framework/base_analysis.py index 47892490f0..071b3db82a 100644 --- a/qiskit_experiments/framework/base_analysis.py +++ b/qiskit_experiments/framework/base_analysis.py @@ -53,6 +53,24 @@ def __init__(self): # Store keys of non-default options self._set_options = set() + # Store experiment metadata + self._experiment_metadata = None + + @property + def experiment_metadata(self): + """Metadata of experiment under current analysis.""" + return self._experiment_metadata + + @experiment_metadata.setter + def experiment_metadata(self, metadata: Dict): + to_skip = ["_source"] + in_data = {} + for key, value in metadata.items(): + if key in to_skip: + continue + in_data[key] = value + self._experiment_metadata = in_data + def config(self) -> AnalysisConfig: """Return the config dataclass for this analysis""" args = tuple(getattr(self, "__init_args__", OrderedDict()).values()) @@ -157,6 +175,7 @@ def run( else: analysis = self.copy() analysis.set_options(**options) + analysis.experiment_metadata = experiment_data.metadata def run_analysis(expdata): results, figures = analysis._run_analysis(expdata) diff --git a/qiskit_experiments/library/characterization/analysis/t2ramsey_analysis.py b/qiskit_experiments/library/characterization/analysis/t2ramsey_analysis.py index d33d60a478..b26c604ea0 100644 --- a/qiskit_experiments/library/characterization/analysis/t2ramsey_analysis.py +++ b/qiskit_experiments/library/characterization/analysis/t2ramsey_analysis.py @@ -14,7 +14,7 @@ """ from typing import Union import qiskit_experiments.curve_analysis as curve -from qiskit_experiments.framework import Options +from qiskit_experiments.framework import Options, ExperimentData class T2RamseyAnalysis(curve.DampedOscillationAnalysis): @@ -66,3 +66,12 @@ def _evaluate_quality(self, fit_data: curve.CurveFitResult) -> Union[str, None]: return "good" return "bad" + + def _initialize( + self, + experiment_data: ExperimentData, + ): + super()._initialize(experiment_data) + + if "virtual_freq" in self.experiment_metadata: + self.set_options(extra={"virtual_freq": self.experiment_metadata["virtual_freq"]}) diff --git a/qiskit_experiments/library/characterization/cr_hamiltonian.py b/qiskit_experiments/library/characterization/cr_hamiltonian.py index b1cce00928..bc69b0f1e2 100644 --- a/qiskit_experiments/library/characterization/cr_hamiltonian.py +++ b/qiskit_experiments/library/characterization/cr_hamiltonian.py @@ -344,17 +344,6 @@ def circuits(self) -> List[QuantumCircuit]: expr_circs.append(tomo_circ) return expr_circs - def _finalize(self): - """Set analysis option for initial guess that depends on experiment option values.""" - edge_duration = np.sqrt(2 * np.pi) * self.experiment_options.sigma * self.num_pulses - - for analysis in self.analysis.analyses(): - init_guess = analysis.options.p0.copy() - if "t_off" in init_guess: - continue - init_guess["t_off"] = edge_duration * self._dt - analysis.set_options(p0=init_guess) - def _metadata(self): metadata = super()._metadata() # Store measurement level and meas return if they have been @@ -362,6 +351,11 @@ def _metadata(self): for run_opt in ["meas_level", "meas_return"]: if hasattr(self.run_options, run_opt): metadata[run_opt] = getattr(self.run_options, run_opt) + + # Store effective edge duration + edge_duration = np.sqrt(2 * np.pi) * self.experiment_options.sigma * self.num_pulses + metadata["xval_offset"] = edge_duration * self._dt + return metadata diff --git a/qiskit_experiments/library/characterization/t2ramsey.py b/qiskit_experiments/library/characterization/t2ramsey.py index 5bb7328b0c..ba8c9ec139 100644 --- a/qiskit_experiments/library/characterization/t2ramsey.py +++ b/qiskit_experiments/library/characterization/t2ramsey.py @@ -158,4 +158,6 @@ def _metadata(self): for run_opt in ["meas_level", "meas_return"]: if hasattr(self.run_options, run_opt): metadata[run_opt] = getattr(self.run_options, run_opt) + metadata["virtual_freq"] = self.experiment_options.osc_freq + return metadata