Skip to content

Commit 3aa2065

Browse files
committed
Update experiments
1 parent 8401957 commit 3aa2065

File tree

8 files changed

+77
-68
lines changed

8 files changed

+77
-68
lines changed

qiskit_experiments/characterization/t1_experiment.py

Lines changed: 40 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from qiskit.providers import Backend
2020
from qiskit.circuit import QuantumCircuit
2121
from qiskit.utils import apply_prefix
22+
from qiskit.providers.options import Options
2223

2324
from qiskit_experiments.base_experiment import BaseExperiment
2425
from qiskit_experiments.base_analysis import BaseAnalysis
@@ -29,9 +30,29 @@
2930

3031

3132
class T1Analysis(BaseAnalysis):
32-
"""T1 Experiment result analysis class."""
33+
"""T1 Experiment result analysis class.
3334
34-
# pylint: disable=arguments-differ, unused-argument
35+
Analysis Options:
36+
t1_guess (float): Optional, an initial guess of T1
37+
amplitude_guess (float): Optional, an initial guess of the coefficient of the exponent
38+
offset_guess (float): Optional, an initial guess of the offset
39+
t1_bounds (list of two floats): Optional, lower bound and upper bound to T1
40+
amplitude_bounds (list of two floats): Optional, lower bound and upper bound to the amplitude
41+
offset_bounds (list of two floats): Optional, lower bound and upper bound to the offset
42+
"""
43+
44+
@classmethod
45+
def _default_options(cls):
46+
return Options(
47+
t1_guess=None,
48+
amplitude_guess=None,
49+
offset_guess=None,
50+
t1_bounds=None,
51+
amplitude_bounds=None,
52+
offset_bounds=None,
53+
)
54+
55+
# pylint: disable=arguments-differ
3556
def _run_analysis(
3657
self,
3758
experiment_data,
@@ -41,10 +62,7 @@ def _run_analysis(
4162
t1_bounds=None,
4263
amplitude_bounds=None,
4364
offset_bounds=None,
44-
plot=True,
45-
ax=None,
46-
**kwargs,
47-
) -> Tuple[AnalysisResult, List["plotting.pyplot.Figure"]]:
65+
) -> Tuple[AnalysisResult, None]:
4866
"""
4967
Calculate T1
5068
@@ -54,23 +72,15 @@ def _run_analysis(
5472
amplitude_guess (float): Optional, an initial guess of the coefficient
5573
of the exponent
5674
offset_guess (float): Optional, an initial guess of the offset
57-
t1_bounds (list of two floats): Optional, lower bound and upper
58-
bound to T1
59-
amplitude_bounds (list of two floats): Optional, lower bound and
60-
upper bound to the amplitude
61-
offset_bounds (list of two floats): Optional, lower bound and upper
62-
bound to the offset
63-
plot: If True generate a plot of fitted data.
64-
ax: Optional, matplotlib axis to add plot to.
65-
kwargs: Trailing unused function parameters
75+
t1_bounds (list of two floats): Optional, lower bound and upper bound to T1
76+
amplitude_bounds (list of two floats): Optional, lower bound and upper bound to the amplitude
77+
offset_bounds (list of two floats): Optional, lower bound and upper bound to the offset
6678
6779
Returns:
6880
The analysis result with the estimated T1
6981
"""
70-
data = experiment_data.data()
71-
unit = data[0]["metadata"]["unit"]
72-
conversion_factor = data[0]["metadata"].get("dt_factor", None)
73-
qubit = data[0]["metadata"]["qubit"]
82+
unit = experiment_data._data[0]["metadata"]["unit"]
83+
conversion_factor = experiment_data._data[0]["metadata"].get("dt_factor", None)
7484
if conversion_factor is None:
7585
conversion_factor = 1 if unit == "s" else apply_prefix(1, unit)
7686

@@ -190,6 +200,10 @@ class T1Experiment(BaseExperiment):
190200

191201
__analysis_class__ = T1Analysis
192202

203+
@classmethod
204+
def _default_options(cls) -> Options:
205+
return Options(delays=None, unit="s")
206+
193207
def __init__(
194208
self,
195209
qubit: int,
@@ -210,13 +224,9 @@ def __init__(
210224
"""
211225
if len(delays) < 3:
212226
raise ValueError("T1 experiment: number of delays must be at least 3")
227+
super().__init__([qubit], delays=delays, unit=unit)
213228

214-
self._delays = delays
215-
self._unit = unit
216-
super().__init__([qubit])
217-
218-
# pylint: disable=arguments-differ
219-
def circuits(self, backend: Optional[Backend] = None) -> List[QuantumCircuit]:
229+
def circuits(self, backend: Optional["Backend"] = None) -> List[QuantumCircuit]:
220230
"""
221231
Return a list of experiment circuits
222232
@@ -229,31 +239,30 @@ def circuits(self, backend: Optional[Backend] = None) -> List[QuantumCircuit]:
229239
Raises:
230240
AttributeError: if unit is dt but dt parameter is missing in the backend configuration
231241
"""
232-
233-
if self._unit == "dt":
242+
if self.options.unit == "dt":
234243
try:
235244
dt_factor = getattr(backend.configuration(), "dt")
236245
except AttributeError as no_dt:
237246
raise AttributeError("Dt parameter is missing in backend configuration") from no_dt
238247

239248
circuits = []
240249

241-
for delay in self._delays:
250+
for delay in self.options.delays:
242251
circ = QuantumCircuit(1, 1)
243252
circ.x(0)
244253
circ.barrier(0)
245-
circ.delay(delay, 0, self._unit)
254+
circ.delay(delay, 0, self.options.unit)
246255
circ.barrier(0)
247256
circ.measure(0, 0)
248257

249258
circ.metadata = {
250259
"experiment_type": self._type,
251260
"qubit": self.physical_qubits[0],
252261
"xval": delay,
253-
"unit": self._unit,
262+
"unit": self.options.unit,
254263
}
255264

256-
if self._unit == "dt":
265+
if self.options.unit == "dt":
257266
circ.metadata["dt_factor"] = dt_factor
258267

259268
circuits.append(circ)

qiskit_experiments/composite/batch_experiment.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def __init__(self, experiments):
4141
qubits = tuple(self._qubit_map.keys())
4242
super().__init__(experiments, qubits)
4343

44-
def circuits(self, backend=None, **circuit_options):
44+
def circuits(self, backend=None):
4545

4646
batch_circuits = []
4747

@@ -51,7 +51,7 @@ def circuits(self, backend=None, **circuit_options):
5151
qubit_mapping = None
5252
else:
5353
qubit_mapping = [self._qubit_map[qubit] for qubit in expr.physical_qubits]
54-
for circuit in expr.circuits(**circuit_options):
54+
for circuit in expr.circuits(backend):
5555
# Update metadata
5656
circuit.metadata = {
5757
"experiment_type": self._type,

qiskit_experiments/composite/composite_analysis.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,16 @@ def _run_analysis(self, experiment_data: CompositeExperimentData, **options):
4040
QiskitError: if analysis is attempted on non-composite
4141
experiment data.
4242
"""
43-
# Run analysis for sub-experiments and add sub-experiment metadata
44-
# as result of batch experiment
43+
if not isinstance(experiment_data, CompositeExperimentData):
44+
raise QiskitError("CompositeAnalysis must be run on CompositeExperimentData.")
45+
46+
# Run analysis for sub-experiments
47+
for expr, expr_data in zip(
48+
experiment_data._experiment._experiments, experiment_data._composite_expdata
49+
):
50+
expr.analysis(**expr.analysis_options.__dict__).run(expr_data, **options)
51+
52+
# Add sub-experiment metadata as result of batch experiment
4553
# Note: if Analysis results had ID's these should be included here
4654
# rather than just the sub-experiment IDs
4755
sub_types = []

qiskit_experiments/composite/composite_experiment.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,24 +26,21 @@ class CompositeExperiment(BaseExperiment):
2626
__analysis_class__ = CompositeAnalysis
2727
__experiment_data__ = CompositeExperimentData
2828

29-
def __init__(self, experiments, qubits, experiment_type=None, circuit_options=None):
29+
def __init__(self, experiments, qubits, experiment_type=None):
3030
"""Initialize the composite experiment object.
3131
3232
Args:
3333
experiments (List[BaseExperiment]): a list of experiment objects.
3434
qubits (int or Iterable[int]): the number of qubits or list of
3535
physical qubits for the experiment.
3636
experiment_type (str): Optional, composite experiment subclass name.
37-
circuit_options (str): Optional, Optional, dictionary of allowed
38-
kwargs and default values for the `circuit`
39-
method.
4037
"""
4138
self._experiments = experiments
4239
self._num_experiments = len(experiments)
43-
super().__init__(qubits, experiment_type=experiment_type, circuit_options=circuit_options)
40+
super().__init__(qubits, experiment_type=experiment_type)
4441

4542
@abstractmethod
46-
def circuits(self, backend=None, **circuit_options):
43+
def circuits(self, backend=None):
4744
pass
4845

4946
@property
@@ -55,6 +52,6 @@ def component_experiment(self, index):
5552
"""Return the component Experiment object"""
5653
return self._experiments[index]
5754

58-
def component_analysis(self, index, **kwargs):
55+
def component_analysis(self, index, **analysis_options):
5956
"""Return the component experiment Analysis object"""
60-
return self.component_experiment(index).analysis(**kwargs)
57+
return self.component_experiment(index).analysis(**analysis_options)

qiskit_experiments/composite/parallel_experiment.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def __init__(self, experiments):
3232
qubits += exp.physical_qubits
3333
super().__init__(experiments, qubits)
3434

35-
def circuits(self, backend=None, **circuit_options):
35+
def circuits(self, backend=None):
3636

3737
sub_circuits = []
3838
sub_qubits = []
@@ -42,7 +42,7 @@ def circuits(self, backend=None, **circuit_options):
4242
# Generate data for combination
4343
for expr in self._experiments:
4444
# Add subcircuits
45-
circs = expr.circuits(**circuit_options)
45+
circs = expr.circuits(backend)
4646
sub_circuits.append(circs)
4747
sub_size.append(len(circs))
4848

qiskit_experiments/randomized_benchmarking/rb_analysis.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
"""
1515

1616
from typing import Optional, List
17+
import numpy as np
1718

19+
from qiskit.providers.options import Options
1820
from qiskit_experiments.base_analysis import BaseAnalysis
1921
from qiskit_experiments.analysis.curve_fitting import curve_fit, process_curve_data
2022
from qiskit_experiments.analysis.data_processing import (
@@ -30,7 +32,21 @@
3032

3133

3234
class RBAnalysis(BaseAnalysis):
33-
"""RB Analysis class."""
35+
"""RB Analysis class.
36+
37+
Analysis Options:
38+
p0: Optional, initial parameter values for curve_fit.
39+
plot: If True generate a plot of fitted data.
40+
ax: Optional, matplotlib axis to add plot to.
41+
"""
42+
43+
@classmethod
44+
def _default_options(cls):
45+
return Options(
46+
p0=None,
47+
plot=True,
48+
ax=None,
49+
)
3450

3551
# pylint: disable = arguments-differ, invalid-name
3652
def _run_analysis(

qiskit_experiments/randomized_benchmarking/rb_experiment.py

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -76,27 +76,6 @@ def circuits(self, backend: Optional[Backend] = None) -> List[QuantumCircuit]:
7676
circuits += self._sample_circuits(self._lengths, seed=self._rng)
7777
return circuits
7878

79-
def transpiled_circuits(
80-
self, backend: Optional[Backend] = None, **kwargs
81-
) -> List[QuantumCircuit]:
82-
"""Return a list of transpiled RB circuits.
83-
84-
Args:
85-
backend: Optional, a backend object to use as the
86-
argument for the :func:`qiskit.transpile` function.
87-
kwargs: kwarg options for the :func:`qiskit.transpile` function.
88-
89-
Returns:
90-
A list of :class:`QuantumCircuit`.
91-
92-
Raises:
93-
QiskitError: if an initial layout is specified in the
94-
kwarg options for transpilation. The initial
95-
layout must be generated from the experiment.
96-
"""
97-
circuits = super().transpiled_circuits(backend=backend, **kwargs)
98-
return circuits
99-
10079
def _sample_circuits(
10180
self, lengths: Iterable[int], seed: Optional[Union[int, Generator]] = None
10281
) -> List[QuantumCircuit]:

test/data_processing/test_data_processing.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def __init__(self):
3939
self._type = None
4040
super().__init__((0,), "fake_test_experiment")
4141

42-
def circuits(self, backend=None, **circuit_options):
42+
def circuits(self, backend=None):
4343
"""Fake circuits."""
4444
return []
4545

0 commit comments

Comments
 (0)