Readout Raw Data¶
In this notebook, you'll learn how to access the raw time traces of the readout integration unit for both UHFQA and SHFQA, which may be used to optimize the readout fidelity when designing matched filter functions for the readout integration weights.
0. Python Imports¶
In [ ]:
Copied!
# LabOne Q:
from laboneq.simple import *
import numpy as np
import matplotlib.pyplot as plt
# LabOne Q:
from laboneq.simple import *
import numpy as np
import matplotlib.pyplot as plt
In [ ]:
Copied!
descriptor = """\
instruments:
HDAWG:
- address: DEV8001
uid: device_hdawg
UHFQA:
- address: DEV2001
uid: device_uhfqa
SHFQA:
- address: DEV12001
uid: device_shfqa
PQSC:
- address: DEV10001
uid: device_pqsc
connections:
device_hdawg:
- iq_signal: q0/drive_line
ports: [SIGOUTS/0, SIGOUTS/1]
- iq_signal: q1/drive_line
ports: [SIGOUTS/2, SIGOUTS/3]
- rf_signal: q0/flux_line
ports: [SIGOUTS/4]
- rf_signal: q1/flux_line
ports: [SIGOUTS/5]
- to: device_uhfqa
port: DIOS/0
device_uhfqa:
- iq_signal: q0/measure_line
ports: [SIGOUTS/0, SIGOUTS/1]
- acquire_signal: q0/acquire_line
device_shfqa:
- iq_signal: q1/measure_line
ports: QACHANNELS/0/OUTPUT
- acquire_signal: q1/acquire_line
ports: QACHANNELS/0/INPUT
device_pqsc:
- to: device_hdawg
port: ZSYNCS/0
- to: device_shfqa
port: ZSYNCS/1
"""
descriptor = """\
instruments:
HDAWG:
- address: DEV8001
uid: device_hdawg
UHFQA:
- address: DEV2001
uid: device_uhfqa
SHFQA:
- address: DEV12001
uid: device_shfqa
PQSC:
- address: DEV10001
uid: device_pqsc
connections:
device_hdawg:
- iq_signal: q0/drive_line
ports: [SIGOUTS/0, SIGOUTS/1]
- iq_signal: q1/drive_line
ports: [SIGOUTS/2, SIGOUTS/3]
- rf_signal: q0/flux_line
ports: [SIGOUTS/4]
- rf_signal: q1/flux_line
ports: [SIGOUTS/5]
- to: device_uhfqa
port: DIOS/0
device_uhfqa:
- iq_signal: q0/measure_line
ports: [SIGOUTS/0, SIGOUTS/1]
- acquire_signal: q0/acquire_line
device_shfqa:
- iq_signal: q1/measure_line
ports: QACHANNELS/0/OUTPUT
- acquire_signal: q1/acquire_line
ports: QACHANNELS/0/INPUT
device_pqsc:
- to: device_hdawg
port: ZSYNCS/0
- to: device_shfqa
port: ZSYNCS/1
"""
1.2 Calibration¶
In [ ]:
Copied!
def calibrate_devices(device_setup):
device_setup.logical_signal_groups["q0"].logical_signals[
"drive_line"
].calibration = SignalCalibration(
oscillator=Oscillator(
uid="drive_q0_osc", frequency=1e8, modulation_type=ModulationType.HARDWARE
),
mixer_calibration=MixerCalibration(
voltage_offsets=[0.02, 0.01],
correction_matrix=[
[1.0, 0.0],
[0.0, 1.0],
],
),
)
device_setup.logical_signal_groups["q0"].logical_signals[
"measure_line"
].calibration = SignalCalibration(
oscillator=Oscillator(
uid="measure_q0_osc", frequency=1e8, modulation_type=ModulationType.SOFTWARE
),
)
device_setup.logical_signal_groups["q0"].logical_signals[
"acquire_line"
].calibration = SignalCalibration(
oscillator=Oscillator(
uid="acquire_q0_osc", frequency=1e8, modulation_type=ModulationType.SOFTWARE
),
# delay between readout pulse and start of signal integration
port_delay=50e-9,
)
device_setup.logical_signal_groups["q1"].logical_signals[
"drive_line"
].calibration = SignalCalibration(
oscillator=Oscillator(
uid="drive_q1_osc", frequency=1e8, modulation_type=ModulationType.HARDWARE
),
mixer_calibration=MixerCalibration(
voltage_offsets=[0.02, 0.01],
correction_matrix=[
[1.0, 0.0],
[0.0, 1.0],
],
),
)
device_setup.logical_signal_groups["q1"].logical_signals[
"measure_line"
].calibration = SignalCalibration(
oscillator=Oscillator(
uid="measure_q1_osc", frequency=1e8, modulation_type=ModulationType.SOFTWARE
),
local_oscillator=Oscillator(frequency=4e9, carrier_type=CarrierType.RF),
range=10,
)
device_setup.logical_signal_groups["q1"].logical_signals[
"acquire_line"
].calibration = SignalCalibration(
oscillator=Oscillator(
uid="acquire_q1_osc", frequency=1e8, modulation_type=ModulationType.SOFTWARE
),
# delay between readout pulse and start of signal integration
port_delay=150e-9,
)
def calibrate_devices(device_setup):
device_setup.logical_signal_groups["q0"].logical_signals[
"drive_line"
].calibration = SignalCalibration(
oscillator=Oscillator(
uid="drive_q0_osc", frequency=1e8, modulation_type=ModulationType.HARDWARE
),
mixer_calibration=MixerCalibration(
voltage_offsets=[0.02, 0.01],
correction_matrix=[
[1.0, 0.0],
[0.0, 1.0],
],
),
)
device_setup.logical_signal_groups["q0"].logical_signals[
"measure_line"
].calibration = SignalCalibration(
oscillator=Oscillator(
uid="measure_q0_osc", frequency=1e8, modulation_type=ModulationType.SOFTWARE
),
)
device_setup.logical_signal_groups["q0"].logical_signals[
"acquire_line"
].calibration = SignalCalibration(
oscillator=Oscillator(
uid="acquire_q0_osc", frequency=1e8, modulation_type=ModulationType.SOFTWARE
),
# delay between readout pulse and start of signal integration
port_delay=50e-9,
)
device_setup.logical_signal_groups["q1"].logical_signals[
"drive_line"
].calibration = SignalCalibration(
oscillator=Oscillator(
uid="drive_q1_osc", frequency=1e8, modulation_type=ModulationType.HARDWARE
),
mixer_calibration=MixerCalibration(
voltage_offsets=[0.02, 0.01],
correction_matrix=[
[1.0, 0.0],
[0.0, 1.0],
],
),
)
device_setup.logical_signal_groups["q1"].logical_signals[
"measure_line"
].calibration = SignalCalibration(
oscillator=Oscillator(
uid="measure_q1_osc", frequency=1e8, modulation_type=ModulationType.SOFTWARE
),
local_oscillator=Oscillator(frequency=4e9, carrier_type=CarrierType.RF),
range=10,
)
device_setup.logical_signal_groups["q1"].logical_signals[
"acquire_line"
].calibration = SignalCalibration(
oscillator=Oscillator(
uid="acquire_q1_osc", frequency=1e8, modulation_type=ModulationType.SOFTWARE
),
# delay between readout pulse and start of signal integration
port_delay=150e-9,
)
1.3 Create device setup¶
In [ ]:
Copied!
def create_device_setup():
device_setup = DeviceSetup.from_descriptor(
descriptor,
server_host="my_ip_address",
server_port="8004",
setup_name="my_QCCS_setup",
)
calibrate_devices(device_setup)
return device_setup
def create_device_setup():
device_setup = DeviceSetup.from_descriptor(
descriptor,
server_host="my_ip_address",
server_port="8004",
setup_name="my_QCCS_setup",
)
calibrate_devices(device_setup)
return device_setup
In [ ]:
Copied!
# create the device setup
device_setup = create_device_setup()
# how many averages
average_exponent = 10 # used for 2^n averages, n=average_exponent, maximum: n = 19
## define pulses used for experiment
# qubit drive - needs to be calibrated pulse to bring qubit into excited state
x180 = pulse_library.gaussian(uid="x180", length=100e-9, amplitude=1.0)
# qubit readout pulse
readout_pulse = pulse_library.const(uid="readout_pulse", length=100e-9, amplitude=1.0)
# readout integration weights - here simple square pulse, i.e. same weights at all times
readout_weighting_function = pulse_library.const(
uid="readout_weighting_function", length=200e-9, amplitude=1.0
)
# create the device setup
device_setup = create_device_setup()
# how many averages
average_exponent = 10 # used for 2^n averages, n=average_exponent, maximum: n = 19
## define pulses used for experiment
# qubit drive - needs to be calibrated pulse to bring qubit into excited state
x180 = pulse_library.gaussian(uid="x180", length=100e-9, amplitude=1.0)
# qubit readout pulse
readout_pulse = pulse_library.const(uid="readout_pulse", length=100e-9, amplitude=1.0)
# readout integration weights - here simple square pulse, i.e. same weights at all times
readout_weighting_function = pulse_library.const(
uid="readout_weighting_function", length=200e-9, amplitude=1.0
)
In [ ]:
Copied!
# Create Experiment - qubit remains in ground state
exp_0 = Experiment(
uid="Optimal weights",
signals=[
ExperimentSignal(uid="drive"),
ExperimentSignal(uid="measure"),
ExperimentSignal(uid="acquire"),
],
)
# outer averaging loop - real-time averaging of raw data
with exp_0.acquire_loop_rt(
uid="shots",
count=pow(2, average_exponent),
averaging_mode=AveragingMode.CYCLIC,
acquisition_type=AcquisitionType.RAW,
):
# qubit readout and data acquisition
with exp_0.section(uid="qubit_readout"):
exp_0.play(signal="measure", pulse=readout_pulse)
exp_0.acquire(
signal="acquire", handle="ac_0", kernel=readout_weighting_function
)
# delay section - to facilitate signal processing
with exp_0.section(uid="relax"):
exp_0.delay(signal="measure", time=1e-6)
# Create Experiment - qubit remains in ground state
exp_0 = Experiment(
uid="Optimal weights",
signals=[
ExperimentSignal(uid="drive"),
ExperimentSignal(uid="measure"),
ExperimentSignal(uid="acquire"),
],
)
# outer averaging loop - real-time averaging of raw data
with exp_0.acquire_loop_rt(
uid="shots",
count=pow(2, average_exponent),
averaging_mode=AveragingMode.CYCLIC,
acquisition_type=AcquisitionType.RAW,
):
# qubit readout and data acquisition
with exp_0.section(uid="qubit_readout"):
exp_0.play(signal="measure", pulse=readout_pulse)
exp_0.acquire(
signal="acquire", handle="ac_0", kernel=readout_weighting_function
)
# delay section - to facilitate signal processing
with exp_0.section(uid="relax"):
exp_0.delay(signal="measure", time=1e-6)
In [ ]:
Copied!
# Create Experiment - qubit gets excited into excited state
exp_1 = Experiment(
uid="Optimal weights",
signals=[
ExperimentSignal(uid="drive"),
ExperimentSignal(uid="measure"),
ExperimentSignal(uid="acquire"),
],
)
# outer averaging loop - real-time averaging of raw data
with exp_1.acquire_loop_rt(
uid="shots",
count=pow(2, average_exponent),
averaging_mode=AveragingMode.CYCLIC,
acquisition_type=AcquisitionType.RAW,
):
# qubit excitation section - drive qubit into excited state
with exp_1.section(uid="qubit_excitation"):
exp_1.play(signal="drive", pulse=x180)
# qubit readout and data acquisition
with exp_1.section(uid="qubit_readout"):
exp_1.reserve(signal="drive")
exp_1.play(signal="measure", pulse=readout_pulse)
exp_1.acquire(
signal="acquire", handle="ac_1", kernel=readout_weighting_function
)
# delay section - to facilitate signal processing
with exp_1.section(uid="relax"):
exp_1.delay(signal="measure", time=1e-6)
# Create Experiment - qubit gets excited into excited state
exp_1 = Experiment(
uid="Optimal weights",
signals=[
ExperimentSignal(uid="drive"),
ExperimentSignal(uid="measure"),
ExperimentSignal(uid="acquire"),
],
)
# outer averaging loop - real-time averaging of raw data
with exp_1.acquire_loop_rt(
uid="shots",
count=pow(2, average_exponent),
averaging_mode=AveragingMode.CYCLIC,
acquisition_type=AcquisitionType.RAW,
):
# qubit excitation section - drive qubit into excited state
with exp_1.section(uid="qubit_excitation"):
exp_1.play(signal="drive", pulse=x180)
# qubit readout and data acquisition
with exp_1.section(uid="qubit_readout"):
exp_1.reserve(signal="drive")
exp_1.play(signal="measure", pulse=readout_pulse)
exp_1.acquire(
signal="acquire", handle="ac_1", kernel=readout_weighting_function
)
# delay section - to facilitate signal processing
with exp_1.section(uid="relax"):
exp_1.delay(signal="measure", time=1e-6)
In [ ]:
Copied!
# play pulses on and readout qubit 0 to use UHFQA for readout
signal_map_q0 = {
"drive": "/logical_signal_groups/q0/drive_line",
"measure": "/logical_signal_groups/q0/measure_line",
"acquire": "/logical_signal_groups/q0/acquire_line",
}
# play pulses on and readout qubit 0 to use UHFQA for readout
signal_map_q0 = {
"drive": "/logical_signal_groups/q0/drive_line",
"measure": "/logical_signal_groups/q0/measure_line",
"acquire": "/logical_signal_groups/q0/acquire_line",
}
In [ ]:
Copied!
# create session and connect to it
session = Session(device_setup=device_setup)
session.connect(do_emulation=True)
# apply signal map for qubit 0
exp_0.set_signal_map(signal_map_q0)
exp_1.set_signal_map(signal_map_q0)
# run the first experiment and access the data
results_0 = session.run(exp_0)
raw_0 = results_0.get_data("ac_0")
# run the second experiment and access the data
results_1 = session.run(exp_1)
raw_1 = results_1.get_data("ac_1")
# create session and connect to it
session = Session(device_setup=device_setup)
session.connect(do_emulation=True)
# apply signal map for qubit 0
exp_0.set_signal_map(signal_map_q0)
exp_1.set_signal_map(signal_map_q0)
# run the first experiment and access the data
results_0 = session.run(exp_0)
raw_0 = results_0.get_data("ac_0")
# run the second experiment and access the data
results_1 = session.run(exp_1)
raw_1 = results_1.get_data("ac_1")
2.2 Plot the results¶
In [ ]:
Copied!
time = np.linspace(0, len(raw_0) / 1.8, len(raw_0))
# for groundstate
plt.plot(time, np.real(raw_0), "b")
plt.plot(time, np.imag(raw_0), "-b")
# for excited state
plt.plot(time, np.real(raw_1), "r")
plt.plot(time, np.imag(raw_1), "-r")
plt.xlabel("Time (ns)")
plt.ylabel("Amplitude (a.u.)")
time = np.linspace(0, len(raw_0) / 1.8, len(raw_0))
# for groundstate
plt.plot(time, np.real(raw_0), "b")
plt.plot(time, np.imag(raw_0), "-b")
# for excited state
plt.plot(time, np.real(raw_1), "r")
plt.plot(time, np.imag(raw_1), "-r")
plt.xlabel("Time (ns)")
plt.ylabel("Amplitude (a.u.)")
In [ ]:
Copied!