From 3a7c3747cefff01d3f956ec2abfafde8aa41c0af Mon Sep 17 00:00:00 2001 From: Hayk Sargsyan <52532457+hay-k@users.noreply.github.com> Date: Thu, 17 Oct 2024 13:13:03 +0400 Subject: [PATCH 1/6] Switch to acquisition with qubit state discrimination --- .../protocols/couplers/coupler_chevron.py | 53 +++++-------------- 1 file changed, 12 insertions(+), 41 deletions(-) diff --git a/src/qibocal/protocols/couplers/coupler_chevron.py b/src/qibocal/protocols/couplers/coupler_chevron.py index 2a5195dd2..6892fbca7 100644 --- a/src/qibocal/protocols/couplers/coupler_chevron.py +++ b/src/qibocal/protocols/couplers/coupler_chevron.py @@ -1,6 +1,3 @@ -from dataclasses import dataclass -from typing import Optional - import numpy as np from qibolab import AcquisitionType, AveragingMode, ExecutionParameters from qibolab.platform import Platform @@ -18,25 +15,8 @@ from ..two_qubit_interaction.utils import order_pair -@dataclass -class ChevronCouplersParameters(ChevronParameters): - - native_gate: Optional[str] = "CZ" - """Native gate to implement, CZ or iSWAP.""" - - """ChevronCouplers protocol parameters. - - Amplitude and duration are referred to the coupler pulse. - """ - - -@dataclass -class ChevronCouplersData(ChevronData): - """Data structure for chevron couplers protocol.""" - - def _aquisition( - params: ChevronCouplersParameters, + params: ChevronParameters, platform: Platform, targets: list[QubitPairId], ) -> ChevronData: @@ -50,7 +30,7 @@ def _aquisition( targets (list): List of pairs to use sequentially. Returns: - ChevronCouplersData: Acquisition data. + ChevronData: Acquisition data. """ # define the parameter to sweep and its range: delta_amplitude_range = np.arange( @@ -62,16 +42,14 @@ def _aquisition( params.duration_min, params.duration_max, params.duration_step ) - # create a DataUnits object to store the results, data = ChevronData() - # sort high and low frequency qubit for pair in targets: sequence = PulseSequence() ordered_pair = order_pair(pair, platform) - # initialize in system in 11(CZ) or 10(iSWAP) state - if params.native_gate == "CZ": + # initialize system to state 11(CZ) or 10(iSWAP) + if params.native == "CZ": initialize_lowfreq = platform.create_RX_pulse(ordered_pair[0], start=0) sequence.add(initialize_lowfreq) @@ -79,12 +57,12 @@ def _aquisition( sequence.add(initialize_highfreq) - if params.native_gate == "CZ": + if params.native == "CZ": native_gate, _ = platform.create_CZ_pulse_sequence( (ordered_pair[1], ordered_pair[0]), start=sequence.finish + params.dt, ) - elif params.native_gate == "iSWAP": + elif params.native == "iSWAP": native_gate, _ = platform.create_iSWAP_pulse_sequence( (ordered_pair[1], ordered_pair[0]), start=sequence.finish + params.dt, @@ -115,42 +93,35 @@ def _aquisition( pulses=[p for p in native_gate.coupler_pulses(*pair)], ) - # repeat the experiment as many times as defined by nshots results = platform.sweep( sequence, ExecutionParameters( nshots=params.nshots, - acquisition_type=AcquisitionType.INTEGRATION, + acquisition_type=AcquisitionType.DISCRIMINATION, averaging_mode=AveragingMode.CYCLIC, ), sweeper_duration, sweeper_amplitude, ) - # TODO: Explore probabilities instead of magnitude data.register_qubit( ordered_pair[0], ordered_pair[1], delta_duration_range, delta_amplitude_range * data.native_amplitude[ordered_pair], - results[ordered_pair[0]].magnitude, - results[ordered_pair[1]].magnitude, + results[ordered_pair[0]].probability(state=1), + results[ordered_pair[1]].probability(state=1), ) return data -@dataclass -class ChevronCouplersResults(Results): - """Empty fitting outputs for chevron couplers is not implemented in this case.""" - - -def _fit(data: ChevronCouplersData) -> ChevronCouplersResults: +def _fit(data: ChevronData) -> Results: """ "Results for ChevronCouplers.""" - return ChevronCouplersResults() + return Results() -def plot(data: ChevronCouplersData, fit: ChevronCouplersResults, target): +def plot(data: ChevronData, fit: Results, target): return _plot(data, None, target) From 6307f678d4e832718ec45452c66d01c5580ecdbf Mon Sep 17 00:00:00 2001 From: Hayk Sargsyan <52532457+hay-k@users.noreply.github.com> Date: Thu, 17 Oct 2024 15:46:34 +0400 Subject: [PATCH 2/6] associate custom label with the plot --- src/qibocal/protocols/couplers/coupler_chevron.py | 1 + .../protocols/two_qubit_interaction/chevron/chevron.py | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/qibocal/protocols/couplers/coupler_chevron.py b/src/qibocal/protocols/couplers/coupler_chevron.py index 6892fbca7..aeea85dce 100644 --- a/src/qibocal/protocols/couplers/coupler_chevron.py +++ b/src/qibocal/protocols/couplers/coupler_chevron.py @@ -112,6 +112,7 @@ def _aquisition( results[ordered_pair[0]].probability(state=1), results[ordered_pair[1]].probability(state=1), ) + data.label = "Probability of state |1>" return data diff --git a/src/qibocal/protocols/two_qubit_interaction/chevron/chevron.py b/src/qibocal/protocols/two_qubit_interaction/chevron/chevron.py index c65ce9aeb..d11714e81 100644 --- a/src/qibocal/protocols/two_qubit_interaction/chevron/chevron.py +++ b/src/qibocal/protocols/two_qubit_interaction/chevron/chevron.py @@ -109,6 +109,9 @@ class ChevronData(Data): """Sweetspot value for high frequency qubit.""" data: dict[QubitPairId, npt.NDArray[ChevronType]] = field(default_factory=dict) + label: Optional[str] = None + """Label for the data.""" + def register_qubit(self, low_qubit, high_qubit, length, amp, prob_low, prob_high): """Store output for single qubit.""" size = len(length) * len(amp) @@ -308,7 +311,7 @@ def _plot(data: ChevronData, fit: ChevronResults, target: QubitPairId): fig.update_layout( xaxis_title="Duration [ns]", xaxis2_title="Duration [ns]", - yaxis_title="Amplitude [a.u.]", + yaxis_title=data.label or "Amplitude [a.u.]", legend=dict(orientation="h"), ) fig.update_layout( From 9bd0397c41e96f5a73c49c18fbd19e2d0a96827d Mon Sep 17 00:00:00 2001 From: Hayk Sargsyan <52532457+hay-k@users.noreply.github.com> Date: Thu, 17 Oct 2024 16:41:29 +0400 Subject: [PATCH 3/6] In coupler_chevron sweep the duration of qubit flux pulse(s)(if any) as well --- .../protocols/couplers/coupler_chevron.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/qibocal/protocols/couplers/coupler_chevron.py b/src/qibocal/protocols/couplers/coupler_chevron.py index aeea85dce..fc544398e 100644 --- a/src/qibocal/protocols/couplers/coupler_chevron.py +++ b/src/qibocal/protocols/couplers/coupler_chevron.py @@ -1,7 +1,7 @@ import numpy as np from qibolab import AcquisitionType, AveragingMode, ExecutionParameters from qibolab.platform import Platform -from qibolab.pulses import PulseSequence +from qibolab.pulses import PulseSequence, PulseType from qibolab.qubits import QubitPairId from qibolab.sweeper import Parameter, Sweeper, SweeperType @@ -81,16 +81,27 @@ def _aquisition( sequence += ro_pulse1 + ro_pulse2 + coupler_flux_pulses = [p for p in native_gate.coupler_pulses(*pair)] + assert ( + len(coupler_flux_pulses) == 1 + ), f"coupler_chevron expects exactly one coupler flux pulse, but {len(coupler_flux_pulses)} are present." + qubit_flux_pulses = [ + p for p in native_gate.get_qubit_pulses(*pair) if p.type is PulseType.FLUX + ] + assert all( + len(list(filter(lambda x: x.qubit == q, qubit_flux_pulses))) < 2 + for q in pair + ), f"coupler_chevron expects no more than 1 flux pulse for each qubit, but more are present for the pair {pair}" sweeper_amplitude = Sweeper( Parameter.amplitude, delta_amplitude_range, - pulses=[p for p in native_gate.coupler_pulses(*pair)][:1], + pulses=coupler_flux_pulses, type=SweeperType.FACTOR, ) sweeper_duration = Sweeper( Parameter.duration, delta_duration_range, - pulses=[p for p in native_gate.coupler_pulses(*pair)], + pulses=coupler_flux_pulses + qubit_flux_pulses, ) results = platform.sweep( From 1ca57b04bd54d72aa63abab51303303ce07f00d4 Mon Sep 17 00:00:00 2001 From: Hayk Sargsyan <52532457+hay-k@users.noreply.github.com> Date: Thu, 17 Oct 2024 16:51:09 +0400 Subject: [PATCH 4/6] update test runcard --- tests/runcards/protocols_couplers.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/runcards/protocols_couplers.yml b/tests/runcards/protocols_couplers.yml index 0c8dd1644..78a31ae02 100644 --- a/tests/runcards/protocols_couplers.yml +++ b/tests/runcards/protocols_couplers.yml @@ -66,7 +66,7 @@ actions: duration_min: 50 duration_max: 100 duration_step: 10 - native_gate: "CZ" + native: "CZ" dt: 5 nshots: 10 @@ -81,6 +81,6 @@ actions: duration_min: 50 duration_max: 100 duration_step: 10 - native_gate: "iSWAP" + native: "iSWAP" dt: 5 nshots: 10 From 5f4e7018252ff187c0a65ef9ee29529b4c9dacad Mon Sep 17 00:00:00 2001 From: Hayk Sargsyan <52532457+hay-k@users.noreply.github.com> Date: Fri, 18 Oct 2024 10:34:45 +0400 Subject: [PATCH 5/6] Fix docstring --- src/qibocal/protocols/couplers/coupler_chevron.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qibocal/protocols/couplers/coupler_chevron.py b/src/qibocal/protocols/couplers/coupler_chevron.py index fc544398e..d1b4a9fad 100644 --- a/src/qibocal/protocols/couplers/coupler_chevron.py +++ b/src/qibocal/protocols/couplers/coupler_chevron.py @@ -129,7 +129,7 @@ def _aquisition( def _fit(data: ChevronData) -> Results: - """ "Results for ChevronCouplers.""" + """Results for ChevronCouplers.""" return Results() From f724746dbf654c87183151a5df79f649970a2297 Mon Sep 17 00:00:00 2001 From: Hayk Sargsyan <52532457+hay-k@users.noreply.github.com> Date: Fri, 18 Oct 2024 11:36:20 +0400 Subject: [PATCH 6/6] fix typo --- src/qibocal/protocols/couplers/coupler_chevron.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qibocal/protocols/couplers/coupler_chevron.py b/src/qibocal/protocols/couplers/coupler_chevron.py index d1b4a9fad..dc69a71a9 100644 --- a/src/qibocal/protocols/couplers/coupler_chevron.py +++ b/src/qibocal/protocols/couplers/coupler_chevron.py @@ -15,7 +15,7 @@ from ..two_qubit_interaction.utils import order_pair -def _aquisition( +def _acquisition( params: ChevronParameters, platform: Platform, targets: list[QubitPairId], @@ -137,5 +137,5 @@ def plot(data: ChevronData, fit: Results, target): return _plot(data, None, target) -coupler_chevron = Routine(_aquisition, _fit, plot, two_qubit_gates=True) +coupler_chevron = Routine(_acquisition, _fit, plot, two_qubit_gates=True) """Coupler cz/swap flux routine."""