nettracer3d 0.7.0__py3-none-any.whl → 0.7.2__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.
Potentially problematic release.
This version of nettracer3d might be problematic. Click here for more details.
- nettracer3d/morphology.py +2 -2
- nettracer3d/nettracer.py +16 -3
- nettracer3d/nettracer_gui.py +39 -8
- nettracer3d/proximity.py +1 -1
- nettracer3d/smart_dilate.py +5 -5
- {nettracer3d-0.7.0.dist-info → nettracer3d-0.7.2.dist-info}/METADATA +24 -29
- {nettracer3d-0.7.0.dist-info → nettracer3d-0.7.2.dist-info}/RECORD +11 -11
- {nettracer3d-0.7.0.dist-info → nettracer3d-0.7.2.dist-info}/WHEEL +1 -1
- {nettracer3d-0.7.0.dist-info → nettracer3d-0.7.2.dist-info}/entry_points.txt +0 -0
- {nettracer3d-0.7.0.dist-info → nettracer3d-0.7.2.dist-info}/licenses/LICENSE +0 -0
- {nettracer3d-0.7.0.dist-info → nettracer3d-0.7.2.dist-info}/top_level.txt +0 -0
nettracer3d/morphology.py
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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)
|
nettracer3d/nettracer.py
CHANGED
|
@@ -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
|
-
|
|
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(
|
|
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
|
|
nettracer3d/nettracer_gui.py
CHANGED
|
@@ -2384,7 +2384,10 @@ class ImageViewerWindow(QMainWindow):
|
|
|
2384
2384
|
|
|
2385
2385
|
|
|
2386
2386
|
if self.selection_rect is not None:
|
|
2387
|
-
|
|
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:
|
nettracer3d/proximity.py
CHANGED
|
@@ -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)
|
nettracer3d/smart_dilate.py
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
3
|
+
Version: 0.7.2
|
|
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/
|
|
@@ -9,26 +9,26 @@ Project-URL: Reference_Citation_For_Use, https://doi.org/10.1101/2024.07.29.6056
|
|
|
9
9
|
Classifier: Programming Language :: Python :: 3
|
|
10
10
|
Classifier: License :: Other/Proprietary License
|
|
11
11
|
Classifier: Operating System :: OS Independent
|
|
12
|
-
Requires-Python:
|
|
12
|
+
Requires-Python: >=3.7
|
|
13
13
|
Description-Content-Type: text/markdown
|
|
14
14
|
License-File: LICENSE
|
|
15
|
-
Requires-Dist: numpy
|
|
16
|
-
Requires-Dist: scipy
|
|
17
|
-
Requires-Dist: scikit-image
|
|
18
|
-
Requires-Dist: Pillow
|
|
19
|
-
Requires-Dist: matplotlib
|
|
20
|
-
Requires-Dist: networkx
|
|
21
|
-
Requires-Dist: opencv-python-headless
|
|
22
|
-
Requires-Dist: openpyxl
|
|
23
|
-
Requires-Dist: pandas==2.2.
|
|
24
|
-
Requires-Dist: napari
|
|
25
|
-
Requires-Dist: python-louvain
|
|
26
|
-
Requires-Dist: tifffile
|
|
27
|
-
Requires-Dist: qtrangeslider
|
|
28
|
-
Requires-Dist: PyQt6
|
|
29
|
-
Requires-Dist: scikit-learn
|
|
30
|
-
Requires-Dist: nibabel
|
|
31
|
-
Requires-Dist: setuptools
|
|
15
|
+
Requires-Dist: numpy
|
|
16
|
+
Requires-Dist: scipy
|
|
17
|
+
Requires-Dist: scikit-image
|
|
18
|
+
Requires-Dist: Pillow
|
|
19
|
+
Requires-Dist: matplotlib
|
|
20
|
+
Requires-Dist: networkx
|
|
21
|
+
Requires-Dist: opencv-python-headless
|
|
22
|
+
Requires-Dist: openpyxl
|
|
23
|
+
Requires-Dist: pandas==2.2.5
|
|
24
|
+
Requires-Dist: napari
|
|
25
|
+
Requires-Dist: python-louvain
|
|
26
|
+
Requires-Dist: tifffile
|
|
27
|
+
Requires-Dist: qtrangeslider
|
|
28
|
+
Requires-Dist: PyQt6
|
|
29
|
+
Requires-Dist: scikit-learn
|
|
30
|
+
Requires-Dist: nibabel
|
|
31
|
+
Requires-Dist: setuptools
|
|
32
32
|
Provides-Extra: cuda11
|
|
33
33
|
Requires-Dist: cupy-cuda11x; extra == "cuda11"
|
|
34
34
|
Provides-Extra: cuda12
|
|
@@ -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.
|
|
76
|
+
-- Version 0.7.2 Updates --
|
|
77
77
|
|
|
78
|
-
|
|
79
|
-
*
|
|
80
|
-
|
|
81
|
-
|
|
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.
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
nettracer3d/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
2
|
nettracer3d/community_extractor.py,sha256=5v9SCCLX3P1RX0fjPVKH5NHMFkMolZ5BTe0bR_a67xg,24479
|
|
3
3
|
nettracer3d/modularity.py,sha256=FH3GpTHorRNkdQULe-2DWgFE3i0_u__hrao7Nx_6Ge4,30249
|
|
4
|
-
nettracer3d/morphology.py,sha256=
|
|
5
|
-
nettracer3d/nettracer.py,sha256=
|
|
6
|
-
nettracer3d/nettracer_gui.py,sha256=
|
|
4
|
+
nettracer3d/morphology.py,sha256=jyDjYzrZ4LvI5jOyw8DLsxmo-i5lpqHsejYpW7Tq7Mo,19786
|
|
5
|
+
nettracer3d/nettracer.py,sha256=aNeRZq6EAbtPC3uEtgIX35t7y0PtGUc3I4BEk9H7ato,218669
|
|
6
|
+
nettracer3d/nettracer_gui.py,sha256=CsVMxHu3vP61gMIgebqejYE14W7mxTM9GsTOiNWdhDU,427477
|
|
7
7
|
nettracer3d/network_analysis.py,sha256=q1q7lxtA3lebxitfC_jfiT9cnpYXJw4q0Oy2_-Aj8qE,48068
|
|
8
8
|
nettracer3d/network_draw.py,sha256=F7fw6Pcf4qWOhdKwLmhwqWdschbDlHzwCVolQC9imeU,14117
|
|
9
9
|
nettracer3d/node_draw.py,sha256=k3sCTfUCJs3aH1C1q1gTNxDz9EAQbBd1hsUIJajxRx8,9823
|
|
10
|
-
nettracer3d/proximity.py,sha256=
|
|
10
|
+
nettracer3d/proximity.py,sha256=nlVBXzJ6r84TlP8UaLcdamWifYn-jfVIF0uB-56k_Js,24752
|
|
11
11
|
nettracer3d/run.py,sha256=xYeaAc8FCx8MuzTGyL3NR3mK7WZzffAYAH23bNRZYO4,127
|
|
12
12
|
nettracer3d/segmenter.py,sha256=gJS2AXqHhnw29cbzIxAah2LsrE7_7XnzG7mYSAovZ4I,87847
|
|
13
13
|
nettracer3d/simple_network.py,sha256=fP1gkDdtQcHruEZpUdasKdZeVacoLOxKhR3bY0L1CAQ,15426
|
|
14
|
-
nettracer3d/smart_dilate.py,sha256=
|
|
15
|
-
nettracer3d-0.7.
|
|
16
|
-
nettracer3d-0.7.
|
|
17
|
-
nettracer3d-0.7.
|
|
18
|
-
nettracer3d-0.7.
|
|
19
|
-
nettracer3d-0.7.
|
|
20
|
-
nettracer3d-0.7.
|
|
14
|
+
nettracer3d/smart_dilate.py,sha256=69z9Bn8xtA7rkhcVpqd1PxRSxxRFnIQse9lc2-LU4TU,25879
|
|
15
|
+
nettracer3d-0.7.2.dist-info/licenses/LICENSE,sha256=gM207DhJjWrxLuEWXl0Qz5ISbtWDmADfjHp3yC2XISs,888
|
|
16
|
+
nettracer3d-0.7.2.dist-info/METADATA,sha256=YSXRHaxODA8bPM_ipSdCQZQZM53g19U5btGiuDjGYhQ,4474
|
|
17
|
+
nettracer3d-0.7.2.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
|
|
18
|
+
nettracer3d-0.7.2.dist-info/entry_points.txt,sha256=Nx1rr_0QhJXDBHAQg2vcqCzLMKBzSHfwy3xwGkueVyc,53
|
|
19
|
+
nettracer3d-0.7.2.dist-info/top_level.txt,sha256=zsYy9rZwirfCEOubolhee4TyzqBAL5gSUeFMzhFTX8c,12
|
|
20
|
+
nettracer3d-0.7.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|