Пример #1
0
def create_prep(name='preproc'):
    """ Base preprocessing workflow for task and resting state fMRI
    
    Parameters
    ----------
    name : name of workflow. Default = 'preproc'
    
    Inputs
    ------
    inputspec.fssubject_id : 
    inputspec.fssubject_dir :
    inputspec.func :
    inputspec.highpass :
    inputspec.num_noise_components :
    inputspec.ad_normthresh :
    inputspec.ad_zthresh :
    inputspec.tr :
    inputspec.interleaved :
    inputspec.sliceorder :
    inputspec.compcor_select :
    inputspec.highpass_sigma :
    inputspec.lowpass_sigma :
    inputspec.reg_params :
    inputspec.FM_TEdiff :
    inputspec.FM_Echo_spacing :
    inputspec.FM_sigma :
    
    Outputs
    -------
    outputspec.reference : 
    outputspec.motion_parameters : 
    outputspec.realigned_files :
    outputspec.mask :
    outputspec.smoothed_files :
    outputspec.highpassed_files :
    outputspec.mean :
    outputspec.combined_motion :
    outputspec.outlier_files :
    outputspec.mask :
    outputspec.reg_cost :
    outputspec.reg_file :
    outputspec.noise_components :
    outputspec.tsnr_file :
    outputspec.stddev_file :
    outputspec.filter_file :
    outputspec.scaled_files :
    outputspec.z_img :
    outputspec.motion_plots :
    outputspec.FM_unwarped_mean :
    outputspec.FM_unwarped_epi :
    
    Returns
    -------
    workflow : preprocessing workflow
    """

    import nipype.interfaces.fsl as fsl         # fsl
    import nipype.algorithms.rapidart as ra     # rapid artifact detection
    from nipype.workflows.smri.freesurfer.utils import create_getmask_flow
    from modular_nodes import create_mod_smooth, mod_realign, mod_despike
    import nipype.pipeline.engine as pe
    import nipype.interfaces.utility as util

    preproc = pe.Workflow(name=name)

    # Compcorr node
    compcor = create_compcorr()

    # Input node
    inputnode = pe.Node(util.IdentityInterface(fields=['fssubject_id',
                                                      'fssubject_dir',
                                                      'func',
                                                      'highpass',
                                                      'num_noise_components',
                                                      'ad_normthresh',
                                                      'ad_zthresh',
                                                      'tr',
                                                      'do_slicetime',
                                                      'sliceorder',
                                                      'compcor_select',
                                                      'highpass_freq',
                                                      'lowpass_freq',
                                                      'reg_params',
                                                      'FM_TEdiff',
                                                      'FM_Echo_spacing',
                                                      'FM_sigma',
                                                      'motion_correct_node',
                                                      'smooth_type',
                                                      'surface_fwhm',
                                                      'filter_type',
                                                      'timepoints_to_remove',
                                                      'do_whitening',
                                                      'regress_before_PCA',
                                                      'realign_parameters',
                                                      'do_despike',
                                                      'anatomical']),
                        name='inputspec')

    # Separate input node for FWHM
    inputnode_fwhm = pe.Node(util.IdentityInterface(fields=['fwhm']),
                             name='fwhm_input')

    # strip ids
    strip_rois = pe.MapNode(fsl.ExtractROI(),name='extractroi',iterfield='in_file')
    strip_rois.inputs.t_size = -1
    preproc.connect(inputnode,'timepoints_to_remove',strip_rois,'t_min')

    # convert BOLD images to float
    img2float = pe.MapNode(interface=fsl.ImageMaths(out_data_type='float',
                                                    op_string='',
                                                    suffix='_dtype'),
                           iterfield=['in_file'],
                           name='img2float')

    #afni despike
    despike=pe.MapNode(util.Function(input_names=['in_file',"do_despike"],
                                     output_names=["out_file"],
                                     function=mod_despike),
        name="despike",iterfield=["in_file"])
    preproc.connect(inputnode,"do_despike",despike,"do_despike")
    # define the motion correction node
    #motion_correct = pe.Node(interface=FmriRealign4d(),
    #                            name='realign')

    motion_correct = pe.Node(util.Function(input_names=['node','in_file','tr',
                                                        'do_slicetime','sliceorder',"parameters"],
        output_names=['out_file','par_file','parameter_source'],
        function=mod_realign),
        name="mod_realign")

    preproc.connect(inputnode,'motion_correct_node',
                    motion_correct, 'node')

    # construct motion plots
    #plot_motion = pe.MapNode(interface=fsl.PlotMotionParams(in_source='fsl'),
    #                         name='plot_motion',
    #                         iterfield=['in_file'])

    # rapidArt for artifactual timepoint detection
    ad = pe.Node(ra.ArtifactDetect(save_plot=False),
                 name='artifactdetect')

    # extract the mean volume if the first functional run
    meanfunc = art_mean_workflow()

    # generate a freesurfer workflow that will return the mask
    getmask = create_getmask_flow()

    # create a SUSAN smoothing workflow, and smooth each run with
    # 75% of the median value for each run as the brightness
    # threshold.
    smooth = create_mod_smooth(name="modular_smooth",
                                 separate_masks=False)
    preproc.connect(inputnode,'smooth_type', smooth,'inputnode.smooth_type')
    # choose susan function
    """
    The following node selects smooth or unsmoothed data
    depending on the fwhm. This is because SUSAN defaults
    to smoothing the data with about the voxel size of
    the input data if the fwhm parameter is less than 1/3 of
    the voxel size.
    """
    choosesusan = pe.Node(util.Function(input_names=['fwhm',
                                                       'motion_files',
                                                       'smoothed_files'],
                                        output_names=['cor_smoothed_files'],
                                        function=choose_susan),
                          name='select_smooth')

    # scale the median value of each run to 10,000
    meanscale = pe.MapNode(interface=fsl.ImageMaths(suffix='_gms'),
                           iterfield=['in_file',
                                      'op_string'],
                           name='scale_median')

    # determine the median value of the MASKED functional runs
    medianval = pe.MapNode(interface=fsl.ImageStats(op_string='-k %s -p 50'),
                           iterfield=['in_file'],
                           name='compute_median_val')

    # temporal highpass filtering
    highpass = pe.MapNode(interface=fsl.ImageMaths(suffix='_tempfilt'),
                          iterfield=['in_file'],
                          name='highpass')

    # Calculate the z-score of output
    zscore = pe.MapNode(interface=util.Function(input_names=['image','outliers'],
                                             output_names=['z_img'],
                                             function=z_image),
                        name='z_score',
                        iterfield=['image','outliers'])

    # declare some node inputs...
    #plot_motion.iterables = ('plot_type', ['rotations', 'translations'])

    #ad.inputs.parameter_source = 'FSL'
    meanfunc.inputs.inputspec.parameter_source = 'FSL'
    ad.inputs.mask_type = 'file'
    ad.inputs.use_differences = [True, False]
    getmask.inputs.inputspec.contrast_type = 't2'
    getmask.inputs.register.out_fsl_file = True
    fssource = getmask.get_node('fssource')

    # make connections...
    preproc.connect(inputnode, 'fssubject_id',
                    getmask, 'inputspec.subject_id')
    preproc.connect(inputnode, 'ad_normthresh',
                    ad, 'norm_threshold')
    preproc.connect(inputnode, 'ad_zthresh',
                    ad, 'zintensity_threshold')
    preproc.connect(inputnode, 'tr',
                    motion_correct, 'tr')
    preproc.connect(inputnode, 'realign_parameters',
        motion_correct, 'parameters')
    preproc.connect(motion_correct,'parameter_source',
        ad,'parameter_source')
    preproc.connect(inputnode, 'do_slicetime',
                    motion_correct, 'do_slicetime')
    preproc.connect(inputnode, 'sliceorder',
                    motion_correct, 'sliceorder')
    preproc.connect(inputnode, 'compcor_select',
                    compcor, 'inputspec.selector')
    preproc.connect(inputnode, 'fssubject_dir',
                    getmask, 'inputspec.subjects_dir')

    #preproc.connect(inputnode, 'func',
    #                img2float, 'in_file')
    preproc.connect(inputnode, 'func', strip_rois, 'in_file')
    preproc.connect(strip_rois, 'roi_file', img2float, 'in_file')

    preproc.connect(img2float, 'out_file', despike, "in_file")
    preproc.connect(despike,"out_file", motion_correct, 'in_file')
    #preproc.connect(motion_correct, 'par_file',
    #                plot_motion, 'in_file')
    preproc.connect(motion_correct, 'out_file', 
                    meanfunc, 'inputspec.realigned_files')
    preproc.connect(motion_correct, 'par_file',
                    meanfunc, 'inputspec.realignment_parameters')
    preproc.connect(meanfunc, 'outputspec.mean_image',
                    getmask, 'inputspec.source_file')
    preproc.connect(inputnode, 'num_noise_components',
                    compcor, 'inputspec.num_components')
    preproc.connect(inputnode, 'regress_before_PCA',
                    compcor, 'inputspec.regress_before_PCA')
    preproc.connect(motion_correct, 'out_file',
                    compcor, 'inputspec.realigned_file')
    preproc.connect(meanfunc, 'outputspec.mean_image',
                    compcor, 'inputspec.mean_file')
    preproc.connect(fssource, 'aseg',
                    compcor, 'inputspec.fsaseg_file')
    preproc.connect(getmask, ('outputspec.reg_file', pickfirst),
                    compcor, 'inputspec.reg_file')
    preproc.connect(ad, 'outlier_files',
                    compcor, 'inputspec.outlier_files')
    preproc.connect(motion_correct, 'par_file',
                    compcor, 'inputspec.realignment_parameters')
    preproc.connect(motion_correct, 'out_file',
                    ad, 'realigned_files')
    preproc.connect(motion_correct, 'par_file',
                    ad, 'realignment_parameters')
    preproc.connect(getmask, ('outputspec.mask_file', pickfirst),
                    ad, 'mask_file')
    preproc.connect(getmask, ('outputspec.mask_file', pickfirst),
                    medianval, 'mask_file')
    preproc.connect(inputnode_fwhm, 'fwhm',
                    smooth, 'inputnode.fwhm')
    preproc.connect(motion_correct, 'out_file',
                    smooth, 'inputnode.in_files')
    preproc.connect(getmask, ('outputspec.mask_file',pickfirst),
                    smooth, 'inputnode.mask_file')
    preproc.connect(getmask, ('outputspec.reg_file', pickfirst),
                    smooth, 'inputnode.reg_file')
    preproc.connect(inputnode,'surface_fwhm',
                    smooth, 'inputnode.surface_fwhm')
    preproc.connect(inputnode, 'fssubject_dir',
                    smooth, 'inputnode.surf_dir')
    preproc.connect(smooth, 'outputnode.smoothed_files',
                    choosesusan, 'smoothed_files')
    preproc.connect(motion_correct, 'out_file',
                    choosesusan, 'motion_files')
    preproc.connect(inputnode_fwhm, 'fwhm',
                    choosesusan, 'fwhm')
    preproc.connect(choosesusan, 'cor_smoothed_files',
                    meanscale, 'in_file')
    preproc.connect(choosesusan, 'cor_smoothed_files',
                    medianval, 'in_file')
    preproc.connect(medianval, ('out_stat', getmeanscale),
                    meanscale, 'op_string')
    preproc.connect(inputnode, ('highpass', highpass_operand),
                    highpass, 'op_string')
    preproc.connect(meanscale, 'out_file',
                    highpass, 'in_file')
    preproc.connect(highpass, 'out_file',
                    zscore, 'image')
    preproc.connect(ad, 'outlier_files',
                    zscore, 'outliers')

    # create output node
    outputnode = pe.Node(interface=util.IdentityInterface(
        fields=['mean',
                'motion_parameters',
                'realigned_files',
                'smoothed_files',
                'highpassed_files',
                'combined_motion',
                'outlier_files',
                'outlier_stat_files',
                'mask',
                'reg_cost',
                'reg_file',
                'reg_fsl_file',
                'noise_components',
                'tsnr_file',
                'stddev_file',
                'tsnr_detrended',
                'filter_file',
                'scaled_files','unmasked_fullspectrum',
                'z_img',
                'motion_plots',
                'FM_unwarped_epi',
                'FM_unwarped_mean',
                'vsm_file',
                'bandpassed_file',
                'intensity_files',
                'noise_mask',
                'csf_mask']),
                        name='outputspec')

    # make output connection
    preproc.connect(meanfunc, 'outputspec.mean_image',
                    outputnode, 'mean')
    preproc.connect(motion_correct, 'par_file',
                    outputnode, 'motion_parameters')
    preproc.connect(motion_correct, 'out_file',
                    outputnode, 'realigned_files')
    preproc.connect(highpass, 'out_file',
                    outputnode, 'highpassed_files')
    preproc.connect(ad, 'norm_files',
                    outputnode, 'combined_motion')
    preproc.connect(ad, 'outlier_files',
                    outputnode, 'outlier_files')
    preproc.connect(ad, 'intensity_files',
                    outputnode, 'intensity_files')
    preproc.connect(ad, 'statistic_files',
                    outputnode, 'outlier_stat_files')
    preproc.connect(compcor, 'outputspec.noise_components',
                    outputnode, 'noise_components')
    preproc.connect(compcor, 'outputspec.noise_mask',
                    outputnode, 'noise_mask')
    preproc.connect(compcor, 'outputspec.csf_mask',
                    outputnode, 'csf_mask')
    preproc.connect(getmask, 'outputspec.mask_file',
                    outputnode, 'mask')
    preproc.connect(getmask, 'register.out_fsl_file',
                    outputnode, 'reg_fsl_file')                
    preproc.connect(getmask, 'outputspec.reg_file',
                    outputnode, 'reg_file')
    preproc.connect(getmask, 'outputspec.reg_cost',
                    outputnode, 'reg_cost')
    preproc.connect(choosesusan, 'cor_smoothed_files',
                    outputnode, 'smoothed_files')
    preproc.connect(compcor, 'outputspec.tsnr_file',
                    outputnode, 'tsnr_file')
    preproc.connect(compcor, 'outputspec.stddev_file',
                    outputnode, 'stddev_file')
    preproc.connect(compcor, 'outputspec.tsnr_detrended',
                    outputnode, 'tsnr_detrended')
    preproc.connect(zscore,'z_img',
                    outputnode,'z_img')
    #preproc.connect(plot_motion,'out_file',
    #                outputnode,'motion_plots')

                    

    return preproc
Пример #2
0
def create_prep(name='preproc'):
    """ Base preprocessing workflow for task and resting state fMRI
    
    Parameters
    ----------
    name : name of workflow. Default = 'preproc'
    
    Inputs
    ------
    inputspec.fssubject_id : 
    inputspec.fssubject_dir :
    inputspec.func :
    inputspec.highpass :
    inputspec.num_noise_components :
    inputspec.ad_normthresh :
    inputspec.ad_zthresh :
    inputspec.tr :
    inputspec.interleaved :
    inputspec.sliceorder :
    inputspec.compcor_select :
    inputspec.highpass_sigma :
    inputspec.lowpass_sigma :
    inputspec.reg_params :
    inputspec.FM_TEdiff :
    inputspec.FM_Echo_spacing :
    inputspec.FM_sigma :
    
    Outputs
    -------
    outputspec.reference : 
    outputspec.motion_parameters : 
    outputspec.realigned_files :
    outputspec.mask :
    outputspec.smoothed_files :
    outputspec.highpassed_files :
    outputspec.mean :
    outputspec.combined_motion :
    outputspec.outlier_files :
    outputspec.mask :
    outputspec.reg_cost :
    outputspec.reg_file :
    outputspec.noise_components :
    outputspec.tsnr_file :
    outputspec.stddev_file :
    outputspec.filter_file :
    outputspec.scaled_files :
    outputspec.z_img :
    outputspec.motion_plots :
    outputspec.FM_unwarped_mean :
    outputspec.FM_unwarped_epi :
    
    Returns
    -------
    workflow : preprocessing workflow
    """

    import nipype.interfaces.fsl as fsl  # fsl
    import nipype.algorithms.rapidart as ra  # rapid artifact detection
    from nipype.workflows.smri.freesurfer.utils import create_getmask_flow
    from modular_nodes import create_mod_smooth, mod_realign, mod_despike
    import nipype.pipeline.engine as pe
    import nipype.interfaces.utility as util

    preproc = pe.Workflow(name=name)

    # Compcorr node
    compcor = create_compcorr()

    # Input node
    inputnode = pe.Node(util.IdentityInterface(fields=[
        'fssubject_id', 'fssubject_dir', 'func', 'highpass',
        'num_noise_components', 'ad_normthresh', 'ad_zthresh', 'tr',
        'do_slicetime', 'sliceorder', 'compcor_select', 'highpass_freq',
        'lowpass_freq', 'reg_params', 'FM_TEdiff', 'FM_Echo_spacing',
        'FM_sigma', 'motion_correct_node', 'smooth_type', 'surface_fwhm',
        'filter_type', 'timepoints_to_remove', 'do_whitening',
        'regress_before_PCA', 'realign_parameters', 'do_despike', 'anatomical'
    ]),
                        name='inputspec')

    # Separate input node for FWHM
    inputnode_fwhm = pe.Node(util.IdentityInterface(fields=['fwhm']),
                             name='fwhm_input')

    # strip ids
    strip_rois = pe.MapNode(fsl.ExtractROI(),
                            name='extractroi',
                            iterfield='in_file')
    strip_rois.inputs.t_size = -1
    preproc.connect(inputnode, 'timepoints_to_remove', strip_rois, 't_min')

    # convert BOLD images to float
    img2float = pe.MapNode(interface=fsl.ImageMaths(out_data_type='float',
                                                    op_string='',
                                                    suffix='_dtype'),
                           iterfield=['in_file'],
                           name='img2float')

    #afni despike
    despike = pe.MapNode(util.Function(input_names=['in_file', "do_despike"],
                                       output_names=["out_file"],
                                       function=mod_despike),
                         name="despike",
                         iterfield=["in_file"])
    preproc.connect(inputnode, "do_despike", despike, "do_despike")
    # define the motion correction node
    #motion_correct = pe.Node(interface=FmriRealign4d(),
    #                            name='realign')

    motion_correct = pe.Node(util.Function(
        input_names=[
            'node', 'in_file', 'tr', 'do_slicetime', 'sliceorder', "parameters"
        ],
        output_names=['out_file', 'par_file', 'parameter_source'],
        function=mod_realign),
                             name="mod_realign")

    preproc.connect(inputnode, 'motion_correct_node', motion_correct, 'node')

    # construct motion plots
    #plot_motion = pe.MapNode(interface=fsl.PlotMotionParams(in_source='fsl'),
    #                         name='plot_motion',
    #                         iterfield=['in_file'])

    # rapidArt for artifactual timepoint detection
    ad = pe.Node(ra.ArtifactDetect(save_plot=False), name='artifactdetect')

    # extract the mean volume if the first functional run
    meanfunc = art_mean_workflow()

    # generate a freesurfer workflow that will return the mask
    getmask = create_getmask_flow()

    # create a SUSAN smoothing workflow, and smooth each run with
    # 75% of the median value for each run as the brightness
    # threshold.
    smooth = create_mod_smooth(name="modular_smooth", separate_masks=False)
    preproc.connect(inputnode, 'smooth_type', smooth, 'inputnode.smooth_type')
    # choose susan function
    """
    The following node selects smooth or unsmoothed data
    depending on the fwhm. This is because SUSAN defaults
    to smoothing the data with about the voxel size of
    the input data if the fwhm parameter is less than 1/3 of
    the voxel size.
    """
    choosesusan = pe.Node(util.Function(
        input_names=['fwhm', 'motion_files', 'smoothed_files'],
        output_names=['cor_smoothed_files'],
        function=choose_susan),
                          name='select_smooth')

    # scale the median value of each run to 10,000
    meanscale = pe.MapNode(interface=fsl.ImageMaths(suffix='_gms'),
                           iterfield=['in_file', 'op_string'],
                           name='scale_median')

    # determine the median value of the MASKED functional runs
    medianval = pe.MapNode(interface=fsl.ImageStats(op_string='-k %s -p 50'),
                           iterfield=['in_file'],
                           name='compute_median_val')

    # temporal highpass filtering
    highpass = pe.MapNode(interface=fsl.ImageMaths(suffix='_tempfilt'),
                          iterfield=['in_file'],
                          name='highpass')

    # Calculate the z-score of output
    zscore = pe.MapNode(interface=util.Function(
        input_names=['image', 'outliers'],
        output_names=['z_img'],
        function=z_image),
                        name='z_score',
                        iterfield=['image', 'outliers'])

    # declare some node inputs...
    #plot_motion.iterables = ('plot_type', ['rotations', 'translations'])

    #ad.inputs.parameter_source = 'FSL'
    meanfunc.inputs.inputspec.parameter_source = 'FSL'
    ad.inputs.mask_type = 'file'
    ad.inputs.use_differences = [True, False]
    getmask.inputs.inputspec.contrast_type = 't2'
    getmask.inputs.register.out_fsl_file = True
    fssource = getmask.get_node('fssource')

    # make connections...
    preproc.connect(inputnode, 'fssubject_id', getmask, 'inputspec.subject_id')
    preproc.connect(inputnode, 'ad_normthresh', ad, 'norm_threshold')
    preproc.connect(inputnode, 'ad_zthresh', ad, 'zintensity_threshold')
    preproc.connect(inputnode, 'tr', motion_correct, 'tr')
    preproc.connect(inputnode, 'realign_parameters', motion_correct,
                    'parameters')
    preproc.connect(motion_correct, 'parameter_source', ad, 'parameter_source')
    preproc.connect(inputnode, 'do_slicetime', motion_correct, 'do_slicetime')
    preproc.connect(inputnode, 'sliceorder', motion_correct, 'sliceorder')
    preproc.connect(inputnode, 'compcor_select', compcor, 'inputspec.selector')
    preproc.connect(inputnode, 'fssubject_dir', getmask,
                    'inputspec.subjects_dir')

    #preproc.connect(inputnode, 'func',
    #                img2float, 'in_file')
    preproc.connect(inputnode, 'func', strip_rois, 'in_file')
    preproc.connect(strip_rois, 'roi_file', img2float, 'in_file')

    preproc.connect(img2float, 'out_file', despike, "in_file")
    preproc.connect(despike, "out_file", motion_correct, 'in_file')
    #preproc.connect(motion_correct, 'par_file',
    #                plot_motion, 'in_file')
    preproc.connect(motion_correct, 'out_file', meanfunc,
                    'inputspec.realigned_files')
    preproc.connect(motion_correct, 'par_file', meanfunc,
                    'inputspec.realignment_parameters')
    preproc.connect(meanfunc, 'outputspec.mean_image', getmask,
                    'inputspec.source_file')
    preproc.connect(inputnode, 'num_noise_components', compcor,
                    'inputspec.num_components')
    preproc.connect(inputnode, 'regress_before_PCA', compcor,
                    'inputspec.regress_before_PCA')
    preproc.connect(motion_correct, 'out_file', compcor,
                    'inputspec.realigned_file')
    preproc.connect(meanfunc, 'outputspec.mean_image', compcor,
                    'inputspec.mean_file')
    preproc.connect(fssource, 'aseg', compcor, 'inputspec.fsaseg_file')
    preproc.connect(getmask, ('outputspec.reg_file', pickfirst), compcor,
                    'inputspec.reg_file')
    preproc.connect(ad, 'outlier_files', compcor, 'inputspec.outlier_files')
    preproc.connect(motion_correct, 'par_file', compcor,
                    'inputspec.realignment_parameters')
    preproc.connect(motion_correct, 'out_file', ad, 'realigned_files')
    preproc.connect(motion_correct, 'par_file', ad, 'realignment_parameters')
    preproc.connect(getmask, ('outputspec.mask_file', pickfirst), ad,
                    'mask_file')
    preproc.connect(getmask, ('outputspec.mask_file', pickfirst), medianval,
                    'mask_file')
    preproc.connect(inputnode_fwhm, 'fwhm', smooth, 'inputnode.fwhm')
    preproc.connect(motion_correct, 'out_file', smooth, 'inputnode.in_files')
    preproc.connect(getmask, ('outputspec.mask_file', pickfirst), smooth,
                    'inputnode.mask_file')
    preproc.connect(getmask, ('outputspec.reg_file', pickfirst), smooth,
                    'inputnode.reg_file')
    preproc.connect(inputnode, 'surface_fwhm', smooth,
                    'inputnode.surface_fwhm')
    preproc.connect(inputnode, 'fssubject_dir', smooth, 'inputnode.surf_dir')
    preproc.connect(smooth, 'outputnode.smoothed_files', choosesusan,
                    'smoothed_files')
    preproc.connect(motion_correct, 'out_file', choosesusan, 'motion_files')
    preproc.connect(inputnode_fwhm, 'fwhm', choosesusan, 'fwhm')
    preproc.connect(choosesusan, 'cor_smoothed_files', meanscale, 'in_file')
    preproc.connect(choosesusan, 'cor_smoothed_files', medianval, 'in_file')
    preproc.connect(medianval, ('out_stat', getmeanscale), meanscale,
                    'op_string')
    preproc.connect(inputnode, ('highpass', highpass_operand), highpass,
                    'op_string')
    preproc.connect(meanscale, 'out_file', highpass, 'in_file')
    preproc.connect(highpass, 'out_file', zscore, 'image')
    preproc.connect(ad, 'outlier_files', zscore, 'outliers')

    # create output node
    outputnode = pe.Node(interface=util.IdentityInterface(fields=[
        'mean', 'motion_parameters', 'realigned_files', 'smoothed_files',
        'highpassed_files', 'combined_motion', 'outlier_files',
        'outlier_stat_files', 'mask', 'reg_cost', 'reg_file', 'reg_fsl_file',
        'noise_components', 'tsnr_file', 'stddev_file', 'tsnr_detrended',
        'filter_file', 'scaled_files', 'unmasked_fullspectrum', 'z_img',
        'motion_plots', 'FM_unwarped_epi', 'FM_unwarped_mean', 'vsm_file',
        'bandpassed_file', 'intensity_files', 'noise_mask', 'csf_mask'
    ]),
                         name='outputspec')

    # make output connection
    preproc.connect(meanfunc, 'outputspec.mean_image', outputnode, 'mean')
    preproc.connect(motion_correct, 'par_file', outputnode,
                    'motion_parameters')
    preproc.connect(motion_correct, 'out_file', outputnode, 'realigned_files')
    preproc.connect(highpass, 'out_file', outputnode, 'highpassed_files')
    preproc.connect(ad, 'norm_files', outputnode, 'combined_motion')
    preproc.connect(ad, 'outlier_files', outputnode, 'outlier_files')
    preproc.connect(ad, 'intensity_files', outputnode, 'intensity_files')
    preproc.connect(ad, 'statistic_files', outputnode, 'outlier_stat_files')
    preproc.connect(compcor, 'outputspec.noise_components', outputnode,
                    'noise_components')
    preproc.connect(compcor, 'outputspec.noise_mask', outputnode, 'noise_mask')
    preproc.connect(compcor, 'outputspec.csf_mask', outputnode, 'csf_mask')
    preproc.connect(getmask, 'outputspec.mask_file', outputnode, 'mask')
    preproc.connect(getmask, 'register.out_fsl_file', outputnode,
                    'reg_fsl_file')
    preproc.connect(getmask, 'outputspec.reg_file', outputnode, 'reg_file')
    preproc.connect(getmask, 'outputspec.reg_cost', outputnode, 'reg_cost')
    preproc.connect(choosesusan, 'cor_smoothed_files', outputnode,
                    'smoothed_files')
    preproc.connect(compcor, 'outputspec.tsnr_file', outputnode, 'tsnr_file')
    preproc.connect(compcor, 'outputspec.stddev_file', outputnode,
                    'stddev_file')
    preproc.connect(compcor, 'outputspec.tsnr_detrended', outputnode,
                    'tsnr_detrended')
    preproc.connect(zscore, 'z_img', outputnode, 'z_img')
    #preproc.connect(plot_motion,'out_file',
    #                outputnode,'motion_plots')

    return preproc
Пример #3
0
def create_spm_preproc(c, name='preproc'):
    """Create an spm preprocessing workflow with freesurfer registration and
artifact detection.

The workflow realigns and smooths and registers the functional images with
the subject's freesurfer space.

Example
-------

>>> preproc = create_spm_preproc()
>>> preproc.base_dir = '.'
>>> preproc.inputs.inputspec.fwhm = 6
>>> preproc.inputs.inputspec.subject_id = 's1'
>>> preproc.inputs.inputspec.subjects_dir = '.'
>>> preproc.inputs.inputspec.functionals = ['f3.nii', 'f5.nii']
>>> preproc.inputs.inputspec.norm_threshold = 1
>>> preproc.inputs.inputspec.zintensity_threshold = 3

Inputs::

inputspec.functionals : functional runs use 4d nifti
inputspec.subject_id : freesurfer subject id
inputspec.subjects_dir : freesurfer subjects dir
inputspec.fwhm : smoothing fwhm
inputspec.norm_threshold : norm threshold for outliers
inputspec.zintensity_threshold : intensity threshold in z-score

Outputs::

outputspec.realignment_parameters : realignment parameter files
outputspec.smoothed_files : smoothed functional files
outputspec.outlier_files : list of outliers
outputspec.outlier_stats : statistics of outliers
outputspec.outlier_plots : images of outliers
outputspec.mask_file : binary mask file in reference image space
outputspec.reg_file : registration file that maps reference image to
freesurfer space
outputspec.reg_cost : cost of registration (useful for detecting misalignment)
"""
    from nipype.workflows.smri.freesurfer.utils import create_getmask_flow
    import nipype.algorithms.rapidart as ra
    import nipype.interfaces.spm as spm
    import nipype.interfaces.utility as niu
    import nipype.pipeline.engine as pe
    import nipype.interfaces.io as nio
    """
Initialize the workflow
"""

    workflow = pe.Workflow(name=name)
    """
Define the inputs to this workflow
"""

    inputnode = pe.Node(niu.IdentityInterface(fields=[
        'functionals', 'subject_id', 'subjects_dir', 'fwhm', 'norm_threshold',
        'zintensity_threshold', 'tr', 'do_slicetime', 'sliceorder', 'node',
        'csf_prob', 'wm_prob', 'gm_prob'
    ]),
                        name='inputspec')
    """
Setup the processing nodes and create the mask generation and coregistration
workflow
"""

    poplist = lambda x: x.pop()
    #realign = pe.Node(spm.Realign(), name='realign')

    sym_func = pe.Node(niu.Function(input_names=['in_file'],
                                    output_names=['out_link'],
                                    function=do_symlink),
                       name='func_symlink')

    realign = pe.Node(niu.Function(
        input_names=['node', 'in_file', 'tr', 'do_slicetime', 'sliceorder'],
        output_names=['out_file', 'par_file'],
        function=mod_realign),
                      name="mod_realign")

    mean = art_mean_workflow()
    workflow.connect(realign, 'out_file', mean, 'inputspec.realigned_files')
    workflow.connect(realign, 'par_file', mean,
                     'inputspec.realignment_parameters')
    mean.inputs.inputspec.parameter_source = 'FSL'  # Modular realign puts it in FSL format for consistency

    #workflow.connect(inputnode, 'functionals', realign, 'in_file')
    workflow.connect(inputnode, 'functionals', sym_func, 'in_file')
    workflow.connect(sym_func, 'out_link', realign, 'in_file')

    workflow.connect(inputnode, 'tr', realign, 'tr')
    workflow.connect(inputnode, 'do_slicetime', realign, 'do_slicetime')
    workflow.connect(inputnode, 'sliceorder', realign, 'sliceorder')
    workflow.connect(inputnode, 'node', realign, 'node')

    maskflow = create_getmask_flow()
    workflow.connect([(inputnode, maskflow,
                       [('subject_id', 'inputspec.subject_id'),
                        ('subjects_dir', 'inputspec.subjects_dir')])])
    maskflow.inputs.inputspec.contrast_type = 't2'
    workflow.connect(mean, 'outputspec.mean_image', maskflow,
                     'inputspec.source_file')
    smooth = pe.Node(spm.Smooth(), name='smooth')

    normalize = pe.Node(spm.Normalize(jobtype='write'), name='normalize')
    normalize_struct = normalize.clone('normalize_struct')
    segment = pe.Node(spm.Segment(csf_output_type=[True, True, False],
                                  gm_output_type=[True, True, False],
                                  wm_output_type=[True, True, False]),
                      name='segment')

    mergefunc = lambda in1, in2, in3: [in1, in2, in3]

    # merge = pe.Node(niu.Merge(),name='merge')
    merge = pe.Node(niu.Function(input_names=['in1', 'in2', 'in3'],
                                 output_names=['out'],
                                 function=mergefunc),
                    name='merge')
    workflow.connect(inputnode, 'csf_prob', merge, 'in3')
    workflow.connect(inputnode, 'wm_prob', merge, 'in2')
    workflow.connect(inputnode, 'gm_prob', merge, 'in1')

    #workflow.connect(merge,'out', segment,'tissue_prob_maps')

    sym_prob = sym_func.clone('sym_prob')
    workflow.connect(merge, 'out', sym_prob, 'in_file')
    workflow.connect(sym_prob, 'out_link', segment, 'tissue_prob_maps')

    workflow.connect(maskflow, ('outputspec.mask_file', pickfirst), segment,
                     'mask_image')
    workflow.connect(inputnode, 'fwhm', smooth, 'fwhm')

    #sym_brain = sym_func.clone('sym_brain')
    #workflow.connect(realign, 'mean_image', normalize, 'source')
    #workflow.connect(maskflow,'fssource.brain',segment,'data')
    fssource = maskflow.get_node('fssource')
    import nipype.interfaces.freesurfer as fs
    convert_brain = pe.Node(interface=fs.ApplyVolTransform(inverse=True),
                            name='convert')
    workflow.connect(fssource, 'brain', convert_brain, 'target_file')
    workflow.connect(maskflow, ('outputspec.reg_file', pickfirst),
                     convert_brain, 'reg_file')
    workflow.connect(mean, 'outputspec.mean_image', convert_brain,
                     'source_file')
    convert2nii = pe.Node(fs.MRIConvert(in_type='mgz', out_type='nii'),
                          name='convert2nii')
    workflow.connect(convert_brain, 'transformed_file', convert2nii, 'in_file')
    workflow.connect(convert2nii, 'out_file', segment, 'data')

    workflow.connect(segment, 'transformation_mat', normalize,
                     'parameter_file')
    workflow.connect(segment, 'transformation_mat', normalize_struct,
                     'parameter_file')
    workflow.connect(convert2nii, 'out_file', normalize_struct,
                     'apply_to_files')
    workflow.connect(realign, 'out_file', normalize, 'apply_to_files')
    #normalize.inputs.template='/software/spm8/templates/EPI.nii'
    workflow.connect(normalize, 'normalized_files', smooth, 'in_files')
    #workflow.connect(realign, 'realigned_files', smooth, 'in_files')

    artdetect = pe.Node(ra.ArtifactDetect(mask_type='file',
                                          parameter_source='FSL',
                                          use_differences=[True, False],
                                          use_norm=True,
                                          save_plot=True),
                        name='artdetect')
    workflow.connect([(inputnode, artdetect,
                       [('norm_threshold', 'norm_threshold'),
                        ('zintensity_threshold', 'zintensity_threshold')])])
    workflow.connect([(realign, artdetect, [('out_file', 'realigned_files'),
                                            ('par_file',
                                             'realignment_parameters')])])
    workflow.connect(maskflow, ('outputspec.mask_file', poplist), artdetect,
                     'mask_file')
    """
Define the outputs of the workflow and connect the nodes to the outputnode
"""

    outputnode = pe.Node(niu.IdentityInterface(fields=[
        "realignment_parameters", "smoothed_files", "mask_file", "mean_image",
        "reg_file", "reg_cost", 'outlier_files', 'outlier_stats',
        'outlier_plots', 'norm_components', 'mod_csf', 'unmod_csf', 'mod_wm',
        'unmod_wm', 'mod_gm', 'unmod_gm', 'mean', 'normalized_struct',
        'struct_in_functional_space', 'normalization_parameters',
        'reverse_normalize_parameters'
    ]),
                         name="outputspec")
    workflow.connect([
        (maskflow, outputnode, [("outputspec.reg_file", "reg_file")]),
        (maskflow, outputnode, [("outputspec.reg_cost", "reg_cost")]),
        (maskflow, outputnode, [(("outputspec.mask_file", poplist),
                                 "mask_file")]),
        (realign, outputnode, [('par_file', 'realignment_parameters')]),
        (smooth, outputnode, [('smoothed_files', 'smoothed_files')]),
        (artdetect, outputnode, [('outlier_files', 'outlier_files'),
                                 ('statistic_files', 'outlier_stats'),
                                 ('plot_files', 'outlier_plots'),
                                 ('norm_files', 'norm_components')])
    ])
    workflow.connect(segment, 'modulated_csf_image', outputnode, 'mod_csf')
    workflow.connect(segment, 'modulated_wm_image', outputnode, 'mod_wm')
    workflow.connect(segment, 'modulated_gm_image', outputnode, 'mod_gm')
    workflow.connect(segment, 'normalized_csf_image', outputnode, 'unmod_csf')
    workflow.connect(segment, 'normalized_wm_image', outputnode, 'unmod_wm')
    workflow.connect(segment, 'normalized_gm_image', outputnode, 'unmod_gm')
    workflow.connect(mean, 'outputspec.mean_image', outputnode, 'mean')
    workflow.connect(normalize_struct, 'normalized_files', outputnode,
                     'normalized_struct')
    workflow.connect(segment, 'transformation_mat', outputnode,
                     'normalization_parameters')
    workflow.connect(segment, 'inverse_transformation_mat', outputnode,
                     'reverse_normalize_parameters')
    workflow.connect(convert2nii, 'out_file', outputnode,
                     'struct_in_functional_space')

    workflow.inputs.inputspec.fwhm = c.fwhm
    workflow.inputs.inputspec.subjects_dir = c.surf_dir
    workflow.inputs.inputspec.norm_threshold = c.norm_thresh
    workflow.inputs.inputspec.zintensity_threshold = c.z_thresh
    workflow.inputs.inputspec.node = c.motion_correct_node
    workflow.inputs.inputspec.tr = c.TR
    workflow.inputs.inputspec.do_slicetime = c.do_slicetiming
    workflow.inputs.inputspec.sliceorder = c.SliceOrder
    workflow.inputs.inputspec.csf_prob = c.csf_prob
    workflow.inputs.inputspec.gm_prob = c.grey_prob
    workflow.inputs.inputspec.wm_prob = c.white_prob
    workflow.base_dir = c.working_dir
    workflow.config = {'execution': {'crashdump_dir': c.crash_dir}}

    datagrabber = get_dataflow(c)

    workflow.connect(datagrabber, 'func', inputnode, 'functionals')

    infosource = pe.Node(niu.IdentityInterface(fields=['subject_id']),
                         name='subject_names')
    if not c.test_mode:
        infosource.iterables = ('subject_id', c.subjects)
    else:
        infosource.iterables = ('subject_id', c.subjects[:1])

    workflow.connect(infosource, 'subject_id', inputnode, 'subject_id')
    workflow.connect(infosource, 'subject_id', datagrabber, 'subject_id')
    sub = lambda x: [('_subject_id_%s' % x, '')]

    sinker = pe.Node(nio.DataSink(), name='sinker')
    workflow.connect(infosource, 'subject_id', sinker, 'container')
    workflow.connect(infosource, ('subject_id', sub), sinker, 'substitutions')
    sinker.inputs.base_directory = c.sink_dir
    outputspec = workflow.get_node('outputspec')
    workflow.connect(outputspec, 'realignment_parameters', sinker,
                     'spm_preproc.realignment_parameters')
    workflow.connect(outputspec, 'smoothed_files', sinker,
                     'spm_preproc.smoothed_outputs')
    workflow.connect(outputspec, 'outlier_files', sinker,
                     'spm_preproc.art.@outlier_files')
    workflow.connect(outputspec, 'outlier_stats', sinker,
                     'spm_preproc.art.@outlier_stats')
    workflow.connect(outputspec, 'outlier_plots', sinker,
                     'spm_preproc.art.@outlier_plots')
    workflow.connect(outputspec, 'norm_components', sinker,
                     'spm_preproc.art.@norm')
    workflow.connect(outputspec, 'reg_file', sinker,
                     'spm_preproc.bbreg.@reg_file')
    workflow.connect(outputspec, 'reg_cost', sinker,
                     'spm_preproc.bbreg.@reg_cost')
    workflow.connect(outputspec, 'mask_file', sinker,
                     'spm_preproc.mask.@mask_file')
    workflow.connect(outputspec, 'mod_csf', sinker,
                     'spm_preproc.segment.mod.@csf')
    workflow.connect(outputspec, 'mod_wm', sinker,
                     'spm_preproc.segment.mod.@wm')
    workflow.connect(outputspec, 'mod_gm', sinker,
                     'spm_preproc.segment.mod.@gm')
    workflow.connect(outputspec, 'unmod_csf', sinker,
                     'spm_preproc.segment.unmod.@csf')
    workflow.connect(outputspec, 'unmod_wm', sinker,
                     'spm_preproc.segment.unmod.@wm')
    workflow.connect(outputspec, 'unmod_gm', sinker,
                     'spm_preproc.segment.unmod.@gm')
    workflow.connect(outputspec, 'mean', sinker, 'spm_preproc.mean')
    workflow.connect(outputspec, 'normalized_struct', sinker,
                     'spm_preproc.normalized_struct')
    workflow.connect(outputspec, 'normalization_parameters', sinker,
                     'spm_preproc.normalization_parameters.@forward')
    workflow.connect(outputspec, 'reverse_normalize_parameters', sinker,
                     'spm_preproc.normalization_parameters.@reverse')
    workflow.connect(outputspec, 'struct_in_functional_space', sinker,
                     'spm_preproc.struct_in_func_space')

    return workflow
def create_spm_preproc(c, name='preproc'):
    """
"""

    from nipype.workflows.smri.freesurfer.utils import create_getmask_flow
    import nipype.algorithms.rapidart as ra
    import nipype.interfaces.spm as spm
    import nipype.interfaces.utility as niu
    import nipype.pipeline.engine as pe
    import nipype.interfaces.io as nio
    import nipype.interfaces.freesurfer as fs

    workflow = pe.Workflow(name=name)

    inputnode = pe.Node(niu.IdentityInterface(fields=[
        'functionals', 'subject_id', 'subjects_dir', 'fwhm', 'norm_threshold',
        'zintensity_threshold', 'tr', 'do_slicetime', 'sliceorder',
        'parameters', 'node', 'csf_prob', 'wm_prob', 'gm_prob'
    ]),
                        name='inputspec')

    poplist = lambda x: x.pop()

    sym_func = pe.Node(niu.Function(input_names=['in_file'],
                                    output_names=['out_link'],
                                    function=do_symlink),
                       name='func_symlink')

    # REALIGN

    realign = pe.Node(niu.Function(
        input_names=[
            'node', 'in_file', 'tr', 'do_slicetime', 'sliceorder', 'parameters'
        ],
        output_names=['out_file', 'par_file', 'parameter_source'],
        function=mod_realign),
                      name="mod_realign")
    workflow.connect(inputnode, 'parameters', realign, 'parameters')
    workflow.connect(inputnode, 'functionals', realign, 'in_file')
    workflow.connect(inputnode, 'tr', realign, 'tr')
    workflow.connect(inputnode, 'do_slicetime', realign, 'do_slicetime')
    workflow.connect(inputnode, 'sliceorder', realign, 'sliceorder')
    workflow.connect(inputnode, 'node', realign, 'node')

    # TAKE MEAN IMAGE

    mean = art_mean_workflow()
    workflow.connect(realign, 'out_file', mean, 'inputspec.realigned_files')
    workflow.connect(realign, 'par_file', mean,
                     'inputspec.realignment_parameters')
    workflow.connect(realign, 'parameter_source', mean,
                     'inputspec.parameter_source')

    # CREATE BRAIN MASK

    maskflow = create_getmask_flow()
    workflow.connect([(inputnode, maskflow,
                       [('subject_id', 'inputspec.subject_id'),
                        ('subjects_dir', 'inputspec.subjects_dir')])])
    maskflow.inputs.inputspec.contrast_type = 't2'
    workflow.connect(mean, 'outputspec.mean_image', maskflow,
                     'inputspec.source_file')

    # SEGMENT

    segment = pe.Node(spm.Segment(csf_output_type=[True, True, False],
                                  gm_output_type=[True, True, False],
                                  wm_output_type=[True, True, False]),
                      name='segment')
    mergefunc = lambda in1, in2, in3: [in1, in2, in3]

    merge = pe.Node(niu.Function(input_names=['in1', 'in2', 'in3'],
                                 output_names=['out'],
                                 function=mergefunc),
                    name='merge')
    workflow.connect(inputnode, 'csf_prob', merge, 'in3')
    workflow.connect(inputnode, 'wm_prob', merge, 'in2')
    workflow.connect(inputnode, 'gm_prob', merge, 'in1')

    sym_prob = sym_func
    workflow.connect(merge, 'out', sym_prob, 'in_file')
    workflow.connect(sym_prob, 'out_link', segment, 'tissue_prob_maps')

    xform_mask = pe.Node(fs.ApplyVolTransform(fs_target=True),
                         name='transform_mask')
    workflow.connect(maskflow, ('outputspec.reg_file', pickfirst), xform_mask,
                     'reg_file')
    workflow.connect(maskflow, ('outputspec.mask_file', pickfirst), xform_mask,
                     'source_file')
    workflow.connect(xform_mask, "transformed_file", segment, 'mask_image')

    fssource = maskflow.get_node('fssource')
    convert2nii = pe.Node(fs.MRIConvert(in_type='mgz', out_type='nii'),
                          name='convert2nii')
    workflow.connect(fssource, 'brain', convert2nii, 'in_file')
    workflow.connect(convert2nii, 'out_file', segment, 'data')

    # NORMALIZE

    normalize = pe.MapNode(spm.Normalize(jobtype='write'),
                           name='normalize',
                           iterfield=['apply_to_files'])
    normalize_struct = normalize.clone('normalize_struct')
    normalize_mask = normalize.clone('normalize_mask')

    workflow.connect(segment, 'transformation_mat', normalize,
                     'parameter_file')
    workflow.connect(segment, 'transformation_mat', normalize_mask,
                     'parameter_file')
    workflow.connect(segment, 'transformation_mat', normalize_struct,
                     'parameter_file')
    workflow.connect(convert2nii, 'out_file', normalize_struct,
                     'apply_to_files')
    workflow.connect(xform_mask, "transformed_file", normalize_mask,
                     'apply_to_files')

    xform_image = pe.MapNode(fs.ApplyVolTransform(fs_target=True),
                             name='xform_image',
                             iterfield=['source_file'])
    workflow.connect(maskflow, ('outputspec.reg_file', pickfirst), xform_image,
                     'reg_file')
    workflow.connect(realign, 'out_file', xform_image, "source_file")
    workflow.connect(xform_image, "transformed_file", normalize,
                     "apply_to_files")

    #SMOOTH

    smooth = pe.Node(spm.Smooth(), name='smooth')

    workflow.connect(inputnode, 'fwhm', smooth, 'fwhm')
    workflow.connect(normalize, 'normalized_files', smooth, 'in_files')

    # ART

    artdetect = pe.Node(ra.ArtifactDetect(mask_type='file',
                                          use_differences=[True, False],
                                          use_norm=True,
                                          save_plot=True),
                        name='artdetect')
    workflow.connect(realign, 'parameter_source', artdetect,
                     'parameter_source')
    workflow.connect([(inputnode, artdetect,
                       [('norm_threshold', 'norm_threshold'),
                        ('zintensity_threshold', 'zintensity_threshold')])])
    workflow.connect([(realign, artdetect, [('out_file', 'realigned_files'),
                                            ('par_file',
                                             'realignment_parameters')])])
    workflow.connect(maskflow, ('outputspec.mask_file', poplist), artdetect,
                     'mask_file')

    # OUTPUTS

    outputnode = pe.Node(niu.IdentityInterface(fields=[
        "realignment_parameters", "smoothed_files", "mask_file", "mean_image",
        "reg_file", "reg_cost", 'outlier_files', 'outlier_stats',
        'outlier_plots', 'norm_components', 'mod_csf', 'unmod_csf', 'mod_wm',
        'unmod_wm', 'mod_gm', 'unmod_gm', 'mean', 'normalized_struct',
        'normalization_parameters', 'reverse_normalize_parameters'
    ]),
                         name="outputspec")
    workflow.connect([
        (maskflow, outputnode, [("outputspec.reg_file", "reg_file")]),
        (maskflow, outputnode, [("outputspec.reg_cost", "reg_cost")]),
        (realign, outputnode, [('par_file', 'realignment_parameters')]),
        (smooth, outputnode, [('smoothed_files', 'smoothed_files')]),
        (artdetect, outputnode, [('outlier_files', 'outlier_files'),
                                 ('statistic_files', 'outlier_stats'),
                                 ('plot_files', 'outlier_plots'),
                                 ('norm_files', 'norm_components')])
    ])
    workflow.connect(normalize_mask, "normalized_files", outputnode,
                     "mask_file")
    workflow.connect(segment, 'modulated_csf_image', outputnode, 'mod_csf')
    workflow.connect(segment, 'modulated_wm_image', outputnode, 'mod_wm')
    workflow.connect(segment, 'modulated_gm_image', outputnode, 'mod_gm')
    workflow.connect(segment, 'normalized_csf_image', outputnode, 'unmod_csf')
    workflow.connect(segment, 'normalized_wm_image', outputnode, 'unmod_wm')
    workflow.connect(segment, 'normalized_gm_image', outputnode, 'unmod_gm')
    workflow.connect(mean, 'outputspec.mean_image', outputnode, 'mean')
    workflow.connect(normalize_struct, 'normalized_files', outputnode,
                     'normalized_struct')
    workflow.connect(segment, 'transformation_mat', outputnode,
                     'normalization_parameters')
    workflow.connect(segment, 'inverse_transformation_mat', outputnode,
                     'reverse_normalize_parameters')

    # CONNECT TO CONFIG

    workflow.inputs.inputspec.fwhm = c.fwhm
    workflow.inputs.inputspec.subjects_dir = c.surf_dir
    workflow.inputs.inputspec.norm_threshold = c.norm_thresh
    workflow.inputs.inputspec.zintensity_threshold = c.z_thresh
    workflow.inputs.inputspec.node = c.motion_correct_node
    workflow.inputs.inputspec.tr = c.TR
    workflow.inputs.inputspec.do_slicetime = c.do_slicetiming
    workflow.inputs.inputspec.sliceorder = c.SliceOrder
    workflow.inputs.inputspec.csf_prob = c.csf_prob
    workflow.inputs.inputspec.gm_prob = c.grey_prob
    workflow.inputs.inputspec.wm_prob = c.white_prob
    workflow.inputs.inputspec.parameters = {"order": c.order}
    workflow.base_dir = c.working_dir
    workflow.config = {'execution': {'crashdump_dir': c.crash_dir}}

    datagrabber = get_dataflow(c)

    workflow.connect(datagrabber, 'func', inputnode, 'functionals')

    infosource = pe.Node(niu.IdentityInterface(fields=['subject_id']),
                         name='subject_names')
    if not c.test_mode:
        infosource.iterables = ('subject_id', c.subjects)
    else:
        infosource.iterables = ('subject_id', c.subjects[:1])

    workflow.connect(infosource, 'subject_id', inputnode, 'subject_id')
    workflow.connect(infosource, 'subject_id', datagrabber, 'subject_id')
    sub = lambda x: [('_subject_id_%s' % x, '')]

    sinker = pe.Node(nio.DataSink(), name='sinker')
    workflow.connect(infosource, 'subject_id', sinker, 'container')
    workflow.connect(infosource, ('subject_id', sub), sinker, 'substitutions')
    sinker.inputs.base_directory = c.sink_dir
    outputspec = workflow.get_node('outputspec')
    workflow.connect(outputspec, 'realignment_parameters', sinker,
                     'spm_preproc.realignment_parameters')
    workflow.connect(outputspec, 'smoothed_files', sinker,
                     'spm_preproc.smoothed_outputs')
    workflow.connect(outputspec, 'outlier_files', sinker,
                     'spm_preproc.art.@outlier_files')
    workflow.connect(outputspec, 'outlier_stats', sinker,
                     'spm_preproc.art.@outlier_stats')
    workflow.connect(outputspec, 'outlier_plots', sinker,
                     'spm_preproc.art.@outlier_plots')
    workflow.connect(outputspec, 'norm_components', sinker,
                     'spm_preproc.art.@norm')
    workflow.connect(outputspec, 'reg_file', sinker,
                     'spm_preproc.bbreg.@reg_file')
    workflow.connect(outputspec, 'reg_cost', sinker,
                     'spm_preproc.bbreg.@reg_cost')
    workflow.connect(outputspec, 'mask_file', sinker,
                     'spm_preproc.mask.@mask_file')
    workflow.connect(outputspec, 'mod_csf', sinker,
                     'spm_preproc.segment.mod.@csf')
    workflow.connect(outputspec, 'mod_wm', sinker,
                     'spm_preproc.segment.mod.@wm')
    workflow.connect(outputspec, 'mod_gm', sinker,
                     'spm_preproc.segment.mod.@gm')
    workflow.connect(outputspec, 'unmod_csf', sinker,
                     'spm_preproc.segment.unmod.@csf')
    workflow.connect(outputspec, 'unmod_wm', sinker,
                     'spm_preproc.segment.unmod.@wm')
    workflow.connect(outputspec, 'unmod_gm', sinker,
                     'spm_preproc.segment.unmod.@gm')
    workflow.connect(outputspec, 'mean', sinker, 'spm_preproc.mean')
    workflow.connect(outputspec, 'normalized_struct', sinker,
                     'spm_preproc.normalized_struct')
    workflow.connect(outputspec, 'normalization_parameters', sinker,
                     'spm_preproc.normalization_parameters.@forward')
    workflow.connect(outputspec, 'reverse_normalize_parameters', sinker,
                     'spm_preproc.normalization_parameters.@reverse')

    return workflow
def create_spm_preproc(c, name="preproc"):
    """
"""

    from nipype.workflows.smri.freesurfer.utils import create_getmask_flow
    import nipype.algorithms.rapidart as ra
    import nipype.interfaces.spm as spm
    import nipype.interfaces.utility as niu
    import nipype.pipeline.engine as pe
    import nipype.interfaces.io as nio
    import nipype.interfaces.freesurfer as fs

    workflow = pe.Workflow(name=name)

    inputnode = pe.Node(
        niu.IdentityInterface(
            fields=[
                "functionals",
                "subject_id",
                "subjects_dir",
                "fwhm",
                "norm_threshold",
                "zintensity_threshold",
                "tr",
                "do_slicetime",
                "sliceorder",
                "parameters",
                "node",
                "csf_prob",
                "wm_prob",
                "gm_prob",
            ]
        ),
        name="inputspec",
    )

    poplist = lambda x: x.pop()

    sym_func = pe.Node(
        niu.Function(input_names=["in_file"], output_names=["out_link"], function=do_symlink), name="func_symlink"
    )

    # REALIGN

    realign = pe.Node(
        niu.Function(
            input_names=["node", "in_file", "tr", "do_slicetime", "sliceorder", "parameters"],
            output_names=["out_file", "par_file", "parameter_source"],
            function=mod_realign,
        ),
        name="mod_realign",
    )
    workflow.connect(inputnode, "parameters", realign, "parameters")
    workflow.connect(inputnode, "functionals", realign, "in_file")
    workflow.connect(inputnode, "tr", realign, "tr")
    workflow.connect(inputnode, "do_slicetime", realign, "do_slicetime")
    workflow.connect(inputnode, "sliceorder", realign, "sliceorder")
    workflow.connect(inputnode, "node", realign, "node")

    # TAKE MEAN IMAGE

    mean = art_mean_workflow()
    workflow.connect(realign, "out_file", mean, "inputspec.realigned_files")
    workflow.connect(realign, "par_file", mean, "inputspec.realignment_parameters")
    workflow.connect(realign, "parameter_source", mean, "inputspec.parameter_source")

    # CREATE BRAIN MASK

    maskflow = create_getmask_flow()
    workflow.connect(
        [(inputnode, maskflow, [("subject_id", "inputspec.subject_id"), ("subjects_dir", "inputspec.subjects_dir")])]
    )
    maskflow.inputs.inputspec.contrast_type = "t2"
    workflow.connect(mean, "outputspec.mean_image", maskflow, "inputspec.source_file")

    # SEGMENT

    segment = pe.Node(
        spm.Segment(
            csf_output_type=[True, True, False], gm_output_type=[True, True, False], wm_output_type=[True, True, False]
        ),
        name="segment",
    )
    mergefunc = lambda in1, in2, in3: [in1, in2, in3]

    merge = pe.Node(
        niu.Function(input_names=["in1", "in2", "in3"], output_names=["out"], function=mergefunc), name="merge"
    )
    workflow.connect(inputnode, "csf_prob", merge, "in3")
    workflow.connect(inputnode, "wm_prob", merge, "in2")
    workflow.connect(inputnode, "gm_prob", merge, "in1")

    sym_prob = sym_func
    workflow.connect(merge, "out", sym_prob, "in_file")
    workflow.connect(sym_prob, "out_link", segment, "tissue_prob_maps")

    xform_mask = pe.Node(fs.ApplyVolTransform(fs_target=True), name="transform_mask")
    workflow.connect(maskflow, ("outputspec.reg_file", pickfirst), xform_mask, "reg_file")
    workflow.connect(maskflow, ("outputspec.mask_file", pickfirst), xform_mask, "source_file")
    workflow.connect(xform_mask, "transformed_file", segment, "mask_image")

    fssource = maskflow.get_node("fssource")
    convert2nii = pe.Node(fs.MRIConvert(in_type="mgz", out_type="nii"), name="convert2nii")
    workflow.connect(fssource, "brain", convert2nii, "in_file")
    workflow.connect(convert2nii, "out_file", segment, "data")

    # NORMALIZE

    normalize = pe.MapNode(spm.Normalize(jobtype="write"), name="normalize", iterfield=["apply_to_files"])
    normalize_struct = normalize.clone("normalize_struct")
    normalize_mask = normalize.clone("normalize_mask")

    workflow.connect(segment, "transformation_mat", normalize, "parameter_file")
    workflow.connect(segment, "transformation_mat", normalize_mask, "parameter_file")
    workflow.connect(segment, "transformation_mat", normalize_struct, "parameter_file")
    workflow.connect(convert2nii, "out_file", normalize_struct, "apply_to_files")
    workflow.connect(xform_mask, "transformed_file", normalize_mask, "apply_to_files")

    xform_image = pe.MapNode(fs.ApplyVolTransform(fs_target=True), name="xform_image", iterfield=["source_file"])
    workflow.connect(maskflow, ("outputspec.reg_file", pickfirst), xform_image, "reg_file")
    workflow.connect(realign, "out_file", xform_image, "source_file")
    workflow.connect(xform_image, "transformed_file", normalize, "apply_to_files")

    # SMOOTH

    smooth = pe.Node(spm.Smooth(), name="smooth")

    workflow.connect(inputnode, "fwhm", smooth, "fwhm")
    workflow.connect(normalize, "normalized_files", smooth, "in_files")

    # ART

    artdetect = pe.Node(
        ra.ArtifactDetect(mask_type="file", use_differences=[True, False], use_norm=True, save_plot=True),
        name="artdetect",
    )
    workflow.connect(realign, "parameter_source", artdetect, "parameter_source")
    workflow.connect(
        [
            (
                inputnode,
                artdetect,
                [("norm_threshold", "norm_threshold"), ("zintensity_threshold", "zintensity_threshold")],
            )
        ]
    )
    workflow.connect([(realign, artdetect, [("out_file", "realigned_files"), ("par_file", "realignment_parameters")])])
    workflow.connect(maskflow, ("outputspec.mask_file", poplist), artdetect, "mask_file")

    # OUTPUTS

    outputnode = pe.Node(
        niu.IdentityInterface(
            fields=[
                "realignment_parameters",
                "smoothed_files",
                "mask_file",
                "mean_image",
                "reg_file",
                "reg_cost",
                "outlier_files",
                "outlier_stats",
                "outlier_plots",
                "norm_components",
                "mod_csf",
                "unmod_csf",
                "mod_wm",
                "unmod_wm",
                "mod_gm",
                "unmod_gm",
                "mean",
                "normalized_struct",
                "normalization_parameters",
                "reverse_normalize_parameters",
            ]
        ),
        name="outputspec",
    )
    workflow.connect(
        [
            (maskflow, outputnode, [("outputspec.reg_file", "reg_file")]),
            (maskflow, outputnode, [("outputspec.reg_cost", "reg_cost")]),
            (realign, outputnode, [("par_file", "realignment_parameters")]),
            (smooth, outputnode, [("smoothed_files", "smoothed_files")]),
            (
                artdetect,
                outputnode,
                [
                    ("outlier_files", "outlier_files"),
                    ("statistic_files", "outlier_stats"),
                    ("plot_files", "outlier_plots"),
                    ("norm_files", "norm_components"),
                ],
            ),
        ]
    )
    workflow.connect(normalize_mask, "normalized_files", outputnode, "mask_file")
    workflow.connect(segment, "modulated_csf_image", outputnode, "mod_csf")
    workflow.connect(segment, "modulated_wm_image", outputnode, "mod_wm")
    workflow.connect(segment, "modulated_gm_image", outputnode, "mod_gm")
    workflow.connect(segment, "normalized_csf_image", outputnode, "unmod_csf")
    workflow.connect(segment, "normalized_wm_image", outputnode, "unmod_wm")
    workflow.connect(segment, "normalized_gm_image", outputnode, "unmod_gm")
    workflow.connect(mean, "outputspec.mean_image", outputnode, "mean")
    workflow.connect(normalize_struct, "normalized_files", outputnode, "normalized_struct")
    workflow.connect(segment, "transformation_mat", outputnode, "normalization_parameters")
    workflow.connect(segment, "inverse_transformation_mat", outputnode, "reverse_normalize_parameters")

    # CONNECT TO CONFIG

    workflow.inputs.inputspec.fwhm = c.fwhm
    workflow.inputs.inputspec.subjects_dir = c.surf_dir
    workflow.inputs.inputspec.norm_threshold = c.norm_thresh
    workflow.inputs.inputspec.zintensity_threshold = c.z_thresh
    workflow.inputs.inputspec.node = c.motion_correct_node
    workflow.inputs.inputspec.tr = c.TR
    workflow.inputs.inputspec.do_slicetime = c.do_slicetiming
    workflow.inputs.inputspec.sliceorder = c.SliceOrder
    workflow.inputs.inputspec.csf_prob = c.csf_prob
    workflow.inputs.inputspec.gm_prob = c.grey_prob
    workflow.inputs.inputspec.wm_prob = c.white_prob
    workflow.inputs.inputspec.parameters = {"order": c.order}
    workflow.base_dir = c.working_dir
    workflow.config = {"execution": {"crashdump_dir": c.crash_dir}}

    datagrabber = get_dataflow(c)

    workflow.connect(datagrabber, "func", inputnode, "functionals")

    infosource = pe.Node(niu.IdentityInterface(fields=["subject_id"]), name="subject_names")
    if not c.test_mode:
        infosource.iterables = ("subject_id", c.subjects)
    else:
        infosource.iterables = ("subject_id", c.subjects[:1])

    workflow.connect(infosource, "subject_id", inputnode, "subject_id")
    workflow.connect(infosource, "subject_id", datagrabber, "subject_id")
    sub = lambda x: [("_subject_id_%s" % x, "")]

    sinker = pe.Node(nio.DataSink(), name="sinker")
    workflow.connect(infosource, "subject_id", sinker, "container")
    workflow.connect(infosource, ("subject_id", sub), sinker, "substitutions")
    sinker.inputs.base_directory = c.sink_dir
    outputspec = workflow.get_node("outputspec")
    workflow.connect(outputspec, "realignment_parameters", sinker, "spm_preproc.realignment_parameters")
    workflow.connect(outputspec, "smoothed_files", sinker, "spm_preproc.smoothed_outputs")
    workflow.connect(outputspec, "outlier_files", sinker, "spm_preproc.art.@outlier_files")
    workflow.connect(outputspec, "outlier_stats", sinker, "spm_preproc.art.@outlier_stats")
    workflow.connect(outputspec, "outlier_plots", sinker, "spm_preproc.art.@outlier_plots")
    workflow.connect(outputspec, "norm_components", sinker, "spm_preproc.art.@norm")
    workflow.connect(outputspec, "reg_file", sinker, "spm_preproc.bbreg.@reg_file")
    workflow.connect(outputspec, "reg_cost", sinker, "spm_preproc.bbreg.@reg_cost")
    workflow.connect(outputspec, "mask_file", sinker, "spm_preproc.mask.@mask_file")
    workflow.connect(outputspec, "mod_csf", sinker, "spm_preproc.segment.mod.@csf")
    workflow.connect(outputspec, "mod_wm", sinker, "spm_preproc.segment.mod.@wm")
    workflow.connect(outputspec, "mod_gm", sinker, "spm_preproc.segment.mod.@gm")
    workflow.connect(outputspec, "unmod_csf", sinker, "spm_preproc.segment.unmod.@csf")
    workflow.connect(outputspec, "unmod_wm", sinker, "spm_preproc.segment.unmod.@wm")
    workflow.connect(outputspec, "unmod_gm", sinker, "spm_preproc.segment.unmod.@gm")
    workflow.connect(outputspec, "mean", sinker, "spm_preproc.mean")
    workflow.connect(outputspec, "normalized_struct", sinker, "spm_preproc.normalized_struct")
    workflow.connect(outputspec, "normalization_parameters", sinker, "spm_preproc.normalization_parameters.@forward")
    workflow.connect(
        outputspec, "reverse_normalize_parameters", sinker, "spm_preproc.normalization_parameters.@reverse"
    )

    return workflow
Пример #6
0
def create_spm_preproc(c, name='preproc'):
    """Create an spm preprocessing workflow with freesurfer registration and
artifact detection.

The workflow realigns and smooths and registers the functional images with
the subject's freesurfer space.

Example
-------

>>> preproc = create_spm_preproc()
>>> preproc.base_dir = '.'
>>> preproc.inputs.inputspec.fwhm = 6
>>> preproc.inputs.inputspec.subject_id = 's1'
>>> preproc.inputs.inputspec.subjects_dir = '.'
>>> preproc.inputs.inputspec.functionals = ['f3.nii', 'f5.nii']
>>> preproc.inputs.inputspec.norm_threshold = 1
>>> preproc.inputs.inputspec.zintensity_threshold = 3

Inputs::

inputspec.functionals : functional runs use 4d nifti
inputspec.subject_id : freesurfer subject id
inputspec.subjects_dir : freesurfer subjects dir
inputspec.fwhm : smoothing fwhm
inputspec.norm_threshold : norm threshold for outliers
inputspec.zintensity_threshold : intensity threshold in z-score

Outputs::

outputspec.realignment_parameters : realignment parameter files
outputspec.smoothed_files : smoothed functional files
outputspec.outlier_files : list of outliers
outputspec.outlier_stats : statistics of outliers
outputspec.outlier_plots : images of outliers
outputspec.mask_file : binary mask file in reference image space
outputspec.reg_file : registration file that maps reference image to
freesurfer space
outputspec.reg_cost : cost of registration (useful for detecting misalignment)
"""
    from nipype.workflows.smri.freesurfer.utils import create_getmask_flow
    import nipype.algorithms.rapidart as ra
    import nipype.interfaces.spm as spm
    import nipype.interfaces.utility as niu
    import nipype.pipeline.engine as pe
    import nipype.interfaces.io as nio

    """
Initialize the workflow
"""

    workflow = pe.Workflow(name=name)

    """
Define the inputs to this workflow
"""

    inputnode = pe.Node(niu.IdentityInterface(fields=['functionals',
                                                      'subject_id',
                                                      'subjects_dir',
                                                      'fwhm',
                                                      'norm_threshold',
                                                      'zintensity_threshold',
                                                      'tr',
                                                      'do_slicetime',
                                                      'sliceorder',
                                                      'node',
                                                      'csf_prob','wm_prob','gm_prob']),
        name='inputspec')

    """
Setup the processing nodes and create the mask generation and coregistration
workflow
"""

    poplist = lambda x: x.pop()
    #realign = pe.Node(spm.Realign(), name='realign')
    
    sym_func = pe.Node(niu.Function(input_names=['in_file'],output_names=['out_link'],function=do_symlink),name='func_symlink')

    realign = pe.Node(niu.Function(input_names=['node','in_file','tr','do_slicetime','sliceorder'],
        output_names=['out_file','par_file'],
        function=mod_realign),
        name="mod_realign")

    mean = art_mean_workflow()
    workflow.connect(realign,'out_file', mean, 'inputspec.realigned_files')
    workflow.connect(realign,'par_file', mean, 'inputspec.realignment_parameters')
    mean.inputs.inputspec.parameter_source='FSL' # Modular realign puts it in FSL format for consistency

    #workflow.connect(inputnode, 'functionals', realign, 'in_file')
    workflow.connect(inputnode,'functionals', sym_func, 'in_file')
    workflow.connect(sym_func,'out_link',realign,'in_file')

    workflow.connect(inputnode, 'tr',
        realign, 'tr')
    workflow.connect(inputnode, 'do_slicetime',
        realign, 'do_slicetime')
    workflow.connect(inputnode, 'sliceorder',
        realign, 'sliceorder')
    workflow.connect(inputnode, 'node',
        realign, 'node')

    maskflow = create_getmask_flow()
    workflow.connect([(inputnode, maskflow, [('subject_id','inputspec.subject_id'),
        ('subjects_dir', 'inputspec.subjects_dir')])])
    maskflow.inputs.inputspec.contrast_type = 't2'
    workflow.connect(mean, 'outputspec.mean_image', maskflow, 'inputspec.source_file')
    smooth = pe.Node(spm.Smooth(), name='smooth')

    normalize = pe.Node(spm.Normalize(jobtype='write'),name='normalize')
    normalize_struct = normalize.clone('normalize_struct')
    segment = pe.Node(spm.Segment(csf_output_type=[True,True,False],
                                  gm_output_type=[True,True,False],
                                  wm_output_type=[True,True,False]),name='segment')

    mergefunc = lambda in1,in2,in3:[in1,in2,in3]

    # merge = pe.Node(niu.Merge(),name='merge')
    merge = pe.Node(niu.Function(input_names=['in1','in2','in3'],output_names=['out'],function=mergefunc),name='merge')
    workflow.connect(inputnode,'csf_prob',merge,'in3')
    workflow.connect(inputnode,'wm_prob',merge,'in2')
    workflow.connect(inputnode,'gm_prob',merge,'in1')

    #workflow.connect(merge,'out', segment,'tissue_prob_maps')

    sym_prob = sym_func.clone('sym_prob')
    workflow.connect(merge,'out',sym_prob,'in_file')
    workflow.connect(sym_prob,'out_link',segment,'tissue_prob_maps')

    workflow.connect(maskflow,('outputspec.mask_file',pickfirst),segment,'mask_image')
    workflow.connect(inputnode, 'fwhm', smooth, 'fwhm')

    #sym_brain = sym_func.clone('sym_brain')
    #workflow.connect(realign, 'mean_image', normalize, 'source')
    #workflow.connect(maskflow,'fssource.brain',segment,'data')
    fssource = maskflow.get_node('fssource')
    import nipype.interfaces.freesurfer as fs
    convert_brain = pe.Node(interface=fs.ApplyVolTransform(inverse=True),name='convert')
    workflow.connect(fssource,'brain',convert_brain,'target_file')
    workflow.connect(maskflow,('outputspec.reg_file',pickfirst),convert_brain,'reg_file')
    workflow.connect(mean,'outputspec.mean_image',convert_brain,'source_file')
    convert2nii = pe.Node(fs.MRIConvert(in_type='mgz',out_type='nii'),name='convert2nii')
    workflow.connect(convert_brain,'transformed_file',convert2nii,'in_file')
    workflow.connect(convert2nii,'out_file',segment,'data')    

    workflow.connect(segment, 'transformation_mat', normalize, 'parameter_file')
    workflow.connect(segment, 'transformation_mat', normalize_struct, 'parameter_file')
    workflow.connect(convert2nii,'out_file',normalize_struct, 'apply_to_files')
    workflow.connect(realign,'out_file',normalize, 'apply_to_files')
    #normalize.inputs.template='/software/spm8/templates/EPI.nii'
    workflow.connect(normalize,'normalized_files',smooth,'in_files')
    #workflow.connect(realign, 'realigned_files', smooth, 'in_files')

    artdetect = pe.Node(ra.ArtifactDetect(mask_type='file',
        parameter_source='FSL',
        use_differences=[True,False],
        use_norm=True,
        save_plot=True),
        name='artdetect')
    workflow.connect([(inputnode, artdetect,[('norm_threshold', 'norm_threshold'),
        ('zintensity_threshold',
         'zintensity_threshold')])])
    workflow.connect([(realign, artdetect, [('out_file', 'realigned_files'),
        ('par_file',
         'realignment_parameters')])])
    workflow.connect(maskflow, ('outputspec.mask_file', poplist), artdetect, 'mask_file')

    """
Define the outputs of the workflow and connect the nodes to the outputnode
"""

    outputnode = pe.Node(niu.IdentityInterface(fields=["realignment_parameters",
                                                       "smoothed_files",
                                                       "mask_file",
                                                       "mean_image",
                                                       "reg_file",
                                                       "reg_cost",
                                                       'outlier_files',
                                                       'outlier_stats',
                                                       'outlier_plots',
                                                       'norm_components',
                                                       'mod_csf',
                                                       'unmod_csf',
                                                       'mod_wm',
                                                       'unmod_wm',
                                                       'mod_gm',
                                                       'unmod_gm',
                                                       'mean',
                                                       'normalized_struct',
                                                       'struct_in_functional_space',
                                                       'normalization_parameters',
                                                       'reverse_normalize_parameters'
    ]),
        name="outputspec")
    workflow.connect([
        (maskflow, outputnode, [("outputspec.reg_file", "reg_file")]),
        (maskflow, outputnode, [("outputspec.reg_cost", "reg_cost")]),
        (maskflow, outputnode, [(("outputspec.mask_file", poplist), "mask_file")]),
        (realign, outputnode, [('par_file', 'realignment_parameters')]),
        (smooth, outputnode, [('smoothed_files', 'smoothed_files')]),
        (artdetect, outputnode,[('outlier_files', 'outlier_files'),
            ('statistic_files','outlier_stats'),
            ('plot_files','outlier_plots'),
            ('norm_files','norm_components')])
    ])
    workflow.connect(segment,'modulated_csf_image',outputnode,'mod_csf')
    workflow.connect(segment,'modulated_wm_image',outputnode,'mod_wm')
    workflow.connect(segment,'modulated_gm_image',outputnode,'mod_gm')
    workflow.connect(segment,'normalized_csf_image',outputnode,'unmod_csf')
    workflow.connect(segment,'normalized_wm_image',outputnode,'unmod_wm')
    workflow.connect(segment,'normalized_gm_image',outputnode,'unmod_gm')
    workflow.connect(mean,'outputspec.mean_image',outputnode, 'mean')
    workflow.connect(normalize_struct, 'normalized_files', outputnode, 'normalized_struct')
    workflow.connect(segment,'transformation_mat', outputnode,'normalization_parameters')
    workflow.connect(segment,'inverse_transformation_mat',outputnode,'reverse_normalize_parameters')
    workflow.connect(convert2nii,'out_file',outputnode,'struct_in_functional_space')

    workflow.inputs.inputspec.fwhm = c.fwhm
    workflow.inputs.inputspec.subjects_dir = c.surf_dir
    workflow.inputs.inputspec.norm_threshold = c.norm_thresh
    workflow.inputs.inputspec.zintensity_threshold = c.z_thresh
    workflow.inputs.inputspec.node = c.motion_correct_node
    workflow.inputs.inputspec.tr = c.TR
    workflow.inputs.inputspec.do_slicetime = c.do_slicetiming
    workflow.inputs.inputspec.sliceorder = c.SliceOrder
    workflow.inputs.inputspec.csf_prob = c.csf_prob
    workflow.inputs.inputspec.gm_prob = c.grey_prob
    workflow.inputs.inputspec.wm_prob = c.white_prob
    workflow.base_dir = c.working_dir
    workflow.config = {'execution': {'crashdump_dir': c.crash_dir}}

    datagrabber = get_dataflow(c)

    workflow.connect(datagrabber,'func',inputnode,'functionals')

    infosource = pe.Node(niu.IdentityInterface(fields=['subject_id']),
        name='subject_names')
    if not c.test_mode:
        infosource.iterables = ('subject_id', c.subjects)
    else:
        infosource.iterables = ('subject_id', c.subjects[:1])


    workflow.connect(infosource,'subject_id',inputnode,'subject_id')
    workflow.connect(infosource,'subject_id',datagrabber,'subject_id')
    sub = lambda x: [('_subject_id_%s'%x,'')]

    sinker = pe.Node(nio.DataSink(),name='sinker')
    workflow.connect(infosource,'subject_id',sinker,'container')
    workflow.connect(infosource,('subject_id',sub),sinker,'substitutions')
    sinker.inputs.base_directory = c.sink_dir
    outputspec = workflow.get_node('outputspec')
    workflow.connect(outputspec,'realignment_parameters',sinker,'spm_preproc.realignment_parameters')
    workflow.connect(outputspec,'smoothed_files',sinker,'spm_preproc.smoothed_outputs')
    workflow.connect(outputspec,'outlier_files',sinker,'spm_preproc.art.@outlier_files')
    workflow.connect(outputspec,'outlier_stats',sinker,'spm_preproc.art.@outlier_stats')
    workflow.connect(outputspec,'outlier_plots',sinker,'spm_preproc.art.@outlier_plots')
    workflow.connect(outputspec,'norm_components',sinker,'spm_preproc.art.@norm')
    workflow.connect(outputspec,'reg_file',sinker,'spm_preproc.bbreg.@reg_file')
    workflow.connect(outputspec,'reg_cost',sinker,'spm_preproc.bbreg.@reg_cost')
    workflow.connect(outputspec,'mask_file',sinker,'spm_preproc.mask.@mask_file')
    workflow.connect(outputspec,'mod_csf',sinker,'spm_preproc.segment.mod.@csf')
    workflow.connect(outputspec,'mod_wm',sinker,'spm_preproc.segment.mod.@wm')
    workflow.connect(outputspec,'mod_gm',sinker,'spm_preproc.segment.mod.@gm')
    workflow.connect(outputspec,'unmod_csf',sinker,'spm_preproc.segment.unmod.@csf')
    workflow.connect(outputspec,'unmod_wm',sinker,'spm_preproc.segment.unmod.@wm')
    workflow.connect(outputspec,'unmod_gm',sinker,'spm_preproc.segment.unmod.@gm')
    workflow.connect(outputspec,'mean',sinker,'spm_preproc.mean')
    workflow.connect(outputspec,'normalized_struct', sinker, 'spm_preproc.normalized_struct')
    workflow.connect(outputspec,'normalization_parameters',sinker,'spm_preproc.normalization_parameters.@forward')
    workflow.connect(outputspec,'reverse_normalize_parameters',sinker,'spm_preproc.normalization_parameters.@reverse')
    workflow.connect(outputspec,'struct_in_functional_space',sinker,'spm_preproc.struct_in_func_space')

    return workflow
def create_spm_preproc(c, name='preproc'):
    """
"""

    from nipype.workflows.smri.freesurfer.utils import create_getmask_flow
    import nipype.algorithms.rapidart as ra
    import nipype.interfaces.spm as spm
    import nipype.interfaces.utility as niu
    import nipype.pipeline.engine as pe
    import nipype.interfaces.io as nio
    import nipype.interfaces.freesurfer as fs


    workflow = pe.Workflow(name=name)

    inputnode = pe.Node(niu.IdentityInterface(fields=['functionals',
                                                      'subject_id',
                                                      'subjects_dir',
                                                      'fwhm',
                                                      'norm_threshold',
                                                      'zintensity_threshold',
                                                      'tr',
                                                      'do_slicetime',
                                                      'sliceorder',
                                                      'parameters',
                                                      'node',
                                                      'csf_prob','wm_prob','gm_prob']),
        name='inputspec')

    poplist = lambda x: x.pop()
    
    sym_func = pe.Node(niu.Function(input_names=['in_file'],output_names=['out_link'],function=do_symlink),name='func_symlink')

    # REALIGN

    realign = pe.Node(niu.Function(input_names=['node','in_file','tr','do_slicetime','sliceorder','parameters'],
        output_names=['out_file','par_file','parameter_source'],
        function=mod_realign),
        name="mod_realign")
    workflow.connect(inputnode,'parameters',realign,'parameters')
    workflow.connect(inputnode,'functionals', realign, 'in_file')
    workflow.connect(inputnode, 'tr', realign, 'tr')
    workflow.connect(inputnode, 'do_slicetime', realign, 'do_slicetime')
    workflow.connect(inputnode, 'sliceorder', realign, 'sliceorder')
    workflow.connect(inputnode, 'node', realign, 'node')

   # TAKE MEAN IMAGE

    mean = art_mean_workflow()
    workflow.connect(realign,'out_file', mean, 'inputspec.realigned_files')
    workflow.connect(realign,'par_file', mean, 'inputspec.realignment_parameters')
    workflow.connect(realign,'parameter_source', mean, 'inputspec.parameter_source')

    # CREATE BRAIN MASK

    maskflow = create_getmask_flow()
    workflow.connect([(inputnode, maskflow, [('subject_id','inputspec.subject_id'),
        ('subjects_dir', 'inputspec.subjects_dir')])])
    maskflow.inputs.inputspec.contrast_type = 't2'
    workflow.connect(mean, 'outputspec.mean_image', maskflow, 'inputspec.source_file')

    # SEGMENT

    segment = pe.Node(spm.Segment(csf_output_type=[True,True,False],
                                  gm_output_type=[True,True,False],
                                  wm_output_type=[True,True,False]),name='segment')
    mergefunc = lambda in1,in2,in3:[in1,in2,in3]

    merge = pe.Node(niu.Function(input_names=['in1','in2','in3'],output_names=['out'],function=mergefunc),name='merge')
    workflow.connect(inputnode,'csf_prob',merge,'in3')
    workflow.connect(inputnode,'wm_prob',merge,'in2')
    workflow.connect(inputnode,'gm_prob',merge,'in1')

    sym_prob = sym_func
    workflow.connect(merge,'out',sym_prob,'in_file')
    workflow.connect(sym_prob,'out_link',segment,'tissue_prob_maps')

    xform_mask = pe.Node(fs.ApplyVolTransform(fs_target=True),name='transform_mask')
    workflow.connect(maskflow,('outputspec.reg_file',pickfirst),xform_mask,'reg_file')
    workflow.connect(maskflow,('outputspec.mask_file',pickfirst),xform_mask,'source_file')
    workflow.connect(xform_mask,"transformed_file",segment,'mask_image')

    fssource = maskflow.get_node('fssource')
    convert2nii = pe.Node(fs.MRIConvert(in_type='mgz',out_type='nii'),name='convert2nii')
    workflow.connect(fssource,'brain',convert2nii,'in_file')
    workflow.connect(convert2nii,'out_file',segment,'data')    

    # NORMALIZE

    normalize = pe.MapNode(spm.Normalize(jobtype='write'),name='normalize',iterfield=['apply_to_files'])
    normalize_struct = normalize.clone('normalize_struct')
    normalize_mask = normalize.clone('normalize_mask')

    workflow.connect(segment, 'transformation_mat', normalize, 'parameter_file')
    workflow.connect(segment, 'transformation_mat', normalize_mask, 'parameter_file')
    workflow.connect(segment, 'transformation_mat', normalize_struct, 'parameter_file')
    workflow.connect(convert2nii,'out_file',normalize_struct, 'apply_to_files')
    workflow.connect(xform_mask,"transformed_file",normalize_mask,'apply_to_files')

    xform_image = pe.MapNode(fs.ApplyVolTransform(fs_target=True),name='xform_image',iterfield=['source_file'])
    workflow.connect(maskflow,('outputspec.reg_file',pickfirst),xform_image,'reg_file')
    workflow.connect(realign,'out_file',xform_image,"source_file")
    workflow.connect(xform_image,"transformed_file",normalize,"apply_to_files")


    #SMOOTH

    smooth = pe.Node(spm.Smooth(), name='smooth')

    workflow.connect(inputnode, 'fwhm', smooth, 'fwhm')
    workflow.connect(normalize,'normalized_files',smooth,'in_files')

    # ART

    artdetect = pe.Node(ra.ArtifactDetect(mask_type='file',
        use_differences=[True,False],
        use_norm=True,
        save_plot=True),
        name='artdetect')
    workflow.connect(realign,'parameter_source',artdetect,'parameter_source')
    workflow.connect([(inputnode, artdetect,[('norm_threshold', 'norm_threshold'),
        ('zintensity_threshold',
         'zintensity_threshold')])])
    workflow.connect([(realign, artdetect, [('out_file', 'realigned_files'),
        ('par_file',
         'realignment_parameters')])])
    workflow.connect(maskflow, ('outputspec.mask_file', poplist), artdetect, 'mask_file')


    # OUTPUTS

    outputnode = pe.Node(niu.IdentityInterface(fields=["realignment_parameters",
                                                       "smoothed_files",
                                                       "mask_file",
                                                       "mean_image",
                                                       "reg_file",
                                                       "reg_cost",
                                                       'outlier_files',
                                                       'outlier_stats',
                                                       'outlier_plots',
                                                       'norm_components',
                                                       'mod_csf',
                                                       'unmod_csf',
                                                       'mod_wm',
                                                       'unmod_wm',
                                                       'mod_gm',
                                                       'unmod_gm',
                                                       'mean',
                                                       'normalized_struct',
                                                       'normalization_parameters',
                                                       'reverse_normalize_parameters'
    ]),
        name="outputspec")
    workflow.connect([
        (maskflow, outputnode, [("outputspec.reg_file", "reg_file")]),
        (maskflow, outputnode, [("outputspec.reg_cost", "reg_cost")]),
        (realign, outputnode, [('par_file', 'realignment_parameters')]),
        (smooth, outputnode, [('smoothed_files', 'smoothed_files')]),
        (artdetect, outputnode,[('outlier_files', 'outlier_files'),
            ('statistic_files','outlier_stats'),
            ('plot_files','outlier_plots'),
            ('norm_files','norm_components')])
    ])
    workflow.connect(normalize_mask,"normalized_files",outputnode,"mask_file")
    workflow.connect(segment,'modulated_csf_image',outputnode,'mod_csf')
    workflow.connect(segment,'modulated_wm_image',outputnode,'mod_wm')
    workflow.connect(segment,'modulated_gm_image',outputnode,'mod_gm')
    workflow.connect(segment,'normalized_csf_image',outputnode,'unmod_csf')
    workflow.connect(segment,'normalized_wm_image',outputnode,'unmod_wm')
    workflow.connect(segment,'normalized_gm_image',outputnode,'unmod_gm')
    workflow.connect(mean,'outputspec.mean_image',outputnode, 'mean')
    workflow.connect(normalize_struct, 'normalized_files', outputnode, 'normalized_struct')
    workflow.connect(segment,'transformation_mat', outputnode,'normalization_parameters')
    workflow.connect(segment,'inverse_transformation_mat',outputnode,'reverse_normalize_parameters')
    
    # CONNECT TO CONFIG

    workflow.inputs.inputspec.fwhm = c.fwhm
    workflow.inputs.inputspec.subjects_dir = c.surf_dir
    workflow.inputs.inputspec.norm_threshold = c.norm_thresh
    workflow.inputs.inputspec.zintensity_threshold = c.z_thresh
    workflow.inputs.inputspec.node = c.motion_correct_node
    workflow.inputs.inputspec.tr = c.TR
    workflow.inputs.inputspec.do_slicetime = c.do_slicetiming
    workflow.inputs.inputspec.sliceorder = c.SliceOrder
    workflow.inputs.inputspec.csf_prob = c.csf_prob
    workflow.inputs.inputspec.gm_prob = c.grey_prob
    workflow.inputs.inputspec.wm_prob = c.white_prob
    workflow.inputs.inputspec.parameters = {"order": c.order}
    workflow.base_dir = c.working_dir
    workflow.config = {'execution': {'crashdump_dir': c.crash_dir}}

    datagrabber = get_dataflow(c)

    workflow.connect(datagrabber,'func',inputnode,'functionals')

    infosource = pe.Node(niu.IdentityInterface(fields=['subject_id']),
        name='subject_names')
    if not c.test_mode:
        infosource.iterables = ('subject_id', c.subjects)
    else:
        infosource.iterables = ('subject_id', c.subjects[:1])


    workflow.connect(infosource,'subject_id',inputnode,'subject_id')
    workflow.connect(infosource,'subject_id',datagrabber,'subject_id')
    sub = lambda x: [('_subject_id_%s'%x,'')]

    sinker = pe.Node(nio.DataSink(),name='sinker')
    workflow.connect(infosource,'subject_id',sinker,'container')
    workflow.connect(infosource,('subject_id',sub),sinker,'substitutions')
    sinker.inputs.base_directory = c.sink_dir
    outputspec = workflow.get_node('outputspec')
    workflow.connect(outputspec,'realignment_parameters',sinker,'spm_preproc.realignment_parameters')
    workflow.connect(outputspec,'smoothed_files',sinker,'spm_preproc.smoothed_outputs')
    workflow.connect(outputspec,'outlier_files',sinker,'spm_preproc.art.@outlier_files')
    workflow.connect(outputspec,'outlier_stats',sinker,'spm_preproc.art.@outlier_stats')
    workflow.connect(outputspec,'outlier_plots',sinker,'spm_preproc.art.@outlier_plots')
    workflow.connect(outputspec,'norm_components',sinker,'spm_preproc.art.@norm')
    workflow.connect(outputspec,'reg_file',sinker,'spm_preproc.bbreg.@reg_file')
    workflow.connect(outputspec,'reg_cost',sinker,'spm_preproc.bbreg.@reg_cost')
    workflow.connect(outputspec,'mask_file',sinker,'spm_preproc.mask.@mask_file')
    workflow.connect(outputspec,'mod_csf',sinker,'spm_preproc.segment.mod.@csf')
    workflow.connect(outputspec,'mod_wm',sinker,'spm_preproc.segment.mod.@wm')
    workflow.connect(outputspec,'mod_gm',sinker,'spm_preproc.segment.mod.@gm')
    workflow.connect(outputspec,'unmod_csf',sinker,'spm_preproc.segment.unmod.@csf')
    workflow.connect(outputspec,'unmod_wm',sinker,'spm_preproc.segment.unmod.@wm')
    workflow.connect(outputspec,'unmod_gm',sinker,'spm_preproc.segment.unmod.@gm')
    workflow.connect(outputspec,'mean',sinker,'spm_preproc.mean')
    workflow.connect(outputspec,'normalized_struct', sinker, 'spm_preproc.normalized_struct')
    workflow.connect(outputspec,'normalization_parameters',sinker,'spm_preproc.normalization_parameters.@forward')
    workflow.connect(outputspec,'reverse_normalize_parameters',sinker,'spm_preproc.normalization_parameters.@reverse')

    return workflow
def simple_preproc(c):
    from .fmri_preprocessing import extract_meta
    import nipype.pipeline.engine as pe
    import nipype.interfaces.utility as util
    from ...scripts.modular_nodes import mod_realign
    from nipype.workflows.smri.freesurfer.utils import create_getmask_flow
    from ...scripts.utils import art_mean_workflow
    from nipype.algorithms.misc import TSNR
    import nipype.interfaces.io as nio
    import nipype.interfaces.fsl as fsl

    wf = pe.Workflow(name='simple_preproc')
    datagrabber = c.datagrabber.create_dataflow()
    infosource = datagrabber.get_node('subject_id_iterable')
    img2float = pe.MapNode(interface=fsl.ImageMaths(out_data_type='float',
        op_string='',
        suffix='_dtype'),
        iterfield=['in_file'],
        name='img2float')
    motion_correct = pe.Node(util.Function(input_names=['node','in_file','tr',
                                                        'do_slicetime','sliceorder',"parameters"],
        output_names=['out_file','par_file','parameter_source'],
        function=mod_realign),
        name="mod_realign")

    meanfunc = art_mean_workflow()
    art = meanfunc.get_node('strict_artifact_detect')
    getmask = create_getmask_flow()

    tsnr = pe.MapNode(TSNR(regress_poly=2),  #SG: advanced parameter
        name='tsnr',
        iterfield=['in_file'])

    if c.use_metadata:
        get_meta = pe.Node(util.Function(input_names=['func'],output_names=['so','tr'],function=extract_meta),name="get_metadata")
        wf.connect(datagrabber,'datagrabber.epi',get_meta, 'func')
        wf.connect(get_meta,'so',motion_correct,"sliceorder")
        wf.connect(get_meta,'tr',motion_correct,"tr")
    else:
        motion_correct.inputs.sliceorder = c.SliceOrder
        motion_correct.inputs.tr = c.TR

    # inputs
    motion_correct.inputs.do_slicetime = c.do_slicetiming
    motion_correct.inputs.node = c.motion_correct_node
    motion_correct.inputs.parameters = {"loops":c.loops,
                                                   "speedup":c.speedup,
                                                   "order": c.order}
    wf.connect(datagrabber,'datagrabber.epi',img2float,'in_file')
    wf.connect(img2float,'out_file', motion_correct,'in_file')
    wf.connect(motion_correct,'out_file',meanfunc,'inputspec.realigned_files')
    wf.connect(motion_correct,'parameter_source',meanfunc,'inputspec.parameter_source')
    wf.connect(motion_correct,'par_file',meanfunc,'inputspec.realignment_parameters')


    wf.connect(motion_correct,'out_file',tsnr,'in_file')

    wf.connect(meanfunc,'outputspec.mean_image',getmask,'inputspec.source_file')
    wf.connect(infosource,'subject_id',getmask,'inputspec.subject_id')
    getmask.inputs.inputspec.subjects_dir = c.surf_dir
    getmask.inputs.inputspec.contrast_type = 't2'

    sink = pe.Node(nio.DataSink(),name='sinker')
    sink.inputs.base_directory = c.sink_dir
    wf.connect(infosource,'subject_id',sink,'container')
    wf.connect(infosource,('subject_id', get_substitutions),sink,'substitutions')
    wf.connect(motion_correct,'out_file',sink,'simple_preproc.output')
    wf.connect(motion_correct,'par_file',sink,'simple_preproc.motion')
    wf.connect(meanfunc,'outputspec.mean_image',sink,'simple_preproc.mean')
    wf.connect(getmask,'outputspec.mask_file',sink,'simple_preproc.mask')
    wf.connect(getmask,'outputspec.reg_file',sink,'simple_preproc.bbreg.@reg')
    wf.connect(getmask,'outputspec.reg_cost',sink,'simple_preproc.bbreg.@regcost')
    wf.connect(tsnr,'tsnr_file',sink,'simple_preproc.tsnr.@tsnr')
    wf.connect(tsnr,'detrended_file',sink,'simple_preproc.tsnr.@detrended')
    wf.connect(tsnr,'stddev_file',sink,'simple_preproc.tsnr.@stddev')
    wf.connect(tsnr,'mean_file',sink,'simple_preproc.tsnr.@mean')
    wf.connect(art,'intensity_files',sink,'simple_preproc.art.@intensity')
    wf.connect(art,'norm_files',sink,'simple_preproc.art.@norm')
    wf.connect(art,'outlier_files',sink,'simple_preproc.art.@outlier')
    wf.connect(art,'statistic_files',sink,'simple_preproc.art.@stats')

    return wf
Пример #9
0
def simple_preproc(c):
    from .fmri_preprocessing import extract_meta
    import nipype.pipeline.engine as pe
    import nipype.interfaces.utility as util
    from ...scripts.modular_nodes import mod_realign
    from nipype.workflows.smri.freesurfer.utils import create_getmask_flow
    from ...scripts.utils import art_mean_workflow
    from nipype.algorithms.misc import TSNR
    import nipype.interfaces.io as nio
    import nipype.interfaces.fsl as fsl

    wf = pe.Workflow(name='simple_preproc')
    datagrabber = c.datagrabber.create_dataflow()
    infosource = datagrabber.get_node('subject_id_iterable')
    img2float = pe.MapNode(interface=fsl.ImageMaths(out_data_type='float',
                                                    op_string='',
                                                    suffix='_dtype'),
                           iterfield=['in_file'],
                           name='img2float')
    motion_correct = pe.Node(util.Function(
        input_names=[
            'node', 'in_file', 'tr', 'do_slicetime', 'sliceorder', "parameters"
        ],
        output_names=['out_file', 'par_file', 'parameter_source'],
        function=mod_realign),
                             name="mod_realign")

    meanfunc = art_mean_workflow()
    art = meanfunc.get_node('strict_artifact_detect')
    getmask = create_getmask_flow()

    tsnr = pe.MapNode(
        TSNR(regress_poly=2),  #SG: advanced parameter
        name='tsnr',
        iterfield=['in_file'])

    if c.use_metadata:
        get_meta = pe.Node(util.Function(input_names=['func'],
                                         output_names=['so', 'tr'],
                                         function=extract_meta),
                           name="get_metadata")
        wf.connect(datagrabber, 'datagrabber.epi', get_meta, 'func')
        wf.connect(get_meta, 'so', motion_correct, "sliceorder")
        wf.connect(get_meta, 'tr', motion_correct, "tr")
    else:
        motion_correct.inputs.sliceorder = c.SliceOrder
        motion_correct.inputs.tr = c.TR

    # inputs
    motion_correct.inputs.do_slicetime = c.do_slicetiming
    motion_correct.inputs.node = c.motion_correct_node
    motion_correct.inputs.parameters = {
        "loops": c.loops,
        "speedup": c.speedup,
        "order": c.order
    }
    wf.connect(datagrabber, 'datagrabber.epi', img2float, 'in_file')
    wf.connect(img2float, 'out_file', motion_correct, 'in_file')
    wf.connect(motion_correct, 'out_file', meanfunc,
               'inputspec.realigned_files')
    wf.connect(motion_correct, 'parameter_source', meanfunc,
               'inputspec.parameter_source')
    wf.connect(motion_correct, 'par_file', meanfunc,
               'inputspec.realignment_parameters')

    wf.connect(motion_correct, 'out_file', tsnr, 'in_file')

    wf.connect(meanfunc, 'outputspec.mean_image', getmask,
               'inputspec.source_file')
    wf.connect(infosource, 'subject_id', getmask, 'inputspec.subject_id')
    getmask.inputs.inputspec.subjects_dir = c.surf_dir
    getmask.inputs.inputspec.contrast_type = 't2'

    sink = pe.Node(nio.DataSink(), name='sinker')
    sink.inputs.base_directory = c.sink_dir
    wf.connect(infosource, 'subject_id', sink, 'container')
    wf.connect(infosource, ('subject_id', get_substitutions), sink,
               'substitutions')
    wf.connect(motion_correct, 'out_file', sink, 'simple_preproc.output')
    wf.connect(motion_correct, 'par_file', sink, 'simple_preproc.motion')
    wf.connect(meanfunc, 'outputspec.mean_image', sink, 'simple_preproc.mean')
    wf.connect(getmask, 'outputspec.mask_file', sink, 'simple_preproc.mask')
    wf.connect(getmask, 'outputspec.reg_file', sink,
               'simple_preproc.bbreg.@reg')
    wf.connect(getmask, 'outputspec.reg_cost', sink,
               'simple_preproc.bbreg.@regcost')
    wf.connect(tsnr, 'tsnr_file', sink, 'simple_preproc.tsnr.@tsnr')
    wf.connect(tsnr, 'detrended_file', sink, 'simple_preproc.tsnr.@detrended')
    wf.connect(tsnr, 'stddev_file', sink, 'simple_preproc.tsnr.@stddev')
    wf.connect(tsnr, 'mean_file', sink, 'simple_preproc.tsnr.@mean')
    wf.connect(art, 'intensity_files', sink, 'simple_preproc.art.@intensity')
    wf.connect(art, 'norm_files', sink, 'simple_preproc.art.@norm')
    wf.connect(art, 'outlier_files', sink, 'simple_preproc.art.@outlier')
    wf.connect(art, 'statistic_files', sink, 'simple_preproc.art.@stats')

    return wf