nettracer3d 0.5.7__tar.gz → 0.5.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 (26) hide show
  1. {nettracer3d-0.5.7/src/nettracer3d.egg-info → nettracer3d-0.5.9}/PKG-INFO +3 -3
  2. {nettracer3d-0.5.7 → nettracer3d-0.5.9}/README.md +2 -2
  3. {nettracer3d-0.5.7 → nettracer3d-0.5.9}/pyproject.toml +1 -1
  4. {nettracer3d-0.5.7 → nettracer3d-0.5.9}/src/nettracer3d/nettracer_gui.py +8 -4
  5. {nettracer3d-0.5.7 → nettracer3d-0.5.9}/src/nettracer3d/segmenter.py +107 -54
  6. {nettracer3d-0.5.7 → nettracer3d-0.5.9/src/nettracer3d.egg-info}/PKG-INFO +3 -3
  7. {nettracer3d-0.5.7 → nettracer3d-0.5.9}/LICENSE +0 -0
  8. {nettracer3d-0.5.7 → nettracer3d-0.5.9}/setup.cfg +0 -0
  9. {nettracer3d-0.5.7 → nettracer3d-0.5.9}/src/nettracer3d/__init__.py +0 -0
  10. {nettracer3d-0.5.7 → nettracer3d-0.5.9}/src/nettracer3d/community_extractor.py +0 -0
  11. {nettracer3d-0.5.7 → nettracer3d-0.5.9}/src/nettracer3d/hub_getter.py +0 -0
  12. {nettracer3d-0.5.7 → nettracer3d-0.5.9}/src/nettracer3d/modularity.py +0 -0
  13. {nettracer3d-0.5.7 → nettracer3d-0.5.9}/src/nettracer3d/morphology.py +0 -0
  14. {nettracer3d-0.5.7 → nettracer3d-0.5.9}/src/nettracer3d/nettracer.py +0 -0
  15. {nettracer3d-0.5.7 → nettracer3d-0.5.9}/src/nettracer3d/network_analysis.py +0 -0
  16. {nettracer3d-0.5.7 → nettracer3d-0.5.9}/src/nettracer3d/network_draw.py +0 -0
  17. {nettracer3d-0.5.7 → nettracer3d-0.5.9}/src/nettracer3d/node_draw.py +0 -0
  18. {nettracer3d-0.5.7 → nettracer3d-0.5.9}/src/nettracer3d/proximity.py +0 -0
  19. {nettracer3d-0.5.7 → nettracer3d-0.5.9}/src/nettracer3d/run.py +0 -0
  20. {nettracer3d-0.5.7 → nettracer3d-0.5.9}/src/nettracer3d/simple_network.py +0 -0
  21. {nettracer3d-0.5.7 → nettracer3d-0.5.9}/src/nettracer3d/smart_dilate.py +0 -0
  22. {nettracer3d-0.5.7 → nettracer3d-0.5.9}/src/nettracer3d.egg-info/SOURCES.txt +0 -0
  23. {nettracer3d-0.5.7 → nettracer3d-0.5.9}/src/nettracer3d.egg-info/dependency_links.txt +0 -0
  24. {nettracer3d-0.5.7 → nettracer3d-0.5.9}/src/nettracer3d.egg-info/entry_points.txt +0 -0
  25. {nettracer3d-0.5.7 → nettracer3d-0.5.9}/src/nettracer3d.egg-info/requires.txt +0 -0
  26. {nettracer3d-0.5.7 → nettracer3d-0.5.9}/src/nettracer3d.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: nettracer3d
3
- Version: 0.5.7
3
+ Version: 0.5.9
4
4
  Summary: Scripts for intializing and analyzing networks from segmentations of three dimensional images.
5
5
  Author-email: Liam McLaughlin <mclaughlinliam99@gmail.com>
6
6
  Project-URL: User_Tutorial, https://www.youtube.com/watch?v=cRatn5VTWDY
@@ -44,6 +44,6 @@ NetTracer3D is free to use/fork for academic/nonprofit use so long as citation i
44
44
 
45
45
  NetTracer3D was developed by Liam McLaughlin while working under Dr. Sanjay Jain at Washington University School of Medicine.
46
46
 
47
- -- Version 0.5.7 updates --
47
+ -- Version 0.5.9 updates --
48
48
 
49
- 1. Minor change - Can now export network as .gexf (Gephi), .GraphML, or .net (Pajek) for other network analysis softwares to use.
49
+ 1. Bug fixes
@@ -8,6 +8,6 @@ NetTracer3D is free to use/fork for academic/nonprofit use so long as citation i
8
8
 
9
9
  NetTracer3D was developed by Liam McLaughlin while working under Dr. Sanjay Jain at Washington University School of Medicine.
10
10
 
11
- -- Version 0.5.7 updates --
11
+ -- Version 0.5.9 updates --
12
12
 
13
- 1. Minor change - Can now export network as .gexf (Gephi), .GraphML, or .net (Pajek) for other network analysis softwares to use.
13
+ 1. Bug fixes
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "nettracer3d"
3
- version = "0.5.7"
3
+ version = "0.5.9"
4
4
  authors = [
5
5
  { name="Liam McLaughlin", email="mclaughlinliam99@gmail.com" },
6
6
  ]
@@ -6546,9 +6546,10 @@ class MachineWindow(QMainWindow):
6546
6546
  # Reset any processing flags in the segmenter
6547
6547
  if hasattr(self.segmenter, '_currently_processing'):
6548
6548
  self.segmenter._currently_processing = None
6549
-
6550
- # Create a new worker after a brief delay
6551
- QTimer.singleShot(500, self.start_segmentation)
6549
+
6550
+ if 0 in self.parent().highlight_overlay[current_z, :, :]:
6551
+ # Create a new worker after a brief delay
6552
+ QTimer.singleShot(500, self.start_segmentation)
6552
6553
 
6553
6554
 
6554
6555
 
@@ -6665,7 +6666,7 @@ class SegmentationWorker(QThread):
6665
6666
  self._stop = True
6666
6667
 
6667
6668
  def get_poked(self):
6668
- self.poked = True
6669
+ self.machine_window.poke_segmenter()
6669
6670
 
6670
6671
  def run(self):
6671
6672
  try:
@@ -6680,6 +6681,9 @@ class SegmentationWorker(QThread):
6680
6681
 
6681
6682
  # Process the slice with chunked generator
6682
6683
  for foreground, background in self.segmenter.segment_slice_chunked(current_z):
6684
+ if foreground == None and background == None:
6685
+ self.get_poked()
6686
+
6683
6687
  if self._stop:
6684
6688
  break
6685
6689
 
@@ -18,6 +18,7 @@ from concurrent.futures import ThreadPoolExecutor
18
18
  import threading
19
19
  from scipy import ndimage
20
20
  import multiprocessing
21
+ from collections import defaultdict
21
22
 
22
23
 
23
24
  class InteractiveSegmenter:
@@ -98,24 +99,41 @@ class InteractiveSegmenter:
98
99
  # First attempt to get the feature map
99
100
  feature_map = None
100
101
 
101
- if slice_z in self.feature_cache:
102
- feature_map = self.feature_cache[slice_z]
103
- elif hasattr(self, 'map_slice') and self.map_slice is not None and slice_z == self.current_z:
104
- feature_map = self.map_slice
105
- else:
102
+ try:
103
+ if slice_z in self.feature_cache:
104
+ feature_map = self.feature_cache[slice_z]
105
+ elif hasattr(self, 'map_slice') and self.map_slice is not None and slice_z == self.current_z:
106
+ feature_map = self.map_slice
107
+ else:
108
+ # Generate new feature map
109
+ try:
110
+ feature_map = self.get_feature_map_slice(slice_z, self.current_speed, False)
111
+ self.map_slice = feature_map
112
+ # Cache the feature map for future use
113
+ #if not hasattr(self, 'feature_cache'):
114
+ #self.feature_cache = {}
115
+ #self.feature_cache[slice_z] = feature_map
116
+ except Exception as e:
117
+ print(f"Error generating feature map: {e}")
118
+ import traceback
119
+ traceback.print_exc()
120
+ return # Exit if we can't generate the feature map
121
+ except:
106
122
  # Generate new feature map
123
+ #self.feature_cache = {}
107
124
  try:
108
125
  feature_map = self.get_feature_map_slice(slice_z, self.current_speed, False)
109
126
  self.map_slice = feature_map
110
127
  # Cache the feature map for future use
111
- if not hasattr(self, 'feature_cache'):
112
- self.feature_cache = {}
113
- self.feature_cache[slice_z] = feature_map
128
+ #if not hasattr(self, 'feature_cache'):
129
+ #self.feature_cache = {}
130
+ #self.feature_cache[slice_z] = feature_map
114
131
  except Exception as e:
115
132
  print(f"Error generating feature map: {e}")
116
133
  import traceback
117
134
  traceback.print_exc()
118
135
  return # Exit if we can't generate the feature map
136
+
119
137
 
120
138
  # Check that we have a valid feature map
121
139
  if feature_map is None:
@@ -152,7 +170,12 @@ class InteractiveSegmenter:
152
170
 
153
171
  # Predict
154
172
  try:
155
- predictions = self.model.predict(features)
173
+ try:
174
+ predictions = self.model.predict(features)
175
+ except ValueError:
176
+ self.feature_cache = None
177
+ self.map_slice = None
178
+ return None, None
156
179
 
157
180
  # Split results
158
181
  foreground = set()
@@ -692,18 +715,12 @@ class InteractiveSegmenter:
692
715
  Returns:
693
716
  Dictionary with z-values as keys and lists of corresponding [y, x] coordinates as values
694
717
  """
695
- z_dict = {}
718
+ z_dict = defaultdict(list)
696
719
 
697
- for coord in coordinates:
698
- z, y, x = coord # Unpack the coordinates
699
-
700
- # Add the y, x coordinate to the appropriate z-value group
701
- if z not in z_dict:
702
- z_dict[z] = []
703
-
704
- z_dict[z].append((y, x)) # Store as tuple, not list, so it's hashable
720
+ for z, y, x in coordinates:
721
+ z_dict[z].append((y, x))
705
722
 
706
- return z_dict
723
+ return dict(z_dict) # Convert back to regular dict
707
724
 
708
725
  def process_chunk(self, chunk_coords):
709
726
  """Process a chunk of coordinates"""
@@ -727,10 +744,13 @@ class InteractiveSegmenter:
727
744
  chunk_by_z = self.organize_by_z(chunk_coords)
728
745
  for z, coords in chunk_by_z.items():
729
746
 
730
- if z not in self.feature_cache and not self.previewing:
747
+ if self.feature_cache is None:
748
+ features = self.get_feature_map_slice(z, self.speed, self.cur_gpu)
749
+ features = [features[y, x] for y, x in coords]
750
+ elif z not in self.feature_cache and not self.previewing:
731
751
  features = self.get_feature_map_slice(z, self.speed, self.cur_gpu)
732
752
  features = [features[y, x] for y, x in coords]
733
- elif z not in self.feature_cache and self.previewing:
753
+ elif z not in self.feature_cache or self.feature_cache is None and self.previewing:
734
754
  features = self.map_slice
735
755
  try:
736
756
  features = [features[y, x] for y, x in coords]
@@ -850,6 +870,7 @@ class InteractiveSegmenter:
850
870
  chunks.append(list(map(tuple, coords)))
851
871
  else:
852
872
  chunks = create_2d_chunks()
873
+ self.feature_cache = None #Decided this should not maintain training data for segmenting 2D
853
874
 
854
875
  foreground_coords = set()
855
876
  background_coords = set()
@@ -904,8 +925,9 @@ class InteractiveSegmenter:
904
925
  # Only clear map_slice if z changes and we're not already generating a new one
905
926
  if self.current_z != self.prev_z:
906
927
  # Instead of setting to None, check if we already have it in the cache
907
- if hasattr(self, 'feature_cache') and self.current_z not in self.feature_cache:
908
- self.map_slice = None
928
+ if hasattr(self, 'feature_cache') and self.feature_cache is not None:
929
+ if self.current_z not in self.feature_cache:
930
+ self.map_slice = None
909
931
  self._currently_segmenting = None
910
932
 
911
933
  # Update previous z
@@ -1077,8 +1099,11 @@ class InteractiveSegmenter:
1077
1099
  def cleanup(self):
1078
1100
  """Clean up GPU memory"""
1079
1101
  if self.use_gpu:
1080
- cp.get_default_memory_pool().free_all_blocks()
1081
- torch.cuda.empty_cache()
1102
+ try:
1103
+ cp.get_default_memory_pool().free_all_blocks()
1104
+ torch.cuda.empty_cache()
1105
+ except:
1106
+ pass
1082
1107
 
1083
1108
  def train_batch(self, foreground_array, speed = True, use_gpu = False, use_two = False):
1084
1109
  """Train directly on foreground and background arrays"""
@@ -1088,60 +1113,88 @@ class InteractiveSegmenter:
1088
1113
 
1089
1114
  if self.current_speed != speed:
1090
1115
  self.feature_cache = None
1116
+ if use_gpu:
1117
+ try:
1118
+ self.model = cuRandomForestClassifier(
1119
+ n_estimators=100,
1120
+ max_depth=None
1121
+ )
1122
+ except:
1123
+ self.model = RandomForestClassifier(
1124
+ n_estimators=100,
1125
+ n_jobs=-1,
1126
+ max_depth=None
1127
+ )
1128
+ else:
1129
+ self.model = RandomForestClassifier(
1130
+ n_estimators=100,
1131
+ n_jobs=-1,
1132
+ max_depth=None
1133
+ )
1134
+
1091
1135
 
1092
1136
  if use_two:
1093
1137
 
1094
- changed = [] #Track which slices need feature maps
1138
+ #changed = [] #Track which slices need feature maps
1095
1139
 
1096
1140
  if not self.use_two: #Clarifies if we need to redo feature cache for 2D
1097
1141
  self.feature_cache = None
1098
1142
  self.use_two = True
1099
1143
 
1144
+ self.feature_cache = None #Decided this should reset, can remove this line to have it retain prev feature maps
1145
+ self.two_slices = []
1146
+
1100
1147
  if self.feature_cache == None:
1101
1148
  self.feature_cache = {}
1102
1149
 
1103
1150
  # Get foreground coordinates and features
1104
1151
  z_fore, y_fore, x_fore = np.where(foreground_array == 1)
1152
+
1153
+
1154
+ fore_coords = list(zip(z_fore, y_fore, x_fore))
1105
1155
 
1106
1156
  # Get background coordinates and features
1107
1157
  z_back, y_back, x_back = np.where(foreground_array == 2)
1108
1158
 
1109
- slices = set(list(z_back) + list(z_fore))
1159
+ back_coords = list(zip(z_back, y_back, x_back))
1110
1160
 
1111
- for z in slices:
1112
- if z not in self.two_slices:
1113
- changed.append(z)
1114
- self.two_slices.append(z) #Tracks assigning coords to feature map slices
1161
+
1162
+ #slices = set(list(z_back) + list(z_fore))
1163
+
1164
+ #for z in slices:
1165
+ #if z not in self.two_slices:
1166
+ #changed.append(z)
1167
+ #self.two_slices.append(z) #Tracks assigning coords to feature map slices
1115
1168
 
1116
1169
  foreground_features = []
1117
1170
  background_features = []
1118
1171
 
1119
- for i, z in enumerate(z_fore):
1120
- if z in changed: # Means this slice needs a feature map
1121
- new_map = self.get_feature_map_slice(z, speed, use_gpu)
1122
- self.feature_cache[z] = new_map
1123
- changed.remove(z)
1124
-
1125
- current_map = self.feature_cache[z]
1126
-
1127
- # Get the feature vector for this foreground point
1128
- feature_vector = current_map[y_fore[i], x_fore[i]]
1129
-
1130
- # Add to our collection
1131
- foreground_features.append(feature_vector)
1172
+ z_fores = self.organize_by_z(fore_coords)
1173
+ z_backs = self.organize_by_z(back_coords)
1174
+ slices = set(list(z_fores.keys()) + list(z_backs.keys()))
1132
1175
 
1133
- for i, z in enumerate(z_back):
1134
- if z in changed: # Means this slice needs a feature map
1135
- new_map = self.get_feature_map_slice(z, speed, use_gpu)
1136
- self.feature_cache[z] = new_map
1137
-
1138
- current_map = self.feature_cache[z]
1176
+ for z in slices:
1177
+
1178
+
1179
+ current_map = self.get_feature_map_slice(z, speed, use_gpu)
1180
+
1181
+ if z in z_fores:
1139
1182
 
1140
- # Get the feature vector for this foreground point
1141
- feature_vector = current_map[y_back[i], x_back[i]]
1183
+ for y, x in z_fores[z]:
1184
+ # Get the feature vector for this foreground point
1185
+ feature_vector = current_map[y, x]
1186
+
1187
+ # Add to our collection
1188
+ foreground_features.append(feature_vector)
1189
+
1190
+ if z in z_backs:
1142
1191
 
1143
- # Add to our collection
1144
- background_features.append(feature_vector)
1192
+ for y, x in z_backs[z]:
1193
+ # Get the feature vector for this foreground point
1194
+ feature_vector = current_map[y, x]
1195
+
1196
+ # Add to our collection
1197
+ background_features.append(feature_vector)
1145
1198
 
1146
1199
 
1147
1200
  else:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: nettracer3d
3
- Version: 0.5.7
3
+ Version: 0.5.9
4
4
  Summary: Scripts for intializing and analyzing networks from segmentations of three dimensional images.
5
5
  Author-email: Liam McLaughlin <mclaughlinliam99@gmail.com>
6
6
  Project-URL: User_Tutorial, https://www.youtube.com/watch?v=cRatn5VTWDY
@@ -44,6 +44,6 @@ NetTracer3D is free to use/fork for academic/nonprofit use so long as citation i
44
44
 
45
45
  NetTracer3D was developed by Liam McLaughlin while working under Dr. Sanjay Jain at Washington University School of Medicine.
46
46
 
47
- -- Version 0.5.7 updates --
47
+ -- Version 0.5.9 updates --
48
48
 
49
- 1. Minor change - Can now export network as .gexf (Gephi), .GraphML, or .net (Pajek) for other network analysis softwares to use.
49
+ 1. Bug fixes
File without changes
File without changes