def _build_elements(self): self._user_elements = [] self._physical_elements = {} self._physical_elements_set = set() pool = self._get_pool() for user_element_id in self._user_element_ids: # an internal element internal = type(user_element_id) is int if internal: try: user_element = pool.get_element(id=user_element_id) except KeyError: self._pending = True self._user_elements = None self._physical_elements = None self._physical_elements_set = None raise internal = self._is_managed_element(user_element) if not internal: user_element_id = user_element.get_source() # a tango channel or non internal element (ex: ioregister or motor # in measurement group) if not internal: validator = TangoAttributeNameValidator() params = validator.getParams(user_element_id) params['pool'] = self._get_pool() user_element = PoolExternalObject(**params) self.add_user_element(user_element) self._pending = False
def set_configuration_from_user(self, cfg, propagate=1): config = {} user_elements = self.get_user_elements() pool = self.pool timer_name = cfg.get('timer', user_elements[0].full_name) monitor_name = cfg.get('monitor', user_elements[0].full_name) config['timer'] = pool.get_element_by_full_name(timer_name) config['monitor'] = pool.get_element_by_full_name(monitor_name) config['controllers'] = controllers = {} for c_name, c_data in cfg['controllers'].items(): # discard controllers which don't have items (garbage) ch_count = 0 for u_data in c_data['units'].values(): ch_count += len(u_data['channels']) if ch_count == 0: continue external = c_name.startswith('__') if external: ctrl = c_name else: ctrl = pool.get_element_by_full_name(c_name) assert ctrl.get_type() == ElementType.Controller controllers[ctrl] = ctrl_data = {} ctrl_data['units'] = units = {} for u_id, u_data in c_data['units'].items(): # discard units which don't have items (garbage) if len(u_data['channels']) == 0: continue units[u_id] = unit_data = dict(u_data) unit_data['id'] = u_data.get('id', u_id) if not external and ctrl.is_timerable(): unit_data['timer'] = pool.get_element_by_full_name( u_data['timer']) unit_data['monitor'] = pool.get_element_by_full_name( u_data['monitor']) unit_data['trigger_type'] = u_data['trigger_type'] unit_data['channels'] = channels = {} for ch_name, ch_data in u_data['channels'].items(): if external: validator = TangoAttributeNameValidator() params = validator.getParams(ch_data['full_name']) params['pool'] = self.pool channel = PoolExternalObject(**params) else: channel = pool.get_element_by_full_name(ch_name) channels[channel] = dict(ch_data) config['label'] = cfg.get('label', self.name) config['description'] = cfg.get('description', self.DFT_DESC) self.set_configuration(config, propagate=propagate)
def set_configuration_from_user(self, cfg, propagate=1, to_fqdn=True): config = {} user_elements = self.get_user_elements() pool = self.pool timer_name = cfg.get('timer', user_elements[0].full_name) monitor_name = cfg.get('monitor', user_elements[0].full_name) if to_fqdn: timer_name = _to_fqdn(timer_name, logger=self) config['timer'] = pool.get_element_by_full_name(timer_name) if to_fqdn: monitor_name = _to_fqdn(monitor_name, logger=self) config['monitor'] = pool.get_element_by_full_name(monitor_name) config['controllers'] = controllers = {} for c_name, c_data in cfg['controllers'].items(): # backwards compatibility for measurement groups created before # implementing feature-372: # https://sourceforge.net/p/sardana/tickets/372/ # WARNING: this is one direction backwards compatibility - it just # reads channels from the units, but does not write channels to the # units back if 'units' in c_data: c_data = c_data['units']['0'] # discard controllers which don't have items (garbage) ch_count = len(c_data['channels']) if ch_count == 0: continue external = c_name.startswith('__') if external: ctrl = c_name else: if to_fqdn: c_name = _to_fqdn(c_name, logger=self) ctrl = pool.get_element_by_full_name(c_name) assert ctrl.get_type() == ElementType.Controller controllers[ctrl] = ctrl_data = {} # exclude external and not timerable elements if not external and ctrl.is_timerable(): timer_name = c_data['timer'] if to_fqdn: timer_name = _to_fqdn(timer_name, logger=self) timer = pool.get_element_by_full_name(timer_name) ctrl_data['timer'] = timer monitor_name = c_data['monitor'] if to_fqdn: monitor_name = _to_fqdn(monitor_name, logger=self) monitor = pool.get_element_by_full_name(monitor_name) ctrl_data['monitor'] = monitor synchronizer = c_data.get('synchronizer') # for backwards compatibility purposes # protect measurement groups without synchronizer defined if synchronizer is None: synchronizer = 'software' elif synchronizer != 'software': if to_fqdn: synchronizer = _to_fqdn(synchronizer, logger=self) synchronizer = pool.get_element_by_full_name(synchronizer) ctrl_data['synchronizer'] = synchronizer try: synchronization = c_data['synchronization'] except KeyError: # backwards compatibility for configurations before SEP6 synchronization = c_data['trigger_type'] msg = ("trigger_type configuration parameter is deprecated" " in favor of synchronization. Re-apply " "configuration in order to upgrade.") self.warning(msg) ctrl_data['synchronization'] = synchronization ctrl_data['channels'] = channels = {} for ch_name, ch_data in c_data['channels'].items(): if external: validator = TangoAttributeNameValidator() params = validator.getParams(ch_data['full_name']) params['pool'] = self.pool channel = PoolExternalObject(**params) else: if to_fqdn: ch_name = _to_fqdn(ch_name, logger=self) channel = pool.get_element_by_full_name(ch_name) channels[channel] = dict(ch_data) config['label'] = cfg.get('label', self.name) config['description'] = cfg.get('description', self.DFT_DESC) self.set_configuration(config, propagate=propagate, to_fqdn=to_fqdn)
def set_configuration_from_user(self, cfg, to_fqdn=True): """Load measurement configuration from serializable data structure.""" user_elements = self._parent.get_user_elements() if len(user_elements) == 0: # All channels were disabled raise ValueError('The configuration has all the channels disabled') pool = self._parent.pool label = cfg.get('label', self._parent.name) description = cfg.get('description', self.DFT_DESC) timerable_ctrls = { AcqSynch.HardwareGate: [], AcqSynch.HardwareStart: [], AcqSynch.HardwareTrigger: [], AcqSynch.SoftwareStart: [], AcqSynch.SoftwareTrigger: [], AcqSynch.SoftwareGate: [] } zerod_ctrls = [] synch_ctrls = [] other_ctrls = [] master_timer_sw = None master_monitor_sw = None master_timer_sw_start = None master_monitor_sw_start = None master_timer_idx_sw = float("+inf") master_monitor_idx_sw = float("+inf") master_timer_idx_sw_start = float("+inf") master_monitor_idx_sw_start = float("+inf") user_elem_ids = {} channel_acq_synch = {} ctrl_acq_synch = {} user_config = {} user_config['controllers'] = {} user_config['label'] = label user_config['description'] = description for ctrl_name, ctrl_data in cfg['controllers'].items(): # backwards compatibility for measurement groups created before # implementing feature-372: # https://sourceforge.net/p/sardana/tickets/372/ # WARNING: this is one direction backwards compatibility - it just # reads channels from the units, but does not write channels to the # units back if 'units' in ctrl_data: ctrl_data = ctrl_data['units']['0'] # discard controllers which don't have items (garbage) ch_count = len(ctrl_data['channels']) if ch_count == 0: continue external = ctrl_name.startswith('__') if external: ctrl = ctrl_name else: if to_fqdn: ctrl_name = _to_fqdn(ctrl_name, logger=self._parent) ctrl = pool.get_element_by_full_name(ctrl_name) assert ctrl.get_type() == ElementType.Controller user_config['controllers'][ctrl_name] = user_config_ctrl = {} ctrl_conf = {} synchronizer = ctrl_data.get('synchronizer', 'software') conf_synch = None if synchronizer is None or synchronizer == 'software': ctrl_conf['synchronizer'] = 'software' user_config_ctrl['synchronizer'] = 'software' else: if to_fqdn: synchronizer = _to_fqdn(synchronizer, logger=self._parent) user_config_ctrl['synchronizer'] = synchronizer pool_synch = pool.get_element_by_full_name(synchronizer) pool_synch_ctrl = pool_synch.controller conf_synch = SynchronizerConfiguration(pool_synch) conf_synch_ctrl = None if len(synch_ctrls) > 0: conf_synch_ctrl = None for conf_ctrl in synch_ctrls: if pool_synch_ctrl == conf_ctrl.element: conf_synch_ctrl = conf_ctrl if conf_synch_ctrl is None: conf_synch_ctrl = ControllerConfiguration(pool_synch_ctrl) conf_synch_ctrl.add_channel(conf_synch) synch_ctrls.append(conf_synch_ctrl) ctrl_conf['synchronizer'] = conf_synch try: synchronization = ctrl_data['synchronization'] except KeyError: # backwards compatibility for configurations before SEP6 try: synchronization = ctrl_data['trigger_type'] msg = ("trigger_type configuration parameter is deprecated" " in favor of synchronization. Re-apply " "configuration in order to upgrade.") self._parent.warning(msg) except KeyError: synchronization = AcqSynchType.Trigger ctrl_conf['synchronization'] = synchronization user_config_ctrl['synchronization'] = synchronization acq_synch = None if external: ctrl_item = ExternalControllerConfiguration(ctrl) elif ctrl.is_timerable(): is_software = synchronizer == 'software' acq_synch = AcqSynch.from_synch_type(is_software, synchronization) ctrl_acq_synch[ctrl] = acq_synch ctrl_item = TimerableControllerConfiguration(ctrl, ctrl_conf) else: ctrl_item = ControllerConfiguration(ctrl, ctrl_conf) ctrl_enabled = False if 'channels' in ctrl_data: user_config_ctrl['channels'] = user_config_channel = {} for ch_name, ch_data in ctrl_data['channels'].items(): if external: validator = TangoAttributeNameValidator() full_name = ch_data.get('full_name', ch_name) params = validator.getParams(full_name) params['pool'] = pool channel = PoolExternalObject(**params) else: if to_fqdn: ch_name = _to_fqdn(ch_name, logger=self._parent) channel = pool.get_element_by_full_name(ch_name) ch_data = self._fill_channel_data(channel, ch_data) user_config_channel[ch_name] = ch_data ch_item = ChannelConfiguration(channel, ch_data) ch_item.controller = ctrl_item ctrl_item.add_channel(ch_item) if ch_item.enabled: if external: id_ = channel.full_name else: id_ = channel.id user_elem_ids[ch_item.index] = id_ if ch_item.enabled: ctrl_enabled = True if acq_synch is not None: channel_acq_synch[channel] = acq_synch if not external and ctrl.is_timerable(): ctrl_item.update_timer() ctrl_item.update_monitor() user_config_ctrl['timer'] = ctrl_item.timer.full_name user_config_ctrl['monitor'] = ctrl_item.monitor.full_name # Update synchronizer state if conf_synch is not None: conf_synch.enabled = ctrl_enabled ctrl_item.validate() if external: other_ctrls.append(ctrl_item) elif ctrl.is_timerable(): timerable_ctrls[acq_synch].append(ctrl_item) # Find master timer/monitor the system take the channel with # less index if acq_synch in (AcqSynch.SoftwareTrigger, AcqSynch.SoftwareGate): if ctrl_item.timer.index < master_timer_idx_sw: master_timer_sw = ctrl_item.timer master_timer_idx_sw = ctrl_item.timer.index if ctrl_item.monitor.index < master_monitor_idx_sw: master_monitor_sw = ctrl_item.monitor master_monitor_idx_sw = ctrl_item.monitor.index elif acq_synch == AcqSynch.SoftwareStart: if ctrl_item.timer.index < master_timer_idx_sw_start: master_timer_sw_start = ctrl_item.timer master_timer_idx_sw_start = ctrl_item.timer.index if ctrl_item.monitor.index < master_monitor_idx_sw_start: master_monitor_sw_start = ctrl_item.monitor master_monitor_idx_sw_start = ctrl_item.monitor.index elif ctrl.get_ctrl_types()[0] == ElementType.ZeroDExpChannel: zerod_ctrls.append(ctrl_item) # Update synchronizer controller states for conf_synch_ctrl in synch_ctrls: conf_synch_ctrl.update_state() # Fill user configuration with measurement group's timer & monitor # This is a backwards compatibility cause the measurement group's # timer & monitor are not used if master_timer_sw is not None: user_config['timer'] = master_timer_sw.full_name elif master_timer_sw_start is not None: user_config['timer'] = master_timer_sw_start.full_name else: user_config['timer'] = cfg['timer'] if master_monitor_sw is not None: user_config['monitor'] = master_monitor_sw.full_name elif master_monitor_sw_start is not None: user_config['monitor'] = master_monitor_sw_start.full_name else: user_config['monitor'] = cfg['monitor'] # Update internals values self._label = label self._description = description self._timerable_ctrls = timerable_ctrls self._zerod_ctrls = zerod_ctrls self._synch_ctrls = synch_ctrls self._other_ctrls = other_ctrls self._master_timer_sw = master_timer_sw self._master_monitor_sw = master_monitor_sw self._master_timer_sw_start = master_timer_sw_start self._master_monitor_sw_start = master_monitor_sw_start self._user_confg = user_config self._channel_acq_synch = channel_acq_synch self._ctrl_acq_synch = ctrl_acq_synch # sorted ids may not be consecutive (if a channel is disabled) indexes = sorted(user_elem_ids.keys()) user_elem_ids_list = [user_elem_ids[idx] for idx in indexes] for conf_synch_ctrl in synch_ctrls: for conf_synch in conf_synch_ctrl.get_channels(enabled=True): user_elem_ids_list.append(conf_synch.id) self._parent.set_user_element_ids(user_elem_ids_list) self.changed = True