Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Base calibrations #1200

Open
wants to merge 31 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
e2992f0
* Added the restless mix-in to the init for documentation.
eggerdj Apr 29, 2022
1716aee
Merge branch 'main' of github.com:Qiskit/qiskit-experiments
eggerdj May 4, 2022
f406c30
Merge branch 'main' of github.com:Qiskit/qiskit-experiments
eggerdj May 13, 2022
cba70ea
Merge branch 'main' of github.com:Qiskit/qiskit-experiments
eggerdj Jun 8, 2022
c944772
Merge branch 'main' of github.com:Qiskit/qiskit-experiments
eggerdj Jul 7, 2022
2fa0251
Merge branch 'main' of github.com:Qiskit/qiskit-experiments
eggerdj Jul 8, 2022
f94be94
Merge branch 'main' of github.com:Qiskit/qiskit-experiments
eggerdj Aug 15, 2022
9fdb84f
Merge branch 'main' of github.com:Qiskit/qiskit-experiments
eggerdj Oct 6, 2022
187bb33
Merge branch 'main' of github.com:Qiskit/qiskit-experiments
eggerdj Oct 10, 2022
5593342
Merge branch 'main' of github.com:Qiskit/qiskit-experiments
eggerdj Oct 12, 2022
c6106db
Merge branch 'main' of github.com:Qiskit/qiskit-experiments
eggerdj Oct 14, 2022
4b39095
Merge branch 'main' of github.com:Qiskit/qiskit-experiments
eggerdj Oct 25, 2022
93f1180
Merge branch 'main' of github.com:Qiskit/qiskit-experiments
eggerdj Oct 26, 2022
ca0f59e
Merge branch 'Qiskit:main' into main
eggerdj Nov 1, 2022
5afc28f
Merge branch 'main' of github.com:eggerdj/qiskit-experiments
eggerdj Nov 1, 2022
7716463
Merge branch 'main' of github.com:Qiskit/qiskit-experiments
eggerdj Nov 2, 2022
b2e9db2
Merge branch 'main' of github.com:Qiskit/qiskit-experiments
eggerdj Nov 22, 2022
7d44612
Merge branch 'main' of github.com:Qiskit/qiskit-experiments
eggerdj Dec 14, 2022
9000df0
Merge branch 'main' of github.com:Qiskit/qiskit-experiments
eggerdj Dec 14, 2022
9262f96
Merge branch 'main' of github.com:Qiskit/qiskit-experiments
eggerdj Jan 10, 2023
d385010
Merge branch 'Qiskit:main' into main
eggerdj May 13, 2023
f450b6f
* Added BaseCalibrations and made Calibrations inherite form it.
eggerdj Jun 12, 2023
c1aa9a4
Merge branch 'main' of github.com:Qiskit-Extensions/qiskit-experiment…
eggerdj Jun 12, 2023
b3e666f
* Align test import
eggerdj Jun 12, 2023
b363c82
* Add new line at EOF
eggerdj Jun 12, 2023
908fe6c
* Fix lint
eggerdj Jun 12, 2023
8a72fba
Update releasenotes/notes/base_calibrations-220741e03e5c7279.yaml
eggerdj Jun 12, 2023
4fb24bb
* Docs.
eggerdj Jun 12, 2023
72dec29
Merge branch 'main' of github.com:Qiskit-Extensions/qiskit-experiment…
eggerdj Jun 21, 2023
6f21049
* Removed reserved vars and simplified base class methods.
eggerdj Jun 21, 2023
d8382d6
* Lint
eggerdj Jun 21, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
SetLayout,
)

from qiskit_experiments.calibration_management.calibrations import Calibrations
from qiskit_experiments.calibration_management.base_calibrations import BaseCalibrations
from qiskit_experiments.calibration_management.update_library import BaseUpdater
from qiskit_experiments.framework.base_analysis import BaseAnalysis
from qiskit_experiments.framework.base_experiment import BaseExperiment
Expand Down Expand Up @@ -112,7 +112,7 @@ def __init_subclass__(cls, **kwargs):
# pylint: disable=super-init-not-called
def __init__(
self,
calibrations: Calibrations,
calibrations: BaseCalibrations,
*args,
schedule_name: Optional[str] = None,
cal_parameter_name: Optional[str] = None,
Expand Down Expand Up @@ -144,7 +144,7 @@ def __init__(
self.auto_update = auto_update

@property
def calibrations(self) -> Calibrations:
def calibrations(self) -> BaseCalibrations:
"""Return the calibrations."""
return self._cals

Expand Down
114 changes: 114 additions & 0 deletions qiskit_experiments/calibration_management/base_calibrations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2023.
#
# 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.

"""Base calibrations class."""

from abc import ABC, abstractmethod
from typing import Dict, Tuple, Union

from qiskit.circuit import Parameter
from qiskit.pulse import ScheduleBlock

from qiskit_experiments.calibration_management.parameter_value import ParameterValue
from qiskit_experiments.calibration_management.calibration_key_types import (
ParameterKey,
ParameterValueType,
)


class BaseCalibrations(ABC):
"""An abstract base calibration class that defines the methods needed by cal. experiments.

A calibration experiment uses an instance of `BaseCalibrations` that defines where
to get parameter values from and where to save them. This class also defines a method from
which to retrieve pulse-schedules.
"""

@abstractmethod
def add_parameter_value(
self,
value: Union[int, float, complex, ParameterValue],
param: Union[Parameter, str],
qubits: Union[int, Tuple[int, ...]] = None,
schedule: Union[ScheduleBlock, str] = None,
):
"""Add a parameter value to the stored parameters.

This parameter value may be applied to several channels, for instance, all
DRAG pulses may have the same standard deviation.

Args:
value: The value of the parameter to add. If an int, float, or complex is given
then the timestamp of the parameter value will automatically be generated
and set to the current local time of the user.
param: The parameter or its name for which to add the measured value.
qubits: The qubits to which this parameter applies.
schedule: The schedule or its name for which to add the measured parameter value.
"""

@abstractmethod
def get_parameter_value(
self,
param: Union[Parameter, str],
qubits: Union[int, Tuple[int, ...]],
schedule: Union[ScheduleBlock, str, None] = None,
) -> Union[int, float, complex]:
"""Retrieves the value of a parameter.

Parameters may be linked. :meth:`get_parameter_value` does the following steps:
Copy link
Contributor

Choose a reason for hiding this comment

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

Note that this sentence is not finished. Also, what do you mean with "Parameters may be linked"? There's only one parameter here,

Copy link
Collaborator

Choose a reason for hiding this comment

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

This indicates parameter update can affect other schedules since it's linked.


Args:
param: The parameter or the name of the parameter for which to get the parameter value.
qubits: The qubits for which to get the value of the parameter.
schedule: The schedule or its name for which to get the parameter value.

Returns:
value: The value of the parameter.
"""

@abstractmethod
def get_schedule(
self,
name: str,
qubits: Union[int, Tuple[int, ...]],
assign_params: Dict[Union[str, ParameterKey], ParameterValueType] = None,
) -> ScheduleBlock:
"""Get the template schedule with parameters assigned to values.

All the parameters in the template schedule block will be assigned to the values managed
by the calibrations unless they are specified in assign_params. In this case the value in
assign_params will override the value stored by the calibrations. A parameter value in
assign_params may also be a :class:`ParameterExpression`.

.. code-block:: python

# Get an xp schedule with a parametric amplitude
sched = cals.get_schedule("xp", 3, assign_params={"amp": Parameter("amp")})

# Get an echoed-cross-resonance schedule between qubits (0, 2) where the xp echo gates
# are referenced schedules but leave their amplitudes as parameters.
assign_dict = {("amp", (0,), "xp"): Parameter("my_amp")}
sched = cals.get_schedule("cr", (0, 2), assign_params=assign_dict)

Args:
name: The name of the schedule to get.
qubits: The qubits for which to get the schedule.
assign_params: The parameters to assign manually. Each parameter is specified by a
ParameterKey which is a named tuple of the form (parameter name, qubits,
schedule name). Each entry in assign_params can also be a string corresponding
to the name of the parameter. In this case, the schedule name and qubits of the
corresponding ParameterKey will be the name and qubits given as arguments to
get_schedule.

Returns:
schedule: A copy of the template schedule with all parameters assigned.
"""
3 changes: 2 additions & 1 deletion qiskit_experiments/calibration_management/calibrations.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
from qiskit.utils.deprecation import deprecate_func, deprecate_arg

from qiskit_experiments.exceptions import CalibrationError
from qiskit_experiments.calibration_management.base_calibrations import BaseCalibrations
from qiskit_experiments.calibration_management.basis_gate_library import BasisGateLibrary
from qiskit_experiments.calibration_management.parameter_value import ParameterValue
from qiskit_experiments.calibration_management.control_channel_map import ControlChannelMap
Expand All @@ -55,7 +56,7 @@
from qiskit_experiments.framework import BackendData, ExperimentEncoder, ExperimentDecoder


class Calibrations:
class Calibrations(BaseCalibrations):
"""
A class to manage schedules with calibrated parameter values. Schedules are
intended to be fully parameterized, including the index of the channels. See
Expand Down
8 changes: 4 additions & 4 deletions qiskit_experiments/calibration_management/update_library.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from qiskit.pulse import ScheduleBlock

from qiskit_experiments.framework.experiment_data import ExperimentData
from qiskit_experiments.calibration_management.calibrations import Calibrations
from qiskit_experiments.calibration_management.base_calibrations import BaseCalibrations
from qiskit_experiments.calibration_management.parameter_value import ParameterValue
from qiskit_experiments.calibration_management.calibration_key_types import ParameterValueType
from qiskit_experiments.exceptions import CalibrationError
Expand Down Expand Up @@ -60,7 +60,7 @@ def _time_stamp(exp_data: ExperimentData) -> datetime:
@classmethod
def add_parameter_value(
cls,
cal: Calibrations,
cal: BaseCalibrations,
exp_data: ExperimentData,
value: ParameterValueType,
param: Union[Parameter, str],
Expand Down Expand Up @@ -94,7 +94,7 @@ def add_parameter_value(
@classmethod
def update(
cls,
calibrations: Calibrations,
calibrations: BaseCalibrations,
exp_data: ExperimentData,
parameter: str,
schedule: Optional[Union[ScheduleBlock, str]],
Expand Down Expand Up @@ -146,7 +146,7 @@ class Frequency(BaseUpdater):
@classmethod
def update(
cls,
calibrations: Calibrations,
calibrations: BaseCalibrations,
exp_data: ExperimentData,
result_index: Optional[int] = None,
parameter: str = "drive_freq",
Expand Down
12 changes: 5 additions & 7 deletions qiskit_experiments/library/calibration/fine_amplitude.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,8 @@
from qiskit.circuit import Gate, QuantumCircuit
from qiskit.providers.backend import Backend

from qiskit_experiments.calibration_management import (
BaseCalibrationExperiment,
Calibrations,
)
from qiskit_experiments.calibration_management import BaseCalibrationExperiment
from qiskit_experiments.calibration_management.base_calibrations import BaseCalibrations
from qiskit_experiments.library.characterization import FineAmplitude
from qiskit_experiments.framework import ExperimentData, Options
from qiskit_experiments.calibration_management.update_library import BaseUpdater
Expand All @@ -41,7 +39,7 @@ class FineAmplitudeCal(BaseCalibrationExperiment, FineAmplitude):
def __init__(
self,
physical_qubits: Sequence[int],
calibrations: Calibrations,
calibrations: BaseCalibrations,
schedule_name: str,
backend: Optional[Backend] = None,
cal_parameter_name: Optional[str] = "amp",
Expand Down Expand Up @@ -161,7 +159,7 @@ class FineXAmplitudeCal(FineAmplitudeCal):
def __init__(
self,
physical_qubits: Sequence[int],
calibrations: Calibrations,
calibrations: BaseCalibrations,
schedule_name: str,
backend: Optional[Backend] = None,
cal_parameter_name: Optional[str] = "amp",
Expand Down Expand Up @@ -209,7 +207,7 @@ class FineSXAmplitudeCal(FineAmplitudeCal):
def __init__(
self,
physical_qubits: Sequence[int],
calibrations: Calibrations,
calibrations: BaseCalibrations,
schedule_name: str,
backend: Optional[Backend] = None,
cal_parameter_name: Optional[str] = "amp",
Expand Down
12 changes: 5 additions & 7 deletions qiskit_experiments/library/calibration/fine_drag_cal.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,8 @@

from qiskit_experiments.exceptions import CalibrationError
from qiskit_experiments.framework import ExperimentData, Options
from qiskit_experiments.calibration_management import (
BaseCalibrationExperiment,
Calibrations,
)
from qiskit_experiments.calibration_management import BaseCalibrationExperiment
from qiskit_experiments.calibration_management.base_calibrations import BaseCalibrations
from qiskit_experiments.calibration_management.update_library import BaseUpdater
from qiskit_experiments.library.characterization.fine_drag import FineDrag

Expand All @@ -35,7 +33,7 @@ class FineDragCal(BaseCalibrationExperiment, FineDrag):
def __init__(
self,
physical_qubits: Sequence[int],
calibrations: Calibrations,
calibrations: BaseCalibrations,
schedule_name: str,
backend: Optional[Backend] = None,
cal_parameter_name: Optional[str] = "β",
Expand Down Expand Up @@ -153,7 +151,7 @@ class FineXDragCal(FineDragCal):
def __init__(
self,
physical_qubits: Sequence[int],
calibrations: Calibrations,
calibrations: BaseCalibrations,
backend: Optional[Backend] = None,
cal_parameter_name: Optional[str] = "β",
auto_update: bool = True,
Expand Down Expand Up @@ -185,7 +183,7 @@ class FineSXDragCal(FineDragCal):
def __init__(
self,
physical_qubits: Sequence[int],
calibrations: Calibrations,
calibrations: BaseCalibrations,
backend: Optional[Backend] = None,
cal_parameter_name: Optional[str] = "β",
auto_update: bool = True,
Expand Down
8 changes: 3 additions & 5 deletions qiskit_experiments/library/calibration/fine_frequency_cal.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,8 @@

from qiskit_experiments.framework import ExperimentData
from qiskit_experiments.calibration_management.update_library import BaseUpdater
from qiskit_experiments.calibration_management import (
BaseCalibrationExperiment,
Calibrations,
)
from qiskit_experiments.calibration_management import BaseCalibrationExperiment
from qiskit_experiments.calibration_management.base_calibrations import BaseCalibrations
from qiskit_experiments.library.characterization.fine_frequency import FineFrequency


Expand All @@ -33,7 +31,7 @@ class FineFrequencyCal(BaseCalibrationExperiment, FineFrequency):
def __init__(
self,
physical_qubits: Sequence[int],
calibrations: Calibrations,
calibrations: BaseCalibrations,
backend: Optional[Backend] = None,
cal_parameter_name: Optional[str] = "drive_freq",
delay_duration: Optional[int] = None,
Expand Down
4 changes: 2 additions & 2 deletions qiskit_experiments/library/calibration/frequency_cal.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

from qiskit_experiments.framework import ExperimentData
from qiskit_experiments.library.characterization.ramsey_xy import RamseyXY
from qiskit_experiments.calibration_management.calibrations import Calibrations
from qiskit_experiments.calibration_management.base_calibrations import BaseCalibrations
from qiskit_experiments.calibration_management.update_library import BaseUpdater
from qiskit_experiments.calibration_management.base_calibration_experiment import (
BaseCalibrationExperiment,
Expand All @@ -32,7 +32,7 @@ class FrequencyCal(BaseCalibrationExperiment, RamseyXY):
def __init__(
self,
physical_qubits: Sequence[int],
calibrations: Calibrations,
calibrations: BaseCalibrations,
backend: Optional[Backend] = None,
cal_parameter_name: Optional[str] = "drive_freq",
delays: Optional[List] = None,
Expand Down
10 changes: 4 additions & 6 deletions qiskit_experiments/library/calibration/half_angle_cal.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,8 @@

from qiskit_experiments.framework import ExperimentData
from qiskit_experiments.exceptions import CalibrationError
from qiskit_experiments.calibration_management import (
BaseCalibrationExperiment,
Calibrations,
)
from qiskit_experiments.calibration_management import BaseCalibrationExperiment
from qiskit_experiments.calibration_management.base_calibrations import BaseCalibrations
from qiskit_experiments.library.characterization import HalfAngle
from qiskit_experiments.calibration_management.update_library import BaseUpdater

Expand All @@ -33,7 +31,7 @@ class HalfAngleCal(BaseCalibrationExperiment, HalfAngle):
def __init__(
self,
physical_qubits: Sequence[int],
calibrations: Calibrations,
calibrations: BaseCalibrations,
backend: Optional[Backend] = None,
schedule_name: str = "sx",
cal_parameter_name: Optional[str] = "angle",
Expand Down Expand Up @@ -98,7 +96,7 @@ def __init__(
)

def _metadata(self) -> Dict[str, any]:
"""Add metadata to the experiment data making it more self contained.
"""Add metadata to the experiment data making it more self-contained.

The following keys are added to the experiment's metadata:
cal_param_value: The value of the pulse amplitude. This value together with
Expand Down
14 changes: 9 additions & 5 deletions qiskit_experiments/library/calibration/rough_amplitude_cal.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
from qiskit.providers.backend import Backend

from qiskit_experiments.framework import ExperimentData
from qiskit_experiments.calibration_management import BaseCalibrationExperiment, Calibrations
from qiskit_experiments.calibration_management import BaseCalibrationExperiment
from qiskit_experiments.calibration_management.base_calibrations import BaseCalibrations
from qiskit_experiments.exceptions import CalibrationError
from qiskit_experiments.library.characterization import Rabi
from qiskit_experiments.calibration_management.update_library import BaseUpdater

Expand All @@ -36,7 +38,7 @@ class RoughAmplitudeCal(BaseCalibrationExperiment, Rabi):
def __init__(
self,
physical_qubits: Sequence[int],
calibrations: Calibrations,
calibrations: BaseCalibrations,
schedule_name: str = "x",
amplitudes: Iterable[float] = None,
cal_parameter_name: Optional[str] = "amp",
Expand Down Expand Up @@ -194,7 +196,7 @@ class RoughXSXAmplitudeCal(RoughAmplitudeCal):
def __init__(
self,
physical_qubits: Sequence[int],
calibrations: Calibrations,
calibrations: BaseCalibrations,
amplitudes: Iterable[float] = None,
backend: Optional[Backend] = None,
):
Expand Down Expand Up @@ -227,7 +229,7 @@ class EFRoughXSXAmplitudeCal(RoughAmplitudeCal):
def __init__(
self,
physical_qubits: Sequence[int],
calibrations: Calibrations,
calibrations: BaseCalibrations,
amplitudes: Iterable[float] = None,
backend: Optional[Backend] = None,
ef_pulse_label: str = "12",
Expand Down Expand Up @@ -281,6 +283,8 @@ def _attach_calibrations(self, circuit: QuantumCircuit):
# Attach the x calibration as well if it is in self._cals. We allow for
# it not to be present in case a user wants to rely on the default x
# calibration and only calibrate the pulses between levels 1 and 2.
if self._cals.has_template("x", self.physical_qubits):
try:
schedule = self._cals.get_schedule("x", self.physical_qubits)
circuit.add_calibration("x", self.physical_qubits, schedule)
except CalibrationError:
pass
Loading