Skip to content

Commit 3e32b87

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 c215fc8 commit 3e32b87

File tree

3 files changed

+38
-723
lines changed

3 files changed

+38
-723
lines changed

niworkflows/anat/ants.py

Lines changed: 30 additions & 66 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,7 +332,6 @@ 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)]),
@@ -355,19 +349,11 @@ def init_brain_extraction_wf(
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,16 @@ 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")]),
653632
(inputnode, atropos, [
654633
("in_files", "intensity_images"),
655634
("in_mask_dilated", "mask_image"),
656635
]),
657-
(inputnode, msk_conform, [(("in_files", _pop), "in_reference")]),
658636
(atropos, pad_segm, [("classified_image", "op1")]),
659637
(pad_segm, sel_labels, [("output_image", "in_segm")]),
660638
(sel_labels, get_wm, [("out_wm", "op1")]),
@@ -687,15 +665,10 @@ def init_atropos_wf(
687665
(depad_csf, merge_tpms, [("output_image", "in1")]),
688666
(depad_gm, merge_tpms, [("output_image", "in2")]),
689667
(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-
]),
668+
(depad_mask, msk_dtype, [("output_image", "in_mask")]),
669+
(msk_dtype, outputnode, [("out", "out_mask")]),
670+
(depad_segm, outputnode, [("output_image", "out_segm")]),
671+
(merge_tpms, outputnode, [("out", "out_tpms")]),
699672
])
700673
# fmt: on
701674
return wf
@@ -747,7 +720,7 @@ def init_n4_only_wf(
747720
Allows to specify a particular segmentation model, overwriting
748721
the defaults based on ``bids_suffix``
749722
name : str, optional
750-
Workflow name (default: ``'n4_only_wf'``).
723+
Workflow name (default: ``"n4_only_wf"``).
751724
752725
Inputs
753726
------
@@ -923,34 +896,25 @@ def _select_labels(in_segm, labels):
923896
return out_files
924897

925898

926-
def _conform_mask(in_mask, in_reference):
927-
"""Ensures the mask headers make sense and match those of the T1w"""
899+
def _ensure_dtype(in_mask, dtype="uint8"):
900+
"""Ensure the mask headers make sense and match those of the T1w."""
928901
from pathlib import Path
929902
import numpy as np
930903
import nibabel as nb
931904
from nipype.utils.filemanip import fname_presuffix
932905

933-
ref = nb.load(in_reference)
934906
nii = nb.load(in_mask)
935907
hdr = nii.header.copy()
936-
hdr.set_data_dtype("int16")
908+
hdr.set_data_dtype(dtype)
937909
hdr.set_slope_inter(1, 0)
938910

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-
947911
if "_maths" in in_mask: # Cut the name at first _maths occurrence
948912
ext = "".join(Path(in_mask).suffixes)
949913
basename = Path(in_mask).name
950914
in_mask = basename.split("_maths")[0] + ext
951915

952916
out_file = fname_presuffix(in_mask, suffix="_mask", newpath=str(Path()))
953917
nii.__class__(
954-
np.asanyarray(nii.dataobj).astype("int16"), ref.affine, hdr
918+
np.asanyarray(nii.dataobj).astype(dtype), nii.affine, hdr
955919
).to_filename(out_file)
956920
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)