From 120a594f34be8380d4a1229c517963597629d527 Mon Sep 17 00:00:00 2001 From: Edoardo-Pedicillo Date: Tue, 26 Nov 2024 12:51:35 +0400 Subject: [PATCH 01/13] feat: xyz_timing protocol --- src/qibocal/protocols/__init__.py | 2 + src/qibocal/protocols/xyz_timing.py | 171 ++++++++++++++++++++++++++++ 2 files changed, 173 insertions(+) create mode 100644 src/qibocal/protocols/xyz_timing.py diff --git a/src/qibocal/protocols/__init__.py b/src/qibocal/protocols/__init__.py index f6aa87e61..cae853c47 100644 --- a/src/qibocal/protocols/__init__.py +++ b/src/qibocal/protocols/__init__.py @@ -52,6 +52,7 @@ optimize_two_qubit_gate, ) from .two_qubit_state_tomography import two_qubit_state_tomography +from .xyz_timing import xyz_timing __all__ = [ "allxy", @@ -104,4 +105,5 @@ "standard_rb_2q_inter", "optimize_two_qubit_gate", "ramsey_zz", + "xyz_timing", ] diff --git a/src/qibocal/protocols/xyz_timing.py b/src/qibocal/protocols/xyz_timing.py new file mode 100644 index 000000000..91c5ade8a --- /dev/null +++ b/src/qibocal/protocols/xyz_timing.py @@ -0,0 +1,171 @@ +from dataclasses import dataclass, field + +import numpy as np +import numpy.typing as npt +import plotly.graph_objects as go +from qibolab import ( + AcquisitionType, + AveragingMode, + Delay, + Parameter, + Pulse, + PulseSequence, + Rectangular, + Sweeper, +) + +from qibocal.auto.operation import Data, Parameters, Results, Routine +from qibocal.calibration.calibration import QubitId +from qibocal.calibration.platform import CalibrationPlatform +from qibocal.result import probability + +COLORBAND = "rgba(0,100,80,0.2)" +COLORBAND_LINE = "rgba(255,255,255,0)" + + +@dataclass +class XYZTimingResults(Results): + pass + + +@dataclass +class XYZTimingParameters(Parameters): + + flux_amplitude: float + delay_step: float + delay_stop: float + flux_pulse_duration: float + + +XYZTimingType = np.dtype( + [("delay", np.float64), ("prob", np.float64), ("errors", np.float64)] +) + + +@dataclass +class XYZTimingData(Data): + + data: dict[QubitId, npt.NDArray] = field(default_factory=dict) + """Raw data acquired.""" + + +def _acquisition( + params: XYZTimingParameters, + platform: CalibrationPlatform, + targets: list[QubitId], +) -> XYZTimingData: + + data = XYZTimingData() + natives = platform.natives.single_qubit + delays = np.arange( + 0, + params.delay_stop, + params.delay_step, + ) + sequence = PulseSequence() + flux_delays = [] + for qubit in targets: + drive_channel = platform.qubits[qubit].drive + flux_channel = platform.qubits[qubit].flux + ro_channel = platform.qubits[qubit].acquisition + drive_pulse = natives[qubit].RX()[0] + readout_pulse = natives[qubit].MZ()[0] + + flux_pulse = Pulse( + duration=params.flux_pulse_duration, + amplitude=params.flux_amplitude, + relative_phase=0, + envelope=Rectangular(), + ) + qd_delay = Delay(duration=params.flux_pulse_duration) + flux_delay = Delay(duration=0) + flux_delays.append(flux_delay) + + sequence.extend( + [ + (drive_channel, qd_delay), + drive_pulse, + (flux_channel, flux_delay), + (flux_channel, flux_pulse), + ] + ) + sequence.align([drive_channel, flux_channel, ro_channel]) + sequence.append(readout_pulse) + + sweeper = Sweeper( + parameter=Parameter.duration, + values=delays, + pulses=flux_delays, + ) + + results = platform.execute( + [sequence], + [[sweeper]], + nshots=params.nshots, + relaxation_time=params.relaxation_time, + acquisition_type=AcquisitionType.DISCRIMINATION, + averaging_mode=AveragingMode.SINGLESHOT, + ) + + for qubit in targets: + ro_pulse = list(sequence.channel(platform.qubits[qubit].acquisition)) + ro_pulse = list(sequence.channel(platform.qubits[qubit].acquisition))[-1] + probs = probability(results[ro_pulse.id], state=1) + # The probability errors are the standard errors of the binomial distribution + errors = [np.sqrt(prob * (1 - prob) / params.nshots) for prob in probs] + data.register_qubit( + XYZTimingType, + (qubit), + dict( + delay=delays, + prob=probs, + errors=errors, + ), + ) + return data + + +def _fit(data: XYZTimingData) -> XYZTimingResults: + return XYZTimingResults() + + +def _plot(data: XYZTimingData, target: QubitId, fit: XYZTimingResults = None): + figures = [] + qubit_data = data.data[target] + delays = qubit_data.delay + probs = qubit_data.prob + error_bars = qubit_data.errors + fig = go.Figure( + [ + go.Scatter( + x=delays, + y=probs, + opacity=1, + name="Probability of State 0", + showlegend=True, + legendgroup="Probability of State 0", + mode="lines", + ), + go.Scatter( + x=np.concatenate((delays, delays[::-1])), + y=np.concatenate((probs + error_bars, (probs - error_bars)[::-1])), + fill="toself", + fillcolor=COLORBAND, + line=dict(color=COLORBAND_LINE), + showlegend=True, + name="Errors", + ), + ] + ) + fig.update_layout( + showlegend=True, + xaxis_title="Time [ns]", + yaxis_title="Ground state probability", + ) + + figures.append(fig) + + return figures, "" + + +xyz_timing = Routine(_acquisition, _fit, _plot) From 40cfe4ed0b4e42001bbc2fe9ea22714089c3ecb8 Mon Sep 17 00:00:00 2001 From: Edoardo-Pedicillo Date: Fri, 6 Dec 2024 13:08:37 +0800 Subject: [PATCH 02/13] fix: use padding instead of delays --- src/qibocal/protocols/xyz_timing.py | 130 ++++++++++++++-------------- 1 file changed, 67 insertions(+), 63 deletions(-) diff --git a/src/qibocal/protocols/xyz_timing.py b/src/qibocal/protocols/xyz_timing.py index 91c5ade8a..889f33cdf 100644 --- a/src/qibocal/protocols/xyz_timing.py +++ b/src/qibocal/protocols/xyz_timing.py @@ -3,16 +3,7 @@ import numpy as np import numpy.typing as npt import plotly.graph_objects as go -from qibolab import ( - AcquisitionType, - AveragingMode, - Delay, - Parameter, - Pulse, - PulseSequence, - Rectangular, - Sweeper, -) +from qibolab import AcquisitionType, AveragingMode, Custom, Delay, Pulse, PulseSequence from qibocal.auto.operation import Data, Parameters, Results, Routine from qibocal.calibration.calibration import QubitId @@ -57,71 +48,84 @@ def _acquisition( data = XYZTimingData() natives = platform.natives.single_qubit - delays = np.arange( + durations = np.arange( 0, params.delay_stop, params.delay_step, ) - sequence = PulseSequence() flux_delays = [] - for qubit in targets: - drive_channel = platform.qubits[qubit].drive - flux_channel = platform.qubits[qubit].flux - ro_channel = platform.qubits[qubit].acquisition - drive_pulse = natives[qubit].RX()[0] - readout_pulse = natives[qubit].MZ()[0] - - flux_pulse = Pulse( - duration=params.flux_pulse_duration, - amplitude=params.flux_amplitude, - relative_phase=0, - envelope=Rectangular(), - ) - qd_delay = Delay(duration=params.flux_pulse_duration) - flux_delay = Delay(duration=0) - flux_delays.append(flux_delay) - - sequence.extend( - [ - (drive_channel, qd_delay), - drive_pulse, - (flux_channel, flux_delay), - (flux_channel, flux_pulse), - ] - ) - sequence.align([drive_channel, flux_channel, ro_channel]) - sequence.append(readout_pulse) - - sweeper = Sweeper( - parameter=Parameter.duration, - values=delays, - pulses=flux_delays, - ) + sequences = [] + ro_pulses = [] + for duration in durations: + ro_pulses.append([]) + for qubit in targets: + sequence = PulseSequence() + drive_channel = platform.qubits[qubit].drive + flux_channel = platform.qubits[qubit].flux + ro_channel = platform.qubits[qubit].acquisition + drive_pulse = natives[qubit].RX()[0] + readout_pulse = natives[qubit].MZ()[0] + + flux_pulse = Pulse( + duration=params.flux_pulse_duration, + amplitude=params.flux_amplitude, + relative_phase=0, + envelope=Custom( + i_=np.concatenate([np.zeros(duration), np.ones(50), np.zeros(10)]), + q_=np.zeros(duration), + ), + ) + # flux_pulse = Pulse( + # duration=params.flux_pulse_duration, + # amplitude=params.flux_amplitude, + # relative_phase=0, + # envelope=Rectangular(), + # ) + qd_delay = Delay(duration=params.flux_pulse_duration) + # flux_delay = Delay(duration=0) + # flux_delays.append(flux_delay) + + sequence.extend( + [ + (drive_channel, qd_delay), + drive_pulse, + (flux_channel, flux_pulse), + ] + ) + sequence.align([drive_channel, flux_channel, ro_channel]) + sequence.append(readout_pulse) + sequences.append(sequence) + ro_pulses[-1].append(readout_pulse) + # sweeper = Sweeper( + # parameter=Parameter.duration, + # values=delays, + # pulses=flux_delays, + # ) results = platform.execute( - [sequence], - [[sweeper]], + sequences, nshots=params.nshots, relaxation_time=params.relaxation_time, acquisition_type=AcquisitionType.DISCRIMINATION, averaging_mode=AveragingMode.SINGLESHOT, ) - - for qubit in targets: - ro_pulse = list(sequence.channel(platform.qubits[qubit].acquisition)) - ro_pulse = list(sequence.channel(platform.qubits[qubit].acquisition))[-1] - probs = probability(results[ro_pulse.id], state=1) - # The probability errors are the standard errors of the binomial distribution - errors = [np.sqrt(prob * (1 - prob) / params.nshots) for prob in probs] - data.register_qubit( - XYZTimingType, - (qubit), - dict( - delay=delays, - prob=probs, - errors=errors, - ), - ) + for i, duration in enumerate(durations): + for j, qubit in enumerate(targets): + ro_pulse = ro_pulses[i][j][1] + print(ro_pulse) + prob = probability(results[ro_pulse.id], state=1) + print(prob) + # The probability errors are the standard errors of the binomial distribution + error = np.sqrt(prob * (1 - prob) / params.nshots) + data.register_qubit( + XYZTimingType, + (qubit), + dict( + delay=np.array([duration]), + prob=np.array([prob]), + errors=np.array([error]), + ), + ) return data From 6650a1b27c7ecfef9a0904bcd4fe96d63197a2f7 Mon Sep 17 00:00:00 2001 From: Edoardo-Pedicillo Date: Fri, 6 Dec 2024 10:50:40 +0400 Subject: [PATCH 03/13] fix: same duration for drive and flux pulse --- src/qibocal/protocols/xyz_timing.py | 54 ++++++++++++++--------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/src/qibocal/protocols/xyz_timing.py b/src/qibocal/protocols/xyz_timing.py index 889f33cdf..c5527c539 100644 --- a/src/qibocal/protocols/xyz_timing.py +++ b/src/qibocal/protocols/xyz_timing.py @@ -12,6 +12,7 @@ COLORBAND = "rgba(0,100,80,0.2)" COLORBAND_LINE = "rgba(255,255,255,0)" +PADDING_FLUX = 10 @dataclass @@ -23,9 +24,8 @@ class XYZTimingResults(Results): class XYZTimingParameters(Parameters): flux_amplitude: float - delay_step: float - delay_stop: float - flux_pulse_duration: float + delay_step: int + delay_stop: int XYZTimingType = np.dtype( @@ -36,6 +36,8 @@ class XYZTimingParameters(Parameters): @dataclass class XYZTimingData(Data): + pulse_duration: dict[QubitId, int] + """Duration of the drive and flux pulse""" data: dict[QubitId, npt.NDArray] = field(default_factory=dict) """Raw data acquired.""" @@ -46,16 +48,21 @@ def _acquisition( targets: list[QubitId], ) -> XYZTimingData: - data = XYZTimingData() natives = platform.natives.single_qubit durations = np.arange( - 0, + 1, params.delay_stop, params.delay_step, ) flux_delays = [] sequences = [] ro_pulses = [] + drive_durations = {} + for qubit in targets: + drive_pulse = natives[qubit].RX()[0] + drive_durations[qubit] = int(drive_pulse[1].duration) + + data = XYZTimingData(pulse_duration=drive_durations) for duration in durations: ro_pulses.append([]) for qubit in targets: @@ -65,25 +72,24 @@ def _acquisition( ro_channel = platform.qubits[qubit].acquisition drive_pulse = natives[qubit].RX()[0] readout_pulse = natives[qubit].MZ()[0] - + drive_duration = int(drive_pulse[1].duration) + total_flux_duration = duration + drive_duration + PADDING_FLUX flux_pulse = Pulse( - duration=params.flux_pulse_duration, + duration=total_flux_duration, amplitude=params.flux_amplitude, relative_phase=0, envelope=Custom( - i_=np.concatenate([np.zeros(duration), np.ones(50), np.zeros(10)]), - q_=np.zeros(duration), + i_=np.concatenate( + [ + np.zeros(duration), + np.ones(drive_duration), + np.zeros(PADDING_FLUX), + ] + ), + q_=np.zeros(total_flux_duration), ), ) - # flux_pulse = Pulse( - # duration=params.flux_pulse_duration, - # amplitude=params.flux_amplitude, - # relative_phase=0, - # envelope=Rectangular(), - # ) - qd_delay = Delay(duration=params.flux_pulse_duration) - # flux_delay = Delay(duration=0) - # flux_delays.append(flux_delay) + qd_delay = Delay(duration=drive_duration) sequence.extend( [ @@ -96,11 +102,6 @@ def _acquisition( sequence.append(readout_pulse) sequences.append(sequence) ro_pulses[-1].append(readout_pulse) - # sweeper = Sweeper( - # parameter=Parameter.duration, - # values=delays, - # pulses=flux_delays, - # ) results = platform.execute( sequences, @@ -112,9 +113,7 @@ def _acquisition( for i, duration in enumerate(durations): for j, qubit in enumerate(targets): ro_pulse = ro_pulses[i][j][1] - print(ro_pulse) prob = probability(results[ro_pulse.id], state=1) - print(prob) # The probability errors are the standard errors of the binomial distribution error = np.sqrt(prob * (1 - prob) / params.nshots) data.register_qubit( @@ -139,10 +138,11 @@ def _plot(data: XYZTimingData, target: QubitId, fit: XYZTimingResults = None): delays = qubit_data.delay probs = qubit_data.prob error_bars = qubit_data.errors + x = delays - data.pulse_duration[target] fig = go.Figure( [ go.Scatter( - x=delays, + x=x, y=probs, opacity=1, name="Probability of State 0", @@ -151,7 +151,7 @@ def _plot(data: XYZTimingData, target: QubitId, fit: XYZTimingResults = None): mode="lines", ), go.Scatter( - x=np.concatenate((delays, delays[::-1])), + x=np.concatenate((x, x[::-1])), y=np.concatenate((probs + error_bars, (probs - error_bars)[::-1])), fill="toself", fillcolor=COLORBAND, From 0ff181dc20580d5d3c8194567433dbcf1f384b89 Mon Sep 17 00:00:00 2001 From: Edoardo-Pedicillo Date: Mon, 9 Dec 2024 15:46:37 +0400 Subject: [PATCH 04/13] feat: fit data in xyz-timing --- src/qibocal/protocols/xyz_timing.py | 46 +++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/src/qibocal/protocols/xyz_timing.py b/src/qibocal/protocols/xyz_timing.py index c5527c539..581733e60 100644 --- a/src/qibocal/protocols/xyz_timing.py +++ b/src/qibocal/protocols/xyz_timing.py @@ -3,7 +3,9 @@ import numpy as np import numpy.typing as npt import plotly.graph_objects as go +from qibo.models.error_mitigation import curve_fit from qibolab import AcquisitionType, AveragingMode, Custom, Delay, Pulse, PulseSequence +from scipy import special from qibocal.auto.operation import Data, Parameters, Results, Routine from qibocal.calibration.calibration import QubitId @@ -17,7 +19,9 @@ @dataclass class XYZTimingResults(Results): - pass + fitted_parameters: dict[QubitId, list[float]] + fitted_errors: dict[QubitId, list[float]] + delays: dict[QubitId, float] @dataclass @@ -128,8 +132,46 @@ def _acquisition( return data +def fit_function(x, a, b, c, d): + return a + b * (special.erf(x - c) - special.erf(x + d)) + + def _fit(data: XYZTimingData) -> XYZTimingResults: - return XYZTimingResults() + qubits = data.qubits + params = {} + errors = {} + delays = {} + for qubit in qubits: + data_qubit = qubits[qubit] + delay = data_qubit.delay + prob = data_qubit.prob + err = data_qubit.errors + initial_pars = [ + 1, + -0.5, + data.pulse_duration[qubit] / 2, + data.pulse_duration[qubit] / 2, + ] + fit_parameters, perr = curve_fit( + fit_function, + delay - data.pulse_duration[qubit], + prob, + p0=initial_pars, + sigma=err, + ) + + err = np.sqrt(np.diag(perr)).tolist() + params[qubit] = fit_parameters + errors[qubit] = err + delays[qubit] = [ + (fit_parameters[3] - fit_parameters[2]) / 2, + np.linalg.norm([err[2], err[3]]) / 2, + ] + return XYZTimingResults( + fitted_parameters=params, + fitted_errors=errors, + delays=delays, + ) def _plot(data: XYZTimingData, target: QubitId, fit: XYZTimingResults = None): From 8d6e59c9ac41c478eb79addc38c21a5254523e95 Mon Sep 17 00:00:00 2001 From: Edoardo-Pedicillo Date: Mon, 9 Dec 2024 19:02:03 +0400 Subject: [PATCH 05/13] feat: report delay --- src/qibocal/protocols/xyz_timing.py | 47 +++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/src/qibocal/protocols/xyz_timing.py b/src/qibocal/protocols/xyz_timing.py index 581733e60..d57220707 100644 --- a/src/qibocal/protocols/xyz_timing.py +++ b/src/qibocal/protocols/xyz_timing.py @@ -12,6 +12,8 @@ from qibocal.calibration.platform import CalibrationPlatform from qibocal.result import probability +from .utils import table_dict, table_html + COLORBAND = "rgba(0,100,80,0.2)" COLORBAND_LINE = "rgba(255,255,255,0)" PADDING_FLUX = 10 @@ -132,8 +134,8 @@ def _acquisition( return data -def fit_function(x, a, b, c, d): - return a + b * (special.erf(x - c) - special.erf(x + d)) +def fit_function(x, a, b, c, d, e): + return a + b * (special.erf(e * x - c) - special.erf(e * x + d)) def _fit(data: XYZTimingData) -> XYZTimingResults: @@ -142,15 +144,16 @@ def _fit(data: XYZTimingData) -> XYZTimingResults: errors = {} delays = {} for qubit in qubits: - data_qubit = qubits[qubit] + data_qubit = data.data[qubit] delay = data_qubit.delay prob = data_qubit.prob err = data_qubit.errors initial_pars = [ 1, - -0.5, + 0.5, data.pulse_duration[qubit] / 2, data.pulse_duration[qubit] / 2, + 1, ] fit_parameters, perr = curve_fit( fit_function, @@ -161,11 +164,11 @@ def _fit(data: XYZTimingData) -> XYZTimingResults: ) err = np.sqrt(np.diag(perr)).tolist() - params[qubit] = fit_parameters + params[qubit] = fit_parameters.tolist() errors[qubit] = err delays[qubit] = [ - (fit_parameters[3] - fit_parameters[2]) / 2, - np.linalg.norm([err[2], err[3]]) / 2, + (fit_parameters[2] - fit_parameters[3]) / (2 * fit_parameters[4]), + float(np.linalg.norm([err[2], err[3]]) / 2) / fit_parameters[4] ** 2, ] return XYZTimingResults( fitted_parameters=params, @@ -181,13 +184,23 @@ def _plot(data: XYZTimingData, target: QubitId, fit: XYZTimingResults = None): probs = qubit_data.prob error_bars = qubit_data.errors x = delays - data.pulse_duration[target] + fitting_report = "" fig = go.Figure( [ go.Scatter( x=x, y=probs, opacity=1, - name="Probability of State 0", + name="Probability of State 1", + showlegend=True, + legendgroup="Probability of State 1", + mode="lines", + ), + go.Scatter( + x=x, + y=fit_function(x, *fit.fitted_parameters[target]), + opacity=1, + name="Fit", showlegend=True, legendgroup="Probability of State 0", mode="lines", @@ -203,15 +216,29 @@ def _plot(data: XYZTimingData, target: QubitId, fit: XYZTimingResults = None): ), ] ) + if fit is not None: + fig.add_vline( + x=fit.delays[target][0], + line=dict(color="grey", width=3, dash="dash"), + ) + fitting_report = table_html( + table_dict( + target, + ["Flux pulse delay [ns]"], + [fit.delays[target]], + display_error=True, + ) + ) + fig.update_layout( showlegend=True, xaxis_title="Time [ns]", - yaxis_title="Ground state probability", + yaxis_title="Excited state probability", ) figures.append(fig) - return figures, "" + return figures, fitting_report xyz_timing = Routine(_acquisition, _fit, _plot) From 1e1b70d398560bebd55ec493cc35f028b3321992 Mon Sep 17 00:00:00 2001 From: Edoardo-Pedicillo Date: Thu, 16 Jan 2025 12:34:13 +0400 Subject: [PATCH 06/13] fix: move the fit curve in the fit branch --- src/qibocal/protocols/xyz_timing.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/qibocal/protocols/xyz_timing.py b/src/qibocal/protocols/xyz_timing.py index d57220707..119cc4f28 100644 --- a/src/qibocal/protocols/xyz_timing.py +++ b/src/qibocal/protocols/xyz_timing.py @@ -196,15 +196,6 @@ def _plot(data: XYZTimingData, target: QubitId, fit: XYZTimingResults = None): legendgroup="Probability of State 1", mode="lines", ), - go.Scatter( - x=x, - y=fit_function(x, *fit.fitted_parameters[target]), - opacity=1, - name="Fit", - showlegend=True, - legendgroup="Probability of State 0", - mode="lines", - ), go.Scatter( x=np.concatenate((x, x[::-1])), y=np.concatenate((probs + error_bars, (probs - error_bars)[::-1])), @@ -217,6 +208,17 @@ def _plot(data: XYZTimingData, target: QubitId, fit: XYZTimingResults = None): ] ) if fit is not None: + fig.add_trace( + go.Scatter( + x=x, + y=fit_function(x, *fit.fitted_parameters[target]), + opacity=1, + name="Fit", + showlegend=True, + legendgroup="Probability of State 0", + mode="lines", + ), + ) fig.add_vline( x=fit.delays[target][0], line=dict(color="grey", width=3, dash="dash"), From 50b44f2bc1fa8d5f8ebac7dc6c4e57f65b2a1aa9 Mon Sep 17 00:00:00 2001 From: Edoardo-Pedicillo Date: Mon, 20 Jan 2025 16:01:30 +0400 Subject: [PATCH 07/13] docs: write proper documentation for xyz-timing routine --- doc/source/protocols/index.rst | 2 ++ doc/source/protocols/xyz_timing.png | Bin 0 -> 73607 bytes doc/source/protocols/xyz_timing.rst | 36 ++++++++++++++++++++++++++++ src/qibocal/protocols/xyz_timing.py | 15 +++++++++--- 4 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 doc/source/protocols/xyz_timing.png create mode 100644 doc/source/protocols/xyz_timing.rst diff --git a/doc/source/protocols/index.rst b/doc/source/protocols/index.rst index 65d13f95d..d1bc47b2d 100644 --- a/doc/source/protocols/index.rst +++ b/doc/source/protocols/index.rst @@ -33,5 +33,7 @@ In this section we introduce the basics of all protocols supported by ``qibocal` standard_rb chevron virtual_z + xyz_timing state_tomographies + references diff --git a/doc/source/protocols/xyz_timing.png b/doc/source/protocols/xyz_timing.png new file mode 100644 index 0000000000000000000000000000000000000000..d40485669db5dddbffb85cfc770c65dc00ccc56a GIT binary patch literal 73607 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�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 literal 0 HcmV?d00001 diff --git a/doc/source/protocols/xyz_timing.rst b/doc/source/protocols/xyz_timing.rst new file mode 100644 index 000000000..e4889e55e --- /dev/null +++ b/doc/source/protocols/xyz_timing.rst @@ -0,0 +1,36 @@ +XYZ-TIMING +========== + +This routine is evaluating the different time of arrival of the flux and drive +pulse to the qubit. These delays are usually originated by the differences in +cable length or by the electronics. + +In this procedure, we vary the relative start times of the flux and drive pulses, +keeping their durations identical. +By measuring the probability of the qubit being in the excited state, +we identify the point where the two pulses arrive simultaneously. +At this point, the probability drops to zero because the qubit is off-resonance, +allowing us to determine the delay. + +Parameters +^^^^^^^^^^ + +.. autoclass:: + qibocal.protocols.xyz_timing.XYZTimingParameters + :noindex: + +Example +^^^^^^^ +It follows a runcard example of this experiment and the report. + +.. code-block:: yaml + + - id: xyz_timing + operation: xyz_timing + parameters: + delay_step: 1 + delay_stop: 100 + flux_amplitude: 0.3 + nshots: 5000The expected output is the following: + +.. image:: xyz_timing.png diff --git a/src/qibocal/protocols/xyz_timing.py b/src/qibocal/protocols/xyz_timing.py index 119cc4f28..b0486b463 100644 --- a/src/qibocal/protocols/xyz_timing.py +++ b/src/qibocal/protocols/xyz_timing.py @@ -21,17 +21,26 @@ @dataclass class XYZTimingResults(Results): + """Outputs of the xyz-timing protocol.""" + fitted_parameters: dict[QubitId, list[float]] + """Output parameters of the fitted function.""" fitted_errors: dict[QubitId, list[float]] + """Errors of the fit parameters.""" delays: dict[QubitId, float] + """Flux-drive delays.""" @dataclass class XYZTimingParameters(Parameters): + """XYZ-timing runcard inputs.""" flux_amplitude: float + """Amplitude of the flux pulse.""" delay_step: int + """Sweeper step value of the relative starts.""" delay_stop: int + """Sweeper stop value of the relative starts.""" XYZTimingType = np.dtype( @@ -53,14 +62,13 @@ def _acquisition( platform: CalibrationPlatform, targets: list[QubitId], ) -> XYZTimingData: - + """Data acquisition for drive-flux channels timing""" natives = platform.natives.single_qubit durations = np.arange( 1, params.delay_stop, params.delay_step, ) - flux_delays = [] sequences = [] ro_pulses = [] drive_durations = {} @@ -120,7 +128,6 @@ def _acquisition( for j, qubit in enumerate(targets): ro_pulse = ro_pulses[i][j][1] prob = probability(results[ro_pulse.id], state=1) - # The probability errors are the standard errors of the binomial distribution error = np.sqrt(prob * (1 - prob) / params.nshots) data.register_qubit( XYZTimingType, @@ -139,6 +146,7 @@ def fit_function(x, a, b, c, d, e): def _fit(data: XYZTimingData) -> XYZTimingResults: + """Post-processing for drive-flux channels timing""" qubits = data.qubits params = {} errors = {} @@ -178,6 +186,7 @@ def _fit(data: XYZTimingData) -> XYZTimingResults: def _plot(data: XYZTimingData, target: QubitId, fit: XYZTimingResults = None): + """Plotting function for drive-flux channels timing""" figures = [] qubit_data = data.data[target] delays = qubit_data.delay From c60b0f86be7428f901e44ec2d723418a25679e42 Mon Sep 17 00:00:00 2001 From: Edoardo-Pedicillo Date: Mon, 20 Jan 2025 16:12:39 +0400 Subject: [PATCH 08/13] test: add test for xyz_timing and fix docs --- doc/source/protocols/xyz_timing.rst | 1 - tests/runcards/protocols.yml | 7 +++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/doc/source/protocols/xyz_timing.rst b/doc/source/protocols/xyz_timing.rst index e4889e55e..f85eb0d39 100644 --- a/doc/source/protocols/xyz_timing.rst +++ b/doc/source/protocols/xyz_timing.rst @@ -31,6 +31,5 @@ It follows a runcard example of this experiment and the report. delay_step: 1 delay_stop: 100 flux_amplitude: 0.3 - nshots: 5000The expected output is the following: .. image:: xyz_timing.png diff --git a/tests/runcards/protocols.yml b/tests/runcards/protocols.yml index 9c54bd387..5239496b6 100644 --- a/tests/runcards/protocols.yml +++ b/tests/runcards/protocols.yml @@ -850,3 +850,10 @@ actions: parameters: nshots: 1024 circuit: tests/circuit2q.json + + - id: xyz_timing + operation: xyz_timing + parameters: + delay_step: 1 + delay_stop: 10 + flux_amplitude: 0.3 From f759ac6d67305a31a20046432606ae87c89ead43 Mon Sep 17 00:00:00 2001 From: Edoardo Pedicillo Date: Tue, 21 Jan 2025 10:30:38 +0400 Subject: [PATCH 09/13] Apply suggestions from code review Co-authored-by: Andrea Pasquale --- doc/source/protocols/xyz_timing.rst | 4 ++-- src/qibocal/protocols/xyz_timing.py | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/doc/source/protocols/xyz_timing.rst b/doc/source/protocols/xyz_timing.rst index f85eb0d39..3d572af48 100644 --- a/doc/source/protocols/xyz_timing.rst +++ b/doc/source/protocols/xyz_timing.rst @@ -1,8 +1,8 @@ XYZ-TIMING ========== -This routine is evaluating the different time of arrival of the flux and drive -pulse to the qubit. These delays are usually originated by the differences in +This protocol is evaluating the different time of arrival of the flux and drive +pulse to the qubit. These delays are usually caused by differences in cable length or by the electronics. In this procedure, we vary the relative start times of the flux and drive pulses, diff --git a/src/qibocal/protocols/xyz_timing.py b/src/qibocal/protocols/xyz_timing.py index b0486b463..2008506c2 100644 --- a/src/qibocal/protocols/xyz_timing.py +++ b/src/qibocal/protocols/xyz_timing.py @@ -147,11 +147,10 @@ def fit_function(x, a, b, c, d, e): def _fit(data: XYZTimingData) -> XYZTimingResults: """Post-processing for drive-flux channels timing""" - qubits = data.qubits params = {} errors = {} delays = {} - for qubit in qubits: + for qubit in data.qubits: data_qubit = data.data[qubit] delay = data_qubit.delay prob = data_qubit.prob From e3b308a74724f8f0cfae0fe5f28378b006b574e8 Mon Sep 17 00:00:00 2001 From: Edoardo-Pedicillo Date: Tue, 21 Jan 2025 10:42:35 +0400 Subject: [PATCH 10/13] fix: remove flux padding and add missing docs --- src/qibocal/protocols/xyz_timing.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/qibocal/protocols/xyz_timing.py b/src/qibocal/protocols/xyz_timing.py index b0486b463..092fb17f0 100644 --- a/src/qibocal/protocols/xyz_timing.py +++ b/src/qibocal/protocols/xyz_timing.py @@ -16,7 +16,6 @@ COLORBAND = "rgba(0,100,80,0.2)" COLORBAND_LINE = "rgba(255,255,255,0)" -PADDING_FLUX = 10 @dataclass @@ -87,7 +86,7 @@ def _acquisition( drive_pulse = natives[qubit].RX()[0] readout_pulse = natives[qubit].MZ()[0] drive_duration = int(drive_pulse[1].duration) - total_flux_duration = duration + drive_duration + PADDING_FLUX + total_flux_duration = duration + drive_duration flux_pulse = Pulse( duration=total_flux_duration, amplitude=params.flux_amplitude, @@ -97,7 +96,6 @@ def _acquisition( [ np.zeros(duration), np.ones(drive_duration), - np.zeros(PADDING_FLUX), ] ), q_=np.zeros(total_flux_duration), @@ -142,6 +140,7 @@ def _acquisition( def fit_function(x, a, b, c, d, e): + """Fit function of the xyz-timing protocol""" return a + b * (special.erf(e * x - c) - special.erf(e * x + d)) From 7af453dfdc5b3b24a73434e4c504ec6fb0e680a6 Mon Sep 17 00:00:00 2001 From: Edoardo-Pedicillo Date: Fri, 24 Jan 2025 13:03:25 +0400 Subject: [PATCH 11/13] doc: add documentation for COLORBAND and COLORBAND_LINE --- src/qibocal/protocols/xyz_timing.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/qibocal/protocols/xyz_timing.py b/src/qibocal/protocols/xyz_timing.py index 20525af6e..2eb670869 100644 --- a/src/qibocal/protocols/xyz_timing.py +++ b/src/qibocal/protocols/xyz_timing.py @@ -15,7 +15,9 @@ from .utils import table_dict, table_html COLORBAND = "rgba(0,100,80,0.2)" +"""Color of the error bands.""" COLORBAND_LINE = "rgba(255,255,255,0)" +"""Color of the plot line.""" @dataclass From 18a53cda0200595eef773406eb5773c3eedd0d08 Mon Sep 17 00:00:00 2001 From: Edoardo Pedicillo Date: Fri, 24 Jan 2025 13:03:48 +0400 Subject: [PATCH 12/13] Update src/qibocal/protocols/xyz_timing.py Co-authored-by: Andrea Pasquale --- src/qibocal/protocols/xyz_timing.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qibocal/protocols/xyz_timing.py b/src/qibocal/protocols/xyz_timing.py index 20525af6e..696cdcf73 100644 --- a/src/qibocal/protocols/xyz_timing.py +++ b/src/qibocal/protocols/xyz_timing.py @@ -83,8 +83,8 @@ def _acquisition( drive_channel = platform.qubits[qubit].drive flux_channel = platform.qubits[qubit].flux ro_channel = platform.qubits[qubit].acquisition - drive_pulse = natives[qubit].RX()[0] - readout_pulse = natives[qubit].MZ()[0] + drive_channel, drive_pulse = natives[qubit].RX()[0] + readout_channel, readout_pulse = natives[qubit].MZ()[0] drive_duration = int(drive_pulse[1].duration) total_flux_duration = duration + drive_duration flux_pulse = Pulse( From 9f9a9d2b90ffa20ca81de6bf3fcb5028b3431808 Mon Sep 17 00:00:00 2001 From: Edoardo-Pedicillo Date: Fri, 24 Jan 2025 13:10:46 +0400 Subject: [PATCH 13/13] refactor: merge all sequences in a PulseSequence --- src/qibocal/protocols/xyz_timing.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/qibocal/protocols/xyz_timing.py b/src/qibocal/protocols/xyz_timing.py index 2eb670869..6847cec66 100644 --- a/src/qibocal/protocols/xyz_timing.py +++ b/src/qibocal/protocols/xyz_timing.py @@ -78,10 +78,10 @@ def _acquisition( drive_durations[qubit] = int(drive_pulse[1].duration) data = XYZTimingData(pulse_duration=drive_durations) + sequence = PulseSequence() for duration in durations: ro_pulses.append([]) for qubit in targets: - sequence = PulseSequence() drive_channel = platform.qubits[qubit].drive flux_channel = platform.qubits[qubit].flux ro_channel = platform.qubits[qubit].acquisition @@ -114,11 +114,11 @@ def _acquisition( ) sequence.align([drive_channel, flux_channel, ro_channel]) sequence.append(readout_pulse) - sequences.append(sequence) + # sequences.append(sequence) ro_pulses[-1].append(readout_pulse) results = platform.execute( - sequences, + [sequence], nshots=params.nshots, relaxation_time=params.relaxation_time, acquisition_type=AcquisitionType.DISCRIMINATION,