def create_templates_2func_workflow(threshold=0.5, name='templates_2func_workflow'): templates_2func_workflow = Workflow(name=name) # Input Node inputspec = Node(utility.IdentityInterface(fields=[ 'func_file', 'premat', 'warp', 'templates', ]), name='inputspec') # Get the overal EPI to MNI warp func_2mni_warp = Node(fsl.ConvertWarp(), name='func_2mni_warp') func_2mni_warp.inputs.reference = fsl.Info.standard_image( 'MNI152_T1_2mm.nii.gz') # Calculate the inverse warp mni_2func_warp = Node(fsl.InvWarp(), name='mni_2func_warp') # Transform MNI templates to EPI space templates_2func_apply = MapNode(fsl.ApplyWarp(), iterfield=['in_file'], name='templates_2func_apply') # Threshold templates templates_threshold = MapNode( fsl.ImageMaths(op_string='-thr {0} -bin'.format(threshold)), iterfield=['in_file'], name='templates_threshold') # Output Node outputspec = Node(utility.IdentityInterface( fields=['templates_2func_files', 'func_2mni_warp']), name='outputspec') # Connect the workflow nodes templates_2func_workflow.connect(inputspec, 'premat', func_2mni_warp, 'premat') templates_2func_workflow.connect(inputspec, 'warp', func_2mni_warp, 'warp1') templates_2func_workflow.connect(inputspec, 'func_file', mni_2func_warp, 'reference') templates_2func_workflow.connect(func_2mni_warp, 'out_file', mni_2func_warp, 'warp') templates_2func_workflow.connect(inputspec, 'templates', templates_2func_apply, 'in_file') templates_2func_workflow.connect(inputspec, 'func_file', templates_2func_apply, 'ref_file') templates_2func_workflow.connect(mni_2func_warp, 'inverse_warp', templates_2func_apply, 'field_file') templates_2func_workflow.connect(templates_2func_apply, 'out_file', templates_threshold, 'in_file') templates_2func_workflow.connect(func_2mni_warp, 'out_file', outputspec, 'func_2mni_warp') templates_2func_workflow.connect(templates_threshold, 'out_file', outputspec, 'templates_2func_files') return templates_2func_workflow
def invert_warp(in_file: Path, ref: Path, out_warp: Path, in_warp: Path): """ Apply FSL's invwarp to invert a warp file Arguments: in_file {Path} -- [description] out_file {Path} -- [description] in_warp {Path} -- [description] """ invwarp = fsl.InvWarp() invwarp.inputs.warp = in_warp invwarp.inputs.reference = ref invwarp.inputs.inverse_warp = out_warp return invert_warp
def create_normalization_wf(transformations=["mni2func"]): wf = pe.Workflow(name="normalization") inputspec = pe.Node(util.IdentityInterface(fields=[ 'T1', 'skullstripped_T1', 'preprocessed_epi', 'func2anat_transform' ]), name="inputspec") anat2mni = create_nonlinear_register("anat2mni") linear_reg = anat2mni.get_node("linear_reg_0") linear_reg.inputs.searchr_x = [-180, 180] linear_reg.inputs.searchr_y = [-180, 180] linear_reg.inputs.searchr_z = [-180, 180] skull_mgz2nii = pe.Node(fs.MRIConvert(out_type="nii"), name="skull_mgs2nii") brain_mgz2nii = skull_mgz2nii.clone(name="brain_mgs2nii") wf.connect(inputspec, "skullstripped_T1", brain_mgz2nii, "in_file") wf.connect(inputspec, "T1", skull_mgz2nii, "in_file") anat2mni.inputs.inputspec.reference_skull = fsl.Info.standard_image( "MNI152_T1_2mm.nii.gz") anat2mni.inputs.inputspec.reference_brain = fsl.Info.standard_image( "MNI152_T1_2mm_brain.nii.gz") anat2mni.inputs.inputspec.fnirt_config = "T1_2_MNI152_2mm" wf.connect(skull_mgz2nii, "out_file", anat2mni, "inputspec.input_skull") wf.connect(brain_mgz2nii, "out_file", anat2mni, "inputspec.input_brain") if 'mni2func' in transformations: invert_warp = pe.Node(fsl.InvWarp(), name="invert_warp") wf.connect(anat2mni, "outputspec.nonlinear_xfm", invert_warp, "warp_file") wf.connect(skull_mgz2nii, "out_file", invert_warp, "ref_file") if 'func2mni' in transformations: mni_warp = pe.Node(interface=fsl.ApplyWarp(), name='mni_warp') mni_warp.inputs.ref_file = fsl.Info.standard_image( "MNI152_T1_2mm.nii.gz") wf.connect(inputspec, 'preprocessed_epi', mni_warp, 'in_file') wf.connect(anat2mni, 'outputspec.nonlinear_xfm', mni_warp, 'field_file') wf.connect(inputspec, 'func2anat_transform', mni_warp, 'premat') return wf
def process_vsm(name='VSM2DFM'): """ A workflow that computes the inverse and the determinant of jacobians map """ inputnode = pe.Node(niu.IdentityInterface( fields=['vsm', 'reference', 'scaling', 'enc_dir']), name='inputnode') outputnode = pe.Node(niu.IdentityInterface( fields=['dfm', 'inv_dfm', 'jacobian', 'inv_jacobian']), name='outputnode') vsm2dfm = nwu.vsm2warp() invwarp = pe.Node(fsl.InvWarp(relative=True), name='InvWarp') coeffs = pe.Node(fsl.WarpUtils(out_format='spline'), name='CoeffComp') jacobian = pe.Node(fsl.WarpUtils(write_jacobian=True), name='JacobianComp') invcoef = pe.Node(fsl.WarpUtils(out_format='spline'), name='InvCoeffComp') invjac = pe.Node(fsl.WarpUtils(write_jacobian=True), name='InvJacobianComp') wf = pe.Workflow(name=name) wf.connect([(inputnode, vsm2dfm, [('reference', 'inputnode.in_ref'), ('enc_dir', 'inputnode.enc_dir'), ('vsm', 'inputnode.in_vsm'), ('scaling', 'inputnode.scaling')]), (vsm2dfm, invwarp, [('outputnode.out_warp', 'warp')]), (inputnode, invwarp, [('reference', 'reference')]), (vsm2dfm, coeffs, [('outputnode.out_warp', 'in_file')]), (inputnode, coeffs, [('reference', 'reference')]), (inputnode, jacobian, [('reference', 'reference')]), (coeffs, jacobian, [('out_file', 'in_file')]), (vsm2dfm, outputnode, [('outputnode.out_warp', 'dfm')]), (invwarp, outputnode, [('inverse_warp', 'inv_dfm')]), (jacobian, outputnode, [('out_jacobian', 'jacobian')]), (invwarp, invcoef, [('inverse_warp', 'in_file')]), (inputnode, invcoef, [('reference', 'reference')]), (inputnode, invjac, [('reference', 'reference')]), (invcoef, invjac, [('out_file', 'in_file')]), (invjac, outputnode, [('out_jacobian', 'inv_jacobian')])]) return wf
def create_registration_pipeline(working_dir, freesurfer_dir, ds_dir, name='registration'): """ find transformations between struct, funct, and MNI """ # initiate workflow reg_wf = Workflow(name=name) reg_wf.base_dir = os.path.join(working_dir, 'LeiCA_resting', 'rsfMRI_preprocessing') # set fsl output fsl.FSLCommand.set_default_output_type('NIFTI_GZ') freesurfer.FSCommand.set_default_subjects_dir(freesurfer_dir) # inputnode inputnode = Node(util.IdentityInterface(fields=[ 'initial_mean_epi_moco', 't1w', 't1w_brain', 'subject_id', 'wm_mask_4_bbr', 'struct_brain_mask' ]), name='inputnode') outputnode = Node(util.IdentityInterface(fields=[ 'struct_2_MNI_warp', 'epi_2_struct_mat', 'struct_2_epi_mat', 'epi_2_MNI_warp', 'MNI_2_epi_warp', 'fs_2_struct_mat', 'mean_epi_structSpace', 'mean_epi_MNIspace', 'struct_MNIspace' ]), name='outputnode') ds = Node(nio.DataSink(base_directory=ds_dir), name='ds') ds.inputs.substitutions = [('_TR_id_', 'TR_')] ########################################## # TOC REGISTRATION MATS AND WARPS ########################################## # I. STRUCT -> MNI ## 1. STRUCT -> MNI with FLIRT ## 2. CALC. WARP STRUCT -> MNI with FNIRT # II.EPI -> STRUCT ## 3. calc EPI->STRUCT initial registration ## 4. run EPI->STRUCT via bbr ## 5. INVERT to get: STRUCT -> EPI # III. COMBINE I. & II.: EPI -> MNI ## 6. COMBINE MATS: EPI -> MNI ## 7. MNI -> EPI ########################################## # CREATE REGISTRATION MATS AND WARPS ########################################## # I. STRUCT -> MNI ########################################## # 1. REGISTER STRUCT -> MNI with FLIRT struct_2_MNI_mat = Node(fsl.FLIRT(dof=12), name='struct_2_MNI_mat') struct_2_MNI_mat.inputs.reference = fsl.Info.standard_image( 'MNI152_T1_2mm_brain.nii.gz') reg_wf.connect(inputnode, 't1w_brain', struct_2_MNI_mat, 'in_file') reg_wf.connect(struct_2_MNI_mat, 'out_matrix_file', outputnode, 'struct_2_MNI_mat_flirt') # 2. CALC. WARP STRUCT -> MNI with FNIRT # cf. wrt. 2mm # https://www.jiscmail.ac.uk/cgi-bin/webadmin?A2=ind1311&L=FSL&P=R86108&1=FSL&9=A&J=on&d=No+Match%3BMatch%3BMatches&z=4 struct_2_MNI_warp = Node(fsl.FNIRT(), name='struct_2_MNI_warp') struct_2_MNI_warp.inputs.config_file = 'T1_2_MNI152_2mm' struct_2_MNI_warp.inputs.ref_file = fsl.Info.standard_image( 'MNI152_T1_2mm.nii.gz') struct_2_MNI_warp.inputs.field_file = 'struct_2_MNI_warp.nii.gz' struct_2_MNI_warp.plugin_args = {'submit_specs': 'request_memory = 4000'} reg_wf.connect(inputnode, 't1w', struct_2_MNI_warp, 'in_file') reg_wf.connect(struct_2_MNI_mat, 'out_matrix_file', struct_2_MNI_warp, 'affine_file') reg_wf.connect(struct_2_MNI_warp, 'field_file', ds, 'registration.struct_2_MNI_warp') reg_wf.connect(struct_2_MNI_warp, 'field_file', outputnode, 'struct_2_MNI_warp') reg_wf.connect(struct_2_MNI_warp, 'warped_file', outputnode, 'struct_MNIspace') reg_wf.connect(struct_2_MNI_warp, 'warped_file', ds, 'registration.struct_MNIspace') # II.EPI -> STRUCT (via bbr) ########################################## # 3. calc EPI->STRUCT initial registration with flirt dof=6 and corratio epi_2_struct_flirt6_mat = Node(fsl.FLIRT(dof=6, cost='corratio'), name='epi_2_struct_flirt6_mat') epi_2_struct_flirt6_mat.inputs.out_file = 'epi_structSpace_flirt6.nii.gz' reg_wf.connect(inputnode, 't1w_brain', epi_2_struct_flirt6_mat, 'reference') reg_wf.connect(inputnode, 'initial_mean_epi_moco', epi_2_struct_flirt6_mat, 'in_file') # 4. run EPI->STRUCT via bbr bbr_shedule = os.path.join(os.getenv('FSLDIR'), 'etc/flirtsch/bbr.sch') epi_2_struct_bbr_mat = Node(interface=fsl.FLIRT(dof=6, cost='bbr'), name='epi_2_struct_bbr_mat') epi_2_struct_bbr_mat.inputs.schedule = bbr_shedule epi_2_struct_bbr_mat.inputs.out_file = 'epi_structSpace.nii.gz' reg_wf.connect(inputnode, 'initial_mean_epi_moco', epi_2_struct_bbr_mat, 'in_file') reg_wf.connect(inputnode, 't1w_brain', epi_2_struct_bbr_mat, 'reference') reg_wf.connect(epi_2_struct_flirt6_mat, 'out_matrix_file', epi_2_struct_bbr_mat, 'in_matrix_file') reg_wf.connect(inputnode, 'wm_mask_4_bbr', epi_2_struct_bbr_mat, 'wm_seg') reg_wf.connect(epi_2_struct_bbr_mat, 'out_matrix_file', ds, 'registration.epi_2_struct_mat') reg_wf.connect(epi_2_struct_bbr_mat, 'out_file', outputnode, 'mean_epi_structSpace') # 5. INVERT to get: STRUCT -> EPI struct_2_epi_mat = Node(fsl.ConvertXFM(invert_xfm=True), name='struct_2_epi_mat') reg_wf.connect(epi_2_struct_bbr_mat, 'out_matrix_file', struct_2_epi_mat, 'in_file') reg_wf.connect(struct_2_epi_mat, 'out_file', outputnode, 'struct_2_epi_mat') # III. COMBINE I. & II.: EPI -> MNI ########################################## # 6. COMBINE MATS: EPI -> MNI epi_2_MNI_warp = Node(fsl.ConvertWarp(), name='epi_2_MNI_warp') epi_2_MNI_warp.inputs.reference = fsl.Info.standard_image( 'MNI152_T1_2mm.nii.gz') reg_wf.connect(epi_2_struct_bbr_mat, 'out_matrix_file', epi_2_MNI_warp, 'premat') # epi2struct reg_wf.connect(struct_2_MNI_warp, 'field_file', epi_2_MNI_warp, 'warp1') # struct2mni reg_wf.connect(epi_2_MNI_warp, 'out_file', outputnode, 'epi_2_MNI_warp') reg_wf.connect(epi_2_MNI_warp, 'out_file', ds, 'registration.epi_2_MNI_warp') # output: out_file # 7. MNI -> EPI MNI_2_epi_warp = Node(fsl.InvWarp(), name='MNI_2_epi_warp') MNI_2_epi_warp.inputs.reference = fsl.Info.standard_image( 'MNI152_T1_2mm.nii.gz') reg_wf.connect(epi_2_MNI_warp, 'out_file', MNI_2_epi_warp, 'warp') reg_wf.connect(inputnode, 'initial_mean_epi_moco', MNI_2_epi_warp, 'reference') reg_wf.connect(MNI_2_epi_warp, 'inverse_warp', outputnode, 'MNI_2_epi_warp') # output: inverse_warp ########################################## # TRANSFORM VOLUMES ########################################## # CREATE STRUCT IN EPI SPACE FOR DEBUGGING struct_epiSpace = Node(fsl.ApplyXfm(), name='struct_epiSpace') struct_epiSpace.inputs.out_file = 'struct_brain_epiSpace.nii.gz' reg_wf.connect(inputnode, 't1w_brain', struct_epiSpace, 'in_file') reg_wf.connect(inputnode, 'initial_mean_epi_moco', struct_epiSpace, 'reference') reg_wf.connect(struct_2_epi_mat, 'out_file', struct_epiSpace, 'in_matrix_file') reg_wf.connect(struct_epiSpace, 'out_file', ds, 'QC.struct_brain_epiSpace') # CREATE EPI IN MNI SPACE mean_epi_MNIspace = Node(fsl.ApplyWarp(), name='mean_epi_MNIspace') mean_epi_MNIspace.inputs.ref_file = fsl.Info.standard_image( 'MNI152_T1_2mm_brain.nii.gz') mean_epi_MNIspace.inputs.out_file = 'mean_epi_MNIspace.nii.gz' reg_wf.connect(inputnode, 'initial_mean_epi_moco', mean_epi_MNIspace, 'in_file') reg_wf.connect(epi_2_MNI_warp, 'out_file', mean_epi_MNIspace, 'field_file') reg_wf.connect(mean_epi_MNIspace, 'out_file', ds, 'registration.mean_epi_MNIspace') reg_wf.connect(mean_epi_MNIspace, 'out_file', outputnode, 'mean_epi_MNIspace') # CREATE MNI IN EPI SPACE FOR DEBUGGING MNI_epiSpace = Node(fsl.ApplyWarp(), name='MNI_epiSpace') MNI_epiSpace.inputs.in_file = fsl.Info.standard_image( 'MNI152_T1_2mm_brain.nii.gz') MNI_epiSpace.inputs.out_file = 'MNI_epiSpace.nii.gz' reg_wf.connect(inputnode, 'initial_mean_epi_moco', MNI_epiSpace, 'ref_file') reg_wf.connect(MNI_2_epi_warp, 'inverse_warp', MNI_epiSpace, 'field_file') reg_wf.connect(MNI_epiSpace, 'out_file', ds, 'registration.MNI_epiSpace') reg_wf.write_graph(dotfilename=reg_wf.name, graph2use='flat', format='pdf') return reg_wf
def prepro_func(i): try: subj = i for s in (['session2']): # Define input files: 2xfMRI + 1xMPRAGE func1 = data_path + subj + '/Functional_scans/' + s[:-2] + s[ -1] + '_a/epi.nii.gz' #choose this for patients func2 = data_path + subj + '/Functional_scans/' + s[:-2] + s[ -1] + '_b/epi.nii.gz' #choose this for patients #anat = glob.glob(anat_path + subj +'/'+ s + '/anat/reorient/anat_*.nii.gz') #choose this for session 1 lesion_mask_file = anat_path + subj + '/session1/anat/reorient/lesion_seg.nii.gz' old_lesion_mask_file = glob.glob( anat_path + subj + '/session1/anat/reorient/old_lesion_seg.nii.gz' ) #choose this for ones with no old lesion #old_lesion_mask_file = anat_path + subj +'/session1/anat/reorient/old_lesion_seg.nii.gz' #choose this for ones with old lesion anat = glob.glob(anat_path + subj + '/' + s + '/anat/anat2hr/anat_*.nii.gz' ) #choose this for sessions 2 and 3 anat_CSF = glob.glob( anat_path + subj + '/session1/seg_anat/segmentation/anat_*_pve_0.nii.gz' ) # don't change, same for all sessions anat_WM = glob.glob( anat_path + subj + '/session1/seg_anat/segmentation/anat_*_pve_2.nii.gz' ) # don't change, same for all sessions anat_GM = glob.glob( anat_path + subj + '/session1/seg_anat/segmentation/anat_*_pve_1.nii.gz' ) # don't change, same for all sessions anat2MNI_fieldwarp = glob.glob( anat_path + subj + '/session1/anat/nonlinear_reg/anat_*_fieldwarp.nii.gz' ) # don't change, same for all sessions if not os.path.isdir(data_path + subj + '/' + s): # No data exists continue if not os.path.isfile(func1): print '1. functional file ' + func1 + ' not found. Skipping!' continue if not os.path.isfile(func2): print '2. functional file ' + func2 + ' not found. Skipping!' continue if not anat: print 'Preprocessed anatomical file not found. Skipping!' continue if len(anat) > 1: print 'WARNING: found multiple files of preprocessed anatomical image!' continue anat = anat[0] if not anat2MNI_fieldwarp: print 'Anatomical registration to MNI152-space field file not found. Skipping!' continue if len(anat2MNI_fieldwarp) > 1: print 'WARNING: found multiple files of anat2MNI fieldwarp!' continue anat2MNI_fieldwarp = anat2MNI_fieldwarp[0] if not anat_CSF: anat_CSF = glob.glob( anat_path + subj + '/' + s + '/seg_anat/segmentation/anat_*_pve_0.nii.gz') if not anat_CSF: print 'Anatomical segmentation CSF file not found. Skipping!' continue if len(anat_CSF) > 1: print 'WARNING: found multiple files of anatomical CSF file!' continue anat_CSF = anat_CSF[0] if not anat_WM: anat_WM = glob.glob( anat_path + subj + '/' + s + '/seg_anat/segmentation/anat_*_pve_2.nii.gz') if not anat_WM: print 'Anatomical segmentation WM file not found. Skipping!' continue if len(anat_WM) > 1: print 'WARNING: found multiple files of anatomical WM file!' continue anat_WM = anat_WM[0] if not anat_GM: anat_GM = glob.glob( anat_path + subj + '/' + s + '/seg_anat/segmentation/anat_*_pve_1.nii.gz') if not anat_GM: print 'Anatomical segmentation GM file not found. Skipping!' continue if len(anat_GM) > 1: print 'WARNING: found multiple files of anatomical GM file!' continue anat_GM = anat_GM[0] if not os.path.isdir(results_path + subj): os.mkdir(results_path + subj) if not os.path.isdir(results_path + subj + '/' + s): os.mkdir(results_path + subj + '/' + s) for data in acquisitions: os.chdir(results_path + subj + '/' + s) print "Currently processing subject: " + subj + '/' + s + ' ' + data #Initialize workflows workflow = pe.Workflow(name=data) workflow.base_dir = '.' inputnode = pe.Node( interface=util.IdentityInterface(fields=['source_file']), name='inputspec') outputnode = pe.Node( interface=util.IdentityInterface(fields=['result_func']), name='outputspec') if data == 'func1': inputnode.inputs.source_file = func1 else: inputnode.inputs.source_file = func2 # Remove n_dummies first volumes trim = pe.Node(interface=Trim(begin_index=n_dummies), name='trim') workflow.connect(inputnode, 'source_file', trim, 'in_file') # Motion correction + slice timing correction realign4d = pe.Node(interface=SpaceTimeRealigner(), name='realign4d') #realign4d.inputs.ignore_exception=True realign4d.inputs.slice_times = 'asc_alt_siemens' realign4d.inputs.slice_info = 2 # horizontal slices realign4d.inputs.tr = mytr # TR in seconds workflow.connect(trim, 'out_file', realign4d, 'in_file') # Reorient #deoblique = pe.Node(interface=afni.Warp(deoblique=True, outputtype='NIFTI_GZ'), name='deoblique') #leave out if you don't need this #workflow.connect(realign4d, 'out_file', deoblique, 'in_file') reorient = pe.Node( interface=fsl.Reorient2Std(output_type='NIFTI_GZ'), name='reorient') workflow.connect(realign4d, 'out_file', reorient, 'in_file') # AFNI skullstrip and mean image skullstrip tstat1 = pe.Node(interface=afni.TStat(args='-mean', outputtype="NIFTI_GZ"), name='tstat1') automask = pe.Node(interface=afni.Automask( dilate=1, outputtype="NIFTI_GZ"), name='automask') skullstrip = pe.Node(interface=afni.Calc( expr='a*b', outputtype="NIFTI_GZ"), name='skullstrip') tstat2 = pe.Node(interface=afni.TStat(args='-mean', outputtype="NIFTI_GZ"), name='tstat2') workflow.connect(reorient, 'out_file', tstat1, 'in_file') workflow.connect(tstat1, 'out_file', automask, 'in_file') workflow.connect(automask, 'out_file', skullstrip, 'in_file_b') workflow.connect(reorient, 'out_file', skullstrip, 'in_file_a') workflow.connect(skullstrip, 'out_file', tstat2, 'in_file') # Register to anatomical space #can be changed #mean2anat = pe.Node(fsl.FLIRT(bins=40, cost='normmi', dof=7, interp='nearestneighbour', searchr_x=[-180,180], searchr_y=[-180,180], searchr_z=[-180,180]), name='mean2anat') mean2anat = pe.Node(fsl.FLIRT(bins=40, cost='normmi', dof=7, interp='nearestneighbour'), name='mean2anat') #mean2anat = pe.Node(fsl.FLIRT(no_search=True), name='mean2anat') mean2anat.inputs.reference = anat workflow.connect(tstat2, 'out_file', mean2anat, 'in_file') # Transform mean functional image warpmean = pe.Node(interface=fsl.ApplyWarp(), name='warpmean') warpmean.inputs.ref_file = MNI_brain warpmean.inputs.field_file = anat2MNI_fieldwarp workflow.connect(mean2anat, 'out_matrix_file', warpmean, 'premat') workflow.connect(tstat2, 'out_file', warpmean, 'in_file') # ----- inversion matrix and eroded brain mask for regression ----- # create inverse matrix from mean2anat registration invmat = pe.Node(fsl.ConvertXFM(), name='invmat') invmat.inputs.invert_xfm = True workflow.connect(mean2anat, 'out_matrix_file', invmat, 'in_file') # erode functional brain mask erode_brain = pe.Node(fsl.ImageMaths(), name='erode_brain') erode_brain.inputs.args = '-kernel boxv 3 -ero' workflow.connect(automask, 'out_file', erode_brain, 'in_file') # register GM mask to functional image space, this is done for quality control reg_GM = pe.Node(fsl.preprocess.ApplyXFM(), name='register_GM') reg_GM.inputs.apply_xfm = True reg_GM.inputs.in_file = anat_GM workflow.connect(tstat2, 'out_file', reg_GM, 'reference') workflow.connect(invmat, 'out_file', reg_GM, 'in_matrix_file') # --------- motion regression and censor signals ------------------ # normalize motion parameters norm_motion = pe.Node(interface=Function( input_names=['in_file'], output_names=['out_file'], function=normalize_motion_data), name='normalize_motion') workflow.connect(realign4d, 'par_file', norm_motion, 'in_file') # create censor file, for censoring motion get_censor = pe.Node(afni.OneDToolPy(), name='motion_censors') get_censor.inputs.set_nruns = 1 get_censor.inputs.censor_motion = (censor_thr, 'motion') get_censor.inputs.show_censor_count = True if overwrite: get_censor.inputs.args = '-overwrite' workflow.connect(norm_motion, 'out_file', get_censor, 'in_file') # compute motion parameter derivatives (for use in regression) deriv_motion = pe.Node(afni.OneDToolPy(), name='deriv_motion') deriv_motion.inputs.set_nruns = 1 deriv_motion.inputs.derivative = True if overwrite: deriv_motion.inputs.args = '-overwrite' deriv_motion.inputs.out_file = 'motion_derivatives.txt' workflow.connect(norm_motion, 'out_file', deriv_motion, 'in_file') # scale motion parameters and get quadratures quadr_motion = pe.Node(interface=Function( input_names=['in_file', 'multicol'], output_names=['out_file', 'out_quadr_file'], function=scale_and_quadrature), name='quadr_motion') quadr_motion.inputs.multicol = True workflow.connect(norm_motion, 'out_file', quadr_motion, 'in_file') # scale motion derivatives and get quadratures quadr_motion_deriv = pe.Node(interface=Function( input_names=['in_file', 'multicol'], output_names=['out_file', 'out_quadr_file'], function=scale_and_quadrature), name='quadr_motion_deriv') quadr_motion_deriv.inputs.multicol = True workflow.connect(deriv_motion, 'out_file', quadr_motion_deriv, 'in_file') # -------- CSF regression signals --------------- # threshold and erode CSF mask erode_CSF_mask = pe.Node(fsl.ImageMaths(), name='erode_CSF_mask') erode_CSF_mask.inputs.args = '-thr 0.5 -kernel boxv 3 -ero' erode_CSF_mask.inputs.in_file = anat_CSF # register CSF mask to functional image space reg_CSF_mask = pe.Node(fsl.preprocess.ApplyXFM(), name='register_CSF_mask') reg_CSF_mask.inputs.apply_xfm = True workflow.connect(tstat2, 'out_file', reg_CSF_mask, 'reference') workflow.connect(invmat, 'out_file', reg_CSF_mask, 'in_matrix_file') # inverse lesion mask and remove it from CSF mask #remove this if you don't have a lesion mask inverse_lesion_mask = pe.Node(fsl.ImageMaths(), name='inverse_lesion_mask') inverse_lesion_mask.inputs.args = '-add 1 -rem 2' inverse_lesion_mask.inputs.in_file = lesion_mask_file rem_lesion = pe.Node(fsl.ImageMaths(), name='remove_lesion') workflow.connect(erode_CSF_mask, 'out_file', rem_lesion, 'in_file') workflow.connect(inverse_lesion_mask, 'out_file', rem_lesion, 'mask_file') ''' # Transform lesion mask to MNI152 space #remove if lesion masks are already in MNI152 space warp_lesion = pe.Node(interface=fsl.ApplyWarp(), name='warp_lesion') warp_lesion.inputs.ref_file = MNI_brain warp_lesion.inputs.field_file = anat2MNI_fieldwarp warp_lesion.inputs.in_file = lesion_mask_file warp_lesion.inputs.out_file = anat_path + subj +'/'+ s + '/anat/nonlinear_reg/lesion_seg_warp.nii.gz' warp_lesion.run() ''' # inverse old lesion mask and remove it from CSF mask #remove this if you don't have a lesion mask if old_lesion_mask_file: inverse_old_lesion_mask = pe.Node( fsl.ImageMaths(), name='inverse_old_lesion_mask') inverse_old_lesion_mask.inputs.args = '-add 1 -rem 3' #inverse_old_lesion_mask.inputs.in_file = old_lesion_mask_file[0] inverse_old_lesion_mask.inputs.in_file = old_lesion_mask_file rem_old_lesion = pe.Node(fsl.ImageMaths(), name='remove_old_lesion') workflow.connect(rem_lesion, 'out_file', rem_old_lesion, 'in_file') workflow.connect(inverse_old_lesion_mask, 'out_file', rem_old_lesion, 'mask_file') workflow.connect(rem_old_lesion, 'out_file', reg_CSF_mask, 'in_file') ''' # Transform old lesion mask to MNI152 space #remove if lesion masks are already in MNI152 space warp_old_lesion = pe.Node(interface=fsl.ApplyWarp(), name='warp_old_lesion') warp_old_lesion.inputs.ref_file = MNI_brain warp_old_lesion.inputs.field_file = anat2MNI_fieldwarp warp_old_lesion.inputs.in_file = old_lesion_mask_file warp_old_lesion.inputs.out_file = anat_path + subj +'/'+ s + '/anat/nonlinear_reg/old_lesion_seg_warp.nii.gz' warp_old_lesion.run() ''' else: workflow.connect(rem_lesion, 'out_file', reg_CSF_mask, 'in_file') # threshold CSF mask and intersect with functional brain mask thr_CSF_mask = pe.Node(fsl.ImageMaths(), name='threshold_CSF_mask') thr_CSF_mask.inputs.args = '-thr 0.25' workflow.connect(reg_CSF_mask, 'out_file', thr_CSF_mask, 'in_file') workflow.connect(erode_brain, 'out_file', thr_CSF_mask, 'mask_file') # extract CSF values get_CSF_noise = pe.Node(fsl.ImageMeants(), name='get_CSF_noise') workflow.connect(skullstrip, 'out_file', get_CSF_noise, 'in_file') workflow.connect(thr_CSF_mask, 'out_file', get_CSF_noise, 'mask') # compute CSF noise derivatives deriv_CSF = pe.Node(afni.OneDToolPy(), name='deriv_CSF') deriv_CSF.inputs.set_nruns = 1 deriv_CSF.inputs.derivative = True if overwrite: deriv_CSF.inputs.args = '-overwrite' deriv_CSF.inputs.out_file = 'CSF_derivatives.txt' workflow.connect(get_CSF_noise, 'out_file', deriv_CSF, 'in_file') # scale SCF noise and get quadratures quadr_CSF = pe.Node(interface=Function( input_names=['in_file', 'multicol'], output_names=['out_file', 'out_quadr_file'], function=scale_and_quadrature), name='quadr_CSF') quadr_CSF.inputs.multicol = False workflow.connect(get_CSF_noise, 'out_file', quadr_CSF, 'in_file') # scale CSF noise derivatives and get quadratures quadr_CSF_deriv = pe.Node(interface=Function( input_names=['in_file', 'multicol'], output_names=['out_file', 'out_quadr_file'], function=scale_and_quadrature), name='quadr_CSF_deriv') quadr_CSF_deriv.inputs.multicol = False workflow.connect(deriv_CSF, 'out_file', quadr_CSF_deriv, 'in_file') # -------- WM regression signals ----------------- # threshold and erode WM mask erode_WM_mask = pe.Node(fsl.ImageMaths(), name='erode_WM_mask') erode_WM_mask.inputs.args = '-thr 0.5 -kernel boxv 7 -ero' erode_WM_mask.inputs.in_file = anat_WM # registrer WM mask to functional image space reg_WM_mask = pe.Node(fsl.preprocess.ApplyXFM(), name='register_WM_mask') reg_WM_mask.inputs.apply_xfm = True workflow.connect(tstat2, 'out_file', reg_WM_mask, 'reference') workflow.connect(invmat, 'out_file', reg_WM_mask, 'in_matrix_file') workflow.connect(erode_WM_mask, 'out_file', reg_WM_mask, 'in_file') # create inverse nonlinear registration MNI2anat invwarp = pe.Node(fsl.InvWarp(output_type='NIFTI_GZ'), name='invwarp') invwarp.inputs.warp = anat2MNI_fieldwarp invwarp.inputs.reference = anat # transform ventricle mask to functional space reg_ventricles = pe.Node(fsl.ApplyWarp(), name='register_ventricle_mask') reg_ventricles.inputs.in_file = ventricle_mask workflow.connect(tstat2, 'out_file', reg_ventricles, 'ref_file') workflow.connect(invwarp, 'inverse_warp', reg_ventricles, 'field_file') workflow.connect(invmat, 'out_file', reg_ventricles, 'postmat') # threshold WM mask and intersect with functional brain mask thr_WM_mask = pe.Node(fsl.ImageMaths(), name='threshold_WM_mask') thr_WM_mask.inputs.args = '-thr 0.25' workflow.connect(reg_WM_mask, 'out_file', thr_WM_mask, 'in_file') workflow.connect(erode_brain, 'out_file', thr_WM_mask, 'mask_file') # remove ventricles from WM mask exclude_ventricles = pe.Node(fsl.ImageMaths(), name='exclude_ventricles') workflow.connect(thr_WM_mask, 'out_file', exclude_ventricles, 'in_file') workflow.connect(reg_ventricles, 'out_file', exclude_ventricles, 'mask_file') # check that WM is collected from both hemispheres check_WM_bilat = pe.Node(interface=Function( input_names=['in_file'], output_names=['errors'], function=check_bilateralism), name='check_WM_bilateralism') workflow.connect(exclude_ventricles, 'out_file', check_WM_bilat, 'in_file') # extract WM values get_WM_noise = pe.Node(fsl.ImageMeants(), name='get_WM_noise') workflow.connect(skullstrip, 'out_file', get_WM_noise, 'in_file') workflow.connect(exclude_ventricles, 'out_file', get_WM_noise, 'mask') # compute WM noise derivatives deriv_WM = pe.Node(afni.OneDToolPy(), name='deriv_WM') deriv_WM.inputs.set_nruns = 1 deriv_WM.inputs.derivative = True if overwrite: deriv_WM.inputs.args = '-overwrite' deriv_WM.inputs.out_file = 'WM_derivatives.txt' workflow.connect(get_WM_noise, 'out_file', deriv_WM, 'in_file') # scale WM noise and get quadratures quadr_WM = pe.Node(interface=Function( input_names=['in_file', 'multicol'], output_names=['out_file', 'out_quadr_file'], function=scale_and_quadrature), name='quadr_WM') quadr_WM.inputs.multicol = False workflow.connect(get_WM_noise, 'out_file', quadr_WM, 'in_file') # scale WM noise derivatives and get quadratures quadr_WM_deriv = pe.Node(interface=Function( input_names=['in_file', 'multicol'], output_names=['out_file', 'out_quadr_file'], function=scale_and_quadrature), name='quadr_WM_deriv') quadr_WM_deriv.inputs.multicol = False workflow.connect(deriv_WM, 'out_file', quadr_WM_deriv, 'in_file') # ---------- global regression signals ---------------- if global_reg: # register anatomical whole brain mask to functional image space reg_glob_mask = pe.Node(fsl.preprocess.ApplyXFM(), name='register_global_mask') reg_glob_mask.inputs.apply_xfm = True reg_glob_mask.inputs.in_file = anat workflow.connect(tstat2, 'out_file', reg_glob_mask, 'reference') workflow.connect(invmat, 'out_file', reg_glob_mask, 'in_matrix_file') # threshold anatomical brain mask and intersect with functional brain mask thr_glob_mask = pe.Node(fsl.ImageMaths(), name='threshold_global_mask') thr_glob_mask.inputs.args = '-thr -0.1' workflow.connect(reg_glob_mask, 'out_file', thr_glob_mask, 'in_file') workflow.connect(erode_brain, 'out_file', thr_glob_mask, 'mask_file') # extract global signal values get_glob_noise = pe.Node(fsl.ImageMeants(), name='get_global_noise') workflow.connect(skullstrip, 'out_file', get_glob_noise, 'in_file') workflow.connect(thr_glob_mask, 'out_file', get_glob_noise, 'mask') # compute global noise derivative deriv_glob = pe.Node(afni.OneDToolPy(), name='deriv_global') deriv_glob.inputs.set_nruns = 1 deriv_glob.inputs.derivative = True if overwrite: deriv_glob.inputs.args = '-overwrite' deriv_glob.inputs.out_file = 'global_derivatives.txt' workflow.connect(get_glob_noise, 'out_file', deriv_glob, 'in_file') # scale global noise and get quadratures quadr_glob = pe.Node(interface=Function( input_names=['in_file', 'multicol'], output_names=['out_file', 'out_quadr_file'], function=scale_and_quadrature), name='quadr_glob') quadr_glob.inputs.multicol = False workflow.connect(get_glob_noise, 'out_file', quadr_glob, 'in_file') # scale global noise derivatives and get quadratures quadr_glob_deriv = pe.Node(interface=Function( input_names=['in_file', 'multicol'], output_names=['out_file', 'out_quadr_file'], function=scale_and_quadrature), name='quadr_glob_deriv') quadr_glob_deriv.inputs.multicol = False workflow.connect(deriv_glob, 'out_file', quadr_glob_deriv, 'in_file') # ---------- regression matrix ---------- # create bandpass regressors, can not be easily implemented to workflow get_bandpass = pe.Node(interface=Function( input_names=['minf', 'maxf', 'example_file', 'tr'], output_names=['out_tuple'], function=bandpass), name='bandpass_regressors') get_bandpass.inputs.minf = myminf get_bandpass.inputs.maxf = mymaxf get_bandpass.inputs.tr = mytr workflow.connect(norm_motion, 'out_file', get_bandpass, 'example_file') # concatenate regressor time series cat_reg_name = 'cat_regressors' if global_reg: cat_reg_name = cat_reg_name + '_global' cat_reg = pe.Node(interface=Function( input_names=[ 'mot', 'motd', 'motq', 'motdq', 'CSF', 'CSFd', 'CSFq', 'CSFdq', 'WM', 'WMd', 'WMq', 'WMdq', 'include_global', 'glob', 'globd', 'globq', 'globdq' ], output_names=['reg_file_args'], function=concatenate_regressors), name=cat_reg_name) cat_reg.inputs.include_global = global_reg workflow.connect(quadr_motion, 'out_file', cat_reg, 'mot') workflow.connect(quadr_motion_deriv, 'out_file', cat_reg, 'motd') workflow.connect(quadr_motion, 'out_quadr_file', cat_reg, 'motq') workflow.connect(quadr_motion_deriv, 'out_quadr_file', cat_reg, 'motdq') workflow.connect(quadr_CSF, 'out_file', cat_reg, 'CSF') workflow.connect(quadr_CSF_deriv, 'out_file', cat_reg, 'CSFd') workflow.connect(quadr_CSF, 'out_quadr_file', cat_reg, 'CSFq') workflow.connect(quadr_CSF_deriv, 'out_quadr_file', cat_reg, 'CSFdq') workflow.connect(quadr_WM, 'out_file', cat_reg, 'WM') workflow.connect(quadr_WM_deriv, 'out_file', cat_reg, 'WMd') workflow.connect(quadr_WM, 'out_quadr_file', cat_reg, 'WMq') workflow.connect(quadr_WM_deriv, 'out_quadr_file', cat_reg, 'WMdq') if global_reg: workflow.connect(quadr_glob, 'out_file', cat_reg, 'glob') workflow.connect(quadr_glob_deriv, 'out_file', cat_reg, 'globd') workflow.connect(quadr_glob, 'out_quadr_file', cat_reg, 'globq') workflow.connect(quadr_glob_deriv, 'out_quadr_file', cat_reg, 'globdq') else: cat_reg.inputs.glob = None cat_reg.inputs.globd = None cat_reg.inputs.globq = None cat_reg.inputs.globdq = None # create regression matrix deconvolve_name = 'deconvolve' if global_reg: deconvolve_name = deconvolve_name + '_global' deconvolve = pe.Node(afni.Deconvolve(), name=deconvolve_name) deconvolve.inputs.polort = 2 # contstant, linear and quadratic background signals removed deconvolve.inputs.fout = True deconvolve.inputs.tout = True deconvolve.inputs.x1D_stop = True deconvolve.inputs.force_TR = mytr workflow.connect(cat_reg, 'reg_file_args', deconvolve, 'args') workflow.connect(get_bandpass, 'out_tuple', deconvolve, 'ortvec') workflow.connect([(skullstrip, deconvolve, [(('out_file', str2list), 'in_files')])]) # regress out motion and other unwanted signals tproject_name = 'tproject' if global_reg: tproject_name = tproject_name + '_global' tproject = pe.Node(afni.TProject(outputtype="NIFTI_GZ"), name=tproject_name) tproject.inputs.TR = mytr tproject.inputs.polort = 0 # use matrix created with 3dDeconvolve, higher order polynomials not needed tproject.inputs.cenmode = 'NTRP' # interpolate removed time points workflow.connect(get_censor, 'out_file', tproject, 'censor') workflow.connect(skullstrip, 'out_file', tproject, 'in_file') workflow.connect(automask, 'out_file', tproject, 'mask') workflow.connect(deconvolve, 'x1D', tproject, 'ort') # Transform all images warpall_name = 'warpall' if global_reg: warpall_name = warpall_name + '_global' warpall = pe.Node(interface=fsl.ApplyWarp(), name=warpall_name) warpall.inputs.ref_file = MNI_brain warpall.inputs.field_file = anat2MNI_fieldwarp workflow.connect(mean2anat, 'out_matrix_file', warpall, 'premat') workflow.connect(tproject, 'out_file', warpall, 'in_file') workflow.connect(warpall, 'out_file', outputnode, 'result_func') # Run workflow workflow.write_graph() workflow.run() print "FUNCTIONAL PREPROCESSING DONE! Results in ", results_path + subj + '/' + s except: print "Error with patient: ", subj traceback.print_exc()
def anat2mni_nonlinear(): config = '/scr/sambesi1/workspace/Projects/GluREST/registration/T1_2_MNI152_2mm.cnf' mni_brain_2mm = '/usr/share/fsl/5.0/data/standard/MNI152_T1_2mm_brain.nii.gz' mni_skull_2mm = '/usr/share/fsl/5.0/data/standard/MNI152_T1_2mm.nii.gz' #mni_1mm = '/usr/share/fsl/5.0/data/standard/MNI152_T1_1mm_brain.nii.gz' #define workflow flow = Workflow('anat2mni') inputnode = Node(util.IdentityInterface(fields=['anat_image', 'anat_wm', 'anat_gm', 'anat_cm', 'anat_first']), name = 'inputnode') outputnode = Node(util.IdentityInterface(fields=['anat2mni', 'nonlinear_warp', 'mni_mask_gm', 'mni_mask_wm', 'mni_mask_cm' , 'mni_mask_first', 'mni2anat_warp']), name = 'outputnode') flirt = Node(interface= fsl.FLIRT(), name = 'anat2mni_linear_flirt') flirt.inputs.cost = 'mutualinfo' flirt.inputs.dof = 12 flirt.inputs.output_type = "NIFTI_GZ" flirt.inputs.reference = mni_brain_2mm # without skull here.. see example on fsl website. fnirt = Node(interface=fsl.FNIRT(), name = 'anat2mni_nonlinear_fnirt') fnirt.inputs.config_file = config fnirt.inputs.fieldcoeff_file = True fnirt.inputs.jacobian_file = True fnirt.inputs.ref_file = mni_brain_2mm # no skull invwarp = Node(interface=fsl.InvWarp(), name = 'mni2anat_warp') warp_gm = Node(interface=fsl.ApplyWarp(), name='warp_gm') warp_gm.inputs.ref_file =mni_brain_2mm warp_wm = Node(interface=fsl.ApplyWarp(), name='warp_wm') warp_wm.inputs.ref_file =mni_brain_2mm warp_cm = Node(interface=fsl.ApplyWarp(), name='warp_csf') warp_cm.inputs.ref_file =mni_brain_2mm warp_first = Node(interface=fsl.ApplyWarp(), name='warp_first') warp_first.inputs.ref_file =mni_brain_2mm thresh_gm = Node(fsl.Threshold(), name= 'mni_mask_gm') thresh_gm.inputs.thresh = 0.5 thresh_gm.inputs.args = '-bin' thresh_wm = Node(fsl.Threshold(), name= 'mni_mask_wm') thresh_wm.inputs.thresh = 0.6 thresh_wm.inputs.args = '-bin' thresh_csf = Node(fsl.Threshold(), name= 'mni_mask_csf') thresh_csf.inputs.thresh = 0.6 thresh_csf.inputs.args = '-bin' thresh_first = Node(fsl.Threshold(), name= 'mni_mask_first') thresh_first.inputs.thresh = 0.5 thresh_first.inputs.args = '-bin' flow.connect(inputnode, 'anat_image' , flirt, 'in_file' ) flow.connect(inputnode, 'anat_image' , fnirt, 'in_file' ) flow.connect(flirt, 'out_matrix_file' , fnirt, 'affine_file' ) flow.connect(inputnode, 'anat_gm' , warp_gm, 'in_file' ) flow.connect(inputnode, 'anat_wm' , warp_wm, 'in_file' ) flow.connect(inputnode, 'anat_cm' , warp_cm, 'in_file' ) flow.connect(inputnode, 'anat_first' , warp_first, 'in_file' ) flow.connect(fnirt, 'fieldcoeff_file' , invwarp, 'warp' ) flow.connect(inputnode, 'anat_image' , invwarp, 'reference' ) flow.connect(fnirt, 'fieldcoeff_file' , warp_gm, 'field_file' ) flow.connect(fnirt, 'fieldcoeff_file' , warp_wm, 'field_file' ) flow.connect(fnirt, 'fieldcoeff_file' , warp_cm, 'field_file' ) flow.connect(fnirt, 'fieldcoeff_file' , warp_first, 'field_file' ) flow.connect(warp_gm, 'out_file' , thresh_gm, 'in_file' ) flow.connect(warp_wm, 'out_file' , thresh_wm, 'in_file' ) flow.connect(warp_cm, 'out_file' , thresh_csf, 'in_file' ) flow.connect(warp_first,'out_file' , thresh_first,'in_file' ) flow.connect(fnirt, 'warped_file' , outputnode, 'anat2mni' ) flow.connect(invwarp, 'inverse_warp' , outputnode, 'mni2anat_warp' ) flow.connect(thresh_gm, 'out_file' , outputnode, 'mni_mask_gm' ) flow.connect(thresh_wm, 'out_file' , outputnode, 'mni_mask_wm' ) flow.connect(thresh_csf,'out_file' , outputnode, 'mni_mask_cm' ) flow.connect(thresh_first,'out_file' , outputnode, 'mni_mask_first' ) flow.connect(fnirt, 'fieldcoeff_file' , outputnode, 'nonlinear_warp' ) return flow
def prepare_template_wf(name="prepare_template"): wf = Workflow(name=name) inputnode = pe.Node(niu.IdentityInterface( fields=['tpl_t1w', 'tpl_t1w_brainmask', 'CSF_pve']), name='inputnode') tpl_t1w_brain = pe.Node(fsl.ApplyMask(), name='tpl_t1w_brain') wf.connect(inputnode, "tpl_t1w", tpl_t1w_brain, "in_file") wf.connect(inputnode, "tpl_t1w_brainmask", tpl_t1w_brain, "mask_file") norm_wf = get_norm_wf() wf.connect(inputnode, 'tpl_t1w', norm_wf, "inputnode.t1w") wf.connect(tpl_t1w_brain, 'out_file', norm_wf, "inputnode.t1w_brain") MNI_2_t1w_warp = pe.Node(fsl.InvWarp(), name='MNI_2_t1w_warp') wf.connect(inputnode, 'tpl_t1w', MNI_2_t1w_warp, 'reference') wf.connect(norm_wf, 'outputnode.t1w_2_MNI_warp', MNI_2_t1w_warp, 'warp') bianca_mask = pe.Node(MakeBiancaMask(), name='bianca_mask') bianca_mask.inputs.keep_intermediate_files = 0 wf.connect(inputnode, 'tpl_t1w', bianca_mask, 'structural_image') wf.connect(inputnode, 'CSF_pve', bianca_mask, 'CSF_pve') wf.connect(MNI_2_t1w_warp, 'inverse_warp', bianca_mask, 'warp_file_MNI2structural') wf.connect(tpl_t1w_brain, 'out_file', bianca_mask, 'structural_image_brainextracted') wf.connect(inputnode, 'tpl_t1w_brainmask', bianca_mask, 'brainmask') # distancemap # dilate for distancemap to avoid rim effects when resampling distancemap brainmask_dil = pe.Node(fsl.DilateImage(operation="max"), name="brainmask_dil") wf.connect(inputnode, 'tpl_t1w_brainmask', brainmask_dil, "in_file") distancemap = pe.Node(fsl.DistanceMap(), name="distancemap") wf.connect(bianca_mask, 'vent_file', distancemap, "in_file") wf.connect(brainmask_dil, 'out_file', distancemap, "mask_file") perivent_mask_init = pe.Node(fsl.maths.MathsCommand(), name="perivent_mask_init") perivent_mask_init.inputs.args = "-uthr 10 -bin" wf.connect(distancemap, "distance_map", perivent_mask_init, "in_file") perivent_mask = pe.Node(fsl.ApplyMask(), name="perivent_mask") wf.connect(perivent_mask_init, "out_file", perivent_mask, "in_file") wf.connect(inputnode, "tpl_t1w_brainmask", perivent_mask, "mask_file") deepWM_mask_init = pe.Node(fsl.maths.MathsCommand(), name="deepWM_mask_init") deepWM_mask_init.inputs.args = "-thr 10 -bin" wf.connect(distancemap, "distance_map", deepWM_mask_init, "in_file") deepWM_mask = pe.Node(fsl.ApplyMask(), name="deepWM_mask") wf.connect(deepWM_mask_init, "out_file", deepWM_mask, "in_file") wf.connect(inputnode, "tpl_t1w_brainmask", deepWM_mask, "mask_file") outputnode = pe.Node(niu.IdentityInterface(fields=[ "t1w_2_MNI_mat", "t1w_MNIspace", "t1w_2_MNI_warp", "bianca_wm_mask_file", "vent_file", "distance_map", "perivent_mask", "deepWM_mask" ]), name='outputnode') wf.connect(norm_wf, 'outputnode.t1w_2_MNI_mat', outputnode, "t1w_2_MNI_mat") wf.connect(norm_wf, 'outputnode.t1w_MNIspace', outputnode, "t1w_MNIspace") wf.connect(norm_wf, 'outputnode.t1w_2_MNI_warp', outputnode, "t1w_2_MNI_warp") wf.connect(bianca_mask, 'mask_file', outputnode, "bianca_wm_mask_file") wf.connect(bianca_mask, 'vent_file', outputnode, "vent_file") wf.connect(distancemap, "distance_map", outputnode, "distance_map") wf.connect(perivent_mask, "out_file", outputnode, "perivent_mask") wf.connect(deepWM_mask, "out_file", outputnode, "deepWM_mask") return wf