Skip to content

Commit f5ab000

Browse files
committed
RF/ENH: Clean up template handling, use cleaned T2w instead of raw
1 parent fe0769b commit f5ab000

File tree

1 file changed

+32
-35
lines changed

1 file changed

+32
-35
lines changed

nibabies/workflows/anatomical/brain_extraction.py

Lines changed: 32 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ def init_infant_brain_extraction_wf(
6060
6161
Inputs
6262
------
63-
in_t2w : :obj:`str`
64-
The unprocessed input T2w image.
63+
t2w_preproc : :obj:`str`
64+
The preprocessed T2w image (Denoising/INU/N4)
6565
6666
Outputs
6767
-------
@@ -87,7 +87,6 @@ def init_infant_brain_extraction_wf(
8787
BinaryDilation,
8888
IntensityClip,
8989
)
90-
from templateflow.api import get as get_template
9190

9291
from ...utils.misc import cohort_by_months
9392

@@ -101,41 +100,20 @@ def init_infant_brain_extraction_wf(
101100
raise KeyError(f"Age or cohort for {skull_strip_template} must be provided!")
102101
template_specs["cohort"] = cohort_by_months(skull_strip_template, age_months)
103102

104-
tpl_target_path = get_template(
105-
skull_strip_template,
106-
suffix="T1w", # no T2w template
107-
desc=None,
108-
**template_specs,
109-
)
110-
if not tpl_target_path:
111-
raise RuntimeError(
112-
f"An instance of template <tpl-{skull_strip_template}> with T1w suffix "
113-
"could not be found."
114-
)
115-
116-
tpl_brainmask_path = get_template(
117-
skull_strip_template, label="brain", suffix="probseg", **template_specs
118-
) or get_template(skull_strip_template, desc="brain", suffix="mask", **template_specs)
119-
120-
tpl_regmask_path = get_template(
121-
skull_strip_template,
122-
label="BrainCerebellumExtraction",
123-
suffix="mask",
124-
**template_specs,
125-
)
103+
template_files = fetch_templates(skull_strip_template, template_specs)
126104

127105
# main workflow
128106
workflow = pe.Workflow(name)
129107

130-
inputnode = pe.Node(niu.IdentityInterface(fields=["in_t2w"]), name="inputnode")
108+
inputnode = pe.Node(niu.IdentityInterface(fields=["t2w_preproc"]), name="inputnode")
131109
outputnode = pe.Node(
132-
niu.IdentityInterface(fields=["t2w_preproc", "t2w_brain", "out_mask", "out_probmap"]),
110+
niu.IdentityInterface(fields=["t2w_brain", "out_mask", "out_probmap"]),
133111
name="outputnode",
134112
)
135113

136114
# Ensure template comes with a range of intensities ANTs will like
137115
clip_tmpl = pe.Node(IntensityClip(p_max=99), name="clip_tmpl")
138-
clip_tmpl.inputs.in_file = _pop(tpl_target_path)
116+
clip_tmpl.inputs.in_file = _pop(template_files['anat'])
139117

140118
# Generate laplacian registration targets
141119
lap_tmpl = pe.Node(ImageMath(operation="Laplacian", op2="0.4 1"), name="lap_tmpl")
@@ -147,13 +125,15 @@ def init_infant_brain_extraction_wf(
147125
mrg_tmpl = pe.Node(niu.Merge(2), name="mrg_tmpl", run_without_submitting=True)
148126
mrg_t2w = pe.Node(niu.Merge(2), name="mrg_t2w", run_without_submitting=True)
149127
bin_regmask = pe.Node(Binarize(thresh_low=0.20), name="bin_regmask")
150-
bin_regmask.inputs.in_file = str(tpl_brainmask_path)
128+
bin_regmask.inputs.in_file = str(template_files['mask'])
151129
refine_mask = pe.Node(BinaryDilation(radius=3, iterations=2), name="refine_mask")
152130

153131
fixed_masks = pe.Node(niu.Merge(4), name="fixed_masks", run_without_submitting=True)
154132
fixed_masks.inputs.in1 = "NULL"
155133
fixed_masks.inputs.in2 = "NULL"
156-
fixed_masks.inputs.in3 = "NULL" if not tpl_regmask_path else _pop(tpl_regmask_path)
134+
fixed_masks.inputs.in3 = (
135+
"NULL" if not template_files['regmask'] else _pop(template_files['regmask'])
136+
)
157137

158138
# Set up initial spatial normalization
159139
ants_params = "testing" if sloppy else "precise"
@@ -176,7 +156,7 @@ def init_infant_brain_extraction_wf(
176156
)
177157

178158
# map template brainmask to t2w space
179-
map_mask_t2w.inputs.input_image = str(tpl_brainmask_path)
159+
map_mask_t2w.inputs.input_image = str(template_files['mask'])
180160

181161
thr_t2w_mask = pe.Node(Binarize(thresh_low=0.80), name="thr_t2w_mask")
182162

@@ -200,7 +180,7 @@ def init_infant_brain_extraction_wf(
200180

201181
# fmt:off
202182
workflow.connect([
203-
(inputnode, final_n4, [("in_t2w", "input_image")]),
183+
(inputnode, final_n4, [("t2w_preproc", "input_image")]),
204184
# 1. Massage T2w
205185
(inputnode, mrg_t2w, [("in_t2w", "in1")]),
206186
(inputnode, lap_t2w, [("in_t2w", "op1")]),
@@ -229,7 +209,7 @@ def init_infant_brain_extraction_wf(
229209
# 5. Refine T2w INU correction with brain mask
230210
(map_mask_t2w, final_n4, [("output_image", "weight_image")]),
231211
(final_n4, final_clip, [("output_image", "in_file")]),
232-
# 9. Outputs
212+
# 6. Outputs
233213
(final_clip, outputnode, [("out_file", "t2w_preproc")]),
234214
(map_mask_t2w, outputnode, [("output_image", "out_probmap")]),
235215
(thr_t2w_mask, outputnode, [("out_mask", "out_mask")]),
@@ -255,8 +235,8 @@ def init_infant_brain_extraction_wf(
255235
name="init_aff",
256236
n_procs=omp_nthreads,
257237
)
258-
if tpl_regmask_path:
259-
init_aff.inputs.fixed_image_mask = _pop(tpl_regmask_path)
238+
if template_files['regmask']:
239+
init_aff.inputs.fixed_image_mask = _pop(template_files['regmask'])
260240

261241
# fmt:off
262242
workflow.connect([
@@ -349,3 +329,20 @@ def _norm_lap(in_file):
349329
hdr.set_data_dtype("float32")
350330
img.__class__(data.astype("float32"), img.affine, hdr).to_filename(out_file)
351331
return out_file
332+
333+
334+
def fetch_templates(template: str, specs: dict) -> dict:
335+
from templateflow.api import get
336+
337+
template_files = {}
338+
# Anatomical reference
339+
template_files['anat'] = get(template, suffix="T1w", desc=None, raise_empty=True, **specs)
340+
# Anatomical mask, prefer probseg if available
341+
template_files['mask'] = get(template, label="brain", suffix="probseg", **specs) or get(
342+
template, desc="brain", suffix="mask", **specs
343+
)
344+
# More dilated mask to facilitate registration
345+
template_files['regmask'] = get(
346+
template, label="BrainCerebellumExtraction", suffix="mask", **specs
347+
)
348+
return template_files

0 commit comments

Comments
 (0)