Experiment Module

The experiment module provides a hierarchy of classes for building, validating, and executing NMR pulse sequences on the OPX-1000. The base class Experiment holds the command queue, configuration, and shared infrastructure. The concrete subclasses Experiment1D, Experiment2D, and Experiment3D implement the loop structure and data-processing logic appropriate to each experiment dimensionality.

Designing Experiments

The three concrete subclasses differ only in how many swept parameters they support:

Class

Swept parameters

Typical use cases

Experiment1D

0

FID, single-pulse readout

Experiment2D

1

T1, T2, pulse calibration, Floquet correlation measurements

Experiment3D

2

Joint relaxation / amplitude scans, Multiple Quantum Coherence (MQC) experiments

Adding commands

Pulse sequences are built by appending commands before execution. All commands accept either scalar or iterable (NumPy array) arguments for the swept dimension.

expt.add_pulse(name, element, phase=0.0, amplitude=1.0, length=None)
expt.add_delay(duration)
expt.add_align(elements=None)
expt.add_floquet_sequence(phases, delays, repetitions)
expt.add_z_rotation(angle, element)    # virtual-Z gate (frame rotation)
expt.add_frame_change(angle, element)  # per-pulse frame correction

Scalar arguments produce a fixed value in the compiled QUA program. Passing a NumPy array registers a loop variable; the array becomes the sweep vector iterated over in the QUA for_ loop.

Loop layers and QUA variables

Each swept dimension corresponds to one loop layer. The loop_layer keyword selects which QUA loop variable a command’s array is bound to. The indexing is 1-based:

loop_layer

Internal slot var_vec_lst[...]

QUA variable name

Sweep speed

1

var_vec_lst[0]

var_outer (3D) / var (2D)

Outermost swept loop — slowest changing

2

var_vec_lst[1]

var_inner (3D only)

Inner swept loop — fastest changing

The default value loop_layer=-1 instructs the class to automatically assign the variable to the first unfilled slot. Explicit values are strongly preferred in 3D experiments to avoid accidental axis transposition.

Designing a 2D experiment

Assign a NumPy array to any add_* argument. All arrays across all commands in the experiment must be identical or a constant scalar multiple of each other — they all map to the same QUA variable.

import numpy as np, qeg_nmr_qua as qnmr
from qualang_tools.units import unit

u = unit(coerce_to_integer=True)
amp_list = np.arange(0.93, 1.05, 0.01)

expt = qnmr.Experiment2D(settings=settings, config=cfg)
expt.add_pulse(
    name=settings.pi_half_key,
    element=settings.res_key,
    amplitude=amp_list,       # marks amp_list as layer-1 sweep
)
# A second pulse whose amplitude is 2× amp_list is still consistent:
expt.add_pulse(
    name=settings.pi_half_key,
    element=settings.res_key,
    amplitude=2 * amp_list,   # scalar-multiple of existing vector — OK
)
expt.update_sweep_axis(amp_list * settings.pulse_amplitude)
expt.update_sweep_label("Pulse Amplitude (Vpp)")
expt.execute_experiment()

Designing a 3D experiment

Two independent arrays must be provided, one per loop layer. The data shape returned after execute_experiment is ``(n_outer, n_inner, n_time)`` — axes ordered from slowest to fastest varying, followed by the readout time axis.

Rule summary

  • loop_layer=1 → stored in var_vec_lst[0] → compiled into the outer (slow) QUA loop as var_outer.

  • loop_layer=2 → stored in var_vec_lst[1] → compiled into the inner (fast) QUA loop as var_inner.

  • Multiple commands may share the same loop_layer provided their arrays are constant multiples of each other.

  • Mixing integer and fixed-point types within the same layer raises a ValueError at build time.

import numpy as np, qeg_nmr_qua as qnmr
from qualang_tools.units import unit

u = unit(coerce_to_integer=True)

# Define the two sweep axes explicitly:
delay_list = np.array([1, 2, 4, 8, 16, 32]) * u.us   # outer (slow)
amp_list   = np.arange(0.95, 1.06, 0.01)             # inner (fast)

expt = qnmr.Experiment3D(settings=settings, config=cfg)

# layer=1 → outer loop (slow sweep, var_outer in QUA)
expt.add_delay(delay_list, loop_layer=1)

# layer=2 → inner loop (fast sweep, var_inner in QUA)
expt.add_pulse(
    name=settings.pi_half_key,
    element=settings.res_key,
    amplitude=amp_list,
    loop_layer=2,
)

expt.update_sweep_axis_outer(delay_list / u.us)
expt.update_sweep_label_outer("Delay (µs)")
expt.update_sweep_axis_inner(amp_list * settings.pulse_amplitude)
expt.update_sweep_label_inner("Pulse Amplitude (Vpp)")

expt.execute_experiment()

# I_data shape: (6, 11, n_time)
I_data = expt.save_data_dict["I_data"]

Warning

Incorrect ``loop_layer`` is a silent data-ordering bug. The program will compile and run without error, but the outer and inner axes of the data array will be swapped. To verify loop assignments before running on hardware, use compile_to_qua() with offline=True and inspect the generated for_ nesting in the output file.

Variable types: integer vs. fixed-point

QUA distinguishes between integer (int) and fixed-point (fixed) variables. The type is inferred from the swept parameter:

  • Amplitudes and phasesfixed (fractional values).

  • Durations (delays, pulse lengths) → int (clock cycles, always integer).

The class records the inferred type in use_fixed_lst and declares the corresponding QUA variable type when the program is compiled. You cannot mix integer and fixed-point arrays on the same loop layer.

Inspecting the compiled program

compile_to_qua() generates the full QUA script as a plain-text file without connecting to hardware:

expt.compile_to_qua(offline=True, save_path=Path("my_experiment.qua"))

This is the recommended first step for any new 3D experiment — confirm that var_outer and var_inner appear in the expected for_ loop positions.

Subclassing the base class

Advanced users can subclass Experiment directly to implement custom loop structures or non-standard readout schemes. Three methods must be overridden:

validate_experiment()

Called before the QUA program is compiled. Raise ValueError for any inconsistency that would cause a QUA runtime error (e.g. missing loop vectors, incompatible lengths). This catches user errors before they propagate into hard-to-read QUA tracebacks.

create_experiment()

Builds and returns the QUA program() object. Call translate_command() for each item in self._commands to emit the pulse/delay/align QUA instructions. All timings must be expressed in clock cycles (divide nanoseconds by 4). Data streams must be buffered consistently with the expected shape consumed in data_processing.

data_processing()

Called after the job is launched. Fetch data via qualang_tools.results.fetching_tool, convert demodulated values to volts, and populate self.save_data_dict.

Safety macros

The macros module provides three macros that must be called in the correct order to protect the hardware:

drive_mode(switch, amplifier)    # open switch, unblank amplifier — before pulse sequence
safe_mode(switch, amplifier)     # blank amplifier, open switch   — after pulse sequence
readout_mode(switch, amplifier)  # close switch, blank amplifier  — during readout

All three insert align() calls and explicit wait times (RX_SWITCH_DELAY, AMPLIFIER_BLANKING_TIME) to ensure hardware state transitions complete before the next operation.

Base Experiment

class qeg_nmr_qua.experiment.experiment.Experiment(settings, config=None, connect=True)[source]

Bases: object

Base class for conducting NMR experiments on the OPX-1000.

This class manages quantum machine configurations, experiment commands (pulses, delays, alignments), and data collection. It provides a structured interface for building and executing pulse sequences with support for looped experiments and real-time data acquisition.

Subclasses should implement experiment-specific logic in:

  • create_experiment(): Build the QUA program from stored commands

  • validate_experiment(): Validate settings and command consistency

  • data_processing(): Handle real-time data during hardware execution

Typical workflow:

  1. Create an Experiment subclass instance with relevant settings and config

  2. Build sequence: add pulses, delays, and alignments using add_* methods

  3. Test: call simulate_experiment() to verify timing and waveforms

  4. Execute: call execute_experiment() to run on hardware

  5. Save: call save_data() to persist configuration, settings, and results

settings

Experiment-specific parameters (frequencies, pulse lengths, etc.)

config

OPX configuration object

save_dir

Directory to save experiment data

save_data_dict

Dictionary which contains data extracted during the experiment for saving

qmm

QuantumMachinesManager instance for managing connection to the OPX-1000

__init__(settings, config=None, connect=True)[source]

Initialize experiment with configuration and settings.

Parameters:
  • settings (ExperimentSettings) – Experiment-specific parameters (frequencies, pulse lengths, etc.).

  • config (OPXConfig) – OPX configuration. If None, automatically generated from settings.

  • connect (bool) – Whether to establish a live connection to the OPX-1000 via QuantumMachinesManager. Set to False for offline compilation or unit testing. Defaults to True.

Raises:

ValueError – If readout delay is too short to accommodate switching times.

add_pulse(element, shape=None, phase=0.0, amplitude=1.0, length=None, loop_layer=-1)[source]

Adds a pulse command to the experiment. Stores the data to control the pulse in the experiment’s command list, and ensures the command is well defined. Timings are converted from ns and stored in clock cycles (4 ns).

Parameters:
  • element (str) – Element to which the pulse is applied. Must be defined in the config.

  • shape (str) – Shape of the pulse operation, defaults to settings.pulse_shape if not provided.

  • phase (float | Iterable) – Phase of the pulse in degrees. Stored as a fraction of 2π.

  • amplitude (float | Iterable) – Amplitude scale factor for the pulse waveform.

  • length (int | Iterable) – Length of the pulse in nanoseconds, overriding the waveform default.

  • loop_layer (int) – Loop layer (1-based) to associate with the swept parameter. Use -1 (default) to auto-assign to the first available layer.

add_delay(duration, loop_layer=-1)[source]

Adds a delay command to the experiment. Stores the data to control the delay in the experiment’s command list.

Parameters:
  • duration (int | Iterable) – Duration of the delay in nanoseconds.

  • loop_layer (int) – Loop layer (1-based) to associate with the swept duration. Use -1 (default) to auto-assign to the first available layer.

add_align(elements=None)[source]

Adds an align command to the experiment. Stores the data to control the alignment in the experiment’s command list.

Parameters:

elements (list[str]) – List of elements to align.

add_floquet_sequence(phases, delays, repetitions, loop_layer=-1, element=None, shape=None)[source]

Adds a Floquet sequence to the experiment. This is a repeating block of evenly-spaced, phase-cycled pulses of the form:

delay[0] — (R(phase[0]) — delay[1]) — (R(phase[1]) — delay[2]) — … repeated N times

The number of repetitions can be a fixed integer or a 1-D array, in which case it becomes the swept loop variable for the given loop_layer.

Parameters:
  • phases (list[float]) – Phase of each pulse in the block, in degrees.

  • delays (list[int]) – Inter-pulse delays in nanoseconds. Must contain exactly len(phases) + 1 entries (one leading delay plus one after each pulse).

  • repetitions (int | Iterable) – Number of times the pulse block is repeated. Pass an array to sweep over this parameter.

  • loop_layer (int) – Loop layer (1-based) to associate with a swept repetitions array. Use -1 (default) to auto-assign.

  • element (str) – Element to apply the sequence to. Defaults to settings.res_key (the probe channel) when None.

  • shape (str) – Pulse shape key, defaults to settings.pulse_shape.

Raises:
  • ValueError – If len(delays) != len(phases) + 1.

  • ValueError – If element or shape are not recognised in the config.

add_z_rotation(angle, elements, loop_layer=-1)[source]

Adds a virtual Z rotation to the experiment. This is implemented as a frame rotation in QUA.

Parameters:
  • angle (float | Iterable) – Angle(s) of the Z rotation in degrees.

  • elements (str | Iterable[str]) – Element(s) to which the Z rotation is applied. Must be defined in the config.

  • loop_layer (int) – Loop layer (1-based) to associate with a swept angle array. Use -1 (default) to auto-assign.

add_frame_change(angle, elements)[source]

Adds frame change compensation to the experiment, which is implemented as a frame rotation after each applied pi-half pulse. This feature is useful for correcting out-of-phase overrotation errors in pi-half only pulse sequences. In principle, any pulse sequence can be written with only pi-half pulses and z-rotations, allowing for frame change compensation to be applied in all cases.

Parameters:
  • angle (float) – Angle of the frame change in degrees.

  • elements (str | Iterable[str]) – Element(s) to which the frame change is applied. Must be defined in the config.

remove_initial_delay(remove=True)[source]

Removes the 5 T1 delay from the start of the sequence. Useful for testing with the simulator, but should be generally used to ensure proper thermalization between experiments. By default, the delay is included. The delay can be re-added by calling this method with remove set to False.

Parameters:

remove (bool) – By default, is True, removes the initial delay. If False, the delay is re-added.

translate_command(command, vars=None, loop_idx=None)[source]

Translates a command dictionary into QUA code.

Parameters:
  • command (dict) – Command dictionary to translate.

  • vars (Any, optional) – QUA Variables to use for swept parameters.

  • loop_idx (Any, optional) – QUA Variable to use for loop index.

Raises:

ValueError – If the command type is unknown.

create_experiment()[source]

Creates the Quantum Machine program for the experiment, and returns the experiment object as a qua program. This is used by the execute_experiment() and simulate_experiment() methods.

Returns:

The QUA program for the experiment defined by this class’s commands.

Return type:

program

validate_experiment()[source]

Function to be implemented by subclasses to validate that the commands and settings for the experiment are consistent and valid. Running this function should return helpful error messages if the experiment is not properly defined.

compile_to_qua(offline=True, save_path=None)[source]

Compiles the experiment to a QUA program, running all python code in order to generate the final QUA program as a string, which is then saved to disk at the specified path. This is useful for inspecting the generated QUA program to verify that the commands are being translated as expected, and can be used for debugging command translation and config interpreation issues without needing to run the experiment on hardware or in the simulator.

Parameters:
  • offline (bool) – Whether to compile offline, or to use the connected Quantum Machine. Defaults to True for offline compilation.

  • save_path (Path) – The path to save the compiled QUA program. If None, saves to the same directory as this file with the name “compiled_experiment.qua”.

simulate_experiment(sim_length=40000)[source]

Simulates the experiment using the configured experiment defined by this class based on the current config defined by this instance’s config attribute. The simulation returns the generated waveforms of the experiment up to the duration sim_length in ns. Useful for checking the timings before running on hardware.

Parameters:

sim_length (int, optional) – The duration of the simulation in ns. Defaults to 40_000.

execute_experiment(live=True, wait_on_close=True, title_prefix='')[source]

Executes the experiment using the configured experiment defined by this class based on the current config defined by this instance’s config attribute. The method handles the execution on hardware, data fetching, and basic plotting of results.

Parameters:
  • live (bool) – Passed into data_processing to determine whether to display data live during execution or only after completion, depending on the subclass implementation.

  • wait_on_close (bool) – Whether to wait for user to close plot window after experiment completes. Only relevant when live=True. Defaults to True.

  • title_prefix (str) – Prefix to add to plot title for identification. Defaults to empty string.

Raises:

ValueError – Throws an error if insufficient details about the experiment are defined.

data_processing(qm, job, live=True, wait_on_close=True, title_prefix='')[source]

Grabs the results of the experiment as it is being executed. This method must be implemented by subclasses to determine how to fetch and plot the data specific to the experiment. The specific handles for the quantum machine and the active job are provided for data fetching. Additionally, this method can (and should) update the save_data_dict attribute with relevant raw data for saving to disk after the experiment completes.

Subclass implementations should make use of the live argument to determine whether to plot data live during execution or only after the experiment completes. Autonomous experiments will typically want to set live to False to avoid blocking execution when waiting for user input to close plots.

Parameters:
  • qm (QuantumMachine) – The quantum machine executing the experiment.

  • job (RunningQmJob) – The job running the experiment.

  • live (bool) – Whether to display data live during execution or only after completion.

  • wait_on_close (bool) – Whether to wait for user to close plot after completion. Only relevant when live=True.

  • title_prefix (str) – Prefix to add to plot titles for identification.

save_data(experiment_prefix='experiment')[source]

Saves the experiment data to the specified directory using the DataSaver.

Creates a folder with an auto-incremented name based on experiment_prefix (e.g., prefix_0001, prefix_0002) containing: - config.json: OPX configuration - settings.json: Experiment settings - commands.json: List of commands executed - data.json: Experimental results and metadata

Each experiment is saved in a newly created folder with a simple naming structure for easy loading elsewhere.

Parameters:

experiment_prefix (str) – Prefix for the experiment folder naming. Defaults to “experiment”. The created folder name will be <experiment_prefix>_NNNN with a 4-digit counter.

Raises:

ValueError – If experiment_prefix contains path separators or is invalid.

1D Experiments

class qeg_nmr_qua.experiment.experiment_1d.Experiment1D(settings, config=None, connect=True)[source]

Bases: Experiment

Class to create and run 1D NMR experiments using the QUA programming language. Inherits from the base Experiment class and implements methods specific to 1D experiments, usually used for measuring free induction decay (FID) signals. The resulting signal is used to calibrate drifts in the nuclear spin frequency phase reference.

In solid-state systems, the FID signal typically decays within 100-500 microseconds due to strong dipolar interactions between nuclear spins. Direct fitting of T2* from the FID is often unreliable because of this rapid decay.

validate_experiment()[source]

Checks to make sure that the experiment contains no variable operations, since it is a 1D experiment. Variable operations require looping which is not supported in 1D experiments.

Raises:

ValueError – A looping operation was found in the experiment commands.

create_experiment()[source]

Creates the Quantum Machine program for the experiment, and returns the experiment object as a qua program. This is used by the execute_experiment() and simulate_experiment() methods.

Returns:

The QUA program for the experiment defined by this class’s commands.

Return type:

program

data_processing(qm, job, live, wait_on_close=True, title_prefix='')[source]

Handles live data processing for a 1D experiment during execution.

This method fetches data from the Quantum Machine job, processes it into voltage units via digital demodulation, and generates a live plot when live is set to True. The plot shows I and Q as a function of acquisition time. After the experiment completes, the final data is saved into save_data_dict for later analysis and storage.

Parameters:
  • qm (QuantumMachine) – The Quantum Machine instance used to run the experiment.

  • job (RunningQmJob) – The job object representing the running experiment.

  • live (bool) – Flag indicating whether to generate live plots during data acquisition.

  • wait_on_close (bool) – Whether to wait for user to close plot after completion.

  • title_prefix (str) – Prefix to add to plot title.

2D Experiments

class qeg_nmr_qua.experiment.experiment_2d.Experiment2D(settings, config=None, connect=True)[source]

Bases: Experiment

Class to create and run 2D NMR experiments using the QUA programming language. Inherits from the base Experiment class and implements methods specific to 2D experiments, which can have a broad range of applications such as measuring relaxation times (T1, T2), performing pulse amplitude sweeps, and performing two-point correlation measurements under Hamiltonian engineering pulse sequences.

2D experiments involve sweeping one parameter (e.g., pulse amplitude, delay time, evolution time) while measuring the system’s response. This is typically done by defining a variable vector that contains the values to be swept. The experiment loops over this vector, applying the corresponding parameter value in each iteration. In this class’s implementation, the swept parameter is varied first, then the averaging loop is performed. During longer experiments, this ordering should help mitigate the effects of slow drifts in system parameters.

__init__(settings, config=None, connect=True)[source]

Initialize experiment with configuration and settings.

Parameters:
  • settings (ExperimentSettings) – Experiment-specific parameters (frequencies, pulse lengths, etc.).

  • config (OPXConfig) – OPX configuration. If None, automatically generated from settings.

  • connect (bool) – Whether to establish a live connection to the OPX-1000 via QuantumMachinesManager. Set to False for offline compilation or unit testing. Defaults to True.

Raises:

ValueError – If readout delay is too short to accommodate switching times.

update_sweep_axis(new_axis)[source]

Updates the sweep axis for live plotting and data saving. If this method is not called, the first element of the variable vector collection var_vec_list will be used as the sweep axis by default. It can be convienient to change the sweep axis to a more physically meaningful quantity (e.g., converting pulse amplitude rescaling factor physical Vpp units).

update_sweep_label(new_label)[source]

Updates the label for the sweep axis in live plotting. If this method is not called, the default label “Swept Variable” will be used.

validate_experiment()[source]

Checks to make sure that the experiment contains variable operations, since it is a 2D experiment. Variable operations require looping which is supported in 2D experiments.

Raises:

ValueError – No variable vector was found in the experiment commands.

create_experiment()[source]

Creates the Quantum Machine program for the experiment, and returns the experiment object as a qua program(). This is used by the execute_experiment() and simulate_experiment() methods.

Returns:

The QUA program for the experiment defined by this class’s commands.

Return type:

program

data_processing(qm, job, live, wait_on_close=True, title_prefix='')[source]

Handles live data processing for a 2D experiment during execution. This method fetches data from the Quantum Machine job, processes it into voltage units via digital demodulation, and generates live plots when live is set to True. The plot includes 2D color plots of the I and Q signals as functions of the swept variable and acquisition time, as well as a line plot of the primary signal, determined to be the first element of each FID’s I data. This captures the essential observable for 2D NMR experiments, such as calibrations of T1, T2, pulse amplitude sweeps, and Hamiltonian engineering measurements of two-point correlations.

After the experiment completes, the final data is saved into the save_data_dict for later analysis and storage.

Parameters:
  • qm (QuantumMachine) – The Quantum Machine instance used to run the experiment.

  • job (RunningQmJob) – The job object representing the running experiment.

  • live (bool) – Flag indicating whether to generate live plots during data acquisition.

  • wait_on_close (bool) – Whether to wait for user to close plot after completion.

  • title_prefix (str) – Prefix to add to plot title.

3D Experiments

class qeg_nmr_qua.experiment.experiment_3d.Experiment3D(settings, config=None, connect=True)[source]

Bases: Experiment

Class to create and run 3D NMR experiments using the QUA programming language. Inherits from the base Experiment class and implements methods specific to 3D experiments, which can have a broad range of applications such as measuring relaxation times (T1, T2), performing pulse amplitude sweeps, and performing two-point correlation measurements under Hamiltonian engineering pulse sequences.

3D experiments involve sweeping two parameters (e.g., pulse amplitude, delay time, evolution time) while measuring the system’s response. This is typically done by defining two variable vectors that contain the values to be swept. The experiment loops over these vectors, applying the corresponding parameter values in each iteration. In this class’s implementation, the swept parameters are varied first, then the averaging loop is performed. During longer experiments, this ordering should help mitigate the effects of slow drifts in system parameters.

__init__(settings, config=None, connect=True)[source]

Initialize experiment with configuration and settings.

Parameters:
  • settings (ExperimentSettings) – Experiment-specific parameters (frequencies, pulse lengths, etc.).

  • config (OPXConfig) – OPX configuration. If None, automatically generated from settings.

  • connect (bool) – Whether to establish a live connection to the OPX-1000 via QuantumMachinesManager. Set to False for offline compilation or unit testing. Defaults to True.

Raises:

ValueError – If readout delay is too short to accommodate switching times.

update_sweep_axis_inner(new_axis)[source]

Updates the sweep axis for live plotting and data saving. If this method is not called, the variable vector var_vec will be used as the sweep axis by default. It can be convenient to change the sweep axis to a more physically meaningful quantity (e.g., converting pulse amplitude rescaling factor physical Vpp units).

update_sweep_label_inner(new_label)[source]

Updates the label for the sweep axis in live plotting. If this method is not called, the default label “Swept Variable” will be used.

update_sweep_axis_outer(new_axis)[source]

Updates the sweep axis for live plotting and data saving. If this method is not called, the variable vector var_vec will be used as the sweep axis by default. It can be convenient to change the sweep axis to a more physically meaningful quantity (e.g., converting pulse amplitude rescaling factor physical Vpp units).

update_sweep_label_outer(new_label)[source]

Updates the label for the sweep axis in live plotting. If this method is not called, the default label “Swept Variable” will be used.

validate_experiment()[source]

Checks to make sure that the experiment contains variable operations, since it is a 3D experiment. Variable operations require looping which is supported in 3D experiments.

Raises:

ValueError – No variable vector was found in the experiment commands.

create_experiment()[source]

Creates the Quantum Machine program for the experiment, and returns the experiment object as a qua program(). This is used by the execute_experiment() and simulate_experiment() methods.

Returns:

The QUA program for the experiment defined by this class’s commands.

Return type:

program

data_processing(qm, job, live, wait_on_close=True, title_prefix='')[source]

Handles live data processing for a 3D experiment during execution.

Fetched data has shape (n_outer, n_inner, n_time) after on-FPGA averaging. Two heatmaps are displayed, both with the outer-sweep variable on the y-axis and the inner-sweep variable on the x-axis:

  • Left panelI[:, :, 0]: the first sampled time-point of the I quadrature for every (outer, inner) parameter pair, in µV. This is the primary NMR observable for sequences that refocus at time zero.

  • Right panelstd of Q[:, :, -20:]: the standard deviation computed over the final 20 readout points of the Q quadrature, in µV. This tracks the noise floor of the tail of the FID.

Parameters:
  • qm (QuantumMachine) – The Quantum Machine instance used to run the experiment.

  • job (RunningQmJob) – The job object representing the running experiment.

  • live (bool) – Flag indicating whether to generate live plots during data acquisition.

  • wait_on_close (bool) – Whether to wait for user to close plot after completion.

  • title_prefix (str) – Prefix to add to plot title.

Experiment Macros

qeg_nmr_qua.experiment.macros.drive_mode(switch, amplifier)[source]

Configures the hardware such that the receiver switch does not allow signal to pass through, and the amplifier is turned on and unblanked, ready for driving the system. This adds 4 align() calls and 730 clock cycles of wait time.

qeg_nmr_qua.experiment.macros.readout_mode(switch, amplifier)[source]

Configures the hardware such that the receiver switch allows signal to pass through, and the amplifier off (blanked) for reading out the resonator. This adds 4 align() calls and 730 clock cycles of wait time.

qeg_nmr_qua.experiment.macros.safe_mode(switch, amplifier)[source]

Turns off the amplifier and opens the switch to ensure that no signal can pass through. This adds 3 align() calls and 500 clock cycles of wait time.