# This file was auto generated by Styx.
# Do not edit this file directly.

import typing
import pathlib
from styxdefs import *

VOLUME_TO_SURFACE_MAPPING_METADATA = Metadata(
    id="677cb03d3aef10ca7afb17c714f6c3c6f70b3a93.boutiques",
    name="volume-to-surface-mapping",
    package="workbench",
    container_image_tag="brainlife/connectome_workbench:1.5.0-freesurfer-update",
)


VolumeToSurfaceMappingVolumeRoiParameters = typing.TypedDict('VolumeToSurfaceMappingVolumeRoiParameters', {
    "@type": typing.NotRequired[typing.Literal["volume_roi"]],
    "roi_volume": InputPathType,
    "opt_weighted": bool,
})
VolumeToSurfaceMappingVolumeRoiParametersTagged = typing.TypedDict('VolumeToSurfaceMappingVolumeRoiParametersTagged', {
    "@type": typing.Literal["volume_roi"],
    "roi_volume": InputPathType,
    "opt_weighted": bool,
})


VolumeToSurfaceMappingOutputWeightsParameters = typing.TypedDict('VolumeToSurfaceMappingOutputWeightsParameters', {
    "@type": typing.NotRequired[typing.Literal["output_weights"]],
    "vertex": int,
    "weights_out": str,
})
VolumeToSurfaceMappingOutputWeightsParametersTagged = typing.TypedDict('VolumeToSurfaceMappingOutputWeightsParametersTagged', {
    "@type": typing.Literal["output_weights"],
    "vertex": int,
    "weights_out": str,
})


VolumeToSurfaceMappingRibbonConstrainedParameters = typing.TypedDict('VolumeToSurfaceMappingRibbonConstrainedParameters', {
    "@type": typing.NotRequired[typing.Literal["ribbon_constrained"]],
    "inner_surf": InputPathType,
    "outer_surf": InputPathType,
    "volume_roi": typing.NotRequired[VolumeToSurfaceMappingVolumeRoiParameters | None],
    "opt_voxel_subdiv_subdiv_num": typing.NotRequired[int | None],
    "opt_thin_columns": bool,
    "opt_gaussian_scale": typing.NotRequired[float | None],
    "opt_interpolate_method": typing.NotRequired[str | None],
    "opt_bad_vertices_out_roi_out": typing.NotRequired[str | None],
    "output_weights": typing.NotRequired[VolumeToSurfaceMappingOutputWeightsParameters | None],
    "opt_output_weights_text_text_out": typing.NotRequired[str | None],
})
VolumeToSurfaceMappingRibbonConstrainedParametersTagged = typing.TypedDict('VolumeToSurfaceMappingRibbonConstrainedParametersTagged', {
    "@type": typing.Literal["ribbon_constrained"],
    "inner_surf": InputPathType,
    "outer_surf": InputPathType,
    "volume_roi": typing.NotRequired[VolumeToSurfaceMappingVolumeRoiParameters | None],
    "opt_voxel_subdiv_subdiv_num": typing.NotRequired[int | None],
    "opt_thin_columns": bool,
    "opt_gaussian_scale": typing.NotRequired[float | None],
    "opt_interpolate_method": typing.NotRequired[str | None],
    "opt_bad_vertices_out_roi_out": typing.NotRequired[str | None],
    "output_weights": typing.NotRequired[VolumeToSurfaceMappingOutputWeightsParameters | None],
    "opt_output_weights_text_text_out": typing.NotRequired[str | None],
})


VolumeToSurfaceMappingMyelinStyleParameters = typing.TypedDict('VolumeToSurfaceMappingMyelinStyleParameters', {
    "@type": typing.NotRequired[typing.Literal["myelin_style"]],
    "ribbon_roi": InputPathType,
    "thickness": InputPathType,
    "sigma": float,
    "opt_legacy_bug": bool,
})
VolumeToSurfaceMappingMyelinStyleParametersTagged = typing.TypedDict('VolumeToSurfaceMappingMyelinStyleParametersTagged', {
    "@type": typing.Literal["myelin_style"],
    "ribbon_roi": InputPathType,
    "thickness": InputPathType,
    "sigma": float,
    "opt_legacy_bug": bool,
})


VolumeToSurfaceMappingParameters = typing.TypedDict('VolumeToSurfaceMappingParameters', {
    "@type": typing.NotRequired[typing.Literal["workbench/volume-to-surface-mapping"]],
    "volume": InputPathType,
    "surface": InputPathType,
    "metric_out": str,
    "opt_trilinear": bool,
    "opt_enclosing": bool,
    "opt_cubic": bool,
    "ribbon_constrained": typing.NotRequired[VolumeToSurfaceMappingRibbonConstrainedParameters | None],
    "myelin_style": typing.NotRequired[VolumeToSurfaceMappingMyelinStyleParameters | None],
    "opt_subvol_select_subvol": typing.NotRequired[str | None],
})
VolumeToSurfaceMappingParametersTagged = typing.TypedDict('VolumeToSurfaceMappingParametersTagged', {
    "@type": typing.Literal["workbench/volume-to-surface-mapping"],
    "volume": InputPathType,
    "surface": InputPathType,
    "metric_out": str,
    "opt_trilinear": bool,
    "opt_enclosing": bool,
    "opt_cubic": bool,
    "ribbon_constrained": typing.NotRequired[VolumeToSurfaceMappingRibbonConstrainedParameters | None],
    "myelin_style": typing.NotRequired[VolumeToSurfaceMappingMyelinStyleParameters | None],
    "opt_subvol_select_subvol": typing.NotRequired[str | None],
})


def volume_to_surface_mapping_volume_roi_params(
    roi_volume: InputPathType,
    opt_weighted: bool = False,
) -> VolumeToSurfaceMappingVolumeRoiParametersTagged:
    """
    Build parameters.
    
    Args:
        roi_volume: the roi volume file.
        opt_weighted: treat the roi values as weightings rather than binary.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "volume_roi",
        "roi_volume": roi_volume,
        "opt_weighted": opt_weighted,
    }
    return params


def volume_to_surface_mapping_volume_roi_cargs(
    params: VolumeToSurfaceMappingVolumeRoiParameters,
    execution: Execution,
) -> list[str]:
    """
    Build command-line arguments from parameters.
    
    Args:
        params: The parameters.
        execution: The execution object for resolving input paths.
    Returns:
        Command-line arguments.
    """
    cargs = []
    cargs.append("-volume-roi")
    cargs.append(execution.input_file(params.get("roi_volume", None)))
    if params.get("opt_weighted", False):
        cargs.append("-weighted")
    return cargs


class VolumeToSurfaceMappingOutputWeightsOutputs(typing.NamedTuple):
    """
    Output object returned when calling `VolumeToSurfaceMappingOutputWeightsParameters | None(...)`.
    """
    root: OutputPathType
    """Output root folder. This is the root folder for all outputs."""
    weights_out: OutputPathType
    """volume to write the weights to"""


def volume_to_surface_mapping_output_weights_params(
    vertex: int,
    weights_out: str,
) -> VolumeToSurfaceMappingOutputWeightsParametersTagged:
    """
    Build parameters.
    
    Args:
        vertex: the vertex number to get the voxel weights for, 0-based.
        weights_out: volume to write the weights to.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "output_weights",
        "vertex": vertex,
        "weights_out": weights_out,
    }
    return params


def volume_to_surface_mapping_output_weights_cargs(
    params: VolumeToSurfaceMappingOutputWeightsParameters,
    execution: Execution,
) -> list[str]:
    """
    Build command-line arguments from parameters.
    
    Args:
        params: The parameters.
        execution: The execution object for resolving input paths.
    Returns:
        Command-line arguments.
    """
    cargs = []
    cargs.append("-output-weights")
    cargs.append(str(params.get("vertex", None)))
    cargs.append(params.get("weights_out", None))
    return cargs


def volume_to_surface_mapping_output_weights_outputs(
    params: VolumeToSurfaceMappingOutputWeightsParameters,
    execution: Execution,
) -> VolumeToSurfaceMappingOutputWeightsOutputs:
    """
    Build outputs object containing output file paths and possibly stdout/stderr.
    
    Args:
        params: The parameters.
        execution: The execution object for resolving input paths.
    Returns:
        Outputs object.
    """
    ret = VolumeToSurfaceMappingOutputWeightsOutputs(
        root=execution.output_file("."),
        weights_out=execution.output_file(params.get("weights_out", None)),
    )
    return ret


class VolumeToSurfaceMappingRibbonConstrainedOutputs(typing.NamedTuple):
    """
    Output object returned when calling `VolumeToSurfaceMappingRibbonConstrainedParameters | None(...)`.
    """
    root: OutputPathType
    """Output root folder. This is the root folder for all outputs."""
    output_weights: VolumeToSurfaceMappingOutputWeightsOutputs | None
    """Outputs from `volume_to_surface_mapping_output_weights_outputs`."""


def volume_to_surface_mapping_ribbon_constrained_params(
    inner_surf: InputPathType,
    outer_surf: InputPathType,
    volume_roi: VolumeToSurfaceMappingVolumeRoiParameters | None = None,
    opt_voxel_subdiv_subdiv_num: int | None = None,
    opt_thin_columns: bool = False,
    opt_gaussian_scale: float | None = None,
    opt_interpolate_method: str | None = None,
    opt_bad_vertices_out_roi_out: str | None = None,
    output_weights: VolumeToSurfaceMappingOutputWeightsParameters | None = None,
    opt_output_weights_text_text_out: str | None = None,
) -> VolumeToSurfaceMappingRibbonConstrainedParametersTagged:
    """
    Build parameters.
    
    Args:
        inner_surf: the inner surface of the ribbon.
        outer_surf: the outer surface of the ribbon.
        volume_roi: use a volume roi.
        opt_voxel_subdiv_subdiv_num: voxel divisions while estimating voxel\
            weights: number of subdivisions, default 3.
        opt_thin_columns: use non-overlapping polyhedra.
        opt_gaussian_scale: reduce weight to voxels that aren't near <surface>:\
            value to multiply the local thickness by, to get the gaussian sigma.
        opt_interpolate_method: instead of a weighted average of voxels,\
            interpolate at subpoints inside the ribbon: interpolation method, must\
            be CUBIC, ENCLOSING_VOXEL, or TRILINEAR.
        opt_bad_vertices_out_roi_out: output an ROI of which vertices didn't\
            intersect any valid voxels: the output metric file of vertices that\
            have no data.
        output_weights: write the voxel weights for a vertex to a volume file.
        opt_output_weights_text_text_out: write the voxel weights for all\
            vertices to a text file: output - the output text filename.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "ribbon_constrained",
        "inner_surf": inner_surf,
        "outer_surf": outer_surf,
        "opt_thin_columns": opt_thin_columns,
    }
    if volume_roi is not None:
        params["volume_roi"] = volume_roi
    if opt_voxel_subdiv_subdiv_num is not None:
        params["opt_voxel_subdiv_subdiv_num"] = opt_voxel_subdiv_subdiv_num
    if opt_gaussian_scale is not None:
        params["opt_gaussian_scale"] = opt_gaussian_scale
    if opt_interpolate_method is not None:
        params["opt_interpolate_method"] = opt_interpolate_method
    if opt_bad_vertices_out_roi_out is not None:
        params["opt_bad_vertices_out_roi_out"] = opt_bad_vertices_out_roi_out
    if output_weights is not None:
        params["output_weights"] = output_weights
    if opt_output_weights_text_text_out is not None:
        params["opt_output_weights_text_text_out"] = opt_output_weights_text_text_out
    return params


def volume_to_surface_mapping_ribbon_constrained_cargs(
    params: VolumeToSurfaceMappingRibbonConstrainedParameters,
    execution: Execution,
) -> list[str]:
    """
    Build command-line arguments from parameters.
    
    Args:
        params: The parameters.
        execution: The execution object for resolving input paths.
    Returns:
        Command-line arguments.
    """
    cargs = []
    cargs.append("-ribbon-constrained")
    cargs.append(execution.input_file(params.get("inner_surf", None)))
    cargs.append(execution.input_file(params.get("outer_surf", None)))
    if params.get("volume_roi", None) is not None:
        cargs.extend(volume_to_surface_mapping_volume_roi_cargs(params.get("volume_roi", None), execution))
    if params.get("opt_voxel_subdiv_subdiv_num", None) is not None:
        cargs.extend([
            "-voxel-subdiv",
            str(params.get("opt_voxel_subdiv_subdiv_num", None))
        ])
    if params.get("opt_thin_columns", False):
        cargs.append("-thin-columns")
    if params.get("opt_gaussian_scale", None) is not None:
        cargs.extend([
            "-gaussian",
            str(params.get("opt_gaussian_scale", None))
        ])
    if params.get("opt_interpolate_method", None) is not None:
        cargs.extend([
            "-interpolate",
            params.get("opt_interpolate_method", None)
        ])
    if params.get("opt_bad_vertices_out_roi_out", None) is not None:
        cargs.extend([
            "-bad-vertices-out",
            params.get("opt_bad_vertices_out_roi_out", None)
        ])
    if params.get("output_weights", None) is not None:
        cargs.extend(volume_to_surface_mapping_output_weights_cargs(params.get("output_weights", None), execution))
    if params.get("opt_output_weights_text_text_out", None) is not None:
        cargs.extend([
            "-output-weights-text",
            params.get("opt_output_weights_text_text_out", None)
        ])
    return cargs


def volume_to_surface_mapping_ribbon_constrained_outputs(
    params: VolumeToSurfaceMappingRibbonConstrainedParameters,
    execution: Execution,
) -> VolumeToSurfaceMappingRibbonConstrainedOutputs:
    """
    Build outputs object containing output file paths and possibly stdout/stderr.
    
    Args:
        params: The parameters.
        execution: The execution object for resolving input paths.
    Returns:
        Outputs object.
    """
    ret = VolumeToSurfaceMappingRibbonConstrainedOutputs(
        root=execution.output_file("."),
        output_weights=volume_to_surface_mapping_output_weights_outputs(params.get("output_weights"), execution) if params.get("output_weights") else None,
    )
    return ret


def volume_to_surface_mapping_myelin_style_params(
    ribbon_roi: InputPathType,
    thickness: InputPathType,
    sigma: float,
    opt_legacy_bug: bool = False,
) -> VolumeToSurfaceMappingMyelinStyleParametersTagged:
    """
    Build parameters.
    
    Args:
        ribbon_roi: an roi volume of the cortical ribbon for this hemisphere.
        thickness: a metric file of cortical thickness.
        sigma: gaussian kernel in mm for weighting voxels within range.
        opt_legacy_bug: emulate old v1.2.3 and earlier code that didn't follow\
            a cylinder cutoff.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "myelin_style",
        "ribbon_roi": ribbon_roi,
        "thickness": thickness,
        "sigma": sigma,
        "opt_legacy_bug": opt_legacy_bug,
    }
    return params


def volume_to_surface_mapping_myelin_style_cargs(
    params: VolumeToSurfaceMappingMyelinStyleParameters,
    execution: Execution,
) -> list[str]:
    """
    Build command-line arguments from parameters.
    
    Args:
        params: The parameters.
        execution: The execution object for resolving input paths.
    Returns:
        Command-line arguments.
    """
    cargs = []
    cargs.append("-myelin-style")
    cargs.append(execution.input_file(params.get("ribbon_roi", None)))
    cargs.append(execution.input_file(params.get("thickness", None)))
    cargs.append(str(params.get("sigma", None)))
    if params.get("opt_legacy_bug", False):
        cargs.append("-legacy-bug")
    return cargs


class VolumeToSurfaceMappingOutputs(typing.NamedTuple):
    """
    Output object returned when calling `VolumeToSurfaceMappingParameters(...)`.
    """
    root: OutputPathType
    """Output root folder. This is the root folder for all outputs."""
    metric_out: OutputPathType
    """the output metric file"""
    ribbon_constrained: VolumeToSurfaceMappingRibbonConstrainedOutputs | None
    """Outputs from `volume_to_surface_mapping_ribbon_constrained_outputs`."""


def volume_to_surface_mapping_params(
    volume: InputPathType,
    surface: InputPathType,
    metric_out: str,
    opt_trilinear: bool = False,
    opt_enclosing: bool = False,
    opt_cubic: bool = False,
    ribbon_constrained: VolumeToSurfaceMappingRibbonConstrainedParameters | None = None,
    myelin_style: VolumeToSurfaceMappingMyelinStyleParameters | None = None,
    opt_subvol_select_subvol: str | None = None,
) -> VolumeToSurfaceMappingParametersTagged:
    """
    Build parameters.
    
    Args:
        volume: the volume to map data from.
        surface: the surface to map the data onto.
        metric_out: the output metric file.
        opt_trilinear: use trilinear volume interpolation.
        opt_enclosing: use value of the enclosing voxel.
        opt_cubic: use cubic splines.
        ribbon_constrained: use ribbon constrained mapping algorithm.
        myelin_style: use the method from myelin mapping.
        opt_subvol_select_subvol: select a single subvolume to map: the\
            subvolume number or name.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "workbench/volume-to-surface-mapping",
        "volume": volume,
        "surface": surface,
        "metric_out": metric_out,
        "opt_trilinear": opt_trilinear,
        "opt_enclosing": opt_enclosing,
        "opt_cubic": opt_cubic,
    }
    if ribbon_constrained is not None:
        params["ribbon_constrained"] = ribbon_constrained
    if myelin_style is not None:
        params["myelin_style"] = myelin_style
    if opt_subvol_select_subvol is not None:
        params["opt_subvol_select_subvol"] = opt_subvol_select_subvol
    return params


def volume_to_surface_mapping_cargs(
    params: VolumeToSurfaceMappingParameters,
    execution: Execution,
) -> list[str]:
    """
    Build command-line arguments from parameters.
    
    Args:
        params: The parameters.
        execution: The execution object for resolving input paths.
    Returns:
        Command-line arguments.
    """
    cargs = []
    cargs.append("wb_command")
    cargs.append("-volume-to-surface-mapping")
    cargs.append(execution.input_file(params.get("volume", None)))
    cargs.append(execution.input_file(params.get("surface", None)))
    cargs.append(params.get("metric_out", None))
    if params.get("opt_trilinear", False):
        cargs.append("-trilinear")
    if params.get("opt_enclosing", False):
        cargs.append("-enclosing")
    if params.get("opt_cubic", False):
        cargs.append("-cubic")
    if params.get("ribbon_constrained", None) is not None:
        cargs.extend(volume_to_surface_mapping_ribbon_constrained_cargs(params.get("ribbon_constrained", None), execution))
    if params.get("myelin_style", None) is not None:
        cargs.extend(volume_to_surface_mapping_myelin_style_cargs(params.get("myelin_style", None), execution))
    if params.get("opt_subvol_select_subvol", None) is not None:
        cargs.extend([
            "-subvol-select",
            params.get("opt_subvol_select_subvol", None)
        ])
    return cargs


def volume_to_surface_mapping_outputs(
    params: VolumeToSurfaceMappingParameters,
    execution: Execution,
) -> VolumeToSurfaceMappingOutputs:
    """
    Build outputs object containing output file paths and possibly stdout/stderr.
    
    Args:
        params: The parameters.
        execution: The execution object for resolving input paths.
    Returns:
        Outputs object.
    """
    ret = VolumeToSurfaceMappingOutputs(
        root=execution.output_file("."),
        metric_out=execution.output_file(params.get("metric_out", None)),
        ribbon_constrained=volume_to_surface_mapping_ribbon_constrained_outputs(params.get("ribbon_constrained"), execution) if params.get("ribbon_constrained") else None,
    )
    return ret


def volume_to_surface_mapping_execute(
    params: VolumeToSurfaceMappingParameters,
    runner: Runner | None = None,
) -> VolumeToSurfaceMappingOutputs:
    """
    volume-to-surface-mapping
    
    Map volume to surface.
    
    You must specify exactly one mapping method. Enclosing voxel uses the value
    from the voxel the vertex lies inside, while trilinear does a 3D linear
    interpolation based on the voxels immediately on each side of the vertex's
    position.
    
    The ribbon mapping method constructs a polyhedron from the vertex's
    neighbors on each surface, and estimates the amount of this polyhedron's
    volume that falls inside any nearby voxels, to use as the weights for
    sampling. If -thin-columns is specified, the polyhedron uses the edge
    midpoints and triangle centroids, so that neighboring vertices do not have
    overlapping polyhedra. This may require increasing -voxel-subdiv to get
    enough samples in each voxel to reliably land inside these smaller
    polyhedra. The volume ROI is useful to exclude partial volume effects of
    voxels the surfaces pass through, and will cause the mapping to ignore
    voxels that don't have a positive value in the mask. The subdivision number
    specifies how it approximates the amount of the volume the polyhedron
    intersects, by splitting each voxel into NxNxN pieces, and checking whether
    the center of each piece is inside the polyhedron. If you have very large
    voxels, consider increasing this if you get zeros in your output. The
    -gaussian option makes it act more like the myelin method, where the
    distance of a voxel from <surface> is used to downweight the voxel. The
    -interpolate suboption, instead of doing a weighted average of voxels,
    interpolates from the volume at the subdivided points inside the ribbon. If
    using both -interpolate and the -weighted suboption to -volume-roi, the roi
    volume weights are linearly interpolated, unless the -interpolate method is
    ENCLOSING_VOXEL, in which case ENCLOSING_VOXEL is also used for sampling the
    roi volume weights.
    
    The myelin style method uses part of the caret5 myelin mapping command to do
    the mapping: for each surface vertex, take all voxels that are in a cylinder
    with radius and height equal to cortical thickness, centered on the vertex
    and aligned with the surface normal, and that are also within the ribbon
    ROI, and apply a gaussian kernel with the specified sigma to them to get the
    weights to use. The -legacy-bug flag reverts to the unintended behavior
    present from the initial implementation up to and including v1.2.3, which
    had only the tangential cutoff and a bounding box intended to be larger than
    where the cylinder cutoff should have been.
    
    Author: Connectome Workbench Developers
    
    URL: https://github.com/Washington-University/workbench
    
    Args:
        params: The parameters.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `VolumeToSurfaceMappingOutputs`).
    """
    runner = runner or get_global_runner()
    execution = runner.start_execution(VOLUME_TO_SURFACE_MAPPING_METADATA)
    params = execution.params(params)
    cargs = volume_to_surface_mapping_cargs(params, execution)
    ret = volume_to_surface_mapping_outputs(params, execution)
    execution.run(cargs)
    return ret


def volume_to_surface_mapping(
    volume: InputPathType,
    surface: InputPathType,
    metric_out: str,
    opt_trilinear: bool = False,
    opt_enclosing: bool = False,
    opt_cubic: bool = False,
    ribbon_constrained: VolumeToSurfaceMappingRibbonConstrainedParameters | None = None,
    myelin_style: VolumeToSurfaceMappingMyelinStyleParameters | None = None,
    opt_subvol_select_subvol: str | None = None,
    runner: Runner | None = None,
) -> VolumeToSurfaceMappingOutputs:
    """
    volume-to-surface-mapping
    
    Map volume to surface.
    
    You must specify exactly one mapping method. Enclosing voxel uses the value
    from the voxel the vertex lies inside, while trilinear does a 3D linear
    interpolation based on the voxels immediately on each side of the vertex's
    position.
    
    The ribbon mapping method constructs a polyhedron from the vertex's
    neighbors on each surface, and estimates the amount of this polyhedron's
    volume that falls inside any nearby voxels, to use as the weights for
    sampling. If -thin-columns is specified, the polyhedron uses the edge
    midpoints and triangle centroids, so that neighboring vertices do not have
    overlapping polyhedra. This may require increasing -voxel-subdiv to get
    enough samples in each voxel to reliably land inside these smaller
    polyhedra. The volume ROI is useful to exclude partial volume effects of
    voxels the surfaces pass through, and will cause the mapping to ignore
    voxels that don't have a positive value in the mask. The subdivision number
    specifies how it approximates the amount of the volume the polyhedron
    intersects, by splitting each voxel into NxNxN pieces, and checking whether
    the center of each piece is inside the polyhedron. If you have very large
    voxels, consider increasing this if you get zeros in your output. The
    -gaussian option makes it act more like the myelin method, where the
    distance of a voxel from <surface> is used to downweight the voxel. The
    -interpolate suboption, instead of doing a weighted average of voxels,
    interpolates from the volume at the subdivided points inside the ribbon. If
    using both -interpolate and the -weighted suboption to -volume-roi, the roi
    volume weights are linearly interpolated, unless the -interpolate method is
    ENCLOSING_VOXEL, in which case ENCLOSING_VOXEL is also used for sampling the
    roi volume weights.
    
    The myelin style method uses part of the caret5 myelin mapping command to do
    the mapping: for each surface vertex, take all voxels that are in a cylinder
    with radius and height equal to cortical thickness, centered on the vertex
    and aligned with the surface normal, and that are also within the ribbon
    ROI, and apply a gaussian kernel with the specified sigma to them to get the
    weights to use. The -legacy-bug flag reverts to the unintended behavior
    present from the initial implementation up to and including v1.2.3, which
    had only the tangential cutoff and a bounding box intended to be larger than
    where the cylinder cutoff should have been.
    
    Author: Connectome Workbench Developers
    
    URL: https://github.com/Washington-University/workbench
    
    Args:
        volume: the volume to map data from.
        surface: the surface to map the data onto.
        metric_out: the output metric file.
        opt_trilinear: use trilinear volume interpolation.
        opt_enclosing: use value of the enclosing voxel.
        opt_cubic: use cubic splines.
        ribbon_constrained: use ribbon constrained mapping algorithm.
        myelin_style: use the method from myelin mapping.
        opt_subvol_select_subvol: select a single subvolume to map: the\
            subvolume number or name.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `VolumeToSurfaceMappingOutputs`).
    """
    params = volume_to_surface_mapping_params(
        volume=volume,
        surface=surface,
        metric_out=metric_out,
        opt_trilinear=opt_trilinear,
        opt_enclosing=opt_enclosing,
        opt_cubic=opt_cubic,
        ribbon_constrained=ribbon_constrained,
        myelin_style=myelin_style,
        opt_subvol_select_subvol=opt_subvol_select_subvol,
    )
    return volume_to_surface_mapping_execute(params, runner)


__all__ = [
    "VOLUME_TO_SURFACE_MAPPING_METADATA",
    "VolumeToSurfaceMappingOutputWeightsOutputs",
    "VolumeToSurfaceMappingOutputs",
    "VolumeToSurfaceMappingRibbonConstrainedOutputs",
    "volume_to_surface_mapping",
    "volume_to_surface_mapping_execute",
    "volume_to_surface_mapping_myelin_style_params",
    "volume_to_surface_mapping_output_weights_params",
    "volume_to_surface_mapping_params",
    "volume_to_surface_mapping_ribbon_constrained_params",
    "volume_to_surface_mapping_volume_roi_params",
]
