VISA

README

VISA

This module leverages pyvisa to communicate to VISA compatible devices and is meant to be inherited by a labscript device’s components. The module also provides GUI widgets for an instrument’s status bytes, as well as the option for analog and digital outputs.

API Documentation

Boiler plate labscript_device for VISA instruments.

class naqs_devices.VISA.labscript_devices.VISA(name, parent_device, VISA_name, **kwargs)[source]

Bases: Device

Base VISA labscript_device class.

Inheritors should call VISA.__init__() in their own __init__() method. Generate_code must be overridden.

Parameters:
  • name (str) – name of device in connectiontable

  • parent_device (obj) – Handle to any parent device.

  • VISA_name (str) – Can be full VISA connection string or NI-MAX alias.

description = 'VISA Compatible Instrument'

Brief description of the device.

allowed_children = []

Defines types of devices that are allowed to be children of this device.

Type:

list

generate_code(hdf5_file)[source]

Method to generate instructions for blacs_worker to program device.

Must be over-ridden.

add_device(device)

Adds a child device to this device.

Parameters:

device (Device) – Device to add.

Raises:

LabscriptError – If device is not an allowed child of this device.

get_all_children()

Get all children devices for this device.

Returns:

List of children Device.

Return type:

list

get_all_outputs()

Get all children devices that are outputs.

Recursively calls get_all_outputs() on each child device. Output’s will return a list containing just themselves.

Returns:

List of children Output.

Return type:

list

get_properties(location=None)

Get all properties in location.

Parameters:

location (str, optional) – Location to get properties from. If None, return all properties.

Returns:

Dictionary of properties.

Return type:

dict

get_property(name, location=None, *args, **kwargs)

Method to get a property of this device already set using Device.set_property().

If the property is not already set, a default value will be returned if specified as the argument after ‘name’, if there is only one argument after ‘name’ and the argument is either not a keyword argurment or is a keyword argument with the name ‘default’.

Parameters:
  • name (str) – Name of property to get.

  • location (str, optional) – If not None, only search for name in location.

  • default – The default value. If not provided, an exception is raised if the value is not set.

Returns:

Property value.

Raises:

LabscriptError – If property not set and default not provided, or default conventions not followed.

Examples

Examples of acceptable signatures:

>>> get_property('example')             # 'example' will be returned if set, or an exception raised
>>> get_property('example', 7)          # 7 returned if 'example' is not set
>>> get_property('example', default=7)  # 7 returnd if 'example' is not set

Example signatures that WILL ALWAYS RAISE AN EXCEPTION:

>>> get_property('example', 7, 8)
>>> get_property('example', 7, default=9)
>>> get_property('example', default=7, x=9)
init_device_group(hdf5_file)

Creates the device group in the shot file.

Parameters:

hdf5_file (h5py:h5py.File) – File handle to create the group in.

Returns:

Created group handle.

Return type:

h5py:h5py.Group

property parent_clock_line

Stores the clocking clockline, which may be itself.

Type:

ClockLine

property pseudoclock_device

Stores the clocking pseudoclock, which may be itself.

Type:

PseudoclockDevice

quantise_to_pseudoclock(times)

Quantises times to the resolution of the controlling pseudoclock.

Parameters:

times (numpy:numpy.ndarray or list or set or float) – Time, in seconds, to quantise.

Returns:

Quantised times.

Return type:

same type as times

set_properties(properties_dict, property_names, overwrite=False)

Add one or a bunch of properties packed into properties_dict

Parameters:
  • properties_dict (dict) – Dictionary of properties and their values.

  • property_names (dict) – Is a dictionary {key:val, …} where each val is a list [var1, var2, …] of variables to be pulled from properties_dict and added to the property localtion with name key

  • overwrite (bool, optional) – Toggles overwriting of existing properties.

set_property(name, value, location=None, overwrite=False)

Method to set a property for this device.

Property will be stored in the connection table and used during connection table comparisons.

Value must satisfy eval(repr(value)) == value.

Parameters:
  • name (str) – Name to save property value to.

  • value – Value to set property to.

  • location (str, optional) – Specify a location to save property to, such as ‘device_properties’ or ‘connection_table_properties’.

  • overwrite (bool, optional) – If True, allow overwriting a property already set.

Raises:

LabscriptError – If ‘location’ is not valid or trying to overwrite an existing property with ‘overwrite’=False.

property t0

The earliest time output can be commanded from this device at the start of the experiment. This is nonzero on secondary pseudoclock devices due to triggering delays.

Type:

float

Boiler plate blacs_tab for VISA instruments.

Defines the common STBstatus.ui widget all devices use to report their current status.

class naqs_devices.VISA.blacs_tabs.VISATab(*args, **kwargs)[source]

Bases: DeviceTab

You MUST override this method in order to define the device worker. You then call this parent method to finish initialization.

status_byte_labels = {'bit 0': 'bit 0 label', 'bit 1': 'bit 1 label', 'bit 2': 'bit 2 label', 'bit 3': 'bit 3 label', 'bit 4': 'bit 4 label', 'bit 5': 'bit 5 label', 'bit 6': 'bit 6 label', 'bit 7': 'bit 7 label'}
status_widget = 'STBstatus.ui'
STBui_path = '/home/docs/checkouts/readthedocs.org/user_builds/naqs-devices-visa/envs/latest/lib/python3.11/site-packages/naqs_devices/VISA/STBstatus.ui'
initialise_GUI()[source]

Loads the standard STBstatus.ui widget and sets the worker defined in __init__

status_monitor(*args, **kwargs)[source]
send_clear(*args, **kwargs)[source]
ICON_BUSY = ':/qtutils/fugue/hourglass'
ICON_ERROR = ':/qtutils/fugue/exclamation'
ICON_FATAL_ERROR = ':/qtutils/fugue/exclamation-red'
ICON_OK = ':/qtutils/fugue/tick'
abort_buffered(*args, **kwargs)
abort_transition_to_buffered(*args, **kwargs)
add_secondary_worker(worker)
auto_create_widgets()
auto_place_widgets(*args)
check_remote_values(*args, **kwargs)
check_time()
clean_ui_on_restart()
close_tab(finalise=True)

Close the tab, terminate subprocesses and join the mainloop thread. If finalise=False, then do not terminate subprocesses or join the mainloop. In this case, callers must manually call finalise_close_tab() to perform these potentially blocking operations

connect_restart_receiver(function)
continue_restart(currentpage)

Called in a thread for the stages of restarting that may be blocking, so as to not block the main thread. Calls subsequent GUI operations in the main thread once finished blocking.

create_analog_outputs(analog_properties)
create_analog_widgets(channel_properties)
create_dds_outputs(dds_properties)
create_dds_widgets(channel_properties)
create_digital_outputs(digital_properties)
create_digital_widgets(channel_properties)
create_image_outputs(image_properties)
create_image_widgets(channel_properties)
create_worker(name, WorkerClass, workerargs=None)

Set up a worker process. WorkerClass can either be a subclass of Worker, or a string containing a fully qualified import path to a worker. The latter is useful if the worker class is in a separate file with global imports or other import-time behaviour that is undesirable to have run in the main process, for example if the imports may not be available to the main process (as may be the case once remote worker processes are implemented and the worker may be on a separate computer). The worker process will not be started immediately, it will be started once the state machine mainloop begins running. This way errors in startup will be handled using the normal state machine machinery.

property device_name
disconnect_restart_receiver(function)
property error_message
finalise_close_tab(currentpage)
finalise_restart(currentpage)
property force_full_buffered_reprogram
get_all_save_data()
get_builtin_save_data()

Get builtin settings to be restored like whether the terminal is visible. Not to be overridden.

get_channel(channel)
get_child_from_connection_table(parent_device_name, port)
get_front_panel_values()
get_save_data()
get_tab_layout()
hide_error()
initialise_workers()
mainloop()
property mode
on_force_full_buffered_reprogram()
on_resolve_value_inconsistency()
property primary_worker
program_device(*args, **kwargs)
queue_work(worker_process, worker_function, *args, **kwargs)
restart(*args)
restore_builtin_save_data(data)

Restore builtin settings to be restored like whether the terminal is visible. Not to be overridden.

restore_save_data(data)
set_tab_icon_and_colour()

Set the tab icon and the colour of its text to the values of self._tab_icon and self._tab_text_colour respectively

set_terminal_visible(visible)
shutdown_workers(*args, **kwargs)
start_run(*args, **kwargs)
property state
statemachine_timeout_add(delay, statefunction, *args, **kwargs)
statemachine_timeout_remove(statefunction)
statemachine_timeout_remove_all()
supports_remote_value_check(support)
supports_smart_programming(support)
transition_to_buffered(*args, **kwargs)
transition_to_manual(*args, **kwargs)
update_from_settings(settings)

Boiler plate BLACS_worker for VISA instruments.

Inheritors use the same communication protocol, but override the command syntax.

class naqs_devices.VISA.blacs_workers.VISAWorker(*args, **kwargs)[source]

Bases: Worker

init()[source]

Initializes basic worker and opens VISA connection to device.

Default connection timeout is 2 seconds

check_remote_values()[source]
convert_register(register)[source]

Converts returned register value to dict of bools

Parameters:

register (int) – Status register value returned from read_stb

Returns:

Status byte dictionary as formatted in VISATab

Return type:

dict

check_status()[source]

Reads the Status Byte Register of the VISA device.

Returns:

Status byte dictionary as formatted in VISATab

Return type:

dict

program_manual(front_panel_values)[source]

Over-ride this method if remote programming is supported.

Returns:

VISAWorker.check_remote_values()

clear(value)[source]

Sends standard *CLR to clear registers of device.

Parameters:

value (bool) – value of Clear button in STBstatus.ui widget

transition_to_buffered(device_name, h5file, initial_values, fresh)[source]

Stores various device handles for use in transition_to_manual method.

Automatically called by BLACS. Should be over-ridden by inheritors.

Parameters:
  • device_name (str) – Name of device from connectiontable

  • h5file (str) – path to shot h5_file

  • initial_values (dict) – Contains the start of shot values

  • fresh (bool) – Indicates if smart_programming should be refreshed this shot

abort_transition_to_buffered()[source]

Special abort shot configuration code belongs here.

abort_buffered()[source]

Special abort shot code belongs here.

transition_to_manual(abort=False)[source]

Simple transition_to_manual method where no data is saved.

shutdown()[source]

Closes VISA connection to device.

interrupt_startup(reason='Process.interrupt_startup() called')

Called from the parent process. Interrupt all blocking operations on starting the child process, causing Process.start() to raise Interrupted(reason). After interruption, self.child may be None if startup was interrupted before the child was started, otherwise self.child will be the child Popen object, which could be at any stage of setting up its connection with the parent. This method may be called multiple times without raising an exception, it will simply do nothing if startup has previously been interrupted

mainloop()
run(worker_name, device_name, extraargs)

The method that gets called in the subprocess. To be overridden by subclasses

start(*args, **kwargs)

Call in the parent process to start a subprocess. Passes args and kwargs to the run() method

terminate(wait_timeout=None, **kwargs)

Interrupt process startup if not already done, ensuring self.child exists or is None if startup was interrupted before the process was created. Then if the child is not None, call Popen.terminate() and Popen.wait() on it.