nettracer3d 0.6.8__py3-none-any.whl → 0.7.0__py3-none-any.whl

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.
@@ -188,11 +188,9 @@ def dilate_3D_dt(array, search_distance, xy_scaling=1.0, z_scaling=1.0, GPU = Fa
188
188
  Returns:
189
189
  Dilated 3D array
190
190
  """
191
- if array.shape[0] == 1:
192
191
 
193
- return nettracer.dilate_2D(array, search_distance, scaling = xy_scaling)
194
-
195
- # Determine which dimension needs resampling
192
+ # Determine which dimension needs resampling. the moral of the story is read documentation before you do something unecessary.
193
+ """
196
194
  if (z_scaling > xy_scaling):
197
195
  # Z dimension needs to be stretched
198
196
  zoom_factor = [z_scaling/xy_scaling, 1, 1] # Scale factor for [z, y, x]
@@ -208,11 +206,11 @@ def dilate_3D_dt(array, search_distance, xy_scaling=1.0, z_scaling=1.0, GPU = Fa
208
206
  zoom_factor = None
209
207
  rev_factor = None
210
208
  cardinal = xy_scaling
211
-
209
+ """
212
210
 
213
211
  # Resample the mask if needed
214
- if zoom_factor:
215
- array = ndimage.zoom(array, zoom_factor, order=0) # Use order=0 for binary masks
212
+ #if zoom_factor:
213
+ #array = ndimage.zoom(array, zoom_factor, order=0) # Use order=0 for binary masks
216
214
 
217
215
  # Invert the array (find background)
218
216
  inv = array < 1
@@ -220,22 +218,21 @@ def dilate_3D_dt(array, search_distance, xy_scaling=1.0, z_scaling=1.0, GPU = Fa
220
218
  if GPU:
221
219
  try:
222
220
  print("Attempting on GPU...")
223
- inv, indices = compute_distance_transform_GPU(inv, return_dists = True)
221
+ inv, indices = compute_distance_transform_GPU(inv, return_dists = True, sampling = [z_scaling, xy_scaling, xy_scaling])
224
222
  except:
225
223
  print("Failed, attempting on CPU...")
226
224
  #Who would have seen this coming?:
227
- inv, indices = compute_distance_transform(inv, return_dists = True)
225
+ inv, indices = compute_distance_transform(inv, return_dists = True, sampling = [z_scaling, xy_scaling, xy_scaling])
228
226
  else:
229
- inv, indices = compute_distance_transform(inv, return_dists = True)
227
+ inv, indices = compute_distance_transform(inv, return_dists = True, sampling = [z_scaling, xy_scaling, xy_scaling])
230
228
 
231
229
 
232
- inv = inv * cardinal
230
+ #inv = inv * cardinal
233
231
 
234
232
  # Threshold the distance transform to get dilated result
235
233
  inv = inv <= search_distance
236
234
 
237
-
238
- return inv.astype(np.uint8), indices, array, rev_factor
235
+ return inv.astype(np.uint8), indices, array
239
236
 
240
237
 
241
238
 
@@ -275,7 +272,7 @@ def smart_dilate(nodes, dilate_xy, dilate_z, directory = None, GPU = True, fast_
275
272
  binary_nodes = binarize(nodes)
276
273
  dilated_binary_nodes = dilate_3D(binary_nodes, dilate_xy, dilate_xy, dilate_z)
277
274
  else:
278
- dilated_binary_nodes, nearest_label_indices, nodes, rev_factor = dilate_3D_dt(nodes, use_dt_dil_amount, GPU = GPU, xy_scaling = xy_scale, z_scaling = z_scale)
275
+ dilated_binary_nodes, nearest_label_indices, nodes = dilate_3D_dt(nodes, use_dt_dil_amount, GPU = GPU, xy_scaling = xy_scale, z_scaling = z_scale)
279
276
  binary_nodes = binarize(nodes)
280
277
 
281
278
  # Step 3: Isolate the ring (binary dilated mask minus original binary mask)
@@ -352,8 +349,6 @@ def smart_dilate(nodes, dilate_xy, dilate_z, directory = None, GPU = True, fast_
352
349
  if (dilated_nodes_with_labels.shape[1] < original_shape[1]) and fast_dil: #If downsample was used, upsample output
353
350
  dilated_nodes_with_labels = nettracer.upsample_with_padding(dilated_nodes_with_labels, downsample_needed, original_shape)
354
351
  dilated_nodes_with_labels = dilated_nodes_with_labels * dilated_mask
355
- elif (dilated_nodes_with_labels.shape[1] != original_shape[1]) and not fast_dil:
356
- dilated_nodes_with_labels = ndimage.zoom(dilated_nodes_with_labels, rev_factor, order=0)
357
352
 
358
353
  if directory is not None:
359
354
  try:
@@ -472,16 +467,17 @@ def smart_label(binary_array, label_array, directory = None, GPU = True, predown
472
467
 
473
468
  return dilated_nodes_with_labels
474
469
 
475
- def compute_distance_transform_GPU(nodes, return_dists = False):
470
+ def compute_distance_transform_GPU(nodes, return_dists = False, sampling = [1, 1, 1]):
476
471
  is_pseudo_3d = nodes.shape[0] == 1
477
472
  if is_pseudo_3d:
478
473
  nodes = np.squeeze(nodes) # Convert to 2D for processing
474
+ del sampling[0]
479
475
 
480
476
  # Convert numpy array to CuPy array
481
477
  nodes_cp = cp.asarray(nodes)
482
478
 
483
479
  # Compute the distance transform on the GPU
484
- dists, nearest_label_indices = cpx.distance_transform_edt(nodes_cp, return_indices=True)
480
+ dists, nearest_label_indices = cpx.distance_transform_edt(nodes_cp, return_indices=True, sampling = sampling)
485
481
 
486
482
  # Convert results back to numpy arrays
487
483
  nearest_label_indices_np = cp.asnumpy(nearest_label_indices)
@@ -504,12 +500,13 @@ def compute_distance_transform_GPU(nodes, return_dists = False):
504
500
  return dists, nearest_label_indices_np
505
501
 
506
502
 
507
- def compute_distance_transform(nodes, return_dists = False):
503
+ def compute_distance_transform(nodes, return_dists = False, sampling = [1, 1, 1]):
508
504
  is_pseudo_3d = nodes.shape[0] == 1
509
505
  if is_pseudo_3d:
510
506
  nodes = np.squeeze(nodes) # Convert to 2D for processing
507
+ del sampling[0]
511
508
 
512
- dists, nearest_label_indices = distance_transform_edt(nodes, return_indices=True)
509
+ dists, nearest_label_indices = distance_transform_edt(nodes, return_indices=True, sampling = sampling)
513
510
 
514
511
  if is_pseudo_3d:
515
512
  # For 2D input, we get (2, H, W) but need (3, 1, H, W)
@@ -529,17 +526,18 @@ def compute_distance_transform(nodes, return_dists = False):
529
526
 
530
527
 
531
528
 
532
- def compute_distance_transform_distance_GPU(nodes):
529
+ def compute_distance_transform_distance_GPU(nodes, sampling = [1, 1, 1]):
533
530
 
534
531
  is_pseudo_3d = nodes.shape[0] == 1
535
532
  if is_pseudo_3d:
536
533
  nodes = np.squeeze(nodes) # Convert to 2D for processing
534
+ del sampling[0]
537
535
 
538
536
  # Convert numpy array to CuPy array
539
537
  nodes_cp = cp.asarray(nodes)
540
538
 
541
539
  # Compute the distance transform on the GPU
542
- distance = cpx.distance_transform_edt(nodes_cp)
540
+ distance = cpx.distance_transform_edt(nodes_cp, sampling = sampling)
543
541
 
544
542
  # Convert results back to numpy arrays
545
543
  distance = cp.asnumpy(distance)
@@ -550,14 +548,15 @@ def compute_distance_transform_distance_GPU(nodes):
550
548
  return distance
551
549
 
552
550
 
553
- def compute_distance_transform_distance(nodes):
551
+ def compute_distance_transform_distance(nodes, sampling = [1, 1, 1]):
554
552
 
555
553
  is_pseudo_3d = nodes.shape[0] == 1
556
554
  if is_pseudo_3d:
557
555
  nodes = np.squeeze(nodes) # Convert to 2D for processing
556
+ del sampling[0]
558
557
 
559
558
  # Fallback to CPU if there's an issue with GPU computation
560
- distance = distance_transform_edt(nodes)
559
+ distance = distance_transform_edt(nodes, sampling = sampling)
561
560
  if is_pseudo_3d:
562
561
  np.expand_dims(distance, axis = 0)
563
562
  return distance
@@ -1,14 +1,15 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nettracer3d
3
- Version: 0.6.8
3
+ Version: 0.7.0
4
4
  Summary: Scripts for intializing and analyzing networks from segmentations of three dimensional images.
5
- Author-email: Liam McLaughlin <mclaughlinliam99@gmail.com>
6
- Project-URL: User_Tutorial, https://www.youtube.com/watch?v=cRatn5VTWDY
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
7
8
  Project-URL: Reference_Citation_For_Use, https://doi.org/10.1101/2024.07.29.605633
8
9
  Classifier: Programming Language :: Python :: 3
9
10
  Classifier: License :: Other/Proprietary License
10
11
  Classifier: Operating System :: OS Independent
11
- Requires-Python: >=3.8
12
+ Requires-Python: ==3.11
12
13
  Description-Content-Type: text/markdown
13
14
  License-File: LICENSE
14
15
  Requires-Dist: numpy==1.26.4
@@ -38,16 +39,48 @@ Dynamic: license-file
38
39
 
39
40
  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:
40
41
 
42
+ --- Documentation ---
41
43
 
42
- 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. More advanced documentation is coming down the line, but for now please see: https://www.youtube.com/watch?v=cRatn5VTWDY
43
- for a video tutorial on using the GUI.
44
+ Please see: https://nettracer3d.readthedocs.io/en/latest/
45
+
46
+ --- Installation ---
47
+
48
+ To install nettracer3d, simply install Python and use this command in your command terminal:
49
+
50
+ pip install nettracer3d
51
+
52
+ I recommend installing the program as an Anaconda package to ensure its modules are work together on your specific system:
53
+ (Install anaconda at the link below, set up a new python env for nettracer3d, then use the same pip command).
54
+
55
+ https://www.anaconda.com/download?utm_source=anacondadocs&utm_medium=documentation&utm_campaign=download&utm_content=installwindows
56
+
57
+ nettracer3d mostly utilizes the CPU for processing and visualization, although it does have a few GPU-aided options. If you would like to use the GPU for these, you will need an NVIDIA GPU and a corresponding CUDA toolkit which can be installed here:
58
+ https://developer.nvidia.com/cuda-toolkit
59
+
60
+ To install nettracer3d with associated GPU-supporting packages, please use:
61
+
62
+ If your CUDA toolkit is version 11: pip install nettracer3d[CUDA11]
63
+ If your CUDA toolkit is version 12: pip install nettracer3d[CUDA12]
64
+ If you just want the entire cupy library: pip install nettracer3d[cupy]
65
+
66
+
67
+ 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.
68
+
69
+
70
+ For a (slightly outdated) video tutorial on using the GUI: https://www.youtube.com/watch?v=cRatn5VTWDY
44
71
 
45
72
  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).
46
73
 
47
74
  NetTracer3D was developed by Liam McLaughlin while working under Dr. Sanjay Jain at Washington University School of Medicine.
48
75
 
49
- -- Version 0.6.8 updates --
76
+ -- Version 0.7.0 Updates --
77
+
78
+ 1. Added new function in 'Analyze -> Stats -> Cluster Analysis'
79
+ * This function allows the user to create a ripley's K or H function to compare the relative clustering of two types of nodes, or of one type of node vs itself.
50
80
 
51
- 1. Added new fill-can and 3D-brush functionalities to the brush mode (press f in brush mode to toggle the fill can. Press d while in brush mode to use the 3D painting tools. Standard Mouse wheel scrolling in the 3D painter will change how many frames you paint on - ie. 5 lets you paint 2 above and 2 below).
81
+ 2. Added new function in 'Analyze -> Randomize -> Scramble Nodes'
82
+ * This function randomly rearranges the node (centroids) for comparison with other centroid-using methods, as a possible way to demonstrate non-random behavior.
83
+ * The randomize menu is likewise new and the 'Generate Equivalent Random Network' method was moved there.
52
84
 
53
- 1.5. Added single-use ctrl-z functionality to the fill can only because of how easily it can mess up. (Leaving the fill can mode will garbage collect the backup image though).
85
+ 3. Bug fixes.
86
+ * Importantly fixed a bug with dt-based dilation not working in 2D, which I had accidentally introduced recently.
@@ -0,0 +1,20 @@
1
+ nettracer3d/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ nettracer3d/community_extractor.py,sha256=5v9SCCLX3P1RX0fjPVKH5NHMFkMolZ5BTe0bR_a67xg,24479
3
+ nettracer3d/modularity.py,sha256=FH3GpTHorRNkdQULe-2DWgFE3i0_u__hrao7Nx_6Ge4,30249
4
+ nettracer3d/morphology.py,sha256=kEzuzBxHHpWt3o_LHMXYJGJT8-Z_dEP99QpZjOkavzE,19742
5
+ nettracer3d/nettracer.py,sha256=dnnWEr9xpzoxV-NqLJm4DAFmZJ25CSjhA85AR_LT8Qc,218452
6
+ nettracer3d/nettracer_gui.py,sha256=jeqsjaLGdaXdPcuy3Z3iEVnaOvyGDTEjD8uVkoNPFtk,426501
7
+ nettracer3d/network_analysis.py,sha256=q1q7lxtA3lebxitfC_jfiT9cnpYXJw4q0Oy2_-Aj8qE,48068
8
+ nettracer3d/network_draw.py,sha256=F7fw6Pcf4qWOhdKwLmhwqWdschbDlHzwCVolQC9imeU,14117
9
+ nettracer3d/node_draw.py,sha256=k3sCTfUCJs3aH1C1q1gTNxDz9EAQbBd1hsUIJajxRx8,9823
10
+ nettracer3d/proximity.py,sha256=2Fj1UTKDEFBf7r1SgWXhiSINOTMjP4G5_Egu58l2zTk,24756
11
+ nettracer3d/run.py,sha256=xYeaAc8FCx8MuzTGyL3NR3mK7WZzffAYAH23bNRZYO4,127
12
+ nettracer3d/segmenter.py,sha256=gJS2AXqHhnw29cbzIxAah2LsrE7_7XnzG7mYSAovZ4I,87847
13
+ nettracer3d/simple_network.py,sha256=fP1gkDdtQcHruEZpUdasKdZeVacoLOxKhR3bY0L1CAQ,15426
14
+ nettracer3d/smart_dilate.py,sha256=MNFz-7P56OFwkNx2N24SH4gV0kL3KwzmZvAxg-T7f3U,25781
15
+ nettracer3d-0.7.0.dist-info/licenses/LICENSE,sha256=gM207DhJjWrxLuEWXl0Qz5ISbtWDmADfjHp3yC2XISs,888
16
+ nettracer3d-0.7.0.dist-info/METADATA,sha256=AqntVh2fF1VwxjLMongf_L9JpmNuZSO2irf_sFXrHvE,4955
17
+ nettracer3d-0.7.0.dist-info/WHEEL,sha256=SmOxYU7pzNKBqASvQJ7DjX3XGUF92lrGhMb3R6_iiqI,91
18
+ nettracer3d-0.7.0.dist-info/entry_points.txt,sha256=Nx1rr_0QhJXDBHAQg2vcqCzLMKBzSHfwy3xwGkueVyc,53
19
+ nettracer3d-0.7.0.dist-info/top_level.txt,sha256=zsYy9rZwirfCEOubolhee4TyzqBAL5gSUeFMzhFTX8c,12
20
+ nettracer3d-0.7.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (78.1.0)
2
+ Generator: setuptools (79.0.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,20 +0,0 @@
1
- nettracer3d/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- nettracer3d/community_extractor.py,sha256=5v9SCCLX3P1RX0fjPVKH5NHMFkMolZ5BTe0bR_a67xg,24479
3
- nettracer3d/modularity.py,sha256=V1f3s_vGd8EuVz27mzq6ycIGr0BWIpH7c7NU4QjgAHU,30247
4
- nettracer3d/morphology.py,sha256=P7hH9qpDBs0JtMSd95NmrvqoyD8BVq3AjAYv-MWoS_Y,19498
5
- nettracer3d/nettracer.py,sha256=HDU7z9UOpc2rK1tp-gV7vum27NBNVe8CmfZEeJ7lDBc,209469
6
- nettracer3d/nettracer_gui.py,sha256=Uo7INQF89Jb5YioqAjH25Qxxk2rMA9Y5J2hZ35s8ySU,409270
7
- nettracer3d/network_analysis.py,sha256=q1q7lxtA3lebxitfC_jfiT9cnpYXJw4q0Oy2_-Aj8qE,48068
8
- nettracer3d/network_draw.py,sha256=F7fw6Pcf4qWOhdKwLmhwqWdschbDlHzwCVolQC9imeU,14117
9
- nettracer3d/node_draw.py,sha256=k3sCTfUCJs3aH1C1q1gTNxDz9EAQbBd1hsUIJajxRx8,9823
10
- nettracer3d/proximity.py,sha256=B9DfbYMzxdlksQTY6EjyGi8iSQ54RZ5OEqfze2IOrBo,10916
11
- nettracer3d/run.py,sha256=xYeaAc8FCx8MuzTGyL3NR3mK7WZzffAYAH23bNRZYO4,127
12
- nettracer3d/segmenter.py,sha256=NcNeLSfg3ox-CfnUajT1E2iDqDkv5H6zSJOK_L5N4YI,85020
13
- nettracer3d/simple_network.py,sha256=fP1gkDdtQcHruEZpUdasKdZeVacoLOxKhR3bY0L1CAQ,15426
14
- nettracer3d/smart_dilate.py,sha256=ISZR6v52zf-MwhGx-JTfTOP8uo7pNGt-GJj7ydeuMAo,25587
15
- nettracer3d-0.6.8.dist-info/licenses/LICENSE,sha256=gM207DhJjWrxLuEWXl0Qz5ISbtWDmADfjHp3yC2XISs,888
16
- nettracer3d-0.6.8.dist-info/METADATA,sha256=-uaII8GnsHBV7nt_rmSlntFKv9QCDujtfhSEd_OuKVM,3523
17
- nettracer3d-0.6.8.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
18
- nettracer3d-0.6.8.dist-info/entry_points.txt,sha256=Nx1rr_0QhJXDBHAQg2vcqCzLMKBzSHfwy3xwGkueVyc,53
19
- nettracer3d-0.6.8.dist-info/top_level.txt,sha256=zsYy9rZwirfCEOubolhee4TyzqBAL5gSUeFMzhFTX8c,12
20
- nettracer3d-0.6.8.dist-info/RECORD,,