Function Runner

A labscript device to run custom functions before, after, or during (not yet implemented) the experiment in software time.

labscript_devices.FunctionRunner.labscript_devices

labscript_devices.FunctionRunner.blacs_tabs

labscript_devices.FunctionRunner.blacs_workers

labscript_devices.FunctionRunner.utils

Detailed Documentation

class labscript_devices.FunctionRunner.labscript_devices.FunctionRunner(name, **kwargs)[source]

Bases: Device

A labscript device to run custom functions before, after, or during (not yet implemented) the experiment in software time

Creates 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.

add_function(t, function, *args, **kwargs)[source]

Add a function to be run at time t. If t=’start’, then the function will run prior to the shot beginning, and if t=’stop’, it will run after the experiment has completed. Tip: use start_order and stop_order keyword arguments when instantiating this device to control the relative order that its ‘start’ and ‘stop’ functions run compared to the transition_to_manual and transition_to_buffered functions of other devices. Multiple functions added to run at the same time will be run in the order added. Running functions mid-shot in software time is yet to be implemented.

The function must have a call signature like the following:

def func(shot_context, t, …):

When it is called, a ShotContext instance will be passed in as the first argument, and the time at which the function was requested to run as the second argument. The ShotContext instance will be the same for all calls for the same shot, so it can be used to store state for that shot (but not from one shot to the next), the same way you would use the ‘self’ argument of a method to store state in an instance. As an example, you might set shot_context.serial to be an open serial connection to a device during a function set to run at t=’start’, and refer back to it in subsequent functions to read and write data. Other than state stored in shot_context, the functions must be self-contained, containing any imports that they need.

This object has a number of attributes:

  • self.globals: the shot globals

  • self.h5_file: the filepath to the shot’s HDF5 file

  • self.device_name: the name of this FunctionRunner

If you want to save raw data to the HDF5 file at the end of a shot, the recommended place to do it is within the group ‘data/<device_name>’, for .. rubric:: Example

with h5py.File(self.h5_file, ‘r+’) as f:

data_group = f[‘data’].create_group(self.device_name) # save datasets/attributes within this group

Or, if you are doing analysis and want to save results that will be accessible to lyse analysis routines in the usual way, you can instantiate a lyse.Run object and call Run.save_result() etc:

import lyse run = lyse.Run(shot_context.h5_file) run.save_result(‘x’, 7)

The group that the results will be saved to, which is usually the filename of the lyse analysis routine, will instead be the device name of the FunctionRunner.

The use case for which this device was implemented was to update runmanager’s globals immediately after a shot, based on measurement data, such that just-in-time compiled shots imme. This is done by calling the runmanager remote API from within a function to be run at the end of a shot, like so:

import runmanager.remote runmanager.remote.set_globals({‘x’: 7})

generate_code(hdf5_file)[source]

Generate hardware instructions for device and children, then save to h5 file.

Will recursively call generate_code for all children devices.

Parameters:

hdf5_file (h5py.File) – Handle to shot file.

class labscript_devices.FunctionRunner.blacs_tabs.FunctionRunnerTab(notebook, settings, restart=False)[source]

Bases: DeviceTab

initialise_workers()[source]
restore_builtin_save_data(data)[source]

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

class labscript_devices.FunctionRunner.blacs_workers.FunctionRunnerWorker(*args, **kwargs)[source]

Bases: Worker

abort_buffered()[source]
abort_transition_to_buffered()[source]
program_manual(values)[source]
shutdown()[source]
transition_to_buffered(device_name, h5_file, initial_values, fresh)[source]
transition_to_manual()[source]
class labscript_devices.FunctionRunner.blacs_workers.ShotContext(h5_file, device_name)[source]

Bases: object

labscript_devices.FunctionRunner.blacs_workers.deserialise_function_table(function_table, device_name)[source]
labscript_devices.FunctionRunner.utils.deserialise_function(name, source, args, kwargs, __name__=None, __file__='<string>')[source]

Deserialise a function that was serialised by serialise_function. Optional __name__ and __file__ arguments set those attributes in the namespace that the function will be defined.

labscript_devices.FunctionRunner.utils.serialise_function(function, *args, **kwargs)[source]

Serialise a function based on its source code, and serialise the additional args and kwargs that it will be called with. Raise an exception if the function signature does not begin with (shot_context, t) or if the additional args and kwargs are incompatible with the rest of the function signature