def do_config(self, **config_params): """Start doing a configuration using config_params. Return DState.Configuring, message when started """ for d in self.children: assert d.state in DState.canConfig(), \ "Child device {} in state {} is not configurable"\ .format(d, d.state) # Setup self for name, value in config_params.items(): setattr(self, name, value) self.stepsPerRun = 1 self.currentStep = 0 # make some sequences for config self._sconfig = Sequence( self.name + ".SConfig", SeqFunctionItem( "Configuring dets", self._configure_simDetector), SeqFunctionItem( "Configuring progScan", self._configure_progScan), SeqTransitionItem( "Wait for plugins to configure", self.child_statemachines, DState.Ready, DState.rest()), ) item_done, msg = self._sconfig.start() if item_done: # Arrange for a callback to process the next item self.post_changes(None, None) return DState.Configuring, msg
def do_configure(self, config_params, task): """Start doing a configuration using config_params. Return DState.Configuring, message when started """ for d in self.children: assert d.state in DState.canConfig(), \ "Child device {} in state {} is not configurable"\ .format(d, d.state) # Setup self for name, value in config_params.items(): setattr(self, name, value) self.stepsPerRun = 1 self.currentStep = 0 task.report("Configuring simDetectorDriver") self._configure_simDetectorDriver() task.report("Configuring positionPlugin") self._configure_positionPlugin() # Setup config matcher self._sconfig = ConfigMatcher( SeqTransitionItem( self.child_statemachines, DState.Ready, DState.rest())) name, changes = task.report_wait("Wait for plugins to configure") while not self._sconfig.check_done(name, changes): name, changes = task.report_wait() task.report("Configuring hdf5Writer") self._configure_hdf5Writer(self.positionPlugin.dimensions) # Finished task.report("Configuring done", DState.Ready)
def do_reset(self): """Start doing a reset from aborted or fault state. Return DState.Resetting, message when started """ seq_items = [] # Abort any items that need to be aborted need_wait = [] need_reset = [] self.running = False for d in self.children: if d.state not in DState.rest(): d.abort(block=False) need_wait.append(d.stateMachine) need_reset.append(d) elif d.state in DState.canReset(): need_reset.append(d) if need_wait: seq_items.append(SeqTransitionItem( "Wait for plugins to stop aborting", need_wait, DState.rest())) if need_reset: for d in need_reset: seq_items.append(SeqFunctionItem( "Reset {}".format(d.name), d.reset, block=False)) seq_items.append(SeqTransitionItem( "Wait for plugins to stop resetting", [d.stateMachine for d in need_reset], DState.rest())) # Add a resetting object if seq_items: self._sreset = Sequence(self.name + ".SReset", *seq_items) # Start the sequence item_done, msg = self._sreset.start() if item_done: # Arrange for a callback to process the next item self.post_changes(None, None) else: self._sreset = None msg = "Started resetting" self.post_changes(None, None) return DState.Resetting, msg
def do_abort(self): """Stop acquisition """ if self.state == DState.Configuring: self._sconfig.abort() elif self.state == DState.Running: self._srun.abort() elif self.state == DState.Rewinding: self._spause.abort() for d in self.children: if d.state in DState.canAbort(): d.abort(block=False) self.post_changes(None, None) return DState.Aborting, "Aborting started"
def do_rewind(self, steps=None): """Start a pause""" # make some sequences for config plugins = [self.simDetectorDriver.stateMachine, self.positionPlugin.stateMachine] for d in plugins: assert d.state in DState.canAbort(), \ "Child device {} in state {} is not abortable"\ .format(d, d.state) seq_items = [] # if we need to abort if self.simDetectorDriver.state not in DState.canConfig() or \ self.positionPlugin.state not in DState.canConfig(): seq_items += [ SeqFunctionItem( "Stopping simDetectorDriver", self.simDetectorDriver.abort, block=False), SeqFunctionItem( "Stopping positionPlugin", self.positionPlugin.abort, block=False), SeqTransitionItem( "Wait for plugins to stop", plugins, DState.Aborted, DState.rest()), SeqFunctionItem( "Reset simDetectorDriver", self.simDetectorDriver.reset, block=False), SeqFunctionItem( "Reset positionPlugin", self.positionPlugin.reset, block=False), SeqTransitionItem( "Wait for plugins to reset", plugins, DState.Idle, DState.rest()) ] # Add the config stages seq_items += [ SeqFunctionItem( "Configuring positionPlugin", self._configure_positionPlugin), SeqFunctionItem( "Configuring simDetectorDriver", self._configure_simDetectorDriver), SeqTransitionItem( "Wait for plugins to configure", plugins, DState.Ready, DState.rest()), ] # Add a configuring object self._spause = Sequence(self.name + ".SPause", *seq_items) if self.state == DState.Ready: self._post_rewind_state = DState.Ready else: self._post_rewind_state = DState.Paused if steps is not None: self.currentStep -= steps # Start the sequence item_done, msg = self._spause.start() if item_done: # Arrange for a callback to process the next item self.post_changes(None, None) return DState.Rewinding, msg
def do_run(self): """Start doing a run. Return DState.Running, message when started """ assert self.progScan.state == DState.Ready, \ "ProgScan in state {} is not runnable"\ .format(self.progScan.state) assert self.det1.state in \ [DState.Ready, DState.Paused], \ "det1 in state {} is not runnable"\ .format(self.det1.state) assert self.det2.state in \ [DState.Ready, DState.Paused], \ "det2 in state {} is not runnable"\ .format(self.det2.state) # If det1 is paused then resume, otherwise run if self.det1.state == DState.Paused: det1func = self.det1.resume det2func = self.det2.resume elif self.det1.state == DState.Ready: det1func = self.det1.run det2func = self.det2.run # Add a configuring object self._srun = Sequence( self.name + ".SRun", SeqFunctionItem( "Running det1", det1func, block=False), SeqFunctionItem( "Running det2", det2func, block=False), SeqTransitionItem( "Wait for det1 to run", self.det1.attributes["running"], True), SeqTransitionItem( "Wait for det2 to run", self.det2.attributes["running"], True), SeqFunctionItem( "Running progScan", self.progScan.run, block=False), SeqTransitionItem( "Wait for run to finish", self.child_statemachines, DState.Idle, DState.rest())) # Start the sequence item_done, msg = self._srun.start() if item_done: # Arrange for a callback to process the next item self.post_changes(None, None) return DState.Running, msg
def do_aborting(self, value, changes): """Work out if the changes mean aborting is complete. Return None, message if it isn't. Return DState.Aborted, message if it is. """ child_states = [c.state for c in self.children] rest = [s in DState.rest() for s in child_states] if all(rest): # All are in rest states no_fault = [s != DState.Fault for s in child_states] assert all(no_fault), \ "Expected no fault, got {}".format(child_states) return DState.Aborted, "Aborting finished" else: # No change return None, None
def do_run(self): """Start doing a run. Return DState.Running, message when started """ plugins = [self.simDetectorDriver.stateMachine, self.positionPlugin.stateMachine] for d in plugins: assert d.state == DState.Ready, \ "Child device {} in state {} is not runnable"\ .format(d.name, d.state) self.report("Running positionPlugin") self.positionPlugin.run(block=False) # If hdf writer is not already running then run it if self.hdf5Writer.state != DState.Running: self.hdf5Writer.run(block=False) t = SeqTransitionItem(self.hdf5Writer.attributes["capture"], True) name, changes = yield "Wait for hdf5Writer to run" while not t.check_done(name, changes): name, changes = yield "Wait for hdf5Writer to run" # Now start the other plugins t = SeqTransitionItem(self.positionPlugin.attributes["running"], True) name, changes = yield "Wait for hdf5Writer to run" while not t.check_done(name, changes): name, changes = yield "Wait for hdf5Writer to run" seq_items += [ SeqTransitionItem( "Wait for positionPlugin to run", self.positionPlugin.attributes["running"], True), SeqFunctionItem( "Running simDetectorDriver", self.simDetectorDriver.run, block=False), SeqTransitionItem( "Wait for run to finish", self.child_statemachines, DState.Idle, DState.rest()), ] # Add a configuring object self._srun = Sequence(self.name + ".SRun", *seq_items) # Start the sequence item_done, msg = self._srun.start() if item_done: # Arrange for a callback to process the next item self.post_changes(None, None) return DState.Running, msg
def do_rewind(self, steps=None): """Start a pause""" # make some sequences for config assert self.progScan.state in DState.canAbort(), \ "progScan in state {} is not abortable"\ .format(self.progScan.state) seq_items = [] need_prog_abort = self.progScan.state not in DState.canConfig() need_det_pause = self.det1.state == DState.Running if not need_det_pause: assert self.det1.state in DState.canRewind(), \ "SimDetector state {} isn't paused and can't rewind" \ .format(self.det1.state) if self.state == DState.Ready: self._post_rewind_state = DState.Ready else: self._post_rewind_state = DState.Paused # if we need to abort progScan if need_prog_abort: seq_items.append( SeqFunctionItem( "Stopping progScan", self.progScan.abort, block=False)) # either pause or resume det1 if need_det_pause: seq_items += [ SeqFunctionItem( "Pausing det1", self.det1.pause, block=False), SeqFunctionItem( "Pausing det2", self.det2.pause, block=False) ] else: seq_items += [ SeqFunctionItem( "Rewinding det1", self.det1.rewind, steps=steps, block=False), SeqFunctionItem( "Rewinding det2", self.det2.rewind, steps=steps, block=False) ] # wait for progScan to stop if need_prog_abort: seq_items += [ SeqTransitionItem( "Wait for progScan to stop", self.progScan.stateMachine, DState.Aborted, DState.rest()), SeqFunctionItem( "Reset progScan", self.progScan.reset, block=False), SeqTransitionItem( "Wait for progScan to reset", self.progScan.stateMachine, DState.Idle, DState.rest()) ] # Add the config stages seq_items += [ SeqTransitionItem( "Wait for det1 to rewind", self.det1.stateMachine, self._post_rewind_state, DState.doneRewind()), SeqTransitionItem( "Wait for det2 to rewind", self.det2.stateMachine, self._post_rewind_state, DState.doneRewind()), SeqFunctionItem( "Configuring progScan", self._configure_progScan), SeqTransitionItem( "Wait for progScan to configure", self.progScan.stateMachine, DState.Ready, DState.rest()), ] # Add a configuring object self._spause = Sequence(self.name + ".SPause", *seq_items) if steps is not None: self.currentStep -= steps # Start the sequence item_done, msg = self._spause.start() if item_done: # Arrange for a callback to process the next item self.post_changes(None, None) return DState.Rewinding, msg