def on_button_export_data_clicked(self, widget, data=None):
        export_path = path(
            os.path.join(self.results.log.directory,
                         str(self.results.log.experiment_id), 'data.xlsx'))
        if export_path.exists():
            result = yesno(
                'Export file already exists. Would like '
                'like to overwrite it? Selecting "No" will '
                'open the existing file.',
                default=gtk.RESPONSE_NO)

        if not export_path.exists() or result == gtk.RESPONSE_YES:
            export_data = emit_signal('on_export_experiment_log_data',
                                      self.results.log)

            if export_data:
                writer = pd.ExcelWriter(export_path, engine='openpyxl')
                for i, (plugin_name,
                        plugin_data) in enumerate(export_data.iteritems()):
                    for name, df in plugin_data.iteritems():
                        # Excel sheet names have a 31 character max
                        sheet_name = ('%03d-%s' % (i, name))[:31]
                        df.to_excel(writer, sheet_name)
                try:
                    writer.save()
                except IOError:
                    logger.warning(
                        "Error writing to file (maybe it is already open?).")
            else:
                logger.warning("No data to export.")

        # launch the file in excel
        if export_path.exists():
            export_path.startfile()
    def on_button_export_data_clicked(self, widget, data=None):
        export_path = path(os.path.join(self.results.log.directory,
                                        str(self.results.log.experiment_id),
                                        'data.xlsx'))
        if export_path.exists():
            result = yesno('Export file already exists. Would like '
                           'like to overwrite it? Selecting "No" will '
                           'open the existing file.', default=gtk.RESPONSE_NO)

        if not export_path.exists() or result == gtk.RESPONSE_YES:
            export_data = emit_signal('on_export_experiment_log_data',
                                      self.results.log)

            if export_data:
                writer = pd.ExcelWriter(export_path, engine='openpyxl')
                for i, (plugin_name, plugin_data) in enumerate(export_data.iteritems()):
                    for name, df in plugin_data.iteritems():
                         # Excel sheet names have a 31 character max
                         sheet_name = ('%03d-%s' % (i, name))[:31]
                         df.to_excel(writer, sheet_name)
                try:
                    writer.save()
                except IOError:
                    logger.warning("Error writing to file (maybe it is already open?).")
            else:
                logger.warning("No data to export.")

        # launch the file in excel
        if export_path.exists():
            export_path.startfile()
    def connect(self):
        '''
        Connect to dropbot-dx instrument.
        '''
        self.has_environment_data = False
        self.environment_sensor_master = None

        # if the dropbot dx plugin is installed and enabled, try getting its
        # reference
        try:
            service = get_service_instance_by_name('wheelerlab.dropbot_dx')
            if service.enabled():
                self.dropbot_dx_remote = service.control_board
        except:
            pass

        if self.dropbot_dx_remote is None:
            # if we couldn't get a reference, try finding a DropBot DX connected to
            # a serial port
            try:
                self.dropbot_dx_remote = dx.SerialProxy()
                host_version = self.dropbot_dx_remote.host_software_version
                remote_version = self.dropbot_dx_remote.remote_software_version

                if remote_version != host_version:
                    response = yesno('The DropBot DX firmware version (%s) '
                                     'does not match the driver version (%s). '
                                     'Update firmware?' % (remote_version,
                                                           host_version))
                    if response == gtk.RESPONSE_YES:
                        self.on_flash_firmware()

                # turn on the light by default
                self.dropbot_dx_remote.light_enabled = True
            except IOError:
                logger.warning('Could not connect to DropBot DX.')

        try:
            env = self.get_environment_state(self.dropbot_dx_remote).to_dict()
            logger.info('temp=%.1fC, Rel. humidity=%.1f%%' %
                        (env['temperature_celsius'],
                         100 * env['relative_humidity']))
            self.has_environment_data = True
            self.environment_sensor_master = self.dropbot_dx_remote
        except:
            service = get_service_instance_by_name('wheelerlab.dmf_control_board_plugin')
            if service.enabled() and service.control_board.connected():
                try:
                    env = self.get_environment_state(service.control_board).to_dict()
                    logger.info('temp=%.1fC, Rel. humidity=%.1f%%' %
                                (env['temperature_celsius'],
                                 100 * env['relative_humidity']))
                    self.has_environment_data = True
                    self.environment_sensor_master = service.control_board
                except:
                    pass

        # Get instrument identifier, if available.
        self.dropbot_dx_id = getattr(self.dropbot_dx_remote, 'id', None)
    def on_protocol_pause(self):
        app = get_app()

        # if we're on the last step of the last repetition, start a new
        # experiment log
        if ((app.protocol.current_step_number == len(app.protocol) - 1) and
            (app.protocol.current_repetition == app.protocol.n_repeats - 1)):

            result = yesno('Experiment complete. Would you like to start a new experiment?')
            if result == gtk.RESPONSE_YES:
                self.save()
    def on_protocol_pause(self):
        app = get_app()

        # if we're on the last step of the last repetition, start a new
        # experiment log
        if ((app.protocol.current_step_number == len(app.protocol) - 1) and
            (app.protocol.current_repetition == app.protocol.n_repeats - 1)):

            result = yesno(
                'Experiment complete. Would you like to start a new experiment?'
            )
            if result == gtk.RESPONSE_YES:
                self.save()
Example #6
0
 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
Example #7
0
    def open_board_connection(self):
        '''
        Establish serial connection to MR-Box peripheral board.
        '''
        # Try to connect to peripheral board through serial connection.

        # XXX Try to connect multiple times.
        # See [issue 1][1] on the [MR-Box peripheral board firmware
        # project][2].
        #
        # [1]: https://github.com/wheeler-microfluidics/mr-box-peripheral-board.py/issues/1
        # [2]: https://github.com/wheeler-microfluidics/mr-box-peripheral-board.py
        retry_count = 2
        for i in xrange(retry_count):
            try:
                self.board.close()
                self.board = None
            except Exception:
                pass

            try:

                self.board = mrbox.SerialProxy()

                host_software_version = utility.Version.fromstring(
                    str(self.board.host_software_version))
                remote_software_version = utility.Version.fromstring(
                    str(self.board.remote_software_version))

                # Offer to reflash the firmware if the major and minor versions
                # are not not identical. If micro versions are different,
                # the firmware is assumed to be compatible. See [1]
                #
                # [1]: https://github.com/wheeler-microfluidics/base-node-rpc/
                #              issues/8
                if any([host_software_version.major !=
                        remote_software_version.major,
                        host_software_version.minor !=
                        remote_software_version.minor]):
                    response = yesno("The MR-box peripheral board firmware "
                                     "version (%s) does not match the driver "
                                     "version (%s). Update firmware?" %
                                     (remote_software_version,
                                      host_software_version))
                    if response == gtk.RESPONSE_YES:
                        self.on_flash_firmware()

                # Serial connection to peripheral **successfully established**.
                logger.info('Serial connection to peripheral board '
                            '**successfully established**')

                logger.info('Peripheral board properties:\n%s',
                            self.board.properties)
                logger.info('Reset board state to defaults.')
                break
            except (serial.SerialException, IOError):
                time.sleep(1)
        else:
            # Serial connection to peripheral **could not be established**.
            logger.warning('Serial connection to peripheral board could not '
                           'be established.')
    def apply_notebook_dir(self, notebook_directory):
        '''
        Set the notebook directory to the specified directory.

        If the specified directory is empty or `None`, use the default
        directory (i.e., in the default Microdrop user directory) as the new
        directory path.

        If no directory was previously set and the specified directory does not
        exist, copy the default set of notebooks from the `microdrop` package
        to the new notebook directory.

        If a directory was previously set, copy the contents of the previous
        directory to the new directory (prompting the user to overwrite if the
        new directory already exists).
        '''
        app = get_app()

        print '[{notebook_directory = "%s"}]' % notebook_directory
        if not notebook_directory:
            # The notebook directory is not set (i.e., empty or `None`), so set
            # a default.
            data_directory = path(app.config.data['data_dir'])
            notebook_directory = data_directory.joinpath( 'notebooks')
            print '[{new notebook_directory = "%s"}]' % notebook_directory
            app_values = self.get_app_values().copy()
            app_values['notebook_directory'] = notebook_directory
            self.set_app_values(app_values)

        if self.previous_notebook_dir and (notebook_directory ==
                                           self.previous_notebook_dir):
            # If the data directory hasn't changed, we do nothing
            return False

        notebook_directory = path(notebook_directory)
        if self.previous_notebook_dir:
            notebook_directory.makedirs_p()
            if notebook_directory.listdir():
                result = yesno('Merge?', '''\
Target directory [%s] is not empty.  Merge contents with
current notebooks [%s] (overwriting common paths in the target
directory)?''' % (notebook_directory, self.previous_notebook_dir))
                if not result == gtk.RESPONSE_YES:
                    return False

            original_directory = path(self.previous_notebook_dir)
            for d in original_directory.dirs():
                copytree(d, notebook_directory.joinpath(d.name))
            for f in original_directory.files():
                f.copyfile(notebook_directory.joinpath(f.name))
            original_directory.rmtree()
        elif not notebook_directory.isdir():
            # if the notebook directory doesn't exist, copy the skeleton dir
            notebook_directory.parent.makedirs_p()
            skeleton_dir = path(pkg_resources.resource_filename('microdrop',
                                                                'static'))
            skeleton_dir.joinpath('notebooks').copytree(notebook_directory)
        self.previous_notebook_dir = notebook_directory
        # Set the default template directory of the IPython notebook manager
        # widget to the notebooks directory.
        self.notebook_manager_view.template_dir = notebook_directory
    def apply_notebook_dir(self, notebook_directory):
        '''
        Set the notebook directory to the specified directory.

        If the specified directory is empty or `None`, use the default
        directory (i.e., in the default MicroDrop user directory) as the new
        directory path.

        If no directory was previously set and the specified directory does not
        exist, copy the default set of notebooks from the `microdrop` package
        to the new notebook directory.

        If a directory was previously set, copy the contents of the previous
        directory to the new directory (prompting the user to overwrite if the
        new directory already exists).
        '''
        app = get_app()

        print '[{notebook_directory = "%s"}]' % notebook_directory
        if not notebook_directory:
            # The notebook directory is not set (i.e., empty or `None`), so set
            # a default.
            data_directory = path(app.config.data['data_dir'])
            notebook_directory = data_directory.joinpath('notebooks')
            print '[{new notebook_directory = "%s"}]' % notebook_directory
            app_values = self.get_app_values().copy()
            app_values['notebook_directory'] = notebook_directory
            self.set_app_values(app_values)

        if self.previous_notebook_dir and (notebook_directory
                                           == self.previous_notebook_dir):
            # If the data directory hasn't changed, we do nothing
            return False

        notebook_directory = path(notebook_directory)
        if self.previous_notebook_dir:
            notebook_directory.makedirs_p()
            if notebook_directory.listdir():
                result = yesno(
                    'Merge?', 'Target directory [%s] is not empty.  Merge '
                    'contents with current notebooks [%s] '
                    '(overwriting common paths in the target '
                    'directory)?' %
                    (notebook_directory, self.previous_notebook_dir))
                if not result == gtk.RESPONSE_YES:
                    return False

            original_directory = path(self.previous_notebook_dir)
            for d in original_directory.dirs():
                copytree(d, notebook_directory.joinpath(d.name))
            for f in original_directory.files():
                f.copyfile(notebook_directory.joinpath(f.name))
            original_directory.rmtree()
        elif not notebook_directory.isdir():
            # if the notebook directory doesn't exist, copy the skeleton dir
            if notebook_directory.parent:
                notebook_directory.parent.makedirs_p()
            skeleton_dir = path(
                pkg_resources.resource_filename('microdrop', 'static'))
            skeleton_dir.joinpath('notebooks').copytree(notebook_directory)
        self.previous_notebook_dir = notebook_directory
        # Set the default template directory of the IPython notebook manager
        # widget to the notebooks directory.
        self.notebook_manager_view.template_dir = notebook_directory
 def on_protocol_finished(self):
     result = yesno('Experiment complete. Would you like to start a new '
                    'experiment?')
     if result == gtk.RESPONSE_YES:
         self.save()