Skip to content

Commit fe0769b

Browse files
committed
ENH: Extract shared anat preprocessing step into standalone workflow
1 parent b1ec6e1 commit fe0769b

File tree

1 file changed

+64
-0
lines changed

1 file changed

+64
-0
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import nipype.engine.pipeline as pe
2+
import nipype.interfaces.utility as niu
3+
from niworkflows.engine.workflows import LiterateWorkflow
4+
5+
6+
def init_preproc_anat_wf(
7+
*, bspline_fitting_distance: int = 200, name: str = "preproc_anat_wf"
8+
) -> LiterateWorkflow:
9+
"""Polish up raw anatomical data.
10+
11+
This workflow accepts T1w/T2w images as inputs (either raw or a merged template) and performs:
12+
- Intesity clipping
13+
- Denoising
14+
- N4 Bias Field Correction
15+
16+
The outputs of this workflow will be used to either create the brainmask,
17+
or reconstruct the cortical surfaces.
18+
19+
Inputs
20+
------
21+
in_anat : :obj:`str`
22+
A single volume T1w/T2w image
23+
24+
Outputs
25+
-------
26+
anat_preproc: :obj:`str`
27+
Preprocessed anatomical image (Denoising/INU/Clipping)
28+
"""
29+
from nipype.interfaces.ants import DenoiseImage, N4BiasFieldCorrection
30+
from niworkflows.interfaces.nibabel import IntensityClip
31+
32+
wf = LiterateWorkflow(name=name)
33+
inputnode = pe.Node(niu.IdentityInterface(fields=["in_anat"]), name="inputnode")
34+
outputnode = pe.Node(niu.IdentityInterface(fields=["anat_preproc"]), name="outputnode")
35+
36+
clip = pe.Node(IntensityClip(p_min=10.0, p_max=99.5), name="clip")
37+
denoise = pe.Node(DenoiseImage(dimension=3, noise_model="Rician"), name="denoise")
38+
n4_correct = pe.Node(
39+
N4BiasFieldCorrection(
40+
dimension=3,
41+
bspline_fitting_distance=bspline_fitting_distance,
42+
save_bias=True,
43+
copy_header=True,
44+
n_iterations=[50] * 5,
45+
convergence_threshold=1e-7,
46+
rescale_intensities=True,
47+
shrink_factor=4,
48+
),
49+
name="n4_correct",
50+
)
51+
52+
final_clip = pe.Node(IntensityClip(p_min=5.0, p_max=99.5), name="final_clip")
53+
54+
# fmt:off
55+
wf.connect([
56+
# 1. Massage T2w
57+
(inputnode, clip, [("in_anat", "in_file")]),
58+
(clip, denoise, [("out_file", "input_image")]),
59+
(denoise, n4_correct, [("output_image", "input_image")]),
60+
(n4_correct, final_clip, [("output_image", "in_file")]),
61+
(final_clip, outputnode, [("out_file", "anat_preproc")]),
62+
])
63+
# fmt:on
64+
return wf

0 commit comments

Comments
 (0)