class CriteriaSelection(QtGui.QDialog): def __init__(self, image_info, force_nuclei_load=False, parent=None): super(CriteriaSelection, self).__init__(parent) # nuclei selection? if not hasattr(self, 'is_nuclei_selection'): self.is_nuclei_selection = False # load image infos self.image_info = image_info # prepare criteria self.criteria = dict() # init segmentation self.segmentation = Segmentation(self.image_info) # load segmentation self.segmentation.load(force_nuclei_load=force_nuclei_load) # buttons self.btn_reset = QtGui.QPushButton(gui_labels.btn_reset) self.btn_load = QtGui.QPushButton(gui_labels.btn_load) self.btn_save = QtGui.QPushButton(gui_labels.btn_save) self.btn_close = QtGui.QPushButton(gui_labels.btn_close) # listeners self.btn_reset.clicked.connect(self.reset_criteria) self.btn_load.clicked.connect(self.load_criteria) self.btn_save.clicked.connect(self.save_criteria) self.btn_close.clicked.connect(self.close) def prep_ctn_criteria_select(self, lookup_nucleus): """ Prepare main container for criteria selection :return: """ container = QtGui.QGridLayout() # select criteria criteria = cfg.filter_criteria_labels if lookup_nucleus is True: criteria = cfg.filter_criteria_nuclei counter = 0 for param in criteria: # get container param_ctn = self.prep_criteria(param.lower(), lookup_nucleus=lookup_nucleus) # add container if param_ctn is not None: container.addLayout(param_ctn, counter, 0) counter += 1 # submit buttons container.addLayout(self.prep_ctn_submit(), counter, 0) return container def reset_criteria(self): """ Reset edit boxes :return: """ # go through edit boxes and empty for criteria_raw in self.criteria: self.criteria[criteria_raw]['edt_min'].setText('') self.criteria[criteria_raw]['edt_max'].setText('') def load_criteria(self): """ Load selection criteria :return: """ # load criteria self.loaded_criteria = self.segmentation.get_nuclei_criteria(True) # set min/max fields for critieria for criteria_raw in self.criteria: # edit boxes if self.loaded_criteria is not None and criteria_raw in self.loaded_criteria.keys(): # set value in edit box if self.loaded_criteria[criteria_raw]['MIN'] is not None: self.criteria[criteria_raw]['edt_min'].setText(str(self.loaded_criteria[criteria_raw]['MIN'])) if self.loaded_criteria[criteria_raw]['MAX'] is not None: self.criteria[criteria_raw]['edt_max'].setText(str(self.loaded_criteria[criteria_raw]['MAX'])) def save_criteria(self): """ Save selection criteria for labels :return: """ # create criteria mapping criteria = dict() # go through criteria and get the values for param in self.loaded_criteria.keys(): # is criteria on mask? if param.lower() in self.criteria.keys(): # get min and max min_input = self.criteria[param.lower()]['edt_min'].text() max_input = self.criteria[param.lower()]['edt_max'].text() min_value = None if min_input: min_value = '%.1f' % float(min_input) max_value = None if max_input: max_value = '%.1f' % float(max_input) else: min_value = self.loaded_criteria[param]['MIN'] max_value = self.loaded_criteria[param]['MAX'] # write to mapping criteria[param] = dict() criteria[param]['MIN'] = min_value criteria[param]['MAX'] = max_value # set criteria self.loaded_criteria = criteria # save to file self.segmentation.save_nuclei_criteria(criteria) def close(self): """ Close criteria selection and show the main window again :return: """ # show parent self.parent().showNormal() # close processing super(QtGui.QDialog, self).close() def prep_criteria(self, param, lookup_nucleus): """ Prepare a container with the parameter :param param: :return: """ container = None prep_ctn = True # is param part of the nuclei? if lookup_nucleus is True: if self.segmentation.nuclei.is_param_in_nuclei(param) is False: prep_ctn = False if prep_ctn is True: # prepare dictionary self.prep_criteria_dict(param) # prepare container container = self.prep_criteria_ctn(param) return container def prep_criteria_dict(self, param): """ Prepare dictionary for param :param param: :return: """ self.criteria[param] = dict() # edit boxes self.criteria[param]['edt_min'] = QtGui.QLineEdit() self.criteria[param]['edt_max'] = QtGui.QLineEdit() # figures self.criteria[param]['fig_hist'] = plt.figure(figsize=(5, 2)) self.criteria[param]['fig_example'] = plt.figure(figsize=(5, 2)) # canvases self.criteria[param]['cnv_hist'] = FigureCanvas(self.criteria[param]['fig_hist']) self.criteria[param]['cnv_example'] = FigureCanvas(self.criteria[param]['fig_example']) # misc widgets self.criteria[param]['sld_hist'] = QtGui.QSlider(QtCore.Qt.Horizontal, self) def prep_criteria_ctn(self, param): """ Container to set criteria param :return: """ container = QtGui.QGridLayout() # labels container.addWidget(QtGui.QLabel(getattr(gui_labels, 'crit_sel_label_' + param)), 0, 0) container.addWidget(QtGui.QLabel(gui_labels.crit_sel_min), 1, 0) container.addWidget(QtGui.QLabel(gui_labels.crit_sel_max), 2, 0) container.setRowStretch(3, 1) # edit boxes container.addWidget(self.criteria[param]['edt_min'], 1, 1) container.addWidget(self.criteria[param]['edt_max'], 2, 1) # sort nuclei if self.is_nuclei_selection: # sort nuclei self.segmentation.nuclei.sort_nuclei(param) # get sorted list # TODO transform the props into a dict self.criteria[param]['sorted_labels'] = self.segmentation.nuclei.get_param_list_from_nuclei(param) self.criteria[param]['sorted_props'] = self.segmentation.nuclei.get_param_list_from_nuclei(create_dict=True) else: # sort labels self.criteria[param]['sorted_labels'] = self.segmentation.get_sorted_prop_list(param) self.criteria[param]['sorted_props'] = self.segmentation.sorted_probs.copy() # show histogram Plot.view_histogram_of_value_list(self.criteria[param]['fig_hist'], self.criteria[param]['sorted_labels'], cfg.criteria_select_hist_bins) # add to container container.addWidget(self.criteria[param]['cnv_hist'], 0, 2, 3, 1) container.addWidget(self.criteria[param]['cnv_example'], 0, 3, 4, 1) # slider self.criteria[param]['sld_hist'].valueChanged[int].connect(self.make_change_criteria_example(param)) self.criteria[param]['sld_hist'].setMinimum(0) self.criteria[param]['sld_hist'].setMaximum(len(self.criteria[param]['sorted_props'])) container.addWidget(self.criteria[param]['sld_hist'], 3, 2) return container def make_change_criteria_example(self, param): """ Make function to call change criteria :param param: :return: """ def change_criteria_example_param(example_selected): self.change_criteria_example(param, example_selected) return change_criteria_example_param def change_criteria_example(self, param, example_selected): """ Change example in +/- range :param param: :param example_selected: :return: """ min_range = example_selected - cfg.criteria_select_eg_range if min_range < 0: min_range = 0 max_range = example_selected + cfg.criteria_select_eg_range if max_range > len(self.criteria[param]['sorted_props']): max_range = len(self.criteria[param]['sorted_props']) # prepare examples examples = list() # show examples from each part for i in range(min_range, max_range): example_title = '%i\n%.2f' % (self.criteria[param]['sorted_props'][i]['nID'], self.criteria[param]['sorted_props'][i][param]) # prepare image examples = Plot.prepare_output(examples, self.criteria[param]['sorted_props'][i]['img'], example_title, cfg.criteria_select_eg_colour) # clear figure if len(examples[0]) < (cfg.criteria_select_eg_range * 2): self.criteria[param]['fig_example'].clear() # show examples Plot.show_images(self.criteria[param]['fig_example'], examples, cols=cfg.criteria_select_eg_cols) # update canvas self.criteria[param]['cnv_example'].draw()
# nuclei if processing['nuclei'] == 1: test_window = NucleiCriteria(selected_info) test_window.show() test_window.raise_() test_window.activateWindow() sys.exit(app.exec_()) elif processing['nuclei'] >= 2: force_reload = False if processing['nuclei'] == 3: force_reload = True print('=== Filter ===') seg = Segmentation(selected_info) seg.load(force_nuclei_load=force_reload) seg.get_nuclei_criteria() removed_nuclei = seg.nuclei.filter_nuclei() seg.save(force_nuclei_stack_rebuild=True) print('save correction') # add nuclei to correction corr = Correction(seg) corr.add_nuclei_to_correction_filtered(removed_nuclei, add_to_stack=False) corr.update_correction_stacks() corr.save_corrections() del(seg) del(corr) # select if processing['select'] == 1: