Exemple #1
0
    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)
Exemple #3
0
    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])
Exemple #4
0
 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])
Exemple #10
0
    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)
Exemple #11
0
    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)
Exemple #15
0
    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 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()
Exemple #17
0
 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()
Exemple #18
0
    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
Exemple #19
0
 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:
         _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)
Exemple #24
0
 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()
Exemple #25
0
    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
Exemple #28
0
 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())
Exemple #29
0
 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()
Exemple #31
0
    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)
Exemple #36
0
 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()
Exemple #48
0
    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)
Exemple #49
0
    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 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 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)
Exemple #54
0
    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()