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

import typing
import pathlib
from styxdefs import *

SURFACE_GEODESIC_DISTANCE_SPARSE_TEXT_METADATA = Metadata(
    id="cd601df7eb26b8adf13c26cf609d763a8d458dd0.workbench",
    name="surface-geodesic-distance-sparse-text",
    package="workbench",
    container_image_tag="nx10x/workbench:2.1.0",
)


_SurfaceGeodesicDistanceSparseTextParamsDictNoTag = typing.TypedDict('_SurfaceGeodesicDistanceSparseTextParamsDictNoTag', {
    "surface": InputPathType,
    "limit": float,
    "text-out": str,
    "area-metric": typing.NotRequired[InputPathType | None],
    "naive": bool,
})
SurfaceGeodesicDistanceSparseTextParamsDictTagged = typing.TypedDict('SurfaceGeodesicDistanceSparseTextParamsDictTagged', {
    "@type": typing.Literal["workbench/surface-geodesic-distance-sparse-text"],
    "surface": InputPathType,
    "limit": float,
    "text-out": str,
    "area-metric": typing.NotRequired[InputPathType | None],
    "naive": bool,
})
SurfaceGeodesicDistanceSparseTextParamsDict = _SurfaceGeodesicDistanceSparseTextParamsDictNoTag | SurfaceGeodesicDistanceSparseTextParamsDictTagged


class SurfaceGeodesicDistanceSparseTextOutputs(typing.NamedTuple):
    """
    Output object returned when calling `SurfaceGeodesicDistanceSparseTextParamsDict(...)`.
    """
    root: OutputPathType
    """Output root folder. This is the root folder for all outputs."""


def surface_geodesic_distance_sparse_text_params(
    surface: InputPathType,
    limit: float,
    text_out: str,
    area_metric: InputPathType | None = None,
    naive: bool = False,
) -> SurfaceGeodesicDistanceSparseTextParamsDictTagged:
    """
    Build parameters.
    
    Args:
        surface: the surface to compute on.
        limit: the geodesic distance limit in mm.
        text_out: output - the output text file.
        area_metric: vertex areas to use to correct the distances on a\
            group-average surface\
            \
            the corrected vertex areas, as a metric.
        naive: use only neighbors, don't crawl triangles (not recommended).
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "workbench/surface-geodesic-distance-sparse-text",
        "surface": surface,
        "limit": limit,
        "text-out": text_out,
        "naive": naive,
    }
    if area_metric is not None:
        params["area-metric"] = area_metric
    return params


def surface_geodesic_distance_sparse_text_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `SurfaceGeodesicDistanceSparseTextParamsDict` object.
    
    Args:
        params: The parameters object to validate.
    """
    if params is None or not isinstance(params, dict):
        raise StyxValidationError(f'Params object has the wrong type \'{type(params)}\'')
    if params.get("surface", None) is None:
        raise StyxValidationError("`surface` must not be None")
    if not isinstance(params["surface"], (pathlib.Path, str)):
        raise StyxValidationError(f'`surface` has the wrong type: Received `{type(params.get("surface", None))}` expected `InputPathType`')
    if params.get("limit", None) is None:
        raise StyxValidationError("`limit` must not be None")
    if not isinstance(params["limit"], (float, int)):
        raise StyxValidationError(f'`limit` has the wrong type: Received `{type(params.get("limit", None))}` expected `float`')
    if params.get("text-out", None) is None:
        raise StyxValidationError("`text-out` must not be None")
    if not isinstance(params["text-out"], str):
        raise StyxValidationError(f'`text-out` has the wrong type: Received `{type(params.get("text-out", None))}` expected `str`')
    if params.get("area-metric", None) is not None:
        if not isinstance(params["area-metric"], (pathlib.Path, str)):
            raise StyxValidationError(f'`area-metric` has the wrong type: Received `{type(params.get("area-metric", None))}` expected `InputPathType | None`')
    if params.get("naive", False) is None:
        raise StyxValidationError("`naive` must not be None")
    if not isinstance(params["naive"], bool):
        raise StyxValidationError(f'`naive` has the wrong type: Received `{type(params.get("naive", False))}` expected `bool`')


def surface_geodesic_distance_sparse_text_cargs(
    params: SurfaceGeodesicDistanceSparseTextParamsDict,
    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.extend([
        "wb_command",
        "-surface-geodesic-distance-sparse-text"
    ])
    cargs.append(execution.input_file(params.get("surface", None)))
    cargs.append(str(params.get("limit", None)))
    cargs.append(params.get("text-out", None))
    if params.get("area-metric", None) is not None:
        cargs.extend([
            "-corrected-areas",
            execution.input_file(params.get("area-metric", None))
        ])
    if params.get("naive", False):
        cargs.append("-naive")
    return cargs


def surface_geodesic_distance_sparse_text_outputs(
    params: SurfaceGeodesicDistanceSparseTextParamsDict,
    execution: Execution,
) -> SurfaceGeodesicDistanceSparseTextOutputs:
    """
    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 = SurfaceGeodesicDistanceSparseTextOutputs(
        root=execution.output_file("."),
    )
    return ret


def surface_geodesic_distance_sparse_text_execute(
    params: SurfaceGeodesicDistanceSparseTextParamsDict,
    runner: Runner | None = None,
) -> SurfaceGeodesicDistanceSparseTextOutputs:
    """
    OUTPUT GEODESIC DISTANCES AS TEXT.
    
    Similar to -geodesic-distance-all-to-all, but outputs in a text format that
    only lists the in-range vertices. Each line in the output text file is a
    list of pairs, like '<vertex>,<distance>,<vertex>,<distance>,...' in csv
    format.
    
    The -corrected-areas option should be used when the input is a group average
    surface - group average surfaces have significantly less surface area than
    individual surfaces do, and therefore distances measured on them would be
    smaller than measuring them on individual surfaces. In this case, the input
    to this option should be a group average of the output of
    -surface-vertex-areas for each subject.
    
    If -naive is not specified, the algorithm uses not just immediate neighbors,
    but also neighbors derived from crawling across pairs of triangles that
    share an edge.
    
    Args:
        params: The parameters.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `SurfaceGeodesicDistanceSparseTextOutputs`).
    """
    surface_geodesic_distance_sparse_text_validate(params)
    runner = runner or get_global_runner()
    execution = runner.start_execution(SURFACE_GEODESIC_DISTANCE_SPARSE_TEXT_METADATA)
    params = execution.params(params)
    cargs = surface_geodesic_distance_sparse_text_cargs(params, execution)
    ret = surface_geodesic_distance_sparse_text_outputs(params, execution)
    execution.run(cargs)
    return ret


def surface_geodesic_distance_sparse_text(
    surface: InputPathType,
    limit: float,
    text_out: str,
    area_metric: InputPathType | None = None,
    naive: bool = False,
    runner: Runner | None = None,
) -> SurfaceGeodesicDistanceSparseTextOutputs:
    """
    OUTPUT GEODESIC DISTANCES AS TEXT.
    
    Similar to -geodesic-distance-all-to-all, but outputs in a text format that
    only lists the in-range vertices. Each line in the output text file is a
    list of pairs, like '<vertex>,<distance>,<vertex>,<distance>,...' in csv
    format.
    
    The -corrected-areas option should be used when the input is a group average
    surface - group average surfaces have significantly less surface area than
    individual surfaces do, and therefore distances measured on them would be
    smaller than measuring them on individual surfaces. In this case, the input
    to this option should be a group average of the output of
    -surface-vertex-areas for each subject.
    
    If -naive is not specified, the algorithm uses not just immediate neighbors,
    but also neighbors derived from crawling across pairs of triangles that
    share an edge.
    
    Args:
        surface: the surface to compute on.
        limit: the geodesic distance limit in mm.
        text_out: output - the output text file.
        area_metric: vertex areas to use to correct the distances on a\
            group-average surface\
            \
            the corrected vertex areas, as a metric.
        naive: use only neighbors, don't crawl triangles (not recommended).
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `SurfaceGeodesicDistanceSparseTextOutputs`).
    """
    params = surface_geodesic_distance_sparse_text_params(
        surface=surface,
        limit=limit,
        text_out=text_out,
        area_metric=area_metric,
        naive=naive,
    )
    return surface_geodesic_distance_sparse_text_execute(params, runner)


__all__ = [
    "SURFACE_GEODESIC_DISTANCE_SPARSE_TEXT_METADATA",
    "SurfaceGeodesicDistanceSparseTextOutputs",
    "SurfaceGeodesicDistanceSparseTextParamsDict",
    "SurfaceGeodesicDistanceSparseTextParamsDictTagged",
    "surface_geodesic_distance_sparse_text",
    "surface_geodesic_distance_sparse_text_execute",
    "surface_geodesic_distance_sparse_text_params",
]
