Example #1
0
 def insert_step(self, step_number=None, value=None):
     if step_number is None:
         step_number = self.current_step_number
     if value is None:
         value = Step()
     self.steps.insert(step_number, value)
     emit_signal('on_step_created', args=[self.current_step_number])
Example #2
0
    def check_impedance(self, options, n_voltage_adjustments=0):
        """
        Check the device impedance.
        
        Note that this function blocks until it returns.
        """
        # increment the number of adjustment attempts
        self.n_voltage_adjustments = n_voltage_adjustments

        app_values = self.get_app_values()
        test_options = deepcopy(options)
        # take 5 samples to allow signal/gain to stabilize
        test_options.duration = app_values['sampling_time_ms'] * 5
        test_options.feedback_options = FeedbackOptions(feedback_enabled=True,
                                                        action=RetryAction())
        state = np.zeros(self.control_board.number_of_channels())
        (V_hv, hv_resistor, V_fb, fb_resistor) = \
            self.control_board.measure_impedance(
                app_values['sampling_time_ms'],
                int(math.ceil(test_options.duration/
                    app_values['sampling_time_ms'])),
                app_values['delay_between_samples_ms'],
                state)
        results = FeedbackResults(test_options, app_values['sampling_time_ms'],
                                  app_values['delay_between_samples_ms'], V_hv,
                                  hv_resistor, V_fb, fb_resistor,
                                  self.get_actuated_area(),
                                  self.control_board.calibration, 0)
        emit_signal("on_device_impedance_update", results)
        return results
Example #3
0
 def goto_step(self, step_number):
     logging.debug('[Protocol].goto_step(%s)' % step_number)
     self.current_step_number = step_number
     original_step_number = self.current_step_number
     for plugin_name in self.current_step().plugins:
         emit_signal('on_step_options_swapped',
                 [plugin_name,
                 original_step_number,
                 step_number],
                 interface=IPlugin)
     with closing(StringIO()) as sio:
         for plugin_name, fields in self.plugin_fields.iteritems():
             observers = ExtensionPoint(IPlugin)
             service = observers.service(plugin_name)
             if service is None:
                 # We can end up here if a service has been disabled.
                 # TODO: protocol.plugin_fields should likely be updated
                 #    whenever a plugin is enabled/disabled...
                 continue
             if hasattr(service, 'get_step_value'):
                 print >> sio, '[ProtocolController] plugin.name=%s field_values='\
                         % (plugin_name),
                 print >> sio, [service.get_step_value(f) for f in fields]
         logging.debug(sio.getvalue())
     emit_signal('on_step_swapped', [original_step_number, step_number])
Example #4
0
    def check_impedance(self, options, n_voltage_adjustments=0):
        """
        Check the device impedance.
        
        Note that this function blocks until it returns.
        """
        # increment the number of adjustment attempts
        self.n_voltage_adjustments = n_voltage_adjustments

        app_values = self.get_app_values()
        test_options = deepcopy(options)
        # take 5 samples to allow signal/gain to stabilize
        test_options.duration = app_values['sampling_time_ms']*5
        test_options.feedback_options = FeedbackOptions(
            feedback_enabled=True, action=RetryAction())
        state = np.zeros(self.control_board.number_of_channels())
        (V_hv, hv_resistor, V_fb, fb_resistor) = \
            self.control_board.measure_impedance(
                app_values['sampling_time_ms'],
                int(math.ceil(test_options.duration/ 
                    app_values['sampling_time_ms'])),
                app_values['delay_between_samples_ms'],
                state)
        results = FeedbackResults(test_options,
            app_values['sampling_time_ms'],
            app_values['delay_between_samples_ms'],
            V_hv,
            hv_resistor,
            V_fb,
            fb_resistor,
            self.get_actuated_area(),
            self.control_board.calibration,
            0)
        emit_signal("on_device_impedance_update", results)
        return results
Example #5
0
 def emit(self, record):
     if record.levelname == 'DEBUG':
         plugin_manager.emit_signal('on_debug', [record], interface=ILoggingPlugin)
     elif record.levelname == 'INFO':
         plugin_manager.emit_signal('on_info', [record], interface=ILoggingPlugin)
     elif record.levelname == 'WARNING':
         plugin_manager.emit_signal('on_warning', [record], interface=ILoggingPlugin)
     elif record.levelname == 'ERROR':
         plugin_manager.emit_signal('on_error', [record], interface=ILoggingPlugin)
     elif record.levelname == 'CRITICAL':
         plugin_manager.emit_signal('on_critical', [record], interface=ILoggingPlugin)
Example #6
0
    def on_device_impedance_update(self, impedance):
        app = get_app()
        app.main_window_controller.label_control_board_status. \
            set_text(self.connection_status + ", Voltage: %.1f V" % \
                     impedance.V_actuation()[-1])
        options = impedance.options
        feedback_options = impedance.options.feedback_options

        app_values = self.get_app_values()

        if impedance.V_actuation()[-1] < 5.0:
            logger.error(
                "Low voltage detected. Please check that the amplifier is on.")
        else:
            voltage = options.voltage
            if feedback_options.action.__class__ == RetryAction:
                attempt = app.protocol.current_step_attempt
                voltage += feedback_options.action.increase_voltage * \
                        attempt
            logger.info(
                '[DmfControlBoardPlugin].on_device_impedance_update():')
            logger.info('\tset_voltage=%.1f, measured_voltage=%.1f, '
                        'error=%.1f%%' %
                        (voltage, impedance.V_actuation()[-1], 100 *
                         (impedance.V_actuation()[-1] - voltage) / voltage))

            # check that the signal is within tolerance
            if abs(impedance.V_actuation()[-1]-voltage) > \
                self.control_board.voltage_tolerance():

                # allow maximum of 5 adjustment attempts
                if self.control_board.auto_adjust_amplifier_gain() and \
                self.n_voltage_adjustments is not None and \
                self.n_voltage_adjustments<5:
                    logger.info('\tn_voltage_adjustments=%d' % \
                                self.n_voltage_adjustments)
                    emit_signal("set_voltage",
                                voltage,
                                interface=IWaveformGenerator)
                    self.check_impedance(options,
                                         self.n_voltage_adjustments + 1)
                else:
                    self.n_voltage_adjustments = None
                    logger.error("Unable to achieve the specified voltage.")


            if self.control_board.auto_adjust_amplifier_gain() and not \
            self.amplifier_gain_initialized:
                self.amplifier_gain_initialized = True
                logger.info('Amplifier gain initialized (gain=%.1f)' % \
                            self.control_board.amplifier_gain())
Example #7
0
    def delete_step(self, step_number):
        step_to_remove = self.steps[step_number]
        del self.steps[step_number]
        emit_signal('on_step_removed', args=[step_number, step_to_remove])

        if len(self.steps) == 0:
            # If we deleted the last remaining step, we need to insert a new
            # default Step
            self.insert_step(0, Step())
            self.goto_step(0)
        elif self.current_step_number == len(self.steps):
            self.goto_step(step_number - 1)
        else:
            self.goto_step(self.current_step_number)
Example #8
0
 def get_impedance_data(self, options):
     """
     This function wraps the control_board.get_impedance_data() function
     and sends an on_device_impedance_update.
     """
     app_values = self.get_app_values()
     (V_hv, hv_resistor, V_fb, fb_resistor) = \
         self.control_board.get_impedance_data()
     results = FeedbackResults(options, app_values['sampling_time_ms'],
                               app_values['delay_between_samples_ms'], V_hv,
                               hv_resistor, V_fb, fb_resistor,
                               self.get_actuated_area(),
                               self.control_board.calibration, 0)
     emit_signal("on_device_impedance_update", results)
     return (V_hv, hv_resistor, V_fb, fb_resistor)
Example #9
0
 def set_step_values(self, values_dict, step_number=None):
     step_number = self.get_step(step_number)
     el = self.StepFields(value=values_dict)
     try:
         if not el.validate():
             raise ValueError()
         options = self.get_step_options(step_number=step_number)
         for name, field in el.iteritems():
             if field.value is None:
                 continue
             else:
                 setattr(options, name, field.value)
     finally:
         emit_signal('on_step_options_changed', [self.name, step_number],
                 interface=IPlugin)
Example #10
0
 def emit(self, record):
     if record.levelname == 'DEBUG':
         plugin_manager.emit_signal('on_debug', [record],
                                    interface=ILoggingPlugin)
     elif record.levelname == 'INFO':
         plugin_manager.emit_signal('on_info', [record],
                                    interface=ILoggingPlugin)
     elif record.levelname == 'WARNING':
         plugin_manager.emit_signal('on_warning', [record],
                                    interface=ILoggingPlugin)
     elif record.levelname == 'ERROR':
         plugin_manager.emit_signal('on_error', [record],
                                    interface=ILoggingPlugin)
     elif record.levelname == 'CRITICAL':
         plugin_manager.emit_signal('on_critical', [record],
                                    interface=ILoggingPlugin)
Example #11
0
    def on_device_impedance_update(self, impedance):
        app = get_app()
        app.main_window_controller.label_control_board_status. \
            set_text(self.connection_status + ", Voltage: %.1f V" % \
                     impedance.V_actuation()[-1])
        options = impedance.options
        feedback_options = impedance.options.feedback_options

        app_values = self.get_app_values()            

        if impedance.V_actuation()[-1]<5.0:
            logger.error("Low voltage detected. Please check that the amplifier is on.")
        else:
            voltage = options.voltage
            if feedback_options.action.__class__ == RetryAction:
                attempt = app.protocol.current_step_attempt
                voltage += feedback_options.action.increase_voltage * \
                        attempt
            logger.info('[DmfControlBoardPlugin].on_device_impedance_update():')
            logger.info('\tset_voltage=%.1f, measured_voltage=%.1f, '
                'error=%.1f%%' % (voltage, impedance.V_actuation()[-1],
                100*(impedance.V_actuation()[-1]-voltage)/voltage))
            
            # check that the signal is within tolerance
            if abs(impedance.V_actuation()[-1]-voltage) > \
                self.control_board.voltage_tolerance():
                
                # allow maximum of 5 adjustment attempts
                if self.control_board.auto_adjust_amplifier_gain() and \
                self.n_voltage_adjustments is not None and \
                self.n_voltage_adjustments<5:
                        logger.info('\tn_voltage_adjustments=%d' % \
                                    self.n_voltage_adjustments)
                        emit_signal("set_voltage", voltage,
                            interface=IWaveformGenerator)
                        self.check_impedance(options,
                                             self.n_voltage_adjustments+1)
                else:
                    self.n_voltage_adjustments = None
                    logger.error("Unable to achieve the specified voltage.")
             
             
            if self.control_board.auto_adjust_amplifier_gain() and not \
            self.amplifier_gain_initialized:
                self.amplifier_gain_initialized = True
                logger.info('Amplifier gain initialized (gain=%.1f)' % \
                            self.control_board.amplifier_gain())
Example #12
0
    def _callback_sweep_frequency(self,
                                  options,
                                  results,
                                  state,
                                  frequencies,
                                  first_call=False):
        logger.debug('[DmfControlBoardPlugin] ' '_callback_sweep_frequency')
        app = get_app()
        app_values = self.get_app_values()

        # if this isn'g the first call, we need to retrieve the data from the
        # previous call
        if first_call == False:
            frequency = frequencies.pop(0)
            (V_hv, hv_resistor, V_fb, fb_resistor) = \
                self.get_impedance_data(options)
            results.add_frequency_step(frequency, V_hv, hv_resistor, V_fb,
                                       fb_resistor)
            app.experiment_log.add_data({"SweepFrequencyResults": results},
                                        self.name)
            logger.debug("V_actuation=%s" % results.V_actuation())
            logger.debug("Z_device=%s" % results.Z_device())

        # if there are frequencies left to sweep
        if len(frequencies):
            frequency = frequencies[0]
            emit_signal("set_frequency",
                        frequency,
                        interface=IWaveformGenerator)
            options.frequency = frequency
            self.control_board.measure_impedance_non_blocking(
                app_values['sampling_time_ms'],
                int(
                    math.ceil(options.duration /
                              app_values['sampling_time_ms'])),
                app_values['delay_between_samples_ms'], state)
            logger.debug('[DmfControlBoardPlugin] _callback_sweep_frequency: '
                         'timeout_add(%d, _callback_sweep_frequency)' %
                         options.duration)
            self.timeout_id = \
                gobject.timeout_add(options.duration,
                                    self._callback_sweep_frequency,
                                    options, results, state, frequencies)
        else:
            self.step_complete()
        return False  # stop the timeout from refiring
    def run(self):
        # Empty plugin form vbox
        # Get list of app option forms
        self.forms = emit_signal('get_app_form_class')
        self.form_views = {}
        self.clear_form()
        app = get_app()
        self.no_gui_names = set()
        for name, form in self.forms.iteritems():
            # For each form, generate a pygtkhelpers formview and append the view
            # onto the end of the plugin vbox
            
            if form is None:
                schema_entries = []
            else:
                # Only include fields that do not have show_in_gui set to False in
                # 'properties' dictionary
                schema_entries = [f for f in form.field_schema\
                        if f.properties.get('show_in_gui', True)]
            if not schema_entries:
                self.no_gui_names.add(name)
                continue
            gui_form = Form.of(*schema_entries)
            FormView.schema_type = gui_form
            self.form_views[name] = FormView()
            if name in app.core_plugins:
                self.core_plugins_vbox.pack_start(self.form_views[name].widget)
                self.frame_core_plugins.show()
            else:
                expander = gtk.Expander()
                expander.set_label(name)
                expander.set_expanded(True)
                expander.add(self.form_views[name].widget)
                self.plugin_form_vbox.pack_start(expander)
        for form_name, form in self.forms.iteritems():
            if form_name in self.no_gui_names:
                continue
            form_view = self.form_views[form_name]
            values = self._get_app_values(form_name)
            fields = set(values.keys()).intersection(form_view.form.fields)
            for field in fields:
                value = values[field]
                proxy = proxy_for(getattr(form_view, field))
                proxy.set_widget_value(value)
                form_field = form_view.form.fields[field]
                form_field.label_widget.set_text(
                        re.sub(r'_',  ' ', field).title())

        self.dialog.show_all()

        response = self.dialog.run()
        if response == gtk.RESPONSE_OK:
            self.apply()
        elif response == gtk.RESPONSE_CANCEL:
            pass
        self.dialog.hide()
        return response
Example #14
0
 def set_step_values(self, values_dict, step_number=None):
     step_number = self.get_step_number(step_number)
     logger.debug('[DmfControlBoardPlugin] set_step[%d]_values(): '\
                 'values_dict=%s' % (step_number, values_dict,))
     el = self.StepFields(value=values_dict)
     try:
         if not el.validate():
             raise ValueError()            
         options = self.get_step_options(step_number=step_number)
         for name, field in el.iteritems():
             if field.value is None:
                 continue
             if name in self._feedback_fields:
                 setattr(options.feedback_options, name, field.value)
             else:
                 setattr(options, name, field.value)
     finally:
         emit_signal('on_step_options_changed', [self.name, step_number],
                     interface=IPlugin)
Example #15
0
    def _callback_sweep_frequency(self, options, results, state, frequencies,
                                  first_call=False):
        logger.debug('[DmfControlBoardPlugin] '
                     '_callback_sweep_frequency')
        app = get_app()
        app_values = self.get_app_values()

        # if this isn'g the first call, we need to retrieve the data from the
        # previous call
        if first_call==False:
            frequency = frequencies.pop(0)
            (V_hv, hv_resistor, V_fb, fb_resistor) = \
                self.get_impedance_data(options)
            results.add_frequency_step(frequency, V_hv, hv_resistor, V_fb,
                                       fb_resistor)
            app.experiment_log.add_data(
                {"SweepFrequencyResults":results}, self.name)
            logger.debug("V_actuation=%s" % results.V_actuation())
            logger.debug("Z_device=%s" % results.Z_device())

        # if there are frequencies left to sweep
        if len(frequencies):
            frequency  = frequencies[0]
            emit_signal("set_frequency",
                        frequency,
                        interface=IWaveformGenerator)
            options.frequency = frequency
            self.control_board.measure_impedance_non_blocking(
                app_values['sampling_time_ms'],
                int(math.ceil(options.duration/ 
                    app_values['sampling_time_ms'])),
                app_values['delay_between_samples_ms'],
                state)
            logger.debug('[DmfControlBoardPlugin] _callback_sweep_frequency: '
                         'timeout_add(%d, _callback_sweep_frequency)' %
                         options.duration)
            self.timeout_id = \
                gobject.timeout_add(options.duration,
                                    self._callback_sweep_frequency,
                                    options, results, state, frequencies)
        else:
            self.step_complete()
        return False # stop the timeout from refiring
Example #16
0
 def set_step_values(self, values_dict, step_number=None):
     step_number = self.get_step_number(step_number)
     logger.debug('[DmfControlBoardPlugin] set_step[%d]_values(): '\
                 'values_dict=%s' % (step_number, values_dict,))
     el = self.StepFields(value=values_dict)
     try:
         if not el.validate():
             raise ValueError()
         options = self.get_step_options(step_number=step_number)
         for name, field in el.iteritems():
             if field.value is None:
                 continue
             if name in self._feedback_fields:
                 setattr(options.feedback_options, name, field.value)
             else:
                 setattr(options, name, field.value)
     finally:
         emit_signal('on_step_options_changed', [self.name, step_number],
                     interface=IPlugin)
Example #17
0
 def get_impedance_data(self, options):
     """
     This function wraps the control_board.get_impedance_data() function
     and sends an on_device_impedance_update.
     """
     app_values = self.get_app_values()
     (V_hv, hv_resistor, V_fb, fb_resistor) = \
         self.control_board.get_impedance_data()
     results = FeedbackResults(options,
         app_values['sampling_time_ms'],
         app_values['delay_between_samples_ms'],
         V_hv,
         hv_resistor,
         V_fb,
         fb_resistor,
         self.get_actuated_area(),
         self.control_board.calibration,
         0)
     emit_signal("on_device_impedance_update", results)
     return (V_hv, hv_resistor, V_fb, fb_resistor)
Example #18
0
    def on_select_script(self, widget, data=None):
        """
        Handler called when the user clicks on
        "PSTrace step config..." in the "Tools" menu.
        """
        app = get_app()
        options = self.get_step_options()
        form = Form.of(Filepath.named('script').using(default=options.script,
                                                      optional=True))
        dialog = FormViewDialog()
        valid, response =  dialog.run(form)

        step_options_changed = False
        if valid and (response['script'] and response['script'] !=
                      options.script):
            options.script = response['script']
            step_options_changed = True
        if step_options_changed:
            emit_signal('on_step_options_changed', [self.name,
                                                    app.protocol
                                                    .current_step_number],
                        interface=IPlugin)
Example #19
0
 def set_app_values(self, values_dict):
     if not values_dict:
         return
     if not hasattr(self, 'name'):
         raise NotImplementedError
     for k in values_dict.keys():
         if k not in self.AppFields.field_schema_mapping.keys():
             logger.error("Invalid key (%s) in configuration file section: "
                          "[%s]." % (k, self.name))
             # remove invalid key from config file
             values_dict.pop(k)
     elements = self.AppFields(value=values_dict)
     if not elements.validate():
         raise ValueError('Invalid values: %s' % elements.errors)
     values = dict([(k, v.value)
                    for k, v in elements.iteritems()
                    if v.value is not None])
     app = get_app()
     app_data = app.get_data(self.name)
     app_data.update(values)
     app.set_data(self.name, app_data)
     emit_signal('on_app_options_changed', [self.name], interface=IPlugin)
Example #20
0
    def set_step_values(self, values_dict, step_number=None):
        '''
        Consider a scenario where most step options are simple types that are
        supported by `flatland` and can be listed in `StepOptions` (e.g.,
        `Integer`, `Boolean`, etc.), but there is at least one step option that
        is a type not supported by `flatland`, such as a `numpy.array`.

        Currently, this requires custom handling for all methods related to
        step options, as in the case of the DMF control board. Instead, during
        validation of step option values, we could simply exclude options that
        are not listed in the `StepOptions` definition from the validation, but
        pass along *all* values to be saved in the protocol.

        This should maintain backwards compatibility while simplifying the
        addition of arbitrary Python data types as step options.
        '''
        step_number = self.get_step_number(step_number)
        logger.debug('[StepOptionsController] set_step[%d]_values(): '
                     'values_dict=%s' % (step_number, values_dict))
        validate_dict = dict([(k, v) for k, v in values_dict.iteritems()
                              if k in self.StepFields.field_schema_mapping])
        validation_result = self.StepFields(value=validate_dict)
        if not validation_result.validate():
            raise ValueError('Invalid values: %s' % validation_result.errors)
        values = values_dict.copy()
        for name, field in validation_result.iteritems():
            if field.value is None:
                continue
            values[name] = field.value

        if values:
            app = get_app()
            step = app.protocol.steps[step_number]
            step.set_data(self.name, values)
            emit_signal('on_step_options_changed', [self.name, step_number],
                        interface=IPlugin)
Example #21
0
    def run(self):
        # set realtime mode to false on startup
        if self.name in self.config.data and \
        'realtime_mode' in self.config.data[self.name]:
            self.config.data[self.name]['realtime_mode'] = False

        plugin_manager.emit_signal('on_plugin_enable')
        log_file = self.get_app_values()['log_file']
        if not log_file:
            self.set_app_values({'log_file':
                                 path(self.config['data_dir'])
                                 .joinpath('microdrop.log')})

        self.update_check()
        plugin_manager.load_plugins(self.config['plugins']['directory'])
        self.update_log_file()

        logger.info('User data directory: %s' % self.config['data_dir'])
        logger.info('Plugins directory: %s' %
                    self.config['plugins']['directory'])
        logger.info('Devices directory: %s' % self.get_device_directory())

        FormViewDialog.default_parent = self.main_window_controller.view
        self.builder.connect_signals(self.signals)
        self.update_plugins()

        observers = {}
        # Enable plugins according to schedule requests
        for package_name in self.config['plugins']['enabled']:
            try:
                service = plugin_manager. \
                    get_service_instance_by_package_name(package_name)
                observers[service.name] = service
            except Exception, e:
                self.config['plugins']['enabled'].remove(package_name)
                logger.error(e)
Example #22
0
        # if we successfully loaded a device
        if self.dmf_device:
            # reapply the protocol name to the config file
            self.config['protocol']['name'] = protocol_name

            # load the protocol
            if self.config['protocol']['name']:
                directory = self.get_device_directory()
                if directory:
                    filename = os.path.join(directory,
                        self.config['dmf_device']['name'],
                        "protocols",
                        self.config['protocol']['name'])
                    self.protocol_controller.load_protocol(filename)

        plugin_manager.emit_signal('on_gui_ready')
        self.main_window_controller.main()

    def _set_log_level(self, level):
        if level=='debug':
            logger.setLevel(DEBUG)
        elif level=='info':
            logger.setLevel(INFO)
        elif level=='warning':
            logger.setLevel(WARNING)
        elif level=='error':
            logger.setLevel(ERROR)
        elif level=='critical':
            logger.setLevel(CRITICAL)
        else:
            raise TypeError
Example #23
0
 def complete_step(self, return_value=None):
     app = get_app()
     if app.running or app.realtime_mode:
         emit_signal('on_step_complete', [self.name, return_value])
Example #24
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.
        """
        logger.debug('[DmfControlBoardPlugin] 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('[DmfControlBoardPlugin] options=%s dmf_options=%s' % \
                     (options, dmf_options))
        feedback_options = options.feedback_options
        app_values = self.get_app_values()

        start_time = time.time()
        return_value = None

        try:
            if self.control_board.connected() and \
                (app.realtime_mode or app.running):
                
                # initialize the amplifier gain
                if self.control_board.auto_adjust_amplifier_gain() and \
                    not self.amplifier_gain_initialized:
                    emit_signal("set_frequency",
                                options.frequency,
                                interface=IWaveformGenerator)
                    emit_signal("set_voltage", options.voltage,
                                interface=IWaveformGenerator)
                    self.check_impedance(options)

                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)])
                else:
                    assert(len(state) == max_channels)
    
                if feedback_options.feedback_enabled:
                    # calculate the total area of actuated electrodes
                    area = self.get_actuated_area()
                    
                    if feedback_options.action.__class__ == RetryAction:
                        attempt = app.protocol.current_step_attempt
                        if attempt <= feedback_options.action.max_repeats:
                            voltage = options.voltage + \
                                feedback_options.action.increase_voltage * \
                                attempt
                            frequency = options.frequency
                            emit_signal("set_voltage", voltage,
                                        interface=IWaveformGenerator)
                            if frequency != self.current_frequency:
                                emit_signal("set_frequency", frequency,
                                            interface=IWaveformGenerator)
                                self.check_impedance(options)
                            self.control_board.measure_impedance_non_blocking(
                                app_values['sampling_time_ms'],
                                int(math.ceil(options.duration/ 
                                    app_values['sampling_time_ms'])),
                                app_values['delay_between_samples_ms'],
                                state)
                            logger.debug('[DmfControlBoardPlugin] on_step_run: '
                                         'timeout_add(%d, _callback_retry_action'
                                         '_completed)' % options.duration)
                            self.timeout_id = \
                                gobject.timeout_add(options.duration,
                                    self._callback_retry_action_completed,
                                    options)
                        else:
                            self.step_complete('Fail')
                        return
                    elif feedback_options.action.__class__ == \
                        SweepFrequencyAction:
                        frequencies = np.logspace(
                            np.log10(feedback_options.action.start_frequency),
                            np.log10(feedback_options.action.end_frequency),
                            int(feedback_options.action.n_frequency_steps)
                        ).tolist()
                        voltage = options.voltage
                        results = SweepFrequencyResults(feedback_options,
                            area,
                            self.control_board.calibration)
                        emit_signal("set_voltage", voltage,
                                    interface=IWaveformGenerator)
                        test_options = deepcopy(options)
                        self._callback_sweep_frequency(test_options,
                                                       results,
                                                       state,
                                                       frequencies,
                                                       first_call=True)
                        return
                    elif feedback_options.action.__class__==SweepVoltageAction:
                        voltages = np.linspace(
                           feedback_options.action.start_voltage,
                           feedback_options.action.end_voltage,
                           feedback_options.action.n_voltage_steps).tolist()
                        frequency = options.frequency
                        if frequency != self.current_frequency:
                            emit_signal("set_voltage", options.voltage,
                                        interface=IWaveformGenerator)
                            emit_signal("set_frequency", frequency,
                                        interface=IWaveformGenerator)
                            self.check_impedance(options)
                        results = SweepVoltageResults(feedback_options,
                            area,
                            frequency,
                            self.control_board.calibration)
                        test_options = deepcopy(options)
                        self._callback_sweep_voltage(test_options,
                                                     results,
                                                     state,
                                                     voltages,
                                                     first_call=True)
                        return
                else:
                    emit_signal("set_frequency",
                                options.frequency,
                                interface=IWaveformGenerator)
                    emit_signal("set_voltage", options.voltage,
                                interface=IWaveformGenerator)
                    self.check_impedance(options)
                    self.control_board.state_of_all_channels = state
            # turn off all electrodes if we're not in realtime mode and not
            # running a protocol
            elif self.control_board.connected() and \
                not app.realtime_mode and not app.running:
                # turn off all electrodes
                self.control_board.set_state_of_all_channels(
                    np.zeros(self.control_board.number_of_channels())
                )
            
            # if a protocol is running, wait for the specified minimum duration
            if app.running:
                logger.debug('[DmfControlBoardPlugin] 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()
        except DeviceScaleNotSet:
            logger.error("Please set the area of one of your electrodes.")
Example #25
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.
        """
        logger.debug('[DmfControlBoardPlugin] 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('[DmfControlBoardPlugin] options=%s dmf_options=%s' % \
                     (options, dmf_options))
        feedback_options = options.feedback_options
        app_values = self.get_app_values()

        start_time = time.time()
        return_value = None

        try:
            if self.control_board.connected() and \
                (app.realtime_mode or app.running):

                # initialize the amplifier gain
                if self.control_board.auto_adjust_amplifier_gain() and \
                    not self.amplifier_gain_initialized:
                    emit_signal("set_frequency",
                                options.frequency,
                                interface=IWaveformGenerator)
                    emit_signal("set_voltage",
                                options.voltage,
                                interface=IWaveformGenerator)
                    self.check_impedance(options)

                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)])
                else:
                    assert (len(state) == max_channels)

                if feedback_options.feedback_enabled:
                    # calculate the total area of actuated electrodes
                    area = self.get_actuated_area()

                    if feedback_options.action.__class__ == RetryAction:
                        attempt = app.protocol.current_step_attempt
                        if attempt <= feedback_options.action.max_repeats:
                            voltage = options.voltage + \
                                feedback_options.action.increase_voltage * \
                                attempt
                            frequency = options.frequency
                            emit_signal("set_voltage",
                                        voltage,
                                        interface=IWaveformGenerator)
                            if frequency != self.current_frequency:
                                emit_signal("set_frequency",
                                            frequency,
                                            interface=IWaveformGenerator)
                                self.check_impedance(options)
                            self.control_board.measure_impedance_non_blocking(
                                app_values['sampling_time_ms'],
                                int(
                                    math.ceil(options.duration /
                                              app_values['sampling_time_ms'])),
                                app_values['delay_between_samples_ms'], state)
                            logger.debug(
                                '[DmfControlBoardPlugin] on_step_run: '
                                'timeout_add(%d, _callback_retry_action'
                                '_completed)' % options.duration)
                            self.timeout_id = \
                                gobject.timeout_add(options.duration,
                                    self._callback_retry_action_completed,
                                    options)
                        else:
                            self.step_complete('Fail')
                        return
                    elif feedback_options.action.__class__ == \
                        SweepFrequencyAction:
                        frequencies = np.logspace(
                            np.log10(feedback_options.action.start_frequency),
                            np.log10(feedback_options.action.end_frequency),
                            int(feedback_options.action.n_frequency_steps)
                        ).tolist()
                        voltage = options.voltage
                        results = SweepFrequencyResults(
                            feedback_options, area,
                            self.control_board.calibration)
                        emit_signal("set_voltage",
                                    voltage,
                                    interface=IWaveformGenerator)
                        test_options = deepcopy(options)
                        self._callback_sweep_frequency(test_options,
                                                       results,
                                                       state,
                                                       frequencies,
                                                       first_call=True)
                        return
                    elif feedback_options.action.__class__ == SweepVoltageAction:
                        voltages = np.linspace(
                            feedback_options.action.start_voltage,
                            feedback_options.action.end_voltage,
                            feedback_options.action.n_voltage_steps).tolist()
                        frequency = options.frequency
                        if frequency != self.current_frequency:
                            emit_signal("set_voltage",
                                        options.voltage,
                                        interface=IWaveformGenerator)
                            emit_signal("set_frequency",
                                        frequency,
                                        interface=IWaveformGenerator)
                            self.check_impedance(options)
                        results = SweepVoltageResults(
                            feedback_options, area, frequency,
                            self.control_board.calibration)
                        test_options = deepcopy(options)
                        self._callback_sweep_voltage(test_options,
                                                     results,
                                                     state,
                                                     voltages,
                                                     first_call=True)
                        return
                else:
                    emit_signal("set_frequency",
                                options.frequency,
                                interface=IWaveformGenerator)
                    emit_signal("set_voltage",
                                options.voltage,
                                interface=IWaveformGenerator)
                    self.check_impedance(options)
                    self.control_board.state_of_all_channels = state
            # turn off all electrodes if we're not in realtime mode and not
            # running a protocol
            elif self.control_board.connected() and \
                not app.realtime_mode and not app.running:
                # turn off all electrodes
                self.control_board.set_state_of_all_channels(
                    np.zeros(self.control_board.number_of_channels()))

            # if a protocol is running, wait for the specified minimum duration
            if app.running:
                logger.debug('[DmfControlBoardPlugin] 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()
        except DeviceScaleNotSet:
            logger.error("Please set the area of one of your electrodes.")
Example #26
0
 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])