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

TWPA calibration using SNR #664

Merged
merged 25 commits into from
Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
a345e28
implementing twpa calibration using SNR as a figuere of merit
DavidSarlle Dec 8, 2023
162ffff
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 8, 2023
8d46943
reusing resonator spectroscopy to perform twpa calibration freq
DavidSarlle Jan 10, 2024
3f131d9
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 10, 2024
e7c40fa
adddressing all review comments
DavidSarlle Jan 10, 2024
3114022
Merge branch 'david/twpa_SNR' of https://github.com/qiboteam/qibocal …
DavidSarlle Jan 10, 2024
9414764
removing unused imports
DavidSarlle Jan 10, 2024
885ce83
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 10, 2024
31bef10
Merge branch 'main' into david/twpa_SNR
DavidSarlle Jan 10, 2024
f5a7c53
addressing latest comments
DavidSarlle Jan 12, 2024
31d0634
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 12, 2024
265fb67
testing modifications
DavidSarlle Jan 12, 2024
76ace75
Merge branch 'david/twpa_SNR' of https://github.com/qiboteam/qibocal …
DavidSarlle Jan 12, 2024
12820d3
tests
DavidSarlle Jan 12, 2024
f4ff7da
test
DavidSarlle Jan 12, 2024
1adce17
fixing tests
DavidSarlle Jan 15, 2024
29f3b07
adressing Edoardo's review comments
DavidSarlle Jan 22, 2024
40e1427
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 22, 2024
4f631df
removing impor not used
DavidSarlle Jan 22, 2024
e8abb9c
Merge branch 'david/twpa_SNR' of https://github.com/qiboteam/qibocal …
DavidSarlle Jan 22, 2024
74026df
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 22, 2024
e3a2843
addressing rest of Edoardo's comments
DavidSarlle Jan 24, 2024
de8cf42
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 24, 2024
2ddacbe
refactor: Rename resonator_spec -> resonator_spectroscopy
andrea-pasquale Jan 24, 2024
fa86200
refactor: merge main and improve plots
andrea-pasquale Jan 24, 2024
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
4 changes: 4 additions & 0 deletions src/qibocal/protocols/characterization/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@
from .readout_optimization.resonator_frequency import resonator_frequency
from .readout_optimization.twpa_calibration.frequency import twpa_frequency
from .readout_optimization.twpa_calibration.frequency_power import twpa_frequency_power
from .readout_optimization.twpa_calibration.frequency_SNR import twpa_frequency_SNR
from .readout_optimization.twpa_calibration.power import twpa_power
from .readout_optimization.twpa_calibration.power_SNR import twpa_power_SNR
from .resonator_punchout import resonator_punchout
from .resonator_punchout_attenuation import resonator_punchout_attenuation
from .resonator_spectroscopy import resonator_spectroscopy
Expand Down Expand Up @@ -100,7 +102,9 @@ class Operation(Enum):
chsh_circuits = chsh_circuits
readout_mitigation_matrix = readout_mitigation_matrix
twpa_frequency = twpa_frequency
twpa_frequency_SNR = twpa_frequency_SNR
andrea-pasquale marked this conversation as resolved.
Show resolved Hide resolved
twpa_power = twpa_power
twpa_power_SNR = twpa_power_SNR
twpa_frequency_power = twpa_frequency_power
rabi_amplitude_ef = rabi_amplitude_ef
qubit_spectroscopy_ef = qubit_spectroscopy_ef
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
from dataclasses import dataclass, field
from typing import Optional

import numpy as np
import numpy.typing as npt
import plotly.graph_objects as go
from plotly.subplots import make_subplots
from qibolab import AcquisitionType, AveragingMode, ExecutionParameters
from qibolab.platform import Platform
from qibolab.pulses import PulseSequence
from qibolab.qubits import QubitId
from qibolab.sweeper import Parameter, Sweeper, SweeperType

from qibocal.auto.operation import Data, Parameters, Qubits, Results, Routine
from qibocal.protocols.characterization.utils import HZ_TO_GHZ, V_TO_UV


@dataclass
class ResonatorTWPAFrequencyParameters(Parameters):
"""ResonatorTWPAFrequency runcard inputs."""

freq_width: int
"""Width for frequency sweep relative to the readout frequency (Hz)."""
freq_step: int
"""Frequency step for sweep (Hz)."""
min_twpa_freq: int
"""TPWA frequency minimum value (Hz)."""
max_twpa_freq: int
"""TPWA frequency maximum value (Hz)."""
step_twpa_freq: int
Edoardo-Pedicillo marked this conversation as resolved.
Show resolved Hide resolved
"""TPWA frequency step (Hz)."""
nshots: Optional[int] = None
"""Number of shots."""
relaxation_time: Optional[int] = None
"""Relaxation time (ns)."""


@dataclass
class ResonatorTWPAFrequencyResults(Results):
"""ResonatorTWPAFrequency outputs."""

pass
andrea-pasquale marked this conversation as resolved.
Show resolved Hide resolved


ResonatorTWPAFrequencyType = np.dtype(
[
("freq", np.float64),
("twpa_freq", np.float64),
("msr", np.float64),
andrea-pasquale marked this conversation as resolved.
Show resolved Hide resolved
("phase", np.float64),
]
)
"""Custom dtype for Resonator TWPA Frequency."""


@dataclass
class ResonatorTWPAFrequencyData(Data):
"""ResonatorTWPAFrequency data acquisition."""

resonator_type: str
"""Resonator type."""
Comment on lines +73 to +74
Copy link
Contributor

Choose a reason for hiding this comment

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

This attribute is not used anywhere

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I will keep it because is going to be needed during the fitting.

data: dict[QubitId, npt.NDArray[ResonatorTWPAFrequencyType]] = field(
default_factory=dict
)
"""Raw data acquired."""

def register_qubit(self, qubit, freq, twpa_freq, msr, phase):
"""Store output for single qubit."""
size = len(freq)
ar = np.empty(size, dtype=ResonatorTWPAFrequencyType)
ar["freq"] = freq
ar["twpa_freq"] = np.array([twpa_freq] * size)
Edoardo-Pedicillo marked this conversation as resolved.
Show resolved Hide resolved
ar["msr"] = msr
ar["phase"] = phase
if qubit in self.data:
self.data[qubit] = np.rec.array(np.concatenate((self.data[qubit], ar)))
else:
self.data[qubit] = np.rec.array(ar)


def _acquisition(
params: ResonatorTWPAFrequencyParameters,
platform: Platform,
qubits: Qubits,
) -> ResonatorTWPAFrequencyData:
r"""
Data acquisition for TWPA frequency optmization using SNR.
This protocol perform a classification protocol for twpa frequencies
in the range [twpa_frequency - frequency_width / 2, twpa_frequency + frequency_width / 2]
with step frequency_step.

Args:
params (:class:`ResonatorTWPAFrequencyParameters`): input parameters
platform (:class:`Platform`): Qibolab's platform
qubits (dict): dict of target :class:`Qubit` objects to be characterized

Returns:
data (:class:`ResonatorTWPAFrequencyData`)
"""
# create a sequence of pulses for the experiment:
# MZ

# taking advantage of multiplexing, apply the same set of gates to all qubits in parallel
sequence = PulseSequence()

ro_pulses = {}
for qubit in qubits:
ro_pulses[qubit] = platform.create_qubit_readout_pulse(qubit, start=0)
sequence.add(ro_pulses[qubit])

data = ResonatorTWPAFrequencyData(platform.resonator_type)

# define the parameters to sweep and their range:
# resonator frequency
delta_frequency_range = np.arange(
-params.freq_width // 2, params.freq_width // 2, params.freq_step
)
freq_sweeper = Sweeper(
Parameter.frequency,
delta_frequency_range,
[ro_pulses[qubit] for qubit in qubits],
type=SweeperType.OFFSET,
)

# TWPAFrequency
TWPAFrequency_range = np.arange(
params.min_twpa_freq, params.max_twpa_freq, params.step_twpa_freq
)

for _freq in TWPAFrequency_range:
for z in qubits:
qubits[z].twpa.local_oscillator.frequency = _freq
Edoardo-Pedicillo marked this conversation as resolved.
Show resolved Hide resolved

results = platform.sweep(
sequence,
ExecutionParameters(
nshots=params.nshots,
relaxation_time=params.relaxation_time,
acquisition_type=AcquisitionType.INTEGRATION,
averaging_mode=AveragingMode.CYCLIC,
),
freq_sweeper,
)
Copy link
Contributor

Choose a reason for hiding this comment

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

Since you are basically running a resonator spectroscopy varying the twpa you can just call directly the resonator spectroscopy protocol here. Like we did in the twpa optimization protocols by calling directly the classification protocol

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done


# retrieve the results for every qubit
for qubit in qubits:
# average msr, phase, i and q over the number of shots defined in the runcard
result = results[ro_pulses[qubit].serial]
data.register_qubit(
qubit,
msr=result.magnitude,
phase=result.phase,
freq=delta_frequency_range + ro_pulses[qubit].frequency,
twpa_freq=_freq,
)

return data


def _fit(
data: ResonatorTWPAFrequencyData, fit_type="att"
) -> ResonatorTWPAFrequencyResults:
"""Fit frequency and TWPAFrequency at high and low frequency for a given resonator."""
return ResonatorTWPAFrequencyResults()
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you think that it is feasible to implement a fit for this protocol.
I believe that it should be that hard. Eventually we can even put a limit on the twpa power and search the higher snr. withing that range

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fitting implemented



def _plot(
data: ResonatorTWPAFrequencyData,
fit: ResonatorTWPAFrequencyResults,
qubit,
):
"""Plotting for ResonatorTWPAFrequency."""

figures = []
fitting_report = ""
fig = make_subplots(
rows=1,
cols=2,
horizontal_spacing=0.1,
vertical_spacing=0.2,
subplot_titles=(
"MSR",
"phase (rad)",
andrea-pasquale marked this conversation as resolved.
Show resolved Hide resolved
),
)

qubit_data = data[qubit]
resonator_frequencies = qubit_data.freq * HZ_TO_GHZ
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
resonator_frequencies = qubit_data.freq * HZ_TO_GHZ
resonator_frequencies = qubit_data.freq

Copy link
Contributor Author

Choose a reason for hiding this comment

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

removed conversion

Copy link
Contributor

Choose a reason for hiding this comment

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

Here I don't understand why @Edoardo-Pedicillo asked you to remove the conversion. I suggest to perform the conversion mainly because I don't want to see bilions of Hz in the x axis. I already performed this change in fa86200

Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry, I made a mistake

twpa_frequencies = qubit_data.twpa_freq

fig.add_trace(
go.Heatmap(
x=resonator_frequencies,
y=twpa_frequencies,
z=qubit_data.msr * V_TO_UV,
andrea-pasquale marked this conversation as resolved.
Show resolved Hide resolved
colorbar_x=0.46,
),
row=1,
col=1,
)
fig.update_xaxes(title_text=f"{qubit}: Frequency (Hz)", row=1, col=1)
andrea-pasquale marked this conversation as resolved.
Show resolved Hide resolved
fig.update_yaxes(title_text="TWPA Frequency", row=1, col=1)
fig.add_trace(
go.Heatmap(
x=resonator_frequencies,
y=twpa_frequencies,
z=qubit_data.phase,
colorbar_x=1.01,
),
row=1,
col=2,
)
fig.update_xaxes(title_text=f"{qubit}/: Frequency (Hz)", row=1, col=2)
fig.update_yaxes(title_text="TWPA Frequency", row=1, col=2)

title_text = ""

fitting_report = fitting_report + title_text

fig.update_layout(
showlegend=False,
uirevision="0", # ``uirevision`` allows zooming while live plotting
andrea-pasquale marked this conversation as resolved.
Show resolved Hide resolved
)

figures.append(fig)

return figures, fitting_report


twpa_frequency_SNR = Routine(_acquisition, _fit, _plot)
"""Resonator TWPA Frequency Routine object."""
Loading