Hahn Echo Experiment

Finally, we will do a Hahn Echo experiment, to determine the Echo decay time of the qubit coherence. A Hahn Echo sequence effectively applies a filter function to the noise acting on the qubit, and renders the qubit evolution insensitive to any noise components that stay constant during the pulse sequence. This experiment is very similar to the Ramsey pulse sequence, in that we rotate the qubit state to the equator of the Bloch sphere with an initial π/2-pulse and rotate it back with a final π/2-pulse at the end of the sequence. For the Hahn Echo we additionally insert a π-pulse in the middle between the two π/2-pulses, effectively flipping the qubit state from one hemisphere of the Bloch sphere to the other. Due to this flip, noise components that stay constant during the sequence counteract their own effect from the first part of the sequence in the second part.

As usual, we start by defining some experimental parameters. Here, we set the minimum and maximum delay between the two qubit excitation pulses as well as the number of sweep steps and averages per point. Additionally, we define the π/2-pulse as well as the π-pulse with a Gaussian waveform envelope, and use the amplitudes as calibrated in the Rabi experiment before.

# delay range for echo pulses
echo_min = 0.0
echo_max = 1.5 * qubit_parameters['T2_echo']
# how many delay points to sweep
echo_num = 150

# set up delay sweep parameter - max of sweep parameter is half of max delay since here are two delays in sequence
echo_sweep = LinearSweepParameter(uid="echo_delay", start=echo_min, stop=echo_max/2, count=echo_num)

# how many averages per point: 2^n_average
n_average = 10

# Echo excitation pulses - qubit pi/2 and pi pulse
x90 = pulse_library.gaussian(
uid="x90", length=qubit_parameters['qb_len'], amplitude=qubit_parameters['pihalf_amp']
)
x180 = pulse_library.gaussian(
uid="x180", length=qubit_parameters['qb_len'], amplitude=qubit_parameters['pi_amp']
)

The sweep parameter in the Hahn Echo experiment is the delay between the two outer π/2-pulses played on the qubit drive line. Because this delay is split in two, one before the π-pulse, one after, we are here defining a sweep parameter up to half the maximum delay of the experiment. When plotting that data later, this has to be kept in mind.

# Create Ramsey Experiment - uses qubit drive line, readout drive line and acquisition line
exp_echo = Experiment(
uid="Hahn Echo",
signals=[
ExperimentSignal("drive"),
ExperimentSignal("measure"),
ExperimentSignal("acquire"),
],
)

## define Experiment sequence
# outer loop - real-time, cyclic averaging
with exp_echo.acquire_loop_rt(
uid="echo_shots",
count=pow(2, n_average),
averaging_mode=AveragingMode.CYCLIC,
acquisition_type=AcquisitionType.INTEGRATION
):
# inner loop - sweep Ramsey delay in real time
with exp_echo.sweep(uid="echo_sweep", parameter=echo_sweep):
# Ramsey pulse sequence on qubit - use right-aligned, constant length section for optimised timing behavior
with exp_echo.section(
uid="qubit_excitation",
length=echo_max+2*x90.length+x180.length,
alignment=SectionAlignment.RIGHT
):
exp_echo.play(signal="drive", pulse=x90)
exp_echo.delay(signal="drive", time=echo_sweep)
exp_echo.play(signal="drive", pulse=x180)
exp_echo.delay(signal="drive", time=echo_sweep)
exp_echo.play(signal="drive", pulse=x90)
# readout pulse and data acquisition
)