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
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
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