Esempio n. 1
0
def anatomical_skullstrip_workflow(workflow, resource_pool, config):

    # resource pool should have:
    #     anatomical_reorient

    import os
    import sys

    import nipype.interfaces.io as nio
    import nipype.pipeline.engine as pe

    import nipype.interfaces.utility as util

    from nipype.interfaces.afni import preprocess

    if "anatomical_reorient" not in resource_pool.keys():

        from anatomical_preproc import anatomical_reorient_workflow

        workflow, resource_pool = \
            anatomical_reorient_workflow(workflow, resource_pool, config)

    #check_input_resources(resource_pool, "anatomical_reorient")

    anat_skullstrip = pe.Node(interface=preprocess.SkullStrip(),
                              name='anat_skullstrip')

    anat_skullstrip.inputs.outputtype = 'NIFTI_GZ'

    anat_skullstrip_orig_vol = pe.Node(interface=preprocess.Calc(),
                                       name='anat_skullstrip_orig_vol')

    anat_skullstrip_orig_vol.inputs.expr = 'a*step(b)'
    anat_skullstrip_orig_vol.inputs.outputtype = 'NIFTI_GZ'

    if len(resource_pool["anatomical_reorient"]) == 2:
        node, out_file = resource_pool["anatomical_reorient"]
        workflow.connect(node, out_file, anat_skullstrip, 'in_file')
    else:
        anat_skullstrip.inputs.in_file = \
            resource_pool["anatomical_reorient"]

    if len(resource_pool["anatomical_reorient"]) == 2:
        node, out_file = resource_pool["anatomical_reorient"]
        workflow.connect(node, out_file, anat_skullstrip_orig_vol, 'in_file_a')
    else:
        anat_skullstrip_orig_vol.inputs.in_file_a = \
            resource_pool["anatomical_reorient"]

    workflow.connect(anat_skullstrip, 'out_file', anat_skullstrip_orig_vol,
                     'in_file_b')

    resource_pool["anatomical_brain"] = (anat_skullstrip_orig_vol, 'out_file')

    return workflow, resource_pool
def run_anatomical_reorient(anatomical_scan, run=True):

    # stand-alone runner for anatomical reorient workflow

    import os
    import sys

    import glob

    import nipype.interfaces.io as nio
    import nipype.pipeline.engine as pe

    workflow = pe.Workflow(name='anatomical_reorient_workflow')

    current_dir = os.getcwd()

    workflow_dir = os.path.join(current_dir, "anatomical_reorient")
    workflow.base_dir = workflow_dir


    resource_pool = {}
    config = {}
    num_cores_per_subject = 1


    resource_pool["anatomical_scan"] = anatomical_scan
    
    workflow, resource_pool = \
            anatomical_reorient_workflow(workflow, resource_pool, config)


    ds = pe.Node(nio.DataSink(), name='datasink_anatomical_reorient')
    ds.inputs.base_directory = workflow_dir
    
    node, out_file = resource_pool["anatomical_reorient"]

    workflow.connect(node, out_file, ds, 'anatomical_reorient')


    if run == True:

        workflow.run(plugin='MultiProc', plugin_args= \
                         {'n_procs': num_cores_per_subject})

        outpath = glob.glob(os.path.join(workflow_dir, "anatomical_reorient",\
                                         "*"))[0]

        return outpath

    else:

        return workflow, workflow.base_dir
def anatomical_skullstrip_workflow(workflow, resource_pool, config):

    # resource pool should have:
    #     anatomical_reorient

    import os
    import sys

    import nipype.interfaces.io as nio
    import nipype.pipeline.engine as pe

    import nipype.interfaces.utility as util

    from nipype.interfaces.afni import preprocess

    if "anatomical_reorient" not in resource_pool.keys():

        from anatomical_preproc import anatomical_reorient_workflow

        workflow, resource_pool = anatomical_reorient_workflow(workflow, resource_pool, config)

    # check_input_resources(resource_pool, "anatomical_reorient")

    anat_skullstrip = pe.Node(interface=preprocess.SkullStrip(), name="anat_skullstrip")

    anat_skullstrip.inputs.outputtype = "NIFTI_GZ"

    anat_skullstrip_orig_vol = pe.Node(interface=preprocess.Calc(), name="anat_skullstrip_orig_vol")

    anat_skullstrip_orig_vol.inputs.expr = "a*step(b)"
    anat_skullstrip_orig_vol.inputs.outputtype = "NIFTI_GZ"

    if len(resource_pool["anatomical_reorient"]) == 2:
        node, out_file = resource_pool["anatomical_reorient"]
        workflow.connect(node, out_file, anat_skullstrip, "in_file")
    else:
        anat_skullstrip.inputs.in_file = resource_pool["anatomical_reorient"]

    if len(resource_pool["anatomical_reorient"]) == 2:
        node, out_file = resource_pool["anatomical_reorient"]
        workflow.connect(node, out_file, anat_skullstrip_orig_vol, "in_file_a")
    else:
        anat_skullstrip_orig_vol.inputs.in_file_a = resource_pool["anatomical_reorient"]

    workflow.connect(anat_skullstrip, "out_file", anat_skullstrip_orig_vol, "in_file_b")

    resource_pool["anatomical_brain"] = (anat_skullstrip_orig_vol, "out_file")

    return workflow, resource_pool
Esempio n. 4
0
def run_anatomical_reorient(anatomical_scan, run=True):

    # stand-alone runner for anatomical reorient workflow

    import os
    import sys

    import glob

    import nipype.interfaces.io as nio
    import nipype.pipeline.engine as pe

    workflow = pe.Workflow(name='anatomical_reorient_workflow')

    current_dir = os.getcwd()

    workflow_dir = os.path.join(current_dir, "anatomical_reorient")
    workflow.base_dir = workflow_dir

    resource_pool = {}
    config = {}
    num_cores_per_subject = 1

    resource_pool["anatomical_scan"] = anatomical_scan

    workflow, resource_pool = \
            anatomical_reorient_workflow(workflow, resource_pool, config)

    ds = pe.Node(nio.DataSink(), name='datasink_anatomical_reorient')
    ds.inputs.base_directory = workflow_dir

    node, out_file = resource_pool["anatomical_reorient"]

    workflow.connect(node, out_file, ds, 'anatomical_reorient')

    if run == True:

        workflow.run(plugin='MultiProc', plugin_args= \
                         {'n_procs': num_cores_per_subject})

        outpath = glob.glob(os.path.join(workflow_dir, "anatomical_reorient",\
                                         "*"))[0]

        return outpath

    else:

        return workflow, workflow.base_dir
def run_anatomical_reorient(anatomical_scan, out_dir=None, run=True):
    """Run the 'anatomical_reorient_workflow' function to execute the modular
    workflow with the provided inputs.

    :type anatomical_scan: str
    :param anatomical_scan: The filepath to the raw anatomical image in a
                            NIFTI file.
    :type out_dir: str
    :param out_dir: (default: None) The output directory to write the results
                    to; if left as None, will write to the current directory.
    :type run: bool
    :param run: (default: True) Will run the workflow; if set to False, will
                connect the Nipype workflow and return the workflow object
                instead.
    :rtype: str
    :return: (if run=True) The filepath of the generated anatomical_reorient
             file.
    :rtype: Nipype workflow object
    :return: (if run=False) The connected Nipype workflow object.
    :rtype: str
    :return: (if run=False) The base directory of the workflow if it were to
             be run.
    """

    import os
    import glob

    import nipype.interfaces.io as nio
    import nipype.pipeline.engine as pe

    output = "anatomical_reorient"

    workflow = pe.Workflow(name='anatomical_reorient_workflow')

    if not out_dir:
        out_dir = os.getcwd()

    workflow_dir = os.path.join(out_dir, "workflow_output", output)
    workflow.base_dir = workflow_dir

    resource_pool = {}
    config = {}
    num_cores_per_subject = 1

    resource_pool["anatomical_scan"] = anatomical_scan

    workflow, resource_pool = \
            anatomical_reorient_workflow(workflow, resource_pool, config)

    ds = pe.Node(nio.DataSink(), name='datasink_anatomical_reorient')
    ds.inputs.base_directory = workflow_dir

    node, out_file = resource_pool["anatomical_reorient"]

    workflow.connect(node, out_file, ds, 'anatomical_reorient')

    if run == True:
        workflow.run(plugin='MultiProc', plugin_args= \
                         {'n_procs': num_cores_per_subject})
        outpath = glob.glob(os.path.join(workflow_dir, "anatomical_reorient",\
                                         "*"))[0]
        return outpath
    else:
        return workflow, workflow.base_dir
def afni_anatomical_linear_registration(workflow, resource_pool, \
    config, name="_"):
    """Build Nipype workflow to calculate the linear registration (participant
    to template) of an anatomical image using AFNI's 3dAllineate.

    - If any resources/outputs required by this workflow are not in the
      resource pool, this workflow will call pre-requisite workflow builder
      functions to further populate the pipeline with workflows which will
      calculate/generate these necessary pre-requisites.

    Expected Settings in Configuration
      - skull_on_registration: (optional- default: True) Whether or not to
                               accept anatomical_reorient or anatomical_brain
                               as the input for registration.
      - template_head_for_anat: (for skull-on registration) The reference
                                template of the whole head.
      - template_brain_for_anat: (for skull-off registration) The reference
                                 template of the brain without skull.

    Expected Resources in Resource Pool
      - anatomical_reorient: The deobliqued, reoriented anatomical scan.
        OR
      - anatomical_brain: The skull-stripped anatomical image (brain only).

    New Resources Added to Resource Pool
      - afni_linear_warped_image: The anatomical image transformed to the
                                  template (using linear warps).
      - allineate_linear_xfm: The text file containing the linear warp matrix
                              produced by AFNI's 3dAllineate.

    Workflow Steps
      1. AFNI's 3dAllineate to calculate the linear registration.

    :type workflow: Nipype workflow object
    :param workflow: A Nipype workflow object which can already contain other
                     connected nodes; this function will insert the following
                     workflow into this one provided.
    :type resource_pool: dict
    :param resource_pool: A dictionary defining input files and pointers to
                          Nipype node outputs / workflow connections; the keys
                          are the resource names.
    :type config: dict
    :param config: A dictionary defining the configuration settings for the
                   workflow, such as directory paths or toggled options.
    :type name: str
    :param name: (default: "_") A string to append to the end of each node
                 name.
    :rtype: Nipype workflow object
    :return: The Nipype workflow originally provided, but with this function's
              sub-workflow connected into it.
    :rtype: dict
    :return: The resource pool originally provided, but updated (if
             applicable) with the newest outputs and connections.
    """

    import copy
    import nipype.pipeline.engine as pe
    import nipype.interfaces.afni as afni

    if "skull_on_registration" not in config.keys():
        config["skull_on_registration"] = True

    calc_allineate_warp = pe.Node(interface=afni.Allineate(),
                                    name='calc_3dAllineate_warp%s' % name)
    calc_allineate_warp.inputs.outputtype = "NIFTI_GZ"

    if config["skull_on_registration"]:

        if "anatomical_reorient" not in resource_pool.keys():

            from anatomical_preproc import anatomical_reorient_workflow
            old_rp = copy.copy(resource_pool)
            workflow, new_resource_pool = \
                anatomical_reorient_workflow(workflow, resource_pool,
                                             config, name)

            if resource_pool == old_rp:
                return workflow, resource_pool

        if len(resource_pool["anatomical_reorient"]) == 2:
            node, out_file = resource_pool["anatomical_reorient"]
            workflow.connect(node, out_file, calc_allineate_warp, 'in_file')
        else:
            calc_allineate_warp.inputs.in_file = \
                resource_pool["anatomical_reorient"]

        calc_allineate_warp.inputs.reference = \
            config["template_head_for_anat"]

        calc_allineate_warp.inputs.out_file = "allineate_warped_head.nii.gz"

    else:

        if "anatomical_brain" not in resource_pool.keys():

            from anatomical_preproc import anatomical_skullstrip_workflow
            old_rp = copy.copy(resource_pool)
            workflow, new_resource_pool = \
                anatomical_skullstrip_workflow(workflow, resource_pool, \
                                               config, name)

            if resource_pool == old_rp:
                return workflow, resource_pool

        if len(resource_pool["anatomical_brain"]) == 2:
            node, out_file = resource_pool["anatomical_brain"]
            workflow.connect(node, out_file, calc_allineate_warp, 'in_file')
        else:
            calc_allineate_warp.inputs.in_file = \
                resource_pool["anatomical_brain"]

        calc_allineate_warp.inputs.reference = \
            config["template_brain_for_anat"]

        calc_allineate_warp.inputs.out_file = \
            "allineate_warped_brain.nii.gz"

    calc_allineate_warp.inputs.out_matrix = "3dallineate_warp"

    resource_pool["allineate_linear_xfm"] = \
        (calc_allineate_warp, 'matrix')

    resource_pool["afni_linear_warped_image"] = \
        (calc_allineate_warp, 'out_file')

    return workflow, resource_pool
def anatomical_skullstrip_workflow(workflow, resource_pool, config, name="_"):
    """Build a Nipype workflow to skullstrip an anatomical image using AFNI's
    3dSkullStrip.

    - If any resources/outputs required by this workflow are not in the
      resource pool, this workflow will call pre-requisite workflow builder
      functions to further populate the pipeline with workflows which will
      calculate/generate these necessary pre-requisites.

    Expected Resources in Resource Pool
      - anatomical_reorient: The deobliqued, reoriented anatomical scan.

    New Resources Added to Resource Pool
      - anatomical_brain: The skull-stripped anatomical image (brain only).

    Workflow Steps
      1. AFNI 3dSkullStrip to create a binary mask selecting only the brain.
      2. AFNI 3dcalc to multiply the anatomical image with this mask.

    :type workflow: Nipype workflow object
    :param workflow: A Nipype workflow object which can already contain other
                     connected nodes; this function will insert the following
                     workflow into this one provided.
    :type resource_pool: dict
    :param resource_pool: A dictionary defining input files and pointers to
                          Nipype node outputs / workflow connections; the keys
                          are the resource names.
    :type config: dict
    :param config: A dictionary defining the configuration settings for the
                   workflow, such as directory paths or toggled options.
    :type name: str
    :param name: (default: "_") A string to append to the end of each node
                 name.
    :rtype: Nipype workflow object
    :return: The Nipype workflow originally provided, but with this function's
              sub-workflow connected into it.
    :rtype: dict
    :return: The resource pool originally provided, but updated (if
             applicable) with the newest outputs and connections.
    """

    import copy
    import nipype.pipeline.engine as pe

    from nipype.interfaces.afni import preprocess

    if "anatomical_reorient" not in resource_pool.keys():

        from anatomical_preproc import anatomical_reorient_workflow
        old_rp = copy.copy(resource_pool)
        workflow, new_resource_pool = \
            anatomical_reorient_workflow(workflow, resource_pool, config, name)

        if resource_pool == old_rp:
            return workflow, resource_pool

    anat_skullstrip = pe.Node(interface=preprocess.SkullStrip(),
                              name='anat_skullstrip%s' % name)
    anat_skullstrip.inputs.outputtype = 'NIFTI_GZ'

    anat_skullstrip_orig_vol = pe.Node(interface=preprocess.Calc(),
                                       name='anat_skullstrip_orig_vol%s' % name)
    anat_skullstrip_orig_vol.inputs.expr = 'a*step(b)'
    anat_skullstrip_orig_vol.inputs.outputtype = 'NIFTI_GZ'

    if len(resource_pool["anatomical_reorient"]) == 2:
        node, out_file = resource_pool["anatomical_reorient"]
        workflow.connect(node, out_file, anat_skullstrip, 'in_file')
    else:
        anat_skullstrip.inputs.in_file = \
            resource_pool["anatomical_reorient"]

    if len(resource_pool["anatomical_reorient"]) == 2:
        node, out_file = resource_pool["anatomical_reorient"]
        workflow.connect(node, out_file,
                             anat_skullstrip_orig_vol, 'in_file_a')
    else:
        anat_skullstrip_orig_vol.inputs.in_file_a = \
            resource_pool["anatomical_reorient"]

    workflow.connect(anat_skullstrip, 'out_file',
                        anat_skullstrip_orig_vol, 'in_file_b')

    resource_pool["anatomical_brain"] = (anat_skullstrip_orig_vol, 'out_file')

    return workflow, resource_pool
def qap_anatomical_spatial_workflow(workflow, resource_pool, config):

    # resource pool should have:
    #     anatomical_reorient
    #     qap_head_mask
    #     anatomical_gm_mask
    #     anatomical_wm_mask
    #     anatomical_csf_mask

    import os
    import sys

    import nipype.interfaces.io as nio
    import nipype.pipeline.engine as pe

    import nipype.interfaces.utility as util

    from qap_workflows_utils import qap_anatomical_spatial, write_to_csv

    if "qap_head_mask" not in resource_pool.keys():

        from qap_workflows import qap_mask_workflow

        workflow, resource_pool = qap_mask_workflow(workflow, resource_pool, config)

    if (
        ("anatomical_gm_mask" not in resource_pool.keys())
        or ("anatomical_wm_mask" not in resource_pool.keys())
        or ("anatomical_csf_mask" not in resource_pool.keys())
    ):

        from anatomical_preproc import segmentation_workflow

        workflow, resource_pool = segmentation_workflow(workflow, resource_pool, config)

    if "anatomical_reorient" not in resource_pool.keys():

        from anatomical_preproc import anatomical_reorient_workflow

        workflow, resource_pool = anatomical_reorient_workflow(workflow, resource_pool, config)

    spatial = pe.Node(
        util.Function(
            input_names=[
                "anatomical_reorient",
                "head_mask_path",
                "anatomical_gm_mask",
                "anatomical_wm_mask",
                "anatomical_csf_mask",
                "subject_id",
                "session_id",
                "scan_id",
                "site_name",
            ],
            output_names=["qc"],
            function=qap_anatomical_spatial,
        ),
        name="qap_anatomical_spatial",
    )

    spatial_to_csv = pe.Node(
        util.Function(input_names=["sub_qap_dict"], output_names=["outfile"], function=write_to_csv),
        name="qap_anatomical_spatial_to_csv",
    )

    if len(resource_pool["anatomical_reorient"]) == 2:
        node, out_file = resource_pool["anatomical_reorient"]
        workflow.connect(node, out_file, spatial, "anatomical_reorient")
    else:
        spatial.inputs.anatomical_reorient = resource_pool["anatomical_reorient"]

    if len(resource_pool["qap_head_mask"]) == 2:
        node, out_file = resource_pool["qap_head_mask"]
        workflow.connect(node, out_file, spatial, "head_mask_path")
    else:
        spatial.inputs.head_mask_path = resource_pool["qap_head_mask"]

    if len(resource_pool["anatomical_gm_mask"]) == 2:
        node, out_file = resource_pool["anatomical_gm_mask"]
        workflow.connect(node, out_file, spatial, "anatomical_gm_mask")
    else:
        spatial.inputs.anatomical_gm_mask = resource_pool["anatomical_gm_mask"]

    if len(resource_pool["anatomical_wm_mask"]) == 2:
        node, out_file = resource_pool["anatomical_wm_mask"]
        workflow.connect(node, out_file, spatial, "anatomical_wm_mask")
    else:
        spatial.inputs.anatomical_wm_mask = resource_pool["anatomical_wm_mask"]

    if len(resource_pool["anatomical_csf_mask"]) == 2:
        node, out_file = resource_pool["anatomical_csf_mask"]
        workflow.connect(node, out_file, spatial, "anatomical_csf_mask")
    else:
        spatial.inputs.anatomical_csf_mask = resource_pool["anatomical_csf_mask"]

    # Subject infos

    spatial.inputs.subject_id = config["subject_id"]
    spatial.inputs.session_id = config["session_id"]
    spatial.inputs.scan_id = config["scan_id"]

    if "site_name" in config.keys():
        spatial.inputs.site_name = config["site_name"]

    workflow.connect(spatial, "qc", spatial_to_csv, "sub_qap_dict")

    resource_pool["qap_anatomical_spatial"] = (spatial_to_csv, "outfile")

    return workflow, resource_pool
def qap_mask_workflow(workflow, resource_pool, config):

    import os
    import sys

    import nipype.interfaces.io as nio
    import nipype.pipeline.engine as pe

    import nipype.interfaces.utility as util
    import nipype.interfaces.fsl.maths as fsl

    from qap_workflows_utils import select_thresh, slice_head_mask

    from workflow_utils import check_input_resources, check_config_settings

    # check_input_resources(resource_pool, "anatomical_reorient")
    # check_input_resources(resource_pool, "ants_affine_xfm")
    check_config_settings(config, "template_skull_for_anat")

    if "flirt_affine_xfm" not in resource_pool.keys():

        from anatomical_preproc import flirt_anatomical_linear_registration

        workflow, resource_pool = flirt_anatomical_linear_registration(workflow, resource_pool, config)

    if "anatomical_reorient" not in resource_pool.keys():

        from anatomical_preproc import anatomical_reorient_workflow

        workflow, resource_pool = anatomical_reorient_workflow(workflow, resource_pool, config)

    select_thresh = pe.Node(
        util.Function(input_names=["input_skull"], output_names=["thresh_out"], function=select_thresh),
        name="qap_headmask_select_thresh",
        iterfield=["input_skull"],
    )

    mask_skull = pe.Node(interface=fsl.Threshold(), name="qap_headmask_thresh")

    mask_skull.inputs.args = "-bin"

    dilate_node = pe.Node(interface=fsl.MathsCommand(), name="qap_headmask_dilate")

    dilate_node.inputs.args = "-dilM -dilM -dilM -dilM -dilM -dilM"

    erode_node = pe.Node(interface=fsl.MathsCommand(), name="qap_headmask_erode")

    erode_node.inputs.args = "-eroF -eroF -eroF -eroF -eroF -eroF"

    slice_head_mask = pe.Node(
        util.Function(
            input_names=["infile", "transform", "standard"], output_names=["outfile_path"], function=slice_head_mask
        ),
        name="qap_headmask_slice_head_mask",
    )

    combine_masks = pe.Node(interface=fsl.BinaryMaths(), name="qap_headmask_combine_masks")

    combine_masks.inputs.operation = "add"
    combine_masks.inputs.args = "-bin"

    if len(resource_pool["anatomical_reorient"]) == 2:
        node, out_file = resource_pool["anatomical_reorient"]
        workflow.connect(node, out_file, select_thresh, "input_skull")
        workflow.connect(node, out_file, mask_skull, "in_file")
        # workflow.connect(node, out_file, convert_fsl_xfm, 'infile')
        workflow.connect(node, out_file, slice_head_mask, "infile")
    else:
        select_thresh.inputs.input_skull = resource_pool["anatomical_reorient"]
        mask_skull.inputs.in_file = resource_pool["anatomical_reorient"]
        # convert_fsl_xfm.inputs.infile = \
        #    resource_pool["anatomical_reorient"]
        slice_head_mask.inputs.infile = resource_pool["anatomical_reorient"]

    if len(resource_pool["flirt_affine_xfm"]) == 2:
        node, out_file = resource_pool["flirt_affine_xfm"]
        workflow.connect(node, out_file, slice_head_mask, "transform")
    else:
        slice_head_mask.inputs.transform = resource_pool["flirt_affine_xfm"]

    # convert_fsl_xfm.inputs.standard = config["template_skull_for_anat"]
    slice_head_mask.inputs.standard = config["template_skull_for_anat"]

    workflow.connect(select_thresh, "thresh_out", mask_skull, "thresh")

    # workflow.connect(convert_fsl_xfm, 'converted_xfm', \
    #                     slice_head_mask, 'transform')

    workflow.connect(mask_skull, "out_file", dilate_node, "in_file")

    workflow.connect(dilate_node, "out_file", erode_node, "in_file")

    workflow.connect(erode_node, "out_file", combine_masks, "in_file")

    workflow.connect(slice_head_mask, "outfile_path", combine_masks, "operand_file")

    resource_pool["qap_head_mask"] = (combine_masks, "out_file")

    return workflow, resource_pool
def qap_mask_workflow(workflow, resource_pool, config):

    import os
    import sys

    import nipype.interfaces.io as nio
    import nipype.pipeline.engine as pe

    import nipype.interfaces.utility as niu
    import nipype.interfaces.fsl.maths as fsl
    from nipype.interfaces.fsl.base import Info

    from qap_workflows_utils import select_thresh, slice_head_mask

    from workflow_utils import check_input_resources, check_config_settings

    # check_input_resources(resource_pool, 'anatomical_reorient')
    # check_input_resources(resource_pool, 'ants_affine_xfm')
    if "template_skull_for_anat" not in config:
        config["template_skull_for_anat"] = Info.standard_image("MNI152_T1_2mm.nii.gz")

    check_config_settings(config, "template_skull_for_anat")

    if "flirt_affine_xfm" not in resource_pool.keys():

        from anatomical_preproc import flirt_anatomical_linear_registration

        workflow, resource_pool = flirt_anatomical_linear_registration(workflow, resource_pool, config)

    if "anatomical_reorient" not in resource_pool.keys():

        from anatomical_preproc import anatomical_reorient_workflow

        workflow, resource_pool = anatomical_reorient_workflow(workflow, resource_pool, config)

    select_thresh = pe.Node(
        niu.Function(input_names=["input_skull"], output_names=["thresh_out"], function=select_thresh),
        name="qap_headmask_select_thresh",
        iterfield=["input_skull"],
    )

    mask_skull = pe.Node(fsl.Threshold(args="-bin"), name="qap_headmask_thresh")

    dilate_node = pe.Node(fsl.MathsCommand(args="-dilM -dilM -dilM -dilM -dilM -dilM"), name="qap_headmask_dilate")

    erode_node = pe.Node(fsl.MathsCommand(args="-eroF -eroF -eroF -eroF -eroF -eroF"), name="qap_headmask_erode")

    slice_head_mask = pe.Node(
        niu.Function(
            input_names=["infile", "transform", "standard"], output_names=["outfile_path"], function=slice_head_mask
        ),
        name="qap_headmask_slice_head_mask",
    )

    combine_masks = pe.Node(fsl.BinaryMaths(operation="add", args="-bin"), name="qap_headmask_combine_masks")

    if len(resource_pool["anatomical_reorient"]) == 2:
        node, out_file = resource_pool["anatomical_reorient"]
        workflow.connect(
            [
                (node, select_thresh, [(out_file, "input_skull")]),
                (node, mask_skull, [(out_file, "in_file")]),
                (node, slice_head_mask, [(out_file, "infile")]),
            ]
        )
    else:
        select_thresh.inputs.input_skull = resource_pool["anatomical_reorient"]
        mask_skull.inputs.in_file = resource_pool["anatomical_reorient"]
        # convert_fsl_xfm.inputs.infile =
        #    resource_pool['anatomical_reorient']
        slice_head_mask.inputs.infile = resource_pool["anatomical_reorient"]

    if len(resource_pool["flirt_affine_xfm"]) == 2:
        node, out_file = resource_pool["flirt_affine_xfm"]
        workflow.connect(node, out_file, slice_head_mask, "transform")
    else:
        slice_head_mask.inputs.transform = resource_pool["flirt_affine_xfm"]

    # convert_fsl_xfm.inputs.standard = config['template_skull_for_anat']
    slice_head_mask.inputs.standard = config["template_skull_for_anat"]

    workflow.connect(
        [
            (select_thresh, mask_skull, [("thresh_out", "thresh")]),
            # (convert_fsl_xfm, slice_head_mask, [('converted_xfm', 'transform')])
            (mask_skull, dilate_node, [("out_file", "in_file")]),
            (dilate_node, erode_node, [("out_file", "in_file")]),
            (erode_node, combine_masks, [("out_file", "in_file")]),
            (slice_head_mask, combine_masks, [("outfile_path", "operand_file")]),
        ]
    )

    resource_pool["qap_head_mask"] = (combine_masks, "out_file")
    return workflow, resource_pool
def qap_anatomical_spatial_workflow(workflow, resource_pool, config, report=False):
    # resource pool should have:
    #     anatomical_reorient
    #     qap_head_mask
    #     anatomical_gm_mask
    #     anatomical_wm_mask
    #     anatomical_csf_mask

    import os
    import sys

    import nipype.interfaces.io as nio
    import nipype.pipeline.engine as pe
    import nipype.interfaces.utility as niu
    import nipype.algorithms.misc as nam
    from qap_workflows_utils import qap_anatomical_spatial
    from qap.viz.interfaces import PlotMosaic

    if "qap_head_mask" not in resource_pool.keys():

        from qap_workflows import qap_mask_workflow

        workflow, resource_pool = qap_mask_workflow(workflow, resource_pool, config)

    if (
        ("anatomical_gm_mask" not in resource_pool.keys())
        or ("anatomical_wm_mask" not in resource_pool.keys())
        or ("anatomical_csf_mask" not in resource_pool.keys())
    ):

        from anatomical_preproc import segmentation_workflow

        workflow, resource_pool = segmentation_workflow(workflow, resource_pool, config)

    if "anatomical_reorient" not in resource_pool.keys():
        from anatomical_preproc import anatomical_reorient_workflow

        workflow, resource_pool = anatomical_reorient_workflow(workflow, resource_pool, config)

    spatial = pe.Node(
        niu.Function(
            input_names=[
                "anatomical_reorient",
                "head_mask_path",
                "anatomical_gm_mask",
                "anatomical_wm_mask",
                "anatomical_csf_mask",
                "subject_id",
                "session_id",
                "scan_id",
                "site_name",
            ],
            output_names=["qc"],
            function=qap_anatomical_spatial,
        ),
        name="qap_anatomical_spatial",
    )

    # Subject infos
    spatial.inputs.subject_id = config["subject_id"]
    spatial.inputs.session_id = config["session_id"]
    spatial.inputs.scan_id = config["scan_id"]

    if "site_name" in config.keys():
        spatial.inputs.site_name = config["site_name"]

    if len(resource_pool["anatomical_reorient"]) == 2:
        node, out_file = resource_pool["anatomical_reorient"]
        workflow.connect(node, out_file, spatial, "anatomical_reorient")
    else:
        spatial.inputs.anatomical_reorient = resource_pool["anatomical_reorient"]

    if len(resource_pool["qap_head_mask"]) == 2:
        node, out_file = resource_pool["qap_head_mask"]
        workflow.connect(node, out_file, spatial, "head_mask_path")
    else:
        spatial.inputs.head_mask_path = resource_pool["qap_head_mask"]

    if len(resource_pool["anatomical_gm_mask"]) == 2:
        node, out_file = resource_pool["anatomical_gm_mask"]
        workflow.connect(node, out_file, spatial, "anatomical_gm_mask")
    else:
        spatial.inputs.anatomical_gm_mask = resource_pool["anatomical_gm_mask"]

    if len(resource_pool["anatomical_wm_mask"]) == 2:
        node, out_file = resource_pool["anatomical_wm_mask"]
        workflow.connect(node, out_file, spatial, "anatomical_wm_mask")
    else:
        spatial.inputs.anatomical_wm_mask = resource_pool["anatomical_wm_mask"]

    if len(resource_pool["anatomical_csf_mask"]) == 2:
        node, out_file = resource_pool["anatomical_csf_mask"]
        workflow.connect(node, out_file, spatial, "anatomical_csf_mask")
    else:
        spatial.inputs.anatomical_csf_mask = resource_pool["anatomical_csf_mask"]

    if config.get("write_report", False):
        plot = pe.Node(PlotMosaic(), name="plot_mosaic")
        plot.inputs.subject = config["subject_id"]

        metadata = [config["session_id"], config["scan_id"]]
        if "site_name" in config.keys():
            metadata.append(config["site_name"])

        plot.inputs.metadata = metadata
        plot.inputs.title = "Anatomical reoriented"

        if len(resource_pool["anatomical_reorient"]) == 2:
            node, out_file = resource_pool["anatomical_reorient"]
            workflow.connect(node, out_file, plot, "in_file")
        else:
            plot.inputs.in_file = resource_pool["anatomical_reorient"]

        # Enable this if we want masks
        # if len(resource_pool['qap_head_mask']) == 2:
        #     node, out_file = resource_pool['qap_head_mask']
        #     workflow.connect(node, out_file, plot, 'in_mask')
        # else:
        #     plot.inputs.in_mask = resource_pool['qap_head_mask']

        resource_pool["qap_mosaic"] = (plot, "out_file")

    out_csv = op.join(config["output_directory"], "qap_anatomical_spatial.csv")
    spatial_to_csv = pe.Node(nam.AddCSVRow(in_file=out_csv), name="qap_anatomical_spatial_to_csv")

    workflow.connect(spatial, "qc", spatial_to_csv, "_outputs")
    resource_pool["qap_anatomical_spatial"] = (spatial_to_csv, "csv_file")
    return workflow, resource_pool
Esempio n. 12
0
def qap_mask_workflow(workflow, resource_pool, config):

    import os
    import sys

    import nipype.interfaces.io as nio
    import nipype.pipeline.engine as pe

    import nipype.interfaces.utility as niu
    import nipype.interfaces.fsl.maths as fsl
    from nipype.interfaces.fsl.base import Info

    from qap_workflows_utils import select_thresh, \
        slice_head_mask

    from workflow_utils import check_input_resources, \
        check_config_settings

    # check_input_resources(resource_pool, 'anatomical_reorient')
    # check_input_resources(resource_pool, 'ants_affine_xfm')
    if 'template_skull_for_anat' not in config:
        config['template_skull_for_anat'] = Info.standard_image(
            'MNI152_T1_2mm.nii.gz')

    check_config_settings(config, 'template_skull_for_anat')

    if 'flirt_affine_xfm' not in resource_pool.keys():

        from anatomical_preproc import flirt_anatomical_linear_registration

        workflow, resource_pool = \
            flirt_anatomical_linear_registration(workflow, resource_pool,
                                                 config)

    if 'anatomical_reorient' not in resource_pool.keys():

        from anatomical_preproc import anatomical_reorient_workflow

        workflow, resource_pool = \
            anatomical_reorient_workflow(workflow, resource_pool, config)

    select_thresh = pe.Node(niu.Function(input_names=['input_skull'],
                                         output_names=['thresh_out'],
                                         function=select_thresh),
                            name='qap_headmask_select_thresh',
                            iterfield=['input_skull'])

    mask_skull = pe.Node(fsl.Threshold(args='-bin'),
                         name='qap_headmask_thresh')

    dilate_node = pe.Node(
        fsl.MathsCommand(args='-dilM -dilM -dilM -dilM -dilM -dilM'),
        name='qap_headmask_dilate')

    erode_node = pe.Node(
        fsl.MathsCommand(args='-eroF -eroF -eroF -eroF -eroF -eroF'),
        name='qap_headmask_erode')

    slice_head_mask = pe.Node(niu.Function(
        input_names=['infile', 'transform', 'standard'],
        output_names=['outfile_path'],
        function=slice_head_mask),
                              name='qap_headmask_slice_head_mask')

    combine_masks = pe.Node(fsl.BinaryMaths(operation='add', args='-bin'),
                            name='qap_headmask_combine_masks')

    if len(resource_pool['anatomical_reorient']) == 2:
        node, out_file = resource_pool['anatomical_reorient']
        workflow.connect([(node, select_thresh, [(out_file, 'input_skull')]),
                          (node, mask_skull, [(out_file, 'in_file')]),
                          (node, slice_head_mask, [(out_file, 'infile')])])
    else:
        select_thresh.inputs.input_skull = resource_pool['anatomical_reorient']
        mask_skull.inputs.in_file = resource_pool['anatomical_reorient']
        # convert_fsl_xfm.inputs.infile =
        #    resource_pool['anatomical_reorient']
        slice_head_mask.inputs.infile = resource_pool['anatomical_reorient']

    if len(resource_pool['flirt_affine_xfm']) == 2:
        node, out_file = resource_pool['flirt_affine_xfm']
        workflow.connect(node, out_file, slice_head_mask, 'transform')
    else:
        slice_head_mask.inputs.transform = resource_pool['flirt_affine_xfm']

    # convert_fsl_xfm.inputs.standard = config['template_skull_for_anat']
    slice_head_mask.inputs.standard = config['template_skull_for_anat']

    workflow.connect([
        (select_thresh, mask_skull, [('thresh_out', 'thresh')]),
        # (convert_fsl_xfm, slice_head_mask, [('converted_xfm', 'transform')])
        (mask_skull, dilate_node, [('out_file', 'in_file')]),
        (dilate_node, erode_node, [('out_file', 'in_file')]),
        (erode_node, combine_masks, [('out_file', 'in_file')]),
        (slice_head_mask, combine_masks, [('outfile_path', 'operand_file')])
    ])

    resource_pool['qap_head_mask'] = (combine_masks, 'out_file')
    return workflow, resource_pool
Esempio n. 13
0
def qap_anatomical_spatial_workflow(workflow,
                                    resource_pool,
                                    config,
                                    report=False):
    # resource pool should have:
    #     anatomical_reorient
    #     qap_head_mask
    #     anatomical_gm_mask
    #     anatomical_wm_mask
    #     anatomical_csf_mask

    import os
    import sys

    import nipype.interfaces.io as nio
    import nipype.pipeline.engine as pe
    import nipype.interfaces.utility as niu
    import nipype.algorithms.misc as nam
    from qap_workflows_utils import qap_anatomical_spatial
    from qap.viz.interfaces import PlotMosaic

    if 'qap_head_mask' not in resource_pool.keys():

        from qap_workflows import qap_mask_workflow

        workflow, resource_pool = \
            qap_mask_workflow(workflow, resource_pool, config)

    if ('anatomical_gm_mask' not in resource_pool.keys()) or \
            ('anatomical_wm_mask' not in resource_pool.keys()) or \
            ('anatomical_csf_mask' not in resource_pool.keys()):

        from anatomical_preproc import segmentation_workflow

        workflow, resource_pool = \
            segmentation_workflow(workflow, resource_pool, config)

    if 'anatomical_reorient' not in resource_pool.keys():
        from anatomical_preproc import anatomical_reorient_workflow
        workflow, resource_pool = \
            anatomical_reorient_workflow(workflow, resource_pool, config)

    spatial = pe.Node(niu.Function(input_names=[
        'anatomical_reorient', 'head_mask_path', 'anatomical_gm_mask',
        'anatomical_wm_mask', 'anatomical_csf_mask', 'subject_id',
        'session_id', 'scan_id', 'site_name'
    ],
                                   output_names=['qc'],
                                   function=qap_anatomical_spatial),
                      name='qap_anatomical_spatial')

    # Subject infos
    spatial.inputs.subject_id = config['subject_id']
    spatial.inputs.session_id = config['session_id']
    spatial.inputs.scan_id = config['scan_id']

    if 'site_name' in config.keys():
        spatial.inputs.site_name = config['site_name']

    if len(resource_pool['anatomical_reorient']) == 2:
        node, out_file = resource_pool['anatomical_reorient']
        workflow.connect(node, out_file, spatial, 'anatomical_reorient')
    else:
        spatial.inputs.anatomical_reorient = \
            resource_pool['anatomical_reorient']

    if len(resource_pool['qap_head_mask']) == 2:
        node, out_file = resource_pool['qap_head_mask']
        workflow.connect(node, out_file, spatial, 'head_mask_path')
    else:
        spatial.inputs.head_mask_path = resource_pool['qap_head_mask']

    if len(resource_pool['anatomical_gm_mask']) == 2:
        node, out_file = resource_pool['anatomical_gm_mask']
        workflow.connect(node, out_file, spatial, 'anatomical_gm_mask')
    else:
        spatial.inputs.anatomical_gm_mask = \
            resource_pool['anatomical_gm_mask']

    if len(resource_pool['anatomical_wm_mask']) == 2:
        node, out_file = resource_pool['anatomical_wm_mask']
        workflow.connect(node, out_file, spatial, 'anatomical_wm_mask')
    else:
        spatial.inputs.anatomical_wm_mask = \
            resource_pool['anatomical_wm_mask']

    if len(resource_pool['anatomical_csf_mask']) == 2:
        node, out_file = resource_pool['anatomical_csf_mask']
        workflow.connect(node, out_file, spatial, 'anatomical_csf_mask')
    else:
        spatial.inputs.anatomical_csf_mask = \
            resource_pool['anatomical_csf_mask']

    if config.get('write_report', False):
        plot = pe.Node(PlotMosaic(), name='plot_mosaic')
        plot.inputs.subject = config['subject_id']

        metadata = [config['session_id'], config['scan_id']]
        if 'site_name' in config.keys():
            metadata.append(config['site_name'])

        plot.inputs.metadata = metadata
        plot.inputs.title = 'Anatomical reoriented'

        if len(resource_pool['anatomical_reorient']) == 2:
            node, out_file = resource_pool['anatomical_reorient']
            workflow.connect(node, out_file, plot, 'in_file')
        else:
            plot.inputs.in_file = resource_pool['anatomical_reorient']

        # Enable this if we want masks
        # if len(resource_pool['qap_head_mask']) == 2:
        #     node, out_file = resource_pool['qap_head_mask']
        #     workflow.connect(node, out_file, plot, 'in_mask')
        # else:
        #     plot.inputs.in_mask = resource_pool['qap_head_mask']

        resource_pool['qap_mosaic'] = (plot, 'out_file')

    out_csv = op.join(config['output_directory'], 'qap_anatomical_spatial.csv')
    spatial_to_csv = pe.Node(nam.AddCSVRow(in_file=out_csv),
                             name='qap_anatomical_spatial_to_csv')

    workflow.connect(spatial, 'qc', spatial_to_csv, '_outputs')
    resource_pool['qap_anatomical_spatial'] = (spatial_to_csv, 'csv_file')
    return workflow, resource_pool