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\).
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()
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)