nettracer3d 0.9.6__py3-none-any.whl → 0.9.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.
Potentially problematic release.
This version of nettracer3d might be problematic. Click here for more details.
- nettracer3d/nettracer_gui.py +1 -1
- nettracer3d/segmenter.py +12 -121
- nettracer3d/segmenter_GPU.py +12 -9
- {nettracer3d-0.9.6.dist-info → nettracer3d-0.9.7.dist-info}/METADATA +4 -7
- {nettracer3d-0.9.6.dist-info → nettracer3d-0.9.7.dist-info}/RECORD +9 -9
- {nettracer3d-0.9.6.dist-info → nettracer3d-0.9.7.dist-info}/WHEEL +0 -0
- {nettracer3d-0.9.6.dist-info → nettracer3d-0.9.7.dist-info}/entry_points.txt +0 -0
- {nettracer3d-0.9.6.dist-info → nettracer3d-0.9.7.dist-info}/licenses/LICENSE +0 -0
- {nettracer3d-0.9.6.dist-info → nettracer3d-0.9.7.dist-info}/top_level.txt +0 -0
nettracer3d/nettracer_gui.py
CHANGED
|
@@ -109,7 +109,7 @@ class ImageViewerWindow(QMainWindow):
|
|
|
109
109
|
self.color_dictionary['LIGHT_RED'], # Lighter red
|
|
110
110
|
self.color_dictionary['LIGHT_GREEN'], # Lighter green
|
|
111
111
|
self.color_dictionary['WHITE'], # White
|
|
112
|
-
self.color_dictionary['
|
|
112
|
+
self.color_dictionary['CYAN'] # Now cyan
|
|
113
113
|
]
|
|
114
114
|
|
|
115
115
|
|
nettracer3d/segmenter.py
CHANGED
|
@@ -192,10 +192,10 @@ class InteractiveSegmenter:
|
|
|
192
192
|
if image_2d is None:
|
|
193
193
|
image_2d = self.image_3d[z, :, :]
|
|
194
194
|
|
|
195
|
-
if image_2d.ndim == 3 and image_2d.shape[-1] == 3:
|
|
195
|
+
if image_2d.ndim == 3 and (image_2d.shape[-1] == 3 or image_2d.shape[-1] == 4):
|
|
196
196
|
# RGB case - process each channel
|
|
197
197
|
features_per_channel = []
|
|
198
|
-
for channel in range(
|
|
198
|
+
for channel in range(image_2d.shape[-1]):
|
|
199
199
|
channel_features = self.compute_deep_feature_maps_cpu_2d(image_2d = image_2d[..., channel])
|
|
200
200
|
features_per_channel.append(channel_features)
|
|
201
201
|
|
|
@@ -308,10 +308,10 @@ class InteractiveSegmenter:
|
|
|
308
308
|
if image_2d is None:
|
|
309
309
|
image_2d = self.image_3d[z, :, :]
|
|
310
310
|
|
|
311
|
-
if image_2d.ndim == 3 and image_2d.shape[-1] == 3:
|
|
311
|
+
if image_2d.ndim == 3 and (image_2d.shape[-1] == 3 or image_2d.shape[-1] == 4):
|
|
312
312
|
# RGB case - process each channel
|
|
313
313
|
features_per_channel = []
|
|
314
|
-
for channel in range(
|
|
314
|
+
for channel in range(image_2d.shape[-1]):
|
|
315
315
|
channel_features = self.compute_feature_maps_cpu_2d(image_2d = image_2d[..., channel])
|
|
316
316
|
features_per_channel.append(channel_features)
|
|
317
317
|
|
|
@@ -361,10 +361,10 @@ class InteractiveSegmenter:
|
|
|
361
361
|
if image_3d is None:
|
|
362
362
|
image_3d = self.image_3d
|
|
363
363
|
|
|
364
|
-
if image_3d.ndim == 4 and image_3d.shape[-1] == 3:
|
|
364
|
+
if image_3d.ndim == 4 and (image_3d.shape[-1] == 3 or image_3d.shape[-1] == 4):
|
|
365
365
|
# RGB case - process each channel
|
|
366
366
|
features_per_channel = []
|
|
367
|
-
for channel in range(
|
|
367
|
+
for channel in range(image_3d.shape[-1]):
|
|
368
368
|
channel_features = self.compute_deep_feature_maps_cpu(image_3d[..., channel])
|
|
369
369
|
features_per_channel.append(channel_features)
|
|
370
370
|
|
|
@@ -483,127 +483,15 @@ class InteractiveSegmenter:
|
|
|
483
483
|
|
|
484
484
|
return features
|
|
485
485
|
|
|
486
|
-
def compute_deep_feature_maps_cpu_smaller(self, image_3d=None): #smaller
|
|
487
|
-
"""Optimized version using determinant instead of full eigenvalue computation. Currently not in use anywhere"""
|
|
488
|
-
if image_3d is None:
|
|
489
|
-
image_3d = self.image_3d
|
|
490
|
-
|
|
491
|
-
# Calculate total number of features (using determinant instead of 3 eigenvalues)
|
|
492
|
-
num_basic_features = 1 + len(self.sigmas) + len(self.dogs)
|
|
493
|
-
num_gradient_features = len(self.sigmas)
|
|
494
|
-
num_laplacian_features = len(self.sigmas)
|
|
495
|
-
num_hessian_features = len(self.sigmas) * 3 # determinant + trace + frobenius norm
|
|
496
|
-
|
|
497
|
-
total_features = num_basic_features + num_gradient_features + num_laplacian_features + num_hessian_features
|
|
498
|
-
|
|
499
|
-
# Pre-allocate result array
|
|
500
|
-
features = np.empty(image_3d.shape + (total_features,), dtype=image_3d.dtype)
|
|
501
|
-
features[..., 0] = image_3d
|
|
502
|
-
|
|
503
|
-
feature_idx = 1
|
|
504
|
-
|
|
505
|
-
# Cache for Gaussian filters
|
|
506
|
-
gaussian_cache = {}
|
|
507
|
-
all_sigmas = set(self.sigmas)
|
|
508
|
-
for s1, s2 in self.dogs:
|
|
509
|
-
all_sigmas.add(s1)
|
|
510
|
-
all_sigmas.add(s2)
|
|
511
|
-
|
|
512
|
-
# Pre-compute all Gaussian filters
|
|
513
|
-
for sigma in all_sigmas:
|
|
514
|
-
gaussian_cache[sigma] = ndimage.gaussian_filter(image_3d, sigma)
|
|
515
|
-
|
|
516
|
-
# Gaussian smoothing
|
|
517
|
-
for sigma in self.sigmas:
|
|
518
|
-
features[..., feature_idx] = gaussian_cache[sigma]
|
|
519
|
-
feature_idx += 1
|
|
520
|
-
|
|
521
|
-
# Difference of Gaussians
|
|
522
|
-
for s1, s2 in self.dogs:
|
|
523
|
-
features[..., feature_idx] = gaussian_cache[s1] - gaussian_cache[s2]
|
|
524
|
-
feature_idx += 1
|
|
525
|
-
|
|
526
|
-
# Gaussian gradient magnitudes
|
|
527
|
-
for sigma in self.sigmas:
|
|
528
|
-
gaussian_img = gaussian_cache[sigma]
|
|
529
|
-
gx = ndimage.sobel(gaussian_img, axis=2, mode='reflect')
|
|
530
|
-
gy = ndimage.sobel(gaussian_img, axis=1, mode='reflect')
|
|
531
|
-
gz = ndimage.sobel(gaussian_img, axis=0, mode='reflect')
|
|
532
|
-
features[..., feature_idx] = np.sqrt(gx**2 + gy**2 + gz**2)
|
|
533
|
-
feature_idx += 1
|
|
534
|
-
|
|
535
|
-
# Laplacian of Gaussian
|
|
536
|
-
for sigma in self.sigmas:
|
|
537
|
-
gaussian_img = gaussian_cache[sigma]
|
|
538
|
-
features[..., feature_idx] = ndimage.laplace(gaussian_img, mode='reflect')
|
|
539
|
-
feature_idx += 1
|
|
540
|
-
|
|
541
|
-
# Hessian-based features (much faster than full eigenvalue computation)
|
|
542
|
-
for sigma in self.sigmas:
|
|
543
|
-
gaussian_img = gaussian_cache[sigma]
|
|
544
|
-
|
|
545
|
-
# Compute second derivatives
|
|
546
|
-
hxx = ndimage.gaussian_filter(gaussian_img, sigma=0, order=[0, 0, 2], mode='reflect')
|
|
547
|
-
hyy = ndimage.gaussian_filter(gaussian_img, sigma=0, order=[0, 2, 0], mode='reflect')
|
|
548
|
-
hzz = ndimage.gaussian_filter(gaussian_img, sigma=0, order=[2, 0, 0], mode='reflect')
|
|
549
|
-
hxy = ndimage.gaussian_filter(gaussian_img, sigma=0, order=[0, 1, 1], mode='reflect')
|
|
550
|
-
hxz = ndimage.gaussian_filter(gaussian_img, sigma=0, order=[1, 0, 1], mode='reflect')
|
|
551
|
-
hyz = ndimage.gaussian_filter(gaussian_img, sigma=0, order=[1, 1, 0], mode='reflect')
|
|
552
|
-
|
|
553
|
-
# Hessian determinant (captures overall curvature)
|
|
554
|
-
determinant = (hxx * (hyy * hzz - hyz**2) -
|
|
555
|
-
hxy * (hxy * hzz - hxz * hyz) +
|
|
556
|
-
hxz * (hxy * hyz - hyy * hxz))
|
|
557
|
-
features[..., feature_idx] = determinant
|
|
558
|
-
feature_idx += 1
|
|
559
|
-
|
|
560
|
-
# Hessian trace (sum of eigenvalues)
|
|
561
|
-
trace = hxx + hyy + hzz
|
|
562
|
-
features[..., feature_idx] = trace
|
|
563
|
-
feature_idx += 1
|
|
564
|
-
|
|
565
|
-
# Frobenius norm (overall curvature magnitude)
|
|
566
|
-
frobenius_norm = np.sqrt(hxx**2 + hyy**2 + hzz**2 + 2*(hxy**2 + hxz**2 + hyz**2))
|
|
567
|
-
features[..., feature_idx] = frobenius_norm
|
|
568
|
-
feature_idx += 1
|
|
569
|
-
|
|
570
|
-
"""
|
|
571
|
-
# Normalize features: zero-mean, unit variance per feature band
|
|
572
|
-
# Compute mean and std across spatial dimensions (0,1,2), keeping feature dimension
|
|
573
|
-
feature_means = np.mean(features, axis=(0, 1, 2), keepdims=True)
|
|
574
|
-
feature_stds = np.std(features, axis=(0, 1, 2), keepdims=True)
|
|
575
|
-
|
|
576
|
-
# Avoid division by zero for constant features
|
|
577
|
-
feature_stds = np.where(feature_stds == 0, 1, feature_stds)
|
|
578
|
-
|
|
579
|
-
# Normalize in-place for memory efficiency
|
|
580
|
-
features = (features - feature_means) / feature_stds
|
|
581
|
-
"""
|
|
582
|
-
# Normalize only morphological features, keep intensity features raw
|
|
583
|
-
intensity_features = features[..., :num_basic_features] # original + gaussians + DoGs
|
|
584
|
-
morphology_features = features[..., num_basic_features:] # gradients + laplacians + eigenvalues
|
|
585
|
-
|
|
586
|
-
# Normalize only morphological features
|
|
587
|
-
morph_means = np.mean(morphology_features, axis=(0,1,2), keepdims=True)
|
|
588
|
-
morph_stds = np.std(morphology_features, axis=(0,1,2), keepdims=True)
|
|
589
|
-
morph_stds = np.where(morph_stds == 0, 1, morph_stds)
|
|
590
|
-
morphology_features = (morphology_features - morph_means) / morph_stds
|
|
591
|
-
|
|
592
|
-
# Recombine
|
|
593
|
-
features = np.concatenate([intensity_features, morphology_features], axis=-1)
|
|
594
|
-
|
|
595
|
-
return features
|
|
596
|
-
|
|
597
|
-
|
|
598
486
|
def compute_feature_maps_cpu(self, image_3d=None): #lil
|
|
599
487
|
"""Optimized version that caches Gaussian filters to avoid redundant computation"""
|
|
600
488
|
if image_3d is None:
|
|
601
489
|
image_3d = self.image_3d
|
|
602
490
|
|
|
603
|
-
if image_3d.ndim == 4 and image_3d.shape[-1] == 3:
|
|
491
|
+
if image_3d.ndim == 4 and (image_3d.shape[-1] == 3 or image_3d.shape[-1] == 4):
|
|
604
492
|
# RGB case - process each channel
|
|
605
493
|
features_per_channel = []
|
|
606
|
-
for channel in range(
|
|
494
|
+
for channel in range(image_3d.shape[-1]):
|
|
607
495
|
channel_features = self.compute_feature_maps_cpu(image_3d[..., channel])
|
|
608
496
|
features_per_channel.append(channel_features)
|
|
609
497
|
|
|
@@ -1420,7 +1308,10 @@ class InteractiveSegmenter:
|
|
|
1420
1308
|
chunk_size = max(16, min(chunk_size, min(self.image_3d.shape) // 2))
|
|
1421
1309
|
chunk_size = ((chunk_size + 7) // 16) * 16
|
|
1422
1310
|
|
|
1423
|
-
|
|
1311
|
+
try:
|
|
1312
|
+
depth, height, width = self.image_3d.shape
|
|
1313
|
+
except:
|
|
1314
|
+
depth, height, width, rgb = self.image_3d.shape
|
|
1424
1315
|
|
|
1425
1316
|
# Calculate chunk grid dimensions
|
|
1426
1317
|
z_chunks = (depth + chunk_size - 1) // chunk_size
|
nettracer3d/segmenter_GPU.py
CHANGED
|
@@ -320,10 +320,10 @@ class InteractiveSegmenter:
|
|
|
320
320
|
if image_3d is None:
|
|
321
321
|
image_3d = self.image_3d # Assuming this is already a cupy array
|
|
322
322
|
|
|
323
|
-
if image_3d.ndim == 4 and image_3d.shape[-1] == 3:
|
|
323
|
+
if image_3d.ndim == 4 and (image_3d.shape[-1] == 3 or image_3d.shape[-1] == 4):
|
|
324
324
|
# RGB case - process each channel
|
|
325
325
|
features_per_channel = []
|
|
326
|
-
for channel in range(
|
|
326
|
+
for channel in range(image_3d.shape[-1]):
|
|
327
327
|
channel_features = self.compute_feature_maps_gpu(image_3d[..., channel])
|
|
328
328
|
features_per_channel.append(channel_features)
|
|
329
329
|
|
|
@@ -376,10 +376,10 @@ class InteractiveSegmenter:
|
|
|
376
376
|
if image_3d is None:
|
|
377
377
|
image_3d = self.image_3d # Assuming this is already a cupy array
|
|
378
378
|
|
|
379
|
-
if image_3d.ndim == 4 and image_3d.shape[-1] == 3:
|
|
379
|
+
if image_3d.ndim == 4 and (image_3d.shape[-1] == 3 or image_3d.shape[-1] == 4):
|
|
380
380
|
# RGB case - process each channel
|
|
381
381
|
features_per_channel = []
|
|
382
|
-
for channel in range(
|
|
382
|
+
for channel in range(image_3d.shape[-1]):
|
|
383
383
|
channel_features = self.compute_deep_feature_maps_gpu(image_3d[..., channel])
|
|
384
384
|
features_per_channel.append(channel_features)
|
|
385
385
|
|
|
@@ -507,10 +507,10 @@ class InteractiveSegmenter:
|
|
|
507
507
|
if image_2d is None:
|
|
508
508
|
image_2d = cp.asarray(self.image_3d[z, :, :])
|
|
509
509
|
|
|
510
|
-
if image_2d.ndim == 3 and image_2d.shape[-1] == 3:
|
|
510
|
+
if image_2d.ndim == 3 and (image_2d.shape[-1] == 3 or image_2d.shape[-1] == 4):
|
|
511
511
|
# RGB case - process each channel
|
|
512
512
|
features_per_channel = []
|
|
513
|
-
for channel in range(
|
|
513
|
+
for channel in range(image_2d.shape[-1]):
|
|
514
514
|
channel_features = self.compute_feature_maps_gpu_2d(image_2d = image_2d[..., channel])
|
|
515
515
|
features_per_channel.append(channel_features)
|
|
516
516
|
|
|
@@ -567,10 +567,10 @@ class InteractiveSegmenter:
|
|
|
567
567
|
if image_2d is None:
|
|
568
568
|
image_2d = cp.asarray(self.image_3d[z, :, :])
|
|
569
569
|
|
|
570
|
-
if image_2d.ndim == 3 and image_2d.shape[-1] == 3:
|
|
570
|
+
if image_2d.ndim == 3 and (image_2d.shape[-1] == 3 or image_2d.shape[-1] == 4):
|
|
571
571
|
# RGB case - process each channel
|
|
572
572
|
features_per_channel = []
|
|
573
|
-
for channel in range(
|
|
573
|
+
for channel in range(image_2d.shape[-1]):
|
|
574
574
|
channel_features = self.compute_deep_feature_maps_gpu_2d(image_2d = image_2d[..., channel])
|
|
575
575
|
features_per_channel.append(channel_features)
|
|
576
576
|
|
|
@@ -1082,7 +1082,10 @@ class InteractiveSegmenter:
|
|
|
1082
1082
|
chunk_size = max(16, min(chunk_size, min(self.image_3d.shape) // 2))
|
|
1083
1083
|
chunk_size = ((chunk_size + 7) // 16) * 16
|
|
1084
1084
|
|
|
1085
|
-
|
|
1085
|
+
try:
|
|
1086
|
+
depth, height, width = self.image_3d.shape
|
|
1087
|
+
except:
|
|
1088
|
+
depth, height, width, rgb = self.image_3d.shape
|
|
1086
1089
|
|
|
1087
1090
|
# Calculate chunk grid dimensions
|
|
1088
1091
|
z_chunks = (depth + chunk_size - 1) // chunk_size
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nettracer3d
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.7
|
|
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,10 +110,7 @@ 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 0.9.
|
|
113
|
+
-- Version 0.9.7 Updates --
|
|
114
114
|
|
|
115
|
-
*
|
|
116
|
-
* The
|
|
117
|
-
* Bug Fixes
|
|
118
|
-
* The 'merge nodes' option now can provide centroids prior to the merge, since oftentimes objects end up on top of each other.
|
|
119
|
-
* A few other minor adjustments.
|
|
115
|
+
* Fixed a bug with the segmenter and color images.
|
|
116
|
+
* The overlay 2 is now cyan by default.
|
|
@@ -6,20 +6,20 @@ nettracer3d/modularity.py,sha256=pborVcDBvICB2-g8lNoSVZbIReIBlfeBmjFbPYmtq7Y,224
|
|
|
6
6
|
nettracer3d/morphology.py,sha256=jyDjYzrZ4LvI5jOyw8DLsxmo-i5lpqHsejYpW7Tq7Mo,19786
|
|
7
7
|
nettracer3d/neighborhoods.py,sha256=iIaHU1COIdRtzRpAuIQKfLGLNKYFK3dL8Vb_EeJIlEA,46459
|
|
8
8
|
nettracer3d/nettracer.py,sha256=d9Mhz-pHox5OfGGUSTrkTBJzCWCrbQvClTu2ANt-jUE,267943
|
|
9
|
-
nettracer3d/nettracer_gui.py,sha256=
|
|
9
|
+
nettracer3d/nettracer_gui.py,sha256=VsZep2sgES10ZePVJDoUoFGgsg3wGRW-rAp1NMgQQwQ,628409
|
|
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
|
|
13
13
|
nettracer3d/painting.py,sha256=K_dwngivw80r-Yyg4btKMsWGn566ZE9PnrQl986uxJE,23497
|
|
14
14
|
nettracer3d/proximity.py,sha256=WaHPwE6ypeInFO_LnMT0zaVE53jX3TJx6h7nmtYtr8U,41824
|
|
15
15
|
nettracer3d/run.py,sha256=xYeaAc8FCx8MuzTGyL3NR3mK7WZzffAYAH23bNRZYO4,127
|
|
16
|
-
nettracer3d/segmenter.py,sha256
|
|
17
|
-
nettracer3d/segmenter_GPU.py,sha256=
|
|
16
|
+
nettracer3d/segmenter.py,sha256=aOO3PwZ2UeizEIFX7N8midwzTzbEDzgM2jQ7WTdbrUg,70671
|
|
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-0.9.
|
|
21
|
-
nettracer3d-0.9.
|
|
22
|
-
nettracer3d-0.9.
|
|
23
|
-
nettracer3d-0.9.
|
|
24
|
-
nettracer3d-0.9.
|
|
25
|
-
nettracer3d-0.9.
|
|
20
|
+
nettracer3d-0.9.7.dist-info/licenses/LICENSE,sha256=jnNT-yBeIAKAHpYthPvLeqCzJ6nSurgnKmloVnfsjCI,764
|
|
21
|
+
nettracer3d-0.9.7.dist-info/METADATA,sha256=oJJZS4YPNc21NZd5sFUY6doxe5vpgzZwdEObUGIwswg,7067
|
|
22
|
+
nettracer3d-0.9.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
23
|
+
nettracer3d-0.9.7.dist-info/entry_points.txt,sha256=Nx1rr_0QhJXDBHAQg2vcqCzLMKBzSHfwy3xwGkueVyc,53
|
|
24
|
+
nettracer3d-0.9.7.dist-info/top_level.txt,sha256=zsYy9rZwirfCEOubolhee4TyzqBAL5gSUeFMzhFTX8c,12
|
|
25
|
+
nettracer3d-0.9.7.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|