Resonator Spectroscopy with SHFQA or SHFQC¶
This notebook shows you how to perform CW resonator spectroscopy in LabOne Q with a SHFQA or the quantum analyzer channels of a SHFQC. Here, you'll find the resonance frequency of the qubit readout resonator by looking at the transmission or reflection of a probe signal applied through the readout line.
A demonstration of this notebook, starting from the basics of installing LabOne Q, is also available on our Youtube channel here
0. LabOne Q Imports¶
You'll begin by importing laboneq.simple
and some extra helper functions to run the examples.
# LabOne Q:
from laboneq.simple import *
# Helpers:
from laboneq.contrib.example_helpers.plotting.plot_helpers import plot_results
from laboneq.contrib.example_helpers.generate_example_datastore import (
generate_example_datastore,
get_first_named_entry,
)
from pathlib import Path
import time
# Build an in-memory data store with device setup and qubit parameters for the
# example notebooks
setup_db = generate_example_datastore(in_memory=True)
1. Device Setup¶
Below, you'll create a device setup and specify to run in an emulated mode or on hardware, emulate = True/False
respectively.
If you run on your hardware, the descriptor called by create_device_setup
should be replaced by one of your own, generally stored as a YAML file. Once you have this descriptor, it can be reused for all your experiments.
# load a calibrated device setup from the dummy database
device_setup = get_first_named_entry(
db=setup_db, name="6_qubit_setup_shfsg_shfqa_hdawg_pqsc_calibrated"
)
emulate = True
# create and connect to a session
session = Session(device_setup=device_setup)
session.connect(do_emulation=emulate)
2. Experiment Parameters¶
Now you'll define the frequency sweep parameters to use in your experiment.
# frequency range of spectroscopy scan - around expected centre frequency as defined in qubit parameters
start_freq = -200.0e6
stop_freq = 200.0e6
num_points = 101
integration_time = 1e-3
# define number of averages
# used for 2^num_averages, maximum: num_averages = 17
num_averages = 4
# define sweep parameter
def create_readout_freq_sweep(qubit, start_freq, stop_freq, num_points):
return LinearSweepParameter(
uid=f"{qubit}_res_freq",
start=start_freq,
stop=stop_freq,
count=num_points,
axis_name="Frequency [Hz]",
)
3. Experiment Definition¶
You'll now create a function which generates you CW spectroscopy experiment. In this experiment, you'll pass the LinearSweepParameter
defined previously as an argument to the sweep section. Within the section, you'll create a section containing an acquire
command.
# function that defines a resonator spectroscopy experiment, and takes the frequency sweep as a parameter
def res_spectroscopy_CW(freq_sweep, exp_settings):
# Create resonator spectroscopy experiment - uses only readout drive and signal acquisition
exp_spec = Experiment(
uid="Resonator Spectroscopy",
signals=[
ExperimentSignal("measure"),
ExperimentSignal("acquire"),
],
)
## define experimental sequence
# loop - average multiple measurements for each frequency - measurement in spectroscopy mode
with exp_spec.acquire_loop_rt(
uid="shots",
count=pow(2, exp_settings["num_averages"]),
acquisition_type=AcquisitionType.SPECTROSCOPY,
):
with exp_spec.sweep(uid="res_freq", parameter=freq_sweep):
# readout pulse and data acquisition
with exp_spec.section(uid="spectroscopy"):
# resonator signal readout
exp_spec.acquire(
signal="acquire",
handle="res_spec",
length=exp_settings["integration_time"],
)
with exp_spec.section(uid="delay", length=1e-6):
# holdoff time after signal acquisition
exp_spec.reserve(signal="measure")
exp_spec.reserve(signal="acquire")
return exp_spec
3.1 Experiment Calibration and Signal Map¶
Before running the experiment, you'll need to set an experiment calibration. The sweep parameter is assigned to the hardware oscillator modulating the readout resonator drive line. You'll also define and set the mapping between the experimental and logical lines.
# function that returns the calibration of the readout line oscillator for the experimental signals
def res_spec_calib(freq_sweep):
exp_calibration = Calibration()
# sets the oscillator of the experimental measure signal
exp_calibration["measure"] = SignalCalibration(
# for spectroscopy, use the hardware oscillator of the QA, and set the sweep parameter as frequency
oscillator=Oscillator(
"readout_osc",
frequency=freq_sweep,
modulation_type=ModulationType.HARDWARE,
)
)
return exp_calibration
# signal maps for the two different qubits - maps the logical signal of the device setup to the experimental signals of the experiment
def res_spec_map(qubit):
signal_map = {
"measure": device_setup.logical_signal_groups[f"{qubit}"].logical_signals[
"measure_line"
],
"acquire": device_setup.logical_signal_groups[f"{qubit}"].logical_signals[
"acquire_line"
],
}
return signal_map
# define the experiment with the frequency sweep relevant for qubit 0
freq_sweep = create_readout_freq_sweep("q0", start_freq, stop_freq, num_points)
exp_settings = {"integration_time": integration_time, "num_averages": num_averages}
exp_spec = res_spectroscopy_CW(freq_sweep, exp_settings)
# set signal calibration and signal map for experiment to qubit 0
exp_spec.set_calibration(res_spec_calib(freq_sweep))
exp_spec.set_signal_map(res_spec_map("q0"))
3.2 Compile and Generate Pulse Sheet¶
Now you'll compile the experiment and generate a pulse sheet.
# compile the experiment on the open instrument session
compiled_res_spec = session.compile(exp_spec)
Path("Pulse_Sheets").mkdir(parents=True, exist_ok=True)
# generate a pulse sheet to inspect experiment before runtime
show_pulse_sheet("Pulse_Sheets/Resonator_Spectroscopy_Pulse_Sheet", compiled_res_spec)
3.3 Run, Save, and Plot Results¶
Finally, you'll run the experiment, save, and plot the results.
# run the compiled experiemnt
res_spec_results = session.run(compiled_res_spec)
timestamp = time.strftime("%Y%m%dT%H%M%S")
Path("Results").mkdir(parents=True, exist_ok=True)
session.save_results(f"Results/{timestamp}_results.json")
print(f"File saved as Results/{timestamp}_results.json")
# plot the results
plot_results(res_spec_results, phase=True)