Calibration Set#
The purpose of the Calibration Set is to define all the experiment variables and gate definitions relevant to a set of experiments. The information contained in the Calibration Set falls into two categories: calibration parameters and linkers.
from __future__ import annotations
import numpy as np
import keysight.qcs as qcs
from keysight.qcs.channels import(
Channels,
ConstantEnvelope,
GaussianEnvelope,
PhaseIncrement,
RFWaveform,
SineEnvelope,
)
from keysight.qcs.programs import CalibrationSet
from keysight.qcs.quantum import GATES, PAULIS, ParameterizedGate, Qudits
from keysight.qcs.variables import Array
__all__ = ["calibration__set"]
###############################################################################################
#
# Configuration parameter
#
###############################################################################################
# define the qubits and matching virtual channels
n_qubits = 2
n_channels = 2
qubits = Qudits(range(n_qubits))
control_channels = Channels(qubits.labels, "xy_channels")
readout_channels = Channels(qubits.labels, "readout_channels", absolute_phase=True)
digitizer_channels = Channels(qubits.labels, "acquire_channels", absolute_phase=True)
# initialize the calibration set
calibration_set = CalibrationSet()
First we need to initialize physical and quantum channels and initialize the calibration_set
object.
single_qubit_amplitudes = Array(
"single_qubit_amplitudes", dtype=float, value=[0.5] * n_qubits
)
"""
The amplitudes for each single-qubit X gate or Pi pulse.
"""
Next we should add calibration parameters which should be used in experiments. This is done with Array objects.
##########################################################################################################
#
# Add the X gate
#
##########################################################################################################
x_pulse = RFWaveform(
single_qubit_durations,
GaussianEnvelope(),
single_qubit_amplitudes,
control_frequencies,
)
drag_waveform = x_pulse.drag(single_qubit_drag_coefficients)
calibration_set.add_sq_gate("x", GATES.x, drag_waveform, qubits, control_channels)
We should also create linkers which define quantum gates in terms of physical waveforms. This example is part of a longer list of linkers which can be used in experiment programs.
#########################################################################################################
#
# Add the measurement
#
#########################################################################################################
# define the readout drive pulse and integration filter
readout_pulse = RFWaveform(readout_durations, ConstantEnvelope(), readout_amplitudes, readout_frequencies, readout_phases)
integration_filter = RFWaveform(
acquisition_durations, ConstantEnvelope(), 1, readout_frequencies
)
# define program for measurement
replacement_program = qcs.Program()
replacement_program.add_waveform(readout_oulse, readout_channels, pre_delay=readout_delays)
classifiers = [qcs.MinimumdistanceClassifier(classification_refs[qb]) for qb in range(n_qubits)]
replacement_program.add_acquisition(
integration_filter,
digitizer_channels,
classifiers,
pre_delay=readout_delays + acquisition+delays
)
measure = qcs.Measure()
meas_linker = qcs.ParameterizedLinker(measure, qubits, replacement_program)
calibration_set.add_linker("measurement", meas_linker)
qcs.save(calibration_set, "calibration_set.qcs")
print("Done - Cal file generated successfully")
Just as with the Channel Mapper, the end of our Calibration Set script will generate a file in the .qcs format with all the information needed to run a set of experiments.