nettracer3d 0.7.1__tar.gz → 0.7.3__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 (25) hide show
  1. {nettracer3d-0.7.1/src/nettracer3d.egg-info → nettracer3d-0.7.3}/PKG-INFO +6 -11
  2. {nettracer3d-0.7.1 → nettracer3d-0.7.3}/README.md +5 -10
  3. {nettracer3d-0.7.1 → nettracer3d-0.7.3}/pyproject.toml +1 -1
  4. {nettracer3d-0.7.1 → nettracer3d-0.7.3}/src/nettracer3d/morphology.py +2 -2
  5. {nettracer3d-0.7.1 → nettracer3d-0.7.3}/src/nettracer3d/nettracer.py +16 -3
  6. {nettracer3d-0.7.1 → nettracer3d-0.7.3}/src/nettracer3d/nettracer_gui.py +39 -8
  7. {nettracer3d-0.7.1 → nettracer3d-0.7.3}/src/nettracer3d/proximity.py +1 -1
  8. {nettracer3d-0.7.1 → nettracer3d-0.7.3}/src/nettracer3d/smart_dilate.py +5 -5
  9. {nettracer3d-0.7.1 → nettracer3d-0.7.3/src/nettracer3d.egg-info}/PKG-INFO +6 -11
  10. {nettracer3d-0.7.1 → nettracer3d-0.7.3}/LICENSE +0 -0
  11. {nettracer3d-0.7.1 → nettracer3d-0.7.3}/setup.cfg +0 -0
  12. {nettracer3d-0.7.1 → nettracer3d-0.7.3}/src/nettracer3d/__init__.py +0 -0
  13. {nettracer3d-0.7.1 → nettracer3d-0.7.3}/src/nettracer3d/community_extractor.py +0 -0
  14. {nettracer3d-0.7.1 → nettracer3d-0.7.3}/src/nettracer3d/modularity.py +0 -0
  15. {nettracer3d-0.7.1 → nettracer3d-0.7.3}/src/nettracer3d/network_analysis.py +0 -0
  16. {nettracer3d-0.7.1 → nettracer3d-0.7.3}/src/nettracer3d/network_draw.py +0 -0
  17. {nettracer3d-0.7.1 → nettracer3d-0.7.3}/src/nettracer3d/node_draw.py +0 -0
  18. {nettracer3d-0.7.1 → nettracer3d-0.7.3}/src/nettracer3d/run.py +0 -0
  19. {nettracer3d-0.7.1 → nettracer3d-0.7.3}/src/nettracer3d/segmenter.py +0 -0
  20. {nettracer3d-0.7.1 → nettracer3d-0.7.3}/src/nettracer3d/simple_network.py +0 -0
  21. {nettracer3d-0.7.1 → nettracer3d-0.7.3}/src/nettracer3d.egg-info/SOURCES.txt +0 -0
  22. {nettracer3d-0.7.1 → nettracer3d-0.7.3}/src/nettracer3d.egg-info/dependency_links.txt +0 -0
  23. {nettracer3d-0.7.1 → nettracer3d-0.7.3}/src/nettracer3d.egg-info/entry_points.txt +0 -0
  24. {nettracer3d-0.7.1 → nettracer3d-0.7.3}/src/nettracer3d.egg-info/requires.txt +0 -0
  25. {nettracer3d-0.7.1 → nettracer3d-0.7.3}/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.1
3
+ Version: 0.7.3
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/
@@ -73,14 +73,9 @@ NetTracer3D is free to use/fork for academic/nonprofit use so long as citation i
73
73
 
74
74
  NetTracer3D was developed by Liam McLaughlin while working under Dr. Sanjay Jain at Washington University School of Medicine.
75
75
 
76
- -- Version 0.7.0 Updates --
76
+ -- Version 0.7.2 Updates --
77
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.
80
-
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.
84
-
85
- 3. Bug fixes.
86
- * Importantly fixed a bug with dt-based dilation not working in 2D, which I had accidentally introduced recently.
78
+ * Added new option to the modify network qualities menu to remove node centroids with unassigned id values.
79
+ * Bug fixes, mainly:
80
+ * Had to fix a bug with the ripley's function that was making it always evaluate nodes of one id against themselves even when a seperate id was specified.
81
+ * Fixed some bugs when processing 2D images.
@@ -34,14 +34,9 @@ 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.0 Updates --
37
+ -- Version 0.7.2 Updates --
38
38
 
39
- 1. Added new function in 'Analyze -> Stats -> Cluster Analysis'
40
- * 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.
41
-
42
- 2. Added new function in 'Analyze -> Randomize -> Scramble Nodes'
43
- * This function randomly rearranges the node (centroids) for comparison with other centroid-using methods, as a possible way to demonstrate non-random behavior.
44
- * The randomize menu is likewise new and the 'Generate Equivalent Random Network' method was moved there.
45
-
46
- 3. Bug fixes.
47
- * Importantly fixed a bug with dt-based dilation not working in 2D, which I had accidentally introduced recently.
39
+ * Added new option to the modify network qualities menu to remove node centroids with unassigned id values.
40
+ * Bug fixes, mainly:
41
+ * Had to fix a bug with the ripley's function that was making it always evaluate nodes of one id against themselves even when a seperate id was specified.
42
+ * Fixed some bugs when processing 2D images.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "nettracer3d"
3
- version = "0.7.1"
3
+ version = "0.7.3"
4
4
  authors = [
5
5
  { name="Liam McLaughlin", email="liamm@wustl.edu" },
6
6
  ]
@@ -518,7 +518,7 @@ def compute_distance_transform_distance_GPU(nodes, sampling = [1,1,1]):
518
518
  is_pseudo_3d = nodes.shape[0] == 1
519
519
  if is_pseudo_3d:
520
520
  nodes = cp.squeeze(nodes) # Convert to 2D for processing
521
- del sampling[0]
521
+ sampling = [sampling[1], sampling[2]]
522
522
 
523
523
  # Compute the distance transform on the GPU
524
524
  distance = cpx.distance_transform_edt(nodes, sampling = sampling)
@@ -534,7 +534,7 @@ def compute_distance_transform_distance(nodes, sampling = [1,1,1]):
534
534
  is_pseudo_3d = nodes.shape[0] == 1
535
535
  if is_pseudo_3d:
536
536
  nodes = np.squeeze(nodes) # Convert to 2D for processing
537
- del sampling[0]
537
+ sampling = [sampling[1], sampling[2]]
538
538
 
539
539
  # Fallback to CPU if there's an issue with GPU computation
540
540
  distance = ndimage.distance_transform_edt(nodes, sampling = sampling)
@@ -3948,6 +3948,19 @@ class Network_3D:
3948
3948
  except:
3949
3949
  print("Could not update voxel scaling")
3950
3950
 
3951
+
3952
+
3953
+ def remove_ids(self):
3954
+
3955
+ new_centroids = {}
3956
+
3957
+ for node in self.node_identities.keys():
3958
+ new_centroids[node] = self.node_centroids[node]
3959
+
3960
+ self.node_centroids = new_centroids
3961
+
3962
+
3963
+
3951
3964
  def remove_trunk_post(self):
3952
3965
  """
3953
3966
  Removes the 'edge' trunk from a network. In this case, the trunk is the edge that creates the most node-node connections. There may be times when many nodes are connected by a single, expansive edge that obfuscates the rest of the edges. Removing the trunk to a node can better reveal these edges.
@@ -4444,11 +4457,11 @@ class Network_3D:
4444
4457
  for node, nodeid in self.node_identities.items(): #Otherwise we need to pull out this info
4445
4458
  if nodeid == root:
4446
4459
  roots.append(self._node_centroids[node])
4447
- elif nodeid == targ:
4460
+ if nodeid == targ:
4448
4461
  targs.append(self._node_centroids[node])
4449
-
4462
+
4450
4463
  rooties = proximity.convert_centroids_to_array(roots, xy_scale = self.xy_scale, z_scale = self.z_scale)
4451
- targs = proximity.convert_centroids_to_array(roots, xy_scale = self.xy_scale, z_scale = self.z_scale)
4464
+ targs = proximity.convert_centroids_to_array(targs, xy_scale = self.xy_scale, z_scale = self.z_scale)
4452
4465
  points_array = np.vstack((rooties, targs))
4453
4466
  del rooties
4454
4467
 
@@ -2384,7 +2384,10 @@ class ImageViewerWindow(QMainWindow):
2384
2384
 
2385
2385
 
2386
2386
  if self.selection_rect is not None:
2387
- self.selection_rect.remove()
2387
+ try:
2388
+ self.selection_rect.remove()
2389
+ except:
2390
+ pass
2388
2391
  self.selection_rect = None
2389
2392
  self.canvas.draw()
2390
2393
 
@@ -2793,6 +2796,21 @@ class ImageViewerWindow(QMainWindow):
2793
2796
  show3d_action = image_menu.addAction("Show 3D (Napari)")
2794
2797
  show3d_action.triggered.connect(self.show3d_dialog)
2795
2798
 
2799
+ # Help
2800
+
2801
+ help_button = menubar.addAction("Help")
2802
+ help_button.triggered.connect(self.help_me)
2803
+
2804
+ def help_me(self):
2805
+
2806
+ import webbrowser
2807
+ try:
2808
+ webbrowser.open('https://nettracer3d.readthedocs.io/en/latest/')
2809
+ return True
2810
+ except Exception as e:
2811
+ print(f"Error opening URL: {e}")
2812
+ return False
2813
+
2796
2814
 
2797
2815
  def stats(self):
2798
2816
  """Method to get and display the network stats"""
@@ -3526,13 +3544,12 @@ class ImageViewerWindow(QMainWindow):
3526
3544
  except Exception as e:
3527
3545
  QMessageBox.critical(self, "Error", f"Error loading image: {str(e)}")
3528
3546
 
3529
-
3530
- if len(self.channel_data[channel_index].shape) == 2: # handle 2d data
3531
- self.channel_data[channel_index] = np.expand_dims(self.channel_data[channel_index], axis=0)
3532
-
3533
3547
  else:
3534
3548
  self.channel_data[channel_index] = channel_data
3535
3549
 
3550
+ if len(self.channel_data[channel_index].shape) == 2: # handle 2d data
3551
+ self.channel_data[channel_index] = np.expand_dims(self.channel_data[channel_index], axis=0)
3552
+
3536
3553
  try:
3537
3554
  if len(self.channel_data[channel_index].shape) == 3: # potentially 2D RGB
3538
3555
  if self.channel_data[channel_index].shape[-1] in (3, 4): # last dim is 3 or 4
@@ -3673,8 +3690,8 @@ class ImageViewerWindow(QMainWindow):
3673
3690
  # Update corresponding network property
3674
3691
  if channel_index == 0:
3675
3692
  my_network.nodes = None
3676
- my_network.node_centroids = None
3677
- my_network.node_identities = None
3693
+ #my_network.node_centroids = None
3694
+ #my_network.node_identities = None
3678
3695
  elif channel_index == 1:
3679
3696
  my_network.edges = None
3680
3697
  my_network.edge_centroids = None
@@ -6181,7 +6198,6 @@ class RandNodeDialog(QDialog):
6181
6198
  if mode == 0 and not (my_network.nodes is None and my_network.edges is None and my_network.network_overlay is None and my_network.id_overlay is None):
6182
6199
  pass
6183
6200
  elif mode == 1 or (my_network.nodes is None and my_network.edges is None and my_network.network_overlay is None and my_network.id_overlay is None):
6184
- print("HELLO")
6185
6201
  # Convert string labels to integers if necessary
6186
6202
  if any(isinstance(k, str) for k in my_network.node_centroids.keys()):
6187
6203
  label_map = {label: idx for idx, label in enumerate(my_network.node_centroids.keys())}
@@ -9528,6 +9544,11 @@ class ModifyDialog(QDialog):
9528
9544
  self.setWindowTitle("Modify Network Qualities")
9529
9545
  self.setModal(True)
9530
9546
  layout = QFormLayout(self)
9547
+
9548
+ self.revid = QPushButton("Remove Unassigned")
9549
+ self.revid.setCheckable(True)
9550
+ self.revid.setChecked(False)
9551
+ layout.addRow("Remove Unassigned IDs from Centroid List?:", self.revid)
9531
9552
 
9532
9553
  # trunk checkbox (default false)
9533
9554
  self.trunk = QPushButton("Remove Trunk")
@@ -9595,6 +9616,7 @@ class ModifyDialog(QDialog):
9595
9616
 
9596
9617
  try:
9597
9618
 
9619
+ revid = self.revid.isChecked()
9598
9620
  trunk = self.trunk.isChecked()
9599
9621
  if not trunk:
9600
9622
  trunknode = self.trunknode.isChecked()
@@ -9610,6 +9632,15 @@ class ModifyDialog(QDialog):
9610
9632
  if isolate and my_network.node_identities is not None:
9611
9633
  self.show_isolate_dialog()
9612
9634
 
9635
+ if revid:
9636
+ try:
9637
+ my_network.remove_ids()
9638
+ self.parent().format_for_upperright_table(my_network.node_centroids, 'NodeID', ['Z', 'Y', 'X'], 'Node Centroids')
9639
+ except:
9640
+ pass
9641
+
9642
+
9643
+
9613
9644
  if edgeweight:
9614
9645
  my_network.remove_edge_weights()
9615
9646
  if prune and my_network.node_identities is not None:
@@ -428,7 +428,7 @@ def optimized_ripleys_k(reference_points, subset_points, r_values, bounds=None,
428
428
  """
429
429
  n_ref = len(reference_points)
430
430
  n_subset = len(subset_points)
431
-
431
+
432
432
  # Determine bounds if not provided
433
433
  if bounds is None:
434
434
  min_coords = np.min(reference_points, axis=0)
@@ -165,7 +165,7 @@ def dilate_3D_old(tiff_array, dilated_x=3, dilated_y=3, dilated_z=3):
165
165
  # Handle special case for 2D arrays
166
166
  if tiff_array.shape[0] == 1:
167
167
  # Call 2D dilation function if needed
168
- return dilate_2D(tiff_array, 1) # For a 3x3 kernel, radius is 1
168
+ return nettracer.dilate_2D(tiff_array, 1) # For a 3x3 kernel, radius is 1
169
169
 
170
170
  # Create a simple 3x3x3 cubic kernel (all ones)
171
171
  kernel = np.ones((3, 3, 3), dtype=bool)
@@ -471,7 +471,7 @@ def compute_distance_transform_GPU(nodes, return_dists = False, sampling = [1, 1
471
471
  is_pseudo_3d = nodes.shape[0] == 1
472
472
  if is_pseudo_3d:
473
473
  nodes = np.squeeze(nodes) # Convert to 2D for processing
474
- del sampling[0]
474
+ sampling = [sampling[1], sampling[2]]
475
475
 
476
476
  # Convert numpy array to CuPy array
477
477
  nodes_cp = cp.asarray(nodes)
@@ -504,7 +504,7 @@ def compute_distance_transform(nodes, return_dists = False, sampling = [1, 1, 1]
504
504
  is_pseudo_3d = nodes.shape[0] == 1
505
505
  if is_pseudo_3d:
506
506
  nodes = np.squeeze(nodes) # Convert to 2D for processing
507
- del sampling[0]
507
+ sampling = [sampling[1], sampling[2]]
508
508
 
509
509
  dists, nearest_label_indices = distance_transform_edt(nodes, return_indices=True, sampling = sampling)
510
510
 
@@ -531,7 +531,7 @@ def compute_distance_transform_distance_GPU(nodes, sampling = [1, 1, 1]):
531
531
  is_pseudo_3d = nodes.shape[0] == 1
532
532
  if is_pseudo_3d:
533
533
  nodes = np.squeeze(nodes) # Convert to 2D for processing
534
- del sampling[0]
534
+ sampling = [sampling[1], sampling[2]]
535
535
 
536
536
  # Convert numpy array to CuPy array
537
537
  nodes_cp = cp.asarray(nodes)
@@ -553,7 +553,7 @@ def compute_distance_transform_distance(nodes, sampling = [1, 1, 1]):
553
553
  is_pseudo_3d = nodes.shape[0] == 1
554
554
  if is_pseudo_3d:
555
555
  nodes = np.squeeze(nodes) # Convert to 2D for processing
556
- del sampling[0]
556
+ sampling = [sampling[1], sampling[2]]
557
557
 
558
558
  # Fallback to CPU if there's an issue with GPU computation
559
559
  distance = distance_transform_edt(nodes, sampling = sampling)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nettracer3d
3
- Version: 0.7.1
3
+ Version: 0.7.3
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/
@@ -73,14 +73,9 @@ NetTracer3D is free to use/fork for academic/nonprofit use so long as citation i
73
73
 
74
74
  NetTracer3D was developed by Liam McLaughlin while working under Dr. Sanjay Jain at Washington University School of Medicine.
75
75
 
76
- -- Version 0.7.0 Updates --
76
+ -- Version 0.7.2 Updates --
77
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.
80
-
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.
84
-
85
- 3. Bug fixes.
86
- * Importantly fixed a bug with dt-based dilation not working in 2D, which I had accidentally introduced recently.
78
+ * Added new option to the modify network qualities menu to remove node centroids with unassigned id values.
79
+ * Bug fixes, mainly:
80
+ * Had to fix a bug with the ripley's function that was making it always evaluate nodes of one id against themselves even when a seperate id was specified.
81
+ * Fixed some bugs when processing 2D images.
File without changes
File without changes