Example #1
0
File: fsl.py Project: em-blue/QUIT
    def _list_outputs(self):
        outputs = self._outputs().get()

        outputs['out_file'] = self._gen_outfilename()
        output_dir = os.path.dirname(outputs['out_file'])

        if isdefined(self.inputs.stats_imgs) and self.inputs.stats_imgs:
            if LooseVersion(Info.version()) < LooseVersion('6.0.0'):
                # FSL <6.0 outputs have .nii.gz_variance.nii.gz as extension
                outputs['variance_img'] = self._gen_fname(
                    outputs['out_file'] + '_variance.ext', cwd=output_dir)
                outputs['std_img'] = self._gen_fname(
                    outputs['out_file'] + '_sigma.ext', cwd=output_dir)
            else:
                outputs['variance_img'] = self._gen_fname(
                    outputs['out_file'], suffix='_variance', cwd=output_dir)
                outputs['std_img'] = self._gen_fname(
                    outputs['out_file'], suffix='_sigma', cwd=output_dir)

        # The mean image created if -stats option is specified ('meanvol')
        # is missing the top and bottom slices. Therefore we only expose the
        # mean image created by -meanvol option ('mean_reg') which isn't
        # corrupted.
        # Note that the same problem holds for the std and variance image.

        if isdefined(self.inputs.mean_vol) and self.inputs.mean_vol:
            if LooseVersion(Info.version()) < LooseVersion('6.0.0'):
                # FSL <6.0 outputs have .nii.gz_mean_img.nii.gz as extension
                outputs['mean_img'] = self._gen_fname(
                    outputs['out_file'] + '_mean_reg.ext', cwd=output_dir)
            else:
                outputs['mean_img'] = self._gen_fname(
                    outputs['out_file'], suffix='_mean_reg', cwd=output_dir)

        if isdefined(self.inputs.save_mats) and self.inputs.save_mats:
            _, filename = os.path.split(outputs['out_file'])
            mat_dir = os.path.join(output_dir, filename + '.mat')
            outputs['mat_dir'] = mat_dir
            _, _, _, timepoints = load(self.inputs.in_file).shape
            outputs['mat_file'] = []
            for t in range(timepoints):
                outputs['mat_file'].append(
                    os.path.join(mat_dir, 'MAT_%04d' % t))
        if isdefined(self.inputs.save_plots) and self.inputs.save_plots:
            # Note - if e.g. out_file has .nii.gz, you get .nii.gz.par,
            # which is what mcflirt does!
            outputs['par_file'] = outputs['out_file'] + '.par'
        if isdefined(self.inputs.save_rms) and self.inputs.save_rms:
            outfile = outputs['out_file']
            outputs['rms_files'] = [outfile + '_abs.rms', outfile + '_rel.rms']
        return outputs
Example #2
0
def _get_fsl_slice_output_files(out_base_name, output_type):
    ext = Info.output_type_to_ext(output_type)
    suffix = '_slice_*' + ext
    exact_pattern = '_slice_[0-9][0-9][0-9][0-9]' + ext
    fname_template = os.path.abspath(out_base_name + suffix)
    fname_exact_pattern = os.path.abspath(out_base_name + exact_pattern)
    sliced_files = fnmatch.filter(sorted(glob.glob(fname_template)),
                                  fname_exact_pattern)
    return sliced_files
Example #3
0
    def _gen_fname(self,
                   basename,
                   cwd=None,
                   suffix=None,
                   change_ext=True,
                   ext=None):
        """Generate a filename based on the given parameters.

        The filename will take the form: cwd/basename<suffix><ext>.
        If change_ext is True, it will use the extentions specified in
        <instance>intputs.output_type.

        Parameters
        ----------
        basename : str
            Filename to base the new filename on.
        cwd : str
            Path to prefix to the new filename. (default is os.getcwd())
        suffix : str
            Suffix to add to the `basename`.  (defaults is '' )
        change_ext : bool
            Flag to change the filename extension to the FSL output type.
            (default True)

        Returns
        -------
        fname : str
            New filename based on given parameters.

        """

        if basename == '':
            msg = 'Unable to generate filename for command %s. ' % self.cmd
            msg += 'basename is not set!'
            raise ValueError(msg)
        if cwd is None:
            cwd = os.getcwd()
        if ext is None:
            ext = Info.output_type_to_ext(self.inputs.output_type)
        if change_ext:
            if suffix:
                suffix = ''.join((suffix, ext))
            else:
                suffix = ext
        if suffix is None:
            suffix = ''
        fname = fname_presuffix(basename,
                                suffix=suffix,
                                use_ext=False,
                                newpath=cwd)
        return fname
Example #4
0
def flirt_anatomical_linear_registration(workflow, resource_pool, config):

    # resource pool should have:
    #     anatomical_brain

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

    from workflow_utils import check_input_resources, \
                               check_config_settings

    from nipype.interfaces.fsl.base import Info

    if "template_brain_for_anat" not in config:
        config["template_brain_for_anat"] = Info.standard_image(
            "MNI152_T1_2mm_brain.nii.gz")
    check_config_settings(config, "template_brain_for_anat")

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

        from anatomical_preproc import anatomical_skullstrip_workflow

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

    #check_input_resources(resource_pool, "anatomical_brain")

    calc_flirt_warp = pe.Node(interface=fsl.FLIRT(), name='calc_flirt_warp')

    calc_flirt_warp.inputs.cost = 'corratio'

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

    calc_flirt_warp.inputs.reference = config["template_brain_for_anat"]

    resource_pool["flirt_affine_xfm"] = (calc_flirt_warp, 'out_matrix_file')

    resource_pool["flirt_linear_warped_image"] = (calc_flirt_warp, 'out_file')

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

    # resource pool should have:
    #     anatomical_brain

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

    from workflow_utils import check_input_resources, check_config_settings

    from nipype.interfaces.fsl.base import Info

    if "template_brain_for_anat" not in config:
        config["template_brain_for_anat"] = Info.standard_image("MNI152_T1_2mm_brain.nii.gz")
    check_config_settings(config, "template_brain_for_anat")

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

        from anatomical_preproc import anatomical_skullstrip_workflow

        workflow, resource_pool = anatomical_skullstrip_workflow(workflow, resource_pool, config)

    # check_input_resources(resource_pool, "anatomical_brain")

    calc_flirt_warp = pe.Node(interface=fsl.FLIRT(), name="calc_flirt_warp")

    calc_flirt_warp.inputs.cost = "corratio"

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

    calc_flirt_warp.inputs.reference = config["template_brain_for_anat"]

    resource_pool["flirt_affine_xfm"] = (calc_flirt_warp, "out_matrix_file")

    resource_pool["flirt_linear_warped_image"] = (calc_flirt_warp, "out_file")

    return workflow, resource_pool
Example #6
0
    def _gen_fname(self, basename, cwd=None, suffix=None, change_ext=True,
                   ext=None):
        """Generate a filename based on the given parameters.

        The filename will take the form: cwd/basename<suffix><ext>.
        If change_ext is True, it will use the extentions specified in
        <instance>intputs.output_type.

        Parameters
        ----------
        basename : str
            Filename to base the new filename on.
        cwd : str
            Path to prefix to the new filename. (default is os.getcwd())
        suffix : str
            Suffix to add to the `basename`.  (defaults is '' )
        change_ext : bool
            Flag to change the filename extension to the FSL output type.
            (default True)

        Returns
        -------
        fname : str
            New filename based on given parameters.

        """

        if basename == '':
            msg = 'Unable to generate filename for command %s. ' % self.cmd
            msg += 'basename is not set!'
            raise ValueError(msg)
        if cwd is None:
            cwd = os.getcwd()
        if ext is None:
            ext = Info.output_type_to_ext(self.inputs.output_type)
        if change_ext:
            if suffix:
                suffix = ''.join((suffix, ext))
            else:
                suffix = ext
        if suffix is None:
            suffix = ''
        fname = fname_presuffix(basename, suffix=suffix,
                                use_ext=False, newpath=cwd)
        return fname
Example #7
0
 def _format_arg(self, name, spec, value):
     if name == "project_data":
         if isdefined(value) and value:
             _si = self.inputs
             if isdefined(_si.use_cingulum_mask) and _si.use_cingulum_mask:
                 mask_file = Info.standard_image("LowerCingulum_1mm.nii.gz")
             else:
                 mask_file = _si.search_mask_file
             if not isdefined(_si.projected_data):
                 proj_file = self._list_outputs()["projected_data"]
             else:
                 proj_file = _si.projected_data
             return spec.argstr % (_si.threshold, _si.distance_map, mask_file, _si.data_file, proj_file)
     elif name == "skeleton_file":
         if isinstance(value, bool):
             return spec.argstr % self._list_outputs()["skeleton_file"]
         else:
             return spec.argstr % value
     return super(TractSkeleton, self)._format_arg(name, spec, value)
Example #8
0
 def _format_arg(self, name, spec, value):
     if name == "project_data":
         if isdefined(value) and value:
             _si = self.inputs
             if isdefined(_si.use_cingulum_mask) and _si.use_cingulum_mask:
                 mask_file = Info.standard_image("LowerCingulum_1mm.nii.gz")
             else:
                 mask_file = _si.search_mask_file
             if not isdefined(_si.projected_data):
                 proj_file = self._list_outputs()["projected_data"]
             else:
                 proj_file = _si.projected_data
             return spec.argstr % (_si.threshold, _si.distance_map,
                                   mask_file, _si.data_file, proj_file)
     elif name == "skeleton_file":
         if isinstance(value, bool):
             return spec.argstr % self._list_outputs()["skeleton_file"]
         else:
             return spec.argstr % value
     return super(TractSkeleton, self)._format_arg(name, spec, value)
Example #9
0
    def _list_outputs(self):
        """Create a Bunch which contains all possible files generated
        by running the interface.  Some files are always generated, others
        depending on which ``inputs`` options are set.

        Returns
        -------
        outputs : Bunch object
            Bunch object containing all possible files generated by
            interface object.

            If None, file was not generated
            Else, contains path, filename of generated outputfile

        """
        outputs = self._outputs().get()
        ext = Info.output_type_to_ext(self.inputs.output_type)
        outbase = 'vol*'
        if isdefined(self.inputs.out_base_name):
            outbase = '%s*' % self.inputs.out_base_name
        outputs['out_files'] = sorted(glob(os.path.join(os.getcwd(),
                                                    outbase + ext)))
        return outputs
Example #10
0
    def _list_outputs(self):
        """Create a Bunch which contains all possible files generated
        by running the interface.  Some files are always generated, others
        depending on which ``inputs`` options are set.

        Returns
        -------
        outputs : Bunch object
            Bunch object containing all possible files generated by
            interface object.

            If None, file was not generated
            Else, contains path, filename of generated outputfile

        """
        outputs = self._outputs().get()
        ext = Info.output_type_to_ext(self.inputs.output_type)
        outbase = 'vol*'
        if isdefined(self.inputs.out_base_name):
            outbase = '%s*' % self.inputs.out_base_name
        outputs['out_files'] = sorted(glob(os.path.join(os.getcwd(),
                                                    outbase + ext)))
        return outputs
Example #11
0
    def _list_fsl_split_outputs(self):
        """ Method to list the fsl split interface outputs

        Returns
        -------
        outputs: dict
            all the interface outputs
        """
        from glob import glob
        from nipype.interfaces.fsl.base import Info
        from nipype.interfaces.base import isdefined

        # Get the nipype outputs
        outputs = self._outputs().get()

        # Modify the path outputs
        ext = Info.output_type_to_ext(self.inputs.output_type)
        outbase = 'vol*'
        if isdefined(self.inputs.out_base_name):
            outbase = '%s*' % self.inputs.out_base_name
        outputs['out_files'] = sorted(glob(
            os.path.join(self.inputs.output_directory, outbase + ext)))

        return outputs
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
Example #13
0
def ants_anatomical_linear_registration(workflow, resource_pool, config):

    # resource pool should have:
    #     anatomical_brain

    # linear ANTS registration takes roughly 2.5 minutes per subject running
    # on one core of an Intel Core i7-4800MQ CPU @ 2.70GHz

    import os
    import sys

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

    import nipype.interfaces.utility as util

    from anatomical_preproc_utils import ants_lin_reg, \
                                         separate_warps_list

    from workflow_utils import check_input_resources, \
                               check_config_settings
    from nipype.interfaces.fsl.base import Info

    if "template_brain_for_anat" not in config:
        config["template_brain_for_anat"] = Info.standard_image(
            "MNI152_T1_2mm_brain.nii.gz")
    check_config_settings(config, "template_brain_for_anat")

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

        from anatomical_preproc import anatomical_skullstrip_workflow

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

    #check_input_resources(resource_pool, "anatomical_brain")

    calc_ants_warp = pe.Node(interface=util.Function(
        input_names=['anatomical_brain', 'reference_brain'],
        output_names=['warp_list', 'warped_image'],
        function=ants_lin_reg),
                             name='calc_ants_linear_warp')

    select_forward_initial = pe.Node(util.Function(
        input_names=['warp_list', 'selection'],
        output_names=['selected_warp'],
        function=separate_warps_list),
                                     name='select_forward_initial')

    select_forward_initial.inputs.selection = "Initial"

    select_forward_rigid = pe.Node(util.Function(
        input_names=['warp_list', 'selection'],
        output_names=['selected_warp'],
        function=separate_warps_list),
                                   name='select_forward_rigid')

    select_forward_rigid.inputs.selection = "Rigid"

    select_forward_affine = pe.Node(util.Function(
        input_names=['warp_list', 'selection'],
        output_names=['selected_warp'],
        function=separate_warps_list),
                                    name='select_forward_affine')

    select_forward_affine.inputs.selection = "Affine"

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

    calc_ants_warp.inputs.reference_brain = config["template_brain_for_anat"]

    workflow.connect(calc_ants_warp, 'warp_list', select_forward_initial,
                     'warp_list')

    workflow.connect(calc_ants_warp, 'warp_list', select_forward_rigid,
                     'warp_list')

    workflow.connect(calc_ants_warp, 'warp_list', select_forward_affine,
                     'warp_list')


    resource_pool["ants_initial_xfm"] = \
        (select_forward_initial, 'selected_warp')

    resource_pool["ants_rigid_xfm"] = (select_forward_rigid, 'selected_warp')

    resource_pool["ants_affine_xfm"] = \
        (select_forward_affine, 'selected_warp')

    resource_pool["ants_linear_warped_image"] = \
        (calc_ants_warp, 'warped_image')

    return workflow, resource_pool
Example #14
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
def ants_anatomical_linear_registration(workflow, resource_pool, config):

    # resource pool should have:
    #     anatomical_brain

    # linear ANTS registration takes roughly 2.5 minutes per subject running
    # on one core of an Intel Core i7-4800MQ CPU @ 2.70GHz

    import os
    import sys

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

    import nipype.interfaces.utility as util

    from anatomical_preproc_utils import ants_lin_reg, separate_warps_list

    from workflow_utils import check_input_resources, check_config_settings
    from nipype.interfaces.fsl.base import Info

    if "template_brain_for_anat" not in config:
        config["template_brain_for_anat"] = Info.standard_image("MNI152_T1_2mm_brain.nii.gz")
    check_config_settings(config, "template_brain_for_anat")

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

        from anatomical_preproc import anatomical_skullstrip_workflow

        workflow, resource_pool = anatomical_skullstrip_workflow(workflow, resource_pool, config)

    # check_input_resources(resource_pool, "anatomical_brain")

    calc_ants_warp = pe.Node(
        interface=util.Function(
            input_names=["anatomical_brain", "reference_brain"],
            output_names=["warp_list", "warped_image"],
            function=ants_lin_reg,
        ),
        name="calc_ants_linear_warp",
    )

    select_forward_initial = pe.Node(
        util.Function(
            input_names=["warp_list", "selection"], output_names=["selected_warp"], function=separate_warps_list
        ),
        name="select_forward_initial",
    )

    select_forward_initial.inputs.selection = "Initial"

    select_forward_rigid = pe.Node(
        util.Function(
            input_names=["warp_list", "selection"], output_names=["selected_warp"], function=separate_warps_list
        ),
        name="select_forward_rigid",
    )

    select_forward_rigid.inputs.selection = "Rigid"

    select_forward_affine = pe.Node(
        util.Function(
            input_names=["warp_list", "selection"], output_names=["selected_warp"], function=separate_warps_list
        ),
        name="select_forward_affine",
    )

    select_forward_affine.inputs.selection = "Affine"

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

    calc_ants_warp.inputs.reference_brain = config["template_brain_for_anat"]

    workflow.connect(calc_ants_warp, "warp_list", select_forward_initial, "warp_list")

    workflow.connect(calc_ants_warp, "warp_list", select_forward_rigid, "warp_list")

    workflow.connect(calc_ants_warp, "warp_list", select_forward_affine, "warp_list")

    resource_pool["ants_initial_xfm"] = (select_forward_initial, "selected_warp")

    resource_pool["ants_rigid_xfm"] = (select_forward_rigid, "selected_warp")

    resource_pool["ants_affine_xfm"] = (select_forward_affine, "selected_warp")

    resource_pool["ants_linear_warped_image"] = (calc_ants_warp, "warped_image")

    return workflow, resource_pool