def __init__(self): """ Instantiates Launcher object Parses commandline arguments, connects to logger, loads script config dictionary, scans available servers """ # Get command line arguments as a dict self.args = parse_args() self.name = self.args['script'] self.config = self.args['config'] self.log_ip = self.args['logip'] self.log_port = int(self.args['logport']) self.debug = int(self.args['debug']) self.lab_name = self.args['lab_name'] self.server_debug = int(self.args['server_debug']) self.num_clients = int(self.args['num_clients']) # Connect to logger self.logger = self._connect_to_logger() # Load config self.config_dict = load_script_config(script=self.name, config=self.config, logger=self.logger) if self.debug == 1: import ptvsd import os # 5678 is the default attach port in the VS Code debug configurations self.logger.info( f"Waiting for debugger to attach to PID {os.getpid()} (launcher)" ) ptvsd.enable_attach(address=('localhost', 5678)) ptvsd.wait_for_attach() breakpoint() # Register new exception hook. def log_exceptions(exc_type, exc_value, exc_traceback): """Handler for unhandled exceptions that will write to the logs""" error_msg = ''.join( traceback.format_exception(exc_type, exc_value, exc_traceback)) self.logger.error(f"Uncaught exception: {error_msg}") self.client_dict = self.logger.get_client_data() sys.excepthook = log_exceptions # Connectors are LogClients connected to the current LogServer # Find all servers with port numbers and store them as a dictionary self.connectors = {} self._scan_servers() # Containers for clients that servers that this launcher creates / connects to self.clients = {} # Script server self.script_server_port = None self.script_server = None self.service = None
def _launch_servers(self): """ Searches through active servers and connects/launches them """ for server in self.config_dict['servers']: module_name = server['type'] if "script" in server and server["script"] == "True": server_config = load_script_config(module_name, server['config'], self.logger) else: server_config = load_device_config(module_name, server['config'], self.logger) matches = [] for connector in self.connectors.values(): # Add servers that have the correct name and ID if (connector.name.startswith(module_name)) and ( server_config['device_id'] == connector.device_id): matches.append(connector) if 'auto_connect' in server and server['auto_connect'] == 'False': auto_connect = False else: auto_connect = True self._connect_matched_servers(matches, module_name, server['config'], server_config, auto_connect)
def __init__(self, config=None, host=None, port=None, staticlines=None): QMainWindow.__init__(self) self.config = load_script_config('staticline', config, logger=None) self.N_staticlines = len(self.config['lines']) self.widgets = dict() self.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5()) #self.setMinimumSize(QSize(640, 480)) self.setWindowTitle("Staticline window") self.centralWidget = QWidget(self) self.setCentralWidget(self.centralWidget) self.gridLayout = QGridLayout(self) self.centralWidget.setLayout(self.gridLayout) self.blockgridLayout = [] # Add IP info self.host = host self.port = port self.blockgridLayout.append(QHBoxLayout(self)) self.gridLayout.addLayout(self.blockgridLayout[0], 0, 1) self.ip_label = QtWidgets.QLabel(f"IP Address: {host}") self.port_label = QtWidgets.QLabel(f"Port: {port}") self.blockgridLayout[0].addWidget(self.ip_label) self.blockgridLayout[0].addWidget(self.port_label) self.staticlines = staticlines self.unpack_config_file()
def launch(**kwargs): """ Launches the WLM monitor + lock script """ logger = kwargs['logger'] clients = kwargs['clients'] config = load_script_config(script='laser_stabilizer', config=kwargs['config'], logger=logger) for server in config['servers']: if 'name' in server: if server['name'] == 'input': ai_client = find_client(clients=clients, settings=config, client_type=server['type'], client_config=server['config'], logger=logger) if server['name'] == 'output': ao_client = find_client(clients=clients, settings=config, client_type=server['type'], client_config=server['config'], logger=logger) if server['type'] == 'zi_hdawg': hd = find_client(clients=clients, settings=config, client_type='zi_hdawg', client_config=server['config'], logger=logger) if config['check_aom'] == "True": check_aom = True else: check_aom = False # Instantiate Monitor script laser_stabilizer = LaserStabilizer(config=config, ao_client=ao_client, ai_client=ai_client, hd=hd, check_aom=check_aom, logger=logger) update_service = Service() update_service.assign_module(module=laser_stabilizer) update_service.assign_logger(logger=logger) update_server, update_port = create_server(update_service, logger, host=get_ip()) logger.update_data(data={'port': update_port}) laser_stabilizer.gui.set_network_info(port=update_port) update_server.start() # Run continuously # Note that the actual operation inside run() can be paused using the update server while True: laser_stabilizer.run()
def launch(**kwargs): logger = kwargs['logger'] clients = kwargs['clients'] config = load_script_config(script='filterwheel', config=kwargs['config'], logger=logger) filterwheel1 = find_client(logger=logger, settings=config, clients=clients, client_type="fw102c", client_config='toptica_filterwheel1') filterwheel2 = find_client(logger=logger, settings=config, clients=clients, client_type="fw102c", client_config='toptica_filterwheel2') # Instantiate Monitor script toptica_controller = TopticaFilterWheelController( filterwheel1=filterwheel1, filterwheel2=filterwheel2, logger=logger, port=kwargs['server_port']) toptica_controller.gui.app.exec_()
def launch(**kwargs): logger = kwargs['logger'] clients = kwargs['clients'] config = load_script_config(script='toptica_control', config=kwargs['config'], logger=logger) dlc_client = find_client(clients=clients, settings=config, client_type='toptica_dlc_pro') # Instantiate Monitor script toptica_controller = Controller(dlc_client, logger=logger, port=kwargs['server_port']) # Run continuously # Note that the actual operation inside run() can be paused using the update server start_time = time.time() check_interval = 1 while True: if time.time() - start_time < check_interval: toptica_controller.run() else: toptica_controller.run(check_vals=True) start_time = time.time()
def __init__(self, config, staticline_clients=None, logger_client=None, host=None, port=None): self.log = LogHandler(logger=logger_client) self.config = config self.host = host self.port = port self.config_dict = load_script_config('staticline', config, logger=self.log) self.initialize_drivers(staticline_clients, logger_client)
def __init__(self, ctr_client: si_tt.Client, ui='count_monitor', logger_client=None, server_port=None, combined_channel=False, config=None): """ Constructor for CountMonitor script :param ctr_client: instance of hardware client for counter :param gui_client: (optional) instance of client of desired output GUI :param logger_client: (obj) instance of logger client. :param server_port: (int) port number of script server :combined_channel: (bool) If true, show additional trace with summed counts. """ self._ctr = ctr_client self.log = logger_client self.combined_channel = combined_channel self._bin_width = None self._n_bins = None self._ch_list = None self._plot_list = None # List of channels to assign to each plot (e.g. [[1,2], [3,4]]) self._plots_assigned = [ ] # List of plots on the GUI that have been assigned if self.combined_channel: ui = 'count_monitor_combined' else: ui = 'count_monitor' # Instantiate GUI window self.gui = Window(gui_template=ui, host=get_ip(), port=server_port) # Setup stylesheet. self.gui.apply_stylesheet() if self.combined_channel: num_plots = 3 else: num_plots = 2 # Get all GUI widgets self.widgets = get_gui_widgets(self.gui, graph_widget=num_plots, number_label=8, event_button=num_plots, legend_widget=num_plots) # Load config self.config = {} if config is not None: self.config = load_script_config(script='monitor_counts', config=config, logger=self.logger_client) if not 'name' in self.config: self.config.update({'name': f'monitor{np.random.randint(1000)}'})
def launch(**kwargs): """ Launches the WLM monitor + lock script """ logger = kwargs['logger'] config = load_script_config( script='wlm_monitor', config=kwargs['config'], logger=logger ) # TODO: Generalize this for n lasers. if config['num_lasers'] == 3: three_lasers = True else: three_lasers = False device_id = config['device_id'] wavemeter_client = find_client( clients=kwargs['clients'], settings=config, client_type='high_finesse_ws7', logger=logger ) # Get list of ao client names ao_clients = {} for channel in config['channels'].values(): client_name = channel['ao']['client'] device_config = channel['ao']['config'] ao_clients[(client_name, device_config)] = find_client( kwargs['clients'], config, client_name, client_config=device_config, logger=logger ) channel_params = [p for p in config['channels'].values()] params = dict(channel_params=channel_params) # Instantiate Monitor script wlm_monitor = WlmMonitor( wlm_client=wavemeter_client, ao_clients=ao_clients, logger_client=logger, params=params, three_lasers=three_lasers ) update_service = kwargs['service'] update_service.assign_module(module=wlm_monitor) logger.update_data(data=dict(device_id=device_id)) wlm_monitor.gui.set_network_info(port=kwargs['server_port']) # Run continuously # Note that the actual operation inside run() can be paused using the update server while True: wlm_monitor.run()
def launch(**kwargs): logger = kwargs['logger'] clients = kwargs['clients'] config = load_script_config(script='thorlabs_pm320e', config=kwargs['config'], logger=logger) powermeter = find_client(clients=clients, settings=config, client_type='thorlabs_pm320e') pol_paddle = find_client(clients=clients, settings=config, client_type='thorlabs_mpc320')
def launch(**kwargs): config = load_script_config(script='data_taker', config=kwargs['config'], logger=kwargs['logger']) # Instantiate Monitor script control = DataTaker(logger=kwargs['logger'], client_tuples=kwargs['clients'], config=config, config_name=kwargs['config']) control.gui.set_network_info(port=kwargs['server_port']) # Run continuously control.gui.app.exec_()
def launch(**kwargs): logger = kwargs['logger'] clients = kwargs['clients'] config = load_script_config(script='m2_laserscan', config=kwargs['config'], logger=logger) channel, ip, port, log_tcp = config['channel'], config['ip'], config[ 'port'], config["log_tcp_packets"] wavemeter_client = find_client(clients=clients, settings=config, client_type='high_finesse_ws7', logger=logger) server = MSquaredWMServer(ip, port, channel, logger, wavemeter_client, log_tcp) server.start()
def launch(**kwargs): """ Launches the full nanopositioner control + GUI script """ # Unpack and assign parameters logger = kwargs['logger'] clients = kwargs['clients'] config = load_script_config(script='mcs2_anc300_control', config=kwargs['config'], logger=logger) nanopos_client = find_client(clients=clients, settings=config, client_type='mcs2') attocube_client = find_client(clients=clients, settings=config, client_type='anc300') gui_client = 'positioner_control_mixed' # Instantiate controller control = Controller(nanopos_client, attocube_client, gui_client, logger, config=kwargs['config'], port=kwargs['server_port']) # Initialize parameters for channel_index in range(control.NUM_CHANNELS): params = control.get_GUI_parameters(channel_index) control.initialize_parameters(channel_index, params) try: control.load_settings() except Exception as e: logger.warn(e) logger.warn('Failed to load settings from config file') control.gui.app.exec_() # Mitigate warnings about unused variables if loghost and logport and params: pass
def launch(**kwargs): """ Launches the full fiber controll + GUI script """ # Unpack and assign parameters logger = kwargs['logger'] clients = kwargs['clients'] logport = kwargs['logport'] # Unpack settings settings = load_script_config('power_monitor', kwargs['config'], logger=logger) # Find the client device_config = None for server in settings['servers']: if 'name' in server and server['name'] == 'power_sensor': device_type = server['type'] device_config = server['config'] break try: pm_client = find_client(clients, settings, device_type, device_config, logger) except NameError: logger.error('No power_sensor device identified in script config file') logger.info(f'Found PM client {pm_client}') calibration = [settings['calibration']] name = settings['name'] pm = PMInterface(pm_client, settings) # Instantiate controller control = Monitor(pm_client=pm, logger=logger, calibration=calibration, name=name, port=kwargs['server_port']) time.sleep(2) control.sync_settings() control.run()
def launch(**kwargs): """ Launches the sweeper GUI """ # logger, loghost, logport, clients, guis, params = unpack_launcher(**kwargs) logger = kwargs['logger'] clients = kwargs['clients'] config = load_script_config( 'histogram', kwargs['config'], logger ) ctr = find_client( clients, config, client_type='si_tt', client_config='standard_ctr', logger=logger ) # Instantiate Monitor script trace = TimeTraceGui( ctr=ctr, log=logger, config=config, ) update_service = Service() update_service.assign_module(module=trace) update_service.assign_logger(logger=logger) update_server, update_port = create_server(update_service, logger, host=get_ip()) logger.update_data(data={'port': update_port}) trace.gui.set_network_info(port=update_port) update_server.start() # Run continuously # Note that the actual operation inside run() can be paused using the update server while True: trace.gui.force_update()
def load_gui(self, script_filename, config_filename, folder_root=None, logger=None): """ Loads and applies GUI settings from a config file :param script_filename: (str) name of the script which wishes to update its GUI (used for lookup of the appropriate config file) :param config_filename: (str) name of configuration file to save. Can be an existing config file with other configuration parameters :folder_root: (str) Name of folder where the config files are stored. If None, use pylabnet/config :logger: (LogClient) instance of LogClient (or LogHandler) """ data = load_script_config(script=script_filename, config=config_filename, logger=logger) if 'gui_scalars' in data: for scalar, value in data['gui_scalars'].items(): try: widget = getattr(self, scalar) try: widget.setValue(value) except AttributeError: widget.setChecked(value) except: logger.warn(f"Could not load value for {scalar}") if 'gui_labels' in data: for label, text in data['gui_labels'].items(): try: widget = getattr(self, label) widget.setText(text) except: logger.warn(f"Could not load value for {label}") logger.info( f'Loaded GUI values from {get_config_filepath(config_filename, folder_root)}' )
def __init__(self, logger=None, channels=['Channel 1'], clients={}, config=None, fast=True): """ Instantiates controller (only 1D data supported so far) :param logger: instance of LogClient :param channels: (list) list of channel names :param config: (str) name of config file :param fast: (bool) whether to operate in fast mode fast mode only updates heat maps at the end of each scan (this speeds things up) """ self.config = load_script_config('scan1d', config, logger=logger) if 'sweep_type' in self.config.keys(): self.sweep_type = self.config['sweep_type'] else: self.sweep_type = 'triangle' super().__init__(logger, channels, sweep_type=self.sweep_type) self.module = None # Instantiate GUI self.gui = Window(gui_template='scan_1d', host=get_ip(), max=True) self.widgets = get_gui_widgets(self.gui, p_min=1, p_max=1, pts=1, config=1, graph=2, legend=2, clients=1, exp=1, exp_preview=1, configure=1, run=1, autosave=1, save_name=1, save=1, reps=1, rep_tracker=1, avg=2) # Configure default parameters self.min = self.widgets['p_min'].value() self.max = self.widgets['p_max'].value() self.pts = self.widgets['pts'].value() self.reps = self.widgets['reps'].value() self.data_fwd = [] self.data_fwd_2nd_reading = [] ### ADDED self.data_bwd = [] self.avg_fwd = [] self.avg_fwd_2nd_reading = [] ### ADDED self.avg_bwd = [] self.fit_popup = None self.p0_fwd = None self.p0_bwd = None self.x_fwd = self._generate_x_axis() if self.sweep_type != 'sawtooth': self.x_bwd = self._generate_x_axis(backward=True) else: self.x_bwd = self._generate_x_axis() self.fast = fast # Configure list of experiments self.widgets['config'].setText(config) self.exp_path = self.config['exp_path'] model = QtWidgets.QFileSystemModel() model.setRootPath(self.exp_path) model.setNameFilterDisables(False) model.setNameFilters(['*.py']) self.widgets['exp'].setModel(model) self.widgets['exp'].setRootIndex(model.index(self.exp_path)) self.widgets['exp'].hideColumn(1) self.widgets['exp'].hideColumn(2) self.widgets['exp'].hideColumn(3) self.widgets['exp'].clicked.connect(self.display_experiment) # Configure list of clients self.clients = clients for client_entry in self.config['servers']: client_type = client_entry['type'] client_config = client_entry['config'] client = find_client(clients=self.clients, settings=client_config, client_type=client_type, client_config=client_config, logger=self.log) if (client == None): client_name_concat = client_type client_item = QtWidgets.QListWidgetItem(client_name_concat) client_item.setForeground(Qt.gray) client_item.setToolTip(str("Disconnected")) self.widgets['clients'].addItem(client_item) else: self.log.info(client) client_name_concat = f"{client_type}_{client_config}" client_item = QtWidgets.QListWidgetItem(client_name_concat) client_item.setToolTip(str(client)) self.widgets['clients'].addItem(client_item) #Checking for any missing clients, and adding them as greyed out on the list of clients # Manually add logger to client self.clients['logger'] = logger # Configure button self.widgets['configure'].clicked.connect(self.configure_experiment) self.widgets['run'].clicked.connect(self.run_pressed) self.widgets['autosave'].toggled.connect(self._update_autosave) self.widgets['save'].pressed.connect( lambda: self.save(filename=self.widgets['save_name'].text(), directory=self.config['save_path'])) self.widgets['reps'].valueChanged.connect(self.set_reps) self.widgets['avg'][0].clicked.connect( lambda: self._clear_show_trace(0)) self.widgets['avg'][1].clicked.connect( lambda: self._clear_show_trace(1)) self.gui.fit.clicked.connect(self.fit_config) # Create legends self.widgets['curve'] = [] for index in range(len(self.widgets['graph'])): self.widgets['legend'][index] = get_legend_from_graphics_view( self.widgets['legend'][index]) # Configure hmaps self.widgets['hmap'] = [] for index in range(2): # Configure Hmap to work the way we want hmap = pg.ImageView(view=pg.PlotItem()) self.gui.graph_layout.insertWidget(2 * index + 1, hmap) hmap.setPredefinedGradient('inferno') hmap.show() hmap.view.setAspectLocked(False) hmap.view.invertY(False) self.widgets['hmap'].append(hmap) # Setup stylesheet. self.gui.apply_stylesheet()
def launch(**kwargs): """ Launches the count monitor script """ # logger, loghost, logport, clients, guis, params = unpack_launcher(**kwargs) logger = kwargs['logger'] clients = kwargs['clients'] config = load_script_config('monitor_counts', kwargs['config'], logger) if config['combined_channel'] == 'True': combined_channel = True else: combined_channel = False # Instantiate CountMonitor try: monitor = CountMonitor(ctr_client=find_client( clients, config, client_type='si_tt', client_config='standard_ctr', logger=logger), logger_client=logger, server_port=kwargs['server_port'], combined_channel=combined_channel) except KeyError: print( 'Please make sure the module names for required servers and GUIS are correct.' ) time.sleep(15) raise # except: # config = None # ch_list = [7, 8] # plot_list = [[7], [8]] # Instantiate Pause server # try: # pause_logger = LogClient( # host=loghost, # port=logport, # module_tag='count_monitor_pause_server' # ) # except ConnectionRefusedError: # logger.warn('Could not connect Count Monitor Pause server to logger') # pause_service = PauseService() # pause_service.assign_module(module=monitor) # pause_service.assign_logger(logger=pause_logger) # timeout = 0 # while timeout < 1000: # try: # port = np.random.randint(1, 9999) # pause_server = GenericServer( # host=get_ip(), # port=port, # service=pause_service) # pause_logger.update_data(data=dict(port=port)) # timeout = 9999 # except ConnectionRefusedError: # logger.warn(f'Failed to instantiate Count Monitor Pause server at port {port}') # timeout += 1 # pause_server.start() # Set parameters monitor.set_params(**config['params']) # Run monitor.run()
def reload_config(self): """ Loads a new config file """ self.config = load_script_config(script='data_taker', config=self.gui.config.text(), logger=self.log)