Ramsey with a sampled pulse¶
This notebook demonstrates the use of a sampled pulse in a Ramsey experiment. We sweep the delay between two slightly detuned pi/2 pulses to determine the qubit dephasing time as well as fine calibration its excited state frequency and use a user defined pulse, given as complex valued numpy array.
0. General Imports and Definitions¶
0.1 Python Imports¶
In [ ]:
Copied!
# LabOne Q:
from laboneq.contrib.example_helpers.example_notebook_helper import create_device_setup
# Helpers:
from laboneq.contrib.example_helpers.plotting.plot_helpers import *
from laboneq.simple import *
# LabOne Q:
from laboneq.contrib.example_helpers.example_notebook_helper import create_device_setup
# Helpers:
from laboneq.contrib.example_helpers.plotting.plot_helpers import *
from laboneq.simple import *
1. Device Setup¶
In [ ]:
Copied!
# create device setup
device_setup = create_device_setup(generation=2)
use_emulation = True
# create device setup
device_setup = create_device_setup(generation=2)
use_emulation = True
In [ ]:
Copied!
# signal map for qubits
def map_qubit(qubit_id):
return {
"drive": f"/logical_signal_groups/q{qubit_id}/drive_line",
"measure": f"/logical_signal_groups/q{qubit_id}/measure_line",
"acquire": f"/logical_signal_groups/q{qubit_id}/acquire_line",
}
# signal map for qubits
def map_qubit(qubit_id):
return {
"drive": f"/logical_signal_groups/q{qubit_id}/drive_line",
"measure": f"/logical_signal_groups/q{qubit_id}/measure_line",
"acquire": f"/logical_signal_groups/q{qubit_id}/acquire_line",
}
2. Experiment Definition¶
2.1 Pulse definition¶
In [ ]:
Copied!
## define pulses
# A setup consisting of SHF instruments and HDAWGs has a sampling rate of 2 GSa/s
drive_sampling_rate = 2.0e9
# qubit drive pulse as sampled complex pulse
x90_length = 100e-9
num_samples = round((x90_length * drive_sampling_rate))
samples_complex = np.transpose(
np.array(
[
np.arange(num_samples) * (1 / num_samples),
np.arange(num_samples) * (1 / num_samples),
]
)
)
x90 = pulse_library.sampled_pulse_complex(samples=samples_complex, uid="x90")
# readout drive pulse
readout_pulse = pulse_library.const(uid="readout_pulse", length=400e-9, amplitude=1.0)
# readout integration weights
readout_weighting_function = pulse_library.const(
uid="readout_weighting_function", length=200e-9, amplitude=1.0
)
## define pulses
# A setup consisting of SHF instruments and HDAWGs has a sampling rate of 2 GSa/s
drive_sampling_rate = 2.0e9
# qubit drive pulse as sampled complex pulse
x90_length = 100e-9
num_samples = round((x90_length * drive_sampling_rate))
samples_complex = np.transpose(
np.array(
[
np.arange(num_samples) * (1 / num_samples),
np.arange(num_samples) * (1 / num_samples),
]
)
)
x90 = pulse_library.sampled_pulse_complex(samples=samples_complex, uid="x90")
# readout drive pulse
readout_pulse = pulse_library.const(uid="readout_pulse", length=400e-9, amplitude=1.0)
# readout integration weights
readout_weighting_function = pulse_library.const(
uid="readout_weighting_function", length=200e-9, amplitude=1.0
)
2.2 Pulse Sequence¶
In [ ]:
Copied!
# set up sweep parameter - delay between pi/2 pulses
start = 0.0
stop = 1000e-9
count = 11
delay_sweep = LinearSweepParameter(uid="delay", start=start, stop=stop, count=count)
# number of averages
average_exponent = 1 # used for 2^n averages, n=average_exponent, maximum: n = 17
# Create Experiment
exp = Experiment(
uid="Ramsey",
signals=[
ExperimentSignal("drive"),
ExperimentSignal("measure"),
ExperimentSignal("acquire"),
],
)
## experimental sequence
# outer loop - real-time, cyclic averaging in standard integration mode
with exp.acquire_loop_rt(
uid="shots",
count=pow(2, average_exponent),
averaging_mode=AveragingMode.CYCLIC,
acquisition_type=AcquisitionType.INTEGRATION,
):
# inner loop - sweep over delay between qubit drive pulses
with exp.sweep(
uid="sweep", parameter=delay_sweep, alignment=SectionAlignment.RIGHT
):
# qubit excitation pulses - use right-aligned, constant length section to optimize pulse timings
with exp.section(
uid="qubit_excitation",
length=stop + 2 * x90_length,
alignment=SectionAlignment.RIGHT,
):
exp.play(signal="drive", pulse=x90)
exp.delay(signal="drive", time=delay_sweep)
exp.play(signal="drive", pulse=x90)
# qubit readout pulse and data acquisition
with exp.section(uid="qubit_readout", play_after="qubit_excitation"):
# play readout pulse
exp.play(signal="measure", pulse=readout_pulse)
# signal data acquisition
exp.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.section(uid="relax", play_after="qubit_readout"):
exp.delay(signal="measure", time=1e-6)
# set up sweep parameter - delay between pi/2 pulses
start = 0.0
stop = 1000e-9
count = 11
delay_sweep = LinearSweepParameter(uid="delay", start=start, stop=stop, count=count)
# number of averages
average_exponent = 1 # used for 2^n averages, n=average_exponent, maximum: n = 17
# Create Experiment
exp = Experiment(
uid="Ramsey",
signals=[
ExperimentSignal("drive"),
ExperimentSignal("measure"),
ExperimentSignal("acquire"),
],
)
## experimental sequence
# outer loop - real-time, cyclic averaging in standard integration mode
with exp.acquire_loop_rt(
uid="shots",
count=pow(2, average_exponent),
averaging_mode=AveragingMode.CYCLIC,
acquisition_type=AcquisitionType.INTEGRATION,
):
# inner loop - sweep over delay between qubit drive pulses
with exp.sweep(
uid="sweep", parameter=delay_sweep, alignment=SectionAlignment.RIGHT
):
# qubit excitation pulses - use right-aligned, constant length section to optimize pulse timings
with exp.section(
uid="qubit_excitation",
length=stop + 2 * x90_length,
alignment=SectionAlignment.RIGHT,
):
exp.play(signal="drive", pulse=x90)
exp.delay(signal="drive", time=delay_sweep)
exp.play(signal="drive", pulse=x90)
# qubit readout pulse and data acquisition
with exp.section(uid="qubit_readout", play_after="qubit_excitation"):
# play readout pulse
exp.play(signal="measure", pulse=readout_pulse)
# signal data acquisition
exp.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.section(uid="relax", play_after="qubit_readout"):
exp.delay(signal="measure", time=1e-6)
2.3 Run the Experiment and Plot the Measurement Results and Pulse Sheet¶
In [ ]:
Copied!
# map exp to qubit 0
exp.set_signal_map(map_qubit(0))
# create and connect to session
session = Session(device_setup=device_setup)
session.connect(do_emulation=use_emulation)
# run on qubit 0
my_results = session.run(exp)
# map exp to qubit 0
exp.set_signal_map(map_qubit(0))
# create and connect to session
session = Session(device_setup=device_setup)
session.connect(do_emulation=use_emulation)
# run on qubit 0
my_results = session.run(exp)
In [ ]:
Copied!
# Plot simulated output signals
plot_simulation(session.compiled_experiment, start_time=0, length=10e-6)
# Plot simulated output signals
plot_simulation(session.compiled_experiment, start_time=0, length=10e-6)
In [ ]:
Copied!
# plot measurement results
plot_result_2d(my_results, "ac_0")
# plot measurement results
plot_result_2d(my_results, "ac_0")
In [ ]:
Copied!
# use pulse sheet viewer to display the pulse sequence - only recommended for small number of averages and sweep steps to avoid performance issues
show_pulse_sheet("T1", session.compiled_experiment)
# use pulse sheet viewer to display the pulse sequence - only recommended for small number of averages and sweep steps to avoid performance issues
show_pulse_sheet("T1", session.compiled_experiment)
In [ ]:
Copied!
# map exp to qubit 1
exp.set_signal_map(map_qubit(1))
# create and connect to session
session = Session(device_setup=device_setup)
session.connect(do_emulation=use_emulation)
# run on qubit 1
my_results = session.run(exp)
# map exp to qubit 1
exp.set_signal_map(map_qubit(1))
# create and connect to session
session = Session(device_setup=device_setup)
session.connect(do_emulation=use_emulation)
# run on qubit 1
my_results = session.run(exp)
In [ ]:
Copied!