nettracer3d 0.7.6__tar.gz → 0.7.8__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 (28) hide show
  1. {nettracer3d-0.7.6/src/nettracer3d.egg-info → nettracer3d-0.7.8}/PKG-INFO +11 -2
  2. {nettracer3d-0.7.6 → nettracer3d-0.7.8}/README.md +11 -3
  3. {nettracer3d-0.7.6 → nettracer3d-0.7.8}/pyproject.toml +3 -2
  4. {nettracer3d-0.7.6 → nettracer3d-0.7.8}/src/nettracer3d/community_extractor.py +13 -29
  5. nettracer3d-0.7.8/src/nettracer3d/excelotron.py +1719 -0
  6. {nettracer3d-0.7.6 → nettracer3d-0.7.8}/src/nettracer3d/modularity.py +6 -9
  7. nettracer3d-0.7.8/src/nettracer3d/neighborhoods.py +354 -0
  8. {nettracer3d-0.7.6 → nettracer3d-0.7.8}/src/nettracer3d/nettracer.py +400 -13
  9. {nettracer3d-0.7.6 → nettracer3d-0.7.8}/src/nettracer3d/nettracer_gui.py +1120 -229
  10. {nettracer3d-0.7.6 → nettracer3d-0.7.8}/src/nettracer3d/proximity.py +89 -9
  11. {nettracer3d-0.7.6 → nettracer3d-0.7.8}/src/nettracer3d/smart_dilate.py +20 -15
  12. {nettracer3d-0.7.6 → nettracer3d-0.7.8/src/nettracer3d.egg-info}/PKG-INFO +11 -2
  13. {nettracer3d-0.7.6 → nettracer3d-0.7.8}/src/nettracer3d.egg-info/SOURCES.txt +2 -0
  14. {nettracer3d-0.7.6 → nettracer3d-0.7.8}/src/nettracer3d.egg-info/requires.txt +1 -0
  15. {nettracer3d-0.7.6 → nettracer3d-0.7.8}/LICENSE +0 -0
  16. {nettracer3d-0.7.6 → nettracer3d-0.7.8}/setup.cfg +0 -0
  17. {nettracer3d-0.7.6 → nettracer3d-0.7.8}/src/nettracer3d/__init__.py +0 -0
  18. {nettracer3d-0.7.6 → nettracer3d-0.7.8}/src/nettracer3d/morphology.py +0 -0
  19. {nettracer3d-0.7.6 → nettracer3d-0.7.8}/src/nettracer3d/network_analysis.py +0 -0
  20. {nettracer3d-0.7.6 → nettracer3d-0.7.8}/src/nettracer3d/network_draw.py +0 -0
  21. {nettracer3d-0.7.6 → nettracer3d-0.7.8}/src/nettracer3d/node_draw.py +0 -0
  22. {nettracer3d-0.7.6 → nettracer3d-0.7.8}/src/nettracer3d/run.py +0 -0
  23. {nettracer3d-0.7.6 → nettracer3d-0.7.8}/src/nettracer3d/segmenter.py +0 -0
  24. {nettracer3d-0.7.6 → nettracer3d-0.7.8}/src/nettracer3d/segmenter_GPU.py +0 -0
  25. {nettracer3d-0.7.6 → nettracer3d-0.7.8}/src/nettracer3d/simple_network.py +0 -0
  26. {nettracer3d-0.7.6 → nettracer3d-0.7.8}/src/nettracer3d.egg-info/dependency_links.txt +0 -0
  27. {nettracer3d-0.7.6 → nettracer3d-0.7.8}/src/nettracer3d.egg-info/entry_points.txt +0 -0
  28. {nettracer3d-0.7.6 → nettracer3d-0.7.8}/src/nettracer3d.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nettracer3d
3
- Version: 0.7.6
3
+ Version: 0.7.8
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/
@@ -28,6 +28,7 @@ Requires-Dist: PyQt6
28
28
  Requires-Dist: scikit-learn
29
29
  Requires-Dist: nibabel
30
30
  Requires-Dist: setuptools
31
+ Requires-Dist: umap-learn
31
32
  Provides-Extra: cuda11
32
33
  Requires-Dist: cupy-cuda11x; extra == "cuda11"
33
34
  Provides-Extra: cuda12
@@ -72,6 +73,14 @@ NetTracer3D is free to use/fork for academic/nonprofit use so long as citation i
72
73
 
73
74
  NetTracer3D was developed by Liam McLaughlin while working under Dr. Sanjay Jain at Washington University School of Medicine.
74
75
 
75
- -- Version 0.7.6 Updates --
76
+ -- Version 0.7.8 (and 0.7.7) Updates --
76
77
 
77
78
  * Bug Fixes
79
+ * Added the excel helper loader for better automated loading from QuPath exports specifically
80
+ * Added the ability to cluster communities into broader neighborhoods (with KMeans) based on their compositions.
81
+ * Added heatmap and UMAP graph displays based on community compositions.
82
+ * Added the ability to show heatmaps of nodes based on their density within their communities
83
+ * Added the ability to cluster nodes into communities based on spatial grouping in arbitrarily-sized cells (rather than just using the network)
84
+ * Added function to crop the current image
85
+ * More options under 'Modify Network'
86
+ * 'Show 3D' method now can render a bounding box.
@@ -34,6 +34,14 @@ NetTracer3D is free to use/fork for academic/nonprofit use so long as citation i
34
34
 
35
35
  NetTracer3D was developed by Liam McLaughlin while working under Dr. Sanjay Jain at Washington University School of Medicine.
36
36
 
37
- -- Version 0.7.6 Updates --
38
-
39
- * Bug Fixes
37
+ -- Version 0.7.8 (and 0.7.7) Updates --
38
+
39
+ * Bug Fixes
40
+ * Added the excel helper loader for better automated loading from QuPath exports specifically
41
+ * Added the ability to cluster communities into broader neighborhoods (with KMeans) based on their compositions.
42
+ * Added heatmap and UMAP graph displays based on community compositions.
43
+ * Added the ability to show heatmaps of nodes based on their density within their communities
44
+ * Added the ability to cluster nodes into communities based on spatial grouping in arbitrarily-sized cells (rather than just using the network)
45
+ * Added function to crop the current image
46
+ * More options under 'Modify Network'
47
+ * 'Show 3D' method now can render a bounding box.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "nettracer3d"
3
- version = "0.7.6"
3
+ version = "0.7.8"
4
4
  authors = [
5
5
  { name="Liam McLaughlin", email="liamm@wustl.edu" },
6
6
  ]
@@ -22,7 +22,8 @@ dependencies = [
22
22
  "PyQt6",
23
23
  "scikit-learn",
24
24
  "nibabel",
25
- "setuptools"
25
+ "setuptools",
26
+ "umap-learn"
26
27
  ]
27
28
 
28
29
  readme = "README.md"
@@ -533,46 +533,30 @@ def assign_node_colors(node_list: List[int], labeled_array: np.ndarray) -> Tuple
533
533
  return rgba_array, node_to_color_names
534
534
 
535
535
  def assign_community_colors(community_dict: Dict[int, int], labeled_array: np.ndarray) -> Tuple[np.ndarray, Dict[int, str]]:
536
- """
537
- Assign distinct colors to communities and create an RGBA image.
538
-
539
- Args:
540
- community_dict: Dictionary mapping node IDs to community numbers
541
- labeled_array: 3D numpy array with labels corresponding to node IDs
536
+ """Ultra-fast version using lookup table approach."""
542
537
 
543
- Returns:
544
- Tuple of (RGBA-coded numpy array (H, W, D, 4), dictionary mapping nodes to color names)
545
- """
546
- # Get unique communities and their sizes
538
+ # Same setup as before
547
539
  communities = set(community_dict.values())
548
540
  community_sizes = Counter(community_dict.values())
549
-
550
- # Sort communities by size (descending)
551
541
  sorted_communities = sorted(communities, key=lambda x: community_sizes[x], reverse=True)
552
542
 
553
- # Generate distinct colors
554
543
  colors = generate_distinct_colors(len(communities))
544
+ colors_rgba = np.array([(r, g, b, 255) for r, g, b in colors], dtype=np.uint8)
555
545
 
556
- # Convert RGB colors to RGBA by adding alpha channel
557
- colors_rgba = [(r, g, b, 255) for r, g, b in colors] # Full opacity for colored regions
558
-
559
- # Create mapping from community to color
560
546
  community_to_color = {comm: colors_rgba[i] for i, comm in enumerate(sorted_communities)}
561
-
562
- # Create mapping from node ID to color
563
547
  node_to_color = {node: community_to_color[comm] for node, comm in community_dict.items()}
564
548
 
565
- # Create RGBA array (initialize with transparent background)
566
- rgba_array = np.zeros((*labeled_array.shape, 4), dtype=np.uint8)
549
+ # Create lookup table - this is the key optimization
550
+ max_label = max(max(labeled_array.flat), max(node_to_color.keys()) if node_to_color else 0)
551
+ color_lut = np.zeros((max_label + 1, 4), dtype=np.uint8) # Transparent by default
567
552
 
568
- # Assign colors to each voxel based on its label
569
- for label in np.unique(labeled_array):
570
- if label in node_to_color: # Skip background (usually label 0)
571
- mask = labeled_array == label
572
- for i in range(4): # RGBA channels
573
- rgba_array[mask, i] = node_to_color[label][i]
574
-
575
- # Convert the RGB portion of community_to_color back to RGB for color naming
553
+ for node_id, color in node_to_color.items():
554
+ color_lut[node_id] = color
555
+
556
+ # Single vectorized operation - this is much faster!
557
+ rgba_array = color_lut[labeled_array]
558
+
559
+ # Rest remains the same
576
560
  community_to_color_rgb = {k: tuple(v[:3]) for k, v in community_to_color.items()}
577
561
  node_to_color_names = convert_node_colors_to_names(community_to_color_rgb)
578
562