nettracer3d 0.8.9__py3-none-any.whl → 0.9.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.
nettracer3d/proximity.py CHANGED
@@ -469,68 +469,121 @@ def extract_pairwise_connections(connections):
469
469
  return output
470
470
 
471
471
 
472
- def average_nearest_neighbor_distances(point_centroids, root_set, compare_set, xy_scale=1.0, z_scale=1.0, num = 1):
472
+ def average_nearest_neighbor_distances(point_centroids, root_set, compare_set, xy_scale=1.0, z_scale=1.0, num=1, do_borders=False):
473
473
  """
474
474
  Calculate the average distance between each point in root_set and its nearest neighbor in compare_set.
475
475
 
476
476
  Args:
477
- point_centroids (dict): Dictionary mapping point IDs to [Z, Y, X] coordinates
478
- root_set (set): Set of point IDs to find nearest neighbors for
479
- compare_set (set): Set of point IDs to search for nearest neighbors in
477
+ point_centroids (dict): Dictionary mapping point IDs to [Z, Y, X] coordinates (when do_borders=False)
478
+ OR dictionary mapping labels to border coordinates (when do_borders=True)
479
+ root_set (set or dict): Set of point IDs (when do_borders=False)
480
+ OR dict {label: border_coords} (when do_borders=True)
481
+ compare_set (set or numpy.ndarray): Set of point IDs (when do_borders=False)
482
+ OR 1D array of border coordinates (when do_borders=True)
480
483
  xy_scale (float): Scaling factor for X and Y coordinates
481
484
  z_scale (float): Scaling factor for Z coordinate
485
+ num (int): Number of nearest neighbors (ignored when do_borders=True, always uses 1)
486
+ do_borders (bool): If True, perform border-to-border distance calculation
482
487
 
483
488
  Returns:
484
- float: Average distance to nearest neighbors
489
+ tuple: (average_distance, distances_dict)
485
490
  """
486
491
 
487
- # Extract and scale coordinates for compare_set
488
- compare_coords = []
489
- compare_ids = list(compare_set)
490
-
491
- for point_id in compare_ids:
492
- z, y, x = point_centroids[point_id]
493
- compare_coords.append([z * z_scale, y * xy_scale, x * xy_scale])
494
-
495
- compare_coords = np.array(compare_coords)
496
-
497
- # Build KDTree for efficient nearest neighbor search
498
- tree = KDTree(compare_coords)
499
-
500
- distances = {}
501
- same_sets = root_set == compare_set
492
+ if do_borders:
493
+ # Border comparison mode
494
+ if not isinstance(compare_set, np.ndarray):
495
+ raise ValueError("When do_borders=True, compare_set must be a numpy array of coordinates")
496
+
497
+ # Vectorized scaling for compare coordinates
498
+ compare_coords_scaled = compare_set.astype(float)
499
+ compare_coords_scaled[:, 0] *= z_scale # Z coordinates
500
+ compare_coords_scaled[:, 1:] *= xy_scale # Y and X coordinates
501
+
502
+ distances = {}
503
+
504
+ for label, border_coords in root_set.items():
505
+ if len(border_coords) == 0:
506
+ continue
507
+
508
+ # Vectorized scaling for border coordinates
509
+ border_coords_scaled = border_coords.astype(float)
510
+ border_coords_scaled[:, 0] *= z_scale # Z coordinates
511
+ border_coords_scaled[:, 1:] *= xy_scale # Y and X coordinates
512
+
513
+ # Remove overlapping coordinates to avoid distance = 0
514
+ # Create a set of tuples for fast membership testing
515
+ border_coords_set = set(map(tuple, border_coords_scaled))
516
+
517
+ # Filter out overlapping coordinates from compare set
518
+ non_overlapping_mask = np.array([
519
+ tuple(coord) not in border_coords_set
520
+ for coord in compare_coords_scaled
521
+ ])
522
+
523
+ if not np.any(non_overlapping_mask):
524
+ # All compare coordinates overlap - skip this object or set to NaN
525
+ distances[label] = np.nan
526
+ continue
527
+
528
+ filtered_compare_coords = compare_coords_scaled[non_overlapping_mask]
529
+
530
+ # Build KDTree with filtered coordinates
531
+ tree = KDTree(filtered_compare_coords)
532
+
533
+ # Vectorized nearest neighbor search for all border points at once
534
+ distances_to_all, _ = tree.query(border_coords_scaled, k=1)
535
+
536
+ # Find minimum distance for this object
537
+ distances[label] = np.min(distances_to_all)
538
+
539
+ # Calculate average excluding NaN values
540
+ valid_distances = [d for d in distances.values() if not np.isnan(d)]
541
+ avg = np.mean(valid_distances) if valid_distances else np.nan
542
+ return avg, distances
502
543
 
503
- for root_id in root_set:
504
- # Get scaled coordinates for root point
505
- z, y, x = point_centroids[root_id]
506
- root_coord = np.array([z * z_scale, y * xy_scale, x * xy_scale])
544
+ else:
545
+ # Original centroid comparison mode (unchanged)
546
+ # Extract coordinates for compare_set
547
+ compare_coords = np.array([point_centroids[point_id] for point_id in compare_set])
507
548
 
549
+ # Vectorized scaling for compare coordinates
550
+ compare_coords_scaled = compare_coords.astype(float)
551
+ compare_coords_scaled[:, 0] *= z_scale # Z coordinates
552
+ compare_coords_scaled[:, 1:] *= xy_scale # Y and X coordinates
553
+
554
+ # Build KDTree for efficient nearest neighbor search
555
+ tree = KDTree(compare_coords_scaled)
556
+
557
+ distances = {}
558
+ same_sets = root_set == compare_set
559
+
560
+ # Extract and scale root coordinates all at once
561
+ root_coords = np.array([point_centroids[root_id] for root_id in root_set])
562
+ root_coords_scaled = root_coords.astype(float)
563
+ root_coords_scaled[:, 0] *= z_scale # Z coordinates
564
+ root_coords_scaled[:, 1:] *= xy_scale # Y and X coordinates
565
+
566
+ # Vectorized nearest neighbor search for all root points
508
567
  if same_sets:
509
- # When sets are the same, find 2 nearest neighbors and take the second one
510
- # (first one would be the point itself)
511
- distances_to_all, indices = tree.query(root_coord, k= (num + 1))
512
-
513
- temp_dist = 0
514
- for i in range(1, len(distances_to_all)):
515
- temp_dist += distances_to_all[i]
516
-
517
- distances[root_id] = temp_dist/(len(distances_to_all) - 1)
518
-
568
+ distances_to_all, indices = tree.query(root_coords_scaled, k=(num + 1))
569
+ # Remove self-matches (first column) and average the rest
570
+ if num == 1:
571
+ distances_array = distances_to_all[:, 1] # Just take second nearest
572
+ else:
573
+ distances_array = np.mean(distances_to_all[:, 1:], axis=1)
519
574
  else:
520
- # Different sets, find nearest neighbors
521
- distances_to_all, _ = tree.query(root_coord, k=num)
522
- temp_dist = 0
523
- for val in distances_to_all:
524
- temp_dist += val
525
-
526
- distances[root_id] = temp_dist/(len(distances_to_all))
527
-
528
- avg = np.mean(list(distances.values())) if list(distances.values()) else 0.0
529
-
530
-
531
- # Return average distance
532
- return avg, distances
533
-
575
+ distances_to_all, _ = tree.query(root_coords_scaled, k=num)
576
+ if num == 1:
577
+ distances_array = distances_to_all.flatten()
578
+ else:
579
+ distances_array = np.mean(distances_to_all, axis=1)
580
+
581
+ # Map back to root_ids
582
+ for i, root_id in enumerate(root_set):
583
+ distances[root_id] = distances_array[i]
584
+
585
+ avg = np.mean(distances_array) if len(distances_array) > 0 else 0.0
586
+ return avg, distances
534
587
 
535
588
 
536
589
  #voronois:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nettracer3d
3
- Version: 0.8.9
3
+ Version: 0.9.0
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/
@@ -110,6 +110,16 @@ McLaughlin, L., Zhang, B., Sharma, S. et al. Three dimensional multiscalar neuro
110
110
 
111
111
  NetTracer3D was developed by Liam McLaughlin while working under Dr. Sanjay Jain at Washington University School of Medicine.
112
112
 
113
- -- Version 0.8.9 Updates --
114
-
115
- * See Documentation Once Updated
113
+ -- Version 0.9.0 Updates --
114
+ * Note that this includes updates for 0.8.3 - 0.9.0
115
+ * Bug Fixes
116
+ * Updated network histogram statistics menu, and moved degree distribution here
117
+ * Added gray watershed
118
+ * Updated binary watershed
119
+ * Improved branch labelling method
120
+ * Updated branch removal in skeletonization method to no longer trim branches that do not reach their node.
121
+ * Added default branchpoint and branch-adjacency calculation options.
122
+ * Improved speed of painting and panning.
123
+ * Enabled the nearest neighbor method to handle non-centroid objects, for the first neighbor at least. And updated it to actually predict theoretical clustering when coloring the heatmap.
124
+ * Improved segmenter.
125
+ * Added centroids UMAP method.
@@ -1,25 +1,25 @@
1
1
  nettracer3d/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- nettracer3d/cellpose_manager.py,sha256=qZpTxSkmPb38Pru8TmjJ88xxcD_wM02EfJB5Mw9Xx4Y,6021
2
+ nettracer3d/cellpose_manager.py,sha256=NfRqW6Zl7yRU4qHCS_KjmR0R6QANSSgCO0_dr-eivxg,6694
3
3
  nettracer3d/community_extractor.py,sha256=QG2v2y9lKb07LRU0zXCAlA_z-96BNqLHh5xP17KLmYA,28147
4
4
  nettracer3d/excelotron.py,sha256=X9v_mte8gJBPNGdj6NJNUYja0Z6eorVoKAFx4nHiMnU,72058
5
- nettracer3d/modularity.py,sha256=O9OeKbjD3v6gSFz9K2GzP6LsxlpQaPfeJbM1pyIEigw,21788
5
+ nettracer3d/modularity.py,sha256=pborVcDBvICB2-g8lNoSVZbIReIBlfeBmjFbPYmtq7Y,22443
6
6
  nettracer3d/morphology.py,sha256=jyDjYzrZ4LvI5jOyw8DLsxmo-i5lpqHsejYpW7Tq7Mo,19786
7
- nettracer3d/neighborhoods.py,sha256=VWubD5CBu9aNPhUea7FbAk9aTOq0FLKR9y-1VT7YkAc,39677
8
- nettracer3d/nettracer.py,sha256=TEV-nDmkcGP3UjWEor1LtEwm5mFBQu2nB0VRyz9Lt08,253649
9
- nettracer3d/nettracer_gui.py,sha256=aYU4r8HLLNiKPOpQIjdvRu2BRtvx18Z6OXa8N7g27Xg,546298
7
+ nettracer3d/neighborhoods.py,sha256=qOmN8gDZM-J5zsFFaQ772obj6PzsiISXzVZgnlmGGS8,41349
8
+ nettracer3d/nettracer.py,sha256=cuHc0djb6auNgZ6c38kow9N4zTN7ve00gGBnBSUgEAc,263183
9
+ nettracer3d/nettracer_gui.py,sha256=_JcvHLqb68TooYWu8yFkDLWSJ8wMc6IZ7VFMBzmwenE,568388
10
10
  nettracer3d/network_analysis.py,sha256=kBzsVaq4dZkMe0k-VGvQIUvM-tK0ZZ8bvb-wtsugZRQ,46150
11
11
  nettracer3d/network_draw.py,sha256=F7fw6Pcf4qWOhdKwLmhwqWdschbDlHzwCVolQC9imeU,14117
12
12
  nettracer3d/node_draw.py,sha256=kZcR1PekLg0riioNeGcALIXQyZ5PtHA_9MT6z7Zovdk,10401
13
13
  nettracer3d/painting.py,sha256=K_dwngivw80r-Yyg4btKMsWGn566ZE9PnrQl986uxJE,23497
14
- nettracer3d/proximity.py,sha256=bTaucn_InQ-v1GIk8ug-dXvDhIO59rnBMl5nIwAmNyw,35335
14
+ nettracer3d/proximity.py,sha256=ZCfthYpQbDBwXBcVioxyzgO9PZACu6mQ8pSXdldP1TM,38592
15
15
  nettracer3d/run.py,sha256=xYeaAc8FCx8MuzTGyL3NR3mK7WZzffAYAH23bNRZYO4,127
16
16
  nettracer3d/segmenter.py,sha256=_ZBLe2eqV9c5yxuyfN69XR5mBoc_OD-CZjwdTCUV0YQ,67045
17
17
  nettracer3d/segmenter_GPU.py,sha256=SGOsy8tSRlxAnD1OrJmjhiQ3k6CWiUFZZdrN6pkkgeU,69057
18
18
  nettracer3d/simple_network.py,sha256=dkG4jpc4zzdeuoaQobgGfL3PNo6N8dGKQ5hEEubFIvA,9947
19
19
  nettracer3d/smart_dilate.py,sha256=TvRUh6B4q4zIdCO1BWH-xgTdND5OUNmo99eyxG9oIAU,27145
20
- nettracer3d-0.8.9.dist-info/licenses/LICENSE,sha256=jnNT-yBeIAKAHpYthPvLeqCzJ6nSurgnKmloVnfsjCI,764
21
- nettracer3d-0.8.9.dist-info/METADATA,sha256=3aV3Pcj-2AmQzzRkI5crBVw_ZbsLW8I_kV5WiebYKws,7008
22
- nettracer3d-0.8.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
23
- nettracer3d-0.8.9.dist-info/entry_points.txt,sha256=Nx1rr_0QhJXDBHAQg2vcqCzLMKBzSHfwy3xwGkueVyc,53
24
- nettracer3d-0.8.9.dist-info/top_level.txt,sha256=zsYy9rZwirfCEOubolhee4TyzqBAL5gSUeFMzhFTX8c,12
25
- nettracer3d-0.8.9.dist-info/RECORD,,
20
+ nettracer3d-0.9.0.dist-info/licenses/LICENSE,sha256=jnNT-yBeIAKAHpYthPvLeqCzJ6nSurgnKmloVnfsjCI,764
21
+ nettracer3d-0.9.0.dist-info/METADATA,sha256=ZmAGzdynu4-irBp2Duk0AsBo7y5U4TDG9cPJHRsOYno,7684
22
+ nettracer3d-0.9.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
23
+ nettracer3d-0.9.0.dist-info/entry_points.txt,sha256=Nx1rr_0QhJXDBHAQg2vcqCzLMKBzSHfwy3xwGkueVyc,53
24
+ nettracer3d-0.9.0.dist-info/top_level.txt,sha256=zsYy9rZwirfCEOubolhee4TyzqBAL5gSUeFMzhFTX8c,12
25
+ nettracer3d-0.9.0.dist-info/RECORD,,