nettracer3d 1.2.3__tar.gz → 1.2.9__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.
Files changed (34) hide show
  1. {nettracer3d-1.2.3 → nettracer3d-1.2.9}/LICENSE +2 -2
  2. {nettracer3d-1.2.3/src/nettracer3d.egg-info → nettracer3d-1.2.9}/PKG-INFO +63 -20
  3. {nettracer3d-1.2.3 → nettracer3d-1.2.9}/README.md +54 -16
  4. {nettracer3d-1.2.3 → nettracer3d-1.2.9}/pyproject.toml +7 -7
  5. {nettracer3d-1.2.3 → nettracer3d-1.2.9}/src/nettracer3d/branch_stitcher.py +9 -4
  6. {nettracer3d-1.2.3 → nettracer3d-1.2.9}/src/nettracer3d/filaments.py +24 -9
  7. {nettracer3d-1.2.3 → nettracer3d-1.2.9}/src/nettracer3d/modularity.py +15 -6
  8. {nettracer3d-1.2.3 → nettracer3d-1.2.9}/src/nettracer3d/morphology.py +1 -1
  9. {nettracer3d-1.2.3 → nettracer3d-1.2.9}/src/nettracer3d/nettracer.py +76 -176
  10. {nettracer3d-1.2.3 → nettracer3d-1.2.9}/src/nettracer3d/nettracer_gui.py +219 -128
  11. {nettracer3d-1.2.3 → nettracer3d-1.2.9}/src/nettracer3d/network_analysis.py +36 -48
  12. {nettracer3d-1.2.3 → nettracer3d-1.2.9}/src/nettracer3d/network_draw.py +16 -15
  13. {nettracer3d-1.2.3 → nettracer3d-1.2.9}/src/nettracer3d/node_draw.py +4 -4
  14. {nettracer3d-1.2.3 → nettracer3d-1.2.9}/src/nettracer3d/proximity.py +36 -150
  15. {nettracer3d-1.2.3 → nettracer3d-1.2.9}/src/nettracer3d/simple_network.py +28 -9
  16. {nettracer3d-1.2.3 → nettracer3d-1.2.9}/src/nettracer3d/smart_dilate.py +212 -107
  17. {nettracer3d-1.2.3 → nettracer3d-1.2.9}/src/nettracer3d/tutorial.py +32 -65
  18. {nettracer3d-1.2.3 → nettracer3d-1.2.9/src/nettracer3d.egg-info}/PKG-INFO +63 -20
  19. {nettracer3d-1.2.3 → nettracer3d-1.2.9}/src/nettracer3d.egg-info/requires.txt +8 -1
  20. {nettracer3d-1.2.3 → nettracer3d-1.2.9}/setup.cfg +0 -0
  21. {nettracer3d-1.2.3 → nettracer3d-1.2.9}/src/nettracer3d/__init__.py +0 -0
  22. {nettracer3d-1.2.3 → nettracer3d-1.2.9}/src/nettracer3d/cellpose_manager.py +0 -0
  23. {nettracer3d-1.2.3 → nettracer3d-1.2.9}/src/nettracer3d/community_extractor.py +0 -0
  24. {nettracer3d-1.2.3 → nettracer3d-1.2.9}/src/nettracer3d/excelotron.py +0 -0
  25. {nettracer3d-1.2.3 → nettracer3d-1.2.9}/src/nettracer3d/neighborhoods.py +0 -0
  26. {nettracer3d-1.2.3 → nettracer3d-1.2.9}/src/nettracer3d/painting.py +0 -0
  27. {nettracer3d-1.2.3 → nettracer3d-1.2.9}/src/nettracer3d/run.py +0 -0
  28. {nettracer3d-1.2.3 → nettracer3d-1.2.9}/src/nettracer3d/segmenter.py +0 -0
  29. {nettracer3d-1.2.3 → nettracer3d-1.2.9}/src/nettracer3d/segmenter_GPU.py +0 -0
  30. {nettracer3d-1.2.3 → nettracer3d-1.2.9}/src/nettracer3d/stats.py +0 -0
  31. {nettracer3d-1.2.3 → nettracer3d-1.2.9}/src/nettracer3d.egg-info/SOURCES.txt +0 -0
  32. {nettracer3d-1.2.3 → nettracer3d-1.2.9}/src/nettracer3d.egg-info/dependency_links.txt +0 -0
  33. {nettracer3d-1.2.3 → nettracer3d-1.2.9}/src/nettracer3d.egg-info/entry_points.txt +0 -0
  34. {nettracer3d-1.2.3 → nettracer3d-1.2.9}/src/nettracer3d.egg-info/top_level.txt +0 -0
@@ -1,5 +1,5 @@
1
- NetTracer3D is freely available for academic and nonprofit use and can be obtained from Liam McLaughlin (boom2449@gmail.com) OR at pip (pip install nettracer3d), provided that the following citation is included in any abstract, paper, or presentation utilizing NetTracer3D:
1
+ NetTracer3D is freely available for academic and nonprofit use and can be obtained from Liam McLaughlin (boom2449@gmail.com) OR at pip (pip install nettracer3d), provided that citation is included in any abstract, paper, or presentation utilizing NetTracer3D.
2
2
 
3
- McLaughlin, L., Zhang, B., Sharma, S. et al. Three dimensional multiscalar neurovascular nephron connectivity map of the human kidney across the lifespan. Nat Commun 16, 5161 (2025). https://doi.org/10.1038/s41467-025-60435-8
3
+ (The official paper to cite is coming soon)
4
4
 
5
5
  Commercial use is available for a fee. Copyright © is held by Washington University. Please direct all commercial requests for licensing, information, and limited evaluation copies to Washington University's Office of Technology Management at OTM@wustl.edu.
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nettracer3d
3
- Version: 1.2.3
3
+ Version: 1.2.9
4
4
  Summary: Scripts for intializing and analyzing networks from segmentations of three dimensional images.
5
5
  Author-email: Liam McLaughlin <liamm@wustl.edu>
6
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
7
+ Project-URL: Youtube_Tutorial, https://www.youtube.com/watch?v=_4uDy0mzG94&list=PLsrhxiimzKJMZ3_gTWkfrcAdJQQobUhj7
8
+ Project-URL: Downloadable_Version, https://doi.org/10.5281/zenodo.17873800
9
9
  Classifier: Programming Language :: Python :: 3
10
10
  Classifier: License :: Other/Proprietary License
11
11
  Classifier: Operating System :: OS Independent
@@ -25,7 +25,6 @@ Requires-Dist: tifffile
25
25
  Requires-Dist: qtrangeslider
26
26
  Requires-Dist: PyQt6
27
27
  Requires-Dist: scikit-learn
28
- Requires-Dist: nibabel
29
28
  Requires-Dist: setuptools
30
29
  Requires-Dist: umap-learn
31
30
  Provides-Extra: cuda11
@@ -38,30 +37,78 @@ Provides-Extra: cellpose
38
37
  Requires-Dist: cellpose[GUI]; extra == "cellpose"
39
38
  Provides-Extra: viz
40
39
  Requires-Dist: napari; extra == "viz"
40
+ Provides-Extra: rec
41
+ Requires-Dist: napari; extra == "rec"
42
+ Requires-Dist: edt; extra == "rec"
43
+ Provides-Extra: edt
44
+ Requires-Dist: edt; extra == "edt"
41
45
  Provides-Extra: all
42
46
  Requires-Dist: cellpose[GUI]; extra == "all"
43
47
  Requires-Dist: napari; extra == "all"
48
+ Requires-Dist: edt; extra == "all"
44
49
  Dynamic: license-file
45
50
 
46
51
  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
52
 
53
+
48
54
  --- Documentation ---
49
55
 
50
56
  Please see: https://nettracer3d.readthedocs.io/en/latest/
51
57
 
52
- --- Installation ---
53
58
 
54
- To install nettracer3d, simply install Python and use this command in your command terminal:
59
+ --- Video Tutorial ---
60
+
61
+ Please see: https://www.youtube.com/watch?v=_4uDy0mzG94&list=PLsrhxiimzKJMZ3_gTWkfrcAdJQQobUhj7
62
+
63
+
64
+ --- Installing as a Python package ---
65
+
66
+ 1. **Get Python and Pip on your path**: To install nettracer3d, first install Python version 3.12. Make sure the Python installation installs pip, and that both Python and pip are available on your PATH. I recommend installing Python using the installer which is available here. Make sure to check the option to 'add Python to PATH' when it appears: https://www.python.org/downloads/
67
+
68
+
69
+ 2. **Base Package**: Next, use this command in your command terminal
70
+
71
+ * pip install nettracer3d
55
72
 
56
- pip install nettracer3d
73
+
74
+ 3. **For 3D Displays**: Or if you also want Napari for 3D displays:
75
+
76
+ * pip install nettracer3d[viz]
77
+
78
+
79
+ 4. **Optional Performance Boost**: If you are trying to process large images, you may also want to include the 'edt' module in your package. This will allow parallelized CPU calculations for several of the search functions which can increase their speed by an order of magnitude or more depending on how many cores your CPU has. This can be a major benefit if you have a strong CPU and sufficient RAM. It requires an extra pre-installation step, thus is not included by default. You will also have to install the C++ build tools from windows. Please head to this link, then download and run the installer: https://visualstudio.microsoft.com/visual-cpp-build-tools/. In the menu of the installer, select the 'Desktop Development with C++' option, then proceed to download/install it using the installation menu. You will likely want to be using the Python distributed from the actual Python website and not the windows store (or elsewhere) or the edt module may not work properly. To bundle with edt use:
80
+
81
+ * pip install nettracer3d[edt]
82
+
83
+
84
+ 5. **Recommended full package**: Or if you want to just get both edt and napari at once:
85
+
86
+ * pip install nettracer3d[rec]
87
+
88
+
89
+ 6. Likewise, if you already installed the default version, you can add napari and/or edt with just:
90
+
91
+ * pip install edt
92
+ * pip install napari
93
+
94
+
95
+ --- Installing as a Python package in Anaconda---
57
96
 
58
97
  I recommend installing the program as an Anaconda package to ensure its modules are work together on your specific system:
59
98
  (Install anaconda at the link below, set up a new python env for nettracer3d, then use the same pip command).
60
99
 
61
100
  https://www.anaconda.com/download?utm_source=anacondadocs&utm_medium=documentation&utm_campaign=download&utm_content=installwindows
62
101
 
63
- Optional Packages
64
- ~~~~~~~~~~~~~~~~~~
102
+
103
+ --- Using the downloadable version ---
104
+
105
+ Alternatively, you can download a compiled .exe of version 1.2.7 here: https://doi.org/10.5281/zenodo.17873800
106
+
107
+ Unzip the folder, then double click the NetTracer3D executable to run the program. Note that this version will be missing a few features compared to the Python package, namely GPU segmentation support and the ability to print updates to the command window. It will also not be updated as often.
108
+
109
+
110
+ --- Optional Packages ---
111
+
65
112
  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
113
  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
114
 
@@ -74,13 +121,13 @@ To include Cellpose3 in the install, use this command:
74
121
 
75
122
  pip install nettracer3d[cellpose]
76
123
 
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)
124
+ Alternatively, Napari, Cellpose, and edt can be included in the package with this command: (Or they can be independently installed with pip from the base package env)
78
125
 
79
126
 
80
127
  pip install nettracer3d[all]
81
128
 
82
- GPU
83
- ~~~~~~~~~~~~~~~~~~
129
+
130
+ --- GPU ---
84
131
  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
132
 
86
133
  With a CUDA toolkit installed, use:
@@ -101,17 +148,13 @@ While not related to NetTracer3D, if you want to use Cellpose3 (for which GPU-us
101
148
  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
149
 
103
150
 
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
- The current citation is here:
151
+ NetTracer3D is freely available for academic and nonprofit use and can obtained from pip (pip install nettracer3d), provided that citation is included in any abstract, paper, or presentation utilizing NetTracer3D.
108
152
 
109
- McLaughlin, L., Zhang, B., Sharma, S. et al. Three dimensional multiscalar neurovascular nephron connectivity map of the human kidney across the lifespan. Nat Commun 16, 5161 (2025). https://doi.org/10.1038/s41467-025-60435-8
153
+ (The official paper to cite is coming soon)
110
154
 
111
155
  NetTracer3D was developed by Liam McLaughlin while working under Dr. Sanjay Jain at Washington University School of Medicine.
112
156
 
113
- -- Version 1.2.3 Updates --
157
+ -- Version 1.2.9 Updates --
114
158
 
115
- * Tweaked the 'branch unification params' - now hard rejects any sharp forks in the branches so branches will mostly be straight.
116
-
159
+ * Some minor adjustments.
117
160
 
@@ -1,22 +1,64 @@
1
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
2
 
3
+
3
4
  --- Documentation ---
4
5
 
5
6
  Please see: https://nettracer3d.readthedocs.io/en/latest/
6
7
 
7
- --- Installation ---
8
8
 
9
- To install nettracer3d, simply install Python and use this command in your command terminal:
9
+ --- Video Tutorial ---
10
+
11
+ Please see: https://www.youtube.com/watch?v=_4uDy0mzG94&list=PLsrhxiimzKJMZ3_gTWkfrcAdJQQobUhj7
12
+
13
+
14
+ --- Installing as a Python package ---
15
+
16
+ 1. **Get Python and Pip on your path**: To install nettracer3d, first install Python version 3.12. Make sure the Python installation installs pip, and that both Python and pip are available on your PATH. I recommend installing Python using the installer which is available here. Make sure to check the option to 'add Python to PATH' when it appears: https://www.python.org/downloads/
17
+
18
+
19
+ 2. **Base Package**: Next, use this command in your command terminal
20
+
21
+ * pip install nettracer3d
10
22
 
11
- pip install nettracer3d
23
+
24
+ 3. **For 3D Displays**: Or if you also want Napari for 3D displays:
25
+
26
+ * pip install nettracer3d[viz]
27
+
28
+
29
+ 4. **Optional Performance Boost**: If you are trying to process large images, you may also want to include the 'edt' module in your package. This will allow parallelized CPU calculations for several of the search functions which can increase their speed by an order of magnitude or more depending on how many cores your CPU has. This can be a major benefit if you have a strong CPU and sufficient RAM. It requires an extra pre-installation step, thus is not included by default. You will also have to install the C++ build tools from windows. Please head to this link, then download and run the installer: https://visualstudio.microsoft.com/visual-cpp-build-tools/. In the menu of the installer, select the 'Desktop Development with C++' option, then proceed to download/install it using the installation menu. You will likely want to be using the Python distributed from the actual Python website and not the windows store (or elsewhere) or the edt module may not work properly. To bundle with edt use:
30
+
31
+ * pip install nettracer3d[edt]
32
+
33
+
34
+ 5. **Recommended full package**: Or if you want to just get both edt and napari at once:
35
+
36
+ * pip install nettracer3d[rec]
37
+
38
+
39
+ 6. Likewise, if you already installed the default version, you can add napari and/or edt with just:
40
+
41
+ * pip install edt
42
+ * pip install napari
43
+
44
+
45
+ --- Installing as a Python package in Anaconda---
12
46
 
13
47
  I recommend installing the program as an Anaconda package to ensure its modules are work together on your specific system:
14
48
  (Install anaconda at the link below, set up a new python env for nettracer3d, then use the same pip command).
15
49
 
16
50
  https://www.anaconda.com/download?utm_source=anacondadocs&utm_medium=documentation&utm_campaign=download&utm_content=installwindows
17
51
 
18
- Optional Packages
19
- ~~~~~~~~~~~~~~~~~~
52
+
53
+ --- Using the downloadable version ---
54
+
55
+ Alternatively, you can download a compiled .exe of version 1.2.7 here: https://doi.org/10.5281/zenodo.17873800
56
+
57
+ Unzip the folder, then double click the NetTracer3D executable to run the program. Note that this version will be missing a few features compared to the Python package, namely GPU segmentation support and the ability to print updates to the command window. It will also not be updated as often.
58
+
59
+
60
+ --- Optional Packages ---
61
+
20
62
  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
63
  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
64
 
@@ -29,13 +71,13 @@ To include Cellpose3 in the install, use this command:
29
71
 
30
72
  pip install nettracer3d[cellpose]
31
73
 
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)
74
+ Alternatively, Napari, Cellpose, and edt can be included in the package with this command: (Or they can be independently installed with pip from the base package env)
33
75
 
34
76
 
35
77
  pip install nettracer3d[all]
36
78
 
37
- GPU
38
- ~~~~~~~~~~~~~~~~~~
79
+
80
+ --- GPU ---
39
81
  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
82
 
41
83
  With a CUDA toolkit installed, use:
@@ -56,17 +98,13 @@ While not related to NetTracer3D, if you want to use Cellpose3 (for which GPU-us
56
98
  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
99
 
58
100
 
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
- The current citation is here:
101
+ NetTracer3D is freely available for academic and nonprofit use and can obtained from pip (pip install nettracer3d), provided that citation is included in any abstract, paper, or presentation utilizing NetTracer3D.
63
102
 
64
- McLaughlin, L., Zhang, B., Sharma, S. et al. Three dimensional multiscalar neurovascular nephron connectivity map of the human kidney across the lifespan. Nat Commun 16, 5161 (2025). https://doi.org/10.1038/s41467-025-60435-8
103
+ (The official paper to cite is coming soon)
65
104
 
66
105
  NetTracer3D was developed by Liam McLaughlin while working under Dr. Sanjay Jain at Washington University School of Medicine.
67
106
 
68
- -- Version 1.2.3 Updates --
107
+ -- Version 1.2.9 Updates --
69
108
 
70
- * Tweaked the 'branch unification params' - now hard rejects any sharp forks in the branches so branches will mostly be straight.
71
-
109
+ * Some minor adjustments.
72
110
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "nettracer3d"
3
- version = "1.2.3"
3
+ version = "1.2.9"
4
4
  authors = [
5
5
  { name="Liam McLaughlin", email="liamm@wustl.edu" },
6
6
  ]
@@ -20,10 +20,8 @@ dependencies = [
20
20
  "qtrangeslider",
21
21
  "PyQt6",
22
22
  "scikit-learn",
23
- "nibabel",
24
23
  "setuptools",
25
- "umap-learn"
26
- ]
24
+ "umap-learn"]
27
25
 
28
26
  readme = "README.md"
29
27
  requires-python = ">=3.7"
@@ -42,14 +40,16 @@ cupy = ["cupy"]
42
40
  # Features
43
41
  cellpose = ["cellpose[GUI]"]
44
42
  viz = ["napari"]
43
+ rec = ["napari", "edt"]
44
+ edt = ["edt"]
45
45
 
46
46
  # All non-GPU features
47
- all = ["cellpose[GUI]", "napari"]
47
+ all = ["cellpose[GUI]", "napari", "edt"]
48
48
 
49
49
  [project.scripts]
50
50
  nettracer3d = "nettracer3d.run:main"
51
51
 
52
52
  [project.urls]
53
53
  Documentation = "https://nettracer3d.readthedocs.io/en/latest/"
54
- Video_Tutorial = "https://www.youtube.com/watch?v=cRatn5VTWDY"
55
- Reference_Citation_For_Use = "https://doi.org/10.1101/2024.07.29.605633"
54
+ Youtube_Tutorial = "https://www.youtube.com/watch?v=_4uDy0mzG94&list=PLsrhxiimzKJMZ3_gTWkfrcAdJQQobUhj7"
55
+ Downloadable_Version = "https://doi.org/10.5281/zenodo.17873800"
@@ -3,6 +3,7 @@ import networkx as nx
3
3
  from . import nettracer as n3d
4
4
  from scipy.ndimage import distance_transform_edt, gaussian_filter, binary_fill_holes
5
5
  from scipy.spatial import cKDTree
6
+ from . import smart_dilate as sdl
6
7
  from skimage.morphology import remove_small_objects, skeletonize
7
8
  import warnings
8
9
  warnings.filterwarnings('ignore')
@@ -14,9 +15,13 @@ class VesselDenoiser:
14
15
  """
15
16
 
16
17
  def __init__(self,
17
- score_thresh = 2):
18
+ score_thresh = 2,
19
+ xy_scale = 1,
20
+ z_scale = 1):
18
21
 
19
22
  self.score_thresh = score_thresh
23
+ self.xy_scale = xy_scale
24
+ self.z_scale = z_scale
20
25
 
21
26
 
22
27
  def select_kernel_points_topology(self, data, skeleton):
@@ -336,7 +341,7 @@ class VesselDenoiser:
336
341
  # Compute distance transform
337
342
  if verbose:
338
343
  print("Computing distance transform...")
339
- distance_map = distance_transform_edt(data)
344
+ distance_map = sdl.compute_distance_transform_distance(data, fast_dil = True)
340
345
 
341
346
  # Extract endpoints
342
347
  if verbose:
@@ -390,14 +395,14 @@ class VesselDenoiser:
390
395
  return label_dict
391
396
 
392
397
 
393
- def trace(data, labeled_skeleton, verts, score_thresh=10, verbose=False):
398
+ def trace(data, labeled_skeleton, verts, score_thresh=10, xy_scale = 1, z_scale = 1, verbose=False):
394
399
  """
395
400
  Trace and unify skeleton labels using vertex-based endpoint grouping
396
401
  """
397
402
  skeleton = n3d.binarize(labeled_skeleton)
398
403
 
399
404
  # Create denoiser
400
- denoiser = VesselDenoiser(score_thresh=score_thresh)
405
+ denoiser = VesselDenoiser(score_thresh=score_thresh, xy_scale = xy_scale, z_scale = z_scale)
401
406
 
402
407
  # Run label unification
403
408
  label_dict = denoiser.denoise(data, skeleton, labeled_skeleton, verts, verbose=verbose)
@@ -1,10 +1,11 @@
1
1
  import numpy as np
2
2
  import networkx as nx
3
3
  from . import nettracer as n3d
4
- from scipy.ndimage import distance_transform_edt, gaussian_filter, binary_fill_holes
4
+ from scipy.ndimage import gaussian_filter, binary_fill_holes
5
5
  from scipy.spatial import cKDTree
6
6
  from skimage.morphology import remove_small_objects, skeletonize
7
7
  import warnings
8
+ from . import smart_dilate as sdl
8
9
  warnings.filterwarnings('ignore')
9
10
 
10
11
 
@@ -22,6 +23,8 @@ class VesselDenoiser:
22
23
  blob_volume = 200,
23
24
  spine_removal=0,
24
25
  score_thresh = 2,
26
+ xy_scale = 1,
27
+ z_scale = 1,
25
28
  radius_aware_distance=True):
26
29
  """
27
30
  Parameters:
@@ -46,6 +49,8 @@ class VesselDenoiser:
46
49
  self.spine_removal = spine_removal
47
50
  self.radius_aware_distance = radius_aware_distance
48
51
  self.score_thresh = score_thresh
52
+ self.xy_scale = xy_scale
53
+ self.z_scale = z_scale
49
54
 
50
55
  self._sphere_cache = {} # Cache sphere masks for different radii
51
56
 
@@ -93,16 +98,24 @@ class VesselDenoiser:
93
98
  # A voxel contributes to surface area if any neighbor is different
94
99
  for axis in range(3):
95
100
  for direction in [-1, 1]:
96
- # Shift array to compare with neighbors
97
- shifted = np.roll(labeled, direction, axis=axis)
101
+ # Pad with zeros only on the axis we're checking
102
+ pad_width = [(1, 1) if i == axis else (0, 0) for i in range(3)]
103
+ padded = np.pad(labeled, pad_width, mode='constant', constant_values=0)
98
104
 
99
- # Find faces exposed to different label (including background)
100
- exposed_faces = (labeled != shifted) & (labeled > 0)
105
+ # Roll the padded array
106
+ shifted = np.roll(padded, direction, axis=axis)
107
+
108
+ # Extract the center region (original size) from shifted
109
+ slices = [slice(1, -1) if i == axis else slice(None) for i in range(3)]
110
+ shifted_cropped = shifted[tuple(slices)]
111
+
112
+ # Find exposed faces
113
+ exposed_faces = (labeled != shifted_cropped) & (labeled > 0)
101
114
 
102
- # Count exposed faces per label
103
115
  face_counts = np.bincount(labeled[exposed_faces],
104
116
  minlength=num_features + 1)
105
117
  surface_areas += face_counts
118
+ del padded
106
119
 
107
120
  # Calculate sphericity for each component
108
121
  # Sphericity = (surface area of sphere with same volume) / (actual surface area)
@@ -931,7 +944,7 @@ class VesselDenoiser:
931
944
 
932
945
  if verbose:
933
946
  print("Step 3: Computing distance transform...")
934
- distance_map = distance_transform_edt(cleaned)
947
+ distance_map = sdl.compute_distance_transform_distance(cleaned, fast_dil = True)
935
948
 
936
949
  # Step 3: Sample kernels along skeleton
937
950
  if verbose:
@@ -1028,7 +1041,7 @@ class VesselDenoiser:
1028
1041
  return result
1029
1042
 
1030
1043
 
1031
- def trace(data, kernel_spacing = 1, max_distance = 20, min_component = 20, gap_tolerance = 5, blob_sphericity = 1.0, blob_volume = 200, spine_removal = 0, score_thresh = 2):
1044
+ def trace(data, kernel_spacing = 1, max_distance = 20, min_component = 20, gap_tolerance = 5, blob_sphericity = 1.0, blob_volume = 200, spine_removal = 0, score_thresh = 2, xy_scale = 1, z_scale = 1):
1032
1045
 
1033
1046
  """Main function with user prompts"""
1034
1047
 
@@ -1046,7 +1059,9 @@ def trace(data, kernel_spacing = 1, max_distance = 20, min_component = 20, gap_t
1046
1059
  blob_sphericity = blob_sphericity,
1047
1060
  blob_volume = blob_volume,
1048
1061
  spine_removal = spine_removal,
1049
- score_thresh = score_thresh
1062
+ score_thresh = score_thresh,
1063
+ xy_scale = xy_scale,
1064
+ z_scale = z_scale
1050
1065
  )
1051
1066
 
1052
1067
  # Run denoising
@@ -103,7 +103,7 @@ def read_excel_to_lists(file_path, sheet_name=0):
103
103
 
104
104
 
105
105
 
106
- def show_communities_flex(G, master_list, normalized_weights, geo_info=None, geometric=False, directory=None, weighted=True, partition=None, style=0):
106
+ def show_communities_flex(G, master_list, normalized_weights, geo_info=None, geometric=False, directory=None, weighted=True, partition=None, style=0, show_labels = True):
107
107
 
108
108
  if normalized_weights is None:
109
109
  G, edge_weights = network_analysis.weighted_network(master_list)
@@ -179,7 +179,8 @@ def show_communities_flex(G, master_list, normalized_weights, geo_info=None, geo
179
179
  normalized_weight = G[edge[0]][edge[1]]['weight']
180
180
  nx.draw_networkx_edges(G, pos, edgelist=[edge], width=5 * normalized_weight, edge_color='black')
181
181
 
182
- nx.draw_networkx_labels(G, pos)
182
+ if show_labels:
183
+ nx.draw_networkx_labels(G, pos)
183
184
 
184
185
  else:
185
186
  pos = nx.spring_layout(G)
@@ -195,20 +196,28 @@ def show_communities_flex(G, master_list, normalized_weights, geo_info=None, geo
195
196
  normalized_weight = G[edge[0]][edge[1]]['weight']
196
197
  nx.draw_networkx_edges(G, pos, edgelist=[edge], width=5 * normalized_weight, edge_color='black')
197
198
 
198
- nx.draw_networkx_labels(G, pos)
199
+ if show_labels:
200
+ nx.draw_networkx_labels(G, pos)
199
201
 
200
202
  else:
201
203
  # Create node color list based on partition and the same color mapping
202
- node_colors = [colors_matplotlib[partition[node]] for node in G.nodes()]
204
+ node_colors = []
205
+ for node in G.nodes():
206
+ try:
207
+ node_colors.append(colors_matplotlib[partition[node]])
208
+ except:
209
+ node_colors.append((1, 1, 1))
210
+
211
+ #node_colors = [colors_matplotlib[partition[node]] for node in G.nodes()]
203
212
 
204
213
  if geometric:
205
214
  pos, z_pos = simple_network.geometric_positions(geo_info[0], geo_info[1])
206
215
  node_sizes_list = [z_pos[node] for node in G.nodes()]
207
- nx.draw(G, pos, with_labels=True, font_color='black', font_weight='bold',
216
+ nx.draw(G, pos, with_labels=show_labels, font_color='black', font_weight='bold',
208
217
  node_size=node_sizes_list, node_color=node_colors, alpha=0.8, font_size=12)
209
218
  else:
210
219
  pos = nx.spring_layout(G)
211
- nx.draw(G, pos, with_labels=True, font_color='black', font_weight='bold',
220
+ nx.draw(G, pos, with_labels=show_labels, font_color='black', font_weight='bold',
212
221
  node_size=100, node_color=node_colors, alpha=0.8)
213
222
 
214
223
  plt.axis('off')
@@ -337,7 +337,7 @@ def search_neighbor_ids(nodes, targets, id_dict, neighborhood_dict, totals, sear
337
337
  targets = np.isin(nodes, targets)
338
338
  targets = nettracer.binarize(targets)
339
339
 
340
- dilated = nettracer.dilate(targets, search, xy_scale = xy_scale, z_scale = z_scale, fast_dil = fastdil)
340
+ dilated = nettracer.dilate_3D_dt(targets, search, xy_scaling = xy_scale, z_scaling = z_scale, fast_dil = fastdil)
341
341
  dilated = dilated - targets #technically we dont need the cores
342
342
  search_vol = np.count_nonzero(dilated) * xy_scale * xy_scale * z_scale #need this for density
343
343
  targets = dilated != 0