-
Notifications
You must be signed in to change notification settings - Fork 7
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
Conversation
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## main #664 +/- ##
==========================================
- Coverage 96.01% 96.00% -0.02%
==========================================
Files 106 108 +2
Lines 7356 7584 +228
==========================================
+ Hits 7063 7281 +218
- Misses 293 303 +10
Flags with carried forward coverage won't be shown. Click here to find out more.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @DavidSarlle.
The code looks more or less good to me.
The comments are mainly suggestions to have the code updated to the latest version.
Two important points:
- It would be nice to perform a fitting, let me know if you need help with that.
- Could you please add another entry for these new protocols here
src/qibocal/protocols/characterization/readout_optimization/twpa_calibration/frequency_SNR.py
Outdated
Show resolved
Hide resolved
src/qibocal/protocols/characterization/readout_optimization/twpa_calibration/frequency_SNR.py
Outdated
Show resolved
Hide resolved
resonator_type: str | ||
"""Resonator type.""" |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
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 | ||
|
||
results = platform.sweep( | ||
sequence, | ||
ExecutionParameters( | ||
nshots=params.nshots, | ||
relaxation_time=params.relaxation_time, | ||
acquisition_type=AcquisitionType.INTEGRATION, | ||
averaging_mode=AveragingMode.CYCLIC, | ||
), | ||
freq_sweeper, | ||
) |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
src/qibocal/protocols/characterization/readout_optimization/twpa_calibration/frequency_SNR.py
Outdated
Show resolved
Hide resolved
src/qibocal/protocols/characterization/readout_optimization/twpa_calibration/frequency_SNR.py
Outdated
Show resolved
Hide resolved
src/qibocal/protocols/characterization/readout_optimization/twpa_calibration/frequency_SNR.py
Outdated
Show resolved
Hide resolved
src/qibocal/protocols/characterization/readout_optimization/twpa_calibration/frequency_SNR.py
Outdated
Show resolved
Hide resolved
src/qibocal/protocols/characterization/readout_optimization/twpa_calibration/power_SNR.py
Show resolved
Hide resolved
src/qibocal/protocols/characterization/readout_optimization/twpa_calibration/frequency_SNR.py
Outdated
Show resolved
Hide resolved
for more information, see https://pre-commit.ci
…into david/twpa_SNR
for more information, see https://pre-commit.ci
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @DavidSarlle for all the updates.
I have a few more suggestions.
To fix coverage could you the two new protocols in this runcard ?
src/qibocal/protocols/characterization/readout_optimization/twpa_calibration/frequency_SNR.py
Outdated
Show resolved
Hide resolved
src/qibocal/protocols/characterization/readout_optimization/twpa_calibration/frequency_SNR.py
Outdated
Show resolved
Hide resolved
src/qibocal/protocols/characterization/readout_optimization/twpa_calibration/frequency_SNR.py
Outdated
Show resolved
Hide resolved
for qubit in qubits: | ||
data_qubit = data[qubit] | ||
if data.resonator_type == "3D": | ||
print("3D") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
print("3D") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove all the print
src/qibocal/protocols/characterization/readout_optimization/twpa_calibration/frequency_SNR.py
Outdated
Show resolved
Hide resolved
src/qibocal/protocols/characterization/readout_optimization/twpa_calibration/frequency_SNR.py
Outdated
Show resolved
Hide resolved
src/qibocal/protocols/characterization/readout_optimization/twpa_calibration/power_SNR.py
Outdated
Show resolved
Hide resolved
src/qibocal/protocols/characterization/readout_optimization/twpa_calibration/power_SNR.py
Outdated
Show resolved
Hide resolved
src/qibocal/protocols/characterization/readout_optimization/twpa_calibration/power_SNR.py
Outdated
Show resolved
Hide resolved
@@ -196,5 +196,5 @@ def _update(results: ResonatorSpectroscopyResults, platform: Platform, qubit: Qu | |||
update.bare_resonator_frequency(results.bare_frequency[qubit], platform, qubit) | |||
|
|||
|
|||
resonator_spectroscopy = Routine(_acquisition, _fit, _plot, _update) | |||
resonator_spec = Routine(_acquisition, _fit, _plot, _update) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can I ask why you renamed resonator_spectroscopy
in resonator_spec
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The name of the object "Routine" created in the in the "resonator_spectroscopy" class and the class itself have the same name. This is not a problem until you import that class from a different one. Python understands that you are importing the object "Routine" instead of the class. So, we can not use the dataclasses needed from the class "resonator_spectroscopy" like "ResonatorSpectroscopyParameters" during the twpa routines. Same with the private methods like "_acquisition" (but this is a minor problem because the Routine object inherits the methods needed)
Done |
for more information, see https://pre-commit.ci
…into david/twpa_SNR
@andrea-pasquale the tests are not passing, can you help me with that? |
src/qibocal/protocols/characterization/readout_optimization/twpa_calibration/frequency_SNR.py
Outdated
Show resolved
Hide resolved
src/qibocal/protocols/characterization/readout_optimization/twpa_calibration/frequency_SNR.py
Outdated
Show resolved
Hide resolved
for qubit in qubits: | ||
data_qubit = data[qubit] | ||
if data.resonator_type == "3D": | ||
print("3D") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove all the print
src/qibocal/protocols/characterization/readout_optimization/twpa_calibration/frequency_SNR.py
Show resolved
Hide resolved
if fit is not None: | ||
if qubit in fit.bare_frequency: | ||
summary = table_dict( | ||
qubit, | ||
[ | ||
"High Power Resonator Frequency [Hz]", | ||
"TWPA Frequency [Hz]", | ||
], | ||
[ | ||
np.round(fit.bare_frequency[qubit]), | ||
np.round(fit.twpa_frequency[qubit]), | ||
], | ||
) | ||
else: | ||
summary = table_dict( | ||
qubit, | ||
[ | ||
"Low Power Resonator Frequency [Hz]", | ||
"TWPA Frequency [Hz]", | ||
], | ||
[ | ||
np.round(fit.frequency[qubit]), | ||
np.round(fit.twpa_frequency[qubit]), | ||
], | ||
) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If possible, try not to repeat code, i.e. abstract all the common parts, or define a function collecting what inside the branches.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
size = len(freq) | ||
ar = np.empty(size, dtype=ResonatorTWPAPowerType) | ||
ar["freq"] = freq | ||
ar["twpa_pow"] = np.array([twpa_pow] * size) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add an attribute
src/qibocal/protocols/characterization/readout_optimization/twpa_calibration/power_SNR.py
Show resolved
Hide resolved
|
||
fitting_report = "" | ||
qubit_data = data[qubit] | ||
resonator_frequencies = qubit_data.freq * HZ_TO_GHZ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
resonator_frequencies = qubit_data.freq * HZ_TO_GHZ | |
resonator_frequencies = qubit_data.freq |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed conversion
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
if data.resonator_type == "3D": | ||
index_best_pow = np.argmax(data_qubit["signal"]) | ||
twpa_power[qubit] = data_qubit["twpa_pow"][index_best_pow] | ||
else: | ||
index_best_pow = np.argmin(data_qubit["signal"]) | ||
twpa_power[qubit] = data_qubit["twpa_pow"][index_best_pow] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if data.resonator_type == "3D": | |
index_best_pow = np.argmax(data_qubit["signal"]) | |
twpa_power[qubit] = data_qubit["twpa_pow"][index_best_pow] | |
else: | |
index_best_pow = np.argmin(data_qubit["signal"]) | |
twpa_power[qubit] = data_qubit["twpa_pow"][index_best_pow] | |
if data.resonator_type == "3D": | |
index_best_pow = np.argmax(data_qubit["signal"]) | |
else: | |
index_best_pow = np.argmin(data_qubit["signal"]) | |
twpa_power[qubit] = data_qubit["twpa_pow"][index_best_pow] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implemented
def register_qubit(self, qubit, freq, twpa_freq, signal, 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) | ||
ar["signal"] = signal | ||
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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
def register_qubit(self, qubit, freq, twpa_freq, signal, 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) | |
ar["signal"] = signal | |
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) |
The class Data
has a default register_qubit
method, and it seems that it is not different from the one you implemented.
qibocal/src/qibocal/auto/operation.py
Lines 164 to 181 in 1adce17
def register_qubit(self, dtype, data_keys, data_dict): | |
"""Store output for single qubit. | |
Args: | |
data_keys (tuple): Keys of Data.data. | |
data_dict (dict): The keys are the fields of `dtype` and | |
the values are the related arrays. | |
""" | |
# to be able to handle the non-sweeper case | |
ar = np.empty(np.shape(data_dict[list(data_dict.keys())[0]]), dtype=dtype) | |
for key, value in data_dict.items(): | |
ar[key] = value | |
if data_keys in self.data: | |
self.data[data_keys] = np.rec.array( | |
np.concatenate((self.data[data_keys], ar)) | |
) | |
else: | |
self.data[data_keys] = np.rec.array(ar) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. Implemented
src/qibocal/protocols/characterization/readout_optimization/twpa_calibration/power_SNR.py
Outdated
Show resolved
Hide resolved
…into david/twpa_SNR
for more information, see https://pre-commit.ci
for more information, see https://pre-commit.ci
@Edoardo-Pedicillo all your comments has been addressed. Thanks for the review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for all the updates @DavidSarlle.
I believe we are ready to merge.
Just before merging...
Regarding this:
The name of the object "Routine" created in the in the "resonator_spectroscopy" class and the class itself have the same name. This is not a problem until you import that class from a different one. Python understands that you are importing the object "Routine" instead of the class. So, we can not use the dataclasses needed from the class "resonator_spectroscopy" like "ResonatorSpectroscopyParameters" during the twpa routines. Same with the private methods like "_acquisition" (but this is a minor problem because the Routine object inherits the methods needed)
I tried to replaceresonator_spec
withresonator_spectroscopy
and everything worked as expected. If you want I can push the change directly here.
ok. push the change please. |
Actually it was not as easy as I expected. Strangely only pylint complains but not pytest. I've also tested the code and it works as expected. I manage to fix it but by importing directly the |
This Pr implements 2 routines for characterizing the TWPA frequency and power doing a resonator spectroscopy while modifying the values of frequency / power of the TWPA.
Checklist:
master
main
main