Coherence time \(T_2^*\) of the bosonic mode

Using pulsed mode, we measure the coherance time \(T_2^*\) of the bosonic mode. We first displace the memory with a pulse slightly detuned from the memory frequency with a \(\sin^2\) envelope. Then after the delay time \(\delta\), we displace the memory back, with a pulse with the same detuning from the memory frequency and the same amplitude, but opposite phase compared to the first displacement pulse. The qubit-control pulse is a selective \(\pi\) pulse with a \(\sin^2\) envelope whose frequency is the frequency of the qubit when the memory is in the Fock state \(|0\rangle\). The readout pulse is at the frequency of the readout resonator and has a square envelope. By probing the state of the qubit, we directly get the probablility that the memory is in state \(|0\rangle\).

T2 memory coherent pulse sequence

The class for performing the \(T_2^*\) experiment is available at presto-measure/t2_memory_coherent.py. Here, we run the experiment and observe the qubit population following the typical Ramsey oscillations. We 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 T2_memory_coherent to match your experiment and change presto_address to match the IP address of your Presto:

from t2_memory_coherent import T2_memory_coherent
import numpy as np

experiment = T2_memory_coherent(
    readout_freq=6.2e9,
    control_freq=4.2e9,
    memory_freq=3.5e9,
    readout_amp=0.1,
    control_amp=0.5,
    memory_amp=0.2,
    readout_duration=2.5e-6,
    control_duration=2000e-9,
    memory_duration=50e-9,
    sample_duration=2.5e-6,
    delay_arr=np.linspace(0, 400e-6, 101),
    readout_port=1,
    control_port=2,
    memory_port=5,
    sample_port=1,
    wait_delay=50e-6,
    readout_sample_delay=0e-9,
    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 = T2_memory_coherent.load("../data/t2_memory_coherent_20240219_165516.h5")

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

experiment.analyze()
../../_images/t2_memory_coherent_light.svg ../../_images/t2_memory_coherent_dark.svg

The qubit starts in the excited state at zero delay \(\delta = 0~\mu s\) as the two displacements \(D(\alpha)\) and \(D(-\alpha)\) cancel each other and memory is approximately in the ground state. Similar to Ramsey sequence for a two-level system, we should observe oscillations that are at a frequency difference between the memory drive and the memory frequency. The oscillations have an exponentailly decaying envelope that we fit to extract \(T_2^*\).

The complex-valued readout signal is rotated using utils.rotate_opt() so that all the information about the qubit state is in the I quadrature.

Code explanation

Here we discuss the main part of the code of the t2_memory_coherent class: the definition of the experiment sequence. The full source is available at presto-measure/t2_memory_coherent.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 the qubit tutorial. There we describe the code more pedagogically and in more detail.

We implement the variable delay in the measurement with a single for loop:

T = 0.0  # s, start at time zero ...
for delay in self.delay_arr:
    pls.select_scale(T, 0, self.memory_port, group=0)
    pls.output_pulse(T, memory_pulse)  # displace memory
    T += self.memory_duration
    T += delay  # increasing delay
    pls.select_scale(T, 1, self.memory_port, group=0)
    pls.output_pulse(T, memory_pulse)  # displace memory back
    T += self.memory_duration
    pls.output_pulse(T, control_pulse)  # pi pulse conditioned on memory in |0>
    T += self.control_duration
    pls.output_pulse(T, readout_pulse)  # Readout
    pls.store(T + self.readout_sample_delay)
    T += self.readout_duration
    T += self.wait_delay  # Wait for decay

We first output the memory pulse with positive amplitude, wait for variable amount of time and then output the memory pulse with negative amplitude. Then, we output qubit-control selective \(\pi\) pulse to probe the population of Fock state \(|0\rangle\). Finally, we perform the readout.


run() executes the experiment sequence. We set repeat_count=1 since the whole pulse sequence is already programmed in the for loop.

pls.run(period=T, repeat_count=1, num_averages=self.num_averages)