Skip to content

Commit 8c3f14d

Browse files
Merge pull request #705 from qiboteam/fix_fit_error
Adding `try-except` block in flux fits
2 parents 331fe58 + 0f5e54d commit 8c3f14d

File tree

4 files changed

+86
-57
lines changed

4 files changed

+86
-57
lines changed

src/qibocal/auto/task.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from qibolab.qubits import QubitId, QubitPairId
1111
from qibolab.serialize import dump_platform
1212

13-
from ..config import raise_error
13+
from ..config import log, raise_error
1414
from ..protocols.characterization import Operation
1515
from ..utils import (
1616
allocate_qubits_pairs,
@@ -239,7 +239,12 @@ def update_platform(self, platform: Platform, update: bool):
239239
"""Perform update on platform' parameters by looping over qubits or pairs."""
240240
if self.task.update and update:
241241
for qubit in self.task.qubits:
242-
self.task.operation.update(self.results, platform, qubit)
242+
try:
243+
self.task.operation.update(self.results, platform, qubit)
244+
except KeyError:
245+
log.warning(
246+
f"Skipping update of qubit {qubit} due to error in fit."
247+
)
243248
(self.datapath / PLATFORM_DIR).mkdir(parents=True, exist_ok=True)
244249
dump_platform(platform, self.datapath / PLATFORM_DIR)
245250

src/qibocal/protocols/characterization/flux_dependence/qubit_flux_dependence.py

+29-20
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
from qibocal import update
1414
from qibocal.auto.operation import Data, Parameters, Qubits, Results, Routine
15+
from qibocal.config import log
1516
from qibocal.protocols.characterization.qubit_spectroscopy_ef import (
1617
DEFAULT_ANHARMONICITY,
1718
)
@@ -49,8 +50,8 @@ class QubitFluxResults(Results):
4950
"""Sweetspot for each qubit."""
5051
frequency: dict[QubitId, float]
5152
"""Drive frequency for each qubit."""
52-
d: dict[QubitId, float]
53-
"""Asymmetry."""
53+
asymmetry: dict[QubitId, float]
54+
"""Asymmetry between junctions."""
5455
fitted_parameters: dict[QubitId, dict[str, float]]
5556
"""Raw fitting output."""
5657
matrix_element: dict[QubitId, float]
@@ -179,7 +180,7 @@ def _fit(data: QubitFluxData) -> QubitFluxResults:
179180
qubits = data.qubits
180181
frequency = {}
181182
sweetspot = {}
182-
d = {}
183+
asymmetry = {}
183184
matrix_element = {}
184185
fitted_parameters = {}
185186

@@ -203,25 +204,33 @@ def _fit(data: QubitFluxData) -> QubitFluxResults:
203204
signal,
204205
)
205206

206-
popt = curve_fit(
207-
utils.transmon_frequency,
208-
biases,
209-
frequencies * HZ_TO_GHZ,
210-
bounds=utils.qubit_flux_dependence_fit_bounds(
211-
data.qubit_frequency[qubit], qubit_data.bias
212-
),
213-
maxfev=100000,
214-
)[0]
215-
fitted_parameters[qubit] = popt.tolist()
216-
frequency[qubit] = popt[0] * GHZ_TO_HZ
217-
d[qubit] = popt[1]
218-
sweetspot[qubit] = popt[3]
219-
matrix_element[qubit] = popt[2]
207+
try:
208+
popt = curve_fit(
209+
utils.transmon_frequency,
210+
biases,
211+
frequencies * HZ_TO_GHZ,
212+
bounds=utils.qubit_flux_dependence_fit_bounds(
213+
data.qubit_frequency[qubit], qubit_data.bias
214+
),
215+
maxfev=100000,
216+
)[0]
217+
fitted_parameters[qubit] = popt.tolist()
218+
frequency[qubit] = popt[0] * GHZ_TO_HZ
219+
asymmetry[qubit] = popt[1]
220+
sweetspot[qubit] = popt[3]
221+
matrix_element[qubit] = popt[2]
222+
except ValueError as e:
223+
log.error(
224+
f"Error in qubit_flux protocol fit: {e} "
225+
"The threshold for the SNR mask is probably too high. "
226+
"Lowering the value of `threshold` in `extract_*_feature`"
227+
"should fix the problem."
228+
)
220229

221230
return QubitFluxResults(
222231
frequency=frequency,
223232
sweetspot=sweetspot,
224-
d=d,
233+
asymmetry=asymmetry,
225234
matrix_element=matrix_element,
226235
fitted_parameters=fitted_parameters,
227236
)
@@ -245,7 +254,7 @@ def _plot(data: QubitFluxData, fit: QubitFluxResults, qubit):
245254
[
246255
np.round(fit.sweetspot[qubit], 4),
247256
np.round(fit.frequency[qubit], 4),
248-
np.round(fit.d[qubit], 4),
257+
np.round(fit.asymmetry[qubit], 4),
249258
np.round(fit.matrix_element[qubit], 4),
250259
],
251260
)
@@ -257,7 +266,7 @@ def _plot(data: QubitFluxData, fit: QubitFluxResults, qubit):
257266
def _update(results: QubitFluxResults, platform: Platform, qubit: QubitId):
258267
update.drive_frequency(results.frequency[qubit], platform, qubit)
259268
update.sweetspot(results.sweetspot[qubit], platform, qubit)
260-
update.asymmetry(results.d[qubit], platform, qubit)
269+
update.asymmetry(results.asymmetry[qubit], platform, qubit)
261270

262271

263272
qubit_flux = Routine(_acquisition, _fit, _plot, _update)

src/qibocal/protocols/characterization/flux_dependence/resonator_flux_dependence.py

+45-34
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
from qibocal import update
1313
from qibocal.auto.operation import Data, Parameters, Qubits, Results, Routine
14+
from qibocal.config import log
1415

1516
from ..utils import GHZ_TO_HZ, HZ_TO_GHZ, table_dict, table_html
1617
from . import utils
@@ -38,16 +39,16 @@ class ResonatorFluxResults(Results):
3839
"""Readout frequency for each qubit."""
3940
sweetspot: dict[QubitId, float]
4041
"""Sweetspot for each qubit."""
41-
d: dict[QubitId, float]
42-
"""Asymmetry."""
42+
asymmetry: dict[QubitId, float]
43+
"""Asymmetry between junctions."""
4344
bare_frequency: dict[QubitId, float]
4445
"""Resonator bare frequency."""
4546
drive_frequency: dict[QubitId, float]
4647
"""Qubit frequency at sweetspot."""
4748
fitted_parameters: dict[QubitId, dict[str, float]]
4849
"""Raw fitting output."""
49-
g: dict[QubitId, float]
50-
"""Coupling."""
50+
coupling: dict[QubitId, float]
51+
"""Qubit-resonator coupling."""
5152
matrix_element: dict[QubitId, float]
5253
"""C_ii coefficient."""
5354

@@ -169,12 +170,12 @@ def _fit(data: ResonatorFluxData) -> ResonatorFluxResults:
169170
qubits = data.qubits
170171
frequency = {}
171172
sweetspot = {}
172-
d = {}
173+
asymmetry = {}
173174
bare_frequency = {}
174175
drive_frequency = {}
175176
fitted_parameters = {}
176177
matrix_element = {}
177-
g = {}
178+
coupling = {}
178179

179180
for qubit in qubits:
180181
qubit_data = data[qubit]
@@ -196,36 +197,46 @@ def _fit(data: ResonatorFluxData) -> ResonatorFluxResults:
196197
signal,
197198
)
198199

199-
popt = curve_fit(
200-
utils.transmon_readout_frequency,
201-
biases,
202-
frequencies * HZ_TO_GHZ,
203-
bounds=utils.resonator_flux_dependence_fit_bounds(
204-
data.qubit_frequency[qubit],
205-
qubit_data.bias,
206-
data.bare_resonator_frequency[qubit],
207-
),
208-
maxfev=100000,
209-
)[0]
210-
fitted_parameters[qubit] = popt.tolist()
211-
212-
# frequency corresponds to transmon readout frequency
213-
# at the sweetspot popt[3]
214-
frequency[qubit] = utils.transmon_readout_frequency(popt[3], *popt) * GHZ_TO_HZ
215-
sweetspot[qubit] = popt[3]
216-
d[qubit] = popt[1]
217-
bare_frequency[qubit] = popt[4] * GHZ_TO_HZ
218-
drive_frequency[qubit] = popt[0] * GHZ_TO_HZ
219-
g[qubit] = popt[5]
220-
matrix_element[qubit] = popt[2]
200+
try:
201+
popt = curve_fit(
202+
utils.transmon_readout_frequency,
203+
biases,
204+
frequencies * HZ_TO_GHZ,
205+
bounds=utils.resonator_flux_dependence_fit_bounds(
206+
data.qubit_frequency[qubit],
207+
qubit_data.bias,
208+
data.bare_resonator_frequency[qubit],
209+
),
210+
maxfev=100000,
211+
)[0]
212+
fitted_parameters[qubit] = popt.tolist()
213+
214+
# frequency corresponds to transmon readout frequency
215+
# at the sweetspot popt[3]
216+
frequency[qubit] = (
217+
utils.transmon_readout_frequency(popt[3], *popt) * GHZ_TO_HZ
218+
)
219+
sweetspot[qubit] = popt[3]
220+
asymmetry[qubit] = popt[1]
221+
bare_frequency[qubit] = popt[4] * GHZ_TO_HZ
222+
drive_frequency[qubit] = popt[0] * GHZ_TO_HZ
223+
coupling[qubit] = popt[5]
224+
matrix_element[qubit] = popt[2]
225+
except ValueError as e:
226+
log.error(
227+
f"Error in resonator_flux protocol fit: {e} "
228+
"The threshold for the SNR mask is probably too high. "
229+
"Lowering the value of `threshold` in `extract_*_feature`"
230+
"should fix the problem."
231+
)
221232

222233
return ResonatorFluxResults(
223234
frequency=frequency,
224235
sweetspot=sweetspot,
225-
d=d,
236+
asymmetry=asymmetry,
226237
bare_frequency=bare_frequency,
227238
drive_frequency=drive_frequency,
228-
g=g,
239+
coupling=coupling,
229240
matrix_element=matrix_element,
230241
fitted_parameters=fitted_parameters,
231242
)
@@ -254,8 +265,8 @@ def _plot(data: ResonatorFluxData, fit: ResonatorFluxResults, qubit):
254265
np.round(fit.bare_frequency[qubit], 4),
255266
np.round(fit.frequency[qubit], 4),
256267
np.round(fit.drive_frequency[qubit], 4),
257-
np.round(fit.d[qubit], 4),
258-
np.round(fit.g[qubit], 4),
268+
np.round(fit.asymmetry[qubit], 4),
269+
np.round(fit.coupling[qubit], 4),
259270
np.round(fit.matrix_element[qubit], 4),
260271
],
261272
)
@@ -268,8 +279,8 @@ def _update(results: ResonatorFluxResults, platform: Platform, qubit: QubitId):
268279
update.bare_resonator_frequency(results.bare_frequency[qubit], platform, qubit)
269280
update.readout_frequency(results.frequency[qubit], platform, qubit)
270281
update.drive_frequency(results.drive_frequency[qubit], platform, qubit)
271-
update.asymmetry(results.d[qubit], platform, qubit)
272-
update.coupling(results.g[qubit], platform, qubit)
282+
update.asymmetry(results.asymmetry[qubit], platform, qubit)
283+
update.coupling(results.coupling[qubit], platform, qubit)
273284

274285

275286
resonator_flux = Routine(_acquisition, _fit, _plot, _update)

src/qibocal/protocols/characterization/flux_dependence/utils.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,11 @@ def flux_dependence_plot(data, fit, qubit, fit_function=None):
5252
)
5353

5454
# TODO: This fit is for frequency, can it be reused here, do we even want the fit ?
55-
if fit is not None and not data.__class__.__name__ == "CouplerSpectroscopyData":
55+
if (
56+
fit is not None
57+
and not data.__class__.__name__ == "CouplerSpectroscopyData"
58+
and qubit in fit.fitted_parameters
59+
):
5660
params = fit.fitted_parameters[qubit]
5761
bias = np.unique(qubit_data.bias)
5862
fig.add_trace(

0 commit comments

Comments
 (0)