nettracer3d 0.8.1__tar.gz → 0.8.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nettracer3d-0.8.2/PKG-INFO +117 -0
- nettracer3d-0.8.2/README.md +72 -0
- {nettracer3d-0.8.1 → nettracer3d-0.8.2}/pyproject.toml +12 -11
- nettracer3d-0.8.2/src/nettracer3d/cellpose_manager.py +161 -0
- {nettracer3d-0.8.1 → nettracer3d-0.8.2}/src/nettracer3d/community_extractor.py +97 -20
- {nettracer3d-0.8.1 → nettracer3d-0.8.2}/src/nettracer3d/neighborhoods.py +222 -23
- {nettracer3d-0.8.1 → nettracer3d-0.8.2}/src/nettracer3d/nettracer.py +166 -68
- {nettracer3d-0.8.1 → nettracer3d-0.8.2}/src/nettracer3d/nettracer_gui.py +584 -266
- {nettracer3d-0.8.1 → nettracer3d-0.8.2}/src/nettracer3d/network_analysis.py +222 -230
- {nettracer3d-0.8.1 → nettracer3d-0.8.2}/src/nettracer3d/proximity.py +191 -30
- nettracer3d-0.8.2/src/nettracer3d.egg-info/PKG-INFO +117 -0
- {nettracer3d-0.8.1 → nettracer3d-0.8.2}/src/nettracer3d.egg-info/SOURCES.txt +1 -0
- {nettracer3d-0.8.1 → nettracer3d-0.8.2}/src/nettracer3d.egg-info/requires.txt +10 -1
- nettracer3d-0.8.1/PKG-INFO +0 -80
- nettracer3d-0.8.1/README.md +0 -41
- nettracer3d-0.8.1/src/nettracer3d.egg-info/PKG-INFO +0 -80
- {nettracer3d-0.8.1 → nettracer3d-0.8.2}/LICENSE +0 -0
- {nettracer3d-0.8.1 → nettracer3d-0.8.2}/setup.cfg +0 -0
- {nettracer3d-0.8.1 → nettracer3d-0.8.2}/src/nettracer3d/__init__.py +0 -0
- {nettracer3d-0.8.1 → nettracer3d-0.8.2}/src/nettracer3d/excelotron.py +0 -0
- {nettracer3d-0.8.1 → nettracer3d-0.8.2}/src/nettracer3d/modularity.py +0 -0
- {nettracer3d-0.8.1 → nettracer3d-0.8.2}/src/nettracer3d/morphology.py +0 -0
- {nettracer3d-0.8.1 → nettracer3d-0.8.2}/src/nettracer3d/network_draw.py +0 -0
- {nettracer3d-0.8.1 → nettracer3d-0.8.2}/src/nettracer3d/node_draw.py +0 -0
- {nettracer3d-0.8.1 → nettracer3d-0.8.2}/src/nettracer3d/run.py +0 -0
- {nettracer3d-0.8.1 → nettracer3d-0.8.2}/src/nettracer3d/segmenter.py +0 -0
- {nettracer3d-0.8.1 → nettracer3d-0.8.2}/src/nettracer3d/segmenter_GPU.py +0 -0
- {nettracer3d-0.8.1 → nettracer3d-0.8.2}/src/nettracer3d/simple_network.py +0 -0
- {nettracer3d-0.8.1 → nettracer3d-0.8.2}/src/nettracer3d/smart_dilate.py +0 -0
- {nettracer3d-0.8.1 → nettracer3d-0.8.2}/src/nettracer3d.egg-info/dependency_links.txt +0 -0
- {nettracer3d-0.8.1 → nettracer3d-0.8.2}/src/nettracer3d.egg-info/entry_points.txt +0 -0
- {nettracer3d-0.8.1 → nettracer3d-0.8.2}/src/nettracer3d.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: nettracer3d
|
|
3
|
+
Version: 0.8.2
|
|
4
|
+
Summary: Scripts for intializing and analyzing networks from segmentations of three dimensional images.
|
|
5
|
+
Author-email: Liam McLaughlin <liamm@wustl.edu>
|
|
6
|
+
Project-URL: Documentation, https://nettracer3d.readthedocs.io/en/latest/
|
|
7
|
+
Project-URL: Video_Tutorial, https://www.youtube.com/watch?v=cRatn5VTWDY
|
|
8
|
+
Project-URL: Reference_Citation_For_Use, https://doi.org/10.1101/2024.07.29.605633
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: License :: Other/Proprietary License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Requires-Python: >=3.7
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
License-File: LICENSE
|
|
15
|
+
Requires-Dist: numpy
|
|
16
|
+
Requires-Dist: scipy
|
|
17
|
+
Requires-Dist: scikit-image
|
|
18
|
+
Requires-Dist: Pillow
|
|
19
|
+
Requires-Dist: matplotlib
|
|
20
|
+
Requires-Dist: networkx
|
|
21
|
+
Requires-Dist: opencv-python-headless
|
|
22
|
+
Requires-Dist: openpyxl
|
|
23
|
+
Requires-Dist: pandas
|
|
24
|
+
Requires-Dist: tifffile
|
|
25
|
+
Requires-Dist: qtrangeslider
|
|
26
|
+
Requires-Dist: PyQt6
|
|
27
|
+
Requires-Dist: scikit-learn
|
|
28
|
+
Requires-Dist: nibabel
|
|
29
|
+
Requires-Dist: setuptools
|
|
30
|
+
Requires-Dist: umap-learn
|
|
31
|
+
Provides-Extra: cuda11
|
|
32
|
+
Requires-Dist: cupy-cuda11x; extra == "cuda11"
|
|
33
|
+
Provides-Extra: cuda12
|
|
34
|
+
Requires-Dist: cupy-cuda12x; extra == "cuda12"
|
|
35
|
+
Provides-Extra: cupy
|
|
36
|
+
Requires-Dist: cupy; extra == "cupy"
|
|
37
|
+
Provides-Extra: cellpose
|
|
38
|
+
Requires-Dist: cellpose[GUI]; extra == "cellpose"
|
|
39
|
+
Provides-Extra: viz
|
|
40
|
+
Requires-Dist: napari; extra == "viz"
|
|
41
|
+
Provides-Extra: all
|
|
42
|
+
Requires-Dist: cellpose[GUI]; extra == "all"
|
|
43
|
+
Requires-Dist: napari; extra == "all"
|
|
44
|
+
Dynamic: license-file
|
|
45
|
+
|
|
46
|
+
NetTracer3D is a python package developed for both 2D and 3D analysis of microscopic images in the .tif file format. It supports generation of 3D networks showing the relationships between objects (or nodes) in three dimensional space, either based on their own proximity or connectivity via connecting objects such as nerves or blood vessels. In addition to these functionalities are several advanced 3D data processing algorithms, such as labeling of branched structures or abstraction of branched structures into networks. Note that nettracer3d uses segmented data, which can be segmented from other softwares such as ImageJ and imported into NetTracer3D, although it does offer its own segmentation via intensity and volumetric thresholding, or random forest machine learning segmentation. NetTracer3D currently has a fully functional GUI. To use the GUI, after installing the nettracer3d package via pip, enter the command 'nettracer3d' in your command prompt:
|
|
47
|
+
|
|
48
|
+
--- Documentation ---
|
|
49
|
+
|
|
50
|
+
Please see: https://nettracer3d.readthedocs.io/en/latest/
|
|
51
|
+
|
|
52
|
+
--- Installation ---
|
|
53
|
+
|
|
54
|
+
To install nettracer3d, simply install Python and use this command in your command terminal:
|
|
55
|
+
|
|
56
|
+
pip install nettracer3d
|
|
57
|
+
|
|
58
|
+
I recommend installing the program as an Anaconda package to ensure its modules are work together on your specific system:
|
|
59
|
+
(Install anaconda at the link below, set up a new python env for nettracer3d, then use the same pip command).
|
|
60
|
+
|
|
61
|
+
https://www.anaconda.com/download?utm_source=anacondadocs&utm_medium=documentation&utm_campaign=download&utm_content=installwindows
|
|
62
|
+
|
|
63
|
+
Optional Packages
|
|
64
|
+
~~~~~~~~~~~~~~~~~~
|
|
65
|
+
I recommend including Napari (Chi-Li Chiu, Nathan Clack, the napari community, napari: a Python Multi-Dimensional Image Viewer Platform for the Research Community, Microscopy and Microanalysis, Volume 28, Issue S1, 1 August 2022, Pages 1576–1577, https://doi.org/10.1017/S1431927622006328) in the download as well, which allows NetTracer3D to use 3D displays. The standard package only comes with its native 2D slice display window.
|
|
66
|
+
If Napari is present, all 3D images and overlays from NetTracer3D can be easily displayed in 3D with a click of a button. To package with Napari, use this install command instead:
|
|
67
|
+
|
|
68
|
+
pip install nettracer3d[viz]
|
|
69
|
+
|
|
70
|
+
Additionally, for easy access to high-quality cell segmentation, as of version 0.8.2, NetTracer3D can be optionally packaged with Cellpose3. (Stringer, C., Pachitariu, M. Cellpose3: one-click image restoration for improved cellular segmentation. Nat Methods 22, 592–599 (2025). https://doi.org/10.1038/s41592-025-02595-5)
|
|
71
|
+
Cellpose3 is not involved with the rest of the program in any way, although its GUI can be opened from NetTracer3D's GUI, provided both are installed in the same environment. It is a top-tier cell segmenter which can assist in the production of cell networks.
|
|
72
|
+
To include Cellpose3 in the install, use this command:
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
pip install nettracer3d[cellpose]
|
|
76
|
+
|
|
77
|
+
Alternatively, both Napari and Cellpose can be included in the package with this command: (Or they can be independently installed with pip from the base package env)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
pip install nettracer3d[all]
|
|
81
|
+
|
|
82
|
+
GPU
|
|
83
|
+
~~~~~~~~~~~~~~~~~~
|
|
84
|
+
NetTracer3D is mostly CPU-bound, but a few functions can optionally use the GPU. To install optional GPU functionalities, first set up a CUDA toolkit that runs with the GPU on your machine. This requires an NVIDIA GPU. Then, find your GPUs compatible CUDA toolkit and install it with the auto-installer from the NVIDIA website: https://developer.nvidia.com/cuda-toolkit
|
|
85
|
+
|
|
86
|
+
With a CUDA toolkit installed, use:
|
|
87
|
+
|
|
88
|
+
pip install nettracer3d[CUDA11] #If your CUDA toolkit is version 11
|
|
89
|
+
pip install nettracer3d[CUDA12] #If your CUDA toolkit is version 12
|
|
90
|
+
pip install nettracer3d[cupy] #For the generic cupy library (The above two are usually the ones you want)
|
|
91
|
+
|
|
92
|
+
Or if you've already installed the NetTracer3D base package and want to get just the GPU associated packages:
|
|
93
|
+
|
|
94
|
+
pip install cupy-cuda11x #If your CUDA toolkit is version 11
|
|
95
|
+
pip install cupy-cuda12x #If your CUDA toolkit is version 12
|
|
96
|
+
pip install cupy #For the generic cupy library (The above two are usually the ones you want)
|
|
97
|
+
|
|
98
|
+
While not related to NetTracer3D, if you want to use Cellpose3 (for which GPU-usage is somewhat obligatory) to help segment cells for any networks, you will also want to install pytorch here: https://pytorch.org/. Use the pytorch build menu on this webpage to find a pip install command that is compatible with Python and your CUDA version.
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
This gui is built from the PyQt6 package and therefore may not function on dockers or virtual envs that are unable to support PyQt6 displays.
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
For a (slightly outdated) video tutorial on using the GUI: https://www.youtube.com/watch?v=cRatn5VTWDY
|
|
105
|
+
|
|
106
|
+
NetTracer3D is free to use/fork for academic/nonprofit use so long as citation is provided, and is available for commercial use at a fee (see license file for information).
|
|
107
|
+
|
|
108
|
+
NetTracer3D was developed by Liam McLaughlin while working under Dr. Sanjay Jain at Washington University School of Medicine.
|
|
109
|
+
|
|
110
|
+
-- Version 0.8.2 Updates --
|
|
111
|
+
|
|
112
|
+
* Bug Fixes.
|
|
113
|
+
* Improved some of the image viewer window features.
|
|
114
|
+
* New option to zoom in on specific windows by clicking + dragging while in zoom mode.
|
|
115
|
+
* Added more features to UMAP/community neighborhood clustering (optional DBSCAN clustering, results more robust to node distribution)
|
|
116
|
+
* Made Napari and optional rather than core dependency.
|
|
117
|
+
* Added Cellpose as an optional dependency.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
NetTracer3D is a python package developed for both 2D and 3D analysis of microscopic images in the .tif file format. It supports generation of 3D networks showing the relationships between objects (or nodes) in three dimensional space, either based on their own proximity or connectivity via connecting objects such as nerves or blood vessels. In addition to these functionalities are several advanced 3D data processing algorithms, such as labeling of branched structures or abstraction of branched structures into networks. Note that nettracer3d uses segmented data, which can be segmented from other softwares such as ImageJ and imported into NetTracer3D, although it does offer its own segmentation via intensity and volumetric thresholding, or random forest machine learning segmentation. NetTracer3D currently has a fully functional GUI. To use the GUI, after installing the nettracer3d package via pip, enter the command 'nettracer3d' in your command prompt:
|
|
2
|
+
|
|
3
|
+
--- Documentation ---
|
|
4
|
+
|
|
5
|
+
Please see: https://nettracer3d.readthedocs.io/en/latest/
|
|
6
|
+
|
|
7
|
+
--- Installation ---
|
|
8
|
+
|
|
9
|
+
To install nettracer3d, simply install Python and use this command in your command terminal:
|
|
10
|
+
|
|
11
|
+
pip install nettracer3d
|
|
12
|
+
|
|
13
|
+
I recommend installing the program as an Anaconda package to ensure its modules are work together on your specific system:
|
|
14
|
+
(Install anaconda at the link below, set up a new python env for nettracer3d, then use the same pip command).
|
|
15
|
+
|
|
16
|
+
https://www.anaconda.com/download?utm_source=anacondadocs&utm_medium=documentation&utm_campaign=download&utm_content=installwindows
|
|
17
|
+
|
|
18
|
+
Optional Packages
|
|
19
|
+
~~~~~~~~~~~~~~~~~~
|
|
20
|
+
I recommend including Napari (Chi-Li Chiu, Nathan Clack, the napari community, napari: a Python Multi-Dimensional Image Viewer Platform for the Research Community, Microscopy and Microanalysis, Volume 28, Issue S1, 1 August 2022, Pages 1576–1577, https://doi.org/10.1017/S1431927622006328) in the download as well, which allows NetTracer3D to use 3D displays. The standard package only comes with its native 2D slice display window.
|
|
21
|
+
If Napari is present, all 3D images and overlays from NetTracer3D can be easily displayed in 3D with a click of a button. To package with Napari, use this install command instead:
|
|
22
|
+
|
|
23
|
+
pip install nettracer3d[viz]
|
|
24
|
+
|
|
25
|
+
Additionally, for easy access to high-quality cell segmentation, as of version 0.8.2, NetTracer3D can be optionally packaged with Cellpose3. (Stringer, C., Pachitariu, M. Cellpose3: one-click image restoration for improved cellular segmentation. Nat Methods 22, 592–599 (2025). https://doi.org/10.1038/s41592-025-02595-5)
|
|
26
|
+
Cellpose3 is not involved with the rest of the program in any way, although its GUI can be opened from NetTracer3D's GUI, provided both are installed in the same environment. It is a top-tier cell segmenter which can assist in the production of cell networks.
|
|
27
|
+
To include Cellpose3 in the install, use this command:
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
pip install nettracer3d[cellpose]
|
|
31
|
+
|
|
32
|
+
Alternatively, both Napari and Cellpose can be included in the package with this command: (Or they can be independently installed with pip from the base package env)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
pip install nettracer3d[all]
|
|
36
|
+
|
|
37
|
+
GPU
|
|
38
|
+
~~~~~~~~~~~~~~~~~~
|
|
39
|
+
NetTracer3D is mostly CPU-bound, but a few functions can optionally use the GPU. To install optional GPU functionalities, first set up a CUDA toolkit that runs with the GPU on your machine. This requires an NVIDIA GPU. Then, find your GPUs compatible CUDA toolkit and install it with the auto-installer from the NVIDIA website: https://developer.nvidia.com/cuda-toolkit
|
|
40
|
+
|
|
41
|
+
With a CUDA toolkit installed, use:
|
|
42
|
+
|
|
43
|
+
pip install nettracer3d[CUDA11] #If your CUDA toolkit is version 11
|
|
44
|
+
pip install nettracer3d[CUDA12] #If your CUDA toolkit is version 12
|
|
45
|
+
pip install nettracer3d[cupy] #For the generic cupy library (The above two are usually the ones you want)
|
|
46
|
+
|
|
47
|
+
Or if you've already installed the NetTracer3D base package and want to get just the GPU associated packages:
|
|
48
|
+
|
|
49
|
+
pip install cupy-cuda11x #If your CUDA toolkit is version 11
|
|
50
|
+
pip install cupy-cuda12x #If your CUDA toolkit is version 12
|
|
51
|
+
pip install cupy #For the generic cupy library (The above two are usually the ones you want)
|
|
52
|
+
|
|
53
|
+
While not related to NetTracer3D, if you want to use Cellpose3 (for which GPU-usage is somewhat obligatory) to help segment cells for any networks, you will also want to install pytorch here: https://pytorch.org/. Use the pytorch build menu on this webpage to find a pip install command that is compatible with Python and your CUDA version.
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
This gui is built from the PyQt6 package and therefore may not function on dockers or virtual envs that are unable to support PyQt6 displays.
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
For a (slightly outdated) video tutorial on using the GUI: https://www.youtube.com/watch?v=cRatn5VTWDY
|
|
60
|
+
|
|
61
|
+
NetTracer3D is free to use/fork for academic/nonprofit use so long as citation is provided, and is available for commercial use at a fee (see license file for information).
|
|
62
|
+
|
|
63
|
+
NetTracer3D was developed by Liam McLaughlin while working under Dr. Sanjay Jain at Washington University School of Medicine.
|
|
64
|
+
|
|
65
|
+
-- Version 0.8.2 Updates --
|
|
66
|
+
|
|
67
|
+
* Bug Fixes.
|
|
68
|
+
* Improved some of the image viewer window features.
|
|
69
|
+
* New option to zoom in on specific windows by clicking + dragging while in zoom mode.
|
|
70
|
+
* Added more features to UMAP/community neighborhood clustering (optional DBSCAN clustering, results more robust to node distribution)
|
|
71
|
+
* Made Napari and optional rather than core dependency.
|
|
72
|
+
* Added Cellpose as an optional dependency.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "nettracer3d"
|
|
3
|
-
version = "0.8.
|
|
3
|
+
version = "0.8.2"
|
|
4
4
|
authors = [
|
|
5
5
|
{ name="Liam McLaughlin", email="liamm@wustl.edu" },
|
|
6
6
|
]
|
|
@@ -16,7 +16,6 @@ dependencies = [
|
|
|
16
16
|
"opencv-python-headless",
|
|
17
17
|
"openpyxl",
|
|
18
18
|
"pandas",
|
|
19
|
-
"napari",
|
|
20
19
|
"tifffile",
|
|
21
20
|
"qtrangeslider",
|
|
22
21
|
"PyQt6",
|
|
@@ -35,15 +34,17 @@ classifiers = [
|
|
|
35
34
|
]
|
|
36
35
|
|
|
37
36
|
[project.optional-dependencies]
|
|
38
|
-
|
|
39
|
-
"cupy-cuda11x"
|
|
40
|
-
]
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
"
|
|
46
|
-
|
|
37
|
+
# GPU options (choose one)
|
|
38
|
+
CUDA11 = ["cupy-cuda11x"]
|
|
39
|
+
CUDA12 = ["cupy-cuda12x"]
|
|
40
|
+
cupy = ["cupy"]
|
|
41
|
+
|
|
42
|
+
# Features
|
|
43
|
+
cellpose = ["cellpose[GUI]"]
|
|
44
|
+
viz = ["napari"]
|
|
45
|
+
|
|
46
|
+
# All non-GPU features
|
|
47
|
+
all = ["cellpose[GUI]", "napari"]
|
|
47
48
|
|
|
48
49
|
[project.scripts]
|
|
49
50
|
nettracer3d = "nettracer3d.run:main"
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
import sys
|
|
3
|
+
import threading
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from PyQt6.QtWidgets import QMessageBox, QWidget
|
|
6
|
+
|
|
7
|
+
class CellposeGUILauncher:
|
|
8
|
+
"""Simple launcher for cellpose GUI in PyQt6 applications."""
|
|
9
|
+
|
|
10
|
+
def __init__(self, parent_widget=None):
|
|
11
|
+
"""
|
|
12
|
+
Initialize the launcher.
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
parent_widget: PyQt6 widget for showing message boxes (optional)
|
|
16
|
+
"""
|
|
17
|
+
self.parent_widget = parent_widget
|
|
18
|
+
self.cellpose_process = None
|
|
19
|
+
|
|
20
|
+
def launch_cellpose_gui(self, image_path=None, working_directory=None):
|
|
21
|
+
"""
|
|
22
|
+
Launch cellpose GUI in a separate thread.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
image_path (str, optional): Path to image file to load automatically
|
|
26
|
+
working_directory (str, optional): Directory to start cellpose in
|
|
27
|
+
|
|
28
|
+
Returns:
|
|
29
|
+
bool: True if launch was initiated successfully
|
|
30
|
+
"""
|
|
31
|
+
def run_cellpose():
|
|
32
|
+
"""Function to run in separate thread."""
|
|
33
|
+
try:
|
|
34
|
+
# Build command
|
|
35
|
+
cmd = [sys.executable, "-m", "cellpose"]
|
|
36
|
+
|
|
37
|
+
# Add image path if provided
|
|
38
|
+
if image_path and Path(image_path).exists():
|
|
39
|
+
cmd.extend(["--image_path", str(image_path)])
|
|
40
|
+
|
|
41
|
+
# Set working directory
|
|
42
|
+
cwd = working_directory if working_directory else None
|
|
43
|
+
|
|
44
|
+
# Launch cellpose GUI
|
|
45
|
+
self.cellpose_process = subprocess.Popen(
|
|
46
|
+
cmd,
|
|
47
|
+
cwd=cwd,
|
|
48
|
+
stdout=subprocess.PIPE,
|
|
49
|
+
stderr=subprocess.PIPE
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
# Optional: wait for process to complete
|
|
53
|
+
# self.cellpose_process.wait()
|
|
54
|
+
|
|
55
|
+
except Exception as e:
|
|
56
|
+
if self.parent_widget:
|
|
57
|
+
# Show error in main thread
|
|
58
|
+
self.show_error(f"Failed to launch cellpose GUI: {str(e)}")
|
|
59
|
+
else:
|
|
60
|
+
print(f"Failed to launch cellpose GUI: {str(e)}")
|
|
61
|
+
|
|
62
|
+
try:
|
|
63
|
+
# Start cellpose in separate thread
|
|
64
|
+
thread = threading.Thread(target=run_cellpose, daemon=True)
|
|
65
|
+
thread.start()
|
|
66
|
+
|
|
67
|
+
if self.parent_widget:
|
|
68
|
+
self.show_info("Cellpose GUI launched!")
|
|
69
|
+
else:
|
|
70
|
+
print("Cellpose GUI launched!")
|
|
71
|
+
|
|
72
|
+
return True
|
|
73
|
+
|
|
74
|
+
except Exception as e:
|
|
75
|
+
if self.parent_widget:
|
|
76
|
+
self.show_error(f"Failed to start cellpose thread: {str(e)}")
|
|
77
|
+
else:
|
|
78
|
+
print(f"Failed to start cellpose thread: {str(e)}")
|
|
79
|
+
return False
|
|
80
|
+
|
|
81
|
+
def launch_with_directory(self, directory_path):
|
|
82
|
+
"""
|
|
83
|
+
Launch cellpose GUI with a specific directory.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
directory_path (str): Directory containing images
|
|
87
|
+
"""
|
|
88
|
+
cmd_args = ["--dir", str(directory_path)]
|
|
89
|
+
return self.launch_cellpose_gui_with_args(cmd_args, working_directory=directory_path)
|
|
90
|
+
|
|
91
|
+
def launch_cellpose_gui_with_args(self, additional_args=None, working_directory=None):
|
|
92
|
+
"""
|
|
93
|
+
Launch cellpose GUI with custom arguments.
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
additional_args (list): List of additional command line arguments
|
|
97
|
+
working_directory (str): Working directory for cellpose
|
|
98
|
+
"""
|
|
99
|
+
def run_cellpose_custom():
|
|
100
|
+
try:
|
|
101
|
+
cmd = [sys.executable, "-m", "cellpose"]
|
|
102
|
+
|
|
103
|
+
if additional_args:
|
|
104
|
+
cmd.extend(additional_args)
|
|
105
|
+
|
|
106
|
+
cwd = working_directory if working_directory else None
|
|
107
|
+
|
|
108
|
+
self.cellpose_process = subprocess.Popen(
|
|
109
|
+
cmd,
|
|
110
|
+
cwd=cwd,
|
|
111
|
+
stdout=subprocess.PIPE,
|
|
112
|
+
stderr=subprocess.PIPE
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
except Exception as e:
|
|
116
|
+
if self.parent_widget:
|
|
117
|
+
self.show_error(f"Failed to launch cellpose GUI: {str(e)}")
|
|
118
|
+
else:
|
|
119
|
+
print(f"Failed to launch cellpose GUI: {str(e)}")
|
|
120
|
+
|
|
121
|
+
try:
|
|
122
|
+
thread = threading.Thread(target=run_cellpose_custom, daemon=True)
|
|
123
|
+
thread.start()
|
|
124
|
+
return True
|
|
125
|
+
except Exception as e:
|
|
126
|
+
if self.parent_widget:
|
|
127
|
+
self.show_error(f"Failed to start cellpose: {str(e)}")
|
|
128
|
+
return False
|
|
129
|
+
|
|
130
|
+
def is_cellpose_running(self):
|
|
131
|
+
"""
|
|
132
|
+
Check if cellpose process is still running.
|
|
133
|
+
|
|
134
|
+
Returns:
|
|
135
|
+
bool: True if cellpose is still running
|
|
136
|
+
"""
|
|
137
|
+
if self.cellpose_process is None:
|
|
138
|
+
return False
|
|
139
|
+
|
|
140
|
+
return self.cellpose_process.poll() is None
|
|
141
|
+
|
|
142
|
+
def close_cellpose(self):
|
|
143
|
+
"""Terminate the cellpose process if running."""
|
|
144
|
+
if self.cellpose_process and self.is_cellpose_running():
|
|
145
|
+
try:
|
|
146
|
+
self.cellpose_process.terminate()
|
|
147
|
+
self.cellpose_process.wait(timeout=5) # Wait up to 5 seconds
|
|
148
|
+
except subprocess.TimeoutExpired:
|
|
149
|
+
self.cellpose_process.kill() # Force kill if it doesn't terminate
|
|
150
|
+
except Exception as e:
|
|
151
|
+
print(f"Error closing cellpose: {e}")
|
|
152
|
+
|
|
153
|
+
def show_info(self, message):
|
|
154
|
+
"""Show info message if parent widget available."""
|
|
155
|
+
if self.parent_widget:
|
|
156
|
+
QMessageBox.information(self.parent_widget, "Cellpose Launcher", message)
|
|
157
|
+
|
|
158
|
+
def show_error(self, message):
|
|
159
|
+
"""Show error message if parent widget available."""
|
|
160
|
+
if self.parent_widget:
|
|
161
|
+
QMessageBox.critical(self.parent_widget, "Cellpose Error", message)
|
|
@@ -393,28 +393,105 @@ def find_hub_nodes(G: nx.Graph, proportion: float = 0.1) -> List:
|
|
|
393
393
|
return output
|
|
394
394
|
|
|
395
395
|
def get_color_name_mapping():
|
|
396
|
-
"""Return a dictionary of
|
|
396
|
+
"""Return a dictionary of descriptive color names and their RGB values."""
|
|
397
397
|
return {
|
|
398
|
-
|
|
399
|
-
'
|
|
400
|
-
'
|
|
401
|
-
'
|
|
402
|
-
'
|
|
398
|
+
# Reds
|
|
399
|
+
'crimson_red': (220, 20, 60),
|
|
400
|
+
'bright_red': (255, 0, 0),
|
|
401
|
+
'dark_red': (139, 0, 0),
|
|
402
|
+
'coral_red': (255, 127, 80),
|
|
403
|
+
'rose_red': (255, 102, 102),
|
|
404
|
+
'burgundy': (128, 0, 32),
|
|
405
|
+
'cherry_red': (222, 49, 99),
|
|
406
|
+
|
|
407
|
+
# Greens
|
|
408
|
+
'forest_green': (34, 139, 34),
|
|
409
|
+
'lime_green': (50, 205, 50),
|
|
410
|
+
'bright_green': (0, 255, 0),
|
|
411
|
+
'dark_green': (0, 100, 0),
|
|
412
|
+
'mint_green': (152, 255, 152),
|
|
413
|
+
'sage_green': (159, 183, 121),
|
|
414
|
+
'emerald_green': (80, 200, 120),
|
|
415
|
+
'olive_green': (128, 128, 0),
|
|
416
|
+
|
|
417
|
+
# Blues
|
|
418
|
+
'royal_blue': (65, 105, 225),
|
|
419
|
+
'bright_blue': (0, 0, 255),
|
|
420
|
+
'navy_blue': (0, 0, 128),
|
|
421
|
+
'sky_blue': (135, 206, 235),
|
|
422
|
+
'steel_blue': (70, 130, 180),
|
|
423
|
+
'powder_blue': (176, 224, 230),
|
|
424
|
+
'midnight_blue': (25, 25, 112),
|
|
425
|
+
'cobalt_blue': (0, 71, 171),
|
|
426
|
+
|
|
427
|
+
# Purples
|
|
428
|
+
'deep_purple': (75, 0, 130),
|
|
429
|
+
'royal_purple': (120, 81, 169),
|
|
430
|
+
'lavender': (230, 230, 250),
|
|
431
|
+
'plum_purple': (221, 160, 221),
|
|
432
|
+
'violet_purple': (238, 130, 238),
|
|
403
433
|
'magenta': (255, 0, 255),
|
|
404
|
-
'
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
'
|
|
408
|
-
'
|
|
409
|
-
'
|
|
410
|
-
'
|
|
411
|
-
'
|
|
412
|
-
'
|
|
413
|
-
'
|
|
414
|
-
|
|
415
|
-
|
|
434
|
+
'orchid': (218, 112, 214),
|
|
435
|
+
|
|
436
|
+
# Yellows & Golds
|
|
437
|
+
'bright_yellow': (255, 255, 0),
|
|
438
|
+
'golden_yellow': (255, 215, 0),
|
|
439
|
+
'lemon_yellow': (255, 247, 0),
|
|
440
|
+
'amber': (255, 191, 0),
|
|
441
|
+
'mustard_yellow': (255, 219, 88),
|
|
442
|
+
'cream': (255, 253, 208),
|
|
443
|
+
'wheat': (245, 222, 179),
|
|
444
|
+
|
|
445
|
+
# Oranges
|
|
446
|
+
'bright_orange': (255, 165, 0),
|
|
447
|
+
'burnt_orange': (204, 85, 0),
|
|
448
|
+
'peach': (255, 218, 185),
|
|
449
|
+
'tangerine': (255, 163, 67),
|
|
450
|
+
'pumpkin_orange': (255, 117, 24),
|
|
451
|
+
'apricot': (251, 206, 177),
|
|
452
|
+
|
|
453
|
+
# Pinks
|
|
454
|
+
'hot_pink': (255, 105, 180),
|
|
455
|
+
'light_pink': (255, 192, 203),
|
|
456
|
+
'deep_pink': (255, 20, 147),
|
|
457
|
+
'salmon_pink': (250, 128, 114),
|
|
458
|
+
'blush_pink': (255, 182, 193),
|
|
459
|
+
'fuchsia': (255, 0, 255),
|
|
460
|
+
|
|
461
|
+
# Cyans & Teals
|
|
462
|
+
'bright_cyan': (0, 255, 255),
|
|
463
|
+
'dark_teal': (0, 128, 128),
|
|
416
464
|
'turquoise': (64, 224, 208),
|
|
417
|
-
'
|
|
465
|
+
'aqua': (0, 255, 255),
|
|
466
|
+
'seafoam': (159, 226, 191),
|
|
467
|
+
'teal_blue': (54, 117, 136),
|
|
468
|
+
|
|
469
|
+
# Browns & Earth Tones
|
|
470
|
+
'chocolate_brown': (210, 105, 30),
|
|
471
|
+
'saddle_brown': (139, 69, 19),
|
|
472
|
+
'light_brown': (205, 133, 63),
|
|
473
|
+
'tan': (210, 180, 140),
|
|
474
|
+
'beige': (245, 245, 220),
|
|
475
|
+
'coffee_brown': (111, 78, 55),
|
|
476
|
+
'rust_brown': (183, 65, 14),
|
|
477
|
+
|
|
478
|
+
# Grays & Neutrals
|
|
479
|
+
'charcoal_gray': (54, 69, 79),
|
|
480
|
+
'light_gray': (211, 211, 211),
|
|
481
|
+
'silver': (192, 192, 192),
|
|
482
|
+
'slate_gray': (112, 128, 144),
|
|
483
|
+
'ash_gray': (178, 190, 181),
|
|
484
|
+
'smoke_gray': (152, 152, 152),
|
|
485
|
+
|
|
486
|
+
# Additional Distinctive Colors
|
|
487
|
+
'lime_yellow': (191, 255, 0),
|
|
488
|
+
'electric_blue': (125, 249, 255),
|
|
489
|
+
'neon_green': (57, 255, 20),
|
|
490
|
+
'wine_red': (114, 47, 55),
|
|
491
|
+
'copper': (184, 115, 51),
|
|
492
|
+
'ivory': (255, 255, 240),
|
|
493
|
+
'periwinkle': (204, 204, 255),
|
|
494
|
+
'mint': (189, 252, 201)
|
|
418
495
|
}
|
|
419
496
|
|
|
420
497
|
def rgb_to_color_name(rgb: Tuple[int, int, int]) -> str:
|
|
@@ -440,7 +517,7 @@ def rgb_to_color_name(rgb: Tuple[int, int, int]) -> str:
|
|
|
440
517
|
distance = np.sqrt(np.sum((rgb_array - np.array(color_rgb)) ** 2))
|
|
441
518
|
if distance < min_distance:
|
|
442
519
|
min_distance = distance
|
|
443
|
-
closest_color = color_name
|
|
520
|
+
closest_color = color_name + f" {str(rgb_array)}"
|
|
444
521
|
|
|
445
522
|
return closest_color
|
|
446
523
|
|