Beispiel #1
0
def petpvc_workflow(wf_name="petpvc"):
    """ Run the PET pre-processing workflow against the gunzip_pet.in_file files.
    It coregisters the reference_file and tissues to PET space, then applies PVC and grey matter normalization.

    It does:
    - SPM12 Coregister T1 and tisues to PET
    - PVC the PET image in PET space

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

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

    pvc_input.reference_file: traits.File
        The anatomical image in its native space. For registration reference.

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

    Nipype outputs
    --------------
    pvc_output.coreg_ref: existing file
        The coregistered reference_file image in PET space.

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

    pvc_output.pvc_out: existing file
        The output of the PETPVC process.

    pvc_output.petpvc_mask: existing file
        The mask built for the PETPVC.

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

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

    Returns
    -------
    wf: nipype Workflow
    """
    # fixed parameters of the NUK mMR
    psf_fwhm = (4.3, 4.3, 4.3)

    # specify input and output fields
    in_fields = [
        "in_file",
        "reference_file",
        "tissues",
    ]

    out_fields = [
        "coreg_ref",
        "coreg_others",
        "pvc_out",
        "petpvc_mask",
        "brain_mask",
        "gm_norm",
    ]

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

    flat_list = pe.Node(Function(input_names=['list_of_lists'],
                                 output_names=['out'],
                                 function=flatten_list),
                        name='flatten_tissue_list')

    # coreg pet
    gunzip_pet = setup_node(Gunzip(), name="gunzip_pet")
    coreg_pet = setup_node(spm_coregister(cost_function="mi"),
                           name="coreg_pet")

    tissues_sel = setup_node(Select(index=[0, 1, 2]), name="tissues")
    select_gm = setup_node(Select(index=[0]), name="select_gm")
    pvc = setup_node(petpvc_cmd(fwhm_mm=psf_fwhm, pvc_method='RBV'),
                     name="pvc")

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

    # workflow to create the mask
    mask_wf = petpvc_mask(wf_name="petpvc_mask")

    # workflow for intensity normalization
    norm_wf = intensity_norm(wf_name="intensity_norm_gm")

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

    wf.connect([
        # inputs
        (pet_input, gunzip_pet, [("in_file", "in_file")]),
        (pet_input, tissues_sel, [("tissues", "inlist")]),
    ])

    # check how to perform the registration, to decide how to build the pipeline
    anat2pet = get_config_setting('registration.anat2pet', False)
    if anat2pet:
        wf.connect([
            # inputs
            (pet_input, coreg_pet, [("reference_file", "source")]),

            # unzip to coregister the reference file (anatomical image) to PET space.
            (gunzip_pet, coreg_pet, [("out_file", "target")]),
            (tissues_sel, flat_list, [("out", "list_of_lists")]),
            (flat_list, coreg_pet, [("out", "apply_to_files")]),

            # the list of tissues to the mask wf and the GM for PET intensity normalization
            (coreg_pet, select_gm, [("coregistered_files", "inlist")]),
            (coreg_pet, mask_wf, [("coregistered_files",
                                   "pvcmask_input.tissues")]),

            # the PET in native space to PVC correction
            (gunzip_pet, pvc, [("out_file", "in_file")]),

            # the merged file with 4 tissues to PCV correction
            (mask_wf, pvc, [("pvcmask_output.petpvc_mask", "mask_file")]),

            # normalize voxel values of PET PVCed by demeaning it entirely by GM PET voxel values
            (pvc, norm_wf, [("out_file", "intnorm_input.source")]),
            (select_gm, norm_wf, [("out", "intnorm_input.mask")]),

            # output
            (coreg_pet, pvc_output, [("coregistered_source", "coreg_ref")]),
            (coreg_pet, pvc_output, [("coregistered_files", "coreg_others")]),
            (pvc, pvc_output, [("out_file", "pvc_out")]),
            (mask_wf, pvc_output, [("pvcmask_output.brain_mask", "brain_mask")
                                   ]),
            (mask_wf, pvc_output, [("pvcmask_output.petpvc_mask",
                                    "petpvc_mask")]),
            (norm_wf, pvc_output, [("intnorm_output.out_file", "gm_norm")]),
        ])
    else:  # PET to ANAT
        wf.connect([
            # inputs
            (pet_input, coreg_pet, [("reference_file", "target")]),

            # unzip PET image and set as a source to register it to anatomical space.
            (gunzip_pet, coreg_pet, [("out_file", "source")]),
            (tissues_sel, flat_list, [("out", "list_of_lists")]),
            (flat_list, coreg_pet, [("out", "apply_to_files")]),

            # the list of tissues to the mask wf and the GM for PET intensity normalization
            (tissues_sel, select_gm, [("out", "inlist")]),
            (flat_list, mask_wf, [("out", "pvcmask_input.tissues")]),

            # the PET in ANAT space to PVC correction
            (coreg_pet, pvc, [("coregistered_source", "in_file")]),

            # the merged file with 4 tissues to PCV correction
            (mask_wf, pvc, [("pvcmask_output.petpvc_mask", "mask_file")]),

            # normalize voxel values of PET PVCed by demeaning it entirely by GM PET voxel values
            (pvc, norm_wf, [("out_file", "intnorm_input.source")]),
            (select_gm, norm_wf, [("out", "intnorm_input.mask")]),

            # output
            # TODO: coreg_ref should have a different name in this case
            (coreg_pet, pvc_output, [("coregistered_source", "coreg_ref")]),
            (coreg_pet, pvc_output, [("coregistered_files", "coreg_others")]),
            (pvc, pvc_output, [("out_file", "pvc_out")]),
            (mask_wf, pvc_output, [("pvcmask_output.brain_mask", "brain_mask")
                                   ]),
            (mask_wf, pvc_output, [("pvcmask_output.petpvc_mask",
                                    "petpvc_mask")]),
            (norm_wf, pvc_output, [("intnorm_output.out_file", "gm_norm")]),
        ])

    return wf
Beispiel #2
0
def fmri_cleanup_wf(wf_name="fmri_cleanup"):
    """ Run the resting-state fMRI pre-processing workflow against the rest files in `data_dir`.

    Tasks:
    - Trim first 6 volumes of the rs-fMRI file.
    - Slice Timing correction.
    - Motion and nuisance correction.
    - Calculate brain mask in fMRI space.
    - Bandpass frequency filtering for resting-state fMRI.
    - Smoothing.
    - Tissue maps co-registration to fMRI space.

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

    Nipype Inputs
    -------------
    rest_input.in_file: traits.File
        The resting-state fMRI file.

    rest_input.anat: traits.File
        Path to the high-contrast anatomical image.

    rest_input.tissues: list of traits.File
        Paths to the tissue segmentations in anatomical space.
        Expected to have this order: GM, WM and CSF.

    rest_input.highpass_sigma:traits.Float
        Band pass timeseries filter higher bound in Hz.

    rest_input.lowpass_sigma: traits.Float
        Band pass timeseries filter lower bound in Hz.

    Nipype Outputs
    --------------
    rest_output.smooth: traits.File
        The isotropically smoothed time filtered nuisance corrected image.

    rest_output.nuis_corrected: traits.File
        The nuisance corrected fMRI file.

    rest_output.motion_params: traits.File
        The affine transformation file.

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

    rest_output.epi_brain_mask: traits.File
        An estimated brain mask from mean EPI volume.

    rest_output.tissues_brain_mask: traits.File
        A brain mask calculated from the addition of coregistered
        GM, WM and CSF segmentation volumes from the anatomical
        segmentation.

    rest_output.tissues: list of traits.File
        The tissues segmentation volume in fMRI space.
        Expected to have this order: GM, WM and CSF.

    rest_output.anat: traits.File
        The T1w image in fMRI space.

    rest_output.avg_epi: traits.File
        The average EPI image in fMRI space after slice-time and motion correction.

    rest_output.motion_regressors: traits.File

    rest_output.compcor_regressors: traits.File

    rest_output.art_displacement_files
        One image file containing the voxel-displacement timeseries.

    rest_output.art_intensity_files
        One file containing the global intensity values determined from the brainmask.

    rest_output.art_norm_files
        One file containing the composite norm.

    rest_output.art_outlier_files
         One file containing a list of 0-based indices corresponding to outlier volumes.

    rest_output.art_plot_files
        One image file containing the detected outliers.

    rest_output.art_statistic_files
        One file containing information about the different types of artifacts and if design info is provided then
        details of stimulus correlated motion and a listing or artifacts by event type.

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

    # specify input and output fields
    in_fields = [
        "in_file",
        "anat",
        "atlas_anat",
        "coreg_target",
        "tissues",
        "lowpass_freq",
        "highpass_freq",
    ]

    out_fields = [
        "motion_corrected",
        "motion_params",
        "tissues",
        "anat",
        "avg_epi",
        "time_filtered",
        "smooth",
        "tsnr_file",
        "epi_brain_mask",
        "tissues_brain_mask",
        "motion_regressors",
        "compcor_regressors",
        "gsr_regressors",
        "nuis_corrected",
        "art_displacement_files",
        "art_intensity_files",
        "art_norm_files",
        "art_outlier_files",
        "art_plot_files",
        "art_statistic_files",
    ]

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

    # rs-fMRI preprocessing nodes
    trim = setup_node(Trim(), name="trim")

    stc_wf = auto_spm_slicetime()
    realign = setup_node(nipy_motion_correction(), name='realign')

    # average
    average = setup_node(
        Function(
            function=mean_img,
            input_names=["in_file"],
            output_names=["out_file"],
            imports=['from neuro_pypes.interfaces.nilearn import ni2file']
        ),
        name='average_epi'
    )

    mean_gunzip = setup_node(Gunzip(), name="mean_gunzip")

    # co-registration nodes
    coreg = setup_node(spm_coregister(cost_function="mi"), name="coreg_fmri")
    brain_sel = setup_node(Select(index=[0, 1, 2]), name="brain_sel")

    # brain mask made with EPI
    epi_mask = setup_node(ComputeMask(), name='epi_mask')

    # brain mask made with the merge of the tissue segmentations
    tissue_mask = setup_node(fsl.MultiImageMaths(), name='tissue_mask')
    tissue_mask.inputs.op_string = "-add %s -add %s -abs -kernel gauss 4 -dilM -ero -kernel gauss 1 -dilM -bin"
    tissue_mask.inputs.out_file = "tissue_brain_mask.nii.gz"

    # select tissues
    gm_select = setup_node(Select(index=[0]), name="gm_sel")
    wmcsf_select = setup_node(Select(index=[1, 2]), name="wmcsf_sel")

    # noise filter
    noise_wf = rest_noise_filter_wf()
    wm_select = setup_node(Select(index=[1]), name="wm_sel")
    csf_select = setup_node(Select(index=[2]), name="csf_sel")

    # bandpass filtering
    bandpass = setup_node(
        Function(
            input_names=['files', 'lowpass_freq', 'highpass_freq', 'tr'],
            output_names=['out_files'],
            function=bandpass_filter
        ),
        name='bandpass'
    )

    # smooth
    smooth = setup_node(
        Function(
            function=smooth_img,
            input_names=["in_file", "fwhm"],
            output_names=["out_file"],
            imports=['from neuro_pypes.interfaces.nilearn import ni2file']
        ),
        name="smooth"
    )
    smooth.inputs.fwhm = get_config_setting('fmri_smooth.fwhm', default=8)
    smooth.inputs.out_file = "smooth_std_{}.nii.gz".format(wf_name)

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

    # Connect the nodes
    wf.connect([
        # trim
        (rest_input, trim, [("in_file", "in_file")]),

        # slice time correction
        (trim, stc_wf, [("out_file", "stc_input.in_file")]),

        # motion correction
        (stc_wf, realign, [("stc_output.timecorrected_files", "in_file")]),

        # coregistration target
        (realign, average, [("out_file", "in_file")]),
        (average, mean_gunzip, [("out_file", "in_file")]),
        (mean_gunzip, coreg, [("out_file", "target")]),

        # epi brain mask
        (average, epi_mask, [("out_file", "mean_volume")]),

        # coregistration
        (rest_input, coreg, [("anat", "source")]),
        (rest_input, brain_sel, [("tissues", "inlist")]),
        (brain_sel, coreg, [(("out", flatten_list), "apply_to_files")]),

        # tissue brain mask
        (coreg, gm_select, [("coregistered_files", "inlist")]),
        (coreg, wmcsf_select, [("coregistered_files", "inlist")]),
        (gm_select, tissue_mask, [(("out", flatten_list), "in_file")]),
        (wmcsf_select, tissue_mask, [(("out", flatten_list), "operand_files")]),

        # nuisance correction
        (coreg, wm_select, [("coregistered_files", "inlist",)]),
        (coreg, csf_select, [("coregistered_files", "inlist",)]),
        (realign, noise_wf, [("out_file", "rest_noise_input.in_file",)]),
        (tissue_mask, noise_wf, [("out_file", "rest_noise_input.brain_mask")]),
        (wm_select, noise_wf, [(("out", flatten_list), "rest_noise_input.wm_mask")]),
        (csf_select, noise_wf, [(("out", flatten_list), "rest_noise_input.csf_mask")]),

        (realign, noise_wf, [("par_file", "rest_noise_input.motion_params",)]),

        # temporal filtering
        (noise_wf, bandpass, [("rest_noise_output.nuis_corrected", "files")]),
        # (realign,     bandpass,    [("out_file", "files")]),
        (stc_wf, bandpass, [("stc_output.time_repetition", "tr")]),
        (rest_input, bandpass, [
            ("lowpass_freq", "lowpass_freq"),
            ("highpass_freq", "highpass_freq"),
        ]),
        (bandpass, smooth, [("out_files", "in_file")]),

        # output
        (epi_mask, rest_output, [("brain_mask", "epi_brain_mask")]),
        (tissue_mask, rest_output, [("out_file", "tissues_brain_mask")]),
        (realign, rest_output, [
            ("out_file", "motion_corrected"),
            ("par_file", "motion_params"),
        ]),
        (coreg, rest_output, [
            ("coregistered_files", "tissues"),
            ("coregistered_source", "anat"),
        ]),
        (noise_wf, rest_output, [
            ("rest_noise_output.motion_regressors", "motion_regressors"),
            ("rest_noise_output.compcor_regressors", "compcor_regressors"),
            ("rest_noise_output.gsr_regressors", "gsr_regressors"),
            ("rest_noise_output.nuis_corrected", "nuis_corrected"),
            ("rest_noise_output.tsnr_file", "tsnr_file"),
            ("rest_noise_output.art_displacement_files", "art_displacement_files"),
            ("rest_noise_output.art_intensity_files", "art_intensity_files"),
            ("rest_noise_output.art_norm_files", "art_norm_files"),
            ("rest_noise_output.art_outlier_files", "art_outlier_files"),
            ("rest_noise_output.art_plot_files", "art_plot_files"),
            ("rest_noise_output.art_statistic_files", "art_statistic_files"),
        ]),
        (average, rest_output, [("out_file", "avg_epi")]),
        (bandpass, rest_output, [("out_files", "time_filtered")]),
        (smooth, rest_output, [("out_file", "smooth")]),
    ])

    return wf
Beispiel #3
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
Beispiel #4
0
def spm_mrpet_preprocessing(wf_name="spm_mrpet_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.

    # TODO: organize the anat2pet hack/condition somehow:
    If anat2pet:
    - SPM12 Coregister T1 and tissues to PET
    - PETPVC the PET image in PET space
    - SPM12 Warp PET to MNI
    else:
    - SPM12 Coregister PET to T1
    - PETPVC the PET image in anatomical space
    - SPM12 Warp PET in anatomical space to MNI through the
    `anat_to_mni_warp`.

    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.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.anat_to_mni_warp: traits.File
        The warp field from the transformation of the
        anatomical image to the standard MNI space.

    pet_input.atlas_anat: traits.File
        The atlas file in anatomical 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.

    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.pvc_warped: existing file
        Results from PETPVC normalized to MNI.
        The result of every internal pre-processing step
        is normalized to MNI 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", "anat_to_mni_warp", "tissues"]

    out_fields = [
        "brain_mask",
        "coreg_others",
        "coreg_ref",
        "pvc_warped",
        "pet_warped",  # 'pet_warped' is a dummy entry to keep the fields pattern.
        "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")

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

    warp_pet = setup_node(spm_normalize(), name="warp_pet")

    tpm_bbox = setup_node(Function(function=get_bounding_box,
                                   input_names=["in_file"],
                                   output_names=["bbox"]),
                          name="tpm_bbox")
    tpm_bbox.inputs.in_file = spm_tpm_priors_path()

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

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

    # check how to perform the registration, to decide how to build the pipeline
    anat2pet = get_config_setting('registration.anat2pet', False)
    if anat2pet:
        wf.connect([
            # inputs
            (pet_input, petpvc, [("in_file", "pvc_input.in_file"),
                                 ("anat", "pvc_input.reference_file"),
                                 ("tissues", "pvc_input.tissues")]),

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

            # warp the PET PVCed to MNI
            (petpvc, warp_pet, [("pvc_output.coreg_ref", "image_to_align")]),
            (gunzipper, warp_pet, [("out_file", "apply_to_files")]),
            (tpm_bbox, warp_pet, [("bbox", "write_bounding_box")]),

            # 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")]),

            # output
            (warp_pet, pet_output, [("normalized_files", "pvc_warped"),
                                    ("deformation_field", "warp_field")]),
        ])
    else:  # PET 2 ANAT
        collector = setup_node(Merge(2), name='merge_for_warp')
        apply_warp = setup_node(spm_apply_deformations(), name="warp_pet")

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

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

            # warp the PET PVCed to MNI
            (gunzipper, collector, [("out_file", "in1")]),
            (petpvc, collector, [("pvc_output.coreg_ref", "in2")]),
            (pet_input, apply_warp, [("anat_to_mni_warp", "deformation_file")
                                     ]),
            (collector, apply_warp, [("out", "apply_to_files")]),
            (tpm_bbox, apply_warp, [("bbox", "write_bounding_box")]),

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

            # output
            (apply_warp, pet_output, [("normalized_files", "pvc_warped"),
                                      ("deformation_field", "warp_field")]),
        ])

    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")]),
        ])

    return wf
Beispiel #5
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.fmri2mni 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.fmri2mni 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
    fmri2mni = get_config_setting('registration.fmri2mni', 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 fmri2mni:
        # 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:  # fmri2mni 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 fmri2mni 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 fmri2mni:
        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