nettracer3d 0.3.7__py3-none-any.whl → 0.3.9__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.py +50 -2
- nettracer3d/nettracer_gui.py +43 -12
- {nettracer3d-0.3.7.dist-info → nettracer3d-0.3.9.dist-info}/METADATA +1 -1
- {nettracer3d-0.3.7.dist-info → nettracer3d-0.3.9.dist-info}/RECORD +7 -7
- {nettracer3d-0.3.7.dist-info → nettracer3d-0.3.9.dist-info}/LICENSE +0 -0
- {nettracer3d-0.3.7.dist-info → nettracer3d-0.3.9.dist-info}/WHEEL +0 -0
- {nettracer3d-0.3.7.dist-info → nettracer3d-0.3.9.dist-info}/top_level.txt +0 -0
nettracer3d/nettracer.py
CHANGED
|
@@ -23,8 +23,6 @@ except:
|
|
|
23
23
|
from . import node_draw
|
|
24
24
|
from . import network_draw
|
|
25
25
|
from skimage.morphology import skeletonize_3d
|
|
26
|
-
#from skimage.segmentation import watershed
|
|
27
|
-
from skimage.feature import peak_local_max
|
|
28
26
|
from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
29
27
|
from . import smart_dilate
|
|
30
28
|
from . import modularity
|
|
@@ -864,6 +862,11 @@ def dilate_3D(tiff_array, dilated_x, dilated_y, dilated_z):
|
|
|
864
862
|
"""Internal method to dilate an array in 3D. Dilation this way is much faster than using a distance transform although the latter is theoretically more accurate.
|
|
865
863
|
Arguments are an array, and the desired pixel dilation amounts in X, Y, Z."""
|
|
866
864
|
|
|
865
|
+
|
|
866
|
+
if dilated_x == 3 and dilated_y == 3 and dilated_z == 3:
|
|
867
|
+
|
|
868
|
+
return dilate_3D_old(tiff_array, dilated_x, dilated_y, dilated_z)
|
|
869
|
+
|
|
867
870
|
def create_circular_kernel(diameter):
|
|
868
871
|
"""Create a 2D circular kernel with a given radius.
|
|
869
872
|
|
|
@@ -4182,6 +4185,51 @@ class Network_3D:
|
|
|
4182
4185
|
|
|
4183
4186
|
return array
|
|
4184
4187
|
|
|
4188
|
+
def community_id_info(self):
|
|
4189
|
+
def invert_dict(d):
|
|
4190
|
+
inverted = {}
|
|
4191
|
+
for key, value in d.items():
|
|
4192
|
+
inverted.setdefault(value, []).append(key)
|
|
4193
|
+
return inverted
|
|
4194
|
+
|
|
4195
|
+
community_dict = invert_dict(self.communities)
|
|
4196
|
+
summation = 0
|
|
4197
|
+
id_set = set(self.node_identities.values())
|
|
4198
|
+
output = {sort: 0 for sort in id_set}
|
|
4199
|
+
template = copy.deepcopy(output)
|
|
4200
|
+
|
|
4201
|
+
for community in community_dict:
|
|
4202
|
+
counter = copy.deepcopy(template)
|
|
4203
|
+
nodes = community_dict[community]
|
|
4204
|
+
size = len(nodes)
|
|
4205
|
+
summation += size
|
|
4206
|
+
|
|
4207
|
+
# Count identities in this community
|
|
4208
|
+
for node in nodes:
|
|
4209
|
+
counter[self.node_identities[node]] += 1
|
|
4210
|
+
|
|
4211
|
+
# Convert to proportions within this community and weight by size
|
|
4212
|
+
for sort in counter:
|
|
4213
|
+
if size > 0: # Avoid division by zero
|
|
4214
|
+
counter[sort] = (counter[sort]) * size # proportion * size
|
|
4215
|
+
|
|
4216
|
+
# Add to running totals
|
|
4217
|
+
for sort, weighted_count in counter.items():
|
|
4218
|
+
output[sort] = output.get(sort, 0) + weighted_count
|
|
4219
|
+
|
|
4220
|
+
# Normalize by total size
|
|
4221
|
+
dictsum = 0
|
|
4222
|
+
for sort in output:
|
|
4223
|
+
output[sort] = output[sort]/summation
|
|
4224
|
+
dictsum += output[sort]
|
|
4225
|
+
|
|
4226
|
+
for sort in output:
|
|
4227
|
+
output[sort] = output[sort]/dictsum
|
|
4228
|
+
|
|
4229
|
+
return output
|
|
4230
|
+
|
|
4231
|
+
|
|
4232
|
+
|
|
4185
4233
|
|
|
4186
4234
|
def kd_network(self, distance = 100, targets = None):
|
|
4187
4235
|
|
nettracer3d/nettracer_gui.py
CHANGED
|
@@ -167,6 +167,7 @@ class ImageViewerWindow(QMainWindow):
|
|
|
167
167
|
self.zoom_button.setFixedSize(40, 40)
|
|
168
168
|
self.zoom_button.clicked.connect(self.toggle_zoom_mode)
|
|
169
169
|
control_layout.addWidget(self.zoom_button)
|
|
170
|
+
self.resizing = False
|
|
170
171
|
|
|
171
172
|
self.pan_button = QPushButton("✋")
|
|
172
173
|
self.pan_button.setCheckable(True)
|
|
@@ -1783,8 +1784,10 @@ class ImageViewerWindow(QMainWindow):
|
|
|
1783
1784
|
network_menu = analysis_menu.addMenu("Network")
|
|
1784
1785
|
netshow_action = network_menu.addAction("Show Network")
|
|
1785
1786
|
netshow_action.triggered.connect(self.show_netshow_dialog)
|
|
1786
|
-
partition_action = network_menu.addAction("Community Partition + Community Stats")
|
|
1787
|
+
partition_action = network_menu.addAction("Community Partition +Generic Community Stats")
|
|
1787
1788
|
partition_action.triggered.connect(self.show_partition_dialog)
|
|
1789
|
+
com_identity_action = network_menu.addAction("Identity Makeup of Network Communities (Weighted avg by community size)")
|
|
1790
|
+
com_identity_action.triggered.connect(self.handle_com_id)
|
|
1788
1791
|
stats_menu = analysis_menu.addMenu("Stats")
|
|
1789
1792
|
allstats_action = stats_menu.addAction("Calculate Generic Network Stats")
|
|
1790
1793
|
allstats_action.triggered.connect(self.stats)
|
|
@@ -2797,8 +2800,12 @@ class ImageViewerWindow(QMainWindow):
|
|
|
2797
2800
|
def update_slice(self):
|
|
2798
2801
|
"""Queue a slice update when slider moves."""
|
|
2799
2802
|
# Store current view settings
|
|
2800
|
-
|
|
2801
|
-
|
|
2803
|
+
if not self.resizing:
|
|
2804
|
+
current_xlim = self.ax.get_xlim() if hasattr(self, 'ax') and self.ax.get_xlim() != (0, 1) else None
|
|
2805
|
+
current_ylim = self.ax.get_ylim() if hasattr(self, 'ax') and self.ax.get_ylim() != (0, 1) else None
|
|
2806
|
+
else:
|
|
2807
|
+
current_xlim = None
|
|
2808
|
+
current_ylim = None
|
|
2802
2809
|
|
|
2803
2810
|
# Store the pending slice and view settings
|
|
2804
2811
|
self.pending_slice = (self.slice_slider.value(), (current_xlim, current_ylim))
|
|
@@ -2855,11 +2862,8 @@ class ImageViewerWindow(QMainWindow):
|
|
|
2855
2862
|
self.ax = self.figure.add_subplot(111)
|
|
2856
2863
|
|
|
2857
2864
|
# Store current zoom limits if they exist and weren't provided
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
current_ylim = self.ax.get_ylim() if self.ax.get_ylim() != (0, 1) else None
|
|
2861
|
-
else:
|
|
2862
|
-
current_xlim, current_ylim = preserve_zoom if preserve_zoom else (None, None)
|
|
2865
|
+
|
|
2866
|
+
current_xlim, current_ylim = preserve_zoom if preserve_zoom else (None, None)
|
|
2863
2867
|
|
|
2864
2868
|
# Define base colors for each channel with increased intensity
|
|
2865
2869
|
base_colors = self.base_colors
|
|
@@ -2934,10 +2938,7 @@ class ImageViewerWindow(QMainWindow):
|
|
|
2934
2938
|
cmap=highlight_cmap,
|
|
2935
2939
|
alpha=0.5)
|
|
2936
2940
|
|
|
2937
|
-
|
|
2938
|
-
if current_xlim is not None and current_ylim is not None:
|
|
2939
|
-
self.ax.set_xlim(current_xlim)
|
|
2940
|
-
self.ax.set_ylim(current_ylim)
|
|
2941
|
+
|
|
2941
2942
|
|
|
2942
2943
|
# Style the axes
|
|
2943
2944
|
self.ax.set_xlabel('X')
|
|
@@ -2978,8 +2979,17 @@ class ImageViewerWindow(QMainWindow):
|
|
|
2978
2979
|
if active_channels:
|
|
2979
2980
|
self.ax.set_xlim(-0.5, min_width - 0.5)
|
|
2980
2981
|
self.ax.set_ylim(min_height - 0.5, -0.5)
|
|
2982
|
+
|
|
2983
|
+
if self.resizing:
|
|
2984
|
+
self.original_xlim = self.ax.get_xlim()
|
|
2985
|
+
self.original_ylim = self.ax.get_ylim()
|
|
2986
|
+
# Restore zoom limits if they existed
|
|
2987
|
+
if current_xlim is not None and current_ylim is not None:
|
|
2988
|
+
self.ax.set_xlim(current_xlim)
|
|
2989
|
+
self.ax.set_ylim(current_ylim)
|
|
2981
2990
|
|
|
2982
2991
|
self.canvas.draw()
|
|
2992
|
+
|
|
2983
2993
|
def show_netshow_dialog(self):
|
|
2984
2994
|
dialog = NetShowDialog(self)
|
|
2985
2995
|
dialog.exec()
|
|
@@ -2988,6 +2998,21 @@ class ImageViewerWindow(QMainWindow):
|
|
|
2988
2998
|
dialog = PartitionDialog(self)
|
|
2989
2999
|
dialog.exec()
|
|
2990
3000
|
|
|
3001
|
+
def handle_com_id(self):
|
|
3002
|
+
if my_network.node_identities is None:
|
|
3003
|
+
print("Node identities must be set")
|
|
3004
|
+
|
|
3005
|
+
if my_network.communities is None:
|
|
3006
|
+
self.show_partition_dialog()
|
|
3007
|
+
|
|
3008
|
+
if my_network.communities is None:
|
|
3009
|
+
return
|
|
3010
|
+
|
|
3011
|
+
info = my_network.community_id_info()
|
|
3012
|
+
|
|
3013
|
+
self.format_for_upperright_table(info, 'Node Identity Type', 'Weighted Proportion in Communities', 'Weighted Average of Community Makeup')
|
|
3014
|
+
|
|
3015
|
+
|
|
2991
3016
|
def show_radial_dialog(self):
|
|
2992
3017
|
dialog = RadialDialog(self)
|
|
2993
3018
|
dialog.exec()
|
|
@@ -4360,6 +4385,8 @@ class PartitionDialog(QDialog):
|
|
|
4360
4385
|
except Exception as e:
|
|
4361
4386
|
print(f"Error creating communities: {e}")
|
|
4362
4387
|
|
|
4388
|
+
|
|
4389
|
+
|
|
4363
4390
|
class RadialDialog(QDialog):
|
|
4364
4391
|
|
|
4365
4392
|
def __init__(self, parent=None):
|
|
@@ -4956,6 +4983,7 @@ class ResizeDialog(QDialog):
|
|
|
4956
4983
|
|
|
4957
4984
|
def run_resize(self, undo = False):
|
|
4958
4985
|
try:
|
|
4986
|
+
self.parent().resizing = True
|
|
4959
4987
|
# Get parameters
|
|
4960
4988
|
try:
|
|
4961
4989
|
resize = float(self.resize.text()) if self.resize.text() else None
|
|
@@ -5104,6 +5132,7 @@ class ResizeDialog(QDialog):
|
|
|
5104
5132
|
|
|
5105
5133
|
self.parent().update_display()
|
|
5106
5134
|
self.reset_fields()
|
|
5135
|
+
self.parent().resizing = False
|
|
5107
5136
|
self.accept()
|
|
5108
5137
|
|
|
5109
5138
|
except Exception as e:
|
|
@@ -6034,6 +6063,7 @@ class GenNodesDialog(QDialog):
|
|
|
6034
6063
|
)
|
|
6035
6064
|
|
|
6036
6065
|
if down_factor > 0 and not self.called:
|
|
6066
|
+
self.parent().resizing = True
|
|
6037
6067
|
|
|
6038
6068
|
my_network.edges = n3d.downsample(my_network.edges, down_factor, order = order)
|
|
6039
6069
|
my_network.xy_scale = my_network.xy_scale * down_factor
|
|
@@ -6061,6 +6091,7 @@ class GenNodesDialog(QDialog):
|
|
|
6061
6091
|
|
|
6062
6092
|
|
|
6063
6093
|
self.parent().update_display()
|
|
6094
|
+
self.parent().resizing = False
|
|
6064
6095
|
self.accept()
|
|
6065
6096
|
|
|
6066
6097
|
except Exception as e:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: nettracer3d
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.9
|
|
4
4
|
Summary: Scripts for intializing and analyzing networks from segmentations of three dimensional images.
|
|
5
5
|
Author-email: Liam McLaughlin <boom2449@gmail.com>
|
|
6
6
|
Project-URL: User_Manual, https://drive.google.com/drive/folders/1fTkz3n4LN9_VxKRKC8lVQSlrz_wq0bVn?usp=drive_link
|
|
@@ -3,16 +3,16 @@ nettracer3d/community_extractor.py,sha256=8bRDJOfZhOFLtpkJVaDQrQ4O8wUywyr-EfVvW5
|
|
|
3
3
|
nettracer3d/hub_getter.py,sha256=KiNtxdajLkwB1ftslvrh1FE1Ch9ZCFEmHSEEotwR-To,8298
|
|
4
4
|
nettracer3d/modularity.py,sha256=V1f3s_vGd8EuVz27mzq6ycIGr0BWIpH7c7NU4QjgAHU,30247
|
|
5
5
|
nettracer3d/morphology.py,sha256=wv7v06YUcn5lMyefcc_znQlXF5iDxvUdoc0fXOKlGTw,12982
|
|
6
|
-
nettracer3d/nettracer.py,sha256=
|
|
7
|
-
nettracer3d/nettracer_gui.py,sha256=
|
|
6
|
+
nettracer3d/nettracer.py,sha256=hlBxOPaIP8enow9FZHlSqVFwYjUgiyIRKnjMwtMyYD8,203271
|
|
7
|
+
nettracer3d/nettracer_gui.py,sha256=GSTICp2V0MAwMpw6RcUrR0kdF721bpBOGMHnOK2LHLM,290039
|
|
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=BMiD_FrlOHeGD4AQZ_Emd152PfxFuMgGf2x4S0TOTnw,9752
|
|
11
11
|
nettracer3d/proximity.py,sha256=KYs4QUbt1U79RLzTvt8BmrxeGVaeKOQ2brtzTjjA78c,11011
|
|
12
12
|
nettracer3d/simple_network.py,sha256=fP1gkDdtQcHruEZpUdasKdZeVacoLOxKhR3bY0L1CAQ,15426
|
|
13
13
|
nettracer3d/smart_dilate.py,sha256=howfO6Lw5PxNjkaOBSCjkmf7fyau_-_8iTct2mAuTAQ,22083
|
|
14
|
-
nettracer3d-0.3.
|
|
15
|
-
nettracer3d-0.3.
|
|
16
|
-
nettracer3d-0.3.
|
|
17
|
-
nettracer3d-0.3.
|
|
18
|
-
nettracer3d-0.3.
|
|
14
|
+
nettracer3d-0.3.9.dist-info/LICENSE,sha256=gM207DhJjWrxLuEWXl0Qz5ISbtWDmADfjHp3yC2XISs,888
|
|
15
|
+
nettracer3d-0.3.9.dist-info/METADATA,sha256=c9mvd_DrHGay2lqXcDRKMb-4hi3lJvICANkTNFzkXKY,2894
|
|
16
|
+
nettracer3d-0.3.9.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
17
|
+
nettracer3d-0.3.9.dist-info/top_level.txt,sha256=zsYy9rZwirfCEOubolhee4TyzqBAL5gSUeFMzhFTX8c,12
|
|
18
|
+
nettracer3d-0.3.9.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|