Skip to content

Commit 236a0ff

Browse files
committed
MAINT: Finalize upstreaming of ants interfaces to nipype
After nipy/nipype#3210 the ``niworkflows/interfaces/ants.py`` can go in whole.
1 parent a6a328f commit 236a0ff

File tree

3 files changed

+45
-731
lines changed

3 files changed

+45
-731
lines changed

niworkflows/anat/ants.py

Lines changed: 37 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,24 @@
1212
# nipype
1313
from nipype.pipeline import engine as pe
1414
from nipype.interfaces import utility as niu
15-
from nipype.interfaces.fsl.maths import ApplyMask
16-
from nipype.interfaces.ants import N4BiasFieldCorrection, Atropos, MultiplyImages
15+
from nipype.interfaces.ants import (
16+
AI,
17+
Atropos,
18+
MultiplyImages,
19+
N4BiasFieldCorrection,
20+
ResampleImageBySpacing,
21+
ThresholdImage,
22+
)
1723

1824
from ..utils.misc import get_template_specs
1925

2026
# niworkflows
21-
from ..interfaces.ants import (
22-
ImageMath,
23-
ResampleImageBySpacing,
24-
AI,
25-
ThresholdImage,
26-
)
27+
from ..interfaces.nibabel import ApplyMask
28+
from ..interfaces.ants import ImageMath
2729
from ..interfaces.fixes import (
2830
FixHeaderRegistration as Registration,
2931
FixHeaderApplyTransforms as ApplyTransforms,
3032
)
31-
from ..interfaces.utils import CopyXForm
3233
from ..interfaces.nibabel import Binarize
3334

3435

@@ -83,7 +84,7 @@ def init_brain_extraction_wf(
8384
Parameters
8485
----------
8586
in_template : str
86-
Name of the skull-stripping template ('OASIS30ANTs', 'NKI', or
87+
Name of the skull-stripping template ("OASIS30ANTs", "NKI", or
8788
path).
8889
The brain template from which regions will be projected
8990
Anatomical template created using e.g. LPBA40 data set with
@@ -200,12 +201,6 @@ def init_brain_extraction_wf(
200201
name="outputnode",
201202
)
202203

203-
copy_xform = pe.Node(
204-
CopyXForm(fields=["out_file", "out_mask", "bias_corrected", "bias_image"]),
205-
name="copy_xform",
206-
run_without_submitting=True,
207-
)
208-
209204
trunc = pe.MapNode(
210205
ImageMath(operation="TruncateImageIntensity", op2="0.01 0.999 256"),
211206
name="truncate_images",
@@ -337,37 +332,28 @@ def init_brain_extraction_wf(
337332
# fmt: off
338333
wf.connect([
339334
(inputnode, trunc, [("in_files", "op1")]),
340-
(inputnode, copy_xform, [(("in_files", _pop), "hdr_file")]),
341335
(inputnode, inu_n4_final, [("in_files", "input_image")]),
342336
(inputnode, init_aff, [("in_mask", "fixed_image_mask")]),
343337
(inputnode, norm, [("in_mask", fixed_mask_trait)]),
344338
(inputnode, map_brainmask, [(("in_files", _pop), "reference_image")]),
345339
(trunc, inu_n4, [("output_image", "input_image")]),
346-
(inu_n4, res_target, [(("output_image", _pop), "input_image")]),
340+
(inu_n4, res_target, [
341+
(("output_image", _pop), "input_image")]),
347342
(res_tmpl, init_aff, [("output_image", "fixed_image")]),
348343
(res_target, init_aff, [("output_image", "moving_image")]),
349344
(init_aff, norm, [("output_transform", "initial_moving_transform")]),
350345
(norm, map_brainmask, [
351346
("reverse_transforms", "transforms"),
352-
("reverse_invert_flags", "invert_transform_flags"),
353-
]),
347+
("reverse_invert_flags", "invert_transform_flags")]),
354348
(map_brainmask, thr_brainmask, [("output_image", "input_image")]),
355349
(thr_brainmask, dil_brainmask, [("output_image", "op1")]),
356350
(dil_brainmask, get_brainmask, [("output_image", "op1")]),
357351
(inu_n4_final, apply_mask, [("output_image", "in_file")]),
358-
(get_brainmask, apply_mask, [("output_image", "mask_file")]),
359-
(get_brainmask, copy_xform, [("output_image", "out_mask")]),
360-
(apply_mask, copy_xform, [("out_file", "out_file")]),
361-
(inu_n4_final, copy_xform, [
362-
("output_image", "bias_corrected"),
363-
("bias_image", "bias_image"),
364-
]),
365-
(copy_xform, outputnode, [
366-
("out_file", "out_file"),
367-
("out_mask", "out_mask"),
368-
("bias_corrected", "bias_corrected"),
369-
("bias_image", "bias_image"),
370-
]),
352+
(get_brainmask, apply_mask, [("output_image", "in_mask")]),
353+
(get_brainmask, outputnode, [("output_image", "out_mask")]),
354+
(inu_n4_final, outputnode, [("output_image", "bias_corrected"),
355+
("bias_image", "bias_image")]),
356+
(apply_mask, outputnode, [("out_file", "out_file")]),
371357
])
372358
# fmt: on
373359

@@ -417,8 +403,8 @@ def init_brain_extraction_wf(
417403

418404
# fmt: off
419405
wf.disconnect([
420-
(get_brainmask, apply_mask, [("output_image", "mask_file")]),
421-
(copy_xform, outputnode, [("out_mask", "out_mask")]),
406+
(get_brainmask, apply_mask, [("output_image", "in_mask")]),
407+
(get_brainmask, outputnode, [("output_image", "out_mask")]),
422408
])
423409
wf.connect([
424410
(inu_n4, atropos_wf, [("output_image", "inputnode.in_files")]),
@@ -428,7 +414,7 @@ def init_brain_extraction_wf(
428414
]),
429415
(atropos_wf, sel_wm, [("outputnode.out_tpms", "inlist")]),
430416
(sel_wm, inu_n4_final, [("out", "weight_image")]),
431-
(atropos_wf, apply_mask, [("outputnode.out_mask", "mask_file")]),
417+
(atropos_wf, apply_mask, [("outputnode.out_mask", "in_mask")]),
432418
(atropos_wf, outputnode, [
433419
("outputnode.out_mask", "out_mask"),
434420
("outputnode.out_segm", "out_segm"),
@@ -507,7 +493,6 @@ def init_atropos_wf(
507493
out_tpms : str
508494
Output :abbr:`TPMs (tissue probability maps)`
509495
510-
511496
"""
512497
wf = pe.Workflow(name)
513498

@@ -520,12 +505,6 @@ def init_atropos_wf(
520505
name="outputnode",
521506
)
522507

523-
copy_xform = pe.Node(
524-
CopyXForm(fields=["out_mask", "out_segm", "out_tpms"]),
525-
name="copy_xform",
526-
run_without_submitting=True,
527-
)
528-
529508
# Run atropos (core node)
530509
atropos = pe.Node(
531510
Atropos(
@@ -644,17 +623,14 @@ def init_atropos_wf(
644623
ImageMath(operation="PadImage", op2="-%d" % padding), name="27_depad_csf"
645624
)
646625

647-
msk_conform = pe.Node(niu.Function(function=_conform_mask), name="msk_conform")
626+
msk_dtype = pe.Node(niu.Function(function=_ensure_dtype), name="msk_dtype")
627+
msk_dtype.inputs.dtype = "uint8"
648628
merge_tpms = pe.Node(niu.Merge(in_segmentation_model[0]), name="merge_tpms")
649629
# fmt: off
650630
wf.connect([
651-
(inputnode, copy_xform, [(("in_files", _pop), "hdr_file")]),
652631
(inputnode, pad_mask, [("in_mask", "op1")]),
653-
(inputnode, atropos, [
654-
("in_files", "intensity_images"),
655-
("in_mask_dilated", "mask_image"),
656-
]),
657-
(inputnode, msk_conform, [(("in_files", _pop), "in_reference")]),
632+
(inputnode, atropos, [("in_files", "intensity_images"),
633+
("in_mask_dilated", "mask_image")]),
658634
(atropos, pad_segm, [("classified_image", "op1")]),
659635
(pad_segm, sel_labels, [("output_image", "in_segm")]),
660636
(sel_labels, get_wm, [("out_wm", "op1")]),
@@ -670,7 +646,8 @@ def init_atropos_wf(
670646
(relabel_wm, add_gm_wm, [("output_product_image", "op1")]),
671647
(relabel_gm, add_gm_wm, [("output_product_image", "op2")]),
672648
(add_gm_wm, sel_labels2, [("output_image", "in_segm")]),
673-
(sel_labels2, add_7, [("out_wm", "op1"), ("out_gm", "op2")]),
649+
(sel_labels2, add_7, [("out_wm", "op1"),
650+
("out_gm", "op2")]),
674651
(add_7, me_7, [("output_image", "op1")]),
675652
(me_7, comp_7, [("output_image", "op1")]),
676653
(comp_7, md_7, [("output_image", "op1")]),
@@ -687,15 +664,10 @@ def init_atropos_wf(
687664
(depad_csf, merge_tpms, [("output_image", "in1")]),
688665
(depad_gm, merge_tpms, [("output_image", "in2")]),
689666
(depad_wm, merge_tpms, [("output_image", "in3")]),
690-
(depad_mask, msk_conform, [("output_image", "in_mask")]),
691-
(msk_conform, copy_xform, [("out", "out_mask")]),
692-
(depad_segm, copy_xform, [("output_image", "out_segm")]),
693-
(merge_tpms, copy_xform, [("out", "out_tpms")]),
694-
(copy_xform, outputnode, [
695-
("out_mask", "out_mask"),
696-
("out_segm", "out_segm"),
697-
("out_tpms", "out_tpms"),
698-
]),
667+
(depad_mask, msk_dtype, [("output_image", "in_mask")]),
668+
(msk_dtype, outputnode, [("out", "out_mask")]),
669+
(depad_segm, outputnode, [("output_image", "out_segm")]),
670+
(merge_tpms, outputnode, [("out", "out_tpms")]),
699671
])
700672
# fmt: on
701673
return wf
@@ -747,7 +719,7 @@ def init_n4_only_wf(
747719
Allows to specify a particular segmentation model, overwriting
748720
the defaults based on ``bids_suffix``
749721
name : str, optional
750-
Workflow name (default: ``'n4_only_wf'``).
722+
Workflow name (default: ``"n4_only_wf"``).
751723
752724
Inputs
753725
------
@@ -923,34 +895,25 @@ def _select_labels(in_segm, labels):
923895
return out_files
924896

925897

926-
def _conform_mask(in_mask, in_reference):
927-
"""Ensures the mask headers make sense and match those of the T1w"""
898+
def _ensure_dtype(in_mask, dtype="uint8"):
899+
"""Ensure the mask headers make sense and match those of the T1w."""
928900
from pathlib import Path
929901
import numpy as np
930902
import nibabel as nb
931903
from nipype.utils.filemanip import fname_presuffix
932904

933-
ref = nb.load(in_reference)
934905
nii = nb.load(in_mask)
935906
hdr = nii.header.copy()
936-
hdr.set_data_dtype("int16")
907+
hdr.set_data_dtype(dtype)
937908
hdr.set_slope_inter(1, 0)
938909

939-
qform, qcode = ref.header.get_qform(coded=True)
940-
if qcode is not None:
941-
hdr.set_qform(qform, int(qcode))
942-
943-
sform, scode = ref.header.get_sform(coded=True)
944-
if scode is not None:
945-
hdr.set_sform(sform, int(scode))
946-
947910
if "_maths" in in_mask: # Cut the name at first _maths occurrence
948911
ext = "".join(Path(in_mask).suffixes)
949912
basename = Path(in_mask).name
950913
in_mask = basename.split("_maths")[0] + ext
951914

952915
out_file = fname_presuffix(in_mask, suffix="_mask", newpath=str(Path()))
953916
nii.__class__(
954-
np.asanyarray(nii.dataobj).astype("int16"), ref.affine, hdr
917+
np.asanyarray(nii.dataobj).astype(dtype), nii.affine, hdr
955918
).to_filename(out_file)
956919
return out_file

niworkflows/func/util.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66

77
from nipype.pipeline import engine as pe
88
from nipype.interfaces import utility as niu, fsl, afni
9+
from nipype.interfaces.ants.utils import AI
910

1011
from templateflow.api import get as get_template
1112

1213
from ..engine.workflows import LiterateWorkflow as Workflow
13-
from ..interfaces.ants import AI
1414
from ..interfaces.fixes import (
1515
FixHeaderRegistration as Registration,
1616
FixHeaderApplyTransforms as ApplyTransforms,

0 commit comments

Comments
 (0)