Skip to content

Commit 940875d

Browse files
committed
Apply changes suggested and fix pre-commit
1 parent a8cf969 commit 940875d

File tree

11 files changed

+59
-115
lines changed

11 files changed

+59
-115
lines changed

invesalius/data/mask.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -230,19 +230,19 @@ def __init__(self):
230230
@property
231231
def category(self):
232232
if self.name.lower().startswith("cortical"):
233-
return "Cortical"
233+
return "cortical"
234234
elif self.name.lower().startswith("subcortical"):
235-
return "Subcortical"
235+
return "subcortical"
236236
elif self.name.lower().startswith("ventricles"):
237-
return "Ventricles"
237+
return "ventricles"
238238
elif self.name.lower().startswith("white_matter"):
239-
return "White_matter"
239+
return "white_matter"
240240
elif self.name.lower().startswith("cerebellum"):
241-
return "Cerebellum"
241+
return "cerebellum"
242242
elif self.name.lower().startswith("brain_stem"):
243-
return "Brain_stem"
243+
return "brain_stem"
244244
elif self.name.lower().startswith("choroid_Plexus"):
245-
return "Choroid_Plexus"
245+
return "choroid_plexus"
246246
else:
247247
return "General"
248248

invesalius/data/slice_.py

Lines changed: 18 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,10 @@ class SliceBuffer:
6464

6565
def __init__(self):
6666
self.index: int = -1
67-
self.image: Optional[np.ndarray] = None
68-
self.mask: Optional[np.ndarray] = None
69-
self.vtk_image: Optional[vtkImageData] = None
70-
self.vtk_mask: Optional[vtkImageData] = None
67+
self.image: np.ndarray | None = None
68+
self.mask: np.ndarray | None = None
69+
self.vtk_image: vtkImageData | None = None
70+
self.vtk_mask: vtkImageData | None = None
7171

7272
def discard_vtk_mask(self) -> None:
7373
self.vtk_mask = None
@@ -95,18 +95,16 @@ def discard_buffer(self) -> None:
9595
class Slice(metaclass=utils.Singleton):
9696
def __init__(self):
9797
self.selected_mask_indices = []
98-
self._matrix = None
9998
self._matrix_filename = ""
100-
self.current_mask: Optional[Mask] = None
99+
self.current_mask: Mask | None = None
101100
self.blend_filter = None
102-
self.histogram: Optional[np.ndarray] = None
101+
self.histogram: np.ndarray | None = None
102+
self._matrix: np.ndarray | None = None
103103
self._affine: np.ndarray = np.identity(4)
104104
self._n_tracts: int = 0
105105
self._tracker = None
106106
self.aux_matrices: dict[str, np.ndarray] = {}
107-
self.aux_matrices_colours: dict[
108-
str, dict[Union[int, float], Tuple[float, float, float]]
109-
] = {}
107+
self.aux_matrices_colours: dict[str, dict[int | float, tuple[float, float, float]]] = {}
110108
self.state = const.STATE_DEFAULT
111109

112110
self.to_show_aux = ""
@@ -143,7 +141,7 @@ def __init__(self):
143141
self.opacity: float = 0.8
144142

145143
@property
146-
def matrix(self) -> Optional[np.ndarray]:
144+
def matrix(self) -> np.ndarray | None:
147145
return self._matrix
148146

149147
@matrix.setter
@@ -155,11 +153,11 @@ def matrix(self, value: np.ndarray) -> None:
155153
self.center = [(s * d / 2.0) for (d, s) in zip(self.matrix.shape[::-1], self.spacing)]
156154

157155
@property
158-
def spacing(self) -> Tuple[float, float, float]:
156+
def spacing(self) -> tuple[float, float, float]:
159157
return self._spacing
160158

161159
@spacing.setter
162-
def spacing(self, value: Tuple[float, float, float]) -> None:
160+
def spacing(self, value: tuple[float, float, float]) -> None:
163161
self._spacing = value
164162
self.center = [(s * d / 2.0) for (d, s) in zip(self.matrix.shape[::-1], self.spacing)]
165163

@@ -264,7 +262,7 @@ def __bind_events(self) -> None:
264262
Publisher.subscribe(self.do_threshold_to_all_slices, "Appy threshold all slices")
265263

266264
def GetMaxSliceNumber(self, orientation: str) -> int:
267-
shape: Tuple[int, int, int] = self.matrix.shape
265+
shape: tuple[int, int, int] = self.matrix.shape
268266

269267
# Because matrix indexing starts with 0 so the last slice is the shape
270268
# minu 1.
@@ -283,7 +281,7 @@ def discard_all_buffers(self) -> None:
283281

284282
def get_world_to_invesalius_vtk_affine(
285283
self, inverse: bool = False
286-
) -> Tuple[np.ndarray, "vtkMatrix4x4", float]:
284+
) -> tuple[np.ndarray, "vtkMatrix4x4", float]:
287285
"""
288286
Creates an affine matrix with img_shift adjustment and returns both the NumPy
289287
and VTK versions of the matrix, along with the img_shift value.
@@ -1247,46 +1245,30 @@ def CreateSurfaceFromIndex(self, surface_parameters):
12471245
)
12481246

12491247
def on_select_all_masks_changed(self, select_all_active):
1250-
"""
1251-
Handle when select all masks checkbox is toggled
1252-
"""
1253-
# Notify the UI to update the button text
12541248
Publisher.sendMessage("Update create surface button", select_all_active=select_all_active)
12551249

1256-
def create_surfaces_for_all_masks(self, surface_parameters_template):
1257-
"""
1258-
Create surfaces for all masks that have content (voxels > threshold)
1259-
1260-
Args:
1261-
surface_parameters_template: Template parameters to use for all surface creations
1262-
"""
1250+
def create_surfaces_for_all_masks(self, surface_template):
12631251
proj = Project()
12641252
created_surfaces = []
1265-
1266-
# Get all masks from the project
12671253
mask_dict = proj.mask_dict
12681254

12691255
for mask_index in self.selected_mask_indices:
12701256
if mask_index not in mask_dict:
12711257
continue
12721258
mask = mask_dict[mask_index]
1273-
# Check if mask has content (similar to the check in AddNewActor)
12741259
if mask.matrix.max() < 127:
1275-
print(f"Skipping mask '{mask.name}' (index {mask_index}) - no voxels selected")
1260+
print(f"Skipping mask '{mask.name}' (index {mask_index}) - no voxels available")
12761261
continue
12771262

1278-
# Create a copy of the template parameters for this specific mask
1279-
surface_parameters = surface_parameters_template.copy()
1280-
surface_parameters["options"] = surface_parameters_template["options"].copy()
1263+
surface_parameters = surface_template.copy()
1264+
surface_parameters["options"] = surface_template["options"].copy()
12811265

1282-
# Update the parameters for this specific mask
12831266
surface_parameters["options"]["index"] = mask_index
12841267
surface_parameters["options"]["name"] = f"{mask.name}"
1285-
surface_parameters["options"]["overwrite"] = False # Always create new surfaces
1268+
surface_parameters["options"]["overwrite"] = False # always create new surfaces
12861269

12871270
print(f"Creating surface for mask '{mask.name}' (index {mask_index})")
12881271

1289-
# Create the surface for this mask
12901272
try:
12911273
self.do_threshold_to_all_slices(mask)
12921274
Publisher.sendMessage(

invesalius/data/surface.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@
6666
import invesalius.data.polydata_utils as pu
6767
import invesalius.data.slice_ as sl
6868
import invesalius.data.surface_process as surface_process
69-
import invesalius.data.vtk_utils as vtk_utils
7069
import invesalius.project as prj
7170
import invesalius.session as ses
7271
import invesalius.utils as utl
@@ -238,7 +237,6 @@ def __bind_events(self):
238237
Publisher.subscribe(self.export_all_surfaces_separately, "Export all surfaces separately")
239238

240239
Publisher.subscribe(self.on_surfaces_creation_completed, "Surfaces creation completed")
241-
Publisher.subscribe(self.on_no_surfaces_created, "No surfaces created")
242240

243241
def on_surfaces_creation_completed(self, created_count):
244242
"""

invesalius/gui/data_notebook.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -740,7 +740,7 @@ def on_selection_changed(self, evt):
740740
if hasattr(self, "category"):
741741
Publisher.sendMessage("Update mask select all checkbox", category=self.category)
742742
else:
743-
print(f"[DEBUG] Selection changed but 'category' attribute not found on self.")
743+
print(f"Selection changed but 'category' attribute not found on self.")
744744
if evt:
745745
evt.Skip()
746746

@@ -894,7 +894,7 @@ def OnEditLabel(self, evt):
894894
evt.Skip()
895895

896896
def OnCheckItem(self, index, flag):
897-
print(f"[DEBUG] OnCheckItem called with index: {index}, flag: {flag}")
897+
print(f" OnCheckItem called with index: {index}, flag: {flag}")
898898

899899
global_idx = -1
900900
for g_id, l_id in self.mask_list_index.items():
@@ -903,10 +903,10 @@ def OnCheckItem(self, index, flag):
903903
break
904904

905905
if global_idx == -1:
906-
print(f"[DEBUG] OnCheckItem: global_idx not found for local index {index}")
906+
print(f" OnCheckItem: global_idx not found for local index {index}")
907907
return
908908

909-
print(f"[DEBUG] OnCheckItem: global_idx = {global_idx}")
909+
print(f" OnCheckItem: global_idx = {global_idx}")
910910

911911
if flag:
912912
Publisher.sendMessage("Change mask selected", index=global_idx)
@@ -915,7 +915,7 @@ def OnCheckItem(self, index, flag):
915915
Publisher.sendMessage("Show mask", index=global_idx, value=flag)
916916

917917
# Also trigger selection update since this affects the overall selection state
918-
print(f"[DEBUG] OnCheckItem: triggering selection update")
918+
print(f" OnCheckItem: triggering selection update")
919919
self.on_selection_changed(None)
920920

921921
def InsertNewItem(self, index=0, label=_("Mask"), threshold="(1000, 4500)", colour=None):

invesalius/gui/deep_learning_seg_dialog.py

Lines changed: 14 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#!/usr/bin/env python3
22
# -*- coding: UTF-8 -*-
33

4-
import importlib
54
import multiprocessing
65
import time
76
from typing import Dict
@@ -439,13 +438,13 @@ def __init__(self, parent, auto_segment=False):
439438
class SubpartSegmenterDialog(DeepLearningSegmenterDialog):
440439
def __init__(self, parent, auto_segment=False):
441440
self.mask_types = {
442-
"Cortical": _("Cortical"),
443-
"Subcortical": _("Subcortical"),
444-
"White_matter": _("White Matter"),
445-
"Cerebellum": _("Cerebellum"),
446-
"Ventricles": _("Ventricles"),
447-
"Brain_stem": _("Brain Stem"),
448-
"Choroid_Plexus": _("Choroid Plexus"),
441+
"cortical": _("Cortical"),
442+
"subcortical": _("Subcortical"),
443+
"white_matter": _("White Matter"),
444+
"cerebellum": _("Cerebellum"),
445+
"ventricles": _("Ventricles"),
446+
"brain_stem": _("Brain Stem"),
447+
"choroid_plexus": _("Choroid Plexus"),
449448
}
450449

451450
self.selected_mask_types = []
@@ -455,7 +454,7 @@ def __init__(self, parent, auto_segment=False):
455454
title=_("Subpart Segmentation"),
456455
has_torch=True,
457456
has_tinygrad=True,
458-
segmenter=segment.SubpartSegementProcess,
457+
segmenter=segment.SubpartSegmentProcess,
459458
auto_segment=auto_segment,
460459
)
461460

@@ -477,28 +476,6 @@ def _init_gui(self):
477476
self.mask_checkboxes[mask_id] = wx.CheckBox(self, wx.ID_ANY, mask_label)
478477
self.mask_checkboxes[mask_id].SetValue(False)
479478

480-
self._check_model_availability()
481-
482-
def _check_model_availability(self):
483-
"""Check if required models and dependencies are available"""
484-
try:
485-
# Try to create a dummy process to check model availability
486-
# This is safer than calling slc.Slice().matrix which might not be ready
487-
self.models_missing = False
488-
self.missing_reason = ""
489-
490-
# We could add specific checks here, but for now we'll do it lazily
491-
# during segmentation start to avoid initialization issues
492-
493-
except Exception as e:
494-
self.models_missing = True
495-
self.missing_reason = str(e)
496-
497-
if self.models_missing:
498-
self.lbl_models_missing = wx.StaticText(
499-
self, -1, _("FastSurfer models not found. Please check installation.")
500-
)
501-
502479
def _do_layout(self):
503480
"""Override _do_layout to arrange FastSurferCNN specific UI elements"""
504481
super()._do_layout()
@@ -545,15 +522,6 @@ def _do_layout(self):
545522
# Fallback - just add to the main sizer
546523
self.main_sizer.Add(self.mask_types_sizer, 0, wx.ALL | wx.EXPAND, 5)
547524

548-
if self.models_missing:
549-
error_sizer = wx.BoxSizer(wx.VERTICAL)
550-
error_sizer.Add(self.lbl_models_missing, 0, wx.ALL, 5)
551-
552-
index = self.main_sizer.GetItemCount() - 1
553-
self.main_sizer.Insert(index, error_sizer, 0, wx.EXPAND | wx.ALL, 5)
554-
555-
self.btn_segment.Enable(False)
556-
557525
self.main_sizer.Fit(self)
558526
self.Layout()
559527

@@ -575,7 +543,7 @@ def OnSegment(self, evt):
575543
device_id = self.torch_devices[self.cb_devices.GetValue()]
576544
except (KeyError, AttributeError):
577545
device_id = "cpu"
578-
use_gpu = True if not "cpu" in device_id.lower() else False
546+
use_gpu = True if "cpu" not in device_id.lower() else False
579547
elif backend.lower() == "tinygrad":
580548
try:
581549
device_id = self.tinygrad_devices[self.cb_devices.GetValue()]
@@ -637,18 +605,10 @@ def AfterSegment(self):
637605
checkbox.Enable()
638606

639607
def apply_segment_threshold(self):
640-
print("apply_segment_threshold: Starting...")
641608
threshold = self.sld_threshold.GetValue() / 100.0
642-
print(f"apply_segment_threshold: Threshold value: {threshold}")
643-
644-
print("apply_segment_threshold: Calling apply_segment_threshold...")
645609
self.ps.apply_segment_threshold(threshold)
646-
print("apply_segment_threshold: apply_segment_threshold completed")
647-
648-
print("apply_segment_threshold: Discarding buffers and reloading slice...")
649610
slc.Slice().discard_all_buffers()
650611
Publisher.sendMessage("Reload actual slice")
651-
print("apply_segment_threshold: Completed successfully")
652612

653613
def OnStop(self, evt):
654614
super().OnStop(evt)
@@ -811,6 +771,10 @@ def _init_gui(self):
811771

812772
self.patch_cmb = wx.ComboBox(self, choices=patch_size, value="480")
813773

774+
self.path_sizer = wx.BoxSizer(wx.HORIZONTAL)
775+
self.path_sizer.Add(self.patch_txt, 0, wx.EXPAND | wx.ALL, 5)
776+
self.path_sizer.Add(self.patch_cmb, 2, wx.EXPAND | wx.ALL, 5)
777+
814778
self.method = wx.RadioBox(
815779
self,
816780
-1,
@@ -849,7 +813,7 @@ def OnSegment(self, evt):
849813
apply_wwwl = self.chk_apply_wwwl.GetValue()
850814
create_new_mask = self.chk_new_mask.GetValue()
851815
use_gpu = self.chk_use_gpu.GetValue()
852-
prob_threshold = self.sld_threshold.GetValue() / 100.0
816+
# prob_threshold = self.sld_threshold.GetValue() / 100.0
853817
method = self.method.GetSelection()
854818

855819
self.btn_close.Disable()
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__all__ = ["fastsurfer", "segment.py"]
1+
__all__ = ["fastsurfer_subpart", "segment"]

invesalius/segmentation/deep_learning/fastsurfer_subpart/__init__.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313
# limitations under the License.
1414

1515
__all__ = [
16-
"misc" "models",
17-
"data_process" "inference",
16+
"misc",
17+
"models",
18+
"data_process",
19+
"inference",
1820
"quick_qc",
1921
"reduce_to_aseg",
2022
"pipeline",

invesalius/segmentation/deep_learning/fastsurfer_subpart/data_process.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,6 @@ def read_classes_from_lut(lut_file: str | Path):
148148
dtype=names,
149149
**kwargs,
150150
)
151-
return lut
152151

153152

154153
def aparc_aseg_to_label(

invesalius/segmentation/deep_learning/fastsurfer_subpart/misc.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -831,9 +831,7 @@ def make_subjects_dir(self):
831831
Try to create the subject directory.
832832
"""
833833
if self.config.out_dir is None:
834-
LOGGER.info(
835-
"No Subjects directory found, absolute paths for filenames are " "required."
836-
)
834+
LOGGER.info("No Subjects directory found, absolute paths for filenames are required.")
837835
return
838836

839837
LOGGER.info(f"Output will be stored in Subjects Directory: {self.config.out_dir}")

0 commit comments

Comments
 (0)