Fork PyRPL on GitHub

Source code for pyrpl.software_modules.lockbox.stage

from __future__ import division
from . import LockboxModule
from ...attributes import SelectProperty, FloatProperty, BoolProperty, \
    StringProperty
from ...module_attributes import *
from ...hardware_modules import InputSelectProperty
from ...widgets.module_widgets import ReducedModuleWidget, \
    LockboxSequenceWidget, LockboxStageWidget, StageOutputWidget
from qtpy import QtCore
from collections import OrderedDict


[docs]class StageSignalLauncher(SignalLauncher): stage_created = QtCore.Signal(list) stage_deleted = QtCore.Signal(list)
#stage_renamed = QtCore.Signal()
[docs]class StageOutput(LockboxModule): _setup_attributes = ['lock_on', 'reset_offset', 'offset'] _gui_attributes = _setup_attributes _widget_class = StageOutputWidget lock_on = BoolIgnoreProperty(default=False, call_setup=True) reset_offset = BoolProperty(default=False, call_setup=True) offset = FloatProperty(default=0, min=-1., max=1., increment=1e-4, call_setup=True) def _setup(self): # forward changes to parent module self.parent._setup()
[docs]class StageInputSelectProperty(InputSelectProperty): pass
#def validate_and_normalize(self, obj, value): # if isinstance(value, SignalModule): # value = SignalModule.name # return value
[docs]class Stage(LockboxModule): """ A stage is a single step in the lock acquisition process """ _gui_attributes = ['input', 'setpoint', 'duration', 'gain_factor', 'function_call'] _setup_attributes = _gui_attributes + ['outputs'] _widget_class = LockboxStageWidget _signal_launcher = StageSignalLauncher input = StageInputSelectProperty(ignore_errors=True, options=lambda stage: stage.lockbox.inputs.keys(), call_setup=True) setpoint = FloatProperty(default=0, min=-1e6, max=1e6, increment=0.1, call_setup=True) gain_factor = FloatProperty(default=1., min=-1e6, max=1e6, increment=0.1, call_setup=True) function_call = StringProperty(default="", call_setup=True) duration = FloatProperty(default=0, min=0, max=1e6, increment=0.1) # outputs is a dict of submodules, containing an entry of # StageOutput per Lockbox output (initialized in __init__) outputs = ModuleDictProperty(module_cls=LockboxModule) def __init__(self, parent, name=None): super(Stage, self).__init__(parent, name=name) for output in self.lockbox.outputs: self.outputs[output.name] = StageOutput self._signal_launcher.stage_created.emit([self]) self.parent._signal_launcher.stage_created.emit([self]) self.lockbox._logger.debug("Stage %s initialized"%self.name) def _clear(self): self.lockbox._logger.debug("Deleting stage %s"%self.name) self._signal_launcher.stage_deleted.emit([self]) self.parent._signal_launcher.stage_deleted.emit([self]) super(Stage, self)._clear() @property def _states(self): """ Returns the config file branch corresponding to the saved states of the module. """ return None # saving individual stage states is not allowed #return self.c._root._get_or_create("stage_" + str(self.name) + "_states")
[docs] def enable(self): """ Setup the lockbox parameters according to this stage """ for output in self.lockbox.outputs: setting = self.outputs[output.name] if setting.lock_on == 'ignore': # this part is here to remind you that BoolIgnoreProperties # should not be typecasted into bools, i.e. you should avoid # to write "if setting.lock_on: do_sth()" because the setting # 'ignore' will be interpreted identically as "True" pass if setting.lock_on == False: output.unlock() if setting.reset_offset: output._setup_offset(setting.offset) # make a new iteration for enabling lock, in order # to be sure that all offsets are reset before starting lock for output in self.lockbox.outputs: setting = self.outputs[output.name] if setting.lock_on == True: output.lock(input=self.input, setpoint=self.setpoint, offset=setting.offset if setting.reset_offset else None, gain_factor=self.gain_factor) # optionally call a user function at the end of the stage if self.function_call != "": try: func = recursive_getattr(self.lockbox, self.function_call) except AttributeError: self._logger.warning("Could not find the function '%s' called " "in stage %s in the Lockbox class. " "Please specify a valid function name " "to call!", self.function_call, self.name) else: try: func() except TypeError: func(self) # set lockbox state to stage name self.lockbox.current_state = self.name
def _setup(self): # the first test is needed to avoid startup problems if hasattr(self.lockbox, '_sequence'): if self.lockbox.current_state == self.name: # enable a stage if its parameters have changed self.enable() # synchronize (active) final_stage with the last stage of sequence elif self.lockbox.current_state == 'lock' and self == self.parent[-1]: self.lockbox.final_stage = self.setup_attributes