See also
A Jupyter notebook version of this tutorial can be downloaded here.

Time of flight#
Prior to the start of quantum experiments, it is crucial to calibrate the delay between sending a measurement pulse and beginning the acquisition on the instrument. This delay should be equal to the time it takes for the readout signal to travel through the fridge and is determined by the length of the cables. For the experiment a square pulse is played over the output of the readout line, while a trace acquisition is done. The time at which the pulse is detected on the acquisition path is determined to be the acquisition delay. This also allows us to set the NCO propagation delay, which corrects for the phase accumulated during the time of flight.
[1]:
from dependencies.analysis_utils import TimeOfFlightAnalysis
from xarray import open_dataset
from qblox_scheduler import HardwareAgent, Schedule
from qblox_scheduler.operations import (
IdlePulse,
Measure,
SetClockFrequency,
)
from qblox_scheduler.operations.expressions import DType
from qblox_scheduler.operations.loop_domains import arange
Generating hash table for SingleQubitClifford.
Hash table generated.
Generating hash table for TwoQubitCliffordCZ.
Hash table generated.
Generating hash table for TwoQubitCliffordZX.
Hash table generated.
Testing decompositions.
Test passed.
Setup#
The hardware agent manages the connection to the instrument and ensures that pulses and acquisitions happen over the appropriate input and output channels of the Cluster. The cell below creates an instance of the HardwareAgent based on the hardware- and device-under-test configuration files in the ./dependencies/configs folder, allowing us to start doing measurements. We also define some convenient aliases to use throughout our measurements. For a more thorough discussion of the
hardware- and device-under-test configuration files, check out this tutorial.
[2]:
# Set up hardware agent, this automatically connects to the instrument
hw_agent = HardwareAgent(
hardware_configuration="./dependencies/configs/hw_config.json",
quantum_device_configuration="./dependencies/configs/dut_config.json",
)
# convenience aliases
q0 = hw_agent.quantum_device.get_element("q0")
q2 = hw_agent.quantum_device.get_element("q2")
cluster = hw_agent.get_clusters()["cluster"]
hw_options = hw_agent.hardware_configuration.hardware_options
qubit = q0
/builds/0/.venv/lib/python3.10/site-packages/qblox_scheduler/qblox/hardware_agent.py:460: UserWarning: cluster: Trying to instantiate cluster with ip 'None'.Creating a dummy cluster.
warnings.warn(
Experiment settings#
[3]:
# Pulse settings
pulse_attenuation = 0 # dB
pulse_amplitude = 1 # a.u.
pulse_frequency_detuning = 100e6 # Hz
pulse_duration = 300e-9 # ns
acquisition_duration = 1e-6 # Hz
repetitions = 1000
Experiment schedule#
[4]:
# Set pulse attenuation
prior_att = hw_options.output_att[f"{qubit.name}:res-{qubit.name}.ro"]
hw_options.output_att[f"{qubit.name}:res-{qubit.name}.ro"] = pulse_attenuation
tof_sched = Schedule("time_of_flight")
tof_sched.add(
SetClockFrequency(
clock=qubit.name + ".ro",
clock_freq_new=qubit.clock_freqs.readout - pulse_frequency_detuning,
) # Detune clock 100MHz from expected resonance frequency
)
tof_sched.add(IdlePulse(4e-9))
with tof_sched.loop(arange(0, repetitions, 1, DType.NUMBER)):
tof_sched.add(
Measure(
qubit.name,
acq_protocol="Trace",
pulse_duration=pulse_duration,
acq_duration=acquisition_duration,
acq_channel="S_21",
acq_delay=0,
)
)
# Execute the experiment
tof_data = hw_agent.run(tof_sched)
if cluster.is_dummy:
example_data = open_dataset("./dependencies/datasets/time_of_flight.hdf5", engine="h5netcdf")
tof_data = tof_data.update({"S_21": example_data.S_21})
# Reset attenuation
hw_options.output_att[f"{qubit.name}:res-{qubit.name}.ro"] = prior_att
Analyze the experiment#
[5]:
tof_analysis = TimeOfFlightAnalysis(tof_data).run()
tof_analysis.display_figs_mpl()
Post-run#
[6]:
qubit.measure.acq_delay = tof_analysis.quantities_of_interest["tof"]
# Set the NCO propagation delay of the readout line.
cluster.module4.sequencer0.nco_prop_delay_comp_en(True)
cluster.module4.sequencer0.nco_prop_delay_comp(
tof_analysis.quantities_of_interest["nco_prop_delay"]
)
Update the device configuration file#
After measurement, we may store the measured device properties inside a new file to use in future experiments. The time-unique identifier ensures that it is easy to find back previously found measurement results.
[7]:
hw_agent.quantum_device.to_json_file("./dependencies/configs", add_timestamp=True)
[7]:
'./dependencies/configs/two_flux_tunable_transmons_2025-10-30_00-37-56_UTC.json'