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.
- nettracer3d/nettracer_gui.py +38 -5
- nettracer3d/segmenter.py +15 -11
- {nettracer3d-0.5.5.dist-info → nettracer3d-0.5.7.dist-info}/METADATA +3 -7
- {nettracer3d-0.5.5.dist-info → nettracer3d-0.5.7.dist-info}/RECORD +8 -8
- {nettracer3d-0.5.5.dist-info → nettracer3d-0.5.7.dist-info}/LICENSE +0 -0
- {nettracer3d-0.5.5.dist-info → nettracer3d-0.5.7.dist-info}/WHEEL +0 -0
- {nettracer3d-0.5.5.dist-info → nettracer3d-0.5.7.dist-info}/entry_points.txt +0 -0
- {nettracer3d-0.5.5.dist-info → nettracer3d-0.5.7.dist-info}/top_level.txt +0 -0
nettracer3d/nettracer_gui.py
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
6573
|
-
|
|
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
|
-
#
|
|
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
|
|
779
|
-
|
|
780
|
-
|
|
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
|
|
783
|
-
chunks.append(list(map(tuple,
|
|
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.
|
|
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.
|
|
47
|
+
-- Version 0.5.7 updates --
|
|
48
48
|
|
|
49
|
-
1.
|
|
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=
|
|
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=
|
|
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.
|
|
17
|
-
nettracer3d-0.5.
|
|
18
|
-
nettracer3d-0.5.
|
|
19
|
-
nettracer3d-0.5.
|
|
20
|
-
nettracer3d-0.5.
|
|
21
|
-
nettracer3d-0.5.
|
|
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,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|