Skip to content
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
117fdb1
* First draft of new resonator spec.
eggerdj Dec 17, 2021
b6821f5
* Resonator spectroscopy.
eggerdj Jan 11, 2022
4b00b55
* Added IQ plotting.
eggerdj Jan 11, 2022
f568738
* Adding methodology to handle the Classical bit.
eggerdj Jan 13, 2022
660766a
* Switched to a parallelizable methodology for the classical bit.
eggerdj Jan 13, 2022
c36d329
* Data processing for the resonator spectroscopy experiment.
eggerdj Jan 14, 2022
6786c83
Merge branch 'main' into resonator_spec
eggerdj Jan 14, 2022
3db95ee
* Added a test for the ToAbs node.
eggerdj Jan 14, 2022
e1de77f
* Black and tests for resonator spectroscopy.
eggerdj Jan 17, 2022
a807b10
* Reno and lint.
eggerdj Jan 17, 2022
d3674a1
* Docs.
eggerdj Jan 17, 2022
7f920fd
* Change the sqrt in ToAbs node to the unp version.
eggerdj Jan 19, 2022
7331ae0
* Refactored processor library.
eggerdj Jan 20, 2022
2c1c124
* processor_library docstring.
eggerdj Jan 20, 2022
fb3eaf1
* Add ResSpecAnalysis to tree.
eggerdj Jan 20, 2022
a0072d8
Update qiskit_experiments/library/characterization/resonator_spectros…
eggerdj Jan 20, 2022
2355825
* Simplified resonator spectroscopy doc.
eggerdj Jan 20, 2022
c42dcf8
Merge branch 'resonator_spec' of github.com:eggerdj/qiskit-experiment…
eggerdj Jan 20, 2022
5515f2d
* Added key word arguments to init for one liner execution.
eggerdj Jan 20, 2022
5a07e94
* Release note text.
eggerdj Jan 20, 2022
bde77fb
* Create the Spectroscopy base class for spectroscopy experiments.
eggerdj Jan 20, 2022
a2bc3da
* made center_frequency private.
eggerdj Jan 20, 2022
8bdce88
* Center frequency refactor.
eggerdj Jan 20, 2022
e9f7ae4
* circuit metadata refactor.
eggerdj Jan 20, 2022
dfe3149
* Added acquire delay and set default amplitude to 1 for resonator spec.
eggerdj Jan 21, 2022
b5bce85
* Reonator spectroscopy test Lorentzian resonance.
eggerdj Jan 21, 2022
6d487cc
* IQ plot robustness.
eggerdj Jan 21, 2022
c438b15
Merge branch 'main' into resonator_spec
eggerdj Jan 24, 2022
be7b264
Merge branch 'main' of github.com:Qiskit/qiskit-experiments into reso…
eggerdj Jan 24, 2022
26dfd60
Merge branch 'resonator_spec' of github.com:eggerdj/qiskit-experiment…
eggerdj Jan 24, 2022
0ef184b
* Refactored ResonatorSpectroscopyAnalysis
eggerdj Jan 24, 2022
bab4a73
* Test fix.
eggerdj Jan 24, 2022
13d5bb2
* Units, corresponding test fix, and black.
eggerdj Jan 24, 2022
cd436f8
* Lint and default frequencies.
eggerdj Jan 24, 2022
58f9535
* Fix factor omission.
eggerdj Jan 24, 2022
256c3f6
* Align tests.
eggerdj Jan 24, 2022
86001af
* Simplified resonator spec options.
eggerdj Jan 25, 2022
67865cd
* Reno.
eggerdj Jan 25, 2022
7c44dd1
* More robust IQ plotting.
eggerdj Jan 25, 2022
b8b99d6
* Y-axis label.
eggerdj Jan 25, 2022
26848e3
* Resonator spec doc string.
eggerdj Jan 25, 2022
373dfd3
* Resonator spec doc.
eggerdj Jan 25, 2022
7d7fa8e
* Docstring.
eggerdj Jan 25, 2022
a357bf0
* Metadata always has absolute frequencies.
eggerdj Jan 25, 2022
62ce701
* Moved projector type.
eggerdj Jan 25, 2022
7524359
* Refactor resonance analysis to use a Lorentzian and renamed the exi…
eggerdj Jan 25, 2022
8796b32
* Lorentz normalization, small bug fixes, black.
eggerdj Jan 25, 2022
723202c
* Test normalozation.
eggerdj Jan 25, 2022
dac1681
* Reno.
eggerdj Jan 25, 2022
4461880
Merge branch 'main' into resonator_spec
eggerdj Jan 25, 2022
ead7c55
* Removed center_frequency.
eggerdj Jan 25, 2022
a994631
* black.
eggerdj Jan 25, 2022
e7ccdf0
* Qubit spec test align.
eggerdj Jan 25, 2022
9dbe059
* Device components.
eggerdj Jan 26, 2022
3e258cb
* Resonator kappa in result.
eggerdj Jan 26, 2022
fd97988
Update qiskit_experiments/library/characterization/analysis/resonator…
eggerdj Jan 26, 2022
5d9f0b4
* Resonator spectroscopy kappa and fit function.
eggerdj Jan 26, 2022
4b7715d
* Adapted tests.
eggerdj Jan 27, 2022
73eaa4e
* Update default options.
eggerdj Jan 27, 2022
d38558e
Merge branch 'main' into resonator_spec
eggerdj Jan 27, 2022
8eb9d20
* Moved qubit spectroscopy to units of seconds.
eggerdj Jan 27, 2022
c09f9bf
Merge branch 'resonator_spec' of github.com:eggerdj/qiskit-experiment…
eggerdj Jan 27, 2022
9a6417f
* set backend
eggerdj Jan 27, 2022
6e7c915
Merge branch 'main' into resonator_spec
eggerdj Jan 27, 2022
a999744
* Lint
eggerdj Jan 27, 2022
40dd598
Merge branch 'resonator_spec' of github.com:eggerdj/qiskit-experiment…
eggerdj Jan 27, 2022
fac4995
* Square root lorentzian.
eggerdj Jan 28, 2022
9358a2b
* Remove acquire delay and duration.
eggerdj Jan 28, 2022
da67d69
* Doc fix.
eggerdj Jan 28, 2022
35e5af4
Update qiskit_experiments/library/characterization/analysis/resonator…
eggerdj Jan 28, 2022
45f6dac
Update test/test_resonator_spectroscopy.py
eggerdj Feb 2, 2022
c947b2a
Merge branch 'main' into resonator_spec
eggerdj Feb 2, 2022
83a1b3e
* Docs
eggerdj Feb 3, 2022
9990736
* Reno
eggerdj Feb 3, 2022
77e8fb4
* Added more tests values.
eggerdj Feb 3, 2022
322ed86
* Black
eggerdj Feb 3, 2022
072c40d
Merge branch 'main' into resonator_spec
eggerdj Feb 3, 2022
ba5d9ac
* Docs.
eggerdj Feb 3, 2022
30e0898
Merge branch 'resonator_spec' of github.com:eggerdj/qiskit-experiment…
eggerdj Feb 3, 2022
0664a21
* Added warning in resonator spectroscopy docstring.
eggerdj Feb 3, 2022
2904da9
Update qiskit_experiments/library/characterization/resonator_spectros…
eggerdj Feb 4, 2022
cd795b3
Merge branch 'main' into resonator_spec
eggerdj Feb 4, 2022
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
15 changes: 15 additions & 0 deletions qiskit_experiments/data_processing/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,21 @@ def _process(self, data: np.ndarray) -> np.ndarray:
return data[..., 1] * self.scale


class ToAbs(IQPart):
"""IQ data post-processing. Take the absolute value of the IQ point."""

def _process(self, data: np.array) -> np.array:
"""Take the absolute value of the IQ data.

Args:
data: An N-dimensional array of complex IQ point as [real, imaginary].

Returns:
A N-1 dimensional array, each entry is the absolute value of the given IQ data.
"""
return unp.sqrt(data[..., 0] ** 2 + data[..., 1] ** 2) * self.scale


class Probability(DataAction):
r"""Compute the mean probability of a single measurement outcome from counts.

Expand Down
38 changes: 36 additions & 2 deletions qiskit_experiments/data_processing/processor_library.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,39 +12,73 @@

"""A collection of functions that return various data processors."""

from enum import Enum
from typing import Union

from qiskit.qobj.utils import MeasLevel

from qiskit_experiments.data_processing.exceptions import DataProcessorError
from qiskit_experiments.data_processing.data_processor import DataProcessor
from qiskit_experiments.data_processing import nodes


class ProjectorType(Enum):
Comment thread
eggerdj marked this conversation as resolved.
Outdated
"""Types of projectors for data dimensionality reduction."""
SVD = nodes.SVD
ABS = nodes.ToAbs
REAL = nodes.ToReal
IMAG = nodes.ToImag


def get_processor(
meas_level: MeasLevel = MeasLevel.CLASSIFIED,
meas_return: str = "avg",
normalize: bool = True,
dimensionality_reduction: Union[str, ProjectorType] = ProjectorType.SVD,
Comment thread
eggerdj marked this conversation as resolved.
Outdated
) -> DataProcessor:
"""Get a DataProcessor that produces a continuous signal given the options.

Args:
meas_level: The measurement level of the data to process.
meas_return: The measurement return (single or avg) of the data to process.
normalize: Add a data normalization node to the Kerneled data processor.
dimensionality_reduction: An optional string or instance of :class:`ProjectorType`
to represent the dimensionality reduction node for Kerneled data. For the
supported nodes, see :class:`ProjectorType`. Typically, these nodes convert
complex IQ data to real data, for example by performing a singular-value
decomposition. This argument is only needed for Kerneled data (i.e. level 1)
and can thus be ignored if Classified data (the default) is used.

Returns:
An instance of DataProcessor capable of dealing with the given options.

Raises:
DataProcessorError: if the measurement level is not supported.
DataProcessorError: if the wrong dimensionality reduction for kerneled data
is specified.
"""
if meas_level == MeasLevel.CLASSIFIED:
return DataProcessor("counts", [nodes.Probability("1")])

if meas_level == MeasLevel.KERNELED:

try:
if isinstance(dimensionality_reduction, ProjectorType):
projector_name = dimensionality_reduction.name
else:
projector_name = dimensionality_reduction

projector = ProjectorType[projector_name].value

except KeyError as error:
raise DataProcessorError(
f"Invalid dimensionality reduction: {dimensionality_reduction}."
) from error

if meas_return == "single":
processor = DataProcessor("memory", [nodes.AverageData(axis=1), nodes.SVD()])
processor = DataProcessor("memory", [nodes.AverageData(axis=1), projector()])
else:
processor = DataProcessor("memory", [nodes.SVD()])
processor = DataProcessor("memory", [projector()])

if normalize:
processor.append(nodes.MinMaxNormalize())
Expand Down
35 changes: 20 additions & 15 deletions qiskit_experiments/library/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
~characterization.RamseyXY
~characterization.FineFrequency
~characterization.ReadoutAngle
~characterization.ResonatorSpectroscopy


.. _calibration:
Expand Down Expand Up @@ -103,21 +104,7 @@ class instance to manage parameters and pulse schedules.
~calibration.EFRoughXSXAmplitudeCal

"""
from .calibration import (
RoughDragCal,
FineDragCal,
FineXDragCal,
FineSXDragCal,
RoughAmplitudeCal,
RoughXSXAmplitudeCal,
EFRoughXSXAmplitudeCal,
FineAmplitudeCal,
FineXAmplitudeCal,
FineSXAmplitudeCal,
RoughFrequencyCal,
FrequencyCal,
FineFrequencyCal,
)

from .characterization import (
T1,
T2Ramsey,
Expand All @@ -138,7 +125,25 @@ class instance to manage parameters and pulse schedules.
RamseyXY,
FineFrequency,
ReadoutAngle,
ResonatorSpectroscopy,
)

from .calibration import (
RoughDragCal,
FineDragCal,
FineXDragCal,
FineSXDragCal,
RoughAmplitudeCal,
RoughXSXAmplitudeCal,
EFRoughXSXAmplitudeCal,
FineAmplitudeCal,
FineXAmplitudeCal,
FineSXAmplitudeCal,
RoughFrequencyCal,
FrequencyCal,
FineFrequencyCal,
)

from .randomized_benchmarking import StandardRB, InterleavedRB
from .tomography import StateTomography, ProcessTomography
from .quantum_volume import QuantumVolume
Expand Down
4 changes: 4 additions & 0 deletions qiskit_experiments/library/characterization/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
FineDrag
FineXDrag
FineSXDrag
ResonatorSpectroscopy


Analysis
Expand All @@ -59,6 +60,7 @@
FineAmplitudeAnalysis
RamseyXYAnalysis
ReadoutAngleAnalysis
ResonatorSpectroscopyAnalysis
"""

from .analysis import (
Expand All @@ -71,6 +73,7 @@
T1Analysis,
CrossResonanceHamiltonianAnalysis,
ReadoutAngleAnalysis,
ResonatorSpectroscopyAnalysis,
)

from .t1 import T1
Expand All @@ -86,3 +89,4 @@
from .drag import RoughDrag
from .readout_angle import ReadoutAngle
from .fine_drag import FineDrag, FineXDrag, FineSXDrag
from .resonator_spectroscopy import ResonatorSpectroscopy
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@
from .t1_analysis import T1Analysis
from .cr_hamiltonian_analysis import CrossResonanceHamiltonianAnalysis
from .readout_angle_analysis import ReadoutAngleAnalysis
from .resonator_spectroscopy_analysis import ResonatorSpectroscopyAnalysis
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# 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.

"""Spectroscopy analysis class for resonators."""

from typing import List, Tuple
import numpy as np

import qiskit_experiments.curve_analysis as curve
from qiskit_experiments.curve_analysis import ResonanceAnalysis
from qiskit_experiments.framework import AnalysisResultData, ExperimentData
from qiskit_experiments.framework.matplotlib import get_non_gui_ax


class ResonatorSpectroscopyAnalysis(ResonanceAnalysis):
"""Class to analysis resonator spectroscopy."""

@classmethod
def _default_options(cls):
options = super()._default_options()
options.dimensionality_reduction = "ToAbs"
options.result_parameters = [curve.ParameterRepr("freq", "meas_freq", "Hz")]
Comment thread
wshanks marked this conversation as resolved.
Outdated
Comment thread
eggerdj marked this conversation as resolved.
Outdated

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

#171 had proposed adding non-qubit components and flagged this experiment as likely the first experiment to add such a component. Do we want to set the component for the result to be a Resonator instead of a Qubit? This is what the current production system uses.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

That makes sense. It does not seem straight forward to implement without a small change to BaseAnalysis. How about this: 9dbe059?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

That looks good to me. It is preferrable to the current patch in #387 because it allows making the resonator the only component whereas #387 would result in a qubit and resonator component (unless you unset physical_qubits which could have some side effects). We might later need to add more flexibility to set components per result. With our older code, we have an experiment like the one in this PR that does resonator spectroscopy but with and without a pi on the qubit. In that case, it extracts resonator frequency and linewidth results with the resonator component set and the qubit-resonator chi with both the qubit and resonator components set.

Should we propose this change in #387 since a different set of reviewers were interested there?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

That makes sense to me. We can propose this change in #387. Alternatively we simply merge this PR and close #387.

options.plot_iq_data = True
Comment thread
eggerdj marked this conversation as resolved.
return options

def _run_analysis(
self, experiment_data: ExperimentData
) -> Tuple[List[AnalysisResultData], List["pyplot.Figure"]]:
"""Wrap the analysis to optionally plot the IQ data."""
analysis_results, figures = super()._run_analysis(experiment_data)

if self.options.plot_iq_data:
axis = get_non_gui_ax()
figure = axis.get_figure()
figure.set_size_inches(*self.options.style.figsize)

iqs = []

for datum in experiment_data.data():
if "memory" in datum:
Comment thread
wshanks marked this conversation as resolved.
mem = np.array(datum["memory"])

# Average single-shot data.
if len(mem.shape) == 3:
iqs.append(np.average(mem.reshape(mem.shape[0], mem.shape[2]), axis=0))
Comment thread
wshanks marked this conversation as resolved.
Outdated

iqs = np.array(iqs)
axis.scatter(iqs[:, 0], iqs[:, 1], color="b")
axis.set_xlabel("In phase [arb. units]", fontsize=self.options.style.axis_label_size)
axis.set_ylabel("Quadrature [arb. units]", fontsize=self.options.style.axis_label_size)
axis.tick_params(labelsize=self.options.style.tick_label_size)
axis.grid(True)

figures.append(figure)

return analysis_results, figures
67 changes: 37 additions & 30 deletions qiskit_experiments/library/characterization/qubit_spectroscopy.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,21 @@ def __init__(

self.analysis.set_options(ylabel="Signal [arb. unit]")

@property
def center_frequency(self) -> float:
Comment thread
eggerdj marked this conversation as resolved.
Outdated
"""Returns the center frequency of the experiment.

Returns:
The center frequency of the experiment.

Raises:
QiskitError: If the experiment does not have a backend set.
"""
if self.backend is None:
raise QiskitError("backend not set. Cannot call center_frequency.")

return self.backend.defaults().qubit_freq_est[self.physical_qubits[0]]

def _spec_gate_schedule(
self, backend: Optional[Backend] = None
) -> Tuple[pulse.ScheduleBlock, Parameter]:
Expand Down Expand Up @@ -151,6 +166,20 @@ def _template_circuit(self, freq_param) -> QuantumCircuit:

return circuit

def _add_metadata(self, circuit: QuantumCircuit, freq: float, sched: pulse.ScheduleBlock):
"""Helper method to add the metadata to avoid code duplication with subclasses."""
circuit.metadata = {
Comment thread
eggerdj marked this conversation as resolved.
Outdated
"experiment_type": self._type,
"qubits": (self.physical_qubits[0],),
"xval": np.round(freq, decimals=3),
"unit": "Hz",
"amplitude": self.experiment_options.amp,
"duration": self.experiment_options.duration,
"sigma": self.experiment_options.sigma,
"width": self.experiment_options.width,
"schedule": str(sched),
}

def circuits(self):
"""Create the circuit for the spectroscopy experiment.

Expand All @@ -161,52 +190,30 @@ def circuits(self):
circuits: The circuits that will run the spectroscopy experiment.

Raises:
QiskitError:
- If absolute frequencies are used but no backend is given.
- If the backend configuration does not define dt.
QiskitError: If absolute frequencies are used but no backend is given.
QiskitError: If the backend configuration does not define dt.
AttributeError: If backend to run on does not contain 'dt' configuration.
"""
if self.backend is None and self._absolute:
raise QiskitError("Cannot run spectroscopy absolute to qubit without a backend.")
raise QiskitError("Cannot run spectroscopy in absolute without a backend.")

# Create a template circuit
sched, freq_param = self._spec_gate_schedule(self.backend)
circuit = self._template_circuit(freq_param)
circuit.add_calibration("Spec", (self.physical_qubits[0],), sched, params=[freq_param])

# Get dt
try:
dt_factor = getattr(self.backend.configuration(), "dt")
except AttributeError as no_dt:
raise AttributeError("dt parameter is missing in backend configuration") from no_dt

# Get center frequency from backend
if self._absolute:
center_freq = self.backend.defaults().qubit_freq_est[self.physical_qubits[0]]
else:
center_freq = None
circuit.add_calibration(
self.__spec_gate_name__, self.physical_qubits, sched, params=[freq_param]
)

# Create the circuits to run
circs = []
for freq in self._frequencies:
freq_shift = freq
if self._absolute:
freq_shift -= center_freq
freq_shift -= self.center_frequency
freq_shift = np.round(freq_shift, decimals=3)

assigned_circ = circuit.assign_parameters({freq_param: freq_shift}, inplace=False)
assigned_circ.metadata = {
"experiment_type": self._type,
"qubits": (self.physical_qubits[0],),
"xval": np.round(freq, decimals=3),
"unit": "Hz",
"amplitude": self.experiment_options.amp,
"duration": self.experiment_options.duration,
"sigma": self.experiment_options.sigma,
"width": self.experiment_options.width,
"schedule": str(sched),
"dt": dt_factor,
}
self._add_metadata(assigned_circ, freq, sched)

circs.append(assigned_circ)

Expand Down
Loading