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!
import matplotlib.pyplot as plt
import numpy as np
# Helpers:
from laboneq.contrib.example_helpers.generate_device_setup import (
generate_device_setup_qubits,
)
# LabOne Q:
from laboneq.simple import *
import matplotlib.pyplot as plt
import numpy as np
# Helpers:
from laboneq.contrib.example_helpers.generate_device_setup import (
generate_device_setup_qubits,
)
# LabOne Q:
from laboneq.simple import *
In [ ]:
Copied!
# specify the number of qubits you want to use
number_of_qubits = 1
# generate the device setup and the qubit objects using a helper function - remove either the UHFQA or the SHFQC to make this work
device_setup, qubits = generate_device_setup_qubits(
number_qubits=number_of_qubits,
pqsc=[{"serial": "DEV10001"}],
hdawg=[
{
"serial": "DEV8001",
"zsync": 0,
"number_of_channels": 8,
"options": None,
"dio": "DEV2001",
}
],
# uhfqa=[{"serial": "DEV2001", "readout_multiplex": 6}],
shfqc=[
{
"serial": "DEV12001",
"zsync": 1,
"number_of_channels": 6,
"readout_multiplex": 6,
"options": None,
}
],
include_flux_lines=False,
server_host="localhost",
setup_name=f"my_{number_of_qubits}_fixed_qubit_setup",
)
q0 = qubits[0]
# specify the number of qubits you want to use
number_of_qubits = 1
# generate the device setup and the qubit objects using a helper function - remove either the UHFQA or the SHFQC to make this work
device_setup, qubits = generate_device_setup_qubits(
number_qubits=number_of_qubits,
pqsc=[{"serial": "DEV10001"}],
hdawg=[
{
"serial": "DEV8001",
"zsync": 0,
"number_of_channels": 8,
"options": None,
"dio": "DEV2001",
}
],
# uhfqa=[{"serial": "DEV2001", "readout_multiplex": 6}],
shfqc=[
{
"serial": "DEV12001",
"zsync": 1,
"number_of_channels": 6,
"readout_multiplex": 6,
"options": None,
}
],
include_flux_lines=False,
server_host="localhost",
setup_name=f"my_{number_of_qubits}_fixed_qubit_setup",
)
q0 = qubits[0]
In [ ]:
Copied!
# use emulation mode - no connection to instruments
use_emulation = True
# create and connect to a LabOne Q session
session = Session(device_setup=device_setup)
session.connect(do_emulation=use_emulation)
# use emulation mode - no connection to instruments
use_emulation = True
# create and connect to a LabOne Q session
session = Session(device_setup=device_setup)
session.connect(do_emulation=use_emulation)
In [ ]:
Copied!
# 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
)
# 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", map_to=q0.signals["drive"]),
ExperimentSignal(uid="measure", map_to=q0.signals["measure"]),
ExperimentSignal(uid="acquire", map_to=q0.signals["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
)
# relax time after readout - for signal processing and qubit relaxation to ground state
with exp_0.section(uid="relax", length=1e-6):
exp_0.reserve(signal="measure")
# Create Experiment - qubit remains in ground state
exp_0 = Experiment(
uid="Optimal weights",
signals=[
ExperimentSignal(uid="drive", map_to=q0.signals["drive"]),
ExperimentSignal(uid="measure", map_to=q0.signals["measure"]),
ExperimentSignal(uid="acquire", map_to=q0.signals["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
)
# relax time after readout - for signal processing and qubit relaxation to ground state
with exp_0.section(uid="relax", length=1e-6):
exp_0.reserve(signal="measure")
In [ ]:
Copied!
# Create Experiment - qubit gets excited into excited state
exp_1 = Experiment(
uid="Optimal weights",
signals=[
ExperimentSignal(uid="drive", map_to=q0.signals["drive"]),
ExperimentSignal(uid="measure", map_to=q0.signals["measure"]),
ExperimentSignal(uid="acquire", map_to=q0.signals["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
)
# relax time after readout - for signal processing and qubit relaxation to ground state
with exp_1.section(uid="relax", length=1e-6):
exp_1.reserve(signal="measure")
# Create Experiment - qubit gets excited into excited state
exp_1 = Experiment(
uid="Optimal weights",
signals=[
ExperimentSignal(uid="drive", map_to=q0.signals["drive"]),
ExperimentSignal(uid="measure", map_to=q0.signals["measure"]),
ExperimentSignal(uid="acquire", map_to=q0.signals["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
)
# relax time after readout - for signal processing and qubit relaxation to ground state
with exp_1.section(uid="relax", length=1e-6):
exp_1.reserve(signal="measure")
In [ ]:
Copied!
# 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")
# 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!