Instrumental
Instrumental copied to clipboard
Observer or Callback mechamism
Hi,
I am thinking about using Instrumental, but what I am missing is the ability to observe certain device values. This can simplify GUI writing a lot. Do I miss something or is this not supported?
greetings Till
It sounds like you’re wanting to poll devices periodically for some quantity, is this correct?
Sent with GitHawk
In some cases polling may be involved, but for most cases polling is not necessary.
I am more looking for something like some functinalty which in Qt-signals, traitlets, traits or atom. Let's say the device is camera with a settable gain and a Label showing the gain. Right now, if you change the gain at any point in the code, you have to update the label manually in the same step. If you have e.g. _gain_changed
observer, you use a callback to update your label.
I don’t have enough experience writing GUIs for instrumentation. I think Hernan Grecco’s lantz (or lantz-project) may have some more of this baked into their repository.
No, this isn't really baked into Instrumental right now. That said, I've had an easy time making lightweight persistent GUIs for plotting streamed data from instrumental-interfaced instruments using a combination of socket https://docs.python.org/3/library/socket.html and PyQtGraph http://www.pyqtgraph.org/ (on suggestions from @natezb, Instrumental's legendary creator) for TCP/IP service and plot GUI coding, respectively. Separating it into a data-streaming server and a plotting client has a couple really nice benefits
- You can live-stream data from an instrument to a persistent plot GUI and simultaneously and asynchronously perform data collection with another python kernel (eg. in a Jupyter notebook). This is not possible if you're only running one python kernel.
- The data stream server can easily be accessed by other computers on your local network, so you can hook up instruments to lab computers that are always on and running the little python-based server code, and then access the data stream for live plotting or data collection on other computers, or multiple computers at the same time (eg. one plotting the data near the experiment, one collecting/saving/analyzing data elsewhere).
Here are example python scripts that do this with an instrumental-connected Bristol 721 IR spectrometer. Sorry the code is messy and largely copied from other sources, but it does work well and could be adapted for some other instrument just by changing a few lines. https://github.com/doddgray/experiment_control/blob/master/bristol721_server.py https://github.com/doddgray/experiment_control/blob/master/PlotBristol.py
This was one of the use cases I had in mind when introducing Facets, which are similar to Lantz's Feats (which have this GUI stuff baked in). Since Facets are basically properties with some extra features, callbacks should be pretty quick and simple to add.
It would be nice to have optional GUI support that lets you create "test panels" as Lantz allows you to do, but should not require everyone who uses Instrumental to have Qt installed.
Check out the changes in 82a23b841f15491d3e9b3746d4baeb176b78d40a. This adds an observe()
method to the Instrument
base class, which lets you register a facet observer on a per-instance level.
For example, let's say I have an MXG function generator and I want to print changes to the frequency:
>>> mxg.observe('cw_frequency', print)
>>> mxg.cw_frequency += Q_(1, 'MHz')
ChangeEvent(name='cw_frequency', old=<Quantity(933330000.0, 'hertz')>, new=<Quantity(934330000.0, 'hertz')>)
Note that this doesn't track changes made on an instrument's front panel, it only knows about changes made through the Facet interface.
Let me know what you think, the API is still very much open to change.