# Hahn echo T{sub}`2` Using {mod}`.pulsed` mode, we perform a Hahn echo experiment: we repeat the [Ramsey experiment](ramsey) from the previous chapter with an additional $\pi$ pulse in the middle of the interferometry sequence. We send two $\pi/2$ pulses to the qubit, separated by variable time $\delta$. At half time between the two $\pi/2$ pulses, we send a $\pi$ pulse. The frequency of the pulses is the qubit frequency and their envelope has a $\sin^2$ shape. The readout pulse is at the frequency of the readout resonator and has a square envelope. ![Ramsey echo pulse sequence](images/Ramsey_echo_pulse_sequence.svg){align=center} The full source code for performing the Hahn echo experiment is available at [presto-measure/ramsey_echo.py][ramsey_echo.py]. Here we first run the experiment and then look into the most interesting parts of the code. You can create a new experiment and run it on your Presto. Be sure to change the parameters of `RamseyEcho` to match your experiment and change `presto_address` to match the IP address of your Presto: ```python from ramsey_echo import RamseyEcho import numpy as np experiment = RamseyEcho( readout_freq=6.2e9, control_freq=4.2e9, readout_amp=0.1, control_amp_90=0.25, control_amp_180=0.5, readout_duration=2.1e-6, control_duration=100e-9, sample_duration=2.1e-6, delay_arr=np.linspace(0, 50e-6, 101), readout_port=1, control_port=4, sample_port=1, wait_delay=100e-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: ```python experiment = RamseyEcho.load("data/ramsey_echo_20220405_113517.h5") ``` In either case, we analyze the data to get a nice plot: ```python experiment.analyze() ``` ```{image} images/ramsey_echo_light.svg :align: center :class: only-light ``` ```{image} images/ramsey_echo_dark.svg :align: center :class: only-dark ``` In the Hahn echo experiment, for delay $\delta = 0$ we apply the equivalent of a $2\pi$ pulse, so the qubit ends up in the ground state. For a delay much longer than the decoherence time, the qubit ends up in a mixed state at the center of the Bloch sphere. For any delay $\delta$, we measure an exponential decay. The $\pi$ pulse in the middle of the sequence "echoes out" a part of the pure dephasing noise so, usually, the Hahn echo time $T_2$ is longer than the Ramsey decay time {math}`T_2^*`. ## Code explanation Here we discuss the main parts of the code of the `RamseyEcho` class: the definition of the qubit-control pulses and the scheduling of the experimental sequence. The full source is available at [presto-measure/ramsey_echo.py][ramsey_echo.py]. :::{note} If this is your first measurement in {mod}`.pulsed` mode, you might want to first have a look at the [Rabi amplitude](rabi_amp) chapter in this tutorial. There we describe the code more pedagogically and in more detail. ::: We choose to encode the $\pi$ and $\pi/2$ pulses as two separate templates with different amplitudes: ```python control_ns = int(round(self.control_duration * pls.get_fs("dac"))) control_envelope = sin2(control_ns) * (1.0 + 1j) control_pulse_90 = pls.setup_template( self.control_port, group=0, template=self.control_amp_90 * control_envelope, ) control_pulse_180 = pls.setup_template( self.control_port, group=0, template=self.control_amp_180 * control_envelope, ) ``` Because the amplitude is encoded directly into the templates, we program a single entry `1.0` in the scale look-up table (LUT) for the qubit control: ```python pls.setup_scale_lut(self.control_port, group=0, scales=1.0) ``` The pulse sequence is then very similar to that of the previous chapter [Ramsey {math}`T_2^*`](ramsey), but with the extra $\pi$ pulse in between the two $\pi/2$ pulses: ```python for delay in self.delay_arr: # first π/2 pulse pls.output_pulse(T, control_pulse_90) T += self.control_duration T += delay / 2 # wait first half of delay # π pulse (echo) pls.output_pulse(T, control_pulse_180) T += self.control_duration T += delay / 2 # wait second half of delay # second π/2 pulse pls.output_pulse(T, control_pulse_90) 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 ``` --- Alternatively, we could have used a single template for both the $\pi$ and the $\pi/2$ pulses, and encoded the different amplitudes as two entries in the scale LUT: ```python control_ns = int(round(self.control_duration * pls.get_fs("dac"))) control_envelope = sin2(control_ns) * (1.0 + 1j) control_pulse = pls.setup_template( output_port=self.control_port, group=0, template=control_envelope, ) pls.setup_scale_lut(self.control_port, group=0, scales=[self.control_amp_90, self.control_amp_180]) ``` Then in the pulse sequence we would output the same pulse three times, but we would move the pointer of the scale LUT to the desired amplitude using {meth}`~.Pulsed.select_scale` before each pulse. Remember that Python arrays are indexed starting from 0. ```python for delay in self.delay_arr: # first π/2 pulse pls.select_scale(T, index=0, output_ports=self.control_port) pls.output_pulse(T, control_pulse) T += self.control_duration T += delay / 2 # wait first half of delay # π pulse (echo) pls.select_scale(T, index=1, output_ports=self.control_port) pls.output_pulse(T, control_pulse) T += self.control_duration T += delay / 2 # wait second half of delay # second π/2 pulse pls.select_scale(T, index=0, output_ports=self.control_port) 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 ``` --- When performing simple experiments such as this Hahn echo, both approaches are equivalent. For more resource-intensive experiments, it is good to keep in mind that the same experiment can often be implemented in different ways on Presto, and depending on the specific case some approaches can be more efficient or flexible than others. [ramsey_echo.py]: https://github.com/intermod-pro/presto-measure/blob/master/ramsey_echo.py