def __init__(self, in_file='path', **options): from nipype.interfaces import afni as afni skullstrip = afni.SkullStrip() skullstrip.inputs.in_file = in_file for ef in options: setattr(skullstrip.inputs, ef, options[ef]) self.res = skullstrip.run()
def test_skullstrip(): input_map = dict( args=dict(argstr='%s', ), environ=dict(usedefault=True, ), ignore_exception=dict(usedefault=True, ), in_file=dict( argstr='-input %s', mandatory=True, ), out_file=dict(argstr='%s', ), outputtype=dict(), ) instance = afni.SkullStrip() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(instance.inputs.traits()[key], metakey), value
def afni_wf(name='AFNISkullStripWorkflow'): """ Skull-stripping workflow Derived from the codebase of the QAP: https://github.com/preprocessed-connectomes-project/\ quality-assessment-protocol/blob/master/qap/anatomical_preproc.py#L105 """ workflow = pe.Workflow(name=name) inputnode = pe.Node(niu.IdentityInterface(fields=['in_file']), name='inputnode') outputnode = pe.Node(niu.IdentityInterface( fields=['bias_corrected', 'out_file', 'out_mask', 'bias_image']), name='outputnode') inu_n4 = pe.Node(ants.N4BiasFieldCorrection(dimension=3, save_bias=True), name='CorrectINU') sstrip = pe.Node(afni.SkullStrip(outputtype='NIFTI_GZ'), name='skullstrip') sstrip_orig_vol = pe.Node(afni.Calc(expr='a*step(b)', outputtype='NIFTI_GZ'), name='sstrip_orig_vol') binarize = pe.Node(fsl.Threshold(args='-bin', thresh=1.e-3), name='binarize') workflow.connect([(inputnode, sstrip_orig_vol, [('in_file', 'in_file_a')]), (inputnode, inu_n4, [('in_file', 'input_image')]), (inu_n4, sstrip, [('output_image', 'in_file')]), (sstrip, sstrip_orig_vol, [('out_file', 'in_file_b')]), (sstrip_orig_vol, binarize, [('out_file', 'in_file')]), (sstrip_orig_vol, outputnode, [('out_file', 'out_file') ]), (binarize, outputnode, [('out_file', 'out_mask')]), (inu_n4, outputnode, [('output_image', 'bias_corrected'), ('bias_image', 'bias_image')])]) return workflow
def create_workflow(config: AttrDict, resource_pool: ResourcePool, context: Context): for _, rp in resource_pool[['label-reorient_T1w']]: anat_image = rp[R('T1w', label='reorient')] anat_skullstrip = NipypeJob(interface=afni.SkullStrip( outputtype='NIFTI_GZ', args=create_3dskullstrip_arg_string(**config)), reference='anat_skullstrip') anat_skullstrip.in_file = anat_image anat_brain_mask = NipypeJob(interface=afni.Calc(expr='step(a)', outputtype='NIFTI_GZ'), reference='anat_brain_mask') anat_skullstrip_orig_vol = NipypeJob( interface=afni.Calc(expr='a*step(b)', outputtype='NIFTI_GZ'), reference='anat_skullstrip_orig_vol') anat_brain_mask.in_file_a = anat_skullstrip.out_file anat_skullstrip_orig_vol.in_file_a = anat_image anat_skullstrip_orig_vol.in_file_b = anat_brain_mask.out_file rp[R('T1w', desc='skullstrip-afni', suffix='mask')] = anat_brain_mask.out_file rp[R('T1w', desc='skullstrip-afni', suffix='brain')] = anat_skullstrip_orig_vol.out_file
def create_anat_preproc(template_path=None, mask_path=None, regmask_path=None, method='afni', already_skullstripped=False, non_local_means_filtering=True, n4_correction=True, wf_name='anat_preproc'): """ The main purpose of this workflow is to process T1 scans. Raw mprage file is deobliqued, reoriented into RPI and skullstripped. Also, a whole brain only mask is generated from the skull stripped image for later use in registration. Returns ------- anat_preproc : workflow Anatomical Preprocessing Workflow Notes ----- `Source <https://github.com/FCP-INDI/C-PAC/blob/master/CPAC/anat_preproc/anat_preproc.py>`_ Workflow Inputs:: inputspec.anat : string User input anatomical (T1) Image, in any of the 8 orientations Workflow Outputs:: outputspec.refit : string Path to deobliqued anatomical image outputspec.reorient : string Path to RPI oriented anatomical image outputspec.skullstrip : string Path to skull stripped RPI oriented mprage file with normalized intensities. outputspec.brain : string Path to skull stripped RPI brain image with original intensity values and not normalized or scaled. Order of commands: - Deobliqing the scans. :: 3drefit -deoblique mprage.nii.gz - Re-orienting the Image into Right-to-Left Posterior-to-Anterior Inferior-to-Superior (RPI) orientation :: 3dresample -orient RPI -prefix mprage_RPI.nii.gz -inset mprage.nii.gz - Skull-Stripping the image :: Using AFNI :: 3dSkullStrip -input mprage_RPI.nii.gz -o_ply mprage_RPI_3dT.nii.gz or using BET :: bet mprage_RPI.nii.gz - The skull-stripping step modifies the intensity values. To get back the original intensity values, we do an element wise product of RPI data with step function of skull-stripped data :: 3dcalc -a mprage_RPI.nii.gz -b mprage_RPI_3dT.nii.gz -expr 'a*step(b)' -prefix mprage_RPI_3dc.nii.gz High Level Workflow Graph: .. image:: ../images/anatpreproc_graph.dot.png :width: 500 Detailed Workflow Graph: .. image:: ../images/anatpreproc_graph_detailed.dot.png :width: 500 Examples -------- >>> from CPAC.anat_preproc import create_anat_preproc >>> preproc = create_anat_preproc() >>> preproc.inputs.inputspec.anat = 'sub1/anat/mprage.nii.gz' >>> preproc.run() #doctest: +SKIP """ preproc = pe.Workflow(name=wf_name) inputnode = pe.Node(util.IdentityInterface(fields=['anat', 'brain_mask']), name='inputspec') outputnode = pe.Node(util.IdentityInterface( fields=['refit', 'reorient', 'skullstrip', 'brain', 'brain_mask']), name='outputspec') anat_deoblique = pe.Node(interface=afni.Refit(), name='anat_deoblique') anat_deoblique.inputs.deoblique = True preproc.connect(inputnode, 'anat', anat_deoblique, 'in_file') preproc.connect(anat_deoblique, 'out_file', outputnode, 'refit') # Disable non_local_means_filtering and n4_correction when run niworkflows-ants if method == 'niworkflows-ants': non_local_means_filtering = False n4_correction = False if non_local_means_filtering and n4_correction: denoise = pe.Node(interface=ants.DenoiseImage(), name='anat_denoise') preproc.connect(anat_deoblique, 'out_file', denoise, 'input_image') n4 = pe.Node(interface=ants.N4BiasFieldCorrection(dimension=3, shrink_factor=2, copy_header=True), name='anat_n4') preproc.connect(denoise, 'output_image', n4, 'input_image') elif non_local_means_filtering and not n4_correction: denoise = pe.Node(interface=ants.DenoiseImage(), name='anat_denoise') preproc.connect(anat_deoblique, 'out_file', denoise, 'input_image') elif not non_local_means_filtering and n4_correction: n4 = pe.Node(interface=ants.N4BiasFieldCorrection(dimension=3, shrink_factor=2, copy_header=True), name='anat_n4') preproc.connect(anat_deoblique, 'out_file', n4, 'input_image') # Anatomical reorientation anat_reorient = pe.Node(interface=afni.Resample(), name='anat_reorient') anat_reorient.inputs.orientation = 'RPI' anat_reorient.inputs.outputtype = 'NIFTI_GZ' if n4_correction: preproc.connect(n4, 'output_image', anat_reorient, 'in_file') elif non_local_means_filtering and not n4_correction: preproc.connect(denoise, 'output_image', anat_reorient, 'in_file') else: preproc.connect(anat_deoblique, 'out_file', anat_reorient, 'in_file') preproc.connect(anat_reorient, 'out_file', outputnode, 'reorient') if already_skullstripped: anat_skullstrip = pe.Node( interface=util.IdentityInterface(fields=['out_file']), name='anat_skullstrip') preproc.connect(anat_reorient, 'out_file', anat_skullstrip, 'out_file') preproc.connect(anat_skullstrip, 'out_file', outputnode, 'skullstrip') preproc.connect(anat_skullstrip, 'out_file', outputnode, 'brain') else: if method == 'afni': # Skull-stripping using AFNI 3dSkullStrip inputnode_afni = pe.Node(util.IdentityInterface(fields=[ 'shrink_factor', 'var_shrink_fac', 'shrink_fac_bot_lim', 'avoid_vent', 'niter', 'pushout', 'touchup', 'fill_hole', 'avoid_eyes', 'use_edge', 'exp_frac', 'smooth_final', 'push_to_edge', 'use_skull', 'perc_int', 'max_inter_iter', 'blur_fwhm', 'fac', 'monkey' ]), name='AFNI_options') skullstrip_args = pe.Node(util.Function( input_names=[ 'spat_norm', 'spat_norm_dxyz', 'shrink_fac', 'var_shrink_fac', 'shrink_fac_bot_lim', 'avoid_vent', 'niter', 'pushout', 'touchup', 'fill_hole', 'avoid_eyes', 'use_edge', 'exp_frac', 'smooth_final', 'push_to_edge', 'use_skull', 'perc_int', 'max_inter_iter', 'blur_fwhm', 'fac', 'monkey' ], output_names=['expr'], function=create_3dskullstrip_arg_string), name='anat_skullstrip_args') preproc.connect([(inputnode_afni, skullstrip_args, [('shrink_factor', 'shrink_fac'), ('var_shrink_fac', 'var_shrink_fac'), ('shrink_fac_bot_lim', 'shrink_fac_bot_lim'), ('avoid_vent', 'avoid_vent'), ('niter', 'niter'), ('pushout', 'pushout'), ('touchup', 'touchup'), ('fill_hole', 'fill_hole'), ('avoid_eyes', 'avoid_eyes'), ('use_edge', 'use_edge'), ('exp_frac', 'exp_frac'), ('smooth_final', 'smooth_final'), ('push_to_edge', 'push_to_edge'), ('use_skull', 'use_skull'), ('perc_int', 'perc_int'), ('max_inter_iter', 'max_inter_iter'), ('blur_fwhm', 'blur_fwhm'), ('fac', 'fac'), ('monkey', 'monkey')])]) anat_skullstrip = pe.Node(interface=afni.SkullStrip(), name='anat_skullstrip') anat_skullstrip.inputs.outputtype = 'NIFTI_GZ' preproc.connect(anat_reorient, 'out_file', anat_skullstrip, 'in_file') preproc.connect(skullstrip_args, 'expr', anat_skullstrip, 'args') preproc.connect(anat_skullstrip, 'out_file', outputnode, 'skullstrip') # Apply skull-stripping step mask to original volume anat_skullstrip_orig_vol = pe.Node(interface=afni.Calc(), name='anat_skullstrip_orig_vol') anat_skullstrip_orig_vol.inputs.expr = 'a*step(b)' anat_skullstrip_orig_vol.inputs.outputtype = 'NIFTI_GZ' preproc.connect(anat_reorient, 'out_file', anat_skullstrip_orig_vol, 'in_file_a') anat_brain_mask = pe.Node(interface=afni.Calc(), name='anat_brain_mask') anat_brain_mask.inputs.expr = 'step(a)' anat_brain_mask.inputs.outputtype = 'NIFTI_GZ' preproc.connect(anat_skullstrip, 'out_file', anat_brain_mask, 'in_file_a') preproc.connect(anat_skullstrip, 'out_file', anat_skullstrip_orig_vol, 'in_file_b') preproc.connect(anat_brain_mask, 'out_file', outputnode, 'brain_mask') preproc.connect(anat_skullstrip_orig_vol, 'out_file', outputnode, 'brain') elif method == 'fsl': # Skull-stripping using FSL BET inputnode_bet = pe.Node(util.IdentityInterface(fields=[ 'frac', 'mask_boolean', 'mesh_boolean', 'outline', 'padding', 'radius', 'reduce_bias', 'remove_eyes', 'robust', 'skull', 'surfaces', 'threshold', 'vertical_gradient' ]), name='BET_options') anat_skullstrip = pe.Node(interface=fsl.BET(), name='anat_skullstrip') preproc.connect(anat_reorient, 'out_file', anat_skullstrip, 'in_file') preproc.connect([(inputnode_bet, anat_skullstrip, [ ('frac', 'frac'), ('mask_boolean', 'mask'), ('mesh_boolean', 'mesh'), ('outline', 'outline'), ('padding', 'padding'), ('radius', 'radius'), ('reduce_bias', 'reduce_bias'), ('remove_eyes', 'remove_eyes'), ('robust', 'robust'), ('skull', 'skull'), ('surfaces', 'surfaces'), ('threshold', 'threshold'), ('vertical_gradient', 'vertical_gradient'), ])]) preproc.connect(anat_skullstrip, 'out_file', outputnode, 'skullstrip') # Apply skull-stripping step mask to original volume anat_skullstrip_orig_vol = pe.Node(interface=afni.Calc(), name='anat_skullstrip_orig_vol') anat_skullstrip_orig_vol.inputs.expr = 'a*step(b)' anat_skullstrip_orig_vol.inputs.outputtype = 'NIFTI_GZ' preproc.connect(anat_reorient, 'out_file', anat_skullstrip_orig_vol, 'in_file_a') preproc.connect(anat_skullstrip, 'out_file', anat_skullstrip_orig_vol, 'in_file_b') preproc.connect(anat_skullstrip, 'mask_file', outputnode, 'brain_mask') preproc.connect(anat_skullstrip_orig_vol, 'out_file', outputnode, 'brain') elif method == 'niworkflows-ants': # Skull-stripping using niworkflows-ants anat_skullstrip_ants = init_brain_extraction_wf( tpl_target_path=template_path, tpl_mask_path=mask_path, tpl_regmask_path=regmask_path, name='anat_skullstrip_ants') preproc.connect(anat_reorient, 'out_file', anat_skullstrip_ants, 'inputnode.in_files') preproc.connect(anat_skullstrip_ants, 'copy_xform.out_file', outputnode, 'skullstrip') preproc.connect(anat_skullstrip_ants, 'copy_xform.out_file', outputnode, 'brain') preproc.connect(anat_skullstrip_ants, 'atropos_wf.copy_xform.out_mask', outputnode, 'brain_mask') elif method == 'mask': anat_skullstrip_orig_vol = pe.Node(interface=afni.Calc(), name='anat_skullstrip_orig_vol') anat_skullstrip_orig_vol.inputs.expr = 'a*step(b)' anat_skullstrip_orig_vol.inputs.outputtype = 'NIFTI_GZ' preproc.connect(anat_reorient, 'out_file', anat_skullstrip_orig_vol, 'in_file_a') preproc.connect(inputnode, 'brain_mask', anat_skullstrip_orig_vol, 'in_file_b') preproc.connect(inputnode, 'brain_mask', outputnode, 'brain_mask') preproc.connect(anat_skullstrip_orig_vol, 'out_file', outputnode, 'brain') return preproc
def run(options): # fix! out_dir = os.path.join('option', '1') err_dir = os.path.join('option', '2') data_dir = os.path.join('option', '3') work_dir = os.path.join('something', 'else') # Workflow merica_wf = pe.Workflow('merica_wf') merica_wf.base_dir = work_dir inputspec = pe.Node(util.IdentityInterface(fields=options.keys()), name='inputspec') # Node: subject_iterable run_iterable = pe.Node(util.IdentityInterface(fields=['run'], mandatory_inputs=True), name='run_iterable') run_iterable.iterables = ('run', runs) info = dict(mri_files=[['run']]) # Create a datasource node to get the mri files datasource = pe.Node(nio.DataGrabber(infields=['run'], outfields=info.keys()), name='datasource') datasource.inputs.template = '*' datasource.inputs.base_directory = abspath(data_dir) datasource.inputs.field_template = dict(mri_files='%s/func/*.nii.gz') datasource.inputs.template_args = info datasource.inputs.sort_filelist = True datasource.inputs.ignore_exception = False datasource.inputs.raise_on_empty = True meica_wf.connect(run_iterable, 'run', datasource, 'run') # Create a Function node to rename output files getsubs = pe.Node(util.Function(input_names=['run', 'mri_files'], output_names=['subs'], function=get_subs), name='getsubs') getsubs.inputs.ignore_exception = False meica_wf.connect(run_iterable, 'run', getsubs, 'run') meica_wf.connect(datasource, 'mri_files', getsubs, 'mri_files') get_cm = pe.Node(util.Function(input_names=['fname'], output_names=['x', 'y', 'z'], function=find_CM), name='get_cm') get_obliquity = pe.Node(util.Function(input_names=['fname'], output_names=['angmerit'], function=check_obliquity), name='get_cm') if get_obliquity.is_oblique == True: deoblique = pe.Node(afni.Warp(deoblique=True) name='deoblique') merica_wf.connect(upstream, 't1', deoblique, 'in_file') warpspeed = pe.Node(afni.Warp(args='-card2oblique -newgrid 1.0')) if skull-stripped == False: unifeyes = pe.Node(afni.Unifize() name='unifeyes') if get_obliquity.is_oblique == True: merica_wf.connect(deoblique, 'out_file', unifeyes, 'in_file') else: merica_wf.connect(upstream, 't1', unifeyes, 'in_file') skullstrip = pe.Node(afni.SkullStrip(args='-shrink_fac_bot_lim 0.3 -orig_vol') name='skullstrip') autobots = pe.Node(afni.Autobox() name='autobots') merica_wf.connect(skullstrip, 'out_file', autobots, 'in_file') # Moving on to functional preprocessing, be back later! if despike == True: despike = pe.Node(afni.Despike() name='despike') if skull-stripped == False: merica_wf.connect(autobots, 'out_file', despike, 'in_file') else: merica_wf.connect(upstream, 't1', despike, 'in_file') meica_wf.connect(run_iterable, 'run', get_cm, 'fname') meica_wf.connect(run_iterable, 'run', get_cm, 'fname')
def create_anat_preproc(method='afni', already_skullstripped=False, c=None, wf_name='anat_preproc'): """The main purpose of this workflow is to process T1 scans. Raw mprage file is deobliqued, reoriented into RPI and skullstripped. Also, a whole brain only mask is generated from the skull stripped image for later use in registration. Returns ------- anat_preproc : workflow Anatomical Preprocessing Workflow Notes ----- `Source <https://github.com/FCP-INDI/C-PAC/blob/master/CPAC/anat_preproc/anat_preproc.py>`_ Workflow Inputs:: inputspec.anat : string User input anatomical (T1) Image, in any of the 8 orientations Workflow Outputs:: outputspec.refit : string Path to deobliqued anatomical image outputspec.reorient : string Path to RPI oriented anatomical image outputspec.skullstrip : string Path to skull stripped RPI oriented mprage file with normalized intensities. outputspec.brain : string Path to skull stripped RPI brain image with original intensity values and not normalized or scaled. Order of commands: - Deobliqing the scans. :: 3drefit -deoblique mprage.nii.gz - Re-orienting the Image into Right-to-Left Posterior-to-Anterior Inferior-to-Superior (RPI) orientation :: 3dresample -orient RPI -prefix mprage_RPI.nii.gz -inset mprage.nii.gz - Skull-Stripping the image :: Using AFNI :: 3dSkullStrip -input mprage_RPI.nii.gz -o_ply mprage_RPI_3dT.nii.gz or using BET :: bet mprage_RPI.nii.gz - The skull-stripping step modifies the intensity values. To get back the original intensity values, we do an element wise product of RPI data with step function of skull-stripped data :: 3dcalc -a mprage_RPI.nii.gz -b mprage_RPI_3dT.nii.gz -expr 'a*step(b)' -prefix mprage_RPI_3dc.nii.gz High Level Workflow Graph: .. image:: ../images/anatpreproc_graph.dot.png :width: 500 Detailed Workflow Graph: .. image:: ../images/anatpreproc_graph_detailed.dot.png :width: 500 Examples -------- >>> from CPAC.anat_preproc import create_anat_preproc >>> preproc = create_anat_preproc() >>> preproc.inputs.inputspec.anat = 'sub1/anat/mprage.nii.gz' >>> preproc.run() #doctest: +SKIP """ preproc = pe.Workflow(name=wf_name) inputnode = pe.Node(util.IdentityInterface(fields=['anat', 'brain_mask']), name='inputspec') outputnode = pe.Node(util.IdentityInterface( fields=['refit', 'reorient', 'skullstrip', 'brain', 'brain_mask']), name='outputspec') anat_deoblique = pe.Node(interface=afni.Refit(), name='anat_deoblique') anat_deoblique.inputs.deoblique = True preproc.connect(inputnode, 'anat', anat_deoblique, 'in_file') preproc.connect(anat_deoblique, 'out_file', outputnode, 'refit') # Disable non_local_means_filtering and n4_bias_field_correction when run niworkflows-ants if method == 'niworkflows-ants': c.non_local_means_filtering = False c.n4_bias_field_correction = False if c.non_local_means_filtering and c.n4_bias_field_correction: denoise = pe.Node(interface=ants.DenoiseImage(), name='anat_denoise') preproc.connect(anat_deoblique, 'out_file', denoise, 'input_image') n4 = pe.Node(interface=ants.N4BiasFieldCorrection(dimension=3, shrink_factor=2, copy_header=True), name='anat_n4') preproc.connect(denoise, 'output_image', n4, 'input_image') elif c.non_local_means_filtering and not c.n4_bias_field_correction: denoise = pe.Node(interface=ants.DenoiseImage(), name='anat_denoise') preproc.connect(anat_deoblique, 'out_file', denoise, 'input_image') elif not c.non_local_means_filtering and c.n4_bias_field_correction: n4 = pe.Node(interface=ants.N4BiasFieldCorrection(dimension=3, shrink_factor=2, copy_header=True), name='anat_n4') preproc.connect(anat_deoblique, 'out_file', n4, 'input_image') # Anatomical reorientation anat_reorient = pe.Node(interface=afni.Resample(), name='anat_reorient') anat_reorient.inputs.orientation = 'RPI' anat_reorient.inputs.outputtype = 'NIFTI_GZ' if c.n4_bias_field_correction: preproc.connect(n4, 'output_image', anat_reorient, 'in_file') elif c.non_local_means_filtering and not c.n4_bias_field_correction: preproc.connect(denoise, 'output_image', anat_reorient, 'in_file') else: preproc.connect(anat_deoblique, 'out_file', anat_reorient, 'in_file') preproc.connect(anat_reorient, 'out_file', outputnode, 'reorient') if already_skullstripped: anat_skullstrip = pe.Node( interface=util.IdentityInterface(fields=['out_file']), name='anat_skullstrip') preproc.connect(anat_reorient, 'out_file', anat_skullstrip, 'out_file') preproc.connect(anat_skullstrip, 'out_file', outputnode, 'skullstrip') preproc.connect(anat_skullstrip, 'out_file', outputnode, 'brain') else: if method == 'afni': # Skull-stripping using AFNI 3dSkullStrip inputnode_afni = pe.Node(util.IdentityInterface(fields=[ 'mask_vol', 'shrink_factor', 'var_shrink_fac', 'shrink_fac_bot_lim', 'avoid_vent', 'niter', 'pushout', 'touchup', 'fill_hole', 'avoid_eyes', 'use_edge', 'exp_frac', 'smooth_final', 'push_to_edge', 'use_skull', 'perc_int', 'max_inter_iter', 'blur_fwhm', 'fac', 'monkey' ]), name='AFNI_options') skullstrip_args = pe.Node(util.Function( input_names=[ 'spat_norm', 'spat_norm_dxyz', 'mask_vol', 'shrink_fac', 'var_shrink_fac', 'shrink_fac_bot_lim', 'avoid_vent', 'niter', 'pushout', 'touchup', 'fill_hole', 'avoid_eyes', 'use_edge', 'exp_frac', 'smooth_final', 'push_to_edge', 'use_skull', 'perc_int', 'max_inter_iter', 'blur_fwhm', 'fac', 'monkey' ], output_names=['expr'], function=create_3dskullstrip_arg_string), name='anat_skullstrip_args') preproc.connect([(inputnode_afni, skullstrip_args, [('mask_vol', 'mask_vol'), ('shrink_factor', 'shrink_fac'), ('var_shrink_fac', 'var_shrink_fac'), ('shrink_fac_bot_lim', 'shrink_fac_bot_lim'), ('avoid_vent', 'avoid_vent'), ('niter', 'niter'), ('pushout', 'pushout'), ('touchup', 'touchup'), ('fill_hole', 'fill_hole'), ('avoid_eyes', 'avoid_eyes'), ('use_edge', 'use_edge'), ('exp_frac', 'exp_frac'), ('smooth_final', 'smooth_final'), ('push_to_edge', 'push_to_edge'), ('use_skull', 'use_skull'), ('perc_int', 'perc_int'), ('max_inter_iter', 'max_inter_iter'), ('blur_fwhm', 'blur_fwhm'), ('fac', 'fac'), ('monkey', 'monkey')])]) anat_skullstrip = pe.Node(interface=afni.SkullStrip(), name='anat_skullstrip') anat_skullstrip.inputs.outputtype = 'NIFTI_GZ' preproc.connect(anat_reorient, 'out_file', anat_skullstrip, 'in_file') preproc.connect(skullstrip_args, 'expr', anat_skullstrip, 'args') # Generate anatomical brain mask anat_brain_mask = pe.Node(interface=afni.Calc(), name='anat_brain_mask') anat_brain_mask.inputs.expr = 'step(a)' anat_brain_mask.inputs.outputtype = 'NIFTI_GZ' preproc.connect(anat_skullstrip, 'out_file', anat_brain_mask, 'in_file_a') # Apply skull-stripping step mask to original volume anat_skullstrip_orig_vol = pe.Node(interface=afni.Calc(), name='anat_skullstrip_orig_vol') anat_skullstrip_orig_vol.inputs.expr = 'a*step(b)' anat_skullstrip_orig_vol.inputs.outputtype = 'NIFTI_GZ' preproc.connect(anat_reorient, 'out_file', anat_skullstrip_orig_vol, 'in_file_a') preproc.connect(anat_brain_mask, 'out_file', anat_skullstrip_orig_vol, 'in_file_b') preproc.connect(anat_brain_mask, 'out_file', outputnode, 'brain_mask') preproc.connect(anat_skullstrip_orig_vol, 'out_file', outputnode, 'brain') elif method == 'fsl': # Skull-stripping using FSL BET inputnode_bet = pe.Node(util.IdentityInterface(fields=[ 'frac', 'mask_boolean', 'mesh_boolean', 'outline', 'padding', 'radius', 'reduce_bias', 'remove_eyes', 'robust', 'skull', 'surfaces', 'threshold', 'vertical_gradient' ]), name='BET_options') anat_skullstrip = pe.Node(interface=fsl.BET(), name='anat_skullstrip') anat_skullstrip.inputs.output_type = 'NIFTI_GZ' preproc.connect(anat_reorient, 'out_file', anat_skullstrip, 'in_file') preproc.connect([(inputnode_bet, anat_skullstrip, [ ('frac', 'frac'), ('mask_boolean', 'mask'), ('mesh_boolean', 'mesh'), ('outline', 'outline'), ('padding', 'padding'), ('radius', 'radius'), ('reduce_bias', 'reduce_bias'), ('remove_eyes', 'remove_eyes'), ('robust', 'robust'), ('skull', 'skull'), ('surfaces', 'surfaces'), ('threshold', 'threshold'), ('vertical_gradient', 'vertical_gradient'), ])]) preproc.connect(anat_skullstrip, 'out_file', outputnode, 'skullstrip') # Apply skull-stripping step mask to original volume anat_skullstrip_orig_vol = pe.Node(interface=afni.Calc(), name='anat_skullstrip_orig_vol') anat_skullstrip_orig_vol.inputs.expr = 'a*step(b)' anat_skullstrip_orig_vol.inputs.outputtype = 'NIFTI_GZ' preproc.connect(anat_reorient, 'out_file', anat_skullstrip_orig_vol, 'in_file_a') preproc.connect(anat_skullstrip, 'out_file', anat_skullstrip_orig_vol, 'in_file_b') preproc.connect(anat_skullstrip, 'mask_file', outputnode, 'brain_mask') preproc.connect(anat_skullstrip_orig_vol, 'out_file', outputnode, 'brain') elif method == 'niworkflows-ants': # Skull-stripping using niworkflows-ants anat_skullstrip_ants = init_brain_extraction_wf( tpl_target_path=c.niworkflows_ants_template_path, tpl_mask_path=c.niworkflows_ants_mask_path, tpl_regmask_path=c.niworkflows_ants_regmask_path, name='anat_skullstrip_ants') preproc.connect(anat_reorient, 'out_file', anat_skullstrip_ants, 'inputnode.in_files') preproc.connect(anat_skullstrip_ants, 'copy_xform.out_file', outputnode, 'skullstrip') preproc.connect(anat_skullstrip_ants, 'copy_xform.out_file', outputnode, 'brain') preproc.connect(anat_skullstrip_ants, 'atropos_wf.copy_xform.out_mask', outputnode, 'brain_mask') elif method == 'mask': brain_mask_deoblique = pe.Node(interface=afni.Refit(), name='brain_mask_deoblique') brain_mask_deoblique.inputs.deoblique = True preproc.connect(inputnode, 'brain_mask', brain_mask_deoblique, 'in_file') brain_mask_reorient = pe.Node(interface=afni.Resample(), name='brain_mask_reorient') brain_mask_reorient.inputs.orientation = 'RPI' brain_mask_reorient.inputs.outputtype = 'NIFTI_GZ' preproc.connect(brain_mask_deoblique, 'out_file', brain_mask_reorient, 'in_file') anat_skullstrip_orig_vol = pe.Node(interface=afni.Calc(), name='anat_skullstrip_orig_vol') anat_skullstrip_orig_vol.inputs.expr = 'a*step(b)' anat_skullstrip_orig_vol.inputs.outputtype = 'NIFTI_GZ' preproc.connect(anat_reorient, 'out_file', anat_skullstrip_orig_vol, 'in_file_a') preproc.connect(brain_mask_reorient, 'out_file', anat_skullstrip_orig_vol, 'in_file_b') preproc.connect(brain_mask_reorient, 'out_file', outputnode, 'brain_mask') preproc.connect(anat_skullstrip_orig_vol, 'out_file', outputnode, 'brain') elif method == 'unet': """ UNet options (following numbers are default): input_slice: 3 conv_block: 5 kernel_root: 16 rescale_dim: 256 """ # TODO: add options to pipeline_config train_model = UNet2d(dim_in=3, num_conv_block=5, kernel_root=16) unet_path = check_for_s3(c.unet_model) checkpoint = torch.load(unet_path, map_location={'cuda:0': 'cpu'}) train_model.load_state_dict(checkpoint['state_dict']) model = nn.Sequential(train_model, nn.Softmax2d()) # create a node called unet_mask unet_mask = pe.Node(util.Function(input_names=['model', 'cimg_in'], output_names=['out_path'], function=predict_volumes), name='unet_mask') unet_mask.inputs.model = model preproc.connect(anat_reorient, 'out_file', unet_mask, 'cimg_in') """ Revised mask with ANTs """ # fslmaths <whole head> -mul <mask> brain.nii.gz unet_masked_brain = pe.Node(interface=fsl.MultiImageMaths(), name='unet_masked_brain') unet_masked_brain.inputs.op_string = "-mul %s" preproc.connect(anat_reorient, 'out_file', unet_masked_brain, 'in_file') preproc.connect(unet_mask, 'out_path', unet_masked_brain, 'operand_files') # flirt -v -dof 6 -in brain.nii.gz -ref NMT_SS_0.5mm.nii.gz -o brain_rot2atl -omat brain_rot2atl.mat -interp sinc # TODO change it to ANTs linear transform native_brain_to_template_brain = pe.Node( interface=fsl.FLIRT(), name='native_brain_to_template_brain') native_brain_to_template_brain.inputs.reference = c.template_brain_only_for_anat native_brain_to_template_brain.inputs.dof = 6 native_brain_to_template_brain.inputs.interp = 'sinc' preproc.connect(unet_masked_brain, 'out_file', native_brain_to_template_brain, 'in_file') # flirt -in head.nii.gz -ref NMT_0.5mm.nii.gz -o head_rot2atl -applyxfm -init brain_rot2atl.mat # TODO change it to ANTs linear transform native_head_to_template_head = pe.Node( interface=fsl.FLIRT(), name='native_head_to_template_head') native_head_to_template_head.inputs.reference = c.template_skull_for_anat native_head_to_template_head.inputs.apply_xfm = True preproc.connect(anat_reorient, 'out_file', native_head_to_template_head, 'in_file') preproc.connect(native_brain_to_template_brain, 'out_matrix_file', native_head_to_template_head, 'in_matrix_file') # fslmaths NMT_SS_0.5mm.nii.gz -bin templateMask.nii.gz template_brain_mask = pe.Node(interface=fsl.maths.MathsCommand(), name='template_brain_mask') template_brain_mask.inputs.in_file = c.template_brain_only_for_anat template_brain_mask.inputs.args = '-bin' # ANTS 3 -m CC[head_rot2atl.nii.gz,NMT_0.5mm.nii.gz,1,5] -t SyN[0.25] -r Gauss[3,0] -o atl2T1rot -i 60x50x20 --use-Histogram-Matching --number-of-affine-iterations 10000x10000x10000x10000x10000 --MI-option 32x16000 ants_template_head_to_template = pe.Node( interface=ants.Registration(), name='template_head_to_template') ants_template_head_to_template.inputs.metric = ['CC'] ants_template_head_to_template.inputs.metric_weight = [1, 5] ants_template_head_to_template.inputs.moving_image = c.template_skull_for_anat ants_template_head_to_template.inputs.transforms = ['SyN'] ants_template_head_to_template.inputs.transform_parameters = [ (0.25, ) ] ants_template_head_to_template.inputs.interpolation = 'NearestNeighbor' ants_template_head_to_template.inputs.number_of_iterations = [[ 60, 50, 20 ]] ants_template_head_to_template.inputs.smoothing_sigmas = [[ 0.6, 0.2, 0.0 ]] ants_template_head_to_template.inputs.shrink_factors = [[4, 2, 1]] ants_template_head_to_template.inputs.convergence_threshold = [ 1.e-8 ] preproc.connect(native_head_to_template_head, 'out_file', ants_template_head_to_template, 'fixed_image') # antsApplyTransforms -d 3 -i templateMask.nii.gz -t atl2T1rotWarp.nii.gz atl2T1rotAffine.txt -r brain_rot2atl.nii.gz -o brain_rot2atl_mask.nii.gz template_head_transform_to_template = pe.Node( interface=ants.ApplyTransforms(), name='template_head_transform_to_template') template_head_transform_to_template.inputs.dimension = 3 preproc.connect(template_brain_mask, 'out_file', template_head_transform_to_template, 'input_image') preproc.connect(native_brain_to_template_brain, 'out_file', template_head_transform_to_template, 'reference_image') preproc.connect(ants_template_head_to_template, 'forward_transforms', template_head_transform_to_template, 'transforms') # convert_xfm -omat brain_rot2native.mat -inverse brain_rot2atl.mat invt = pe.Node(interface=fsl.ConvertXFM(), name='convert_xfm') invt.inputs.invert_xfm = True preproc.connect(native_brain_to_template_brain, 'out_matrix_file', invt, 'in_file') # flirt -in brain_rot2atl_mask.nii.gz -ref brain.nii.gz -o brain_mask.nii.gz -applyxfm -init brain_rot2native.mat template_brain_to_native_brain = pe.Node( interface=fsl.FLIRT(), name='template_brain_to_native_brain') template_brain_to_native_brain.inputs.apply_xfm = True preproc.connect(template_head_transform_to_template, 'output_image', template_brain_to_native_brain, 'in_file') preproc.connect(unet_masked_brain, 'out_file', template_brain_to_native_brain, 'reference') preproc.connect(invt, 'out_file', template_brain_to_native_brain, 'in_matrix_file') # fslmaths brain_mask.nii.gz -thr .5 -bin brain_mask_thr.nii.gz refined_mask = pe.Node(interface=fsl.Threshold(), name='refined_mask') refined_mask.inputs.thresh = 0.5 preproc.connect(template_brain_to_native_brain, 'out_file', refined_mask, 'in_file') # get a new brain with mask refined_brain = pe.Node(interface=fsl.MultiImageMaths(), name='refined_brain') refined_brain.inputs.op_string = "-mul %s" preproc.connect(anat_reorient, 'out_file', refined_brain, 'in_file') preproc.connect(refined_mask, 'out_file', refined_brain, 'operand_files') preproc.connect(refined_mask, 'out_file', outputnode, 'brain_mask') preproc.connect(refined_brain, 'out_file', outputnode, 'brain') return preproc
def afni_brain_connector(wf, cfg, strat_pool, pipe_num, opt): # Skull-stripping using AFNI 3dSkullStrip inputnode_afni = pe.Node(util.IdentityInterface(fields=[ 'mask_vol', 'shrink_factor', 'var_shrink_fac', 'shrink_fac_bot_lim', 'avoid_vent', 'niter', 'pushout', 'touchup', 'fill_hole', 'NN_smooth', 'smooth_final', 'avoid_eyes', 'use_edge', 'exp_frac', 'push_to_edge', 'use_skull', 'perc_int', 'max_inter_iter', 'blur_fwhm', 'fac', 'monkey' ]), name=f'AFNI_options_{pipe_num}') skullstrip_args = pe.Node(util.Function( input_names=[ 'spat_norm', 'spat_norm_dxyz', 'mask_vol', 'shrink_fac', 'var_shrink_fac', 'shrink_fac_bot_lim', 'avoid_vent', 'niter', 'pushout', 'touchup', 'fill_hole', 'NN_smooth', 'smooth_final', 'avoid_eyes', 'use_edge', 'exp_frac', 'push_to_edge', 'use_skull', 'perc_int', 'max_inter_iter', 'blur_fwhm', 'fac', 'monkey' ], output_names=['expr'], function=create_3dskullstrip_arg_string), name=f'anat_skullstrip_args_{pipe_num}') inputnode_afni.inputs.set( mask_vol=cfg.anatomical_preproc['brain_extraction'] ['AFNI-3dSkullStrip']['mask_vol'], shrink_factor=cfg.anatomical_preproc['brain_extraction'] ['AFNI-3dSkullStrip']['shrink_factor'], var_shrink_fac=cfg.anatomical_preproc['brain_extraction'] ['AFNI-3dSkullStrip']['var_shrink_fac'], shrink_fac_bot_lim=cfg.anatomical_preproc['brain_extraction'] ['AFNI-3dSkullStrip']['shrink_factor_bot_lim'], avoid_vent=cfg.anatomical_preproc['brain_extraction'] ['AFNI-3dSkullStrip']['avoid_vent'], niter=cfg.anatomical_preproc['brain_extraction']['AFNI-3dSkullStrip'] ['n_iterations'], pushout=cfg.anatomical_preproc['brain_extraction']['AFNI-3dSkullStrip'] ['pushout'], touchup=cfg.anatomical_preproc['brain_extraction']['AFNI-3dSkullStrip'] ['touchup'], fill_hole=cfg.anatomical_preproc['brain_extraction'] ['AFNI-3dSkullStrip']['fill_hole'], NN_smooth=cfg.anatomical_preproc['brain_extraction'] ['AFNI-3dSkullStrip']['NN_smooth'], smooth_final=cfg.anatomical_preproc['brain_extraction'] ['AFNI-3dSkullStrip']['smooth_final'], avoid_eyes=cfg.anatomical_preproc['brain_extraction'] ['AFNI-3dSkullStrip']['avoid_eyes'], use_edge=cfg.anatomical_preproc['brain_extraction'] ['AFNI-3dSkullStrip']['use_edge'], exp_frac=cfg.anatomical_preproc['brain_extraction'] ['AFNI-3dSkullStrip']['exp_frac'], push_to_edge=cfg.anatomical_preproc['brain_extraction'] ['AFNI-3dSkullStrip']['push_to_edge'], use_skull=cfg.anatomical_preproc['brain_extraction'] ['AFNI-3dSkullStrip']['use_skull'], perc_int=cfg.anatomical_preproc['brain_extraction'] ['AFNI-3dSkullStrip']['perc_int'], max_inter_iter=cfg.anatomical_preproc['brain_extraction'] ['AFNI-3dSkullStrip']['max_inter_iter'], fac=cfg.anatomical_preproc['brain_extraction']['AFNI-3dSkullStrip'] ['fac'], blur_fwhm=cfg.anatomical_preproc['brain_extraction'] ['AFNI-3dSkullStrip']['blur_fwhm'], monkey=cfg.anatomical_preproc['brain_extraction']['AFNI-3dSkullStrip'] ['monkey'], ) wf.connect([(inputnode_afni, skullstrip_args, [('mask_vol', 'mask_vol'), ('shrink_factor', 'shrink_fac'), ('var_shrink_fac', 'var_shrink_fac'), ('shrink_fac_bot_lim', 'shrink_fac_bot_lim'), ('avoid_vent', 'avoid_vent'), ('niter', 'niter'), ('pushout', 'pushout'), ('touchup', 'touchup'), ('fill_hole', 'fill_hole'), ('avoid_eyes', 'avoid_eyes'), ('use_edge', 'use_edge'), ('exp_frac', 'exp_frac'), ('NN_smooth', 'NN_smooth'), ('smooth_final', 'smooth_final'), ('push_to_edge', 'push_to_edge'), ('use_skull', 'use_skull'), ('perc_int', 'perc_int'), ('max_inter_iter', 'max_inter_iter'), ('blur_fwhm', 'blur_fwhm'), ('fac', 'fac'), ('monkey', 'monkey')])]) anat_skullstrip = pe.Node(interface=afni.SkullStrip(), name=f'anat_skullstrip_{pipe_num}') anat_skullstrip.inputs.outputtype = 'NIFTI_GZ' node, out = strat_pool.get_data( ['desc-preproc_T1w', 'desc-reorient_T1w', 'T1w']) wf.connect(node, out, anat_skullstrip, 'in_file') wf.connect(skullstrip_args, 'expr', anat_skullstrip, 'args') # Generate anatomical brain mask anat_brain_mask = pe.Node(interface=afni.Calc(), name=f'anat_brain_mask_{pipe_num}') anat_brain_mask.inputs.expr = 'step(a)' anat_brain_mask.inputs.outputtype = 'NIFTI_GZ' wf.connect(anat_skullstrip, 'out_file', anat_brain_mask, 'in_file_a') outputs = {'space-T1w_desc-brain_mask': (anat_brain_mask, 'out_file')} return (wf, outputs)
), name='struct_bias', ) preproc_struct.connect([(selectfiles, struct_bias, [('struct', 'input_image')]) ]) # Reslice reslice = Node(afni.Resample(voxel_size=(0.1, 0.1, 0.1), resample_mode='Cu', out_file='struct_resliced.nii.gz'), name='reslice') preproc_struct.connect([(selectfiles, reslice, [('struct', 'in_file')])]) # Skull stripping skullstrip = Node(afni.SkullStrip(outputtype='NIFTI_GZ', args='-rat -surface_coil'), name='skullstrip') preproc_struct.connect([(reslice, skullstrip, [('out_file', 'in_file')])]) # Binarize mask struct_mask = Node(fs.Binarize(out_type='nii.gz', min=0.1, erode=1), name='struct_mask') preproc_struct.connect([(skullstrip, struct_mask, [('out_file', 'in_file')])]) #Reslice mask reslice_mask = Node(afni.Resample(resample_mode='NN', out_file='struct_mask.nii.gz'), name='reslice_mask') preproc_struct.connect([ (struct_bias, reslice_mask, [('output_image', 'master')]), (struct_mask, reslice_mask, [('binary_file', 'in_file')])
# Initialize workflow workflow = pe.Workflow(name='anat') workflow.base_dir = '.' ref_brain = '/usr/share/fsl/5.0/data/standard/MNI152_T1_2mm_brain.nii.gz' ref_mask = '/usr/share/fsl/5.0/data/standard/MNI152_T1_2mm_brain_mask.nii.gz' reference_skull = '/usr/share/fsl/5.0/data/standard/MNI152_T1_2mm.nii.gz' fnirt_config = '/usr/share/fsl/5.0/etc/flirtsch/T1_2_MNI152_2mm.cnf' # Reorient to FSL standard orientation deoblique = pe.Node(interface=afni.Warp(in_file=anat, deoblique=True, outputtype='NIFTI_GZ'), name='deoblique') reorient = pe.Node(interface=fsl.Reorient2Std(output_type='NIFTI_GZ'), name='reorient') workflow.connect(deoblique, 'out_file', reorient, 'in_file') # AFNI skullstrip skullstrip = pe.Node(interface=afni.SkullStrip(args='-push_to_edge -ld 30', outputtype='NIFTI_GZ'), name='skullstrip') workflow.connect(reorient, 'out_file', skullstrip, 'in_file') # Segment with FSL FAST #tissue priors #tissue_path = '/usr/share/fsl/5.0/data/standard/tissuepriors/2mm/' #csf_prior = tissue_path + 'avg152T1_csf_bin.nii.gz' #white_prior = tissue_path + 'avg152T1_white_bin.nii.gz' #gray_prior = tissue_path + 'avg152T1_gray_bin.nii.gz' #segmentation = pe.Node(interface=fsl.FAST(number_classes=3, use_priors=True, img_type=1), name='segmentation') #workflow.connect(skullstrip, 'out_file', segmentation, 'in_files') # Register to standard MNI template #1. linear linear_reg = pe.Node(interface=fsl.FLIRT(cost='corratio', reference=ref_brain), name='linear_reg')
def prepro_anat(k): try: subj = k for s in (['session2']): if (not os.path.isdir(data_path + subj + '/' + s)): continue if (os.path.isfile( results_path + subj + '/' + s + '/anat/nonlinear_reg/anat_HR_reoriented_warped.nii.gz')): print "Skipping " + subj + '/' + s continue ''' if (os.path.isfile(pilot_path +subj +'/anat/nonlinear_reg/anat_reoriented_skullstrip_warped.nii.gz')): print "Skipping "+ subj +'/' + s continue ''' try: os.stat(results_path) except: os.mkdir(results_path) try: os.stat(results_path + subj) except: os.mkdir(results_path + subj) try: os.stat(results_path + subj + '/' + s) except: os.mkdir(results_path + subj + '/' + s) os.chdir(results_path + subj + '/' + s) print "Currently processing subject: ", subj + '/' + s anat = data_path + subj + '/' + s + '/anat_HR.nii.gz' # Initialize workflow workflow = pe.Workflow(name='anat') workflow.base_dir = '.' # Reorient to FSL standard orientation deoblique = pe.Node( interface=afni.Warp(in_file=anat, deoblique=True, outputtype='NIFTI_GZ'), name='deoblique') #leave out if you don't need this reorient = pe.Node( interface=fsl.Reorient2Std(output_type='NIFTI_GZ'), name='reorient') workflow.connect(deoblique, 'out_file', reorient, 'in_file') # AFNI skullstrip skullstrip = pe.Node( interface=afni.SkullStrip(outputtype='NIFTI_GZ'), name='skullstrip') workflow.connect(reorient, 'out_file', skullstrip, 'in_file') # Segment with FSL FAST segmentation = pe.Node(interface=fsl.FAST(number_classes=3, use_priors=True, img_type=1), name='segmentation') segmentation.segments = True segmentation.probability_maps = True workflow.connect(skullstrip, 'out_file', segmentation, 'in_files') # Register to HR anatomical hranat = results_path + subj + '/session1/anat/reorient/anat_HR_brain_reoriented.nii.gz' #anat2hr = pe.Node(interface=fsl.FLIRT(no_search=True, reference=hranat), name='anat2hr') anat2hr = pe.Node(interface=fsl.FLIRT(dof=6, reference=hranat), name='anat2hr') workflow.connect(reorient, 'out_file', anat2hr, 'in_file') # Register to standard MNI template #1. linear linear_reg = pe.Node(interface=fsl.FLIRT(cost='corratio', reference=ref_brain), name='linear_reg') #2.nonlinear nonlinear_reg = pe.Node(interface=fsl.FNIRT(fieldcoeff_file=True, jacobian_file=True, ref_file=ref_brain, refmask_file=ref_mask), name='nonlinear_reg') inv_flirt_xfm = pe.Node( interface=fsl.utils.ConvertXFM(invert_xfm=True), name='inv_linear_xfm') workflow.connect(skullstrip, 'out_file', linear_reg, 'in_file') #workflow.connect(anat2hr, 'out_matrix_file', linear_reg, 'in_matrix_file') workflow.connect(linear_reg, 'out_matrix_file', nonlinear_reg, 'affine_file') workflow.connect(skullstrip, 'out_file', nonlinear_reg, 'in_file') workflow.connect(linear_reg, 'out_matrix_file', inv_flirt_xfm, 'in_file') # Run workflow workflow.write_graph() workflow.run() print "ANATOMICAL PREPROCESSING DONE! Results in ", results_path + subj + '/' + s except: print "Error with patient: ", subj traceback.print_exc()
def __init__(self, settings): # call base constructor super().__init__(settings) # define input/output node self.set_input(['T1', 'orig', 'brainmask']) self.set_output(['T1_skullstrip', 'allineate_freesurfer2anat']) # define datasink substitutions self.set_subs([('_maskop40', ''), ('_calc_calc_calc_calc_calc', '')]) # 3dAllineate (FSorig) self.allineate_orig = MapNode(afni.Allineate( out_matrix='FSorig2MPR.aff12.1D', overwrite=True, outputtype='NIFTI_GZ'), iterfield=['in_file', 'reference'], name='3dallineate_orig') # 3dAllineate (FSbrainmask) self.allineate_bm = MapNode( afni.Allineate(overwrite=True, no_pad=True, outputtype='NIFTI_GZ'), iterfield=['in_file', 'reference', 'in_matrix'], name='3dallineate_brainmask') # skullstrip mprage (afni) self.afni_skullstrip = MapNode(afni.SkullStrip(args="-orig_vol", outputtype="NIFTI_GZ"), iterfield=['in_file'], name='afni_skullstrip') # 3dcalc operations for achieving final mask self.maskop1 = MapNode(afni.Calc(expr='step(a)', overwrite=True, outputtype='NIFTI_GZ'), iterfield=['in_file_a'], name='maskop1') self.maskop2 = [] for n in range(3): self.maskop2.append( MapNode(afni.Calc( args='-b a+i -c a-i -d a+j -e a-j -f a+k -g a-k', expr='ispositive(a+b+c+d+e+f+g)', overwrite=True, outputtype='NIFTI_GZ'), iterfield=['in_file_a'], name='maskop2_{}'.format(n))) # Inline function for setting up to copy IJK_TO_DICOM_REAL file attribute self.refit_setup = MapNode(Function(input_names=['noskull_T1'], output_names=['refit_input'], function=lambda noskull_T1: (noskull_T1, 'IJK_TO_DICOM_REAL')), iterfield=['noskull_T1'], name='refitsetup') # 3dRefit self.refit = MapNode(afni.Refit(), iterfield=['in_file', 'atrcopy'], name='3drefit') # 3dcalc for uniform intensity self.uniform = MapNode(afni.Calc(expr='a*and(b,b)', overwrite=True, outputtype='NIFTI_GZ'), iterfield=['in_file_a', 'in_file_b'], name='uniformintensity') # skullstrip mprage (fsl) self.fsl_skullstrip = MapNode(fsl.BET(), iterfield=['in_file'], name='fsl_skullstrip') self.maskop3 = MapNode( afni.Calc(expr='or(a,b,c)', overwrite=True, outputtype='NIFTI_GZ'), iterfield=['in_file_a', 'in_file_b', 'in_file_c'], name='maskop3') self.maskop4 = MapNode( afni.Calc(expr='c*and(a,b)', overwrite=True, outputtype='NIFTI_GZ'), iterfield=['in_file_a', 'in_file_b', 'in_file_c'], name='maskop4') # Convert from list to string input self.select0T1 = Node(Function(input_names=['T1_list'], output_names=['T1_0'], function=lambda T1_list: T1_list[0]), name='select0T1') # apply bias field correction self.biasfieldcorrect = Node(ants.N4BiasFieldCorrection( num_threads=settings['num_threads'], copy_header=True), name='biasfieldcorrect')
def skullstrip_anatomical(method='afni', config=None, wf_name='skullstrip_anatomical'): method = method.lower() preproc = pe.Workflow(name=wf_name) inputnode = pe.Node(util.IdentityInterface(fields=['anat_data', 'brain_mask', 'template_brain_only_for_anat', 'template_skull_for_anat']), name='inputspec') outputnode = pe.Node(util.IdentityInterface(fields=['skullstrip', 'brain', 'brain_mask']), name='outputspec') if method == 'afni': # Skull-stripping using AFNI 3dSkullStrip inputnode_afni = pe.Node( util.IdentityInterface(fields=['mask_vol', 'shrink_factor', 'var_shrink_fac', 'shrink_fac_bot_lim', 'avoid_vent', 'niter', 'pushout', 'touchup', 'fill_hole', 'avoid_eyes', 'use_edge', 'exp_frac', 'smooth_final', 'push_to_edge', 'use_skull', 'perc_int', 'max_inter_iter', 'blur_fwhm', 'fac', 'monkey']), name='AFNI_options') skullstrip_args = pe.Node(util.Function(input_names=['spat_norm', 'spat_norm_dxyz', 'mask_vol', 'shrink_fac', 'var_shrink_fac', 'shrink_fac_bot_lim', 'avoid_vent', 'niter', 'pushout', 'touchup', 'fill_hole', 'avoid_eyes', 'use_edge', 'exp_frac', 'smooth_final', 'push_to_edge', 'use_skull', 'perc_int', 'max_inter_iter', 'blur_fwhm', 'fac', 'monkey'], output_names=['expr'], function=create_3dskullstrip_arg_string), name='anat_skullstrip_args') inputnode_afni.inputs.set( mask_vol=config.skullstrip_mask_vol, shrink_factor=config.skullstrip_shrink_factor, var_shrink_fac=config.skullstrip_var_shrink_fac, shrink_fac_bot_lim=config.skullstrip_shrink_factor_bot_lim, avoid_vent=config.skullstrip_avoid_vent, niter=config.skullstrip_n_iterations, pushout=config.skullstrip_pushout, touchup=config.skullstrip_touchup, fill_hole=config.skullstrip_fill_hole, avoid_eyes=config.skullstrip_avoid_eyes, use_edge=config.skullstrip_use_edge, exp_frac=config.skullstrip_exp_frac, smooth_final=config.skullstrip_smooth_final, push_to_edge=config.skullstrip_push_to_edge, use_skull=config.skullstrip_use_skull, perc_int=config.skullstrip_perc_int, max_inter_iter=config.skullstrip_max_inter_iter, blur_fwhm=config.skullstrip_blur_fwhm, fac=config.skullstrip_fac, monkey=config.skullstrip_monkey, ) preproc.connect([ (inputnode_afni, skullstrip_args, [ ('mask_vol', 'mask_vol'), ('shrink_factor', 'shrink_fac'), ('var_shrink_fac', 'var_shrink_fac'), ('shrink_fac_bot_lim', 'shrink_fac_bot_lim'), ('avoid_vent', 'avoid_vent'), ('niter', 'niter'), ('pushout', 'pushout'), ('touchup', 'touchup'), ('fill_hole', 'fill_hole'), ('avoid_eyes', 'avoid_eyes'), ('use_edge', 'use_edge'), ('exp_frac', 'exp_frac'), ('smooth_final', 'smooth_final'), ('push_to_edge', 'push_to_edge'), ('use_skull', 'use_skull'), ('perc_int', 'perc_int'), ('max_inter_iter', 'max_inter_iter'), ('blur_fwhm', 'blur_fwhm'), ('fac', 'fac'), ('monkey','monkey') ]) ]) anat_skullstrip = pe.Node(interface=afni.SkullStrip(), name='anat_skullstrip') anat_skullstrip.inputs.outputtype = 'NIFTI_GZ' preproc.connect(inputnode, 'anat_data', anat_skullstrip, 'in_file') preproc.connect(skullstrip_args, 'expr', anat_skullstrip, 'args') # Generate anatomical brain mask anat_brain_mask = pe.Node(interface=afni.Calc(), name='anat_brain_mask') anat_brain_mask.inputs.expr = 'step(a)' anat_brain_mask.inputs.outputtype = 'NIFTI_GZ' preproc.connect(anat_skullstrip, 'out_file', anat_brain_mask, 'in_file_a') # Apply skull-stripping step mask to original volume anat_skullstrip_orig_vol = pe.Node(interface=afni.Calc(), name='anat_skullstrip_orig_vol') anat_skullstrip_orig_vol.inputs.expr = 'a*step(b)' anat_skullstrip_orig_vol.inputs.outputtype = 'NIFTI_GZ' preproc.connect(inputnode, 'anat_data', anat_skullstrip_orig_vol, 'in_file_a') preproc.connect(anat_brain_mask, 'out_file', anat_skullstrip_orig_vol, 'in_file_b') preproc.connect(anat_brain_mask, 'out_file', outputnode, 'brain_mask') preproc.connect(anat_skullstrip_orig_vol, 'out_file', outputnode, 'brain') elif method == 'fsl': # Skull-stripping using FSL BET inputnode_bet = pe.Node( util.IdentityInterface(fields=['frac', 'mask_boolean', 'mesh_boolean', 'outline', 'padding', 'radius', 'reduce_bias', 'remove_eyes', 'robust', 'skull', 'surfaces', 'threshold', 'vertical_gradient']), name='BET_options') anat_skullstrip = pe.Node( interface=fsl.BET(), name='anat_skullstrip') anat_skullstrip.inputs.output_type = 'NIFTI_GZ' inputnode_bet.inputs.set( frac=config.bet_frac, mask_boolean=config.bet_mask_boolean, mesh_boolean=config.bet_mesh_boolean, outline=config.bet_outline, padding=config.bet_padding, radius=config.bet_radius, reduce_bias=config.bet_reduce_bias, remove_eyes=config.bet_remove_eyes, robust=config.bet_robust, skull=config.bet_skull, surfaces=config.bet_surfaces, threshold=config.bet_threshold, vertical_gradient=config.bet_vertical_gradient, ) preproc.connect(inputnode, 'anat_data', anat_skullstrip, 'in_file') preproc.connect([ (inputnode_bet, anat_skullstrip, [ ('frac', 'frac'), ('mask_boolean', 'mask'), ('mesh_boolean', 'mesh'), ('outline', 'outline'), ('padding', 'padding'), ('radius', 'radius'), ('reduce_bias', 'reduce_bias'), ('remove_eyes', 'remove_eyes'), ('robust', 'robust'), ('skull', 'skull'), ('surfaces', 'surfaces'), ('threshold', 'threshold'), ('vertical_gradient', 'vertical_gradient'), ]) ]) preproc.connect(anat_skullstrip, 'out_file', outputnode, 'skullstrip') # Apply skull-stripping step mask to original volume anat_skullstrip_orig_vol = pe.Node(interface=afni.Calc(), name='anat_skullstrip_orig_vol') anat_skullstrip_orig_vol.inputs.expr = 'a*step(b)' anat_skullstrip_orig_vol.inputs.outputtype = 'NIFTI_GZ' preproc.connect(inputnode, 'anat_data', anat_skullstrip_orig_vol, 'in_file_a') preproc.connect(anat_skullstrip, 'out_file', anat_skullstrip_orig_vol, 'in_file_b') preproc.connect(anat_skullstrip, 'mask_file', outputnode, 'brain_mask') preproc.connect(anat_skullstrip_orig_vol, 'out_file', outputnode, 'brain') elif method == 'niworkflows-ants': # Skull-stripping using niworkflows-ants anat_skullstrip_ants = init_brain_extraction_wf(tpl_target_path=config.niworkflows_ants_template_path, tpl_mask_path=config.niworkflows_ants_mask_path, tpl_regmask_path=config.niworkflows_ants_regmask_path, name='anat_skullstrip_ants') preproc.connect(inputnode, 'anat_data', anat_skullstrip_ants, 'inputnode.in_files') preproc.connect(anat_skullstrip_ants, 'copy_xform.out_file', outputnode, 'skullstrip') preproc.connect(anat_skullstrip_ants, 'copy_xform.out_file', outputnode, 'brain') preproc.connect(anat_skullstrip_ants, 'atropos_wf.copy_xform.out_mask', outputnode, 'brain_mask') elif method == 'mask': brain_mask_deoblique = pe.Node(interface=afni.Refit(), name='brain_mask_deoblique') brain_mask_deoblique.inputs.deoblique = True preproc.connect(inputnode, 'brain_mask', brain_mask_deoblique, 'in_file') brain_mask_reorient = pe.Node(interface=afni.Resample(), name='brain_mask_reorient') brain_mask_reorient.inputs.orientation = 'RPI' brain_mask_reorient.inputs.outputtype = 'NIFTI_GZ' preproc.connect(brain_mask_deoblique, 'out_file', brain_mask_reorient, 'in_file') anat_skullstrip_orig_vol = pe.Node(interface=afni.Calc(), name='anat_skullstrip_orig_vol') anat_skullstrip_orig_vol.inputs.expr = 'a*step(b)' anat_skullstrip_orig_vol.inputs.outputtype = 'NIFTI_GZ' preproc.connect(inputnode, 'anat_data', anat_skullstrip_orig_vol, 'in_file_a') preproc.connect(brain_mask_reorient, 'out_file', anat_skullstrip_orig_vol, 'in_file_b') preproc.connect(brain_mask_reorient, 'out_file', outputnode, 'brain_mask') preproc.connect(anat_skullstrip_orig_vol, 'out_file', outputnode, 'brain') elif method == 'unet': """ UNet options (following numbers are default): input_slice: 3 conv_block: 5 kernel_root: 16 rescale_dim: 256 """ # TODO: add options to pipeline_config unet_check_for_s3 = create_check_for_s3_node('unet', config.unet_model) unet_mask = pe.Node(util.Function(input_names=['model_path', 'cimg_in'], output_names=['out_path'], function=predict_volumes), name='unet_mask') preproc.connect(unet_check_for_s3, 'local_path', unet_mask, 'model_path') preproc.connect(inputnode, 'anat_data', unet_mask, 'cimg_in') """ Revised mask with ANTs """ # fslmaths <whole head> -mul <mask> brain.nii.gz unet_masked_brain = pe.Node(interface=fsl.MultiImageMaths(), name='unet_masked_brain') unet_masked_brain.inputs.op_string = "-mul %s" preproc.connect(inputnode, 'anat_data', unet_masked_brain, 'in_file') preproc.connect(unet_mask, 'out_path', unet_masked_brain, 'operand_files') # flirt -v -dof 6 -in brain.nii.gz -ref NMT_SS_0.5mm.nii.gz -o brain_rot2atl -omat brain_rot2atl.mat -interp sinc # TODO: antsRegistration -z 0 -d 3 -r [NMT_SS_0.5mm.nii.gz,brain.nii.gz,0] -o [transform,brain_rot2atl.nii.gz,brain_inv_rot2atl.nii.gz] -t Rigid[0.1] -m MI[NMT_SS_0.5mm.nii.gz,brain.nii.gz,1,32,Regular,0.25] -c [1000x500x250x100,1e-08,10] -s 3.0x2.0x1.0x0.0 -f 8x4x2x1 -u 1 -t Affine[0.1] -m MI[NMT_SS_0.5mm.nii.gz,brain.nii.gz,1,32,Regular,0.25] -c [1000x500x250x100,1e-08,10] -s 3.0x2.0x1.0x0.0 -f 8x4x2x1 -u 1 native_brain_to_template_brain = pe.Node(interface=fsl.FLIRT(), name='native_brain_to_template_brain') native_brain_to_template_brain.inputs.dof = 6 native_brain_to_template_brain.inputs.interp = 'sinc' preproc.connect(unet_masked_brain, 'out_file', native_brain_to_template_brain, 'in_file') preproc.connect(inputnode, 'template_brain_only_for_anat', native_brain_to_template_brain, 'reference') # flirt -in head.nii.gz -ref NMT_0.5mm.nii.gz -o head_rot2atl -applyxfm -init brain_rot2atl.mat # TODO: antsApplyTransforms -d 3 -i head.nii.gz -r NMT_0.5mm.nii.gz -n Linear -o head_rot2atl.nii.gz -v -t transform1Rigid.mat -t transform2Affine.mat -t transform0DerivedInitialMovingTranslation.mat native_head_to_template_head = pe.Node(interface=fsl.FLIRT(), name='native_head_to_template_head') native_head_to_template_head.inputs.apply_xfm = True preproc.connect(inputnode, 'anat_data', native_head_to_template_head, 'in_file') preproc.connect(native_brain_to_template_brain, 'out_matrix_file', native_head_to_template_head, 'in_matrix_file') preproc.connect(inputnode, 'template_skull_for_anat', native_head_to_template_head, 'reference') # fslmaths NMT_SS_0.5mm.nii.gz -bin templateMask.nii.gz template_brain_mask = pe.Node(interface=fsl.maths.MathsCommand(), name='template_brain_mask') template_brain_mask.inputs.args = '-bin' preproc.connect(inputnode, 'template_brain_only_for_anat', template_brain_mask, 'in_file') # ANTS 3 -m CC[head_rot2atl.nii.gz,NMT_0.5mm.nii.gz,1,5] -t SyN[0.25] -r Gauss[3,0] -o atl2T1rot -i 60x50x20 --use-Histogram-Matching --number-of-affine-iterations 10000x10000x10000x10000x10000 --MI-option 32x16000 ants_template_head_to_template = pe.Node(interface=ants.Registration(), name='template_head_to_template') ants_template_head_to_template.inputs.metric = ['CC'] ants_template_head_to_template.inputs.metric_weight = [1,5] ants_template_head_to_template.inputs.transforms = ['SyN'] ants_template_head_to_template.inputs.transform_parameters = [(0.25,)] ants_template_head_to_template.inputs.interpolation = 'NearestNeighbor' ants_template_head_to_template.inputs.number_of_iterations = [[60,50,20]] ants_template_head_to_template.inputs.smoothing_sigmas = [[0.6,0.2,0.0]] ants_template_head_to_template.inputs.shrink_factors = [[4,2,1]] ants_template_head_to_template.inputs.convergence_threshold = [1.e-8] preproc.connect(native_head_to_template_head, 'out_file', ants_template_head_to_template, 'fixed_image') preproc.connect(inputnode, 'template_skull_for_anat', ants_template_head_to_template, 'moving_image') # antsApplyTransforms -d 3 -i templateMask.nii.gz -t atl2T1rotWarp.nii.gz atl2T1rotAffine.txt -r brain_rot2atl.nii.gz -o brain_rot2atl_mask.nii.gz template_head_transform_to_template = pe.Node(interface=ants.ApplyTransforms(), name='template_head_transform_to_template') template_head_transform_to_template.inputs.dimension = 3 preproc.connect(template_brain_mask, 'out_file', template_head_transform_to_template, 'input_image') preproc.connect(native_brain_to_template_brain, 'out_file', template_head_transform_to_template, 'reference_image') preproc.connect(ants_template_head_to_template, 'forward_transforms', template_head_transform_to_template, 'transforms') # TODO: replace convert_xfm and flirt with: # antsApplyTransforms -d 3 -i brain_rot2atl_mask.nii.gz -r brain.nii.gz -n linear -o brain_mask.nii.gz -t [transform0DerivedInitialMovingTranslation.mat,1] -t [transform2Affine.mat,1] -t [transform1Rigid.mat,1] # convert_xfm -omat brain_rot2native.mat -inverse brain_rot2atl.mat invt = pe.Node(interface=fsl.ConvertXFM(), name='convert_xfm') invt.inputs.invert_xfm = True preproc.connect(native_brain_to_template_brain, 'out_matrix_file', invt, 'in_file') # flirt -in brain_rot2atl_mask.nii.gz -ref brain.nii.gz -o brain_mask.nii.gz -applyxfm -init brain_rot2native.mat template_brain_to_native_brain = pe.Node(interface=fsl.FLIRT(), name='template_brain_to_native_brain') template_brain_to_native_brain.inputs.apply_xfm = True preproc.connect(template_head_transform_to_template, 'output_image', template_brain_to_native_brain, 'in_file') preproc.connect(unet_masked_brain, 'out_file', template_brain_to_native_brain, 'reference') preproc.connect(invt, 'out_file', template_brain_to_native_brain, 'in_matrix_file') # fslmaths brain_mask.nii.gz -thr .5 -bin brain_mask_thr.nii.gz refined_mask = pe.Node(interface=fsl.Threshold(), name='refined_mask') refined_mask.inputs.thresh = 0.5 refined_mask.inputs.args = '-bin' preproc.connect(template_brain_to_native_brain, 'out_file', refined_mask, 'in_file') # get a new brain with mask refined_brain = pe.Node(interface=fsl.MultiImageMaths(), name='refined_brain') refined_brain.inputs.op_string = "-mul %s" preproc.connect(inputnode, 'anat_data', refined_brain, 'in_file') preproc.connect(refined_mask, 'out_file', refined_brain, 'operand_files') preproc.connect(refined_mask, 'out_file', outputnode, 'brain_mask') preproc.connect(refined_brain, 'out_file', outputnode, 'brain') return preproc
ref_brain = '/usr/share/fsl/5.0/data/standard/MNI152_T1_2mm_brain.nii.gz' ref_mask = '/usr/share/fsl/5.0/data/standard/MNI152_T1_2mm_brain_mask.nii.gz' reference_skull = '/usr/share/fsl/5.0/data/standard/MNI152_T1_2mm.nii.gz' fnirt_config = '/usr/share/fsl/5.0/etc/flirtsch/T1_2_MNI152_2mm.cnf' # Reorient to FSL standard orientation deoblique = pe.Node(interface=afni.Warp(in_file=anat, deoblique=True, outputtype='NIFTI_GZ'), name='deoblique') reorient = pe.Node(interface=fsl.Reorient2Std(output_type='NIFTI_GZ'), name='reorient') workflow.connect(deoblique, 'out_file', reorient, 'in_file') # AFNI skullstrip skullstrip = pe.Node(interface=afni.SkullStrip(args='-no_use_edge -ld 20', outputtype='NIFTI_GZ'), name='skullstrip') workflow.connect(reorient, 'out_file', skullstrip, 'in_file') # Segment with FSL FAST #tissue priors #tissue_path = '/usr/share/fsl/5.0/data/standard/tissuepriors/2mm/' #csf_prior = tissue_path + 'avg152T1_csf_bin.nii.gz' #white_prior = tissue_path + 'avg152T1_white_bin.nii.gz' #gray_prior = tissue_path + 'avg152T1_gray_bin.nii.gz' #segmentation = pe.Node(interface=fsl.FAST(number_classes=3, use_priors=True, img_type=1), name='segmentation') #workflow.connect(skullstrip, 'out_file', segmentation, 'in_files') # Register to standard MNI template #1. linear
def afni_wf(name='AFNISkullStripWorkflow', unifize=False, n4_nthreads=1): """ Skull-stripping workflow Originally derived from the `codebase of the QAP <https://github.com/preprocessed-connectomes-project/\ quality-assessment-protocol/blob/master/qap/anatomical_preproc.py#L105>`_. Now, this workflow includes :abbr:`INU (intensity non-uniformity)` correction using the N4 algorithm and (optionally) intensity harmonization using ANFI's ``3dUnifize``. """ workflow = pe.Workflow(name=name) inputnode = pe.Node(niu.IdentityInterface(fields=['in_file']), name='inputnode') outputnode = pe.Node(niu.IdentityInterface( fields=['bias_corrected', 'out_file', 'out_mask', 'bias_image']), name='outputnode') inu_n4 = pe.Node(ants.N4BiasFieldCorrection(dimension=3, save_bias=True, num_threads=n4_nthreads, copy_header=True), n_procs=n4_nthreads, name='inu_n4') sstrip = pe.Node(afni.SkullStrip(outputtype='NIFTI_GZ'), name='skullstrip') sstrip_orig_vol = pe.Node(afni.Calc(expr='a*step(b)', outputtype='NIFTI_GZ'), name='sstrip_orig_vol') binarize = pe.Node(fsl.Threshold(args='-bin', thresh=1.e-3), name='binarize') if unifize: # Add two unifize steps, pre- and post- skullstripping. inu_uni_0 = pe.Node(afni.Unifize(outputtype='NIFTI_GZ'), name='unifize_pre_skullstrip') inu_uni_1 = pe.Node(afni.Unifize(gm=True, outputtype='NIFTI_GZ'), name='unifize_post_skullstrip') workflow.connect([ (inu_n4, inu_uni_0, [('output_image', 'in_file')]), (inu_uni_0, sstrip, [('out_file', 'in_file')]), (inu_uni_0, sstrip_orig_vol, [('out_file', 'in_file_a')]), (sstrip_orig_vol, inu_uni_1, [('out_file', 'in_file')]), (inu_uni_1, outputnode, [('out_file', 'out_file')]), (inu_uni_0, outputnode, [('out_file', 'bias_corrected')]), ]) else: workflow.connect([ (inputnode, sstrip_orig_vol, [('in_file', 'in_file_a')]), (inu_n4, sstrip, [('output_image', 'in_file')]), (sstrip_orig_vol, outputnode, [('out_file', 'out_file')]), (inu_n4, outputnode, [('output_image', 'bias_corrected')]), ]) # Remaining connections workflow.connect([ (sstrip, sstrip_orig_vol, [('out_file', 'in_file_b')]), (inputnode, inu_n4, [('in_file', 'input_image')]), (sstrip_orig_vol, binarize, [('out_file', 'in_file')]), (binarize, outputnode, [('out_file', 'out_mask')]), (inu_n4, outputnode, [('bias_image', 'bias_image')]), ]) return workflow
def afni_wf(name="AFNISkullStripWorkflow", unifize=False, n4_nthreads=1): """ Create a skull-stripping workflow based on AFNI's tools. Originally derived from the `codebase of the QAP <https://github.com/preprocessed-connectomes-project/quality-assessment-protocol/blob/master/qap/anatomical_preproc.py#L105>`_. Now, this workflow includes :abbr:`INU (intensity non-uniformity)` correction using the N4 algorithm and (optionally) intensity harmonization using ANFI's ``3dUnifize``. Workflow Graph .. workflow:: :graph2use: orig :simple_form: yes from niworkflows.anat.skullstrip import afni_wf wf = afni_wf() Parameters ---------- n4_nthreads : int number of cpus N4 bias field correction can utilize. unifize : bool whether AFNI's ``3dUnifize`` should be applied (default: ``False``). name : str name for the workflow hierarchy of Nipype Inputs ------ in_file : str input T1w image. Outputs ------- bias_corrected : str path to the bias corrected input MRI. out_file : str path to the skull-stripped image. out_mask : str path to the generated brain mask. bias_image : str path to the B1 inhomogeneity field. """ workflow = pe.Workflow(name=name) inputnode = pe.Node(niu.IdentityInterface(fields=["in_file"]), name="inputnode") outputnode = pe.Node( niu.IdentityInterface( fields=["bias_corrected", "out_file", "out_mask", "bias_image"]), name="outputnode", ) inu_n4 = pe.Node( N4BiasFieldCorrection( dimension=3, save_bias=True, num_threads=n4_nthreads, rescale_intensities=True, copy_header=True, ), n_procs=n4_nthreads, name="inu_n4", ) sstrip = pe.Node(afni.SkullStrip(outputtype="NIFTI_GZ"), name="skullstrip") sstrip_orig_vol = pe.Node(afni.Calc(expr="a*step(b)", outputtype="NIFTI_GZ"), name="sstrip_orig_vol") binarize = pe.Node(Binarize(thresh_low=0.0), name="binarize") if unifize: # Add two unifize steps, pre- and post- skullstripping. inu_uni_0 = pe.Node(afni.Unifize(outputtype="NIFTI_GZ"), name="unifize_pre_skullstrip") inu_uni_1 = pe.Node(afni.Unifize(gm=True, outputtype="NIFTI_GZ"), name="unifize_post_skullstrip") # fmt: off workflow.connect([ (inu_n4, inu_uni_0, [("output_image", "in_file")]), (inu_uni_0, sstrip, [("out_file", "in_file")]), (inu_uni_0, sstrip_orig_vol, [("out_file", "in_file_a")]), (sstrip_orig_vol, inu_uni_1, [("out_file", "in_file")]), (inu_uni_1, outputnode, [("out_file", "out_file")]), (inu_uni_0, outputnode, [("out_file", "bias_corrected")]), ]) # fmt: on else: # fmt: off workflow.connect([ (inputnode, sstrip_orig_vol, [("in_file", "in_file_a")]), (inu_n4, sstrip, [("output_image", "in_file")]), (sstrip_orig_vol, outputnode, [("out_file", "out_file")]), (inu_n4, outputnode, [("output_image", "bias_corrected")]), ]) # fmt: on # Remaining connections # fmt: off workflow.connect([ (sstrip, sstrip_orig_vol, [("out_file", "in_file_b")]), (inputnode, inu_n4, [("in_file", "input_image")]), (sstrip_orig_vol, binarize, [("out_file", "in_file")]), (binarize, outputnode, [("out_mask", "out_mask")]), (inu_n4, outputnode, [("bias_image", "bias_image")]), ]) # fmt: on return workflow
#find the mean, matched_mean = outdir + '/meanmatchpe.nii.gz' opposed_mean = outdir + '/meanoppppe.nii.gz' meanimage(matched_pe, matched_mean) meanimage(opposed_pe, opposed_mean) matched_bias = n4_correction(in_file=matched_mean) opposed_bias = n4_correction(in_file=opposed_mean) matched_brain = outdir + '/matchpe_brain.nii.gz' #afni 3dskulkstrip is better matched_brain = outdir + '/matchpe_brain.nii.gz' opposed_brain = outdir + '/opppe_brain.nii.gz' matched_mask = outdir + '/matchpe_mask.nii.gz' opposed_mask = outdir + '/opppe_mask.nii.gz' skultri = afni.SkullStrip() skultri.inputs.in_file = matched_bias skultri.inputs.out_file = matched_brain skultri.run() skultri.inputs.in_file = opposed_mean skultri.inputs.out_file = opposed_brain skultri.run() #register both AP and PA to bold opposed_warped = outdir + '/opposewd_warped.nii.gz' matched_warped = outdir + '/matched_warped.nii.gz' opposed_regis = antsregistration(fixed=reference, moving=opposed_brain, output_warped=opposed_warped,
name='io_BIDSDataGrabber') #Flexibly collect data from disk to feed into workflows. io_SelectFiles = pe.Node(io.SelectFiles(templates={}), name='io_SelectFiles') #Use spm_realign for estimating within modality rigid body alignment spm_Realign = pe.Node(interface=spm.Realign(), name='spm_Realign') #Use spm_smooth for 3D Gaussian smoothing of image volumes. spm_Smooth = pe.Node(interface=spm.Smooth(), name='spm_Smooth') #Use spm_coreg for estimating cross-modality rigid body alignment spm_Coregister = pe.Node(interface=spm.Coregister(), name='spm_Coregister') #Wraps the executable command ``3dSkullStrip``. afni_SkullStrip = pe.Node(interface=afni.SkullStrip(), name='afni_SkullStrip') #Wraps the executable command ``3dretroicor``. afni_Retroicor = pe.Node(interface=afni.Retroicor(), name='afni_Retroicor') #Wraps the executable command ``3dvolreg``. afni_Volreg = pe.Node(interface=afni.Volreg(), name='afni_Volreg') #Calculates the diffusion tensor model parameters dipy_DTI = pe.Node(interface=dipy.DTI(), name='dipy_DTI') #An interface to denoising diffusion datasets [Coupe2008]_. dipy_Denoise = pe.Node(interface=dipy.Denoise(), name='dipy_Denoise') #Wraps the executable command ``flirt``. fsl_FLIRT = pe.Node(interface=fsl.FLIRT(), name='fsl_FLIRT')
def prepro_anat(k): try: subj = k for s in (['session2', 'session3']): if (not os.path.isdir(results_path + subj + '/' + s)): continue os.chdir(results_path + subj + '/' + s) # go to patient directory print "Currently processing subject: ", subj + '/' + s if reskullstrip: anat = results_path + subj + '/' + s + '/anat/reorient/anat_reoriented.nii.gz' # Initialize workflow workflow = pe.Workflow(name='seg_anat') workflow.base_dir = '.' # AFNI skullstrip skullstrip = pe.Node(interface=afni.SkullStrip( in_file=anat, outputtype='NIFTI_GZ'), name='skullstrip_default') # Segment with FSL FAST segmentation = pe.Node(interface=fsl.FAST(number_classes=3, use_priors=True, img_type=1), name='segmentation') segmentation.segments = True segmentation.probability_maps = True workflow.connect(reorient, 'out_file', segmentation, 'in_files') # Run workflow workflow.write_graph() workflow.run() else: if not os.path.isdir('seg_anat'): os.mkdir('seg_anat') if not os.path.isdir('seg_anat/segmentation'): os.mkdir('seg_anat/segmentation') os.chdir('seg_anat/segmentation') # Segment with FSL FAST segmentation = fsl.FAST() segmentation.inputs.number_classes = 3 segmentation.inputs.use_priors = True segmentation.inputs.img_type = 1 segmentation.inputs.segments = True segmentation.inputs.probability_maps = True segmentation.inputs.in_files = results_path + subj + '/' + s + '/anat/reorient/anat_LR_brain_reoriented.nii.gz' segmentation.inputs.out_basename = 'anat_LR_brain_reoriented' segmentation.run() print "ANATOMICAL SEGMENTATION DONE! Results in ", results_path + subj + '/' + s except: print "Error with patient: ", subj traceback.print_exc()
preproc.connect([(img_split, struct_bias, [('out_files', 'input_image')])]) # Merge corrected files again img_merge = Node(fsl.Merge(dimension='t', output_type='NIFTI_GZ', merged_file='struct_corr.nii.gz'), name='img_merge') preproc.connect([(struct_bias, img_merge, [('output_image', 'in_files')])]) # Create average across all echo times average = Node(fsl.MeanImage(out_file='struct_corr_avg.nii.gz'), name='struct_average') preproc.connect([(img_merge, average, [('merged_file', 'in_file')])]) # Skull stripping on first echo time (highest SNR) skullstrip = Node(afni.SkullStrip(outputtype='NIFTI_GZ', args='-rat -push_to_edge -orig_vol'), name='skullstrip') preproc.connect([(struct_bias, skullstrip, [(('output_image', selectindex, [0]), 'in_file')])]) # Binarize mask struct_mask = Node(fs.Binarize(out_type='nii.gz', min=0.1, binary_file='struct_mask.nii.gz'), name='struct_mask') preproc.connect([(skullstrip, struct_mask, [('out_file', 'in_file')])]) # Create masked, weighted image for coregistration weighted_avg = Node(util.Function(input_names=['in_file', 'mask_file'], output_names=['out_file'], function=weighted_avg),
def create_EPI_DistCorr(use_BET, wf_name='epi_distcorr'): """ Fieldmap correction takes in an input magnitude image which is Skull Stripped (Tight). The magnitude images are obtained from each echo series. It also requires a phase image as an input, the phase image is a subtraction of the two phase images from each echo. Created on Thu Nov 9 10:44:47 2017 @author: nrajamani Order of commands and inputs: -- SkullStrip: 3d-SkullStrip (or FSL-BET) is used to strip the non-brain (tissue) regions from the fMRI Parameters: -f, default: 0.5 in_file: fmap_mag -- fslmath_mag: Magnitude image is eroded using the -ero option in fslmath, in order to remove the non-zero voxels Parameters: -ero in_file:fmap_mag -- bet_anat : Brain extraction of the anat file to provide as an input for the epi-registration interface Parameters: -f, default: 0.5 in_file: anat_file -- fast_anat : Fast segmentation to provide partial volume files of the anat file, which is further processed to provide the white mater segmentation input for the epi-registration interface. The most important output required from this is the second segment, (e.g.,'T1_brain_pve_2.nii.gz') Parameters: -img_type = 1 -bias_iters = 10 (-I) -bias_lowpass = 10 (-l) in_file: brain_extracted anat_file -- fslmath_anat: The output of the FAST interface is then analyzed to select all the voxels with more than 50% partial volume into the binary mask Parameters: -thr = 0.5 in_file : T1_brain_pve_2 -- fslmath_wmseg:The selected voxels are now used to create a binary mask which would can then be sent as the white matter segmentation (wm_seg) Parameters: -bin in_file: T1_brain_pve_2 -- Prepare :Preparing the fieldmap. Parameters: -deltaTE = default, 2.46 ms -Scanner = SIEMENS in_files: fmap_phase fmap_magnitude For more details, check:https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/FUGUE/Guide -- FUGUE :One of the steps in EPI-DistCorrection toolbox, it unwarps the fieldmaps Parameters: dwell_to_asymm ratio = (0.77e-3 * 3)/(2.46e-3) dwell time = 0.0005 ms in_file = field map which is a 4D image (containing 2 unwarpped image) """ preproc = pe.Workflow(name=wf_name) inputNode = pe.Node( util.IdentityInterface(fields=['anat_file', 'fmap_pha', 'fmap_mag']), name='inputspec') inputNode_delTE = pe.Node(util.IdentityInterface(fields=['deltaTE']), name='deltaTE_input') inputNode_dwellT = pe.Node(util.IdentityInterface(fields=['dwellT']), name='dwellT_input') inputNode_dwell_asym_ratio = pe.Node( util.IdentityInterface(fields=['dwell_asym_ratio']), name='dwell_asym_ratio_input') inputNode_bet_frac = pe.Node(util.IdentityInterface(fields=['bet_frac']), name='bet_frac_input') inputNode_afni_threshold = pe.Node( util.IdentityInterface(fields=['afni_threshold']), name='afni_threshold_input') outputNode = pe.Node(util.IdentityInterface( fields=['fieldmap', 'fmap_despiked', 'fmapmagbrain', 'fieldmapmask']), name='outputspec') # Skull-strip, outputs a masked image file if use_BET == False: skullstrip_args = pe.Node(util.Function(input_names=['shrink_fac'], output_names=['expr'], function=createAFNIiterable), name='distcorr_skullstrip_arg') preproc.connect(inputNode_afni_threshold, 'afni_threshold', skullstrip_args, 'shrink_fac') bet = pe.Node(interface=afni.SkullStrip(), name='bet') bet.inputs.outputtype = 'NIFTI_GZ' preproc.connect(skullstrip_args, 'expr', bet, 'args') preproc.connect(inputNode, 'fmap_mag', bet, 'in_file') preproc.connect(bet, 'out_file', outputNode, 'magnitude_image') else: bet = pe.Node(interface=fsl.BET(), name='bet') bet.inputs.output_type = 'NIFTI_GZ' preproc.connect(inputNode_bet_frac, 'bet_frac', bet, 'frac') preproc.connect(inputNode, 'fmap_mag', bet, 'in_file') preproc.connect(bet, 'out_file', outputNode, 'magnitude_image') # Prepare Fieldmap # prepare the field map prepare = pe.Node(interface=fsl.epi.PrepareFieldmap(), name='prepare') prepare.inputs.output_type = "NIFTI_GZ" preproc.connect(inputNode_delTE, 'deltaTE', prepare, 'delta_TE') preproc.connect(inputNode, 'fmap_pha', prepare, 'in_phase') preproc.connect(bet, 'out_file', prepare, 'in_magnitude') preproc.connect(prepare, 'out_fieldmap', outputNode, 'fieldmap') # erode the masked magnitude image fslmath_mag = pe.Node(interface=fsl.ErodeImage(), name='fslmath_mag') preproc.connect(bet, 'out_file', fslmath_mag, 'in_file') preproc.connect(fslmath_mag, 'out_file', outputNode, 'fmapmagbrain') # calculate the absolute value of the eroded and masked magnitude # image fslmath_abs = pe.Node(interface=fsl.UnaryMaths(), name='fslmath_abs') fslmath_abs.inputs.operation = 'abs' preproc.connect(fslmath_mag, 'out_file', fslmath_abs, 'in_file') preproc.connect(fslmath_abs, 'out_file', outputNode, 'fmapmag_abs') # binarize the absolute value of the eroded and masked magnitude # image fslmath_bin = pe.Node(interface=fsl.UnaryMaths(), name='fslmath_bin') fslmath_bin.inputs.operation = 'bin' preproc.connect(fslmath_abs, 'out_file', fslmath_bin, 'in_file') preproc.connect(fslmath_bin, 'out_file', outputNode, 'fmapmag_bin') # take the absolute value of the fieldmap calculated in the prepare step fslmath_mask_1 = pe.Node(interface=fsl.UnaryMaths(), name='fslmath_mask_1') fslmath_mask_1.inputs.operation = 'abs' preproc.connect(prepare, 'out_fieldmap', fslmath_mask_1, 'in_file') preproc.connect(fslmath_mask_1, 'out_file', outputNode, 'fieldmapmask_abs') # binarize the absolute value of the fieldmap calculated in the prepare step fslmath_mask_2 = pe.Node(interface=fsl.UnaryMaths(), name='fslmath_mask_2') fslmath_mask_2.inputs.operation = 'bin' preproc.connect(fslmath_mask_1, 'out_file', fslmath_mask_2, 'in_file') preproc.connect(fslmath_mask_2, 'out_file', outputNode, 'fieldmapmask_bin') # multiply together the binarized magnitude and fieldmap images fslmath_mask = pe.Node(interface=fsl.BinaryMaths(), name='fslmath_mask') fslmath_mask.inputs.operation = 'mul' preproc.connect(fslmath_mask_2, 'out_file', fslmath_mask, 'in_file') preproc.connect(fslmath_bin, 'out_file', fslmath_mask, 'operand_file') preproc.connect(fslmath_mask, 'out_file', outputNode, 'fieldmapmask') # Note for the user. Ensure the phase image is within 0-4096 (upper # threshold is 90% of 4096), fsl_prepare_fieldmap will only work in the # case of the SIEMENS format. #Maybe we could use deltaTE also as an # option in the GUI. # fugue fugue1 = pe.Node(interface=fsl.FUGUE(), name='fugue1') fugue1.inputs.save_fmap = True fugue1.outputs.fmap_out_file = 'fmap_rads' preproc.connect(fslmath_mask, 'out_file', fugue1, 'mask_file') preproc.connect(inputNode_dwellT, 'dwellT', fugue1, 'dwell_time') preproc.connect(inputNode_dwell_asym_ratio, 'dwell_asym_ratio', fugue1, 'dwell_to_asym_ratio') preproc.connect(prepare, 'out_fieldmap', fugue1, 'fmap_in_file') preproc.connect(fugue1, 'fmap_out_file', outputNode, 'fmap_despiked') return preproc
NodeHash_30bb950.inputs.template = 'sub-01/anat/sub-01_T1w.nii.gz' #Wraps command **N4BiasFieldCorrection** NodeHash_1ea4b50 = pe.Node(interface=ants.N4BiasFieldCorrection(), name='NodeName_1ea4b50') NodeHash_1ea4b50.inputs.copy_header = False NodeHash_1ea4b50.inputs.dimension = 3 NodeHash_1ea4b50.inputs.num_threads = 4 NodeHash_1ea4b50.inputs.save_bias = True #Wraps command **3dUnifize** NodeHash_291d6d0 = pe.Node(interface=afni.Unifize(), name='NodeName_291d6d0') NodeHash_291d6d0.inputs.outputtype = 'NIFTI_GZ' #Wraps command **3dSkullStrip** NodeHash_1ddfa30 = pe.Node(interface=afni.SkullStrip(), name='NodeName_1ddfa30') NodeHash_1ddfa30.inputs.outputtype = 'NIFTI_GZ' #Wraps command **3dcalc** NodeHash_3bd6370 = pe.Node(interface=afni.Calc(), name='NodeName_3bd6370') NodeHash_3bd6370.inputs.expr = 'a*step(b)' NodeHash_3bd6370.inputs.outputtype = 'NIFTI_GZ' #Wraps command **fslmaths** NodeHash_49ddb10 = pe.Node(interface=fsl.Threshold(), name='NodeName_49ddb10') NodeHash_49ddb10.inputs.args = '-bin' NodeHash_49ddb10.inputs.thresh = 1.e-3 #Wraps command **3dUnifize** NodeHash_229c200 = pe.Node(interface=afni.Unifize(), name='NodeName_229c200')