From 23559b00743a0e3406f0cb3f73cc6903da8fc936 Mon Sep 17 00:00:00 2001 From: zoccoler Date: Fri, 12 Jul 2024 14:47:03 +0200 Subject: [PATCH 1/5] compute pixel coords chunck sizes (fix dask Error) --- src/napari_flim_phasor_plotter/_widget.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/napari_flim_phasor_plotter/_widget.py b/src/napari_flim_phasor_plotter/_widget.py index 794a202..6db45aa 100644 --- a/src/napari_flim_phasor_plotter/_widget.py +++ b/src/napari_flim_phasor_plotter/_widget.py @@ -90,11 +90,16 @@ def make_flim_phasor_plot(image_layer: "napari.layers.Image", g_flat_masked = np.ravel(g[space_mask]) s_flat_masked = np.ravel(s[space_mask]) + t_coords, z_coords, y_coords, x_coords = np.where(space_mask) if isinstance(g, da.Array): g_flat_masked.compute_chunk_sizes() s_flat_masked.compute_chunk_sizes() + if isinstance(space_mask, da.Array): + t_coords.compute_chunk_sizes() + z_coords.compute_chunk_sizes() + y_coords.compute_chunk_sizes() + x_coords.compute_chunk_sizes() - t_coords, z_coords, y_coords, x_coords = np.where(space_mask) phasor_components = pd.DataFrame({ 'label': np.ravel(label_image[space_mask]), 'G': g_flat_masked, From 991b207189062c39a826758e33cf4f30cadd7cf5 Mon Sep 17 00:00:00 2001 From: Marcelo Zoccoler Date: Mon, 12 Aug 2024 11:12:48 +0200 Subject: [PATCH 2/5] Handle color property differently based on napari version --- src/napari_flim_phasor_plotter/_widget.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/napari_flim_phasor_plotter/_widget.py b/src/napari_flim_phasor_plotter/_widget.py index 6db45aa..1d48efc 100644 --- a/src/napari_flim_phasor_plotter/_widget.py +++ b/src/napari_flim_phasor_plotter/_widget.py @@ -2,11 +2,13 @@ from magicgui import magic_factory from magicgui.widgets import Container, PushButton, ComboBox, SpinBox from typing import List +from importlib.metadata import version if TYPE_CHECKING: import napari import pandas +napari_version = tuple(map(int, list(version("napari").split(".")[:2]))) def connect_events(widget): ''' @@ -238,10 +240,13 @@ def manual_label_extract(cluster_labels_layer: "napari.layers.Labels", label_num unitary_dims = [i for i, size in enumerate(np.asarray(cluster_labels_layer.data).shape) if size == 1] labels_data = np.squeeze(np.asarray(cluster_labels_layer.data).copy()) labels_data[labels_data != label_number] = 0 - # TODO: update to use DirectLabelColormap once napari-clusters-plotter has this issue fixed - label_color = cluster_labels_layer.color + if napari_version >= (0, 5): + colormap = cluster_labels_layer.colormap + else: + label_color = cluster_labels_layer.color + colormap = DirectLabelColormap(color_dict=label_color) new_scale = np.array([scale for i, scale in enumerate(cluster_labels_layer.scale) if i not in unitary_dims]) - return Labels(labels_data, colormap=DirectLabelColormap(color_dict=label_color), name=f'Cluster Label #{label_number}', scale=new_scale) + return Labels(labels_data, colormap=colormap, name=f'Cluster Label #{label_number}', scale=new_scale) def get_n_largest_cluster_labels(features_table: 'pandas.DataFrame', n: int=1, clustering_id: str='MANUAL_CLUSTER_ID') -> List[int]: """Get the labels of the n largest clusters in a features table @@ -424,7 +429,10 @@ def smooth_cluster_mask(cluster_mask_layer: "napari.layers.Labels", fill_area_px labels_data = morphology.isotropic_opening(labels_data, smooth_radius) # Restore label number labels_data = labels_data.astype(cluster_mask_layer.data.dtype)*cluster_mask_layer.data.max() - # TODO: update to use DirectLabelColormap once napari-clusters-plotter has this issue fixed - label_color = cluster_mask_layer.color + if napari_version >= (0, 5): + colormap = cluster_mask_layer.colormap + else: + label_color = cluster_mask_layer.color + colormap = DirectLabelColormap(color_dict=label_color) new_scale = np.array([scale for i, scale in enumerate(cluster_mask_layer.scale) if i not in unitary_dims]) - return Labels(labels_data, colormap=DirectLabelColormap(color_dict=label_color), scale=new_scale, name=cluster_mask_layer.name + ' smoothed') \ No newline at end of file + return Labels(labels_data, colormap=colormap, scale=new_scale, name=cluster_mask_layer.name + ' smoothed') \ No newline at end of file From 249d7f599b5dd92a75c7028c463dec8148f10f59 Mon Sep 17 00:00:00 2001 From: Marcelo Zoccoler Date: Mon, 12 Aug 2024 11:13:13 +0200 Subject: [PATCH 3/5] bump version --- src/napari_flim_phasor_plotter/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/napari_flim_phasor_plotter/__init__.py b/src/napari_flim_phasor_plotter/__init__.py index 5317b14..f1042c2 100644 --- a/src/napari_flim_phasor_plotter/__init__.py +++ b/src/napari_flim_phasor_plotter/__init__.py @@ -1,4 +1,4 @@ -__version__ = "0.1.1" +__version__ = "0.1.2" from ._reader import napari_get_reader from ._sample_data import load_seminal_receptacle_image, load_hazelnut_image, load_hazelnut_z_stack, load_lifetime_cat_synthtetic_single_image From 7304a450afc900ad82daa0fb4dc6779f305521c6 Mon Sep 17 00:00:00 2001 From: Marcelo Zoccoler Date: Wed, 14 Aug 2024 09:44:39 +0200 Subject: [PATCH 4/5] fix minimal version of clusters-plotter to avoid bug with napari>=0.5.0 with .color property This also means minimal napari version should be 0.4.19 --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index fd9ecfd..2208e75 100644 --- a/setup.cfg +++ b/setup.cfg @@ -34,7 +34,7 @@ install_requires = magicgui qtpy napari>=0.4.19 - napari-clusters-plotter>=0.8.0 + napari-clusters-plotter>=0.8.1 ptufile sdtfile natsort From 7201748809d3dbb613b7c4387f7e29b2cd0eaa1e Mon Sep 17 00:00:00 2001 From: Marcelo Zoccoler Date: Wed, 14 Aug 2024 09:45:15 +0200 Subject: [PATCH 5/5] update documentation to depend only on specify used plugins --- README.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/README.md b/README.md index 3e5cf1b..fcea0f3 100644 --- a/README.md +++ b/README.md @@ -61,10 +61,6 @@ Alternatively, clone this repository and install the latest plugin development v pip install git+https://github.com/zoccoler/napari-flim-phasor-plotter.git -_Optional, but we **strongly** recommend having the `devbio-napari` plugin bundle also installed for post-processing. This can be done with:_ - - mamba install -c conda-forge devbio-napari=0.10.0 scikit-image=0.24.0 - ## Usage ### Loading Raw FLIM Data @@ -157,7 +153,7 @@ A common step is to select a single cluster of interest for further processing. To connect small isolated regions and remove small holes within the mask, we can use the `smooth_cluster_mask` function. This can be accessed via `Plugins -> FLIM phasor plotter -> Smooth Cluster Mask`. This will remove holes with an area smaller than the specified `fill area px` in total number of pixels and connect regions within a given `smooth radius`. Don't forget to select the layer containing the mask before running the function, because this function expects a layer with a single label (like a binary mask). -Beyond this point, we can use other plugins, like the `devbio-napari` plugin bundle, to further process the mask. For example, we can perform instance segmentation on the mask via `Tools -> Segmentation / labeling -> Connectec component labeling (scikit-image, nsbatwm)`. We can also extract features from the objects via `Tools -> Measurement tables -> Objetct Features/Properties (scikit-image, nsr)`. +Beyond this point, we can use other plugins, like the `napari-segment-blobs-and-things-with-membranes` and `napari-skimage-regionprops` plugins, to further process the mask. For example, we can perform instance segmentation on the mask via `Tools -> Segmentation / labeling -> Connectec component labeling (scikit-image, nsbatwm)`. We can also extract features from the objects via `Tools -> Measurement tables -> Objetct Features/Properties (scikit-image, nsr)`. Below is a demonstration of the post-processing steps: