qibocal.protocols.two_qubit_interaction package#

Subpackages#

Submodules#

qibocal.protocols.two_qubit_interaction.cryoscope module#

Cryoscope experiment.

qibocal.protocols.two_qubit_interaction.cryoscope.FEEDFORWARD_MAX = 1.9999847412109375#

Maximum feedforward tap value

qibocal.protocols.two_qubit_interaction.cryoscope.FEEDBACK_MAX = 0.9999990463256836#

Maximum feedback tap value

qibocal.protocols.two_qubit_interaction.cryoscope.SAMPLING_RATE = 1#

Instrument sampling rate in GSamples

class qibocal.protocols.two_qubit_interaction.cryoscope.CryoscopeParameters(duration_min: int, duration_max: int, duration_step: int, flux_pulse_amplitude: float, fir: int = 20, unrolling: bool = True)[source]#

Bases: Parameters

Cryoscope runcard inputs.

duration_min: int#

Minimum flux pulse duration.

duration_max: int#

Maximum flux duration start.

duration_step: int#

Flux pulse duration step.

flux_pulse_amplitude: float#

Flux pulse amplitude.

fir: int = 20#

Number of feedforward taps to be optimized after IIR.

unrolling: bool = True#
hardware_average: bool = False#

By default hardware average will be performed.

nshots: int#

Number of executions on hardware.

relaxation_time: float#

Wait time for the qubit to decohere back to the gnd state.

class qibocal.protocols.two_qubit_interaction.cryoscope.CryoscopeResults(fitted_parameters: dict[tuple[typing.Union[int, str], str], list[float]] = <factory>, detuning: dict[typing.Union[int, str], list[float]] = <factory>, amplitude: dict[typing.Union[int, str], list[float]] = <factory>, step_response: dict[typing.Union[int, str], list[float]] = <factory>, exp_amplitude: dict[typing.Union[int, str], list[float]] = <factory>, tau: dict[typing.Union[int, str], list[float]] = <factory>, feedforward_taps: dict[typing.Union[int, str], list[float]] = <factory>, feedforward_taps_iir: dict[typing.Union[int, str], list[float]] = <factory>, feedback_taps: dict[typing.Union[int, str], list[float]] = <factory>)[source]#

Bases: Results

Cryoscope outputs.

fitted_parameters: dict[tuple[Union[int, str], str], list[float]]#

Fitted <X> and <Y> for each qubit.

detuning: dict[Union[int, str], list[float]]#

Expected detuning.

amplitude: dict[Union[int, str], list[float]]#

Flux amplitude computed from detuning.

step_response: dict[Union[int, str], list[float]]#

Waveform normalized to 1.

exp_amplitude: dict[Union[int, str], list[float]]#

A parameters for the exp decay approximation

tau: dict[Union[int, str], list[float]]#

time decay constant in exp decay approximation

feedforward_taps: dict[Union[int, str], list[float]]#

feedforward taps

feedforward_taps_iir: dict[Union[int, str], list[float]]#

feedforward taps for IIR

feedback_taps: dict[Union[int, str], list[float]]#

feedback taps

_to_json(path: Path, filename: str)#

Helper function to dump to json.

_to_npz(path: Path, filename: str)#

Helper function to use np.savez while converting keys into strings.

static load_data(path: Path, filename: str)#

Load data stored in a npz file.

static load_params(path: Path, filename: str)#

Load parameters stored in a json file.

property params: dict#

Convert non-arrays attributes into dict.

save(path: Path)#

Store results to file.

qibocal.protocols.two_qubit_interaction.cryoscope.CryoscopeType = dtype([('duration', '<i8'), ('prob_1', '<f8')])#

Custom dtype for Cryoscope.

qibocal.protocols.two_qubit_interaction.cryoscope.generate_sequences(platform: Platform, qubit: Union[int, str], duration: int, params: CryoscopeParameters) tuple[qibolab._core.sequence.PulseSequence, qibolab._core.sequence.PulseSequence][source]#

Compute sequences at fixed duration of flux pulse for <X> and <Y>

class qibocal.protocols.two_qubit_interaction.cryoscope.CryoscopeData(flux_pulse_amplitude: float, fir: int, flux_coefficients: dict[typing.Union[int, str], list[float]] = <factory>, filters: dict[typing.Union[int, str], float] = <factory>, data: dict[tuple[typing.Union[int, str], str], numpy.ndarray[typing.Any, numpy.dtype[dtype([('duration', '<i8'), ('prob_1', '<f8')])]]] = <factory>)[source]#

Bases: Data

Cryoscope acquisition outputs.

_to_json(path: Path, filename: str)#

Helper function to dump to json.

_to_npz(path: Path, filename: str)#

Helper function to use np.savez while converting keys into strings.

static load_data(path: Path, filename: str)#

Load data stored in a npz file.

static load_params(path: Path, filename: str)#

Load parameters stored in a json file.

property pairs#

Access qubit pairs ordered alphanumerically from data structure.

property params: dict#

Convert non-arrays attributes into dict.

property qubits#

Access qubits from data structure.

register_qubit(dtype, data_keys, data_dict)#

Store output for single qubit.

Parameters:
  • data_keys (tuple) – Keys of Data.data.

  • data_dict (dict) – The keys are the fields of dtype and

  • arrays. (the values are the related) –

save(path: Path)#

Store data to file.

flux_pulse_amplitude: float#

Flux pulse amplitude.

fir: int#

Number of feedforward taps to be optimized after IIR.

flux_coefficients: dict[Union[int, str], list[float]]#

Flux - amplitude relation coefficients obtained from flux_amplitude_frequency routine

filters: dict[Union[int, str], float]#

Check if there are filters already.

data: dict[tuple[typing.Union[int, str], str], numpy.ndarray[typing.Any, numpy.dtype[dtype([('duration', '<i8'), ('prob_1', '<f8')])]]]#
has_filters(qubit: Union[int, str]) bool[source]#

Checking if for qubit there are already filters.

qibocal.protocols.two_qubit_interaction.cryoscope._acquisition(params: CryoscopeParameters, platform: Platform, targets: list[Union[int, str]]) CryoscopeData[source]#

Acquisition for cryoscope experiment.

The following sequence is played for each qubit.

drive — RY90 ——————- RY90 ——- flux ——— FluxPulse(t) —————— readout ———————————– MZ –

The previous sequence measures <X>, to measure <Y> the second drive pulse is replaced with RX90. The delay between the two pi/2 pulses is fixed at t_max (maximum duration of flux pulse) + 100 ns (following the paper).

qibocal.protocols.two_qubit_interaction.cryoscope.exponential_params(step_response, acquisition_time)[source]#
qibocal.protocols.two_qubit_interaction.cryoscope.filter_calc(params)[source]#
qibocal.protocols.two_qubit_interaction.cryoscope._fit(data: CryoscopeData) CryoscopeResults[source]#

Postprocessing for cryoscope experiment.

From <X> and <Y> we compute the expecting step response. The complex data <X> + i <Y> are demodulated using the frequency found by fitting a sinusoid to both <X> and <Y>. Next, the phase is computed and finally the detuning using a savgol_filter. The “real” detuning is computed by reintroducing the demodulation frequency. Finally, using the parameters given by the flux_amplitude_frequency experiment, we compute the expected flux_amplitude by inverting the formula:

f = c_1 A^2 + c_2 A + c_3

where f is the detuning and A is the flux amplitude. The step response is computed by normalizing the amplitude by its value computed above. For some of the manipulations see: https://github.com/DiCarloLab-Delft/PycQED_py3/blob/c4279cbebd97748dc47127e56f6225021f169257/pycqed/analysis/tools/cryoscope_tools.py#L73

qibocal.protocols.two_qubit_interaction.cryoscope._plot(data: CryoscopeData, fit: CryoscopeResults, target: Union[int, str])[source]#

Cryoscope plots.

qibocal.protocols.two_qubit_interaction.cryoscope._update(results: CryoscopeResults, platform: Platform, target: Union[int, str])[source]#

qibocal.protocols.two_qubit_interaction.optimize module#

virtual correction experiment for two qubit gates, tune landscape.

class qibocal.protocols.two_qubit_interaction.optimize.OptimizeTwoQubitGateParameters(theta_start: float, theta_end: float, theta_step: float, flux_pulse_amplitude_min: float, flux_pulse_amplitude_max: float, flux_pulse_amplitude_step: float, duration_min: int, duration_max: int, duration_step: int, dt: Optional[float] = 0, native: str = 'CZ')[source]#

Bases: Parameters

OptimizeTwoQubitGate runcard inputs.

theta_start: float#

Initial angle for the low frequency qubit measurement in radians.

theta_end: float#

Final angle for the low frequency qubit measurement in radians.

theta_step: float#

Step size for the theta sweep in radians.

flux_pulse_amplitude_min: float#

Minimum amplitude of flux pulse swept.

flux_pulse_amplitude_max: float#

Maximum amplitude of flux pulse swept.

flux_pulse_amplitude_step: float#

Step amplitude of flux pulse swept.

duration_min: int#

Minimum duration of flux pulse swept.

duration_max: int#

Maximum duration of flux pulse swept.

duration_step: int#

Step duration of flux pulse swept.

dt: Optional[float] = 0#

Time delay between flux pulses and readout.

native: str = 'CZ'#

Two qubit interaction to be calibrated.

iSWAP and CZ are the possible options.

hardware_average: bool = False#

By default hardware average will be performed.

nshots: int#

Number of executions on hardware.

relaxation_time: float#

Wait time for the qubit to decohere back to the gnd state.

class qibocal.protocols.two_qubit_interaction.optimize.OptimizeTwoQubitGateResults(fitted_parameters: dict[tuple[str, Union[int, str], float], list], native: str, angles: dict[tuple[tuple[Union[int, str], Union[int, str]], float], float], virtual_phases: dict[tuple[tuple[Union[int, str], Union[int, str]], float], dict[Union[int, str], float]], leakages: dict[tuple[tuple[Union[int, str], Union[int, str]], float], dict[Union[int, str], float]], best_amp: dict[tuple[Union[int, str], Union[int, str]]], best_dur: dict[tuple[Union[int, str], Union[int, str]]], best_virtual_phase: dict[tuple[Union[int, str], Union[int, str]]])[source]#

Bases: Results

CzVirtualZ outputs when fitting will be done.

fitted_parameters: dict[tuple[str, Union[int, str], float], list]#

Fitted parameters

native: str#

Native two qubit gate.

angles: dict[tuple[tuple[Union[int, str], Union[int, str]], float], float]#

Two qubit gate angle.

virtual_phases: dict[tuple[tuple[Union[int, str], Union[int, str]], float], dict[Union[int, str], float]]#

Virtual Z phase correction.

leakages: dict[tuple[tuple[Union[int, str], Union[int, str]], float], dict[Union[int, str], float]]#

Leakage on control qubit for pair.

best_amp: dict[tuple[Union[int, str], Union[int, str]]]#

Flux pulse amplitude of best configuration.

_to_json(path: Path, filename: str)#

Helper function to dump to json.

_to_npz(path: Path, filename: str)#

Helper function to use np.savez while converting keys into strings.

static load_data(path: Path, filename: str)#

Load data stored in a npz file.

static load_params(path: Path, filename: str)#

Load parameters stored in a json file.

property params: dict#

Convert non-arrays attributes into dict.

save(path: Path)#

Store results to file.

best_dur: dict[tuple[Union[int, str], Union[int, str]]]#

Flux pulse duration of best configuration.

best_virtual_phase: dict[tuple[Union[int, str], Union[int, str]]]#

Virtual phase to correct best configuration.

class qibocal.protocols.two_qubit_interaction.optimize.OptimizeTwoQubitGateData(data: dict[tuple, numpy.ndarray[typing.Any, numpy.dtype[dtype([('amp', '<f8'), ('theta', '<f8'), ('duration', '<f8'), ('prob_target', '<f8'), ('prob_control', '<f8')])]]] = <factory>, thetas: list = <factory>, native: str = 'CZ', amplitudes: dict[tuple[typing.Union[int, str], typing.Union[int, str]], float] = <factory>, durations: dict[tuple[typing.Union[int, str], typing.Union[int, str]], float] = <factory>)[source]#

Bases: Data

OptimizeTwoQubitGate data.

_to_json(path: Path, filename: str)#

Helper function to dump to json.

_to_npz(path: Path, filename: str)#

Helper function to use np.savez while converting keys into strings.

static load_data(path: Path, filename: str)#

Load data stored in a npz file.

static load_params(path: Path, filename: str)#

Load parameters stored in a json file.

property pairs#

Access qubit pairs ordered alphanumerically from data structure.

property params: dict#

Convert non-arrays attributes into dict.

property qubits#

Access qubits from data structure.

save(path: Path)#

Store data to file.

data: dict[tuple, numpy.ndarray[typing.Any, numpy.dtype[dtype([('amp', '<f8'), ('theta', '<f8'), ('duration', '<f8'), ('prob_target', '<f8'), ('prob_control', '<f8')])]]]#

Raw data.

thetas: list#

Angles swept.

native: str = 'CZ'#

Native two qubit gate.

amplitudes: dict[tuple[Union[int, str], Union[int, str]], float]#

“Amplitudes swept.

durations: dict[tuple[Union[int, str], Union[int, str]], float]#

Durations swept.

register_qubit(target, control, setup, theta, amp, duration, prob_control, prob_target)[source]#

Store output for single pair.

qibocal.protocols.two_qubit_interaction.optimize._acquisition(params: OptimizeTwoQubitGateParameters, platform: CalibrationPlatform, targets: list[tuple[Union[int, str], Union[int, str]]]) OptimizeTwoQubitGateData[source]#

Repetition of correct virtual phase experiment for several amplitude and duration values.

qibocal.protocols.two_qubit_interaction.optimize._fit(data: OptimizeTwoQubitGateData) OptimizeTwoQubitGateResults[source]#

Repetition of correct virtual phase fit for all configurations.

qibocal.protocols.two_qubit_interaction.optimize._plot(data: OptimizeTwoQubitGateData, fit: OptimizeTwoQubitGateResults, target: tuple[Union[int, str], Union[int, str]])[source]#

Plot routine for OptimizeTwoQubitGate.

qibocal.protocols.two_qubit_interaction.optimize._update(results: OptimizeTwoQubitGateResults, platform: CalibrationPlatform, target: tuple[Union[int, str], Union[int, str]])[source]#
qibocal.protocols.two_qubit_interaction.optimize.optimize_two_qubit_gate = Routine(acquisition=<function _acquisition>, fit=<function _fit>, report=<function _plot>, update=<function _update>, two_qubit_gates=True)#

Optimize two qubit gate protocol

qibocal.protocols.two_qubit_interaction.utils module#

qibocal.protocols.two_qubit_interaction.utils.order_pair(pair: tuple[Union[int, str], Union[int, str]], platform: Platform) tuple[Union[int, str], Union[int, str]][source]#

Order a pair of qubits by drive frequency.

qibocal.protocols.two_qubit_interaction.utils.fit_flux_amplitude(matrix, amps, times)[source]#

Estimate amplitude for CZ gate.

Given the pattern of a chevron plot (see for example Fig. 2 here https://arxiv.org/pdf/1907.04818.pdf). This function estimates the CZ amplitude by finding the amplitude which gives the standard deviation, indicating that there are oscillation along the z axis.

Parameters:
  • matrix (np.ndarray) – signal matrix

  • amps (np.ndarray) – amplitudes swept

  • times (np.ndarray) – duration swept

Returns:

estimated amplitude index (int): amplitude index delta (float): omega for estimated amplitude

Return type:

amplitude (float)

qibocal.protocols.two_qubit_interaction.virtual_z_phases module#

CZ virtual correction experiment for two qubit gates, tune landscape.

class qibocal.protocols.two_qubit_interaction.virtual_z_phases.VirtualZPhasesParameters(theta_start: float, theta_end: float, theta_step: float, native: str = 'CZ', dt: Optional[float] = 0)[source]#

Bases: Parameters

VirtualZ runcard inputs.

theta_start: float#

Initial angle for the low frequency qubit measurement in radians.

theta_end: float#

Final angle for the low frequency qubit measurement in radians.

theta_step: float#

Step size for the theta sweep in radians.

native: str = 'CZ'#

Two qubit interaction to be calibrated.

iSWAP and CZ are the possible options.

dt: Optional[float] = 0#

Time delay between flux pulses and readout.

hardware_average: bool = False#

By default hardware average will be performed.

nshots: int#

Number of executions on hardware.

relaxation_time: float#

Wait time for the qubit to decohere back to the gnd state.

class qibocal.protocols.two_qubit_interaction.virtual_z_phases.VirtualZPhasesResults(fitted_parameters: dict[tuple[str, Union[int, str]]], native: str, angle: dict[tuple[Union[int, str], Union[int, str]], float], virtual_phase: dict[tuple[Union[int, str], Union[int, str]], dict[Union[int, str], float]], leakage: dict[tuple[Union[int, str], Union[int, str]], dict[Union[int, str], float]])[source]#

Bases: Results

VirtualZ outputs when fitting will be done.

fitted_parameters: dict[tuple[str, Union[int, str]]]#

Fitted parameters

native: str#

Native two qubit gate.

angle: dict[tuple[Union[int, str], Union[int, str]], float]#

Native angle.

virtual_phase: dict[tuple[Union[int, str], Union[int, str]], dict[Union[int, str], float]]#

Virtual Z phase correction.

leakage: dict[tuple[Union[int, str], Union[int, str]], dict[Union[int, str], float]]#

Leakage on control qubit for pair.

_to_json(path: Path, filename: str)#

Helper function to dump to json.

_to_npz(path: Path, filename: str)#

Helper function to use np.savez while converting keys into strings.

static load_data(path: Path, filename: str)#

Load data stored in a npz file.

static load_params(path: Path, filename: str)#

Load parameters stored in a json file.

property params: dict#

Convert non-arrays attributes into dict.

save(path: Path)#

Store results to file.

class qibocal.protocols.two_qubit_interaction.virtual_z_phases.VirtualZPhasesData(data: dict[tuple, numpy.ndarray[typing.Any, numpy.dtype[dtype([('target', '<f8'), ('control', '<f8')])]]] = <factory>, native: str = 'CZ', thetas: list = <factory>)[source]#

Bases: Data

VirtualZPhases data.

data: dict[tuple, numpy.ndarray[typing.Any, numpy.dtype[dtype([('target', '<f8'), ('control', '<f8')])]]]#
native: str = 'CZ'#
thetas: list#
_to_json(path: Path, filename: str)#

Helper function to dump to json.

_to_npz(path: Path, filename: str)#

Helper function to use np.savez while converting keys into strings.

static load_data(path: Path, filename: str)#

Load data stored in a npz file.

static load_params(path: Path, filename: str)#

Load parameters stored in a json file.

property pairs#

Access qubit pairs ordered alphanumerically from data structure.

property params: dict#

Convert non-arrays attributes into dict.

property qubits#

Access qubits from data structure.

register_qubit(dtype, data_keys, data_dict)#

Store output for single qubit.

Parameters:
  • data_keys (tuple) – Keys of Data.data.

  • data_dict (dict) – The keys are the fields of dtype and

  • arrays. (the values are the related) –

save(path: Path)#

Store data to file.

qibocal.protocols.two_qubit_interaction.virtual_z_phases.create_sequence(platform: CalibrationPlatform, setup: Literal['I', 'X'], target_qubit: Union[int, str], control_qubit: Union[int, str], ordered_pair: list[Union[int, str], Union[int, str]], native: Literal['CZ', 'iSWAP'], dt: float, flux_pulse_max_duration: float = None) tuple[qibolab._core.sequence.PulseSequence, qibolab._core.pulses.pulse.Pulse, qibolab._core.pulses.pulse.Pulse][source]#

Create the experiment PulseSequence.

qibocal.protocols.two_qubit_interaction.virtual_z_phases._acquisition(params: VirtualZPhasesParameters, platform: CalibrationPlatform, targets: list[tuple[Union[int, str], Union[int, str]]]) VirtualZPhasesData[source]#

Acquisition for VirtualZPhases.

Check the two-qubit landscape created by a flux pulse of a given duration and amplitude. The system is initialized with a Y90 pulse on the low frequency qubit and either an Id or an X gate on the high frequency qubit. Then the flux pulse is applied to the high frequency qubit in order to perform a two-qubit interaction. The Id/X gate is undone in the high frequency qubit and a theta90 pulse is applied to the low frequency qubit before measurement. That is, a pi-half pulse around the relative phase parametereized by the angle theta. Measurements on the low frequency qubit yield the 2Q-phase of the gate and the remnant single qubit Z phase aquired during the execution to be corrected. Population of the high frequency qubit yield the leakage to the non-computational states during the execution of the flux pulse.

qibocal.protocols.two_qubit_interaction.virtual_z_phases.sinusoid(x, amplitude, offset, phase)[source]#

Sinusoidal fit function.

qibocal.protocols.two_qubit_interaction.virtual_z_phases.phase_diff(phase_1, phase_2)[source]#

Return the phase difference of two sinusoids, normalized in the range [0, pi].

qibocal.protocols.two_qubit_interaction.virtual_z_phases.fit_sinusoid(thetas, data)[source]#

Fit sinusoid to the given data.

qibocal.protocols.two_qubit_interaction.virtual_z_phases._fit(data: VirtualZPhasesData) VirtualZPhasesResults[source]#

Fitting routine for the experiment.

The used model is

y=p0sin(x+p2)+p1.
qibocal.protocols.two_qubit_interaction.virtual_z_phases._plot(data: VirtualZPhasesData, fit: VirtualZPhasesResults, target: tuple[Union[int, str], Union[int, str]])[source]#

Plot routine for VirtualZPhases.

qibocal.protocols.two_qubit_interaction.virtual_z_phases._update(results: VirtualZPhasesResults, platform: CalibrationPlatform, target: tuple[Union[int, str], Union[int, str]])[source]#
qibocal.protocols.two_qubit_interaction.virtual_z_phases.correct_virtual_z_phases = Routine(acquisition=<function _acquisition>, fit=<function _fit>, report=<function _plot>, update=<function _update>, two_qubit_gates=True)#

Virtual phases correction protocol.