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

import typing
import pathlib
from styxdefs import *

VOLUME_WEIGHTED_STATS_METADATA = Metadata(
    id="4e95434c5f2fd06962a53dcd7657c6c2bbb93a7b.workbench",
    name="volume-weighted-stats",
    package="workbench",
    container_image_tag="nx10x/workbench:2.1.0",
)


_VolumeWeightedStatsWeightVolumeParamsDictNoTag = typing.TypedDict('_VolumeWeightedStatsWeightVolumeParamsDictNoTag', {
    "weight-volume": InputPathType,
    "match-maps": bool,
})
VolumeWeightedStatsWeightVolumeParamsDictTagged = typing.TypedDict('VolumeWeightedStatsWeightVolumeParamsDictTagged', {
    "@type": typing.Literal["weight-volume"],
    "weight-volume": InputPathType,
    "match-maps": bool,
})
VolumeWeightedStatsWeightVolumeParamsDict = _VolumeWeightedStatsWeightVolumeParamsDictNoTag | VolumeWeightedStatsWeightVolumeParamsDictTagged


_VolumeWeightedStatsRoiParamsDictNoTag = typing.TypedDict('_VolumeWeightedStatsRoiParamsDictNoTag', {
    "roi-volume": InputPathType,
    "match-maps": bool,
})
VolumeWeightedStatsRoiParamsDictTagged = typing.TypedDict('VolumeWeightedStatsRoiParamsDictTagged', {
    "@type": typing.Literal["roi"],
    "roi-volume": InputPathType,
    "match-maps": bool,
})
VolumeWeightedStatsRoiParamsDict = _VolumeWeightedStatsRoiParamsDictNoTag | VolumeWeightedStatsRoiParamsDictTagged


_VolumeWeightedStatsParamsDictNoTag = typing.TypedDict('_VolumeWeightedStatsParamsDictNoTag', {
    "volume-in": InputPathType,
    "weight-volume": typing.NotRequired[VolumeWeightedStatsWeightVolumeParamsDict | None],
    "roi": typing.NotRequired[VolumeWeightedStatsRoiParamsDict | None],
    "percent": typing.NotRequired[float | None],
    "sample": typing.NotRequired[bool | None],
    "subvolume": typing.NotRequired[str | None],
    "show-map-name": bool,
    "sum": bool,
    "mean": bool,
})
VolumeWeightedStatsParamsDictTagged = typing.TypedDict('VolumeWeightedStatsParamsDictTagged', {
    "@type": typing.Literal["workbench/volume-weighted-stats"],
    "volume-in": InputPathType,
    "weight-volume": typing.NotRequired[VolumeWeightedStatsWeightVolumeParamsDict | None],
    "roi": typing.NotRequired[VolumeWeightedStatsRoiParamsDict | None],
    "percent": typing.NotRequired[float | None],
    "sample": typing.NotRequired[bool | None],
    "subvolume": typing.NotRequired[str | None],
    "show-map-name": bool,
    "sum": bool,
    "mean": bool,
})
VolumeWeightedStatsParamsDict = _VolumeWeightedStatsParamsDictNoTag | VolumeWeightedStatsParamsDictTagged


def volume_weighted_stats_weight_volume(
    weight_volume: InputPathType,
    match_maps: bool = False,
) -> VolumeWeightedStatsWeightVolumeParamsDictTagged:
    """
    Build parameters.
    
    Args:
        weight_volume: volume file containing the weights.
        match_maps: each subvolume of input uses the corresponding subvolume\
            from the weights file.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "weight-volume",
        "weight-volume": weight_volume,
        "match-maps": match_maps,
    }
    return params


def volume_weighted_stats_weight_volume_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `VolumeWeightedStatsWeightVolumeParamsDict` 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("weight-volume", None) is None:
        raise StyxValidationError("`weight-volume` must not be None")
    if not isinstance(params["weight-volume"], (pathlib.Path, str)):
        raise StyxValidationError(f'`weight-volume` has the wrong type: Received `{type(params.get("weight-volume", 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 volume_weighted_stats_weight_volume_cargs(
    params: VolumeWeightedStatsWeightVolumeParamsDict,
    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([
        "-weight-volume",
        execution.input_file(params.get("weight-volume", None))
    ])
    if params.get("match-maps", False):
        cargs.append("-match-maps")
    return cargs


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


def volume_weighted_stats_roi_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `VolumeWeightedStatsRoiParamsDict` 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-volume", None) is None:
        raise StyxValidationError("`roi-volume` must not be None")
    if not isinstance(params["roi-volume"], (pathlib.Path, str)):
        raise StyxValidationError(f'`roi-volume` has the wrong type: Received `{type(params.get("roi-volume", 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 volume_weighted_stats_roi_cargs(
    params: VolumeWeightedStatsRoiParamsDict,
    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-volume", None))
    ])
    if params.get("match-maps", False):
        cargs.append("-match-maps")
    return cargs


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


def volume_weighted_stats_params(
    volume_in: InputPathType,
    weight_volume: VolumeWeightedStatsWeightVolumeParamsDict | None = None,
    roi: VolumeWeightedStatsRoiParamsDict | None = None,
    percent: float | None = None,
    sample: bool | None = None,
    subvolume: str | None = None,
    show_map_name: bool = False,
    sum_: bool = False,
    mean: bool = False,
) -> VolumeWeightedStatsParamsDictTagged:
    """
    Build parameters.
    
    Args:
        volume_in: the input volume.
        weight_volume: use weights from a volume file.
        roi: only consider data inside an roi.
        percent: compute weighted percentile\
            \
            the percentile to find, must be between 0 and 100.
        sample: compute weighted standard deviation\
            \
            estimate population stdev from the sample.
        subvolume: only display output for one subvolume\
            \
            the subvolume number or name.
        show_map_name: print map index and name before each output.
        sum_: compute weighted sum.
        mean: compute weighted mean.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "workbench/volume-weighted-stats",
        "volume-in": volume_in,
        "show-map-name": show_map_name,
        "sum": sum_,
        "mean": mean,
    }
    if weight_volume is not None:
        params["weight-volume"] = weight_volume
    if roi is not None:
        params["roi"] = roi
    if percent is not None:
        params["percent"] = percent
    if sample is not None:
        params["sample"] = sample
    if subvolume is not None:
        params["subvolume"] = subvolume
    return params


def volume_weighted_stats_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `VolumeWeightedStatsParamsDict` 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("volume-in", None) is None:
        raise StyxValidationError("`volume-in` must not be None")
    if not isinstance(params["volume-in"], (pathlib.Path, str)):
        raise StyxValidationError(f'`volume-in` has the wrong type: Received `{type(params.get("volume-in", None))}` expected `InputPathType`')
    if params.get("weight-volume", None) is not None:
        volume_weighted_stats_weight_volume_validate(params["weight-volume"])
    if params.get("roi", None) is not None:
        volume_weighted_stats_roi_validate(params["roi"])
    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("sample", None) is not None:
        if not isinstance(params["sample"], bool):
            raise StyxValidationError(f'`sample` has the wrong type: Received `{type(params.get("sample", None))}` expected `bool | None`')
    if params.get("subvolume", None) is not None:
        if not isinstance(params["subvolume"], str):
            raise StyxValidationError(f'`subvolume` has the wrong type: Received `{type(params.get("subvolume", 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`')
    if params.get("sum", False) is None:
        raise StyxValidationError("`sum` must not be None")
    if not isinstance(params["sum"], bool):
        raise StyxValidationError(f'`sum` has the wrong type: Received `{type(params.get("sum", False))}` expected `bool`')
    if params.get("mean", False) is None:
        raise StyxValidationError("`mean` must not be None")
    if not isinstance(params["mean"], bool):
        raise StyxValidationError(f'`mean` has the wrong type: Received `{type(params.get("mean", False))}` expected `bool`')


def volume_weighted_stats_cargs(
    params: VolumeWeightedStatsParamsDict,
    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",
        "-volume-weighted-stats"
    ])
    cargs.append(execution.input_file(params.get("volume-in", None)))
    if params.get("weight-volume", None) is not None or params.get("roi", None) is not None:
        cargs.extend([
            *(volume_weighted_stats_weight_volume_cargs(params.get("weight-volume", None), execution) if (params.get("weight-volume", None) is not None) else []),
            *(volume_weighted_stats_roi_cargs(params.get("roi", None), execution) if (params.get("roi", None) is not None) else [])
        ])
    if params.get("percent", None) is not None:
        cargs.extend([
            "-percentile",
            str(params.get("percent", None))
        ])
    if params.get("sample", None) is not None:
        cargs.extend([
            "-stdev",
            "-sample"
        ])
    if params.get("subvolume", None) is not None:
        cargs.extend([
            "-subvolume",
            params.get("subvolume", None)
        ])
    if params.get("show-map-name", False):
        cargs.append("-show-map-name")
    if params.get("sum", False):
        cargs.append("-sum")
    if params.get("mean", False):
        cargs.append("-mean")
    return cargs


def volume_weighted_stats_outputs(
    params: VolumeWeightedStatsParamsDict,
    execution: Execution,
) -> VolumeWeightedStatsOutputs:
    """
    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 = VolumeWeightedStatsOutputs(
        root=execution.output_file("."),
    )
    return ret


def volume_weighted_stats_execute(
    params: VolumeWeightedStatsParamsDict,
    runner: Runner | None = None,
) -> VolumeWeightedStatsOutputs:
    """
    WEIGHTED SPATIAL STATISTICS ON A VOLUME FILE.
    
    For each subvolume of the input, a line of text is printed, resulting from
    the specified operation. If -weight-volume is not specified, each voxel's
    volume is used. Use -subvolume to only give output for a single subvolume.
    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 -mean, -stdev, -percentile or -sum must be
    specified.
    
    Using -sum without -weight-volume is equivalent to integrating with respect
    to volume.
    
    Args:
        params: The parameters.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `VolumeWeightedStatsOutputs`).
    """
    volume_weighted_stats_validate(params)
    runner = runner or get_global_runner()
    execution = runner.start_execution(VOLUME_WEIGHTED_STATS_METADATA)
    params = execution.params(params)
    cargs = volume_weighted_stats_cargs(params, execution)
    ret = volume_weighted_stats_outputs(params, execution)
    execution.run(cargs)
    return ret


def volume_weighted_stats(
    volume_in: InputPathType,
    weight_volume: VolumeWeightedStatsWeightVolumeParamsDict | None = None,
    roi: VolumeWeightedStatsRoiParamsDict | None = None,
    percent: float | None = None,
    sample: bool | None = None,
    subvolume: str | None = None,
    show_map_name: bool = False,
    sum_: bool = False,
    mean: bool = False,
    runner: Runner | None = None,
) -> VolumeWeightedStatsOutputs:
    """
    WEIGHTED SPATIAL STATISTICS ON A VOLUME FILE.
    
    For each subvolume of the input, a line of text is printed, resulting from
    the specified operation. If -weight-volume is not specified, each voxel's
    volume is used. Use -subvolume to only give output for a single subvolume.
    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 -mean, -stdev, -percentile or -sum must be
    specified.
    
    Using -sum without -weight-volume is equivalent to integrating with respect
    to volume.
    
    Args:
        volume_in: the input volume.
        weight_volume: use weights from a volume file.
        roi: only consider data inside an roi.
        percent: compute weighted percentile\
            \
            the percentile to find, must be between 0 and 100.
        sample: compute weighted standard deviation\
            \
            estimate population stdev from the sample.
        subvolume: only display output for one subvolume\
            \
            the subvolume number or name.
        show_map_name: print map index and name before each output.
        sum_: compute weighted sum.
        mean: compute weighted mean.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `VolumeWeightedStatsOutputs`).
    """
    params = volume_weighted_stats_params(
        volume_in=volume_in,
        weight_volume=weight_volume,
        roi=roi,
        percent=percent,
        sample=sample,
        subvolume=subvolume,
        show_map_name=show_map_name,
        sum_=sum_,
        mean=mean,
    )
    return volume_weighted_stats_execute(params, runner)


__all__ = [
    "VOLUME_WEIGHTED_STATS_METADATA",
    "VolumeWeightedStatsOutputs",
    "VolumeWeightedStatsParamsDict",
    "VolumeWeightedStatsParamsDictTagged",
    "VolumeWeightedStatsRoiParamsDict",
    "VolumeWeightedStatsRoiParamsDictTagged",
    "VolumeWeightedStatsWeightVolumeParamsDict",
    "VolumeWeightedStatsWeightVolumeParamsDictTagged",
    "volume_weighted_stats",
    "volume_weighted_stats_execute",
    "volume_weighted_stats_params",
    "volume_weighted_stats_roi",
    "volume_weighted_stats_weight_volume",
]
