Source code for qibocal.protocols.rabi.ef

from dataclasses import dataclass

import numpy as np
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 import update
from qibocal.auto.operation import Routine

from . import amplitude_signal, utils


[docs]@dataclass class RabiAmplitudeEFParameters(amplitude_signal.RabiAmplitudeSignalParameters): """RabiAmplitudeEF runcard inputs."""
[docs]@dataclass class RabiAmplitudeEFResults(amplitude_signal.RabiAmplitudeSignalResults): """RabiAmplitudeEF outputs."""
[docs]@dataclass class RabiAmplitudeEFData(amplitude_signal.RabiAmplitudeSignalData): """RabiAmplitude data acquisition."""
[docs]def _acquisition( params: RabiAmplitudeEFParameters, platform: Platform, targets: list[QubitId] ) -> RabiAmplitudeEFData: r""" Data acquisition for Rabi EF experiment sweeping amplitude. The rabi protocol is performed after exciting the qubit to state 1. This protocol allows to compute the amplitude of the RX12 pulse to excite the qubit to state 2 starting from state 1. """ # create a sequence of pulses for the experiment sequence = PulseSequence() qd_pulses = {} ro_pulses = {} rx_pulses = {} durations = {} for qubit in targets: rx_pulses[qubit] = platform.create_RX_pulse(qubit, start=0) qd_pulses[qubit] = platform.create_RX_pulse( qubit, start=rx_pulses[qubit].finish ) if params.pulse_length is not None: qd_pulses[qubit].duration = params.pulse_length durations[qubit] = qd_pulses[qubit].duration ro_pulses[qubit] = platform.create_qubit_readout_pulse( qubit, start=qd_pulses[qubit].finish ) sequence.add(rx_pulses[qubit]) sequence.add(qd_pulses[qubit]) sequence.add(ro_pulses[qubit]) # define the parameter to sweep and its range: # qubit drive pulse amplitude qd_pulse_amplitude_range = np.arange( params.min_amp_factor, params.max_amp_factor, params.step_amp_factor, ) sweeper = Sweeper( Parameter.amplitude, qd_pulse_amplitude_range, [qd_pulses[qubit] for qubit in targets], type=SweeperType.FACTOR, ) data = RabiAmplitudeEFData(durations=durations) # sweep the parameter results = platform.sweep( sequence, ExecutionParameters( nshots=params.nshots, relaxation_time=params.relaxation_time, acquisition_type=AcquisitionType.INTEGRATION, averaging_mode=AveragingMode.CYCLIC, ), sweeper, ) for qubit in targets: result = results[ro_pulses[qubit].serial] data.register_qubit( amplitude_signal.RabiAmpSignalType, (qubit), dict( amp=qd_pulses[qubit].amplitude * qd_pulse_amplitude_range, signal=result.magnitude, phase=result.phase, ), ) return data
[docs]def _plot( data: RabiAmplitudeEFData, target: QubitId, fit: RabiAmplitudeEFResults = None ): """Plotting function for RabiAmplitude.""" figures, report = utils.plot(data, target, fit) if report is not None: report = report.replace("Pi pulse", "Pi pulse 12") return figures, report
[docs]def _update(results: RabiAmplitudeEFResults, platform: Platform, target: QubitId): """Update RX2 amplitude_signal""" update.drive_12_amplitude(results.amplitude[target], platform, target) update.drive_12_duration(results.length[target], platform, target)
rabi_amplitude_ef = Routine(_acquisition, amplitude_signal._fit, _plot, _update) """RabiAmplitudeEF Routine object."""