diff --git a/README.md b/README.md index c86068c..af94660 100644 --- a/README.md +++ b/README.md @@ -84,9 +84,9 @@ The user can select categories of features for feature extraction in the user in * extent * feret_diameter_max * local_centroid - * roundness as defined for 2D labels [by ImageJ](https://imagej.nih.gov/ij/docs/menus/analyze.html) - * circularity as defined for 2D labels [by ImageJ](https://imagej.nih.gov/ij/docs/menus/analyze.html) - * aspect_ratio as defined for 2D labels [by ImageJ](https://imagej.nih.gov/ij/docs/menus/analyze.html) + * roundness as defined for 2D labels [by ImageJ](https://imagej.nih.gov/ij/docs/menus/analyze.html#set) + * circularity as defined for 2D labels [by ImageJ](https://imagej.nih.gov/ij/docs/menus/analyze.html#set) + * aspect_ratio as defined for 2D labels [by ImageJ](https://imagej.nih.gov/ij/docs/menus/analyze.html#set) * position: * centroid * bbox diff --git a/napari_skimage_regionprops/__init__.py b/napari_skimage_regionprops/__init__.py index 82e7957..0ac158f 100644 --- a/napari_skimage_regionprops/__init__.py +++ b/napari_skimage_regionprops/__init__.py @@ -8,7 +8,7 @@ try: from ._version import version as __version__ except ImportError: - __version__ = "0.7.0" + __version__ = "0.8.0" @napari_hook_implementation diff --git a/napari_skimage_regionprops/_all_frames.py b/napari_skimage_regionprops/_all_frames.py index 27da9a0..ed5578c 100644 --- a/napari_skimage_regionprops/_all_frames.py +++ b/napari_skimage_regionprops/_all_frames.py @@ -1,5 +1,3 @@ - -import napari from toolz import curry from typing import Callable from functools import wraps @@ -8,6 +6,12 @@ import pandas as pd from ._utilities import isimage +try: + import napari +except ModuleNotFoundError as e: + import warnings + warnings.warn(str(e)) + @curry def analyze_all_frames(function: Callable) -> Callable: from napari_workflows._workflow import _get_layer_from_data diff --git a/napari_skimage_regionprops/_load_csv.py b/napari_skimage_regionprops/_load_csv.py index 3247b79..62a16c8 100644 --- a/napari_skimage_regionprops/_load_csv.py +++ b/napari_skimage_regionprops/_load_csv.py @@ -1,9 +1,15 @@ -import napari import numpy as np from napari_tools_menu import register_function +try: + import napari +except ModuleNotFoundError as e: + import warnings + warnings.warn(str(e)) + + @register_function(menu="Measurement > Load from CSV (nsr)") -def load_csv(csv_filename:"magicgui.types.PathLike", labels_layer:napari.layers.Labels, viewer:napari.Viewer=None): +def load_csv(csv_filename:"magicgui.types.PathLike", labels_layer: "napari.layers.Labels", viewer: "napari.Viewer" = None): """Save contents of a CSV file into a given layer's properties""" import pandas as pd # load region properties from csv file diff --git a/napari_skimage_regionprops/_regionprops.py b/napari_skimage_regionprops/_regionprops.py index 18d4072..a3a0d54 100644 --- a/napari_skimage_regionprops/_regionprops.py +++ b/napari_skimage_regionprops/_regionprops.py @@ -2,13 +2,16 @@ import numpy as np import pandas -from napari import Viewer +try: + import napari +except ModuleNotFoundError as e: + warnings.warn(str(e)) + from napari_tools_menu import register_function -import napari import math from ._all_frames import analyze_all_frames -def regionprops(image_layer : napari.layers.Layer, labels_layer: napari.layers.Labels, size : bool = True, intensity : bool = True, perimeter : bool = False, shape : bool = False, position : bool = False, moments : bool = False, napari_viewer : Viewer = None): +def regionprops(image_layer: "napari.layers.Layer", labels_layer: "napari.layers.Labels", size : bool = True, intensity : bool = True, perimeter : bool = False, shape : bool = False, position : bool = False, moments : bool = False, napari_viewer : "napari.Viewer" = None): warnings.warn("napari_skimage_regionprops.regionprops is deprecated. Use regionprops_table instead.") image_data = None if image_layer is not None: @@ -17,7 +20,7 @@ def regionprops(image_layer : napari.layers.Layer, labels_layer: napari.layers.L regionprops_table(image_data, labels_layer.data, size, intensity, perimeter, shape, position, moments, napari_viewer) @register_function(menu="Measurement tables > Regionprops (scikit-image, nsr)") -def regionprops_table(image : napari.types.ImageData, labels: napari.types.LabelsData, size : bool = True, intensity : bool = True, perimeter : bool = False, shape : bool = False, position : bool = False, moments : bool = False, napari_viewer : Viewer = None) -> "pandas.DataFrame": +def regionprops_table(image: "napari.types.ImageData", labels: "napari.types.LabelsData", size : bool = True, intensity : bool = True, perimeter : bool = False, shape : bool = False, position : bool = False, moments : bool = False, napari_viewer : "napari.Viewer" = None) -> "pandas.DataFrame": """ Adds a table widget to a given napari viewer with quantitative analysis results derived from an image-label pair. """ diff --git a/napari_skimage_regionprops/_table.py b/napari_skimage_regionprops/_table.py index e133abd..e221886 100644 --- a/napari_skimage_regionprops/_table.py +++ b/napari_skimage_regionprops/_table.py @@ -1,9 +1,14 @@ -import time +try: + import napari + from qtpy.QtCore import QTimer + from qtpy.QtWidgets import QTableWidget, QHBoxLayout, QTableWidgetItem, QWidget, QGridLayout, QPushButton, QFileDialog +except ModuleNotFoundError as e: + import warnings + warnings.warn(str(e)) + class QWidget: + pass -import napari from pandas import DataFrame -from qtpy.QtCore import QTimer -from qtpy.QtWidgets import QTableWidget, QHBoxLayout, QTableWidgetItem, QWidget, QGridLayout, QPushButton, QFileDialog from napari_tools_menu import register_function import pandas as pd @@ -16,7 +21,7 @@ class TableWidget(QWidget): The table widget represents a table inside napari. Tables are just views on `properties` of `layers`. """ - def __init__(self, layer: napari.layers.Layer, viewer:napari.Viewer = None): + def __init__(self, layer: "napari.layers.Layer", viewer: "napari.Viewer" = None): super().__init__() self._layer = layer @@ -234,7 +239,7 @@ def append_content(self, table: Union[dict, DataFrame], how: str = 'outer'): @register_function(menu="Measurement > Show table (nsr)") -def add_table(labels_layer: napari.layers.Layer, viewer:napari.Viewer) -> TableWidget: +def add_table(labels_layer: "napari.layers.Layer", viewer: "napari.Viewer") -> TableWidget: """ Add a table to a viewer and return the table widget. The table will show the `properties` of the given layer. """ @@ -250,7 +255,7 @@ def add_table(labels_layer: napari.layers.Layer, viewer:napari.Viewer) -> TableW return dock_widget -def get_table(labels_layer: napari.layers.Layer, viewer:napari.Viewer) -> TableWidget: +def get_table(labels_layer: "napari.layers.Layer", viewer: "napari.Viewer") -> TableWidget: """ Searches inside a viewer for a given table and returns it. If it cannot find it, it will return None. @@ -273,4 +278,4 @@ def _determine_frame_column(table): for c in candidates: if c in table.keys(): return c - return None \ No newline at end of file + return None diff --git a/napari_skimage_regionprops/_utilities.py b/napari_skimage_regionprops/_utilities.py index 45f9244..7355bbd 100644 --- a/napari_skimage_regionprops/_utilities.py +++ b/napari_skimage_regionprops/_utilities.py @@ -1,18 +1,25 @@ import numpy as np -from napari_plugin_engine import napari_hook_implementation -from napari.types import ImageData -from napari import Viewer +try: + from napari_plugin_engine import napari_hook_implementation + from napari.types import ImageData + import napari + from napari.layers import Image, Labels, Layer + from typing_extensions import Annotated + LayerInput = Annotated[Layer, {"label": "Image"}] +except ModuleNotFoundError as e: + import warnings + warnings.warn(str(e)) + LayerInput = None + from napari_tools_menu import register_function -from typing_extensions import Annotated -from napari.layers import Image, Labels, Layer -LayerInput = Annotated[Layer, {"label": "Image"}] + @napari_hook_implementation def napari_experimental_provide_function(): return [duplicate_current_frame] @register_function(menu="Utilities > Duplicate current timepoint (nsr)") -def duplicate_current_frame(layer : LayerInput, napari_viewer : Viewer, axis : int = 0) -> Layer: +def duplicate_current_frame(layer : LayerInput, napari_viewer: "napari.Viewer", axis : int = 0) -> "napari.layers.Layer": image = layer.data current_dim_value = napari_viewer.dims.current_step[axis] new_image = np.take(image, current_dim_value, axis) diff --git a/requirements.txt b/requirements.txt index 619db33..a8c2dd1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,6 +3,6 @@ numpy scikit-image napari pandas -napari-tools-menu>=0.1.11 +napari-tools-menu>=0.1.18 napari-workflows imageio!=2.22.1 diff --git a/setup.py b/setup.py index 811d112..f59577c 100644 --- a/setup.py +++ b/setup.py @@ -36,7 +36,7 @@ def read(fname): packages=find_packages(), python_requires='>=3.8', install_requires=requirements, - version='0.7.0', + version='0.8.0', #use_scm_version=use_scm, setup_requires=['setuptools_scm'], classifiers=[