Ramsey T2*

Using pulsed mode, we measure Ramsey oscillations. We send two \(\pi/2\) pulses separated by a variable delay \(\delta\). The frequency of the pulses is detuned from the qubit frequency by the oscillation frequency of the Ramsey fringes. The \(\pi/2\) pulses have a \(\sin^2\) envelope, while the readout pulse is at the frequency of the readout resonator and has a square envelope.

Ramsey pulse sequence

The full code of the Ramsey experiment is available at presto-measure/ramsey_single.py. Here we run the experiment and fit the resulting data, and then have a look at the main parts of the code.

You can create a new experiment and run it on your Presto. Be sure to change the parameters of RamseySingle to match your experiment and change presto_address to match the IP address of your Presto:

from ramsey_single import RamseySingle
import numpy as np

experiment = RamseySingle(
    delay_arr=np.linspace(0, 50e-6, 101),

presto_address = ""  # your Presto IP address
save_filename = experiment.run(presto_address)

Or you can also load older data:

experiment = RamseySingle.load("data/ramsey_single_20220401_213253.h5")

In either case, we analyze the data to get a nice plot:


We fit the data to an exponentially-decaying cosine function and we extract the Ramsey decay time \(T_2^*\) and the qubit frequency detuning \(\Delta\).

Code explanation

Here we discuss the core part of the code under the hood of the RamseySingle class: the scheduling of the pulse sequence. The full source is available at presto-measure/ramsey_single.py.


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.

Since we are using only one frequency and one amplitude for each output pulse, programming the experimental sequence is just about timing the output of the pulses. We sweep the delay between two identical qubit-control pules in a for loop:

T = 0.0  # s, start at time zero ...
for delay in self.delay_arr:
    # first π/2 pulse
    pls.output_pulse(T, control_pulse)
    T += self.control_duration

    T += delay  # variable delay

    # second π/2 pulse
    pls.output_pulse(T, control_pulse)
    T += self.control_duration

    # readout
    pls.output_pulse(T, readout_pulse)
    pls.store(T + self.readout_sample_delay)
    T += self.readout_duration

    T += self.wait_delay  # wait for decay