def on_plugin_enable(self): super(SyringePumpPlugin, self).on_plugin_enable() self.cleanup_plugin() self.check_device_name_and_version() if not self.initialized: app = get_app() self.tools_menu_item = gtk.MenuItem('Syringe pump controller') app.main_window_controller.menu_tools.append(self.tools_menu_item) self.tools_menu = gtk.Menu() self.tools_menu.show() self.tools_menu_item.set_submenu(self.tools_menu) self.edit_config_menu_item = \ gtk.MenuItem("Edit configuration settings...") self.tools_menu.append(self.edit_config_menu_item) self.edit_config_menu_item.connect("activate", self.on_edit_configuration) self.edit_config_menu_item.show() self.edit_config_menu_item.set_sensitive(False) self.tools_menu_item.show() self.edit_config_menu_item.set_sensitive(self.proxy != None) if get_app().protocol: self.on_step_run() self._update_protocol_grid()
def on_experiment_log_changed(self, experiment_log): # Reset number of completed DStat experiments for each step. self.dstat_experiment_count_by_step = {} self.dstat_experiment_data = None app = get_app() app_values = self.get_app_values() calibrator_file = app_values.get('calibrator_file', '') data = {'calibrator_file': calibrator_file} if hasattr(app, 'experiment_log') and app.experiment_log: app.experiment_log.metadata[self.name] = data # copy the calibrator file to the experiment log directory if calibrator_file: if not path(calibrator_file).isfile(): logger.error('Calibration file (%s) does not exist.' % calibrator_file) else: try: output_path = path(app.experiment_log.get_log_path()) / self.name if not output_path.isdir(): output_path.mkdir() path(calibrator_file).copy2(output_path / 'calibrator.csv') except: logger.error('Could not copy calibration file to the ' 'experiment log directory.' , exc_info=True)
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_swapped(self, original_step_number, new_step_number): logger.info( '[DropBotPlugin] on_step_swapped():' 'original_step_number=%d, new_step_number=%d', original_step_number, new_step_number) self.on_step_options_changed(self.name, get_app().protocol.current_step_number)
def get_label(self): app = get_app() vbox = app.main_window_controller.vbox2 main_window_children = vbox.get_children() # Get reference to metadata label (or add it if necessary). labels = [widget for widget in main_window_children if isinstance(widget, gtk.Label) and (widget.props.name == 'metadata')] if labels: # Metadata label has already been added. Use existing label. label_metadata = labels[0] else: # Metadata label has not been added. Create new metadata label. label_metadata = gtk.Label() label_metadata.props.name = 'metadata' label_metadata.set_alignment(0, .5) # Left, middle vertical align vbox.pack_start(label_metadata, False, False, 0) # Find position in main window `gtk.VBox` to insert metadata label # (after first set of labels). for i, child in enumerate(main_window_children): if not isinstance(child, gtk.Label): break # Move metadata label to new position. vbox.reorder_child(label_metadata, i) # Display label label_metadata.show() return label_metadata
def edit_metadata(self): from pygtkhelpers.schema import schema_dialog app = get_app() metadata = self.get_metadata() schema = json.loads(self.get_app_values()['json_schema']) video_config = json.loads(self.get_app_values().get('video_config', 'null')) if video_config is None: video_config = {} device_name = video_config.get('device_name') max_width = video_config.get('width', 320) max_fps = video_config.get('framerate', 15) try: data = schema_dialog(schema, data=metadata, device_name=device_name, max_width=max_width, max_fps=max_fps, title='Edit metadata', parent=app.main_window_controller.view) except ValueError: logger.info('Metadata edit cancelled.') except KeyError: logger.error('Error setting metadata scanner video config.', exc_info=True) else: self.set_metadata(data)
def on_plugin_enable(self): app = get_app() self.parent = app.builder.get_object("vbox2") self.window = gtk.ScrolledWindow() self.window.show_all() self.parent.add(self.window) super(ProtocolGridController, self).on_plugin_enable()
def _create_accel_group(self, widget): class FocusWrapper(object): ''' This class allows for a function to be executed, restoring the focused state of the protocol grid view if necessary. ''' def __init__(self, controller, func): self.controller = controller self.func = func def __call__(self): focused = self.controller.widget.has_focus() self.func() if focused: self.controller.widget.grab_focus() app = get_app() shortcuts = { '<Control>c': self.widget.copy_rows, '<Control>x': FocusWrapper(self, self.widget.cut_rows), 'Delete': FocusWrapper(self, self.widget.delete_rows), '<Control>v': FocusWrapper(self, self.widget.paste_rows_after), '<Control><Shift>v': FocusWrapper(self, self.widget.paste_rows_before), '<Control><Shift>i': FocusWrapper(self, lambda: app.protocol.insert_step()) } return get_accel_group(widget, shortcuts, enabled_widgets=[self.widget])
def _create_accel_group(self, widget): class FocusWrapper(object): ''' This class allows for a function to be executed, restoring the focused state of the protocol grid view if necessary. ''' def __init__(self, controller, func): self.controller = controller self.func = func def __call__(self): focused = self.controller.widget.has_focus() self.func() if focused: self.controller.widget.grab_focus() app = get_app() shortcuts = { '<Control>c': self.widget.copy_rows, '<Control>x': FocusWrapper(self, self.widget.cut_rows), 'Delete': FocusWrapper(self, self.widget.delete_rows), '<Control>v': FocusWrapper(self, self.widget.paste_rows_after), '<Control><Shift>v': FocusWrapper(self, self.widget.paste_rows_before), '<Control><Shift>i': FocusWrapper(self, lambda: app.protocol.insert_step())} return get_accel_group(widget, shortcuts, enabled_widgets=[self.widget])
def update_connection_status(self): ''' Update connection status message and corresponding UI label. .. versionchanged:: 0.14 Schedule update of control board status label in main GTK thread. ''' self.connection_status = "Not connected" app = get_app() connected = self.control_board is not None if connected: properties = self.control_board.properties version = self.control_board.hardware_version n_channels = self.control_board.number_of_channels id = self.control_board.id uuid = self.control_board.uuid self.connection_status = ('%s v%s (Firmware: %s, id: %s, uuid: ' '%s)\n' '%d channels' % (properties['display_name'], version, properties['software_version'], id, str(uuid)[:8], n_channels)) self.trigger("set-stats", self.connection_status) # Schedule update of control board status label in main GTK thread. gobject.idle_add( app.main_window_controller.label_control_board_status.set_text, self.connection_status)
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:: 2.2.2 Emit ``on_step_complete`` signal within thread-safe function, since signal callbacks may use GTK. ''' 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']: command = 'disable_video' else: command = 'enable_video' hub_execute(self.name, command) # Call as thread-safe function, since signal callbacks may use GTK. gtk_threadsafe(emit_signal)('on_step_complete', [self.name, None])
def on_app_options_changed(self, plugin_name): app = get_app() if plugin_name == self.name: app_values = self.get_app_values() reconnect = False if self.control_board.connected(): for k, v in app_values.items(): if k == 'baud_rate' and self.control_board.baud_rate != v: self.control_board.baud_rate = v reconnect = True if k == 'serial_port' and self.control_board.port != v: reconnect = True if reconnect: self.connect() self._update_protocol_grid() elif plugin_name == app.name: # Turn off all electrodes if we're not in realtime mode and not # running a protocol. if (self.control_board.connected() and not app.realtime_mode and not app.running): logger.info('Turning off all electrodes.') self.control_board.set_state_of_all_channels( np.zeros(self.control_board.number_of_channels()) )
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() if not app.running: return self.kill_running_step() step_options = self.get_step_options() try: self.repeat_i = 0 self.step_start_time = datetime.now() df_routes = self.get_routes() self.route_controller.execute_routes( df_routes, step_options['transition_duration_ms'], trail_length=step_options['trail_length'], on_complete=self.on_step_routes_complete, on_error=self.on_error) except: self.on_error()
def _get_popup_menu(self, item, column_title, value, row_ids, menu_items=None): app = get_app() if menu_items is None: # Use list of tuples (menu label, callback) rather than a dict to # allow ordering. menu_items = [] def request_field_filter(*args, **kwargs): from .field_filter_controller import FieldFilterController ffc = FieldFilterController() response = ffc.run(self.forms, self.enabled_fields_by_form_name) if response == gtk.RESPONSE_OK: self.emit('fields-filter-request', ffc.enabled_fields_by_plugin) # Add menu entry to select enabled fields for each plugin menu_items += [('Select fields...', request_field_filter)] # Add seperator menu_items += [(None, None)] menu_items += [('Insert', lambda x: app.protocol.insert_step())] menu_items += [('Delete', self.delete_rows)] menu_items += [('Cut', self.cut_rows)] menu_items += [('Copy', self.copy_rows)] menu_items += [('Paste before', self.paste_rows_before)] menu_items += [('Paste after', self.paste_rows_after)] # Add seperator menu_items += [(None, None)] return super(ProtocolGridView, self)._get_popup_menu(item, column_title, value, row_ids, menu_items)
def set_electrode_states(self, electrode_states): ''' Set the state of multiple electrodes. Args: electrode_states (pandas.Series) : State of electrodes, indexed by electrode identifier (e.g., `"electrode001"`). Returns: (dict) : States of modified channels and electrodes, as well as the total area of all actuated electrodes. ''' app = get_app() # Set the state of DMF device channels. self.electrode_states = (electrode_states .combine_first(self.electrode_states)) def notify(step_number): emit_signal('on_step_options_changed', [self.name, step_number], interface=IPlugin) gtk.idle_add(notify, app.protocol.current_step_number) result = self.get_state(electrode_states) result['actuated_area'] = self.get_actuated_area(self.electrode_states) return result
def get_actuated_area(self, electrode_states): ''' Get area of actuated electrodes. ''' app = get_app() actuated_electrodes = electrode_states[electrode_states > 0].index return app.dmf_device.electrode_areas.ix[actuated_electrodes].sum()
def on_plugin_enable(self): ''' Handler called when plugin is enabled. For example, when the MicroDrop application is **launched**, or when the plugin is **enabled** from the plugin manager dialog. ''' self.open_board_connection() if not self.initialized: app = get_app() self.tools_menu_item = gtk.MenuItem("PMT-plugin") app.main_window_controller.menu_tools.append(self.tools_menu_item) self.tools_menu = gtk.Menu() self.tools_menu_item.set_submenu(self.tools_menu) self.edit_config_menu_item = \ gtk.MenuItem("Edit configuration settings...") self.tools_menu.append(self.edit_config_menu_item) self.edit_config_menu_item.connect("activate", self.on_edit_configuration) self.edit_config_menu_item.show() self.initialized = True # if we're connected to the board, display the menu if self.board: self.reset_board_state() self.tools_menu.show() self.tools_menu_item.show() try: super(MrBoxPeripheralBoardPlugin, self).on_plugin_enable() except AttributeError: pass
def on_flash_firmware(self, widget=None, data=None): app = get_app() try: self.board.flash_firmware() app.main_window_controller.info("Firmware updated successfully.", "Firmware update") except Exception, why: logger.error("Problem flashing firmware. ""%s" % why)
def on_selection_changed(self, grid_view): if self.selected_ids: _L().debug('selected_ids=%s', self.selected_ids) app = get_app() _L().debug('current_step_number=%d', app.protocol.current_step_number) if app.protocol.current_step_number not in self.selected_ids: app.protocol.goto_step(self.selected_ids[0])
def on_selection_changed(self, grid_view): if self.selected_ids: logger = _L() app = get_app() step_number = app.protocol_controller.protocol_state['step_number'] logger.debug('selected_ids=%s', self.selected_ids) logger.debug('step number=%d', step_number) if step_number not in self.selected_ids: app.protocol_controller.goto_step(self.selected_ids[0])
def on_step_swapped(self, *args): ''' .. versionchanged:: 2.1.3 Pass current step number to as argument to :meth:`update_nearest_step_labels`. ''' app = get_app() step_i = app.protocol.current_step_number self.update_nearest_step_labels(step_i)
def on_step_options_changed(self, plugin, step_number): logger.info('[DropBotPlugin] on_step_options_changed(): %s step #%d', plugin, step_number) app = get_app() if (app.protocol and not app.running and not app.realtime_mode and (plugin == 'microdrop.gui.dmf_device_controller' or plugin == self.name) and app.protocol.current_step_number == step_number): self.on_step_run()
def get_state(self, electrode_states): app = get_app() electrode_channels = (app.dmf_device.actuated_channels(electrode_states .index)) channel_states = pd.Series(electrode_states.values, index=electrode_channels) return {'electrode_states': electrode_states, 'channel_states': channel_states}
def on_selection_changed(self, grid_view): if self.selected_ids: logging.debug('[ProtocolGridView].on_selection_changed: ' 'selected_ids=%s', self.selected_ids) app = get_app() logging.debug('\tcurrent_step_number=%d', app.protocol.current_step_number) if app.protocol.current_step_number not in self.selected_ids: app.protocol.goto_step(self.selected_ids[0])
def metadata(self): ''' Add experiment index and experiment UUID to metadata. ''' metadata = self._metadata.copy() if self._metadata else {} app = get_app() metadata['experiment_id'] = app.experiment_log.experiment_id metadata['experiment_uuid'] = app.experiment_log.uuid return metadata
def create_ui(self): self.menu = gtk.MenuItem('E_xport 2.35+ protocol...') self.menu.set_tooltip_text('Export protocol compatible with MicroDrop ' '2.35+.') self.menu.show_all() app = get_app() # Add main DropBot menu to MicroDrop `Tools` menu. app.main_window_controller.menu_tools.append(self.menu) self.menu.connect('activate', lambda menu_item: self._export_protocol())
def on_protocol_pause(self): """ Handler called when a protocol is paused. """ app = get_app() self._kill_running_step() if self.control_board and not app.realtime_mode: # Turn off all electrodes logger.debug('Turning off all electrodes.') self.control_board.hv_output_enabled = False
def on_step_options_changed(self, plugin, step_number): logger.debug('[OpenDropPlugin] on_step_options_changed(): %s ' 'step #%d' % (plugin, step_number)) app = get_app() app_values = self.get_app_values() options = self.get_step_options(step_number) if (app.protocol and not app.running and not app.realtime_mode and (plugin == 'microdrop.gui.dmf_device_controller' or plugin == self.name) and app.protocol.current_step_number == step_number): self.on_step_run()
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_steps(self): app = get_app() num_steps = len(app.protocol.steps) protocol = [] for i in range(num_steps): protocol.append(self.get_step_options(i)) self.mqtt_client.publish('microdrop/droplet-planning-plugin/step-options', json.dumps(protocol, cls=PandasJsonEncoder), retain=True)
def on_protocol_run(self): """ Handler called when a protocol starts running. """ app = get_app() if not self.control_board.connected(): logger.warning("Warning: no control board connected.") elif (self.control_board.number_of_channels() <= app.dmf_device.max_channel()): logger.warning("Warning: currently connected board does not have " "enough channels for this protocol.")
def on_protocol_pause(self): """ Handler called when a protocol is paused. """ app = get_app() self._kill_running_step() if self.control_board.connected() and not app.realtime_mode: # Turn off all electrodes logger.debug('Turning off all electrodes.') self.control_board.set_state_of_all_channels( np.zeros(self.control_board.number_of_channels()))
def update_steps(self): app = get_app() num_steps = len(app.protocol.steps) protocol = [] for i in range(num_steps): protocol.append(self.get_step_options(i)) self.mqtt_client.publish('microdrop/dmf-device-ui-plugin/step-options', json.dumps(protocol, cls=PandasJsonEncoder), retain=True)
def on_protocol_run(self): """ Handler called when a protocol starts running. """ app = get_app() if not self.control_board: logger.warning("Warning: no control board connected.") elif (self.control_board.number_of_channels <= app.dmf_device.max_channel()): logger.warning("Warning: currently connected board does not have " "enough channels for this protocol.")
def remove_labels(self): ''' .. versionchanged:: 2.1.3 Wrap with :func:`gtk_threadsafe` decorator to ensure the code runs in the main GTK thread. ''' app = get_app() for child_i in app.main_window_controller.box_step.get_children(): if any([child_i is self.label_most_recent_step_label, child_i is self.label_next_step_label]): app.main_window_controller.box_step.remove(child_i) self.label_most_recent_step_label = None self.label_next_step_label = None
def update_channel_states(self, channel_states): # Update locally cached channel states with new modified states. try: self.channel_states = channel_states.combine_first( self.channel_states) except ValueError: logging.info('channel_states: %s', channel_states) logging.info('self.channel_states: %s', self.channel_states) logging.info('', exc_info=True) else: app = get_app() connected = self.control_board != None if connected and (app.realtime_mode or app.running): self.on_step_run()
def on_execute__save_channel_impedances(self, request): data = decode_content_data(request) impedance_structures = data.pop('impedance_structures') output_path = data.pop('output_path') try: self.parent.save_channel_impedances(impedance_structures, output_path, **data) except Exception, error: app = get_app() if app.config.data.get('advanced_ui', False): # Launch debugger to inspect state. import pdb; pdb.set_trace() raise
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. """ 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 set_metadata(self, data): ''' Args ---- data (dict) : New metadata to replace existing metadata. Emits `metadata-changed` signal with original and new metadata. ''' app = get_app() # Validate new metadata against schema. jsonschema.validate(data, self.schema) original_metadata = self.get_metadata() app.experiment_log.metadata[self.name] = data self.emit('metadata-changed', original_metadata, app.experiment_log.metadata[self.name])
def create_ui(self): self.menu = gtk.Menu() self.menu_item = gtk.MenuItem(self.name) self.video_config_menu = gtk.MenuItem('Set barcode scanner video config...') self.video_config_menu.connect('activate', self.on_video_config_menu__activate) self.metadata_menu = gtk.MenuItem('Edit experiment metadata...') self.metadata_menu.connect('activate', self.on_metadata_menu__activate) app = get_app() if not hasattr(app, 'experiment_log') or app.experiment_log is None: self.metadata_menu.set_sensitive(False) self.menu.append(self.video_config_menu) self.menu.append(self.metadata_menu) self.menu.show_all() self.menu_item.set_submenu(self.menu) self.menu_item.show_all() app.main_window_controller.menu_tools.append(self.menu_item)
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_connection_status(self): self.connection_status = "Not connected" app = get_app() connected = self.control_board.connected() if connected: name = self.control_board.name() version = self.control_board.hardware_version() firmware = self.control_board.software_version() n_channels = self.control_board.number_of_channels() serial_number = self.control_board.serial_number self.connection_status = ('%s v%s (Firmware: %s, S/N %03d)\n' '%d channels' % (name, version, firmware, serial_number, n_channels)) app.main_window_controller.label_control_board_status\ .set_text(self.connection_status)
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_plugin_enable(self): self.connect() if not self.initialized: app = get_app() self.tools_menu_item = gtk.MenuItem("DropBot DX") app.main_window_controller.menu_tools.append(self.tools_menu_item) self.tools_menu = gtk.Menu() self.tools_menu.show() self.tools_menu_item.set_submenu(self.tools_menu) menu_item = gtk.MenuItem("Launch Dstat interface") self.tools_menu.append(menu_item) menu_item.connect("activate", self.on_launch_dstat_interface) menu_item.show() menu_item = gtk.MenuItem("Set step Dstat parameters file...") self.tools_menu.append(menu_item) menu_item.connect("activate", self.on_set_dstat_params_file) menu_item.show() self.edit_config_menu_item = \ gtk.MenuItem("Edit configuration settings...") self.tools_menu.append(self.edit_config_menu_item) self.edit_config_menu_item.connect("activate", self.on_edit_configuration) self.view_menu_item = gtk.MenuItem("DropBot DX") app.main_window_controller.menu_view.append(self.view_menu_item) self.view_menu = gtk.Menu() self.view_menu.show() self.view_menu_item.set_submenu(self.view_menu) menu_item = gtk.MenuItem("View DStat results...") self.view_menu.append(menu_item) # Display DStat summary table in dialog. menu_item.connect("activate", lambda *args: dataframe_display_dialog (self.dstat_summary_frame(unit='n'), message='DStat result summary')) menu_item.show() self.initialized = True self.tools_menu_item.show() self.view_menu_item.show() if self.connected(): self.edit_config_menu_item.show() super(DropBotDxAccessoriesPlugin, self).on_plugin_enable()
def update_excel_results(self, launch=False): ''' Update output Excel results file. .. versionadded:: 0.19 Parameters ---------- launch : bool, optional If ``True``, launch Excel spreadsheet after writing. ''' app = get_app() log_dir = app.experiment_log.get_log_path() # Update Excel file with latest PMT results. output_path = log_dir.joinpath('PMT_readings.xlsx') data_files = list(log_dir.files('PMT_readings-*.ndjson')) if not data_files: logger.debug('No PMT readings files found.') return logger.info(TEMPLATE_PATH) def _threadsafe_write_results(): logger.info(launch) while True: try: _write_results(TEMPLATE_PATH, output_path, data_files) if launch: try: output_path.launch() except Exception: pass break except IOError as e: logger.info("I/O error({0}): {1}".format(e.errno, e.strerror)) response = yesno('Error writing PMT summary to Excel ' 'spreadsheet output path: `%s`.\n\nTry ' 'again?' %output_path) if response == gtk.RESPONSE_NO: break # Schedule writing of results to occur in main GTK # thread in case confirmation dialog needs to be # displayed. gobject.idle_add(_threadsafe_write_results)
def on_step_swapped(self, original_step_number, new_step_number): ''' Handler called when a new step is activated/selected. Parameters ---------- original_step_number : int Step number of previously activated step. new_step_number : int Step number of newly activated step. ''' # Step options have changed. app = get_app() if app.realtime_mode and not app.running: # Apply step options. options = self.get_step_options() self.apply_step_options(options)
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 find_next_step_label(self, step_i): ''' .. versionchanged:: 2.1.3 Add :data:`step_i` parameter. Parameters ---------- step_i : int Step number to find labels relative to. ''' app = get_app() for i in xrange(step_i + 1, len(app.protocol.steps)): next_step_label = self.get_step_value('label', step_number=i) if next_step_label: return i, next_step_label else: return None, ''
def update_connection_status(self): self.connection_status = "Not connected" app = get_app() connected = self.control_board != None if connected: properties = self.control_board.properties version = self.control_board.hardware_version n_channels = self.control_board.number_of_channels id = self.control_board.id uuid = self.control_board.uuid self.connection_status = ( '%s v%s (Firmware: %s, id: %s, uuid: %s)\n' '%d channels' % (properties['display_name'], version, properties['software_version'], id, str(uuid)[:8], n_channels)) app.main_window_controller.label_control_board_status\ .set_text(self.connection_status)
def on_step_options_changed(self, plugin, step_number): ''' Handler called when field values for the specified plugin and step. Parameters ---------- plugin : str Name of plugin. step_number : int Step index number. ''' # Step options have changed. app = get_app() if all([plugin == self.plugin_name, app.realtime_mode, step_number == app.protocol.current_step_number]): # Apply step options. options = self.get_step_options() self.apply_step_options(options)
def on_plugin_enable(self): super(DropBotDxPlugin, self).on_plugin_enable() self.cleanup_plugin() # Initialize 0MQ hub plugin and subscribe to hub messages. self.plugin = DmfZmqPlugin(self, self.name, get_hub_uri(), subscribe_options={zmq.SUBSCRIBE: ''}) # Initialize sockets. self.plugin.reset() # Periodically process outstanding message received on plugin sockets. self.plugin_timeout_id = gtk.timeout_add(10, self.plugin.check_sockets) self.check_device_name_and_version() if get_app().protocol: self.on_step_run() self._update_protocol_grid()