def create_preproc_func_pipeline():#ref_slice, n_skip=4, n_slices=30, tr=2.5, sparse=False):
    
#    if sparse:
#        real_tr = tr/2
#    else:
#        real_tr = tr
    
    inputnode = pe.Node(interface=util.IdentityInterface(fields=['func', "struct", "TR", "sparse"]), name="inputnode")
    
    pre_ica = pe.Node(interface=fsl.MELODIC(), name="pre_ica")
    pre_ica.inputs.no_mask = True
    pre_ica.inputs.out_all = True
    pre_ica.inputs.report = True

    skip = pe.Node(interface=fsl.ExtractROI(), name="skip")
    skip.inputs.t_min = 4 #TODO
    skip.inputs.t_size = 100000
    
    realign = pe.Node(interface=spm.Realign(), name="realign")
    realign.inputs.register_to_mean = True
    
    tr_convert = pe.Node(interface=util.Function(input_names=['tr', 'sparse'], 
                                                 output_names=['tr'], 
                                                 function=get_tr), name="tr_converter")
    ta = pe.Node(interface=util.Function(input_names=['real_tr', 'n_slices'], 
                                                 output_names=['ta'], 
                                                 function=get_ta), name="ta")
    
    slice_timing = pe.Node(interface=spm.SliceTiming(), name="slice_timing")
    #slice_timing.inputs.num_slices = n_slices
    #slice_timing.inputs.time_repetition = real_tr
    #slice_timing.inputs.time_acquisition = real_tr - real_tr/float(n_slices)
    #slice_timing.inputs.slice_order = range(1,n_slices+1,2) + range(2,n_slices+1,2)
    #slice_timing.inputs.ref_slice = ref_slice
    
    coregister = pe.Node(interface=spm.Coregister(), name="coregister")
    coregister.inputs.jobtype= "estimate"
    
    smooth = pe.Node(interface=spm.Smooth(), name="smooth")
    smooth.inputs.fwhm = [8, 8, 8]
    susan_smooth = create_susan_smooth(name="susan_smooth")
    susan_smooth.inputs.inputnode.fwhm = 8
    
    art = pe.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'
    
    compute_mask = pe.Node(interface=ComputeMask(), name="compute_mask")
    
    post_ica = pe.Node(interface=fsl.MELODIC(), name="post_ica")
    post_ica.inputs.out_all = True
    post_ica.inputs.report = True
    
    preproc_func = pe.Workflow(name="preproc_func")
    preproc_func.connect([
                          (inputnode,skip, [("func", "in_file")]),
#                          (inputnode, pre_ica, [("func", "in_files"),
#                                                ("TR", "tr_sec")]),
                          
                          (coregister, compute_mask, [('coregistered_source','mean_volume')]),
                          (skip, slice_timing, [("roi_file", "in_files"),
                                                      (('roi_file', get_n_slices), "num_slices"),
                                                      (('roi_file', get_slice_order), "slice_order"),
                                                      (('roi_file', get_ref_slice), "ref_slice")
                                                      ]),
                          (inputnode, tr_convert, [("sparse", "sparse"),
                                                   ("TR", "tr")]),
                          (tr_convert, slice_timing, [("tr", "time_repetition")]),
                          
                          (tr_convert, ta, [("tr", "real_tr")]),
                          (skip, ta, [(('roi_file', get_n_slices), "n_slices")]),
                          
                          (ta, slice_timing, [("ta", "time_acquisition")]),     
                          (slice_timing, realign, [("timecorrected_files", "in_files")]),
#                          (skip, realign, [("roi_file", "in_files")]),
                          
                          (inputnode, coregister, [("struct", "target")]),
                          (realign, coregister,[('mean_image', 'source'),
                                                ('realigned_files','apply_to_files')]),
                          
                          (coregister, susan_smooth, [("coregistered_files","inputnode.in_files")]),
                          (compute_mask, susan_smooth,[('brain_mask','inputnode.mask_file')]),
                          
#                          (susan_smooth, post_ica, [("outputnode.smoothed_files", "in_files")]),
#                          (inputnode, post_ica, [("TR", "tr_sec")]),
#                          (compute_mask,post_ica,[('brain_mask','mask')]),
                          
#                          (coregister, smooth, [("coregistered_files","in_files")]),
                          
                          (compute_mask,art,[('brain_mask','mask_file')]),
                          (realign,art,[('realignment_parameters','realignment_parameters')]),
                          (realign,art,[('realigned_files','realigned_files')]),
                          ])
    
    outputnode = pe.Node(interface=util.IdentityInterface(fields=['preproced_files', 'realignment_parameters', 'outlier_files', 'mask_file']), name="outputnode")
    
    preproc_func.connect(realign, 'realignment_parameters', outputnode, 'realignment_parameters')
    preproc_func.connect(susan_smooth, 'outputnode.smoothed_files', outputnode, 'preproced_files')
    preproc_func.connect(art, 'outlier_files', outputnode, 'outlier_files')
    preproc_func.connect(compute_mask, 'brain_mask', outputnode, 'mask_file')
    
    return preproc_func
def create_func_preproc_workflow(name='functional_preprocessing', func_preproc_name="func_preproc"):
        
    #####
    # Setup workflow
    #####
    
    preproc = pe.Workflow(name=name)
    
    
    #####
    # Setup input node
    #####
    
    input_fields = [
        "func",         # list of functional images to run
        "func_mask",    # list of functional images to run
        "fwhm",         # fwhm
        "highpass",     # highpass filtering
        "lowpass",      # lowpass filtering
    ]
    inputnode = pe.Node(interface=util.IdentityInterface(fields=input_fields), 
                            name="inputspec")
    
    
    #####
    # Setup output node
    #####
    
    # Outputs
    output_fields = [
        func_preproc_name,  # final output (also has been intensity normalized)
    ]
    outputnode = pe.Node(util.IdentityInterface(fields=output_fields),
                        name="outputspec")
    
    #####
    # Setup renaming
    #####
    
    renamer = OutputConnector(preproc, outputnode)  # allows easy renaming of output file names
    
    
    #####
    # Main Commands
    ####
    
    """
    Prepare Input
    """
    
    # Convert functional images to float representation
    img2float = pe.MapNode(fsl.ChangeDataType(output_datatype="float"),
                           iterfield=["in_file"],
                           name="00_img2float")
    preproc.connect(inputnode, 'func', img2float, 'in_file')
    
    """
    Smoothing
    """
    
    # Anisitropic-like? smoothing with your friend susan
    smooth = create_susan_smooth(name="01_susan_smooth")
    preproc.connect(inputnode, 'fwhm', smooth, 'inputnode.fwhm')
    preproc.connect(img2float, 'out_file', smooth, 'inputnode.in_files')
    preproc.connect(inputnode, 'func_mask', smooth, 'inputnode.mask_file')
    
    # Mask smoothed data with dilated mask
    funcbrain = pe.MapNode(fsl.ApplyMask(),
                           iterfield=["in_file", "mask_file"],
                           name="02_funcbrain")
    preproc.connect(smooth, 'outputnode.smoothed_files', funcbrain, 'in_file')
    preproc.connect(inputnode, 'func_mask', funcbrain, 'mask_file')
    
    # Determine if want to take output from smoothed or non-smoothed data forward
    # This would be the case if the fwhm is less than 1/3 of the voxel size
    ## gather 2 types of functional images
    concatnode = pe.Node(interface=util.Merge(2),
                         name='02_concat')
    preproc.connect(img2float, ('out_file', tolist), concatnode, 'in1')
    preproc.connect(funcbrain, ('out_file', tolist), concatnode, 'in2')
    ## select one
    selectnode = pe.Node(interface=util.Select(),name='02_select')
    preproc.connect(concatnode, 'out', selectnode, 'inlist')
    preproc.connect(inputnode, ('fwhm', chooseindex), selectnode, 'index')
    
    """
    Filter
    """
    
    filt = pe.MapNode(fsl.TemporalFilter(),
                          iterfield=["in_file"],
                          name="03_filter")
    preproc.connect(inputnode, 'highpass', filt, 'highpass_sigma')
    preproc.connect(inputnode, 'lowpass', filt, 'lowpass_sigma')
    preproc.connect(selectnode, 'out', filt, 'in_file')
    
    """
    Intensity Normalization
    """
    
    # Determine the median value of the functional runs using the mask
    medianval = pe.MapNode(fsl.ImageStats(op_string="-k %s -p 50"),
                           iterfield = ["in_file", "mask_file"],
                           name="04_medianval")
    preproc.connect(filt, 'out_file', medianval, 'in_file')
    preproc.connect(inputnode, 'func_mask', medianval, 'mask_file')
    
    # Scale mean value of run to 10000
    meanscale = pe.MapNode(interface=fsl.ImageMaths(suffix='_gms'),
                          iterfield=['in_file', 'op_string'],
                          name='04_meanscale')
    preproc.connect(filt, 'out_file', meanscale, 'in_file')
    ## function to get scaling factor
    preproc.connect(medianval, ('out_stat', getmeanscale), meanscale, 'op_string')
    
    """
    Get Final Functional Data and Mean
    """
    ## functional 4D
    renamer.connect(meanscale, 'out_file', func_preproc_name)
    
    return preproc
Example #3
0
def create_resting_workflow(name="resting_state"):
    """Return a preprocessing workflow.

    Input spec node takes these three inputs:
        - Timeseries (image files)
        - FWHM of smoothing kernel for (in mms)
        - FNIRT warp coefficient image
        - Freesurfer Subject ID
 
    Output node returns these files:
        - Smoothed timeseries (fully preprocessed and smoothed timeseries in native space)
        - Unsmoothed timeseries (identical steps except no smoothing in the volume)
        - Example func (target volume for MCFLIRT realignment)
        - Mean func (unsmoothed mean functional)
        - Funcational mask (binary dilated brainmask in functional space)
        - Realignment parameters (text files from MCFLIRT)
        - Outlier Files (outlier text files from ART)
        - Plotted estimated rotations from MCFLIRT
        - Plotted estimated translastion from MCFLIRT
        - Plotted estimated relative and absolute displacement from MCFLIRT
        - Plotted global mean intensity value
        - Sliced png of the example func (MCFLIRT target)
        - Sliced png of the unsmoothed mean functional volume
        - Tkregister-style affine matrix
        - FSL-style affine matrix
        - Sliced png summarizing the functional to anatomical transform
        - Optimization cost file quantitatively summarizing the transformation

    """
    resting = pe.Workflow(name=name)

    # Define the inputs for the preprocessing workflow
    inputnode = pe.Node(util.IdentityInterface(fields=["timeseries",
                                                       "subject_id",
                                                       "warpfield",
                                                       "smooth_fwhm"]),
                        name="inputspec")

    # Remove the first two frames to account for T1 stabalization
    trimmer = pe.MapNode(fsl.ExtractROI(t_min=6),
                         iterfield=["in_file"],
                         name="trimmer")

    # Convert functional images to float representation
    img2float = pe.MapNode(fsl.ChangeDataType(output_datatype="float"),
                           iterfield=["in_file"],
                           name="img2float")


    # Perform slice-timing correction
    slicetime = pe.MapNode(fsl.SliceTimer(interleaved=True,
                                          time_repetition=6),
                           iterfield=["in_file"],
                           name="slicetime")

    # Motion correct
    realign = create_realignment_workflow()

    skullstrip = create_skullstrip_workflow()

    art = create_art_workflow(make_movie=False)

    func2anat = create_bbregister_workflow()

    confounds = create_confound_removal_workflow()
    
    susan = create_susan_smooth()

    normalize = create_normalize_workflow()

    tosurf = create_surface_projection_workflow()

    rename = pe.MapNode(util.Rename(format_string="timeseries",
                                    keep_ext=True),
                        iterfield=["in_file"],
                        name="rename")
    
    resting.connect([
        (inputnode,   trimmer,       [("timeseries", "in_file"),
                                     (("timeseries", get_trimmed_length), "t_size")]),
        (trimmer,     img2float,     [("roi_file", "in_file")]),
        (img2float,   slicetime,     [("out_file", "in_file")]),
        (slicetime,   realign,       [("slice_time_corrected_file", "inputs.timeseries")]),
        (realign,     skullstrip,    [("outputs.timeseries", "inputs.timeseries")]),

        (realign,     art,           [("outputs.realign_parameters", "inputs.realignment_parameters")]),
        (img2float,   art,           [("out_file", "inputs.raw_timeseries")]),
        (skullstrip,  art,           [("outputs.timeseries", "inputs.realigned_timeseries"),
                                      ("outputs.mask_file", "inputs.mask_file")]),
        (skullstrip,  func2anat,     [("outputs.mean_func", "inputs.source_file")]),
        (inputnode,   func2anat,     [("subject_id", "inputs.subject_id")]),
        (inputnode,   confounds,     [("subject_id", "inputs.subject_id")]),
        (skullstrip,  confounds,     [("outputs.timeseries", "inputs.timeseries")]),
        (realign,     confounds,     [("outputs.realign_parameters", "inputs.motion_parameters")]),
        (func2anat,   confounds,     [("outputs.tkreg_mat", "inputs.reg_file")]),
        (confounds,   susan,         [("outputs.timeseries", "inputnode.in_files")]),
        (skullstrip,  susan,         [("outputs.mask_file", "inputnode.mask_file")]),
        (inputnode,   susan,         [("smooth_fwhm", "inputnode.fwhm")]),
        (susan,       rename,        [("outputnode.smoothed_files", "in_file")]),
        (susan,       normalize,     [("outputnode.smoothed_files", "inputs.timeseries")]),
        (inputnode,   normalize,     [("warpfield", "inputs.warpfield")]),
        (func2anat,   normalize,     [("outputs.flirt_mat", "inputs.flirt_affine")]),
        (confounds,   tosurf,        [("outputs.timeseries", "inputs.timeseries")]),
        (func2anat,   tosurf,        [("outputs.tkreg_mat", "inputs.tkreg_affine")]),
        (inputnode,   tosurf,        [("subject_id", "inputs.subject_id"),
                                      ("smooth_fwhm", "inputs.smooth_fwhm")]),
        ])

    # Define the outputs of the top-level workflow
    output_fields = ["volume_timeseries",
                     "surface_timeseries",
                     "native_timeseries",
                     "example_func",
                     "mean_func",
                     "functional_mask",
                     "realign_parameters",
                     "mean_func_slices",
                     "intensity_plot",
                     "outlier_volumes",
                     "realign_report",
                     "flirt_affine",
                     "tkreg_affine",
                     "coreg_report",
                     "confound_sources"]


    outputnode = pe.Node(util.IdentityInterface(fields=output_fields),
                         name="outputspec")

    resting.connect([
        (realign,     outputnode,     [("outputs.realign_report", "realign_report"),
                                       ("outputs.realign_parameters", "realign_parameters"),
                                       ("outputs.example_func", "example_func")]),
        (skullstrip,  outputnode,     [("outputs.mean_func", "mean_func"),
                                       ("outputs.mask_file", "functional_mask"),
                                       ("outputs.report_png", "mean_func_slices")]),
        (art,         outputnode,     [("outputs.intensity_plot", "intensity_plot"),
                                       ("outputs.outlier_volumes", "outlier_volumes")]),
        (func2anat,   outputnode,     [("outputs.tkreg_mat", "tkreg_affine"),
                                       ("outputs.flirt_mat", "flirt_affine"),
                                       ("outputs.report", "coreg_report")]),
        (confounds,    outputnode,     [("outputs.confound_sources", "confound_sources")]),
        (tosurf,       outputnode,    [("outputs.timeseries", "surface_timeseries")]),
        (normalize,    outputnode,    [("outputs.timeseries", "volume_timeseries")]),
        (rename,       outputnode,    [("out_file", "native_timeseries")]),
        ])

    return resting, inputnode, outputnode
Example #4
0
def create_resting_workflow(name="resting_state"):
    """Return a preprocessing workflow.

    Input spec node takes these three inputs:
        - Timeseries (image files)
        - FWHM of smoothing kernel for (in mms)
        - FNIRT warp coefficient image
        - Freesurfer Subject ID
 
    Output node returns these files:
        - Smoothed timeseries (fully preprocessed and smoothed timeseries in native space)
        - Unsmoothed timeseries (identical steps except no smoothing in the volume)
        - Example func (target volume for MCFLIRT realignment)
        - Mean func (unsmoothed mean functional)
        - Funcational mask (binary dilated brainmask in functional space)
        - Realignment parameters (text files from MCFLIRT)
        - Outlier Files (outlier text files from ART)
        - Plotted estimated rotations from MCFLIRT
        - Plotted estimated translastion from MCFLIRT
        - Plotted estimated relative and absolute displacement from MCFLIRT
        - Plotted global mean intensity value
        - Sliced png of the example func (MCFLIRT target)
        - Sliced png of the unsmoothed mean functional volume
        - Tkregister-style affine matrix
        - FSL-style affine matrix
        - Sliced png summarizing the functional to anatomical transform
        - Optimization cost file quantitatively summarizing the transformation

    """
    resting = pe.Workflow(name=name)

    # Define the inputs for the preprocessing workflow
    inputnode = pe.Node(util.IdentityInterface(
        fields=["timeseries", "subject_id", "warpfield", "smooth_fwhm"]),
                        name="inputspec")

    # Remove the first two frames to account for T1 stabalization
    trimmer = pe.MapNode(fsl.ExtractROI(t_min=6),
                         iterfield=["in_file"],
                         name="trimmer")

    # Convert functional images to float representation
    img2float = pe.MapNode(fsl.ChangeDataType(output_datatype="float"),
                           iterfield=["in_file"],
                           name="img2float")

    # Perform slice-timing correction
    slicetime = pe.MapNode(fsl.SliceTimer(interleaved=True, time_repetition=6),
                           iterfield=["in_file"],
                           name="slicetime")

    # Motion correct
    realign = create_realignment_workflow()

    skullstrip = create_skullstrip_workflow()

    art = create_art_workflow(make_movie=False)

    func2anat = create_bbregister_workflow()

    confounds = create_confound_removal_workflow()

    susan = create_susan_smooth()

    normalize = create_normalize_workflow()

    tosurf = create_surface_projection_workflow()

    rename = pe.MapNode(util.Rename(format_string="timeseries", keep_ext=True),
                        iterfield=["in_file"],
                        name="rename")

    resting.connect([
        (inputnode, trimmer, [("timeseries", "in_file"),
                              (("timeseries", get_trimmed_length), "t_size")]),
        (trimmer, img2float, [("roi_file", "in_file")]),
        (img2float, slicetime, [("out_file", "in_file")]),
        (slicetime, realign, [("slice_time_corrected_file",
                               "inputs.timeseries")]),
        (realign, skullstrip, [("outputs.timeseries", "inputs.timeseries")]),
        (realign, art, [("outputs.realign_parameters",
                         "inputs.realignment_parameters")]),
        (img2float, art, [("out_file", "inputs.raw_timeseries")]),
        (skullstrip, art, [("outputs.timeseries",
                            "inputs.realigned_timeseries"),
                           ("outputs.mask_file", "inputs.mask_file")]),
        (skullstrip, func2anat, [("outputs.mean_func", "inputs.source_file")]),
        (inputnode, func2anat, [("subject_id", "inputs.subject_id")]),
        (inputnode, confounds, [("subject_id", "inputs.subject_id")]),
        (skullstrip, confounds, [("outputs.timeseries", "inputs.timeseries")]),
        (realign, confounds, [("outputs.realign_parameters",
                               "inputs.motion_parameters")]),
        (func2anat, confounds, [("outputs.tkreg_mat", "inputs.reg_file")]),
        (confounds, susan, [("outputs.timeseries", "inputnode.in_files")]),
        (skullstrip, susan, [("outputs.mask_file", "inputnode.mask_file")]),
        (inputnode, susan, [("smooth_fwhm", "inputnode.fwhm")]),
        (susan, rename, [("outputnode.smoothed_files", "in_file")]),
        (susan, normalize, [("outputnode.smoothed_files", "inputs.timeseries")
                            ]),
        (inputnode, normalize, [("warpfield", "inputs.warpfield")]),
        (func2anat, normalize, [("outputs.flirt_mat", "inputs.flirt_affine")]),
        (confounds, tosurf, [("outputs.timeseries", "inputs.timeseries")]),
        (func2anat, tosurf, [("outputs.tkreg_mat", "inputs.tkreg_affine")]),
        (inputnode, tosurf, [("subject_id", "inputs.subject_id"),
                             ("smooth_fwhm", "inputs.smooth_fwhm")]),
    ])

    # Define the outputs of the top-level workflow
    output_fields = [
        "volume_timeseries", "surface_timeseries", "native_timeseries",
        "example_func", "mean_func", "functional_mask", "realign_parameters",
        "mean_func_slices", "intensity_plot", "outlier_volumes",
        "realign_report", "flirt_affine", "tkreg_affine", "coreg_report",
        "confound_sources"
    ]

    outputnode = pe.Node(util.IdentityInterface(fields=output_fields),
                         name="outputspec")

    resting.connect([
        (realign, outputnode, [("outputs.realign_report", "realign_report"),
                               ("outputs.realign_parameters",
                                "realign_parameters"),
                               ("outputs.example_func", "example_func")]),
        (skullstrip, outputnode, [("outputs.mean_func", "mean_func"),
                                  ("outputs.mask_file", "functional_mask"),
                                  ("outputs.report_png", "mean_func_slices")]),
        (art, outputnode, [("outputs.intensity_plot", "intensity_plot"),
                           ("outputs.outlier_volumes", "outlier_volumes")]),
        (func2anat, outputnode, [("outputs.tkreg_mat", "tkreg_affine"),
                                 ("outputs.flirt_mat", "flirt_affine"),
                                 ("outputs.report", "coreg_report")]),
        (confounds, outputnode, [("outputs.confound_sources",
                                  "confound_sources")]),
        (tosurf, outputnode, [("outputs.timeseries", "surface_timeseries")]),
        (normalize, outputnode, [("outputs.timeseries", "volume_timeseries")]),
        (rename, outputnode, [("out_file", "native_timeseries")]),
    ])

    return resting, inputnode, outputnode
                                           'anisotropic_voxel',
                                           'isotropic_surface'])]

realign = pe.Node(interface=spm.Realign(), name="realign")
realign.inputs.register_to_mean = True

isotropic_voxel_smooth = pe.Node(interface=spm.Smooth(),
                                 name="isotropic_voxel_smooth")
preprocessing.connect(realign, "realigned_files", isotropic_voxel_smooth,
                      "in_files")
preprocessing.connect(iter_fwhm, "fwhm", isotropic_voxel_smooth, "fwhm")

compute_mask = pe.Node(interface=nipy.ComputeMask(), name="compute_mask")
preprocessing.connect(realign, "mean_image", compute_mask, "mean_volume")

anisotropic_voxel_smooth = fsl_wf.create_susan_smooth(name="anisotropic_voxel_smooth",
                                                      separate_masks=False)
anisotropic_voxel_smooth.inputs.smooth.output_type = 'NIFTI'
preprocessing.connect(realign, "realigned_files", anisotropic_voxel_smooth,
                      "inputnode.in_files")
preprocessing.connect(iter_fwhm, "fwhm", anisotropic_voxel_smooth,
                      "inputnode.fwhm")
preprocessing.connect(compute_mask, "brain_mask", anisotropic_voxel_smooth,
                      'inputnode.mask_file')



recon_all = pe.Node(interface=fs.ReconAll(), name = "recon_all")

surfregister = pe.Node(interface=fs.BBRegister(),name='surfregister')
surfregister.inputs.init = 'fsl'
surfregister.inputs.contrast_type = 't2'
def create_func_preproc_workflow(name='functional_preprocessing', whichvol='middle', timeshift=False, tpattern=None, delete_vols=0, func_preproc_name="func_preproc"):
        
    #####
    # Setup workflow
    #####
    
    preproc = pe.Workflow(name=name)
    
    
    #####
    # Setup input node
    #####
    
    input_fields = [
        "func",     # list of functional images to run
        "fwhm",     # fwhm
        "highpass", # highpass filtering
        "lowpass",  # lowpass filtering
        "motion_nstages"
    ]
    inputnode = pe.Node(interface=util.IdentityInterface(fields=input_fields), 
                            name="inputspec")
    
    
    #####
    # Setup output node
    #####
    
    # Outputs
    output_fields = [
        "func_mc_ref",      # reference for motion correction
        "motion",           # motion parameters
        "motion_rot",       # plot of rotation
        "motion_trans",     # plot of translations
        "motion_disp",      # plot of abs/rel displacement
        "motion_max",       # textfile with max abs/rel displacement
        "func_mc",          # 4D motion corrected and skull stripped data
        "func_afnimask",    # mask from 3dAutomask
        "example_func",     # useful for registration later (simply a mean image)
        "func_mask",        # mask that is less contrained
#        "func_mc_sm",       # smoothed data
#        "func_mc_sm_ft",    # time filtered data
        func_preproc_name,  # final output (also has been intensity normalized)
        "func_mean",        # mean of final output
        "example_func_all", 
        "func_mask_all",
        "motion_all",
        "motion_01",
        "motion_02",
        "motion_03",
        "motion_04",
        "motion_05",
        "motion_06",
        "pics_func_mean_head1",
        "pics_func_mean_head2",
        "pics_func_mean_brain1",
        "pics_func_mean_brain2",
        "global_intensity", 
        "norm", 
        "outlier_vols", 
        "pics_outlier_vols", 
        "pics_global_plot"        
    ]
    outputnode = pe.Node(util.IdentityInterface(fields=output_fields),
                        name="outputspec")
    
    #####
    # Setup renaming
    #####
    
    renamer = OutputConnector(preproc, outputnode)  # allows easy renaming of output file names
    
    
    #####
    # Main Commands
    ####
    
    """
    Prepare Input
    """
    
    # Convert functional images to float representation
    img2float = pe.MapNode(fsl.ChangeDataType(output_datatype="float"),
                           iterfield=["in_file"],
                           name="00_img2float")
    preproc.connect(inputnode, 'func', img2float, 'in_file')
    nextnode = img2float
    nextout = 'out_file'
    
    # Remove the first X frames to account for T2 stabalization
    if delete_vols > 0:
        trimmer = pe.MapNode(fsl.ExtractROI(t_min=delete_vols),
                             iterfield=["in_file"],
                             name="00_trimmer")
        preproc.connect(img2float, 'out_file', trimmer, 'in_file')
        preproc.connect(img2float, ('out_file', get_trimmed_length, delete_vols), 
                        trimmer, 't_size')
        nextnode = trimmer
        nextout = 'roi_file'
    
    """
    Time Shift Slices
    """
    
    if timeshift:
        tshift = pe.MapNode(afni.ThreedTshift(tzero=0),
                            iterfield=["in_file"], name="01_tshift")
        if tpattern is not None:
            tshift.inputs.tpattern = tpattern
        preproc.connect(nextnode, nextout, tshift, 'in_file')
        nextnode = tshift
        nextout = 'out_file'
    
    """
    Deoblique and Reorient to FSL Friendly Space
    """
    
    #deoblique = pe.MapNode(interface=afni.ThreedWarp(deoblique=True), 
    #                        iterfield=["in_file"], name='01_deoblique')
    #preproc.connect(nextnode, nextout, deoblique, "in_file")
    deoblique = pe.MapNode(interface=afni.Threedrefit(deoblique=True), 
                            iterfield=["in_file"], name='01_deoblique')
    preproc.connect(nextnode, nextout, deoblique, "in_file")
    
    # TODO:
    # get orientation using following command:
    # orient=$( 3dinfo /Users/Shared/fsl/data/standard/MNI152_T1_2mm.nii.gz | grep orient | sed -e s/.*orient// -e s/\]// )
    # so add additional input of reference orientation! (maybe this can be a general option?)
    reorient = pe.MapNode(interface=afni.Threedresample(orientation='RPI'), 
                            iterfield=["in_file"], name='01_reorient')
    preproc.connect(deoblique, "out_file", reorient, "in_file")
    
    """
    Motion Correction
    """
    
    # Get the middle volume of each run for motion correction 
    if whichvol != 'mean':
        extract_ref = pe.Node(fsl.ExtractROI(t_size=1), iterfield=["in_file", "t_min"],
                                name = "02_extractref")
        preproc.connect(reorient, ('out_file', pickfirst), extract_ref, 'in_file')
        preproc.connect(reorient, ('out_file', pickvol, 0, whichvol), extract_ref, 't_min')
        renamer.connect(extract_ref, 'roi_file', 'func_mc_ref')
    
    # Realign the functional runs to the reference (some volume from the 1st run)
    motion_correct = pe.MapNode(interface=fsl.MCFLIRT(save_mats = True,
                                                      save_plots = True,
                                                      save_rms = True,
                                                      interpolation = 'sinc'),
                                name='02_realign', iterfield = ['in_file'])
    preproc.connect(reorient, 'out_file', motion_correct, 'in_file')
    preproc.connect(inputnode, 'motion_nstages', motion_correct, 'stages')
    if whichvol != 'mean':
        preproc.connect(extract_ref, 'roi_file', motion_correct, 'ref_file')
    else:
        motion_correct.inputs.mean_vol = True
        renamer.connect(motion_correct, ('mean_img', pickfirst), 'func_mc_ref')
    renamer.connect(motion_correct, 'par_file', 'motion')
    
    # Combine motion parameters from different runs
    combinemotion = pe.Node(util.Function(input_names=["in_files"],
                                    output_names=["out_file"],
                                    function=combine_motion_params),
                           name="combinemotion")
    preproc.connect(motion_correct, 'par_file', combinemotion, 'in_files')
    renamer.connect(combinemotion, 'out_file', 'motion_all')
    
    # Split motion up
    splitmotion = pe.Node(util.Function(input_names=["in_file", "out_prefix"],
                                        output_names=["out_files"], 
                                        function=split_motion_params), 
                          name="splitmotion")
    preproc.connect(combinemotion, "out_file", splitmotion, "in_file")
    preproc.connect(splitmotion, ("out_files", pick_list_elem, 0), outputnode, 'motion_01')
    preproc.connect(splitmotion, ("out_files", pick_list_elem, 1), outputnode, 'motion_02')
    preproc.connect(splitmotion, ("out_files", pick_list_elem, 2), outputnode, 'motion_03')
    preproc.connect(splitmotion, ("out_files", pick_list_elem, 3), outputnode, 'motion_04')
    preproc.connect(splitmotion, ("out_files", pick_list_elem, 4), outputnode, 'motion_05')
    preproc.connect(splitmotion, ("out_files", pick_list_elem, 5), outputnode, 'motion_06')
    
    # Plot rotation parameters from MCFLIRT
    plotrot = pe.MapNode(fsl.PlotMotionParams(in_source="fsl", plot_type="rotations"),
                         name="02_plotrotation", iterfield=["in_file"])
    preproc.connect(motion_correct, 'par_file', plotrot, 'in_file')
    renamer.connect(plotrot, 'out_file', 'motion_rot')
    
    # Plot translation parameters from MCFLIRT
    plottrans = pe.MapNode(fsl.PlotMotionParams(in_source="fsl", plot_type="translations"),
                           name="02_plottranslation", iterfield=["in_file"])
    preproc.connect(motion_correct, 'par_file', plottrans, 'in_file')
    renamer.connect(plottrans, 'out_file', 'motion_trans')
    
    # Plot displacement parameters from MCFLIRT
    plotdisp = pe.MapNode(fsl.PlotMotionParams(in_source="fsl", plot_type="displacement"),
                          name="02_plotdisplacement", iterfield=["in_file"])
    preproc.connect(motion_correct, 'rms_files', plotdisp, 'in_file')
    renamer.connect(plotdisp, 'out_file', 'motion_disp')
    
    # Plot maximum displacement parameters (abs/rel) from MCFLIRT
    maxmotion = pe.MapNode(util.Function(input_names=["rms_files"],
                                         output_names=["out_file"],
                                         function=max_motion_func),
                           iterfield=["rms_files"], name="02_maxmotion")
    preproc.connect(motion_correct, 'rms_files', maxmotion, 'rms_files')
    renamer.connect(maxmotion, 'out_file', 'motion_max')
    
    """
    Skull Strip
    """
    
    # Get a mean image of the realigned timeseries
    meanfunc1 = pe.MapNode(fsl.MeanImage(),
                           iterfield=["in_file"],
                           name="03_meanfunc1")
    preproc.connect(motion_correct, 'out_file', meanfunc1, 'in_file')
    
    # Get slices
    slicer_head1 = pe.MapNode(interface=misc.Slicer(width=5, height=4, slice_name="axial"), 
                                iterfield = ["in_file"], 
                                name = 'slicer_head1')
    slicer_head2 = pe.MapNode(interface=misc.Slicer(width=5, height=4, slice_name="sagittal"), 
                                iterfield = ["in_file"], 
                                name = 'slicer_head2')
    preproc.connect([
        (meanfunc1, slicer_head1, [('out_file', 'in_file')]),
        (meanfunc1, slicer_head2, [('out_file', 'in_file')])
    ])
    renamer.connect(slicer_head1, "out_file", "pics_func_mean_head1")
    renamer.connect(slicer_head2, "out_file", "pics_func_mean_head2")
    
    # Skullstrip the mean functional image
    meanmask1 = pe.MapNode(afni.ThreedAutomask(dilate = 1),
                           iterfield = ["in_file"],
                           name = "03_meanmask1")
    preproc.connect(meanfunc1, 'out_file', meanmask1, 'in_file')
    renamer.connect(meanmask1, 'out_file', 'func_afnimask')
    
    # Apply to mean
    meanfunc2 = pe.MapNode(fsl.ApplyMask(),
                            iterfield=["in_file", "mask_file"],
                            name = "03_meanfunc2")
    preproc.connect(meanfunc1, 'out_file', meanfunc2, 'in_file')
    preproc.connect(meanmask1, 'out_file', meanfunc2, 'mask_file')
    renamer.connect(meanfunc2, 'out_file', 'example_func')
    
    # Get slices
    slicer_brain1 = pe.MapNode(interface=misc.Slicer(width=5, height=4, slice_name="axial"), 
                                iterfield = ["in_file"], 
                                name = 'slicer_brain1')
    slicer_brain2 = pe.MapNode(interface=misc.Slicer(width=5, height=4, slice_name="sagittal"), 
                                iterfield = ["in_file"], 
                                name = 'slicer_brain2')
    preproc.connect([
        (meanfunc2, slicer_brain1, [('out_file', 'in_file')]),
        (meanfunc2, slicer_brain2, [('out_file', 'in_file')])
    ])
    renamer.connect(slicer_brain1, "out_file", "pics_func_mean_brain1")
    renamer.connect(slicer_brain2, "out_file", "pics_func_mean_brain2")
    
    # Combine different means and get their mean
    mergenode = pe.Node(fsl.Merge(dimension="t"), name="03b_merge")
    preproc.connect(meanfunc2, 'out_file', mergenode, 'in_files')
    meanfunc = pe.Node(fsl.MeanImage(), name="03b_meanfunc")
    preproc.connect(mergenode, 'merged_file', meanfunc, 'in_file')
    renamer.connect(meanfunc, 'out_file', 'example_func_all', format_string="example_func")
    
    # Apply to 4D functional
    funcbrain1 = pe.MapNode(fsl.ApplyMask(),
                           iterfield=["in_file", "mask_file"],
                           name = "03_funcbrain1")
    preproc.connect(motion_correct, 'out_file', funcbrain1, 'in_file')
    preproc.connect(meanmask1, 'out_file', funcbrain1, 'mask_file')
    #renamer.connect(funcbrain1, 'out_file', 'func_mc')
    
    """
    Dilated Brain Mask
    """
    
    # Determine the 2nd and 98th percentile intensities of each run
    getthresh = pe.MapNode(fsl.ImageStats(op_string="-p 2 -p 98"),
                           iterfield = ["in_file"],
                           name="04_getthreshold")
    preproc.connect(funcbrain1, 'out_file', getthresh, 'in_file')
    
    # Threshold the functional data at 10% of the 98th percentile
    threshold = pe.MapNode(fsl.ImageMaths(out_data_type="char",
                                          suffix="_thresh"),
                           iterfield = ["in_file", "op_string"],
                           name="04_threshold")
    preproc.connect(funcbrain1, 'out_file', threshold, "in_file")
    preproc.connect(getthresh, ("out_stat", get_thresh_op), threshold, "op_string")
    
    # Determine the median value of the functional runs using the mask
    medianval = pe.MapNode(fsl.ImageStats(op_string="-k %s -p 50"),
                           iterfield = ["in_file", "mask_file"],
                           name="04_medianval")
    preproc.connect(motion_correct, 'out_file', medianval, 'in_file')
    preproc.connect(threshold, 'out_file', medianval, 'mask_file')
    
    # Dilate the mask
    dilatemask = pe.MapNode(fsl.DilateImage(operation="max"),
                            iterfield=["in_file"],
                            name="04_dilatemask")
    preproc.connect(threshold, 'out_file', dilatemask, 'in_file')
    renamer.connect(dilatemask, 'out_file', 'func_mask')
    
    # Combine masks
    mergenode = pe.Node(fsl.Merge(dimension="t"), name="04b_merge")
    preproc.connect(dilatemask, 'out_file', mergenode, 'in_files')
    maskfunc = pe.Node(fsl.ImageMaths(op_string="-Tmin", 
                                          suffix="_mask"),
                           name="04b_maskfunc")
    preproc.connect(mergenode, 'merged_file', maskfunc, 'in_file')
    renamer.connect(maskfunc, 'out_file', 'func_mask_all', format_string="func_mask")
    
    # Mask the runs again with this new mask
    funcbrain2 = pe.MapNode(fsl.ApplyMask(),
                           iterfield=["in_file", "mask_file"],
                           name="04_funcbrain2")
    preproc.connect(motion_correct, 'out_file', funcbrain2, 'in_file')
    preproc.connect(dilatemask, 'out_file', funcbrain2, 'mask_file')
    renamer.connect(funcbrain2, 'out_file', 'func_mc')
    
    # Get a new mean image from each functional run
    meanfunc3 = pe.MapNode(fsl.MeanImage(),
                           iterfield=["in_file"],
                           name="04_meanfunc3")
    preproc.connect(funcbrain2, 'out_file', meanfunc3, 'in_file')        
    
    """
    Detect Any Artifacts
    """
    
    art = pe.MapNode(ra.ArtifactDetect(use_differences = [True, False],
                                       use_norm = True,
                                       zintensity_threshold = 4,
                                       norm_threshold = 1,
                                       parameter_source = "FSL",
                                       mask_type = "file"),
                     iterfield=["realignment_parameters","realigned_files","mask_file"],
                     name="05_art")
    preproc.connect(motion_correct, "par_file", art, "realignment_parameters")
    preproc.connect(funcbrain2, "out_file", art, "realigned_files")
    preproc.connect(dilatemask, "out_file", art, "mask_file")
    renamer.connect(art, 'intensity_files', 'global_intensity')
    renamer.connect(art, 'norm_files', 'norm')
    renamer.connect(art, 'outlier_files', 'outlier_vols')
    renamer.connect(art, 'plot_files', 'pics_outlier_vols')
    
    plotmean = pe.MapNode(fsl.PlotTimeSeries(title="Global Mean Intensity"),
                          iterfield=["in_file"],
                          name="05_plotmean")
    preproc.connect(art, 'intensity_files', plotmean, 'in_file')
    renamer.connect(plotmean, 'out_file', 'pics_global_plot')
    
    """
    Smoothing
    """
    
    # Anisitropic-like? smoothing with your friend susan
    smooth = create_susan_smooth(name="06_susan_smooth")
    preproc.connect(inputnode, 'fwhm', smooth, 'inputnode.fwhm')
    preproc.connect(funcbrain2, 'out_file', smooth, 'inputnode.in_files')
    preproc.connect(dilatemask, 'out_file', smooth, 'inputnode.mask_file')
    
    # Mask smoothed data with dilated mask
    funcbrain3 = pe.MapNode(fsl.ApplyMask(),
                           iterfield=["in_file", "mask_file"],
                           name="06_funcbrain3")
    preproc.connect(smooth, 'outputnode.smoothed_files', funcbrain3, 'in_file')
    preproc.connect(dilatemask, 'out_file', funcbrain3, 'mask_file')
    
    # Determine if want to take output from smoothed or non-smoothed data forward
    # This would be the case if the fwhm is less than 1/3 of the voxel size
    ## gather 2 types of functional images
    concatnode = pe.Node(interface=util.Merge(2),
                         name='06_concat')
    preproc.connect(funcbrain2, ('out_file', tolist), concatnode, 'in1')
    preproc.connect(funcbrain3, ('out_file', tolist), concatnode, 'in2')
    ## select one
    selectnode = pe.Node(interface=util.Select(),name='06_select')
    preproc.connect(concatnode, 'out', selectnode, 'inlist')
    preproc.connect(inputnode, ('fwhm', chooseindex), selectnode, 'index')
    #rename_smooth = renamer.connect(selectnode, 'out', 'func_mc_sm', 
    #                                format_string="func_mc_sm%(fwhm)s", 
    #                                fwhm=None)
    #preproc.connect(inputnode, ('fwhm', fwhm_used), rename_smooth, 'fwhm')
    
    """
    Filter
    """
    
    filt = pe.MapNode(fsl.TemporalFilter(),
                          iterfield=["in_file"],
                          name="07_filter")
    preproc.connect(inputnode, 'highpass', filt, 'highpass_sigma')
    preproc.connect(inputnode, 'lowpass', filt, 'lowpass_sigma')
    preproc.connect(selectnode, 'out', filt, 'in_file')
    ## set renamed output
    #rename_filt = renamer.connect(filt, 'out_file', 'func_mc_sm_ft', 
    #                              format_string="func_mc_sm%(fwhm)s_hp%(hp)s_lp%(lp)s",
    #                              fwhm=None, hp=None, lp=None)
    #preproc.connect(inputnode, ('fwhm', fwhm_used), rename_filt, 'fwhm')
    #preproc.connect(inputnode, ('highpass', filter_used), rename_filt, 'hp')
    #preproc.connect(inputnode, ('lowpass', filter_used), rename_filt, 'lp')
    
    """
    Intensity Normalization
    """
    
    # Scale mean value of run to 10000
    meanscale = pe.MapNode(interface=fsl.ImageMaths(suffix='_gms'),
                          iterfield=['in_file', 'op_string'],
                          name='08_meanscale')
    preproc.connect(filt, 'out_file', meanscale, 'in_file')
    ## function to get scaling factor
    preproc.connect(medianval, ('out_stat', getmeanscale), meanscale, 'op_string')
    
    """
    Get Final Functional Data and Mean
    """
    ## functional 4D
    renamer.connect(meanscale, 'out_file', func_preproc_name)
    ## mean
    meanfunc4 = pe.MapNode(fsl.MeanImage(),
                           iterfield=["in_file"],
                           name="08_meanfunc4")
    preproc.connect(meanscale, 'out_file', meanfunc4, 'in_file')
    renamer.connect(meanfunc4, 'out_file', 'func_mean')
    
    """
    Combine all ? (maybe make another workflow)
    """
    
    # Use the -t Merge option to 
    
    # Use fslmaths -Tmin -bin to get proper mask
    
    # Get mean image across entire run
    
    # Combine all the motion together
    
    return preproc