nettracer3d 0.5.5__py3-none-any.whl → 0.5.7__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.
@@ -3980,10 +3980,17 @@ class CustomTableView(QTableView):
3980
3980
  save_menu = context_menu.addMenu("Save As")
3981
3981
  save_csv = save_menu.addAction("CSV")
3982
3982
  save_excel = save_menu.addAction("Excel")
3983
+ save_gephi = save_menu.addAction("Gephi")
3984
+ save_graphml = save_menu.addAction("GraphML")
3985
+ save_pajek = save_menu.addAction("Pajek")
3983
3986
 
3984
3987
  # Connect the actions - ensure we're saving the active table
3985
3988
  save_csv.triggered.connect(lambda: self.parent.active_table.save_table_as('csv'))
3986
3989
  save_excel.triggered.connect(lambda: self.parent.active_table.save_table_as('xlsx'))
3990
+ save_gephi.triggered.connect(lambda: self.parent.active_table.save_table_as('gexf'))
3991
+ save_graphml.triggered.connect(lambda: self.parent.active_table.save_table_as('graphml'))
3992
+ save_pajek.triggered.connect(lambda: self.parent.active_table.save_table_as('net'))
3993
+
3987
3994
 
3988
3995
  if self == self.parent.selection_table:
3989
3996
  set_action = context_menu.addAction("Swap with network table (also sets internal network properties - may affect related functions)")
@@ -4061,14 +4068,19 @@ class CustomTableView(QTableView):
4061
4068
  table_name = "Selection"
4062
4069
 
4063
4070
  # Get save file name
4064
- file_filter = "CSV Files (*.csv)" if file_type == 'csv' else "Excel Files (*.xlsx)"
4071
+ file_filter = ("CSV Files (*.csv)" if file_type == 'csv' else
4072
+ "Excel Files (*.xlsx)" if file_type == 'excel' else
4073
+ "Gephi Graph (*.gexf)" if file_type == 'gexf' else
4074
+ "GraphML (*.graphml)" if file_type == 'graphml' else
4075
+ "Pajek Network (*.net)")
4076
+
4065
4077
  filename, _ = QFileDialog.getSaveFileName(
4066
4078
  self,
4067
4079
  f"Save {table_name} Table As",
4068
4080
  "",
4069
4081
  file_filter
4070
4082
  )
4071
-
4083
+
4072
4084
  if filename:
4073
4085
  try:
4074
4086
  if file_type == 'csv':
@@ -4076,11 +4088,28 @@ class CustomTableView(QTableView):
4076
4088
  if not filename.endswith('.csv'):
4077
4089
  filename += '.csv'
4078
4090
  df.to_csv(filename, index=False)
4079
- else:
4091
+ elif file_type == 'xlsx':
4080
4092
  # If user didn't type extension, add .xlsx
4081
4093
  if not filename.endswith('.xlsx'):
4082
4094
  filename += '.xlsx'
4083
4095
  df.to_excel(filename, index=False)
4096
+ elif file_type == 'gexf':
4097
+ # If user didn't type extension, add .gexf
4098
+ if not filename.endswith('.gexf'):
4099
+ filename += '.gexf'
4100
+ #for node in my_network.network.nodes():
4101
+ #my_network.network.nodes[node]['label'] = str(node)
4102
+ nx.write_gexf(my_network.network, filename, encoding='utf-8', prettyprint=True)
4103
+ elif file_type == 'graphml':
4104
+ # If user didn't type extension, add .graphml
4105
+ if not filename.endswith('.graphml'):
4106
+ filename += '.graphml'
4107
+ nx.write_graphml(my_network.network, filename)
4108
+ elif file_type == 'net':
4109
+ # If user didn't type extension, add .net
4110
+ if not filename.endswith('.net'):
4111
+ filename += '.net'
4112
+ nx.write_pajek(my_network.network, filename)
4084
4113
 
4085
4114
  QMessageBox.information(
4086
4115
  self,
@@ -6569,8 +6598,12 @@ class MachineWindow(QMainWindow):
6569
6598
  # Clean up when done
6570
6599
  self.segmenter.cleanup()
6571
6600
 
6572
- for z,y,x in foreground_coords:
6573
- self.parent().highlight_overlay[z,y,x] = 255
6601
+ fg_array = np.array(list(foreground_coords))
6602
+ if len(fg_array) > 0: # Check if we have any foreground coordinates
6603
+ # Unpack into separate coordinate arrays
6604
+ z_coords, y_coords, x_coords = fg_array[:, 0], fg_array[:, 1], fg_array[:, 2]
6605
+ # Assign values in a single vectorized operation
6606
+ self.parent().highlight_overlay[z_coords, y_coords, x_coords] = 255
6574
6607
 
6575
6608
  self.parent().load_channel(3, self.parent().highlight_overlay, True)
6576
6609
 
nettracer3d/segmenter.py CHANGED
@@ -764,26 +764,30 @@ class InteractiveSegmenter:
764
764
  Returns:
765
765
  List of chunks, where each chunk contains the coordinates for one z-slice
766
766
  """
767
+ # Pre-calculate the number of coordinates per z-slice
768
+ coords_per_slice = self.image_3d.shape[1] * self.image_3d.shape[2]
769
+
770
+ # Create all coordinates at once
767
771
  chunks = []
768
-
769
- # Process one z-slice at a time
770
772
  for z in range(self.image_3d.shape[0]):
771
- # For each z-slice, gather all y,x coordinates
773
+ # Create y, x meshgrid once
772
774
  y_coords, x_coords = np.meshgrid(
773
775
  np.arange(self.image_3d.shape[1]),
774
776
  np.arange(self.image_3d.shape[2]),
775
777
  indexing='ij'
776
778
  )
777
779
 
778
- # Create the z-slice coordinates
779
- z_array = np.full_like(y_coords, z)
780
- coords = np.stack([z_array, y_coords, x_coords]).reshape(3, -1).T
780
+ # Create the slice coordinates more efficiently
781
+ slice_coords = np.column_stack((
782
+ np.full(coords_per_slice, z),
783
+ y_coords.ravel(),
784
+ x_coords.ravel()
785
+ ))
781
786
 
782
- # Convert to list of tuples and add as a chunk
783
- chunks.append(list(map(tuple, coords)))
784
-
785
- return chunks
787
+ # Convert to list of tuples
788
+ chunks.append(list(map(tuple, slice_coords)))
786
789
 
790
+ return chunks
787
791
  try:
788
792
  from cuml.ensemble import RandomForestClassifier as cuRandomForestClassifier
789
793
  except:
@@ -853,7 +857,7 @@ class InteractiveSegmenter:
853
857
  print("Segmenting chunks...")
854
858
 
855
859
 
856
- with ThreadPoolExecutor() as executor:
860
+ with ThreadPoolExecutor(max_workers=multiprocessing.cpu_count()) as executor:
857
861
  if gpu:
858
862
  try:
859
863
  futures = [executor.submit(self.process_chunk_GPU, chunk) for chunk in chunks]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: nettracer3d
3
- Version: 0.5.5
3
+ Version: 0.5.7
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,10 +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.5 updates --
47
+ -- Version 0.5.7 updates --
48
48
 
49
- 1. When the highlight overlay is being used in big overlays (and therefore defaulting to the mini overlay), updated system to just make one 2d overlay that regenerates on slice movement. Decided this was better than having it sit in a bigger 3d array when said array wasn't being used for anything and had to be rebuilt on slice movement or 3d operations anyway.
50
-
51
- 2. For the random forrest segmenter, added the option to segment by 2D slice instead of 3D. In short, the 3D version was very greedy with its RAM usage and essentially computes a set of feature maps for the target array that are equivalent dims. By default it makes 7 of these, so a 1 GB array is going to demand 7GB of RAM to store its feature maps. The 2D slice version segments by 2D slice instead, meaning it stores only feature maps for slices with actual slices on them for training the model, and then for predicting voxel foreground/background, it computes the feature maps for the current slice (admittedly in the threadpool so this is amplified by core amount in the CPU but generally speaking this will save a lot of RAM). The reason I made this segmenter is to give NetTracer3D all the bells and whistles to let a user do everything in one program, but admittedly there are more efficient ML segmenters out there, such as through FIJI's big data viewer which is a lot better at handling big arrays in memory. I considered a way to compute 3D feature maps one at a time, save them in chunks to hard mem, and then open them while doing the chunked total segmentation but frankly this would likely be too slow to want to use so I will just suggest using 2D slice segmenter if RAM runs low.
52
-
53
- I do not anticipate any major updates for this project for the foreseeable future beyond bug fixes.
49
+ 1. Minor change - Can now export network as .gexf (Gephi), .GraphML, or .net (Pajek) for other network analysis softwares to use.
@@ -4,18 +4,18 @@ nettracer3d/hub_getter.py,sha256=KiNtxdajLkwB1ftslvrh1FE1Ch9ZCFEmHSEEotwR-To,829
4
4
  nettracer3d/modularity.py,sha256=V1f3s_vGd8EuVz27mzq6ycIGr0BWIpH7c7NU4QjgAHU,30247
5
5
  nettracer3d/morphology.py,sha256=yQ0GuieMVXOQpaohZlPnkEXEuCUjf8Fg352axyK8nbM,10755
6
6
  nettracer3d/nettracer.py,sha256=OE95IH1TfAZvT-htv1LEhw1EpnnEpkA83R5EcGMQDQg,209828
7
- nettracer3d/nettracer_gui.py,sha256=lKNl6T9998fMIYKrWdOhoAQlOLGeCiSaAP2chXCIDdQ,365336
7
+ nettracer3d/nettracer_gui.py,sha256=TGxxDRfZzSQsurtn_XC1dlt8NLQCPZN0W5LZSbxTAZE,367424
8
8
  nettracer3d/network_analysis.py,sha256=MJBBjslA1k_R8ymid77U-qGSgzxFVfzGVQhE0IdhnbE,48046
9
9
  nettracer3d/network_draw.py,sha256=F7fw6Pcf4qWOhdKwLmhwqWdschbDlHzwCVolQC9imeU,14117
10
10
  nettracer3d/node_draw.py,sha256=k3sCTfUCJs3aH1C1q1gTNxDz9EAQbBd1hsUIJajxRx8,9823
11
11
  nettracer3d/proximity.py,sha256=FnIiI_AzfXd22HwCIFIyQRZxKYJ8YscIDdPnIv-wsO4,10560
12
12
  nettracer3d/run.py,sha256=xYeaAc8FCx8MuzTGyL3NR3mK7WZzffAYAH23bNRZYO4,127
13
- nettracer3d/segmenter.py,sha256=hqe7VLRkil65d_KYyUwWbU7SbM7v-krVSeZfLUlHlfY,49587
13
+ nettracer3d/segmenter.py,sha256=zFWv9chXZ1rgw24KYKvIaQqkptUHy03vMKjmPgwv0-M,49793
14
14
  nettracer3d/simple_network.py,sha256=fP1gkDdtQcHruEZpUdasKdZeVacoLOxKhR3bY0L1CAQ,15426
15
15
  nettracer3d/smart_dilate.py,sha256=Kekm6YIVlJniMvJMG6_AwwNmCqK2l4Qtvg9VzzqPKMw,24600
16
- nettracer3d-0.5.5.dist-info/LICENSE,sha256=gM207DhJjWrxLuEWXl0Qz5ISbtWDmADfjHp3yC2XISs,888
17
- nettracer3d-0.5.5.dist-info/METADATA,sha256=8t96LyM9LOlvtwllVY0XrFszSZ5pj1J8t6wjPdVQ7Us,4746
18
- nettracer3d-0.5.5.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
19
- nettracer3d-0.5.5.dist-info/entry_points.txt,sha256=Nx1rr_0QhJXDBHAQg2vcqCzLMKBzSHfwy3xwGkueVyc,53
20
- nettracer3d-0.5.5.dist-info/top_level.txt,sha256=zsYy9rZwirfCEOubolhee4TyzqBAL5gSUeFMzhFTX8c,12
21
- nettracer3d-0.5.5.dist-info/RECORD,,
16
+ nettracer3d-0.5.7.dist-info/LICENSE,sha256=gM207DhJjWrxLuEWXl0Qz5ISbtWDmADfjHp3yC2XISs,888
17
+ nettracer3d-0.5.7.dist-info/METADATA,sha256=WR2-IsGW-YlgJhNNutjAQfGPcE-Fl_MS1-itY3nT0FQ,3107
18
+ nettracer3d-0.5.7.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
19
+ nettracer3d-0.5.7.dist-info/entry_points.txt,sha256=Nx1rr_0QhJXDBHAQg2vcqCzLMKBzSHfwy3xwGkueVyc,53
20
+ nettracer3d-0.5.7.dist-info/top_level.txt,sha256=zsYy9rZwirfCEOubolhee4TyzqBAL5gSUeFMzhFTX8c,12
21
+ nettracer3d-0.5.7.dist-info/RECORD,,