Function Runner

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





Detailed Documentation

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

Bases: labscript.labscript.Device

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

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})

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

Bases: blacs.device_base_class.DeviceTab


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: blacs.tab_base_classes.Worker

transition_to_buffered(device_name, h5_file, initial_values, fresh)[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