def on_step_routes_complete(self, start_time, electrode_ids): ''' Callback function executed when all concurrent routes for a step have completed a single run. If repeats are requested, either through repeat counts or a repeat duration, *cycle* routes (i.e., routes that terminate at the start electrode) will repeat as necessary. ''' step_options = self.get_step_options() step_duration_s = (datetime.now() - self.step_start_time).total_seconds() if ((step_options['repeat_duration_s'] > 0 and step_duration_s < step_options['repeat_duration_s']) or (self.repeat_i + 1 < step_options['route_repeats'])): # Either repeat duration has not been met, or the specified number # of repetitions has not been met. Execute another iteration of # the routes. self.repeat_i += 1 df_routes = self.get_routes() self.route_controller.execute_routes( df_routes, step_options['transition_duration_ms'], trail_length=step_options['trail_length'], cyclic=True, acyclic=False, on_complete=self.on_step_routes_complete, on_error=self.on_error) else: logger.info('Completed routes (%s repeats in %ss)', self.repeat_i + 1, si_format(step_duration_s)) # Transitions along all droplet routes have been processed. # Signal step has completed and reset plugin step state. emit_signal('on_step_complete', [self.name, None])
def on_step_run(self): """" Handler called whenever a step is executed. Note that this signal is only emitted in realtime mode or if a protocol is running. Plugins that handle this signal must emit the on_step_complete signal once they have completed the step. The protocol controller will wait until all plugins have completed the current step before proceeding. return_value can be one of: None 'Repeat' - repeat the step or 'Fail' - unrecoverable error (stop the protocol) """ app = get_app() logger.info('[SyringePumpPlugin] on_step_run(): step #%d', app.protocol.current_step_number) app_values = self.get_app_values() options = self.get_step_options() if (self.proxy != None and (app.realtime_mode or app.running)): microsteps = self.proxy.microstep_setting steps = (app_values['steps_per_microliter'] * options['microliters'] * microsteps) steps_per_second = (app_values['steps_per_microliter'] * microsteps * options['microliters_per_min'] / 60.0) self.proxy.move(steps, steps_per_second) print 'move(steps=%d, steps_per_second=%d)' % (steps, steps_per_second) while self.proxy.steps_remaining: gtk.main_iteration() return_value = None emit_signal('on_step_complete', [self.name, return_value])
def on_step_run(self): """ Handler called whenever a step is executed. Plugins that handle this signal must emit the on_step_complete signal once they have completed the step. The protocol controller will wait until all plugins have completed the current step before proceeding. .. versionchanged:: 0.14 Schedule update of control board status label in main GTK thread. """ logger.debug('[DropBotPlugin] on_step_run()') self._kill_running_step() app = get_app() options = self.get_step_options() if (self.control_board and (app.realtime_mode or app.running)): max_channels = self.control_board.number_of_channels # All channels should default to off. channel_states = np.zeros(max_channels, dtype=int) # Set the state of any channels that have been set explicitly. channel_states[self.channel_states.index.values.tolist( )] = self.channel_states emit_signal("set_frequency", options['frequency'], interface=IWaveformGenerator) emit_signal("set_voltage", options['voltage'], interface=IWaveformGenerator) if not self.control_board.hv_output_enabled: self.control_board.hv_output_enabled = True label = ( self.connection_status + ', Voltage: %.1f V' % self.control_board.measure_voltage()) # Schedule update of control board status label in main GTK thread. gobject.idle_add( app.main_window_controller.label_control_board_status. set_markup, label) self.control_board.set_state_of_channels(channel_states) # if a protocol is running, wait for the specified minimum duration if app.running: logger.debug('[DropBotPlugin] on_step_run: ' 'timeout_add(%d, _callback_step_completed)' % options['duration']) self.timeout_id = gobject.timeout_add( options['duration'], self._callback_step_completed) return else: self.step_complete()
def update_grid(self, protocol=None): app = get_app() if protocol is None: protocol = app.protocol if protocol is None: return logging.debug('[ProtocolGridController].update_grid:') logging.debug('[ProtocolGridController] plugin_fields=%s', protocol.plugin_fields) forms = emit_signal('get_step_form_class') steps = protocol.steps logging.debug('[ProtocolGridController] forms=%s steps=%s', forms, steps) if self.enabled_fields is None: # Assign directly to _enabled_fields to avoid recursive call into # update_grid() self._enabled_fields = dict([(form_name, set(form.field_schema_mapping .keys())) for form_name, form in forms.items()]) # The step ID column can be hidden by changing show_ids to False combined_fields = ProtocolGridView(forms, self.enabled_fields, show_ids=True) combined_fields.connect('fields-filter-request', self.set_fields_filter) for i, step in enumerate(steps): values = emit_signal('get_step_values', [i]) logging.debug('[ProtocolGridController] Step[%d]=%s values=%s', i, step, values) attributes = dict() for form_name, form in combined_fields.forms.iteritems(): attr_values = values[form_name] logging.debug('[CombinedRow] attr_values=%s' % attr_values) attributes[form_name] = RowFields(**attr_values) c = CombinedRow(combined_fields, attributes=attributes) combined_fields.append(c) if self.widget: self.window.remove(self.widget) del self.widget self.widget = combined_fields if self.widget: self.widget.show_all() self.widget.select_row(app.protocol.current_step_number) self._register_shortcuts() self.window.add(self.widget)
def on_step_run(self): ''' Handler called whenever a step is executed. Plugins that handle this signal **MUST** emit the ``on_step_complete`` signal once they have completed the step. The protocol controller will wait until all plugins have completed the current step before proceeding. ''' # Get latest step field values for this plugin. options = self.get_step_options() # Apply step options self.apply_step_options(options) emit_signal('on_step_complete', [self.name])
def on_step_run(self): """ Handler called whenever a step is executed. Plugins that handle this signal must emit the on_step_complete signal once they have completed the step. The protocol controller will wait until all plugins have completed the current step before proceeding. """ logger.debug('[OpenDropPlugin] on_step_run()') self._kill_running_step() app = get_app() options = self.get_step_options() dmf_options = app.dmf_device_controller.get_step_options() logger.debug('[OpenDropPlugin] options=%s dmf_options=%s' % (options, dmf_options)) app_values = self.get_app_values() if (self.control_board.connected() and (app.realtime_mode or app.running)): state = dmf_options.state_of_channels max_channels = self.control_board.number_of_channels() if len(state) > max_channels: state = state[0:max_channels] elif len(state) < max_channels: state = np.concatenate([state, np.zeros(max_channels - len(state), int)]) assert(len(state) == max_channels) emit_signal("set_frequency", options['frequency'], interface=IWaveformGenerator) emit_signal("set_voltage", options['voltage'], interface=IWaveformGenerator) self.control_board.set_state_of_all_channels(state) # if a protocol is running, wait for the specified minimum duration if app.running: logger.debug('[OpenDropPlugin] on_step_run: ' 'timeout_add(%d, _callback_step_completed)' % options['duration']) self.timeout_id = gobject.timeout_add( options['duration'], self._callback_step_completed) return else: self.step_complete()
def update_protocol(self, protocol): app = get_app() for i, s in enumerate(protocol): step = app.protocol.steps[i] prevData = step.get_data(self.plugin_name) values = {} for k,v in prevData.iteritems(): if k in s: values[k] = s[k] step.set_data(self.plugin_name, values) emit_signal('on_step_options_changed', [self.plugin_name, i], interface=IPlugin)
def update_protocol(self, protocol): app = get_app() for i, s in enumerate(protocol): step = app.protocol.steps[i] prevData = step.get_data(self.plugin_name) values = {} for k, v in prevData.iteritems(): if k in s: values[k] = s[k] step.set_data(self.plugin_name, values) emit_signal('on_step_options_changed', [self.plugin_name, i], interface=IPlugin)
def on_step_run(self): """ Handler called whenever a step is executed. Plugins that handle this signal must emit the on_step_complete signal once they have completed the step. The protocol controller will wait until all plugins have completed the current step before proceeding. """ logger.debug('[TestPlugin] on_step_run()') app = get_app() if (self.proxy and app.realtime_mode or app.running): options = self.get_step_options() self.proxy.digital_write(pin=13, value=options['led_on']) emit_signal('on_step_complete', [self.name, None])
def on_step_run(self): ''' Handler called whenever a step is executed. Plugins that handle this signal must emit the on_step_complete signal once they have completed the step. The protocol controller will wait until all plugins have completed the current step before proceeding. ''' app = get_app() if (app.realtime_mode or app.running) and self.gui_process is not None: step_options = self.get_step_options() if not step_options['video_enabled']: hub_execute(self.name, 'disable_video', wait_func=lambda *args: refresh_gui(), timeout_s=5, silent=True) else: hub_execute(self.name, 'enable_video', wait_func=lambda *args: refresh_gui(), timeout_s=5, silent=True) emit_signal('on_step_complete', [self.name, None])
def on_step_run(self): ''' Handler called whenever a step is executed. Plugins that handle this signal must emit the on_step_complete signal once they have completed the step. The protocol controller will wait until all plugins have completed the current step before proceeding. ''' app = get_app() # TODO: Migrate video commands to mqtt!! # if (app.realtime_mode or app.running) and self.gui_process is not None: # step_options = self.get_step_options() # if not step_options['video_enabled']: # hub_execute(self.name, 'disable_video', # wait_func=lambda *args: refresh_gui(), timeout_s=5, # silent=True) # else: # hub_execute(self.name, 'enable_video', # wait_func=lambda *args: refresh_gui(), timeout_s=5, # silent=True) emit_signal('on_step_complete', [self.name, None])
def on_step_run(self): """ Handler called whenever a step is executed. Note that this signal is only emitted in realtime mode or if a protocol is running. Plugins that handle this signal must emit the on_step_complete signal once they have completed the step. The protocol controller will wait until all plugins have completed the current step before proceeding. return_value can be one of: None 'Repeat' - repeat the step or 'Fail' - unrecoverable error (stop the protocol) """ app = get_app() logger.info('[AnalystRemotePlugin] on_step_run(): step #%d', app.protocol.current_step_number) # If `acquire` is `True`, start acquisition options = self.get_step_options() if options['acquire']: app_values = self.get_app_values() try: if self.timeout_id is not None: # Timer was already set, so cancel previous timer. gobject.source_remove(self.timeout_id) self.remote = AnalystRemoteControl(app_values['subscribe_uri'], app_values['request_uri']) self.remote.start_acquisition() self.timeout_id = gobject.timeout_add(100, self.remote_check_tick) except: print "Exception in user code:" print '-'*60 traceback.print_exc(file=sys.stdout) print '-'*60 # An error occurred while initializing Analyst remote control. emit_signal('on_step_complete', [self.name, 'Fail']) else: emit_signal('on_step_complete', [self.name, None])
def remote_check_tick(self): if self.remote is not None: try: if self.remote.acquisition_complete(): # Acquisition is complete so notify step complete. self.remote.reset() emit_signal('on_step_complete', [self.name, None]) self.timeout_id = None self.remote = None return False else: print "Waiting for acquisition to complete..." except: print "Exception in user code:" print '-'*60 traceback.print_exc(file=sys.stdout) print '-'*60 emit_signal('on_step_complete', [self.name, 'Fail']) self.timeout_id = None self.remote = None return False return True
def __init__(self): gobject.GObject.__init__(self) super(MetadataPlugin, self).__init__() self.name = self.plugin_name self.timeout_id = None self.start_time = None self.menu_item = None self.menu = None self.video_config_menu = None self.metadata_menu = None self.connect('metadata-changed', lambda obj, original_metadata, metadata: pm.emit_signal('on_metadata_changed', args=[obj.schema, original_metadata, metadata]))
def update_grid(self, protocol=None): app = get_app() if protocol is None: protocol = app.protocol if protocol is None: return _L().debug('plugin_fields=%s', protocol.plugin_fields) forms = dict([ (k, f) for k, f in emit_signal('get_step_form_class').iteritems() if f is not None ]) steps = protocol.steps _L().debug('forms=%s steps=%s', forms, steps) if self.enabled_fields is None: # Assign directly to _enabled_fields to avoid recursive call into # update_grid() self._enabled_fields = dict([ (form_name, set(form.field_schema_mapping.keys())) for form_name, form in forms.items() ]) # The step ID column can be hidden by changing show_ids to False combined_fields = ProtocolGridView(forms, self.enabled_fields, show_ids=True) combined_fields.connect('fields-filter-request', self.set_fields_filter) for i, step in enumerate(steps): values = emit_signal('get_step_values', [i]) attributes = dict() for form_name, form in combined_fields.forms.iteritems(): attr_values = values[form_name] attributes[form_name] = RowFields(**attr_values) combined_row = CombinedRow(combined_fields, attributes=attributes) combined_fields.append(combined_row) if self.widget: # Replacing a previously rendered widget. Maintain original column # order. # Store the position of each column, keyed by column title. column_positions = dict([ (_get_title(c), i) for i, c in enumerate(self.widget.get_columns()) ]) # Remove existing widget to replace with new widget. self.window.remove(self.widget) del self.widget else: # No previously rendered widget. Used saved column positions (if # available). app_values = self.get_app_values() column_positions_json = app_values.get('column_positions', '{}') column_positions = json.loads(column_positions_json) if column_positions: # Explicit column positions are available, so reorder columns # accordingly. # Remove columns so we can reinsert them in an explicit order. columns = combined_fields.get_columns() for c in columns: combined_fields.remove_column(c) # Sort columns according to original order. ordered_column_info = sorted([ (column_positions.get(_get_title(c), len(columns)), _get_title(c), c) for c in columns ]) # Re-add columns in order (sorted according to existing column # order). for i, title_i, column_i in ordered_column_info: combined_fields.append_column(column_i) self.widget = combined_fields app = get_app() if self.widget: self.widget.show_all() self.widget.select_row(app.protocol.current_step_number) self.window.add(self.widget) self.accel_group = self._create_accel_group( app.main_window_controller.view) app.main_window_controller.view.add_accel_group(self.accel_group) else: self.accel_group = None # Disable keyboard shortcuts when a cell edit has started. Without # doing so, certain keys may not behave as expected in edit mode. For # example, see [`step_label_plugin`][1]. # # [1]: https://github.com/wheeler-microfluidics/step_label_plugin/issues/1 self.widget.connect( 'editing-started', lambda *args: app.main_window_controller. disable_keyboard_shortcuts()) # Re-enable keyboard shortcuts when a cell edit has completed. self.widget.connect( 'editing-done', lambda *args: app.main_window_controller.enable_keyboard_shortcuts( ))
def check_dstat_status(self): ''' 1. Check to see if acquisition is finished. 2. If (1), emit `on_step_complete` signal. ''' try: completed_timestamp = hub_execute('dstat-interface', 'acquisition_complete', experiment_id= self.dstat_experiment_id, timeout_s=5.) if completed_timestamp is not None: # ## Acquisition is complete ## app = get_app() # Increment the number of completed DStat experiments for # current step. step_i = app.protocol.current_step_number count_i = 1 + self.dstat_experiment_count_by_step.get(step_i, 0) self.dstat_experiment_count_by_step[step_i] = count_i # ### Save results data and plot ### output_directory = (path(app.experiment_log.get_log_path()) .abspath()) output_namebase = str(app.protocol.current_step_number) step_label = self.get_step_label() if step_label is not None: # Replace characters that are not allowed in a filename # with underscore. output_namebase = re.sub(r'[:/\\\?{}]', '_', step_label) # Save results to a text file in the experiment log directory. output_txt_path = get_unique_path(output_directory .joinpath(output_namebase + '.txt')) logger.info('Save results to: %s', output_txt_path) dstat_params = hub_execute('dstat-interface', 'get_params') hub_execute('dstat-interface', 'save_text', save_data_path=output_txt_path) data_i = hub_execute('dstat-interface', 'get_experiment_data', experiment_id=self.dstat_experiment_id) metadata_i = self.get_step_metadata() # Compute (approximate) `utc_timestamp` for each DStat # measurement. max_time_s = data_i.time_s.max() metadata_i['utc_timestamp'] = (completed_timestamp - data_i.time_s .map(lambda t: timedelta(seconds= max_time_s - t))) # Step label from step label plugin. metadata_i['step_label'] = step_label # Compute UTC start time from local experiment start time. metadata_i['experiment_start'] = \ (dt.datetime.fromtimestamp(app.experiment_log.start_time()) + (dt.datetime.utcnow() - dt.datetime.now())) # Compute UTC start time from local experiment start time. metadata_i['experiment_length_min'] = \ (completed_timestamp - metadata_i['experiment_start']).total_seconds() / 60. # Record synchronous detection parameters from DStat (if set). if dstat_params['sync_true']: metadata_i['target_hz'] = float(dstat_params['sync_freq']) else: metadata_i['target_hz'] = None metadata_i['sample_frequency_hz'] = float(dstat_params['adc_rate_hz']) # Cast metadata `unicode` fields as `str` to enable HDF export. for k, v in metadata_i.iteritems(): if isinstance(v, types.StringTypes): metadata_i[k] = str(v) data_md_i = data_i.copy() for i, (k, v) in enumerate(metadata_i.iteritems()): try: data_md_i.insert(i, k, v) except Exception, e: logger.info('Skipping metadata field %s: %s.\n%s', k, v, e) # Set order for known columns. Unknown columns are ordered # last, alphabetically. column_order = ['instrument_id', 'experiment_id', 'experiment_uuid', 'experiment_start', 'experiment_length_min', 'utc_timestamp', 'device_id', 'batch_id', 'sample_id', 'step_label', 'step_number', 'attempt_number', 'temperature_celsius', 'relative_humidity', 'target_hz', 'sample_frequency_hz', 'time_s', 'current_amps'] column_index = dict([(k, i) for i, k in enumerate(column_order)]) ordered_columns = sorted(data_md_i.columns, key=lambda k: (column_index .get(k, len(column_order)), k)) data_md_i = data_md_i[ordered_columns] namebase_i = ('e[{}]-d[{}]-s[{}]' .format(metadata_i['experiment_uuid'][:8], metadata_i.get('device_id'), metadata_i.get('sample_id'))) if self.dstat_experiment_data is None: self.dstat_experiment_data = data_md_i else: combined = pd.concat([self.dstat_experiment_data, data_md_i]) self.dstat_experiment_data = combined.reset_index(drop= True) # Append DStat experiment data to CSV file. csv_output_path = self.data_dir().joinpath(namebase_i + '.csv') # Only include header if the file does not exist or is empty. include_header = not (csv_output_path.isfile() and (csv_output_path.size > 0)) with csv_output_path.open('a') as output: data_md_i.to_csv(output, index=False, header=include_header) df_dstat_summary = self.dstat_summary_frame(numeric=True) # Write DStat summary table to CSV file. csv_summary_path = self.data_dir().joinpath('dstat-summary' '.csv') with csv_summary_path.open('w') as output: df_dstat_summary.to_csv(output) # Turn light back on after photomultiplier tube (PMT) # measurement. self.dropbot_dx_remote.light_enabled = True # notify step complete. emit_signal('on_step_complete', [self.name, None]) self.dstat_timeout_id = None return False else:
def notify(step_number): emit_signal('on_step_options_changed', [self.name, step_number], interface=IPlugin)
def on_error(self, *args): logger.error('Error executing routes.', exc_info=True) # An error occurred while initializing Analyst remote control. emit_signal('on_step_complete', [self.name, 'Fail'])
def step_complete(self, return_value=None): app = get_app() if app.running or app.realtime_mode: emit_signal('on_step_complete', [self.name, return_value])
def update_grid(self, protocol=None): app = get_app() if protocol is None: protocol = app.protocol if protocol is None: return logging.debug('[ProtocolGridController].update_grid:') logging.debug('[ProtocolGridController] plugin_fields=%s', protocol.plugin_fields) forms = dict([(k, f) for k, f in emit_signal('get_step_form_class').iteritems() if f is not None]) steps = protocol.steps logging.debug('[ProtocolGridController] forms=%s steps=%s', forms, steps) if self.enabled_fields is None: # Assign directly to _enabled_fields to avoid recursive call into # update_grid() self._enabled_fields = dict([(form_name, set(form.field_schema_mapping .keys())) for form_name, form in forms.items()]) # The step ID column can be hidden by changing show_ids to False combined_fields = ProtocolGridView(forms, self.enabled_fields, show_ids=True) combined_fields.connect('fields-filter-request', self.set_fields_filter) for i, step in enumerate(steps): values = emit_signal('get_step_values', [i]) #logging.debug('[ProtocolGridController] Step[%d]=%s values=%s', #i, step, values) attributes = dict() for form_name, form in combined_fields.forms.iteritems(): attr_values = values[form_name] #logging.debug('[CombinedRow] attr_values=%s' % attr_values) attributes[form_name] = RowFields(**attr_values) combined_row = CombinedRow(combined_fields, attributes=attributes) combined_fields.append(combined_row) # Create a shortcut wrapper to lookup column title from each # `TreeViewColumn`. Just makes following code more concise. get_title = lambda c: c.get_data('pygtkhelpers::column').title if self.widget: # Replacing a previously rendered widget. Maintain original column # order. # Store the position of each column, keyed by column title. column_positions = dict([(get_title(c), i) for i, c in enumerate(self.widget .get_columns())]) # Remove existing widget to replace with new widget. self.window.remove(self.widget) del self.widget else: # No previously rendered widget. Used saved column positions (if # available). app_values = self.get_app_values() column_positions_json = app_values.get('column_positions', '{}') column_positions = json.loads(column_positions_json) if column_positions: # Explicit column positions are available, so reorder columns # accordingly. # Remove columns so we can reinsert them in an explicit order. columns = combined_fields.get_columns() for c in columns: combined_fields.remove_column(c) # Sort columns according to original order. ordered_column_info = sorted([(column_positions.get(get_title(c), len(columns)), get_title(c), c) for c in columns]) # Re-add columns in order (sorted according to existing column order). for i, title_i, column_i in ordered_column_info: combined_fields.append_column(column_i) self.widget = combined_fields app = get_app() if self.widget: self.widget.show_all() self.widget.select_row(app.protocol.current_step_number) self.window.add(self.widget) self.accel_group = self._create_accel_group(app .main_window_controller .view) app.main_window_controller.view.add_accel_group(self.accel_group) else: self.accel_group = None # Disable keyboard shortcuts when a cell edit has started. Without # doing so, certain keys may not behave as expected in edit mode. For # example, see [`step_label_plugin`][1]. # # [1]: https://github.com/wheeler-microfluidics/step_label_plugin/issues/1 self.widget.connect('editing-started', lambda *args: app.main_window_controller .disable_keyboard_shortcuts()) # Re-enable keyboard shortcuts when a cell edit has completed. self.widget.connect('editing-done', lambda *args: app.main_window_controller .enable_keyboard_shortcuts())
def on_step_run(self): ''' Handler called whenever a step is executed. Note that this signal is only emitted in realtime mode or if a protocol is running. Plugins that handle this signal must emit the `on_step_complete` signal once they have completed the step. The protocol controller will wait until all plugins have completed the current step before proceeding. The `on_step_complete` signal is emitted with following signature: emit_signal('on_step_complete', [plugin_name, return_value]) where `plugin_name` is the name of the emitting plugin, and `return_value` can be one of: - `None`: Step completed successfully. - `'Repeat'`: Repeat the step. - `'Fail'`: Unrecoverable error (stop the protocol). ''' app = get_app() logger.info('[DropBotDxAccessoriesPlugin] on_step_run(): step #%d', app.protocol.current_step_number) options = self.get_step_options() app_values = self.get_app_values() if self.connected(): self.dropbot_dx_remote.light_enabled = not options['dstat_enabled'] self.dropbot_dx_remote.magnet_engaged=options['magnet_engaged'] try: if self.has_environment_data: env = self.get_environment_state().to_dict() logger.info('temp=%.1fC, Rel. humidity=%.1f%%' % (env['temperature_celsius'], 100 * env['relative_humidity'])) app.experiment_log.add_data({"environment state": env}, self.name) except ValueError: self.has_environment_data = False if options['dstat_enabled']: # D-stat is enabled for step. Request acquisition. try: if 'dstat_params_file' in options: # Load Dstat parameters. hub_execute('dstat-interface', 'load_params', params_path=options['dstat_params_file']) if self.dstat_timeout_id is not None: # Timer was already set, so cancel previous timer. gobject.source_remove(self.dstat_timeout_id) # Delay before D-stat measurement (e.g., to allow webcam # light to turn off). dstat_delay_s = app_values.get('dstat_delay_s', 0) time.sleep(max(0, dstat_delay_s)) step_label = self.get_step_label() # Send Microdrop step label (if available) to provide name # for DStat experiment. metadata = self.metadata.copy() metadata['name'] = (step_label if step_label else str(app.protocol.current_step_number + 1)) metadata['patient_id'] = metadata.get('sample_id', 'None') # Get target path for DStat database directory. dstat_database_path = (path(app.config['data_dir']) .realpath().joinpath('dstat-db')) self.dstat_experiment_id = \ hub_execute('dstat-interface', 'run_active_experiment', metadata=metadata, params={'db_path_entry': str(dstat_database_path), 'db_enable_checkbutton': True}) self._dstat_spinner = itertools.cycle(r'-\|/') print '' # Check every 250ms to see if dstat acquisition has # completed. self.dstat_timeout_id = \ gobject.timeout_add(250, self.check_dstat_status) except: print "Exception in user code:" print '-'*60 traceback.print_exc(file=sys.stdout) print '-'*60 # An error occurred while initializing Analyst remote # control. emit_signal('on_step_complete', [self.name, 'Fail']) else: # D-State is not enabled, so step is complete. emit_signal('on_step_complete', [self.name, None]) else: # DropBox-DX device is not connected, but allow protocol to # continue. # # N.B., A warning message is display once at the *start* of the # protocol if no DropBot-DX connection has been established, but # *not* on each step. emit_signal('on_step_complete', [self.name, None])
df_dstat_summary = self.dstat_summary_frame(numeric=True) # Write DStat summary table to CSV file. csv_summary_path = self.data_dir().joinpath('dstat-summary' '.csv') with csv_summary_path.open('w') as output: df_dstat_summary.to_csv(output) # Turn light back on after photomultiplier tube (PMT) # measurement. self.dropbot_dx_remote.light_enabled = True # notify step complete. emit_signal('on_step_complete', [self.name, None]) self.dstat_timeout_id = None return False else: print '\rWaiting for Dstat...', self._dstat_spinner.next(), except: print "Exception in user code:" print '-'*60 traceback.print_exc(file=sys.stdout) print '-'*60 emit_signal('on_step_complete', [self.name, 'Fail']) self.dstat_timeout_id = None return False return True PluginGlobals.pop_env()