Skip to the content.

index


Status Variables

When working with measurement modules (hardware/logic/GUI) you may want to preserve some variable values across consecutive runs of qudi.

We call measurement module instance variables that are automatically dumped/loaded upon deactivation/activation a "status variable".

The parent Base class will take care of dumping all status variables upon deactivation of the module. This will happen automatically at the end of on_deactivate and does NOT need to be triggered explicitly in the on_deactivate method definition.
This will also happen in case on_deactivate raises an exception.

⚠ WARNING:

Status variables will NOT be automatically saved if the measurement modules are not deactivated properly (i.e. by the module manager).
This can happen for example if the user is just killing the qudi process instead of shutting it down as intended (e.g. by pressing the "stop" button in the PyCharm IDE).

If this happens, the next startup of the modules will load the status variables from the last graceful deactivation.

Upon module activation, immediately before on_activate is run, status variables are read from disk and initialized in the module instance. This means that on_activate can already use these variables.
If there are any exceptions raised during this process, the module activation will still proceed but the status variable will be initialized with its default value instead if defined. This can however easily lead to follow-up errors in on_activate.

The status variables are stored in YAML format in one file per module using the qudi utilities in qudi.util.yaml. They are stored in an OS dependent qudi "AppData" directory.

Usage

In order to simplify the process of dumping/loading these variables to/from disk and prevent each measurement module to implement their own solution, qudi provides the meta object qudi.core.statusvariable.StatusVar.

When implementing a measurement module (hardware/logic/GUI) you can simply instantiate StatusVar class variables. These meta objects will be transformed into regular variable members of your measurement module instances and can be used like any normal instance variable in Python:

from qudi.core.statusvariable import StatusVar
from qudi.core.module import LogicBase

class MyExampleLogic(LogicBase):
    """ Module description goes here """
    
    _my_status_variable = StatusVar(name='my_storage_name', default=42,)

    ...

    def increment_my_variable(self):
        self._my_status_variable += 1

    ...

constructor & representer

Since status variables are dumped as YAML file you are limited in what data types can be stored.
Qudi YAML dumper and loader currently supports any native Python builtin type and numpy arrays.

If your status variables should be of any other type, you need to provide conversion functions to the StatusVar meta object:

You can provide constructor and representer callables as arguments to StatusVar or you can register a callable member of your module as such via decorators, e.g.:

from qudi.core.statusvariable import StatusVar
from qudi.core.module import LogicBase

class FancyDataType:
    def __init__(self, a, b):
        self.a = a
        self.b = b


class MyExampleLogic(LogicBase):
    """ Module description goes here """
    
    _my_status_variable = StatusVar(default=FancyDataType(42, 3.1415))
    _my_other_status_variable = StatusVar(
        default=FancyDataType(1, 2),
        constructor=lambda yaml_data: FancyDataType(*yaml_data), 
        representer=lambda data: [data.a, data.b]
    )
    
    ...

    @_my_status_variable.constructor
    def my_status_variable_constructor(self, yaml_data):
        return FancyDataType(*yaml_data)
    
    @_my_status_variable.representer
    def my_status_variable_constructor(self, data):
        return [data.a, data.b]

    ...

Since these conversion functions are usually static (as the example above also shows), you could also combine that with the @staticmethod decorator. But this is not necessary and just good style.

name

There is an optional name argument for StatusVar. The name given here is used by the YAML dumper as field name for the variable data. So the name argument can be used to store the status variable under a different (e.g. better readable) name in the app status file that is created.
A common use case is (as shown in the example above) to exclude the Pythonic (double-)underscore from the variable name.
By default, the declared variable name in the class body will be used and since the user usually never opens the AppStatus files, this feature is not quite too useful.


index