def process_request(self, h5_filepath): # check connection table try: new_conn = ConnectionTable(h5_filepath) except: 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
], "ports": ["BLACS", "lyse"], } exp_config = LabConfig(config_path, 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') try: connection_table = ConnectionTable(connection_table_h5_file) except: # dialog = gtk.MessageDialog(None,gtk.DIALOG_MODAL,gtk.MESSAGE_ERROR,gtk.BUTTONS_NONE,"The connection table in '%s' is not valid. Please check the compilation of the connection table for errors\n\n"%self.connection_table_h5file) # dialog.run() # dialog.destroy() logger.exception('connection table failed to load') raise sys.exit("Invalid Connection Table") logger.info('connection table loaded') qapplication = QApplication(sys.argv) logger.info('QApplication instantiated') app = BLACS(qapplication) logger.info('BLACS instantiated')
self.create_worker("my_secondary_worker_name", DeviceWorker, {}) self.add_secondary_worker("my_secondary_worker_name") self.supports_remote_value_check(True) # Create buttons to test things! button1 = QPushButton("Transition to Buffered") from Queue import Queue button1.clicked.connect( lambda: self.transition_to_buffered('', Queue())) self.get_tab_layout().addWidget(button1) button2 = QPushButton("Transition to Manual") button2.clicked.connect(lambda: self.transition_to_manual(Queue())) self.get_tab_layout().addWidget(button2) connection_table = ConnectionTable(r'example_connection_table.h5') class MyWindow(QWidget): def __init__(self, *args, **kwargs): QWidget.__init__(self, *args, **kwargs) self.are_we_closed = False def closeEvent(self, event): if not self.are_we_closed: event.ignore() self.my_tab.destroy() self.are_we_closed = True QTimer.singleShot(1000, self.close) else: if not self.my_tab.destroy_complete: QTimer.singleShot(1000, self.close)
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) 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_data.setdefault(row['tab_name'], {}) try: tab_data[row['tab_name']] = { 'notebook': row['notebook'], 'page': row['page'], 'visible': row['visible'], 'data': eval(row['data']) } except: logger.info("Could not load tab data for %s" % row['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)): 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, e: logger.info("Could not load saved settings") logger.info(e.message)
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: # 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)