Ejemplo n.º 1
0
def test_normalize_list_outputs():
    filelist, outdir, cwd = create_files_in_directory()
    norm = spm.Normalize(source=filelist[0])
    yield assert_true, norm._list_outputs()['normalized_source'][0].startswith(
        'w')
    norm = spm.Normalize(source=filelist[0], apply_to_files=filelist[1])
    yield assert_true, norm._list_outputs()['normalized_files'][0].startswith(
        'w')
    clean_directory(outdir, cwd)
Ejemplo n.º 2
0
    def __init__(self, experiment_dir, output_dir, working_dir, func_source,
                 struct_source, datasink):
        self.experiment_dir = experiment_dir
        self.output_dir = output_dir
        self.working_dir = working_dir

        # specify input and output nodes
        self.func_source = func_source
        self.struct_source = struct_source
        self.datasink = datasink

        # specify workflow instance
        self.workflow = pe.Workflow(name='workflow')

        # specify nodes
        self.realign = pe.Node(interface=spm.Realign(), name='realign')

        self.coregister = pe.Node(interface=spm.Coregister(),
                                  name="coregister")
        self.coregister.inputs.jobtype = 'estimate'

        self.segment = pe.Node(interface=spm.Segment(), name="segment")

        self.normalize_func = pe.Node(interface=spm.Normalize(),
                                      name="normalize_func")
        self.normalize_func.inputs.jobtype = "write"

        self.normalize_struc = pe.Node(interface=spm.Normalize(),
                                       name="normalize_struc")
        self.normalize_struc.inputs.jobtype = "write"

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

        # connect the nodes to complete the workflow
        self.workflow.connect([
            (self.func_source, self.realign, [('outfiles', 'in_files')]),
            (self.struct_source, self.coregister, [('outfiles', 'source')]),
            (self.realign, self.coregister, [('mean_image', 'target')]),
            (self.coregister, self.segment, [('coregistered_source', 'data')]),
            (self.segment, self.normalize_func, [('transformation_mat',
                                                  'parameter_file')]),
            (self.realign, self.normalize_func, [('realigned_files',
                                                  'apply_to_files')]),
            (self.normalize_func, self.smooth, [('normalized_files',
                                                 'in_files')]),
            #(self.realign, self.datasink, [('realigned_files', 'realign')]),
            #(self.realign, self.datasink, [('mean_image', 'mean')]),
            (self.normalize_func, self.datasink, [('normalized_files', 'norm')]
             ),
            (self.smooth, self.datasink, [('smoothed_files', 'smooth')])
        ])
Ejemplo n.º 3
0
 def __init__(self,
              parameter_file='path',
              source=['path'],
              template='path',
              **options):
     import nipype.interfaces.spm as spm
     norm = spm.Normalize()
     norm.inputs.parameter_file = parameter_file
     norm.inputs.source = source
     norm.inputs.template = template
     for ef in options:
         setattr(norm.inputs, ef, options[ef])
     self.res = norm.run()
Ejemplo n.º 4
0
def test_normalize():
    yield assert_equal, spm.Normalize._jobtype, 'spatial'
    yield assert_equal, spm.Normalize._jobname, 'normalise'
    yield assert_equal, spm.Normalize().inputs.jobtype, 'estwrite'
    input_map = dict(template=dict(field='eoptions.template',
                                   mandatory=True,
                                   xor=['parameter_file'],
                                   copyfile=False),
                     source=dict(field='subj.source',
                                 xor=['parameter_file'],
                                 mandatory=True,
                                 copyfile=True),
                     apply_to_files=dict(field='subj.resample', copyfile=True),
                     parameter_file=dict(field='subj.matname',
                                         mandatory=True,
                                         xor=['source', 'template'],
                                         copyfile=False),
                     source_weight=dict(field='subj.wtsrc', copyfile=False),
                     template_weight=dict(field='eoptions.weight',
                                          copyfile=False),
                     source_image_smoothing=dict(field='eoptions.smosrc'),
                     template_image_smoothing=dict(field='eoptions.smoref'),
                     affine_regularization_type=dict(field='eoptions.regype'),
                     DCT_period_cutoff=dict(field='eoptions.cutoff'),
                     nonlinear_iterations=dict(field='eoptions.nits'),
                     nonlinear_regularization=dict(field='eoptions.reg'),
                     write_preserve=dict(field='roptions.preserve'),
                     write_bounding_box=dict(field='roptions.bb'),
                     write_voxel_sizes=dict(field='roptions.vox'),
                     write_interp=dict(field='roptions.interp'),
                     write_wrap=dict(field='roptions.wrap'))
    norm = spm.Normalize()
    for key, metadata in input_map.items():
        for metakey, value in metadata.items():
            yield assert_equal, getattr(norm.inputs.traits()[key],
                                        metakey), value
Ejemplo n.º 5
0
def simple_warp(template, warped, other=None):
    """ uses basic spm Normalize to warp warped to template
    applies parameters to other if specified"""
    startdir = os.getcwd()
    pth, _ = os.path.split(warped)
    os.chdir(pth)
    warp = spm.Normalize(matlab_cmd='matlab-spm8')
    warp.inputs.template = template
    warp.inputs.source = warped
    warp.inputs.ignore_exception = True
    if other is not None:
        warp.inputs.apply_to_files = other
    warp_out = warp.run()
    os.chdir(startdir)
    return warp_out
Ejemplo n.º 6
0
def normalize_T1_toMNI152(T1_dir, slice_time_dir):

    # Function normalizes an AC-PC aligned T1 into MNI 152 space
    # Get the name of the ac-pc aligned T1
    os.chdir(T1_dir)
    for files in os.listdir(T1_dir):
        if files.startswith('r'):
            T1name = files

    # Get list of EPIs to apply MNI normalization transform result from T1
    EPI_list = []
    os.chdir(slice_time_dir)
    for files in os.listdir(slice_time_dir):
        if files.startswith('ar'):
            EPI_list.append(files)

    # Initialize SPM normalization
    EPI_list.sort()
    mni_template = matlab_dir + '/toolbox/spm8/canonical/avg152T1.nii'
    os.system('cp %s %s' % (mni_template, slice_time_dir))
    # copy spm mni template to cwd
    norm = spm.Normalize()
    norm.inputs.source = T1_dir + '/' + T1name
    norm.inputs.template = mni_template
    norm.inputs.affine_regularization_type = 'mni'
    EPI_list.append(norm.inputs.source)
    # apply normalization to T1 and all EPIs
    norm.inputs.apply_to_files = EPI_list
    print "<:::Normalizing T1 and EPIs to MNI 152:::>"
    norm.run()

    # Make a new dir for MNI warped EPIs
    MNI_dir = os.mkdir('MNI_Normalized')
    os.system('cp w* %s' % (MNI_dir))

    return MNI_dir
Ejemplo n.º 7
0
"""

skullstrip = pe.Node(fsl.BET(), name="skullstrip")
skullstrip.inputs.mask = True
"""Use :class:`nipype.interfaces.spm.Coregister` to perform a rigid
body registration of the functional data to the structural data.
"""

coregister = pe.Node(spm.Coregister(), name="coregister")
coregister.inputs.jobtype = 'estimate'
"""Warp functional and structural data to SPM's T1 template using
:class:`nipype.interfaces.spm.Normalize`.  The tutorial data set
includes the template image, T1.nii.
"""

normalize = pe.Node(spm.Normalize(), name="normalize")
"""Smooth the functional data using
:class:`nipype.interfaces.spm.Smooth`.
"""

smooth = pe.Node(spm.Smooth(), name="smooth")
fwhmlist = [4]
smooth.iterables = ('fwhm', fwhmlist)

preproc.connect([
    (inputnode, normalize, [(('in_data', _template_path), 'template')]),
    (realign, coregister, [('mean_image', 'source'),
                           ('realigned_files', 'apply_to_files')]),
    (coregister, normalize, [('coregistered_files', 'apply_to_files')]),
    (normalize, smooth, [('normalized_files', 'in_files')]),
    (normalize, skullstrip, [('normalized_source', 'in_file')]),
Ejemplo n.º 8
0
"""

skullstrip = pe.Node(interface=fsl.BET(), name="skullstrip")
skullstrip.inputs.mask = True
"""Use :class:`nipype.interfaces.spm.Coregister` to perform a rigid
body registration of the functional data to the structural data.
"""

coregister = pe.Node(interface=spm.Coregister(), name="coregister")
coregister.inputs.jobtype = 'estimate'
"""Warp functional and structural data to SPM's T1 template using
:class:`nipype.interfaces.spm.Normalize`.  The tutorial data set
includes the template image, T1.nii.
"""

normalize = pe.Node(interface=spm.Normalize(), name="normalize")
normalize.inputs.template = os.path.abspath('data/T1.nii')
"""Smooth the functional data using
:class:`nipype.interfaces.spm.Smooth`.
"""

smooth = pe.Node(interface=spm.Smooth(), name="smooth")
fwhmlist = [4]
smooth.iterables = ('fwhm', fwhmlist)

preproc.connect([
    (realign, coregister, [('mean_image', 'source'),
                           ('realigned_files', 'apply_to_files')]),
    (coregister, normalize, [('coregistered_files', 'apply_to_files')]),
    (normalize, smooth, [('normalized_files', 'in_files')]),
    (normalize, skullstrip, [('normalized_source', 'in_file')]),
Ejemplo n.º 9
0
segment = pe.Node(interface=spm.Segment(), name='segment')
"""
Use :class:`nipype.interfaces.freesurfer.ApplyVolTransform` to convert contrast
images into freesurfer space.
"""

normwreg = pe.MapNode(interface=fs.ApplyVolTransform(),
                      iterfield=['source_file'],
                      name='applyreg2con')
"""
Use :class:`nipype.interfaces.spm.Normalize` to normalize the contrast images
to MNI space
"""

normalize = pe.Node(interface=spm.Normalize(jobtype='write'), name='norm2mni')
"""
Connect up the volume normalization components
"""

volnorm.connect([
    (convert, segment, [('out_file', 'data')]),
    (convert2, normwreg, [('out_file', 'source_file')]),
    (segment, normalize, [('transformation_mat', 'parameter_file')]),
    (normwreg, normalize, [('transformed_file', 'apply_to_files')]),
])
"""
Preproc + Analysis + VolumeNormalization workflow
-------------------------------------------------

Connect up the lower level workflows into an integrated analysis. In addition,
Ejemplo n.º 10
0
def test_normalize_list_outputs(create_files_in_directory):
    filelist, outdir, cwd = create_files_in_directory
    norm = spm.Normalize(source=filelist[0])
    assert norm._list_outputs()['normalized_source'][0].startswith('w')
    norm = spm.Normalize(source=filelist[0], apply_to_files=filelist[1])
    assert norm._list_outputs()['normalized_files'][0].startswith('w')
Ejemplo n.º 11
0
def test_normalize():
    assert spm.Normalize._jobtype == 'spatial'
    assert spm.Normalize._jobname == 'normalise'
    assert spm.Normalize().inputs.jobtype == 'estwrite'
Ejemplo n.º 12
0
def create_spm_preproc_func_pipeline(data_dir=None,
                                     subject_id=None,
                                     task_list=None):

    ###############################
    ## Set up Nodes
    ###############################

    ds = Node(nio.DataGrabber(infields=['subject_id', 'task_id'],
                              outfields=['func', 'struc']),
              name='datasource')
    ds.inputs.base_directory = os.path.abspath(data_dir + '/' + subject_id)
    ds.inputs.template = '*'
    ds.inputs.sort_filelist = True
    ds.inputs.template_args = {'func': [['task_id']], 'struc': []}
    ds.inputs.field_template = {
        'func': 'Functional/Raw/%s/func.nii',
        'struc': 'Structural/SPGR/spgr.nii'
    }
    ds.inputs.subject_id = subject_id
    ds.inputs.task_id = task_list
    ds.iterables = ('task_id', task_list)
    # ds.run().outputs #show datafiles

    # #Setup Data Sinker for writing output files
    # datasink = Node(nio.DataSink(), name='sinker')
    # datasink.inputs.base_directory = '/path/to/output'
    # workflow.connect(realigner, 'realignment_parameters', datasink, 'motion.@par')
    # datasink.inputs.substitutions = [('_variable', 'variable'),('file_subject_', '')]

    #Get Timing Acquisition for slice timing
    tr = 2
    ta = Node(interface=util.Function(input_names=['tr', 'n_slices'],
                                      output_names=['ta'],
                                      function=get_ta),
              name="ta")
    ta.inputs.tr = tr

    #Slice Timing: sequential ascending
    slice_timing = Node(interface=spm.SliceTiming(), name="slice_timing")
    slice_timing.inputs.time_repetition = tr
    slice_timing.inputs.ref_slice = 1

    #Realignment - 6 parameters - realign to first image of very first series.
    realign = Node(interface=spm.Realign(), name="realign")
    realign.inputs.register_to_mean = True

    #Plot Realignment
    plot_realign = Node(interface=PlotRealignmentParameters(),
                        name="plot_realign")

    #Artifact Detection
    art = Node(interface=ra.ArtifactDetect(), name="art")
    art.inputs.use_differences = [True, False]
    art.inputs.use_norm = True
    art.inputs.norm_threshold = 1
    art.inputs.zintensity_threshold = 3
    art.inputs.mask_type = 'file'
    art.inputs.parameter_source = 'SPM'

    #Coregister - 12 parameters, cost function = 'nmi', fwhm 7, interpolate, don't mask
    #anatomical to functional mean across all available data.
    coregister = Node(interface=spm.Coregister(), name="coregister")
    coregister.inputs.jobtype = 'estimate'

    # Segment structural, gray/white/csf,mni,
    segment = Node(interface=spm.Segment(), name="segment")
    segment.inputs.save_bias_corrected = True

    #Normalize - structural to MNI - then apply this to the coregistered functionals
    normalize = Node(interface=spm.Normalize(), name="normalize")
    normalize.inputs.template = os.path.abspath(t1_template_file)

    #Plot normalization Check
    plot_normalization_check = Node(interface=Plot_Coregistration_Montage(),
                                    name="plot_normalization_check")
    plot_normalization_check.inputs.canonical_img = canonical_file

    #Create Mask
    compute_mask = Node(interface=ComputeMask(), name="compute_mask")
    #remove lower 5% of histogram of mean image
    compute_mask.inputs.m = .05

    #Smooth
    #implicit masking (.im) = 0, dtype = 0
    smooth = Node(interface=spm.Smooth(), name="smooth")
    fwhmlist = [0, 5, 8]
    smooth.iterables = ('fwhm', fwhmlist)

    #Create Covariate matrix
    make_covariates = Node(interface=Create_Covariates(),
                           name="make_covariates")

    ###############################
    ## Create Pipeline
    ###############################

    Preprocessed = Workflow(name="Preprocessed")
    Preprocessed.base_dir = os.path.abspath(data_dir + '/' + subject_id +
                                            '/Functional')

    Preprocessed.connect([
        (ds, ta, [(('func', get_n_slices), "n_slices")]),
        (ta, slice_timing, [("ta", "time_acquisition")]),
        (ds, slice_timing, [
            ('func', 'in_files'),
            (('func', get_n_slices), "num_slices"),
            (('func', get_slice_order), "slice_order"),
        ]),
        (slice_timing, realign, [('timecorrected_files', 'in_files')]),
        (realign, compute_mask, [('mean_image', 'mean_volume')]),
        (realign, coregister, [('mean_image', 'target')]),
        (ds, coregister, [('struc', 'source')]),
        (coregister, segment, [('coregistered_source', 'data')]),
        (segment, normalize, [
            ('transformation_mat', 'parameter_file'),
            ('bias_corrected_image', 'source'),
        ]),
        (realign, normalize, [('realigned_files', 'apply_to_files'),
                              (('realigned_files', get_vox_dims),
                               'write_voxel_sizes')]),
        (normalize, smooth, [('normalized_files', 'in_files')]),
        (compute_mask, art, [('brain_mask', 'mask_file')]),
        (realign, art, [('realignment_parameters', 'realignment_parameters')]),
        (realign, art, [('realigned_files', 'realigned_files')]),
        (realign, plot_realign, [('realignment_parameters',
                                  'realignment_parameters')]),
        (normalize, plot_normalization_check, [('normalized_files', 'wra_img')
                                               ]),
        (realign, make_covariates, [('realignment_parameters',
                                     'realignment_parameters')]),
        (art, make_covariates, [('outlier_files', 'spike_id')]),
    ])
    return Preprocessed
Ejemplo n.º 13
0
    def __init__(self,
                 subject,
                 func_source,
                 struct_source,
                 datasink,
                 TR,
                 num_slices,
                 dim=2):
        self.subject = subject
        # specify input and output nodes
        self.func_source = func_source
        self.struct_source = struct_source
        self.datasink = datasink

        self.TR = TR
        self.num_slices = num_slices

        # specify nodes
        # structual process
        self.bet_struct = pe.Node(interface=fsl.BET(),
                                  name='non_brain_removal_BET_struct')
        self.bet_struct.inputs.output_type = "NIFTI"
        self.bet_struct.inputs.frac = 0.3

        self.coregister_struct = pe.Node(interface=spm.Coregister(),
                                         name="coregister_struct_to_mni")
        self.coregister_struct.inputs.target = '/mnt/Program/python/dev/images/MNI152_T1_2mm_brain.nii'
        if dim == 1:
            self.coregister_struct.inputs.target = '/mnt/Program/python/dev/images/MNI152_T1_1mm_brain.nii'
        self.coregister_struct.inputs.write_interp = 7
        self.coregister_struct.inputs.separation = [1.0, 1.0]
        self.coregister_struct.inputs.jobtype = 'estwrite'

        self.segment_struct = pe.Node(interface=spm.Segment(),
                                      name="segment_struct")
        # self.segment_struct.inputs.affine_regularization = 'mni'
        self.segment_struct.inputs.csf_output_type = [True, True, True]
        self.segment_struct.inputs.gm_output_type = [True, True, True]
        self.segment_struct.inputs.wm_output_type = [True, True, True]

        self.normalize_struct = pe.Node(interface=spm.Normalize(),
                                        name='normalize_struct')
        self.normalize_struct.inputs.jobtype = 'write'
        self.normalize_struct.inputs.write_bounding_box = [[-90, -126, -72],
                                                           [90, 90, 108]
                                                           ]  # 91, 109, 91
        if dim == 1:
            self.normalize_struct.inputs.write_bounding_box = [[
                -91, -126, -72
            ], [90, 91, 109]]  # 182, 218, 182
            self.normalize_struct.inputs.write_voxel_sizes = [1, 1, 1]

        self.normalize_gm = pe.Node(interface=spm.Normalize(),
                                    name='normalize_gm')
        self.normalize_gm.inputs.jobtype = 'write'
        self.normalize_gm.inputs.write_bounding_box = [[-90, -126, -72],
                                                       [90, 90,
                                                        108]]  # 91, 109, 91
        if dim == 1:
            self.normalize_gm.inputs.write_bounding_box = [[-91, -126, -72],
                                                           [90, 91, 109]
                                                           ]  # 182, 218, 182
            self.normalize_gm.inputs.write_voxel_sizes = [1, 1, 1]

        self.normalize_wm = pe.Node(interface=spm.Normalize(),
                                    name='normalize_wm')
        self.normalize_wm.inputs.jobtype = 'write'
        self.normalize_wm.inputs.write_bounding_box = [[-90, -126, -72],
                                                       [90, 90,
                                                        108]]  # 91, 109, 91
        if dim == 1:
            self.normalize_wm.inputs.write_bounding_box = [[-91, -126, -72],
                                                           [90, 91, 109]
                                                           ]  # 182, 218, 182
            self.normalize_wm.inputs.write_voxel_sizes = [1, 1, 1]

        self.normalize_csf = pe.Node(interface=spm.Normalize(),
                                     name='normalize_csf')
        self.normalize_csf.inputs.jobtype = 'write'
        self.normalize_csf.inputs.write_bounding_box = [[-90, -126, -72],
                                                        [90, 90,
                                                         108]]  # 91, 109, 91
        if dim == 1:
            self.normalize_csf.inputs.write_bounding_box = [[-91, -126, -72],
                                                            [90, 91, 109]
                                                            ]  # 182, 218, 182
            self.normalize_csf.inputs.write_voxel_sizes = [1, 1, 1]

        ###################################################################################################

        # functional process
        self.fslsplit = pe.Node(interface=fsl.Split(), name='fslsplit')
        self.fslsplit.inputs.dimension = 't'
        self.fslsplit.inputs.output_type = "NIFTI"

        self.fslmerge = pe.Node(interface=fsl.Merge(), name='fslmerge')
        self.fslmerge.inputs.dimension = 't'
        self.fslmerge.inputs.output_type = "NIFTI"

        # helper function(s)
        def bet_each(in_files, subject_name):
            '''
            @param in_files: list of image files
            @return out_files: list of image files after applied fsl.BET on it
            '''
            from nipype.interfaces import fsl
            import nipype.pipeline.engine as pe

            out_files = list()
            step_no = 0
            for file_ in in_files:
                bet = pe.Node(interface=fsl.BET(),
                              name='BET_for_step_{}_{}'.format(
                                  step_no, subject_name))
                bet.inputs.in_file = file_
                bet.inputs.out_file = file_[:len(file_) - 4] + '_bet.nii'
                bet.inputs.output_type = "NIFTI"
                bet.inputs.frac = 0.5

                bet.run()
                out_files.append(bet.inputs.out_file)

                step_no += 1
            return out_files

        # bet_func return a list of NIFITI files
        self.bet_func = pe.Node(interface=Function(
            input_names=['in_files', 'subject_name'],
            output_names=['out_files'],
            function=bet_each),
                                name='non_brain_removal_BET_func')
        self.bet_func.inputs.subject_name = self.subject

        self.realign = pe.Node(interface=spm.Realign(),
                               name='realign_motion_correction')
        self.realign.inputs.register_to_mean = True

        self.coregister_func = pe.Node(interface=spm.Coregister(),
                                       name="coregister_func_to_mni")
        self.coregister_func.inputs.target = '/mnt/Program/python/dev/images/MNI152_T1_2mm_brain.nii'
        self.coregister_func.inputs.write_interp = 7
        self.coregister_func.inputs.separation = [1.0, 1.0]
        self.coregister_func.inputs.jobtype = 'estwrite'

        self.segment = pe.Node(interface=spm.Segment(), name="segment")

        self.normalize_func = pe.Node(interface=spm.Normalize(),
                                      name="normalize_func")
        self.normalize_func.inputs.jobtype = 'write'
        self.normalize_func.inputs.write_bounding_box = [[-90, -126, -72],
                                                         [90, 90,
                                                          108]]  # 91, 109, 91

        self.smooth = pe.Node(interface=spm.Smooth(), name="smooth")
        self.smooth.inputs.fwhm = [8, 8, 8]

        # backup node(s)
        self.slice_timing = pe.Node(interface=spm.SliceTiming(),
                                    name='time_slice_correction')
        self.slice_timing.inputs.time_repetition = self.TR
        self.slice_timing.inputs.num_slices = self.num_slices
        self.slice_timing.inputs.time_acquisition = self.TR - (self.TR /
                                                               self.num_slices)
        self.slice_timing.inputs.slice_order = list(
            range(self.num_slices, 0, -1))
        self.slice_timing.inputs.ref_slice = 1

        self.direct_normalize = pe.Node(interface=spm.Normalize12(),
                                        name='direct_normalize')
        self.direct_normalize.inputs.image_to_align = 'images/MNI152_T1_2mm_brain.nii'
        self.direct_normalize.inputs.affine_regularization_type = 'size'

        # specify workflow instance
        self.workflow = pe.Workflow(name='preprocess_workflow')

        # connect nodes
        self.workflow.connect([
            (self.struct_source, self.bet_struct, [('outfiles', 'in_file')]),
            (self.bet_struct, self.coregister_struct, [('out_file', 'source')
                                                       ]),
            (self.coregister_struct, self.segment_struct,
             [('coregistered_source', 'data')]),
            (self.segment_struct, self.normalize_struct,
             [('transformation_mat', 'parameter_file')]),
            (self.coregister_struct, self.normalize_struct,
             [('coregistered_source', 'apply_to_files')]),
            (self.segment_struct, self.normalize_gm, [('transformation_mat',
                                                       'parameter_file')]),
            (self.segment_struct, self.normalize_gm, [('native_gm_image',
                                                       'apply_to_files')]),
            (self.segment_struct, self.normalize_wm, [('transformation_mat',
                                                       'parameter_file')]),
            (self.segment_struct, self.normalize_wm, [('native_wm_image',
                                                       'apply_to_files')]),
            (self.segment_struct, self.normalize_csf, [('transformation_mat',
                                                        'parameter_file')]),
            (self.segment_struct, self.normalize_csf, [('native_csf_image',
                                                        'apply_to_files')]),
            (self.func_source, self.fslsplit, [('outfiles', 'in_file')]),
            (self.fslsplit, self.bet_func, [('out_files', 'in_files')]),
            (self.bet_func, self.fslmerge, [('out_files', 'in_files')]),
            (self.fslmerge, self.realign, [('merged_file', 'in_files')]),
            (self.realign, self.datasink, [('realignment_parameters',
                                            'realignment_parameters')]),
            (self.realign, self.coregister_func, [('mean_image', 'source')]),
            (self.realign, self.coregister_func, [('realigned_files',
                                                   'apply_to_files')]),
            (self.coregister_func, self.segment, [('coregistered_source',
                                                   'data')]),
            (self.segment, self.normalize_func, [('transformation_mat',
                                                  'parameter_file')]),
            (self.coregister_func, self.normalize_func, [('coregistered_files',
                                                          'apply_to_files')]),
            (self.normalize_func, self.smooth, [('normalized_files',
                                                 'in_files')]),  # end
            (self.normalize_func, self.datasink, [('normalized_files',
                                                   'before_smooth')]),
            (self.smooth, self.datasink, [('smoothed_files', 'final_out')]),
            (self.normalize_struct, self.datasink,
             [('normalized_files', 'standardized_struct_file')]),
            # (self.segment_struct, self.datasink, [('native_csf_image', 'csf'), ('native_gm_image', 'grey_matter'), ('native_wm_image', 'white_matter')])
            (self.normalize_gm, self.datasink, [('normalized_files',
                                                 'grey_matter')]),
            (self.normalize_wm, self.datasink, [('normalized_files',
                                                 'white_matter')]),
            (self.normalize_csf, self.datasink, [('normalized_files', 'csf')]),
        ])

        # backup workflow(s)
        self.workflow_only_fmri = pe.Workflow(name='preprocess_workflow')

        # connect nodes
        self.workflow_only_fmri.connect([
            (self.func_source, self.fslsplit, [('outfiles', 'in_file')]),
            (self.fslsplit, self.bet_func, [('out_files', 'in_files')]),
            (self.bet_func, self.fslmerge, [('out_files', 'in_files')]),
            (self.fslmerge, self.realign, [('merged_file', 'in_files')]),
            (self.realign, self.direct_normalize, [('realigned_files',
                                                    'apply_to_files')]),
            (self.direct_normalize, self.smooth, [('normalized_files',
                                                   'in_files')]),  # end
            (self.direct_normalize, self.datasink, [('normalized_files',
                                                     'before_smooth')]),
            (self.smooth, self.datasink, [('smoothed_files', 'final_out')])
        ])
Ejemplo n.º 14
0
def test_normalize():
    assert spm.Normalize._jobtype == "spatial"
    assert spm.Normalize._jobname == "normalise"
    assert spm.Normalize().inputs.jobtype == "estwrite"
Ejemplo n.º 15
0
def spm_mrpet_grouptemplate_preprocessing(wf_name="spm_mrpet_grouptemplate_preproc"):
    """ Run the PET pre-processing workflow against the gunzip_pet.in_file files.
    It depends on the anat_preproc_workflow, so if this has not been run, this function
    will run it too.

    This is identical to the workflow defined in `spm_mrpet_preprocessing`,
    with the only difference that we now normalize all subjects agains a custom
    template using the spm Old Normalize interface.

    It does:
    - SPM12 Coregister T1 and tissues to PET
    - PVC the PET image in PET space
    - SPM12 Warp PET to the given template

    Parameters
    ----------
    wf_name: str
        Name of the workflow.

    Nipype Inputs
    -------------
    pet_input.in_file: traits.File
        The raw NIFTI_GZ PET image file.

    pet_input.atlas_anat: traits.File
        The atlas file in anatomical space.

    pet_input.anat: traits.File
        Path to the high-contrast anatomical image.
        Reference file of the warp_field, i.e., the anatomical image in its native space.

    pet_input.tissues: list of traits.File
        List of tissues files from the New Segment process. At least the first
        3 tissues must be present.

    pet_input.pet_template: traits.File
        The template file for inter-subject registration reference.

    Nipype outputs
    --------------
    pet_output.pvc_out: existing file
        The results of the PVC process.

    pet_output.brain_mask: existing file
        A brain mask calculated with the tissues file.

    pet_output.coreg_ref: existing file
        The coregistered reference image to PET space.

    pet_output.coreg_others: list of existing files
        List of coregistered files from coreg_pet.apply_to_files.

    pet_output.pet_warped: existing file
        PET image normalized to the group template.

    pet_output.pvc_warped: existing file
        The outputs of the PETPVC workflow normalized to the group template.
        The result of every internal pre-processing step is normalized to the
        group template here.

    pet_output.warp_field: existing files
        Spatial normalization parameters .mat files.

    pet_output.gm_norm: existing file
        The output of the grey matter intensity normalization process.
        This is the last step in the PET signal correction, before registration.

    pet_output.atlas_pet: existing file
        Atlas image warped to PET space.
        If the `atlas_file` option is an existing file and `normalize_atlas` is True.

    Returns
    -------
    wf: nipype Workflow
    """
    # specify input and output fields
    in_fields  = ["in_file",
                  "anat",
                  "tissues",
                  "pet_template"]

    out_fields = ["brain_mask",
                  "coreg_others",
                  "coreg_ref",
                  "pvc_warped",
                  "pet_warped",
                  "warp_field",
                  "pvc_out",
                  "pvc_mask",
                  "gm_norm",]

    do_atlas, _ = check_atlas_file()
    if do_atlas:
        in_fields  += ["atlas_anat"]
        out_fields += ["atlas_pet" ]

    # input
    pet_input = setup_node(IdentityInterface(fields=in_fields, mandatory_inputs=True),
                           name="pet_input")

    # workflow to perform partial volume correction
    petpvc = petpvc_workflow(wf_name="petpvc")

    unzip_mrg = setup_node(Merge(4), name='merge_for_unzip')
    gunzipper = pe.MapNode(Gunzip(), name="gunzip", iterfield=['in_file'])

    # warp each subject to the group template
    gunzip_template = setup_node(Gunzip(), name="gunzip_template",)
    gunzip_pet      = setup_node(Gunzip(), name="gunzip_pet",)

    warp_mrg = setup_node(Merge(2), name='merge_for_warp')
    warp2template = setup_node(spm.Normalize(jobtype="estwrite", out_prefix="wgrptemplate_"),
                               name="warp2template",)

    get_bbox = setup_node(Function(function=get_bounding_box,
                                   input_names=["in_file"],
                                   output_names=["bbox"]),
                          name="get_bbox")

    # output
    pet_output = setup_node(IdentityInterface(fields=out_fields), name="pet_output")

    # Create the workflow object
    wf = pe.Workflow(name=wf_name)

    wf.connect([
                # inputs
                (pet_input,   petpvc,  [("in_file", "pvc_input.in_file"),
                                        ("anat",    "pvc_input.reference_file"),
                                        ("tissues", "pvc_input.tissues")]),

                # get template bounding box to apply to results
                (pet_input, get_bbox,  [("pet_template", "in_file")]),

                # gunzip some inputs
                (pet_input, gunzip_pet,      [("in_file",      "in_file")]),
                (pet_input, gunzip_template, [("pet_template", "in_file")]),

                # gunzip some files for SPM Normalize
                (petpvc,    unzip_mrg, [("pvc_output.pvc_out",    "in1"),
                                        ("pvc_output.brain_mask", "in2"),
                                        ("pvc_output.gm_norm",    "in3")]),
                (pet_input, unzip_mrg, [("in_file",               "in4")]),

                (unzip_mrg, gunzipper, [("out", "in_file")]),

                (gunzipper, warp_mrg,  [("out_file", "in1")]),

                (warp_mrg, warp2template, [(("out", flatten_list), "apply_to_files")]),

                # prepare the target parameters of the warp to template
                (gunzip_pet,      warp2template, [("out_file", "source")]),
                (gunzip_template, warp2template, [("out_file", "template")]),
                (get_bbox,        warp2template, [("bbox",     "write_bounding_box")]),

                # output
                (warp2template, pet_output, [("normalization_parameters", "warp_field"),
                                             ("normalized_files" ,        "pvc_warped"),
                                             ("normalized_source",        "pet_warped"),
                                            ]),

                # output
                (petpvc,   pet_output, [("pvc_output.pvc_out",      "pvc_out"),
                                        ("pvc_output.brain_mask",   "brain_mask"),
                                        ("pvc_output.coreg_ref",    "coreg_ref"),
                                        ("pvc_output.coreg_others", "coreg_others"),
                                        ("pvc_output.gm_norm",      "gm_norm")]),
                ])

    if do_atlas:
        coreg_atlas = setup_node(spm_coregister(cost_function="mi"), name="coreg_atlas")

        # set the registration interpolation to nearest neighbour.
        coreg_atlas.inputs.write_interp = 0
        wf.connect([
                    (pet_input,   coreg_atlas, [("anat",                 "source")]),
                    (petpvc,      coreg_atlas, [("pvc_output.coreg_ref", "target")]),
                    (pet_input,   coreg_atlas, [("atlas_anat",           "apply_to_files")]),
                    (coreg_atlas, pet_output,  [("coregistered_files",   "atlas_pet")]),

                    # warp the atlas to the template space as well
                    (coreg_atlas, warp_mrg,    [("coregistered_files",   "in2")]),
        ])

    return wf
Ejemplo n.º 16
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
Ejemplo n.º 17
0
coregister.iterables = ('target', 'func')
coregister.inputs.source = 't2.nii'

coregister2 = pe.Node(interface=spm.Coregister(), name="coregister2")
coregister2.inputs.jobtype = 'estimate'  # coreg output of T2 and T2* to T1
coregister2.iterables = ('target', ['func','t2.nii'])
coregister2.inputs.source = 't1.nii'


## old segment
# Q: why old?

## old normalize
# prefix = w (norm'd to MNI)

normalize = pe.Node(interface=spm.Normalize(), name="normalize") # Q: is this old norm?
normalize.inputs.template = os.path.abspath('data/T1.nii') # Q: dir of MNI?

## smooth
# 8 fwhm


smooth = pe.Node(interface=spm.Smooth(), name="smooth")
smooth.iterables = ('fwhm', [8])

## set up pipeline

preproc_pipeline = pe.Workflow(name="preproc")
preproc_pipeline.base_dir = os.path.abspath('spm_tutorial/workingdir') #Q: dir?

preproc_pipeline.connect([(infosource, datasource, [('subject_id', 'subject_id')]),
Ejemplo n.º 18
0
def spm_register_to_template_wf(wf_name="spm_registration_to_template"):
    """Return a workflow that registers each reg_input.in_file to the file in reg_input.template.
    For now this does not do atlas registration.

    It does:
    - SPM12 Warp input image to the given template

    Parameters
    ----------
    wf_name: str
        Name of the workflow.

    Nipype Inputs
    -------------
    reg_input.in_file: traits.File
        The raw NIFTI_GZ subject image file.

    reg_input.template: list of traits.File
        The template file for inter-subject registration reference.

    Nipype outputs
    --------------
    reg_output.warped: existing file
        Image normalized to the given template.

    reg_output.warp_field: existing files
        Spatial normalization parameters .mat file.

    Returns
    -------
    wf: nipype Workflow
    """
    # specify input and output fields
    in_fields = [
        "in_file",
        "template",
    ]

    out_fields = [
        "warped",
        "warp_field",
    ]

    # input
    reg_input = setup_node(IdentityInterface(fields=in_fields,
                                             mandatory_inputs=True),
                           name="reg_input")

    # warp each subject to the group template
    gunzip_template = setup_node(
        Gunzip(),
        name="gunzip_template",
    )
    gunzip_input = setup_node(
        Gunzip(),
        name="gunzip_input",
    )

    warp2template = setup_node(spm.Normalize(jobtype="estwrite",
                                             out_prefix="wgrptemplate_"),
                               name="warp2template")

    get_bbox = setup_node(Function(function=get_bounding_box,
                                   input_names=["in_file"],
                                   output_names=["bbox"]),
                          name="get_bbox")

    # output
    reg_output = setup_node(IdentityInterface(fields=out_fields),
                            name="reg_output")

    # Create the workflow object
    wf = pe.Workflow(name=wf_name)

    wf.connect([
        # get template bounding box to apply to results
        (reg_input, get_bbox, [("template", "in_file")]),

        # gunzip some inputs
        (reg_input, gunzip_input, [("in_file", "in_file")]),
        (reg_input, gunzip_template, [("template", "in_file")]),

        # prepare the target parameters of the warp to template
        (gunzip_template, warp2template, [("out_file", "template")]),
        (get_bbox, warp2template, [("bbox", "write_bounding_box")]),

        # directly warp pet to the template
        (gunzip_input, warp2template, [("out_file", "source")]),

        # output
        (warp2template, reg_output, [
            ("normalization_parameters", "warp_field"),
            ("normalized_source", "warped"),
        ]),
    ])

    return wf
Ejemplo n.º 19
0
    def __init__(self, func_source, struct_source, datasink):
        # specify input and output nodes
        self.func_source = func_source
        self.struct_source = struct_source
        self.datasink = datasink

        # specify nodes
        # structual process
        self.bet_struct = pe.Node(interface=fsl.BET(),
                                  name='non_brain_removal_BET_struct')
        self.bet_struct.inputs.output_type = "NIFTI"

        # functional process
        self.slice_timer = pe.Node(interface=fsl.SliceTimer(),
                                   name='time_slice_correction')

        self.mcflirt = pe.Node(interface=fsl.MCFLIRT(),
                               name='motion_correction')
        self.mcflirt.inputs.output_type = "NIFTI"
        self.mcflirt.inputs.mean_vol = True

        self.fslsplit = pe.Node(interface=fsl.Split(), name='fslsplit')
        self.fslsplit.inputs.dimension = 't'
        self.fslsplit.inputs.output_type = "NIFTI"

        self.fslmerge = pe.Node(interface=fsl.Merge(), name='fslmerge')
        self.fslmerge.inputs.dimension = 't'
        self.fslmerge.inputs.output_type = "NIFTI"

        self.bet_mean = pe.Node(interface=fsl.BET(),
                                name='non_brain_removal_BET_mean')
        self.bet_mean.inputs.output_type = "NIFTI"

        # helper function(s)
        def bet_each(in_files):
            '''
            @param in_files: list of image files
            @return out_files: list of image files after applied fsl.BET on it
            '''
            from nipype.interfaces import fsl
            import nipype.pipeline.engine as pe

            out_files = list()
            step_no = 0
            for file_ in in_files:
                bet = pe.Node(interface=fsl.BET(),
                              name='BET_for_step_{}'.format(step_no))
                bet.inputs.in_file = file_
                bet.inputs.out_file = file_[:len(file_) - 4] + '_bet.nii'
                bet.inputs.output_type = "NIFTI"

                bet.run()
                out_files.append(bet.inputs.out_file)

                step_no += 1
            return out_files

        # bet_func return a list of NIFITI files
        self.bet_func = pe.Node(interface=Function(input_names=['in_files'],
                                                   output_names=['out_files'],
                                                   function=bet_each),
                                name='non_brain_removal_BET_func')

        self.coregister = pe.Node(interface=spm.Coregister(),
                                  name="coregister")
        self.coregister.inputs.jobtype = 'estimate'

        self.segment = pe.Node(interface=spm.Segment(), name="segment")
        self.segment.inputs.affine_regularization = 'mni'

        self.normalize_func = pe.Node(interface=spm.Normalize(),
                                      name="normalize_func")
        self.normalize_func.inputs.jobtype = "write"

        # self.fourier = pe.Node(interface=afni.Fourier(), name='temporal_filtering')
        # self.fourier.inputs.highpass = 0.01
        # self.fourier.inputs.lowpass = 0.1

        self.smooth = pe.Node(interface=spm.Smooth(), name="smooth")
        self.smooth.inputs.fwhm = [8, 8, 8]

        # specify workflow instance
        self.workflow = pe.Workflow(name='preprocessing_workflow')

        # connect nodes
        self.workflow.connect([
            (self.struct_source, self.bet_struct, [('outfiles', 'in_file')]),
            (self.func_source, self.slice_timer, [('outfiles', 'in_file')]),
            (self.slice_timer, self.mcflirt, [('slice_time_corrected_file',
                                               'in_file')]),
            (self.mcflirt, self.bet_mean, [('mean_img', 'in_file')]),
            (self.mcflirt, self.fslsplit, [('out_file', 'in_file')]),
            (self.fslsplit, self.bet_func, [('out_files', 'in_files')]),
            (self.bet_func, self.fslmerge, [('out_files', 'in_files')
                                            ]),  # intersect
            (self.bet_struct, self.coregister, [('out_file', 'source')]),
            (self.bet_mean, self.coregister, [('out_file', 'target')]),
            (self.coregister, self.segment, [('coregistered_source', 'data')]),
            (self.segment, self.normalize_func, [('transformation_mat',
                                                  'parameter_file')]),
            (self.fslmerge, self.normalize_func, [('merged_file',
                                                   'apply_to_files')]),
            (self.normalize_func, self.smooth, [('normalized_files',
                                                 'in_files')]),
            (self.coregister, self.datasink, [('coregistered_source',
                                               'registered_file')]),
            (self.normalize_func, self.datasink, [('normalized_files',
                                                   'before_smooth')]),
            (self.smooth, self.datasink, [('smoothed_files', 'final_out')])
        ])
Ejemplo n.º 20
0
def test_normalize():
    yield assert_equal, spm.Normalize._jobtype, 'spatial'
    yield assert_equal, spm.Normalize._jobname, 'normalise'
    yield assert_equal, spm.Normalize().inputs.jobtype, 'estwrite'
Ejemplo n.º 21
0
"""
Use :class:`nipype.interfaces.freesurfer.ApplyVolTransform` to convert contrast
images into freesurfer space.
"""

normwreg = pe.MapNode(interface=fs.ApplyVolTransform(),
                      iterfield=['source_file'],
                      name='applyreg2con')

"""
Use :class:`nipype.interfaces.spm.Normalize` to normalize the contrast images
to MNI space
"""

normalize = pe.Node(interface=spm.Normalize(jobtype='write'),
                    name='norm2mni')

"""
Connect up the volume normalization components
"""

volnorm.connect([(convert, segment, [('out_file','data')]),
                 (convert2, normwreg, [('out_file', 'source_file')]),
                 (segment, normalize, [('transformation_mat', 'parameter_file')]),
                 (normwreg, normalize, [('transformed_file','apply_to_files')]),
                 ])

"""
Preproc + Analysis + VolumeNormalization workflow
-------------------------------------------------
Ejemplo n.º 22
0
def spm_warp_fmri_wf(wf_name="spm_warp_fmri", register_to_grptemplate=False):
    """ Run SPM to warp resting-state fMRI pre-processed data to MNI or a given 
    template.

    Tasks:
    - Warping the inputs to MNI or a template, if `do_group_template` is True

    Parameters
    ----------
    wf_name: str

    register_to_grptemplate: bool
        If True will expect the wfmri_input.epi_template input and use it as a group template
        for inter-subject registratio.

    Nipype Inputs
    -------------
    wfmri_input.in_file: traits.File
        The slice time and motion corrected fMRI file.

    wfmri_input.reference_file: traits.File
        The anatomical image in its native space
        for registration reference.

    wfmri_input.anat_fmri: traits.File
        The anatomical image in fMRI space.

    wfmri_input.anat_to_mni_warp: traits.File
        The warp field from the transformation of the
        anatomical image to the standard MNI space.

    wfmri_input.time_filtered: traits.File
        The bandpass time filtered fMRI file.

    wfmri_input.avg_epi: traits.File
        The average EPI from the fMRI file.

    wfmri_input.epi_template: traits.File
        Reference EPI template file for inter subject registration.
        If `do_group_template` is True you must specify this input.

    wfmri_input.brain_mask: traits.File
        Brain mask in fMRI space.

    wfmri_input.atlas_anat: traits.File
        Atlas in subject anatomical space.

    Nipype Outputs
    --------------
    wfmri_output.warped_fmri: traits.File
        The slice time, motion, and nuisance corrected fMRI
        file registered to the template.

    wfmri_output.wtime_filtered: traits.File
        The bandpass time filtered fMRI file
        registered to the template.

    wfmri_output.smooth: traits.File
        The smooth bandpass time filtered fMRI file
        registered to the template.

    wfmri_output.wavg_epi: traits.File
        The average EPI from the fMRI file
        registered to the template.

    wfmri_output.warp_field: traits.File
        The fMRI to template warp field.

    wfmri_output.coreg_avg_epi: traits.File
        The average EPI image in anatomical space.

        Only if registration.anat2fmri is false.

    wfmri_output.coreg_others: traits.File
        Other mid-preprocessing fmri images registered to
        anatomical space:

        - wfmri_input.in_file,

        - wfmri_input.brain_mask,

        - wfmri_input.time_filtered.

        Only if registration.anat2fmri is false

    wfmri_output.wbrain_mask: traits.File
        Brain mask in fMRI space warped to MNI.

    Returns
    -------
    wf: nipype Workflow
    """
    # Create the workflow object
    wf = pe.Workflow(name=wf_name)

    # specify input and output fields
    in_fields  = ["in_file",
                  "anat_fmri",
                  "anat_to_mni_warp",
                  "brain_mask",
                  "reference_file",
                  "time_filtered",
                  "avg_epi",]

    out_fields = ["warped_fmri",
                  "wtime_filtered",
                  "smooth",
                  "wavg_epi",
                  "wbrain_mask",
                  "warp_field",
                  "coreg_avg_epi",
                  "coreg_others"
                  ]

    if register_to_grptemplate:
        in_fields += ['epi_template']

    do_atlas, _ = check_atlas_file()
    if do_atlas:
        in_fields  += ["atlas_anat"]
        out_fields += ["atlas_fmri"]

    # input identities
    wfmri_input = setup_node(IdentityInterface(fields=in_fields, mandatory_inputs=True),
                             name="wfmri_input")

    # in file unzipper
    in_gunzip = pe.Node(Gunzip(), name="in_gunzip")

    # merge list for normalization input
    merge_list = pe.Node(Merge(2), name='merge_for_warp')
    gunzipper = pe.MapNode(Gunzip(), name="gunzip", iterfield=['in_file'])

    # the template bounding box
    tpm_bbox = setup_node(Function(function=get_bounding_box,
                                   input_names=["in_file"],
                                   output_names=["bbox"]),
                          name="tpm_bbox")

    # smooth the final result
    smooth = setup_node(fsl.IsotropicSmooth(fwhm=8, output_type='NIFTI'), name="smooth_fmri")

    # output identities
    rest_output = setup_node(IdentityInterface(fields=out_fields),
                             name="wfmri_output")


    # check how to perform the registration, to decide how to build the pipeline
    anat2fmri = get_config_setting('registration.anat2fmri', False)
    # register to group template
    if register_to_grptemplate:
        gunzip_template = pe.Node(Gunzip(), name="gunzip_template",)
        warp = setup_node(spm.Normalize(jobtype="estwrite", out_prefix="wgrptmpl_"),
                          name="fmri_grptemplate_warp",)
        warp_source_arg    = "source"
        warp_outsource_arg = "normalized_source"
        warp_field_arg     = "normalization_parameters"

    elif anat2fmri:
        # register to standard template
        warp = setup_node(spm_normalize(), name="fmri_warp")
        tpm_bbox.inputs.in_file = spm_tpm_priors_path()
        warp_source_arg    = "image_to_align"
        warp_outsource_arg = "normalized_image"
        warp_field_arg     = "deformation_field"

    else: # anat2fmri is False
        coreg       = setup_node(spm_coregister(cost_function="mi"), name="coreg_fmri")
        warp        = setup_node(spm_apply_deformations(), name="fmri_warp")
        coreg_files = pe.Node(Merge(3), name='merge_for_coreg')
        warp_files  = pe.Node(Merge(2), name='merge_for_warp')
        tpm_bbox.inputs.in_file = spm_tpm_priors_path()

    # make the connections
    if register_to_grptemplate:
        wf.connect([
                    # get template bounding box to apply to results
                    (wfmri_input, tpm_bbox, [("epi_template", "in_file")]),

                    # unzip and forward the template file
                    (wfmri_input,     gunzip_template, [("epi_template", "in_file")]),
                    (gunzip_template, warp,            [("out_file",     "template")]),

                    # get template bounding box to apply to results
                    (wfmri_input, tpm_bbox, [("epi_template", "in_file")]),
                    ])

    if anat2fmri or register_to_grptemplate:
        # prepare the inputs
        wf.connect([
                    # unzip the in_file input file
                    (wfmri_input, in_gunzip, [("avg_epi", "in_file")]),

                    # warp source file
                    (in_gunzip, warp, [("out_file", warp_source_arg)]),

                    # bounding box
                    (tpm_bbox,  warp, [("bbox", "write_bounding_box")]),

                    # merge the other input files into a list
                    (wfmri_input, merge_list, [("in_file",       "in1"),
                                               ("time_filtered", "in2"),
                                              ]),

                    # gunzip them for SPM
                    (merge_list, gunzipper, [("out", "in_file")]),

                    # apply to files
                    (gunzipper, warp,       [("out_file", "apply_to_files")]),

                    # outputs
                    (warp, rest_output,     [(warp_field_arg,     "warp_field"),
                                             (warp_outsource_arg, "wavg_epi"),
                                            ]),

                   ])

    else: # FMRI to ANAT
        wf.connect([
                    (wfmri_input, coreg,      [("reference_file", "target")]),

                    # unzip the in_file input file
                    (wfmri_input, in_gunzip,  [("avg_epi",  "in_file")]),
                    (in_gunzip,   coreg,      [("out_file", "source")]),

                    # merge the other input files into a list
                    (wfmri_input, coreg_files, [("in_file",       "in1"),
                                                ("time_filtered", "in2"),
                                                ("brain_mask",    "in3"),
                                               ]),

                    # gunzip them for SPM
                    (coreg_files, gunzipper, [("out", "in_file")]),

                    # coregister fmri to anat
                    (gunzipper,   coreg,     [("out_file", "apply_to_files")]),

                    # anat to mni warp field
                    (wfmri_input, warp, [("anat_to_mni_warp", "deformation_file")]),

                    # bounding box
                    (tpm_bbox,  warp, [("bbox", "write_bounding_box")]),

                    # apply to files
                    (coreg, warp_files, [("coregistered_source", "in1")]),
                    (coreg, warp_files, [("coregistered_files",  "in2")]),

                    (warp_files, warp, [("out", "apply_to_files")]),

                    # outputs
                    (warp, rest_output,  [("normalized_files",  "warped_files"),]),
                    (warp, rest_output,  [(("normalized_files", selectindex, 0), "wavg_epi"),]),

                    (coreg, rest_output, [("coregistered_source", "coreg_avg_epi")]),
                    (coreg, rest_output, [("coregistered_files",  "coreg_others")]),
                   ])

    # atlas file in fMRI space
    if anat2fmri:
        coreg_atlas = setup_node(spm_coregister(cost_function="mi"), name="coreg_atlas2fmri")

        # set the registration interpolation to nearest neighbour.
        coreg_atlas.inputs.write_interp = 0
        wf.connect([
                    (wfmri_input, coreg_atlas, [("reference_file", "source"),
                                                ("atlas_anat", "apply_to_files"),
                                               ]),
                    (in_gunzip,   coreg_atlas, [("out_file",           "target")]),
                    (coreg_atlas, rest_output, [("coregistered_files", "atlas_fmri")]),
                  ])

    # smooth and sink
    wf.connect([
                # smooth the final bandpassed image
                (warp,   smooth,      [(("normalized_files", selectindex, 1), "in_file")]),

                # output
                (smooth, rest_output, [("out_file", "smooth")]),
                (warp,   rest_output, [(("normalized_files", selectindex, 0), "warped_fmri"),
                                       (("normalized_files", selectindex, 1), "wtime_filtered"),
                                      ]),
               ])

    return wf
Ejemplo n.º 23
0
coregister = pe.Node(interface=spm.Coregister(), name="coregister")
coregister.inputs.jobtype = 'estimate'

segment = pe.Node(interface=spm.Segment(), name="segment")
segment.inputs.save_bias_corrected = True
"""Uncomment the following line for faster execution
"""

# segment.inputs.gaussians_per_class = [1, 1, 1, 4]
"""Warp functional and structural data to SPM's T1 template using
:class:`nipype.interfaces.spm.Normalize`.  The tutorial data set
includes the template image, T1.nii.
"""

normalize_func = pe.Node(interface=spm.Normalize(), name="normalize_func")
normalize_func.inputs.jobtype = "write"

normalize_struc = pe.Node(interface=spm.Normalize(), name="normalize_struc")
normalize_struc.inputs.jobtype = "write"
"""Smooth the functional data using
:class:`nipype.interfaces.spm.Smooth`.
"""

smooth = pe.Node(interface=spm.Smooth(), name="smooth")
"""`write_voxel_sizes` is the input of the normalize interface that is recommended to be set to
the voxel sizes of the target volume. There is no need to set it manually since we van infer it from data
using the following function:
"""

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