Ejemplo n.º 1
0
def create_workflow():
    parser = argparse.ArgumentParser()
    parser.add_argument('-d', dest='data', help="Path to bids dataset")
    args = parser.parse_args()
    if not os.path.exists(args.data):
        raise IOError('Input data not found')
    if not os.path.exists(OUTDIR):
        os.makedirs(OUTDIR)

    # grab data from bids structure
    layout = BIDSLayout(args.data)
    subj = layout.get_subjects()[0]
    func = [
        f.filename
        for f in layout.get(subject=subj, type='bold', extensions=['nii.gz'])
    ][0]

    outfile = os.path.join(OUTDIR, 'test_{}_{}_motcor'.format(subj, ENV['os']))

    # run interface
    # Just SpatialRealign for the moment - TODO add time element with tr/slices
    realign = SpaceTimeRealigner()
    realign.inputs.in_file = [func]
    # no out_file input, will need to be renamed after
    res = realign.run()

    # write out json to keep track of information
    ENV.update({'inputs': res.inputs})
    ENV.update({'nipype_version': nipype.__version__})
    #ENV.update({'outputs': res.outputs})
    # write out to json
    env_to_json(ENV, outname=outfile + '.json')
Ejemplo n.º 2
0
def nipy_motion_correction(in_file=traits.Undefined):
    """
    Simultaneous motion and slice timing correction algorithm
    If slice_times is not specified, this algorithm performs spatial motion correction
    This interface wraps nipy’s SpaceTimeRealign algorithm [Roche2011] or
    simply the SpatialRealign algorithm when timing info is not provided.

    http://www.mit.edu/~satra/nipype-nightly/interfaces/generated/nipype.interfaces.nipy.preprocess.html#spacetimerealigner

    Returns
    -------
    realign: nipype Interface

    Notes
    -----
    Roche A. A four-dimensional registration algorithm with application to joint correction of motion and slice
    timing in fMRI. IEEE Trans Med Imaging. 2011 Aug;30(8):1546-54. http://dx.doi.org/10.1109/TMI.2011.2131152
    """
    realigner = SpaceTimeRealigner()
    realigner.inputs.in_file = in_file
    return realigner
Ejemplo n.º 3
0
    workflow1.base_dir = '.'
    inputnode = pe.Node(
        interface=util.IdentityInterface(fields=['source_file']),
        name='inputspec')
    outputnode = pe.Node(
        interface=util.IdentityInterface(fields=['mean_image', 'move_par']),
        name='outputspec')

    if data == 'func1':
        inputnode.inputs.source_file = func1
    else:
        inputnode.inputs.source_file = func2

    # 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
    realign4d.inputs.tr = 2.00

    workflow1.connect(inputnode, 'source_file', realign4d, 'in_file')
    workflow1.connect(realign4d, 'par_file', outputnode, 'move_par')

    # Reorient
    #deoblique = pe.Node(interface=afni.Warp(deoblique=True, outputtype='NIFTI_GZ'), name='deoblique')
    #workflow1.connect(realign4d, 'out_file', deoblique, 'in_file')
    reorient = pe.Node(interface=fsl.Reorient2Std(output_type='NIFTI_GZ'),
                       name='reorient')
    workflow1.connect(realign4d, 'out_file', reorient, 'in_file')
    workflow1.connect(reorient, 'out_file', outputnode, 'out_file')
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()