Documentation for the Spectrum AWG Labscript module

This labscript device controls AWGs made by Spectrum Instrumentation https://spectrum-instrumentation.com/products/families/66xx_m4i_pci.php

Change log

  • v2.0.0 (2023-11-10)

    • Renamed SpectrumAwgOut.loop() to SpectrumAwgOut.set_wave_and_enable() and SpectrumAwgOut.wait() to SpectrumAwgOut.disable() to be more consistent with the naming conventions of labscript.

  • v1.0.1 (2023-07-24)

    • Improved front-panel.

    • Fixed bug where the tab would crash when not commanded to do anything.

  • v1.0.0 (2023-05-12)

    • Initial upload.

Labscript API

class SpectrumAwg(*args: Any, **kwargs: Any)

Bases: Device

A labscript.Device representing the AWG card itself.

Parameters:
  • name (str) – Name of the card in labscript and BLACs.

  • BLACS_connection (str) – The handle name of the card (as seen in Spectrum Control Center). Defaults to "/dev/spcm0", which should be correct if you are using a single, local card.

allowed_children = [<class '__init__.SpectrumAwgOut'>, <class '__init__.SpectrumAwgOutCopy'>]

This device accepts output ports SpectrumAwgOut and copied output ports (that is ports running in double or differential modes) SpectrumAwgOutCopy as children.

description = 'Spectrum AWG'
generate_code(hdf5_file)

Prepares the code based on commands in experiment file. The hdf5_file is structured to contain information for instructions that the card natively understands; namely "SEGMENT" and "SEQUENCE" information.

The "SEGMENT" key points to a 3-dimensional array containing the waveforms themselves. The array is structured segments[segment_index, time_index, channel_index]. Each segment contains one waveform per channel. That is, only one segment (one combination of waveforms) can be played at once.

The "SEGMENT" array also contains attributes associated with the card waveforms:

  • "LENGTHS" is a numpy.ndarray of int of the length of each segment (this allows for zero padding)

  • "CONNECTIONS" is a numpy.ndarray of int of the output ports being used in the sequence (excluding copies).

  • "SAMPLE_RATE" is an int of the sample rate of the card in Hz.

  • "DIFFERENTIALS" is a numpy.ndarray of any ports being copied in differential mode.

  • "COPIES" is a numpy.ndarray of int of any ports being copied in double mode.

  • "AMPLITUDES" is a numpy.ndarray of float of the amplitudes of ports, in volts.

  • "AMPLITUDE_INDICES" is a numpy.ndarray of int of the output ports being used in the sequence (including copies). Amplitudes in AMPLITUDES" correspond to these ports.

This generate_code method unrolls the playing of simultaneous waveforms into a sequence of segments (waveforms played simultaneously across all channels). While the segments are loaded into the "SEGMENT" array, the sequence instructions are saved into a "SEQUENCE" h5py.Group. The "SEQUENCE" h5py.Group contains a numpy.ndarray for all the parameters used when programming a sequence on the card. Namely,

  • "STEP" numpy.ndarray of int: the step in the sequence.

  • "NEXT_STEP" numpy.ndarray of int: the step that this step will follow on to.

  • "SEGMENT" numpy.ndarray of int: the segment that plays during this step.

  • "LOOPS" numpy.ndarray of int: The number of times the segment should be looped during this step.

  • "END_OF_SEQUENCE" numpy.ndarray of bool: if True, the card exits the sequence and (if appropriate) will prepare for the next one.

  • "LOOP_UNTIL_TRIGGER" numpy.ndarray of bool: currently unused in this implementation.

The "SEQUENCE" h5py.Group also contains some attributes relating to sequencing and triggers:

  • "START_STEPS": a numpy.ndarray of int that determines the start point of the different sequences. A new sequence is started every time :meth:`SpectrumAwgOut.set_wave_and_enable is called after a call of SpectrumAwgOut.disable().

  • "SOFTWARE_TRIGGER": a bool where if True, the card will be triggered automatically (with inconsistent timing) as soon as the shot is loaded in BLACs.

  • "TRIGGER_LEVEL": a float that determines the voltage on the trigger port that will trigger the card when first reached (that is, triggering happens on a positive edge).

  • "RE_ARM_LEVEL": the voltage level that the trigger port must reach after a trigger before it is able to accept a second trigger.

  • "TRIGGER_PORT": the trigger port number for the active trigger.

Parameters:

hdf5_file (h5py.File) – The HDF5 file to be written to.

init_sample_rate(sample_rate)

Sets the sample rate of the AWG. Will stay constant for the whole sequence.

Parameters:

sample_rate (float) – The sample rate in Hz.

init_trigger(port, level, re_arm_level=None)

Sets triggering setup for the AWG. If not called, the card will automatically be software triggered at the start of a shot.

Parameters:
  • port (int) – The trigger port to be used.

  • level (float) – The voltage on the trigger port that will trigger the card when first reached (that is, triggering happens on a positive edge).

  • re_arm_level (float) – The voltage level that the trigger port must reach after a trigger before it is able to accept a second trigger. If None (default), will be set to level/2.

trigger_delay = 4.781e-06

The delay in seconds between the application of a trigger and a response from the card. Measured as 4.781(7) us, from 2023-04-13 by Alex Tritt.

class SpectrumAwgOut(*args: Any, **kwargs: Any)

Bases: Output

A labscript.Device representing an individual output port of an AWG.

Parameters:
  • name (str) – Name of the channel output in labscript and BLACs.

  • parent_device (SpectrumAwg) – The AWG card that this output is a channel of.

  • connection (str) – A string of the port index of the channel on the card. For example, if this represents the channel sent to output port 2 on a 4-port card, write "2".

disable(time)

Stops the channel (and AWG card) from outputting anything. That is, it stops a waveform from looping (that was set started by a set_wave_and_enable()) It will stay dormant until another set_wave_and_enable() command is called at a later time (or call it at the end of a sequence).

Warning

In the current implementation, calling disable() on one channel will disable all channels.

Parameters:

time (float) – The time at which to start playing the waveform.

init_amplitude(amplitude)

Sets the amplitude of the output. The output will vary from + to - this value. The waveform samples are proportions of this value that the output should be set to. Note that it will stay at this value throughout the whole experiment.

Parameters:

amplitude (float) – Amplitude in volts. Will be precise to the nearest millivolt.

loop(time, wave: ndarray)

Legacy method.

set_wave_and_enable(time, wave: ndarray)

Starts a waveform wave playing on the channel at time time. This waveform will keep looping until either another set_wave_and_enable() or disable() command is called at a later time.

Note

The length of this waveform must be a multiple of 32. Also, when using multiple channels, you must make sure that each waveform being looped has the same length.

Note

If you are triggering the card, you will need to trigger the card the first time set_wave_and_enable() is called, as well as every time set_wave_and_enable() is called after disable() is called.

Parameters:
  • time (float) – The time at which to start playing the waveform.

  • wave (numpy.ndarray) – The waveform to be looped. Samples should be between -1.0 and 1.0. Note that the length of this waveform must be a multiple of 32.

Raises:

ValueError – If the length of wave is not a multiple of 32.

set_wave_until_trigger(time, wave: ndarray)

Starts a waveform wave playing on the channel at time time. This waveform will keep looping until a trigger is sent to the AWG.

Note

The length of this waveform must be a multiple of 32. Also, when using multiple channels, you must make sure that each waveform being looped has the same length.

Note

If you are triggering the card, you will need to trigger the card the first time set_wave_and_enable() is called, as well as every time set_wave_and_enable() is called after disable() and set_wave_until_trigger() are called.

Parameters:
  • time (float) – The time at which to start playing the waveform.

  • wave (numpy.ndarray) – The waveform to be looped. Samples should be between -1.0 and 1.0. Note that the length of this waveform must be a multiple of 32.

Raises:

ValueError – If the length of wave is not a multiple of 32.

wait(time)

Legacy method.

class SpectrumAwgOutCopy(*args: Any, **kwargs: Any)

Bases: Output

A labscript.Device representing an individual output port of an AWG. This particular output port will copy the behaviour of another port (see double and differential output modes in AWG manual).

Note

A port can only be copied if it has an even port number, and the port that copies it must have the next port number after that. For example, port 3 can only copy port 2.

Parameters:
  • name (str) – Name of the channel output in labscript and BLACs.

  • parent_device (SpectrumAwg) – The AWG card that this output is a channel of.

  • connection (str) – A string of the port index of the channel on the card. For example, if this represents the channel sent to output port 2 on a 4-port card, write "2".

  • copied_device (SpectrumAwgOut) – The output port that this port is going to copy.

  • differential (bool) – If set to False (default), the port will be set to double output mode (copying the output), otherwise the port will be set to differential output mode (mirroring the output). See card manual for more details.

init_amplitude(amplitude)

Sets the amplitude of the output. The output will vary from + to - this value. The waveform samples are proportions of this value that the output should be set to. Note that it will stay at this value throughout the whole experiment.

Parameters:

amplitude (float) – Amplitude in volts. Will be precise to the nearest millivolt.

class SpectrumAwgTab(*args: Any, **kwargs: Any)

Bases: DeviceTab

A GUI for some simple functionality of the AWG. The purpose of this is to be able to test to see if the card is working, rather than to actually run an experiment.

The top panel controls the card itself:

  • "Enable" starts and stops a loop from running.

  • "Identify" toggles the flashing identification mode of the status LED.

  • "Sample rate" sets the sample rate of the card in MHz.

  • "Segment size" sets the size of the waveforms being played in manual mode in samples.

The subsequent panels control properties of individual channels:

  • "Amplitude" sets the peak value of the waveform in volts.

  • "Frequency" sets the frequency of the waveform in MHz. Note that the frequency will be automatically changed so that a whole number of periods fit within the whole waveform.

  • "Output enable" enables a specific chanel.

  • "Sawtooth", "Square" and "Sine" is a selection between three waveforms that the chanel can output.

initialise_GUI()
restart()
class SpectrumAwgViewer(path, device)

Bases: object

Currently doesn’t do anything. Sampling the AWG sequence at full resolution is very memory intensive. I have written and commented out some code that subsamples the AWG waveform, although this too may get large fast for a sufficiently complicated sequence.

Warning

Uncomment at own risk!

class SpectrumAwgWorker(*args: Any, **kwargs: Any)

Bases: Worker

The main worker thread for the Spectrum AWG. It implements the front-panel control of the SpectrumAwgTab, as well as handles moving to the buffered mode by hand-passing control of the card to a SpectrumAwgWorkerMidFlight.

abort_buffered()

Calls transition_to_manual.

abort_transition_to_buffered()

Calls transition_to_manual.

amplitude_min = 0.08

The smallest acceptable amplitude in volts for any AWG channel.

check_remote_values()

Polls the card and sees if its status matches that of the SpectrumAwgTab.

Returns:

remote_values – Current status of the card.

Return type:

dict

init()

Initialises the manual front-panel mode for the SpectrumAwgTab.

program_manual(front_panel_values)

Respond to user input from the SpectrumAwgTab GUI.

Parameters:

front_panel_values (dict) – The current state of the GUI.

sample_rate_min = 50

The smallest acceptable sample rate in MHz for the card.

shutdown()

If in buffered mode, safely kills the SpectrumAwgWorkerMidFlight thread. If in manual mode, closes the card handle.

transition_to_buffered(device_name, h5file, initial_values, fresh)

Starts a thread of SpectrumAwgWorkerMidFlight which programs the AWG and handles in mid-shot.

Parameters:
transition_to_manual(abort=False)

Ends the shot and takes back control of the AWG into this thread.

Parameters:

abort – Unused.

class SpectrumAwgWorkerMidFlight(done_queue: Queue, manual_queue: Queue, h5file: str, device_name: str, address: str)

Bases: Process

A multiprocessing.Process that handles programming the AWG when going into buffered mode, as well as rearming the card before any retriggering occurs.

Parameters:
run()

Programs the AWG when going into buffered mode, as well as rearms the card before any retriggering occurs.

wait_time = 1e-06

Polling time in seconds for checking card status during the shot.