nettracer3d 0.5.8__tar.gz → 0.6.0__tar.gz

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.
Files changed (26) hide show
  1. {nettracer3d-0.5.8/src/nettracer3d.egg-info → nettracer3d-0.6.0}/PKG-INFO +3 -3
  2. {nettracer3d-0.5.8 → nettracer3d-0.6.0}/README.md +2 -2
  3. {nettracer3d-0.5.8 → nettracer3d-0.6.0}/pyproject.toml +1 -1
  4. {nettracer3d-0.5.8 → nettracer3d-0.6.0}/src/nettracer3d/nettracer_gui.py +221 -198
  5. {nettracer3d-0.5.8 → nettracer3d-0.6.0}/src/nettracer3d/segmenter.py +5 -2
  6. {nettracer3d-0.5.8 → nettracer3d-0.6.0/src/nettracer3d.egg-info}/PKG-INFO +3 -3
  7. {nettracer3d-0.5.8 → nettracer3d-0.6.0}/LICENSE +0 -0
  8. {nettracer3d-0.5.8 → nettracer3d-0.6.0}/setup.cfg +0 -0
  9. {nettracer3d-0.5.8 → nettracer3d-0.6.0}/src/nettracer3d/__init__.py +0 -0
  10. {nettracer3d-0.5.8 → nettracer3d-0.6.0}/src/nettracer3d/community_extractor.py +0 -0
  11. {nettracer3d-0.5.8 → nettracer3d-0.6.0}/src/nettracer3d/hub_getter.py +0 -0
  12. {nettracer3d-0.5.8 → nettracer3d-0.6.0}/src/nettracer3d/modularity.py +0 -0
  13. {nettracer3d-0.5.8 → nettracer3d-0.6.0}/src/nettracer3d/morphology.py +0 -0
  14. {nettracer3d-0.5.8 → nettracer3d-0.6.0}/src/nettracer3d/nettracer.py +0 -0
  15. {nettracer3d-0.5.8 → nettracer3d-0.6.0}/src/nettracer3d/network_analysis.py +0 -0
  16. {nettracer3d-0.5.8 → nettracer3d-0.6.0}/src/nettracer3d/network_draw.py +0 -0
  17. {nettracer3d-0.5.8 → nettracer3d-0.6.0}/src/nettracer3d/node_draw.py +0 -0
  18. {nettracer3d-0.5.8 → nettracer3d-0.6.0}/src/nettracer3d/proximity.py +0 -0
  19. {nettracer3d-0.5.8 → nettracer3d-0.6.0}/src/nettracer3d/run.py +0 -0
  20. {nettracer3d-0.5.8 → nettracer3d-0.6.0}/src/nettracer3d/simple_network.py +0 -0
  21. {nettracer3d-0.5.8 → nettracer3d-0.6.0}/src/nettracer3d/smart_dilate.py +0 -0
  22. {nettracer3d-0.5.8 → nettracer3d-0.6.0}/src/nettracer3d.egg-info/SOURCES.txt +0 -0
  23. {nettracer3d-0.5.8 → nettracer3d-0.6.0}/src/nettracer3d.egg-info/dependency_links.txt +0 -0
  24. {nettracer3d-0.5.8 → nettracer3d-0.6.0}/src/nettracer3d.egg-info/entry_points.txt +0 -0
  25. {nettracer3d-0.5.8 → nettracer3d-0.6.0}/src/nettracer3d.egg-info/requires.txt +0 -0
  26. {nettracer3d-0.5.8 → nettracer3d-0.6.0}/src/nettracer3d.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: nettracer3d
3
- Version: 0.5.8
3
+ Version: 0.6.0
4
4
  Summary: Scripts for intializing and analyzing networks from segmentations of three dimensional images.
5
5
  Author-email: Liam McLaughlin <mclaughlinliam99@gmail.com>
6
6
  Project-URL: User_Tutorial, https://www.youtube.com/watch?v=cRatn5VTWDY
@@ -44,6 +44,6 @@ NetTracer3D is free to use/fork for academic/nonprofit use so long as citation i
44
44
 
45
45
  NetTracer3D was developed by Liam McLaughlin while working under Dr. Sanjay Jain at Washington University School of Medicine.
46
46
 
47
- -- Version 0.5.8 updates --
47
+ -- Version 0.6.0 updates --
48
48
 
49
- 1. Bug fixes and improvements on the 2d segmenter.
49
+ 1. Bug fixes
@@ -8,6 +8,6 @@ NetTracer3D is free to use/fork for academic/nonprofit use so long as citation i
8
8
 
9
9
  NetTracer3D was developed by Liam McLaughlin while working under Dr. Sanjay Jain at Washington University School of Medicine.
10
10
 
11
- -- Version 0.5.8 updates --
11
+ -- Version 0.6.0 updates --
12
12
 
13
- 1. Bug fixes and improvements on the 2d segmenter.
13
+ 1. Bug fixes
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "nettracer3d"
3
- version = "0.5.8"
3
+ version = "0.6.0"
4
4
  authors = [
5
5
  { name="Liam McLaughlin", email="mclaughlinliam99@gmail.com" },
6
6
  ]
@@ -840,7 +840,7 @@ class ImageViewerWindow(QMainWindow):
840
840
  select_nodes.triggered.connect(lambda: self.handle_select_all(edges = False, nodes = True))
841
841
  select_both.triggered.connect(lambda: self.handle_select_all(edges = True))
842
842
  select_edges.triggered.connect(lambda: self.handle_select_all(edges = True, nodes = False))
843
- if self.highlight_overlay is not None:
843
+ if self.highlight_overlay is not None or self.mini_overlay_data is not None:
844
844
  highlight_select = context_menu.addAction("Add highlight in network selection")
845
845
  highlight_select.triggered.connect(self.handle_highlight_select)
846
846
  show_remove_menu.triggered.connect(self.handle_remove_points)
@@ -3514,206 +3514,211 @@ class ImageViewerWindow(QMainWindow):
3514
3514
  def update_display(self, preserve_zoom=None, dims = None, called = False, reset_resize = False, begin_paint = False):
3515
3515
  """Update the display with currently visible channels and highlight overlay."""
3516
3516
 
3517
- if begin_paint:
3518
- # Store/update the static background with current zoom level
3519
- self.static_background = self.canvas.copy_from_bbox(self.ax.bbox)
3517
+ try:
3520
3518
 
3519
+ if begin_paint:
3520
+ # Store/update the static background with current zoom level
3521
+ self.static_background = self.canvas.copy_from_bbox(self.ax.bbox)
3521
3522
 
3522
- self.figure.clear()
3523
3523
 
3524
- # Get active channels and their dimensions
3525
- active_channels = [i for i in range(4) if self.channel_data[i] is not None]
3526
- if dims is None:
3527
- if active_channels:
3528
- dims = [(self.channel_data[i].shape[1:3] if len(self.channel_data[i].shape) >= 3 else
3529
- self.channel_data[i].shape) for i in active_channels]
3530
- min_height = min(d[0] for d in dims)
3531
- min_width = min(d[1] for d in dims)
3532
- else:
3533
- min_height = 1
3534
- min_width = 1
3535
- else:
3536
- min_height = dims[0]
3537
- min_width = dims[1]
3524
+ self.figure.clear()
3538
3525
 
3539
- # Set axes limits before displaying any images
3540
- self.ax.set_xlim(-0.5, min_width - 0.5)
3541
- self.ax.set_ylim(min_height - 0.5, -0.5)
3542
-
3543
- # Create subplot with tight layout and white figure background
3544
- self.figure.patch.set_facecolor('white')
3545
- self.ax = self.figure.add_subplot(111)
3546
-
3547
- # Store current zoom limits if they exist and weren't provided
3548
-
3549
- current_xlim, current_ylim = preserve_zoom if preserve_zoom else (None, None)
3550
-
3551
- # Define base colors for each channel with increased intensity
3552
- base_colors = self.base_colors
3553
- # Set only the axes (image area) background to black
3554
- self.ax.set_facecolor('black')
3555
-
3556
- # Display each visible channel
3557
- for channel in range(4):
3558
- if (self.channel_visible[channel] and
3559
- self.channel_data[channel] is not None):
3560
-
3561
- # Check if we're dealing with RGB data
3562
- is_rgb = len(self.channel_data[channel].shape) == 4 and (self.channel_data[channel].shape[-1] == 3 or self.channel_data[channel].shape[-1] == 4)
3563
-
3564
- if len(self.channel_data[channel].shape) == 3 and not is_rgb:
3565
- current_image = self.channel_data[channel][self.current_slice, :, :]
3566
- elif is_rgb:
3567
- current_image = self.channel_data[channel][self.current_slice] # Already has RGB channels
3526
+ # Get active channels and their dimensions
3527
+ active_channels = [i for i in range(4) if self.channel_data[i] is not None]
3528
+ if dims is None:
3529
+ if active_channels:
3530
+ dims = [(self.channel_data[i].shape[1:3] if len(self.channel_data[i].shape) >= 3 else
3531
+ self.channel_data[i].shape) for i in active_channels]
3532
+ min_height = min(d[0] for d in dims)
3533
+ min_width = min(d[1] for d in dims)
3568
3534
  else:
3569
- current_image = self.channel_data[channel]
3570
-
3571
- if is_rgb and self.channel_data[channel].shape[-1] == 3:
3572
- # For RGB images, just display directly without colormap
3573
- self.ax.imshow(current_image,
3574
- alpha=0.7)
3575
- elif is_rgb and self.channel_data[channel].shape[-1] == 4:
3576
- self.ax.imshow(current_image) #For images that already have an alpha value and RGB, don't update alpha
3535
+ min_height = 1
3536
+ min_width = 1
3537
+ else:
3538
+ min_height = dims[0]
3539
+ min_width = dims[1]
3577
3540
 
3578
- else:
3579
- # Regular channel processing with colormap
3580
- # Calculate brightness/contrast limits from entire volume
3581
- img_min = self.min_max[channel][0]
3582
- img_max = self.min_max[channel][1]
3541
+ # Set axes limits before displaying any images
3542
+ self.ax.set_xlim(-0.5, min_width - 0.5)
3543
+ self.ax.set_ylim(min_height - 0.5, -0.5)
3544
+
3545
+ # Create subplot with tight layout and white figure background
3546
+ self.figure.patch.set_facecolor('white')
3547
+ self.ax = self.figure.add_subplot(111)
3548
+
3549
+ # Store current zoom limits if they exist and weren't provided
3550
+
3551
+ current_xlim, current_ylim = preserve_zoom if preserve_zoom else (None, None)
3552
+
3553
+ # Define base colors for each channel with increased intensity
3554
+ base_colors = self.base_colors
3555
+ # Set only the axes (image area) background to black
3556
+ self.ax.set_facecolor('black')
3557
+
3558
+ # Display each visible channel
3559
+ for channel in range(4):
3560
+ if (self.channel_visible[channel] and
3561
+ self.channel_data[channel] is not None):
3583
3562
 
3584
- # Calculate vmin and vmax, ensuring we don't get a zero range
3585
- if img_min == img_max:
3586
- vmin = img_min
3587
- vmax = img_min + 1
3588
- else:
3589
- vmin = img_min + (img_max - img_min) * self.channel_brightness[channel]['min']
3590
- vmax = img_min + (img_max - img_min) * self.channel_brightness[channel]['max']
3563
+ # Check if we're dealing with RGB data
3564
+ is_rgb = len(self.channel_data[channel].shape) == 4 and (self.channel_data[channel].shape[-1] == 3 or self.channel_data[channel].shape[-1] == 4)
3591
3565
 
3592
- # Normalize the image safely
3593
- if vmin == vmax:
3594
- normalized_image = np.zeros_like(current_image)
3566
+ if len(self.channel_data[channel].shape) == 3 and not is_rgb:
3567
+ current_image = self.channel_data[channel][self.current_slice, :, :]
3568
+ elif is_rgb:
3569
+ current_image = self.channel_data[channel][self.current_slice] # Already has RGB channels
3595
3570
  else:
3596
- normalized_image = np.clip((current_image - vmin) / (vmax - vmin), 0, 1)
3597
-
3598
- if channel == 2 and self.machine_window is not None:
3599
- custom_cmap = LinearSegmentedColormap.from_list(
3600
- f'custom_{channel}',
3601
- [(0, 0, 0, 0), # transparent for 0
3602
- (0.5, 1, 0.5, 1), # light green for 1
3603
- (1, 0.5, 0.5, 1)] # light red for 2
3604
- )
3571
+ current_image = self.channel_data[channel]
3572
+
3573
+ if is_rgb and self.channel_data[channel].shape[-1] == 3:
3574
+ # For RGB images, just display directly without colormap
3605
3575
  self.ax.imshow(current_image,
3606
- cmap=custom_cmap,
3607
- vmin=0,
3608
- vmax=2,
3609
- alpha=0.7,
3610
- interpolation='nearest',
3611
- extent=(-0.5, min_width-0.5, min_height-0.5, -0.5))
3576
+ alpha=0.7)
3577
+ elif is_rgb and self.channel_data[channel].shape[-1] == 4:
3578
+ self.ax.imshow(current_image) #For images that already have an alpha value and RGB, don't update alpha
3579
+
3612
3580
  else:
3613
- # Create custom colormap with higher intensity
3614
- color = base_colors[channel]
3615
- custom_cmap = LinearSegmentedColormap.from_list(
3616
- f'custom_{channel}',
3617
- [(0,0,0,0), (*color,1)]
3618
- )
3581
+ # Regular channel processing with colormap
3582
+ # Calculate brightness/contrast limits from entire volume
3583
+ img_min = self.min_max[channel][0]
3584
+ img_max = self.min_max[channel][1]
3619
3585
 
3620
- # Display the image with slightly higher alpha
3621
- self.ax.imshow(normalized_image,
3622
- alpha=0.7,
3623
- cmap=custom_cmap,
3624
- vmin=0,
3625
- vmax=1,
3626
- extent=(-0.5, min_width-0.5, min_height-0.5, -0.5))
3627
-
3628
- if self.preview and not called:
3629
- self.create_highlight_overlay_slice(self.targs, bounds = self.bounds)
3630
-
3631
- # Add highlight overlay if it exists
3632
- if self.mini_overlay and self.highlight and self.machine_window is None:
3633
- highlight_cmap = LinearSegmentedColormap.from_list(
3634
- 'highlight',
3635
- [(0, 0, 0, 0), (1, 1, 0, 1)] # yellow
3636
- )
3637
- self.ax.imshow(self.mini_overlay_data,
3638
- cmap=highlight_cmap,
3639
- alpha=0.5)
3640
- elif self.highlight_overlay is not None and self.highlight and self.machine_window is None:
3641
- highlight_slice = self.highlight_overlay[self.current_slice]
3642
- highlight_cmap = LinearSegmentedColormap.from_list(
3643
- 'highlight',
3644
- [(0, 0, 0, 0), (1, 1, 0, 1)] # yellow
3645
- )
3646
- self.ax.imshow(highlight_slice,
3647
- cmap=highlight_cmap,
3648
- alpha=0.5)
3649
- elif self.highlight_overlay is not None and self.highlight:
3650
- highlight_slice = self.highlight_overlay[self.current_slice]
3651
- highlight_cmap = LinearSegmentedColormap.from_list(
3652
- 'highlight',
3653
- [(0, 0, 0, 0), # transparent for 0
3654
- (1, 1, 0, 1), # bright yellow for 1
3655
- (0, 0.7, 1, 1)] # cool blue for 2
3656
- )
3657
- self.ax.imshow(highlight_slice,
3658
- cmap=highlight_cmap,
3659
- vmin=0,
3660
- vmax=2, # Important: set vmax to 2 to accommodate both values
3661
- alpha=0.5)
3662
-
3663
-
3664
-
3665
-
3666
- # Style the axes
3667
- self.ax.set_xlabel('X')
3668
- self.ax.set_ylabel('Y')
3669
- self.ax.set_title(f'Slice {self.current_slice}')
3670
-
3671
- # Make axis labels and ticks black for visibility against white background
3672
- self.ax.xaxis.label.set_color('black')
3673
- self.ax.yaxis.label.set_color('black')
3674
- self.ax.title.set_color('black')
3675
- self.ax.tick_params(colors='black')
3676
- for spine in self.ax.spines.values():
3677
- spine.set_color('black')
3678
-
3679
- # Adjust the layout to ensure the plot fits well in the figure
3680
- self.figure.tight_layout()
3681
-
3682
- # Redraw measurement points and their labels
3683
- for point in self.measurement_points:
3684
- x1, y1, z1 = point['point1']
3685
- x2, y2, z2 = point['point2']
3686
- pair_idx = point['pair_index']
3687
-
3688
- # Draw points and labels if they're on current slice
3689
- if z1 == self.current_slice:
3690
- self.ax.plot(x1, y1, 'yo', markersize=8)
3691
- self.ax.text(x1, y1+5, str(pair_idx),
3692
- color='white', ha='center', va='bottom')
3693
- if z2 == self.current_slice:
3694
- self.ax.plot(x2, y2, 'yo', markersize=8)
3695
- self.ax.text(x2, y2+5, str(pair_idx),
3696
- color='white', ha='center', va='bottom')
3697
-
3698
- # Draw line if both points are on current slice
3699
- if z1 == z2 == self.current_slice:
3700
- self.ax.plot([x1, x2], [y1, y2], 'r--', alpha=0.5)
3701
-
3702
- if active_channels:
3703
- self.ax.set_xlim(-0.5, min_width - 0.5)
3704
- self.ax.set_ylim(min_height - 0.5, -0.5)
3586
+ # Calculate vmin and vmax, ensuring we don't get a zero range
3587
+ if img_min == img_max:
3588
+ vmin = img_min
3589
+ vmax = img_min + 1
3590
+ else:
3591
+ vmin = img_min + (img_max - img_min) * self.channel_brightness[channel]['min']
3592
+ vmax = img_min + (img_max - img_min) * self.channel_brightness[channel]['max']
3593
+
3594
+ # Normalize the image safely
3595
+ if vmin == vmax:
3596
+ normalized_image = np.zeros_like(current_image)
3597
+ else:
3598
+ normalized_image = np.clip((current_image - vmin) / (vmax - vmin), 0, 1)
3599
+
3600
+ if channel == 2 and self.machine_window is not None:
3601
+ custom_cmap = LinearSegmentedColormap.from_list(
3602
+ f'custom_{channel}',
3603
+ [(0, 0, 0, 0), # transparent for 0
3604
+ (0.5, 1, 0.5, 1), # light green for 1
3605
+ (1, 0.5, 0.5, 1)] # light red for 2
3606
+ )
3607
+ self.ax.imshow(current_image,
3608
+ cmap=custom_cmap,
3609
+ vmin=0,
3610
+ vmax=2,
3611
+ alpha=0.7,
3612
+ interpolation='nearest',
3613
+ extent=(-0.5, min_width-0.5, min_height-0.5, -0.5))
3614
+ else:
3615
+ # Create custom colormap with higher intensity
3616
+ color = base_colors[channel]
3617
+ custom_cmap = LinearSegmentedColormap.from_list(
3618
+ f'custom_{channel}',
3619
+ [(0,0,0,0), (*color,1)]
3620
+ )
3621
+
3622
+ # Display the image with slightly higher alpha
3623
+ self.ax.imshow(normalized_image,
3624
+ alpha=0.7,
3625
+ cmap=custom_cmap,
3626
+ vmin=0,
3627
+ vmax=1,
3628
+ extent=(-0.5, min_width-0.5, min_height-0.5, -0.5))
3629
+
3630
+ if self.preview and not called:
3631
+ self.create_highlight_overlay_slice(self.targs, bounds = self.bounds)
3632
+
3633
+ # Add highlight overlay if it exists
3634
+ if self.mini_overlay and self.highlight and self.machine_window is None:
3635
+ highlight_cmap = LinearSegmentedColormap.from_list(
3636
+ 'highlight',
3637
+ [(0, 0, 0, 0), (1, 1, 0, 1)] # yellow
3638
+ )
3639
+ self.ax.imshow(self.mini_overlay_data,
3640
+ cmap=highlight_cmap,
3641
+ alpha=0.5)
3642
+ elif self.highlight_overlay is not None and self.highlight and self.machine_window is None:
3643
+ highlight_slice = self.highlight_overlay[self.current_slice]
3644
+ highlight_cmap = LinearSegmentedColormap.from_list(
3645
+ 'highlight',
3646
+ [(0, 0, 0, 0), (1, 1, 0, 1)] # yellow
3647
+ )
3648
+ self.ax.imshow(highlight_slice,
3649
+ cmap=highlight_cmap,
3650
+ alpha=0.5)
3651
+ elif self.highlight_overlay is not None and self.highlight:
3652
+ highlight_slice = self.highlight_overlay[self.current_slice]
3653
+ highlight_cmap = LinearSegmentedColormap.from_list(
3654
+ 'highlight',
3655
+ [(0, 0, 0, 0), # transparent for 0
3656
+ (1, 1, 0, 1), # bright yellow for 1
3657
+ (0, 0.7, 1, 1)] # cool blue for 2
3658
+ )
3659
+ self.ax.imshow(highlight_slice,
3660
+ cmap=highlight_cmap,
3661
+ vmin=0,
3662
+ vmax=2, # Important: set vmax to 2 to accommodate both values
3663
+ alpha=0.5)
3705
3664
 
3706
- if self.resizing:
3707
- self.original_xlim = self.ax.get_xlim()
3708
- self.original_ylim = self.ax.get_ylim()
3709
- # Restore zoom limits if they existed
3710
- if current_xlim is not None and current_ylim is not None:
3711
- self.ax.set_xlim(current_xlim)
3712
- self.ax.set_ylim(current_ylim)
3713
- if reset_resize:
3714
- self.resizing = False
3665
+
3666
+
3667
+
3668
+ # Style the axes
3669
+ self.ax.set_xlabel('X')
3670
+ self.ax.set_ylabel('Y')
3671
+ self.ax.set_title(f'Slice {self.current_slice}')
3672
+
3673
+ # Make axis labels and ticks black for visibility against white background
3674
+ self.ax.xaxis.label.set_color('black')
3675
+ self.ax.yaxis.label.set_color('black')
3676
+ self.ax.title.set_color('black')
3677
+ self.ax.tick_params(colors='black')
3678
+ for spine in self.ax.spines.values():
3679
+ spine.set_color('black')
3680
+
3681
+ # Adjust the layout to ensure the plot fits well in the figure
3682
+ self.figure.tight_layout()
3683
+
3684
+ # Redraw measurement points and their labels
3685
+ for point in self.measurement_points:
3686
+ x1, y1, z1 = point['point1']
3687
+ x2, y2, z2 = point['point2']
3688
+ pair_idx = point['pair_index']
3689
+
3690
+ # Draw points and labels if they're on current slice
3691
+ if z1 == self.current_slice:
3692
+ self.ax.plot(x1, y1, 'yo', markersize=8)
3693
+ self.ax.text(x1, y1+5, str(pair_idx),
3694
+ color='white', ha='center', va='bottom')
3695
+ if z2 == self.current_slice:
3696
+ self.ax.plot(x2, y2, 'yo', markersize=8)
3697
+ self.ax.text(x2, y2+5, str(pair_idx),
3698
+ color='white', ha='center', va='bottom')
3699
+
3700
+ # Draw line if both points are on current slice
3701
+ if z1 == z2 == self.current_slice:
3702
+ self.ax.plot([x1, x2], [y1, y2], 'r--', alpha=0.5)
3715
3703
 
3716
- self.canvas.draw()
3704
+ if active_channels:
3705
+ self.ax.set_xlim(-0.5, min_width - 0.5)
3706
+ self.ax.set_ylim(min_height - 0.5, -0.5)
3707
+
3708
+ if self.resizing:
3709
+ self.original_xlim = self.ax.get_xlim()
3710
+ self.original_ylim = self.ax.get_ylim()
3711
+ # Restore zoom limits if they existed
3712
+ if current_xlim is not None and current_ylim is not None:
3713
+ self.ax.set_xlim(current_xlim)
3714
+ self.ax.set_ylim(current_ylim)
3715
+ if reset_resize:
3716
+ self.resizing = False
3717
+
3718
+ self.canvas.draw()
3719
+
3720
+ except:
3721
+ pass
3717
3722
 
3718
3723
  def update_display_slice(self, channel, preserve_zoom=None):
3719
3724
  """Ultra minimal update that only changes the paint channel's data"""
@@ -4818,7 +4823,7 @@ class Show3dDialog(QDialog):
4818
4823
  if visible:
4819
4824
  arrays_4d.append(channel)
4820
4825
 
4821
- if self.parent().highlight_overlay is not None:
4826
+ if self.parent().highlight_overlay is not None or self.parent().mini_overlay_data is not None:
4822
4827
  if self.parent().mini_overlay == True:
4823
4828
  self.parent().create_highlight_overlay(node_indices = self.parent().clicked_values['nodes'], edge_indices = self.parent().clicked_values['edges'])
4824
4829
  arrays_3d.append(self.parent().highlight_overlay)
@@ -5048,19 +5053,24 @@ class ShuffleDialog(QDialog):
5048
5053
  target_data = self.parent().channel_data[accepted_target]
5049
5054
 
5050
5055
 
5051
- if accepted_mode == 4:
5052
-
5053
- self.parent().highlight_overlay = n3d.binarize(target_data)
5054
- else:
5055
- self.parent().load_channel(accepted_mode, channel_data = target_data, data = True)
5056
+ try:
5057
+ if accepted_mode == 4:
5056
5058
 
5059
+ self.parent().highlight_overlay = n3d.binarize(target_data)
5060
+ else:
5061
+ self.parent().load_channel(accepted_mode, channel_data = target_data, data = True)
5062
+ except:
5063
+ pass
5057
5064
 
5058
5065
 
5059
- if accepted_target == 4:
5060
- try:
5061
- self.parent().highlight_overlay = n3d.binarize(active_data)
5062
- except:
5063
- self.parent().highlight_overlay = None
5066
+ try:
5067
+ if accepted_target == 4:
5068
+ try:
5069
+ self.parent().highlight_overlay = n3d.binarize(active_data)
5070
+ except:
5071
+ self.parent().highlight_overlay = None
5072
+ except:
5073
+ pass
5064
5074
 
5065
5075
  else:
5066
5076
  self.parent().load_channel(accepted_target, channel_data = active_data, data = True)
@@ -5862,6 +5872,9 @@ class ResizeDialog(QDialog):
5862
5872
 
5863
5873
 
5864
5874
  # Process highlight overlay if it exists
5875
+ if self.parent().mini_overlay_data is not None:
5876
+ self.parent().create_highlight_overlay(self.parent().clicked_values['nodes'], self.parent().clicked_values['edges'])
5877
+
5865
5878
  if self.parent().highlight_overlay is not None:
5866
5879
  self.parent().highlight_overlay = n3d.resize(self.parent().highlight_overlay, resize, order)
5867
5880
  if my_network.search_region is not None:
@@ -5877,6 +5890,10 @@ class ResizeDialog(QDialog):
5877
5890
  resized_data = n3d.upsample_with_padding(self.parent().channel_data[channel], original_shape = self.parent().original_shape)
5878
5891
  self.parent().load_channel(channel, channel_data=resized_data, data=True, assign_shape = False)
5879
5892
 
5893
+ if self.parent().mini_overlay_data is not None:
5894
+
5895
+ self.parent().create_highlight_overlay(self.parent().clicked_values['nodes'], self.parent().clicked_values['edges'])
5896
+
5880
5897
 
5881
5898
  # Process highlight overlay if it exists
5882
5899
  if self.parent().highlight_overlay is not None:
@@ -6105,6 +6122,9 @@ class ThresholdDialog(QDialog):
6105
6122
  if self.parent().volume_dict[self.parent().active_channel] is None:
6106
6123
  self.parent().volumes()
6107
6124
 
6125
+ if self.parent().mini_overlay_data is not None:
6126
+ self.parent().mini_overlay_data = None
6127
+
6108
6128
  thresh_window = ThresholdWindow(self.parent(), accepted_mode)
6109
6129
  thresh_window.show() # Non-modal window
6110
6130
  self.highlight_overlay = None
@@ -6128,6 +6148,8 @@ class ThresholdDialog(QDialog):
6128
6148
  )
6129
6149
  return
6130
6150
 
6151
+ if self.parent().mini_overlay_data is not None:
6152
+ self.parent().mini_overlay_data = None
6131
6153
 
6132
6154
  self.parent().machine_window = MachineWindow(self.parent())
6133
6155
  self.parent().machine_window.show() # Non-modal window
@@ -6774,6 +6796,7 @@ class ThresholdWindow(QMainWindow):
6774
6796
  self.histo_list = self.parent().channel_data[self.parent().active_channel].flatten().tolist()
6775
6797
  self.bounds = True
6776
6798
  self.parent().bounds = True
6799
+
6777
6800
 
6778
6801
  # Create matplotlib figure
6779
6802
  fig = Figure(figsize=(5, 4))
@@ -1099,8 +1099,11 @@ class InteractiveSegmenter:
1099
1099
  def cleanup(self):
1100
1100
  """Clean up GPU memory"""
1101
1101
  if self.use_gpu:
1102
- cp.get_default_memory_pool().free_all_blocks()
1103
- torch.cuda.empty_cache()
1102
+ try:
1103
+ cp.get_default_memory_pool().free_all_blocks()
1104
+ torch.cuda.empty_cache()
1105
+ except:
1106
+ pass
1104
1107
 
1105
1108
  def train_batch(self, foreground_array, speed = True, use_gpu = False, use_two = False):
1106
1109
  """Train directly on foreground and background arrays"""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: nettracer3d
3
- Version: 0.5.8
3
+ Version: 0.6.0
4
4
  Summary: Scripts for intializing and analyzing networks from segmentations of three dimensional images.
5
5
  Author-email: Liam McLaughlin <mclaughlinliam99@gmail.com>
6
6
  Project-URL: User_Tutorial, https://www.youtube.com/watch?v=cRatn5VTWDY
@@ -44,6 +44,6 @@ NetTracer3D is free to use/fork for academic/nonprofit use so long as citation i
44
44
 
45
45
  NetTracer3D was developed by Liam McLaughlin while working under Dr. Sanjay Jain at Washington University School of Medicine.
46
46
 
47
- -- Version 0.5.8 updates --
47
+ -- Version 0.6.0 updates --
48
48
 
49
- 1. Bug fixes and improvements on the 2d segmenter.
49
+ 1. Bug fixes
File without changes
File without changes