Download

Download this file as Jupyter notebook: ramsey.ipynb.

Ramsey Experiment#

This section shows how to perform a Ramsey experiment to learn the dephasing time of a qubit. This experiment can be easily generated with RamseyExperiment.

Following the Qubit Spectroscopy and Rabi Experiment, we have determined the qubit’s resonance frequency and \(\pi\)-pulse amplitude which were stored in the calibration set. Given these, we are now able to implement the \(\frac{\pi}{2}\) gate to create an equal superposition between the ground and excited state. We begin characterizing the intrinsic noise of the system by learning the decay rate of the coherence between the ground and excited states of the qubit. The time scale associated with this decoherence is commonly referred to as the \(T_2^*\) time. The Ramsey experiment can also be used to measure the error in the measured resonance frequency of the qubit (the detuning frequency), and further tune up the calibration parameters.

A \(\frac{\pi}{2}\) gate applied to a qubit in the ground state creates an equal superposition state, shown below as a point on the \(XY\) plane of the Bloch sphere. The phase of the state evolves in time, corresponding to a natural precession around the \(Z\) axis. At the same time, dephasing occurs as the state shrinks on the Bloch sphere towards the center (the completely mixed state). After some time has elapsed, a second \(\frac{\pi}{2}\) gate can be applied to drive the qubit to either the ground or excited state. The magnitude of the dephasing can then be measured as the population in the excited state. The rotation shows up in the measurement as an oscillation between the ground and excited states, while the dephasing appears as an exponentially decaying envelope. By varying the delay time, we can learn the characteristic time scale of the decay.

If the control frequency and the qubit frequency match, i.e. there is no detuning, then we would not observe any oscillations between the ground and excited state. In the case of detuning, we observe an oscillation and this can be used to recalibrate the qubit’s resonance frequency.

../_images/ramsey_exp.png

To learn the \(T_2^*\) time and detuning frequency, we perform a Ramsey experiment as follows:

  1. Initialize the qubit to an equal superposition state between the ground and excited state (in the \(XY\) plane of the Bloch sphere) by applying a \(\frac{\pi}{2}\) gate.

  2. Apply a delay.

  3. Apply a second \(\frac{\pi}{2}\) gate to drive the qubit toward either the ground or excited state.

  4. Measure the population of the qubit in the excited state.

  5. Repeat the above steps with varying delay time.

Note

When selecting a value for the detuning frequency, users must ensure that the control frequency does not deviate from the LO frequency by more then 1 GHz, otherwise an error message will show up during execution. Also, to prevent the control frequency from being set to a value unsupported by the hardware, the library restricts the detune_frequency parameter to a range between -30 MHz and 30 MHz.

We start by initializing a qubit and loading a channel mapper to create a new instance of the RamseyExperiment class. Next, we generate a calibration set for the qubit using make_calibration_set(). This file includes the quantum operations and variables we will need to run the experiment.

[2]:
import keysight.qcs as qcs
import numpy as np
from keysight.qcs.experiments import RamseyExperiment
from keysight.qcs.experiments import make_calibration_set

# set the following to True when connected to hardware
run_on_hw = False

n_qubits = 1
qubits = qcs.Qudits(range(n_qubits))
calibration_set = make_calibration_set(n_qubits)
detune_frequency = 25e6

# generate an empty channel mapper
mapper = qcs.ChannelMapper("ip_addr")

# create Ramsey experiment
ramsey_experiment = RamseyExperiment(
    mapper,
    calibration_set=calibration_set,
    qubits=qubits,
    detune_frequency=detune_frequency,
)

ramsey_experiment.draw()

# The program consists of two simple `X90` gates separated by a variable delay
# followed by a measurement.
Program
keysight-logo-svg
Program Body
Program
Duration undefined
Layers 2
Targets 1
Layer #0
Layer #0
Duration undefined
Layer #1
Layer #1
Duration undefined
qudits 0
X90
Gate X90 on ('qudits', 0)

Matrix:
0.71 -0.71j
-0.71j 0.71
Delay on ('qudits', 0)

Parameters
Duration Array(name=pulse_delay, shape=(1,), dtype=float, unit=s)
X90
Gate X90 on ('qudits', 0)

Matrix:
0.71 -0.71j
-0.71j 0.71
Measure on ('qudits', 0)

Parameters
Dim 2
[3]:
# configure the repetitions for this experiment
start_delay = 40e-9
end_delay = 80e-9
steps = 3
scan_values = np.linspace([start_delay] * n_qubits, [end_delay] * n_qubits, steps)
ramsey_experiment.configure_repetitions(delays=scan_values, n_shots=1)

Compiling this program to the waveform level using the ParameterizedLinkers in the calibration set results in the following program:

[4]:
ramsey_experiment.compiled_program.draw()
Program
Sweep Details:
Repetitions Repeat with 1 repetitions
(HW)Repeat(1)
Sweep Details:
Repetitions Sweep with 3 repetitions
Associations
pulse_delay Array(name=_implicit, shape=(3, 1), dtype=float, unit=none, value=[[40 ns], [60 ns], [80 ns]])
(HW)Sweep_pulse_delay
keysight-logo-svg
Program Body
Program
Duration undefined
Layers 2
Targets 3
Layer #0
Layer #0
Duration undefined
Layer #1
Layer #1
Duration 105 ns
xy_pulse 0
RFWaveform on ('xy_pulse', 0)

Parameters
Duration ScalarRef(name=xy_pulse_durations, value=30 ns, dtype=float, unit=s)
Amplitude ScalarRef(name=_implicit, value=0.25, dtype=float, unit=none)
Frequency ScalarRef(name=xy_pulse_frequencies, value=5.125 GHz, dtype=float, unit=Hz)
Envelope GaussianEnvelope(2.0)
Instantaneous Phase ScalarRef(name=sx_phase, value=0 rad, dtype=float, unit=rad)
Post-phase ScalarRef(name=sx_post_phase, value=0 rad, dtype=float, unit=rad)
Delay on ('xy_pulse', 0)

Parameters
Duration Array(name=pulse_delay, shape=(1,), dtype=float, unit=s)
RFWaveform on ('xy_pulse', 0)

Parameters
Duration ScalarRef(name=xy_pulse_durations, value=30 ns, dtype=float, unit=s)
Amplitude ScalarRef(name=_implicit, value=0.25, dtype=float, unit=none)
Frequency ScalarRef(name=xy_pulse_frequencies, value=5.125 GHz, dtype=float, unit=Hz)
Envelope GaussianEnvelope(2.0)
Instantaneous Phase ScalarRef(name=sx_phase, value=0 rad, dtype=float, unit=rad)
Post-phase ScalarRef(name=sx_post_phase, value=0 rad, dtype=float, unit=rad)
readout_pulse 0
Delay on ('readout_pulse', 0)

Parameters
Duration ScalarRef(name=readout_pulse_delay, value=0 s, dtype=float, unit=s)
RFWaveform on ('readout_pulse', 0)

Parameters
Duration ScalarRef(name=readout_pulse_duration, value=100 ns, dtype=float, unit=s)
Amplitude ScalarRef(name=readout_pulse_amplitudes, value=0.1, dtype=float, unit=none)
Frequency ScalarRef(name=readout_frequencies, value=5.15 GHz, dtype=float, unit=Hz)
Envelope SineEnvelope()
Instantaneous Phase ScalarRef(name=readout_pulse_phases, value=0 rad, dtype=float, unit=rad)
Post-phase ScalarRef(name=measurement_post_phase, value=0 rad, dtype=float, unit=rad)
Delay on ('readout_pulse', 0)

Parameters
Duration Scalar(name=_implicit, value=5 ns, dtype=float, unit=s)
readout_acquisition 0
Delay on ('readout_acquisition', 0)

Parameters
Duration ScalarRef(name=acquisition_delay, value=5 ns, dtype=float, unit=s)
Acquisition on ('readout_acquisition', 0)

Parameters
Duration ScalarRef(name=acquisition_duration, value=100 ns, dtype=float, unit=s)
Integration Filter
RFWaveform

Parameters
Duration ScalarRef(name=acquisition_duration, value=100 ns, dtype=float, unit=s)
Amplitude ScalarRef(name=measurement_integrator_amplitude, value=1, dtype=float, unit=none)
Frequency ScalarRef(name=readout_frequencies, value=5.15 GHz, dtype=float, unit=Hz)
Envelope ConstantEnvelope()
Instantaneous Phase ScalarRef(name=measurement_integrator_phase, value=0 rad, dtype=float, unit=rad)
Post-phase ScalarRef(name=measurement_integrator_post_phase, value=0 rad, dtype=float, unit=rad)
Classifier Classifier(Array(name=references, shape=(1, 2), dtype=complex, unit=none))
Delay on ('readout_acquisition', 0)

Parameters
Duration Scalar(name=_implicit, value=4.96308e-24 s, dtype=float, unit=s)

We again use the render method to visualize this with the ChannelMapper.

[5]:
ramsey_experiment.compiled_program.render(
    channel_subplots=False,
    lo_frequency=5e9,
    sweep_index=2,
    sample_rate=5e9,
)

To execute this experiment, we can simply run

[6]:
if run_on_hw:
    ramsey_experiment.execute()
else:
    # load in a previously executed version of this experiment
    ramsey_experiment = qcs.load("RamseyExperiment.qcs")

For the purposes of this demonstration, we added a second “ancilla” qubit to the Ramsey program and connected the physical output channels for our qubit to the digizer associated with the ancilla to allow us to capture the full pulse sequence.

[7]:
ramsey_experiment.compiled_program.draw()
RamseyExperiment
Sweep Details:
Repetitions Sweep with 3 repetitions
Associations
pulse_delay Array(name=_implicit, shape=(3, 1), dtype=float, unit=none, value=[[40 ns], [60 ns], [80 ns]])
(SW)Sweep_pulse_delay
Sweep Details:
Repetitions Repeat with 1 repetitions
(HW)Repeat(1)
keysight-logo-svg
Program Body
RamseyExperiment
Duration undefined
Layers 2
Targets 4
Layer #0
Layer #0
Duration undefined
Layer #1
Layer #1
Duration 105 ns
xy_pulse 0
RFWaveform on ('xy_pulse', 0)

Parameters
Duration ScalarRef(name=xy_pulse_durations, value=30 ns, dtype=float, unit=s)
Amplitude ScalarRef(name=_implicit, value=0.25, dtype=float, unit=none)
Frequency ScalarRef(name=xy_pulse_frequencies, value=5.125 GHz, dtype=float, unit=Hz)
Envelope GaussianEnvelope(2.0)
Instantaneous Phase ScalarRef(name=sx_phase, value=0 rad, dtype=float, unit=rad)
Post-phase ScalarRef(name=sx_post_phase, value=0 rad, dtype=float, unit=rad)
Delay on ('xy_pulse', 0)

Parameters
Duration Array(name=pulse_delay, shape=(1,), dtype=float, unit=s)
RFWaveform on ('xy_pulse', 0)

Parameters
Duration ScalarRef(name=xy_pulse_durations, value=30 ns, dtype=float, unit=s)
Amplitude ScalarRef(name=_implicit, value=0.25, dtype=float, unit=none)
Frequency ScalarRef(name=xy_pulse_frequencies, value=5.125 GHz, dtype=float, unit=Hz)
Envelope GaussianEnvelope(2.0)
Instantaneous Phase ScalarRef(name=sx_phase, value=0 rad, dtype=float, unit=rad)
Post-phase ScalarRef(name=sx_post_phase, value=0 rad, dtype=float, unit=rad)
readout_acquisition 0
Delay on ('readout_acquisition', 0)

Parameters
Duration ScalarRef(name=acquisition_delay, value=5 ns, dtype=float, unit=s)
Acquisition on ('readout_acquisition', 0)

Parameters
Duration ScalarRef(name=acquisition_duration, value=100 ns, dtype=float, unit=s)
Integration Filter
RFWaveform

Parameters
Duration ScalarRef(name=acquisition_duration, value=100 ns, dtype=float, unit=s)
Amplitude ScalarRef(name=measurement_integrator_amplitude, value=1, dtype=float, unit=none)
Frequency ScalarRef(name=readout_frequencies, value=5.15 GHz, dtype=float, unit=Hz)
Envelope ConstantEnvelope()
Instantaneous Phase ScalarRef(name=measurement_integrator_phase, value=0 rad, dtype=float, unit=rad)
Post-phase ScalarRef(name=measurement_integrator_post_phase, value=0 rad, dtype=float, unit=rad)
Classifier Classifier(Array(name=references, shape=(1, 2), dtype=complex, unit=none))
Delay on ('readout_acquisition', 0)

Parameters
Duration Scalar(name=_implicit, value=4.96308e-24 s, dtype=float, unit=s)
1
Acquisition on ('readout_acquisition', 1)

Parameters
Duration Scalar(name=_implicit, value=40 ns, dtype=float, unit=s)
Integration Filter
DCWaveform

Parameters
Duration Scalar(name=_implicit, value=40 ns, dtype=float, unit=s)
Amplitude 1
Frequency 0 Hz
Envelope ConstantEnvelope()
Instantaneous Phase 0
Post-phase 0
readout_pulse 0
Delay on ('readout_pulse', 0)

Parameters
Duration ScalarRef(name=readout_pulse_delay, value=0 s, dtype=float, unit=s)
RFWaveform on ('readout_pulse', 0)

Parameters
Duration ScalarRef(name=readout_pulse_duration, value=100 ns, dtype=float, unit=s)
Amplitude ScalarRef(name=readout_pulse_amplitudes, value=0.1, dtype=float, unit=none)
Frequency ScalarRef(name=readout_frequencies, value=5.15 GHz, dtype=float, unit=Hz)
Envelope SineEnvelope()
Instantaneous Phase ScalarRef(name=readout_pulse_phases, value=0 rad, dtype=float, unit=rad)
Post-phase ScalarRef(name=measurement_post_phase, value=0 rad, dtype=float, unit=rad)
Delay on ('readout_pulse', 0)

Parameters
Duration Scalar(name=_implicit, value=5 ns, dtype=float, unit=s)

The ancilla qubit is mapped to the digitizer channel 1 and has a single acquisition that spans the duration of both control pulses and the maximum delay between them.

[8]:
ramsey_experiment.plot_trace(channels=qcs.Qudits(1, "ancilla"))

Here we can see two control pulses separated by our varying delays.

Note

The local oscillator (LO) and detuning frequency were set to 5.1 GHz and 25 MHz for this example, and we also limited the number of delay sweep points to keep the visualization easy to interpret.


Download

Download this file as Jupyter notebook: ramsey.ipynb.