Skip to content

Commit d1cba2f

Browse files
authored
Merge pull request #113 from sarthakpati/cli
Added a simple CLI using `typer`
2 parents 8e1a231 + 4639dba commit d1cba2f

File tree

5 files changed

+163
-6
lines changed

5 files changed

+163
-6
lines changed

brainles_preprocessing/cli.py

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
from typing import Optional
2+
from pathlib import Path
3+
import typer
4+
from typing_extensions import Annotated
5+
from importlib.metadata import version
6+
7+
8+
from brainles_preprocessing.modality import Modality, CenterModality
9+
from brainles_preprocessing.normalization.percentile_normalizer import (
10+
PercentileNormalizer,
11+
)
12+
from brainles_preprocessing.preprocessor import Preprocessor
13+
14+
15+
def version_callback(value: bool):
16+
__version__ = version("brainles_preprocessing")
17+
if value:
18+
typer.echo(f"Preprocessor CLI v{__version__}")
19+
raise typer.Exit()
20+
21+
22+
app = typer.Typer(
23+
context_settings={"help_option_names": ["-h", "--help"]}, add_completion=False
24+
)
25+
26+
27+
@app.command()
28+
def main(
29+
input_t1c: Annotated[
30+
str,
31+
typer.Option(
32+
"-t1c",
33+
"--input_t1c",
34+
help="The path to the T1c image",
35+
),
36+
],
37+
input_t1: Annotated[
38+
str,
39+
typer.Option(
40+
"-t1",
41+
"--input_t1",
42+
help="The path to the T1 image",
43+
),
44+
],
45+
input_t2: Annotated[
46+
str,
47+
typer.Option(
48+
"-t2",
49+
"--input_t2",
50+
help="The path to the T2 image",
51+
),
52+
],
53+
input_fla: Annotated[
54+
str,
55+
typer.Option(
56+
"-fl",
57+
"--input_fla",
58+
help="The path to the FLAIR image",
59+
),
60+
],
61+
output_dir: Annotated[
62+
str,
63+
typer.Option(
64+
"-o",
65+
"--output_dir",
66+
help="The path to the output directory",
67+
),
68+
],
69+
input_atlas: Annotated[
70+
Optional[str],
71+
typer.Option(
72+
"-a",
73+
"--input_atlas",
74+
help="The path to the atlas image",
75+
),
76+
] = "SRI24 BraTS atlas",
77+
version: Annotated[
78+
Optional[bool],
79+
typer.Option(
80+
"-v",
81+
"--version",
82+
callback=version_callback,
83+
is_eager=True,
84+
help="Print the version and exit.",
85+
),
86+
] = None,
87+
):
88+
"""
89+
Preprocess the input images according to the BraTS protocol.
90+
"""
91+
92+
output_dir = Path(output_dir)
93+
output_dir.mkdir(parents=True, exist_ok=True)
94+
95+
# specify a normalizer
96+
percentile_normalizer = PercentileNormalizer(
97+
lower_percentile=0.1,
98+
upper_percentile=99.9,
99+
lower_limit=0,
100+
upper_limit=1,
101+
)
102+
103+
# define center and moving modalities
104+
center = CenterModality(
105+
modality_name="t1c",
106+
input_path=input_t1c,
107+
normalizer=percentile_normalizer,
108+
# specify the output paths for the raw and normalized images of each step - here only for atlas registered and brain extraction
109+
raw_skull_output_path=output_dir / "t1c_skull_raw.nii.gz",
110+
raw_bet_output_path=output_dir / "t1c_bet_raw.nii.gz",
111+
raw_defaced_output_path=output_dir / "t1c_defaced_raw.nii.gz",
112+
normalized_skull_output_path=output_dir / "t1c_skull_normalized.nii.gz",
113+
normalized_bet_output_path=output_dir / "t1c_bet_normalized.nii.gz",
114+
normalized_defaced_output_path=output_dir / "t1c_defaced_normalized.nii.gz",
115+
# specify output paths for the brain extraction and defacing masks
116+
bet_mask_output_path=output_dir / "t1c_bet_mask.nii.gz",
117+
defacing_mask_output_path=output_dir / "t1c_defacing_mask.nii.gz",
118+
)
119+
120+
for modality in ["t1", "t2", "fla"]:
121+
moving_modalities = [
122+
Modality(
123+
modality_name=modality,
124+
input_path=eval(f"input_{modality}"),
125+
normalizer=percentile_normalizer,
126+
# specify the output paths for the raw and normalized images of each step - here only for atlas registered and brain extraction
127+
raw_skull_output_path=output_dir / f"{modality}_skull_raw.nii.gz",
128+
raw_bet_output_path=output_dir / f"{modality}_bet_raw.nii.gz",
129+
raw_defaced_output_path=output_dir / f"{modality}_defaced_raw.nii.gz",
130+
normalized_skull_output_path=output_dir
131+
/ f"{modality}_skull_normalized.nii.gz",
132+
normalized_bet_output_path=output_dir
133+
/ f"{modality}_bet_normalized.nii.gz",
134+
normalized_defaced_output_path=output_dir
135+
/ f"{modality}_defaced_normalized.nii.gz",
136+
)
137+
]
138+
139+
# if the input atlas is the SRI24 BraTS atlas, set it to None, because it will be picked up through the package
140+
if input_atlas == "SRI24 BraTS atlas":
141+
input_atlas = None
142+
143+
# instantiate and run the preprocessor using defaults for registration/ brain extraction/ defacing backends
144+
preprocessor = Preprocessor(
145+
center_modality=center,
146+
moving_modalities=moving_modalities,
147+
temp_folder=output_dir / "temp",
148+
input_atlas=input_atlas,
149+
)
150+
151+
preprocessor.run()
152+
153+
154+
if __name__ == "__main__":
155+
app()

brainles_preprocessing/modality.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,6 @@ def deface(
407407
category=DeprecationWarning,
408408
)
409409
if isinstance(defacer, QuickshearDefacer):
410-
411410
defaced_dir_path = Path(defaced_dir_path)
412411
atlas_mask_path = (
413412
defaced_dir_path / f"atlas__{self.modality_name}_deface_mask.nii.gz"
@@ -595,7 +594,6 @@ def deface(
595594
"""
596595

597596
if isinstance(defacer, QuickshearDefacer):
598-
599597
defaced_dir_path = Path(defaced_dir_path)
600598
atlas_mask_path = (
601599
defaced_dir_path / f"atlas__{self.modality_name}_deface_mask.nii.gz"

brainles_preprocessing/preprocessor.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -379,9 +379,9 @@ def run_atlas_correction(
379379
dst=str(center_atlas_corrected_path),
380380
)
381381
# save step result
382-
self.center_modality.steps[PreprocessorSteps.ATLAS_CORRECTED] = (
383-
center_atlas_corrected_path
384-
)
382+
self.center_modality.steps[
383+
PreprocessorSteps.ATLAS_CORRECTED
384+
] = center_atlas_corrected_path
385385

386386
self._save_output(
387387
src=atlas_correction_dir,

pyproject.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ ttictoc = "^0.5.6"
5454
pathlib = "^1.0.1"
5555
nibabel = ">=3.2.1"
5656
numpy = "^1.23.0"
57+
typer = "^0.15.0"
58+
black = "^22.1.0"
5759

5860
# registration
5961
antspyx = "^0.4.2"
@@ -86,3 +88,6 @@ Sphinx = ">=7.0.0"
8688
sphinx-copybutton = ">=0.5.2"
8789
sphinx-rtd-theme = ">=1.3.0"
8890
myst-parser = ">=2.0.0"
91+
92+
[tool.poetry.scripts]
93+
preprocessor = "brainles_preprocessing.cli:app"

tests/registrator_base.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77

88
class RegistratorBase:
9-
109
@abstractmethod
1110
def get_registrator(self):
1211
pass

0 commit comments

Comments
 (0)