def _on_remove_plugin(self, plugin_name): instance = self.plugin_manager.get_plugin_instance(plugin_name) result = False n = len(instance.referees) if n == 0: result = question(None, 'Removing the plugin "%s"' % plugin_name, "Are you sure to remove this plugin?") elif n > 0: detail = '\n'.join(['%s (%s)' % x[:2] for x in instance.referees]) result = question(None, 'Removing the plugin "%s"' % plugin_name, '%d other plugin%s require%s this plugin.\n\nAre you sure to remove this plugin?' % (n, 's' if n > 1 else '', 's' if n == 1 else ''), detail=detail, icon=QMessageBox.Warning) if result: self.remove_plugin(plugin_name) self.plugin_manager.remove_instance(plugin_name, self.settings)
def _on_class_remove(self): ''' Remove a class and all its annotations ''' class_name = self._current_class if (not class_name is None and question(self, "Do you really want to remove class '%s'?" % \ class_name, info="All %d annotations will be lost." % \ self._annotations.get_count_for_class(class_name))): self._activate_objects_for_image(False) learner = self._learner class_label = learner.class_labels[class_name] del learner.class_labels[class_name] del learner.class_names[class_label] del learner.hexcolors[class_name] item = self._find_items_in_class_table(class_name, self.COLUMN_CLASS_NAME)[0] row = item.row() self._class_table.removeRow(row) self._annotations.remove_class(class_name) self._activate_objects_for_image(True, clear=True) row_count = self._class_table.rowCount() if row_count > 0: row = row if row < row_count else row_count-1 item = self._class_table.item(row, self.COLUMN_CLASS_NAME) self._class_table.setCurrentItem(item) else: self._update_annotation_table()
def _on_remove_plugin(self, plugin_name): instance = self.plugin_manager.get_plugin_instance(plugin_name) result = False n = len(instance.referees) if n == 0: result = question(None, 'Removing the plugin "%s"' %plugin_name, "Are you sure to remove this plugin?") elif n > 0: detail = '\n'.join(['%s (%s)' % x[:2] for x in instance.referees]) result = question(None, 'Removing the plugin "%s"' % plugin_name, ('%d other plugin%s require%s this plugin.' '\n\nAre you sure to remove this plugin?') % (n, 's' if n > 1 else '', 's' if n == 1 else ''), detail=detail, icon=QMessageBox.Warning) if result: self.remove_plugin(plugin_name) self.plugin_manager.remove_instance(plugin_name, self.settings)
def _on_new_classifier(self): ok = False if question(self, 'New classifier', 'Are you sure to setup a new classifer?\nAll annotations ' 'will be lost.'): self._learner = self._init_new_classifier() ok = True return ok
def _exit_app(self): do_exit = False if not self._debug: if question(self, 'Do you really want to exit?', modal=True): if self._check_settings_saved() != QMessageBox.Cancel: do_exit = True qApp.exit() else: do_exit = True qApp.exit() return do_exit
def _check_settings_saved(self): if self.isWindowModified(): result = question(self, 'Settings have been modified.', info='Do you want to save settings?', modal=True, show_cancel=True, default=QMessageBox.Yes, escape=QMessageBox.Cancel) if result == QMessageBox.Yes: self.save_settings() else: result = QMessageBox.No return result
def _on_load_input(self): txt = "Error scanning image structure" path_in = self._settings.get(SECTION_NAME_GENERAL, 'pathin') if path_in == '': critical(self, txt, "Image path must be defined.") elif not os.path.isdir(path_in) and \ not os.path.isdir(os.path.join(self.environ.package_dir, path_in)): critical(self, txt, "Image path '%s' not found." % path_in) else: try: infos = list(ImageContainer.iter_check_plates(self._settings)) except: exception(self, txt) else: found_any = numpy.any([not info[3] is None for info in infos]) cancel = False if found_any: found_plates = [info[0] for info in infos if not info[3] is None] missing_plates = [info[0] for info in infos if info[3] is None] has_missing = len(missing_plates) > 0 txt = '%s plates were already scanned.\nDo you want ' \ 'to rescan the file structure(s)? ' \ 'This can take several minutes.' % \ ('Some' if has_missing else 'All') title = 'Rescan input structure?' box = QMessageBox(QMessageBox.Question, title, title, QMessageBox.Cancel, self, Qt.Sheet) box.setWindowModality(Qt.WindowModal) box.setInformativeText(txt) box.setDetailedText('Plates with scanned structure: \n%s\n' '\nPlates without scanned structure: ' '\n%s' % ('\n'.join(found_plates), '\n'.join(missing_plates))) if not has_missing: btn1 = QtGui.QPushButton('No', box) box.addButton(btn1, QMessageBox.NoRole) box.setDefaultButton(btn1) elif len(found_plates) > 0: btn1 = QtGui.QPushButton('Rescan missing', box) box.addButton(btn1, QMessageBox.YesRole) box.setDefaultButton(btn1) else: btn1 = None btn2 = QtGui.QPushButton('Rescan all', box) box.addButton(btn2, QMessageBox.YesRole) if box.exec_() == QMessageBox.Cancel: cancel = True else: btn = box.clickedButton() if btn == btn1: if has_missing: scan_plates = dict([(info[0], info[0] in missing_plates) for info in infos]) else: scan_plates = dict((info[0], False) for info in infos) else: scan_plates = dict((info[0], True) for info in infos) else: has_multiple = self._settings.get(SECTION_NAME_GENERAL, "has_multiple_plates") if not question(self, "No structure data found", "Are you sure to scan %s?\n\nThis can take " "several minutes depending on the number of" " images." % ("%d plates" % len(infos) if has_multiple else "one plate")): cancel = True scan_plates = dict((info[0], True) for info in infos) if not cancel: self._load_image_container(infos, scan_plates)
def _on_process_start(self, name, start_again=False): if not self._is_running or start_again: is_valid = True self._is_abort = False self._has_error = False if self._process_items is None: cls = self._control_buttons[name]['cls'] if type(cls) == types.ListType: self._process_items = cls self._current_process_item = 0 cls = cls[self._current_process_item] else: self._process_items = None self._current_process_item = 0 else: cls = self._process_items[self._current_process_item] if self.name == SECTION_NAME_CLASSIFICATION: result_frame = self._get_result_frame(self._tab_name) result_frame.load_classifier(check=False) learner = result_frame._learner if name == self.PICKING: if not result_frame.classifier.is_annotated: is_valid = False result_frame.msg_pick_samples(self) elif result_frame.classifier.is_trained: if not question(self, 'Samples already picked', 'Do you want to pick samples again and ' 'overwrite previous ' 'results?'): is_valid = False elif name == self.TRAINING: if not result_frame.classifier.is_trained: is_valid = False result_frame.msg_train_classifier(self) elif result_frame.classifier.is_valid: if not question(self, 'Classifier already trained', 'Do you want to train the classifier ' 'again?'): is_valid = False elif name == self.TESTING and not result_frame.classifier.is_valid: is_valid = False result_frame.msg_apply_classifier(self) if cls is MultiAnalyzerThread: ncpu = cpu_count() (ncpu, ok) = QInputDialog.getInt(None, "On your machine are %d processers available." % ncpu, \ "Select the number of processors", \ ncpu, 1, ncpu*2) if not ok: self._process_items = None is_valid = False if is_valid: self._current_process = name if not start_again: self.parent().log_window.clear() self._is_running = True self._stage_infos = {} self._toggle_tabs(False) # disable all section button of the main widget self.toggle_tabs.emit(self.get_name()) self._set_control_button_text(idx=1) self.process_control.toggleButtons(self._current_process) imagecontainer = self.parent().main_window._imagecontainer if cls is PickerThread: self._current_settings = self._get_modified_settings(name, imagecontainer.has_timelapse) self._analyzer = cls(self, self._current_settings, imagecontainer) self._clear_image() elif cls is AnalyzerThread: self._current_settings = self._get_modified_settings(name, imagecontainer.has_timelapse) self._analyzer = cls(self, self._current_settings, imagecontainer) self._clear_image() elif cls is TrainingThread: self._current_settings = self._settings.copy() self._analyzer = cls(self, self._current_settings, result_frame._learner) self._analyzer.setTerminationEnabled(True) self._analyzer.conf_result.connect(result_frame.on_conf_result, Qt.QueuedConnection) result_frame.reset() elif cls is MultiAnalyzerThread: self._current_settings = self._get_modified_settings(name, imagecontainer.has_timelapse) self._analyzer = cls(self, self._current_settings, imagecontainer, ncpu) elif cls is ErrorCorrectionThread: self._current_settings = self._get_modified_settings(name, imagecontainer.has_timelapse) self._analyzer = cls(self, self._current_settings, self.parent().main_window._imagecontainer) self._analyzer.finished.connect(self._on_process_finished) self._analyzer.stage_info.connect(self._on_update_stage_info, Qt.QueuedConnection) self._analyzer.analyzer_error.connect(self._on_error, Qt.QueuedConnection) self._analyzer.image_ready.connect(self._on_update_image) self._analyzer.start(QThread.LowestPriority) if self._current_process_item == 0: self.status_message.emit('Process started...') else: self._abort_processing()
def _on_process_start(self, name, start_again=False): if not self._is_running or start_again: is_valid = True self._is_abort = False self._has_error = False if self._process_items is None: cls = self._control_buttons[name]['cls'] if type(cls) == types.ListType: self._process_items = cls self._current_process_item = 0 cls = cls[self._current_process_item] # remove HmmThread if process is not first in list and # not valid error correction was activated if (HmmThread in self._process_items and self._process_items.index(HmmThread) > 0 and not (self._settings.get( 'Processing', 'primary_errorcorrection') or (self._settings.get( 'Processing', 'secondary_errorcorrection') and self._settings.get( 'Processing', 'secondary_processchannel')))): self._process_items.remove(HmmThread) else: self._process_items = None self._current_process_item = 0 else: cls = self._process_items[self._current_process_item] if self.SECTION_NAME == 'Classification': result_frame = self._get_result_frame(self._tab_name) result_frame.load_classifier(check=False) learner = result_frame._learner if name == self.PROCESS_PICKING: if not result_frame.is_pick_samples(): is_valid = False result_frame.msg_pick_samples(self) elif result_frame.is_train_classifier(): if not question( self, 'Samples already picked', 'Do you want to pick samples again and ' 'overwrite previous ' 'results?'): is_valid = False elif name == self.PROCESS_TRAINING: if not result_frame.is_train_classifier(): is_valid = False result_frame.msg_train_classifier(self) elif result_frame.is_apply_classifier(): if not question( self, 'Classifier already trained', 'Do you want to train the classifier ' 'again?'): is_valid = False elif name == self.PROCESS_TESTING and not result_frame.is_apply_classifier( ): is_valid = False result_frame.msg_apply_classifier(self) elif cls is HmmThread: success, cmd = HmmThread.test_executable( self._settings.get('ErrorCorrection', 'filename_to_R')) if not success: critical(self, 'Error running R', "The R command line program '%s' could not be executed.\n\n"\ "Make sure that the R-project is installed.\n\n"\ "See README.txt for details." % cmd) is_valid = False elif cls is MultiAnalyzerThread: ncpu = cpu_count() (ncpu, ok) = QInputDialog.getInt(None, "On your machine are %d processers available." % ncpu, \ "Select the number of processors", \ ncpu, 1, ncpu*2) if not ok: self._process_items = None is_valid = False if is_valid: self._current_process = name if not start_again: self.parent().main_window.log_window.clear() self._is_running = True self._stage_infos = {} self._toggle_tabs(False) # disable all section button of the main widget self.toggle_tabs.emit(self.get_name()) self._set_control_button_text(idx=1) self._toggle_control_buttons() imagecontainer = self.parent().main_window._imagecontainer if cls is PickerThread: self._current_settings = self._get_modified_settings( name, imagecontainer.has_timelapse) self._analyzer = cls(self, self._current_settings, imagecontainer) self._set_display_renderer_info() self._clear_image() elif cls is AnalyzerThread: self._current_settings = self._get_modified_settings( name, imagecontainer.has_timelapse) self._analyzer = cls(self, self._current_settings, imagecontainer) self._set_display_renderer_info() self._clear_image() elif cls is TrainingThread: self._current_settings = self._settings.copy() self._analyzer = cls(self, self._current_settings, result_frame._learner) self._analyzer.setTerminationEnabled(True) self._analyzer.conf_result.connect( result_frame.on_conf_result, Qt.QueuedConnection) result_frame.reset() elif cls is MultiAnalyzerThread: self._current_settings = self._get_modified_settings( name, imagecontainer.has_timelapse) self._analyzer = cls(self, self._current_settings, imagecontainer, ncpu) self._set_display_renderer_info() elif cls is HmmThread: self._current_settings = self._get_modified_settings( name, imagecontainer.has_timelapse) # FIXME: classifier handling needs revision!!! learner_dict = {} for kind in ['primary', 'secondary']: _resolve = lambda x, y: self._settings.get( x, '%s_%s' % (kind, y)) env_path = CecogEnvironment.convert_package_path( _resolve('Classification', 'classification_envpath')) if (os.path.exists(env_path) and (kind == 'primary' or self._settings.get( 'Processing', 'secondary_processchannel'))): learner = CommonClassPredictor( \ env_path, _resolve('ObjectDetection', 'channelid'), _resolve('Classification', 'classification_regionname')) learner.importFromArff() learner_dict[kind] = learner ### Whee, I like it... "self.parent().main_window._imagecontainer" crazy, crazy, michael... :-) self._analyzer = cls( self, self._current_settings, learner_dict, self.parent().main_window._imagecontainer) self._analyzer.setTerminationEnabled(True) lw = self.parent().main_window.log_window lw.show() elif cls is PostProcessingThread: learner_dict = {} for kind in ['primary', 'secondary']: _resolve = lambda x, y: self._settings.get( x, '%s_%s' % (kind, y)) env_path = CecogEnvironment.convert_package_path( _resolve('Classification', 'classification_envpath')) if (_resolve('Processing', 'classification') and (kind == 'primary' or self._settings.get( 'Processing', 'secondary_processchannel'))): learner = CommonClassPredictor( \ env_path, _resolve('ObjectDetection', 'channelid'), _resolve('Classification', 'classification_regionname')) learner.importFromArff() learner_dict[kind] = learner self._current_settings = self._get_modified_settings( name, imagecontainer.has_timelapse) self._analyzer = cls(self, self._current_settings, learner_dict, imagecontainer) self._analyzer.setTerminationEnabled(True) self._analyzer.finished.connect(self._on_process_finished) self._analyzer.stage_info.connect(self._on_update_stage_info, Qt.QueuedConnection) self._analyzer.analyzer_error.connect(self._on_error, Qt.QueuedConnection) self._analyzer.start(QThread.LowestPriority) if self._current_process_item == 0: status('Process started...') else: self._abort_processing()
def _on_process_start(self, name, start_again=False): if not self._is_running or start_again: is_valid = True self._is_abort = False self._has_error = False if self._process_items is None: cls = self._control_buttons[name]['cls'] if type(cls) == types.ListType: self._process_items = cls self._current_process_item = 0 cls = cls[self._current_process_item] # remove HmmThread if process is not first in list and # not valid error correction was activated if (HmmThread in self._process_items and self._process_items.index(HmmThread) > 0 and not (self._settings.get('Processing', 'primary_errorcorrection') or (self._settings.get('Processing', 'secondary_errorcorrection') and self._settings.get('Processing', 'secondary_processchannel')))): self._process_items.remove(HmmThread) else: self._process_items = None self._current_process_item = 0 else: cls = self._process_items[self._current_process_item] if self.SECTION_NAME == 'Classification': result_frame = self._get_result_frame(self._tab_name) result_frame.load_classifier(check=False) learner = result_frame._learner if name == self.PROCESS_PICKING: if not result_frame.is_pick_samples(): is_valid = False result_frame.msg_pick_samples(self) elif result_frame.is_train_classifier(): if not question(self, 'Samples already picked', 'Do you want to pick samples again and ' 'overwrite previous ' 'results?'): is_valid = False elif name == self.PROCESS_TRAINING: if not result_frame.is_train_classifier(): is_valid = False result_frame.msg_train_classifier(self) elif result_frame.is_apply_classifier(): if not question(self, 'Classifier already trained', 'Do you want to train the classifier ' 'again?'): is_valid = False elif name == self.PROCESS_TESTING and not result_frame.is_apply_classifier(): is_valid = False result_frame.msg_apply_classifier(self) elif cls is HmmThread: success, cmd = HmmThread.test_executable(self._settings.get('ErrorCorrection', 'filename_to_R')) if not success: critical(self, 'Error running R', "The R command line program '%s' could not be executed.\n\n"\ "Make sure that the R-project is installed.\n\n"\ "See README.txt for details." % cmd) is_valid = False elif cls is MultiAnalyzerThread: ncpu = cpu_count() (ncpu, ok) = QInputDialog.getInt(None, "On your machine are %d processers available." % ncpu, \ "Select the number of processors", \ ncpu, 1, ncpu*2) if not ok: self._process_items = None is_valid = False if is_valid: self._current_process = name if not start_again: self.parent().main_window.log_window.clear() self._is_running = True self._stage_infos = {} self._toggle_tabs(False) # disable all section button of the main widget self.toggle_tabs.emit(self.get_name()) self._set_control_button_text(idx=1) self._toggle_control_buttons() imagecontainer = self.parent().main_window._imagecontainer if cls is PickerThread: self._current_settings = self._get_modified_settings(name, imagecontainer.has_timelapse) self._analyzer = cls(self, self._current_settings, imagecontainer) self._set_display_renderer_info() self._clear_image() elif cls is AnalyzerThread: self._current_settings = self._get_modified_settings(name, imagecontainer.has_timelapse) self._analyzer = cls(self, self._current_settings, imagecontainer) self._set_display_renderer_info() self._clear_image() elif cls is TrainingThread: self._current_settings = self._settings.copy() self._analyzer = cls(self, self._current_settings, result_frame._learner) self._analyzer.setTerminationEnabled(True) self._analyzer.conf_result.connect(result_frame.on_conf_result, Qt.QueuedConnection) result_frame.reset() elif cls is MultiAnalyzerThread: self._current_settings = self._get_modified_settings(name, imagecontainer.has_timelapse) self._analyzer = cls(self, self._current_settings, imagecontainer, ncpu) self._set_display_renderer_info() elif cls is HmmThread: self._current_settings = self._get_modified_settings(name, imagecontainer.has_timelapse) # FIXME: classifier handling needs revision!!! learner_dict = {} for kind in ['primary', 'secondary']: _resolve = lambda x,y: self._settings.get(x, '%s_%s' % (kind, y)) env_path = CecogEnvironment.convert_package_path(_resolve('Classification', 'classification_envpath')) if (os.path.exists(env_path) and (kind == 'primary' or self._settings.get('Processing', 'secondary_processchannel')) ): learner = CommonClassPredictor( \ env_path, _resolve('ObjectDetection', 'channelid'), _resolve('Classification', 'classification_regionname')) learner.importFromArff() learner_dict[kind] = learner ### Whee, I like it... "self.parent().main_window._imagecontainer" crazy, crazy, michael... :-) self._analyzer = cls(self, self._current_settings, learner_dict, self.parent().main_window._imagecontainer) self._analyzer.setTerminationEnabled(True) lw = self.parent().main_window.log_window lw.show() elif cls is PostProcessingThread: learner_dict = {} for kind in ['primary', 'secondary']: _resolve = lambda x,y: self._settings.get(x, '%s_%s' % (kind, y)) env_path = CecogEnvironment.convert_package_path(_resolve('Classification', 'classification_envpath')) if (_resolve('Processing', 'classification') and (kind == 'primary' or self._settings.get('Processing', 'secondary_processchannel'))): learner = CommonClassPredictor( \ env_path, _resolve('ObjectDetection', 'channelid'), _resolve('Classification', 'classification_regionname')) learner.importFromArff() learner_dict[kind] = learner self._current_settings = self._get_modified_settings(name, imagecontainer.has_timelapse) self._analyzer = cls(self, self._current_settings, learner_dict, imagecontainer) self._analyzer.setTerminationEnabled(True) self._analyzer.finished.connect(self._on_process_finished) self._analyzer.stage_info.connect(self._on_update_stage_info, Qt.QueuedConnection) self._analyzer.analyzer_error.connect(self._on_error, Qt.QueuedConnection) self._analyzer.start(QThread.LowestPriority) if self._current_process_item == 0: status('Process started...') else: self._abort_processing()