Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ repos:
args: ["--py313-plus"]
files: ^itkit/
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.15.21
rev: v0.16.5
hooks:
- id: ruff-check
types_or: [ python, pyi ]
Expand All @@ -36,7 +36,7 @@ repos:
- id: requirements-txt-fixer
- id: trailing-whitespace
- repo: https://github.com/PyCQA/isort
rev: 9.0.0b1
rev: 9.0.1
hooks:
- id: isort
files: ^itkit/
Expand Down
18 changes: 8 additions & 10 deletions SlicerITKIT/ITKITInference/ITKITInference.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import logging
import os
import tempfile
from typing import Optional

import ctk
import qt
Expand Down Expand Up @@ -279,7 +278,6 @@ def setup(self) -> None:

def cleanup(self) -> None:
"""Called when the application closes and the module widget is destroyed."""
pass

def onServerUrlChanged(self):
"""Called when server URL changes."""
Expand Down Expand Up @@ -330,8 +328,8 @@ def onConnectButton(self):
LOGGER.exception("Connect to server failed")
self.serverStatusLabel.setText("Connection failed")
self.serverStatusLabel.setStyleSheet("color: red;")
self.statusLabel.setText(f"Error: {str(e)}")
slicer.util.errorDisplay(f"Failed to connect to server: {str(e)}")
self.statusLabel.setText(f"Error: {e!s}")
slicer.util.errorDisplay(f"Failed to connect to server: {e!s}")

def updateModelStatus(self, model_info):
"""Update the current model status display."""
Expand Down Expand Up @@ -453,8 +451,8 @@ def onLoadModelButton(self):
except Exception as e:
LOGGER.exception("Load model failed")
self.progressBar.hide()
self.statusLabel.setText(f"Error: {str(e)}")
slicer.util.errorDisplay(f"Failed to load model: {str(e)}")
self.statusLabel.setText(f"Error: {e!s}")
slicer.util.errorDisplay(f"Failed to load model: {e!s}")

def onUnloadModelButton(self):
"""Unload the current model from the server."""
Expand All @@ -474,7 +472,7 @@ def onUnloadModelButton(self):

except Exception as e:
LOGGER.exception("Unload model failed")
slicer.util.errorDisplay(f"Failed to unload model: {str(e)}")
slicer.util.errorDisplay(f"Failed to unload model: {e!s}")

def onApplyButton(self):
"""Run processing when user clicks "Apply" button."""
Expand Down Expand Up @@ -531,8 +529,8 @@ def onComplete():
LOGGER.exception("Inference failed")

def onError():
slicer.util.errorDisplay(f"Inference failed: {str(e)}")
self.statusLabel.setText(f"Error: {str(e)}")
slicer.util.errorDisplay(f"Inference failed: {e!s}")
self.statusLabel.setText(f"Error: {e!s}")
self.applyButton.enabled = True
self.progressBar.hide()

Expand Down Expand Up @@ -572,7 +570,7 @@ def load_model(
self,
server_url: str,
backend_type: str,
config_path: Optional[str],
config_path: str | None,
model_path: str,
inference_config: dict,
) -> bool:
Expand Down
7 changes: 4 additions & 3 deletions SlicerITKIT/server/itkit_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import torch
from flask import Flask, jsonify, request, send_file
from flask_cors import CORS

from itkit.mm.inference import (
InferenceConfig,
Inferencer_Seg3D,
Expand Down Expand Up @@ -54,9 +55,9 @@ def __init__(
self,
name: str,
backend_type: str,
config_path: Optional[str],
config_path: str | None,
model_path: str,
inference_config: Optional[dict] = None,
inference_config: dict | None = None,
):
self.name = name
self.backend_type = backend_type # 'mmengine' or 'onnx'
Expand Down Expand Up @@ -119,7 +120,7 @@ def to_dict(self):

def _get_windowing_from_model(
model: ModelConfig,
) -> tuple[Optional[float], Optional[float]]:
) -> tuple[float | None, float | None]:
"""Try to read window level/width from backend metadata or config."""
if model.backend_type.lower() == "mmengine":
cfg = getattr(model.backend, "cfg", None)
Expand Down
1 change: 1 addition & 0 deletions examples/configs/0.0.AbdomenCT1K_TorchIO/MedNeXt.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from mmengine.config import read_base

with read_base():
from .mgam import *

Expand Down
1 change: 1 addition & 0 deletions examples/configs/0.0.AbdomenCT1K_TorchIO/SegFormer3D.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from mmengine.config import read_base

with read_base():
from .mgam import *

Expand Down
47 changes: 24 additions & 23 deletions examples/configs/0.0.AbdomenCT1K_TorchIO/mgam.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,36 @@
from torch.optim.adamw import AdamW
from torch.distributed.fsdp.api import ShardingStrategy

from mmengine.runner import ValLoop
from mmengine.runner import TestLoop
from mmengine.hooks.iter_timer_hook import IterTimerHook
from mmengine.hooks.param_scheduler_hook import ParamSchedulerHook
from mmengine.hooks.checkpoint_hook import CheckpointHook
from mmengine.hooks import DistSamplerSeedHook
from mmengine.runner import IterBasedTrainLoop
from mmengine.optim.scheduler import LinearLR, PolyLR
from mmengine.optim import OptimWrapper, AmpOptimWrapper
from mmengine.model.wrappers import MMFullyShardedDataParallel
from mmengine._strategy.deepspeed import DeepSpeedOptimWrapper, DeepSpeedStrategy
from mmengine.dataset.sampler import DefaultSampler, InfiniteSampler
from mmengine.dataset.utils import default_collate
from mmengine.hooks import DistSamplerSeedHook
from mmengine.hooks.checkpoint_hook import CheckpointHook
from mmengine.hooks.iter_timer_hook import IterTimerHook
from mmengine.hooks.param_scheduler_hook import ParamSchedulerHook
from mmengine.model.wrappers import MMFullyShardedDataParallel
from mmengine.optim import AmpOptimWrapper, OptimWrapper
from mmengine.optim.scheduler import LinearLR, PolyLR
from mmengine.runner import IterBasedTrainLoop, TestLoop, ValLoop
from mmengine.visualization import TensorboardVisBackend
from torch.distributed.fsdp.api import ShardingStrategy
from torch.optim.adamw import AdamW

from itkit.dataset import ITKITConcatDataset
from itkit.dataset.AbdomenCT_1K.mm_dataset import AbdomenCT_1K_Mha
from itkit.dataset.torchio import TorchIO_PatchedDataset

# customize
from itkit.mm.mmeng_PlugIn import (
RemasteredDDP, LoggerJSON, RuntimeInfoHook, multi_sample_collate,
RatioSampler, RemasteredFSDP_Strategy)
from itkit.process.GeneralPreProcess import WindowSet, TypeConvert
from itkit.process.LoadBiomedicalData import LoadImageFromMHA, LoadMaskFromMHA
LoggerJSON,
RatioSampler,
RemasteredDDP,
RemasteredFSDP_Strategy,
RuntimeInfoHook,
multi_sample_collate,
)
from itkit.mm.mmseg_Dev3D import PackSeg3DInputs, Seg3DDataPreProcessor
from itkit.mm.mmseg_PlugIn import IoUMetric_PerClass
from itkit.dataset import ITKITConcatDataset
from itkit.dataset.torchio import TorchIO_PatchedDataset
from itkit.dataset.AbdomenCT_1K.mm_dataset import AbdomenCT_1K_Mha
from itkit.mm.visualization import SegViser, BaseVisHook, LocalVisBackend


from itkit.mm.visualization import BaseVisHook, LocalVisBackend, SegViser
from itkit.process.GeneralPreProcess import TypeConvert, WindowSet
from itkit.process.LoadBiomedicalData import LoadImageFromMHA, LoadMaskFromMHA

# --------------------PARAMETERS-------------------- #

Expand Down
1 change: 1 addition & 0 deletions examples/configs/0.1.AbdomenCT1K_MONAI/MedNeXt.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from mmengine.config import read_base

with read_base():
from .mgam import *

Expand Down
1 change: 1 addition & 0 deletions examples/configs/0.1.AbdomenCT1K_MONAI/SegFormer3D.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from mmengine.config import read_base

with read_base():
from .mgam import *

Expand Down
47 changes: 24 additions & 23 deletions examples/configs/0.1.AbdomenCT1K_MONAI/mgam.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,36 @@
from torch.optim.adamw import AdamW
from torch.distributed.fsdp.api import ShardingStrategy

from mmengine.runner import ValLoop
from mmengine.runner import TestLoop
from mmengine.hooks.iter_timer_hook import IterTimerHook
from mmengine.hooks.param_scheduler_hook import ParamSchedulerHook
from mmengine.hooks.checkpoint_hook import CheckpointHook
from mmengine.hooks import DistSamplerSeedHook
from mmengine.runner import IterBasedTrainLoop
from mmengine.optim.scheduler import LinearLR, PolyLR
from mmengine.optim import OptimWrapper, AmpOptimWrapper
from mmengine.model.wrappers import MMFullyShardedDataParallel
from mmengine._strategy.deepspeed import DeepSpeedOptimWrapper, DeepSpeedStrategy
from mmengine.dataset.sampler import DefaultSampler, InfiniteSampler
from mmengine.dataset.utils import default_collate
from mmengine.hooks import DistSamplerSeedHook
from mmengine.hooks.checkpoint_hook import CheckpointHook
from mmengine.hooks.iter_timer_hook import IterTimerHook
from mmengine.hooks.param_scheduler_hook import ParamSchedulerHook
from mmengine.model.wrappers import MMFullyShardedDataParallel
from mmengine.optim import AmpOptimWrapper, OptimWrapper
from mmengine.optim.scheduler import LinearLR, PolyLR
from mmengine.runner import IterBasedTrainLoop, TestLoop, ValLoop
from mmengine.visualization import TensorboardVisBackend
from torch.distributed.fsdp.api import ShardingStrategy
from torch.optim.adamw import AdamW

from itkit.dataset import ITKITConcatDataset
from itkit.dataset.AbdomenCT_1K.mm_dataset import AbdomenCT_1K_Mha
from itkit.dataset.monai import MONAI_PatchedDataset

# customize
from itkit.mm.mmeng_PlugIn import (
RemasteredDDP, LoggerJSON, RuntimeInfoHook, multi_sample_collate,
RatioSampler, RemasteredFSDP_Strategy)
from itkit.process.GeneralPreProcess import WindowSet, TypeConvert
from itkit.process.LoadBiomedicalData import LoadImageFromMHA, LoadMaskFromMHA
LoggerJSON,
RatioSampler,
RemasteredDDP,
RemasteredFSDP_Strategy,
RuntimeInfoHook,
multi_sample_collate,
)
from itkit.mm.mmseg_Dev3D import PackSeg3DInputs, Seg3DDataPreProcessor
from itkit.mm.mmseg_PlugIn import IoUMetric_PerClass
from itkit.dataset import ITKITConcatDataset
from itkit.dataset.monai import MONAI_PatchedDataset
from itkit.dataset.AbdomenCT_1K.mm_dataset import AbdomenCT_1K_Mha
from itkit.mm.visualization import SegViser, BaseVisHook, LocalVisBackend


from itkit.mm.visualization import BaseVisHook, LocalVisBackend, SegViser
from itkit.process.GeneralPreProcess import TypeConvert, WindowSet
from itkit.process.LoadBiomedicalData import LoadImageFromMHA, LoadMaskFromMHA

# --------------------PARAMETERS-------------------- #

Expand Down
1 change: 1 addition & 0 deletions examples/configs/0.2.AbdomenCT1K_ITKIT/MedNeXt.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from mmengine.config import read_base

with read_base():
from .mgam import *

Expand Down
1 change: 1 addition & 0 deletions examples/configs/0.2.AbdomenCT1K_ITKIT/SegFormer3D.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from mmengine.config import read_base

with read_base():
from .mgam import *

Expand Down
45 changes: 23 additions & 22 deletions examples/configs/0.2.AbdomenCT1K_ITKIT/mgam.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,35 @@
from torch.optim.adamw import AdamW
from torch.distributed.fsdp.api import ShardingStrategy

from mmengine.runner import ValLoop
from mmengine.runner import TestLoop
from mmengine.hooks.iter_timer_hook import IterTimerHook
from mmengine.hooks.param_scheduler_hook import ParamSchedulerHook
from mmengine.hooks.checkpoint_hook import CheckpointHook
from mmengine.hooks import DistSamplerSeedHook
from mmengine.runner import IterBasedTrainLoop
from mmengine.optim.scheduler import LinearLR, PolyLR
from mmengine.optim import OptimWrapper, AmpOptimWrapper
from mmengine.model.wrappers import MMFullyShardedDataParallel
from mmengine._strategy.deepspeed import DeepSpeedOptimWrapper, DeepSpeedStrategy
from mmengine.dataset.sampler import DefaultSampler, InfiniteSampler
from mmengine.dataset.utils import default_collate
from mmengine.hooks import DistSamplerSeedHook
from mmengine.hooks.checkpoint_hook import CheckpointHook
from mmengine.hooks.iter_timer_hook import IterTimerHook
from mmengine.hooks.param_scheduler_hook import ParamSchedulerHook
from mmengine.model.wrappers import MMFullyShardedDataParallel
from mmengine.optim import AmpOptimWrapper, OptimWrapper
from mmengine.optim.scheduler import LinearLR, PolyLR
from mmengine.runner import IterBasedTrainLoop, TestLoop, ValLoop
from mmengine.visualization import TensorboardVisBackend
from torch.distributed.fsdp.api import ShardingStrategy
from torch.optim.adamw import AdamW

from itkit.dataset import ITKITConcatDataset
from itkit.dataset.AbdomenCT_1K.mm_dataset import AbdomenCT_1K_Mha, AbdomenCT_1K_Patch

# customize
from itkit.mm.mmeng_PlugIn import (
RemasteredDDP, LoggerJSON, RuntimeInfoHook, multi_sample_collate,
RatioSampler, RemasteredFSDP_Strategy)
from itkit.process.GeneralPreProcess import WindowSet, TypeConvert
from itkit.process.LoadBiomedicalData import LoadImageFromMHA, LoadMaskFromMHA
LoggerJSON,
RatioSampler,
RemasteredDDP,
RemasteredFSDP_Strategy,
RuntimeInfoHook,
multi_sample_collate,
)
from itkit.mm.mmseg_Dev3D import PackSeg3DInputs, Seg3DDataPreProcessor
from itkit.mm.mmseg_PlugIn import IoUMetric_PerClass
from itkit.dataset import ITKITConcatDataset
from itkit.dataset.AbdomenCT_1K.mm_dataset import AbdomenCT_1K_Mha, AbdomenCT_1K_Patch
from itkit.mm.visualization import SegViser, BaseVisHook, LocalVisBackend


from itkit.mm.visualization import BaseVisHook, LocalVisBackend, SegViser
from itkit.process.GeneralPreProcess import TypeConvert, WindowSet
from itkit.process.LoadBiomedicalData import LoadImageFromMHA, LoadMaskFromMHA

# --------------------PARAMETERS-------------------- #

Expand Down
17 changes: 8 additions & 9 deletions itkit/dataset/BraTs2024/convert_nii_mha.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,15 +131,14 @@ def convert_brats_to_mha(input_dir, dest_root, spacing=None, size=None, use_mp=F
partial_convert_func = partial(convert_case, dest_root=dest_root, spacing=spacing, size=size)

if use_mp:
with mp.Pool(mp.cpu_count()) as pool:
with tqdm(
total=len(case_dirs),
desc="Converting BraTs2024",
dynamic_ncols=True,
leave=False
) as pbar:
for _ in pool.imap_unordered(partial_convert_func, case_dirs):
pbar.update()
with mp.Pool(mp.cpu_count()) as pool, tqdm(
total=len(case_dirs),
desc="Converting BraTs2024",
dynamic_ncols=True,
leave=False
) as pbar:
for _ in pool.imap_unordered(partial_convert_func, case_dirs):
pbar.update()
else:
with tqdm(total=len(case_dirs), desc="Converting Cases") as pbar:
for case_dir in case_dirs:
Expand Down
4 changes: 2 additions & 2 deletions itkit/dataset/Totalsegmentator/fix_ITKUnreadable_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def fix_nifti_file(input_path, output_path):
nib.save(img, output_path)
return True
except Exception as e:
print(f"处理文件 {input_path} 时出错: {str(e)}")
print(f"处理文件 {input_path} 时出错: {e!s}")
return False


Expand All @@ -39,7 +39,7 @@ def process_file(file_path, input_root, output_root):
output_path = output_root / rel_path
return fix_nifti_file(file_path, output_path)
except ValueError as e:
print(f"计算相对路径时出错: {str(e)}")
print(f"计算相对路径时出错: {e!s}")
return False


Expand Down
6 changes: 3 additions & 3 deletions itkit/dataset/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ def sample_iterator(self) -> Generator[tuple[str, str]]:
if not os.path.exists(image_mha_path):
print_log(f"{series} image mha file not found.\nFullPath: {image_mha_path}",
MMLogger.get_current_instance(),
logging.WARN)
logging.WARNING)
continue
yield (image_mha_path, label_mha_path)

Expand Down Expand Up @@ -253,11 +253,11 @@ def sample_iterator(self) -> Generator[tuple[str, str]]:
# List all image files that match the current series UID
# Files are in format: <seriesUID>_<patchID>.mha (e.g., 1.3.6.1.4.1.9328.50.4.0095_p0.mha)
if not os.path.exists(image_folder):
print_log(f"Image folder not found: {image_folder}", MMLogger.get_current_instance(), logging.WARN)
print_log(f"Image folder not found: {image_folder}", MMLogger.get_current_instance(), logging.WARNING)
continue

if series not in self.precrop_meta["patch_meta"]:
print_log(f"Series {series} not found in patch metadata", MMLogger.get_current_instance(), logging.WARN)
print_log(f"Series {series} not found in patch metadata", MMLogger.get_current_instance(), logging.WARNING)
continue
series_patch_files = self.precrop_meta["patch_meta"][series]["class_within_patch"].keys()

Expand Down
Loading
Loading