nettracer3d 0.3.5__py3-none-any.whl → 0.3.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.
- nettracer3d/nettracer.py +88 -174
- nettracer3d/nettracer_gui.py +48 -17
- {nettracer3d-0.3.5.dist-info → nettracer3d-0.3.6.dist-info}/METADATA +2 -2
- {nettracer3d-0.3.5.dist-info → nettracer3d-0.3.6.dist-info}/RECORD +7 -7
- {nettracer3d-0.3.5.dist-info → nettracer3d-0.3.6.dist-info}/LICENSE +0 -0
- {nettracer3d-0.3.5.dist-info → nettracer3d-0.3.6.dist-info}/WHEEL +0 -0
- {nettracer3d-0.3.5.dist-info → nettracer3d-0.3.6.dist-info}/top_level.txt +0 -0
nettracer3d/nettracer.py
CHANGED
|
@@ -10,7 +10,10 @@ import multiprocessing as mp
|
|
|
10
10
|
import os
|
|
11
11
|
import copy
|
|
12
12
|
import statistics as stats
|
|
13
|
-
|
|
13
|
+
try:
|
|
14
|
+
import napari
|
|
15
|
+
except:
|
|
16
|
+
pass
|
|
14
17
|
import networkx as nx
|
|
15
18
|
from scipy.signal import find_peaks
|
|
16
19
|
try:
|
|
@@ -396,7 +399,7 @@ def upsample_with_padding(data, factor=None, original_shape=None):
|
|
|
396
399
|
raise ValueError("original_shape must be provided")
|
|
397
400
|
|
|
398
401
|
# Handle 4D color arrays
|
|
399
|
-
is_color = len(data.shape) == 4 and data.shape[-1] == 3
|
|
402
|
+
is_color = len(data.shape) == 4 and (data.shape[-1] == 3 or data.shape[-1] == 4)
|
|
400
403
|
if is_color:
|
|
401
404
|
# Split into separate color channels
|
|
402
405
|
channels = [data[..., i] for i in range(3)]
|
|
@@ -623,6 +626,65 @@ def threshold(arr, proportion, custom_rad = None):
|
|
|
623
626
|
|
|
624
627
|
return arr
|
|
625
628
|
|
|
629
|
+
def show_3d(arrays_3d=None, arrays_4d=None, down_factor=None, order=0, xy_scale=1, z_scale=1, colors=['red', 'green', 'white', 'cyan', 'yellow']):
|
|
630
|
+
"""
|
|
631
|
+
Show 3d (or 2d) displays of array data using napari.
|
|
632
|
+
Params: arrays - A list of 3d or 2d numpy arrays to display
|
|
633
|
+
down_factor (int) - Optional downsampling factor to speed up display
|
|
634
|
+
"""
|
|
635
|
+
import os
|
|
636
|
+
# Force PyQt6 usage to avoid binding warning
|
|
637
|
+
os.environ['QT_API'] = 'pyqt6'
|
|
638
|
+
|
|
639
|
+
import napari
|
|
640
|
+
from qtpy.QtWidgets import QApplication
|
|
641
|
+
|
|
642
|
+
if down_factor is not None:
|
|
643
|
+
# Downsample arrays if specified
|
|
644
|
+
arrays_3d = [downsample(array, down_factor, order=order) for array in arrays_3d] if arrays_3d is not None else None
|
|
645
|
+
arrays_4d = [downsample(array, down_factor, order=order) for array in arrays_4d] if arrays_4d is not None else None
|
|
646
|
+
|
|
647
|
+
viewer = napari.Viewer(ndisplay=3)
|
|
648
|
+
scale = [z_scale, xy_scale, xy_scale] # [z, y, x] order for napari
|
|
649
|
+
|
|
650
|
+
# Add 3D arrays if provided
|
|
651
|
+
if arrays_3d is not None:
|
|
652
|
+
for arr, color in zip(arrays_3d, colors):
|
|
653
|
+
viewer.add_image(
|
|
654
|
+
arr,
|
|
655
|
+
scale=scale,
|
|
656
|
+
colormap=color,
|
|
657
|
+
rendering='mip',
|
|
658
|
+
blending='additive',
|
|
659
|
+
opacity=0.5,
|
|
660
|
+
name=f'Channel_{color}'
|
|
661
|
+
)
|
|
662
|
+
|
|
663
|
+
if arrays_4d is not None:
|
|
664
|
+
for i, arr in enumerate(arrays_4d):
|
|
665
|
+
# Check if the last dimension is 3 (RGB) or 4 (RGBA)
|
|
666
|
+
if arr.shape[-1] not in [3, 4]:
|
|
667
|
+
print(f"Warning: Array {i} doesn't appear to be RGB/RGBA. Skipping.")
|
|
668
|
+
continue
|
|
669
|
+
|
|
670
|
+
if arr.shape[3] == 4:
|
|
671
|
+
arr = arr[:, :, :, :3] # Remove alpha
|
|
672
|
+
|
|
673
|
+
# Add each color channel separately
|
|
674
|
+
colors = ['red', 'green', 'blue']
|
|
675
|
+
for c in range(3):
|
|
676
|
+
viewer.add_image(
|
|
677
|
+
arr[:,:,:,c], # Take just one color channel
|
|
678
|
+
scale=scale,
|
|
679
|
+
colormap=colors[c], # Use corresponding color
|
|
680
|
+
rendering='mip',
|
|
681
|
+
blending='additive',
|
|
682
|
+
opacity=0.5,
|
|
683
|
+
name=f'Channel_{colors[c]}_{i}'
|
|
684
|
+
)
|
|
685
|
+
|
|
686
|
+
napari.run()
|
|
687
|
+
|
|
626
688
|
def z_project(array3d, method='max'):
|
|
627
689
|
"""
|
|
628
690
|
Project a 3D numpy array along the Z axis to create a 2D array.
|
|
@@ -733,6 +795,18 @@ def fill_holes_3d(array):
|
|
|
733
795
|
def resize(array, factor, order = 0):
|
|
734
796
|
"""Simply resizes an array by a factor"""
|
|
735
797
|
|
|
798
|
+
if len(array.shape) == 4: # presumably this is a color image
|
|
799
|
+
processed_arrays = []
|
|
800
|
+
for i in range(array.shape[3]): # iterate through the color dimension
|
|
801
|
+
color_array = array[:, :, :, i] # get 3D array for each color channel
|
|
802
|
+
processed_color = zoom(color_array, (factor), order = order)
|
|
803
|
+
|
|
804
|
+
processed_arrays.append(processed_color)
|
|
805
|
+
|
|
806
|
+
# Stack them back together along the 4th dimension
|
|
807
|
+
result = np.stack(processed_arrays, axis=3)
|
|
808
|
+
return result
|
|
809
|
+
|
|
736
810
|
array = zoom(array, (factor), order = order)
|
|
737
811
|
|
|
738
812
|
return array
|
|
@@ -748,103 +822,6 @@ def _rescale(array, original_shape, xy_scale, z_scale):
|
|
|
748
822
|
array = zoom(array, (1, z_scale/xy_scale, z_scale/xy_scale))
|
|
749
823
|
return array
|
|
750
824
|
|
|
751
|
-
def visualize_3D(array, other_arrays=None, xy_scale = 1, z_scale = 1):
|
|
752
|
-
"""
|
|
753
|
-
Mostly internal method for 3D visualization, although can be run directly on tif files to view them. Uses plotly to visualize
|
|
754
|
-
a 3D, binarized isosurface of data. Note this method likely requires downsampling on objects before running.
|
|
755
|
-
:param array: (Mandatory; string or ndarray) - Either a path to a .tif file to visualize in 3D binary, or a ndarray of the same.
|
|
756
|
-
:param other_arrays: (Optional - Val = None; string, ndarray, or list) - Either a path to a an additional .tif file to visualize in 3D binary or an ndarray containing the same,
|
|
757
|
-
or otherwise a path to a directory containing ONLY other .tif files to visualize, or a list of ndarrays containing the same.
|
|
758
|
-
:param xy_scale: (Optional - Val = 1; float) - The xy pixel scaling of an image to visualize.
|
|
759
|
-
:param z_scale: (Optional - Val = 1; float) - The z voxel depth of an image to visualize.
|
|
760
|
-
"""
|
|
761
|
-
|
|
762
|
-
if isinstance(array, str):
|
|
763
|
-
array = tifffile.imread(array)
|
|
764
|
-
|
|
765
|
-
original_shape = array.shape[1]
|
|
766
|
-
|
|
767
|
-
array = _rescale(array, original_shape, xy_scale, z_scale)
|
|
768
|
-
array = binarize(array)
|
|
769
|
-
|
|
770
|
-
# Create a meshgrid for coordinates
|
|
771
|
-
x, y, z = np.indices(array.shape)
|
|
772
|
-
|
|
773
|
-
# Create a figure
|
|
774
|
-
fig = go.Figure()
|
|
775
|
-
|
|
776
|
-
# Plot the main array
|
|
777
|
-
_plot_3D(fig, x, y, z, array, 'red')
|
|
778
|
-
|
|
779
|
-
if other_arrays is not None and ((type(other_arrays) == str) or (type(other_arrays) == list)):
|
|
780
|
-
try: #Presume single tif
|
|
781
|
-
array = tifffile.imread(other_arrays)
|
|
782
|
-
if array.shape[1] != original_shape:
|
|
783
|
-
array = downsample(array, array.shape[1]/original_shape)
|
|
784
|
-
array = _rescale(array, original_shape, xy_scale, z_scale)
|
|
785
|
-
array = binarize(array)
|
|
786
|
-
_plot_3D(fig, x, y, z, array, 'green')
|
|
787
|
-
except: #presume directory or list
|
|
788
|
-
basic_colors = ['blue', 'yellow', 'cyan', 'magenta', 'black', 'white', 'gray', 'orange', 'brown', 'pink', 'purple', 'lime', 'teal', 'navy', 'maroon', 'olive', 'silver', 'red', 'green']
|
|
789
|
-
try: #presume directory
|
|
790
|
-
arrays = directory_info(other_arrays)
|
|
791
|
-
directory = other_arrays
|
|
792
|
-
except: #presume list
|
|
793
|
-
arrays = other_arrays
|
|
794
|
-
for i, array_path in enumerate(arrays):
|
|
795
|
-
try: #presume tif
|
|
796
|
-
array = tifffile.imread(f"{directory}/{array_path}")
|
|
797
|
-
if array.shape[1] != original_shape:
|
|
798
|
-
array = downsample(array, array.shape[1]/original_shape)
|
|
799
|
-
array = _rescale(array, original_shape, xy_scale, z_scale)
|
|
800
|
-
array = binarize(array)
|
|
801
|
-
except: #presume array
|
|
802
|
-
array = array_path
|
|
803
|
-
del array_path
|
|
804
|
-
if array is not None:
|
|
805
|
-
if array.shape[1] != original_shape:
|
|
806
|
-
array = downsample(array, array.shape[1]/original_shape)
|
|
807
|
-
array = _rescale(array, original_shape, xy_scale, z_scale)
|
|
808
|
-
array = binarize(array)
|
|
809
|
-
color = basic_colors[i % len(basic_colors)] # Ensure color index wraps around if more arrays than colors
|
|
810
|
-
if array is not None:
|
|
811
|
-
_plot_3D(fig, x, y, z, array, color)
|
|
812
|
-
else:
|
|
813
|
-
try:
|
|
814
|
-
other_arrays = _rescale(other_arrays, original_shape, xy_scale, z_scale)
|
|
815
|
-
other_arrays = binarize(other_arrays)
|
|
816
|
-
_plot_3D(fig, x, y, z, other_arrays, 'green')
|
|
817
|
-
except:
|
|
818
|
-
pass
|
|
819
|
-
|
|
820
|
-
# Set the layout for better visualization
|
|
821
|
-
fig.update_layout(scene=dict(
|
|
822
|
-
xaxis_title='Z Axis',
|
|
823
|
-
yaxis_title='Y Axis',
|
|
824
|
-
zaxis_title='X Axis'
|
|
825
|
-
))
|
|
826
|
-
|
|
827
|
-
fig.show()
|
|
828
|
-
|
|
829
|
-
def _plot_3D(fig, x, y, z, array, color):
|
|
830
|
-
"""Internal method used for 3D visualization"""
|
|
831
|
-
# Define the isosurface level
|
|
832
|
-
level = 0.5
|
|
833
|
-
|
|
834
|
-
# Add the isosurface to the figure
|
|
835
|
-
fig.add_trace(go.Isosurface(
|
|
836
|
-
x=x.flatten(),
|
|
837
|
-
y=y.flatten(),
|
|
838
|
-
z=z.flatten(),
|
|
839
|
-
value=array.flatten(),
|
|
840
|
-
isomin=level,
|
|
841
|
-
isomax=level,
|
|
842
|
-
opacity=0.6, # Adjust opacity
|
|
843
|
-
surface_count=1, # Show only the isosurface
|
|
844
|
-
colorscale=[[0, color], [1, color]], # Set uniform color
|
|
845
|
-
showscale=False # Hide color scale bar
|
|
846
|
-
))
|
|
847
|
-
|
|
848
825
|
|
|
849
826
|
def remove_trunk(edges):
|
|
850
827
|
"""
|
|
@@ -1380,6 +1357,17 @@ def downsample(data, factor, directory=None, order=0):
|
|
|
1380
1357
|
data = tifffile.imread(data)
|
|
1381
1358
|
else:
|
|
1382
1359
|
data2 = None
|
|
1360
|
+
|
|
1361
|
+
if len(data.shape) == 4: # presumably this is a color image
|
|
1362
|
+
processed_arrays = []
|
|
1363
|
+
for i in range(data.shape[3]): # iterate through the color dimension
|
|
1364
|
+
color_array = data[:, :, :, i] # get 3D array for each color channel
|
|
1365
|
+
processed_color = downsample(color_array, factor, directory = None, order = order) #right now this is only for internal use - color array downsampling that is
|
|
1366
|
+
processed_arrays.append(processed_color)
|
|
1367
|
+
|
|
1368
|
+
# Stack them back together along the 4th dimension
|
|
1369
|
+
result = np.stack(processed_arrays, axis=3)
|
|
1370
|
+
return result
|
|
1383
1371
|
|
|
1384
1372
|
# Check if Z dimension is too small relative to downsample factor
|
|
1385
1373
|
if data.ndim == 3 and data.shape[0] < factor * 4:
|
|
@@ -1389,6 +1377,7 @@ def downsample(data, factor, directory=None, order=0):
|
|
|
1389
1377
|
else:
|
|
1390
1378
|
zoom_factors = 1/factor
|
|
1391
1379
|
|
|
1380
|
+
|
|
1392
1381
|
# Apply downsampling
|
|
1393
1382
|
data = zoom(data, zoom_factors, order=order)
|
|
1394
1383
|
|
|
@@ -3741,81 +3730,6 @@ class Network_3D:
|
|
|
3741
3730
|
|
|
3742
3731
|
|
|
3743
3732
|
|
|
3744
|
-
#Methods relating to visualizing elements of the network in 3D
|
|
3745
|
-
|
|
3746
|
-
def show_3D(self, other_arrays = None, down_factor = 1):
|
|
3747
|
-
"""
|
|
3748
|
-
Allows the Network_3D object to be visualized in 3D using plotly. By default, this will show the nodes and edges properties. All arrays involved will be made binary.
|
|
3749
|
-
Note that nettracer_3D is not primarily a 3D visualization tool, so the funcionality of this method is limited, and additionally it should really only be run on downsampled data.
|
|
3750
|
-
:param other_arrays: (Optional - Val = None; string). A filepath to additional .tif files (or a directory containing only .tif files) to show alongside the Network_3D object, for example a node_indicies or network_lattice overlay.
|
|
3751
|
-
:param down_factor: (Optional - Val = 1; int). A downsampling factor to speed up showing the 3D display and improve processing. Note that ALL arrays being shown will be subject
|
|
3752
|
-
to this downsample factor. If you have files to be shown alongside the Network_3D object that were ALREADY downsampled, instead downsample the Network_3D object FIRST and pass nothing to this value.
|
|
3753
|
-
If arrays are sized to different shapes while show_3D() is being called, there may be unusual results.
|
|
3754
|
-
"""
|
|
3755
|
-
if down_factor > 1:
|
|
3756
|
-
xy_scale = down_factor * self._xy_scale
|
|
3757
|
-
z_scale = down_factor * self._z_scale
|
|
3758
|
-
try:
|
|
3759
|
-
nodes = downsample(self._nodes, down_factor, order = 3)
|
|
3760
|
-
nodes = binarize(nodes)
|
|
3761
|
-
except:
|
|
3762
|
-
pass
|
|
3763
|
-
try:
|
|
3764
|
-
edges = downsample(self._edges, down_factor, order = 3)
|
|
3765
|
-
edges = binarize(edges)
|
|
3766
|
-
except:
|
|
3767
|
-
edges = None
|
|
3768
|
-
try:
|
|
3769
|
-
if not isinstance(other_arrays, np.ndarray):
|
|
3770
|
-
other_arrays = tifffile.imread(other_arrays)
|
|
3771
|
-
if other_arrays.shape == self._nodes.shape:
|
|
3772
|
-
other_arrays = downsample(other_arrays, down_factor, order = 3)
|
|
3773
|
-
other_arrays = binarize(other_arrays)
|
|
3774
|
-
other_arrays = [edges, other_arrays]
|
|
3775
|
-
except:
|
|
3776
|
-
try:
|
|
3777
|
-
arrays = directory_info(other_arrays)
|
|
3778
|
-
directory = other_arrays
|
|
3779
|
-
other_arrays = []
|
|
3780
|
-
for array in arrays:
|
|
3781
|
-
array = tifffile.imread(f'{directory}/{array}')
|
|
3782
|
-
if array.shape == self._nodes.shape:
|
|
3783
|
-
array = downsample(array, down_factor, order = 3)
|
|
3784
|
-
array = binarize(array)
|
|
3785
|
-
other_arrays.append(array)
|
|
3786
|
-
other_arrays.insert(0, edges)
|
|
3787
|
-
except:
|
|
3788
|
-
other_arrays = edges
|
|
3789
|
-
visualize_3D(nodes, other_arrays, xy_scale = xy_scale, z_scale = z_scale)
|
|
3790
|
-
else:
|
|
3791
|
-
try:
|
|
3792
|
-
nodes = binarize(self._nodes)
|
|
3793
|
-
except:
|
|
3794
|
-
pass
|
|
3795
|
-
try:
|
|
3796
|
-
edges = binarize(self._edges)
|
|
3797
|
-
except:
|
|
3798
|
-
edges = None
|
|
3799
|
-
try:
|
|
3800
|
-
if not isinstance(other_arrays, np.ndarray):
|
|
3801
|
-
other_arrays = tifffile.imread(other_arrays)
|
|
3802
|
-
other_arrays = binarize(other_arrays)
|
|
3803
|
-
other_arrays = [edges, other_arrays]
|
|
3804
|
-
except:
|
|
3805
|
-
try:
|
|
3806
|
-
arrays = directory_info(other_arrays)
|
|
3807
|
-
directory = other_arrays
|
|
3808
|
-
other_arrays = []
|
|
3809
|
-
for array in arrays:
|
|
3810
|
-
array = tifffile.imread(f'{directory}/{array}')
|
|
3811
|
-
array = binarize(array)
|
|
3812
|
-
other_arrays.append(array)
|
|
3813
|
-
other_arrays.insert(0, self._edges)
|
|
3814
|
-
except:
|
|
3815
|
-
other_arrays = edges
|
|
3816
|
-
|
|
3817
|
-
visualize_3D(nodes, other_arrays, xy_scale = self._xy_scale, z_scale = self._z_scale)
|
|
3818
|
-
|
|
3819
3733
|
def get_degrees(self, down_factor = 1, directory = None, called = False, no_img = 0):
|
|
3820
3734
|
"""
|
|
3821
3735
|
Method to obtain information on the degrees of nodes in the network, also generating overlays that relate this information to the 3D structure.
|
nettracer3d/nettracer_gui.py
CHANGED
|
@@ -1880,7 +1880,7 @@ class ImageViewerWindow(QMainWindow):
|
|
|
1880
1880
|
searchoverlay_action.triggered.connect(self.show_search_dialog)
|
|
1881
1881
|
shuffle_action = overlay_menu.addAction("Shuffle")
|
|
1882
1882
|
shuffle_action.triggered.connect(self.show_shuffle_dialog)
|
|
1883
|
-
show3d_action = image_menu.addAction("Show 3D (
|
|
1883
|
+
show3d_action = image_menu.addAction("Show 3D (Napari)")
|
|
1884
1884
|
show3d_action.triggered.connect(self.show3d_dialog)
|
|
1885
1885
|
|
|
1886
1886
|
|
|
@@ -2339,7 +2339,9 @@ class ImageViewerWindow(QMainWindow):
|
|
|
2339
2339
|
f"Select Directory for Network3D Object",
|
|
2340
2340
|
"",
|
|
2341
2341
|
QFileDialog.Option.ShowDirsOnly
|
|
2342
|
-
|
|
2342
|
+
)
|
|
2343
|
+
self.reset(nodes = True, network = True, xy_scale = 1, z_scale = 1, edges = True, search_region = True, network_overlay = True, id_overlay = True)
|
|
2344
|
+
|
|
2343
2345
|
|
|
2344
2346
|
my_network.assemble(directory)
|
|
2345
2347
|
|
|
@@ -2597,6 +2599,8 @@ class ImageViewerWindow(QMainWindow):
|
|
|
2597
2599
|
|
|
2598
2600
|
if assign_shape: #keep original shape tracked to undo resampling.
|
|
2599
2601
|
self.original_shape = self.channel_data[channel_index].shape
|
|
2602
|
+
if len(self.original_shape) == 4:
|
|
2603
|
+
self.original_shape = (self.original_shape[0], self.original_shape[1], self.original_shape[2])
|
|
2600
2604
|
|
|
2601
2605
|
self.update_display()
|
|
2602
2606
|
|
|
@@ -3923,19 +3927,19 @@ class ColorDialog(QDialog):
|
|
|
3923
3927
|
class Show3dDialog(QDialog):
|
|
3924
3928
|
def __init__(self, parent=None):
|
|
3925
3929
|
super().__init__(parent)
|
|
3926
|
-
self.setWindowTitle("Display Parameters")
|
|
3930
|
+
self.setWindowTitle("Display Parameters (Napari)")
|
|
3927
3931
|
self.setModal(True)
|
|
3928
3932
|
|
|
3929
3933
|
layout = QFormLayout(self)
|
|
3930
3934
|
|
|
3931
|
-
self.downsample = QLineEdit("
|
|
3932
|
-
layout.addRow("Downsample Factor (
|
|
3935
|
+
self.downsample = QLineEdit("")
|
|
3936
|
+
layout.addRow("Downsample Factor (Optional to speed up display):", self.downsample)
|
|
3933
3937
|
|
|
3934
3938
|
# Network Overlay checkbox (default True)
|
|
3935
|
-
self.
|
|
3936
|
-
self.
|
|
3937
|
-
self.
|
|
3938
|
-
layout.addRow("
|
|
3939
|
+
self.cubic = QPushButton("cubic")
|
|
3940
|
+
self.cubic.setCheckable(True)
|
|
3941
|
+
self.cubic.setChecked(False)
|
|
3942
|
+
layout.addRow("Use cubic downsample (Slower but preserves shape better potentially)?", self.cubic)
|
|
3939
3943
|
|
|
3940
3944
|
# Add Run button
|
|
3941
3945
|
run_button = QPushButton("Show 3D")
|
|
@@ -3949,22 +3953,49 @@ class Show3dDialog(QDialog):
|
|
|
3949
3953
|
|
|
3950
3954
|
# Get amount
|
|
3951
3955
|
try:
|
|
3952
|
-
downsample = float(self.downsample.text()) if self.downsample.text() else
|
|
3956
|
+
downsample = float(self.downsample.text()) if self.downsample.text() else None
|
|
3953
3957
|
except ValueError:
|
|
3954
|
-
downsample =
|
|
3958
|
+
downsample = None
|
|
3955
3959
|
|
|
3956
|
-
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
my_network.show_3D(my_network.network_overlay, downsample)
|
|
3960
|
+
cubic = self.cubic.isChecked()
|
|
3961
|
+
|
|
3962
|
+
if cubic:
|
|
3963
|
+
order = 3
|
|
3961
3964
|
else:
|
|
3962
|
-
|
|
3965
|
+
order = 0
|
|
3966
|
+
|
|
3967
|
+
arrays_3d = []
|
|
3968
|
+
arrays_4d = []
|
|
3969
|
+
|
|
3970
|
+
color_template = ['red', 'green', 'white', 'cyan', 'yellow'] # color list
|
|
3971
|
+
colors = []
|
|
3972
|
+
|
|
3973
|
+
|
|
3974
|
+
for i, channel in enumerate(self.parent().channel_data):
|
|
3975
|
+
if channel is not None:
|
|
3976
|
+
|
|
3977
|
+
if len(channel.shape) == 3:
|
|
3978
|
+
visible = self.parent().channel_buttons[i].isChecked()
|
|
3979
|
+
if visible:
|
|
3980
|
+
arrays_3d.append(channel)
|
|
3981
|
+
colors.append(color_template[i])
|
|
3982
|
+
elif len(channel.shape) == 4:
|
|
3983
|
+
visible = self.parent().channel_buttons[i].isChecked()
|
|
3984
|
+
if visible:
|
|
3985
|
+
arrays_4d.append(channel)
|
|
3986
|
+
|
|
3987
|
+
if self.parent().highlight_overlay is not None:
|
|
3988
|
+
arrays_3d.append(self.parent().highlight_overlay)
|
|
3989
|
+
colors.append(color_template[4])
|
|
3990
|
+
|
|
3991
|
+
n3d.show_3d(arrays_3d, arrays_4d, down_factor = downsample, order = order, xy_scale = my_network.xy_scale, z_scale = my_network.z_scale, colors = colors)
|
|
3963
3992
|
|
|
3964
3993
|
self.accept()
|
|
3965
3994
|
|
|
3966
3995
|
except Exception as e:
|
|
3967
3996
|
print(f"Error: {e}")
|
|
3997
|
+
import traceback
|
|
3998
|
+
print(traceback.format_exc())
|
|
3968
3999
|
|
|
3969
4000
|
|
|
3970
4001
|
class NetOverlayDialog(QDialog):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: nettracer3d
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.6
|
|
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
|
|
@@ -20,7 +20,7 @@ Requires-Dist: networkx
|
|
|
20
20
|
Requires-Dist: opencv-python-headless
|
|
21
21
|
Requires-Dist: openpyxl
|
|
22
22
|
Requires-Dist: pandas
|
|
23
|
-
Requires-Dist:
|
|
23
|
+
Requires-Dist: napari
|
|
24
24
|
Requires-Dist: python-louvain
|
|
25
25
|
Requires-Dist: tifffile
|
|
26
26
|
Requires-Dist: PyQt6
|
|
@@ -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=CfAdS3SnigL4TkfqwHRIg0WeBtwJ1nGysNq5pfSSwVU,201682
|
|
7
|
+
nettracer3d/nettracer_gui.py,sha256=e72Z9Yw0wxZ1ZIvrPv20oCtI49W3o0-YL7pNTLsM5Qc,289120
|
|
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.6.dist-info/LICENSE,sha256=gM207DhJjWrxLuEWXl0Qz5ISbtWDmADfjHp3yC2XISs,888
|
|
15
|
+
nettracer3d-0.3.6.dist-info/METADATA,sha256=8NWQk4tgtrZhISu9b210_FY4Q_GtcLN0Dhb1AdZukmg,2894
|
|
16
|
+
nettracer3d-0.3.6.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
17
|
+
nettracer3d-0.3.6.dist-info/top_level.txt,sha256=zsYy9rZwirfCEOubolhee4TyzqBAL5gSUeFMzhFTX8c,12
|
|
18
|
+
nettracer3d-0.3.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|