Template Device for Labscript¶
README¶
naqs_devices_template_device¶
This repository is both a template to follow for a labscript-device belonging
to a namespace (here naqs_devices) as well as a github template repository.
Use the green Use this template button above to copy the files and structure
of this repository to fit your new device. You will need to modify at least
pyproject.toml, README.md, index.rst, conf.py, and everything in src/.
Directory structure¶
└── naqs_devices_template_device/
├── .gitignore
├── pyproject.toml
├── README.md
├── LICENSE.txt # Choose a license, labscript uses BSD
├── CITATION.cff # Optional to define citation for citing the device repository
├── docs/
│ ├── conf.py
│ ├── make.bat
│ ├── Makefile
│ └── index.rst
└── src/naqs_devices/ # note: must be same as in the parent naqs_devices repo to be in the same namespace
└── TemplateDevice/
├── __init__.py
├── blacs_tabs.py
├── blacs_workers.py
├── labscript_devices.py
├── register_classes.py
└── runviewer_parsers.py
How to document your device¶
To work within the labscript paradigm, we enforce that you write all
specification related documentation in the top-level README.md (here). Then,
any API related documentation should go in the docs/index.rst. The project
is structured and has the machinery so that the device can be hosted on Read
The Docs. This is optional and requires extra configuration steps as outlined
in the RTD Docs.
API Documentation¶
- class naqs_devices.TemplateDevice.labscript_devices.TemplateDevice(name='template_device', BLACS_connection='template_connection', **kwargs)[source]¶
Bases:
DeviceCreates a Device.
- Parameters:
name (str) – python variable name to assign this device to.
parent_device (
Device) – Parent of this device.connection (str) – Connection on this device that links to parent.
call_parents_add_device (bool, optional) – Flag to command device to call its parent device’s add_device when adding a device.
added_properties (dict, optional)
gui
worker
start_order (int, optional) – Priority when starting, sorted with all devices.
stop_order (int, optional) – Priority when stopping, sorted with all devices.
**kwargs – Other options to pass to parent.
- description = 'Template Device, minimal example'¶
Brief description of the device.
- allowed_children = [<class 'naqs_devices.TemplateDevice.labscript_devices._TemplateChildDevice'>]¶
Defines types of devices that are allowed to be children of this device.
- Type:
list
- max_instructions = 100000.0¶
- generate_code(hdf5_file)[source]¶
Writes instructions to an h5 file to be processed by other labscript components. As an example, we generate 3 columns of random data and use h5py to save the data to the shotfile. Labscript commonly makes use of numpy structured arrays to explicitly specify types.
- Parameters:
hdf5_file (str) – The path to the shot-file, passed in by labscript
components.
- 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.ndarrayor 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
keyoverwrite (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
- class naqs_devices.TemplateDevice.blacs_tabs.TemplateDeviceTab(notebook, settings, restart=False)[source]¶
Bases:
DeviceTab- show_widgets = True¶
- initialise_GUI()[source]¶
Required to place GUI widgets and contains options for remote value checking and smart cache capability.
- initialise_workers()[source]¶
Starts the workers, which handle communications between front panel, shot-file, and labscript instructions.
- 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()¶
- 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)¶
- 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)¶
- class naqs_devices.TemplateDevice.blacs_workers.TemplateDeviceInterface[source]¶
Bases:
objectThis optional class holds the functions / methods for logic processing or commands that go between the device hardware and the front panel. It is automatically called by BLACS.
- class naqs_devices.TemplateDevice.blacs_workers.TemplateDeviceWorker(*args, **kwargs)[source]¶
Bases:
WorkerHandles processing of data between a shot’s h5file and the Device. Every Device’s Worker should generally implement the methods defined in this TemplateDeviceWorker.
- Parameters:
Worker (Process) – Inherited from blacs.tab_base_classes.py.
- init()[source]¶
Initialises communications with the device. Not to be confused with the standard python class __init__ method.
- program_manual(values)[source]¶
Allows for user control of the device via the BLACS_tab, setting outputs to the values set in the BLACS_tab widgets.
- Parameters:
values (dict) – dictionary of values to update front panel.
- Returns:
returns are of dictionary shape to allow use from other methods.
- Return type:
dict
- check_remote_values()[source]¶
Queries and reads current settings of the device, updating the BLACS_tab widgets to reflect these values.
- Returns:
returns an empty dictionary, can be populated depending on level of device feedback.
- Return type:
dict
- transition_to_buffered(device_name: str, h5file: str, initial_values: dict, fresh)[source]¶
This method transitions the device from buffered to manual mode. It does any necessary configuration to take the device out of buffered mode and is used to read any measurements and save them to the shot h5 file as results.
- Parameters:
device_name (str) – Name of the device in labscript.
h5file (str) – path to shot file to run.
initial_values (dict) – Dictionary of output states at shot start
fresh (bool)
- Returns:
Dictionary of expected final output states.
- Return type:
dict
- transition_to_manual()[source]¶
Logic that runs after buffered execution to return control to the user/front panel. May need to call
abort_buffered()to handle behavior such as timeouts.- Returns:
returns True for internal logic.
- Return type:
Bool
- abort_buffered()[source]¶
Called when the user presses the abort button during buffered execution. Here returns to initial values, since buffered execution needed to be stopped.
- 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.