Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
2e995f7
* Added demo of wrappers.
eggerdj Jul 28, 2021
f28d7a5
Merge branch 'main' of github.com:Qiskit/qiskit-experiments into cal_…
eggerdj Aug 13, 2021
63b22f7
* Added more flexibility to FineAmplitude.
eggerdj Aug 13, 2021
2bdc95b
* Added calibration base class and amended experiments accordingly.
eggerdj Aug 15, 2021
4005884
* Added tests for Drag and Rabi cals updating.
eggerdj Aug 16, 2021
ad5b120
Merge branch 'main' into cal_wrappers
eggerdj Aug 16, 2021
7fdac59
* Rabi test.
eggerdj Aug 16, 2021
7074d78
* Changed name of init arg: calibrations -> cals.
eggerdj Aug 17, 2021
f11129b
Merge branch 'main' into cal_wrappers
eggerdj Aug 17, 2021
8d88b01
* Fix some merge issues.
eggerdj Aug 17, 2021
3e24236
* Removed wrappers tutorial.
eggerdj Aug 17, 2021
4164860
* Small fixes to experiments.
eggerdj Aug 18, 2021
16b847a
* Updated the demo NB.
eggerdj Aug 18, 2021
6a4c454
* Added ABC
eggerdj Aug 18, 2021
5c45d54
* Added calibration options.
eggerdj Aug 18, 2021
afe05e5
* Override run_analysis(...) instead of run(...)
eggerdj Aug 20, 2021
861a3e3
* Reverted to overriding run_experiment.
eggerdj Aug 25, 2021
1e538be
* Improved docstrings.
eggerdj Aug 26, 2021
4f262d8
Update qiskit_experiments/calibration_management/base_calibration_exp…
eggerdj Aug 31, 2021
417346b
Update qiskit_experiments/calibration_management/base_calibration_exp…
eggerdj Aug 31, 2021
c12dbe2
Update qiskit_experiments/calibration_management/base_calibration_exp…
eggerdj Aug 31, 2021
2514aa2
Update qiskit_experiments/calibration_management/base_calibration_exp…
eggerdj Aug 31, 2021
6671ce9
* Developper docstring.
eggerdj Aug 31, 2021
580f70b
* get_schedules_from_defaults docstring.
eggerdj Aug 31, 2021
53337b7
* Refactored the arguments of get_schedule.
eggerdj Sep 1, 2021
9074e2c
* Added a default implementation of the update_calibrations method.
eggerdj Sep 1, 2021
cc5ebc4
* RaiseNotImplementedError on default schedules.
eggerdj Sep 1, 2021
7ffae87
* Protect against missing schedule name in FineAmplitude.
eggerdj Sep 1, 2021
36baa4f
Merge branch 'main' into cal_wrappers
eggerdj Sep 1, 2021
3111b82
* Black and lint.
eggerdj Sep 1, 2021
bb8fc79
* Lint black and RoughFrequency mixin.
eggerdj Sep 1, 2021
df29ba0
* Black
eggerdj Sep 1, 2021
112d5b7
* RoughEFFrequency
eggerdj Sep 1, 2021
bbd9293
* Small change to DragCal anti schedule.
eggerdj Sep 3, 2021
fad77aa
Merge branch 'main' into cal_wrappers
eggerdj Sep 21, 2021
6da58d0
Merge branch 'main' into cal_wrappers
eggerdj Sep 21, 2021
9ed1449
Update qiskit_experiments/calibration_management/base_calibration_exp…
eggerdj Sep 28, 2021
0ddc1e4
Update qiskit_experiments/calibration_management/base_calibration_exp…
eggerdj Sep 28, 2021
073ead5
Update qiskit_experiments/calibration_management/base_calibration_exp…
eggerdj Sep 28, 2021
60b27af
Update qiskit_experiments/calibration_management/base_calibration_exp…
eggerdj Sep 28, 2021
65d78f0
Update qiskit_experiments/calibration_management/base_calibration_exp…
eggerdj Sep 28, 2021
bdd141b
Update qiskit_experiments/calibration_management/base_calibration_exp…
eggerdj Sep 28, 2021
d354708
* Changed Drag.
eggerdj Sep 28, 2021
cbf74ac
Merge branch 'main' into cal_wrappers
eggerdj Sep 28, 2021
7e2ea6c
* Small changes to align test_drag
eggerdj Sep 28, 2021
94ad1c6
* Fixed drag and its tests.
eggerdj Sep 28, 2021
5c2d9c1
* Removed calibration options.
eggerdj Sep 28, 2021
9a70f1b
* Docstrings.
eggerdj Sep 28, 2021
75d2f11
* Docstring.
eggerdj Sep 28, 2021
906c5ab
* Fixed needed variables in RoughFrequency
eggerdj Sep 28, 2021
a5cc975
* Fix to test_update for drag
eggerdj Sep 28, 2021
c41428c
Merge branch 'main' of github.com:Qiskit/qiskit-experiments into cal_…
eggerdj Sep 30, 2021
8762448
* Made cals non-optional in RoughFrequency.
eggerdj Sep 30, 2021
84a37a2
Update qiskit_experiments/calibration_management/base_calibration_exp…
eggerdj Sep 30, 2021
5438738
Update qiskit_experiments/calibration_management/base_calibration_exp…
eggerdj Sep 30, 2021
53dd7e1
* Reset Rabi, Drag, and FineAmp
eggerdj Sep 30, 2021
a9d7994
* Reset test_update_library
eggerdj Sep 30, 2021
f6d21ff
* Black
eggerdj Sep 30, 2021
75d4fd8
* Added auto_update to the cals.
eggerdj Sep 30, 2021
ab45007
* inits and mixin
eggerdj Oct 1, 2021
ea21af7
* Moved RoughFrequency.
eggerdj Oct 1, 2021
c70179a
* Black, docs, NB
eggerdj Oct 1, 2021
4ea0d09
Merge branch 'main' into cal_wrappers
eggerdj Oct 1, 2021
1703448
* Lint
eggerdj Oct 1, 2021
29a3582
Update qiskit_experiments/calibration_management/base_calibration_exp…
eggerdj Oct 4, 2021
555cf55
Update qiskit_experiments/library/calibration/rough_frequency.py
eggerdj Oct 4, 2021
395a89c
Merge branch 'main' into cal_wrappers
eggerdj Oct 4, 2021
5090893
* Type hints.
eggerdj Oct 4, 2021
6cf1d0b
* Init args.
eggerdj Oct 4, 2021
4c06960
* Docstring on convention.
eggerdj Oct 4, 2021
c5894b1
* Lint on tests.
eggerdj Oct 4, 2021
9f19a6e
* MRO warning.
eggerdj Oct 5, 2021
fe9b244
Merge branch 'main' into cal_wrappers
eggerdj Oct 5, 2021
8c7dd74
Update qiskit_experiments/calibration_management/base_calibration_exp…
eggerdj Oct 14, 2021
ae20f7a
* Added calibrations property
eggerdj Oct 14, 2021
e2c3c39
Merge branch 'cal_wrappers' of github.com:eggerdj/qiskit-experiments …
eggerdj Oct 14, 2021
34518e2
* changed __updater__ -> _updater
eggerdj Oct 14, 2021
8232baa
Merge branch 'main' into cal_wrappers
eggerdj Oct 14, 2021
1f71b96
* black
eggerdj Oct 14, 2021
88652ab
* add_analysis_callback
eggerdj Oct 14, 2021
aa6c973
* Added block for results in the test.
eggerdj Oct 14, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

8 changes: 7 additions & 1 deletion qiskit_experiments/calibration_management/update_library.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ def update(
calibrations: BackendCalibrations,
exp_data: ExperimentData,
result_index: Optional[int] = None,
parameter: str = None,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Now that updater classes are more important it would be good to improve the API documentation of the BaseUpdater class (either in that class doc string, or the cal management module docstring) to explain to developers how to subclass a calibration updater class for their experiments. This can be done as followup PR

group: str = "default",
fit_parameter: Optional[str] = None,
**options,
Expand All @@ -161,16 +162,21 @@ def update(
calibrations: The calibrations to update.
exp_data: The experiment data from which to update.
result_index: The result index to use which defaults to -1.
parameter: The name of the parameter to update. If None is given this will default
to :code:`calibrations.__qubit_freq_parameter__`.
group: The calibrations group to update. Defaults to "default."
options: Trailing options.
fit_parameter: The name of the fit parameter in the analysis result. This will default
to the class variable :code:`__fit_parameter__` if not given.

"""
if parameter is None:
parameter = calibrations.__qubit_freq_parameter__

super().update(
calibrations=calibrations,
exp_data=exp_data,
parameter=calibrations.__qubit_freq_parameter__,
parameter=parameter,
schedule=None,
result_index=result_index,
group=group,
Expand Down
2 changes: 2 additions & 0 deletions qiskit_experiments/library/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ class instance to manage parameters and pulse schedules.
:toctree: ../stubs/
:template: autosummary/experiment.rst

~calibration.RoughFrequencyCal
~calibration.DragCal
~calibration.FineDrag
~calibration.FineXDrag
Expand All @@ -100,6 +101,7 @@ class instance to manage parameters and pulse schedules.
FineAmplitude,
FineXAmplitude,
FineSXAmplitude,
RoughFrequencyCal,
RamseyXY,
)
from .characterization import (
Expand Down
2 changes: 2 additions & 0 deletions qiskit_experiments/library/calibration/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
:toctree: ../stubs/
:template: autosummary/experiment.rst

RoughFrequencyCal
DragCal
FineDrag
FineXDrag
Expand Down Expand Up @@ -66,6 +67,7 @@
See :mod:`qiskit_experiments.calibration_management`.
"""

from .rough_frequency import RoughFrequencyCal
from .drag import DragCal
from .fine_drag import FineDrag, FineXDrag, FineSXDrag
from .rabi import Rabi, EFRabi
Expand Down
109 changes: 109 additions & 0 deletions qiskit_experiments/library/calibration/rough_frequency.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# 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.

"""Calibration version of spectroscopy experiments."""

from typing import Iterable

from qiskit_experiments.library.characterization.qubit_spectroscopy import QubitSpectroscopy
from qiskit_experiments.library.characterization.ef_spectroscopy import EFSpectroscopy
from qiskit_experiments.calibration_management.update_library import Frequency
from qiskit_experiments.calibration_management.backend_calibrations import BackendCalibrations
from qiskit_experiments.calibration_management.base_calibration_experiment import (
BaseCalibrationExperiment,
)


class RoughFrequencyCal(BaseCalibrationExperiment, QubitSpectroscopy):
"""A calibration experiment that runs QubitSpectroscopy."""

def __init__(
self,
qubit: int,
calibrations: BackendCalibrations,
frequencies: Iterable[float],
unit: str = "Hz",
auto_update: bool = True,
absolute: bool = True,
):
"""See :class:`QubitSpectroscopy` for detailed documentation.

Args:
qubit: The qubit on which to run spectroscopy.
calibrations: If calibrations is given then running the experiment may update the values
of the frequencies stored in calibrations.
frequencies: The frequencies to scan in the experiment.
unit: The unit in which the user specifies the frequencies. Can be one of 'Hz', 'kHz',
'MHz', 'GHz'. Internally, all frequencies will be converted to 'Hz'.
auto_update: If set to True, which is the default, then the experiment will
automatically update the frequency in the calibrations.
absolute: Boolean to specify if the frequencies are absolute or relative to the
qubit frequency in the backend.

Raises:
QiskitError: if there are less than three frequency shifts or if the unit is not known.

"""
super().__init__(
calibrations,
qubit,
frequencies,
unit,
absolute,
updater=Frequency,
auto_update=auto_update,
)


class RoughEFFrequencyCal(BaseCalibrationExperiment, EFSpectroscopy):
"""A calibration experiment that runs QubitSpectroscopy."""

__updater__ = Frequency

# pylint: disable=super-init-not-called
def __init__(
self,
qubit: int,
calibrations: BackendCalibrations,
frequencies: Iterable[float],
unit: str = "Hz",
auto_update: bool = True,
absolute: bool = True,
):
"""See :class:`QubitSpectroscopy` for detailed documentation.

Args:
qubit: The qubit on which to run spectroscopy.
calibrations: If calibrations is given then running the experiment may update the values
of the frequencies stored in calibrations.
frequencies: The frequencies to scan in the experiment.
unit: The unit in which the user specifies the frequencies. Can be one of 'Hz', 'kHz',
'MHz', 'GHz'. Internally, all frequencies will be converted to 'Hz'.
auto_update: If set to True, which is the default, then the experiment will
automatically update the frequency in the calibrations.
absolute: Boolean to specify if the frequencies are absolute or relative to the
qubit frequency in the backend.

Raises:
QiskitError: if there are less than three frequency shifts or if the unit is not known.

"""
super().__init__(
calibrations,
qubit,
frequencies,
unit,
absolute,
cal_parameter_name="f12",
updater=Frequency,
auto_update=auto_update,
)
26 changes: 17 additions & 9 deletions qiskit_experiments/library/characterization/qubit_spectroscopy.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

"""Spectroscopy experiment class."""

from typing import List, Optional, Tuple, Union
from typing import Iterable, Optional, Tuple

import numpy as np
import qiskit.pulse as pulse
Expand Down Expand Up @@ -60,7 +60,16 @@ def _default_run_options(cls) -> Options:

@classmethod
def _default_experiment_options(cls) -> Options:
"""Default option values used for the spectroscopy pulse."""
"""Default option values used for the spectroscopy pulse.

Experiment Options:
amp (float): The amplitude of the spectroscopy pulse. Defaults to 0.1.
duration (int): The duration of the spectroscopy pulse. Defaults to 1024 samples.
sigma (float): The standard deviation of the flanks of the spectroscopy pulse.
Defaults to 256.
width (int): The width of the flat-top part of the GaussianSquare pulse.
Defaults to 0.
"""
options = super()._default_experiment_options()

options.amp = 0.1
Expand All @@ -85,8 +94,8 @@ def _default_analysis_options(cls) -> Options:
def __init__(
self,
qubit: int,
frequencies: Union[List[float], np.array],
unit: Optional[str] = "Hz",
frequencies: Iterable[float],
unit: str = "Hz",
absolute: bool = True,
):
"""
Expand All @@ -101,16 +110,17 @@ def __init__(
Args:
qubit: The qubit on which to run spectroscopy.
frequencies: The frequencies to scan in the experiment.
unit: The unit in which the user specifies the frequencies. Can be one
of 'Hz', 'kHz', 'MHz', 'GHz'. Internally, all frequencies will be converted
to 'Hz'.
unit: The unit in which the user specifies the frequencies. Can be one of 'Hz', 'kHz',
'MHz', 'GHz'. Internally, all frequencies will be converted to 'Hz'.
absolute: Boolean to specify if the frequencies are absolute or relative to the
qubit frequency in the backend.

Raises:
QiskitError: if there are less than three frequency shifts or if the unit is not known.

"""
super().__init__([qubit])

if len(frequencies) < 3:
raise QiskitError("Spectroscopy requires at least three frequencies.")

Expand All @@ -119,8 +129,6 @@ def __init__(
else:
self._frequencies = [apply_prefix(freq, unit) for freq in frequencies]

super().__init__([qubit])

self._absolute = absolute

if not self._absolute:
Expand Down
67 changes: 67 additions & 0 deletions test/calibration/experiments/test_rough_frequency.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# 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.

"""Rough frequency calibration tests."""

from test.test_qubit_spectroscopy import SpectroscopyBackend

import numpy as np

from qiskit.test import QiskitTestCase
from qiskit.test.mock import FakeArmonk

from qiskit_experiments.library import RoughFrequencyCal
from qiskit_experiments.calibration_management import BackendCalibrations
from qiskit_experiments.calibration_management.basis_gate_library import FixedFrequencyTransmon


class TestRoughFrequency(QiskitTestCase):
"""Tests for the rough frequency calibration experiment."""

def test_init(self):
"""Test that initialization."""

qubit = 1
cals = BackendCalibrations(FakeArmonk())
frequencies = [1, 2, 3]
unit = "kHz"
auto_update = False
absolute = False

freq = RoughFrequencyCal(qubit, cals, frequencies, unit, auto_update, absolute)

self.assertEqual(freq.physical_qubits, (qubit,))
self.assertEqual(freq._frequencies, [1000, 2000, 3000])
self.assertEqual(freq._absolute, False)
self.assertEqual(freq.auto_update, False)

def test_update_calibrations(self):
"""Test that we can properly update an instance of BackendCalibrations."""

freq01 = FakeArmonk().defaults().qubit_freq_est[0]

backend = SpectroscopyBackend(freq_offset=5e6, line_width=2e6)
backend.defaults().qubit_freq_est = [freq01, freq01]

library = FixedFrequencyTransmon(basis_gates=["x", "sx"])
cals = BackendCalibrations(FakeArmonk(), library=library)

prev_freq = cals.get_parameter_value(cals.__qubit_freq_parameter__, (0,))
self.assertEqual(prev_freq, freq01)

frequencies = np.linspace(freq01 - 10.0e6, freq01 + 10.0e6, 21)

RoughFrequencyCal(0, cals, frequencies).run(backend).block_for_results()

# Check the updated frequency which should be shifted by 5MHz.
post_freq = cals.get_parameter_value(cals.__qubit_freq_parameter__, (0,))
self.assertTrue(abs(post_freq - freq01 - 5e6) < 1e6)
47 changes: 47 additions & 0 deletions test/calibration/test_base_calibration_experiment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# 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.

"""Tests for the base class for calibration-type experiments."""

from qiskit.test import QiskitTestCase

from qiskit_experiments.library import QubitSpectroscopy
from qiskit_experiments.calibration_management.calibrations import Calibrations
from qiskit_experiments.calibration_management.base_calibration_experiment import (
BaseCalibrationExperiment,
)


class TestBaseCalibrationClass(QiskitTestCase):
"""Tests for base calibration experiment classes."""

def test_class_order(self):
"""Test warnings when the BaseCalibrationExperiment is not the first parent."""

class CorrectOrder(BaseCalibrationExperiment, QubitSpectroscopy):
"""A class with the correct order should not produce warnings.."""

def __init__(self):
"""A dummy class for parent order testing."""
super().__init__(Calibrations(), 0, [0, 1, 2])

CorrectOrder()

with self.assertWarns(Warning):

# pylint: disable=unused-variable
class WrongOrder(QubitSpectroscopy, BaseCalibrationExperiment):
"""Merely defining this class is enough to raise the warning."""

def __init__(self):
"""A dummy class for parent order testing."""
super().__init__(Calibrations(), 0, [0, 1, 2])