def action_loop(self): i = 0 states, values = {}, {} for element in self._channels: states[element] = None #values[element] = None nap = self._acq_sleep_time nb_states_per_value = self._nb_states_per_value # read values to send a first event when starting to acquire with ActionContext(self): self.raw_read_value_loop(ret=values) for acquirable, value in values.items(): acquirable.put_value(value, propagate=2) while True: self.read_state_info(ret=states) if not self.in_acquisition(states): break # read value every n times if not i % nb_states_per_value: self.read_value_loop(ret=values) for acquirable, value in values.items(): acquirable.put_value(value) time.sleep(nap) i += 1 for slave in self._slaves: try: slave.stop_action() except: self.warning("Unable to stop slave acquisition %s", slave.getLogName()) self.debug("Details", exc_info=1) with ActionContext(self): self.raw_read_state_info(ret=states) self.raw_read_value_loop(ret=values) for acquirable, state_info in states.items(): # first update the element state so that value calculation # that is done after takes the updated state into account acquirable.set_state_info(state_info, propagate=0) if acquirable in values: value = values[acquirable] acquirable.put_value(value, propagate=2) with acquirable: acquirable.clear_operation() state_info = acquirable._from_ctrl_state_info(state_info) acquirable.set_state_info(state_info, propagate=2)
def start_action(self, *args, **kwargs): """kwargs['items'] is a dict<moveable, (pos, dial, do_backlash, backlash) """ items = kwargs.pop("items") pool = self.pool # prepare data structures self._aborted = False self._stopped = False self._motion_sleep_time = kwargs.pop("motion_sleep_time", pool.motion_loop_sleep_time) self._nb_states_per_position = \ kwargs.pop("nb_states_per_position", pool.motion_loop_states_per_position) self._motion_info = motion_info = {} for moveable, motion_data in items.items(): it = moveable.instability_time motion_info[moveable] = PoolMotionItem(moveable, *motion_data, instability_time=it) pool_ctrls = self.get_pool_controller_list() moveables = self.get_elements() with ActionContext(self): self.pre_start_all(pool_ctrls) self.pre_start_one(moveables, items) self.start_one(moveables, motion_info) self.start_all(pool_ctrls, moveables, motion_info)
def action_loop(self): states, values = {}, {} for element in self._channels: states[element] = None values[element] = None nap = self._acq_sleep_time while True: self.read_value(ret=values) for acquirable, value in values.items(): acquirable.put_value(value) if self._stopped or self._aborted: break time.sleep(nap) with ActionContext(self): self.raw_read_state_info(ret=states) for acquirable, state_info in states.items(): # first update the element state so that value calculation # that is done after takes the updated state into account state_info = acquirable._from_ctrl_state_info(state_info) acquirable.set_state_info(state_info, propagate=0) with acquirable: acquirable.clear_operation() acquirable.set_state_info(state_info, propagate=2)
def start_action(self, *args, **kwargs): """Prepares everything for acquisition and starts it. :param: config""" pool = self.pool # prepare data structures self._aborted = False self._stopped = False self._acq_sleep_time = kwargs.pop("acq_sleep_time", pool.acq_loop_sleep_time) self._nb_states_per_value = \ kwargs.pop("nb_states_per_value", pool.acq_loop_states_per_value) integ_time = kwargs.get("integ_time") mon_count = kwargs.get("monitor_count") if integ_time is None and mon_count is None: raise Exception("must give integration time or monitor counts") if integ_time is not None and mon_count is not None: raise Exception( "must give either integration time or monitor counts (not both)" ) items = kwargs.get("items") if items is None: items = self.get_elements() cfg = kwargs['config'] pool_ctrls_dict = dict(cfg['controllers']) pool_ctrls_dict.pop('__tango__', None) pool_ctrls = [] for ctrl in pool_ctrls_dict: if ElementType.ZeroDExpChannel in ctrl.get_ctrl_types(): pool_ctrls.append(ctrl) # Determine which channels are active self._channels = channels = {} for pool_ctrl in pool_ctrls: ctrl = pool_ctrl.ctrl pool_ctrl_data = pool_ctrls_dict[pool_ctrl] main_unit_data = pool_ctrl_data['units']['0'] elements = main_unit_data['channels'] for element, element_info in elements.items(): channel = Channel(element, info=element_info) channels[element] = channel with ActionContext(self): # set the state of all elements to and inform their listeners for channel in channels: channel.clear_buffer() channel.set_state(State.Moving, propagate=2)
def start_action(self, *args, **kwargs): """Prepares everything for acquisition and starts it. :param: config""" pool = self.pool self._index = kwargs.get("idx") # prepare data structures # TODO: rollback this change when a proper synchronization between # acquisition actions will be develop. # Now the meta acquisition action is resettung them to 0. # self._aborted = False # self._stopped = False self._acq_sleep_time = kwargs.pop("acq_sleep_time", pool.acq_loop_sleep_time) self._nb_states_per_value = \ kwargs.pop("nb_states_per_value", pool.acq_loop_states_per_value) items = kwargs.get("items") if items is None: items = self.get_elements() cfg = kwargs['config'] pool_ctrls_dict = dict(cfg['controllers']) pool_ctrls_dict.pop('__tango__', None) pool_ctrls = [] for ctrl in pool_ctrls_dict: if ElementType.ZeroDExpChannel in ctrl.get_ctrl_types(): pool_ctrls.append(ctrl) # Determine which channels are active self._channels = channels = {} for pool_ctrl in pool_ctrls: ctrl = pool_ctrl.ctrl pool_ctrl_data = pool_ctrls_dict[pool_ctrl] elements = pool_ctrl_data['channels'] for element, element_info in elements.items(): channel = Channel(element, info=element_info) channels[element] = channel with ActionContext(self): # set the state of all elements to and inform their listeners for channel in channels: channel.clear_buffer() channel.set_state(State.Moving, propagate=2)
def action_loop(self): i = 0 states, values = {}, {} for element in self._channels: states[element] = None values[element] = None nap = self._acq_sleep_time nb_states_per_value = self._nb_states_per_value while True: self.read_state_info(ret=states) if not self.in_acquisition(states): break # read value every n times if not i % nb_states_per_value: self.read_value_loop(ret=values) for acquirable, value in values.items(): if is_value_error(value): self.error("Loop read value error for %s" % acquirable.name) acquirable.put_value(value) else: acquirable.extend_value_buffer(value) time.sleep(nap) i += 1 with ActionContext(self): self.raw_read_state_info(ret=states) self.raw_read_value_loop(ret=values) for acquirable, state_info in states.items(): # first update the element state so that value calculation # that is done after takes the updated state into account acquirable.set_state_info(state_info, propagate=0) if acquirable in values: value = values[acquirable] if is_value_error(value): self.error("Loop final read value error for: %s" % acquirable.name) acquirable.put_value(value) else: acquirable.extend_value_buffer(value, propagate=2) with acquirable: acquirable.clear_operation() state_info = acquirable._from_ctrl_state_info(state_info) acquirable.set_state_info(state_info, propagate=2)
def action_loop(self): states, values = {}, {} for element in self._channels: states[element] = None values[element] = None nap = self._acq_sleep_time while True: self.read_state_info(ret=states) if not self.in_acquisition(states): break time.sleep(nap) for slave in self._slaves: try: slave.stop_action() except: self.warning("Unable to stop slave acquisition %s", slave.getLogName()) self.debug("Details", exc_info=1) with ActionContext(self): self.raw_read_state_info(ret=states) self.raw_read_value_loop(ret=values) for acquirable, state_info in states.items(): # first update the element state so that value calculation # that is done after takes the updated state into account acquirable.set_state_info(state_info, propagate=0) if acquirable in values: value = values[acquirable] if is_value_error(value): self.error("Loop final read value error for: %s" % acquirable.name) acquirable.put_value(value) else: acquirable.append_value_buffer(value, self.index) with acquirable: acquirable.clear_operation() state_info = acquirable._from_ctrl_state_info(state_info) acquirable.set_state_info(state_info, propagate=2)
def start_action(self, *args, **kwargs): '''Start action method. Expects the following kwargs: - config - dictionary containing measurement group configuration - synchronization - list of dictionaries containing information about the expected synchronization - moveable (optional)- moveable object used as the synchronization source in the Position domain - monitor (optional) - counter/timer object used as the synchronization source in the Monitor domain ''' cfg = kwargs['config'] synchronization = kwargs.get('synchronization') moveable = kwargs.get('moveable') ctrls_config = cfg.get('controllers') pool_ctrls = ctrls_config.keys() # Prepare a dictionary with the involved channels self._channels = channels = {} for pool_ctrl in pool_ctrls: pool_ctrl_data = ctrls_config[pool_ctrl] elements = pool_ctrl_data['channels'] for element, element_info in elements.items(): channel = TGChannel(element, info=element_info) channels[element] = channel with ActionContext(self): # loads synchronization description for pool_ctrl in pool_ctrls: ctrl = pool_ctrl.ctrl pool_ctrl_data = ctrls_config[pool_ctrl] ctrl.PreSynchAll() elements = pool_ctrl_data['channels'] for element in elements: axis = element.axis ret = ctrl.PreSynchOne(axis, synchronization) if not ret: msg = ("%s.PreSynchOne(%d) returns False" % (pool_ctrl.name, axis)) raise Exception(msg) ctrl.SynchOne(axis, synchronization) ctrl.SynchAll() # attaching listener (usually acquisition action) # to the software trigger gate generator if self._listener is not None: self._synch_soft.set_configuration(synchronization) self._synch_soft.add_listener(self._listener) remove_acq_listener = partial(self._synch_soft.remove_listener, self._listener) self.add_finish_hook(remove_acq_listener, False) self._synch_soft.add_listener( self.main_element.on_element_changed) remove_mg_listener = partial(self._synch_soft.remove_listener, self.main_element) self.add_finish_hook(remove_mg_listener, False) # subscribing to the position change events to generate events # in position domain if moveable is not None: position = moveable.get_position_attribute() position.add_listener(self._synch_soft) remove_pos_listener = partial(position.remove_listener, self._synch_soft) self.add_finish_hook(remove_pos_listener, False) # PreStartAll on all controllers for pool_ctrl in pool_ctrls: pool_ctrl.ctrl.PreStartAll() # PreStartOne & StartOne on all elements for pool_ctrl in pool_ctrls: ctrl = pool_ctrl.ctrl pool_ctrl_data = ctrls_config[pool_ctrl] elements = pool_ctrl_data['channels'] for element in elements: axis = element.axis channel = channels[element] ret = ctrl.PreStartOne(axis) if not ret: raise Exception("%s.PreStartOne(%d) returns False" % (pool_ctrl.name, axis)) ctrl.StartOne(axis) # set the state of all elements to inform their listeners for channel in channels: channel.set_state(State.Moving, propagate=2) # StartAll on all controllers for pool_ctrl in pool_ctrls: pool_ctrl.ctrl.StartAll() if self._listener is not None: self._synch_soft.start() get_thread_pool().add(self._synch_soft.run)
def start_action(self, *args, **kwargs): """Prepares everything for acquisition and starts it. :param: config""" pool = self.pool # prepare data structures self._aborted = False self._stopped = False self._acq_sleep_time = kwargs.pop("acq_sleep_time", pool.acq_loop_sleep_time) self._nb_states_per_value = \ kwargs.pop("nb_states_per_value", pool.acq_loop_states_per_value) self._integ_time = integ_time = kwargs.get("integ_time") self._mon_count = mon_count = kwargs.get("monitor_count") if integ_time is None and mon_count is None: raise Exception("must give integration time or monitor counts") if integ_time is not None and mon_count is not None: raise Exception("must give either integration time or monitor counts (not both)") _ = kwargs.get("items", self.get_elements()) cfg = kwargs['config'] # determine which is the controller which holds the master channel if integ_time is not None: master_key = 'timer' master_value = integ_time if mon_count is not None: master_key = 'monitor' master_value = -mon_count master = cfg[master_key] master_ctrl = master.controller pool_ctrls_dict = dict(cfg['controllers']) pool_ctrls_dict.pop('__tango__', None) pool_ctrls = [] self._pool_ctrl_dict_loop = _pool_ctrl_dict_loop = {} for ctrl, v in pool_ctrls_dict.items(): if ctrl.is_timerable(): pool_ctrls.append(ctrl) if ElementType.CTExpChannel in ctrl.get_ctrl_types(): _pool_ctrl_dict_loop[ctrl] = v # make sure the controller which has the master channel is the last to # be called pool_ctrls.remove(master_ctrl) pool_ctrls.append(master_ctrl) # Determine which channels are active self._channels = channels = {} for pool_ctrl in pool_ctrls: ctrl = pool_ctrl.ctrl pool_ctrl_data = pool_ctrls_dict[pool_ctrl] main_unit_data = pool_ctrl_data['units']['0'] elements = main_unit_data['channels'] for element, element_info in elements.items(): axis = element.axis channel = Channel(element, info=element_info) channels[element] = channel #for channel in channels: # channel.prepare_to_acquire(self) with ActionContext(self): # PreLoadAll, PreLoadOne, LoadOne and LoadAll for pool_ctrl in pool_ctrls: ctrl = pool_ctrl.ctrl pool_ctrl_data = pool_ctrls_dict[pool_ctrl] main_unit_data = pool_ctrl_data['units']['0'] ctrl.PreLoadAll() master = main_unit_data[master_key] axis = master.axis res = ctrl.PreLoadOne(axis, master_value) if not res: raise Exception("%s.PreLoadOne(%d) returns False" % (pool_ctrl.name, axis,)) ctrl.LoadOne(axis, master_value) ctrl.LoadAll() # PreStartAll on all controllers for pool_ctrl in pool_ctrls: pool_ctrl.ctrl.PreStartAll() # PreStartOne & StartOne on all elements for pool_ctrl in pool_ctrls: ctrl = pool_ctrl.ctrl pool_ctrl_data = pool_ctrls_dict[pool_ctrl] main_unit_data = pool_ctrl_data['units']['0'] elements = main_unit_data['channels'] for element in elements: axis = element.axis channel = channels[element] if channel.enabled: ret = ctrl.PreStartOne(axis, master_value) if not ret: raise Exception("%s.PreStartOne(%d) returns False" \ % (pool_ctrl.name, axis)) ctrl.StartOne(axis, master_value) # set the state of all elements to and inform their listeners for channel in channels: channel.set_state(State.Moving, propagate=2) # StartAll on all controllers for pool_ctrl in pool_ctrls: pool_ctrl.ctrl.StartAll()
def start_action(self, *args, **kwargs): """Prepares everything for acquisition and starts it. :param acq_sleep_time: sleep time between state queries :param nb_states_per_value: how many state queries between readouts :param integ_time: integration time(s) :type integ_time: float or seq<float> :param repetitions: repetitions :type repetitions: int :param config: configuration dictionary (with information about involved controllers and channels) """ pool = self.pool self._aborted = False self._stopped = False self._acq_sleep_time = kwargs.pop("acq_sleep_time", pool.acq_loop_sleep_time) self._nb_states_per_value = kwargs.pop("nb_states_per_value", pool.acq_loop_states_per_value) self._integ_time = integ_time = kwargs.get("integ_time") self._mon_count = mon_count = kwargs.get("monitor_count") self._repetitions = repetitions = kwargs.get("repetitions") if integ_time is None and mon_count is None: raise Exception("must give integration time or monitor counts") if integ_time is not None and mon_count is not None: msg = ("must give either integration time or monitor counts " "(not both)") raise Exception(msg) _ = kwargs.get("items", self.get_elements()) cfg = kwargs['config'] # determine which is the controller which holds the master channel if integ_time is not None: master_key = 'timer' master_value = integ_time if mon_count is not None: master_key = 'monitor' master_value = -mon_count master = cfg[master_key] if master is None: self.main_element.set_state(State.Fault, propagate=2) msg = "master {0} is unknown (probably disabled)".format( master_key) raise RuntimeError(msg) master_ctrl = master.controller pool_ctrls_dict = dict(cfg['controllers']) pool_ctrls_dict.pop('__tango__', None) # controllers to be started (only enabled) in the right order pool_ctrls = [] # controllers that will be read at the end of the action self._pool_ctrl_dict_loop = _pool_ctrl_dict_loop = {} # channels that are acquired (only enabled) self._channels = channels = {} # select only suitable e.g. enabled, timerable controllers & channels for ctrl, pool_ctrl_data in pool_ctrls_dict.items(): # skip not timerable controllers e.g. 0D if not ctrl.is_timerable(): continue ctrl_enabled = False elements = pool_ctrl_data['channels'] for element, element_info in elements.items(): # skip disabled elements if not element_info['enabled']: continue # Add only the enabled channels channel = Channel(element, info=element_info) channels[element] = channel ctrl_enabled = True # check if the ctrl has enabled channels if ctrl_enabled: # enabled controller can no be offline if not ctrl.is_online(): self.main_element.set_state(State.Fault, propagate=2) msg = "controller {0} is offline".format(ctrl.name) raise RuntimeError(msg) pool_ctrls.append(ctrl) # only CT will be read in the loop, 1D and 2D not if ElementType.CTExpChannel in ctrl.get_ctrl_types(): _pool_ctrl_dict_loop[ctrl] = pool_ctrl_data # timer/monitor channels can not be disabled for pool_ctrl in pool_ctrls: ctrl = pool_ctrl.ctrl pool_ctrl_data = pool_ctrls_dict[pool_ctrl] timer_monitor = pool_ctrl_data[master_key] if timer_monitor not in channels: self.main_element.set_state(State.Fault, propagate=2) msg = "timer/monitor ({0}) of {1} controller is "\ "disabled)".format(timer_monitor.name, pool_ctrl.name) raise RuntimeError(msg) # make sure the controller which has the master channel is the last to # be called pool_ctrls.remove(master_ctrl) pool_ctrls.append(master_ctrl) with ActionContext(self): # PreLoadAll, PreLoadOne, LoadOne and LoadAll for pool_ctrl in pool_ctrls: try: ctrl = pool_ctrl.ctrl pool_ctrl_data = pool_ctrls_dict[pool_ctrl] ctrl.PreLoadAll() master = pool_ctrl_data[master_key] axis = master.axis try: res = ctrl.PreLoadOne(axis, master_value, repetitions) except TypeError: msg = ("PreLoadOne(axis, value) is deprecated since " "version 2.3.0. Use PreLoadOne(axis, value, " "repetitions) instead.") self.warning(msg) res = ctrl.PreLoadOne(axis, master_value) if not res: msg = ("%s.PreLoadOne(%d) returned False" % (pool_ctrl.name, axis)) raise Exception(msg) try: ctrl.LoadOne(axis, master_value, repetitions) except TypeError: msg = ("LoadOne(axis, value) is deprecated since " "version 2.3.0. Use LoadOne(axis, value, " "repetitions) instead.") self.warning(msg) ctrl.LoadOne(axis, master_value) ctrl.LoadAll() except Exception, e: self.debug(e, exc_info=True) master.set_state(State.Fault, propagate=2) msg = ("Load sequence of %s failed" % pool_ctrl.name) raise Exception(msg) # PreStartAll on all enabled controllers for pool_ctrl in pool_ctrls: pool_ctrl.ctrl.PreStartAll() # PreStartOne & StartOne on all enabled elements for pool_ctrl in pool_ctrls: ctrl = pool_ctrl.ctrl pool_ctrl_data = pool_ctrls_dict[pool_ctrl] elements = pool_ctrl_data['channels'].keys() timer_monitor = pool_ctrl_data[master_key] # make sure that the timer/monitor is started as the last one elements.remove(timer_monitor) elements.append(timer_monitor) for element in elements: try: channel = channels[element] except KeyError: continue axis = element.axis ret = ctrl.PreStartOne(axis, master_value) if not ret: msg = ("%s.PreStartOne(%d) returns False" % (pool_ctrl.name, axis)) raise Exception(msg) try: ctrl.StartOne(axis, master_value) except Exception, e: self.debug(e, exc_info=True) element.set_state(State.Fault, propagate=2) msg = ("%s.StartOne(%d) failed" % (pool_ctrl.name, axis)) raise Exception(msg)
def start_action(self, ctrls, synch_description, moveable=None, sw_synch_initial_domain=None, *args, **kwargs): """Start synchronization action. :param ctrls: list of enabled trigger/gate controllers :type ctrls: list :param synch_description: synchronization description :type synch_description: :class:`~sardana.pool.poolsynchronization.SynchDescription` :param moveable: (optional) moveable object used as the synchronization source in the Position domain :type moveable: :class:`~sardna.pool.poolmotor.PoolMotor` or :class:`~sardana.pool.poolpseudomotor.PoolPseudoMotor` :param sw_synch_initial_domain: (optional) - initial domain for software synchronizer, can be either :obj:`~sardana.pool.pooldefs.SynchDomain.Time` or :obj:`~sardana.pool.pooldefs.SynchDomain.Position` """ with ActionContext(self): # loads synchronization description for ctrl in ctrls: pool_ctrl = ctrl.element pool_ctrl.ctrl.PreSynchAll() for channel in ctrl.get_channels(enabled=True): axis = channel.axis ret = pool_ctrl.ctrl.PreSynchOne(axis, synch_description) if not ret: msg = ("%s.PreSynchOne(%d) returns False" % (ctrl.name, axis)) raise Exception(msg) pool_ctrl.ctrl.SynchOne(axis, synch_description) pool_ctrl.ctrl.SynchAll() # attaching listener (usually acquisition action) # to the software trigger gate generator if self._listener is not None: if sw_synch_initial_domain is not None: self._synch_soft.initial_domain = sw_synch_initial_domain self._synch_soft.set_configuration(synch_description) self._synch_soft.add_listener(self._listener) remove_acq_listener = partial(self._synch_soft.remove_listener, self._listener) self.add_finish_hook(remove_acq_listener, False) self._synch_soft.add_listener( self.main_element.on_element_changed) remove_mg_listener = partial(self._synch_soft.remove_listener, self.main_element) self.add_finish_hook(remove_mg_listener, False) # subscribing to the position change events to generate events # in position domain if moveable is not None: position = moveable.get_position_attribute() position.add_listener(self._synch_soft) remove_pos_listener = partial(position.remove_listener, self._synch_soft) self.add_finish_hook(remove_pos_listener, False) # start software synchronizer if self._listener is not None: self._synch_soft.start() get_thread_pool().add(self._synch_soft.run) # PreStartAll on all controllers for ctrl in ctrls: pool_ctrl = ctrl.element pool_ctrl.ctrl.PreStartAll() # PreStartOne & StartOne on all elements for ctrl in ctrls: pool_ctrl = ctrl.element for channel in ctrl.get_channels(enabled=True): axis = channel.axis ret = pool_ctrl.ctrl.PreStartOne(axis) if not ret: raise Exception("%s.PreStartOne(%d) returns False" % (pool_ctrl.name, axis)) pool_ctrl.ctrl.StartOne(axis) # set the state of all elements to inform their listeners self._channels = [] for ctrl in ctrls: for channel in ctrl.get_channels(enabled=True): channel.set_state(State.Moving, propagate=2) self._channels.append(channel) # StartAll on all controllers for ctrl in ctrls: pool_ctrl = ctrl.element pool_ctrl.ctrl.StartAll()