Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
d1307ef
added T1 experiment
yaelbh Mar 4, 2021
b980a19
--amend
yaelbh Mar 4, 2021
0ec5d64
black
yaelbh Mar 4, 2021
82ac1eb
lint
yaelbh Mar 4, 2021
8b6f569
fixed header
yaelbh Mar 4, 2021
87dc98f
changing variable names
yaelbh Mar 4, 2021
4dadd6c
changed backend in t1 test
yaelbh Mar 7, 2021
1a43b2e
added a test of a parallel experiment with T1
yaelbh Mar 7, 2021
e36046d
preparation and readout error in t1 tests
yaelbh Mar 8, 2021
8e7d313
p0 and bounds as explicit function parameters
yaelbh Mar 8, 2021
f51c76a
black
yaelbh Mar 8, 2021
23bd839
a small implementation change with t1
yaelbh Mar 9, 2021
3ca68ea
added documentation to unit in t1
yaelbh Mar 9, 2021
3544e1c
removed circuit_options from parameter list of circuits in t1
yaelbh Mar 9, 2021
6f67362
a minor doc change
yaelbh Mar 9, 2021
c934818
default values to p0 and bounds
yaelbh Mar 9, 2021
aea7632
updated p0 and removed bounds
yaelbh Mar 10, 2021
4d180b1
black
yaelbh Mar 10, 2021
580f572
return more info about t1 fit
yaelbh Mar 10, 2021
2436044
Merge branch 'main' into t1
yaelbh Mar 10, 2021
04c3dd7
Merge branch 'main' into t1
yaelbh Mar 10, 2021
0ede9ef
a small change in t1 tests
yaelbh Mar 11, 2021
9d34c99
small improvements to t1
yaelbh Mar 11, 2021
2067572
exp_fit_fun and curve_fit wrapper in a shared space
yaelbh Mar 11, 2021
2ff0e3a
unit in circuit metadata and analysis result
yaelbh Mar 11, 2021
a0b30e5
lint
yaelbh Mar 18, 2021
c443951
added a test to t1 analysis class
yaelbh Mar 22, 2021
be7fcae
changed the result structure in t1
yaelbh Mar 22, 2021
3b7d3bd
moved functions from BaseAnalysis to a separate file
yaelbh Mar 22, 2021
e80e7fe
lint
yaelbh Mar 22, 2021
2daa615
review comments
yaelbh Mar 25, 2021
b967814
result unit in microseconds if unit is dt
yaelbh Apr 5, 2021
17005fe
a small change to a test
yaelbh Apr 6, 2021
d67fa9d
T1Analisys._fit_quality
yaelbh Apr 6, 2021
c579517
removed unnecessary pylint disable
yaelbh Apr 6, 2021
5d9b296
test_t1_metadata
yaelbh Apr 6, 2021
e1a9da6
allow the user to set the experiment type
yaelbh Apr 6, 2021
eea32e5
test_t1_low_quality
yaelbh Apr 6, 2021
bd7bf7d
black and lint
yaelbh Apr 6, 2021
7eff4b4
more black and lint
yaelbh Apr 6, 2021
6000cf8
added bounds option to t1
yaelbh Apr 8, 2021
cf7bfbb
a small fix
yaelbh Apr 8, 2021
9581589
no dt info in metadata if unit is not dt
yaelbh Apr 11, 2021
f20ac7b
fix docstring of exp_fit_fun
yaelbh Apr 11, 2021
edebf3e
added generate_delays
yaelbh Apr 11, 2021
70b3411
black and lint
yaelbh Apr 11, 2021
77c54bd
typo fix
yaelbh Apr 18, 2021
65fc269
removed generate_delays
yaelbh Apr 18, 2021
8784f7e
Merge branch 'main' into t1
yaelbh Apr 20, 2021
bfb1e3c
make t1 use the helper functions
yaelbh Apr 21, 2021
945fa3f
black
yaelbh Apr 21, 2021
19bdd5a
T1 to always return results in seconds
yaelbh Apr 22, 2021
e1323bb
Merge branch 'main' into t1
yaelbh Apr 22, 2021
b493932
an attempt to integrate with results db
yaelbh Apr 27, 2021
f32954a
Merge branch 'pr5' into resdb
yaelbh Apr 27, 2021
a3cfa28
replaced if by elif
yaelbh Apr 27, 2021
13c540e
Merge branch 'main' into resdb
yaelbh Apr 27, 2021
b95b230
Merge branch 'main' into t1
yaelbh Apr 27, 2021
5ec6621
Update qiskit_experiments/characterization/t1_experiment.py
yaelbh Apr 28, 2021
f638060
removed experiment_type from t1
yaelbh Apr 28, 2021
e043918
circuit_unit should appear in the result for every unit
yaelbh Apr 28, 2021
73a379b
use AnalysisResultV1
yaelbh Apr 29, 2021
03c2fb3
Merge branch t1 into resdb
yaelbh Apr 29, 2021
47fc3e0
test_t1_end2end is working
yaelbh May 2, 2021
c5b45e1
fixed test_t1_analysis
yaelbh May 2, 2021
4543de7
black
yaelbh May 2, 2021
2304ad9
fixed test_t1_low_quality
yaelbh May 2, 2021
6a183fa
Merge branch 'main' into resdb
yaelbh May 5, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions qiskit_experiments/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@

from .version import __version__

# Base result classes
from .experiment_data import ExperimentData, AnalysisResult

# Experiment modules
from . import composite
from . import characterization
Expand Down
15 changes: 6 additions & 9 deletions qiskit_experiments/analysis/curve_fitting.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import numpy as np
import scipy.optimize as opt
from qiskit.exceptions import QiskitError
from qiskit_experiments.base_analysis import AnalysisResult
from qiskit_experiments.analysis.data_processing import filter_data


Expand All @@ -31,7 +30,7 @@ def curve_fit(
sigma: Optional[np.ndarray] = None,
bounds: Optional[Union[Dict[str, Tuple[float, float]], Tuple[np.ndarray, np.ndarray]]] = None,
**kwargs,
) -> AnalysisResult:
) -> Dict:
r"""Perform a non-linear least squares to fit

This solves the optimization problem
Expand Down Expand Up @@ -110,8 +109,8 @@ def fit_func(x, *params):
kwargs["absolute_sigma"] = True

# Run curve fit
# TODO: Add error handling so if fitting fails we can return an analysis
# result containing this information
# TODO: Add error handling so if fitting fails we can return a
# dictionary containing this information
# pylint: disable = unbalanced-tuple-unpacking
popt, pcov = opt.curve_fit(
fit_func, xdata, ydata, sigma=sigma, p0=param_p0, bounds=param_bounds, **kwargs
Expand All @@ -138,7 +137,7 @@ def fit_func(x, *params):
"xrange": xdata_range,
}

return AnalysisResult(result)
return result


def multi_curve_fit(
Expand All @@ -151,7 +150,7 @@ def multi_curve_fit(
weights: Optional[np.ndarray] = None,
bounds: Optional[Union[Dict[str, Tuple[float, float]], Tuple[np.ndarray, np.ndarray]]] = None,
**kwargs,
) -> AnalysisResult:
) -> Dict:
r"""Perform a linearized multi-objective non-linear least squares fit.

This solves the optimization problem
Expand Down Expand Up @@ -230,9 +229,7 @@ def f(x, *params):
return y

# Run linearized curve_fit
analysis_result = curve_fit(f, xdata, ydata, p0, sigma=wsigma, bounds=bounds, **kwargs)

return analysis_result
return curve_fit(f, xdata, ydata, p0, sigma=wsigma, bounds=bounds, **kwargs)


def process_curve_data(
Expand Down
10 changes: 4 additions & 6 deletions qiskit_experiments/analysis/plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,9 @@
Plotting functions for experiment analysis
"""
import functools
from typing import Callable, Optional
from typing import Callable, Optional, Dict
import numpy as np

from qiskit_experiments.base_analysis import AnalysisResult

try:
from matplotlib import pyplot as plt

Expand All @@ -44,21 +42,21 @@ def wrapped(*args, **kwargs):
@requires_matplotlib
def plot_curve_fit(
func: Callable,
result: AnalysisResult,
result: Dict,
confidence_interval: bool = True,
ax: Optional["AxesSubplot"] = None,
num_fit_points: int = 100,
labelsize: int = 14,
grid: bool = True,
**kwargs,
) -> "AxesSubplot":
"""Generate plot of a curve fit analysis result.
"""Generate plot of a curve fitresult.

Wraps ``matplotlib.pyplot.plot``.

Args:
func: the fit funcion for curve_fit.
result: an AnalysisResult from curve_fit.
result: a result dictionary from curve_fit.
confidence_interval: if True plot the confidence interval from popt_err.
ax: Optional, a matplotlib axes to add the plot to.
num_fit_points: the number of points to plot for xrange.
Expand Down
2 changes: 1 addition & 1 deletion qiskit_experiments/base_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from abc import ABC, abstractmethod

from qiskit.exceptions import QiskitError
from .experiment_data import ExperimentData, AnalysisResult
from qiskit.providers.experiment import AnalysisResult, ExperimentData


class BaseAnalysis(ABC):
Expand Down
7 changes: 3 additions & 4 deletions qiskit_experiments/base_experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from qiskit import transpile, assemble
from qiskit.exceptions import QiskitError

from .experiment_data import ExperimentData
from qiskit.providers.experiment import ExperimentDataV1


_TRANSPILE_OPTIONS = {
Expand Down Expand Up @@ -57,7 +57,7 @@ class BaseExperiment(ABC):
__analysis_class__ = None

# ExperimentData class for experiment
__experiment_data__ = ExperimentData
__experiment_data__ = ExperimentDataV1

# Custom default transpiler options for experiment subclasses
__transpile_defaults__ = {"optimization_level": 0}
Expand Down Expand Up @@ -89,7 +89,6 @@ def __init__(self, qubits, experiment_type=None, circuit_options=None):
self._num_qubits = len(qubits)
self._physical_qubits = tuple(qubits)
if self._num_qubits != len(set(self._physical_qubits)):
print(self._num_qubits, self._physical_qubits)
raise QiskitError("Duplicate qubits in physical qubits list.")

# Store options and values
Expand All @@ -113,7 +112,7 @@ def run(self, backend, experiment_data=None, **kwargs):

# Create new experiment data
if experiment_data is None:
experiment_data = self.__experiment_data__(self)
experiment_data = self.__experiment_data__(backend, self._type)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to pass options (e.g. share_level) to the experiment data constructor, coming from the run method kwargs.


# Filter kwargs
run_options = self.__run_defaults__.copy()
Expand Down
53 changes: 31 additions & 22 deletions qiskit_experiments/characterization/t1_experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@

from qiskit_experiments.base_experiment import BaseExperiment
from qiskit_experiments.base_analysis import BaseAnalysis
from qiskit.providers.experiment import AnalysisResultV1
from qiskit.providers.experiment.device_component import Qubit
from qiskit_experiments.analysis.curve_fitting import process_curve_data, curve_fit
from qiskit_experiments.analysis.data_processing import level2_probability
from qiskit_experiments import AnalysisResult


class T1Analysis(BaseAnalysis):
Expand All @@ -40,12 +41,12 @@ def _run_analysis(
amplitude_bounds=None,
offset_bounds=None,
**kwargs,
) -> Tuple[AnalysisResult, None]:
) -> Tuple[AnalysisResultV1, None]:
"""
Calculate T1

Args:
experiment_data (ExperimentData): the experiment data to analyze
experiment_data (ExperimentDataV1): the experiment data to analyze
t1_guess (float): Optional, an initial guess of T1
amplitude_guess (float): Optional, an initial guess of the coefficient of the exponent
offset_guess (float): Optional, an initial guess of the offset
Expand All @@ -58,13 +59,14 @@ def _run_analysis(
The analysis result with the estimated T1
"""

unit = experiment_data._data[0]["metadata"]["unit"]
conversion_factor = experiment_data._data[0]["metadata"].get("dt_factor", None)
unit = experiment_data.data(0)["metadata"]["unit"]
conversion_factor = experiment_data.data(0)["metadata"].get("dt_factor", None)

if conversion_factor is None:
conversion_factor = 1 if unit == "s" else apply_prefix(1, unit)

xdata, ydata, sigma = process_curve_data(
experiment_data._data, lambda datum: level2_probability(datum, "1")
experiment_data.data(), lambda datum: level2_probability(datum, "1")
)
xdata *= conversion_factor

Expand Down Expand Up @@ -95,22 +97,29 @@ def _run_analysis(
),
)

analysis_result = AnalysisResult(
{
"value": fit_result["popt"][1],
"stderr": fit_result["popt_err"][1],
"unit": "s",
"label": "T1",
"fit": fit_result,
"quality": self._fit_quality(
fit_result["popt"], fit_result["popt_err"], fit_result["reduced_chisq"]
),
}
)
result_data = {
"value": fit_result["popt"][1],
"stderr": fit_result["popt_err"][1],
"unit": "s",
"label": "T1",
"fit": fit_result,
"quality": self._fit_quality(
fit_result["popt"], fit_result["popt_err"], fit_result["reduced_chisq"]
),
}

analysis_result["fit"]["circuit_unit"] = unit
result_data["fit"]["circuit_unit"] = unit
if unit == "dt":
analysis_result["fit"]["dt"] = conversion_factor
result_data["fit"]["dt"] = conversion_factor

analysis_result = AnalysisResultV1(
result_data,
"T1",
[Qubit(experiment_data.data(0)["metadata"]["qubit"])],
experiment_data.id,
quality=result_data["quality"],
verified=True,
)

return analysis_result, None

Expand All @@ -125,9 +134,9 @@ def _fit_quality(fit_out, fit_err, reduced_chisq):
and (fit_err[1] is None or fit_err[1] < fit_out[1])
and (fit_err[2] is None or fit_err[2] < 0.1)
):
return "computer_good"
return "good"
else:
return "computer_bad"
return "bad"


class T1Experiment(BaseExperiment):
Expand Down
3 changes: 2 additions & 1 deletion qiskit_experiments/composite/composite_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
"""

from qiskit.exceptions import QiskitError
from qiskit_experiments.base_analysis import BaseAnalysis, AnalysisResult
from qiskit_experiments.base_analysis import BaseAnalysis
from .composite_experiment_data import CompositeExperimentData
from qiskit.providers.experiment import AnalysisResult


class CompositeAnalysis(BaseAnalysis):
Expand Down
2 changes: 1 addition & 1 deletion qiskit_experiments/composite/composite_experiment_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"""

from qiskit.result import marginal_counts
from qiskit_experiments.experiment_data import ExperimentData
from qiskit.providers.experiment import ExperimentData


class CompositeExperimentData(ExperimentData):
Expand Down
2 changes: 1 addition & 1 deletion qiskit_experiments/composite/parallel_experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class ParallelExperiment(CompositeExperiment):
"""Parallel Experiment class"""

def __init__(self, experiments):
"""Initialize the analysis object.
"""Initialize the parallel experiments object.

Args:
experiments (List[BaseExperiment]): a list of experiments.
Expand Down
Loading