nettracer3d 1.0.4__py3-none-any.whl → 1.0.6__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/nettracer.py +14 -11
- nettracer3d/nettracer_gui.py +38 -32
- {nettracer3d-1.0.4.dist-info → nettracer3d-1.0.6.dist-info}/METADATA +3 -4
- {nettracer3d-1.0.4.dist-info → nettracer3d-1.0.6.dist-info}/RECORD +8 -8
- {nettracer3d-1.0.4.dist-info → nettracer3d-1.0.6.dist-info}/WHEEL +0 -0
- {nettracer3d-1.0.4.dist-info → nettracer3d-1.0.6.dist-info}/entry_points.txt +0 -0
- {nettracer3d-1.0.4.dist-info → nettracer3d-1.0.6.dist-info}/licenses/LICENSE +0 -0
- {nettracer3d-1.0.4.dist-info → nettracer3d-1.0.6.dist-info}/top_level.txt +0 -0
nettracer3d/nettracer.py
CHANGED
|
@@ -5294,32 +5294,35 @@ class Network_3D:
|
|
|
5294
5294
|
new_list.append(centroid)
|
|
5295
5295
|
|
|
5296
5296
|
else:
|
|
5297
|
-
|
|
5298
5297
|
if mode == 1:
|
|
5299
|
-
|
|
5300
5298
|
legal = self.edges != 0
|
|
5301
|
-
|
|
5302
5299
|
elif mode == 2:
|
|
5303
|
-
|
|
5304
5300
|
legal = self.network_overlay != 0
|
|
5305
|
-
|
|
5306
5301
|
elif mode == 3:
|
|
5307
|
-
|
|
5308
5302
|
legal = self.id_overlay != 0
|
|
5309
|
-
|
|
5310
5303
|
if self.nodes is None:
|
|
5311
|
-
|
|
5312
5304
|
temp_array = proximity.populate_array(self.node_centroids, shape = legal.shape)
|
|
5313
5305
|
else:
|
|
5314
5306
|
temp_array = self.nodes
|
|
5315
|
-
|
|
5316
5307
|
if dim == 2:
|
|
5317
5308
|
volume = np.count_nonzero(legal) * self.xy_scale**2
|
|
5309
|
+
# Pad in x and y dimensions (assuming shape is [y, x])
|
|
5310
|
+
legal = np.pad(legal, pad_width=1, mode='constant', constant_values=0)
|
|
5318
5311
|
else:
|
|
5319
5312
|
volume = np.count_nonzero(legal) * self.z_scale * self.xy_scale**2
|
|
5313
|
+
# Pad in x, y, and z dimensions (assuming shape is [z, y, x])
|
|
5314
|
+
legal = np.pad(legal, pad_width=1, mode='constant', constant_values=0)
|
|
5315
|
+
|
|
5320
5316
|
print(f"Using {volume} for the volume measurement (Volume of provided mask as scaled by xy and z scaling)")
|
|
5321
|
-
|
|
5322
|
-
|
|
5317
|
+
|
|
5318
|
+
# Compute distance transform on padded array
|
|
5319
|
+
legal = smart_dilate.compute_distance_transform_distance(legal, sampling = [self.z_scale, self.xy_scale, self.xy_scale])
|
|
5320
|
+
|
|
5321
|
+
# Remove padding after distance transform
|
|
5322
|
+
if dim == 2:
|
|
5323
|
+
legal = legal[1:-1, 1:-1] # Remove padding from x and y dimensions
|
|
5324
|
+
else:
|
|
5325
|
+
legal = legal[1:-1, 1:-1, 1:-1] # Remove padding from x, y, and z dimensions
|
|
5323
5326
|
|
|
5324
5327
|
max_avail = np.max(legal) # Most internal point
|
|
5325
5328
|
min_legal = factor * max_avail # Values of stuff 25% within the tissue
|
nettracer3d/nettracer_gui.py
CHANGED
|
@@ -2009,7 +2009,7 @@ class ImageViewerWindow(QMainWindow):
|
|
|
2009
2009
|
self.parent().toggle_channel(1)
|
|
2010
2010
|
# Navigate to the Z-slice
|
|
2011
2011
|
self.parent().slice_slider.setValue(int(centroid[0]))
|
|
2012
|
-
print(f"Found edge {value} at Z
|
|
2012
|
+
print(f"Found edge {value} at [Z,Y,X] -> {centroid}")
|
|
2013
2013
|
|
|
2014
2014
|
else:
|
|
2015
2015
|
print(f"Edge {value} not found in centroids dictionary")
|
|
@@ -2045,9 +2045,9 @@ class ImageViewerWindow(QMainWindow):
|
|
|
2045
2045
|
# Navigate to the Z-slice
|
|
2046
2046
|
self.parent().slice_slider.setValue(int(centroid[0]))
|
|
2047
2047
|
if mode == 0:
|
|
2048
|
-
print(f"Found node {value} at Z
|
|
2048
|
+
print(f"Found node {value} at [Z,Y,X] -> {centroid}")
|
|
2049
2049
|
elif mode == 2:
|
|
2050
|
-
print(f"Found node {value} from community {com} at Z
|
|
2050
|
+
print(f"Found node {value} from community {com} at [Z,Y,X] -> {centroid}")
|
|
2051
2051
|
|
|
2052
2052
|
|
|
2053
2053
|
else:
|
|
@@ -2332,7 +2332,7 @@ class ImageViewerWindow(QMainWindow):
|
|
|
2332
2332
|
unique_labels = np.unique(input_array[binary_mask])
|
|
2333
2333
|
print(f"Processing {len(unique_labels)} unique labels")
|
|
2334
2334
|
|
|
2335
|
-
# Get all bounding boxes at once
|
|
2335
|
+
# Get all bounding boxes at once
|
|
2336
2336
|
bounding_boxes = ndimage.find_objects(input_array)
|
|
2337
2337
|
|
|
2338
2338
|
# Prepare work items - just check if bounding box exists for each label
|
|
@@ -2348,7 +2348,7 @@ class ImageViewerWindow(QMainWindow):
|
|
|
2348
2348
|
bbox = bounding_boxes[bbox_index]
|
|
2349
2349
|
work_items.append((orig_label, bbox))
|
|
2350
2350
|
|
|
2351
|
-
print(f"Created {len(work_items)} work items")
|
|
2351
|
+
#print(f"Created {len(work_items)} work items")
|
|
2352
2352
|
|
|
2353
2353
|
# If we have work items, process them
|
|
2354
2354
|
if len(work_items) == 0:
|
|
@@ -2368,7 +2368,7 @@ class ImageViewerWindow(QMainWindow):
|
|
|
2368
2368
|
return orig_label, bbox, labeled_sub, num_cc
|
|
2369
2369
|
|
|
2370
2370
|
except Exception as e:
|
|
2371
|
-
print(f"Error processing label {orig_label}: {e}")
|
|
2371
|
+
#print(f"Error processing label {orig_label}: {e}")
|
|
2372
2372
|
return orig_label, bbox, None, 0
|
|
2373
2373
|
|
|
2374
2374
|
# Execute in parallel
|
|
@@ -2384,7 +2384,7 @@ class ImageViewerWindow(QMainWindow):
|
|
|
2384
2384
|
|
|
2385
2385
|
for orig_label, bbox, labeled_sub, num_cc in results:
|
|
2386
2386
|
if num_cc > 0 and labeled_sub is not None:
|
|
2387
|
-
print(f"Label {orig_label}: {num_cc} components")
|
|
2387
|
+
#print(f"Label {orig_label}: {num_cc} components")
|
|
2388
2388
|
# Remap labels and place in output
|
|
2389
2389
|
for cc_id in range(1, num_cc + 1):
|
|
2390
2390
|
mask = labeled_sub == cc_id
|
|
@@ -2397,7 +2397,7 @@ class ImageViewerWindow(QMainWindow):
|
|
|
2397
2397
|
|
|
2398
2398
|
def handle_seperate(self):
|
|
2399
2399
|
"""
|
|
2400
|
-
|
|
2400
|
+
Seperate objects in an array that share a label but do not touch
|
|
2401
2401
|
"""
|
|
2402
2402
|
try:
|
|
2403
2403
|
# Handle nodes
|
|
@@ -2406,7 +2406,6 @@ class ImageViewerWindow(QMainWindow):
|
|
|
2406
2406
|
# Create highlight overlay (this should preserve original label values)
|
|
2407
2407
|
self.create_highlight_overlay(node_indices=self.clicked_values['nodes'])
|
|
2408
2408
|
|
|
2409
|
-
# DON'T convert to boolean yet - we need the original labels!
|
|
2410
2409
|
# Create a boolean mask for where we have highlighted values
|
|
2411
2410
|
highlight_mask = self.highlight_overlay != 0
|
|
2412
2411
|
|
|
@@ -2416,7 +2415,7 @@ class ImageViewerWindow(QMainWindow):
|
|
|
2416
2415
|
# Get non-highlighted part of the array
|
|
2417
2416
|
non_highlighted = np.where(highlight_mask, 0, my_network.nodes)
|
|
2418
2417
|
|
|
2419
|
-
# Calculate max_val
|
|
2418
|
+
# Calculate max_val
|
|
2420
2419
|
max_val = np.max(non_highlighted) if np.any(non_highlighted) else 0
|
|
2421
2420
|
|
|
2422
2421
|
# Process highlighted part
|
|
@@ -10087,7 +10086,7 @@ class ViolinDialog(QDialog):
|
|
|
10087
10086
|
# Convert all remaining columns to float type (batch conversion)
|
|
10088
10087
|
df_copy = df_copy.astype(float)
|
|
10089
10088
|
|
|
10090
|
-
# First, calculate the centerpoint for each column by finding the
|
|
10089
|
+
# First, calculate the centerpoint for each column by finding the min across all identity groups
|
|
10091
10090
|
column_centerpoints = {}
|
|
10092
10091
|
|
|
10093
10092
|
for column in df_copy.columns:
|
|
@@ -10098,7 +10097,7 @@ class ViolinDialog(QDialog):
|
|
|
10098
10097
|
valid_nodes = [node for node in node_list if node in df_copy.index]
|
|
10099
10098
|
if valid_nodes and ((str(identity) == str(column)) or str(identity) == f'{str(column)}+'):
|
|
10100
10099
|
# Get the median value for this identity in this column
|
|
10101
|
-
identity_min = df_copy.loc[valid_nodes, column].
|
|
10100
|
+
identity_min = df_copy.loc[valid_nodes, column].min()
|
|
10102
10101
|
centerpoint = identity_min
|
|
10103
10102
|
break # Found the match, no need to continue
|
|
10104
10103
|
|
|
@@ -10107,6 +10106,7 @@ class ViolinDialog(QDialog):
|
|
|
10107
10106
|
column_centerpoints[column] = centerpoint
|
|
10108
10107
|
else:
|
|
10109
10108
|
# Fallback: if no matching identity, use column median
|
|
10109
|
+
print(f"Could not find {str(column)} in node identities. As a fallback, using the median of all values in this channel rather than the minimum of user-designated valid values.")
|
|
10110
10110
|
column_centerpoints[column] = df_copy[column].median()
|
|
10111
10111
|
|
|
10112
10112
|
# Now normalize each column using Z-score-like calculation with identity centerpoint
|
|
@@ -10191,38 +10191,44 @@ class ViolinDialog(QDialog):
|
|
|
10191
10191
|
|
|
10192
10192
|
from . import neighborhoods
|
|
10193
10193
|
|
|
10194
|
-
|
|
10194
|
+
try:
|
|
10195
10195
|
|
|
10196
|
-
|
|
10197
|
-
iden_list = []
|
|
10198
|
-
import ast
|
|
10196
|
+
if self.idens.currentIndex() != 0:
|
|
10199
10197
|
|
|
10200
|
-
|
|
10198
|
+
iden = self.idens.currentText()
|
|
10199
|
+
iden_list = []
|
|
10200
|
+
import ast
|
|
10201
10201
|
|
|
10202
|
-
|
|
10203
|
-
parse = ast.literal_eval(my_network.node_identities[item])
|
|
10204
|
-
if iden in parse:
|
|
10205
|
-
iden_list.append(item)
|
|
10206
|
-
except:
|
|
10207
|
-
if (iden == my_network.node_identities[item]):
|
|
10208
|
-
iden_list.append(item)
|
|
10202
|
+
for item in my_network.node_identities:
|
|
10209
10203
|
|
|
10210
|
-
|
|
10204
|
+
try:
|
|
10205
|
+
parse = ast.literal_eval(my_network.node_identities[item])
|
|
10206
|
+
if iden in parse:
|
|
10207
|
+
iden_list.append(item)
|
|
10208
|
+
except:
|
|
10209
|
+
if (iden == my_network.node_identities[item]):
|
|
10210
|
+
iden_list.append(item)
|
|
10211
10211
|
|
|
10212
|
-
|
|
10212
|
+
violin_dict = df_to_dict_by_rows(self.df, iden_list, f"Z-Score-like Channel Intensities of Identity {iden}, {len(iden_list)} Nodes")
|
|
10213
10213
|
|
|
10214
|
+
neighborhoods.create_violin_plots(violin_dict, graph_title=f"Z-Score-like Channel Intensities of Identity {iden}, {len(iden_list)} Nodes")
|
|
10215
|
+
except:
|
|
10216
|
+
pass
|
|
10214
10217
|
|
|
10215
|
-
|
|
10218
|
+
try:
|
|
10219
|
+
if self.coms.currentIndex() != 0:
|
|
10216
10220
|
|
|
10217
|
-
|
|
10221
|
+
com = self.coms.currentText()
|
|
10218
10222
|
|
|
10219
|
-
|
|
10223
|
+
com_dict = n3d.invert_dict(my_network.communities)
|
|
10220
10224
|
|
|
10221
|
-
|
|
10225
|
+
com_list = com_dict[int(com)]
|
|
10222
10226
|
|
|
10223
|
-
|
|
10227
|
+
violin_dict = df_to_dict_by_rows(self.df, com_list, f"Z-Score-like Channel Intensities of Community/Neighborhood {com}, {len(com_list)} Nodes")
|
|
10224
10228
|
|
|
10225
|
-
|
|
10229
|
+
neighborhoods.create_violin_plots(violin_dict, graph_title=f"Z-Score-like Channel Intensities of Community/Neighborhood {com}, {len(com_list)} Nodes")
|
|
10230
|
+
except:
|
|
10231
|
+
pass
|
|
10226
10232
|
|
|
10227
10233
|
|
|
10228
10234
|
def run2(self):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nettracer3d
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.6
|
|
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/
|
|
@@ -110,7 +110,6 @@ McLaughlin, L., Zhang, B., Sharma, S. et al. Three dimensional multiscalar neuro
|
|
|
110
110
|
|
|
111
111
|
NetTracer3D was developed by Liam McLaughlin while working under Dr. Sanjay Jain at Washington University School of Medicine.
|
|
112
112
|
|
|
113
|
-
-- Version 1.0.
|
|
113
|
+
-- Version 1.0.5 Updates --
|
|
114
114
|
|
|
115
|
-
*
|
|
116
|
-
* Heatmap theoretical distances can now be calculated based on an area constrained within a binary mask.
|
|
115
|
+
* Bug fix
|
|
@@ -5,8 +5,8 @@ nettracer3d/excelotron.py,sha256=aNof6k-DgMxVyFgsl3ltSCxG4vZW49cuvCBzfzhYhUY,750
|
|
|
5
5
|
nettracer3d/modularity.py,sha256=pborVcDBvICB2-g8lNoSVZbIReIBlfeBmjFbPYmtq7Y,22443
|
|
6
6
|
nettracer3d/morphology.py,sha256=jyDjYzrZ4LvI5jOyw8DLsxmo-i5lpqHsejYpW7Tq7Mo,19786
|
|
7
7
|
nettracer3d/neighborhoods.py,sha256=lh4_zuTwgTq-u8VHy72buBfZf58FEJo9sH3IIBuZr68,52735
|
|
8
|
-
nettracer3d/nettracer.py,sha256=
|
|
9
|
-
nettracer3d/nettracer_gui.py,sha256=
|
|
8
|
+
nettracer3d/nettracer.py,sha256=rgQvMtojoA5UqXbDjeMRcz2BpaebwKLF5CPAlR_xZwY,274675
|
|
9
|
+
nettracer3d/nettracer_gui.py,sha256=5aqo5fWVfzcTVjCa1HlFflnrCFQoZvaPZYjM-QT94_E,666407
|
|
10
10
|
nettracer3d/network_analysis.py,sha256=kBzsVaq4dZkMe0k-VGvQIUvM-tK0ZZ8bvb-wtsugZRQ,46150
|
|
11
11
|
nettracer3d/network_draw.py,sha256=F7fw6Pcf4qWOhdKwLmhwqWdschbDlHzwCVolQC9imeU,14117
|
|
12
12
|
nettracer3d/node_draw.py,sha256=kZcR1PekLg0riioNeGcALIXQyZ5PtHA_9MT6z7Zovdk,10401
|
|
@@ -17,9 +17,9 @@ nettracer3d/segmenter.py,sha256=aOO3PwZ2UeizEIFX7N8midwzTzbEDzgM2jQ7WTdbrUg,7067
|
|
|
17
17
|
nettracer3d/segmenter_GPU.py,sha256=OUekQljLKPiC4d4hNZmqrRa9HSVQ6HcCnILiAfHE5Hg,78051
|
|
18
18
|
nettracer3d/simple_network.py,sha256=dkG4jpc4zzdeuoaQobgGfL3PNo6N8dGKQ5hEEubFIvA,9947
|
|
19
19
|
nettracer3d/smart_dilate.py,sha256=TvRUh6B4q4zIdCO1BWH-xgTdND5OUNmo99eyxG9oIAU,27145
|
|
20
|
-
nettracer3d-1.0.
|
|
21
|
-
nettracer3d-1.0.
|
|
22
|
-
nettracer3d-1.0.
|
|
23
|
-
nettracer3d-1.0.
|
|
24
|
-
nettracer3d-1.0.
|
|
25
|
-
nettracer3d-1.0.
|
|
20
|
+
nettracer3d-1.0.6.dist-info/licenses/LICENSE,sha256=jnNT-yBeIAKAHpYthPvLeqCzJ6nSurgnKmloVnfsjCI,764
|
|
21
|
+
nettracer3d-1.0.6.dist-info/METADATA,sha256=euIZXznP4dHg1VtnfCPyP2c7qK9xC1ovv8OfIUNSXRY,6984
|
|
22
|
+
nettracer3d-1.0.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
23
|
+
nettracer3d-1.0.6.dist-info/entry_points.txt,sha256=Nx1rr_0QhJXDBHAQg2vcqCzLMKBzSHfwy3xwGkueVyc,53
|
|
24
|
+
nettracer3d-1.0.6.dist-info/top_level.txt,sha256=zsYy9rZwirfCEOubolhee4TyzqBAL5gSUeFMzhFTX8c,12
|
|
25
|
+
nettracer3d-1.0.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|