def test_notification_manager_no_gui(monkeypatch): """ Direct test of the notification manager. This does not test the integration with the gui, but test that the notification manager itself can receive a info, warning or error. """ try: from napari._qt.dialogs.qt_notification import NapariQtNotification monkeypatch.setattr(NapariQtNotification, "DISMISS_AFTER", 0) except ModuleNotFoundError: pass previous_exhook = sys.excepthook with notification_manager: notification_manager.records.clear() # save all of the events that get emitted store: List[Notification] = [] notification_manager.notification_ready.connect(store.append) show_info('this is one way of showing an information message') assert (len( notification_manager.records) == 1), notification_manager.records assert store[-1].type == 'info' notification_manager.receive_info( 'This is another information message') assert len(notification_manager.records) == 2 assert store[-1].type == 'info' # test that exceptions that go through sys.excepthook are catalogued with pytest.raises(PurposefulException): raise PurposefulException("this is an exception") # pytest intercepts the error, so we can manually call sys.excepthook assert sys.excepthook == notification_manager.receive_error sys.excepthook(*sys.exc_info()) assert len(notification_manager.records) == 3 assert store[-1].type == 'error' # test that warnings that go through showwarning are catalogued # again, pytest intercepts this, so just manually trigger: assert warnings.showwarning == notification_manager.receive_warning warnings.showwarning('this is a warning', UserWarning, '', 0) assert len(notification_manager.records) == 4 assert store[-1].type == 'warning' show_error('This is an error') assert len(notification_manager.records) == 5 assert store[-1].type == 'error' show_warning('This is a warning') assert len(notification_manager.records) == 6 assert store[-1].type == 'warning' # make sure we've restored the except hook assert sys.excepthook == previous_exhook assert all(isinstance(x, Notification) for x in store)
def run_classifier(event): # TODO: Add Run mode? Fuzzy, Cross-validated, train/test split show_info('Running classifier') self.clf.train() self.create_label_colormap(self.prediction_layer, self.clf.predict_data, 'predict') self.clf.save() self.selection_layer.visible = False self.prediction_layer.visible = True
def check_if_measurement_can_be_calculated(self, name): if name in (NO_MEASUREMENT_STRING, ""): return NO_MEASUREMENT_STRING profile: MeasurementProfile = self.settings.measurement_profiles.get(name) if profile.is_any_mask_measurement() and self.mask_chose.value is None: show_info("To use this measurement set please select mask layer") self.measurement_type.setCurrentIndex(0) return NO_MEASUREMENT_STRING if self.roi_chose.value is None: show_info("Before calculate measurement please select ROI Layer") self.measurement_type.setCurrentIndex(0) return NO_MEASUREMENT_STRING return name
def test_notification_manager_no_gui(): """ Direct test of the notification manager. This does not test the integration with the gui, but test that the notification manager itself can receive a info, warning or error. """ previous_exhook = sys.excepthook with notification_manager: # save all of the events that get emitted store: List[Notification] = [] _append = lambda e: store.append(e) # lambda needed on py3.7 # noqa notification_manager.notification_ready.connect(_append) show_info('this is one way of showing an information message') assert len(notification_manager.records) == 1 assert store[-1].type == 'info' notification_manager.receive_info( 'This is another information message') assert len(notification_manager.records) == 2 assert store[-1].type == 'info' # test that exceptions that go through sys.excepthook are catalogued class PurposefulException(Exception): pass with pytest.raises(PurposefulException): raise PurposefulException("this is an exception") # pytest intercepts the error, so we can manually call sys.excepthook assert sys.excepthook == notification_manager.receive_error sys.excepthook(*sys.exc_info()) assert len(notification_manager.records) == 3 assert store[-1].type == 'error' # test that warnings that go through showwarning are catalogued # again, pytest intercepts this, so just manually trigger: assert warnings.showwarning == notification_manager.receive_warning warnings.showwarning('this is a warning', UserWarning, '', 0) assert len(notification_manager.records) == 4 assert store[-1].type == 'warning' # make sure we've restored the except hook assert sys.excepthook == previous_exhook assert all(isinstance(x, Notification) for x in store)
def _zoom(self): self._stop() if self.napari_viewer.dims.ndisplay != 2: show_info("Zoom in does not work in 3D mode") num = self.component_selector.value labels = self.labels_layer.value bound_info = self.roi_info.bound_info.get(num, None) if bound_info is None: return lower_bound = self._data_to_world(labels, bound_info.lower) upper_bound = self._data_to_world(labels, bound_info.upper) diff = upper_bound - lower_bound frame = diff * 0.2 if self.napari_viewer.dims.ndisplay == 2: rect = Rect(pos=(lower_bound - frame)[-2:][::-1], size=(diff + 2 * frame)[-2:][::-1]) self.napari_viewer.window.qt_viewer.view.camera.set_state({"rect": rect}) self._update_point(lower_bound, upper_bound)
def set_result(self, result: ROIExtractionResult): if result.info_text: show_info(result.info_text) if len(result.roi_info.bound_info) == 0: if not result.info_text: show_info( "There is no ROI in result. Pleas check algorithm parameters." ) return roi = result.roi if self.sender() is not None: self.info_text.setPlainText(self.sender().get_info_text()) with suppress(Exception): roi = self.sender().current_widget( ).algorithm_thread.algorithm.image.fit_array_to_image( result.roi) layer_name = self.target_layer_name.text() self.settings.set(f"{self.prefix()}.target_layer_name", layer_name) column_list = [] column_set = set() for value in result.roi_annotation.values(): for column_name in value.items(): if column_name not in column_set: column_list.append(column_name) column_set.add(column_name) properties = pd.DataFrame.from_dict(result.roi_annotation, orient="index") properties["index"] = list(result.roi_annotation.keys()) if layer_name in self.viewer.layers: self.viewer.layers[layer_name].data = result.roi self.viewer.layers[layer_name].metadata = { "parameters": result.parameters } self.viewer.layers[layer_name].properties = properties else: self.viewer.add_labels( roi, scale=np.array(self._scale)[-result.roi.ndim:] * UNIT_SCALE[Units.nm.value], name=layer_name, metadata={"parameters": result.parameters}, properties=properties, )
def append_measurement_result(self): try: compute_class = self.settings.measurement_profiles[self.measurement_type.currentText()] except KeyError: show_info(f"Measurement profile '{self.measurement_type.currentText()}' not found") return if self.roi_chose.value is None: return if self.channels_chose.value is None: return for name in compute_class.get_channels_num(): if name not in self.napari_viewer.layers: show_info("Cannot calculate this measurement because " f"image do not have layer {name}") return units = self.units_choose.currentEnum() image = generate_image(self.napari_viewer, self.channels_chose.value.name, *compute_class.get_channels_num()) if self.mask_chose.value is not None: image.set_mask(self.mask_chose.value.data) roi_info = ROIInfo(self.roi_chose.value.data).fit_to_image(image) dial = ExecuteFunctionDialog( compute_class.calculate, [image, self.channels_chose.value.name, roi_info, units], text="Measurement calculation", parent=self, ) # , exception_hook=exception_hook) dial.exec_() stat: MeasurementResult = dial.get_result() df = stat.to_dataframe(True) if "Mask component" in df and self.mask_chose.value is not None: df2 = df.groupby("Mask component").mean() df2["index"] = df2.index update_properties(df, self.mask_chose.value, self.overwrite.isChecked()) df["index"] = df.index update_properties(df, self.roi_chose.value, self.overwrite.isChecked()) if stat is None: return # stat.set_filename(self.settings.image_path) self.measurements_storage.add_measurements(stat) self.previous_profile = compute_class.name self.refresh_view()
def save_classifier(event): show_info('Saving classifier') self.clf.save()