1212# nipype
1313from nipype .pipeline import engine as pe
1414from nipype .interfaces import utility as niu
15- from nipype .interfaces .fsl .maths import ApplyMask
16- from nipype .interfaces .ants import N4BiasFieldCorrection , Atropos , MultiplyImages
17-
18- from ..utils .misc import get_template_specs
19- # niworkflows
20- from ..interfaces .ants import (
21- ImageMath ,
22- ResampleImageBySpacing ,
15+ from nipype .interfaces .ants import (
2316 AI ,
17+ Atropos ,
18+ MultiplyImages ,
19+ N4BiasFieldCorrection ,
20+ ResampleImageBySpacing ,
2421 ThresholdImage ,
2522)
23+
24+ from ..utils .misc import get_template_specs
25+ # niworkflows
26+ from ..interfaces .nibabel import ApplyMask
27+ from ..interfaces .ants import ImageMath
2628from ..interfaces .fixes import (
2729 FixHeaderRegistration as Registration ,
2830 FixHeaderApplyTransforms as ApplyTransforms ,
2931)
30- from ..interfaces .utils import CopyXForm
3132from ..interfaces .nibabel import Binarize
3233
3334
5354}
5455
5556
56- def init_brain_extraction_wf (name = 'brain_extraction_wf' ,
57- in_template = 'OASIS30ANTs' ,
58- template_spec = None ,
59- use_float = True ,
60- normalization_quality = 'precise' ,
61- omp_nthreads = None ,
62- mem_gb = 3.0 ,
63- bids_suffix = 'T1w' ,
64- atropos_refine = True ,
65- atropos_use_random_seed = True ,
66- atropos_model = None ,
67- use_laplacian = True ,
68- bspline_fitting_distance = 200 ):
57+ def init_brain_extraction_wf (
58+ name = 'brain_extraction_wf' ,
59+ in_template = 'OASIS30ANTs' ,
60+ template_spec = None ,
61+ use_float = True ,
62+ normalization_quality = 'precise' ,
63+ omp_nthreads = None ,
64+ mem_gb = 3.0 ,
65+ bids_suffix = 'T1w' ,
66+ atropos_refine = True ,
67+ atropos_use_random_seed = True ,
68+ atropos_model = None ,
69+ use_laplacian = True ,
70+ bspline_fitting_distance = 200
71+ ):
6972 """
7073 Build a workflow for atlas-based brain extraction on anatomical MRI data.
7174
@@ -201,10 +204,6 @@ def init_brain_extraction_wf(name='brain_extraction_wf',
201204 'out_segm' , 'out_tpms' ]),
202205 name = 'outputnode' )
203206
204- copy_xform = pe .Node (CopyXForm (
205- fields = ['out_file' , 'out_mask' , 'bias_corrected' , 'bias_image' ]),
206- name = 'copy_xform' , run_without_submitting = True )
207-
208207 trunc = pe .MapNode (ImageMath (operation = 'TruncateImageIntensity' , op2 = '0.01 0.999 256' ),
209208 name = 'truncate_images' , iterfield = ['op1' ])
210209 inu_n4 = pe .MapNode (
@@ -296,7 +295,6 @@ def init_brain_extraction_wf(name='brain_extraction_wf',
296295
297296 wf .connect ([
298297 (inputnode , trunc , [('in_files' , 'op1' )]),
299- (inputnode , copy_xform , [(('in_files' , _pop ), 'hdr_file' )]),
300298 (inputnode , inu_n4_final , [('in_files' , 'input_image' )]),
301299 (inputnode , init_aff , [('in_mask' , 'fixed_image_mask' )]),
302300 (inputnode , norm , [('in_mask' , fixed_mask_trait )]),
@@ -314,16 +312,11 @@ def init_brain_extraction_wf(name='brain_extraction_wf',
314312 (thr_brainmask , dil_brainmask , [('output_image' , 'op1' )]),
315313 (dil_brainmask , get_brainmask , [('output_image' , 'op1' )]),
316314 (inu_n4_final , apply_mask , [('output_image' , 'in_file' )]),
317- (get_brainmask , apply_mask , [('output_image' , 'mask_file' )]),
318- (get_brainmask , copy_xform , [('output_image' , 'out_mask' )]),
319- (apply_mask , copy_xform , [('out_file' , 'out_file' )]),
320- (inu_n4_final , copy_xform , [('output_image' , 'bias_corrected' ),
315+ (get_brainmask , apply_mask , [('output_image' , 'in_mask' )]),
316+ (get_brainmask , outputnode , [('output_image' , 'out_mask' )]),
317+ (inu_n4_final , outputnode , [('output_image' , 'bias_corrected' ),
321318 ('bias_image' , 'bias_image' )]),
322- (copy_xform , outputnode , [
323- ('out_file' , 'out_file' ),
324- ('out_mask' , 'out_mask' ),
325- ('bias_corrected' , 'bias_corrected' ),
326- ('bias_image' , 'bias_image' )]),
319+ (apply_mask , outputnode , [('out_file' , 'out_file' )]),
327320 ])
328321
329322 if use_laplacian :
@@ -363,8 +356,8 @@ def init_brain_extraction_wf(name='brain_extraction_wf',
363356 run_without_submitting = True )
364357
365358 wf .disconnect ([
366- (get_brainmask , apply_mask , [('output_image' , 'mask_file ' )]),
367- (copy_xform , outputnode , [('out_mask ' , 'out_mask' )]),
359+ (get_brainmask , apply_mask , [('output_image' , 'in_mask ' )]),
360+ (get_brainmask , outputnode , [('output_image ' , 'out_mask' )]),
368361 ])
369362 wf .connect ([
370363 (inu_n4 , atropos_wf , [
@@ -376,7 +369,7 @@ def init_brain_extraction_wf(name='brain_extraction_wf',
376369 (atropos_wf , sel_wm , [('outputnode.out_tpms' , 'inlist' )]),
377370 (sel_wm , inu_n4_final , [('out' , 'weight_image' )]),
378371 (atropos_wf , apply_mask , [
379- ('outputnode.out_mask' , 'mask_file ' )]),
372+ ('outputnode.out_mask' , 'in_mask ' )]),
380373 (atropos_wf , outputnode , [
381374 ('outputnode.out_mask' , 'out_mask' ),
382375 ('outputnode.out_segm' , 'out_segm' ),
@@ -451,7 +444,6 @@ def init_atropos_wf(name='atropos_wf',
451444 out_tpms : str
452445 Output :abbr:`TPMs (tissue probability maps)`
453446
454-
455447 """
456448 wf = pe .Workflow (name )
457449
@@ -460,10 +452,6 @@ def init_atropos_wf(name='atropos_wf',
460452 outputnode = pe .Node (niu .IdentityInterface (
461453 fields = ['out_mask' , 'out_segm' , 'out_tpms' ]), name = 'outputnode' )
462454
463- copy_xform = pe .Node (CopyXForm (
464- fields = ['out_mask' , 'out_segm' , 'out_tpms' ]),
465- name = 'copy_xform' , run_without_submitting = True )
466-
467455 # Run atropos (core node)
468456 atropos = pe .Node (Atropos (
469457 dimension = 3 ,
@@ -561,14 +549,13 @@ def init_atropos_wf(name='atropos_wf',
561549 depad_csf = pe .Node (ImageMath (operation = 'PadImage' , op2 = '-%d' % padding ),
562550 name = '27_depad_csf' )
563551
564- msk_conform = pe .Node (niu .Function (function = _conform_mask ), name = 'msk_conform' )
552+ msk_dtype = pe .Node (niu .Function (function = _ensure_dtype ), name = 'msk_dtype' )
553+ msk_dtype .inputs .dtype = 'uint8'
565554 merge_tpms = pe .Node (niu .Merge (in_segmentation_model [0 ]), name = 'merge_tpms' )
566555 wf .connect ([
567- (inputnode , copy_xform , [(('in_files' , _pop ), 'hdr_file' )]),
568556 (inputnode , pad_mask , [('in_mask' , 'op1' )]),
569557 (inputnode , atropos , [('in_files' , 'intensity_images' ),
570558 ('in_mask_dilated' , 'mask_image' )]),
571- (inputnode , msk_conform , [(('in_files' , _pop ), 'in_reference' )]),
572559 (atropos , pad_segm , [('classified_image' , 'op1' )]),
573560 (pad_segm , sel_labels , [('output_image' , 'in_segm' )]),
574561 (sel_labels , get_wm , [('out_wm' , 'op1' )]),
@@ -602,14 +589,10 @@ def init_atropos_wf(name='atropos_wf',
602589 (depad_csf , merge_tpms , [('output_image' , 'in1' )]),
603590 (depad_gm , merge_tpms , [('output_image' , 'in2' )]),
604591 (depad_wm , merge_tpms , [('output_image' , 'in3' )]),
605- (depad_mask , msk_conform , [('output_image' , 'in_mask' )]),
606- (msk_conform , copy_xform , [('out' , 'out_mask' )]),
607- (depad_segm , copy_xform , [('output_image' , 'out_segm' )]),
608- (merge_tpms , copy_xform , [('out' , 'out_tpms' )]),
609- (copy_xform , outputnode , [
610- ('out_mask' , 'out_mask' ),
611- ('out_segm' , 'out_segm' ),
612- ('out_tpms' , 'out_tpms' )]),
592+ (depad_mask , msk_dtype , [('output_image' , 'in_mask' )]),
593+ (msk_dtype , outputnode , [('out' , 'out_mask' )]),
594+ (depad_segm , outputnode , [('output_image' , 'out_segm' )]),
595+ (merge_tpms , outputnode , [('out' , 'out_tpms' )]),
613596 ])
614597 return wf
615598
@@ -799,34 +782,25 @@ def _select_labels(in_segm, labels):
799782 return out_files
800783
801784
802- def _conform_mask (in_mask , in_reference ):
803- """Ensures the mask headers make sense and match those of the T1w"""
785+ def _ensure_dtype (in_mask , dtype = 'uint8' ):
786+ """Ensure the mask headers make sense and match those of the T1w. """
804787 from pathlib import Path
805788 import numpy as np
806789 import nibabel as nb
807790 from nipype .utils .filemanip import fname_presuffix
808791
809- ref = nb .load (in_reference )
810792 nii = nb .load (in_mask )
811793 hdr = nii .header .copy ()
812- hdr .set_data_dtype ('int16' )
794+ hdr .set_data_dtype (dtype )
813795 hdr .set_slope_inter (1 , 0 )
814796
815- qform , qcode = ref .header .get_qform (coded = True )
816- if qcode is not None :
817- hdr .set_qform (qform , int (qcode ))
818-
819- sform , scode = ref .header .get_sform (coded = True )
820- if scode is not None :
821- hdr .set_sform (sform , int (scode ))
822-
823797 if '_maths' in in_mask : # Cut the name at first _maths occurrence
824798 ext = '' .join (Path (in_mask ).suffixes )
825799 basename = Path (in_mask ).name
826800 in_mask = basename .split ('_maths' )[0 ] + ext
827801
828802 out_file = fname_presuffix (in_mask , suffix = '_mask' ,
829803 newpath = str (Path ()))
830- nii .__class__ (np .asanyarray (nii .dataobj ).astype ('int16' ), ref .affine ,
804+ nii .__class__ (np .asanyarray (nii .dataobj ).astype (dtype ), nii .affine ,
831805 hdr ).to_filename (out_file )
832806 return out_file
0 commit comments