12
12
# nipype
13
13
from nipype .pipeline import engine as pe
14
14
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
+ )
17
23
18
24
from ..utils .misc import get_template_specs
19
25
20
26
# 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
27
29
from ..interfaces .fixes import (
28
30
FixHeaderRegistration as Registration ,
29
31
FixHeaderApplyTransforms as ApplyTransforms ,
30
32
)
31
- from ..interfaces .utils import CopyXForm
32
33
from ..interfaces .nibabel import Binarize
33
34
34
35
@@ -83,7 +84,7 @@ def init_brain_extraction_wf(
83
84
Parameters
84
85
----------
85
86
in_template : str
86
- Name of the skull-stripping template (' OASIS30ANTs', ' NKI' , or
87
+ Name of the skull-stripping template (" OASIS30ANTs", " NKI" , or
87
88
path).
88
89
The brain template from which regions will be projected
89
90
Anatomical template created using e.g. LPBA40 data set with
@@ -200,12 +201,6 @@ def init_brain_extraction_wf(
200
201
name = "outputnode" ,
201
202
)
202
203
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
-
209
204
trunc = pe .MapNode (
210
205
ImageMath (operation = "TruncateImageIntensity" , op2 = "0.01 0.999 256" ),
211
206
name = "truncate_images" ,
@@ -337,7 +332,6 @@ def init_brain_extraction_wf(
337
332
# fmt: off
338
333
wf .connect ([
339
334
(inputnode , trunc , [("in_files" , "op1" )]),
340
- (inputnode , copy_xform , [(("in_files" , _pop ), "hdr_file" )]),
341
335
(inputnode , inu_n4_final , [("in_files" , "input_image" )]),
342
336
(inputnode , init_aff , [("in_mask" , "fixed_image_mask" )]),
343
337
(inputnode , norm , [("in_mask" , fixed_mask_trait )]),
@@ -355,19 +349,11 @@ def init_brain_extraction_wf(
355
349
(thr_brainmask , dil_brainmask , [("output_image" , "op1" )]),
356
350
(dil_brainmask , get_brainmask , [("output_image" , "op1" )]),
357
351
(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" )]),
371
357
])
372
358
# fmt: on
373
359
@@ -417,8 +403,8 @@ def init_brain_extraction_wf(
417
403
418
404
# fmt: off
419
405
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" )]),
422
408
])
423
409
wf .connect ([
424
410
(inu_n4 , atropos_wf , [("output_image" , "inputnode.in_files" )]),
@@ -428,7 +414,7 @@ def init_brain_extraction_wf(
428
414
]),
429
415
(atropos_wf , sel_wm , [("outputnode.out_tpms" , "inlist" )]),
430
416
(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 " )]),
432
418
(atropos_wf , outputnode , [
433
419
("outputnode.out_mask" , "out_mask" ),
434
420
("outputnode.out_segm" , "out_segm" ),
@@ -507,7 +493,6 @@ def init_atropos_wf(
507
493
out_tpms : str
508
494
Output :abbr:`TPMs (tissue probability maps)`
509
495
510
-
511
496
"""
512
497
wf = pe .Workflow (name )
513
498
@@ -520,12 +505,6 @@ def init_atropos_wf(
520
505
name = "outputnode" ,
521
506
)
522
507
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
-
529
508
# Run atropos (core node)
530
509
atropos = pe .Node (
531
510
Atropos (
@@ -644,17 +623,16 @@ def init_atropos_wf(
644
623
ImageMath (operation = "PadImage" , op2 = "-%d" % padding ), name = "27_depad_csf"
645
624
)
646
625
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"
648
628
merge_tpms = pe .Node (niu .Merge (in_segmentation_model [0 ]), name = "merge_tpms" )
649
629
# fmt: off
650
630
wf .connect ([
651
- (inputnode , copy_xform , [(("in_files" , _pop ), "hdr_file" )]),
652
631
(inputnode , pad_mask , [("in_mask" , "op1" )]),
653
632
(inputnode , atropos , [
654
633
("in_files" , "intensity_images" ),
655
634
("in_mask_dilated" , "mask_image" ),
656
635
]),
657
- (inputnode , msk_conform , [(("in_files" , _pop ), "in_reference" )]),
658
636
(atropos , pad_segm , [("classified_image" , "op1" )]),
659
637
(pad_segm , sel_labels , [("output_image" , "in_segm" )]),
660
638
(sel_labels , get_wm , [("out_wm" , "op1" )]),
@@ -687,15 +665,10 @@ def init_atropos_wf(
687
665
(depad_csf , merge_tpms , [("output_image" , "in1" )]),
688
666
(depad_gm , merge_tpms , [("output_image" , "in2" )]),
689
667
(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" )]),
699
672
])
700
673
# fmt: on
701
674
return wf
@@ -747,7 +720,7 @@ def init_n4_only_wf(
747
720
Allows to specify a particular segmentation model, overwriting
748
721
the defaults based on ``bids_suffix``
749
722
name : str, optional
750
- Workflow name (default: ``' n4_only_wf' ``).
723
+ Workflow name (default: ``" n4_only_wf" ``).
751
724
752
725
Inputs
753
726
------
@@ -923,34 +896,25 @@ def _select_labels(in_segm, labels):
923
896
return out_files
924
897
925
898
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. """
928
901
from pathlib import Path
929
902
import numpy as np
930
903
import nibabel as nb
931
904
from nipype .utils .filemanip import fname_presuffix
932
905
933
- ref = nb .load (in_reference )
934
906
nii = nb .load (in_mask )
935
907
hdr = nii .header .copy ()
936
- hdr .set_data_dtype ("int16" )
908
+ hdr .set_data_dtype (dtype )
937
909
hdr .set_slope_inter (1 , 0 )
938
910
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
-
947
911
if "_maths" in in_mask : # Cut the name at first _maths occurrence
948
912
ext = "" .join (Path (in_mask ).suffixes )
949
913
basename = Path (in_mask ).name
950
914
in_mask = basename .split ("_maths" )[0 ] + ext
951
915
952
916
out_file = fname_presuffix (in_mask , suffix = "_mask" , newpath = str (Path ()))
953
917
nii .__class__ (
954
- np .asanyarray (nii .dataobj ).astype ("int16" ), ref .affine , hdr
918
+ np .asanyarray (nii .dataobj ).astype (dtype ), nii .affine , hdr
955
919
).to_filename (out_file )
956
920
return out_file
0 commit comments