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

import typing
import pathlib
from styxdefs import *

METRIC_STATS_METADATA = Metadata(
    id="0e12ce38a883534ee44f0de43d440a9587a5a4b6.workbench",
    name="metric-stats",
    package="workbench",
    container_image_tag="nx10x/workbench:2.1.0",
)


_MetricStatsRoiParamsDictNoTag = typing.TypedDict('_MetricStatsRoiParamsDictNoTag', {
    "roi-metric": InputPathType,
    "match-maps": bool,
})
MetricStatsRoiParamsDictTagged = typing.TypedDict('MetricStatsRoiParamsDictTagged', {
    "@type": typing.Literal["roi"],
    "roi-metric": InputPathType,
    "match-maps": bool,
})
MetricStatsRoiParamsDict = _MetricStatsRoiParamsDictNoTag | MetricStatsRoiParamsDictTagged


_MetricStatsParamsDictNoTag = typing.TypedDict('_MetricStatsParamsDictNoTag', {
    "metric-in": InputPathType,
    "roi": typing.NotRequired[MetricStatsRoiParamsDict | None],
    "column": typing.NotRequired[str | None],
    "percent": typing.NotRequired[float | None],
    "operation": typing.NotRequired[str | None],
    "show-map-name": bool,
})
MetricStatsParamsDictTagged = typing.TypedDict('MetricStatsParamsDictTagged', {
    "@type": typing.Literal["workbench/metric-stats"],
    "metric-in": InputPathType,
    "roi": typing.NotRequired[MetricStatsRoiParamsDict | None],
    "column": typing.NotRequired[str | None],
    "percent": typing.NotRequired[float | None],
    "operation": typing.NotRequired[str | None],
    "show-map-name": bool,
})
MetricStatsParamsDict = _MetricStatsParamsDictNoTag | MetricStatsParamsDictTagged


def metric_stats_roi(
    roi_metric: InputPathType,
    match_maps: bool = False,
) -> MetricStatsRoiParamsDictTagged:
    """
    Build parameters.
    
    Args:
        roi_metric: the roi, as a metric file.
        match_maps: each column of input uses the corresponding column from the\
            roi file.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "roi",
        "roi-metric": roi_metric,
        "match-maps": match_maps,
    }
    return params


def metric_stats_roi_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `MetricStatsRoiParamsDict` 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("roi-metric", None) is None:
        raise StyxValidationError("`roi-metric` must not be None")
    if not isinstance(params["roi-metric"], (pathlib.Path, str)):
        raise StyxValidationError(f'`roi-metric` has the wrong type: Received `{type(params.get("roi-metric", None))}` expected `InputPathType`')
    if params.get("match-maps", False) is None:
        raise StyxValidationError("`match-maps` must not be None")
    if not isinstance(params["match-maps"], bool):
        raise StyxValidationError(f'`match-maps` has the wrong type: Received `{type(params.get("match-maps", False))}` expected `bool`')


def metric_stats_roi_cargs(
    params: MetricStatsRoiParamsDict,
    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([
        "-roi",
        execution.input_file(params.get("roi-metric", None))
    ])
    if params.get("match-maps", False):
        cargs.append("-match-maps")
    return cargs


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


def metric_stats_params(
    metric_in: InputPathType,
    roi: MetricStatsRoiParamsDict | None = None,
    column: str | None = None,
    percent: float | None = None,
    operation: str | None = None,
    show_map_name: bool = False,
) -> MetricStatsParamsDictTagged:
    """
    Build parameters.
    
    Args:
        metric_in: the input metric.
        roi: only consider data inside an roi.
        column: only display output for one column\
            \
            the column number or name.
        percent: give the value at a percentile\
            \
            the percentile to find, must be between 0 and 100.
        operation: use a reduction operation\
            \
            the reduction operation.
        show_map_name: print map index and name before each output.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "workbench/metric-stats",
        "metric-in": metric_in,
        "show-map-name": show_map_name,
    }
    if roi is not None:
        params["roi"] = roi
    if column is not None:
        params["column"] = column
    if percent is not None:
        params["percent"] = percent
    if operation is not None:
        params["operation"] = operation
    return params


def metric_stats_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `MetricStatsParamsDict` 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("metric-in", None) is None:
        raise StyxValidationError("`metric-in` must not be None")
    if not isinstance(params["metric-in"], (pathlib.Path, str)):
        raise StyxValidationError(f'`metric-in` has the wrong type: Received `{type(params.get("metric-in", None))}` expected `InputPathType`')
    if params.get("roi", None) is not None:
        metric_stats_roi_validate(params["roi"])
    if params.get("column", None) is not None:
        if not isinstance(params["column"], str):
            raise StyxValidationError(f'`column` has the wrong type: Received `{type(params.get("column", None))}` expected `str | None`')
    if params.get("percent", None) is not None:
        if not isinstance(params["percent"], (float, int)):
            raise StyxValidationError(f'`percent` has the wrong type: Received `{type(params.get("percent", None))}` expected `float | None`')
    if params.get("operation", None) is not None:
        if not isinstance(params["operation"], str):
            raise StyxValidationError(f'`operation` has the wrong type: Received `{type(params.get("operation", None))}` expected `str | None`')
    if params.get("show-map-name", False) is None:
        raise StyxValidationError("`show-map-name` must not be None")
    if not isinstance(params["show-map-name"], bool):
        raise StyxValidationError(f'`show-map-name` has the wrong type: Received `{type(params.get("show-map-name", False))}` expected `bool`')


def metric_stats_cargs(
    params: MetricStatsParamsDict,
    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",
        "-metric-stats"
    ])
    cargs.append(execution.input_file(params.get("metric-in", None)))
    if params.get("roi", None) is not None:
        cargs.extend(metric_stats_roi_cargs(params.get("roi", None), execution))
    if params.get("column", None) is not None:
        cargs.extend([
            "-column",
            params.get("column", None)
        ])
    if params.get("percent", None) is not None:
        cargs.extend([
            "-percentile",
            str(params.get("percent", None))
        ])
    if params.get("operation", None) is not None:
        cargs.extend([
            "-reduce",
            params.get("operation", None)
        ])
    if params.get("show-map-name", False):
        cargs.append("-show-map-name")
    return cargs


def metric_stats_outputs(
    params: MetricStatsParamsDict,
    execution: Execution,
) -> MetricStatsOutputs:
    """
    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 = MetricStatsOutputs(
        root=execution.output_file("."),
    )
    return ret


def metric_stats_execute(
    params: MetricStatsParamsDict,
    runner: Runner | None = None,
) -> MetricStatsOutputs:
    """
    SPATIAL STATISTICS ON A METRIC FILE.
    
    For each column of the input, a line of text is printed, resulting from the
    specified reduction or percentile operation. Use -column to only give output
    for a single column. If the -roi option is used without -match-maps, then
    each line will contain as many numbers as there are maps in the ROI file,
    separated by tab characters. Exactly one of -reduce or -percentile must be
    specified.
    
    The argument to the -reduce option must be one of the following:
    
    MAX: the maximum value
    MIN: the minimum value
    INDEXMAX: the 1-based index of the maximum value
    INDEXMIN: the 1-based index of the minimum value
    SUM: add all values
    PRODUCT: multiply all values
    MEAN: the mean of the data
    STDEV: the standard deviation (N denominator)
    SAMPSTDEV: the sample standard deviation (N-1 denominator)
    VARIANCE: the variance of the data
    TSNR: mean divided by sample standard deviation (N-1 denominator)
    COV: sample standard deviation (N-1 denominator) divided by mean
    L2NORM: square root of sum of squares
    MEDIAN: the median of the data
    MODE: the mode of the data
    COUNT_NONZERO: the number of nonzero elements in the data
    .
    
    Args:
        params: The parameters.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `MetricStatsOutputs`).
    """
    metric_stats_validate(params)
    runner = runner or get_global_runner()
    execution = runner.start_execution(METRIC_STATS_METADATA)
    params = execution.params(params)
    cargs = metric_stats_cargs(params, execution)
    ret = metric_stats_outputs(params, execution)
    execution.run(cargs)
    return ret


def metric_stats(
    metric_in: InputPathType,
    roi: MetricStatsRoiParamsDict | None = None,
    column: str | None = None,
    percent: float | None = None,
    operation: str | None = None,
    show_map_name: bool = False,
    runner: Runner | None = None,
) -> MetricStatsOutputs:
    """
    SPATIAL STATISTICS ON A METRIC FILE.
    
    For each column of the input, a line of text is printed, resulting from the
    specified reduction or percentile operation. Use -column to only give output
    for a single column. If the -roi option is used without -match-maps, then
    each line will contain as many numbers as there are maps in the ROI file,
    separated by tab characters. Exactly one of -reduce or -percentile must be
    specified.
    
    The argument to the -reduce option must be one of the following:
    
    MAX: the maximum value
    MIN: the minimum value
    INDEXMAX: the 1-based index of the maximum value
    INDEXMIN: the 1-based index of the minimum value
    SUM: add all values
    PRODUCT: multiply all values
    MEAN: the mean of the data
    STDEV: the standard deviation (N denominator)
    SAMPSTDEV: the sample standard deviation (N-1 denominator)
    VARIANCE: the variance of the data
    TSNR: mean divided by sample standard deviation (N-1 denominator)
    COV: sample standard deviation (N-1 denominator) divided by mean
    L2NORM: square root of sum of squares
    MEDIAN: the median of the data
    MODE: the mode of the data
    COUNT_NONZERO: the number of nonzero elements in the data
    .
    
    Args:
        metric_in: the input metric.
        roi: only consider data inside an roi.
        column: only display output for one column\
            \
            the column number or name.
        percent: give the value at a percentile\
            \
            the percentile to find, must be between 0 and 100.
        operation: use a reduction operation\
            \
            the reduction operation.
        show_map_name: print map index and name before each output.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `MetricStatsOutputs`).
    """
    params = metric_stats_params(
        metric_in=metric_in,
        roi=roi,
        column=column,
        percent=percent,
        operation=operation,
        show_map_name=show_map_name,
    )
    return metric_stats_execute(params, runner)


__all__ = [
    "METRIC_STATS_METADATA",
    "MetricStatsOutputs",
    "MetricStatsParamsDict",
    "MetricStatsParamsDictTagged",
    "MetricStatsRoiParamsDict",
    "MetricStatsRoiParamsDictTagged",
    "metric_stats",
    "metric_stats_execute",
    "metric_stats_params",
    "metric_stats_roi",
]
