diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 728d50509e..641b193421 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -354,35 +354,26 @@ minor releases and not on patch releases. #### Adding deprecation warnings -We have a deprecation decorator for showing deprecation warnings. To -deprecate a function, for example: +We use the deprecation wrappers in [Qiskit +Utilities](https://qiskit.org/documentation/apidoc/utils.html) to add warnings: ```python - from qiskit_experiments.warnings import deprecated_function + from qiskit.utils.deprecation import deprecate_func - @deprecated_function(last_version="0.3", msg="Use new_function instead.") + @deprecate_func( + since="0.5", + additional_msg="Use ``new_function`` instead.", + removal_timeline="after 0.7", + package_name="qiskit-experiments", + ) def old_function(*args, **kwargs): pass + def new_function(*args, **kwargs): pass ``` -To deprecate a class: - -```python - from qiskit_experiments.warnings import deprecated_class - - @deprecated_class(last_version="0.3", new_cls=NewCls) - class OldClass: - pass - class NewClass: - pass -``` - -This will inform the user which version of Qiskit Experiments will remove the deprecated -class or function. - ### Development cycle The development cycle for Qiskit Experiments is all handled in the open using project diff --git a/docs/manuals/characterization/t2hahn.rst b/docs/manuals/characterization/t2hahn.rst index e8aae5237f..47475d9118 100644 --- a/docs/manuals/characterization/t2hahn.rst +++ b/docs/manuals/characterization/t2hahn.rst @@ -125,7 +125,7 @@ computed for other qubits. .. jupyter-execute:: - exp_with_p0 = T2Hahn(physical_qubits=[qubit], delays=delays, num_echoes=number_of_echoes) + exp_with_p0 = T2Hahn(physical_qubits=(qubit,), delays=delays, num_echoes=number_of_echoes) exp_with_p0.analysis.set_options(p0={"amp": 0.5, "tau": estimated_t2hahn, "base": 0.5}) expdata_with_p0 = exp_with_p0.run(backend=backend, shots=2000, seed_simulator=101) expdata_with_p0.block_for_results() @@ -190,13 +190,13 @@ total delay time. estimated_t2hahn2 = 30 * conversion_factor # Create a T2Hahn experiment with 0 echoes - exp2_0echoes = T2Hahn([qubit2], delays2, num_echoes=0) + exp2_0echoes = T2Hahn((qubit2,), delays2, num_echoes=0) exp2_0echoes.analysis.set_options(p0={"amp": 0.5, "tau": estimated_t2hahn2, "base": 0.5}) print("The first circuit of hahn echo experiment with 0 echoes:") print(exp2_0echoes.circuits()[0]) # Create a T2Hahn experiment with 1 echo. Print the first circuit as an example - exp2_1echoes = T2Hahn([qubit2], delays3, num_echoes=num_echoes) + exp2_1echoes = T2Hahn((qubit2,), delays3, num_echoes=num_echoes) exp2_1echoes.analysis.set_options(p0={"amp": 0.5, "tau": estimated_t2hahn2, "base": 0.5}) print("The first circuit of hahn echo experiment with 1 echo:") print(exp2_1echoes.circuits()[0]) diff --git a/docs/manuals/measurement/restless_measurements.rst b/docs/manuals/measurement/restless_measurements.rst index d71f115de7..c62fe75d27 100644 --- a/docs/manuals/measurement/restless_measurements.rst +++ b/docs/manuals/measurement/restless_measurements.rst @@ -74,7 +74,7 @@ they use always starts with the qubits in the ground state. # Define the experiment qubit = 2 - cal_drag = RoughDragCal(qubit, cals, schedule_name='sx', backend=backend) + cal_drag = RoughDragCal((qubit,), cals, schedule_name='sx', backend=backend) # Enable restless measurements by setting the run options and data processor cal_drag.enable_restless(rep_delay=1e-6) @@ -111,7 +111,7 @@ the standard data processor by providing it to the analysis options and telling # define a standard data processor. standard_processor = DataProcessor("counts", [Probability("1")]) - cal_drag = RoughDragCal(qubit, cals, schedule_name='sx', backend=backend) + cal_drag = RoughDragCal((qubit,), cals, schedule_name='sx', backend=backend) cal_drag.analysis.set_options(data_processor=standard_processor) # enable restless mode and set override_processor_by_restless to False. @@ -162,7 +162,7 @@ using the code below. dt = BackendData(backend).dt inst_map = backend.instruction_schedule_map - meas_length = inst_map.get("measure", (qubit, )).duration * dt + meas_length = inst_map.get("measure", (qubit,)).duration * dt # Compute the average duration of all circuits # Remove measurement instructions diff --git a/docs/manuals/verification/randomized_benchmarking.rst b/docs/manuals/verification/randomized_benchmarking.rst index 12381826e7..aaeb158687 100644 --- a/docs/manuals/verification/randomized_benchmarking.rst +++ b/docs/manuals/verification/randomized_benchmarking.rst @@ -175,7 +175,7 @@ The EPGs of two-qubit RB are analyzed with the corrected EPC if available. # Run a 1-qubit RB experiment on qubits 1, 2 to determine the error-per-gate of 1-qubit gates single_exps = BatchExperiment( [ - StandardRB([qubit], lengths_1_qubit, num_samples=num_samples, seed=seed) + StandardRB((qubit,), lengths_1_qubit, num_samples=num_samples, seed=seed) for qubit in qubits ], flatten_results=True, diff --git a/docs/manuals/verification/state_tomography.rst b/docs/manuals/verification/state_tomography.rst index f541288ae1..f207365756 100644 --- a/docs/manuals/verification/state_tomography.rst +++ b/docs/manuals/verification/state_tomography.rst @@ -168,7 +168,7 @@ For example if we want to perform 1-qubit QST on several qubits at once: for i in range(num_qubits)] subexps = [ - StateTomography(gate, physical_qubits=[i]) + StateTomography(gate, physical_qubits=(i,)) for i, gate in enumerate(gates) ] parexp = ParallelExperiment(subexps) diff --git a/docs/tutorials/calibrations.rst b/docs/tutorials/calibrations.rst index 02dc1613be..3f17641b94 100644 --- a/docs/tutorials/calibrations.rst +++ b/docs/tutorials/calibrations.rst @@ -166,7 +166,7 @@ Instantiate the experiment and draw the first circuit in the sweep: freq01_estimate = backend.defaults().qubit_freq_est[qubit] frequencies = np.linspace(freq01_estimate-15e6, freq01_estimate+15e6, 51) - spec = RoughFrequencyCal([qubit], cals, frequencies, backend=backend) + spec = RoughFrequencyCal((qubit,), cals, frequencies, backend=backend) spec.set_experiment_options(amp=0.005) .. jupyter-execute:: @@ -391,7 +391,7 @@ over/under rotations is the highest. .. jupyter-execute:: - overamp_exp = FineXAmplitude(qubit, backend=backend) + overamp_exp = FineXAmplitude((qubit,), backend=backend) overamp_exp.set_transpile_options(inst_map=inst_map) overamp_exp.circuits()[4].draw(output='mpl') @@ -415,7 +415,7 @@ experiment detects this error. We will compare the results to the over-rotation inst_map.add("x", (qubit,), x_under) # do the experiment - underamp_exp = FineXAmplitude(qubit, backend=backend) + underamp_exp = FineXAmplitude((qubit,), backend=backend) underamp_exp.set_transpile_options(inst_map=inst_map) exp_data_under = underamp_exp.run(backend).block_for_results() @@ -459,7 +459,7 @@ error which we want to correct. from qiskit_experiments.library import FineSXAmplitudeCal - amp_cal = FineSXAmplitudeCal([qubit], cals, backend=backend, schedule_name="sx") + amp_cal = FineSXAmplitudeCal((qubit,), cals, backend=backend, schedule_name="sx") amp_cal.circuits()[4].draw(output="mpl") Let's run the calibration experiment: diff --git a/docs/tutorials/data_processor.rst b/docs/tutorials/data_processor.rst index dec2c19184..96eb265a0c 100644 --- a/docs/tutorials/data_processor.rst +++ b/docs/tutorials/data_processor.rst @@ -88,7 +88,7 @@ The code below sets up the Rabi experiment. backend = SingleTransmonTestBackend(seed=100) exp = Rabi( - qubit=0, + physical_qubits=(0,), backend=backend, schedule=sched, amplitudes=np.linspace(-0.1, 0.1, 21) diff --git a/qiskit_experiments/curve_analysis/__init__.py b/qiskit_experiments/curve_analysis/__init__.py index b1884eb781..2a3b77e7a0 100644 --- a/qiskit_experiments/curve_analysis/__init__.py +++ b/qiskit_experiments/curve_analysis/__init__.py @@ -81,9 +81,6 @@ fit_function.sqrt_lorentzian fit_function.sin fit_function.sin_decay - fit_function.bloch_oscillation_x - fit_function.bloch_oscillation_y - fit_function.bloch_oscillation_z Initial Guess Estimators ======================== @@ -129,8 +126,6 @@ SeriesDef, ) from .curve_fit import ( - curve_fit, - multi_curve_fit, process_curve_data, process_multi_curve_data, ) diff --git a/qiskit_experiments/curve_analysis/base_curve_analysis.py b/qiskit_experiments/curve_analysis/base_curve_analysis.py index faf9481b6c..408aff89a4 100644 --- a/qiskit_experiments/curve_analysis/base_curve_analysis.py +++ b/qiskit_experiments/curve_analysis/base_curve_analysis.py @@ -20,6 +20,8 @@ import lmfit +from qiskit.utils.deprecation import deprecate_func + from qiskit_experiments.data_processing import DataProcessor from qiskit_experiments.data_processing.processor_library import get_processor from qiskit_experiments.framework import ( @@ -35,7 +37,6 @@ LegacyCurveCompatDrawer, MplDrawer, ) -from qiskit_experiments.warnings import deprecated_function from .curve_data import CurveData, CurveFitResult, ParameterRepr @@ -131,9 +132,11 @@ def plotter(self) -> BasePlotter: return self._options.plotter @property - @deprecated_function( - last_version="0.6", - msg="Replaced by `plotter` from the new visualization submodule.", + @deprecate_func( + since="0.5", + additional_msg="Use `plotter` from the new visualization module.", + removal_timeline="after 0.6", + package_name="qiskit-experiments", ) def drawer(self) -> BaseDrawer: """A short-cut for curve drawer instance, if set. ``None`` otherwise.""" diff --git a/qiskit_experiments/curve_analysis/composite_curve_analysis.py b/qiskit_experiments/curve_analysis/composite_curve_analysis.py index 438b7ae573..093bc5f791 100644 --- a/qiskit_experiments/curve_analysis/composite_curve_analysis.py +++ b/qiskit_experiments/curve_analysis/composite_curve_analysis.py @@ -21,6 +21,8 @@ import numpy as np from uncertainties import unumpy as unp +from qiskit.utils.deprecation import deprecate_func + from qiskit_experiments.framework import ( AnalysisResultData, BaseAnalysis, @@ -34,7 +36,6 @@ LegacyCurveCompatDrawer, MplDrawer, ) -from qiskit_experiments.warnings import deprecated_function from .base_curve_analysis import PARAMS_ENTRY_PREFIX, BaseCurveAnalysis from .curve_data import CurveFitResult @@ -142,9 +143,11 @@ def plotter(self) -> BasePlotter: return self._options.plotter @property - @deprecated_function( - last_version="0.6", - msg="Replaced by `plotter` from the new visualization submodule.", + @deprecate_func( + since="0.5", + additional_msg="Use `plotter` from the new visualization module instead.", + removal_timeline="after 0.6", + package_name="qiskit-experiments", ) def drawer(self) -> BaseDrawer: """A short-cut for curve drawer instance, if set. ``None`` otherwise.""" diff --git a/qiskit_experiments/curve_analysis/curve_data.py b/qiskit_experiments/curve_analysis/curve_data.py index 4a84a78bd8..0c30a29451 100644 --- a/qiskit_experiments/curve_analysis/curve_data.py +++ b/qiskit_experiments/curve_analysis/curve_data.py @@ -21,11 +21,12 @@ import numpy as np import uncertainties from uncertainties.unumpy import uarray + +from qiskit.utils.deprecation import deprecate_func + from qiskit_experiments.exceptions import AnalysisError -from qiskit_experiments.warnings import deprecated_function, deprecated_class -@deprecated_class("0.5", msg="SeriesDef is now replaced with LMFIT Model.") @dataclasses.dataclass(frozen=True) class SeriesDef: """A dataclass to describe the definition of the curve. @@ -62,6 +63,16 @@ class SeriesDef: model_description: Optional[str] = None signature: Tuple[str, ...] = dataclasses.field(init=False) + @deprecate_func( + since="0.5", + additional_msg="SeriesDef has been replaced by the LMFIT module.", + removal_timeline="after 0.6", + package_name="qiskit-experiments", + ) + def __init__(self, *args, **kwargs): + self.args = args + self.kwargs = kwargs + def __post_init__(self): """Parse the fit function signature to extract the names of the variables. Fit functions take arguments F(x, p0, p1, p2, ...) thus the first value should be excluded. @@ -249,11 +260,6 @@ def correl(self): setattr(self, "_correl", correl) return correl - @deprecated_function("0.5", "Use '.ufloat_params' which returns a dictionary instead.") - def fitval(self, key: str) -> uncertainties.UFloat: - """Deprecated. Return UFloat parameter specified by the key.""" - return self.ufloat_params[key] - def __str__(self): ret = "CurveFitResult:" ret += f"\n - fitting method: {self.method}" @@ -328,9 +334,6 @@ def __json_decode__(cls, value): return cls(**value) -@deprecated_class( - "0.5", msg="Fit data is replaced with 'CurveFitResult' based on LMFIT minimizer result." -) @dataclasses.dataclass(frozen=True) class FitData: """A dataclass to store the outcome of the fitting. @@ -353,6 +356,15 @@ class FitData: x_data: np.ndarray y_data: np.ndarray + @deprecate_func( + since="0.5", + additional_msg="Fit data is replaced with 'CurveFitResult' based on LMFIT minimizer result.", + removal_timeline="after 0.6", + package_name="qiskit-experiments", + ) + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + @property def x_range(self) -> Tuple[float, float]: """Range of x values.""" diff --git a/qiskit_experiments/curve_analysis/curve_fit.py b/qiskit_experiments/curve_analysis/curve_fit.py index 103770260d..6eef235dca 100644 --- a/qiskit_experiments/curve_analysis/curve_fit.py +++ b/qiskit_experiments/curve_analysis/curve_fit.py @@ -12,254 +12,10 @@ """ Curve fitting functions for experiment analysis """ -# pylint: disable = invalid-name - -from typing import List, Dict, Tuple, Callable, Optional, Union +from typing import List, Dict, Tuple, Callable import numpy as np -import uncertainties -import scipy.optimize as opt -from qiskit_experiments.exceptions import AnalysisError from qiskit_experiments.curve_analysis.utils import filter_data -from qiskit_experiments.curve_analysis.curve_data import FitData -from qiskit_experiments.warnings import deprecated_function - - -@deprecated_function("0.5", "This function has been replaced with the LMFIT library.") -def curve_fit( - func: Callable, - xdata: np.ndarray, - ydata: np.ndarray, - p0: Union[Dict[str, float], np.ndarray], - sigma: Optional[np.ndarray] = None, - bounds: Optional[Union[Dict[str, Tuple[float, float]], Tuple[np.ndarray, np.ndarray]]] = None, - **kwargs, -) -> FitData: - r"""Perform a non-linear least squares to fit - - This solves the optimization problem - - .. math:: - \Theta_{\mbox{opt}} = \arg\min_\Theta \sum_i - \sigma_i^{-2} (f(x_i, \Theta) - y_i)^2 - - using :func:`scipy.optimize.curve_fit`. - - Args: - func: a fit function `f(x, *params)`. - xdata: a 1D float array of x-data. - ydata: a 1D float array of y-data. - p0: initial guess for optimization parameters. - sigma: Optional, a 1D array of standard deviations in ydata - in absolute units. - bounds: Optional, lower and upper bounds for optimization - parameters. - kwargs: additional kwargs for :func:`scipy.optimize.curve_fit`. - - Returns: - result containing ``popt`` the optimal fit parameters, - ``popt_err`` the standard error estimates popt, - ``pcov`` the covariance matrix for the fit, - ``reduced_chisq`` the reduced chi-squared parameter of fit, - ``dof`` the degrees of freedom of the fit, - ``xrange`` the range of xdata values used for fit. - - Raises: - AnalysisError: - When the number of degrees of freedom of the fit is - less than 1, or the curve fitting fails. - - .. note:: - ``sigma`` is assumed to be specified in the same units as ``ydata`` - (absolute units). If sigma is instead specified in relative units - the `absolute_sigma=False` kwarg of scipy - :func:`~scipy.optimize.curve_fit` must be used. This affects the - returned covariance ``pcov`` and error ``popt_err`` parameters via - ``pcov(absolute_sigma=False) = pcov * reduced_chisq`` - ``popt_err(absolute_sigma=False) = popt_err * sqrt(reduced_chisq)``. - """ - # Format p0 parameters if specified as dictionary - if isinstance(p0, dict): - param_keys = list(p0.keys()) - param_p0 = list(p0.values()) - - # Convert bounds - if bounds: - lower = [bounds[key][0] for key in param_keys] - upper = [bounds[key][1] for key in param_keys] - param_bounds = (lower, upper) - else: - param_bounds = ([-np.inf] * len(param_keys), [np.inf] * len(param_keys)) - - # Convert fit function - def fit_func(x, *params): - return func(x, **dict(zip(param_keys, params))) - - else: - param_keys = [f"p{i}" for i in range(len(p0))] - param_p0 = p0 - if bounds: - param_bounds = bounds - else: - param_bounds = ([-np.inf] * len(p0), [np.inf] * len(p0)) - fit_func = func - - # Check the degrees of freedom is greater than 0 - dof = len(ydata) - len(param_p0) - if dof < 1: - raise AnalysisError( - "The number of degrees of freedom of the fit data and model " - " (len(ydata) - len(p0)) is less than 1" - ) - - # Format non-number sigma values - if sigma is not None: - if np.all(np.isnan(sigma)): - sigma = None - else: - sigma = np.nan_to_num(sigma) - if np.count_nonzero(sigma) != len(sigma): - # Sigma = 0 causes zero division error - sigma = None - - # Override scipy.curve_fit default for absolute_sigma=True - # if sigma is specified. - if sigma is not None and "absolute_sigma" not in kwargs: - kwargs["absolute_sigma"] = True - - # Run curve fit - try: - # pylint: disable = unbalanced-tuple-unpacking - popt, pcov = opt.curve_fit( - fit_func, xdata, ydata, sigma=sigma, p0=param_p0, bounds=param_bounds, **kwargs - ) - except Exception as ex: - raise AnalysisError(f"scipy.optimize.curve_fit failed with error: {str(ex)}") from ex - - if np.isfinite(pcov).all(): - # Keep parameter correlations in following analysis steps - fit_params = uncertainties.correlated_values( - nom_values=popt, covariance_mat=pcov, tags=param_keys - ) - else: - # Ignore correlations, add standard error if finite. - fit_params = [ - uncertainties.ufloat(nominal_value=n, std_dev=s if np.isfinite(s) else np.nan) - for n, s in zip(popt, np.sqrt(np.diag(pcov))) - ] - - # Calculate the reduced chi-squared for fit - yfits = fit_func(xdata, *popt) - residues = (yfits - ydata) ** 2 - if sigma is not None: - residues = residues / (sigma**2) - reduced_chisq = np.sum(residues) / dof - - return FitData( - popt=list(fit_params), - popt_keys=list(param_keys), - pcov=pcov, - reduced_chisq=reduced_chisq, - dof=dof, - x_data=xdata, - y_data=ydata, - ) - - -@deprecated_function("0.5", "This function has been replaced with the LMFIT library.") -def multi_curve_fit( - funcs: List[Callable], - series: np.ndarray, - xdata: np.ndarray, - ydata: np.ndarray, - p0: np.ndarray, - sigma: Optional[np.ndarray] = None, - weights: Optional[np.ndarray] = None, - bounds: Optional[Union[Dict[str, Tuple[float, float]], Tuple[np.ndarray, np.ndarray]]] = None, - **kwargs, -) -> FitData: - r"""Perform a linearized multi-objective non-linear least squares fit. - - This solves the optimization problem - - .. math:: - \Theta_{\mbox{opt}} = \arg\min_\Theta \sum_{k} w_k - \sum_{i} \sigma_{k, i}^{-2} - (f_k(x_{k, i}, \Theta) - y_{k, i})^2 - - for multiple series of :math:`x_k, y_k, \sigma_k` data evaluated using - a list of objective functions :math:`[f_k]` - using :func:`scipy.optimize.curve_fit`. - - Args: - funcs: a list of objective functions :math:`[f_0, f_1, ...]` where - each function has signature :math`f_k(x, \Theta)`. - series: a 1D int array that specifies the component objective - function :math:`f_k` to evaluate corresponding x and y - data with. - xdata: a 1D float array of xdata. - ydata: a 1D float array of ydata. - p0: initial guess for optimization parameters. - sigma: Optional, a 1D array of standard deviations in ydata - in absolute units. - weights: Optional, a 1D float list of weights :math:`w_k` for each - component function :math:`f_k`. - bounds: Optional, lower and upper bounds for optimization - parameters. - kwargs: additional kwargs for :func:`scipy.optimize.curve_fit`. - - Returns: - result containing ``popt`` the optimal fit parameters, - ``popt_err`` the standard error estimates popt, - ``pcov`` the covariance matrix for the fit, - ``reduced_chisq`` the reduced chi-squared parameter of fit, - ``dof`` the degrees of freedom of the fit, - ``xrange`` the range of xdata values used for fit. - - Raises: - AnalysisError: If the number of degrees of freedom of the fit is - less than 1, or the curve fitting fails. - - .. note:: - ``sigma`` is assumed to be specified in the same units as ``ydata`` - (absolute units). If sigma is instead specified in relative units - the `absolute_sigma=False` kwarg of scipy - :func:`~scipy.optimize.curve_fit` must be used. This affects the - returned covariance ``pcov`` and error ``popt_err`` parameters via - ``pcov(absolute_sigma=False) = pcov * reduced_chisq`` - ``popt_err(absolute_sigma=False) = popt_err * sqrt(reduced_chisq)``. - """ - num_funcs = len(funcs) - - # Get positions for indexes data sets - series = np.asarray(series, dtype=int) - idxs = [series == i for i in range(num_funcs)] - - # Combine weights and sigma for transformation - if weights is None: - wsigma = sigma - else: - wsigma = np.zeros(ydata.size) - if sigma is None: - for i in range(num_funcs): - wsigma[idxs[i]] = 1 / np.sqrt(weights[i]) - else: - for i in range(num_funcs): - wsigma[idxs[i]] = sigma[idxs[i]] / np.sqrt(weights[i]) - - # Define multi-objective function - def f(x, *args, **kwargs): - y = np.zeros(x.size) - for i in range(num_funcs): - xi = x[idxs[i]] - yi = funcs[i](xi, *args, **kwargs) - y[idxs[i]] = yi - return y - - # Run linearized curve_fit - result_data = curve_fit(f, xdata, ydata, p0, sigma=wsigma, bounds=bounds, **kwargs) - - return result_data def process_curve_data( diff --git a/qiskit_experiments/curve_analysis/fit_function.py b/qiskit_experiments/curve_analysis/fit_function.py index d70ac10e84..6b5d655ff5 100644 --- a/qiskit_experiments/curve_analysis/fit_function.py +++ b/qiskit_experiments/curve_analysis/fit_function.py @@ -14,37 +14,7 @@ A library of fit functions. """ # pylint: disable=invalid-name, no-member - -import functools -from typing import Callable, Union - import numpy as np -from uncertainties import UFloat -from qiskit_experiments.warnings import deprecated_function - - -@deprecated_function("0.5", "LMFIT fitter does not take UFloat functions.") -def typecast_float(fit_func: Callable) -> Callable: - """A decorator to typecast y values to a float array if the input parameters have no error. - - Args: - fit_func: Fit function that returns a ufloat array or an array of float. - - Returns: - Fit function with typecast. - """ - - @functools.wraps(fit_func) - def _wrapper(x, *args, **kwargs) -> Union[float, UFloat, np.ndarray]: - yvals = fit_func(x, *args, **kwargs) - try: - if isinstance(x, float): - return float(yvals) - return yvals.astype(float) - except TypeError: - return yvals - - return _wrapper def cos( @@ -149,57 +119,3 @@ def sin_decay( + {\rm phase}\right) + {\rm baseline} """ return exponential_decay(x, lamb=1 / tau) * sin(x, amp=amp, freq=freq, phase=phase) + baseline - - -@deprecated_function("0.5", "Now fit function can be defined with Python string.") -def bloch_oscillation_x( - x: np.ndarray, px: float = 0.0, py: float = 0.0, pz: float = 0.0, baseline: float = 0.0 -): - r"""Bloch oscillation in x basis. - - .. math:: - y = \frac{\left( - p_z p_x + p_z p_x \cos (\omega x) - + \omega p_y \sin (\omega x) \right)}{\omega^2} + {\rm baseline}, - - where :math:`\omega = \sqrt{p_x^2 + p_y^2 + p_z^2}`. The `p_i` stands for the - measured probability in :math:`i \in \left\{ X, Y, Z \right\}` basis. - """ - w = np.sqrt(px**2 + py**2 + pz**2) - - return (-pz * px + pz * px * np.cos(w * x) + w * py * np.sin(w * x)) / (w**2) + baseline - - -@deprecated_function("0.5", "Now fit function can be defined with Python string.") -def bloch_oscillation_y( - x: np.ndarray, px: float = 0.0, py: float = 0.0, pz: float = 0.0, baseline: float = 0.0 -): - r"""Bloch oscillation in y basis. - - .. math:: - y = \frac{\left( p_z p_y - p_z p_y \cos (\omega x) - - \omega p_x \sin (\omega x) \right)}{\omega^2} + {\rm baseline}, - - where :math:`\omega = \sqrt{p_x^2 + p_y^2 + p_z^2}`. The `p_i` stands for the - measured probability in :math:`i \in \left\{ X, Y, Z \right\}` basis. - """ - w = np.sqrt(px**2 + py**2 + pz**2) - - return (pz * py - pz * py * np.cos(w * x) - w * px * np.sin(w * x)) / (w**2) + baseline - - -@deprecated_function("0.5", "Now fit function can be defined with Python string.") -def bloch_oscillation_z( - x: np.ndarray, px: float = 0.0, py: float = 0.0, pz: float = 0.0, baseline: float = 0.0 -): - r"""Bloch oscillation in z basis. - - .. math:: - y = \frac{\left( p_z^2 + (p_x^2 + p_y^2) \cos (\omega x) \right)}{\omega^2} - + {\rm baseline}, - - where :math:`\omega = \sqrt{p_x^2 + p_y^2 + p_z^2}`. The `p_i` stands for the - measured probability in :math:`i \in \left\{ X, Y, Z \right\}` basis. - """ - w = np.sqrt(px**2 + py**2 + pz**2) - - return (pz**2 + (px**2 + py**2) * np.cos(w * x)) / (w**2) + baseline diff --git a/qiskit_experiments/curve_analysis/standard_analysis/oscillation.py b/qiskit_experiments/curve_analysis/standard_analysis/oscillation.py index 68155340ea..461698c367 100644 --- a/qiskit_experiments/curve_analysis/standard_analysis/oscillation.py +++ b/qiskit_experiments/curve_analysis/standard_analysis/oscillation.py @@ -18,7 +18,6 @@ import numpy as np import qiskit_experiments.curve_analysis as curve -from qiskit_experiments.warnings import deprecated_class class OscillationAnalysis(curve.CurveAnalysis): @@ -278,10 +277,3 @@ def _evaluate_quality(self, fit_data: curve.CurveFitResult) -> Union[str, None]: return "good" return "bad" - - -@deprecated_class("0.5", new_cls=DampedOscillationAnalysis) -class DumpedOscillationAnalysis: - """Deprecated.""" - - pass diff --git a/qiskit_experiments/curve_analysis/visualization/base_drawer.py b/qiskit_experiments/curve_analysis/visualization/base_drawer.py index 60fbca8f8f..c620927b88 100644 --- a/qiskit_experiments/curve_analysis/visualization/base_drawer.py +++ b/qiskit_experiments/curve_analysis/visualization/base_drawer.py @@ -15,15 +15,11 @@ from abc import ABC, abstractmethod from typing import Dict, Optional, Sequence +from qiskit.utils.deprecation import deprecate_func + from qiskit_experiments.framework import Options -from qiskit_experiments.warnings import deprecated_class -@deprecated_class( - "0.6", - msg="Plotting and drawing of analysis figures has been moved to the new " - "`qiskit_experiments.visualization` module.", -) class BaseCurveDrawer(ABC): """Abstract class for the serializable Qiskit Experiments curve drawer. @@ -84,6 +80,13 @@ class BaseCurveDrawer(ABC): """ + @deprecate_func( + since="0.5", + additional_msg="Plotting and drawing functionality has been moved to the new " + "`qiskit_experiments.visualization` module.", + removal_timeline="after 0.6", + package_name="qiskit-experiments", + ) def __init__(self): self._options = self._default_options() self._set_options = set() diff --git a/qiskit_experiments/curve_analysis/visualization/curves.py b/qiskit_experiments/curve_analysis/visualization/curves.py index c04318d39f..2b2d61dce0 100644 --- a/qiskit_experiments/curve_analysis/visualization/curves.py +++ b/qiskit_experiments/curve_analysis/visualization/curves.py @@ -17,15 +17,18 @@ import numpy as np from uncertainties import unumpy as unp +from qiskit.utils.deprecation import deprecate_func + from qiskit_experiments.curve_analysis.curve_data import FitData from qiskit_experiments.framework.matplotlib import get_non_gui_ax -from qiskit_experiments.warnings import deprecated_function -@deprecated_function( - "0.6", - msg="Plotting and drawing functionality has been moved to the new " +@deprecate_func( + since="0.5", + additional_msg="Plotting and drawing functionality has been moved to the new " "`qiskit_experiments.visualization` module.", + removal_timeline="after 0.6", + package_name="qiskit-experiments", ) def plot_curve_fit( func: Callable, @@ -101,10 +104,12 @@ def plot_curve_fit( return ax -@deprecated_function( - "0.6", - msg="Plotting and drawing functionality has been moved to the new " +@deprecate_func( + since="0.5", + additional_msg="Plotting and drawing functionality has been moved to the new " "`qiskit_experiments.visualization` module.", + removal_timeline="after 0.6", + package_name="qiskit-experiments", ) def plot_scatter( xdata: np.ndarray, @@ -150,10 +155,12 @@ def plot_scatter( return ax -@deprecated_function( - "0.6", - msg="Plotting and drawing functionality has been moved to the new " +@deprecate_func( + since="0.5", + additional_msg="Plotting and drawing functionality has been moved to the new " "`qiskit_experiments.visualization` module.", + removal_timeline="after 0.6", + package_name="qiskit-experiments", ) def plot_errorbar( xdata: np.ndarray, diff --git a/qiskit_experiments/curve_analysis/visualization/fit_result_plotters.py b/qiskit_experiments/curve_analysis/visualization/fit_result_plotters.py index a6f835c88f..5c9e9cbfbd 100644 --- a/qiskit_experiments/curve_analysis/visualization/fit_result_plotters.py +++ b/qiskit_experiments/curve_analysis/visualization/fit_result_plotters.py @@ -29,24 +29,29 @@ import uncertainties from matplotlib.ticker import FuncFormatter from qiskit.utils import detach_prefix +from qiskit.utils.deprecation import deprecate_func from qiskit_experiments.curve_analysis.curve_data import CurveData, FitData, SeriesDef from qiskit_experiments.framework import AnalysisResultData from qiskit_experiments.framework.matplotlib import get_non_gui_ax -from qiskit_experiments.warnings import deprecated_class, deprecated_function from .curves import plot_curve_fit, plot_errorbar, plot_scatter from .style import PlotterStyle -@deprecated_class( - "0.6", - msg="Plotting and drawing of analysis figures has been moved to the new " - "`qiskit_experiments.visualization` module.", -) class MplDrawSingleCanvas: """A plotter to draw a single canvas figure for fit result.""" + @deprecate_func( + since="0.5", + additional_msg="Plotting and drawing of analysis figures has been moved to the new " + "`qiskit_experiments.visualization` module.", + removal_timeline="after 0.6", + package_name="qiskit-experiments", + ) + def __init__(self): + super().__init__() + @classmethod def draw( cls, @@ -150,14 +155,19 @@ def draw( return figure -@deprecated_class( - "0.6", - msg="Plotting and drawing of analysis figures has been replaced with the new" - "`qiskit_experiments.visualization` module.", -) class MplDrawMultiCanvasVstack: """A plotter to draw a vertically stacked multi canvas figure for fit result.""" + @deprecate_func( + since="0.5", + additional_msg="Plotting and drawing of analysis figures has been moved to the new " + "`qiskit_experiments.visualization` module.", + removal_timeline="after 0.6", + package_name="qiskit-experiments", + ) + def __init__(self): + pass + @classmethod def draw( cls, @@ -313,10 +323,12 @@ def draw( return figure -@deprecated_function( - "0.6", - msg="Plotting and drawing of analysis figures has been replaced with the new" +@deprecate_func( + since="0.5", + additional_msg="Plotting and drawing of analysis figures has been moved to the new " "`qiskit_experiments.visualization` module.", + removal_timeline="after 0.6", + package_name="qiskit-experiments", ) def draw_single_curve_mpl( axis: "matplotlib.axes.Axes", @@ -371,10 +383,12 @@ def draw_single_curve_mpl( ) -@deprecated_function( - "0.6", - msg="Plotting and drawing of analysis figures has been replaced with the new" +@deprecate_func( + since="0.5", + additional_msg="Plotting and drawing of analysis figures has been moved to the new " "`qiskit_experiments.visualization` module.", + removal_timeline="after 0.6", + package_name="qiskit-experiments", ) def write_fit_report(result_entries: List[AnalysisResultData]) -> str: """A function that generates fit reports documentation from list of data. @@ -439,13 +453,18 @@ def format_val(float_val: float) -> str: # pylint: disable=invalid-name -@deprecated_class( - "0.6", - msg="Plotting and drawing of analysis figures has been moved to the new " - "`qiskit_experiments.visualization` module.", -) class FitResultPlotters(Enum): """Map the plotter name to the plotters.""" mpl_single_canvas = MplDrawSingleCanvas mpl_multiv_canvas = MplDrawMultiCanvasVstack + + @deprecate_func( + since="0.5", + additional_msg="Plotting and drawing of analysis figures has been moved to the new " + "`qiskit_experiments.visualization` module.", + removal_timeline="after 0.6", + package_name="qiskit-experiments", + ) + def __post_init__(self): + pass diff --git a/qiskit_experiments/curve_analysis/visualization/mpl_drawer.py b/qiskit_experiments/curve_analysis/visualization/mpl_drawer.py index 424d329bd9..3463dac1c1 100644 --- a/qiskit_experiments/curve_analysis/visualization/mpl_drawer.py +++ b/qiskit_experiments/curve_analysis/visualization/mpl_drawer.py @@ -21,24 +21,29 @@ from matplotlib.markers import MarkerStyle from matplotlib.ticker import Formatter, ScalarFormatter from qiskit.utils import detach_prefix +from qiskit.utils.deprecation import deprecate_func from qiskit_experiments.framework.matplotlib import get_non_gui_ax -from qiskit_experiments.warnings import deprecated_class from .base_drawer import BaseCurveDrawer -@deprecated_class( - "0.6", - msg="Plotting and drawing of analysis figures has been replaced with the new" - "`qiskit_experiments.visualization` module.", -) class MplCurveDrawer(BaseCurveDrawer): """Curve drawer for MatplotLib backend.""" DefaultMarkers = MarkerStyle.filled_markers DefaultColors = tab10.colors + @deprecate_func( + since="0.5", + additional_msg="Plotting and drawing of analysis figures has been moved to the new " + "`qiskit_experiments.visualization` module.", + removal_timeline="after 0.6", + package_name="qiskit-experiments", + ) + def __init__(self): + super().__init__() + class PrefixFormatter(Formatter): """Matplotlib axis formatter to detach prefix. diff --git a/qiskit_experiments/curve_analysis/visualization/style.py b/qiskit_experiments/curve_analysis/visualization/style.py index 2248ed6fc2..af6fc264c5 100644 --- a/qiskit_experiments/curve_analysis/visualization/style.py +++ b/qiskit_experiments/curve_analysis/visualization/style.py @@ -15,14 +15,9 @@ import dataclasses from typing import List, Tuple -from qiskit_experiments.warnings import deprecated_class +from qiskit.utils.deprecation import deprecate_func -@deprecated_class( - "0.6", - msg="Plotting and drawing of analysis figures has been replaced with the new" - "`qiskit_experiments.visualization` module.", -) @dataclasses.dataclass class PlotterStyle: """A stylesheet for curve analysis figure.""" @@ -50,3 +45,13 @@ class PlotterStyle: plot_sigma: List[Tuple[float, float]] = dataclasses.field( default_factory=lambda: [(1.0, 0.7), (3.0, 0.3)] ) + + @deprecate_func( + since="0.5", + additional_msg="Plotting and drawing of analysis figures has been replaced with the new" + "`qiskit_experiments.visualization` module.", + removal_timeline="after 0.6", + package_name="qiskit-experiments", + ) + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) diff --git a/qiskit_experiments/framework/base_experiment.py b/qiskit_experiments/framework/base_experiment.py index ba43fa9976..bb14cdc610 100644 --- a/qiskit_experiments/framework/base_experiment.py +++ b/qiskit_experiments/framework/base_experiment.py @@ -29,13 +29,11 @@ from qiskit_experiments.framework.experiment_data import ExperimentData from qiskit_experiments.framework.configs import ExperimentConfig from qiskit_experiments.database_service import Qubit -from qiskit_experiments.warnings import deprecate_arguments class BaseExperiment(ABC, StoreInitArgs): """Abstract base class for experiments.""" - @deprecate_arguments({"qubits": "physical_qubits"}, "0.5") def __init__( self, physical_qubits: Sequence[int], diff --git a/qiskit_experiments/framework/composite/composite_experiment.py b/qiskit_experiments/framework/composite/composite_experiment.py index d010979304..16c15a79f3 100644 --- a/qiskit_experiments/framework/composite/composite_experiment.py +++ b/qiskit_experiments/framework/composite/composite_experiment.py @@ -17,7 +17,6 @@ from abc import abstractmethod import warnings from qiskit.providers.backend import Backend -from qiskit_experiments.warnings import deprecate_arguments from qiskit_experiments.exceptions import QiskitError from qiskit_experiments.framework import BaseExperiment from .composite_analysis import CompositeAnalysis @@ -26,7 +25,6 @@ class CompositeExperiment(BaseExperiment): """Composite Experiment base class""" - @deprecate_arguments({"qubits": "physical_qubits"}, "0.5") def __init__( self, experiments: List[BaseExperiment], diff --git a/qiskit_experiments/framework/experiment_data.py b/qiskit_experiments/framework/experiment_data.py index 72bad3ccb8..a1c1ef23f6 100644 --- a/qiskit_experiments/framework/experiment_data.py +++ b/qiskit_experiments/framework/experiment_data.py @@ -738,7 +738,7 @@ def source(self) -> Dict: def add_data( self, - data: Union[Result, List[Result], Job, List[Job], Dict, List[Dict]], + data: Union[Result, List[Result], Dict, List[Dict]], ) -> None: """Add experiment data. @@ -749,8 +749,6 @@ def add_data( * List[Result]: Add data from the ``Result`` objects. * Dict: Add this data. * List[Dict]: Add this list of data. - * Job: (Deprecated) Add data from the job result. - * List[Job]: (Deprecated) Add data from the job results. Raises: TypeError: If the input data type is invalid. diff --git a/qiskit_experiments/framework/json.py b/qiskit_experiments/framework/json.py index 9308ea2bc5..207a69c801 100644 --- a/qiskit_experiments/framework/json.py +++ b/qiskit_experiments/framework/json.py @@ -34,11 +34,7 @@ import uncertainties from qiskit import qpy from qiskit.circuit import ParameterExpression, QuantumCircuit, Instruction -from qiskit.circuit.library import BlueprintCircuit from qiskit.pulse import ScheduleBlock -from qiskit.quantum_info import DensityMatrix -from qiskit.quantum_info.operators.channel.quantum_channel import QuantumChannel -from qiskit.result import LocalReadoutMitigator, CorrelatedReadoutMitigator from qiskit_experiments.version import __version__ @@ -508,9 +504,6 @@ def default(self, obj: Any) -> Any: # pylint: disable=arguments-renamed ) return {"__type__": "Instruction", "__value__": value} if isinstance(obj, QuantumCircuit): - # TODO Remove the decompose when terra 6713 is released. - if isinstance(obj, BlueprintCircuit): - obj = obj.decompose() value = _serialize_and_encode( data=obj, serializer=lambda buff, data: qpy.dump(data, buff) ) @@ -527,31 +520,6 @@ def default(self, obj: Any) -> Any: # pylint: disable=arguments-renamed compress=False, ) return {"__type__": "ParameterExpression", "__value__": value} - if isinstance(obj, QuantumChannel): - # Temporary fix for incorrect settings in qiskit-terra - # See https://github.com/Qiskit/qiskit-terra/pull/7194 - settings = { - "data": obj.data, - "input_dims": obj.input_dims(), - "output_dims": obj.output_dims(), - } - return _serialize_object(obj, settings=settings) - if isinstance(obj, LocalReadoutMitigator): - # Temporary handling until serialization is added to terra stable release - settings = {"assignment_matrices": obj._assignment_mats, "qubits": obj.qubits} - return _serialize_object(obj, settings=settings) - if isinstance(obj, CorrelatedReadoutMitigator): - # Temporary handling until serialization is added to terra stable release - settings = {"assignment_matrix": obj._assignment_mat, "qubits": obj.qubits} - return _serialize_object(obj, settings=settings) - if isinstance(obj, DensityMatrix): - # Temporary fix for incorrect settings in qiskit-terra - # See https://github.com/Qiskit/qiskit-terra/pull/7194 - settings = { - "data": obj.data, - "dims": obj.dims(), - } - return _serialize_object(obj, settings=settings) if istype(obj): return _serialize_type(obj) try: diff --git a/qiskit_experiments/library/calibration/fine_amplitude.py b/qiskit_experiments/library/calibration/fine_amplitude.py index fad3ef344e..8e3ff17972 100644 --- a/qiskit_experiments/library/calibration/fine_amplitude.py +++ b/qiskit_experiments/library/calibration/fine_amplitude.py @@ -25,7 +25,6 @@ from qiskit_experiments.library.characterization import FineAmplitude from qiskit_experiments.framework import ExperimentData, Options from qiskit_experiments.calibration_management.update_library import BaseUpdater -from qiskit_experiments.warnings import qubit_deprecate class FineAmplitudeCal(BaseCalibrationExperiment, FineAmplitude): @@ -39,7 +38,6 @@ class FineAmplitudeCal(BaseCalibrationExperiment, FineAmplitude): """ - @qubit_deprecate() def __init__( self, physical_qubits: Sequence[int], @@ -160,7 +158,6 @@ def update_calibrations(self, experiment_data: ExperimentData): class FineXAmplitudeCal(FineAmplitudeCal): """A calibration experiment to calibrate the amplitude of the X schedule.""" - @qubit_deprecate() def __init__( self, physical_qubits: Sequence[int], @@ -209,7 +206,6 @@ def _pre_circuit(self, num_clbits: int) -> QuantumCircuit: class FineSXAmplitudeCal(FineAmplitudeCal): """A calibration experiment to calibrate the amplitude of the SX schedule.""" - @qubit_deprecate() def __init__( self, physical_qubits: Sequence[int], diff --git a/qiskit_experiments/library/calibration/fine_drag_cal.py b/qiskit_experiments/library/calibration/fine_drag_cal.py index e21b4489d9..7c52e2d6bd 100644 --- a/qiskit_experiments/library/calibration/fine_drag_cal.py +++ b/qiskit_experiments/library/calibration/fine_drag_cal.py @@ -27,13 +27,11 @@ ) from qiskit_experiments.calibration_management.update_library import BaseUpdater from qiskit_experiments.library.characterization.fine_drag import FineDrag -from qiskit_experiments.warnings import qubit_deprecate class FineDragCal(BaseCalibrationExperiment, FineDrag): """A calibration version of the fine drag experiment.""" - @qubit_deprecate() def __init__( self, physical_qubits: Sequence[int], @@ -152,7 +150,6 @@ def update_calibrations(self, experiment_data: ExperimentData): class FineXDragCal(FineDragCal): """Fine drag calibration of X gate.""" - @qubit_deprecate() def __init__( self, physical_qubits: Sequence[int], @@ -185,7 +182,6 @@ def __init__( class FineSXDragCal(FineDragCal): """Fine drag calibration of X gate.""" - @qubit_deprecate() def __init__( self, physical_qubits: Sequence[int], diff --git a/qiskit_experiments/library/calibration/fine_frequency_cal.py b/qiskit_experiments/library/calibration/fine_frequency_cal.py index 049712b7f9..676d51ed26 100644 --- a/qiskit_experiments/library/calibration/fine_frequency_cal.py +++ b/qiskit_experiments/library/calibration/fine_frequency_cal.py @@ -25,13 +25,11 @@ Calibrations, ) from qiskit_experiments.library.characterization.fine_frequency import FineFrequency -from qiskit_experiments.warnings import qubit_deprecate class FineFrequencyCal(BaseCalibrationExperiment, FineFrequency): """A calibration version of the fine frequency experiment.""" - @qubit_deprecate() def __init__( self, physical_qubits: Sequence[int], diff --git a/qiskit_experiments/library/calibration/frequency_cal.py b/qiskit_experiments/library/calibration/frequency_cal.py index 82e52c4eb2..b7b7302109 100644 --- a/qiskit_experiments/library/calibration/frequency_cal.py +++ b/qiskit_experiments/library/calibration/frequency_cal.py @@ -24,13 +24,11 @@ from qiskit_experiments.calibration_management.base_calibration_experiment import ( BaseCalibrationExperiment, ) -from qiskit_experiments.warnings import qubit_deprecate class FrequencyCal(BaseCalibrationExperiment, RamseyXY): """A qubit frequency calibration experiment based on the Ramsey XY experiment.""" - @qubit_deprecate() def __init__( self, physical_qubits: Sequence[int], diff --git a/qiskit_experiments/library/calibration/half_angle_cal.py b/qiskit_experiments/library/calibration/half_angle_cal.py index 2d82512a58..e56ca7f7df 100644 --- a/qiskit_experiments/library/calibration/half_angle_cal.py +++ b/qiskit_experiments/library/calibration/half_angle_cal.py @@ -25,13 +25,11 @@ ) from qiskit_experiments.library.characterization import HalfAngle from qiskit_experiments.calibration_management.update_library import BaseUpdater -from qiskit_experiments.warnings import qubit_deprecate class HalfAngleCal(BaseCalibrationExperiment, HalfAngle): """Calibration version of the half-angle experiment.""" - @qubit_deprecate() def __init__( self, physical_qubits: Sequence[int], diff --git a/qiskit_experiments/library/calibration/rough_amplitude_cal.py b/qiskit_experiments/library/calibration/rough_amplitude_cal.py index a04a13a050..c6bea05d53 100644 --- a/qiskit_experiments/library/calibration/rough_amplitude_cal.py +++ b/qiskit_experiments/library/calibration/rough_amplitude_cal.py @@ -24,7 +24,6 @@ from qiskit_experiments.calibration_management import BaseCalibrationExperiment, Calibrations from qiskit_experiments.library.characterization import Rabi from qiskit_experiments.calibration_management.update_library import BaseUpdater -from qiskit_experiments.warnings import qubit_deprecate AnglesSchedules = namedtuple( "AnglesSchedules", ["target_angle", "parameter", "schedule", "previous_value"] @@ -34,7 +33,6 @@ class RoughAmplitudeCal(BaseCalibrationExperiment, Rabi): """A calibration version of the Rabi experiment.""" - @qubit_deprecate() def __init__( self, physical_qubits: Sequence[int], @@ -193,7 +191,6 @@ def update_calibrations(self, experiment_data: ExperimentData): class RoughXSXAmplitudeCal(RoughAmplitudeCal): """A rough amplitude calibration of x and sx gates.""" - @qubit_deprecate() def __init__( self, physical_qubits: Sequence[int], @@ -227,7 +224,6 @@ class EFRoughXSXAmplitudeCal(RoughAmplitudeCal): __outcome__ = "rabi_rate_12" - @qubit_deprecate() def __init__( self, physical_qubits: Sequence[int], diff --git a/qiskit_experiments/library/calibration/rough_drag_cal.py b/qiskit_experiments/library/calibration/rough_drag_cal.py index d4d2d009ec..53c0efcb63 100644 --- a/qiskit_experiments/library/calibration/rough_drag_cal.py +++ b/qiskit_experiments/library/calibration/rough_drag_cal.py @@ -24,7 +24,6 @@ ) from qiskit_experiments.calibration_management.update_library import BaseUpdater from qiskit_experiments.library.characterization.drag import RoughDrag -from qiskit_experiments.warnings import qubit_deprecate class RoughDragCal(BaseCalibrationExperiment, RoughDrag): @@ -35,7 +34,6 @@ class RoughDragCal(BaseCalibrationExperiment, RoughDrag): """ - @qubit_deprecate() def __init__( self, physical_qubits: Sequence[int], diff --git a/qiskit_experiments/library/calibration/rough_frequency.py b/qiskit_experiments/library/calibration/rough_frequency.py index a618c53749..83d2e6a113 100644 --- a/qiskit_experiments/library/calibration/rough_frequency.py +++ b/qiskit_experiments/library/calibration/rough_frequency.py @@ -24,14 +24,12 @@ from qiskit_experiments.calibration_management.base_calibration_experiment import ( BaseCalibrationExperiment, ) -from qiskit_experiments.warnings import qubit_deprecate class RoughFrequencyCal(BaseCalibrationExperiment, QubitSpectroscopy): """A calibration experiment that runs :class:`.QubitSpectroscopy` to calibrate the qubit transition frequency.""" - @qubit_deprecate() def __init__( self, physical_qubits: Sequence[int], diff --git a/qiskit_experiments/library/characterization/correlated_readout_error.py b/qiskit_experiments/library/characterization/correlated_readout_error.py index d32db59e6e..4fd7742a62 100644 --- a/qiskit_experiments/library/characterization/correlated_readout_error.py +++ b/qiskit_experiments/library/characterization/correlated_readout_error.py @@ -16,7 +16,6 @@ from qiskit import QuantumCircuit from qiskit.providers.backend import BackendV2, Backend from qiskit.exceptions import QiskitError -from qiskit_experiments.warnings import deprecate_arguments from qiskit_experiments.framework import BaseExperiment from qiskit_experiments.library.characterization.analysis.correlated_readout_error_analysis import ( CorrelatedReadoutErrorAnalysis, @@ -81,7 +80,6 @@ class CorrelatedReadoutError(BaseExperiment): .. ref_arxiv:: 1 2006.14044 """ - @deprecate_arguments({"qubits": "physical_qubits"}, "0.5") def __init__( self, physical_qubits: Optional[Iterable[int]] = None, diff --git a/qiskit_experiments/library/characterization/cr_hamiltonian.py b/qiskit_experiments/library/characterization/cr_hamiltonian.py index 11aeb4bc63..e655fd2fc5 100644 --- a/qiskit_experiments/library/characterization/cr_hamiltonian.py +++ b/qiskit_experiments/library/characterization/cr_hamiltonian.py @@ -13,15 +13,13 @@ Cross resonance Hamiltonian tomography. """ -from typing import List, Tuple, Sequence, Iterable, Optional, Type +from typing import List, Tuple, Sequence, Optional, Type -import warnings import numpy as np from qiskit import pulse, circuit, QuantumCircuit from qiskit.circuit.parameterexpression import ParameterValueType from qiskit.exceptions import QiskitError from qiskit.providers import Backend -from qiskit_experiments.warnings import deprecate_arguments from qiskit_experiments.framework import ( BaseExperiment, BackendTiming, @@ -136,11 +134,9 @@ class CRPulseGate(circuit.Gate): def __init__(self, width: ParameterValueType): super().__init__("cr_gate", 2, [width]) - @deprecate_arguments({"qubits": "physical_qubits"}, "0.5") def __init__( self, physical_qubits: Tuple[int, int], - flat_top_widths: Optional[Iterable[float]] = None, backend: Optional[Backend] = None, cr_gate: Optional[Type[circuit.Gate]] = None, durations: Optional[Sequence[int]] = None, @@ -151,10 +147,6 @@ def __init__( Args: physical_qubits: Two-value tuple of qubit indices on which to run tomography. The first index stands for the control qubit. - flat_top_widths: Deprecated. The total duration of the square part of - cross resonance pulse(s) to scan, in units of dt. - The total pulse duration including Gaussian rising and falling edges is - implicitly computed with experiment parameters ``sigma`` and ``risefall``. backend: Optional, the backend to run the experiment on. cr_gate: Optional, circuit gate class representing the cross resonance pulse. Providing this object allows us to run this experiment with circuit simulator, @@ -189,16 +181,11 @@ def __init__( ) self.set_experiment_options(durations=durations, **kwargs) - if flat_top_widths is not None: - # TODO remove this in Qiskit Experiments 0.6 - self.set_experiment_options(flat_top_widths=flat_top_widths) - @classmethod def _default_experiment_options(cls) -> Options: """Default experiment options. Experiment Options: - flat_top_widths (np.ndarray): Deprecated. Length of Gaussian flat top to scan. durations (np.ndarray): The total duration of the cross resonance pulse(s) to scan, in units of sec. Values should be longer than pulse ramps. min_durations (int): The minimum default pulse duration in samples. @@ -212,7 +199,6 @@ def _default_experiment_options(cls) -> Options: risefall (float): Ratio of edge durations to sigma. """ options = super()._default_experiment_options() - options.flat_top_widths = None # to be removed in Qiskit Experiments 0.6 options.durations = None options.min_durations = 60e-9 options.max_durations = 1200e-9 @@ -224,18 +210,6 @@ def _default_experiment_options(cls) -> Options: return options - def set_experiment_options(self, **fields): - if "flat_top_widths" in fields: - # TODO remove this in Qiskit Experiments 0.6 - warnings.warn( - "'flat_top_widths' argument has been deprecated and will be removed. " - "Use 'durations' instead. New variable includes pulse ramps, " - "and it cannot include zero in the sequence. " - "This argument will be dropped with this warning in Qiskit Experiments 0.6.", - DeprecationWarning, - ) - super().set_experiment_options(**fields) - def _set_backend(self, backend: Backend): """Set the backend for the experiment with timing analysis.""" super()._set_backend(backend) @@ -269,11 +243,6 @@ def _get_durations(self) -> np.ndarray: """Return cross resonance pulse durations in units of sec.""" opt = self.experiment_options - if opt.flat_top_widths is not None: - # TODO Remove this in Qiskit Experiments 0.6 - widths = np.asarray(opt.flat_top_widths, dtype=float) - return self._get_dt() * (widths + 2 * opt.sigma * opt.risefall) - if opt.durations is None: return np.linspace(opt.min_durations, opt.max_durations, opt.num_durations) diff --git a/qiskit_experiments/library/characterization/drag.py b/qiskit_experiments/library/characterization/drag.py index c0a0d2f427..7e7639fe3b 100644 --- a/qiskit_experiments/library/characterization/drag.py +++ b/qiskit_experiments/library/characterization/drag.py @@ -24,7 +24,6 @@ from qiskit_experiments.framework import BaseExperiment, Options from qiskit_experiments.framework.restless_mixin import RestlessMixin from qiskit_experiments.library.characterization.analysis import DragCalAnalysis -from qiskit_experiments.warnings import qubit_deprecate class RoughDrag(BaseExperiment, RestlessMixin): @@ -93,7 +92,6 @@ def _default_experiment_options(cls) -> Options: return options - @qubit_deprecate() def __init__( self, physical_qubits: Sequence[int], diff --git a/qiskit_experiments/library/characterization/ef_spectroscopy.py b/qiskit_experiments/library/characterization/ef_spectroscopy.py index ab5795269d..7e07d93cd6 100644 --- a/qiskit_experiments/library/characterization/ef_spectroscopy.py +++ b/qiskit_experiments/library/characterization/ef_spectroscopy.py @@ -19,7 +19,6 @@ from qiskit_experiments.curve_analysis import ParameterRepr from qiskit_experiments.library.characterization.qubit_spectroscopy import QubitSpectroscopy -from qiskit_experiments.warnings import qubit_deprecate class EFSpectroscopy(QubitSpectroscopy): @@ -38,7 +37,6 @@ class EFSpectroscopy(QubitSpectroscopy): """ - @qubit_deprecate() def __init__( self, physical_qubits: Sequence[int], diff --git a/qiskit_experiments/library/characterization/fine_amplitude.py b/qiskit_experiments/library/characterization/fine_amplitude.py index e8502c6cd7..7cf32a6138 100644 --- a/qiskit_experiments/library/characterization/fine_amplitude.py +++ b/qiskit_experiments/library/characterization/fine_amplitude.py @@ -23,7 +23,6 @@ from qiskit_experiments.framework import BaseExperiment, Options from qiskit_experiments.framework.restless_mixin import RestlessMixin from qiskit_experiments.library.characterization.analysis import FineAmplitudeAnalysis -from qiskit_experiments.warnings import deprecate_arguments, qubit_deprecate class FineAmplitude(BaseExperiment, RestlessMixin): @@ -113,7 +112,6 @@ def _default_experiment_options(cls) -> Options: return options - @deprecate_arguments({"qubits": "physical_qubits"}, "0.5") def __init__( self, physical_qubits: Sequence[int], @@ -261,7 +259,6 @@ class FineXAmplitude(FineAmplitude): the appropriate values for the default options. """ - @qubit_deprecate() def __init__(self, physical_qubits: Sequence[int], backend: Optional[Backend] = None): """Initialize the experiment.""" super().__init__(physical_qubits, XGate(), backend=backend) @@ -300,7 +297,6 @@ class FineSXAmplitude(FineAmplitude): the appropriate values for the default options. """ - @qubit_deprecate() def __init__(self, physical_qubits: Sequence[int], backend: Optional[Backend] = None): """Initialize the experiment.""" super().__init__(physical_qubits, SXGate(), backend=backend) @@ -361,7 +357,6 @@ class FineZXAmplitude(FineAmplitude): :code:`RZXGate(np.pi / 2)` rotation. """ - @deprecate_arguments({"qubits": "physical_qubits"}, "0.5") def __init__(self, physical_qubits: Sequence[int], backend: Optional[Backend] = None): """Initialize the experiment.""" diff --git a/qiskit_experiments/library/characterization/fine_drag.py b/qiskit_experiments/library/characterization/fine_drag.py index bde071bf00..175aa6e571 100644 --- a/qiskit_experiments/library/characterization/fine_drag.py +++ b/qiskit_experiments/library/characterization/fine_drag.py @@ -22,7 +22,6 @@ from qiskit_experiments.framework import BaseExperiment, Options from qiskit_experiments.framework.restless_mixin import RestlessMixin from qiskit_experiments.curve_analysis.standard_analysis import ErrorAmplificationAnalysis -from qiskit_experiments.warnings import qubit_deprecate class FineDrag(BaseExperiment, RestlessMixin): @@ -150,7 +149,6 @@ def _default_experiment_options(cls) -> Options: return options - @qubit_deprecate() def __init__( self, physical_qubits: Sequence[int], gate: Gate, backend: Optional[Backend] = None ): @@ -244,7 +242,6 @@ def _metadata(self): class FineXDrag(FineDrag): """Class to fine characterize the DRAG parameter of an X gate.""" - @qubit_deprecate() def __init__(self, physical_qubits: Sequence[int], backend: Optional[Backend] = None): """Initialize the experiment.""" super().__init__(physical_qubits, XGate(), backend=backend) @@ -270,7 +267,6 @@ def _pre_circuit() -> QuantumCircuit: class FineSXDrag(FineDrag): """Class to fine characterize the DRAG parameter of an :math:`SX` gate.""" - @qubit_deprecate() def __init__(self, physical_qubits: Sequence[int], backend: Optional[Backend] = None): """Initialize the experiment.""" super().__init__(physical_qubits, SXGate(), backend=backend) diff --git a/qiskit_experiments/library/characterization/fine_frequency.py b/qiskit_experiments/library/characterization/fine_frequency.py index d280d9fff4..5505b320a9 100644 --- a/qiskit_experiments/library/characterization/fine_frequency.py +++ b/qiskit_experiments/library/characterization/fine_frequency.py @@ -20,7 +20,6 @@ from qiskit_experiments.framework import BaseExperiment, Options from qiskit_experiments.curve_analysis.standard_analysis import ErrorAmplificationAnalysis -from qiskit_experiments.warnings import qubit_deprecate class FineFrequency(BaseExperiment): @@ -51,7 +50,6 @@ class FineFrequency(BaseExperiment): :class:`~qiskit_experiments.curve_analysis.ErrorAmplificationAnalysis` """ - @qubit_deprecate() def __init__( self, physical_qubits: Sequence[int], diff --git a/qiskit_experiments/library/characterization/half_angle.py b/qiskit_experiments/library/characterization/half_angle.py index 7a3b84bf8b..2b17e68949 100644 --- a/qiskit_experiments/library/characterization/half_angle.py +++ b/qiskit_experiments/library/characterization/half_angle.py @@ -21,7 +21,6 @@ from qiskit_experiments.framework import BaseExperiment, Options from qiskit_experiments.curve_analysis.standard_analysis import ErrorAmplificationAnalysis from qiskit_experiments.curve_analysis import ParameterRepr -from qiskit_experiments.warnings import qubit_deprecate class HalfAngle(BaseExperiment): @@ -79,7 +78,6 @@ def _default_transpile_options(cls) -> Options: options.inst_map = None return options - @qubit_deprecate() def __init__(self, physical_qubits: Sequence[int], backend: Optional[Backend] = None): """Setup a half angle experiment on the given qubit. diff --git a/qiskit_experiments/library/characterization/local_readout_error.py b/qiskit_experiments/library/characterization/local_readout_error.py index ed7e7941d4..dfc893e7ba 100644 --- a/qiskit_experiments/library/characterization/local_readout_error.py +++ b/qiskit_experiments/library/characterization/local_readout_error.py @@ -16,7 +16,6 @@ from qiskit import QuantumCircuit from qiskit.providers.backend import BackendV2, Backend from qiskit.exceptions import QiskitError -from qiskit_experiments.warnings import deprecate_arguments from qiskit_experiments.framework import BaseExperiment from qiskit_experiments.library.characterization.analysis.local_readout_error_analysis import ( LocalReadoutErrorAnalysis, @@ -70,7 +69,6 @@ class LocalReadoutError(BaseExperiment): .. ref_arxiv:: 1 2006.14044 """ - @deprecate_arguments({"qubits": "physical_qubits"}, "0.5") def __init__( self, physical_qubits: Optional[Iterable[int]] = None, diff --git a/qiskit_experiments/library/characterization/multi_state_discrimination.py b/qiskit_experiments/library/characterization/multi_state_discrimination.py index f4e2689f7b..14078af813 100644 --- a/qiskit_experiments/library/characterization/multi_state_discrimination.py +++ b/qiskit_experiments/library/characterization/multi_state_discrimination.py @@ -21,7 +21,6 @@ from qiskit.pulse import ScheduleBlock from qiskit.qobj.utils import MeasLevel, MeasReturnType from qiskit_experiments.framework import BaseExperiment -from qiskit_experiments.warnings import qubit_deprecate from qiskit_experiments.library.characterization import MultiStateDiscriminationAnalysis @@ -87,7 +86,6 @@ def _default_experiment_options(cls) -> Options: return options - @qubit_deprecate() def __init__( self, physical_qubits: Sequence[int], diff --git a/qiskit_experiments/library/characterization/rabi.py b/qiskit_experiments/library/characterization/rabi.py index 2b2d73ae10..2ce4f1a83b 100644 --- a/qiskit_experiments/library/characterization/rabi.py +++ b/qiskit_experiments/library/characterization/rabi.py @@ -25,7 +25,6 @@ from qiskit_experiments.framework import BaseExperiment, Options from qiskit_experiments.framework.restless_mixin import RestlessMixin from qiskit_experiments.curve_analysis import ParameterRepr, OscillationAnalysis -from qiskit_experiments.warnings import qubit_deprecate class Rabi(BaseExperiment, RestlessMixin): @@ -89,7 +88,6 @@ def _default_experiment_options(cls) -> Options: return options - @qubit_deprecate() def __init__( self, physical_qubits: Sequence[int], diff --git a/qiskit_experiments/library/characterization/ramsey_xy.py b/qiskit_experiments/library/characterization/ramsey_xy.py index 0a74c194b2..642b97422a 100644 --- a/qiskit_experiments/library/characterization/ramsey_xy.py +++ b/qiskit_experiments/library/characterization/ramsey_xy.py @@ -23,7 +23,6 @@ from qiskit_experiments.framework import BaseExperiment, Options, BackendTiming from qiskit_experiments.framework.restless_mixin import RestlessMixin from qiskit_experiments.library.characterization.analysis import RamseyXYAnalysis -from qiskit_experiments.warnings import qubit_deprecate class RamseyXY(BaseExperiment, RestlessMixin): @@ -100,7 +99,6 @@ def _default_experiment_options(cls) -> Options: return options - @qubit_deprecate() def __init__( self, physical_qubits: Sequence[int], diff --git a/qiskit_experiments/library/characterization/readout_angle.py b/qiskit_experiments/library/characterization/readout_angle.py index 51c4bab605..72df20c40b 100644 --- a/qiskit_experiments/library/characterization/readout_angle.py +++ b/qiskit_experiments/library/characterization/readout_angle.py @@ -20,7 +20,6 @@ from qiskit.providers.backend import Backend from qiskit_experiments.framework import BaseExperiment, Options -from qiskit_experiments.warnings import qubit_deprecate from qiskit_experiments.library.characterization.analysis.readout_angle_analysis import ( ReadoutAngleAnalysis, ) @@ -61,7 +60,6 @@ def _default_run_options(cls) -> Options: return options - @qubit_deprecate() def __init__( self, physical_qubits: Sequence[int], diff --git a/qiskit_experiments/library/characterization/resonator_spectroscopy.py b/qiskit_experiments/library/characterization/resonator_spectroscopy.py index a26c31c1dd..1d7f6eabd3 100644 --- a/qiskit_experiments/library/characterization/resonator_spectroscopy.py +++ b/qiskit_experiments/library/characterization/resonator_spectroscopy.py @@ -23,7 +23,6 @@ from qiskit_experiments.framework import BackendData, BackendTiming, Options from qiskit_experiments.library.characterization.spectroscopy import Spectroscopy -from qiskit_experiments.warnings import qubit_deprecate from qiskit_experiments.database_service import Resonator from .analysis.resonator_spectroscopy_analysis import ResonatorSpectroscopyAnalysis @@ -147,7 +146,6 @@ def set_experiment_options(self, **fields): ) return super().set_experiment_options(**fields) - @qubit_deprecate() def __init__( self, physical_qubits: Sequence[int], diff --git a/qiskit_experiments/library/characterization/spectroscopy.py b/qiskit_experiments/library/characterization/spectroscopy.py index 8d2de48115..3ca3e3687f 100644 --- a/qiskit_experiments/library/characterization/spectroscopy.py +++ b/qiskit_experiments/library/characterization/spectroscopy.py @@ -24,7 +24,6 @@ from qiskit_experiments.framework import BaseAnalysis, BaseExperiment, Options from qiskit_experiments.curve_analysis import ResonanceAnalysis -from qiskit_experiments.warnings import qubit_deprecate class Spectroscopy(BaseExperiment, ABC): @@ -62,7 +61,6 @@ def _default_run_options(cls) -> Options: return options - @qubit_deprecate() def __init__( self, physical_qubits: Sequence[int], diff --git a/qiskit_experiments/library/characterization/t1.py b/qiskit_experiments/library/characterization/t1.py index 3deb734982..5a70200e64 100644 --- a/qiskit_experiments/library/characterization/t1.py +++ b/qiskit_experiments/library/characterization/t1.py @@ -19,7 +19,6 @@ from qiskit import QuantumCircuit from qiskit.providers.backend import Backend from qiskit_experiments.framework import BackendTiming, BaseExperiment, Options -from qiskit_experiments.warnings import qubit_deprecate from qiskit_experiments.library.characterization.analysis.t1_analysis import T1Analysis @@ -53,7 +52,6 @@ def _default_experiment_options(cls) -> Options: options.delays = None return options - @qubit_deprecate() def __init__( self, physical_qubits: Sequence[int], diff --git a/qiskit_experiments/library/characterization/t2hahn.py b/qiskit_experiments/library/characterization/t2hahn.py index 0f624d5a10..db32fe7431 100644 --- a/qiskit_experiments/library/characterization/t2hahn.py +++ b/qiskit_experiments/library/characterization/t2hahn.py @@ -22,7 +22,6 @@ from qiskit_experiments.framework import BackendTiming, BaseExperiment, Options from qiskit_experiments.library.characterization.analysis.t2hahn_analysis import T2HahnAnalysis -from qiskit_experiments.warnings import qubit_deprecate class T2Hahn(BaseExperiment): @@ -78,7 +77,6 @@ def _default_experiment_options(cls) -> Options: options.num_echoes = 1 return options - @qubit_deprecate() def __init__( self, physical_qubits: Sequence[int], diff --git a/qiskit_experiments/library/characterization/t2ramsey.py b/qiskit_experiments/library/characterization/t2ramsey.py index 75c5ae635c..920c6f25f0 100644 --- a/qiskit_experiments/library/characterization/t2ramsey.py +++ b/qiskit_experiments/library/characterization/t2ramsey.py @@ -23,7 +23,6 @@ from qiskit_experiments.framework import BackendTiming, BaseExperiment, Options from qiskit_experiments.library.characterization.analysis.t2ramsey_analysis import T2RamseyAnalysis -from qiskit_experiments.warnings import qubit_deprecate class T2Ramsey(BaseExperiment): @@ -79,7 +78,6 @@ def _default_experiment_options(cls) -> Options: return options - @qubit_deprecate() def __init__( self, physical_qubits: Sequence[int], diff --git a/qiskit_experiments/library/characterization/tphi.py b/qiskit_experiments/library/characterization/tphi.py index c59717dd87..b19a805c84 100644 --- a/qiskit_experiments/library/characterization/tphi.py +++ b/qiskit_experiments/library/characterization/tphi.py @@ -19,7 +19,6 @@ from qiskit import QiskitError from qiskit.providers import Backend from qiskit_experiments.framework.composite.batch_experiment import BatchExperiment -from qiskit_experiments.warnings import qubit_deprecate from qiskit_experiments.library.characterization import ( T1, T2Ramsey, @@ -64,7 +63,6 @@ class Tphi(BatchExperiment): """ - @qubit_deprecate() def __init__( self, physical_qubits: Sequence[int], diff --git a/qiskit_experiments/library/characterization/zz_ramsey.py b/qiskit_experiments/library/characterization/zz_ramsey.py index 0554153cd0..79b2b05a3d 100644 --- a/qiskit_experiments/library/characterization/zz_ramsey.py +++ b/qiskit_experiments/library/characterization/zz_ramsey.py @@ -21,7 +21,6 @@ from qiskit.providers.backend import Backend from qiskit.circuit import Parameter, ParameterExpression -from qiskit_experiments.warnings import deprecate_arguments from qiskit_experiments.framework import BackendTiming, BaseExperiment, Options from .analysis.zz_ramsey_analysis import ZZRamseyAnalysis @@ -127,7 +126,6 @@ class ZZRamsey(BaseExperiment): :class:`ZZRamseyAnalysis` """ - @deprecate_arguments({"qubits": "physical_qubits"}, "0.5") def __init__( self, physical_qubits: Tuple[int, int], diff --git a/qiskit_experiments/library/quantum_volume/qv_experiment.py b/qiskit_experiments/library/quantum_volume/qv_experiment.py index 0770c2bbcf..1b05436e2c 100644 --- a/qiskit_experiments/library/quantum_volume/qv_experiment.py +++ b/qiskit_experiments/library/quantum_volume/qv_experiment.py @@ -23,7 +23,6 @@ from qiskit.circuit.library import QuantumVolume as QuantumVolumeCircuit from qiskit import transpile from qiskit.providers.backend import Backend -from qiskit_experiments.warnings import deprecate_arguments from qiskit_experiments.framework import BaseExperiment, Options from .qv_analysis import QuantumVolumeAnalysis @@ -69,7 +68,6 @@ class QuantumVolume(BaseExperiment): """ - @deprecate_arguments({"qubits": "physical_qubits"}, "0.5") def __init__( self, physical_qubits: Sequence[int], diff --git a/qiskit_experiments/library/randomized_benchmarking/clifford_utils.py b/qiskit_experiments/library/randomized_benchmarking/clifford_utils.py index 4e35890c7d..fb5759ac8d 100644 --- a/qiskit_experiments/library/randomized_benchmarking/clifford_utils.py +++ b/qiskit_experiments/library/randomized_benchmarking/clifford_utils.py @@ -30,8 +30,7 @@ from qiskit.compiler import transpile from qiskit.exceptions import QiskitError from qiskit.quantum_info import Clifford, random_clifford -from qiskit_experiments.warnings import deprecated_function - +from qiskit.utils.deprecation import deprecate_func _DATA_FOLDER = os.path.join(os.path.dirname(__file__), "data") @@ -203,7 +202,11 @@ def clifford_2_qubit(cls, num): return Clifford(cls.clifford_2_qubit_circuit(num), validate=False) @classmethod - @deprecated_function("0.6") + @deprecate_func( + since="0.5", + removal_timeline="after 0.6", + package_name="qiskit-experiments", + ) def random_cliffords( cls, num_qubits: int, size: int = 1, rng: Optional[Union[int, Generator]] = None ): @@ -223,7 +226,11 @@ def random_cliffords( return [random_clifford(num_qubits, seed=rng) for _ in range(size)] @classmethod - @deprecated_function("0.6") + @deprecate_func( + since="0.5", + removal_timeline="after 0.6", + package_name="qiskit-experiments", + ) def random_clifford_circuits( cls, num_qubits: int, size: int = 1, rng: Optional[Union[int, Generator]] = None ): @@ -557,7 +564,6 @@ def _create_cliff_2q_layer_2(): _create_cliff_2q_layer_1(), _create_cliff_2q_layer_2(), ) -_NUM_LAYER_0 = 36 _NUM_LAYER_1 = 20 _NUM_LAYER_2 = 16 diff --git a/qiskit_experiments/library/randomized_benchmarking/interleaved_rb_experiment.py b/qiskit_experiments/library/randomized_benchmarking/interleaved_rb_experiment.py index a01be23f8e..d4d75ffd83 100644 --- a/qiskit_experiments/library/randomized_benchmarking/interleaved_rb_experiment.py +++ b/qiskit_experiments/library/randomized_benchmarking/interleaved_rb_experiment.py @@ -25,7 +25,6 @@ from qiskit.providers.backend import Backend from qiskit.quantum_info import Clifford from qiskit.transpiler.exceptions import TranspilerError -from qiskit_experiments.warnings import deprecate_arguments from qiskit_experiments.framework import Options from qiskit_experiments.framework.backend_timing import BackendTiming from .clifford_utils import _truncate_inactive_qubits @@ -58,7 +57,6 @@ class InterleavedRB(StandardRB): """ - @deprecate_arguments({"qubits": "physical_qubits"}, "0.5") def __init__( self, interleaved_element: Union[QuantumCircuit, Gate, Delay, Clifford], diff --git a/qiskit_experiments/library/randomized_benchmarking/standard_rb.py b/qiskit_experiments/library/randomized_benchmarking/standard_rb.py index 60bb8e23aa..7ba0e4a5fa 100644 --- a/qiskit_experiments/library/randomized_benchmarking/standard_rb.py +++ b/qiskit_experiments/library/randomized_benchmarking/standard_rb.py @@ -31,7 +31,6 @@ from qiskit.quantum_info.random import random_clifford from qiskit.transpiler import CouplingMap -from qiskit_experiments.warnings import deprecate_arguments from qiskit_experiments.framework import BaseExperiment, Options from qiskit_experiments.framework.restless_mixin import RestlessMixin @@ -86,7 +85,6 @@ class StandardRB(BaseExperiment, RestlessMixin): .. ref_arxiv:: 2 1109.6887 """ - @deprecate_arguments({"qubits": "physical_qubits"}, "0.5") def __init__( self, physical_qubits: Sequence[int], diff --git a/qiskit_experiments/library/tomography/__init__.py b/qiskit_experiments/library/tomography/__init__.py index b068970892..17e6661661 100644 --- a/qiskit_experiments/library/tomography/__init__.py +++ b/qiskit_experiments/library/tomography/__init__.py @@ -52,8 +52,6 @@ :toctree: ../stubs/ fitters.linear_inversion - fitters.scipy_gaussian_lstsq - fitters.scipy_linear_lstsq fitters.cvxpy_gaussian_lstsq fitters.cvxpy_linear_lstsq diff --git a/qiskit_experiments/library/tomography/fitters/__init__.py b/qiskit_experiments/library/tomography/fitters/__init__.py index 45d84d2fc2..280245fdd3 100644 --- a/qiskit_experiments/library/tomography/fitters/__init__.py +++ b/qiskit_experiments/library/tomography/fitters/__init__.py @@ -15,5 +15,4 @@ from .fitter_data import tomography_fitter_data from .postprocess_fit import postprocess_fitter from .lininv import linear_inversion -from .scipy_lstsq import scipy_linear_lstsq, scipy_gaussian_lstsq from .cvxpy_lstsq import cvxpy_linear_lstsq, cvxpy_gaussian_lstsq diff --git a/qiskit_experiments/library/tomography/fitters/lstsq_utils.py b/qiskit_experiments/library/tomography/fitters/lstsq_utils.py index e3c653639c..881c3528e2 100644 --- a/qiskit_experiments/library/tomography/fitters/lstsq_utils.py +++ b/qiskit_experiments/library/tomography/fitters/lstsq_utils.py @@ -16,7 +16,7 @@ from typing import Optional, Tuple, Callable, Sequence, Union import functools import numpy as np -from qiskit.utils import deprecate_arguments +from qiskit.utils.deprecation import deprecate_arg from qiskit_experiments.exceptions import AnalysisError from qiskit_experiments.library.tomography.basis import ( MeasurementBasis, @@ -189,7 +189,12 @@ def zero(_): return basis_mat, probs, prob_weights -@deprecate_arguments({"beta": "outcome_prior"}) +@deprecate_arg( + "beta", + new_alias="outcome_prior", + since="0.5", + package_name="qiskit-experiments", +) def binomial_weights( outcome_data: np.ndarray, shot_data: Optional[Union[np.ndarray, int]] = None, diff --git a/qiskit_experiments/library/tomography/fitters/scipy_lstsq.py b/qiskit_experiments/library/tomography/fitters/scipy_lstsq.py deleted file mode 100644 index 868369aa75..0000000000 --- a/qiskit_experiments/library/tomography/fitters/scipy_lstsq.py +++ /dev/null @@ -1,280 +0,0 @@ -# This code is part of Qiskit. -# -# (C) Copyright IBM 2021. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. -""" -Linear least-square MLE tomography fitter. -""" - -from typing import Optional, Dict, Tuple, Union -import time -import numpy as np -import scipy.linalg as la -from qiskit.utils import deprecate_function -from qiskit_experiments.exceptions import AnalysisError -from qiskit_experiments.library.tomography.basis import ( - MeasurementBasis, - PreparationBasis, -) -from . import lstsq_utils -from .fitter_data import _basis_dimensions - -# Note this warning doesnt show up when run in analysis so we -# also add a warning when setting the option value that calls this function - -# pylint: disable = bad-docstring-quotes -@deprecate_function( - "The scipy lstsq tomography fitters are deprecated as of 0.4 and will " - "be removed after the 0.5 release. Use the `linear_lstsq`, " - "`cvxpy_linear_lstsq`, or `cvxpy_gaussian_lstsq` fitters instead." -) -def scipy_linear_lstsq( - outcome_data: np.ndarray, - shot_data: np.ndarray, - measurement_data: np.ndarray, - preparation_data: np.ndarray, - measurement_basis: Optional[MeasurementBasis] = None, - preparation_basis: Optional[PreparationBasis] = None, - measurement_qubits: Optional[Tuple[int, ...]] = None, - preparation_qubits: Optional[Tuple[int, ...]] = None, - weights: Optional[np.ndarray] = None, - **kwargs, -) -> Tuple[np.ndarray, Dict]: - r"""Weighted linear least-squares tomography fitter. - - Overview - This fitter reconstructs the maximum-likelihood estimate by using - :func:`scipy.linalg.lstsq` to minimize the least-squares negative log - likelihood function - - .. math:: - \hat{\rho} - &= -\mbox{argmin }\log\mathcal{L}{\rho} \\ - &= \mbox{argmin }\sum_i w_i^2(\mbox{Tr}[E_j\rho] - \hat{p}_i)^2 \\ - &= \mbox{argmin }\|W(Ax - y) \|_2^2 - - where - - - :math:`A = \sum_j |j \rangle\!\langle\!\langle E_j|` is the matrix of measured - basis elements. - - :math:`W = \sum_j w_j|j\rangle\!\langle j|` is an optional diagonal weights - matrix if an optional weights vector is supplied. - - :math:`y = \sum_j \hat{p}_j |j\langle` is the vector of estimated measurement - outcome probabilites for each basis element. - - :math:`x = |\rho\rangle\!\rangle` is the vectorized density matrix. - - .. note:: - - Linear least-squares constructs the full basis matrix :math:`A` as a dense - numpy array so should not be used for than 5 or 6 qubits. For larger number - of qubits try the - :func:`~qiskit_experiments.library.tomography.fitters.linear_inversion` - fitter function. - - Args: - outcome_data: measurement outcome frequency data. - shot_data: basis measurement total shot data. - measurement_data: measurement basis indice data. - preparation_data: preparation basis indice data. - measurement_basis: Optional, measurement matrix basis. - preparation_basis: Optional, preparation matrix basis. - measurement_qubits: Optional, the physical qubits that were measured. - If None they are assumed to be ``[0, ..., M-1]`` for M measured qubits. - preparation_qubits: Optional, the physical qubits that were prepared. - If None they are assumed to be ``[0, ..., N-1]`` for N preparated qubits. - weights: Optional array of weights for least squares objective. - kwargs: additional kwargs for :func:`scipy.linalg.lstsq`. - - Raises: - AnalysisError: If the fitted vector is not a square matrix - - Returns: - The fitted matrix rho that maximizes the least-squares likelihood function. - """ - t_start = time.time() - - if kwargs.pop("conditional_measurement_indices", None): - raise AnalysisError( - "scipy_linear_lstsq fitter does not support conditional_measurement_indices." - ) - if kwargs.pop("conditional_preparation_indices", None): - raise AnalysisError( - "scipy_linear_lstsq fitter does not support conditional_preparation_indices." - ) - if measurement_basis and measurement_qubits is None: - measurement_qubits = tuple(range(measurement_data.shape[1])) - if preparation_basis and preparation_qubits is None: - preparation_qubits = tuple(range(preparation_data.shape[1])) - - input_dims = _basis_dimensions( - basis=preparation_basis, - qubits=preparation_qubits, - ) - output_dims = _basis_dimensions( - basis=measurement_basis, - qubits=measurement_qubits, - ) - - metadata = { - "fitter": "scipy_linear_lstsq", - "input_dims": input_dims, - "output_dims": output_dims, - } - - basis_matrix, probability_data, probability_weights = lstsq_utils.lstsq_data( - outcome_data, - shot_data, - measurement_data, - preparation_data, - measurement_basis=measurement_basis, - preparation_basis=preparation_basis, - measurement_qubits=measurement_qubits, - preparation_qubits=preparation_qubits, - weights=weights, - ) - - # Perform least squares fit using Scipy.linalg lstsq function - lstsq_options = {"check_finite": False, "lapack_driver": "gelsy"} - for key, val in kwargs.items(): - lstsq_options[key] = val - - # Solve each conditional component independently - num_circ_components = probability_data.shape[0] - - if probability_weights is not None: - probability_data = probability_weights * probability_data - - fits = [] - if num_circ_components > 1: - metadata["conditional_circuit_outcome"] = [] - for i in range(num_circ_components): - if probability_weights is not None: - wt_basis_matrix = probability_weights[i, 0][:, None] * basis_matrix - else: - wt_basis_matrix = basis_matrix - - sol, _, _, _ = la.lstsq(wt_basis_matrix, probability_data[i, 0], **lstsq_options) - - # Reshape fit to a density matrix - size = len(sol) - dim = int(np.sqrt(size)) - if dim * dim != size: - raise AnalysisError("Least-squares fitter: invalid result shape.") - fit = np.reshape(sol, (dim, dim), order="F") - fits.append(fit) - if num_circ_components > 1: - metadata["conditional_circuit_outcome"].append(i) - - t_stop = time.time() - metadata["fitter_time"] = t_stop - t_start - - if len(fits) == 1: - return fits[0], metadata - return fits, metadata - - -def scipy_gaussian_lstsq( - outcome_data: np.ndarray, - shot_data: np.ndarray, - measurement_data: np.ndarray, - preparation_data: np.ndarray, - measurement_basis: Optional[MeasurementBasis] = None, - preparation_basis: Optional[PreparationBasis] = None, - measurement_qubits: Optional[Tuple[int, ...]] = None, - preparation_qubits: Optional[Tuple[int, ...]] = None, - outcome_prior: Union[np.ndarray, int] = 0.5, - max_weight: float = 1e10, - **kwargs, -) -> Dict: - r"""Gaussian linear least-squares tomography fitter. - - .. note:: - - This function calls :func:`scipy_linear_lstsq` with a Gaussian weights - vector. Refer to its documentation for additional details. - - Overview - This fitter uses the :func:`scipy_linear_lstsq` fitter to reconstructs - the maximum-likelihood estimate of the Gaussian weighted least-squares - log-likelihood function - - .. math:: - \hat{rho} &= \mbox{argmin} -\log\mathcal{L}{\rho} \\ - -\log\mathcal{L}(\rho) - &= \sum_i \frac{1}{\sigma_i^2}(\mbox{Tr}[E_j\rho] - \hat{p}_i)^2 - = \|W(Ax -y) \|_2^2 - - Additional Details - The Gaussian weights are estimated from the observed frequency and shot data - via a Bayesian update of a Dirichlet distribution with observed outcome data - frequences :math:`f_i(s)`, and Dirichlet prior :math:`\alpha_i(s)` for - tomography basis index `i` and measurement outcome `s`. - - The mean posterior probabilities are computed as - - .. math: - p_i(s) &= \frac{f_i(s) + \alpha_i(s)}{\bar{\alpha}_i + N_i} \\ - Var[p_i(s)] &= \frac{p_i(s)(1-p_i(s))}{\bar{\alpha}_i + N_i + 1} - w_i(s) = \sqrt{Var[p_i(s)]}^{-1} - - where :math:`N_i = \sum_s f_i(s)` is the total number of shots, and - :math:`\bar{\alpha}_i = \sum_s \alpha_i(s)` is the norm of the prior. - - Args: - outcome_data: measurement outcome frequency data. - shot_data: basis measurement total shot data. - measurement_data: measurement basis indice data. - preparation_data: preparation basis indice data. - measurement_basis: Optional, measurement matrix basis. - preparation_basis: Optional, preparation matrix basis. - measurement_qubits: Optional, the physical qubits that were measured. - If None they are assumed to be ``[0, ..., M-1]`` for M measured qubits. - preparation_qubits: Optional, the physical qubits that were prepared. - If None they are assumed to be ``[0, ..., N-1]`` for N preparated qubits. - outcome_prior: The Baysian prior :math:`\alpha` to use computing Gaussian - weights. See additional information. - max_weight: Set the maximum value allowed for weights vector computed from - tomography data variance. - kwargs: additional kwargs for :func:`scipy.linalg.lstsq`. - - Raises: - AnalysisError: If the fitted vector is not a square matrix - - Returns: - The fitted matrix rho that maximizes the least-squares likelihood function. - """ - t_start = time.time() - - weights = lstsq_utils.binomial_weights( - outcome_data, - shot_data=shot_data, - outcome_prior=outcome_prior, - max_weight=max_weight, - ) - - fits, metadata = scipy_linear_lstsq( - outcome_data, - shot_data, - measurement_data, - preparation_data, - measurement_basis=measurement_basis, - preparation_basis=preparation_basis, - measurement_qubits=measurement_qubits, - preparation_qubits=preparation_qubits, - weights=weights, - **kwargs, - ) - t_stop = time.time() - - # Update metadata - metadata["fitter"] = "scipy_gaussian_lstsq" - metadata["fitter_time"] = t_stop - t_start - - return fits, metadata diff --git a/qiskit_experiments/library/tomography/qpt_analysis.py b/qiskit_experiments/library/tomography/qpt_analysis.py index 7101866c90..0881b3d23e 100644 --- a/qiskit_experiments/library/tomography/qpt_analysis.py +++ b/qiskit_experiments/library/tomography/qpt_analysis.py @@ -30,12 +30,8 @@ class ProcessTomographyAnalysis(TomographyAnalysis): * ``"linear_inversion"``: :func:`~qiskit_experiments.library.tomography.fitters.linear_inversion` (Default) - * ``"scipy_linear_lstsq"``: - :func:`~qiskit_experiments.library.tomography.fitters.scipy_linear_lstsq` * ``"cvxpy_linear_lstsq"``: :func:`~qiskit_experiments.library.tomography.fitters.cvxpy_linear_lstsq` - * ``"scipy_gaussian_lstsq"``: - :func:`~qiskit_experiments.library.tomography.fitters.scipy_gaussian_lstsq` * ``"cvxpy_gaussian_lstsq"``: :func:`~qiskit_experiments.library.tomography.fitters.cvxpy_gaussian_lstsq` diff --git a/qiskit_experiments/library/tomography/qpt_experiment.py b/qiskit_experiments/library/tomography/qpt_experiment.py index b109ecf597..cb7c981ebc 100644 --- a/qiskit_experiments/library/tomography/qpt_experiment.py +++ b/qiskit_experiments/library/tomography/qpt_experiment.py @@ -20,7 +20,6 @@ from qiskit.quantum_info.operators.base_operator import BaseOperator from qiskit.quantum_info import Choi, Operator, Statevector, DensityMatrix, partial_trace -from qiskit_experiments.warnings import deprecate_arguments from qiskit_experiments.exceptions import QiskitError from .tomography_experiment import TomographyExperiment, TomographyAnalysis, BaseAnalysis from .qpt_analysis import ProcessTomographyAnalysis @@ -49,14 +48,6 @@ class ProcessTomography(TomographyExperiment): """ - @deprecate_arguments( - { - "qubits": "physical_qubits", - "measurement_qubits": "measurement_indices", - "preparation_qubits": "preparation_indices", - }, - "0.5", - ) def __init__( self, circuit: Union[QuantumCircuit, Instruction, BaseOperator], diff --git a/qiskit_experiments/library/tomography/qst_analysis.py b/qiskit_experiments/library/tomography/qst_analysis.py index 1e6cf6d000..3e80b79c83 100644 --- a/qiskit_experiments/library/tomography/qst_analysis.py +++ b/qiskit_experiments/library/tomography/qst_analysis.py @@ -29,12 +29,8 @@ class StateTomographyAnalysis(TomographyAnalysis): * ``"linear_inversion"``: :func:`~qiskit_experiments.library.tomography.fitters.linear_inversion` (Default) - * ``"scipy_linear_lstsq"``: - :func:`~qiskit_experiments.library.tomography.fitters.scipy_linear_lstsq` * ``"cvxpy_linear_lstsq"``: :func:`~qiskit_experiments.library.tomography.fitters.cvxpy_linear_lstsq` - * ``"scipy_gaussian_lstsq"``: - :func:`~qiskit_experiments.library.tomography.fitters.scipy_gaussian_lstsq` * ``"cvxpy_gaussian_lstsq"``: :func:`~qiskit_experiments.library.tomography.fitters.cvxpy_gaussian_lstsq` diff --git a/qiskit_experiments/library/tomography/qst_experiment.py b/qiskit_experiments/library/tomography/qst_experiment.py index 0ae0f06a8c..fd81a8e2fa 100644 --- a/qiskit_experiments/library/tomography/qst_experiment.py +++ b/qiskit_experiments/library/tomography/qst_experiment.py @@ -19,7 +19,6 @@ from qiskit.quantum_info.operators.base_operator import BaseOperator from qiskit.quantum_info import Statevector, DensityMatrix, partial_trace -from qiskit_experiments.warnings import deprecate_arguments from qiskit_experiments.exceptions import QiskitError from .tomography_experiment import TomographyExperiment, TomographyAnalysis, BaseAnalysis from .qst_analysis import StateTomographyAnalysis @@ -50,9 +49,6 @@ class StateTomography(TomographyExperiment): """ - @deprecate_arguments( - {"qubits": "physical_qubits", "measurement_qubits": "measurement_indices"}, "0.5" - ) def __init__( self, circuit: Union[QuantumCircuit, Instruction, BaseOperator, Statevector], diff --git a/qiskit_experiments/library/tomography/tomography_analysis.py b/qiskit_experiments/library/tomography/tomography_analysis.py index 409d7653a3..55a588a70c 100644 --- a/qiskit_experiments/library/tomography/tomography_analysis.py +++ b/qiskit_experiments/library/tomography/tomography_analysis.py @@ -16,7 +16,6 @@ from typing import List, Union, Callable from collections import defaultdict -import warnings import numpy as np import scipy.linalg as la from uncertainties import ufloat @@ -31,8 +30,6 @@ tomography_fitter_data, postprocess_fitter, linear_inversion, - scipy_linear_lstsq, - scipy_gaussian_lstsq, cvxpy_linear_lstsq, cvxpy_gaussian_lstsq, ) @@ -43,8 +40,6 @@ class TomographyAnalysis(BaseAnalysis): _builtin_fitters = { "linear_inversion": linear_inversion, - "scipy_linear_lstsq": scipy_linear_lstsq, - "scipy_gaussian_lstsq": scipy_gaussian_lstsq, "cvxpy_linear_lstsq": cvxpy_linear_lstsq, "cvxpy_gaussian_lstsq": cvxpy_gaussian_lstsq, } @@ -139,22 +134,6 @@ def _default_options(cls) -> Options: options.conditional_preparation_indices = None return options - def set_options(self, **fields): - if fields.get("fitter", None) in [ - "scipy_linear_lstsq", - "scipy_gaussian_lstsq", - scipy_linear_lstsq, - scipy_gaussian_lstsq, - ]: - warnings.warn( - "The scipy lstsq tomography fitters are deprecated as of 0.4 and will " - "be removed after the 0.5 release. Use the `linear_lstsq`, " - "`cvxpy_linear_lstsq`, or `cvxpy_gaussian_lstsq` fitter instead.", - DeprecationWarning, - stacklevel=2, - ) - super().set_options(**fields) - @classmethod def _get_fitter(cls, fitter: Union[str, Callable]) -> Callable: """Return fitter function for named builtin fitters""" diff --git a/qiskit_experiments/library/tomography/tomography_experiment.py b/qiskit_experiments/library/tomography/tomography_experiment.py index 87cb9dad48..ddf02e6f21 100644 --- a/qiskit_experiments/library/tomography/tomography_experiment.py +++ b/qiskit_experiments/library/tomography/tomography_experiment.py @@ -20,7 +20,6 @@ from qiskit.providers.backend import Backend from qiskit.quantum_info.operators.base_operator import BaseOperator -from qiskit_experiments.warnings import deprecate_arguments from qiskit_experiments.exceptions import QiskitError from qiskit_experiments.framework import BaseExperiment, BaseAnalysis, Options from .basis import PreparationBasis, MeasurementBasis @@ -47,14 +46,6 @@ def _default_experiment_options(cls) -> Options: options.basis_indices = None return options - @deprecate_arguments( - { - "qubits": "physical_qubits", - "measurement_qubits": "measurement_indices", - "preparation_qubits": "preparation_indices", - }, - "0.5", - ) def __init__( self, circuit: Union[QuantumCircuit, Instruction, BaseOperator], diff --git a/qiskit_experiments/visualization/drawers/legacy_curve_compat_drawer.py b/qiskit_experiments/visualization/drawers/legacy_curve_compat_drawer.py index 3f2764f6c7..2a175744a7 100644 --- a/qiskit_experiments/visualization/drawers/legacy_curve_compat_drawer.py +++ b/qiskit_experiments/visualization/drawers/legacy_curve_compat_drawer.py @@ -14,21 +14,16 @@ import warnings from typing import Any, Optional, Sequence, Tuple, Union - import numpy as np +from qiskit.utils.deprecation import deprecate_func + from qiskit_experiments.curve_analysis.visualization import BaseCurveDrawer -from qiskit_experiments.warnings import deprecated_class from ..utils import ExtentTuple from .base_drawer import BaseDrawer -@deprecated_class( - "0.6", - msg="Legacy drawers from `.curve_analysis.visualization are deprecated. This compatibility wrapper " - "will be removed alongside the deprecated modules removal", -) class LegacyCurveCompatDrawer(BaseDrawer): """A compatibility wrapper for the legacy and deprecated :class:`BaseCurveDrawer`. @@ -44,6 +39,13 @@ class wraps the legacy :class:`BaseCurveDrawer` class so it can be used by analy :meth:`scatter`) are unsupported and do nothing. """ + @deprecate_func( + since="0.5", + additional_msg="Legacy drawers from ``curve_analysis.visualization`` are deprecated. " + "This compatibility wrapper will be removed alongside the deprecated modules removal", + removal_timeline="after 0.6", + package_name="qiskit-experiments", + ) def __init__(self, curve_drawer: BaseCurveDrawer): """Create a LegacyCurveCompatDrawer instance. diff --git a/qiskit_experiments/warnings.py b/qiskit_experiments/warnings.py index 8f13d115dc..c5197ef07d 100644 --- a/qiskit_experiments/warnings.py +++ b/qiskit_experiments/warnings.py @@ -12,238 +12,9 @@ """A collection of typical warnings.""" -import functools -import warnings -from typing import Callable, Optional, Type, Dict - from qiskit.utils.lazy_tester import LazyImportTester -def deprecated_function( - last_version: Optional[str] = None, - msg: Optional[str] = None, - stacklevel: int = 2, -) -> Callable: - """A function or method decorator to show deprecation warning. - - Args: - last_version: The last Qiskit Experiment version that will have this function. - msg: Extra message, for example, to indicate an alternative approach. - stacklevel: Stacklevel of this warning. See Python Warnings documentation for details. - - Examples: - - .. code-block:: - - @deprecated_function(last_version="0.3", msg="Use new_function instead.") - def old_function(*args, **kwargs): - pass - - def new_function(*args, **kwargs): - pass - - Returns: - Deprecated function or method. - """ - - def deprecated_wrapper(func: Callable): - @functools.wraps(func) - def _wrap(*args, **kwargs): - namespace = func.__qualname__.split(".") - if len(namespace) == 1: - message = f"The function '{func.__name__}' has been deprecated and " - else: - cls_name, meth_name = namespace - message = ( - f"The method '{meth_name}' of '{cls_name}' class has been deprecated and " - "will be removed " - ) - if last_version: - message += f"after Qiskit Experiments {last_version}. " - else: - message += "in a future release. " - if msg: - message += msg - warnings.warn(message, DeprecationWarning, stacklevel=stacklevel) - return func(*args, **kwargs) - - return _wrap - - return deprecated_wrapper - - -def deprecated_class( - last_version: Optional[str] = None, - new_cls: Optional[Type] = None, - msg: Optional[str] = None, - stacklevel: int = 2, -) -> Callable: - """A class decorator to show deprecation warning and - patch __new__ method of the class to instantiate the new class. - - Args: - last_version: The last Qiskit Experiments version that will have this class. - new_cls: Alternative class type. - msg: Extra message, for example, to indicate an alternative approach. - stacklevel: Stacklevel of this warning. See Python Warnings documentation for details. - - Examples: - - .. code-block:: - - @deprecated_class(last_version="0.3", new_cls=NewCls) - class OldClass: - pass - - class NewClass: - pass - - Returns: - Deprecated class. - """ - - def patch_new(cls) -> Type: - @functools.wraps(cls.__init__, assigned=("__annotations__",)) - def new(deprecated_cls, *args, **kwargs): - message = f"Class '{deprecated_cls.__name__}' has been deprecated" - if new_cls: - message += f" and replaced with '{new_cls.__name__}'. " - else: - message += ". " - if last_version: - message += f"This class will be removed after Qiskit Experiments {last_version}. " - else: - message += "This class will be removed in a future release." - message += f"The '{deprecated_cls.__name__}' instance cannot be loaded after removal. " - if msg: - message += msg - warnings.warn(message, DeprecationWarning, stacklevel=stacklevel) - instance = object.__new__(new_cls or deprecated_cls) - instance.__init__(*args, **kwargs) # pylint: disable=unnecessary-dunder-call - return instance - - cls.__new__ = new - return cls - - return patch_new - - -def deprecate_arguments( - kwarg_map: Dict, - last_version: Optional[str] = None, - msg: Optional[str] = None, - stacklevel: int = 3, -) -> Callable: - """Decorator to automatically alias deprecated argument names and warn upon use. - - Args: - kwarg_map: A dictionary mapping old arguments to their new names. - last_version: The last Qiskit Experiments version that will support the old argument name. - msg: Extra message, for example, to indicate an alternative approach. - stacklevel: Stacklevel of this warning. See Python Warnings documentation for details. - - Examples: - - .. code-block:: - - @deprecated_argument(last_version="0.5", kwmap={"qubits": "physical_qubits"}) - def function(*args, **kwargs): # physical_qubits in in args or kwargs - pass - - Returns: - Function with argument name replaced from old to new. - """ - - def decorator(func): - @functools.wraps(func) - def wrapper(*args, **kwargs): - if kwargs: - _rename_kwargs( - args[0].__class__.__name__ + "." + func.__name__, - kwargs, - kwarg_map, - last_version, - msg, - stacklevel, - ) - return func(*args, **kwargs) - - return wrapper - - return decorator - - -def _rename_kwargs(func_name, kwargs, kwarg_map, last_version, msg, stacklevel): - for old_arg, new_arg in kwarg_map.items(): - if old_arg in kwargs: - if new_arg in kwargs: - raise TypeError( - f"{func_name} received both {new_arg} and the deprecated {old_arg} " - "parameter. Only {new_arg} should be supplied." - ) - - message = f"{func_name} keyword argument {old_arg} is deprecated and will be removed " - if last_version: - message += f"after Qiskit Experiments {last_version}. " - else: - message += "in a future release. " - if new_arg is not None: - message += f"It is now replaced with {new_arg}. " - kwargs[new_arg] = kwargs.pop(old_arg) - if msg: - message += msg - - warnings.warn(message, DeprecationWarning, stacklevel=stacklevel) - - -def qubit_deprecate() -> Callable: - """Decorator to deprecate from qubit to physical_qubits""" - - def decorator(func): - @functools.wraps(func) - def wrapper(*args, **kwargs): - category = DeprecationWarning - func_name = args[0].__class__.__name__ + ".__init__" - - if len(args) > 1 and isinstance(args[1], int): - args = list(args) - args[1] = [args[1]] - args = tuple(args) - warnings.warn( - f'The first argument of {func_name} has been renamed from "qubit" to ' - '"physical_qubits" and is expecting a sequence with a single integer. ' - "Support for directly passing an integer argument is " - "deprecated and will be removed after Qiskit Experiments " - "0.5.", - category=category, - stacklevel=3, - ) - - if kwargs and "qubit" in kwargs: - if "physical_qubits" in kwargs: - raise TypeError( - f'{func_name} received both "physical_qubits" and the deprecated "qubit" ' - 'parameter. Only "physical_qubits" should be supplied.' - ) - - warnings.warn( - f'{func_name} keyword argument "qubit" is deprecated and has been ' - 'replaced with "physical_qubits". "physical_qubits" should be ' - "passed as a sequence containing a single integer. " - 'Support for using "qubit" with an integer argument is ' - "deprecated and will be removed after Qiskit Experiments 0.5.", - category=category, - stacklevel=3, - ) - kwargs["physical_qubits"] = [kwargs.pop("qubit")] - - return func(*args, **kwargs) - - return wrapper - - return decorator - - HAS_SKLEARN = LazyImportTester( { "sklearn.discriminant_analysis": ( diff --git a/releasenotes/notes/0.4/0_3_1_release-43f09573952ce3ee.yaml b/releasenotes/notes/0.4/0_3_1_release-43f09573952ce3ee.yaml new file mode 100644 index 0000000000..a4d1144602 --- /dev/null +++ b/releasenotes/notes/0.4/0_3_1_release-43f09573952ce3ee.yaml @@ -0,0 +1,24 @@ +--- +features: + - | + The class :class:`.MockIQBackend` for testing has been updated to support + multiple qubits. It now takes lists of IQ cluster centers and widths as input, + and specific backends are now defined as subclasses of + :class:`.MockIQExperimentHelper`. +fixes: + - | + Fixes a bug where instantiating the + :class:`.CrossResonanceHamiltonian` experiment without specifying the + ``cr_gate`` and ``backend`` init kwargs raises an exception. + - | + Fixes a visualization error in the figure produced during analysis of + :class:`.CrossResonanceHamiltonian` when multi-canvas plotting mode is enabled. + - | + Fixes an issue with marginalization of kerneled and discriminated memory in + :class:`.CompositeAnalysis` not working correctly. This fixes + :class:`.ParallelExperiments` not working correctly for level-1 measurement + data. + - | + Fixes a bug with JSON serialization of :class:`.ExperimentData` due to + Qiskit ``backend`` and ``service`` objects not being JSON serializable. These + properties are now set to ``None`` in the serialized experiment data. \ No newline at end of file diff --git a/releasenotes/notes/0.5_deprecations-4188ada026cb682b.yaml b/releasenotes/notes/0.5_deprecations-4188ada026cb682b.yaml new file mode 100644 index 0000000000..085add3d87 --- /dev/null +++ b/releasenotes/notes/0.5_deprecations-4188ada026cb682b.yaml @@ -0,0 +1,21 @@ +--- +upgrade: + - | + Several deprecated methods and options have been removed and will no longer work: + + * Passing the ``qubits`` keyword argument or an integer qubit index to experiments is no longer + allowed. Use ``physical_qubits`` keyword argument with a sequence type input. + * The ``scipy_linear_lstsq`` and ``scipy_gaussian_lstsq`` fitters for the + :class:`.StateTomographyAnalysis` and :class:`.ProcessTomographyAnalysis` + classes have been removed. Use the :func:`.linear_lstsq`, :func:`.cvxpy_linear_lstsq`, + or :func:`.cvxpy_gaussian_lstsq` fitters instead. + * Curve fit solvers ``curve_fit()`` and ``multi_curve_fit()`` as well as fit functions + ``bloch_oscillation_x()``, ``bloch_oscillation_y()``, and ``bloch_oscillation_z()`` have been + removed. Use the LMFIT library instead. + * The scipy lstsq tomography fitters ``scipy_linear_lstsq`` and ``scipy_gaussian_lstsq`` have + been removed. Use the `linear_lstsq`, `cvxpy_linear_lstsq`, or `cvxpy_gaussian_lstsq` fitter + instead. + * The ``flat_top_widths`` argument and experiment option of the + :class:`.CrossResonanceHamiltonian` experiment and its subclass have been removed. Use + ``durations`` instead. + * The ``DumpedOscillationAnalysis`` class has been renamed to :class:`.DampedOscillationAnalysis`. diff --git a/test/calibration/test_base_calibration_experiment.py b/test/calibration/test_base_calibration_experiment.py index 679d20580c..8227e89eee 100644 --- a/test/calibration/test_base_calibration_experiment.py +++ b/test/calibration/test_base_calibration_experiment.py @@ -88,7 +88,7 @@ def test_update_calibration(self): param_name="to_calibrate", sched_name="test", ) - exp.run(backend).block_for_results() + self.assertExperimentDone(exp.run(backend)) # Get new value new_value = cals.get_parameter_value("to_calibrate", (0,), "test") @@ -133,7 +133,7 @@ def test_update_calibration_update_analysis(self): sched_name="test", ) exp.analysis.set_options(return_value=ref_new_value) # Update analysis option here - exp.run(backend).block_for_results() + self.assertExperimentDone(exp.run(backend)) # Get new value new_value = cals.get_parameter_value("to_calibrate", (0,), "test") @@ -181,7 +181,7 @@ def test_update_calibration_custom_analysis(self): user_analysis = DoNothingAnalysis() user_analysis.set_options(return_value=ref_new_value) exp.analysis = user_analysis # Update analysis instance itself here - exp.run(backend).block_for_results() + self.assertExperimentDone(exp.run(backend)) # Get new value new_value = cals.get_parameter_value("to_calibrate", (0,), "test") @@ -240,7 +240,7 @@ def test_update_calibration_batch(self): sched_name="test", ) batch_exp = BatchExperiment([exp1, exp2], flatten_results=False, backend=backend) - batch_exp.run(backend).block_for_results() + self.assertExperimentDone(batch_exp.run(backend)) # Get new value new_value1 = cals.get_parameter_value("to_calibrate1", (0,), "test") @@ -310,7 +310,7 @@ def test_update_calibration_parallel(self): sched_name="test2", ) batch_exp = ParallelExperiment([exp1, exp2], flatten_results=False, backend=backend) - batch_exp.run(backend).block_for_results() + self.assertExperimentDone(batch_exp.run(backend)) # Get new value new_value1 = cals.get_parameter_value("to_calibrate1", (0,), "test1") diff --git a/test/curve_analysis/test_baseclass.py b/test/curve_analysis/test_baseclass.py index a744a13059..4f49745c9d 100644 --- a/test/curve_analysis/test_baseclass.py +++ b/test/curve_analysis/test_baseclass.py @@ -224,7 +224,8 @@ def test_end_to_end_single_function(self): y = amp * np.exp(-x / tau) test_data = self.single_sampler(x, y) - result = analysis.run(test_data).block_for_results() + result = analysis.run(test_data) + self.assertExperimentDone(result) self.assertAlmostEqual(result.analysis_results("amp").value.nominal_value, 0.5, delta=0.1) self.assertAlmostEqual(result.analysis_results("tau").value.nominal_value, 0.3, delta=0.1) @@ -270,7 +271,8 @@ def test_end_to_end_multi_objective(self): expdata.add_data(test_data2.data()) expdata.metadata["meas_level"] = MeasLevel.CLASSIFIED - result = analysis.run(expdata).block_for_results() + result = analysis.run(expdata) + self.assertExperimentDone(result) self.assertAlmostEqual(result.analysis_results("amp").value.nominal_value, amp, delta=0.1) self.assertAlmostEqual(result.analysis_results("freq").value.nominal_value, freq, delta=0.1) @@ -294,7 +296,8 @@ def test_end_to_end_single_function_with_fixed_parameter(self): y = amp * np.exp(-x / tau) test_data = self.single_sampler(x, y) - result = analysis.run(test_data).block_for_results() + result = analysis.run(test_data) + self.assertExperimentDone(result) self.assertEqual(result.analysis_results("amp").value.nominal_value, 0.5) self.assertEqual(result.analysis_results("amp").value.std_dev, 0.0) @@ -334,7 +337,8 @@ def _create_analysis_results(self, fit_data, quality, **metadata): y = amp * np.exp(-x / tau) test_data = self.single_sampler(x, y) - result = analysis.run(test_data).block_for_results() + result = analysis.run(test_data) + self.assertExperimentDone(result) new_value = result.analysis_results("new_value").value @@ -388,7 +392,8 @@ def _initialize(self, experiment_data): y = 0.5 * amp * np.exp(-x / tau) test_data = self.single_sampler(x, y) - result = analysis.run(test_data).block_for_results() + result = analysis.run(test_data) + self.assertExperimentDone(result) self.assertAlmostEqual(result.analysis_results("amp").value.nominal_value, 0.5, delta=0.1) self.assertAlmostEqual(result.analysis_results("tau").value.nominal_value, 0.3, delta=0.1) @@ -423,7 +428,8 @@ def test_end_to_end_parallel_analysis(self): y2 = amp2 * np.exp(-x / tau2) test_data = self.parallel_sampler(x, y1, y2) - result = composite.run(test_data).block_for_results() + result = composite.run(test_data) + self.assertExperimentDone(result) amps = result.analysis_results("amp") taus = result.analysis_results("tau") @@ -450,7 +456,8 @@ def test_get_init_params(self): y_true = amp * np.exp(-x / tau) test_data = self.single_sampler(x, y_true) - result = analysis.run(test_data).block_for_results() + result = analysis.run(test_data) + self.assertExperimentDone(result) overview = result.analysis_results(0).value @@ -526,7 +533,8 @@ def test_multi_composite_curve_analysis(self): expdata.add_data(test_data2b.data()) expdata.metadata["meas_level"] = MeasLevel.CLASSIFIED - result = group_analysis.run(expdata).block_for_results() + result = group_analysis.run(expdata) + self.assertExperimentDone(result) amps = result.analysis_results("amp") # two entries are generated for group A and group B diff --git a/test/curve_analysis/test_curve_fitting.py b/test/curve_analysis/test_curve_fitting.py index 1c4bdb09f5..e64b5b5d65 100644 --- a/test/curve_analysis/test_curve_fitting.py +++ b/test/curve_analysis/test_curve_fitting.py @@ -16,7 +16,7 @@ from qiskit import QuantumCircuit, transpile from qiskit.providers.basicaer import QasmSimulatorPy -from qiskit_experiments.curve_analysis import curve_fit, multi_curve_fit, process_curve_data +from qiskit_experiments.curve_analysis import process_curve_data from qiskit_experiments.curve_analysis.utils import ( level2_probability, mean_xy_data, @@ -85,44 +85,6 @@ def test_process_curve_data(self): self.assertTrue(np.allclose(xdiff, 0)) self.assertTrue(np.allclose(ydiff, 0, atol=0.05)) - def test_curve_fit(self): - """Test curve_fit function""" - thetas = thetas = np.linspace(0.5, 4 * np.pi - 0.5, 20) - data = self.simulate_experiment_data(thetas) - xdata, ydata, sigma = process_curve_data(data, data_processor=self.data_processor_p0) - p0 = [0.6] - bounds = ([0], [2]) - with self.assertWarns(DeprecationWarning): - sol = curve_fit(self.objective0, xdata, ydata, p0, sigma=sigma, bounds=bounds) - self.assertTrue(abs(sol.popt[0] - 0.5) < 0.05) - - def test_multi_curve_fit(self): - """Test multi_curve_fit function""" - thetas = thetas = np.linspace(0.5, 4 * np.pi - 0.5, 20) - data = self.simulate_experiment_data(thetas) - xdata0, ydata0, sigma0 = process_curve_data(data, data_processor=self.data_processor_p0) - xdata1, ydata1, sigma1 = process_curve_data(data, data_processor=self.data_processor_p1) - - # Combine curve data - xdata = np.concatenate([xdata0, xdata1]) - series = np.concatenate([np.zeros(len(xdata0)), np.ones(len(xdata1))]) - ydata = np.concatenate([ydata0, ydata1]) - sigma = np.concatenate([sigma0, sigma1]) - - p0 = [0.6] - bounds = ([0], [2]) - with self.assertWarns(DeprecationWarning): - sol = multi_curve_fit( - [self.objective0, self.objective1], - series, - xdata, - ydata, - p0, - sigma=sigma, - bounds=bounds, - ) - self.assertTrue(abs(sol.popt[0] - 0.5) < 0.05) - def test_mean_xy_data(self): """Test mean_xy_data function""" # pylint: disable=unbalanced-tuple-unpacking diff --git a/test/curve_analysis/test_standard_analysis.py b/test/curve_analysis/test_standard_analysis.py index b12c543e38..41d970f892 100644 --- a/test/curve_analysis/test_standard_analysis.py +++ b/test/curve_analysis/test_standard_analysis.py @@ -69,7 +69,8 @@ def _default_options(cls) -> Options: analysis = FakeAmpAnalysis() analysis.set_options(data_processor=processor) - fake_data = analysis.run(fake_data).block_for_results() + fake_data = analysis.run(fake_data) + self.assertExperimentDone(fake_data) self.assertAlmostEqual( fake_data.analysis_results("d_theta").value.n, d_theta_targ, delta=0.01 diff --git a/test/framework/test_composite.py b/test/framework/test_composite.py index e71d9b25d7..fc0d126b2f 100644 --- a/test/framework/test_composite.py +++ b/test/framework/test_composite.py @@ -767,12 +767,14 @@ def test_composite_properties_setting(self): exp2 = FakeExperiment([1]) exp2.analysis = FakeAnalysis() batch_exp = BatchExperiment([exp1, exp2], flatten_results=True) - exp_data = batch_exp.run(backend=self.backend).block_for_results() + exp_data = batch_exp.run(backend=self.backend) + self.assertExperimentDone(exp_data) # when flattening, individual analysis result share exp id for result in exp_data.analysis_results(): self.assertEqual(result.experiment_id, exp_data.experiment_id) batch_exp = BatchExperiment([exp1, exp2], flatten_results=False) - exp_data = batch_exp.run(backend=self.backend).block_for_results() + exp_data = batch_exp.run(backend=self.backend) + self.assertExperimentDone(exp_data) self.assertEqual(exp_data.child_data(0).experiment_type, exp1.experiment_type) self.assertEqual(exp_data.child_data(1).experiment_type, exp2.experiment_type) @@ -860,7 +862,7 @@ def test_batch_transpile_options_integrated(self): noise_model.add_all_qubit_quantum_error(noise.depolarizing_error(0.5, 2), ["cx", "swap"]) expdata = self.batch2.run(backend, noise_model=noise_model, shots=1000) - expdata.block_for_results() + self.assertExperimentDone(expdata) self.assertEqual(expdata.child_data(0).analysis_results(0).value, 8) self.assertEqual(expdata.child_data(1).child_data(0).analysis_results(0).value, 16) diff --git a/test/framework/test_warnings.py b/test/framework/test_warnings.py index 365176ffae..e1f8460c29 100644 --- a/test/framework/test_warnings.py +++ b/test/framework/test_warnings.py @@ -19,9 +19,6 @@ from test.base import QiskitExperimentsTestCase from qiskit_experiments.framework import BaseExperiment -from qiskit_experiments.warnings import deprecated_class -from qiskit_experiments.warnings import deprecate_arguments -from qiskit_experiments.warnings import qubit_deprecate class TempExperiment(BaseExperiment): @@ -37,59 +34,6 @@ def circuits(self): class TestWarningsHelper(QiskitExperimentsTestCase): """Test case for warnings decorator with tricky behavior.""" - def test_switch_class(self): - """Test old class is instantiated as a new class instance.""" - - # Here we assume we want to rename class but want to have deprecation period - class NewExperiment(TempExperiment): - """Experiment to be renamed.""" - - pass - - @deprecated_class( - new_cls=NewExperiment, - ) - class OldExperiment(TempExperiment): - """Original experiment.""" - - pass - - with self.assertWarns(DeprecationWarning): - instance = OldExperiment([0]) - - self.assertIsInstance(instance, NewExperiment) - - def test_deprecated_argument(self): - """Test that deprecating arguments works as expected.""" - - class OldExperiment(TempExperiment): - """Original experiment.""" - - @deprecate_arguments({"qubits": "physical_qubits"}) - def __init__(self, physical_qubits): - super().__init__(physical_qubits) - - # Test that providing both old and new kwargs throws an error - with self.assertRaises(TypeError): - instance = OldExperiment(qubits=[0], physical_qubits=[0]) - with self.assertWarns(DeprecationWarning): - instance = OldExperiment(qubits=[0]) - self.assertEqual(instance._physical_qubits, (0,)) - - def test_deprecated_qubit(self): - """Test for the temporary qubit_deprecate wrapper.""" - - class OldExperiment(TempExperiment): - """Original experiment.""" - - @qubit_deprecate() - def __init__(self, physical_qubits): - super().__init__(physical_qubits) - - with self.assertWarns(DeprecationWarning): - instance = OldExperiment(qubit=0) - self.assertEqual(instance._physical_qubits, (0,)) - def test_warn_sklearn(self): """Test that a suggestion to import scikit-learn is given when appropriate""" script = """ diff --git a/test/library/calibration/test_drag.py b/test/library/calibration/test_drag.py index 97260f1b06..5372f37eba 100644 --- a/test/library/calibration/test_drag.py +++ b/test/library/calibration/test_drag.py @@ -136,7 +136,8 @@ def test_drag_reanalysis(self): # DRAG reps numbers might be different from the default value, # but the client doesn't know the original setting. analysis = DragCalAnalysis() - expdata1 = analysis.run(expdata.copy(), replace_results=True).block_for_results() + expdata1 = analysis.run(expdata.copy(), replace_results=True) + self.assertExperimentDone(expdata1) # Check mapping of model name to circuit metadata. self.assertDictEqual( analysis.options.data_subfit_map, @@ -148,8 +149,9 @@ def test_drag_reanalysis(self): ) # Running experiment twice. - # Reported by https://github.com/Qiskit-Extensions/qiskit-experiments/issues/1086. - expdata2 = analysis.run(expdata.copy(), replace_results=True).block_for_results() + # Reported by https://github.com/Qiskit/qiskit-experiments/issues/1086. + expdata2 = analysis.run(expdata.copy(), replace_results=True) + self.assertExperimentDone(expdata2) self.assertEqual(len(analysis.models), 3) self.assertAlmostEqual( diff --git a/test/library/calibration/test_ramsey_xy.py b/test/library/calibration/test_ramsey_xy.py index 391700b8b6..ab7effeb95 100644 --- a/test/library/calibration/test_ramsey_xy.py +++ b/test/library/calibration/test_ramsey_xy.py @@ -113,8 +113,7 @@ def _run_analysis(self, experiment_data): expt = FrequencyCal([0], self.cals, backend, auto_update=True) expt.analysis = NoResults() - expdata = expt.run() - expdata.block_for_results(timeout=3) + expdata = expt.run().block_for_results(timeout=3) self.assertEqual(expdata.analysis_status(), AnalysisStatus.ERROR) def test_ramseyxy_experiment_config(self): diff --git a/test/library/characterization/test_cross_resonance_hamiltonian.py b/test/library/characterization/test_cross_resonance_hamiltonian.py index 0a9f4fed56..d49f74d7b7 100644 --- a/test/library/characterization/test_cross_resonance_hamiltonian.py +++ b/test/library/characterization/test_cross_resonance_hamiltonian.py @@ -40,14 +40,13 @@ def test_circuit_generation(self): """Test generated circuits.""" backend = FakeBogotaV2() - with self.assertWarns(DeprecationWarning): - expr = cr_hamiltonian.CrossResonanceHamiltonian( - physical_qubits=(0, 1), - flat_top_widths=[1000], - amp=0.1, - sigma=64, - risefall=2, - ) + expr = cr_hamiltonian.CrossResonanceHamiltonian( + physical_qubits=(0, 1), + amp=0.1, + sigma=64, + risefall=2, + durations=[backend.dt * (1000 + 4 * 64)], + ) expr.backend = backend with pulse.build(default_alignment="left", name="cr") as ref_cr_sched: @@ -115,15 +114,14 @@ class FakeCRGate(HamiltonianGate): def __init__(self, width): super().__init__(data=np.eye(4), time=width) - with self.assertWarns(DeprecationWarning): - expr = cr_hamiltonian.CrossResonanceHamiltonian( - physical_qubits=(0, 1), - flat_top_widths=[1000], - cr_gate=FakeCRGate, - amp=0.1, - sigma=64, - risefall=2, - ) + expr = cr_hamiltonian.CrossResonanceHamiltonian( + physical_qubits=(0, 1), + cr_gate=FakeCRGate, + amp=0.1, + sigma=64, + risefall=2, + durations=[1256], + ) # Not raise an error expr.circuits() @@ -189,7 +187,7 @@ def test_integration(self, ix, iy, iz, zx, zy, zz): self.assertAlmostEqual(exp_data.analysis_results("omega_zz").value.n, zz, delta=delta) def test_integration_backward_compat(self): - """Integration test for Hamiltonian tomography with implicitly setting flat_top_widths.""" + """Integration test for Hamiltonian tomography.""" ix, iy, iz, zx, zy, zz = 1e6, 2e6, 1e3, -3e6, -2e6, 1e4 delta = 3e4 @@ -214,16 +212,15 @@ def test_integration_backward_compat(self): ) ) - with self.assertWarns(DeprecationWarning): - expr = cr_hamiltonian.CrossResonanceHamiltonian( - (0, 1), - np.linspace(0, 700, 50), - sigma=sigma, - # A hack to avoild local function in pickle, i.e. in transpile. - cr_gate=functools.partial( - SimulatableCRGate, hamiltonian=hamiltonian, sigma=sigma, dt=dt - ), - ) + expr = cr_hamiltonian.CrossResonanceHamiltonian( + (0, 1), + np.linspace(0, 700, 50), + sigma=sigma, + # A hack to avoild local function in pickle, i.e. in transpile. + cr_gate=functools.partial( + SimulatableCRGate, hamiltonian=hamiltonian, sigma=sigma, dt=dt + ), + ) expr.backend = backend exp_data = expr.run() diff --git a/test/library/characterization/test_qubit_spectroscopy.py b/test/library/characterization/test_qubit_spectroscopy.py index b42d6a273d..7390e91ff8 100644 --- a/test/library/characterization/test_qubit_spectroscopy.py +++ b/test/library/characterization/test_qubit_spectroscopy.py @@ -181,7 +181,7 @@ def test_expdata_serialization(self): exp = QubitSpectroscopy([qubit], frequencies) exp.set_run_options(meas_level=MeasLevel.CLASSIFIED, shots=1024) - expdata = exp.run(backend).block_for_results() + expdata = exp.run(backend) self.assertExperimentDone(expdata) # Checking serialization of the experiment data @@ -208,7 +208,7 @@ def test_kerneled_expdata_serialization(self): exp = QubitSpectroscopy([qubit], frequencies) exp.set_run_options(meas_level=MeasLevel.KERNELED, shots=1024) - expdata = exp.run(backend).block_for_results() + expdata = exp.run(backend) self.assertExperimentDone(expdata) # Checking serialization of the experiment data @@ -271,7 +271,7 @@ def test_parallel_experiment(self): ) par_experiment.set_run_options(meas_level=MeasLevel.KERNELED, meas_return="single") - par_data = par_experiment.run().block_for_results() + par_data = par_experiment.run() self.assertExperimentDone(par_data) # since under _experiment in kwargs there is an argument of the backend which isn't serializable. diff --git a/test/library/characterization/test_readout_angle.py b/test/library/characterization/test_readout_angle.py index f9656944ca..31087b835e 100644 --- a/test/library/characterization/test_readout_angle.py +++ b/test/library/characterization/test_readout_angle.py @@ -59,7 +59,7 @@ def test_kerneled_expdata_serialization(self): exp = ReadoutAngle([0]) exp.set_run_options(meas_level=MeasLevel.KERNELED, shots=1024) - expdata = exp.run(backend).block_for_results() + expdata = exp.run(backend) self.assertExperimentDone(expdata) # Checking serialization of the experiment data diff --git a/test/library/characterization/test_readout_error.py b/test/library/characterization/test_readout_error.py index b4fe8a876c..384fc377bb 100644 --- a/test/library/characterization/test_readout_error.py +++ b/test/library/characterization/test_readout_error.py @@ -180,7 +180,8 @@ def test_parallel_running(self): exp1 = CorrelatedReadoutError([0, 2]) exp2 = CorrelatedReadoutError([1, 3]) exp = ParallelExperiment([exp1, exp2], flatten_results=False) - expdata = exp.run(backend=backend).block_for_results() + expdata = exp.run(backend=backend) + self.assertExperimentDone(expdata) mit1 = expdata.child_data(0).analysis_results(0).value mit2 = expdata.child_data(1).analysis_results(0).value assignment_matrix1 = mit1.assignment_matrix() @@ -192,7 +193,8 @@ def test_database_save_and_load(self): qubits = [0, 1] backend = FakeParisV2() exp = LocalReadoutError(qubits) - exp_data = exp.run(backend).block_for_results() + exp_data = exp.run(backend) + self.assertExperimentDone(exp_data) exp_data.service = IBMExperimentService(local=True, local_save=False) exp_data.save() loaded_data = ExperimentData.load(exp_data.experiment_id, exp_data.service) @@ -207,7 +209,8 @@ def test_json_serialization(self): qubits = [0, 1] backend = FakeParisV2() exp = LocalReadoutError(qubits) - exp_data = exp.run(backend).block_for_results() + exp_data = exp.run(backend) + self.assertExperimentDone(exp_data) mitigator = exp_data.analysis_results(0).value serialized = json.dumps(mitigator, cls=ExperimentEncoder) loaded = json.loads(serialized, cls=ExperimentDecoder) diff --git a/test/library/characterization/test_resonator_spectroscopy.py b/test/library/characterization/test_resonator_spectroscopy.py index bf378d94a7..0bd8986c9c 100644 --- a/test/library/characterization/test_resonator_spectroscopy.py +++ b/test/library/characterization/test_resonator_spectroscopy.py @@ -162,7 +162,7 @@ def test_kerneled_expdata_serialization(self, freq_shift): frequencies = np.linspace(res_freq - 20e6, res_freq + 20e6, 51) exp = ResonatorSpectroscopy([qubit], backend=backend, frequencies=frequencies) - expdata = exp.run(backend).block_for_results() + expdata = exp.run(backend) self.assertExperimentDone(expdata) # since under _experiment in kwargs there is an argument of the backend which isn't serializable. @@ -231,7 +231,7 @@ def test_parallel_experiment(self): ) par_experiment.set_run_options(meas_level=MeasLevel.KERNELED, meas_return="single") - par_data = par_experiment.run().block_for_results() + par_data = par_experiment.run() self.assertExperimentDone(par_data) # since under _experiment in kwargs there is an argument of the backend which isn't serializable. diff --git a/test/library/characterization/test_t1.py b/test/library/characterization/test_t1.py index 145be4c010..b7fc99874a 100644 --- a/test/library/characterization/test_t1.py +++ b/test/library/characterization/test_t1.py @@ -41,7 +41,7 @@ def test_t1_end2end(self): exp = T1([0], delays) exp.analysis.set_options(p0={"amp": 1, "tau": t1, "base": 0}) - exp_data = exp.run(backend, shots=10000, seed_simulator=1).block_for_results() + exp_data = exp.run(backend, shots=10000, seed_simulator=1) self.assertExperimentDone(exp_data) self.assertRoundTripSerializable(exp_data) self.assertRoundTripPickle(exp_data) @@ -84,7 +84,7 @@ def test_t1_measurement_level_1(self): meas_return="avg", meas_level=MeasLevel.KERNELED, shots=num_shots, - ).block_for_results() + ) self.assertExperimentDone(expdata0) self.assertRoundTripSerializable(expdata0) @@ -114,7 +114,7 @@ def test_t1_parallel(self): exp2 = T1(physical_qubits=[qubit2], delays=delays) par_exp = ParallelExperiment([exp0, exp2], flatten_results=False) - res = par_exp.run(backend=backend, shots=10000, seed_simulator=1).block_for_results() + res = par_exp.run(backend=backend, shots=10000, seed_simulator=1) self.assertExperimentDone(res) for i, qb in enumerate(quantum_bit): @@ -181,7 +181,7 @@ def test_t1_parallel_measurement_level_1(self): rng_seed=1, meas_level=MeasLevel.KERNELED, meas_return="avg", - ).block_for_results() + ) self.assertExperimentDone(res) # Checking analysis diff --git a/test/library/characterization/test_t2hahn.py b/test/library/characterization/test_t2hahn.py index 8124582046..cce94bdb11 100644 --- a/test/library/characterization/test_t2hahn.py +++ b/test/library/characterization/test_t2hahn.py @@ -110,7 +110,8 @@ def test_t2hahn_parallel(self): readout0to1=0.02, readout1to0=0.02, ) - expdata = par_exp.run(backend=backend, shots=1024).block_for_results() + expdata = par_exp.run(backend=backend, shots=1024) + self.assertExperimentDone(expdata) for i in range(2): res_t2 = expdata.child_data(i).analysis_results("T2") @@ -141,14 +142,15 @@ def test_t2hahn_concat_2_experiments(self): # run circuits expdata0 = exp0.run(backend=backend, shots=1000) - expdata0.block_for_results() + self.assertExperimentDone(expdata0) res_t2_0 = expdata0.analysis_results("T2") # second experiment delays1 = list(range(4, 180, 6)) exp1 = T2Hahn([qubit], delays1) exp1.analysis.set_options(p0={"amp": 0.5, "tau": estimated_t2hahn, "base": 0.5}, plot=True) - expdata1 = exp1.run(backend=backend, analysis=None, shots=1000).block_for_results() + expdata1 = exp1.run(backend=backend, analysis=None, shots=1000) + self.assertExperimentDone(expdata1) expdata1.add_data(expdata0.data()) exp1.analysis.run(expdata1) @@ -192,7 +194,7 @@ def test_roundtrip_serializable(self): readout1to0=[0.02], ) exp.analysis.set_options(p0={"amp": 0.5, "tau": estimated_t2hahn, "base": 0.5}, plot=False) - expdata = exp.run(backend=backend, shots=1000).block_for_results() + expdata = exp.run(backend=backend, shots=1000) self.assertExperimentDone(expdata) # Checking serialization of the experiment data diff --git a/test/library/characterization/test_t2ramsey.py b/test/library/characterization/test_t2ramsey.py index 49faee948a..345a0745d2 100644 --- a/test/library/characterization/test_t2ramsey.py +++ b/test/library/characterization/test_t2ramsey.py @@ -75,7 +75,7 @@ def test_t2ramsey_run_end2end(self): for user_p0 in [default_p0, {}]: exp.analysis.set_options(p0=user_p0) - expdata = exp.run(backend=backend, shots=2000, seed_simulator=1).block_for_results() + expdata = exp.run(backend=backend, shots=2000, seed_simulator=1) self.assertExperimentDone(expdata) self.assertRoundTripSerializable(expdata) self.assertRoundTripPickle(expdata) @@ -137,7 +137,7 @@ def test_t2ramsey_parallel(self): exp0.analysis.set_options(p0=exp0_p0) exp2.analysis.set_options(p0=exp2_p0) - expdata = par_exp.run(backend=backend, shots=2000, seed_simulator=1).block_for_results() + expdata = par_exp.run(backend=backend, shots=2000, seed_simulator=1) self.assertExperimentDone(expdata) for i, qb in enumerate(par_exp_qubits): diff --git a/test/library/quantum_volume/qv_generate_data.py b/test/library/quantum_volume/qv_generate_data.py index 2401f8aff5..61feecc519 100644 --- a/test/library/quantum_volume/qv_generate_data.py +++ b/test/library/quantum_volume/qv_generate_data.py @@ -59,8 +59,7 @@ def create_qv_data_70_trials(dir_path: str): qv_exp = QuantumVolume(range(num_of_qubits), seed=SEED) qv_exp.set_experiment_options(trials=70) - qv_data = qv_exp.run(backend) - qv_data.block_for_results() + qv_data = qv_exp.run(backend).block_for_results() result_file_path = os.path.join(dir_path, "qv_data_70_trials.json") with open(result_file_path, "w", encoding="utf-8") as json_file: @@ -81,8 +80,7 @@ def create_qv_data_low_hop(dir_path: str): qv_exp = QuantumVolume(range(num_of_qubits), seed=SEED) qv_exp.set_transpile_options(basis_gates=basis_gates) - qv_data = qv_exp.run(backend, noise_model=noise, basis_gates=basis_gates) - qv_data.block_for_results() + qv_data = qv_exp.run(backend, noise_model=noise, basis_gates=basis_gates).block_for_results() result_file_path = os.path.join(dir_path, "qv_data_high_noise.json") with open(result_file_path, "w", encoding="utf-8") as json_file: @@ -104,8 +102,7 @@ def create_qv_data_low_confidence(dir_path: str): qv_exp = QuantumVolume(range(num_of_qubits), seed=SEED) qv_exp.set_transpile_options(basis_gates=basis_gates) - qv_data = qv_exp.run(backend, noise_model=noise, basis_gates=basis_gates) - qv_data.block_for_results() + qv_data = qv_exp.run(backend, noise_model=noise, basis_gates=basis_gates).block_for_results() result_file_path = os.path.join(dir_path, "qv_data_moderate_noise_100_trials.json") with open(result_file_path, "w", encoding="utf-8") as json_file: @@ -128,8 +125,7 @@ def create_qv_data_high_confidence(dir_path: str): qv_exp = QuantumVolume(range(num_of_qubits), seed=SEED) qv_exp.set_experiment_options(trials=300) qv_exp.set_transpile_options(basis_gates=basis_gates) - qv_data = qv_exp.run(backend, noise_model=noise, basis_gates=basis_gates) - qv_data.block_for_results() + qv_data = qv_exp.run(backend, noise_model=noise, basis_gates=basis_gates).block_for_results() result_file_path = os.path.join(dir_path, "qv_data_moderate_noise_300_trials.json") with open(result_file_path, "w", encoding="utf-8") as json_file: diff --git a/test/library/randomized_benchmarking/test_rb_analysis.py b/test/library/randomized_benchmarking/test_rb_analysis.py index 2e4cddfee0..e9ab6ffe5a 100644 --- a/test/library/randomized_benchmarking/test_rb_analysis.py +++ b/test/library/randomized_benchmarking/test_rb_analysis.py @@ -70,7 +70,8 @@ def setUp(self): backend=backend, ) exp_1qrb_q0.set_transpile_options(**transpiler_options) - expdata_1qrb_q0 = exp_1qrb_q0.run(analysis=None).block_for_results(timeout=300) + expdata_1qrb_q0 = exp_1qrb_q0.run(analysis=None) + self.assertExperimentDone(expdata_1qrb_q0, timeout=300) exp_1qrb_q1 = rb.StandardRB( physical_qubits=(1,), @@ -79,7 +80,8 @@ def setUp(self): backend=backend, ) exp_1qrb_q1.set_transpile_options(**transpiler_options) - expdata_1qrb_q1 = exp_1qrb_q1.run(analysis=None).block_for_results(timeout=300) + expdata_1qrb_q1 = exp_1qrb_q1.run(analysis=None) + self.assertExperimentDone(expdata_1qrb_q1, timeout=300) exp_2qrb = rb.StandardRB( physical_qubits=(0, 1), @@ -88,7 +90,8 @@ def setUp(self): backend=backend, ) exp_2qrb.set_transpile_options(**transpiler_options) - expdata_2qrb = exp_2qrb.run(analysis=None).block_for_results(timeout=300) + expdata_2qrb = exp_2qrb.run(analysis=None) + self.assertExperimentDone(expdata_2qrb, timeout=300) self.expdata_1qrb_q0 = expdata_1qrb_q0 self.expdata_1qrb_q1 = expdata_1qrb_q1 diff --git a/test/library/tomography/test_process_tomography.py b/test/library/tomography/test_process_tomography.py index 59b55da5d3..3eb9b506d9 100644 --- a/test/library/tomography/test_process_tomography.py +++ b/test/library/tomography/test_process_tomography.py @@ -438,7 +438,7 @@ def test_qpt_spam_mitigated_basis(self): CXGate(), measurement_basis=meas_basis, preparation_basis=prep_basis ) exp.backend = backend - expdata = exp.run(shots=2000).block_for_results() + expdata = exp.run(shots=2000) self.assertExperimentDone(expdata) fid = expdata.analysis_results("process_fidelity").value self.assertGreater(fid, 0.95) @@ -467,7 +467,7 @@ def test_qpt_amat_pauli_basis(self): # Run experiment exp = ProcessTomography(CXGate(), measurement_basis=meas_basis) exp.backend = backend - expdata = exp.run(shots=2000).block_for_results() + expdata = exp.run(shots=2000) self.assertExperimentDone(expdata) fid = expdata.analysis_results("process_fidelity").value self.assertGreater(fid, 0.95) diff --git a/test/library/tomography/test_state_tomography.py b/test/library/tomography/test_state_tomography.py index 7b746044d3..fec16be57c 100644 --- a/test/library/tomography/test_state_tomography.py +++ b/test/library/tomography/test_state_tomography.py @@ -332,7 +332,7 @@ def test_qst_spam_mitigated_basis(self): circ.cx(i - 1, i) exp = StateTomography(circ, measurement_basis=meas_basis) exp.backend = backend - expdata = exp.run(shots=2000).block_for_results() + expdata = exp.run(shots=2000) self.assertExperimentDone(expdata) fid = expdata.analysis_results("state_fidelity").value self.assertGreater(fid, 0.95) @@ -365,7 +365,7 @@ def test_qst_amat_pauli_basis(self): circ.cx(i - 1, i) exp = StateTomography(circ, measurement_basis=meas_basis) exp.backend = backend - expdata = exp.run(shots=2000).block_for_results() + expdata = exp.run(shots=2000) self.assertExperimentDone(expdata) fid = expdata.analysis_results("state_fidelity").value self.assertGreater(fid, 0.945)