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

import typing
import pathlib
from styxdefs import *

CREATE_SIGNED_DISTANCE_VOLUME_METADATA = Metadata(
    id="a3c155c43199f00044e684ccce6c00d843dcec5a.boutiques",
    name="create-signed-distance-volume",
    package="workbench",
    container_image_tag="brainlife/connectome_workbench:1.5.0-freesurfer-update",
)


CreateSignedDistanceVolumeParameters = typing.TypedDict('CreateSignedDistanceVolumeParameters', {
    "@type": typing.NotRequired[typing.Literal["workbench/create-signed-distance-volume"]],
    "surface": InputPathType,
    "refspace": str,
    "outvol": str,
    "opt_roi_out_roi_vol": typing.NotRequired[str | None],
    "opt_fill_value_value": typing.NotRequired[float | None],
    "opt_exact_limit_dist": typing.NotRequired[float | None],
    "opt_approx_limit_dist": typing.NotRequired[float | None],
    "opt_approx_neighborhood_num": typing.NotRequired[int | None],
    "opt_winding_method": typing.NotRequired[str | None],
})
CreateSignedDistanceVolumeParametersTagged = typing.TypedDict('CreateSignedDistanceVolumeParametersTagged', {
    "@type": typing.Literal["workbench/create-signed-distance-volume"],
    "surface": InputPathType,
    "refspace": str,
    "outvol": str,
    "opt_roi_out_roi_vol": typing.NotRequired[str | None],
    "opt_fill_value_value": typing.NotRequired[float | None],
    "opt_exact_limit_dist": typing.NotRequired[float | None],
    "opt_approx_limit_dist": typing.NotRequired[float | None],
    "opt_approx_neighborhood_num": typing.NotRequired[int | None],
    "opt_winding_method": typing.NotRequired[str | None],
})


class CreateSignedDistanceVolumeOutputs(typing.NamedTuple):
    """
    Output object returned when calling `CreateSignedDistanceVolumeParameters(...)`.
    """
    root: OutputPathType
    """Output root folder. This is the root folder for all outputs."""
    outvol: OutputPathType
    """the output volume"""
    opt_roi_out_roi_vol: OutputPathType | None
    """output an roi volume of where the output has a computed value: the output
    roi volume"""


def create_signed_distance_volume_params(
    surface: InputPathType,
    refspace: str,
    outvol: str,
    opt_roi_out_roi_vol: str | None = None,
    opt_fill_value_value: float | None = None,
    opt_exact_limit_dist: float | None = None,
    opt_approx_limit_dist: float | None = None,
    opt_approx_neighborhood_num: int | None = None,
    opt_winding_method: str | None = None,
) -> CreateSignedDistanceVolumeParametersTagged:
    """
    Build parameters.
    
    Args:
        surface: the input surface.
        refspace: a volume in the desired output space (dims, spacing, origin).
        outvol: the output volume.
        opt_roi_out_roi_vol: output an roi volume of where the output has a\
            computed value: the output roi volume.
        opt_fill_value_value: specify a value to put in all voxels that don't\
            get assigned a distance: value to fill with (default 0).
        opt_exact_limit_dist: specify distance for exact output: distance in mm\
            (default 5).
        opt_approx_limit_dist: specify distance for approximate output:\
            distance in mm (default 20).
        opt_approx_neighborhood_num: voxel neighborhood for approximate\
            calculation: size of neighborhood cube measured from center to face, in\
            voxels (default 2 = 5x5x5).
        opt_winding_method: winding method for point inside surface test: name\
            of the method (default EVEN_ODD).
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "workbench/create-signed-distance-volume",
        "surface": surface,
        "refspace": refspace,
        "outvol": outvol,
    }
    if opt_roi_out_roi_vol is not None:
        params["opt_roi_out_roi_vol"] = opt_roi_out_roi_vol
    if opt_fill_value_value is not None:
        params["opt_fill_value_value"] = opt_fill_value_value
    if opt_exact_limit_dist is not None:
        params["opt_exact_limit_dist"] = opt_exact_limit_dist
    if opt_approx_limit_dist is not None:
        params["opt_approx_limit_dist"] = opt_approx_limit_dist
    if opt_approx_neighborhood_num is not None:
        params["opt_approx_neighborhood_num"] = opt_approx_neighborhood_num
    if opt_winding_method is not None:
        params["opt_winding_method"] = opt_winding_method
    return params


def create_signed_distance_volume_cargs(
    params: CreateSignedDistanceVolumeParameters,
    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("-create-signed-distance-volume")
    cargs.append(execution.input_file(params.get("surface", None)))
    cargs.append(params.get("refspace", None))
    cargs.append(params.get("outvol", None))
    if params.get("opt_roi_out_roi_vol", None) is not None:
        cargs.extend([
            "-roi-out",
            params.get("opt_roi_out_roi_vol", None)
        ])
    if params.get("opt_fill_value_value", None) is not None:
        cargs.extend([
            "-fill-value",
            str(params.get("opt_fill_value_value", None))
        ])
    if params.get("opt_exact_limit_dist", None) is not None:
        cargs.extend([
            "-exact-limit",
            str(params.get("opt_exact_limit_dist", None))
        ])
    if params.get("opt_approx_limit_dist", None) is not None:
        cargs.extend([
            "-approx-limit",
            str(params.get("opt_approx_limit_dist", None))
        ])
    if params.get("opt_approx_neighborhood_num", None) is not None:
        cargs.extend([
            "-approx-neighborhood",
            str(params.get("opt_approx_neighborhood_num", None))
        ])
    if params.get("opt_winding_method", None) is not None:
        cargs.extend([
            "-winding",
            params.get("opt_winding_method", None)
        ])
    return cargs


def create_signed_distance_volume_outputs(
    params: CreateSignedDistanceVolumeParameters,
    execution: Execution,
) -> CreateSignedDistanceVolumeOutputs:
    """
    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 = CreateSignedDistanceVolumeOutputs(
        root=execution.output_file("."),
        outvol=execution.output_file(params.get("outvol", None)),
        opt_roi_out_roi_vol=execution.output_file(params.get("opt_roi_out_roi_vol", None)) if (params.get("opt_roi_out_roi_vol") is not None) else None,
    )
    return ret


def create_signed_distance_volume_execute(
    params: CreateSignedDistanceVolumeParameters,
    runner: Runner | None = None,
) -> CreateSignedDistanceVolumeOutputs:
    """
    create-signed-distance-volume
    
    Create signed distance volume from surface.
    
    Computes the signed distance function of the surface. Exact distance is
    calculated by finding the closest point on any surface triangle to the
    center of the voxel. Approximate distance is calculated starting with these
    distances, using dijkstra's method with a neighborhood of voxels. Specifying
    too small of an exact distance may produce unexpected results. Valid
    specifiers for winding methods are as follows:
    
    EVEN_ODD (default)
    NEGATIVE
    NONZERO
    NORMALS
    
    The NORMALS method uses the normals of triangles and edges, or the closest
    triangle hit by a ray from the point. This method may be slightly faster,
    but is only reliable for a closed surface that does not cross through
    itself. All other methods count entry (positive) and exit (negative)
    crossings of a vertical ray from the point, then counts as inside if the
    total is odd, negative, or nonzero, respectively.
    
    Author: Connectome Workbench Developers
    
    URL: https://github.com/Washington-University/workbench
    
    Args:
        params: The parameters.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `CreateSignedDistanceVolumeOutputs`).
    """
    runner = runner or get_global_runner()
    execution = runner.start_execution(CREATE_SIGNED_DISTANCE_VOLUME_METADATA)
    params = execution.params(params)
    cargs = create_signed_distance_volume_cargs(params, execution)
    ret = create_signed_distance_volume_outputs(params, execution)
    execution.run(cargs)
    return ret


def create_signed_distance_volume(
    surface: InputPathType,
    refspace: str,
    outvol: str,
    opt_roi_out_roi_vol: str | None = None,
    opt_fill_value_value: float | None = None,
    opt_exact_limit_dist: float | None = None,
    opt_approx_limit_dist: float | None = None,
    opt_approx_neighborhood_num: int | None = None,
    opt_winding_method: str | None = None,
    runner: Runner | None = None,
) -> CreateSignedDistanceVolumeOutputs:
    """
    create-signed-distance-volume
    
    Create signed distance volume from surface.
    
    Computes the signed distance function of the surface. Exact distance is
    calculated by finding the closest point on any surface triangle to the
    center of the voxel. Approximate distance is calculated starting with these
    distances, using dijkstra's method with a neighborhood of voxels. Specifying
    too small of an exact distance may produce unexpected results. Valid
    specifiers for winding methods are as follows:
    
    EVEN_ODD (default)
    NEGATIVE
    NONZERO
    NORMALS
    
    The NORMALS method uses the normals of triangles and edges, or the closest
    triangle hit by a ray from the point. This method may be slightly faster,
    but is only reliable for a closed surface that does not cross through
    itself. All other methods count entry (positive) and exit (negative)
    crossings of a vertical ray from the point, then counts as inside if the
    total is odd, negative, or nonzero, respectively.
    
    Author: Connectome Workbench Developers
    
    URL: https://github.com/Washington-University/workbench
    
    Args:
        surface: the input surface.
        refspace: a volume in the desired output space (dims, spacing, origin).
        outvol: the output volume.
        opt_roi_out_roi_vol: output an roi volume of where the output has a\
            computed value: the output roi volume.
        opt_fill_value_value: specify a value to put in all voxels that don't\
            get assigned a distance: value to fill with (default 0).
        opt_exact_limit_dist: specify distance for exact output: distance in mm\
            (default 5).
        opt_approx_limit_dist: specify distance for approximate output:\
            distance in mm (default 20).
        opt_approx_neighborhood_num: voxel neighborhood for approximate\
            calculation: size of neighborhood cube measured from center to face, in\
            voxels (default 2 = 5x5x5).
        opt_winding_method: winding method for point inside surface test: name\
            of the method (default EVEN_ODD).
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `CreateSignedDistanceVolumeOutputs`).
    """
    params = create_signed_distance_volume_params(
        surface=surface,
        refspace=refspace,
        outvol=outvol,
        opt_roi_out_roi_vol=opt_roi_out_roi_vol,
        opt_fill_value_value=opt_fill_value_value,
        opt_exact_limit_dist=opt_exact_limit_dist,
        opt_approx_limit_dist=opt_approx_limit_dist,
        opt_approx_neighborhood_num=opt_approx_neighborhood_num,
        opt_winding_method=opt_winding_method,
    )
    return create_signed_distance_volume_execute(params, runner)


__all__ = [
    "CREATE_SIGNED_DISTANCE_VOLUME_METADATA",
    "CreateSignedDistanceVolumeOutputs",
    "create_signed_distance_volume",
    "create_signed_distance_volume_execute",
    "create_signed_distance_volume_params",
]
