From 0be466d46e9ac97c731f9423f38a5175c22a3ab7 Mon Sep 17 00:00:00 2001 From: Daniel Egger Date: Thu, 21 Apr 2022 19:46:10 +0200 Subject: [PATCH 1/9] * Deprecate library. --- .../calibration_management/calibrations.py | 88 +++++++++++++------ test/calibration/test_calibrations.py | 46 ++++++---- 2 files changed, 88 insertions(+), 46 deletions(-) diff --git a/qiskit_experiments/calibration_management/calibrations.py b/qiskit_experiments/calibration_management/calibrations.py index 8446ca931b..a84f6609a2 100644 --- a/qiskit_experiments/calibration_management/calibrations.py +++ b/qiskit_experiments/calibration_management/calibrations.py @@ -73,22 +73,25 @@ def __init__( coupling_map: Optional[List[List[int]]] = None, control_channel_map: Optional[Dict[Tuple[int, ...], List[ControlChannel]]] = None, library: Optional[Union[BasisGateLibrary, List[BasisGateLibrary]]] = None, + libraries: Optional[List[BasisGateLibrary]] = None, add_parameter_defaults: bool = True, backend_name: Optional[str] = None, backend_version: Optional[str] = None, ): """Initialize the calibrations. - Calibrations can be initialized from a basis gate library, i.e. a subclass of + Calibrations can be initialized from a list of basis gate libraries, i.e. a subclass of :class:`BasisGateLibrary`. As example consider the following code: .. code-block:: python cals = Calibrations( - library=FixedFrequencyTransmon( - basis_gates=["x", "sx"], - default_values={duration: 320} - ) + libraries=[ + FixedFrequencyTransmon( + basis_gates=["x", "sx"], + default_values={duration: 320} + ) + ] ) Args: @@ -99,10 +102,12 @@ def __init__( keys are tuples of qubits and the values are a list of ControlChannels that correspond to the qubits in the keys. If a control_channel_map is given then the qubits must be in the coupling_map. - library: A library instance from which to get template schedules to register as well - as default parameter values. + library (deprecated): A library instance from which to get template schedules to + register as well as default parameter values. + libraries: A list of library instance from which to get template schedules to register + as well as default parameter values. add_parameter_defaults: A boolean to indicate weather the default parameter values of - the given library should be used to populate the calibrations. By default this + the given libraries should be used to populate the calibrations. By default this value is True but can be set to false when deserializing a calibrations object. backend_name: The name of the backend that these calibrations are attached to. backend_version: The version of the backend that these calibrations are attached to. @@ -114,12 +119,22 @@ def __init__( self._backend_name = backend_name self._backend_version = backend_version - if isinstance(library, list): - raise NotImplementedError( - "Passing a list of libraries from which to instantiate " - "will be supported in future releases." + if library: + warnings.warn( + f"library has been deprecated, please provide libraries instead." + "This warning will be removed with backport in Qiskit Experiments 0.4.", + DeprecationWarning, + stacklevel=2, ) + if libraries: + raise CalibrationError("Cannot supply both library and libraries.") + + if not isinstance(library, list): + libraries = [library] + else: + libraries = library + # Mapping between qubits and their control channels. self._control_channel_map = control_channel_map if control_channel_map else {} @@ -149,18 +164,18 @@ def __init__( self._hash_to_counter_map = {} self._parameter_counter = 0 - self._library = None - if library is not None: - self._library = library + self._libraries = libraries + if libraries is not None: + for lib in libraries: - # Add the basis gates - for gate in library.basis_gates: - self.add_schedule(library[gate], num_qubits=library.num_qubits(gate)) + # Add the basis gates + for gate in lib.basis_gates: + self.add_schedule(lib[gate], num_qubits=lib.num_qubits(gate)) - # Add the default values - if add_parameter_defaults: - for param_conf in library.default_values(): - self.add_parameter_value(*param_conf, update_inst_map=False) + # Add the default values + if add_parameter_defaults: + for param_conf in lib.default_values(): + self.add_parameter_value(*param_conf, update_inst_map=False) # This internal parameter is False so that if a schedule is added after the # init it will be set to True and serialization will raise an error. @@ -220,6 +235,7 @@ def from_backend( cls, backend: Backend, library: Optional[BasisGateLibrary] = None, + libraries: Optional[List[BasisGateLibrary]] = None, add_parameter_defaults: bool = True, ) -> "Calibrations": """Create an instance of Calibrations from a backend. @@ -228,8 +244,10 @@ def from_backend( backend: A backend instance from which to extract the qubit and readout frequencies (which will be added as first guesses for the corresponding parameters) as well as the coupling map. - library: A library instance from which to get template schedules to register as well - as default parameter values. + library: A library or list thereof from which to get template schedules to register as + well as default parameter values. + libraries: A list of libraries from which to get template schedules to register as + well as default parameter values. add_parameter_defaults: A boolean to indicate whether the default parameter values of the given library should be used to populate the calibrations. By default this value is ``True``. @@ -246,6 +264,7 @@ def from_backend( getattr(backend.configuration(), "coupling_map", []), getattr(backend.configuration(), "control_channels", None), library, + libraries, add_parameter_defaults, backend_name, getattr(backend, "version", None), @@ -264,9 +283,20 @@ def from_backend( return cals @property - def library(self) -> Optional[BasisGateLibrary]: - """Return the name of the library, e.g. for experiment metadata.""" - return self._library + def libraries(self) -> Optional[List[BasisGateLibrary]]: + """Return the libraries used to initialize the calibrations.""" + return self._libraries + + @property + def library(self) -> Optional[List[BasisGateLibrary]]: + """Return the libraries used to initialize the calibrations.""" + warnings.warn( + f"library has been deprecated, use libraries instead." + "This warning will be removed with backport in Qiskit Experiments 0.4.", + DeprecationWarning, + stacklevel=2, + ) + return self._libraries def _get_operated_qubits(self) -> Dict[int, List[int]]: """Get a dict describing qubit couplings. @@ -1609,7 +1639,7 @@ def __eq__(self, other: "Calibrations") -> bool: - The backends have the same name. - The backends have the same version. - The calibrations contain the same schedules. - - The stored paramters have the same values. + - The stored parameters have the same values. """ if self.backend_name != other.backend_name: return False @@ -1654,7 +1684,7 @@ def config(self) -> Dict[str, Any]: kwargs = { "coupling_map": self._coupling_map, "control_channel_map": ControlChannelMap(self._control_channel_map), - "library": self.library, + "libraries": self.libraries, "add_parameter_defaults": False, # the parameters will be added outside of the init "backend_name": self._backend_name, "backend_version": self._backend_version, diff --git a/test/calibration/test_calibrations.py b/test/calibration/test_calibrations.py index dfe9d85fd2..2f2e4c218d 100644 --- a/test/calibration/test_calibrations.py +++ b/test/calibration/test_calibrations.py @@ -1434,7 +1434,7 @@ def test_save_load_library(self): library = FixedFrequencyTransmon() backend = FakeArmonk() - cals = Calibrations.from_backend(backend, library) + cals = Calibrations.from_backend(backend, libraries=[library]) cals.parameters_table() @@ -1458,9 +1458,11 @@ def test_setup_withLibrary(self): cals = Calibrations.from_backend( FakeArmonk(), - library=FixedFrequencyTransmon( - basis_gates=["x", "sx"], default_values={"duration": 320} - ), + libraries=[ + FixedFrequencyTransmon( + basis_gates=["x", "sx"], default_values={"duration": 320} + ) + ], ) # Check the x gate @@ -1482,7 +1484,7 @@ def test_instruction_schedule_map_export(self): cals = Calibrations.from_backend( backend, - library=FixedFrequencyTransmon(basis_gates=["sx"]), + libraries=[FixedFrequencyTransmon(basis_gates=["sx"])], ) u_chan = pulse.ControlChannel(Parameter("ch0.1")) @@ -1508,7 +1510,7 @@ def test_inst_map_transpilation(self): cals = Calibrations.from_backend( FakeArmonk(), - library=FixedFrequencyTransmon(basis_gates=["x"]), + libraries=[FixedFrequencyTransmon(basis_gates=["x"])], ) param = Parameter("amp") @@ -1558,7 +1560,7 @@ def test_inst_map_updates(self): cals = Calibrations.from_backend( FakeBelem(), - library=FixedFrequencyTransmon(basis_gates=["sx", "x"]), + libraries=[FixedFrequencyTransmon(basis_gates=["sx", "x"])], ) # Test the schedules before the update. @@ -1656,9 +1658,9 @@ def test_alternate_initialization(self): backend = FakeBelem() library = FixedFrequencyTransmon(basis_gates=["sx", "x"]) - cals1 = Calibrations.from_backend(backend, library) + cals1 = Calibrations.from_backend(backend, libraries=[library]) cals2 = Calibrations( - library=library, + libraries=[library], control_channel_map=backend.configuration().control_channels, coupling_map=backend.configuration().coupling_map, ) @@ -1675,7 +1677,7 @@ def test_serialization(self): backend = FakeBelem() library = FixedFrequencyTransmon(basis_gates=["sx", "x"]) - cals = Calibrations.from_backend(backend, library) + cals = Calibrations.from_backend(backend, libraries=[library]) cals.add_parameter_value(0.12345, "amp", 3, "x") self.assertRoundTripSerializable(cals, self.json_equiv) @@ -1685,8 +1687,12 @@ def test_equality(self): backend = FakeBelem() library = FixedFrequencyTransmon(basis_gates=["sx", "x"]) - cals1 = Calibrations.from_backend(backend, library, add_parameter_defaults=False) - cals2 = Calibrations.from_backend(backend, library, add_parameter_defaults=False) + cals1 = Calibrations.from_backend( + backend, libraries=[library], add_parameter_defaults=False + ) + cals2 = Calibrations.from_backend( + backend, libraries=[library], add_parameter_defaults=False + ) self.assertTrue(cals1 == cals2) date_time = datetime.now(timezone.utc).astimezone() @@ -1702,7 +1708,9 @@ def test_equality(self): self.assertFalse(cals1 == cals2) # The two objects are different due to missing parameter value - cals3 = Calibrations.from_backend(backend, library, add_parameter_defaults=False) + cals3 = Calibrations.from_backend( + backend, libraries=[library], add_parameter_defaults=False + ) self.assertFalse(cals1 == cals3) # The two objects are identical due to time stamps @@ -1711,13 +1719,17 @@ def test_equality(self): # The schedules contained in the cals are different. library2 = FixedFrequencyTransmon(basis_gates=["sx", "x", "y"]) - cals1 = Calibrations.from_backend(backend, library) - cals2 = Calibrations.from_backend(backend, library2) + cals1 = Calibrations.from_backend(backend, libraries=[library]) + cals2 = Calibrations.from_backend(backend, libraries=[library2]) self.assertFalse(cals1 == cals2) # Ensure that the equality is not sensitive to parameter adding order. - cals1 = Calibrations.from_backend(backend, library, add_parameter_defaults=False) - cals2 = Calibrations.from_backend(backend, library, add_parameter_defaults=False) + cals1 = Calibrations.from_backend( + backend, libraries=[library], add_parameter_defaults=False + ) + cals2 = Calibrations.from_backend( + backend, libraries=[library], add_parameter_defaults=False + ) param_val1 = ParameterValue(0.54321, date_time=date_time) param_val2 = ParameterValue(0.12345, date_time=date_time - timedelta(seconds=1)) From 77ef2a6d86cf84acba74a8500aedd387e618bb2b Mon Sep 17 00:00:00 2001 From: Daniel Egger Date: Thu, 21 Apr 2022 19:48:04 +0200 Subject: [PATCH 2/9] * Added reno. --- .../notes/deprecate-cals-library-128909c1379330fe.yaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 releasenotes/notes/deprecate-cals-library-128909c1379330fe.yaml diff --git a/releasenotes/notes/deprecate-cals-library-128909c1379330fe.yaml b/releasenotes/notes/deprecate-cals-library-128909c1379330fe.yaml new file mode 100644 index 0000000000..eac8550a9c --- /dev/null +++ b/releasenotes/notes/deprecate-cals-library-128909c1379330fe.yaml @@ -0,0 +1,5 @@ +--- +deprecations: + - | + The library argument to :class:`.Calibrations` has been deprecated in favour + of a new argument called libraries. From b25e79787542a0c8cca895c5a4860156fcd4f6c8 Mon Sep 17 00:00:00 2001 From: Daniel Egger Date: Thu, 21 Apr 2022 20:02:00 +0200 Subject: [PATCH 3/9] * black. --- test/calibration/test_calibrations.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/calibration/test_calibrations.py b/test/calibration/test_calibrations.py index 2f2e4c218d..e2a6838a53 100644 --- a/test/calibration/test_calibrations.py +++ b/test/calibration/test_calibrations.py @@ -1459,9 +1459,7 @@ def test_setup_withLibrary(self): cals = Calibrations.from_backend( FakeArmonk(), libraries=[ - FixedFrequencyTransmon( - basis_gates=["x", "sx"], default_values={"duration": 320} - ) + FixedFrequencyTransmon(basis_gates=["x", "sx"], default_values={"duration": 320}) ], ) From 87541fcc7962c4427c74a535eeeff38c262c8bc3 Mon Sep 17 00:00:00 2001 From: Daniel Egger Date: Fri, 22 Apr 2022 17:51:46 +0200 Subject: [PATCH 4/9] * Fix tests. --- test/calibration/experiments/test_drag.py | 2 +- test/calibration/experiments/test_fine_amplitude.py | 2 +- test/calibration/experiments/test_fine_drag.py | 2 +- test/calibration/experiments/test_fine_frequency.py | 2 +- test/calibration/experiments/test_ramsey_xy.py | 2 +- test/calibration/experiments/test_rough_amplitude.py | 4 ++-- test/calibration/experiments/test_rough_frequency.py | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/test/calibration/experiments/test_drag.py b/test/calibration/experiments/test_drag.py index 60c2b362ee..58da70846d 100644 --- a/test/calibration/experiments/test_drag.py +++ b/test/calibration/experiments/test_drag.py @@ -172,7 +172,7 @@ def setUp(self): library = FixedFrequencyTransmon() self.backend = DragBackend(gate_name="Drag(x)") - self.cals = Calibrations.from_backend(self.backend, library) + self.cals = Calibrations.from_backend(self.backend, libraries=[library]) self.test_tol = 0.05 def test_update(self): diff --git a/test/calibration/experiments/test_fine_amplitude.py b/test/calibration/experiments/test_fine_amplitude.py index cbba7e1508..25891bd83f 100644 --- a/test/calibration/experiments/test_fine_amplitude.py +++ b/test/calibration/experiments/test_fine_amplitude.py @@ -209,7 +209,7 @@ def setUp(self): library = FixedFrequencyTransmon() self.backend = MockFineAmp(-np.pi * 0.07, np.pi, "xp") - self.cals = Calibrations.from_backend(self.backend, library) + self.cals = Calibrations.from_backend(self.backend, libraries=[library]) def test_cal_options(self): """Test that the options are properly propagated.""" diff --git a/test/calibration/experiments/test_fine_drag.py b/test/calibration/experiments/test_fine_drag.py index 087c06506b..1174af0572 100644 --- a/test/calibration/experiments/test_fine_drag.py +++ b/test/calibration/experiments/test_fine_drag.py @@ -97,7 +97,7 @@ def setUp(self): library = FixedFrequencyTransmon() self.backend = FineDragTestBackend() - self.cals = Calibrations.from_backend(self.backend, library) + self.cals = Calibrations.from_backend(self.backend, libraries=[library]) def test_experiment_config(self): """Test converting to and from config works""" diff --git a/test/calibration/experiments/test_fine_frequency.py b/test/calibration/experiments/test_fine_frequency.py index 7beb808a25..5939374a76 100644 --- a/test/calibration/experiments/test_fine_frequency.py +++ b/test/calibration/experiments/test_fine_frequency.py @@ -44,7 +44,7 @@ def setUp(self): self.inst_map.add("sx", 0, sx_sched) - self.cals = Calibrations.from_backend(FakeArmonk(), FixedFrequencyTransmon()) + self.cals = Calibrations.from_backend(FakeArmonk(), libraries=[FixedFrequencyTransmon()]) @data(-0.5e6, -0.1e6, 0.1e6, 0.5e6) def test_end_to_end(self, freq_shift): diff --git a/test/calibration/experiments/test_ramsey_xy.py b/test/calibration/experiments/test_ramsey_xy.py index 3107a87dfb..a9d3d6abd3 100644 --- a/test/calibration/experiments/test_ramsey_xy.py +++ b/test/calibration/experiments/test_ramsey_xy.py @@ -31,7 +31,7 @@ def setUp(self): super().setUp() library = FixedFrequencyTransmon() - self.cals = Calibrations.from_backend(FakeArmonk(), library) + self.cals = Calibrations.from_backend(FakeArmonk(), libraries=[library]) def test_end_to_end(self): """Test that we can run on a mock backend and perform a fit. diff --git a/test/calibration/experiments/test_rough_amplitude.py b/test/calibration/experiments/test_rough_amplitude.py index ed8caac160..fb8d635c70 100644 --- a/test/calibration/experiments/test_rough_amplitude.py +++ b/test/calibration/experiments/test_rough_amplitude.py @@ -35,7 +35,7 @@ def setUp(self): library = FixedFrequencyTransmon() self.backend = FakeArmonk() - self.cals = Calibrations.from_backend(self.backend, library) + self.cals = Calibrations.from_backend(self.backend, libraries=[library]) def test_circuits(self): """Test the quantum circuits.""" @@ -86,7 +86,7 @@ def setUp(self): library = FixedFrequencyTransmon() self.backend = FakeArmonk() - self.cals = Calibrations.from_backend(self.backend, library) + self.cals = Calibrations.from_backend(self.backend, libraries=[library]) # Add some pulses on the 1-2 transition. d0 = pulse.DriveChannel(0) diff --git a/test/calibration/experiments/test_rough_frequency.py b/test/calibration/experiments/test_rough_frequency.py index c2263333ba..643bd78667 100644 --- a/test/calibration/experiments/test_rough_frequency.py +++ b/test/calibration/experiments/test_rough_frequency.py @@ -53,7 +53,7 @@ def test_update_calibrations(self): backend.defaults().qubit_freq_est = [freq01, freq01] library = FixedFrequencyTransmon(basis_gates=["x", "sx"]) - cals = Calibrations.from_backend(FakeArmonk(), library=library) + cals = Calibrations.from_backend(FakeArmonk(), libraries=[library]) prev_freq = cals.get_parameter_value(cals.__drive_freq_parameter__, (0,)) self.assertEqual(prev_freq, freq01) From 5505927f02c01cc7922480116d0f183c3f87a91f Mon Sep 17 00:00:00 2001 From: Daniel Egger Date: Fri, 22 Apr 2022 17:55:38 +0200 Subject: [PATCH 5/9] * Updated cal tutorial --- docs/tutorials/calibrating_armonk.ipynb | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/docs/tutorials/calibrating_armonk.ipynb b/docs/tutorials/calibrating_armonk.ipynb index 0bdf760be7..df6799fe2d 100644 --- a/docs/tutorials/calibrating_armonk.ipynb +++ b/docs/tutorials/calibrating_armonk.ipynb @@ -150,7 +150,7 @@ "outputs": [], "source": [ "library = FixedFrequencyTransmon(default_values={\"duration\": 320})\n", - "cals = Calibrations.from_backend(backend, library)" + "cals = Calibrations.from_backend(backend, libraries=[library])" ] }, { @@ -897,19 +897,10 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 1, "id": "317994db", "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/home/daniel/Documents/IBM/qiskit/qiskit-experiments/qiskit_experiments/calibration_management/calibrations.py:1333: UserWarning: Schedules are only saved in text format. They cannot be re-loaded.\n", - " warnings.warn(\"Schedules are only saved in text format. They cannot be re-loaded.\")\n" - ] - } - ], + "outputs": [], "source": [ "cals.save(file_type=\"csv\", overwrite=True, file_prefix=\"Armonk\")" ] From 37cc67581a744522b77ffc6f5c5a430d1281b873 Mon Sep 17 00:00:00 2001 From: Daniel Egger Date: Fri, 22 Apr 2022 17:57:54 +0200 Subject: [PATCH 6/9] * pylint. --- .../calibration_management/calibrations.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/qiskit_experiments/calibration_management/calibrations.py b/qiskit_experiments/calibration_management/calibrations.py index a84f6609a2..bdc9585e8d 100644 --- a/qiskit_experiments/calibration_management/calibrations.py +++ b/qiskit_experiments/calibration_management/calibrations.py @@ -113,15 +113,16 @@ def __init__( backend_version: The version of the backend that these calibrations are attached to. Raises: - NotImplementedError: if a list of libraries is given. This will be implemented in - the future. + CalibrationError: if both library and libraries are given. Note that library will be + removed in future versions. + """ self._backend_name = backend_name self._backend_version = backend_version if library: warnings.warn( - f"library has been deprecated, please provide libraries instead." + "library has been deprecated, please provide libraries instead." "This warning will be removed with backport in Qiskit Experiments 0.4.", DeprecationWarning, stacklevel=2, @@ -291,7 +292,7 @@ def libraries(self) -> Optional[List[BasisGateLibrary]]: def library(self) -> Optional[List[BasisGateLibrary]]: """Return the libraries used to initialize the calibrations.""" warnings.warn( - f"library has been deprecated, use libraries instead." + "library has been deprecated, use libraries instead." "This warning will be removed with backport in Qiskit Experiments 0.4.", DeprecationWarning, stacklevel=2, From fcf6b91a30fbc11971e8b576505b04d2da3e8f9c Mon Sep 17 00:00:00 2001 From: "Daniel J. Egger" <38065505+eggerdj@users.noreply.github.com> Date: Fri, 22 Apr 2022 18:03:31 +0200 Subject: [PATCH 7/9] Update docs/tutorials/calibrating_armonk.ipynb --- docs/tutorials/calibrating_armonk.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/calibrating_armonk.ipynb b/docs/tutorials/calibrating_armonk.ipynb index df6799fe2d..84ca0d99a1 100644 --- a/docs/tutorials/calibrating_armonk.ipynb +++ b/docs/tutorials/calibrating_armonk.ipynb @@ -897,7 +897,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 27, "id": "317994db", "metadata": {}, "outputs": [], From 38b6eddd80ebecbc3fdc280467745ade25992da9 Mon Sep 17 00:00:00 2001 From: "Daniel J. Egger" <38065505+eggerdj@users.noreply.github.com> Date: Mon, 25 Apr 2022 15:44:16 +0200 Subject: [PATCH 8/9] Update qiskit_experiments/calibration_management/calibrations.py Co-authored-by: Will Shanks --- qiskit_experiments/calibration_management/calibrations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit_experiments/calibration_management/calibrations.py b/qiskit_experiments/calibration_management/calibrations.py index bdc9585e8d..e510b02d2a 100644 --- a/qiskit_experiments/calibration_management/calibrations.py +++ b/qiskit_experiments/calibration_management/calibrations.py @@ -123,7 +123,7 @@ def __init__( if library: warnings.warn( "library has been deprecated, please provide libraries instead." - "This warning will be removed with backport in Qiskit Experiments 0.4.", + 'The "library" argument along with this warning will be removed in Qiskit Experiments 0.4.', DeprecationWarning, stacklevel=2, ) From efbcdaa1b3989e6814e469964e6c94376f000c55 Mon Sep 17 00:00:00 2001 From: Daniel Egger Date: Mon, 25 Apr 2022 15:52:01 +0200 Subject: [PATCH 9/9] * Line length. --- qiskit_experiments/calibration_management/calibrations.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/qiskit_experiments/calibration_management/calibrations.py b/qiskit_experiments/calibration_management/calibrations.py index e510b02d2a..6c8ecf6efc 100644 --- a/qiskit_experiments/calibration_management/calibrations.py +++ b/qiskit_experiments/calibration_management/calibrations.py @@ -122,8 +122,9 @@ def __init__( if library: warnings.warn( - "library has been deprecated, please provide libraries instead." - 'The "library" argument along with this warning will be removed in Qiskit Experiments 0.4.', + "library has been deprecated, please provide `libraries` instead." + "The `library` argument along with this warning will be removed " + "in Qiskit Experiments 0.4.", DeprecationWarning, stacklevel=2, )