Configuration Module
The configuration module provides classes and utilities for managing OPX-1000 configurations. The Settings
class contains high-level parameters for nuclear spin control, while the other classes define specific configuration
elements such as chasis, controller, element, pulse, waveform, and integration weights. Unless modifying the
hardware configureation, users will primarily interact with the Settings class and the configuration generator function,
config_from_settings().
Settings
- class qeg_nmr_qua.config.settings.ExperimentSettings(n_avg=4, pulse_length=1100, pulse_amplitude=0.25, pulse_shape='square', pulse_rise_fall=0.0, rotation_angle=90.0, const_len=100, const_amp=0.03, thermal_reset=4000000000, center_freq=282190100, offset_freq=750, readout_delay=20000, readout_amp=0.01, dwell_time=4000, readout_start=0, readout_end=256000, resonator_relaxation=250000, excitation_length=5000, save_dir=None, res_key='resonator', amp_key='amplifier', helper_key='helper', sw_key='switch', square_key='square', square_pi_key='square_pi', gaussian_key='gaussian', gaussian_square_key='gaussian_square', lowpass_square_key='lowpass_square', tukey_key='tukey')[source]
Bases:
objectContainer for experiment-specific program parameters and hardware configuration.
This dataclass manages all user-facing settings for NMR experiments on the OPX-1000, including pulse parameters, frequencies, readout configuration, and data handling. All values are stored in standard units (nanoseconds, Hz, amplitude) and converted internally as needed.
Features:
Mutable with validation: Settings can be updated atomically with
update()Serialization: Convert to/from dictionaries with
to_dict()andfrom_dict()Change notifications: Register callbacks with
register_update_callback()to be notified when settings changeAtomic updates: All changes are validated before being applied
Parameter Groups:
Pulse Parameters: Core pulse control settings
n_avg: Number of signal averages (default: 4)pulse_length: Duration of control pulse in nanoseconds (default: 1.1 µs)pulse_amplitude: Normalized pulse amplitude 0-0.5 (default: 0.25, representing 0.5 Vpp)pulse_shape: Name of pulse shape operation (default: “sqr_pi_half”)pulse_rise_fall: Fraction of pulse length for rise/fall time from 0 to 1 (default: 0.0)rotation_angle: Pulse rotation angle in degrees (default: 90°)
Continuous Wave (CW) Parameters: For continuous wave experiments
const_len: Length of continuous wave pulse in nanoseconds (default: 100 ns)const_amp: Amplitude of continuous wave pulse (default: 0.03)
Timing Parameters: Experiment timing and delays
thermal_reset: Pre-scan delay for thermal equilibration, in nanoseconds (default: 4 s)readout_delay: Minimum delay before measurement occurs, in nanoseconds (default: 20 µs)dwell_time: Demodulation interval during readout, in nanoseconds (default: 4 µs)readout_start: Start time of readout window, in nanoseconds (default: 0)readout_end: End time of readout window, in nanoseconds (default: 256 µs)
Frequency Parameters: NMR frequency configuration
center_freq: Center frequency for NMR in Hz (default: 282.1901 MHz for ¹⁹F)offset_freq: Frequency offset in Hz. This increases by 50-100 Hz every few days (default: 750 Hz)
Resonator Parameters: Resonator excitation settings
readout_amp: Readout pulse amplitude, should be small (default: 0.01)excitation_length: Duration of resonator excitation pulse in nanoseconds (default: 5 µs)excitation_amp: Amplitude of resonator excitation (default: 0.03)
Data Handling:
save_dir: Directory for saving experimental data (default: None, usesdata/folder)
Configuration Keys: Element names in the OPX configuration
res_key: Resonator element name (default: “resonator”)amp_key: Amplifier element name (default: “amplifier”)helper_key: Helper element name (default: “helper”)sw_key: Switch control element name (default: “switch”)sqr_pi_half_key: π/2 pulse operation name (default: “sqr_pi_half”)gaus_pi_half_key: Gaussian π/2 pulse operation name (default: “gaus_pi_half”)gaus_sqr_pi_half_key: Gaussian square pulse operation name (default: “gaus_sqr_pi_half”)
Validation:
All settings are validated on instantiation and update:
n_avgmust be an integer >= 1pulse_lengthmust be >= 64 nspulse_amplitudemust be in range [-0.5, 0.5]pulse_rise_fallmust be in range [0, 1]readout_delaymust be >= 5 µsFrequency must be in valid OPX range: 0 <= (center_freq - offset_freq) < 750 MHz
- excitation_amp = 0.03
- validate()[source]
Validate all current settings and raise ValueError if any are invalid.
This method checks all constraints defined for ExperimentSettings:
n_avgmust be a positive integerpulse_lengthmust be at least 64 ns (4 clock cycles @ 16 ns each)pulse_amplitudemust be in range [-0.5, 0.5] (max ±1 Vpp)readout_delaymust be at least 5 µs for ringdown protectionEffective frequency (center_freq - offset_freq) must be in OPX range [0, 750 MHz)
rotation_angleis normalized to [0, 360) automatically
- Raises:
ValueError – If any setting violates the defined constraints.
- Return type:
- update(**kwargs)[source]
Update one or more settings atomically with full validation.
All requested changes are validated together before any are applied, ensuring the settings object remains in a valid state even if update fails. Registered callbacks are invoked only if changes are actually made.
Thread Safety: Not thread-safe. Callers must serialize access if concurrent updates are possible in their environment.
- Parameters:
**kwargs – Field names and new values. Unknown fields raise AttributeError.
- Returns:
- Dictionary of fields that actually changed (name -> new_value).
Empty dict if no changes were made or all new values matched existing ones.
- Return type:
- Raises:
AttributeError – If an unknown setting name is provided.
ValueError – If validation fails for any changed setting (no changes applied).
Example
>>> settings = ExperimentSettings() >>> changes = settings.update(pulse_length=2000, n_avg=8) >>> # changes now contains {"pulse_length": 2000, "n_avg": 8}
- to_dict()[source]
Convert settings to a serializable dictionary.
Returns all user-facing settings as a plain Python dict suitable for JSON serialization or storage. Internal fields (callbacks, locks, etc.) are excluded.
- Returns:
A shallow copy of all settings with internal fields excluded.
- Return type:
See also
from_dict()to reconstruct settings from a dict.
- classmethod from_dict(data)[source]
Create a new ExperimentSettings instance from a dictionary.
Constructs a new instance with validation. Unknown fields in the input dict are silently ignored. All settings are validated before the instance is returned, ensuring consistency with class constraints.
- Parameters:
data (
Dict[str,Any]) – Dictionary with setting names as keys. Can contain extra keys which will be ignored.- Returns:
A new validated instance.
- Return type:
- Raises:
ValueError – If any settings in the dict violate validation constraints.
TypeError – If any setting value is of an incompatible type.
See also
to_dict()to convert an instance to a dict.Example
>>> data = {"n_avg": 16, "pulse_length": 2000, "extra_field": "ignored"} >>> settings = ExperimentSettings.from_dict(data)
- register_update_callback(fn)[source]
Register a callback to be notified when settings change.
The callback will be invoked each time settings are updated via
update(). The callback signature isfn(self, changes_dict)wherechanges_dictcontains the field names and new values.Exception Handling: Callback exceptions are caught and suppressed to prevent failures from propagating to the caller. Consider logging exceptions if needed.
- Parameters:
fn (
Callable[[ExperimentSettings,Dict[str,Any]],None]) – A callable with signature(self: ExperimentSettings, changes: Dict[str, Any]) -> None.- Raises:
TypeError – If
fnis not callable.- Return type:
See also
unregister_update_callback()to remove a callback.Example
>>> def on_settings_change(settings, changes): ... print(f"Settings changed: {changes}") >>> settings = ExperimentSettings() >>> settings.register_update_callback(on_settings_change) >>> settings.update(n_avg=10) # Prints: Settings changed: {'n_avg': 10}
- unregister_update_callback(fn)[source]
Unregister a previously registered callback.
Removes the callback from the list of callbacks to be invoked on updates. If the callback was not registered, this method does nothing (no error).
- Parameters:
fn (
Callable[[ExperimentSettings,Dict[str,Any]],None]) – The callback function to unregister. Must be the same object that was passed toregister_update_callback().- Return type:
See also
register_update_callback()to register a callback.Example
>>> def on_change(settings, changes): ... pass >>> settings = ExperimentSettings() >>> settings.register_update_callback(on_change) >>> settings.unregister_update_callback(on_change)
- copy()[source]
Create a shallow copy of these settings.
Creates a new independent instance with the same field values. Callbacks are not copied (the new instance starts with no callbacks). Modifications to the copy do not affect the original.
- Returns:
A new instance with identical settings.
- Return type:
Example
>>> settings1 = ExperimentSettings(n_avg=8) >>> settings2 = settings1.copy() >>> settings2.update(n_avg=16) >>> settings1.n_avg # Still 8 8
- rf_freq()[source]
Calculate the effective RF (radio frequency) in MHz.
Computes the actual RF frequency used by the OPX by subtracting the frequency offset from the center frequency. This accounts for any frequency calibration adjustments stored in
offset_freq.- Returns:
The effective RF frequency in MHz.
- Return type:
Example
>>> settings = ExperimentSettings(center_freq=282_190_100, offset_freq=75_000) >>> settings.rf_freq() 282_115_100
- __init__(n_avg=4, pulse_length=1100, pulse_amplitude=0.25, pulse_shape='square', pulse_rise_fall=0.0, rotation_angle=90.0, const_len=100, const_amp=0.03, thermal_reset=4000000000, center_freq=282190100, offset_freq=750, readout_delay=20000, readout_amp=0.01, dwell_time=4000, readout_start=0, readout_end=256000, resonator_relaxation=250000, excitation_length=5000, save_dir=None, res_key='resonator', amp_key='amplifier', helper_key='helper', sw_key='switch', square_key='square', square_pi_key='square_pi', gaussian_key='gaussian', gaussian_square_key='gaussian_square', lowpass_square_key='lowpass_square', tukey_key='tukey')
Configuration from Settings
Chassis Configuration
OPX-1000 Configuration Module.
This module provides configuration utilities for the OPX-1000 LF-FEM for solid state NMR experiments.
- class qeg_nmr_qua.config.config.OPXConfig(qop_ip='192.168.88.253', cluster='lex', controllers=<factory>, elements=<factory>, pulses=<factory>, waveforms=<factory>, digital_waveforms=<factory>, integration_weights=<factory>)[source]
Bases:
objectComplete configuration for the OPX-1000 low-frequency front-end module.
This is the main configuration class that aggregates all sub-configurations needed to operate the OPX-1000 for NMR experiments. It manages controllers, elements (physical connections), pulses, waveforms, digital waveforms, and integration weights.
Connection Settings:
qop_ip: IP address of the Quantum Orchestration Platform (default: “192.168.88.253”)cluster: Name of the OPX cluster to use (default: “lex”)
Configuration Components:
Each component is a nested configuration object:
controllers:ControllerConfig- Hardware controllers (analog/digital I/O)elements:ElementConfig- Physical elements (resonators, amplifiers, etc.)pulses:PulseConfig- Pulse definitions (control and measurement)waveforms:AnalogWaveformConfig- Analog waveform shapesdigital_waveforms:DigitalWaveformConfig- Digital marker waveformsintegration_weights:IntegrationWeights- Integration weight sets for demodulation
Serialization:
Use
to_dict()andfrom_dict()for programmatic serialization, or usesave_to_file()andload_from_file()for JSON file I/O.OPX Format:
Use
to_opx_config()to generate the configuration in OPX-compatible format for passing to the Quantum Orchestration Platform.Example
>>> config = OPXConfig(qop_ip="192.168.1.100") >>> config.elements.add_element("resonator", frequency=282.1901e6) >>> opx_config_dict = config.to_opx_config()
- qop_ip: str = '192.168.88.253'
- cluster: str = 'lex'
- controllers: ControllerConfig
- elements: ElementConfig
- pulses: PulseConfig
- waveforms: AnalogWaveformConfig
- digital_waveforms: DigitalWaveformConfig
- integration_weights: IntegrationWeights
- classmethod from_dict(d)[source]
- Return type:
OPXConfig
- classmethod load_from_file(filepath)[source]
Load an OPXConfig from a JSON file at filepath.
- Return type:
OPXConfig
- add_controller(controller_config)[source]
Add a controller configuration.
- add_element(name, element)[source]
- add_pulse(name, pulse)[source]
Add a pulse configuration.
- add_control_pulse(pulse_name, element_name, amplitude, length, waveform)[source]
Add a control pulse configuration.
- add_waveform(name, waveform)[source]
Add an analog waveform configuration.
- add_digital_waveform(name, state=0, length=0)[source]
Add a digital waveform (marker) configuration.
- add_integration_weight(name, length, real_weight=1, imag_weight=0)[source]
Add an integration weight configuration.
- __init__(qop_ip='192.168.88.253', cluster='lex', controllers=<factory>, elements=<factory>, pulses=<factory>, waveforms=<factory>, digital_waveforms=<factory>, integration_weights=<factory>)
Controller Configuration
OPX-1000 Controller Configuration Module.
This module provides configuration utilities for the OPX-1000 LF-FEM for solid state NMR experiments.
- class qeg_nmr_qua.config.controller.AnalogOutput(offset=0.0, sampling_rate=1000000000, output_mode='direct')[source]
Bases:
objectConfiguration for an analog output channel of the OPX.
Analog outputs are used to generate control signals (pulses, RF signals, etc.) for driving quantum elements. Each output has an independent offset, sampling rate, and output mode.
- offset
DC offset applied to the output in volts (default: 0.0). Used for calibration and bias adjustment.
- Type:
- sampling_rate
Output sampling rate in Hz (default: 1 GHz). Typically 1e9 for high-speed operations.
- Type:
- output_mode
Output mode, typically “direct” for direct waveform output (default: “direct”).
- Type:
- offset: float = 0.0
- sampling_rate: int = 1000000000
- output_mode: str = 'direct'
- classmethod from_dict(d)[source]
- Return type:
AnalogOutput
- __init__(offset=0.0, sampling_rate=1000000000, output_mode='direct')
- class qeg_nmr_qua.config.controller.AnalogInput(offset=0.0, gain_db=0, sampling_rate=1000000000)[source]
Bases:
objectConfiguration for an analog input channel of the OPX.
Analog inputs measure signals from quantum elements (e.g., resonator readout). Each input has independent offset, gain, and sampling rate for signal conditioning.
- offset
Input offset in volts (default: 0.0). Compensates for DC bias in the measurement.
- Type:
- gain_db
Programmable gain amplifier setting in dB (default: 0). Amplifies or attenuates the input signal.
- Type:
- sampling_rate
Input sampling rate in Hz (default: 1 GHz). Must match the acquisition requirements.
- Type:
- offset: float = 0.0
- gain_db: int = 0
- sampling_rate: int = 1000000000
- classmethod from_dict(d)[source]
- Return type:
AnalogInput
- __init__(offset=0.0, gain_db=0, sampling_rate=1000000000)
- class qeg_nmr_qua.config.controller.DigitalIO(name='TTL', direction='output', inverted=False)[source]
Bases:
objectConfiguration for digital input/output lines.
Digital I/O is used for control signals like RF switching, marker pulses, and external triggering. Digital signals are binary (0 or 1) and can be synchronized with analog operations.
- name
Descriptive name for this digital line (default: “TTL”). Example names: “RF_switch”, “marker1”, “trigger”.
- Type:
- direction
Signal direction, either “input” or “output” (default: “output”). Determines whether this line reads or drives digital signals.
- Type:
- inverted
Whether the signal logic is inverted (default: False). If True, a logical 0 is represented as a high voltage and vice versa.
- Type:
- name: str = 'TTL'
- direction: str = 'output'
- inverted: bool = False
- classmethod from_dict(d)[source]
- Return type:
DigitalIO
- __init__(name='TTL', direction='output', inverted=False)
- class qeg_nmr_qua.config.controller.FEModuleConfig(slot=1, fem_type='LF', analog_outputs=<factory>, analog_inputs=<factory>, digital_outputs=<factory>)[source]
Bases:
objectConfiguration for the OPX-1000 controller.
- slot: int = 1
- fem_type: str = 'LF'
- add_digital_output(port, name='TTL', inverted=False)[source]
Add a digital output channel configuration.
- Return type:
- add_analog_output(port, offset=0.0, sampling_rate=1000000000, output_mode='direct')[source]
Add an analog output channel configuration.
- Return type:
- add_analog_input(port, offset=0.0, gain_db=0, sampling_rate=1000000000)[source]
Add an analog input channel configuration.
- Return type:
- classmethod from_dict(d)[source]
- Return type:
FEModuleConfig
- __init__(slot=1, fem_type='LF', analog_outputs=<factory>, analog_inputs=<factory>, digital_outputs=<factory>)
- class qeg_nmr_qua.config.controller.ControllerConfig(model='opx1000', controller_name='con1', modules=<factory>)[source]
Bases:
objectOverall OPX Chassis configuration.
- model: str = 'opx1000'
- controller_name: str = 'con1'
- classmethod from_dict(d)[source]
- Return type:
ControllerConfig
- __init__(model='opx1000', controller_name='con1', modules=<factory>)
Element Configuration
OPX-1000 Element Configuration Module.
This module provides configuration utilities for the OPX-1000 LF-FEM for solid state NMR experiments.
- class qeg_nmr_qua.config.element.digitalElementConfig(port, delay=0, buffer=0)[source]
Bases:
objectConfiguration for a digital element’s paired input/output connection.
Specifies how a digital marker or trigger signal is routed between the OPX and a physical element (like an RF switch or frequency marker).
- port
Physical port specification as (controller_name, chassis_slot, port_number). Example: (“con1”, 1, 1) specifies controller 1, chassis slot 1, digital port 1.
- delay
Delay applied to the digital signal in nanoseconds (default: 0). Useful for synchronization with analog signals.
- Type:
- buffer
Buffer/timing margin in nanoseconds (default: 0). Provides timing headroom for signal stabilization.
- Type:
- delay: int = 0
- buffer: int = 0
- classmethod from_dict(d)[source]
- Return type:
digitalElementConfig
- __init__(port, delay=0, buffer=0)
- class qeg_nmr_qua.config.element.Element(name, frequency, analog_input, analog_output, digital_inputs=<factory>, operations=<factory>, time_of_flight=0.0, sticky=False)[source]
Bases:
objectConfiguration for a physical quantum element connected to the OPX-1000.
An Element represents a physical connection to the OPX, such as a resonator, amplifier, or signal source. It aggregates analog I/O ports, digital control lines, and associated pulse operations.
Port Mapping:
In OPX convention:
analog_input: The OPX’s output port that drives this elementanalog_output: The OPX’s input port that reads from this elementThis naming convention reflects the signal direction relative to the element, not the OPX.
- name
Unique identifier for this element (e.g., “resonator”, “amplifier”).
- Type:
- frequency
Intermediate frequency (IF) of this element in Hz. For direct sampling, this is the actual RF frequency.
- Type:
- analog_input
Port specification for OPX output as (controller_name, chassis_slot, port_number).
- analog_output
Port specification for OPX input as (controller_name, chassis_slot, port_number).
- digital_inputs
Mapping of operation names to digital control configurations (default: empty).
- operations
Mapping of operation names to pulse config names (default: empty). Example: {“pi_half”: “pi_half_pulse”}.
- time_of_flight
Signal propagation delay in nanoseconds (default: 0.0). Delay between when a pulse is output and when the response is received.
- Type:
- sticky
Whether this element retains state between operations (default: False). If True, the element state persists after pulse completion.
- Type:
- name: str
- frequency: float
- time_of_flight: float = 0.0
- sticky: bool = False
- add_digital_input(operation, controller_name, chasis_slot, port_number, delay=0, buffer=0)[source]
Add a digital input configuration for a specific operation.
- Parameters:
- Return type:
- to_opx_config()[source]
Convert the Element configuration to a dictionary.
- classmethod from_dict(d)[source]
- Return type:
Element
- __init__(name, frequency, analog_input, analog_output, digital_inputs=<factory>, operations=<factory>, time_of_flight=0.0, sticky=False)
- class qeg_nmr_qua.config.element.ElementConfig(elements=<factory>)[source]
Bases:
objectContainer for multiple Element configurations.
- add_element(name, element)[source]
Add an element configuration.
- Parameters:
name (
str) – Name of the element.frequency – Operating frequency in Hz.
analog_input – Tuple specifying the analog input (controller_name, chasis_slot, port_number).
analog_output – Tuple specifying the analog output (controller_name, chasis_slot, port_number).
time_of_flight – Delay between output and input signals in nanoseconds.
sticky – Whether the element retains state between operations.
- Return type:
- to_opx_config()[source]
Convert the Element configurations to OPX configuration format.
- classmethod from_dict(d)[source]
- Return type:
ElementConfig
- __init__(elements=<factory>)
Pulse Configuration
- class qeg_nmr_qua.config.pulse.ControlPulse(length=0, waveform='zero_wf', digital_marker='OFF')[source]
Bases:
objectConfiguration for a control (drive) pulse.
Defines a pulse used to drive/manipulate quantum states. Control pulses output a waveform to an element and may optionally trigger a digital marker for synchronization or external monitoring.
Current Limitations:
Single waveform only (no waveform mixing)
See
MeasPulsefor measurement pulses with integration.
- length
Pulse duration in nanoseconds (default: 0). Must be a multiple of 4 ns (1 clock cycle).
- Type:
- waveform
Name of the waveform to play (default: “zero_wf”). Must be defined in the waveform configuration.
- Type:
- digital_marker
Whether to set a digital marker during pulse execution (default: “OFF”). “ON” activates the marker, “OFF” deactivates it. Use None for no marker.
- Type:
Literal[“ON”, “OFF”] | None
- length: int = 0
- waveform: str = 'zero_wf'
- classmethod from_dict(d)[source]
- Return type:
ControlPulse
- __init__(length=0, waveform='zero_wf', digital_marker='OFF')
- class qeg_nmr_qua.config.pulse.MeasPulse(length=1000, waveform='readout_wf', integration_weights=<factory>, digital_marker=None)[source]
Bases:
objectConfiguration for a measurement pulse.
Defines a pulse used for measurement/readout of quantum states. Measurement pulses output a waveform, acquire data, and apply integration weights for demodulation and signal extraction. Optionally triggers a digital marker.
Current Limitations:
Single waveform only (no waveform mixing)
See
ControlPulsefor simple control pulses.
Demodulation:
Integration weights are applied to the acquired signal to extract in-phase (I) and quadrature (Q) components. Common weight sets include cosine/sine, rotated, and optimized variants.
- length
Measurement duration in nanoseconds (default: 1000). Must be a multiple of 4 ns (1 clock cycle).
- Type:
- waveform
Name of the readout waveform (default: “readout_wf”). Must be defined in the waveform configuration.
- Type:
- integration_weights
Mapping of demodulation weights for extracting I/Q components (default: default mapping).
- Type:
IntegrationWeightMapping
- digital_marker
Whether to trigger a digital marker during measurement (default: None). None means no marker action.
- Type:
Literal[“ON”, “OFF”] | None
- length: int = 1000
- waveform: str = 'readout_wf'
- integration_weights: IntegrationWeightMapping
- classmethod from_dict(d)[source]
- Return type:
MeasPulse
- __init__(length=1000, waveform='readout_wf', integration_weights=<factory>, digital_marker=None)
- class qeg_nmr_qua.config.pulse.PulseConfig(pulses=<factory>)[source]
Bases:
objectConfiguration for a pulse, which can be either a control pulse or a measurement.
- add_pulse(name, pulse)[source]
Add a pulse configuration from one of the pulse types.
- add_control_pulse(name, length, waveform='const', digital_marker='OFF')[source]
Add a control pulse configuration.
- add_measurement_pulse(name, length, waveform='readout_wf', digital_marker=None, integration_weights=<IntegrationWeightMapping cos=cosine_weights sin=sine_weights opt_cos=opt_cosine_weights>)[source]
Add a measurement pulse configuration.
- classmethod from_dict(d)[source]
- Return type:
PulseConfig
- __init__(pulses=<factory>)
Waveform Configuration
- class qeg_nmr_qua.config.waveform.AnalogWaveform(sample=0.0)[source]
Bases:
objectConfiguration for a single analog waveform.
Represents a waveform that can be output on an analog channel. Supports both constant-amplitude waveforms and arbitrary waveforms with sample-by-sample amplitude specification.
- sample
Waveform amplitude specification. - If float: Constant waveform with that amplitude (in volts) - If list: Arbitrary waveform with per-sample amplitudes (in volts)
- to_dict()[source]
It may be better to link to a file when sample is an array.
- classmethod from_dict(d)[source]
- Return type:
AnalogWaveform
- __init__(sample=0.0)
- class qeg_nmr_qua.config.waveform.ArbitraryWaveform(samples=<factory>)[source]
Bases:
objectConfiguration for an arbitrary (custom) analog waveform.
Represents a shaped waveform defined sample-by-sample. Useful for complex pulse shapes like STIRAP, RAPID, or other optimal control pulses.
- samples
List of amplitude values (in volts) for each sample. The waveform is played back in sequence at the OPX sampling rate.
- classmethod from_dict(d)[source]
- Return type:
ArbitraryWaveform
- __init__(samples=<factory>)
- class qeg_nmr_qua.config.waveform.DigitalWaveform(state=0, length=0)[source]
Bases:
objectConfiguration for a digital marker waveform.
Defines a digital (binary) signal that can be used for RF switching, trigger signals, or monitoring pulse execution. The marker holds its specified state for the specified duration, then returns to 0 when the pulse ends.
Timing Behavior:
Length 0: Marker holds its state for the entire duration of the associated pulse
Length > 0: Marker holds its state for the specified nanoseconds, then returns to 0
- state
Digital state (0 or 1). 0 = low/off, 1 = high/on (default: 0).
- Type:
- length
Duration the marker holds its state in nanoseconds (default: 0). Special case: 0 means hold for entire pulse duration.
- Type:
- state: int = 0
- length: int = 0
- classmethod from_dict(d)[source]
- Return type:
DigitalWaveform
- __init__(state=0, length=0)
- class qeg_nmr_qua.config.waveform.AnalogWaveformConfig(waveforms=<factory>)[source]
Bases:
objectContainer for analog waveform definitions.
Manages a collection of named analog waveforms. Waveforms are referenced by name in pulse configurations. This design allows arbitrary key names for maximum flexibility.
Waveform Types:
Waveforms can be:
Constant amplitude (flat pulse)
Arbitrary shaped (custom pulse envelope)
- waveforms
Mapping of waveform names to their configurations. Example: {“pi_pulse”: AnalogWaveform(…)}.
- Type:
Dict[str, AnalogWaveform]
- add_waveform(name, sample=0.0)[source]
Add a waveform to the configuration for defining multiple pulse-types. Pulses are either constant amplitude or arbitrary waveforms. If constant, sample is a float amplitude value. If arbitrary, sample is a list of amplitude values which define the waveform shape, between -1 and 1.
- Return type:
- classmethod from_dict(d)[source]
- Return type:
AnalogWaveformConfig
- __init__(waveforms=<factory>)
- class qeg_nmr_qua.config.waveform.DigitalWaveformConfig(waveforms=<factory>)[source]
Bases:
object- add_waveform(name, state=0, length=0)[source]
Add a digital waveform (marker) to the configuration. A length of 0 means the marker will hold its state for the duration of the pulse it is associated with. If the pulse ends, the marker returns to 0.
- Return type:
- classmethod from_dict(d)[source]
- Return type:
DigitalWaveformConfig
- __init__(waveforms=<factory>)
Integration Weights
- class qeg_nmr_qua.config.integration.IntegrationWeightMapping(cos='cosine_weights', sin='sine_weights', minus_sin='minus_sine_weights', rotated_cos='rotated_cosine_weights', rotated_sin='rotated_sine_weights', rotated_minus_sin='rotated_minus_sine_weights', opt_cos='opt_cosine_weights', opt_sin='opt_sine_weights', opt_minus_sin='opt_minus_sine_weights')[source]
Bases:
objectMapping of demodulation weight names to integration weight set identifiers.
This class defines the naming convention for different integration weight sets used during measurement. Each attribute maps a weight type to its identifier in the integration weights configuration.
Standard Weight Sets:
cos,sin,minus_sin: Standard cosine/sine demodulationrotated_cos,rotated_sin,rotated_minus_sin: Rotated basis demodulationopt_cos,opt_sin,opt_minus_sin: Optimized weights for specific experiments
- cos
Cosine weight set name (default: “cosine_weights”)
- Type:
- sin
Sine weight set name (default: “sine_weights”)
- Type:
- minus_sin
Negative sine weight set name (default: “minus_sine_weights”)
- Type:
- rotated_cos
Rotated cosine weight set (default: “rotated_cosine_weights”)
- Type:
- rotated_sin
Rotated sine weight set (default: “rotated_sine_weights”)
- Type:
- rotated_minus_sin
Rotated negative sine weight set (default: “rotated_minus_sine_weights”)
- Type:
- opt_cos
Optimized cosine weight set (default: “opt_cosine_weights”)
- Type:
- opt_sin
Optimized sine weight set (default: “opt_sine_weights”)
- Type:
- opt_minus_sin
Optimized negative sine weight set (default: “opt_minus_sine_weights”)
- Type:
- cos: str = 'cosine_weights'
- sin: str = 'sine_weights'
- minus_sin: str = 'minus_sine_weights'
- rotated_cos: str = 'rotated_cosine_weights'
- rotated_sin: str = 'rotated_sine_weights'
- rotated_minus_sin: str = 'rotated_minus_sine_weights'
- opt_cos: str = 'opt_cosine_weights'
- opt_sin: str = 'opt_sine_weights'
- opt_minus_sin: str = 'opt_minus_sine_weights'
- classmethod from_dict(d)[source]
- Return type:
IntegrationWeightMapping
- __init__(cos='cosine_weights', sin='sine_weights', minus_sin='minus_sine_weights', rotated_cos='rotated_cosine_weights', rotated_sin='rotated_sine_weights', rotated_minus_sin='rotated_minus_sine_weights', opt_cos='opt_cosine_weights', opt_sin='opt_sine_weights', opt_minus_sin='opt_minus_sine_weights')
- class qeg_nmr_qua.config.integration.IntegrationWeight(length=0, real_weight=1, imag_weight=0)[source]
Bases:
objectConfiguration for a single integration weight set for demodulation.
Defines how to demodulate and integrate an acquired signal. During measurement, the acquired signal is multiplied by cosine and sine reference signals (weighted by these parameters) and integrated over the measurement duration to extract in-phase (I) and quadrature (Q) components.
- length
Integration window duration in nanoseconds (default: 0). Typically matches the measurement pulse length.
- Type:
- real_weight
Weight factor for cosine (I) component (default: 1.0). Scales the in-phase signal amplitude.
- Type:
- imag_weight
Weight factor for sine (Q) component (default: 0.0). Scales the quadrature signal amplitude.
- Type:
- length: int = 0
- real_weight: float = 1
- imag_weight: float = 0
- classmethod from_dict(d)[source]
- Return type:
IntegrationWeight
- __init__(length=0, real_weight=1, imag_weight=0)
- class qeg_nmr_qua.config.integration.IntegrationWeights(weights=<factory>)[source]
Bases:
objectContainer for all integration weight sets used in the experiment.
Manages a collection of named integration weight configurations. During measurement, these weights are applied to demodulate and integrate the acquired signals, extracting I/Q components for data analysis.
- weights
Mapping of weight set names to their configurations (default: empty).
- add_weight(name, length, real_weight=1, imag_weight=0)[source]
Add an integration weight set to the configuration.
- Return type:
- classmethod from_dict(d)[source]
- Return type:
IntegrationWeights
- __init__(weights=<factory>)