Access to BLACS worker outside of labscript framework

69 views
Skip to first unread message

Matthew Peters

unread,
Apr 17, 2022, 7:37:12 PM4/17/22
to the labscript suite
Hi all,

I'm considering writing code to check the alignment of parts of my experiment similar in function to this BLACS plugin: https://github.com/zakv/blacs/tree/lock-monitor/blacs/plugins/lock_monitor. My plan is to adjust mirrors (which I have already integrated into to BLACS) based on some scope or camera data. However, I'm unsure of  how to access the DeviceTab/worker through a plugin. 

My end goal would be to write some line of code like
MirrorTab.queue_work('main_worker', 'align_mirror', measured_data)
in my custom plugin. My initial approach would be to try to track down the DeviceTab "MirrorTab", but it wasn't clear how to actually extract this or if I would run into some threading issue with this approach. Could someone offer some guidance on how to do this (or an alternative/superior way)?

Thanks,
Matthew

Zak V

unread,
Apr 18, 2022, 11:13:23 PM4/18/22
to the labscript suite
Hey Matthew,

I'm not sure whether or not there's a good way to send commands from a blacs plugin to other tabs to control labscript devices. The laser locking classes I wrote for lock monitor just used their own hardware which they controlled directly. Those pieces of hardware weren't otherwise incorporated into blacs, i.e. they didn't have their own blacs tab.

Generally I didn't want those pieces of hardware controlled directly by a user as part of an experiment; I wanted them controlled by lock monitor as needed to keep the lasers in lock. So it made sense for that hardware not to have a blacs tab or labscript device class. I'm not about the details of your application, but would you say that your mirrors have a similar role? If so, you could take a similar approach and just control them directly from your plugin, or maybe you could even just use lock monitor. If not, then could you provide some more context on what you're trying to set up? For example, do you need to run a hardware-timed sequence with atoms in order to determine the proper mirror position, or can you just get the required beam position from the scope/camera data directly?

Cheers,
Zak

Matthew Peters

unread,
Apr 20, 2022, 8:17:12 PM4/20/22
to the labscript suite
Thanks for the response Zak!!

For this particular application that I'm immediately implementing, there are no reasons why it couldn't be run outside of the blacs framework. A scope and a photodetector will work fine. However, I and other people I work with have plans for future applications involving sweeping mirror positions using runmanager, using lyse to analyse the results, and then feeding back based on the shot results.

I could separate the mirrors that I use for this application from the ones I'd like to sweep in runmanager, although that wasn't my preferred solution because then I'd need to write independent two sets of code to control them (one in blacs and one for a lock monitor). Another solution is that I could write a server independent of labscript that could accept commands from any source of code, with one source of commands being from blacs and another code being from some locking monitor, but that seems to be a bit complicated. If there's not an easy way to access the worker, then I'll probably go with the former solution unless you have another suggestion!

Best,
Matt 

Philip Starkey

unread,
Apr 20, 2022, 11:29:25 PM4/20/22
to labscri...@googlegroups.com
Hi Matthew,

This is something we should probably support properly, but it turns out you can access the tablist from a plugin. If we look at the connection table compilation plugin here we can see that it gets a list of devices that failed to load via the experiment queue (which plugins have access too) as the experiment queue holds a reference to the main BLACS Python instance. This instance also holds references to the successfully loaded devices. So in your case you could write:

def plugin_setup_complete(self, BLACS):
    tablist = BLACS["experiment_queue"].BLACS.tablist
    # store it so it can be used by some other part of your plugin or whatever.

Plugins are a work-in-progress so if you need specific functionality added to BLACS we're always happy to accept pull requests that address your specific requirements.

Cheers,
Phil

--
You received this message because you are subscribed to the Google Groups "the labscript suite" group.
To unsubscribe from this group and stop receiving emails from it, send an email to labscriptsuit...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/labscriptsuite/3060d1c3-31d7-45ff-85e0-e93f23dc60c3n%40googlegroups.com.


--
Dr Philip Starkey
Senior Technician (Lightboard developer)

School of Physics & Astronomy
Monash University
10 College Walk, Clayton Campus
Victoria 3800, Australia

Zak V

unread,
Apr 20, 2022, 11:54:05 PM4/20/22
to the labscript suite
Hi Matt, Phil,

Phil - do you know how sending work to a tab would jive with the blacs state machine? I don't remember enough details to know how things would go, but I could imagine that maybe a plugin could queue work for a blacs device but it wouldn't happen until after a shot completed or something. I could be way off base here though.

I think that the mirrors which only need an oscilloscope and photodetector to align could be controlled with a plugin by controlling that hardware directly instead of via a blacs tab. In fact lock monitor would be pretty well suited to this, so you probably wouldn't even need to create your own plugin. You'd still need to write some code to talk to the hardware etc., but you wouldn't have to learn how to write blacs plugins. You could have it read the optical power from a scope, then have it automatically realign the beam if the power falls below some threshold. You can actually have pretty minimal code duplication too if you organize it well. For example, see how the Zaber stage labscript device is set up. There is a `ZaberInterface` class that can be used from anywhere, even outside of blacs/labscript, to control a Zaber stage. All of the blacs-specific code is contained in `ZaberWorker`. So your plugin could just use its `ZaberInterface`-equivalent class to control any hardware that doesn't have an associated blacs tab, and then it would use the same hardware interfacing code that blacs uses.

As for the alignment which requires running experiments with atoms, I can't think of a great way to do that with a plugin so I think it might be better to use a lyse script. In this approach you could have lyse use runmanager's remote interface to run experiments.  The lyse script would run a series of these experiments, scanning the mirror position, then do some analysis to determine the optimal position. You could then have it update your hdf5 globals file with the result so that future shots will be compiled with the newly-calibrated mirror position. This approach could also be used for alignments which don't require atoms since you could write a labscript sequence which just read a value off of a scope. That is probably slower than using a plugin, and probably less convenient to automatically trigger a realignment when needed, but maybe it would be convenient to use the same approach to align your beams whether or not you need atoms to do so.

I also have a vague memory that others on this mailing list have done some work on just-in-time compilation of sequences to handle calibrated values. They may have done things very similar to what you are considering, so they would likely have more helpful input.

Cheers,
Zak

Philip Starkey

unread,
Apr 21, 2022, 5:39:26 AM4/21/22
to labscri...@googlegroups.com
Hi Zak, Matthew,

I should be fine to call any method within the device tab that uses the @define_state decorator (see https://github.com/labscript-suite/labscript-devices/blob/8de7a40ad32c2e1cebbb9b96350567d339be0765/labscript_devices/PulseBlaster.py#L840 for an example)

The arguments to the decorator determine which modes the method can run in, whether the call should be queued up if the tab isn't in an allowed mode, and whether duplicate queued up calls should be ignored in favour of the most recent. We used to have detailed documentation on this, but it might have got lost in the transition to the new docs format.

There is nothing technically stopping a method from being called and queueing work during a shot as this is how the pseudoclock state checks work. But most likely you would only want to allow the method to be called in manual mode. Note that calling a device tab method (decorated with @define_state) does not cause it to be executed synchronously. If you need to know when the method completes, or get return data from the method, you need to pass in a Python queue as an argument and use that for communication between the calling code and the device tab method (e.g. have the method put in the return data and wait on the queue in the calling code). This is a requirement in order to enforce thread safety. But the upside is you don't have to worry about thread safety!

Hope that helps! Happy to answer further questions.

Cheers,
Phil

Reply all
Reply to author
Forward
0 new messages