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

import typing
import pathlib
from styxdefs import *

SURFACE_GEODESIC_ROIS_METADATA = Metadata(
    id="ec6694baabf8b66b3eafbe5048653b2c790dbe3c.workbench",
    name="surface-geodesic-rois",
    package="workbench",
    container_image_tag="nx10x/workbench:2.1.0",
)


_SurfaceGeodesicRoisParamsDictNoTag = typing.TypedDict('_SurfaceGeodesicRoisParamsDictNoTag', {
    "surface": InputPathType,
    "limit": float,
    "vertex-list-file": str,
    "metric-out": str,
    "area-metric": typing.NotRequired[InputPathType | None],
    "name-list-file": typing.NotRequired[str | None],
    "method": typing.NotRequired[str | None],
    "sigma": typing.NotRequired[float | None],
})
SurfaceGeodesicRoisParamsDictTagged = typing.TypedDict('SurfaceGeodesicRoisParamsDictTagged', {
    "@type": typing.Literal["workbench/surface-geodesic-rois"],
    "surface": InputPathType,
    "limit": float,
    "vertex-list-file": str,
    "metric-out": str,
    "area-metric": typing.NotRequired[InputPathType | None],
    "name-list-file": typing.NotRequired[str | None],
    "method": typing.NotRequired[str | None],
    "sigma": typing.NotRequired[float | None],
})
SurfaceGeodesicRoisParamsDict = _SurfaceGeodesicRoisParamsDictNoTag | SurfaceGeodesicRoisParamsDictTagged


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


def surface_geodesic_rois_params(
    surface: InputPathType,
    limit: float,
    vertex_list_file: str,
    metric_out: str,
    area_metric: InputPathType | None = None,
    name_list_file: str | None = None,
    method: str | None = None,
    sigma: float | None = None,
) -> SurfaceGeodesicRoisParamsDictTagged:
    """
    Build parameters.
    
    Args:
        surface: the surface to draw on.
        limit: geodesic distance limit from vertex, in mm.
        vertex_list_file: a text file containing the vertices to draw ROIs\
            around.
        metric_out: the output metric.
        area_metric: vertex areas to use instead of computing them from the\
            surface\
            \
            the corrected vertex areas, as a metric.
        name_list_file: name the columns from text file\
            \
            a text file containing column names, one per line.
        method: how to handle overlapping ROIs, default ALLOW\
            \
            the method of resolving overlaps.
        sigma: generate a gaussian kernel instead of a flat ROI\
            \
            the sigma for the gaussian kernel, in mm.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "workbench/surface-geodesic-rois",
        "surface": surface,
        "limit": limit,
        "vertex-list-file": vertex_list_file,
        "metric-out": metric_out,
    }
    if area_metric is not None:
        params["area-metric"] = area_metric
    if name_list_file is not None:
        params["name-list-file"] = name_list_file
    if method is not None:
        params["method"] = method
    if sigma is not None:
        params["sigma"] = sigma
    return params


def surface_geodesic_rois_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `SurfaceGeodesicRoisParamsDict` 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("vertex-list-file", None) is None:
        raise StyxValidationError("`vertex-list-file` must not be None")
    if not isinstance(params["vertex-list-file"], str):
        raise StyxValidationError(f'`vertex-list-file` has the wrong type: Received `{type(params.get("vertex-list-file", None))}` expected `str`')
    if params.get("metric-out", None) is None:
        raise StyxValidationError("`metric-out` must not be None")
    if not isinstance(params["metric-out"], str):
        raise StyxValidationError(f'`metric-out` has the wrong type: Received `{type(params.get("metric-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("name-list-file", None) is not None:
        if not isinstance(params["name-list-file"], str):
            raise StyxValidationError(f'`name-list-file` has the wrong type: Received `{type(params.get("name-list-file", None))}` expected `str | None`')
    if params.get("method", None) is not None:
        if not isinstance(params["method"], str):
            raise StyxValidationError(f'`method` has the wrong type: Received `{type(params.get("method", None))}` expected `str | None`')
    if params.get("sigma", None) is not None:
        if not isinstance(params["sigma"], (float, int)):
            raise StyxValidationError(f'`sigma` has the wrong type: Received `{type(params.get("sigma", None))}` expected `float | None`')


def surface_geodesic_rois_cargs(
    params: SurfaceGeodesicRoisParamsDict,
    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-rois"
    ])
    cargs.append(execution.input_file(params.get("surface", None)))
    cargs.append(str(params.get("limit", None)))
    cargs.append(params.get("vertex-list-file", None))
    cargs.append(params.get("metric-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("name-list-file", None) is not None:
        cargs.extend([
            "-names",
            params.get("name-list-file", None)
        ])
    if params.get("method", None) is not None:
        cargs.extend([
            "-overlap-logic",
            params.get("method", None)
        ])
    if params.get("sigma", None) is not None:
        cargs.extend([
            "-gaussian",
            str(params.get("sigma", None))
        ])
    return cargs


def surface_geodesic_rois_outputs(
    params: SurfaceGeodesicRoisParamsDict,
    execution: Execution,
) -> SurfaceGeodesicRoisOutputs:
    """
    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 = SurfaceGeodesicRoisOutputs(
        root=execution.output_file("."),
        metric_out=execution.output_file(params.get("metric-out", None)),
    )
    return ret


def surface_geodesic_rois_execute(
    params: SurfaceGeodesicRoisParamsDict,
    runner: Runner | None = None,
) -> SurfaceGeodesicRoisOutputs:
    """
    DRAW GEODESIC LIMITED ROIS AT VERTICES.
    
    For each vertex in the list file, a column in the output metric is created,
    and an ROI around that vertex is drawn in that column. Each metric column
    will have zeros outside the geodesic distance spacified by <limit>, and by
    default will have a value of 1.0 inside it. If the -gaussian option is
    specified, the values inside the ROI will instead form a gaussian with the
    specified value of sigma, normalized so that the sum of the nonzero values
    in the metric column is 1.0. The <method> argument to -overlap-logic must be
    one of ALLOW, CLOSEST, or EXCLUDE. ALLOW is the default, and means that ROIs
    are treated independently and may overlap. CLOSEST means that ROIs may not
    overlap, and that no ROI contains vertices that are closer to a different
    seed vertex. EXCLUDE means that ROIs may not overlap, and that any vertex
    within range of more than one ROI does not belong to any ROI.
    
    Args:
        params: The parameters.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `SurfaceGeodesicRoisOutputs`).
    """
    surface_geodesic_rois_validate(params)
    runner = runner or get_global_runner()
    execution = runner.start_execution(SURFACE_GEODESIC_ROIS_METADATA)
    params = execution.params(params)
    cargs = surface_geodesic_rois_cargs(params, execution)
    ret = surface_geodesic_rois_outputs(params, execution)
    execution.run(cargs)
    return ret


def surface_geodesic_rois(
    surface: InputPathType,
    limit: float,
    vertex_list_file: str,
    metric_out: str,
    area_metric: InputPathType | None = None,
    name_list_file: str | None = None,
    method: str | None = None,
    sigma: float | None = None,
    runner: Runner | None = None,
) -> SurfaceGeodesicRoisOutputs:
    """
    DRAW GEODESIC LIMITED ROIS AT VERTICES.
    
    For each vertex in the list file, a column in the output metric is created,
    and an ROI around that vertex is drawn in that column. Each metric column
    will have zeros outside the geodesic distance spacified by <limit>, and by
    default will have a value of 1.0 inside it. If the -gaussian option is
    specified, the values inside the ROI will instead form a gaussian with the
    specified value of sigma, normalized so that the sum of the nonzero values
    in the metric column is 1.0. The <method> argument to -overlap-logic must be
    one of ALLOW, CLOSEST, or EXCLUDE. ALLOW is the default, and means that ROIs
    are treated independently and may overlap. CLOSEST means that ROIs may not
    overlap, and that no ROI contains vertices that are closer to a different
    seed vertex. EXCLUDE means that ROIs may not overlap, and that any vertex
    within range of more than one ROI does not belong to any ROI.
    
    Args:
        surface: the surface to draw on.
        limit: geodesic distance limit from vertex, in mm.
        vertex_list_file: a text file containing the vertices to draw ROIs\
            around.
        metric_out: the output metric.
        area_metric: vertex areas to use instead of computing them from the\
            surface\
            \
            the corrected vertex areas, as a metric.
        name_list_file: name the columns from text file\
            \
            a text file containing column names, one per line.
        method: how to handle overlapping ROIs, default ALLOW\
            \
            the method of resolving overlaps.
        sigma: generate a gaussian kernel instead of a flat ROI\
            \
            the sigma for the gaussian kernel, in mm.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `SurfaceGeodesicRoisOutputs`).
    """
    params = surface_geodesic_rois_params(
        surface=surface,
        limit=limit,
        vertex_list_file=vertex_list_file,
        metric_out=metric_out,
        area_metric=area_metric,
        name_list_file=name_list_file,
        method=method,
        sigma=sigma,
    )
    return surface_geodesic_rois_execute(params, runner)


__all__ = [
    "SURFACE_GEODESIC_ROIS_METADATA",
    "SurfaceGeodesicRoisOutputs",
    "SurfaceGeodesicRoisParamsDict",
    "SurfaceGeodesicRoisParamsDictTagged",
    "surface_geodesic_rois",
    "surface_geodesic_rois_execute",
    "surface_geodesic_rois_params",
]
