def _activate_hook(self): self.monitor = SystemMonitor(manager=self, name='system_monitor') self.monitor.monitor() if self.gauge_manager: self.info('start gauge scans') self.gauge_manager.start_scans() if self.use_hardware_update and self.switch_manager: do_after(self.hardware_update_period * 1000, self._update_states)
def finish_loading(self): ''' ''' if self.mode != 'client': self.monitor = SystemMonitor(manager=self, name='system_monitor' ) self.monitor.monitor() if self.use_network: p = os.path.join(paths.canvas2D_dir, 'canvas.xml') self.network.load(p)
def finish_loading(self): if self.mode != 'client': self.monitor = SystemMonitor(manager=self, name='system_monitor') self.monitor.monitor() if self.use_network: p = os.path.join(paths.canvas2D_dir, 'canvas.xml') self.network.load(p)
class ExtractionLineManager(Manager, Consoleable): """ Manager for interacting with the extraction line contains reference to valve manager, gauge manager and laser manager """ canvas = Instance(ExtractionLineCanvas) _canvases = List explanation = Instance(ExtractionLineExplanation, ()) monitor = Instance(SystemMonitor) switch_manager = Any gauge_manager = Any multiplexer_manager = Any network = Instance(ExtractionLineGraph) runscript = None learner = None mode = 'normal' _update_status_flag = None _monitoring_valve_status = False valve_state_frequency = Int valve_lock_frequency = Int check_master_owner = Bool use_network = Bool display_volume = Bool volume_key = Str sample_changer = Instance(SampleChanger) link_valve_actuation_dict = Dict canvas_path = File canvas_config_path = File valves_path = File use_hardware_update = Bool hardware_update_period = Float _active = False file_listener = None wait_group = Instance(WaitGroup, ()) console_bgcolor = 'black' def activate(self): self._active = True # need to wait until now to load the ptrackers # this way our canvases are created self.reload_canvas() self._activate_hook() def _activate_hook(self): self.monitor = SystemMonitor(manager=self, name='system_monitor') self.monitor.monitor() if self.gauge_manager: self.info('start gauge scans') self.gauge_manager.start_scans() if self.use_hardware_update and self.switch_manager: do_after(self.hardware_update_period * 1000, self._update_states) def _update_states(self): self.switch_manager.load_hardware_states() do_after(self.hardware_update_period * 1000, self._update_states) def _refresh_canvas(self): self.refresh_canvas() if self._active: do_after(200, self._refresh_canvas) def deactivate(self): if self.gauge_manager: self.gauge_manager.stop_scans() if self.monitor: self.monitor.stop() self._active = False self._deactivate_hook() def _deactivate_hook(self): pass def bind_preferences(self): prefid = 'pychron.extraction_line' attrs = ('canvas_path', 'canvas_config_path', 'valves_path', 'use_hardware_update', 'hardware_update_period', 'check_master_owner', 'use_network') for attr in attrs: try: bind_preference(self, attr, '{}.{}'.format(prefid, attr)) except BaseException, e: print attr, e # bind_preference(self, 'canvas_path', '{}.canvas_path'.format(prefid)) # bind_preference(self, 'canvas_config_path', '{}.canvas_config_path'.format(prefid)) # bind_preference(self, 'valves_path', '{}.valves_path'.format(prefid)) # bind_preference(self, 'use_hardware_update', '{}.use_hardware_update'.format(prefid)) # bind_preference(self, 'hardware_update_period', '{}.hardware_update_period'.format(prefid)) # bind_preference(self, 'check_master_owner', # '{}.check_master_owner'.format(prefid)) # bind_preference(self, 'use_network', # '{}.use_network'.format(prefid)) bind_preference(self.network, 'inherit_state', '{}.inherit_state'.format(prefid)) self.console_bind_preferences('{}.console'.format(prefid)) if self.gauge_manager: bind_preference(self.gauge_manager, 'update_period', '{}.gauge_update_period'.format(prefid)) bind_preference(self.gauge_manager, 'use_update', '{}.use_gauge_update'.format(prefid)) if self.canvas: bind_preference(self.canvas.canvas2D, 'display_volume', '{}.display_volume'.format(prefid)) bind_preference(self.canvas.canvas2D, 'volume_key', '{}.volume_key'.format(prefid))
class ExtractionLineManager(Manager, Consoleable): """ Manager for interacting with the extraction line contains reference to valve manager, gauge manager and laser manager """ canvas = Instance(ExtractionLineCanvas) _canvases = List explanation = Instance(ExtractionLineExplanation, ()) monitor = Instance(SystemMonitor) switch_manager = Any gauge_manager = Any multiplexer_manager = Any network = Instance(ExtractionLineGraph) runscript = None learner = None mode = 'normal' _update_status_flag = None _monitoring_valve_status = False valve_state_frequency = Int valve_lock_frequency = Int check_master_owner = Bool use_network = Bool display_volume = Bool volume_key = Str sample_changer = Instance(SampleChanger) link_valve_actuation_dict = Dict canvas_path = File canvas_config_path = File valves_path = File use_hardware_update = Bool hardware_update_period = Float _active = False file_listener = None wait_group = Instance(WaitGroup, ()) console_bgcolor = 'black' def set_extract_state(self, *args, **kw): pass def activate(self): self._active = True # need to wait until now to load the ptrackers # this way our canvases are created self.reload_canvas() self._activate_hook() def _activate_hook(self): self.monitor = SystemMonitor(manager=self, name='system_monitor') self.monitor.monitor() if self.gauge_manager: self.info('start gauge scans') self.gauge_manager.start_scans() if self.use_hardware_update and self.switch_manager: do_after(self.hardware_update_period * 1000, self._update_states) def _update_states(self): self.switch_manager.load_hardware_states() do_after(self.hardware_update_period * 1000, self._update_states) def _refresh_canvas(self): self.refresh_canvas() if self._active: do_after(200, self._refresh_canvas) def deactivate(self): if self.gauge_manager: self.gauge_manager.stop_scans() if self.monitor: self.monitor.stop() self._active = False self._deactivate_hook() def _deactivate_hook(self): pass def bind_preferences(self): prefid = 'pychron.extraction_line' attrs = ('canvas_path', 'canvas_config_path', 'valves_path', 'use_hardware_update', 'hardware_update_period', 'check_master_owner', 'use_network') for attr in attrs: try: bind_preference(self, attr, '{}.{}'.format(prefid, attr)) except BaseException, e: print attr, e # bind_preference(self, 'canvas_path', '{}.canvas_path'.format(prefid)) # bind_preference(self, 'canvas_config_path', '{}.canvas_config_path'.format(prefid)) # bind_preference(self, 'valves_path', '{}.valves_path'.format(prefid)) # bind_preference(self, 'use_hardware_update', '{}.use_hardware_update'.format(prefid)) # bind_preference(self, 'hardware_update_period', '{}.hardware_update_period'.format(prefid)) # bind_preference(self, 'check_master_owner', # '{}.check_master_owner'.format(prefid)) # bind_preference(self, 'use_network', # '{}.use_network'.format(prefid)) bind_preference(self.network, 'inherit_state', '{}.inherit_state'.format(prefid)) self.console_bind_preferences('{}.console'.format(prefid)) if self.gauge_manager: bind_preference(self.gauge_manager, 'update_period', '{}.gauge_update_period'.format(prefid)) bind_preference(self.gauge_manager, 'use_update', '{}.use_gauge_update'.format(prefid)) if self.canvas: bind_preference(self.canvas.canvas2D, 'display_volume', '{}.display_volume'.format(prefid)) bind_preference(self.canvas.canvas2D, 'volume_key', '{}.volume_key'.format(prefid))
class ExtractionLineManager(Manager, Consoleable): """ Manager for interacting with the extraction line contains 2 interaction canvases, 2D and 3D contains reference to valve manager, gauge manager and laser manager """ canvas = Instance(ExtractionLineCanvas) _canvases = List explanation = Instance(ExtractionLineExplanation, ()) gauge_manager = Instance(Manager) monitor = Instance(SystemMonitor) valve_manager = Any # Instance(Manager) status_monitor = Any multiplexer_manager = Any # Instance(Manager) multruns_report_manager = Any # Instance(Manager) network = Instance(ExtractionLineGraph) # multruns_report_manager = Instance(MultrunsReportManager) # environmental_manager = Instance(Manager) # device_stream_manager = Instance(Manager) # view_controller = Instance(ViewController) # pumping_monitor = Instance(PumpingMonitor) runscript = None learner = None mode = 'normal' use_status_monitor = Bool _update_status_flag = None _monitoring_valve_status = False valve_state_frequency = Int valve_lock_frequency = Int check_master_owner = Bool use_network = Bool display_volume = Bool volume_key = Str sample_changer = Instance(SampleChanger) link_valve_actuation_dict = Dict def bind_preferences(self): bind_preference(self, 'check_master_owner', 'pychron.extraction_line.check_master_owner') bind_preference(self, 'use_network', 'pychron.extraction_line.use_network') bind_preference(self.network, 'inherit_state', 'pychron.extraction_line.inherit_state') # self.console_bind_preferences('pychron.extraction_line') def link_valve_actuation(self, name, func, remove=False): if remove: try: del self.link_valve_actuation_dict[name] except KeyError: self.debug('could not remove "{}". not in dict {}'.format(name, ','.join( self.link_valve_actuation_dict.keys()))) else: self.debug('adding name="{}", func="{}" to link_valve_actuation_dict'.format(name, func.func_name)) self.link_valve_actuation_dict[name] = func def isolate_chamber(self): #get chamber name sc = self._sample_changer_factory() if sc: sc.isolate_chamber() def evacuate_chamber(self): sc = self.sample_changer #confirm evacuation if sample chamber is not (not isolated) # or check for evacuation fails msg = None if sc is None: msg = 'Are you sure you want to evacuate a chamber. No chamber has been isolated' else: err = sc.check_evacuation() if err: name = sc.chamber msg = 'Are you sure you want to evacuate the {} chamber. {}'.format(name, err) if msg: if self.confirmation_dialog(msg): sc = self._sample_changer_factory() if sc: sc.evacuate_chamber() def finish_chamber_change(self): sc = self.sample_changer if sc is None: msg = 'Sample change procedure was not started for any chamber' else: msg = sc.check_finish() if msg: if self.confirmation_dialog('{}. Are sure you want to finish?'.format(msg)): sc = self._sample_changer_factory() if sc: sc.finish_chamber_change() self.sample_changer = None def get_volume(self, node_name): v = 0 if self.use_network: v = self.network.calculate_volumes(node_name)[0][1] return v def test_connection(self): return self.get_valve_states() is not None def refresh_canvas(self): for ci in self._canvases: ci.refresh() def finish_loading(self): if self.mode != 'client': self.monitor = SystemMonitor(manager=self, name='system_monitor') self.monitor.monitor() if self.use_network: p = os.path.join(paths.canvas2D_dir, 'canvas.xml') self.network.load(p) def deactivate(self): self.stop_status_monitor() if self.gauge_manager: self.gauge_manager.stop_scans() if self.monitor: self.monitor.stop() def stop_status_monitor(self): self.info('stopping status monitor') self.status_monitor.stop() def reload_canvas(self, load_states=False): self.reload_scene_graph() net = self.network vm = self.valve_manager if net: p = os.path.join(paths.canvas2D_dir, 'canvas.xml') net.load(p) if net: net.suppress_changes = True vm.load_valve_states(refresh=False, force_network_change=True) vm.load_valve_lock_states(refresh=False) if self.mode == 'client': self.valve_manager.load_valve_owners(refresh=False) if net: net.suppress_changes = False vm.load_valve_states(refresh=False, force_network_change=True) for p in vm.pipette_trackers: self._set_pipette_counts(p.name, p.counts) self.refresh_canvas() def activate(self): self.debug('$$$$$$$$$$$$$$$$$$$$$$$$ EL Activated') if self.mode == 'client': self.start_status_monitor() else: if self.gauge_manager: self.info('start gauge scans') self.gauge_manager.start_scans() self.reload_canvas(load_states=True) # need to wait until now to load the ptrackers # this way our canvases are created for p in self.valve_manager.pipette_trackers: p.load() def start_status_monitor(self): self.info('starting status monitor') self.status_monitor.start(self.valve_manager) def reload_scene_graph(self): self.info('reloading canvas scene') for c in self._canvases: if c is not None: c.load_canvas_file(c.config_name) if self.valve_manager: for k, v in self.valve_manager.valves.iteritems(): vc = c.get_object(k) if vc: vc.soft_lock = v.software_lock vc.state = v.state def update_valve_state(self, name, state, *args, **kw): if self.use_network: self.network.set_valve_state(name, state) for c in self._canvases: self.network.set_canvas_states(c, name) for c in self._canvases: c.update_valve_state(name, state, *args, **kw) def update_valve_lock_state(self, *args, **kw): for c in self._canvases: c.update_valve_lock_state(*args, **kw) def update_valve_owned_state(self, *args, **kw): for c in self._canvases: c.update_valve_owned_state(*args, **kw) def set_valve_owner(self, name, owner): """ set flag indicating if the valve is owned by a system """ if self.valve_manager is not None: self.valve_manager.set_valve_owner(name, owner) def show_valve_properties(self, name): if self.valve_manager is not None: self.valve_manager.show_valve_properties(name) def get_software_lock(self, name, **kw): if self.valve_manager is not None: return self.valve_manager.get_software_lock(name, **kw) def set_software_lock(self, name, lock): if self.valve_manager is not None: if lock: self.valve_manager.lock(name) else: self.valve_manager.unlock(name) description=self.valve_manager.get_valve_by_name(name).description self.info('Valve-{} ({}) {}'.format(name, description, 'lock' if lock else 'unlock'), color='blue' if lock else 'black') self.update_valve_lock_state(name, lock) def get_valve_owners(self): if self.valve_manager is not None: return self.valve_manager.get_owners() def get_valve_lock_states(self): if self.valve_manager is not None: return self.valve_manager.get_software_locks() def get_valve_state(self, name=None, description=None): if self.valve_manager is not None: if description is not None and description.strip(): return self.valve_manager.get_state_by_description(description) else: return self.valve_manager.get_state_by_name(name) def get_valve_states(self): if self.valve_manager is not None: return self.valve_manager.get_states() def get_valve_by_name(self, name): if self.valve_manager is not None: return self.valve_manager.get_valve_by_name(name) def get_valve_names(self): names =[] if self.valve_manager is not None: names = self.valve_manager.get_valve_names() return names def get_pressure(self, controller, name): if self.gauge_manager: return self.gauge_manager.get_pressure(controller, name) def disable_valve(self, description): self._enable_valve(description, False) def enable_valve(self, description): self._enable_valve(description, True) def open_valve(self, name, **kw): return self._open_close_valve(name, 'open', **kw) def close_valve(self, name, **kw): return self._open_close_valve(name, 'close', **kw) def sample(self, name, **kw): def sample(): valve = self.valve_manager.get_valve_by_name(name) if valve is not None: self.info('start sample') self.open_valve(name, **kw) time.sleep(valve.sample_period) self.info('end sample') self.close_valve(name, **kw) t = Thread(target=sample) t.start() def cycle(self, name, **kw): def cycle(): valve = self.valve_manager.get_valve_by_name(name) if valve is not None: n = valve.cycle_n period = valve.cycle_period self.info('start cycle n={} period={}'.format(n, period)) for i in range(n): self.info('valve cycling iteration ={}'.format(i + 1)) self.open_valve(name, **kw) time.sleep(period) self.close_valve(name, **kw) time.sleep(period) t = Thread(target=cycle) t.start() def get_script_state(self, key): return self.pyscript_editor.get_script_state(key) def set_selected_explanation_item(self, obj): if self.explanation: selected = None if obj: selected = next((i for i in self.explanation.explanable_items if obj.name == i.name), None) self.explanation.selected = selected #=============================================================================== # private #=============================================================================== def _log_spec_event(self, name, action): sm = self.application.get_service('pychron.spectrometer.scan_manager.ScanManager') if sm: color = 0x98FF98 if action=='open' else 0xFF9A9A sm.add_spec_event_marker('{} ({})'.format(name, action), mode='valve', extra=name, bgcolor=color) def _enable_valve(self, description, state): if self.valve_manager: valve = self.valve_manager.get_valve_by_description(description) if valve is None: valve = self.valve_manager.get_valve_by_name(description) if valve is not None: if not state: self.close_valve(valve.name) valve.enabled = state def _open_close_valve(self, name, action, description=None, address=None, mode='remote', **kw): vm = self.valve_manager if vm is not None: oname = name if address: name = vm.get_name_by_address(address) if description and description != '---': name = vm.get_name_by_description(description) #check if specified valve is in the valves.xml file if not name: self.warning('Invalid valve name={}, description={}'.format(oname, description)) return False result = self._change_valve_state(name, mode, action, **kw) if result: description=vm.get_valve_by_name(name).description self._log_spec_event(name, action) self.info('{:<6s} Valve-{} ({})'.format(action.upper(), name, description), color='red' if action=='close' else 'green') vm.actuate_children(name, action, mode) ld = self.link_valve_actuation_dict if ld: try: func = ld[name] func(name, action) except KeyError: self.debug('name="{}" not in ' 'link_valve_actuation_dict. keys={}'.format(name, ','.join(ld.keys()))) return result def _change_valve_state(self, name, mode, action, sender_address=None): result, change = False, False if self._check_ownership(name, sender_address): func = getattr(self.valve_manager, '{}_by_name'.format(action)) ret = func(name, mode=mode) if ret: result, change = ret if isinstance(result, bool): if change: self.update_valve_state(name, True if action == 'open' else False) self.refresh_canvas() return result, change def _check_ownership(self, name, requestor): """ check if this valve is owned by another client if this is not a client but you want it to respect valve ownership set check_master_owner=True """ ret = True if self.mode == 'client' or self.check_master_owner: if requestor is None: requestor = gethostbyname(gethostname()) self.debug('checking ownership. requestor={}'.format(requestor)) try: v = self.valve_manager.valves[name] ret = not (v.owner and v.owner != requestor) except KeyError: pass return ret def _set_pipette_counts(self, name, value): for c in self._canvases: scene = c.canvas2D.scene obj = scene.get_item('vlabel_{}Pipette'.format(name)) if obj is not None: obj.value = value c.refresh() def _sample_changer_factory(self): sc = self.sample_changer if sc is None: sc = SampleChanger(manager=self, chamber='CO2') result = sc.edit_traits(view='chamber_select_view') if result: if sc.chamber and sc.chamber != 'None': self.sample_changer = sc return sc def _create_manager(self, klass, manager, params, **kw): # try a lazy load of the required module if 'fusions' in manager: package = 'pychron.managers.laser_managers.{}'.format(manager) self.laser_manager_id = manager elif 'rpc' in manager: package = 'pychron.rpc.manager' else: package = 'pychron.managers.{}'.format(manager) class_factory = self.get_manager_factory(package, klass, warn=False) if class_factory is None: package = 'pychron.extraction_line.{}'.format(manager) class_factory = self.get_manager_factory(package, klass) if class_factory: m = class_factory(**params) if manager in ['gauge_manager', 'valve_manager', 'multiplexer_manager', # 'environmental_manager', 'device_stream_manager', 'multruns_report_manager']: self.trait_set(**{manager: m}) else: self.add_trait(manager, m) return m else: self.debug('could not create manager {}, {},{},{}'.format(klass, manager, params, kw)) #=============================================================================== # handlers #=============================================================================== def _use_status_monitor_changed(self): if self.mode == 'client': if self.use_status_monitor: #start bind_preference(self.status_monitor, 'state_freq', 'pychron.extraction_line.valve_state_frequency') bind_preference(self.status_monitor, 'lock_freq', 'pychron.extraction_line.valve_lock_frequency') bind_preference(self.status_monitor, 'owner_freq', 'pychron.extraction_line.valve_owner_frequency') bind_preference(self.status_monitor, 'update_period', 'pychron.extraction_line.update_period') else: if self.status_monitor.isAlive(): self.status_monitor.stop() def _valve_manager_changed(self): if self.valve_manager is not None: self.status_monitor.valve_manager = self.valve_manager e = self.explanation if e is not None: e.load(self.valve_manager.explanable_items) self.valve_manager.on_trait_change(e.load_item, 'explanable_items[]') @on_trait_change('valve_manager:pipette_trackers:counts') def _update_pipette_counts(self, obj, name, old, new): self._set_pipette_counts(obj.name, new) @on_trait_change('use_network,network:inherit_state') def _update_network(self): from pychron.canvas.canvas2D.scene.primitives.valves import Valve if not self.use_network: for c in self._canvases: scene = c.canvas2D.scene for item in scene.get_items(): if not isinstance(item, Valve): item.active_color = item.default_color else: item.active_color = item.oactive_color else: net = self.network for k, vi in self.valve_manager.valves.iteritems(): net.set_valve_state(k, vi.state) self.reload_canvas() @on_trait_change('display_volume,volume_key') def _update_canvas_inspector(self, name, new): for c in self._canvases: c.canvas2D.trait_set(**{name: new}) #=============================================================================== # defaults #=============================================================================== def _status_monitor_default(self): sm = StatusMonitor(valve_manager=self.valve_manager) return sm def _valve_manager_default(self): from pychron.extraction_line.valve_manager import ValveManager return ValveManager(extraction_line_manager=self) # def _gauge_manager_default(self): # from pychron.extraction_line.gauge_manager import GaugeManager # return GaugeManager() def _explanation_default(self): # ''' # ''' e = ExtractionLineExplanation() if self.valve_manager is not None: e.load(self.valve_manager.explanable_items) self.valve_manager.on_trait_change(e.load_item, 'explanable_items[]') return e def new_canvas(self, name='canvas_config'): c = ExtractionLineCanvas(manager=self, config_name='{}.xml'.format(name)) self._canvases.append(c) c.canvas2D.trait_set(display_volume=self.display_volume, volume_key=self.volume_key) return c def _canvas_default(self): """ """ return self.new_canvas() def _network_default(self): return ExtractionLineGraph()
class ExtractionLineManager(Manager, Consoleable): """ Manager for interacting with the extraction line contains reference to valve manager, gauge manager and laser manager """ canvas = Instance(ExtractionLineCanvas) canvases = List plugin_canvases = List explanation = Instance(ExtractionLineExplanation, ()) monitor = Instance(SystemMonitor) switch_manager = Any gauge_manager = Any cryo_manager = Any multiplexer_manager = Any network = Instance(ExtractionLineGraph) readback_items = List runscript = None learner = None mode = 'normal' valve_state_frequency = Int valve_lock_frequency = Int check_master_owner = Bool use_network = Bool display_volume = Bool volume_key = Str sample_changer = Instance(SampleChanger) link_valve_actuation_dict = Dict canvas_path = File canvas_config_path = File valves_path = File use_hardware_update = Bool hardware_update_period = Float file_listener = None wait_group = Instance(WaitGroup, ()) console_bgcolor = 'black' _active = False _update_status_flag = None _monitoring_valve_status = False def set_extract_state(self, *args, **kw): pass def activate(self): self._active = True self._load_additional_canvases() self._activate_hook() self.reload_canvas() devs = self.application.get_services(ICoreDevice) self.devices = devs def deactivate(self): if self.gauge_manager: self.gauge_manager.stop_scans() if self.monitor: self.monitor.stop() self._active = False self._deactivate_hook() def bind_preferences(self): prefid = 'pychron.extraction_line' attrs = ('canvas_path', 'canvas_config_path', 'valves_path', 'use_hardware_update', 'hardware_update_period', 'check_master_owner', 'use_network') for attr in attrs: try: bind_preference(self, attr, '{}.{}'.format(prefid, attr)) except BaseException as e: print('fffffffff', attr, e) bind_preference(self.network, 'inherit_state', '{}.inherit_state'.format(prefid)) self.console_bind_preferences('{}.console'.format(prefid)) if self.gauge_manager: bind_preference(self.gauge_manager, 'update_period', '{}.gauge_update_period'.format(prefid)) bind_preference(self.gauge_manager, 'use_update', '{}.use_gauge_update'.format(prefid)) if self.canvas: bind_preference(self.canvas.canvas2D, 'display_volume', '{}.display_volume'.format(prefid)) bind_preference(self.canvas.canvas2D, 'volume_key', '{}.volume_key'.format(prefid)) def link_valve_actuation(self, name, func, remove=False): if remove: try: del self.link_valve_actuation_dict[name] except KeyError: self.debug('could not remove "{}". not in dict {}'.format(name, ','.join( list( self.link_valve_actuation_dict.keys())))) else: self.debug('adding name="{}", func="{}" to link_valve_actuation_dict'.format(name, func.__name__)) self.link_valve_actuation_dict[name] = func def enable_auto_reload(self): self.file_listener = fm = FileListener(path=self.canvas_path, callback=self.reload_canvas) def disable_auto_reload(self): if self.file_listener: self.file_listener.stop() def do_sample_loading(self): """ 1. isolate chamber 2. :return: """ sc = self._sample_changer_factory() if sc: if self.confirmation_dialog('Ready to Isolate Chamber'): self._handle_console_message(('===== Isolate Chamber =====', 'maroon')) if not sc.isolate_chamber(): return else: return if self.confirmation_dialog('Ready to Evacuate Chamber'): self._handle_console_message(('===== Evacuate Chamber =====', 'maroon')) err = sc.check_evacuation() if err: name = sc.chamber msg = 'Are you sure you want to evacuate the {} chamber. {}'.format(name, err) if not self.confirmation_dialog(msg): return if not sc.evacuate_chamber(): return else: return if self.confirmation_dialog('Ready to Finish Sample Change'): self._handle_console_message(('===== Finish Sample Change =====', 'maroon')) sc.finish_chamber_change() def get_volume(self, node_name): v = 0 if self.use_network: v = self.network.calculate_volumes(node_name)[0][1] return v def test_cryo_communication(self): self.info('test cryo communication') ret, err = True, '' if self.cryo_manager: if self.cryo_manager.simulation: ret = globalv.communication_simulation else: ret = self.cryo_manager.test_connection() return ret, err def test_gauge_communication(self): self.info('test gauge communication') ret, err = True, '' if self.gauge_manager: if self.gauge_manager.simulation: ret = globalv.communication_simulation else: ret = self.gauge_manager.test_connection() return ret, err def test_connection(self): self.info('test connection') return self.test_valve_communication() def test_valve_communication(self): self.info('test valve communication') ret, err = True, '' if self.switch_manager: if self.switch_manager.simulation: ret = globalv.communication_simulation elif hasattr(self.switch_manager, 'get_state_checksum'): valves = self.switch_manager.switches vkeys = sorted(valves.keys()) state = self.switch_manager.get_state_checksum(vkeys) ret = bool(state) return ret, err def setup_status_monitor(self): self.stop_status_monitor(id(self), block=True) self.start_status_monitor(id(self)) self.refresh_states() def stop_status_monitor(self, *args, **kw): pass def start_status_monitor(self, *args, **kw): pass def refresh_states(self, *args, **kw): pass def refresh_canvas(self): self.debug('refresh canvas') for ci in self.canvases: ci.refresh() def finish_loading(self): if self.use_network: self.network.load(self.canvas_path) def reload_canvas(self): self.debug('reload canvas') self.reload_scene_graph() if self.use_network: self.network.load(self.canvas_path) sm = self.switch_manager if sm: sm.refresh_network() for p in sm.pipette_trackers: p.load() for p in sm.pipette_trackers: self._set_pipette_counts(p.name, p.counts) self._reload_canvas_hook() self.refresh_canvas() def reload_scene_graph(self): self.info('reloading canvas scene') for c in self.canvases: c.load_canvas_file(self.canvas_path, self.canvas_config_path, self.valves_path) # c.load_canvas_file(c.config_name) if self.switch_manager: for k, v in self.switch_manager.switches.items(): vc = c.get_object(k) if vc: vc.soft_lock = v.software_lock vc.state = v.state def update_switch_state(self, name, state, *args, **kw): # self.debug('update switch state {} {} args={} kw={}'.format(name, state, args, kw)) if self.use_network: self.network.set_valve_state(name, state) for c in self.canvases: self.network.set_canvas_states(c, name) for c in self.canvases: c.update_switch_state(name, state, *args, **kw) def update_switch_lock_state(self, *args, **kw): for c in self.canvases: c.update_switch_lock_state(*args, **kw) def update_switch_owned_state(self, *args, **kw): for c in self.canvases: c.update_switch_owned_state(*args, **kw) def set_valve_owner(self, name, owner): """ set flag indicating if the valve is owned by a system """ if self.switch_manager is not None: self.switch_manager.set_valve_owner(name, owner) def show_valve_properties(self, name): if self.switch_manager is not None: self.switch_manager.show_valve_properties(name) def get_software_lock(self, name, **kw): if self.switch_manager is not None: return self.switch_manager.get_software_lock(name, **kw) def set_software_lock(self, name, lock): if self.switch_manager is not None: if lock: self.switch_manager.lock(name) else: self.switch_manager.unlock(name) description = self.switch_manager.get_switch_by_name(name).description self.info('{} ({}) {}'.format(name, description, 'lock' if lock else 'unlock'), color='blue' if lock else 'black') self.update_switch_lock_state(name, lock) def get_state_checksum(self, vkeys): if self.switch_manager is not None: return self.switch_manager.calculate_checksum(vkeys) def get_valve_owners(self): if self.switch_manager is not None: return self.switch_manager.get_owners() def get_locked(self): if self.switch_manager is not None: return self.switch_manager.get_locked() def get_valve_lock_states(self): if self.switch_manager is not None: return self.switch_manager.get_software_locks() def get_valve_state(self, name=None, description=None): if self.switch_manager is not None: if description is not None and description.strip(): return self.switch_manager.get_state_by_description(description) else: return self.switch_manager.get_state_by_name(name) def get_indicator_state(self, name=None, description=None): if self.switch_manager is not None: if description is not None and description.strip(): return self.switch_manager.get_indicator_state_by_description(description) else: return self.switch_manager.get_indicator_state_by_name(name) def get_valve_states(self): if self.switch_manager is not None: # only query valve states if not already doing a # hardware_update via _trigger_update return self.switch_manager.get_states(query=not self.use_hardware_update) def get_valve_by_name(self, name): if self.switch_manager is not None: return self.switch_manager.get_switch_by_name(name) def get_valve_names(self): names = [] if self.switch_manager is not None: names = self.switch_manager.get_valve_names() return names def get_pressure(self, controller, name): if self.gauge_manager: return self.gauge_manager.get_pressure(controller, name) def get_device_value(self, dev_name): dev = self.get_device(dev_name) if dev is None: self.unique_warning('No device named {}'.format(dev_name)) else: return dev.get() def disable_valve(self, description): self._enable_valve(description, False) def enable_valve(self, description): self._enable_valve(description, True) def lock_valve(self, name, **kw): return self._lock_valve(name, True, **kw) def unlock_valve(self, name, **kw): return self._lock_valve(name, False, **kw) def open_valve(self, name, **kw): return self._open_close_valve(name, 'open', **kw) def close_valve(self, name, **kw): return self._open_close_valve(name, 'close', **kw) def sample(self, name, **kw): def sample(): valve = self.switch_manager.get_switch_by_name(name) if valve is not None: self.info('start sample') self.open_valve(name, **kw) time.sleep(valve.sample_period) self.info('end sample') self.close_valve(name, **kw) t = Thread(target=sample) t.start() def cycle(self, name, **kw): def cycle(): valve = self.switch_manager.get_switch_by_name(name) if valve is not None: n = valve.cycle_n period = valve.cycle_period self.info('start cycle n={} period={}'.format(n, period)) for i in range(n): self.info('valve cycling iteration ={}'.format(i + 1)) self.open_valve(name, **kw) time.sleep(period) self.close_valve(name, **kw) time.sleep(period) t = Thread(target=cycle) t.start() def get_script_state(self, key): return self.pyscript_editor.get_script_state(key) def set_selected_explanation_item(self, obj): if self.explanation: selected = None if obj: selected = next((i for i in self.explanation.explanable_items if obj.name == i.name), None) self.explanation.selected = selected def new_canvas(self, config=None): c = ExtractionLineCanvas(manager=self, display_name='Extraction Line') c.load_canvas_file(canvas_config_path=config) self.canvases.append(c) c.canvas2D.trait_set(display_volume=self.display_volume, volume_key=self.volume_key) if self.switch_manager: self.switch_manager.load_valve_states() self.switch_manager.load_valve_lock_states(force=True) self.switch_manager.load_valve_owners() c.refresh() return c def get_wait_control(self): wd = self.wait_group.active_control if wd.is_active(): wd = self.wait_group.add_control() return wd def set_cryo(self, v, v2=None): self.debug('setting cryo to {}, {}'.format(v, v2)) if self.cryo_manager: return self.cryo_manager.set_setpoint(v, v2) else: self.warning('cryo manager not available') return 0, 0 def get_cryo_temp(self, iput): self.debug('get cryo temp {}'.format(iput)) if self.cryo_manager: return self.cryo_manager.read_input(iput) else: self.warning('cryo manager not available') return 0 def set_experiment_type(self, v): self.debug('setting experiment type={}'.format(v)) if self.cryo_manager: self.cryo_manager.species = v # =============================================================================== # private # =============================================================================== def _load_additional_canvases(self): for ci in self.plugin_canvases: c = ExtractionLineCanvas(manager=self, display_name=ci['display_name'], ) c.load_canvas_file(ci['canvas_path'], ci['config_path'], ci['valve_path']) self.canvases.append(c) def _activate_hook(self): self.monitor = SystemMonitor(manager=self, name='system_monitor') self.monitor.monitor() if self.gauge_manager: self.info('start gauge scans') self.gauge_manager.start_scans() if self.switch_manager and self.use_hardware_update: do_after(1000, self._update) def _update(self): if self.use_hardware_update: self.switch_manager.load_hardware_states() do_after(self.hardware_update_period * 1000, self._update) def _deactivate_hook(self): pass def _reload_canvas_hook(self): pass def _log_spec_event(self, name, action): sm = self.application.get_service('pychron.spectrometer.scan_manager.ScanManager') if sm: color = 0x98FF98 if action == 'open' else 0xFF9A9A sm.add_spec_event_marker('{} ({})'.format(name, action), mode='valve', extra=name, bgcolor=color) def _enable_valve(self, description, state): if self.switch_manager: valve = self.switch_manager.get_valve_by_description(description) if valve is None: valve = self.switch_manager.get_switch_by_name(description) if valve is not None: if not state: self.close_valve(valve.name) valve.enabled = state def _lock_valve(self, name, action, description=None, address=None, **kw): """ :param name: :param action: bool True ==lock false ==unlock :param description: :param kw: :return: """ vm = self.switch_manager if vm is not None: oname = name if address: name = vm.get_name_by_address(address) if description and description != '---': name = vm.get_name_by_description(description) if not name: self.warning('Invalid valve name={}, description={}'.format(oname, description)) return False v = vm.get_switch_by_name(name) if action: v.lock() else: v.unlock() self.update_switch_lock_state(name, action) self.refresh_canvas() return True def _open_close_valve(self, name, action, description=None, address=None, mode='remote', **kw): vm = self.switch_manager if vm is not None: oname = name if address: name = vm.get_name_by_address(address) if description and description != '---': name = vm.get_name_by_description(description) # check if specified valve is in the valves.xml file if not name: self.warning('Invalid valve name={}, description={}'.format(oname, description)) return False, False result = self._change_switch_state(name, mode, action, **kw) self.debug('open_close_valve, mode={}'.format(mode)) if mode == 'script': invoke_in_main_thread(self.refresh_canvas) if result: if all(result): valve = vm.get_switch_by_name(name) description = valve.description self._log_spec_event(name, action) self.info('{:<6s} {} ({})'.format(action.upper(), valve.name, description), color='red' if action == 'close' else 'green') vm.actuate_children(name, action, mode) ld = self.link_valve_actuation_dict if ld: try: func = ld[name] func(name, action) except KeyError: self.debug('name="{}" not in ' 'link_valve_actuation_dict. keys={}'.format(name, ','.join(list(ld.keys())))) return result def _change_switch_state(self, name, mode, action, sender_address=None, **kw): result, change = False, False if self._check_ownership(name, sender_address): func = getattr(self.switch_manager, '{}_by_name'.format(action)) ret = func(name, mode=mode, **kw) self.debug('change switch state name={} action={} ret={}'.format(name, action, ret)) if ret: result, change = ret if isinstance(result, bool): if change: self.update_switch_state(name, True if action == 'open' else False) return result, change def _check_ownership(self, name, requestor, force=False): """ check if this valve is owned by another client if this is not a client but you want it to respect valve ownership set check_master_owner=True """ ret = True if force or self.check_master_owner: if requestor is None: requestor = gethostbyname(gethostname()) self.debug('checking ownership. requestor={}'.format(requestor)) try: v = self.switch_manager.switches[name] ret = not (v.owner and v.owner != requestor) except KeyError: pass return ret def _set_pipette_counts(self, name, value): for c in self.canvases: scene = c.canvas2D.scene obj = scene.get_item('vlabel_{}Pipette'.format(name)) if obj is not None: obj.value = int(value) c.refresh() def _sample_changer_factory(self): sc = self.sample_changer if sc is None: sc = SampleChanger(manager=self) if sc.setup(): result = sc.edit_traits(view='chamber_select_view') if result: if sc.chamber and sc.chamber != NULL_STR: self.sample_changer = sc return sc def _create_manager(self, klass, manager, params, **kw): # try a lazy load of the required module # if 'fusions' in manager: # package = 'pychron.managers.laser_managers.{}'.format(manager) # self.laser_manager_id = manager if 'rpc' in manager: package = 'pychron.rpc.manager' else: package = 'pychron.managers.{}'.format(manager) if manager in ('switch_manager', 'gauge_manager', 'multiplexer_manager', 'cryo_manager'): if manager == 'switch_manager': man = self._switch_manager_factory() self.switch_manager = man return man else: return getattr(self, manager) else: class_factory = self.get_manager_factory(package, klass, warn=False) if class_factory is None: package = 'pychron.extraction_line.{}'.format(manager) class_factory = self.get_manager_factory(package, klass) if class_factory: m = class_factory(**params) self.add_trait(manager, m) return m else: self.debug('could not create manager {}, {},{},{}'.format(klass, manager, params, kw)) # =============================================================================== # handlers # =============================================================================== @on_trait_change('use_hardware_update') def _update_use_hardware_update(self): if self.use_hardware_update: self._trigger_update() @on_trait_change('switch_manager:pipette_trackers:counts') def _update_pipette_counts(self, obj, name, old, new): self._set_pipette_counts(obj.name, new) @on_trait_change('use_network,network:inherit_state') def _update_network(self): from pychron.canvas.canvas2D.scene.primitives.valves import Valve if not self.use_network: for c in self.canvases: scene = c.canvas2D.scene for item in scene.get_items(): if not isinstance(item, Valve): item.active_color = item.default_color else: item.active_color = item.oactive_color else: net = self.network if self.switch_manager: for k, vi in self.switch_manager.switches.items(): net.set_valve_state(k, vi.state) self.reload_canvas() @on_trait_change('display_volume,volume_key') def _update_canvas_inspector(self, name, new): for c in self.canvases: c.canvas2D.trait_set(**{name: new}) def _handle_state(self, new): # self.debug('handle state {}'.format(new)) if isinstance(new, tuple): self.update_switch_state(*new) else: # n = len(new) for i, ni in enumerate(new): self.update_switch_state(*ni) # self.update_switch_state(refresh=i == n - 1, *ni) def _handle_lock_state(self, new): self.debug('refresh_lock_state fired. {}'.format(new)) self.update_switch_lock_state(*new) def _handle_owned_state(self, new): self.update_switch_owned_state(*new) def _handle_refresh_canvas(self, new): self.debug('refresh_canvas_needed fired') self.refresh_canvas() def _handle_console_message(self, new): color = None if isinstance(new, tuple): msg, color = new else: msg = new if color is None: color = self.console_default_color if self.console_display: self.console_display.add_text(msg, color=color) # =============================================================================== # defaults # =============================================================================== def _cryo_manager_default(self): from pychron.extraction_line.cryo_manager import CryoManager return CryoManager(application=self.application) def _gauge_manager_default(self): from pychron.extraction_line.gauge_manager import GaugeManager return GaugeManager(application=self.application) def _switch_manager_factory(self): klass = self._get_switch_manager_klass() vm = klass(application=self.application) vm.on_trait_change(self._handle_state, 'refresh_state') vm.on_trait_change(self._handle_lock_state, 'refresh_lock_state') vm.on_trait_change(self._handle_owned_state, 'refresh_owned_state') vm.on_trait_change(self._handle_refresh_canvas, 'refresh_canvas_needed') vm.on_trait_change(self._handle_console_message, 'console_message') return vm def _get_switch_manager_klass(self): from pychron.extraction_line.switch_manager import SwitchManager return SwitchManager def _explanation_default(self): e = ExtractionLineExplanation() if self.switch_manager is not None: e.load(self.switch_manager.explanable_items) self.switch_manager.on_trait_change(e.load_item, 'explanable_items[]') return e def _canvas_default(self): return self.new_canvas() def _network_default(self): return ExtractionLineGraph()
class ExtractionLineManager(Manager, Consoleable): """ Manager for interacting with the extraction line contains reference to valve manager, gauge manager and laser manager """ canvas = Instance(ExtractionLineCanvas) canvases = List plugin_canvases = List explanation = Instance(ExtractionLineExplanation, ()) monitor = Instance(SystemMonitor) switch_manager = Any gauge_manager = Any cryo_manager = Any multiplexer_manager = Any network = Instance(ExtractionLineGraph) readback_items = List runscript = None learner = None mode = 'normal' valve_state_frequency = Int valve_lock_frequency = Int check_master_owner = Bool use_network = Bool display_volume = Bool volume_key = Str sample_changer = Instance(SampleChanger) link_valve_actuation_dict = Dict canvas_path = File canvas_config_path = File valves_path = File use_hardware_update = Bool hardware_update_period = Float file_listener = None wait_group = Instance(WaitGroup, ()) console_bgcolor = 'black' _active = False _update_status_flag = None _monitoring_valve_status = False canvas_editor = Instance(CanvasEditor, ()) def set_extract_state(self, *args, **kw): pass def activate(self): self._active = True self._load_additional_canvases() self._activate_hook() self.reload_canvas() devs = self.application.get_services(ICoreDevice) self.devices = devs def deactivate(self): if self.gauge_manager: self.gauge_manager.stop_scans() if self.monitor: self.monitor.stop() self._active = False self._deactivate_hook() def bind_preferences(self): prefid = 'pychron.extraction_line' attrs = ('canvas_path', 'canvas_config_path', 'valves_path', 'use_hardware_update', 'hardware_update_period', 'check_master_owner', 'use_network') for attr in attrs: try: bind_preference(self, attr, '{}.{}'.format(prefid, attr)) except BaseException as e: print('fffffffff', attr, e) bind_preference(self.network, 'inherit_state', '{}.inherit_state'.format(prefid)) self.console_bind_preferences('{}.console'.format(prefid)) if self.gauge_manager: bind_preference(self.gauge_manager, 'update_period', '{}.gauge_update_period'.format(prefid)) bind_preference(self.gauge_manager, 'use_update', '{}.use_gauge_update'.format(prefid)) if self.canvas: bind_preference(self.canvas.canvas2D, 'display_volume', '{}.display_volume'.format(prefid)) bind_preference(self.canvas.canvas2D, 'volume_key', '{}.volume_key'.format(prefid)) def link_valve_actuation(self, name, func, remove=False): if remove: try: del self.link_valve_actuation_dict[name] except KeyError: self.debug('could not remove "{}". not in dict {}'.format(name, ','.join( list( self.link_valve_actuation_dict.keys())))) else: self.debug('adding name="{}", func="{}" to link_valve_actuation_dict'.format(name, func.__name__)) self.link_valve_actuation_dict[name] = func def enable_auto_reload(self): self.file_listener = fm = FileListener(path=self.canvas_path, callback=self.reload_canvas) def disable_auto_reload(self): if self.file_listener: self.file_listener.stop() def do_sample_loading(self): """ 1. isolate chamber 2. :return: """ sc = self._sample_changer_factory() if sc: if self.confirmation_dialog('Ready to Isolate Chamber'): self._handle_console_message(('===== Isolate Chamber =====', 'maroon')) if not sc.isolate_chamber(): return else: return if self.confirmation_dialog('Ready to Evacuate Chamber'): self._handle_console_message(('===== Evacuate Chamber =====', 'maroon')) err = sc.check_evacuation() if err: name = sc.chamber msg = 'Are you sure you want to evacuate the {} chamber. {}'.format(name, err) if not self.confirmation_dialog(msg): return if not sc.evacuate_chamber(): return else: return if self.confirmation_dialog('Ready to Finish Sample Change'): self._handle_console_message(('===== Finish Sample Change =====', 'maroon')) sc.finish_chamber_change() def get_volume(self, node_name): v = 0 if self.use_network: v = self.network.calculate_volumes(node_name)[0][1] return v def test_cryo_communication(self): self.info('test cryo communication') ret, err = True, '' if self.cryo_manager: if self.cryo_manager.simulation: ret = globalv.communication_simulation else: ret = self.cryo_manager.test_connection() return ret, err def test_gauge_communication(self): self.info('test gauge communication') ret, err = True, '' if self.gauge_manager: if self.gauge_manager.simulation: ret = globalv.communication_simulation else: ret = self.gauge_manager.test_connection() return ret, err def test_connection(self): self.info('test connection') return self.test_valve_communication() def test_valve_communication(self): self.info('test valve communication') ret, err = True, '' if self.switch_manager: if self.switch_manager.simulation: ret = globalv.communication_simulation elif hasattr(self.switch_manager, 'get_state_checksum'): valves = self.switch_manager.switches vkeys = sorted(valves.keys()) state = self.switch_manager.get_state_checksum(vkeys) ret = bool(state) return ret, err def setup_status_monitor(self): self.stop_status_monitor(id(self), block=True) self.start_status_monitor(id(self)) self.refresh_states() def stop_status_monitor(self, *args, **kw): pass def start_status_monitor(self, *args, **kw): pass def refresh_states(self, *args, **kw): pass def refresh_canvas(self): self.debug('refresh canvas') for ci in self.canvases: ci.refresh() def finish_loading(self): if self.use_network: self.network.load(self.canvas_path) def reload_canvas(self): self.debug('reload canvas') self.reload_scene_graph() if self.use_network: self.network.load(self.canvas_path) sm = self.switch_manager if sm: sm.refresh_network() for p in sm.pipette_trackers: p.load() for p in sm.pipette_trackers: self._set_pipette_counts(p.name, p.counts) self._reload_canvas_hook() self.refresh_canvas() def reload_scene_graph(self): self.info('reloading canvas scene') for c in self.canvases: c.load_canvas_file(self.canvas_path, self.canvas_config_path, self.valves_path) self.canvas_editor.load(c.canvas2D, self.canvas_path) # c.load_canvas_file(c.config_name) if self.switch_manager: for k, v in self.switch_manager.switches.items(): vc = c.get_object(k) if vc: vc.soft_lock = v.software_lock vc.state = v.state def update_switch_state(self, name, state, *args, **kw): # self.debug('update switch state {} {} args={} kw={}'.format(name, state, args, kw)) if self.use_network: self.network.set_valve_state(name, state) for c in self.canvases: self.network.set_canvas_states(c, name) for c in self.canvases: c.update_switch_state(name, state, *args, **kw) def update_switch_lock_state(self, *args, **kw): for c in self.canvases: c.update_switch_lock_state(*args, **kw) def update_switch_owned_state(self, *args, **kw): for c in self.canvases: c.update_switch_owned_state(*args, **kw) def set_valve_owner(self, name, owner): """ set flag indicating if the valve is owned by a system """ if self.switch_manager is not None: self.switch_manager.set_valve_owner(name, owner) def show_valve_properties(self, name): if self.switch_manager is not None: self.switch_manager.show_valve_properties(name) def get_software_lock(self, name, **kw): if self.switch_manager is not None: return self.switch_manager.get_software_lock(name, **kw) def set_software_lock(self, name, lock): if self.switch_manager is not None: if lock: self.switch_manager.lock(name) else: self.switch_manager.unlock(name) description = self.switch_manager.get_switch_by_name(name).description self.info('{} ({}) {}'.format(name, description, 'lock' if lock else 'unlock'), color='blue' if lock else 'black') self.update_switch_lock_state(name, lock) def get_state_checksum(self, vkeys): if self.switch_manager is not None: return self.switch_manager.calculate_checksum(vkeys) def get_valve_owners(self): if self.switch_manager is not None: return self.switch_manager.get_owners() def get_locked(self): if self.switch_manager is not None: return self.switch_manager.get_locked() def get_valve_lock_states(self): if self.switch_manager is not None: return self.switch_manager.get_software_locks() def get_valve_state(self, name=None, description=None): if self.switch_manager is not None: if description is not None and description.strip(): return self.switch_manager.get_state_by_description(description) else: return self.switch_manager.get_state_by_name(name) def get_indicator_state(self, name=None, description=None): if self.switch_manager is not None: if description is not None and description.strip(): return self.switch_manager.get_indicator_state_by_description(description) else: return self.switch_manager.get_indicator_state_by_name(name) def get_valve_states(self): if self.switch_manager is not None: # only query valve states if not already doing a # hardware_update via _trigger_update return self.switch_manager.get_states(query=not self.use_hardware_update) def get_state_word(self): if self.switch_manager is not None: # only query valve states if not already doing a # hardware_update via _trigger_update return self.switch_manager.get_states(query=not self.use_hardware_update, version=1) def get_lock_word(self): if self.switch_manager is not None: # only query valve states if not already doing a # hardware_update via _trigger_update return self.switch_manager.get_software_locks(version=1) def get_valve_by_name(self, name): if self.switch_manager is not None: return self.switch_manager.get_switch_by_name(name) def get_valve_names(self): names = [] if self.switch_manager is not None: names = self.switch_manager.get_valve_names() return names def get_pressure(self, controller, name): if self.gauge_manager: return self.gauge_manager.get_pressure(controller, name) def get_device_value(self, dev_name): dev = self.get_device(dev_name) if dev is None: self.unique_warning('No device named {}'.format(dev_name)) else: return dev.get() def disable_valve(self, description): self._enable_valve(description, False) def enable_valve(self, description): self._enable_valve(description, True) def lock_valve(self, name, **kw): return self._lock_valve(name, True, **kw) def unlock_valve(self, name, **kw): return self._lock_valve(name, False, **kw) def open_valve(self, name, **kw): return self._open_close_valve(name, 'open', **kw) def close_valve(self, name, **kw): return self._open_close_valve(name, 'close', **kw) def sample(self, name, **kw): def sample(): valve = self.switch_manager.get_switch_by_name(name) if valve is not None: self.info('start sample') self.open_valve(name, **kw) time.sleep(valve.sample_period) self.info('end sample') self.close_valve(name, **kw) t = Thread(target=sample) t.start() def cycle(self, name, **kw): def cycle(): valve = self.switch_manager.get_switch_by_name(name) if valve is not None: n = valve.cycle_n period = valve.cycle_period self.info('start cycle n={} period={}'.format(n, period)) for i in range(n): self.info('valve cycling iteration ={}'.format(i + 1)) self.open_valve(name, **kw) time.sleep(period) self.close_valve(name, **kw) time.sleep(period) t = Thread(target=cycle) t.start() def get_script_state(self, key): return self.pyscript_editor.get_script_state(key) def set_selected_explanation_item(self, obj): if self.explanation: selected = None if obj: selected = next((i for i in self.explanation.explanable_items if obj.name == i.name), None) self.explanation.selected = selected def new_canvas(self, config=None): c = ExtractionLineCanvas(manager=self, display_name='Extraction Line') c.load_canvas_file(canvas_config_path=config) self.canvases.append(c) c.canvas2D.trait_set(display_volume=self.display_volume, volume_key=self.volume_key) if self.switch_manager: self.switch_manager.load_valve_states() self.switch_manager.load_valve_lock_states(force=True) self.switch_manager.load_valve_owners() c.refresh() return c def get_wait_control(self): wd = self.wait_group.active_control if wd.is_active(): wd = self.wait_group.add_control() return wd def set_cryo(self, v, v2=None): self.debug('setting cryo to {}, {}'.format(v, v2)) if self.cryo_manager: return self.cryo_manager.set_setpoint(v, v2) else: self.warning('cryo manager not available') return 0, 0 def get_cryo_temp(self, iput): self.debug('get cryo temp {}'.format(iput)) if self.cryo_manager: return self.cryo_manager.read_input(iput) else: self.warning('cryo manager not available') return 0 def set_experiment_type(self, v): self.debug('setting experiment type={}'.format(v)) if self.cryo_manager: self.cryo_manager.species = v # =============================================================================== # private # =============================================================================== def _load_additional_canvases(self): for ci in self.plugin_canvases: c = ExtractionLineCanvas(manager=self, display_name=ci['display_name'], ) c.load_canvas_file(ci['canvas_path'], ci['config_path'], ci['valve_path']) self.canvases.append(c) def _activate_hook(self): self.monitor = SystemMonitor(manager=self, name='system_monitor') self.monitor.monitor() if self.gauge_manager: self.info('start gauge scans') self.gauge_manager.start_scans() if self.switch_manager and self.use_hardware_update: do_after(1000, self._update) def _update(self): if self.use_hardware_update: self.switch_manager.load_hardware_states() do_after(self.hardware_update_period * 1000, self._update) def _deactivate_hook(self): pass def _reload_canvas_hook(self): pass def _log_spec_event(self, name, action): sm = self.application.get_service('pychron.spectrometer.scan_manager.ScanManager') if sm: color = 0x98FF98 if action == 'open' else 0xFF9A9A sm.add_spec_event_marker('{} ({})'.format(name, action), mode='valve', extra=name, bgcolor=color) def _enable_valve(self, description, state): if self.switch_manager: valve = self.switch_manager.get_valve_by_description(description) if valve is None: valve = self.switch_manager.get_switch_by_name(description) if valve is not None: if not state: self.close_valve(valve.name) valve.enabled = state def _lock_valve(self, name, action, description=None, address=None, **kw): """ :param name: :param action: bool True ==lock false ==unlock :param description: :param kw: :return: """ vm = self.switch_manager if vm is not None: oname = name if address: name = vm.get_name_by_address(address) if description and description != NULL_STR: name = vm.get_name_by_description(description, name=name) if not name: self.warning('Invalid valve name={}, description={}'.format(oname, description)) return False v = vm.get_switch_by_name(name) if action: v.lock() else: v.unlock() self.update_switch_lock_state(name, action) self.refresh_canvas() return True def _open_close_valve(self, name, action, description=None, address=None, mode='remote', **kw): vm = self.switch_manager if vm is not None: oname = name if address: name = vm.get_name_by_address(address) if description and description != NULL_STR: name = vm.get_name_by_description(description, name) # check if specified valve is in the valves.xml file if not name: self.warning('Invalid valve name={}, description={}'.format(oname, description)) return False, False result = self._change_switch_state(name, mode, action, **kw) self.debug('open_close_valve, mode={}'.format(mode)) if mode == 'script': invoke_in_main_thread(self.refresh_canvas) if result: if all(result): valve = vm.get_switch_by_name(name) description = valve.description self._log_spec_event(name, action) self.info('{:<6s} {} ({})'.format(action.upper(), valve.name, description), color='red' if action == 'close' else 'green') vm.actuate_children(name, action, mode) ld = self.link_valve_actuation_dict if ld: try: func = ld[name] func(name, action) except KeyError: self.debug('name="{}" not in ' 'link_valve_actuation_dict. keys={}'.format(name, ','.join(list(ld.keys())))) return result def _change_switch_state(self, name, mode, action, sender_address=None, **kw): result, change = False, False if self._check_ownership(name, sender_address): func = getattr(self.switch_manager, '{}_by_name'.format(action)) ret = func(name, mode=mode, **kw) self.debug('change switch state name={} action={} ret={}'.format(name, action, ret)) if ret: result, change = ret if isinstance(result, bool): if change: self.update_switch_state(name, True if action == 'open' else False) return result, change def _check_ownership(self, name, requestor, force=False): """ check if this valve is owned by another client if this is not a client but you want it to respect valve ownership set check_master_owner=True """ ret = True if force or self.check_master_owner: if requestor is None: requestor = gethostbyname(gethostname()) self.debug('checking ownership. requestor={}'.format(requestor)) try: v = self.switch_manager.switches[name] ret = not (v.owner and v.owner != requestor) except KeyError: pass return ret def _set_pipette_counts(self, name, value): for c in self.canvases: scene = c.canvas2D.scene obj = scene.get_item('vlabel_{}Pipette'.format(name)) if obj is not None: obj.value = int(value) c.refresh() def _sample_changer_factory(self): sc = self.sample_changer if sc is None: sc = SampleChanger(manager=self) if sc.setup(): result = sc.edit_traits(view='chamber_select_view') if result: if sc.chamber and sc.chamber != NULL_STR: self.sample_changer = sc return sc def _create_manager(self, klass, manager, params, **kw): # try a lazy load of the required module # if 'fusions' in manager: # package = 'pychron.managers.laser_managers.{}'.format(manager) # self.laser_manager_id = manager if 'rpc' in manager: package = 'pychron.rpc.manager' else: package = 'pychron.managers.{}'.format(manager) if manager in ('switch_manager', 'gauge_manager', 'multiplexer_manager', 'cryo_manager'): if manager == 'switch_manager': man = self._switch_manager_factory() self.switch_manager = man return man else: return getattr(self, manager) else: class_factory = self.get_manager_factory(package, klass, warn=False) if class_factory is None: package = 'pychron.extraction_line.{}'.format(manager) class_factory = self.get_manager_factory(package, klass) if class_factory: m = class_factory(**params) self.add_trait(manager, m) return m else: self.debug('could not create manager {}, {},{},{}'.format(klass, manager, params, kw)) # =============================================================================== # handlers # =============================================================================== @on_trait_change('use_hardware_update') def _update_use_hardware_update(self): if self.use_hardware_update: do_after(1000, self._update) @on_trait_change('switch_manager:pipette_trackers:counts') def _update_pipette_counts(self, obj, name, old, new): self._set_pipette_counts(obj.name, new) @on_trait_change('use_network,network:inherit_state') def _update_network(self): from pychron.canvas.canvas2D.scene.primitives.valves import Valve if not self.use_network: for c in self.canvases: scene = c.canvas2D.scene for item in scene.get_items(): if not isinstance(item, Valve): item.active_color = item.default_color else: item.active_color = item.oactive_color else: net = self.network if self.switch_manager: for k, vi in self.switch_manager.switches.items(): net.set_valve_state(k, vi.state) self.reload_canvas() @on_trait_change('display_volume,volume_key') def _update_canvas_inspector(self, name, new): for c in self.canvases: c.canvas2D.trait_set(**{name: new}) def _handle_state(self, new): # self.debug('handle state {}'.format(new)) if isinstance(new, tuple): self.update_switch_state(*new) else: # n = len(new) for i, ni in enumerate(new): self.update_switch_state(*ni) # self.update_switch_state(refresh=i == n - 1, *ni) def _handle_lock_state(self, new): self.debug('refresh_lock_state fired. {}'.format(new)) self.update_switch_lock_state(*new) def _handle_owned_state(self, new): self.update_switch_owned_state(*new) def _handle_refresh_canvas(self, new): self.debug('refresh_canvas_needed fired') self.refresh_canvas() def _handle_console_message(self, new): color = None if isinstance(new, tuple): msg, color = new else: msg = new if color is None: color = self.console_default_color if self.console_display: self.console_display.add_text(msg, color=color) # =============================================================================== # defaults # =============================================================================== def _cryo_manager_default(self): from pychron.extraction_line.cryo_manager import CryoManager return CryoManager(application=self.application) def _gauge_manager_default(self): from pychron.extraction_line.gauge_manager import GaugeManager return GaugeManager(application=self.application) def _switch_manager_factory(self): klass = self._get_switch_manager_klass() vm = klass(application=self.application) vm.on_trait_change(self._handle_state, 'refresh_state') vm.on_trait_change(self._handle_lock_state, 'refresh_lock_state') vm.on_trait_change(self._handle_owned_state, 'refresh_owned_state') vm.on_trait_change(self._handle_refresh_canvas, 'refresh_canvas_needed') vm.on_trait_change(self._handle_console_message, 'console_message') return vm def _get_switch_manager_klass(self): from pychron.extraction_line.switch_manager import SwitchManager return SwitchManager def _explanation_default(self): e = ExtractionLineExplanation() if self.switch_manager is not None: e.load(self.switch_manager.switches) self.switch_manager.on_trait_change(e.refresh, 'refresh_explanation') return e def _canvas_default(self): return self.new_canvas() def _network_default(self): return ExtractionLineGraph()
class ExtractionLineManager(Manager): ''' Manager for interacting with the extraction line contains 2 interaction canvases, 2D and 3D contains reference to valve manager, gauge manager and laser manager ''' canvas = Instance(ExtractionLineCanvas) _canvases = List explanation = Instance(ExtractionLineExplanation, ()) gauge_manager = Instance(Manager) monitor = Instance(SystemMonitor) valve_manager = Any # Instance(Manager) status_monitor = Any multiplexer_manager = Any # Instance(Manager) multruns_report_manager = Any # Instance(Manager) network = Instance(ExtractionLineGraph) # multruns_report_manager = Instance(MultrunsReportManager) # environmental_manager = Instance(Manager) # device_stream_manager = Instance(Manager) # view_controller = Instance(ViewController) # pumping_monitor = Instance(PumpingMonitor) runscript = None learner = None mode = 'normal' _update_status_flag = None _monitoring_valve_status = False _valve_state_frequency = 3 _valve_lock_frequency = 10 check_master_owner = Bool use_network = Bool display_volume = Bool volume_key = Str sample_changer = Instance(SampleChanger) def _sample_changer_factory(self): sc = self.sample_changer if sc is None: sc = SampleChanger(manager=self, chamber='CO2') result = 1 result = sc.edit_traits(view='chamber_select_view') if result: if sc.chamber and sc.chamber != 'None': self.sample_changer = sc return sc def isolate_chamber(self): #get chamber name sc = self._sample_changer_factory() if sc: sc.isolate_chamber() def evacuate_chamber(self): sc = self.sample_changer #confirm evacuation if sample chamber is not (not isolated) # or check for evacuation fails msg = None if sc is None: msg = 'Are you sure you want to evacuate a chamber. No chamber has been isolated' else: err = sc.check_evacuation() if err: name = sc.chamber msg = 'Are you sure you want to evacuate the {} chamber. {}'.format(name, err) if msg: if self.confirmation_dialog(msg): sc = self._sample_changer_factory() if sc: sc.evacuate_chamber() def finish_chamber_change(self): sc = self.sample_changer if sc is None: msg = 'Sample change procedure was not started for any chamber' else: msg = sc.check_finish() if msg: if self.confirmation_dialog('{}. Are sure you want to finish?'.format(msg)): sc = self._sample_changer_factory() if sc: sc.finish_chamber_change() self.sample_changer = None def get_volume(self, node_name): v = 0 if self.use_network: v = self.network.calculate_volumes(node_name)[0][1] return v def test_connection(self): return self.get_valve_states() is not None def get_subsystem_module(self, subsystem, module): ''' ''' try: ss = getattr(self, subsystem) return ss.get_module(module) except AttributeError: self.warning('{} not initialized'.format(subsystem)) def _create_manager(self, klass, manager, params, **kw): #gdict = globals() #if klass in gdict: # class_factory = gdict[klass] #else: # try a lazy load of the required module if 'fusions' in manager: package = 'pychron.managers.laser_managers.{}'.format(manager) self.laser_manager_id = manager elif 'rpc' in manager: package = 'pychron.rpc.manager' else: package = 'pychron.managers.{}'.format(manager) class_factory = self.get_manager_factory(package, klass, warn=False) if class_factory is None: package = 'pychron.extraction_line.{}'.format(manager) class_factory = self.get_manager_factory(package, klass) if class_factory: # params['application'] = self.application m = class_factory(**params) if manager in ['gauge_manager', 'valve_manager', 'multiplexer_manager', # 'environmental_manager', 'device_stream_manager', 'multruns_report_manager', ]: self.trait_set(**{manager: m}) else: self.add_trait(manager, m) # m.exit_on_close = False return m else: self.debug('could not create manager {}, {},{},{}'.format(klass, manager, params, kw)) def refresh_canvas(self): for ci in self._canvases: ci.refresh() def finish_loading(self): ''' ''' if self.mode != 'client': self.monitor = SystemMonitor(manager=self, name='system_monitor' ) self.monitor.monitor() if self.use_network: p = os.path.join(paths.canvas2D_dir, 'canvas.xml') self.network.load(p) def deactivate(self): self.stop_status_monitor() if self.gauge_manager: self.gauge_manager.stop_scans() if self.monitor: self.monitor.stop() def stop_status_monitor(self): self.info('stopping status monitor') self.status_monitor.stop() def reload_canvas(self, load_states=False): self.reload_scene_graph() net = self.network vm = self.valve_manager if net: p = os.path.join(paths.canvas2D_dir, 'canvas.xml') net.load(p) if net: net.suppress_changes = True vm.load_valve_states(refresh=False, force_network_change=True) vm.load_valve_lock_states(refresh=False) if self.mode == 'client': self.valve_manager.load_valve_owners(refresh=False) if net: net.suppress_changes = False vm.load_valve_states(refresh=False, force_network_change=True) for p in vm.pipette_trackers: self._set_pipette_counts(p.name, p.counts) self.refresh_canvas() def activate(self): # p = os.path.join(paths.hidden_dir, 'show_explanantion') # if os.path.isfile(p): # with open(p, 'rb') as f: # try: # self.show_explanation = pickle.load(f) # except pickle.PickleError: # pass self.debug('$$$$$$$$$$$$$$$$$$$$$$$$ EL Activated') if self.mode == 'client': self.start_status_monitor() else: if self.gauge_manager: self.info('start gauge scans') self.gauge_manager.start_scans() self.reload_canvas(load_states=True) # need to wait until now to load the ptrackers # this way our canvases are created for p in self.valve_manager.pipette_trackers: p.load() def start_status_monitor(self): self.info('starting status monitor') # return # self.info('starting status monitor NOT') self.status_monitor.start() def bind_preferences(self): from apptools.preferences.preference_binding import bind_preference bind_preference(self, 'check_master_owner', 'pychron.extraction_line.check_master_owner') bind_preference(self, 'use_network', 'pychron.extraction_line.use_network') bind_preference(self.network, 'inherit_state', 'pychron.extraction_line.inherit_state') bind_preference(self, 'display_volume', 'pychron.extraction_line.display_volume') bind_preference(self, 'volume_key', 'pychron.extraction_line.volume_key') # bind_preference(self, 'enable_close_after', 'pychron.extraction_line.enable_close_after') # bind_preference(self, 'close_after_minutes', 'pychron.extraction_line.close_after') # from pychron.extraction_line.plugins.extraction_line_preferences_page import get_valve_group_names def reload_scene_graph(self): self.info('reloading canvas scene') for c in self._canvases: if c is not None: c.load_canvas_file(c.config_name) # # load state if self.valve_manager: for k, v in self.valve_manager.valves.iteritems(): vc = c.get_object(k) if vc: vc.soft_lock = v.software_lock vc.state = v.state # def load_canvas(self): # ''' # ''' # p = self._file_dialog_('open', **dict(default_dir=paths.canvas2D_dir)) # # if p is not None: # self.canvas.load_canvas(p) # def set_canvas_size(self, width=None, height=None): # self.canvas.set_size(width, height) # def pressure_update(self, o, oo, n): # ''' # on_trait_change handler for gauge_manager.gauges.pressure # # ''' # if self.canvas: # self.canvas.update_pressure(o.name, n, o.state) def update_valve_state(self, name, state, *args, **kw): if self.use_network: self.network.set_valve_state(name, state) for c in self._canvases: self.network.set_canvas_states(c, name) for c in self._canvases: c.update_valve_state(name, state, *args, **kw) def update_valve_lock_state(self, *args, **kw): for c in self._canvases: c.update_valve_lock_state(*args, **kw) def update_valve_owned_state(self, *args, **kw): for c in self._canvases: c.update_valve_owned_state(*args, **kw) def set_valve_owner(self, name, owner): ''' set flag indicating if the valve is owned by a system ''' if self.valve_manager is not None: self.valve_manager.set_valve_owner(name, owner) # def show_valve_properties(self, name): if self.valve_manager is not None: self.valve_manager.show_valve_properties(name) def get_software_lock(self, name, **kw): if self.valve_manager is not None: return self.valve_manager.get_software_lock(name, **kw) def set_software_lock(self, name, lock): if self.valve_manager is not None: if lock: self.valve_manager.lock(name) else: self.valve_manager.unlock(name) self.update_valve_lock_state(name, lock) def get_valve_owners(self): if self.valve_manager is not None: return self.valve_manager.get_owners() def get_valve_lock_states(self): if self.valve_manager is not None: return self.valve_manager.get_software_locks() def get_valve_state(self, name=None, description=None): if self.valve_manager is not None: if description is not None and description.strip(): return self.valve_manager.get_state_by_description(description) else: return self.valve_manager.get_state_by_name(name) def get_valve_states(self): if self.valve_manager is not None: return self.valve_manager.get_states() def get_valve_by_name(self, name): if self.valve_manager is not None: return self.valve_manager.get_valve_by_name(name) def get_pressure(self, controller, name): if self.gauge_manager: return self.gauge_manager.get_pressure(controller, name) def disable_valve(self, description): self._enable_valve(description, False) def enable_valve(self, description): self._enable_valve(description, True) def open_valve(self, name, **kw): ''' ''' return self._open_close_valve(name, 'open', **kw) def close_valve(self, name, **kw): ''' ''' return self._open_close_valve(name, 'close', **kw) def sample(self, name, **kw): def sample(): valve = self.valve_manager.get_valve_by_name(name) if valve is not None: self.info('start sample') self.open_valve(name, **kw) time.sleep(valve.sample_period) self.info('end sample') self.close_valve(name, **kw) t = Thread(target=sample) t.start() def cycle(self, name, **kw): def cycle(): valve = self.valve_manager.get_valve_by_name(name) if valve is not None: n = valve.cycle_n period = valve.cycle_period self.info('start cycle n={} period={}'.format(n, period)) for i in range(n): self.info('valve cycling iteration ={}'.format(i + 1)) self.open_valve(name, **kw) time.sleep(period) self.close_valve(name, **kw) time.sleep(period) t = Thread(target=cycle) t.start() def get_script_state(self, key): return self.pyscript_editor.get_script_state(key) def set_selected_explanation_item(self, obj): if self.explanation: selected = None if obj: selected = next((i for i in self.explanation.explanable_items if obj.name == i.name), None) self.explanation.selected = selected #=============================================================================== # private #=============================================================================== def _enable_valve(self, description, state): if self.valve_manager: valve = self.valve_manager.get_valve_by_description(description) if valve is None: valve = self.valve_manager.get_valve_by_name(description) if valve is not None: if not state: self.close_valve(valve.name) valve.enabled = state def _open_close_valve(self, name, action, description=None, address=None, mode='remote', **kw): vm = self.valve_manager if vm is not None: if address: name = vm.get_name_by_address(address) if description and description != '---': name = vm.get_name_by_description(description) result = self._change_valve_state(name, mode, action, **kw) # if self.learner: # self.learner.open_close_valve(name, action, result) return result def _change_valve_state(self, name, mode, action, sender_address=None): result, change = False, False if self._check_ownership(name, sender_address): func = getattr(self.valve_manager, '{}_by_name'.format(action)) ret = func(name, mode=mode) if ret: result, change = ret if isinstance(result, bool): if change: self.update_valve_state(name, True if action == 'open' else False) self.refresh_canvas() return result, change def _check_ownership(self, name, requestor): """ check if this valve is owned by another client if this is not a client but you want it to respect valve ownership set check_master_owner=True """ if self.mode == 'client' or self.check_master_owner: if requestor is None: requestor = gethostbyname(gethostname()) self.debug('checking ownership. requestor={}'.format(requestor)) if name in self.valve_manager.valves: v = self.valve_manager.valves[name] return not (v.owner and v.owner != requestor) return True #=============================================================================== # handlers #=============================================================================== def _valve_manager_changed(self): if self.valve_manager is not None: self.status_monitor.valve_manager = self.valve_manager e = self.explanation if e is not None: e.load(self.valve_manager.explanable_items) self.valve_manager.on_trait_change(e.load_item, 'explanable_items[]') @on_trait_change('valve_manager:pipette_trackers:counts') def _update_pipette_counts(self, obj, name, old, new): self._set_pipette_counts(obj.name, new) def _set_pipette_counts(self, name, value): for c in self._canvases: scene = c.canvas2D.scene obj = scene.get_item('vlabel_{}Pipette'.format(name)) if obj is not None: obj.value = value c.refresh() @on_trait_change('use_network,network:inherit_state') def _update_network(self): from pychron.canvas.canvas2D.scene.primitives.valves import Valve if not self.use_network: for c in self._canvases: scene = c.canvas2D.scene for item in scene.get_items(): if not isinstance(item, Valve): item.active_color = item.default_color else: item.active_color = item.oactive_color else: net = self.network for k, vi in self.valve_manager.valves.iteritems(): net.set_valve_state(k, vi.state) self.reload_canvas() @on_trait_change('display_volume,volume_key') def _update_canvas_inspector(self, name, new): for c in self._canvases: c.canvas2D.trait_set(**{name: new}) #=============================================================================== # defaults #=============================================================================== # return self._view_controller_factory() # def _pyscript_editor_default(self): # return PyScriptManager(parent=self) def _status_monitor_default(self): sm = StatusMonitor(valve_manager=self.valve_manager, state_freq=self._valve_state_frequency, lock_freq=self._valve_lock_frequency) return sm def _valve_manager_default(self): from pychron.extraction_line.valve_manager import ValveManager return ValveManager(extraction_line_manager=self) # def _gauge_manager_default(self): # from pychron.extraction_line.gauge_manager import GaugeManager # return GaugeManager() def _explanation_default(self): # ''' # ''' e = ExtractionLineExplanation() if self.valve_manager is not None: e.load(self.valve_manager.explanable_items) self.valve_manager.on_trait_change(e.load_item, 'explanable_items[]') return e def new_canvas(self, name='canvas_config'): c = ExtractionLineCanvas(manager=self, config_name='{}.xml'.format(name), # path_name='{}.xml'.format(name) ) self._canvases.append(c) c.canvas2D.trait_set(display_volume=self.display_volume, volume_key=self.volume_key) return c def _canvas_default(self): ''' ''' return self.new_canvas() def _network_default(self): return ExtractionLineGraph()