Plot pulse sequences#

After programming a pulse sequence, we sometimes want to visually inspect what it looks like. The helper function utils.plot_sequence() does just that. Here is an example to highlight all the features. We program the pulse sequence in the same way we do it when we want to run the experiment. If we don’t have access to a Presto unit at the moment, we can pass dry_run=True to the Pulsed object. If we don’t get any error messages, we are sure the pulses sequence will run once we connect to Presto.

from presto import pulsed
from presto.hardware import AdcMode, DacMode
from presto.utils import plot_sequence
import numpy as np

with pulsed.Pulsed(dry_run=True, adc_mode=AdcMode.Mixed, dac_mode=DacMode.Mixed) as pls:
    pls.hardware.configure_mixer(freq=5.2e9, in_ports=1, out_ports=1)
    pls.hardware.configure_mixer(freq=5.5e9, out_ports=2)

    pls.setup_scale_lut(1, 0, np.linspace(-1, 1, 101), axis=0)
    pls.setup_scale_lut(1, 1, np.linspace(-1, 1, 128), axis=1)
    pls.setup_scale_lut(2, 0, 0.5)
    pls.setup_freq_lut(
        output_ports=1,
        group=0,
        frequencies=np.linspace(10e6, 100e6, 128),
        phases=[0.0] * 128,
        phases_q=[np.pi / 2] * 128,
        axis=1,
    )

    readout = pls.setup_long_drive(
        1, 0, 500e-9, rise_time=50e-9, fall_time=30e-9, amplitude=1 + 1j * 0.7, envelope=True
    )

    readout_1 = pls.setup_long_drive(
        1, 1, 500e-9, rise_time=50e-9, fall_time=30e-9, amplitude=1 + 1j * 0.05, envelope=False
    )
    control = pls.setup_template(2, 0, np.ones(40) - 1j * np.ones(40))

    pls.set_store_ports(1)
    pls.set_store_duration(1e-6)
    matches = pls.setup_template_matching_pair(
        1,
        np.cos(2 * np.pi * 100e6 * np.linspace(0, 100e-9, 100, False)),
        0.5 * np.sin(2 * np.pi * 100e6 * np.linspace(0, 100e-9, 100, False)),
    )

    T = 0.0
    pls.output_pulse(T, control)
    T += control.get_duration()
    pls.output_pulse(T, [readout, readout_1])
    pls.store(T + 230e-9)
    pls.match(T + 300e-9, matches)
    T += readout.get_duration()
    pls.next_scale(2000e-9, output_ports=1)
    pls.next_frequency(2000e-9, output_ports=1, group=0)
    T = 100e-6
    pls.run(T, (101, 128), 10)

To visualize the pulses we call utils.plot_sequence() just before or right after the Pulsed.run() command.

plot_sequence(pls, T, (101, 128), 10)

We pass the pls object that contains all the information about the programmed sequence, as well as the first three parameters that define the Pulsed.run() method: period, repeat_count, and num_averages.

../_images/plot_sequence_video_1.gif

We get an interactive plot. The sequence contains 3 complex-valued pulses since we are running in the Mixed mode. We can display only the real part (re), or both the real and the imaginary part (re+im) of the pulses by toggling the (re, re+im) toggle in the upper-right corner. The real part has a horizontal fill pattern, while the imaginary part has a vertical pattern. This way it is possible to distinguish the real and imaginary parts even if they are identical.

To better see individual pulses, we can decide to display output channels together (ch+) or separately (ch-), as well as displaying groups together (gr+) or separately (gr-). Pulses keep their colors, only the baseline is moving when we use this toggle.

It is possible to display raw templates (templ), templates multiplied by scales (scale) or normalized templates (norm) in case a template contains really small values and is hard to see in the first two modes.

The sampling windows and the matching templates are displayed in the store and match plots.

../_images/plot_sequence_video_2.gif

It is possible to perform multidimensional sweeps with Presto by passing a tuple to the repeat_count attribute. In this example, we perform a two-dimensional sweep 101x128. The frequency of the blue pulse and the amplitude of the orange pulse is simultaneously swept in the inner loop (axis=1), and the amplitude of the blue pulse is swept in the outer loop (axis=0). We can visualize the pulses in each iteration by moving the sliders. The number on the right of the axis sliders indicates the index of the iteration. The x-limit slider allows for the x limits of the plot to be adjusted.