qibocal.protocols.readout package

Submodules

qibocal.protocols.readout.amplitude_frequency_optimization module

qibocal.protocols.readout.amplitude_frequency_optimization.ro_amplitude_frequency = Protocol(acquisition=<function _acquisition>, fit=<function _fit>, report=<function _plot>, update=<function _update>, two_qubit_gates=False)

Optimize the readout amplitude and frequency for each target qubit.

The protocol sweeps a two-dimensional grid of readout-pulse amplitudes and frequencies. At every grid point it prepares the qubit in the ground and excited states, performs two consecutive readout measurements to evaluate the assignment fidelity and QND fidelity, and applies a \(\pi\) pulse before a third measurement to evaluate the QND-\(\pi\) fidelity (see https://arxiv.org/pdf/2110.04285). Single-shot IQsamples are classified independently at each grid point, yielding the optimal classification angle and threshold as well as the three readout-quality metrics.

The fit selects the grid point that optimizes the readout quality and returns the corresponding amplitude, frequency, IQ angle, threshold, assignment fidelity, QND fidelity, and QND-\(\pi\) fidelity.

qibocal.protocols.readout.amplitude_optimization module

qibocal.protocols.readout.amplitude_optimization.ro_amplitude = Protocol(acquisition=<function _acquisition>, fit=<function readout_fit>, report=<function _plot>, update=<function _update>, two_qubit_gates=False)

Optimize the readout pulse amplitude for each target qubit.

The protocol sweeps the amplitude of the resonator probe pulse over the range specified by ReadoutAmplitudeParameters.amplitude_range and acquires integrated readout signals for each value. The acquired data are fitted to identify the amplitude that best separates the readout states. The fit also determines the optimal IQ rotation angle and discrimination threshold.

When updated, the selected amplitude, IQ angle, and threshold are written to the platform calibration for every target qubit. Set save_iq=True to retain the acquired IQ data.

qibocal.protocols.readout.frequency_optimization module

qibocal.protocols.readout.frequency_optimization.ro_frequency = Protocol(acquisition=<function _acquisition>, fit=<function readout_fit>, report=<function _plot>, update=<function _update>, two_qubit_gates=False)

Readout resonator frequency optimization protocol.

The protocol sweeps the probe frequency of the resonator probe pulse over the range specified by ReadoutFrequencyParameters.frequency_range and acquires integrated readout signals for each value. The acquired data are fitted to identify the frequency that best separates the readout states. The fit also determines the optimal IQ rotation angle and discrimination threshold.

When updated, the selected frequency, IQ angle, and threshold are written to the platform calibration for every target qubit. Set save_iq=True to retain the acquired IQ data.

qibocal.protocols.readout.readout_characterization module

qibocal.protocols.readout.readout_characterization.readout_characterization = Protocol(acquisition=<function _acquisition>, fit=<function _fit>, report=<function _plot>, update=<function _update>, two_qubit_gates=False)

ReadoutCharacterization Protocol object.

qibocal.protocols.readout.readout_mitigation_matrix module

qibocal.protocols.readout.readout_mitigation_matrix.readout_mitigation_matrix = Protocol(acquisition=<function _acquisition>, fit=<function _fit>, report=<function _plot>, update=<function _update>, two_qubit_gates=False)

Readout mitigation matrix protocol.

qibocal.protocols.readout.utils module

class qibocal.protocols.readout.utils.ReadoutResults(best_swept_param: dict[Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], float], highest_fidelities: dict[Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], float], best_angle: dict[Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], float], best_threshold: dict[Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], float], measured_fidelities: dict[Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], list])[source]

Bases: Results

Optimization RO frequency results.

best_swept_param: dict[Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], float]

Best swept parameter value.

highest_fidelities: dict[Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], float]

Highest Assignment fidelities.

best_angle: dict[Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], float]

IQ angle that maximes assignment fidelity.

best_threshold: dict[Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], float]

Threshold that maximes assignment fidelity.

measured_fidelities: dict[Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], list]

Measured assignment fidelities.

_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, filename: str = 'results')

Store results to file.

class qibocal.protocols.readout.utils.ReadoutData(swept_parameter: dict[~types.Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], list[float]] = <factory>, data: dict[tuple[~types.Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], int, float], ~numpy.ndarray[tuple[~typing.Any, ...], ~numpy.dtype[~numpy.float64]]] = <factory>, classification_info: dict[~types.Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], list[list[float]]] = <factory>, save_iq: bool = False)[source]

Bases: Data

Optimization RO frequency acquisition outputs.

swept_parameter: dict[Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], list[float]]

List of parameter values swept for each qubit.

data: dict[tuple[Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], int, float], ndarray[tuple[Any, ...], dtype[float64]]]

Measured data for each qubit, with shape (Nshots, N_freq_sweep, 2).

_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: list[~typing.Annotated[tuple[~types.Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], ~types.Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])]], ~pydantic.functional_validators.BeforeValidator(func=~qibocal.calibration.calibration.<lambda>, json_schema_input_type=PydanticUndefined), ~pydantic.functional_serializers.PlainSerializer(func=~qibocal.calibration.calibration.<lambda>, return_type=PydanticUndefined, when_used=always)]]

Access qubit pairs from data structure.

property params: dict

Convert non-arrays attributes into dict.

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, filename: str = 'data')

Store data to file.

classification_info: dict[Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], list[list[float]]]

Classification information for each qubit (Assignment Fidelity, Angle and Threshold of the classifier).

save_iq: bool = False

Whether to save the IQ data during the acquisition.

property qubits: list[Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])]]

Return the list of qubits for which data was acquired.

qibocal.protocols.readout.utils.base_sequence(platform: CalibrationPlatform, targets: list[Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])]]) tuple[list[PulseSequence], dict[Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], dict[int, Annotated[Align | Pulse | Delay | VirtualZ | Acquisition | Readout, FieldInfo(annotation=NoneType, required=True, discriminator='kind')]]]][source]

Build readout sequences for ground- and excited-state measurements.

qibocal.protocols.readout.utils.fit_classification_model(measured_0: ndarray[tuple[Any, ...], dtype[float64]], measured_1: ndarray[tuple[Any, ...], dtype[float64]]) QubitFit[source]

Fit a binary readout classification model to IQ samples.

It returns the fitted qubit classification model.

qibocal.protocols.readout.utils.fit_readout_classification_models(targets: list[Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])]], parameter_dict: dict[Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], list[float]], pulses_dict: dict[Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], dict[int, Annotated[Align | Pulse | Delay | VirtualZ | Acquisition | Readout, FieldInfo(annotation=NoneType, required=True, discriminator='kind')]]], results: dict[Annotated[UUID, UuidVersion(uuid_version=4)], ndarray[tuple[Any, ...], dtype[float64]]], save_iq: bool) ReadoutData[source]

Fit readout classification models for each target qubit and parameter sweep.

For each qubit and swept readout parameter value, the function loads the ground- and excited-state IQ data from the acquisition results, optionally stores the raw IQ samples, and fits a binary classifier. The fitted assignment fidelity, IQ rotation angle, and discrimination threshold are collected for each sweep point and returned together with the optional IQ samples.

qibocal.protocols.readout.utils.readout_fit(data: ReadoutData) ReadoutResults[source]

Fit the readout data for each qubit and return the results.

qibocal.protocols.readout.utils.readout_plot(data: ReadoutData, fit: ReadoutResults, target: Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], label: str) tuple[list[Figure], str | None][source]

Create an assignment-fidelity plot for a target qubit.