Pulsed two-tone spectroscopy¶
Two-tone spectroscopy using pulsed
mode. 1D sweep of qubit drive frequency with fixed
amplitude, and fixed resonator drive frequency and amplitude. This is the pulsed version of the
Resonator spectroscopy chapter in this tutorial on qubit calibration.
The source code for the class TwoTonePulsed
that performs this experiment is available at
presto-measure/two_tone_pulsed.py. Here, we first run the experiment and
extract an estimate of the qubit frequency, and we then have a deeper look at what the code
actually does.
You can create a new experiment and run it on your Presto. Be sure to change the parameters of
TwoTonePulsed
to match your experiment and change presto_address
to match the IP address of
your Presto.
from two_tone_pulsed import TwoTonePulsed
experiment = TwoTonePulsed(
readout_freq=6.2e9,
control_freq_center=4.2e9,
control_freq_span=250e6,
control_freq_nr=101,
readout_amp=0.2,
control_amp=0.1,
readout_duration=2.5e-6,
control_duration=2.5e-6,
sample_duration=2.5e-6,
readout_port=1,
control_port=4,
sample_port=1,
wait_delay=100e-6,
readout_sample_delay=0,
num_averages=100,
)
presto_address = "192.168.88.65" # your Presto IP address
save_filename = experiment.run(presto_address)
Or you can also load older data:
experiment = TwoTonePulsed.load("data/two_tone_pulsed_20220331_164030.h5")
In either case, we analyze the data to get a nice plot:
experiment.analyze()
Code explanation¶
Here we discuss the main parts of the code in the TwoTonePulsed
class, you can see the full
source code at presto-measure/two_tone_pulsed.py.
Note
If this is your first measurement in pulsed
mode, you might want to first have a look at
the Rabi amplitude chapter in this tutorial. There we describe the code more
pedagogically and in more detail.
We want to sweep the frequency of the qubit-control pulse. We do that by changing the intermediate frequency (IF) and keeping the NCO frequency constant, just like we already did in Ramsey fringes. Note that this is the opposite to what we did in the continuous-wave Resonator spectroscopy chapter of this tutorial.
pls.hardware.configure_mixer(
self.readout_freq, # <-- output frequency (zero IF)
in_ports=self.sample_port,
out_ports=self.readout_port,
)
pls.hardware.configure_mixer(
control_nco, # <-- up-conversion frequency (nonzero IF)
out_ports=self.control_port,
)
pls.setup_freq_lut(
self.control_port, group=0,
frequencies=control_if_arr,
phases=np.full_like(control_if_arr, 0.0),
phases_q=np.full_like(control_if_arr, -np.pi / 2), # upper sideband
)
And we make sure to use the IF generator with the qubit-control pulse by setting envelope=True
:
control_pulse = pls.setup_template(
self.control_port, group=0,
template=control_envelope + 1j * control_envelope,
envelope=True, # <-- multiply by IF generator
)
The pulse sequence is rather simple:
T = 0.0 # s, start at time zero ...
pls.reset_phase(T, self.control_port)
pls.output_pulse(T, control_pulse) # Control pulse
T += self.control_duration
pls.output_pulse(T, readout_pulse) # Readout pulse
pls.store(T + self.readout_sample_delay) # Sampling window
T += self.readout_duration
pls.next_frequency(T, self.control_port) # Move to next control frequency
T += self.wait_delay # Wait for decay
We readout the resonator right after outputting the qubit-control pulse. Before waiting for the
qubit to decay, we call next_frequency()
to proceed to the next control frequency
for the next iteration of the experiment.
We finish up by running the experiment, setting repeat_count
to the number of frequencies in the
qubit-control sweep:
pls.run(period=T, repeat_count=self.control_freq_nr, num_averages=self.num_averages)