From 8327f4690b1888ca7628258016b2e5a1c2650cfe Mon Sep 17 00:00:00 2001 From: Will Shanks Date: Thu, 6 Mar 2025 22:54:53 -0500 Subject: [PATCH] Promote pending curve analysis deprecations to current The functions in `qiskit_experiments.curve_analysis.utils` and methods of `ScatterTable` that had previously been marked as pending deprecation have been promoted to full deprecation status. Additionally, some helper methods in `qiskit_experiments.curve_analysis.utils` that had help replace the deprecated functions have been documented as public. Also, some methods on `QiskitExperimentsTestCase` that had been marked as pending deprecation have been removed. `QiskitExperimentsTestCase` is not part of the public API so these methods could be removed without a deprecation cycle. --- docs/tutorials/curve_analysis.rst | 9 +-- qiskit_experiments/curve_analysis/__init__.py | 7 ++- .../curve_analysis/base_curve_analysis.py | 6 +- .../curve_analysis/scatter_table.py | 9 +-- qiskit_experiments/curve_analysis/utils.py | 12 ++-- ...precate-old-curvefit-8f532de113c184c4.yaml | 25 ++++++++ test/base.py | 57 ------------------- 7 files changed, 46 insertions(+), 79 deletions(-) create mode 100644 releasenotes/notes/deprecate-old-curvefit-8f532de113c184c4.yaml diff --git a/docs/tutorials/curve_analysis.rst b/docs/tutorials/curve_analysis.rst index ccf61cf599..c25f76db83 100644 --- a/docs/tutorials/curve_analysis.rst +++ b/docs/tutorials/curve_analysis.rst @@ -526,10 +526,11 @@ boundary value can be a tuple of floats representing minimum and maximum values. Apart from user provided guesses, the analysis can systematically generate those values with the method :meth:`_generate_fit_guesses`, which is called with the :class:`.ScatterTable` class. If the analysis contains multiple model definitions, we can get the subset -of curve data with :meth:`.ScatterTable.get_subset_of` using the name of the series. A -developer can implement the algorithm to generate initial guesses and boundaries by -using this curve data object, which will be provided to the fitter. Note that there are -several common initial guess estimators available in :mod:`curve_analysis.guess`. +of curve data with :meth:`.ScatterTable.filter` by passing the name of the +series to the ``series`` argument. A developer can implement the algorithm to +generate initial guesses and boundaries by using this curve data object, which +will be provided to the fitter. Note that there are several common initial +guess estimators available in :mod:`curve_analysis.guess`. The :meth:`_generate_fit_guesses` also receives the :class:`.FitOptions` instance ``user_opt``, which contains user provided guesses and boundaries. This is a diff --git a/qiskit_experiments/curve_analysis/__init__.py b/qiskit_experiments/curve_analysis/__init__.py index 03c8a57119..6653cf420a 100644 --- a/qiskit_experiments/curve_analysis/__init__.py +++ b/qiskit_experiments/curve_analysis/__init__.py @@ -91,16 +91,19 @@ .. autosummary:: :toctree: ../stubs/ - utils.is_error_not_significant utils.analysis_result_to_repr utils.convert_lmfit_result + utils.data_sort utils.eval_with_uncertainties utils.filter_data + utils.inverse_weighted_variance + utils.is_error_not_significant utils.mean_xy_data utils.multi_mean_xy_data - utils.data_sort utils.level2_probability utils.probability + utils.sample_average + utils.shot_weighted_average """ from .base_curve_analysis import BaseCurveAnalysis diff --git a/qiskit_experiments/curve_analysis/base_curve_analysis.py b/qiskit_experiments/curve_analysis/base_curve_analysis.py index c477a2dfb7..de441dc43d 100644 --- a/qiskit_experiments/curve_analysis/base_curve_analysis.py +++ b/qiskit_experiments/curve_analysis/base_curve_analysis.py @@ -148,8 +148,10 @@ def _default_options(cls) -> Options: average_method (Literal["sample", "iwv", "shots_weighted"]): Method to average the y values when the same x values appear multiple times. One of "sample", "iwv" (i.e. inverse - weighted variance), "shots_weighted". See :func:`.mean_xy_data` - for details. Default to "shots_weighted". + weighted variance), "shots_weighted". See + :func:`.sample_average`, :func:`.inverse_weighted_variance`, + and :func:`.shot_weighted_average` for details. Default to + "shots_weighted". p0 (Dict[str, float]): Initial guesses for the fit parameters. The dictionary is keyed on the fit parameter names. bounds (Dict[str, Tuple[float, float]]): Boundary of fit parameters. diff --git a/qiskit_experiments/curve_analysis/scatter_table.py b/qiskit_experiments/curve_analysis/scatter_table.py index bbb5f91bbd..ca9510397e 100644 --- a/qiskit_experiments/curve_analysis/scatter_table.py +++ b/qiskit_experiments/curve_analysis/scatter_table.py @@ -408,9 +408,8 @@ def _warn_composite_data(self): @property @deprecate_func( - since="0.6", + since="0.9", additional_msg="Curve data uses dataframe representation. Call .series_id instead.", - pending=True, package_name="qiskit-experiments", is_property=True, ) @@ -420,9 +419,8 @@ def data_allocation(self) -> np.ndarray: @property @deprecate_func( - since="0.6", + since="0.9", additional_msg="No alternative is provided. Use .series_name with set operation.", - pending=True, package_name="qiskit-experiments", is_property=True, ) @@ -433,9 +431,8 @@ def labels(self) -> list[str]: return [k[0] for k in sorted(name_id_tups, key=lambda k: k[1])] @deprecate_func( - since="0.6", + since="0.9", additional_msg="Use filter method instead.", - pending=True, package_name="qiskit-experiments", ) def get_subset_of(self, index: str | int) -> "ScatterTable": diff --git a/qiskit_experiments/curve_analysis/utils.py b/qiskit_experiments/curve_analysis/utils.py index 3b34d0554d..25d5ed5e29 100644 --- a/qiskit_experiments/curve_analysis/utils.py +++ b/qiskit_experiments/curve_analysis/utils.py @@ -321,10 +321,9 @@ def sample_average( @deprecate_func( - since="0.6", + since="0.9", additional_msg="The curve data representation has been replaced by the `DataFrame` format.", package_name="qiskit-experiments", - pending=True, ) def filter_data(data: List[Dict[str, any]], **filters) -> List[Dict[str, any]]: """Return the list of filtered data @@ -354,10 +353,9 @@ def filter_data(data: List[Dict[str, any]], **filters) -> List[Dict[str, any]]: @deprecate_func( - since="0.6", + since="0.9", additional_msg="The curve data representation has been replaced by the `DataFrame` format.", package_name="qiskit-experiments", - pending=True, ) def mean_xy_data( xdata: np.ndarray, @@ -480,10 +478,9 @@ def mean_xy_data( @deprecate_func( - since="0.6", + since="0.9", additional_msg="The curve data representation has been replaced by the `DataFrame` format.", package_name="qiskit-experiments", - pending=True, ) def multi_mean_xy_data( series: np.ndarray, @@ -544,10 +541,9 @@ def multi_mean_xy_data( @deprecate_func( - since="0.6", + since="0.9", additional_msg="The curve data representation has been replaced by the `DataFrame` format.", package_name="qiskit-experiments", - pending=True, ) def data_sort( series: np.ndarray, diff --git a/releasenotes/notes/deprecate-old-curvefit-8f532de113c184c4.yaml b/releasenotes/notes/deprecate-old-curvefit-8f532de113c184c4.yaml new file mode 100644 index 0000000000..280ba513fc --- /dev/null +++ b/releasenotes/notes/deprecate-old-curvefit-8f532de113c184c4.yaml @@ -0,0 +1,25 @@ +--- +features: + - | + Curve analysis helper functions :class:`.utils.inverse_weighted_variance`, + :class:`.utils.sample_weighted_average`, and + :class:`.utils.shot_weighted_average` were documented as public. These + functions were present in previous releases but not documented as public. +deprecations: + - | + Curve analysis utility functions + :func:`qiskit_experiments.curve_analysis.utils.filter_data`, + :func:`.mean_xy_data`, :func:`.multi_mean_xy_data`, and + :func:`qiskit_experiments.curve_analysis.utils.data_sort`` have been + deprecated. These methods were written to work with the previous + representation of curve data. Curve analysis now works with + :class:`.ScatterTable` which provides a ``filter`` method which can be used + with functions like :func:`.shot_weighted_average` to achieve similar + results to the deprecated functions. + - | + The :class:`.ScatterTable` properties ``data_allocation`` and + ``labels`` and method ``get_subset_of``have been deprecated. + ``data_allocation`` was renamed to ``series_id``. ``labels`` can be found + by looking at the ``series_name`` of the scatter table's ``dataframe``. + Data subsets can be obtained using :meth:`.ScatterTable.filter` in place of + ``get_subset_of``. diff --git a/test/base.py b/test/base.py index b4c44e8c02..44e22e7221 100644 --- a/test/base.py +++ b/test/base.py @@ -22,7 +22,6 @@ import fixtures import testtools -import uncertainties from qiskit_experiments.framework import ( ExperimentDecoder, @@ -30,7 +29,6 @@ ExperimentData, ) from qiskit_experiments.framework.experiment_data import ExperimentStatus -from qiskit_experiments.framework.deprecation import deprecate_func from .extended_equality import is_equivalent @@ -225,61 +223,6 @@ def assertRoundTripPickle( else: self.assertEqualExtended(obj, decoded, strict_type=strict_type) - @classmethod - @deprecate_func( - since="0.6", - additional_msg="Use test.extended_equality.is_equivalent instead.", - pending=True, - package_name="qiskit-experiments", - ) - def json_equiv(cls, data1, data2) -> bool: - """Check if two experiments are equivalent by comparing their configs""" - return is_equivalent(data1, data2) - - @staticmethod - @deprecate_func( - since="0.6", - additional_msg="Use test.extended_equality.is_equivalent instead.", - pending=True, - package_name="qiskit-experiments", - ) - def ufloat_equiv(data1: uncertainties.UFloat, data2: uncertainties.UFloat) -> bool: - """Check if two values with uncertainties are equal. No correlation is considered.""" - return is_equivalent(data1, data2) - - @classmethod - @deprecate_func( - since="0.6", - additional_msg="Use test.extended_equality.is_equivalent instead.", - pending=True, - package_name="qiskit-experiments", - ) - def analysis_result_equiv(cls, result1, result2): - """Test two analysis results are equivalent""" - return is_equivalent(result1, result2) - - @classmethod - @deprecate_func( - since="0.6", - additional_msg="Use test.extended_equality.is_equivalent instead.", - pending=True, - package_name="qiskit-experiments", - ) - def curve_fit_data_equiv(cls, data1, data2): - """Test two curve fit result are equivalent.""" - return is_equivalent(data1, data2) - - @classmethod - @deprecate_func( - since="0.6", - additional_msg="Use test.extended_equality.is_equivalent instead.", - pending=True, - package_name="qiskit-experiments", - ) - def experiment_data_equiv(cls, data1, data2): - """Check two experiment data containers are equivalent""" - return is_equivalent(data1, data2) - return QETestCase