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

import typing
import pathlib
from styxdefs import *

SIGNED_DISTANCE_TO_SURFACE_METADATA = Metadata(
    id="8c819d933d40718709f36a80f07be61f04dd0058.boutiques",
    name="signed-distance-to-surface",
    package="workbench",
    container_image_tag="brainlife/connectome_workbench:1.5.0-freesurfer-update",
)


SignedDistanceToSurfaceParameters = typing.TypedDict('SignedDistanceToSurfaceParameters', {
    "@type": typing.NotRequired[typing.Literal["workbench/signed-distance-to-surface"]],
    "surface_comp": InputPathType,
    "surface_ref": InputPathType,
    "metric": str,
    "opt_winding_method": typing.NotRequired[str | None],
})
SignedDistanceToSurfaceParametersTagged = typing.TypedDict('SignedDistanceToSurfaceParametersTagged', {
    "@type": typing.Literal["workbench/signed-distance-to-surface"],
    "surface_comp": InputPathType,
    "surface_ref": InputPathType,
    "metric": str,
    "opt_winding_method": typing.NotRequired[str | None],
})


class SignedDistanceToSurfaceOutputs(typing.NamedTuple):
    """
    Output object returned when calling `SignedDistanceToSurfaceParameters(...)`.
    """
    root: OutputPathType
    """Output root folder. This is the root folder for all outputs."""
    metric: OutputPathType
    """the output metric"""


def signed_distance_to_surface_params(
    surface_comp: InputPathType,
    surface_ref: InputPathType,
    metric: str,
    opt_winding_method: str | None = None,
) -> SignedDistanceToSurfaceParametersTagged:
    """
    Build parameters.
    
    Args:
        surface_comp: the comparison surface to measure the signed distance on.
        surface_ref: the reference surface that defines the signed distance\
            function.
        metric: the output metric.
        opt_winding_method: winding method for point inside surface test: name\
            of the method (default EVEN_ODD).
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "workbench/signed-distance-to-surface",
        "surface_comp": surface_comp,
        "surface_ref": surface_ref,
        "metric": metric,
    }
    if opt_winding_method is not None:
        params["opt_winding_method"] = opt_winding_method
    return params


def signed_distance_to_surface_cargs(
    params: SignedDistanceToSurfaceParameters,
    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("-signed-distance-to-surface")
    cargs.append(execution.input_file(params.get("surface_comp", None)))
    cargs.append(execution.input_file(params.get("surface_ref", None)))
    cargs.append(params.get("metric", None))
    if params.get("opt_winding_method", None) is not None:
        cargs.extend([
            "-winding",
            params.get("opt_winding_method", None)
        ])
    return cargs


def signed_distance_to_surface_outputs(
    params: SignedDistanceToSurfaceParameters,
    execution: Execution,
) -> SignedDistanceToSurfaceOutputs:
    """
    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 = SignedDistanceToSurfaceOutputs(
        root=execution.output_file("."),
        metric=execution.output_file(params.get("metric", None)),
    )
    return ret


def signed_distance_to_surface_execute(
    params: SignedDistanceToSurfaceParameters,
    runner: Runner | None = None,
) -> SignedDistanceToSurfaceOutputs:
    """
    signed-distance-to-surface
    
    Compute signed distance from one surface to another.
    
    Compute the signed distance function of the reference surface at every
    vertex on the comparison surface. NOTE: this relation is NOT symmetric, the
    line from a vertex to the closest point on the 'ref' surface (the one that
    defines the signed distance function) will only align with the normal of the
    'ref' surface. 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 `SignedDistanceToSurfaceOutputs`).
    """
    runner = runner or get_global_runner()
    execution = runner.start_execution(SIGNED_DISTANCE_TO_SURFACE_METADATA)
    params = execution.params(params)
    cargs = signed_distance_to_surface_cargs(params, execution)
    ret = signed_distance_to_surface_outputs(params, execution)
    execution.run(cargs)
    return ret


def signed_distance_to_surface(
    surface_comp: InputPathType,
    surface_ref: InputPathType,
    metric: str,
    opt_winding_method: str | None = None,
    runner: Runner | None = None,
) -> SignedDistanceToSurfaceOutputs:
    """
    signed-distance-to-surface
    
    Compute signed distance from one surface to another.
    
    Compute the signed distance function of the reference surface at every
    vertex on the comparison surface. NOTE: this relation is NOT symmetric, the
    line from a vertex to the closest point on the 'ref' surface (the one that
    defines the signed distance function) will only align with the normal of the
    'ref' surface. 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_comp: the comparison surface to measure the signed distance on.
        surface_ref: the reference surface that defines the signed distance\
            function.
        metric: the output metric.
        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 `SignedDistanceToSurfaceOutputs`).
    """
    params = signed_distance_to_surface_params(
        surface_comp=surface_comp,
        surface_ref=surface_ref,
        metric=metric,
        opt_winding_method=opt_winding_method,
    )
    return signed_distance_to_surface_execute(params, runner)


__all__ = [
    "SIGNED_DISTANCE_TO_SURFACE_METADATA",
    "SignedDistanceToSurfaceOutputs",
    "signed_distance_to_surface",
    "signed_distance_to_surface_execute",
    "signed_distance_to_surface_params",
]
