Example #1
0
def create_resting(subject, working_dir, data_dir, freesurfer_dir, out_dir,
                   vol_to_remove, TR, epi_resolution, highpass, lowpass,
                   echo_space, pe_dir, standard_brain,
                   standard_brain_resampled, standard_brain_mask,
                   standard_brain_mask_resampled, fwhm_smoothing):
    # set fsl output type to nii.gz
    fsl.FSLCommand.set_default_output_type('NIFTI_GZ')
    # main workflow
    func_preproc = Workflow(name='resting_postscrub')
    func_preproc.base_dir = working_dir
    func_preproc.config['execution'][
        'crashdump_dir'] = func_preproc.base_dir + "/crash_files"
    # select files
    templates = {
        'epi_scrubbed_interp':
        'preprocessing/preprocessed/{subject}/scrubbed_interpolated/rest2anat_denoised_scrubbed_intep.nii.gz',
        'anat_head':
        'preprocessing/preprocessed/{subject}/structural/T1.nii.gz',
        'anat_brain':
        'preprocessing/preprocessed/{subject}/structural/brain.nii.gz',
        'brain_mask':
        'preprocessing/preprocessed/{subject}/structural/T1_brain_mask.nii.gz',
        'ants_affine':
        'preprocessing/preprocessed/{subject}/structural/transforms2mni/transform0GenericAffine.mat',
        'ants_warp':
        'preprocessing/preprocessed/{subject}/structural/transforms2mni/transform1Warp.nii.gz'
    }

    selectfiles = Node(nio.SelectFiles(templates, base_directory=data_dir),
                       name="selectfiles")
    selectfiles.inputs.subject = subject

    # node to remove first volumes
    #    remove_vol = Node(util.Function(input_names=['in_file', 't_min'],
    #                                    output_names=["out_file"],
    #                                    function=strip_rois_func),
    #                      name='remove_vol')
    #    remove_vol.inputs.t_min = vol_to_remove
    #    # workflow for motion correction
    #    moco = create_moco_pipeline()
    #
    #    # workflow for fieldmap correction and coregistration
    #    topup_coreg = create_topup_coreg_pipeline()
    #    topup_coreg.inputs.inputnode.fs_subjects_dir = freesurfer_dir
    #    topup_coreg.inputs.inputnode.fs_subject_id = subject
    #    topup_coreg.inputs.inputnode.echo_space = echo_space
    #    topup_coreg.inputs.inputnode.pe_dir = pe_dir
    #
    #    # workflow for applying transformations to timeseries
    #    transform_ts = create_transform_pipeline()
    #    transform_ts.inputs.inputnode.resolution = epi_resolution
    #
    #
    #    # workflow to denoise timeseries
    denoise = create_denoise_pipeline()
    denoise.inputs.inputnode.highpass_sigma = 1. / (2 * TR * highpass)
    denoise.inputs.inputnode.lowpass_sigma = 1. / (2 * TR * lowpass)
    # https://www.jiscmail.ac.uk/cgi-bin/webadmin?A2=ind1205&L=FSL&P=R57592&1=FSL&9=A&I=-3&J=on&d=No+Match%3BMatch%3BMatches&z=4
    denoise.inputs.inputnode.tr = TR

    # workflow to transform timeseries to MNI
    ants_registration = create_ants_registration_pipeline()
    ants_registration.inputs.inputnode.ref = standard_brain
    ants_registration.inputs.inputnode.tr_sec = TR

    # FL added fullspectrum
    # workflow to transform fullspectrum timeseries to MNI
    #ants_registration_full = create_ants_registration_pipeline('ants_registration_full')
    #ants_registration_full.inputs.inputnode.ref = standard_brain
    #ants_registration_full.inputs.inputnode.tr_sec = TR

    # workflow to smooth
    smoothing = create_smoothing_pipeline()
    smoothing.inputs.inputnode.fwhm = fwhm_smoothing

    # visualize registration results
    visualize = create_visualize_pipeline()
    visualize.inputs.inputnode.mni_template = standard_brain

    # sink to store files
    sink = Node(nio.DataSink(
        parameterization=False,
        base_directory=out_dir,
        substitutions=[('rest_denoised_bandpassed_norm_trans.nii.gz',
                        'rest_scrubbed_int_mni_unsmoothed.nii.gz'),
                       ('rest_denoised_bandpassed_norm_trans_smooth.nii.gz',
                        'rest_scrubbed_int_mni_smoothed.nii.gz'),
                       ('rest_denoised_bandpassed_norm.nii.gz',
                        'rest_denoised_scrubbed_int_bp.nii.gz')]),
                name='sink')

    # connections
    func_preproc.connect([
        # remove the first volumes
        #        (selectfiles, remove_vol, [('func', 'in_file')]),
        #
        #        # align volumes and motion correction
        #        (remove_vol, moco, [('out_file', 'inputnode.epi')]),
        #
        #        # prepare field map
        #        (selectfiles, topup_coreg, [('ap', 'inputnode.ap'),
        #                                   ('pa', 'inputnode.pa'),
        #                                   ('anat_head', 'inputnode.anat_head'),
        #                                   ('anat_brain', 'inputnode.anat_brain')
        #                                   ]),
        #        (moco, topup_coreg, [('outputnode.epi_mean', 'inputnode.epi_mean')]),
        #
        #        # transform timeseries
        #        (remove_vol, transform_ts, [('out_file', 'inputnode.orig_ts')]),
        #        (selectfiles, transform_ts, [('anat_head', 'inputnode.anat_head')]),
        #        (selectfiles, transform_ts, [('brain_mask', 'inputnode.brain_mask')]),
        #        (moco, transform_ts, [('outputnode.mat_moco', 'inputnode.mat_moco')]),
        #        (topup_coreg, transform_ts, [('outputnode.fmap_fullwarp', 'inputnode.fullwarp')]),
        #
        #        # correct slicetiming
        #        # FIXME slice timing?
        #        # (transform_ts, slicetiming, [('outputnode.trans_ts_masked', 'inputnode.ts')]),
        #        # (slicetiming, denoise, [('outputnode.ts_slicetcorrected', 'inputnode.epi_coreg')]),
        #        (transform_ts, denoise, [('outputnode.trans_ts_masked', 'inputnode.epi_coreg')]),

        # denoise data
        (selectfiles, denoise, [('brain_mask', 'inputnode.brain_mask'),
                                ('anat_brain', 'inputnode.anat_brain'),
                                ('epi_scrubbed_interp',
                                 'inputnode.epi_denoised')]),
        (denoise, ants_registration, [('outputnode.normalized_file',
                                       'inputnode.denoised_ts')]),

        # registration to MNI space
        (selectfiles, ants_registration, [('ants_affine',
                                           'inputnode.ants_affine')]),
        (selectfiles, ants_registration, [('ants_warp', 'inputnode.ants_warp')
                                          ]),

        # FL added fullspectrum
        #(selectfiles, ants_registration_full, [('epi_scrubbed_interp', 'inputnode.denoised_ts')]),
        #(selectfiles, ants_registration_full, [('ants_affine', 'inputnode.ants_affine')]),
        #(selectfiles, ants_registration_full, [('ants_warp', 'inputnode.ants_warp')]),
        (ants_registration, smoothing, [('outputnode.ants_reg_ts',
                                         'inputnode.ts_transformed')]),
        (smoothing, visualize, [('outputnode.ts_smoothed',
                                 'inputnode.ts_transformed')]),

        ##all the output
        #        (moco, sink, [  # ('outputnode.epi_moco', 'realign.@realigned_ts'),
        #                        ('outputnode.par_moco', 'realign.@par'),
        #                        ('outputnode.rms_moco', 'realign.@rms'),
        #                        ('outputnode.mat_moco', 'realign.MAT.@mat'),
        #                        ('outputnode.epi_mean', 'realign.@mean'),
        #                        ('outputnode.rotplot', 'realign.plots.@rotplot'),
        #                        ('outputnode.transplot', 'realign.plots.@transplot'),
        #                        ('outputnode.dispplots', 'realign.plots.@dispplots'),
        #                        ('outputnode.tsnr_file', 'realign.@tsnr')]),
        #        (topup_coreg, sink, [('outputnode.fmap', 'coregister.transforms2anat.@fmap'),
        #                            # ('outputnode.unwarpfield_epi2fmap', 'coregister.@unwarpfield_epi2fmap'),
        #                            ('outputnode.unwarped_mean_epi2fmap', 'coregister.@unwarped_mean_epi2fmap'),
        #                            ('outputnode.epi2fmap', 'coregister.@epi2fmap'),
        #                            # ('outputnode.shiftmap', 'coregister.@shiftmap'),
        #                            ('outputnode.fmap_fullwarp', 'coregister.transforms2anat.@fmap_fullwarp'),
        #                            ('outputnode.epi2anat', 'coregister.@epi2anat'),
        #                            ('outputnode.epi2anat_mat', 'coregister.transforms2anat.@epi2anat_mat'),
        #                            ('outputnode.epi2anat_dat', 'coregister.transforms2anat.@epi2anat_dat'),
        #                            ('outputnode.epi2anat_mincost', 'coregister.@epi2anat_mincost')
        #                            ]),
        #
        #        (transform_ts, sink, [('outputnode.trans_ts_masked', 'coregister.@full_transform_ts'),
        #                              ('outputnode.trans_ts_mean', 'coregister.@full_transform_mean'),
        #                              ('outputnode.resamp_brain', 'coregister.@resamp_brain')]),
        (
            denoise,
            sink,
            [
                ('outputnode.normalized_file', 'denoise.@normalized'),
                # FL added fullspectrum
            ]),
        (ants_registration, sink, [('outputnode.ants_reg_ts',
                                    'ants.@antsnormalized')]),
        #(ants_registration_full, sink, [('outputnode.ants_reg_ts', 'ants.@antsnormalized_fullspectrum')]),
        (smoothing, sink, [('outputnode.ts_smoothed', '@smoothed.FWHM6')]),
    ])

    func_preproc.write_graph(dotfilename='func_preproc.dot',
                             graph2use='colored',
                             format='pdf',
                             simple_form=True)
    func_preproc.run()
Example #2
0
def create_lemon_resting(subject, working_dir, data_dir, freesurfer_dir,
                         out_dir, vol_to_remove, TR, epi_resolution, highpass,
                         lowpass, echo_space, te_diff, pe_dir, standard_brain,
                         standard_brain_resampled, standard_brain_mask,
                         standard_brain_mask_resampled, fwhm_smoothing):
    # set fsl output type to nii.gz
    fsl.FSLCommand.set_default_output_type('NIFTI_GZ')
    # main workflow
    func_preproc = Workflow(name='lemon_resting')
    func_preproc.base_dir = working_dir
    func_preproc.config['execution'][
        'crashdump_dir'] = func_preproc.base_dir + "/crash_files"
    # select files
    templates = {
        'func': 'func/EPI_t2.nii',
        'fmap_phase': 'unwarp/B0_ph.nii',
        'fmap_mag': 'unwarp/B0_mag.nii',
        'anat_head':
        'preprocessed/mod/anat/T1.nii.gz',  #either with mod or without
        'anat_brain':
        'preprocessed/mod/anat/brain.nii.gz',  #new version with brain_extraction from freesurfer  #T1_brain_brain.nii.gz',
        'brain_mask':
        'preprocessed/mod/anat/T1_brain_mask.nii.gz',  #T1_brain_brain_mask.nii.gz',
        'ants_affine':
        'preprocessed/mod/anat/transforms2mni/transform0GenericAffine.mat',
        'ants_warp':
        'preprocessed/mod/anat/transforms2mni/transform1Warp.nii.gz'
    }

    selectfiles = Node(nio.SelectFiles(templates, base_directory=data_dir),
                       name="selectfiles")

    # node to remove first volumes
    remove_vol = Node(util.Function(input_names=['in_file', 't_min'],
                                    output_names=["out_file"],
                                    function=strip_rois_func),
                      name='remove_vol')
    remove_vol.inputs.t_min = vol_to_remove
    # workflow for motion correction
    moco = create_moco_pipeline()
    # workflow for fieldmap correction and coregistration
    fmap_coreg = create_fmap_coreg_pipeline()
    fmap_coreg.inputs.inputnode.fs_subjects_dir = freesurfer_dir
    fmap_coreg.inputs.inputnode.fs_subject_id = subject
    fmap_coreg.inputs.inputnode.echo_space = echo_space
    fmap_coreg.inputs.inputnode.te_diff = te_diff
    fmap_coreg.inputs.inputnode.pe_dir = pe_dir
    # workflow for applying transformations to timeseries
    transform_ts = create_transform_pipeline()
    transform_ts.inputs.inputnode.resolution = epi_resolution

    #workflow to convert signal into percent signal change
    normalize = create_normalize_pipeline()
    normalize.inputs.inputnode.tr = TR

    #workflow to transform timeseries to MNI
    ants_registration = create_ants_registration_pipeline()
    ants_registration.inputs.inputnode.ref = standard_brain_resampled

    #workflow to smooth
    smoothing = create_smoothing_pipeline()
    smoothing.inputs.inputnode.fwhm = fwhm_smoothing

    #workflow to correct slice timing
    slicetiming = create_slice_timing_pipeline()

    #visualize registration results
    visualize = create_visualize_pipeline()
    visualize.inputs.inputnode.mni_template = standard_brain_resampled

    #sink to store files
    sink = Node(nio.DataSink(
        parameterization=False,
        base_directory=out_dir,
        substitutions=[
            ('fmap_phase_fslprepared', 'fieldmap'),
            ('fieldmap_fslprepared_fieldmap_unmasked_vsm', 'shiftmap'),
            ('plot.rest_coregistered', 'outlier_plot'),
            ('filter_motion_comp_norm_compcor_art_dmotion',
             'nuissance_matrix'),
            ('rest_realigned.nii.gz_abs.rms', 'rest_realigned_abs.rms'),
            ('rest_realigned.nii.gz.par', 'rest_realigned.par'),
            ('rest_realigned.nii.gz_rel.rms', 'rest_realigned_rel.rms'),
            ('rest_realigned.nii.gz_abs_disp', 'abs_displacement_plot'),
            ('rest_realigned.nii.gz_rel_disp', 'rel_displacment_plot'),
            ('art.rest_coregistered_outliers', 'outliers'),
            ('global_intensity.rest_coregistered', 'global_intensity'),
            ('norm.rest_coregistered', 'composite_norm'),
            ('stats.rest_coregistered', 'stats'),
            ('rest_denoised_bandpassed_norm.nii.gz',
             'rest_preprocessed.nii.gz'),
            ('rest_denoised_bandpassed_norm_trans.nii.gz', 'rest_mni.nii.gz'),
            ('rest2anat_masked_st_norm_trans_smooth.nii',
             'rest_mni_smoothed.nii')
        ]),
                name='sink')

    # connections
    func_preproc.connect([
        #remove the first volumes
        (selectfiles, remove_vol, [('func', 'in_file')]),

        #align volumes and motion correction
        (remove_vol, moco, [('out_file', 'inputnode.epi')]),

        #prepare field map
        (selectfiles, fmap_coreg, [('fmap_phase', 'inputnode.phase'),
                                   ('fmap_mag', 'inputnode.mag'),
                                   ('anat_head', 'inputnode.anat_head'),
                                   ('anat_brain', 'inputnode.anat_brain')]),
        (moco, fmap_coreg, [('outputnode.epi_mean', 'inputnode.epi_mean')]),
        (remove_vol, transform_ts, [('out_file', 'inputnode.orig_ts')]),
        (selectfiles, transform_ts, [('anat_head', 'inputnode.anat_head')]),
        (selectfiles, transform_ts, [('brain_mask', 'inputnode.brain_mask')]),
        (moco, transform_ts, [('outputnode.mat_moco', 'inputnode.mat_moco')]),
        (fmap_coreg, transform_ts, [('outputnode.fmap_fullwarp',
                                     'inputnode.fullwarp')]),

        ##add slice time correction after applying motion realignement + unwarping
        (transform_ts, slicetiming, [('outputnode.trans_ts_masked',
                                      'inputnode.ts')]),
        (slicetiming, normalize, [('outputnode.ts_slicetcorrected',
                                   'inputnode.epi_coreg')]),
        (normalize, ants_registration, [('outputnode.normalized_file',
                                         'inputnode.denoised_ts')]),

        #registration to MNI space
        (selectfiles, ants_registration, [('ants_affine',
                                           'inputnode.ants_affine')]),
        (selectfiles, ants_registration, [('ants_warp', 'inputnode.ants_warp')
                                          ]),
        (ants_registration, smoothing, [('outputnode.ants_reg_ts',
                                         'inputnode.ts_transformed')]),
        (smoothing, visualize, [('outputnode.ts_smoothed',
                                 'inputnode.ts_transformed')]),

        ##all the output
        (
            moco,
            sink,
            [  #('outputnode.epi_moco', 'realign.@realigned_ts'),
                ('outputnode.par_moco', 'realign.@par'),
                ('outputnode.rms_moco', 'realign.@rms'),
                ('outputnode.mat_moco', 'realign.MAT.@mat'),
                ('outputnode.epi_mean', 'realign.@mean'),
                ('outputnode.rotplot', 'realign.plots.@rotplot'),
                ('outputnode.transplot', 'realign.plots.@transplot'),
                ('outputnode.dispplots', 'realign.plots.@dispplots'),
                ('outputnode.tsnr_file', 'realign.@tsnr')
            ]),
        (
            fmap_coreg,
            sink,
            [
                ('outputnode.fmap', 'coregister.transforms2anat.@fmap'),
                #('outputnode.unwarpfield_epi2fmap', 'coregister.@unwarpfield_epi2fmap'),
                ('outputnode.unwarped_mean_epi2fmap',
                 'coregister.@unwarped_mean_epi2fmap'),
                ('outputnode.epi2fmap', 'coregister.@epi2fmap'),
                #('outputnode.shiftmap', 'coregister.@shiftmap'),
                ('outputnode.fmap_fullwarp',
                 'coregister.transforms2anat.@fmap_fullwarp'),
                ('outputnode.epi2anat', 'coregister.@epi2anat'),
                ('outputnode.epi2anat_mat',
                 'coregister.transforms2anat.@epi2anat_mat'),
                ('outputnode.epi2anat_dat',
                 'coregister.transforms2anat.@epi2anat_dat'),
                ('outputnode.epi2anat_mincost', 'coregister.@epi2anat_mincost')
            ]),
        (
            transform_ts,
            sink,
            [  #('outputnode.trans_ts', 'coregister.@full_transform_ts'),
                ('outputnode.trans_ts_mean',
                 'coregister.@full_transform_mean'),
                ('outputnode.resamp_brain', 'coregister.@resamp_brain')
            ]),
        (ants_registration, sink, [('outputnode.ants_reg_ts',
                                    'ants.@antsnormalized')]),
        (smoothing, sink, [('outputnode.ts_smoothed', '@smoothed.FWHM6')]),
    ])

    #func_preproc.write_graph(dotfilename='func_preproc.dot', graph2use='colored', format='pdf', simple_form=True)
    func_preproc.run()
Example #3
0
def create_hc_connec(subject, working_dir, data_dir, freesurfer_dir, out_dir,
                     epi_resolution, standard_brain, standard_brain_resampled,
                     standard_brain_mask, standard_brain_mask_resampled,
                     fwhm_smoothing, side, TR, highpass, lowpass):
    # set fsl output type to nii.gz
    fsl.FSLCommand.set_default_output_type('NIFTI_GZ')
    # main workflow
    hc_connec = Workflow(name='hc_connec_thr099_scrubbed')
    hc_connec.base_dir = working_dir
    hc_connec.config['execution'][
        'crashdump_dir'] = hc_connec.base_dir + "/crash_files"

    # select files
    templates = {
        #'rest_head': 'resting_state/denoise/rest_preprocessed_nativespace.nii.gz', #denoised and bandpass-filtered native space (2x2x2mm) image
        'rest2anat_scrubbed':
        'preprocessing/preprocessed/{subject}/scrubbed_interpolated/rest2anat_denoised_scrubbed_intep.nii.gz',  #denoised, scrubbed, interp, bp-filtered native space
        'ants_affine':
        'preprocessing/preprocessed/{subject}/structural/transforms2mni/transform0GenericAffine.mat',
        'ants_warp':
        'preprocessing/preprocessed/{subject}/structural/transforms2mni/transform1Warp.nii.gz',
        'scrubvols': 'quality_reports/poldrack_reports/{subject}/scrubvols.txt'
    }

    selectfiles = Node(nio.SelectFiles(templates, base_directory=data_dir),
                       name="selectfiles")
    selectfiles.inputs.subject = subject

    denoise = create_denoise_pipeline()
    denoise.inputs.inputnode.highpass_sigma = 1. / (2 * TR * highpass)
    denoise.inputs.inputnode.lowpass_sigma = 1. / (2 * TR * lowpass)
    # https://www.jiscmail.ac.uk/cgi-bin/webadmin?A2=ind1205&L=FSL&P=R57592&1=FSL&9=A&I=-3&J=on&d=No+Match%3BMatch%3BMatches&z=4
    denoise.inputs.inputnode.tr = TR

    #drop scrubbed volumes
    scrub_volumes = Node(util.Function(
        input_names=['scrubvols', 'in_file', 'working_dir'],
        output_names=['filename_scrubbed_img'],
        function=scrub_timepoints),
                         name='scrub_volumes')
    scrub_volumes.inputs.working_dir = working_dir

    #get T1 brainmask
    get_T1_brainmask = create_get_T1_brainmask()
    get_T1_brainmask.inputs.inputnode.fs_subjects_dir = freesurfer_dir
    get_T1_brainmask.inputs.inputnode.fs_subject_id = subject

    #workflow to extract HC and transform into individual space
    transform_hc = create_transform_hc()
    transform_hc.inputs.inputnode.fs_subjects_dir = freesurfer_dir
    transform_hc.inputs.inputnode.fs_subject_id = subject
    transform_hc.inputs.inputnode.resolution = 2
    transform_hc.inputs.inputnode.working_dir = working_dir

    #workflow to extract timeseries and correlate
    corr_ts = create_corr_ts()

    #workflow to tranform correlations to MNI space
    ants_registration = create_ants_registration_pipeline()
    ants_registration.inputs.inputnode.ref = standard_brain  #_resampled: 2x2x2mm brain for RSV

    #
    smoothing = create_smoothing_pipeline()
    smoothing.inputs.inputnode.fwhm = fwhm_smoothing
    #sink to store files
    sink = Node(
        nio.DataSink(parameterization=True, base_directory=out_dir),
        #   substitutions=[('_binarize', 'binarize'), -> don't really seem to work and I don't know why.
        #                   #('_binarize', 'anterior_hc'),
        #                   ('_ants_reg1', 'posterior_hc'),
        #                   #('_ants_reg', 'anterior_hc'),
        #                   ('_smooth1', 'posterior_hc'),
        #                   ('_smooth0', 'anterior_hc'),
        #                   ('corr_Z_trans', 'corr_Z_MNI')],
        name='sink')

    sink.inputs.substitutions = [('_binarize0', 'posterior_hc'),
                                 ('_binarize1', 'anterior_hc'),
                                 ('_ants_reg0', 'posterior_hc'),
                                 ('_ants_reg1', 'anterior_hc'),
                                 ('_smooth0', 'posterior_hc'),
                                 ('_smooth1', 'anterior_hc'),
                                 ('_apply_FisherZ0', 'posterior_hc'),
                                 ('_apply_FisherZ1', 'anterior_hc')]

    # connections
    hc_connec.connect([
        #bandpass-filtering implemented after scrubbing and replacement!
        (selectfiles, scrub_volumes, [('scrubvols', 'scrubvols')]),
        (get_T1_brainmask, transform_hc, [('outputnode.T1',
                                           'inputnode.anat_head')]),
        (transform_hc, corr_ts, [('outputnode.hc_transformed_bin',
                                  'inputnode.hc_mask')]),
        (selectfiles, denoise, [('rest2anat_scrubbed',
                                 'inputnode.epi_denoised')]),
        (denoise, scrub_volumes, [('outputnode.normalized_file', 'in_file')]),
        (scrub_volumes, corr_ts, [('filename_scrubbed_img', 'inputnode.ts')]),
        (corr_ts, sink,
         [('outputnode.corrmap_z', 'hc_connectivity_thr099.scrubbed.' + side +
           '.corr.nativespace.@transformed')]),
        (corr_ts, ants_registration, [('outputnode.corrmap_z',
                                       'inputnode.corr_Z')]),
        (selectfiles, ants_registration, [('ants_affine',
                                           'inputnode.ants_affine')]),
        (selectfiles, ants_registration, [('ants_warp', 'inputnode.ants_warp')
                                          ]),
        (ants_registration, sink,
         [('outputnode.ants_reg_corr_Z',
           'hc_connectivity_thr099.scrubbed.' + side + '.corr.ants')]),
        (ants_registration, smoothing, [('outputnode.ants_reg_corr_Z',
                                         'inputnode.ts_transformed')]),
        (smoothing, sink,
         [('outputnode.ts_smoothed',
           'hc_connectivity_thr099.scrubbed.' + side + '.corr.smoothed')]),
    ])

    hc_connec.run(
    )  #it can't run in multiproc as in one moment one file is hardcoded and saved to the disk which is
def create_resting():

    # main workflow
    func_preproc = Workflow(name='resting')

    inputnode = Node(util.IdentityInterface(fields=[
        'subject_id', 'out_dir', 'freesurfer_dir', 'func', 'rs_mag', 'rs_ph',
        'anat_head', 'anat_brain', 'anat_brain_mask', 'wmseg', 'csfseg',
        'vol_to_remove', 'TR', 'highpass_freq', 'epi_resolution', 'echo_space',
        'te_diff', 'fwhm', 'pe_dir', 'composite_transform', 'standard_brain',
        'standard_downsampled'
    ]),
                     name='inputnode')

    #Use correct subject ID from long timepoint for bbregister
    def change_subject_id(subject):
        import re
        [subj, ses] = re.split("_", subject)

        new_subject_id = subject + '.long.' + subj
        return new_subject_id

    change_subject_id = Node(util.Function(input_names=["subject"],
                                           output_names=["new_subject_id"],
                                           function=change_subject_id),
                             name="change_subject_id")

    outputnode = Node(util.IdentityInterface(fields=[
        'brain', 'brainmask', 'anat2std_transforms', 'std2anat_transforms',
        'anat2std', 'anat_head', 'wmseg', 'csfseg', 'wmedge', 'subject_id'
    ]),
                      name='outputnode')

    ##PREPROCESSING FOR AROMA (Steps 1 - 7)
    def merge_if_list(in_file):
        if type(in_file) == list:
            import numpy as np
            import nibabel as nb
            import os
            from nipype.utils.filemanip import split_filename
            nii1 = nb.load(in_file[0])
            nii1d = nii1.get_data()
            nii2 = nb.load(in_file[1])
            nii2d = nii2.get_data()
            x = np.concatenate((nii1d, nii2d), axis=3)
            new_nii = nb.Nifti1Image(x, nii1.get_affine(), nii1.get_header())
            new_nii.set_data_dtype(np.float32)
            _, base, _ = split_filename(in_file[0])
            nb.save(new_nii, base + "_merged.nii.gz")
            return os.path.abspath(base + "_merged.nii.gz")
        else:
            return in_file

    #if rsfmri is a list -> merge files, otherwise return single list.
    merge_rs = Node(util.Function(input_names=['in_file'],
                                  output_names=["out_file"],
                                  function=merge_if_list),
                    name='merge_rs')

    # node to remove first volumes
    remove_vol = Node(util.Function(input_names=['in_file', 't_min'],
                                    output_names=["out_file"],
                                    function=strip_rois_func),
                      name='remove_vol')

    # workflow for motion correction
    moco = create_moco_pipeline()

    # workflow for fieldmap correction and coregistration
    fmap_coreg = create_fmap_coreg_pipeline()

    # workflow for applying transformations to timeseries
    transform_ts = create_transform_pipeline()

    #mean intensity normalization
    meanintensnorm = Node(fsl.ImageMaths(op_string='-ing 10000'),
                          name='meanintensnorm')

    smoothing = create_smoothing_pipeline()

    # connections
    func_preproc.connect([
        (inputnode, merge_rs, [('func', 'in_file')]),
        (merge_rs, remove_vol, [('out_file', 'in_file')]),
        (inputnode, remove_vol, [('vol_to_remove', 't_min')]),
        (inputnode, moco, [('anat_brain_mask', 'inputnode.brainmask')]),
        (remove_vol, moco, [('out_file', 'inputnode.epi')]),
        (inputnode, change_subject_id, [('subject_id', 'subject')]),
        (change_subject_id, fmap_coreg, [('new_subject_id',
                                          'inputnode.fs_subject_id')]),
        (inputnode, fmap_coreg, [('rs_mag', 'inputnode.mag'),
                                 ('rs_ph', 'inputnode.phase'),
                                 ('freesurfer_dir',
                                  'inputnode.fs_subjects_dir'),
                                 ('echo_space', 'inputnode.echo_space'),
                                 ('te_diff', 'inputnode.te_diff'),
                                 ('pe_dir', 'inputnode.pe_dir'),
                                 ('anat_head', 'inputnode.anat_head'),
                                 ('anat_brain', 'inputnode.anat_brain')]),
        (moco, fmap_coreg, [('outputnode.epi_mean', 'inputnode.epi_mean')]),
        (remove_vol, transform_ts, [('out_file', 'inputnode.orig_ts')]),
        (inputnode, transform_ts, [('anat_head', 'inputnode.anat_head')]),
        (inputnode, transform_ts, [('anat_brain_mask', 'inputnode.brain_mask')
                                   ]),
        (inputnode, transform_ts, [('epi_resolution', 'inputnode.resolution')
                                   ]),
        (moco, transform_ts, [('outputnode.mat_moco', 'inputnode.mat_moco')]),
        (fmap_coreg, transform_ts, [('outputnode.fmap_fullwarp',
                                     'inputnode.fullwarp')]),
        (transform_ts, meanintensnorm, [('outputnode.trans_ts', 'in_file')]),
        (meanintensnorm, smoothing, [('out_file', 'inputnode.ts_transformed')
                                     ]),
        (inputnode, smoothing, [('fwhm', 'inputnode.fwhm')])
    ])

    ##CALCULATE TRANSFORM from anatomical to standard space with FSL tools
    # Anat > Standard
    # register high-resolution to standard template with non-linear transform
    # flirt serves as preparation for fnirt)

    #reorient brain to standard (because Freesurfer space can cause problems)
    reorient2std = Node(fsl.Reorient2Std(), name="reorient2std")

    reorient2std_rs = Node(fsl.Reorient2Std(), name="reorient2std_rs")
    reorient2std_mask = Node(fsl.Reorient2Std(), name="reorient2std_mask")

    flirt_prep = Node(fsl.FLIRT(cost_func='mutualinfo', interp='trilinear'),
                      name='flirt_prep')
    flirt_prep.inputs.interp = 'trilinear'
    flirt_prep.inputs.dof = 12

    fnirt = Node(fsl.FNIRT(), name='fnirt')
    fnirt.inputs.field_file = True
    fnirt.inputs.fieldcoeff_file = True

    func_preproc.connect([
        (inputnode, reorient2std, [('anat_brain', 'in_file')]),
        (reorient2std, flirt_prep, [('out_file', 'in_file')]),
        #(inputnode, flirt_prep,  [('anat_brain', 'in_file')]),
        (inputnode, flirt_prep, [('standard_brain', 'reference')]),
        (flirt_prep, fnirt, [('out_matrix_file', 'affine_file')]),
        (reorient2std, fnirt, [('out_file', 'in_file')]),
        (inputnode, fnirt, [('standard_brain', 'ref_file')]),
    ])

    def getcwd(subject_id):
        import os
        tmp = os.getcwd()
        tmp = tmp[:-6]
        tmp = tmp + 'ica_aroma/out'  #%(subject_id)
        return tmp

    get_wd = Node(util.Function(input_names=['subject_id'],
                                output_names=["d"],
                                function=getcwd),
                  name='get_wd')

    ica_aroma = Node(ICA_AROMA(), name="ica_aroma")
    ica_aroma.inputs.denoise_type = 'both'
    #ica_aroma.inputs.out_dir = os.getcwd()

    func_preproc.connect([
        (moco, ica_aroma, [('outputnode.par_moco', 'motion_parameters')]),
        (smoothing, reorient2std_rs, [('outputnode.ts_smoothed', 'in_file')]),
        (reorient2std_rs, ica_aroma, [('out_file', 'in_file')]),
        (fnirt, ica_aroma, [('field_file', 'fnirt_warp_file')]),
        (transform_ts, reorient2std_mask, [('outputnode.comb_mask_resamp',
                                            'in_file')]),
        (reorient2std_mask, ica_aroma, [('out_file', 'mask')]),
        (inputnode, get_wd, [('subject_id', 'subject_id')]),
        (get_wd, ica_aroma, [('d', 'out_dir')])
    ])

    ##POSTPROCESSING
    postprocess = create_denoise_pipeline()

    func_preproc.connect([
        (reorient2std_mask, postprocess, [
            ('out_file', 'inputnode.brain_mask')
        ]),  #use the correctly oriented mask                           
        (ica_aroma, postprocess, [
            ('nonaggr_denoised_file', 'inputnode.epi_coreg')
        ]),  #use the nonaggr_denoised_file
        (inputnode, postprocess, [('TR', 'inputnode.tr')]),
        (inputnode, postprocess, [('highpass_freq', 'inputnode.highpass_freq')
                                  ]),
        (inputnode, postprocess, [('wmseg', 'inputnode.wmseg')]),
        (inputnode, postprocess, [('csfseg', 'inputnode.csfseg')]),
    ])

    #outputnode
    outputnode = Node(util.IdentityInterface(fields=[
        'par', 'rms', 'mean_epi', 'tsnr', 'stddev_file', 'realigned_ts',
        'fmap', 'unwarped_mean_epi2fmap', 'coregistered_epi2fmap',
        'fmap_fullwarp', 'epi2anat', 'epi2anat_mat', 'epi2anat_dat',
        'epi2anat_mincost', 'full_transform_ts', 'full_transform_mean',
        'resamp_t1', 'comb_mask_resamp', 'dvars_file', 'out_flirt_prep',
        'out_matrix_flirt_prep', 'out_warped', 'out_warp_field',
        'aggr_denoised_file', 'nonaggr_denoised_file', 'out_dir', 'wmcsf_mask',
        'combined_motion', 'comp_regressor', 'comp_F', 'comp_pF', 'out_betas',
        'ts_fullspectrum', 'ts_filtered'
    ]),
                      name='outputnode')

    # connections
    func_preproc.connect([
        (
            moco,
            outputnode,
            [  #('outputnode.epi_moco', 'realign.@realigned_ts'),
                ('outputnode.par_moco', 'par'),
                ('outputnode.rms_moco', 'rms'),
                ('outputnode.epi_moco', 'realigned_ts'),
                ('outputnode.epi_mean', 'mean_epi'),
                ('outputnode.tsnr_file', 'tsnr'),
                ('outputnode.stddev_file', 'stddev'),
            ]),
        (fmap_coreg, outputnode,
         [('outputnode.fmap', 'fmap'),
          ('outputnode.unwarped_mean_epi2fmap', 'unwarped_mean_epi2fmap'),
          ('outputnode.epi2fmap', 'coregistered_epi2fmap'),
          ('outputnode.fmap_fullwarp', 'fmap_fullwarp'),
          ('outputnode.epi2anat', 'epi2anat'),
          ('outputnode.epi2anat_mat', 'epi2anat_mat'),
          ('outputnode.epi2anat_dat', 'epi2anat_dat'),
          ('outputnode.epi2anat_mincost', 'epi2anat_mincost')]),
        (transform_ts, outputnode,
         [('outputnode.trans_ts', 'full_transform_ts'),
          ('outputnode.trans_ts_mean', 'full_transform_mean'),
          ('outputnode.resamp_t1', 'resamp_t1'),
          ('outputnode.comb_mask_resamp', 'comb_mask_resamp'),
          ('outputnode.out_dvars', 'dvars_file')]),
        (flirt_prep, outputnode, [('out_file', 'out_flirt_prep'),
                                  ('out_matrix_file', 'out_matrix_flirt_prep')
                                  ]),
        (fnirt, outputnode, [('warped_file', 'out_warped'),
                             ('field_file', 'out_warp_field')]),
        (ica_aroma, outputnode, [('aggr_denoised_file', 'aggr_denoised_file'),
                                 ('nonaggr_denoised_file',
                                  'nonaggr_denoised_file'),
                                 ('out_dir', 'out_dir')]),
        (postprocess, outputnode,
         [('outputnode.wmcsf_mask', 'wmcsf_mask'),
          ('outputnode.combined_motion', 'combined_motion'),
          ('outputnode.comp_regressor', 'comp_regressor'),
          ('outputnode.comp_F', 'comp_F'), ('outputnode.comp_pF', 'comp_pF'),
          ('outputnode.out_betas', 'out_betas'),
          ('outputnode.ts_fullspectrum', 'ts_fullspectrum'),
          ('outputnode.ts_filtered', 'ts_filtered')])
    ])

    return func_preproc
Example #5
0
def create_hc_connec(subject, working_dir, data_dir, freesurfer_dir, out_dir,
                     epi_resolution, standard_brain, standard_brain_resampled,
                     standard_brain_mask, standard_brain_mask_resampled,
                     fwhm_smoothing, side):
    # set fsl output type to nii.gz
    fsl.FSLCommand.set_default_output_type('NIFTI_GZ')
    # main workflow
    hc_connec = Workflow(name='hc_connec_thr099')
    hc_connec.base_dir = working_dir
    hc_connec.config['execution'][
        'crashdump_dir'] = hc_connec.base_dir + "/crash_files"

    # select files
    templates = {
        'rest_head':
        'resting_state/denoise/rest_preprocessed_nativespace.nii.gz',  #denoised and bandpass-filtered native space (2x2x2mm) image
        #'rest_head': 'scrubbed_interpolated/denoise/rest_denoised_scrubbed_int_bp.nii.gz', #denoised, scrubbed, interp, bp-filtered native space
        'ants_affine':
        'structural/transforms2mni/transform0GenericAffine.mat',
        'ants_warp':
        'structural/transforms2mni/transform1Warp.nii.gz',
        'ts_smoothed_nativ':
        'resting_state/denoise/rest_preprocessed_nativespace.nii.gz'
    }

    selectfiles = Node(nio.SelectFiles(templates, base_directory=data_dir),
                       name="selectfiles")

    #get T1 brainmask
    get_T1_brainmask = create_get_T1_brainmask()
    get_T1_brainmask.inputs.inputnode.fs_subjects_dir = freesurfer_dir
    get_T1_brainmask.inputs.inputnode.fs_subject_id = subject

    #workflow to extract HC and transform into individual space
    transform_hc = create_transform_hc()
    transform_hc.inputs.inputnode.fs_subjects_dir = freesurfer_dir
    transform_hc.inputs.inputnode.fs_subject_id = subject
    transform_hc.inputs.inputnode.resolution = 2
    transform_hc.inputs.inputnode.working_dir = working_dir

    #workflow to extract timeseries and correlate
    corr_ts = create_corr_ts()

    #workflow to tranform correlations to MNI space
    ants_registration = create_ants_registration_pipeline()
    ants_registration.inputs.inputnode.ref = standard_brain  #_resampled: 2x2x2mm brain for RSV

    #
    smoothing = create_smoothing_pipeline()
    smoothing.inputs.inputnode.fwhm = fwhm_smoothing
    #sink to store files
    sink = Node(
        nio.DataSink(parameterization=True, base_directory=out_dir),
        #   substitutions=[('_binarize', 'binarize'), -> don't really seem to work and I don't know why.
        #                   #('_binarize', 'anterior_hc'),
        #                   ('_ants_reg1', 'posterior_hc'),
        #                   #('_ants_reg', 'anterior_hc'),
        #                   ('_smooth1', 'posterior_hc'),
        #                   ('_smooth0', 'anterior_hc'),
        #                   ('corr_Z_trans', 'corr_Z_MNI')],
        name='sink')

    sink.inputs.substitutions = [('_binarize0', 'posterior_hc'),
                                 ('_binarize1', 'anterior_hc'),
                                 ('_ants_reg0', 'posterior_hc'),
                                 ('_ants_reg1', 'anterior_hc'),
                                 ('_smooth0', 'posterior_hc'),
                                 ('_smooth1', 'anterior_hc'),
                                 ('_apply_FisherZ0', 'posterior_hc'),
                                 ('_apply_FisherZ1', 'anterior_hc')]

    # connections
    hc_connec.connect([
        (get_T1_brainmask, transform_hc, [('outputnode.T1',
                                           'inputnode.anat_head')]),
        #(selectfiles, transform_hc, [('rest_head', 'inputnode.anat_head')]),
        (selectfiles, corr_ts, [('ts_smoothed_nativ', 'inputnode.ts')]),
        (transform_hc, corr_ts, [('outputnode.hc_transformed_bin',
                                  'inputnode.hc_mask')]),
        (transform_hc, sink, [('outputnode.hc_transformed_bin',
                               'hc_connectivity_thr099.' + side + '.hc_masks')
                              ]),
        (corr_ts, sink, [('outputnode.corrmap_z', 'hc_connectivity_thr099.' +
                          side + '.corr.nativespace.@transformed')]),
        (corr_ts, ants_registration, [('outputnode.corrmap_z',
                                       'inputnode.corr_Z')]),
        (selectfiles, ants_registration, [('ants_affine',
                                           'inputnode.ants_affine')]),
        (selectfiles, ants_registration, [('ants_warp', 'inputnode.ants_warp')
                                          ]),
        (ants_registration, sink,
         [('outputnode.ants_reg_corr_Z',
           'hc_connectivity_thr099.' + side + '.corr.ants')]),
        (ants_registration, smoothing, [('outputnode.ants_reg_corr_Z',
                                         'inputnode.ts_transformed')]),
        (smoothing, sink,
         [('outputnode.ts_smoothed',
           'hc_connectivity_thr099.' + side + '.corr.smoothed')]),
    ])

    hc_connec.run(
    )  #it can't run in multiproc as in one moment one file is hardcoded and saved to the disk which is
def create_lemon_resting(subject, working_dir, data_dir, data_dir_WDR, freesurfer_dir, out_dir,
    vol_to_remove, TR, epi_resolution, highpass, lowpass,
    echo_space, te_diff, pe_dir, standard_brain, standard_brain_resampled, standard_brain_mask, 
    standard_brain_mask_resampled, fwhm_smoothing):
    # set fsl output type to nii.gz
    fsl.FSLCommand.set_default_output_type('NIFTI_GZ')
    # main workflow
    func_preproc = Workflow(name='lemon_resting')
    func_preproc.base_dir = working_dir
    func_preproc.config['execution']['crashdump_dir'] = func_preproc.base_dir + "/crash_files"
    # select files
   
   
       # select files
    templates={
    'anat_brain' : 'preprocessed/mod/anat/brain.nii.gz', 
    'brain_mask' : 'preprocessed/mod/anat/T1_brain_mask.nii.gz',
    'ants_affine': 'preprocessed/mod/anat/transforms2mni/transform0GenericAffine.mat',
    'ants_warp':   'preprocessed/mod/anat/transforms2mni/transform1Warp.nii.gz',

    }
         
    templates_WDR={
    'par_moco': 'lemon_resting/motion_correction/mcflirt/rest_realigned.nii.gz.par',
    'trans_ts': 'lemon_resting/transform_timeseries/merge/rest2anat.nii.gz',
    'epi2anat_dat': 'lemon_resting/fmap_coreg/bbregister/rest2anat.dat',
    'unwarped_mean_epi2fmap': 'lemon_resting/fmap_coreg/applywarp0/rest_mean2fmap_unwarped.nii.gz',
     
    }
    
    selectfiles = Node(nio.SelectFiles(templates, base_directory=data_dir),    name="selectfiles")
    selectfiles_WDR = Node(nio.SelectFiles(templates_WDR, base_directory=data_dir_WDR),    name="selectfiles_WDR")
   
      
       
          
    # workflow to denoise timeseries
    denoise = create_denoise_pipeline()
    denoise.inputs.inputnode.highpass_sigma= 1./(2*TR*highpass)
    denoise.inputs.inputnode.lowpass_sigma= 1./(2*TR*lowpass)
    #https://www.jiscmail.ac.uk/cgi-bin/webadmin?A2=ind1205&L=FSL&P=R57592&1=FSL&9=A&I=-3&J=on&d=No+Match%3BMatch%3BMatches&z=4
    denoise.inputs.inputnode.tr = TR
    
    #workflow to transform timeseries to MNI
    ants_registration=create_ants_registration_pipeline()
    ants_registration.inputs.inputnode.ref=standard_brain_resampled    
    
    #workflow to smooth
    smoothing = create_smoothing_pipeline() 
    smoothing.inputs.inputnode.fwhm=fwhm_smoothing
   
    #workflow to slice time in the end as a try
    slicetiming = create_slice_timing_pipeline() 
    
    #visualize registration results
    visualize = create_visualize_pipeline()
    visualize.inputs.inputnode.mni_template=standard_brain_resampled 
    

    
    #sink to store files
    sink = Node(nio.DataSink(parameterization=False,
    base_directory=out_dir,
    substitutions=[('fmap_phase_fslprepared', 'fieldmap'),
    ('fieldmap_fslprepared_fieldmap_unmasked_vsm', 'shiftmap'),
    ('plot.rest_coregistered', 'outlier_plot'),
    ('filter_motion_comp_norm_compcor_art_dmotion', 'nuissance_matrix'),
    ('rest_realigned.nii.gz_abs.rms', 'rest_realigned_abs.rms'),
    ('rest_realigned.nii.gz.par','rest_realigned.par'),
    ('rest_realigned.nii.gz_rel.rms', 'rest_realigned_rel.rms'),
    ('rest_realigned.nii.gz_abs_disp', 'abs_displacement_plot'),
    ('rest_realigned.nii.gz_rel_disp', 'rel_displacment_plot'),
    ('art.rest_coregistered_outliers', 'outliers'),
    ('global_intensity.rest_coregistered', 'global_intensity'),
    ('norm.rest_coregistered', 'composite_norm'),
    ('stats.rest_coregistered', 'stats'),
    ('rest_denoised_bandpassed_norm.nii.gz', 'rest_preprocessed_nativespace.nii.gz'),
    ('rest_denoised_bandpassed_norm_trans.nii.gz', 'rest_mni_unsmoothed.nii.gz'),
    ('rest_denoised_bandpassed_norm_trans_smooth.nii', 'rest_mni_smoothed.nii')]),
    name='sink')
    
    
    # connections
    func_preproc.connect([
    
    #correct slicetiming
    (selectfiles_WDR, slicetiming, [('trans_ts', 'inputnode.ts')]),
    (slicetiming, denoise, [('outputnode.ts_slicetcorrected','inputnode.epi_coreg')]),
    
    #denoise data
    (selectfiles, denoise, [('brain_mask', 'inputnode.brain_mask'),
    ('anat_brain', 'inputnode.anat_brain')]),
    (selectfiles_WDR, denoise, [('par_moco', 'inputnode.moco_par')]),
    (selectfiles_WDR, denoise, [('epi2anat_dat', 'inputnode.epi2anat_dat'),
    ('unwarped_mean_epi2fmap', 'inputnode.unwarped_mean')]),
    (denoise, ants_registration, [('outputnode.normalized_file', 'inputnode.denoised_ts')]),
        
   
    #registration to MNI space
    (selectfiles, ants_registration, [('ants_affine', 'inputnode.ants_affine')] ),
    (selectfiles, ants_registration, [('ants_warp', 'inputnode.ants_warp')] ),

    (ants_registration, smoothing, [('outputnode.ants_reg_ts', 'inputnode.ts_transformed')]),

    (smoothing, visualize,  [('outputnode.ts_smoothed', 'inputnode.ts_transformed')]),


    ##all the output
    (denoise, sink, [
    ('outputnode.wmcsf_mask', 'denoise.mask.@wmcsf_masks'),
    ('outputnode.combined_motion','denoise.artefact.@combined_motion'),
    ('outputnode.outlier_files','denoise.artefact.@outlier'),
    ('outputnode.intensity_files','denoise.artefact.@intensity'),
    ('outputnode.outlier_stats','denoise.artefact.@outlierstats'),
    ('outputnode.outlier_plots','denoise.artefact.@outlierplots'),
    ('outputnode.mc_regressor', 'denoise.regress.@mc_regressor'),
    ('outputnode.comp_regressor', 'denoise.regress.@comp_regressor'),
    ('outputnode.mc_F', 'denoise.regress.@mc_F'),
    ('outputnode.mc_pF', 'denoise.regress.@mc_pF'),
    ('outputnode.comp_F', 'denoise.regress.@comp_F'),
    ('outputnode.comp_pF', 'denoise.regress.@comp_pF'),
    ('outputnode.brain_mask_resamp', 'denoise.mask.@brain_resamp'),
    ('outputnode.brain_mask2epi', 'denoise.mask.@brain_mask2epi'),
    ('outputnode.normalized_file', 'denoise.@normalized')
    ]),
    (ants_registration, sink, [('outputnode.ants_reg_ts', 'ants.@antsnormalized')
    ]),
    (smoothing, sink, [('outputnode.ts_smoothed', '@smoothed.FWHM6')]),
    ])

    #func_preproc.write_graph(dotfilename='func_preproc.dot', graph2use='colored', format='pdf', simple_form=True)
    func_preproc.run()
    # plugin='MultiProc'plugin='MultiProc'plugin='CondorDAGMan')
    #func_preproc.run()plugin='CondorDAGMan'plugin='CondorDAGMan'plugin='CondorDAGMan'plugin='CondorDAGMan'
#plugin='CondorDAGMan'
def create_lemon_resting(subject, working_dir, data_dir, freesurfer_dir, out_dir,
                         vol_to_remove, TR, epi_resolution, highpass, lowpass,
                         echo_space, te_diff, pe_dir, standard_brain, standard_brain_resampled, standard_brain_mask,
                         standard_brain_mask_resampled, fwhm_smoothing):
    # set fsl output type to nii.gz
    fsl.FSLCommand.set_default_output_type('NIFTI_GZ')
    # main workflow
    func_preproc = Workflow(name='lemon_resting')
    func_preproc.base_dir = working_dir
    func_preproc.config['execution']['crashdump_dir'] = func_preproc.base_dir + "/crash_files"
    # select files
    templates = {'func': 'raw_data/{subject}/func/EPI_t2.nii',
                 'fmap_phase': 'raw_data/{subject}/unwarp/B0_ph.nii',
                 'fmap_mag': 'raw_data/{subject}/unwarp/B0_mag.nii',
                 'anat_head': 'preprocessed/{subject}/structural/T1.nii.gz',  # either with mod or without
                 'anat_brain': 'preprocessed/{subject}/structural/brain.nii.gz',
                 # new version with brain_extraction from freesurfer  #T1_brain_brain.nii.gz',
                 'brain_mask': 'preprocessed/{subject}/structural/T1_brain_mask.nii.gz',  # T1_brain_brain_mask.nii.gz',
                 'ants_affine': 'preprocessed/{subject}/structural/transforms2mni/transform0GenericAffine.mat',
                 'ants_warp': 'preprocessed/{subject}/structural/transforms2mni/transform1Warp.nii.gz'
                 }

    selectfiles = Node(nio.SelectFiles(templates,
                                       base_directory=data_dir),
                       name="selectfiles")
    selectfiles.inputs.subject = subject


    # node to remove first volumes
    remove_vol = Node(util.Function(input_names=['in_file', 't_min'],
                                    output_names=["out_file"],
                                    function=strip_rois_func),
                      name='remove_vol')
    remove_vol.inputs.t_min = vol_to_remove
    # workflow for motion correction
    moco = create_moco_pipeline()

    # workflow for fieldmap correction and coregistration
    fmap_coreg = create_fmap_coreg_pipeline()
    fmap_coreg.inputs.inputnode.fs_subjects_dir = freesurfer_dir
    fmap_coreg.inputs.inputnode.fs_subject_id = subject
    fmap_coreg.inputs.inputnode.echo_space = echo_space
    fmap_coreg.inputs.inputnode.te_diff = te_diff
    fmap_coreg.inputs.inputnode.pe_dir = pe_dir

    # workflow for applying transformations to timeseries
    transform_ts = create_transform_pipeline()
    transform_ts.inputs.inputnode.resolution = epi_resolution


    # workflow to denoise timeseries
    denoise = create_denoise_pipeline()
    denoise.inputs.inputnode.highpass_sigma = 1. / (2 * TR * highpass)
    denoise.inputs.inputnode.lowpass_sigma = 1. / (2 * TR * lowpass)
    # https://www.jiscmail.ac.uk/cgi-bin/webadmin?A2=ind1205&L=FSL&P=R57592&1=FSL&9=A&I=-3&J=on&d=No+Match%3BMatch%3BMatches&z=4
    denoise.inputs.inputnode.tr = TR

    # workflow to transform timeseries to MNI
    ants_registration = create_ants_registration_pipeline()
    ants_registration.inputs.inputnode.ref = standard_brain_resampled
    ants_registration.inputs.inputnode.tr_sec = TR

    # FL added fullspectrum
    # workflow to transform fullspectrum timeseries to MNI
    ants_registration_full = create_ants_registration_pipeline('ants_registration_full')
    ants_registration_full.inputs.inputnode.ref = standard_brain_resampled
    ants_registration_full.inputs.inputnode.tr_sec = TR

    # workflow to smooth
    smoothing = create_smoothing_pipeline()
    smoothing.inputs.inputnode.fwhm = fwhm_smoothing

    # visualize registration results
    visualize = create_visualize_pipeline()
    visualize.inputs.inputnode.mni_template = standard_brain_resampled



    # sink to store files
    sink = Node(nio.DataSink(parameterization=False,
                             base_directory=out_dir,
                             substitutions=[('fmap_phase_fslprepared', 'fieldmap'),
                                            ('fieldmap_fslprepared_fieldmap_unmasked_vsm', 'shiftmap'),
                                            ('plot.rest_coregistered', 'outlier_plot'),
                                            ('filter_motion_comp_norm_compcor_art_dmotion', 'nuissance_matrix'),
                                            ('rest_realigned.nii.gz_abs.rms', 'rest_realigned_abs.rms'),
                                            ('rest_realigned.nii.gz.par', 'rest_realigned.par'),
                                            ('rest_realigned.nii.gz_rel.rms', 'rest_realigned_rel.rms'),
                                            ('rest_realigned.nii.gz_abs_disp', 'abs_displacement_plot'),
                                            ('rest_realigned.nii.gz_rel_disp', 'rel_displacment_plot'),
                                            ('art.rest_coregistered_outliers', 'outliers'),
                                            ('global_intensity.rest_coregistered', 'global_intensity'),
                                            ('norm.rest_coregistered', 'composite_norm'),
                                            ('stats.rest_coregistered', 'stats'),
                                            ('rest_denoised_bandpassed_norm.nii.gz',
                                             'rest_preprocessed_nativespace.nii.gz'),
                                            ('rest_denoised_bandpassed_norm_trans.nii.gz',
                                             'rest_mni_unsmoothed.nii.gz'),
                                            ('rest_denoised_bandpassed_norm_trans_smooth.nii',
                                             'rest_mni_smoothed.nii'),
                                            # FL added
                                            ('rest2anat_masked.nii.gz', 'rest_coregistered_nativespace.nii.gz'),
                                            ('rest2anat_denoised.nii.gz',
                                             'rest_preprocessed_nativespace_fullspectrum.nii.gz'),
                                            ('rest2anat_denoised_trans.nii.gz',
                                             'rest_mni_unsmoothed_fullspectrum.nii.gz')
                                            ]),
                name='sink')


    # connections
    func_preproc.connect([
        # remove the first volumes
        (selectfiles, remove_vol, [('func', 'in_file')]),

        # align volumes and motion correction
        (remove_vol, moco, [('out_file', 'inputnode.epi')]),

        # prepare field map
        (selectfiles, fmap_coreg, [('fmap_phase', 'inputnode.phase'),
                                   ('fmap_mag', 'inputnode.mag'),
                                   ('anat_head', 'inputnode.anat_head'),
                                   ('anat_brain', 'inputnode.anat_brain')
                                   ]),
        (moco, fmap_coreg, [('outputnode.epi_mean', 'inputnode.epi_mean')]),

        # transform timeseries
        (remove_vol, transform_ts, [('out_file', 'inputnode.orig_ts')]),
        (selectfiles, transform_ts, [('anat_head', 'inputnode.anat_head')]),
        (selectfiles, transform_ts, [('brain_mask', 'inputnode.brain_mask')]),
        (moco, transform_ts, [('outputnode.mat_moco', 'inputnode.mat_moco')]),
        (fmap_coreg, transform_ts, [('outputnode.fmap_fullwarp', 'inputnode.fullwarp')]),

        # correct slicetiming
        # FIXME slice timing?
        # (transform_ts, slicetiming, [('outputnode.trans_ts_masked', 'inputnode.ts')]),
        # (slicetiming, denoise, [('outputnode.ts_slicetcorrected', 'inputnode.epi_coreg')]),
        (transform_ts, denoise, [('outputnode.trans_ts_masked', 'inputnode.epi_coreg')]),

        # denoise data
        (selectfiles, denoise, [('brain_mask', 'inputnode.brain_mask'),
                                ('anat_brain', 'inputnode.anat_brain')]),
        (moco, denoise, [('outputnode.par_moco', 'inputnode.moco_par')]),
        (fmap_coreg, denoise, [('outputnode.epi2anat_dat', 'inputnode.epi2anat_dat'),
                               ('outputnode.unwarped_mean_epi2fmap', 'inputnode.unwarped_mean')]),
        (denoise, ants_registration, [('outputnode.normalized_file', 'inputnode.denoised_ts')]),

        # registration to MNI space
        (selectfiles, ants_registration, [('ants_affine', 'inputnode.ants_affine')]),
        (selectfiles, ants_registration, [('ants_warp', 'inputnode.ants_warp')]),

        # FL added fullspectrum
        (denoise, ants_registration_full, [('outputnode.ts_fullspectrum', 'inputnode.denoised_ts')]),
        (selectfiles, ants_registration_full, [('ants_affine', 'inputnode.ants_affine')]),
        (selectfiles, ants_registration_full, [('ants_warp', 'inputnode.ants_warp')]),

        (ants_registration, smoothing, [('outputnode.ants_reg_ts', 'inputnode.ts_transformed')]),

        (smoothing, visualize, [('outputnode.ts_smoothed', 'inputnode.ts_transformed')]),

        ##all the output
        (moco, sink, [  # ('outputnode.epi_moco', 'realign.@realigned_ts'),
                        ('outputnode.par_moco', 'realign.@par'),
                        ('outputnode.rms_moco', 'realign.@rms'),
                        ('outputnode.mat_moco', 'realign.MAT.@mat'),
                        ('outputnode.epi_mean', 'realign.@mean'),
                        ('outputnode.rotplot', 'realign.plots.@rotplot'),
                        ('outputnode.transplot', 'realign.plots.@transplot'),
                        ('outputnode.dispplots', 'realign.plots.@dispplots'),
                        ('outputnode.tsnr_file', 'realign.@tsnr')]),
        (fmap_coreg, sink, [('outputnode.fmap', 'coregister.transforms2anat.@fmap'),
                            # ('outputnode.unwarpfield_epi2fmap', 'coregister.@unwarpfield_epi2fmap'),
                            ('outputnode.unwarped_mean_epi2fmap', 'coregister.@unwarped_mean_epi2fmap'),
                            ('outputnode.epi2fmap', 'coregister.@epi2fmap'),
                            # ('outputnode.shiftmap', 'coregister.@shiftmap'),
                            ('outputnode.fmap_fullwarp', 'coregister.transforms2anat.@fmap_fullwarp'),
                            ('outputnode.epi2anat', 'coregister.@epi2anat'),
                            ('outputnode.epi2anat_mat', 'coregister.transforms2anat.@epi2anat_mat'),
                            ('outputnode.epi2anat_dat', 'coregister.transforms2anat.@epi2anat_dat'),
                            ('outputnode.epi2anat_mincost', 'coregister.@epi2anat_mincost')
                            ]),

        (transform_ts, sink, [('outputnode.trans_ts_masked', 'coregister.@full_transform_ts'),
                              ('outputnode.trans_ts_mean', 'coregister.@full_transform_mean'),
                              ('outputnode.resamp_brain', 'coregister.@resamp_brain')]),

        (denoise, sink, [
            ('outputnode.wmcsf_mask', 'denoise.mask.@wmcsf_masks'),
            ('outputnode.combined_motion', 'denoise.artefact.@combined_motion'),
            ('outputnode.outlier_files', 'denoise.artefact.@outlier'),
            ('outputnode.intensity_files', 'denoise.artefact.@intensity'),
            ('outputnode.outlier_stats', 'denoise.artefact.@outlierstats'),
            ('outputnode.outlier_plots', 'denoise.artefact.@outlierplots'),
            ('outputnode.mc_regressor', 'denoise.regress.@mc_regressor'),
            ('outputnode.comp_regressor', 'denoise.regress.@comp_regressor'),
            ('outputnode.mc_F', 'denoise.regress.@mc_F'),
            ('outputnode.mc_pF', 'denoise.regress.@mc_pF'),
            ('outputnode.comp_F', 'denoise.regress.@comp_F'),
            ('outputnode.comp_pF', 'denoise.regress.@comp_pF'),
            ('outputnode.brain_mask_resamp', 'denoise.mask.@brain_resamp'),
            ('outputnode.brain_mask2epi', 'denoise.mask.@brain_mask2epi'),
            ('outputnode.normalized_file', 'denoise.@normalized'),
            # FL added fullspectrum
            ('outputnode.ts_fullspectrum', 'denoise.@ts_fullspectrum')
        ]),
        (ants_registration, sink, [('outputnode.ants_reg_ts', 'ants.@antsnormalized')]),
        (ants_registration_full, sink, [('outputnode.ants_reg_ts', 'ants.@antsnormalized_fullspectrum')]),
        (smoothing, sink, [('outputnode.ts_smoothed', '@smoothed.FWHM6')]),
    ])

    func_preproc.write_graph(dotfilename='func_preproc.dot', graph2use='colored', format='pdf', simple_form=True)
    func_preproc.run(plugin='CondorDAGMan', plugin_args={'initial_specs': 'request_memory = 1500'})
def create_lemon_resting(
    subject,
    working_dir,
    data_dir,
    freesurfer_dir,
    out_dir,
    vol_to_remove,
    TR,
    epi_resolution,
    highpass,
    lowpass,
    echo_space,
    te_diff,
    pe_dir,
    standard_brain,
    standard_brain_resampled,
    standard_brain_mask,
    standard_brain_mask_resampled,
    fwhm_smoothing,
):
    # set fsl output type to nii.gz
    fsl.FSLCommand.set_default_output_type("NIFTI_GZ")
    # main workflow
    func_preproc = Workflow(name="lemon_resting")
    func_preproc.base_dir = working_dir
    func_preproc.config["execution"]["crashdump_dir"] = func_preproc.base_dir + "/crash_files"
    # select files
    templates = {
        "func": "func/EPI_t2.nii",
        "fmap_phase": "unwarp/B0_ph.nii",
        "fmap_mag": "unwarp/B0_mag.nii",
        "anat_head": "preprocessed/mod/anat/T1.nii.gz",  # either with mod or without
        "anat_brain": "preprocessed/mod/anat/brain.nii.gz",  # new version with brain_extraction from freesurfer  #T1_brain_brain.nii.gz',
        "brain_mask": "preprocessed/mod/anat/T1_brain_mask.nii.gz",  # T1_brain_brain_mask.nii.gz',
        "ants_affine": "preprocessed/mod/anat/transforms2mni/transform0GenericAffine.mat",
        "ants_warp": "preprocessed/mod/anat/transforms2mni/transform1Warp.nii.gz",
    }

    selectfiles = Node(nio.SelectFiles(templates, base_directory=data_dir), name="selectfiles")

    # node to remove first volumes
    remove_vol = Node(
        util.Function(input_names=["in_file", "t_min"], output_names=["out_file"], function=strip_rois_func),
        name="remove_vol",
    )
    remove_vol.inputs.t_min = vol_to_remove
    # workflow for motion correction
    moco = create_moco_pipeline()
    # workflow for fieldmap correction and coregistration
    fmap_coreg = create_fmap_coreg_pipeline()
    fmap_coreg.inputs.inputnode.fs_subjects_dir = freesurfer_dir
    fmap_coreg.inputs.inputnode.fs_subject_id = subject
    fmap_coreg.inputs.inputnode.echo_space = echo_space
    fmap_coreg.inputs.inputnode.te_diff = te_diff
    fmap_coreg.inputs.inputnode.pe_dir = pe_dir
    # workflow for applying transformations to timeseries
    transform_ts = create_transform_pipeline()
    transform_ts.inputs.inputnode.resolution = epi_resolution

    # workflow to convert signal into percent signal change
    normalize = create_normalize_pipeline()
    normalize.inputs.inputnode.tr = TR

    # workflow to transform timeseries to MNI
    ants_registration = create_ants_registration_pipeline()
    ants_registration.inputs.inputnode.ref = standard_brain_resampled

    # workflow to smooth
    smoothing = create_smoothing_pipeline()
    smoothing.inputs.inputnode.fwhm = fwhm_smoothing

    # workflow to correct slice timing
    slicetiming = create_slice_timing_pipeline()

    # visualize registration results
    visualize = create_visualize_pipeline()
    visualize.inputs.inputnode.mni_template = standard_brain_resampled

    # sink to store files
    sink = Node(
        nio.DataSink(
            parameterization=False,
            base_directory=out_dir,
            substitutions=[
                ("fmap_phase_fslprepared", "fieldmap"),
                ("fieldmap_fslprepared_fieldmap_unmasked_vsm", "shiftmap"),
                ("plot.rest_coregistered", "outlier_plot"),
                ("filter_motion_comp_norm_compcor_art_dmotion", "nuissance_matrix"),
                ("rest_realigned.nii.gz_abs.rms", "rest_realigned_abs.rms"),
                ("rest_realigned.nii.gz.par", "rest_realigned.par"),
                ("rest_realigned.nii.gz_rel.rms", "rest_realigned_rel.rms"),
                ("rest_realigned.nii.gz_abs_disp", "abs_displacement_plot"),
                ("rest_realigned.nii.gz_rel_disp", "rel_displacment_plot"),
                ("art.rest_coregistered_outliers", "outliers"),
                ("global_intensity.rest_coregistered", "global_intensity"),
                ("norm.rest_coregistered", "composite_norm"),
                ("stats.rest_coregistered", "stats"),
                ("rest_denoised_bandpassed_norm.nii.gz", "rest_preprocessed.nii.gz"),
                ("rest_denoised_bandpassed_norm_trans.nii.gz", "rest_mni.nii.gz"),
                ("rest2anat_masked_st_norm_trans_smooth.nii", "rest_mni_smoothed.nii"),
            ],
        ),
        name="sink",
    )

    # connections
    func_preproc.connect(
        [
            # remove the first volumes
            (selectfiles, remove_vol, [("func", "in_file")]),
            # align volumes and motion correction
            (remove_vol, moco, [("out_file", "inputnode.epi")]),
            # prepare field map
            (
                selectfiles,
                fmap_coreg,
                [
                    ("fmap_phase", "inputnode.phase"),
                    ("fmap_mag", "inputnode.mag"),
                    ("anat_head", "inputnode.anat_head"),
                    ("anat_brain", "inputnode.anat_brain"),
                ],
            ),
            (moco, fmap_coreg, [("outputnode.epi_mean", "inputnode.epi_mean")]),
            (remove_vol, transform_ts, [("out_file", "inputnode.orig_ts")]),
            (selectfiles, transform_ts, [("anat_head", "inputnode.anat_head")]),
            (selectfiles, transform_ts, [("brain_mask", "inputnode.brain_mask")]),
            (moco, transform_ts, [("outputnode.mat_moco", "inputnode.mat_moco")]),
            (fmap_coreg, transform_ts, [("outputnode.fmap_fullwarp", "inputnode.fullwarp")]),
            ##add slice time correction after applying motion realignement + unwarping
            (transform_ts, slicetiming, [("outputnode.trans_ts_masked", "inputnode.ts")]),
            (slicetiming, normalize, [("outputnode.ts_slicetcorrected", "inputnode.epi_coreg")]),
            (normalize, ants_registration, [("outputnode.normalized_file", "inputnode.denoised_ts")]),
            # registration to MNI space
            (selectfiles, ants_registration, [("ants_affine", "inputnode.ants_affine")]),
            (selectfiles, ants_registration, [("ants_warp", "inputnode.ants_warp")]),
            (ants_registration, smoothing, [("outputnode.ants_reg_ts", "inputnode.ts_transformed")]),
            (smoothing, visualize, [("outputnode.ts_smoothed", "inputnode.ts_transformed")]),
            ##all the output
            (
                moco,
                sink,
                [  # ('outputnode.epi_moco', 'realign.@realigned_ts'),
                    ("outputnode.par_moco", "realign.@par"),
                    ("outputnode.rms_moco", "realign.@rms"),
                    ("outputnode.mat_moco", "realign.MAT.@mat"),
                    ("outputnode.epi_mean", "realign.@mean"),
                    ("outputnode.rotplot", "realign.plots.@rotplot"),
                    ("outputnode.transplot", "realign.plots.@transplot"),
                    ("outputnode.dispplots", "realign.plots.@dispplots"),
                    ("outputnode.tsnr_file", "realign.@tsnr"),
                ],
            ),
            (
                fmap_coreg,
                sink,
                [
                    ("outputnode.fmap", "coregister.transforms2anat.@fmap"),
                    # ('outputnode.unwarpfield_epi2fmap', 'coregister.@unwarpfield_epi2fmap'),
                    ("outputnode.unwarped_mean_epi2fmap", "coregister.@unwarped_mean_epi2fmap"),
                    ("outputnode.epi2fmap", "coregister.@epi2fmap"),
                    # ('outputnode.shiftmap', 'coregister.@shiftmap'),
                    ("outputnode.fmap_fullwarp", "coregister.transforms2anat.@fmap_fullwarp"),
                    ("outputnode.epi2anat", "coregister.@epi2anat"),
                    ("outputnode.epi2anat_mat", "coregister.transforms2anat.@epi2anat_mat"),
                    ("outputnode.epi2anat_dat", "coregister.transforms2anat.@epi2anat_dat"),
                    ("outputnode.epi2anat_mincost", "coregister.@epi2anat_mincost"),
                ],
            ),
            (
                transform_ts,
                sink,
                [  # ('outputnode.trans_ts', 'coregister.@full_transform_ts'),
                    ("outputnode.trans_ts_mean", "coregister.@full_transform_mean"),
                    ("outputnode.resamp_brain", "coregister.@resamp_brain"),
                ],
            ),
            (ants_registration, sink, [("outputnode.ants_reg_ts", "ants.@antsnormalized")]),
            (smoothing, sink, [("outputnode.ts_smoothed", "@smoothed.FWHM6")]),
        ]
    )

    # func_preproc.write_graph(dotfilename='func_preproc.dot', graph2use='colored', format='pdf', simple_form=True)
    func_preproc.run()
def create_lemon_resting(subject, working_dir, data_dir, data_dir_WDR,
                         freesurfer_dir, out_dir, vol_to_remove, TR,
                         epi_resolution, highpass, lowpass, echo_space,
                         te_diff, pe_dir, standard_brain,
                         standard_brain_resampled, standard_brain_mask,
                         standard_brain_mask_resampled, fwhm_smoothing):
    # set fsl output type to nii.gz
    fsl.FSLCommand.set_default_output_type('NIFTI_GZ')
    # main workflow
    func_preproc = Workflow(name='lemon_resting')
    func_preproc.base_dir = working_dir
    func_preproc.config['execution'][
        'crashdump_dir'] = func_preproc.base_dir + "/crash_files"
    # select files

    # select files
    templates = {
        'anat_brain': 'preprocessed/mod/anat/brain.nii.gz',
        'brain_mask': 'preprocessed/mod/anat/T1_brain_mask.nii.gz',
        'ants_affine':
        'preprocessed/mod/anat/transforms2mni/transform0GenericAffine.mat',
        'ants_warp':
        'preprocessed/mod/anat/transforms2mni/transform1Warp.nii.gz',
    }

    templates_WDR = {
        'par_moco':
        'lemon_resting/motion_correction/mcflirt/rest_realigned.nii.gz.par',
        'trans_ts':
        'lemon_resting/transform_timeseries/merge/rest2anat.nii.gz',
        'epi2anat_dat':
        'lemon_resting/fmap_coreg/bbregister/rest2anat.dat',
        'unwarped_mean_epi2fmap':
        'lemon_resting/fmap_coreg/applywarp0/rest_mean2fmap_unwarped.nii.gz',
    }

    selectfiles = Node(nio.SelectFiles(templates, base_directory=data_dir),
                       name="selectfiles")
    selectfiles_WDR = Node(nio.SelectFiles(templates_WDR,
                                           base_directory=data_dir_WDR),
                           name="selectfiles_WDR")

    # workflow to denoise timeseries
    denoise = create_denoise_pipeline()
    denoise.inputs.inputnode.highpass_sigma = 1. / (2 * TR * highpass)
    denoise.inputs.inputnode.lowpass_sigma = 1. / (2 * TR * lowpass)
    #https://www.jiscmail.ac.uk/cgi-bin/webadmin?A2=ind1205&L=FSL&P=R57592&1=FSL&9=A&I=-3&J=on&d=No+Match%3BMatch%3BMatches&z=4
    denoise.inputs.inputnode.tr = TR

    #workflow to transform timeseries to MNI
    ants_registration = create_ants_registration_pipeline()
    ants_registration.inputs.inputnode.ref = standard_brain_resampled

    #workflow to smooth
    smoothing = create_smoothing_pipeline()
    smoothing.inputs.inputnode.fwhm = fwhm_smoothing

    #workflow to slice time in the end as a try
    slicetiming = create_slice_timing_pipeline()

    #visualize registration results
    visualize = create_visualize_pipeline()
    visualize.inputs.inputnode.mni_template = standard_brain_resampled

    #sink to store files
    sink = Node(nio.DataSink(
        parameterization=False,
        base_directory=out_dir,
        substitutions=[
            ('fmap_phase_fslprepared', 'fieldmap'),
            ('fieldmap_fslprepared_fieldmap_unmasked_vsm', 'shiftmap'),
            ('plot.rest_coregistered', 'outlier_plot'),
            ('filter_motion_comp_norm_compcor_art_dmotion',
             'nuissance_matrix'),
            ('rest_realigned.nii.gz_abs.rms', 'rest_realigned_abs.rms'),
            ('rest_realigned.nii.gz.par', 'rest_realigned.par'),
            ('rest_realigned.nii.gz_rel.rms', 'rest_realigned_rel.rms'),
            ('rest_realigned.nii.gz_abs_disp', 'abs_displacement_plot'),
            ('rest_realigned.nii.gz_rel_disp', 'rel_displacment_plot'),
            ('art.rest_coregistered_outliers', 'outliers'),
            ('global_intensity.rest_coregistered', 'global_intensity'),
            ('norm.rest_coregistered', 'composite_norm'),
            ('stats.rest_coregistered', 'stats'),
            ('rest_denoised_bandpassed_norm.nii.gz',
             'rest_preprocessed_nativespace.nii.gz'),
            ('rest_denoised_bandpassed_norm_trans.nii.gz',
             'rest_mni_unsmoothed.nii.gz'),
            ('rest_denoised_bandpassed_norm_trans_smooth.nii',
             'rest_mni_smoothed.nii')
        ]),
                name='sink')

    # connections
    func_preproc.connect([

        #correct slicetiming
        (selectfiles_WDR, slicetiming, [('trans_ts', 'inputnode.ts')]),
        (slicetiming, denoise, [('outputnode.ts_slicetcorrected',
                                 'inputnode.epi_coreg')]),

        #denoise data
        (selectfiles, denoise, [('brain_mask', 'inputnode.brain_mask'),
                                ('anat_brain', 'inputnode.anat_brain')]),
        (selectfiles_WDR, denoise, [('par_moco', 'inputnode.moco_par')]),
        (selectfiles_WDR, denoise, [('epi2anat_dat', 'inputnode.epi2anat_dat'),
                                    ('unwarped_mean_epi2fmap',
                                     'inputnode.unwarped_mean')]),
        (denoise, ants_registration, [('outputnode.normalized_file',
                                       'inputnode.denoised_ts')]),

        #registration to MNI space
        (selectfiles, ants_registration, [('ants_affine',
                                           'inputnode.ants_affine')]),
        (selectfiles, ants_registration, [('ants_warp', 'inputnode.ants_warp')
                                          ]),
        (ants_registration, smoothing, [('outputnode.ants_reg_ts',
                                         'inputnode.ts_transformed')]),
        (smoothing, visualize, [('outputnode.ts_smoothed',
                                 'inputnode.ts_transformed')]),

        ##all the output
        (denoise, sink,
         [('outputnode.wmcsf_mask', 'denoise.mask.@wmcsf_masks'),
          ('outputnode.combined_motion', 'denoise.artefact.@combined_motion'),
          ('outputnode.outlier_files', 'denoise.artefact.@outlier'),
          ('outputnode.intensity_files', 'denoise.artefact.@intensity'),
          ('outputnode.outlier_stats', 'denoise.artefact.@outlierstats'),
          ('outputnode.outlier_plots', 'denoise.artefact.@outlierplots'),
          ('outputnode.mc_regressor', 'denoise.regress.@mc_regressor'),
          ('outputnode.comp_regressor', 'denoise.regress.@comp_regressor'),
          ('outputnode.mc_F', 'denoise.regress.@mc_F'),
          ('outputnode.mc_pF', 'denoise.regress.@mc_pF'),
          ('outputnode.comp_F', 'denoise.regress.@comp_F'),
          ('outputnode.comp_pF', 'denoise.regress.@comp_pF'),
          ('outputnode.brain_mask_resamp', 'denoise.mask.@brain_resamp'),
          ('outputnode.brain_mask2epi', 'denoise.mask.@brain_mask2epi'),
          ('outputnode.normalized_file', 'denoise.@normalized')]),
        (ants_registration, sink, [('outputnode.ants_reg_ts',
                                    'ants.@antsnormalized')]),
        (smoothing, sink, [('outputnode.ts_smoothed', '@smoothed.FWHM6')]),
    ])

    #func_preproc.write_graph(dotfilename='func_preproc.dot', graph2use='colored', format='pdf', simple_form=True)
    func_preproc.run()
    # plugin='MultiProc'plugin='MultiProc'plugin='CondorDAGMan')
    #func_preproc.run()plugin='CondorDAGMan'plugin='CondorDAGMan'plugin='CondorDAGMan'plugin='CondorDAGMan'


#plugin='CondorDAGMan'
Example #10
0
def create_aroma_prep(subject, working_dir, data_dir, freesurfer_dir, out_dir,
                      vol_to_remove, TR, epi_resolution, highpass, echo_space,
                      te_diff, pe_dir, standard_brain,
                      standard_brain_resampled, standard_brain_mask,
                      standard_brain_mask_resampled, fwhm_smoothing):
    # set fsl output type to nii.gz
    fsl.FSLCommand.set_default_output_type('NIFTI_GZ')
    # main workflow
    aroma_prep = Workflow(name='aroma_prep')
    aroma_prep.base_dir = working_dir
    aroma_prep.config['execution'][
        'crashdump_dir'] = aroma_prep.base_dir + "/crash_files"

    #helper function to save array output of AROMA functions
    def small_save(filename, in_data):
        import numpy as np
        np.save(filename, in_data)
        return filename

    # select files
    templates = {
        #'anat_head' : subject+'/preprocessed/mod/anat/T1.nii.gz',
        'anat_brain': subject + '/preprocessed/mod/anat/brain.nii.gz',
        'brain_mask': subject + '/preprocessed/mod/anat/T1_brain_mask.nii.gz',
        'func': subject + '/func/EPI_t2.nii',
        'mag': subject + '/unwarp/B0_mag.nii',
        'phase': subject + '/unwarp/B0_ph.nii'
    }

    selectfiles = Node(nio.SelectFiles(templates, base_directory=data_dir),
                       name="selectfiles")

    ##################preprocessing############################################
    # node to remove first volumes
    remove_vol = Node(util.Function(input_names=['in_file', 't_min'],
                                    output_names=["out_file"],
                                    function=strip_rois_func),
                      name='remove_vol')
    remove_vol.inputs.t_min = vol_to_remove

    aroma_prep.connect([(selectfiles, remove_vol, [('func', 'in_file')])])

    #motion correction
    moco = create_moco_pipeline()

    #creating and applying the fieldmap
    fmap_coreg = create_fmap_pipeline()
    fmap_coreg.inputs.inputnode.echo_space = echo_space
    fmap_coreg.inputs.inputnode.te_diff = te_diff
    fmap_coreg.inputs.inputnode.pe_dir = pe_dir

    aroma_prep.connect([
        (selectfiles, fmap_coreg, [('mag', 'inputnode.mag')]),
        (selectfiles, fmap_coreg, [('phase', 'inputnode.phase')]),
        (moco, fmap_coreg, [('outputnode.epi_moco', 'inputnode.epi_coreg')]),
        (moco, fmap_coreg, [('outputnode.epi_mean', 'inputnode.epi_mean')])
    ])

    #reorient to std
    reorient2std = Node(fsl.Reorient2Std(), name="reorient2std")
    #mean intensity normalization
    meanintensnorm = Node(fsl.ImageMaths(op_string='-ing 10000'),
                          name='meanintensnorm')

    aroma_prep.connect([
        #(unwarp, moco,    [('warped_file', 'inputnode.epi')]),
        (remove_vol, moco, [('out_file', 'inputnode.epi')]),
        (selectfiles, reorient2std, [
            ('anat_brain', 'in_file')
        ]),  #reorient to standard to avoid registration issues seen previously
        (fmap_coreg, meanintensnorm, [('outputnode.unwarped_epi', 'in_file')])
    ])

    #mask functional image
    betfunctional = Node(fsl.BET(frac=0.3), name='betfunctional')
    binmask = Node(fsl.ImageMaths(op_string='-bin'), name='binmask')

    #smoothing (@6mm FWHM)
    smoothing = create_smoothing_pipeline()
    smoothing.inputs.inputnode.fwhm = fwhm_smoothing

    aroma_prep.connect([(meanintensnorm, smoothing,
                         [('out_file', 'inputnode.ts_transformed')]),
                        (fmap_coreg, betfunctional,
                         [('outputnode.unwarped_mean_epi2fmap', 'in_file')]),
                        (betfunctional, binmask, [('out_file', 'in_file')])])

    # Func > Anat
    # register example func to high-resolution (use linear registration with 7 degrees of freedom and output
    #matrix example_func2highres.mat
    flirt = Node(fsl.FLIRT(cost_func='mutualinfo', interp='trilinear'),
                 name='flirt')
    flirt.inputs.dof = 7
    #
    # Anat > Standard
    # register high-resolution to standard template - ###flirt## (as preparation for fnirt)
    flirt_prep = Node(fsl.FLIRT(cost_func='mutualinfo', interp='trilinear'),
                      name='flirt_prep')
    flirt_prep.inputs.reference = standard_brain
    flirt_prep.inputs.interp = 'trilinear'
    flirt_prep.inputs.dof = 12

    fnirt = Node(fsl.FNIRT(), name='fnirt')
    fnirt.inputs.ref_file = standard_brain
    fnirt.inputs.field_file = True
    fnirt.inputs.fieldcoeff_file = True

    aroma_prep.connect([
        (reorient2std, flirt, [('out_file', 'reference')]),
        (betfunctional, flirt, [('out_file', 'in_file')]),
        (reorient2std, flirt_prep, [('out_file', 'in_file')]),
        (flirt_prep, fnirt, [('out_matrix_file', 'affine_file')]),
        (reorient2std, fnirt, [('out_file', 'in_file')]),
    ])

    ##################ICA-AROMA###############################################
    #Step 1) MELODIC
    runICA = Node(
        name="runICA",
        interface=Function(input_names=[
            "fslDir", "outDir", "inFile", "melDirIn", "mask", "dim", "TR"
        ],
                           output_names=["mdir", 'melICmix', 'melodic_FTmix'],
                           function=aromafunc.runICA))
    runICA.inputs.fslDir = os.path.join(os.environ["FSLDIR"], 'bin', '')
    runICA.inputs.dim = 0  #automatically estimates network number using MDL
    runICA.inputs.TR = 2.0
    runICA.inputs.melDirIn = ""
    runICA.inputs.outDir = out_dir

    #Step 2) Automatic classification of the components
    #  - registering the spatial maps to MNI
    regMNI = Node(name="regMNI",
                  interface=Function(input_names=[
                      "fslDir", "inFile", "outFile", "affmat", "warp"
                  ],
                                     output_names=['melodic_IC_MNI2mm'],
                                     function=aromafunc.register2MNI))

    regMNI.inputs.fslDir = os.path.join(os.environ["FSLDIR"], 'bin', '')
    regMNI.inputs.outFile = out_dir + 'melodic.ica/melodic_IC_thr_MNI2mm.nii.gz'

    #connect inputs to Melodic-ICA
    aroma_prep.connect([
        (binmask, runICA, [('out_file', 'mask')]),
        (smoothing, runICA, [('outputnode.ts_smoothed', 'inFile')]),
        #connect inputs to registration node
        (runICA, regMNI, [('mdir', 'inFile')]),
        (flirt, regMNI, [('out_matrix_file', 'affmat')]),
        (fnirt, regMNI, [('fieldcoeff_file', 'warp')])
    ])

    #extracting the Maximum RP correlation feature
    feature_time_series = Node(name="feature_time_series",
                               interface=Function(
                                   input_names=["melmix", "mc"],
                                   output_names=["maxRPcorr"],
                                   function=aromafunc.feature_time_series))

    save_featts = Node(name="save_featts",
                       interface=Function(input_names=["filename", "in_data"],
                                          output_names=["filename"],
                                          function=small_save))

    save_featts.inputs.filename = working_dir + '/aroma_prep/save_featts/maxRPcorr.npy'

    aroma_prep.connect([(runICA, feature_time_series, [('melICmix', 'melmix')])
                        ])

    #connect moco to time_series features
    aroma_prep.connect([
        (moco, feature_time_series, [('outputnode.par_moco', 'mc')]),
        (feature_time_series, save_featts, [("maxRPcorr", "in_data")])
    ])

    #extracting the High-frequency content feature
    feature_freq = Node(name="feature_freq",
                        interface=Function(
                            input_names=["melFTmix", "TR"],
                            output_names=["HFC"],
                            function=aromafunc.feature_frequency))
    feature_freq.inputs.TR = 2.0

    save_featfreq = Node(name="save_featfreq",
                         interface=Function(
                             input_names=["filename", "in_data"],
                             output_names=["filename"],
                             function=small_save))
    save_featfreq.inputs.filename = working_dir + '/aroma_prep/feature_freq/HFC.npy'

    aroma_prep.connect([(runICA, feature_freq, [('melodic_FTmix', 'melFTmix')
                                                ]),
                        (feature_freq, save_featfreq, [('HFC', 'in_data')])])

    #extracting the CSF & Edge fraction features
    feature_spatial = Node(
        name="feature_spatial",
        interface=Function(
            input_names=["fslDir", "tempDir", "aromaDir", "melIC"],
            output_names=["edgeFract", "csfFract"],
            function=aromafunc.feature_spatial))

    feature_spatial.inputs.fslDir = os.path.join(os.environ["FSLDIR"], 'bin',
                                                 '')
    feature_spatial.inputs.tempDir = working_dir + "/aroma_prep/feature_spatial/"
    feature_spatial.inputs.aromaDir = "/home/raid1/fbeyer/Documents/Scripts/ICA-AROMA/"

    save_featsp_edge = Node(name="save_featsp_edge",
                            interface=Function(
                                input_names=["filename", "in_data"],
                                output_names=["filename"],
                                function=small_save))
    save_featsp_edge.inputs.filename = working_dir + '/aroma_prep/feature_spatial/edge.npy'

    save_featsp_csf = Node(name="save_featsp_csf",
                           interface=Function(
                               input_names=["filename", "in_data"],
                               output_names=["filename"],
                               function=small_save))
    save_featsp_csf.inputs.filename = working_dir + '/aroma_prep/feature_spatial/csf.npy'

    aroma_prep.connect([
        (regMNI, feature_spatial, [('melodic_IC_MNI2mm', 'melIC')]),
        (feature_spatial, save_featsp_edge, [('edgeFract', 'in_data')]),
        (feature_spatial, save_featsp_csf, [('csfFract', 'in_data')])
    ])

    #classification of features using predefined feature space
    classification = Node(
        name="classification",
        interface=Function(input_names=[
            "outDir", "maxRPcorr", "edgeFract", "HFC", "csfFract"
        ],
                           output_names=["motionICs"],
                           function=aromafunc.classification))
    classification.inputs.outDir = out_dir + '/melodic.ica/'

    save_class_mic = Node(name="save_class_mic",
                          interface=Function(
                              input_names=["filename", "in_data"],
                              output_names=["filename"],
                              function=small_save))
    save_class_mic.inputs.filename = working_dir + '/aroma_prep/classification/motionICs.npy'

    aroma_prep.connect([(classification, save_class_mic, [('motionICs',
                                                           'in_data')])])

    #connections of classification with all features
    aroma_prep.connect([
        (feature_time_series, classification, [('maxRPcorr', 'maxRPcorr')]),
        (feature_spatial, classification, [('edgeFract', 'edgeFract')]),
        (feature_spatial, classification, [('csfFract', 'csfFract')]),
        (feature_freq, classification, [('HFC', 'HFC')])
    ])

    #Step 3) Data denoising' (using input data (=intensity normalized, motion corrected, smoothed fMRI in subject space))
    denoising_ICA = Node(name="denoising_ICA",
                         interface=Function(input_names=[
                             "fslDir", "inFile", "outDir", "melmix", "denType",
                             "denIdx"
                         ],
                                            output_names=["denoised_func"],
                                            function=aromafunc.denoising))
    denoising_ICA.inputs.fslDir = os.path.join(os.environ["FSLDIR"], 'bin', '')
    denoising_ICA.inputs.outDir = out_dir
    denoising_ICA.inputs.melmix = out_dir + '/melodic.ica/melodic_mix'
    denoising_ICA.inputs.denType = 2  #1=aggr, 2=non-aggr, 3=both

    aroma_prep.connect([
        (classification, denoising_ICA, [('motionICs', 'denIdx')]),
        (smoothing, denoising_ICA, [('outputnode.ts_smoothed', 'inFile')])
    ])

    ##################post-processing###########################################
    #WM/CSF/linear trend removal using regression of compcor-components
    #highpass-filtering here!!
    #registration of denoised image to MNI space
    postprocess = create_denoise_pipeline()
    postprocess.inputs.inputnode.highpass_sigma = 1. / (2 * TR * highpass)
    # https://www.jiscmail.ac.uk/cgi-bin/webadmin?A2=ind1205&L=FSL&P=R57592&1=FSL&9=A&I=-3&J=on&d=No+Match%3BMatch%3BMatches&z=4
    postprocess.inputs.inputnode.tr = TR

    aroma_prep.connect([
        (binmask, postprocess, [('out_file', 'inputnode.brain_mask')]),
        (denoising_ICA, postprocess, [('denoised_func', 'inputnode.epi_coreg')
                                      ]),
        (moco, postprocess, [('outputnode.epi_mean', 'inputnode.unwarped_mean')
                             ]),
        (flirt, postprocess, [('out_matrix_file', 'inputnode.flirt_mat')]),
        (reorient2std, postprocess, [('out_file', 'inputnode.anat_brain')])
    ])

    #register only-AROMA denoised file	into MNI space (without CSF/WM removal + highpass-filtering)
    apply_TF = Node(fsl.ApplyWarp(), name="apply_TF")
    apply_TF.inputs.ref_file = standard_brain

    #register AROMA and CSF/WM denoised file	into MNI space
    apply_TF_denoised = Node(fsl.ApplyWarp(), name="apply_TF_denoised")
    apply_TF_denoised.inputs.ref_file = standard_brain

    aroma_prep.connect([
        (postprocess, apply_TF_denoised, [
            ('outputnode.normalized_file', 'in_file')
        ]),  #with bandpass-filtering
        (flirt, apply_TF_denoised, [('out_matrix_file', 'premat')]),
        (fnirt, apply_TF_denoised, [('fieldcoeff_file', 'field_file')]),
        (denoising_ICA, apply_TF, [('denoised_func', 'in_file')]),
        (flirt, apply_TF, [('out_matrix_file', 'premat')]),
        (fnirt, apply_TF, [('fieldcoeff_file', 'field_file')]),
    ])

    #sink to store files
    sink = Node(nio.DataSink(
        parameterization=False,
        base_directory=out_dir,
        substitutions=[
            ('brain_reoriented_warped.nii', 'brain2mni_warp_fnirt.nii'),
            ('brain_reoriented_flirt.nii', 'brain2mni_aff_flirt.nii'),
            ('brain_reoriented_fieldwarp.nii', 'brain2mni_warpcoeff_cout.nii'),
            ('brain_reoriented_field.nii', 'brain2mni_warpfield_fout.nii'),
            ('rest2anat_maths_smooth', 'func_preproc_smoothed'),
            ('rest_mean2fmap_unwarped_brain_maths', 'func_brain_mask'),
            ('denoised_func_data_nonaggr_warp', 'aroma_denoised_MNI'),
            ('rest_denoised_highpassed_norm_warp.nii',
             'aroma_csfwm_denoised_MNI.nii'),
            ('rest2anat_denoised', 'rest_denoised_fullspectrum'),
            ('rest_denoised_highpassed_norm', 'rest_denoised_highpass'),
            ('wmcsf_mask_lowres_flirt', 'wmcsf_mask2epi'),
            ('brain2mni_aff_flirt', 'brain2epi')
        ]),
                name='sink')

    ##all the output
    aroma_prep.connect([
        (moco, sink, [('outputnode.epi_moco', 'realign.@realigned_ts'),
                      ('outputnode.par_moco', 'realign.@par'),
                      ('outputnode.rms_moco', 'realign.@rms'),
                      ('outputnode.mat_moco', 'realign.MAT.@mat'),
                      ('outputnode.epi_mean', 'realign.@mean'),
                      ('outputnode.rotplot', 'realign.plots.@rotplot'),
                      ('outputnode.transplot', 'realign.plots.@transplot'),
                      ('outputnode.dispplots', 'realign.plots.@dispplots'),
                      ('outputnode.tsnr_file', 'realign.@tsnr')]),
        (fmap_coreg, sink,
         [('outputnode.fmap', 'fmap.transforms2anat.@fmap'),
          ('outputnode.unwarped_mean_epi2fmap',
           'fmap.@unwarped_mean_epi2fmap'),
          ('outputnode.epi2fmap', 'fmap.@epi2fmap'),
          ('outputnode.unwarpfield_epi2fmap', 'fmap.@fmap_fullwarp'),
          ('outputnode.mean_from_unwarped_epi', 'fmap.@mean_from_unwarped')]),
        (binmask, sink, [('out_file', 'aroma_inputs.@brainmask')]),
        (smoothing, sink, [('outputnode.ts_smoothed', 'aroma_inputs.@FWHM6')]),
        (flirt, sink, [('out_file', 'aroma_inputs.reg.affine.@result')]),
        (flirt, sink, [('out_matrix_file', 'aroma_inputs.reg.affine.@matrix')
                       ]),
        (fnirt, sink, [('warped_file', 'aroma_inputs.reg.fnirt.@image')]),
        (fnirt, sink, [('fieldcoeff_file',
                        'aroma_inputs.reg.fnirt.@fieldcoeff')]),
        (fnirt, sink, [('field_file', 'aroma_inputs.reg.fnirt.@field')]),
        (flirt_prep, sink, [('out_matrix_file', 'aroma_inputs.reg.fnirt.@mat')
                            ]),
        (flirt_prep, sink, [('out_file', 'aroma_inputs.reg.fnirt.@resultflirt')
                            ]),
        (save_featts, sink, [('filename', 'aroma_res.features.@rescorr')]),
        (save_featsp_edge, sink, [('filename', 'aroma_res.features.@edge')]),
        (save_featsp_csf, sink, [('filename', 'aroma_res.features.@csf')]),
        (save_featfreq, sink, [('filename', 'aroma_res.features.@HFC')]),
        (denoising_ICA, sink, [('denoised_func', 'aroma_res.@denoised_func')]),
        (
            postprocess,
            sink,
            [
                ('outputnode.wmcsf_mask', 'denoise.mask.@wmcsf_masks'),
                ('outputnode.combined_motion',
                 'denoise.artefact.@combined_motion'),
                ('outputnode.comp_regressor',
                 'denoise.regress.@comp_regressor'),
                ('outputnode.comp_F', 'denoise.regress.@comp_F'),
                ('outputnode.comp_pF', 'denoise.regress.@comp_pF'),
                ('outputnode.brain2epi', 'denoise.mask.@brain2epi'),
                ('outputnode.wmcsf_mask2epi', 'denoise.mask.@wmcsf_mask2epi'),
                ('outputnode.normalized_file', 'denoise.@normalized'),
                # FL added fullspectrum
                ('outputnode.ts_fullspectrum', 'denoise.@ts_fullspectrum')
            ]),
        (apply_TF, sink, [
            ('out_file', 'transforms.withoutCSFWM.@denoised_result_MNI')
        ]),  #with only motion
        (apply_TF_denoised, sink, [
            ('out_file', 'transforms.withCSFWM.@denoised_result_MNI')
        ])  #with motion, compcor CSF/WM + highpass
    ])

    aroma_prep.write_graph(dotfilename='aroma_prep.dot',
                           graph2use='colored',
                           format='pdf',
                           simple_form=True)
    aroma_prep.run(
        plugin='MultiProc'
    )  #plugin='CondorDAGMan', plugin_args={'initial_specs': 'request_memory = 1500'}
Example #11
0
def create_resting(subject, working_dir, data_dir, freesurfer_dir, out_dir,
                         vol_to_remove, TR, epi_resolution, highpass, lowpass,
                         echo_space, pe_dir, standard_brain, standard_brain_resampled, standard_brain_mask,
                         standard_brain_mask_resampled, fwhm_smoothing):
    # set fsl output type to nii.gz
    fsl.FSLCommand.set_default_output_type('NIFTI_GZ')
    # main workflow
    func_preproc = Workflow(name='lemon_resting')
    func_preproc.base_dir = working_dir
    func_preproc.config['execution']['crashdump_dir'] = func_preproc.base_dir + "/crash_files"
    # select files
    templates = {'func': 'raw/{subject}/func/EPI_t2.nii',
                 'ap': 'raw/{subject}/topup/se.nii',
                 'pa': 'raw/{subject}/topup/seinv_ph.nii',
                 'anat_head': 'preprocessing/preprocessed/{subject}/structural/T1.nii.gz',  
                 'anat_brain': 'preprocessing/preprocessed/{subject}/structural/brain.nii.gz',
                 'brain_mask': 'preprocessing/preprocessed/{subject}/structural/T1_brain_mask.nii.gz',  
                 'ants_affine': 'preprocessing/preprocessed/{subject}/structural/transforms2mni/transform0GenericAffine.mat',
                 'ants_warp': 'preprocessing/preprocessed/{subject}/structural/transforms2mni/transform1Warp.nii.gz'
                 }

    selectfiles = Node(nio.SelectFiles(templates,
                                       base_directory=data_dir),
                       name="selectfiles")
    selectfiles.inputs.subject = subject


    # node to remove first volumes
    remove_vol = Node(util.Function(input_names=['in_file', 't_min'],
                                    output_names=["out_file"],
                                    function=strip_rois_func),
                      name='remove_vol')
    remove_vol.inputs.t_min = vol_to_remove
    # workflow for motion correction
    moco = create_moco_pipeline()

    # workflow for fieldmap correction and coregistration
    topup_coreg = create_topup_coreg_pipeline()
    topup_coreg.inputs.inputnode.fs_subjects_dir = freesurfer_dir
    topup_coreg.inputs.inputnode.fs_subject_id = subject
    topup_coreg.inputs.inputnode.echo_space = echo_space
    topup_coreg.inputs.inputnode.pe_dir = pe_dir

    # workflow for applying transformations to timeseries
    transform_ts = create_transform_pipeline()
    transform_ts.inputs.inputnode.resolution = epi_resolution


    # workflow to denoise timeseries
    denoise = create_denoise_pipeline()
    denoise.inputs.inputnode.highpass_sigma = 1. / (2 * TR * highpass)
    denoise.inputs.inputnode.lowpass_sigma = 1. / (2 * TR * lowpass)
    # https://www.jiscmail.ac.uk/cgi-bin/webadmin?A2=ind1205&L=FSL&P=R57592&1=FSL&9=A&I=-3&J=on&d=No+Match%3BMatch%3BMatches&z=4
    denoise.inputs.inputnode.tr = TR

    # workflow to transform timeseries to MNI
    ants_registration = create_ants_registration_pipeline()
    ants_registration.inputs.inputnode.ref = standard_brain
    ants_registration.inputs.inputnode.tr_sec = TR

    # FL added fullspectrum
    # workflow to transform fullspectrum timeseries to MNI
    ants_registration_full = create_ants_registration_pipeline('ants_registration_full')
    ants_registration_full.inputs.inputnode.ref = standard_brain
    ants_registration_full.inputs.inputnode.tr_sec = TR

    # workflow to smooth
    smoothing = create_smoothing_pipeline()
    smoothing.inputs.inputnode.fwhm = fwhm_smoothing

    # visualize registration results
    visualize = create_visualize_pipeline()
    visualize.inputs.inputnode.mni_template = standard_brain



    # sink to store files
    sink = Node(nio.DataSink(parameterization=False,
                             base_directory=out_dir,
                             substitutions=[('fmap_phase_fslprepared', 'fieldmap'),
                                            ('fieldmap_fslprepared_fieldmap_unmasked_vsm', 'shiftmap'),
                                            ('plot.rest_coregistered', 'outlier_plot'),
                                            ('filter_motion_comp_norm_compcor_art_dmotion', 'nuissance_matrix'),
                                            ('rest_realigned.nii.gz_abs.rms', 'rest_realigned_abs.rms'),
                                            ('rest_realigned.nii.gz.par', 'rest_realigned.par'),
                                            ('rest_realigned.nii.gz_rel.rms', 'rest_realigned_rel.rms'),
                                            ('rest_realigned.nii.gz_abs_disp', 'abs_displacement_plot'),
                                            ('rest_realigned.nii.gz_rel_disp', 'rel_displacment_plot'),
                                            ('art.rest_coregistered_outliers', 'outliers'),
                                            ('global_intensity.rest_coregistered', 'global_intensity'),
                                            ('norm.rest_coregistered', 'composite_norm'),
                                            ('stats.rest_coregistered', 'stats'),
                                            ('rest_denoised_bandpassed_norm.nii.gz',
                                             'rest_preprocessed_nativespace.nii.gz'),
                                            ('rest_denoised_bandpassed_norm_trans.nii.gz',
                                             'rest_mni_unsmoothed.nii.gz'),
                                            ('rest_denoised_bandpassed_norm_trans_smooth.nii',
                                             'rest_mni_smoothed.nii'),
                                            # FL added
                                            ('rest2anat_masked.nii.gz', 'rest_coregistered_nativespace.nii.gz'),
                                            ('rest2anat_denoised.nii.gz',
                                             'rest_preprocessed_nativespace_fullspectrum.nii.gz'),
                                            ('rest2anat_denoised_trans.nii.gz',
                                             'rest_mni_unsmoothed_fullspectrum.nii.gz')
                                            ]),
                name='sink')


    # connections
    func_preproc.connect([
        # remove the first volumes
        (selectfiles, remove_vol, [('func', 'in_file')]),

        # align volumes and motion correction
        (remove_vol, moco, [('out_file', 'inputnode.epi')]),

        # prepare field map
        (selectfiles, topup_coreg, [('ap', 'inputnode.ap'),
                                   ('pa', 'inputnode.pa'),
                                   ('anat_head', 'inputnode.anat_head'),
                                   ('anat_brain', 'inputnode.anat_brain')
                                   ]),
        (moco, topup_coreg, [('outputnode.epi_mean', 'inputnode.epi_mean')]),

        # transform timeseries
        (remove_vol, transform_ts, [('out_file', 'inputnode.orig_ts')]),
        (selectfiles, transform_ts, [('anat_head', 'inputnode.anat_head')]),
        (selectfiles, transform_ts, [('brain_mask', 'inputnode.brain_mask')]),
        (moco, transform_ts, [('outputnode.mat_moco', 'inputnode.mat_moco')]),
        (topup_coreg, transform_ts, [('outputnode.fmap_fullwarp', 'inputnode.fullwarp')]),

        # correct slicetiming
        # FIXME slice timing?
        # (transform_ts, slicetiming, [('outputnode.trans_ts_masked', 'inputnode.ts')]),
        # (slicetiming, denoise, [('outputnode.ts_slicetcorrected', 'inputnode.epi_coreg')]),
        (transform_ts, denoise, [('outputnode.trans_ts_masked', 'inputnode.epi_coreg')]),

        # denoise data
        (selectfiles, denoise, [('brain_mask', 'inputnode.brain_mask'),
                                ('anat_brain', 'inputnode.anat_brain')]),
        (moco, denoise, [('outputnode.par_moco', 'inputnode.moco_par')]),
        (topup_coreg, denoise, [('outputnode.epi2anat_dat', 'inputnode.epi2anat_dat'),
                               ('outputnode.unwarped_mean_epi2fmap', 'inputnode.unwarped_mean')]),
        (denoise, ants_registration, [('outputnode.normalized_file', 'inputnode.denoised_ts')]),

        # registration to MNI space
        (selectfiles, ants_registration, [('ants_affine', 'inputnode.ants_affine')]),
        (selectfiles, ants_registration, [('ants_warp', 'inputnode.ants_warp')]),

        # FL added fullspectrum
        (denoise, ants_registration_full, [('outputnode.ts_fullspectrum', 'inputnode.denoised_ts')]),
        (selectfiles, ants_registration_full, [('ants_affine', 'inputnode.ants_affine')]),
        (selectfiles, ants_registration_full, [('ants_warp', 'inputnode.ants_warp')]),

        (ants_registration, smoothing, [('outputnode.ants_reg_ts', 'inputnode.ts_transformed')]),

        (smoothing, visualize, [('outputnode.ts_smoothed', 'inputnode.ts_transformed')]),

        ##all the output
        (moco, sink, [  # ('outputnode.epi_moco', 'realign.@realigned_ts'),
                        ('outputnode.par_moco', 'realign.@par'),
                        ('outputnode.rms_moco', 'realign.@rms'),
                        ('outputnode.mat_moco', 'realign.MAT.@mat'),
                        ('outputnode.epi_mean', 'realign.@mean'),
                        ('outputnode.rotplot', 'realign.plots.@rotplot'),
                        ('outputnode.transplot', 'realign.plots.@transplot'),
                        ('outputnode.dispplots', 'realign.plots.@dispplots'),
                        ('outputnode.tsnr_file', 'realign.@tsnr')]),
        (topup_coreg, sink, [('outputnode.fmap', 'coregister.transforms2anat.@fmap'),
                            # ('outputnode.unwarpfield_epi2fmap', 'coregister.@unwarpfield_epi2fmap'),
                            ('outputnode.unwarped_mean_epi2fmap', 'coregister.@unwarped_mean_epi2fmap'),
                            ('outputnode.epi2fmap', 'coregister.@epi2fmap'),
                            # ('outputnode.shiftmap', 'coregister.@shiftmap'),
                            ('outputnode.fmap_fullwarp', 'coregister.transforms2anat.@fmap_fullwarp'),
                            ('outputnode.epi2anat', 'coregister.@epi2anat'),
                            ('outputnode.epi2anat_mat', 'coregister.transforms2anat.@epi2anat_mat'),
                            ('outputnode.epi2anat_dat', 'coregister.transforms2anat.@epi2anat_dat'),
                            ('outputnode.epi2anat_mincost', 'coregister.@epi2anat_mincost')
                            ]),

        (transform_ts, sink, [('outputnode.trans_ts_masked', 'coregister.@full_transform_ts'),
                              ('outputnode.trans_ts_mean', 'coregister.@full_transform_mean'),
                              ('outputnode.resamp_brain', 'coregister.@resamp_brain')]),

        (denoise, sink, [
            ('outputnode.wmcsf_mask', 'denoise.mask.@wmcsf_masks'),
            ('outputnode.combined_motion', 'denoise.artefact.@combined_motion'),
            ('outputnode.outlier_files', 'denoise.artefact.@outlier'),
            ('outputnode.intensity_files', 'denoise.artefact.@intensity'),
            ('outputnode.outlier_stats', 'denoise.artefact.@outlierstats'),
            ('outputnode.outlier_plots', 'denoise.artefact.@outlierplots'),
            ('outputnode.mc_regressor', 'denoise.regress.@mc_regressor'),
            ('outputnode.comp_regressor', 'denoise.regress.@comp_regressor'),
            ('outputnode.mc_F', 'denoise.regress.@mc_F'),
            ('outputnode.mc_pF', 'denoise.regress.@mc_pF'),
            ('outputnode.comp_F', 'denoise.regress.@comp_F'),
            ('outputnode.comp_pF', 'denoise.regress.@comp_pF'),
            ('outputnode.brain_mask_resamp', 'denoise.mask.@brain_resamp'),
            ('outputnode.brain_mask2epi', 'denoise.mask.@brain_mask2epi'),
            ('outputnode.normalized_file', 'denoise.@normalized'),
            # FL added fullspectrum
            ('outputnode.ts_fullspectrum', 'denoise.@ts_fullspectrum')
        ]),
        (ants_registration, sink, [('outputnode.ants_reg_ts', 'ants.@antsnormalized')]),
        (ants_registration_full, sink, [('outputnode.ants_reg_ts', 'ants.@antsnormalized_fullspectrum')]),
        (smoothing, sink, [('outputnode.ts_smoothed', '@smoothed.FWHM6')]),
    ])

    func_preproc.write_graph(dotfilename='func_preproc.dot', graph2use='colored', format='pdf', simple_form=True)
    func_preproc.run(plugin='MultiProc')