def process_request(self, h5_filepath): # check connection table try: new_conn = ConnectionTable(h5_filepath, logging_prefix='BLACS') except Exception: return "H5 file not accessible to Control PC\n" result, error = inmain(self.BLACS.connection_table.compare_to, new_conn) if result: # Has this run file been run already? with h5py.File(h5_filepath) as h5_file: if 'data' in h5_file['/']: rerun = True else: rerun = False if rerun or self.is_in_queue(h5_filepath): self._logger.debug( 'Run file has already been run! Creating a fresh copy to rerun' ) new_h5_filepath, repeat_number = self.new_rep_name(h5_filepath) # Keep counting up until we get a filename that isn't in the filesystem: while os.path.exists(new_h5_filepath): new_h5_filepath, repeat_number = self.new_rep_name( new_h5_filepath) success = self.clean_h5_file(h5_filepath, new_h5_filepath, repeat_number=repeat_number) if not success: return 'Cannot create a re run of this experiment. Is it a valid run file?' self.append([new_h5_filepath]) message = "Experiment added successfully: experiment to be re-run\n" else: self.append([h5_filepath]) message = "Experiment added successfully\n" if self.manager_paused: message += "Warning: Queue is currently paused\n" if not self.manager_running: message = "Error: Queue is not running\n" return message else: # TODO: Parse and display the contents of "error" in a more human readable format for analysis of what is wrong! message = ( "Connection table of your file is not a subset of the experimental control apparatus.\n" "You may have:\n" " Submitted your file to the wrong control PC\n" " Added new channels to your h5 file, without rewiring the experiment and updating the control PC\n" " Renamed a channel at the top of your script\n" " Submitted an old file, and the experiment has since been rewired\n" "\n" "Please verify your experiment script matches the current experiment configuration, and try again\n" "The error was %s\n" % error) return message
def restore(self): # Get list of DO/AO # Does the object have a name? # yes: Then, find the device in the BLACS connection table that matches that name # Also Find the device in the saved connection table. # Do the connection table entries match? # yes: Restore as is # no: Is it JUST the parent device and "connected to" that has changed? # yes: Restore to new device # no: Show error that this device could not be restored # no: Ok, so it isn't in the saved connection table # Does this device/channel exist in the BLACS connection table? # yes: Don't restore, show error that this chanel is now in use by a new device # Give option to restore anyway... # no: Restore as is # # Display errors, give option to cancel starting of BLACS so that the connection table can be edited # Create saved connection table settings = {} question = {} error = {} tab_data = {'BLACS settings': {}} try: saved_ct = ConnectionTable(self.settings_path, logging_prefix='BLACS', exceptions_in_thread=True) ct_match, error = self.connection_table.compare_to(saved_ct) with h5py.File(self.settings_path, 'r') as hdf5_file: # Get Tab Data dataset = hdf5_file['/front_panel'].get('_notebook_data', []) for row in dataset: tab_name = _ensure_str(row['tab_name']) tab_data.setdefault(tab_name, {}) try: tab_data[tab_name] = { 'notebook': row['notebook'], 'page': row['page'], 'visible': row['visible'], 'data': eval(_ensure_str(row['data'])) } except Exception: logger.info("Could not load tab data for %s" % tab_name) #now get dataset attributes tab_data['BLACS settings'] = dict(dataset.attrs) # Get the front panel values if 'front_panel' in hdf5_file["/front_panel"]: dataset = hdf5_file["/front_panel"].get('front_panel', []) for row in dataset: result = self.check_row(row, ct_match, self.connection_table, saved_ct) columns = [ 'name', 'device_name', 'channel', 'base_value', 'locked', 'base_step_size', 'current_units' ] data_dict = {} for i in range(len(row)): if isinstance(row[i], bytes) or isinstance( row[i], str): data_dict[columns[i]] = _ensure_str(row[i]) else: data_dict[columns[i]] = row[i] settings, question, error = self.handle_return_code( data_dict, result, settings, question, error) # Else Legacy restore from GTK save data! else: # open Datasets type_list = ["AO", "DO", "DDS"] for key in type_list: dataset = hdf5_file["/front_panel"].get(key, []) for row in dataset: result = self.check_row(row, ct_match, self.connection_table, saved_ct) columns = [ 'name', 'device_name', 'channel', 'base_value', 'locked', 'base_step_size', 'current_units' ] data_dict = {} for i in range(len(row)): data_dict[columns[i]] = row[i] settings, question, error = self.handle_return_code( data_dict, result, settings, question, error) except Exception as e: logger.info("Could not load saved settings") logger.info(str(e)) return settings, question, error, tab_data
def save_front_panel_to_h5(self, current_file, states, tab_positions, window_data, plugin_data, silent={}, force_new_conn_table=False): # Save the front panel! # Does the file exist? # Yes: Check connection table inside matches current connection table. Does it match? # Yes: Does the file have a front panel already saved in it? # Yes: Can we overwrite? # Yes: Delete front_panel group, save new front panel # No: Create error dialog! # No: Save front panel in here # # No: Return # No: Create new file, place inside the connection table and front panel if os.path.isfile(current_file): save_conn_table = True if force_new_conn_table else False result = False if not save_conn_table: try: new_conn = ConnectionTable(current_file) result, error = self.connection_table.compare_to(new_conn) except Exception: # no connection table is present, so also save the connection table! save_conn_table = True # if save_conn_table is True, we don't bother checking to see if the connection tables match, because save_conn_table is only true when the connection table doesn't exist in the current file # As a result, if save_conn_table is True, we ignore connection table checking, and save the connection table in the h5file. if save_conn_table or result: with h5py.File(current_file, 'r+') as hdf5_file: if hdf5_file['/'].get('front_panel') != None: # Create a dialog to ask whether we can overwrite! overwrite = False if not silent: message = QMessageBox() message.setText( "This file '%s' already contains a connection table." % current_file) message.setInformativeText( "Do you wish to replace the existing front panel configuration in this file?" ) message.setStandardButtons(QMessageBox.Yes | QMessageBox.No) message.setDefaultButton(QMessageBox.No) message.setIcon(QMessageBox.Question) message.setWindowTitle("BLACS") resp = message.exec_() if resp == QMessageBox.Yes: overwrite = True else: overwrite = silent["overwrite"] if overwrite: # Delete Front panel group, save new front panel del hdf5_file['/front_panel'] self.store_front_panel_in_h5( hdf5_file, states, tab_positions, window_data, plugin_data, save_conn_table) else: if not silent: message = QMessageBox() message.setText("Front Panel not saved.") message.setIcon(QMessageBox.Information) message.setWindowTitle("BLACS") message.exec_() else: logger.info( "Front Panel not saved as it already existed in the h5 file '" + current_file + "'") return else: # Save Front Panel in here self.store_front_panel_in_h5(hdf5_file, states, tab_positions, window_data, plugin_data, save_conn_table) else: # Create Error dialog (invalid connection table) if not silent: message = QMessageBox() message.setText( "The Front Panel was not saved as the file selected contains a connection table which is not a subset of the BLACS connection table." ) message.setIcon(QMessageBox.Information) message.setWindowTitle("BLACS") message.exec_() else: logger.info( "Front Panel not saved as the connection table in the h5 file '" + current_file + "' didn't match the current connection table.") return else: with h5py.File(current_file, 'w') as hdf5_file: # save connection table, save front panel self.store_front_panel_in_h5(hdf5_file, states, tab_positions, window_data, plugin_data, save_conn_table=True)
], "ports": ["BLACS", "lyse"], } exp_config = LabConfig(required_params=required_config_params) port = int(exp_config.get('ports', 'BLACS')) # Start experiment server experiment_server = ExperimentServer(port) # Create Connection Table object logger.info('About to load connection table: %s' % exp_config.get('paths', 'connection_table_h5')) connection_table_h5_file = exp_config.get('paths', 'connection_table_h5') connection_table = ConnectionTable(connection_table_h5_file, logging_prefix='BLACS', exceptions_in_thread=True) logger.info('connection table loaded') qapplication = QApplication(sys.argv) qapplication.setAttribute(Qt.AA_DontShowIconsInMenus, False) logger.info('QApplication instantiated') app = BLACS(qapplication) logger.info('BLACS instantiated') def execute_program(): qapplication.exec_() sys.exit(execute_program())