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

import typing
import pathlib
from styxdefs import *

VOLUME_ROIS_FROM_EXTREMA_METADATA = Metadata(
    id="9741081a1f9bdfe5deb553d7d2cb39c92eb6cafe.workbench",
    name="volume-rois-from-extrema",
    package="workbench",
    container_image_tag="nx10x/workbench:2.1.0",
)


_VolumeRoisFromExtremaParamsDictNoTag = typing.TypedDict('_VolumeRoisFromExtremaParamsDictNoTag', {
    "volume-in": InputPathType,
    "limit": float,
    "volume-out": str,
    "subvol": typing.NotRequired[str | None],
    "method": typing.NotRequired[str | None],
    "roi-volume": typing.NotRequired[InputPathType | None],
    "sigma": typing.NotRequired[float | None],
})
VolumeRoisFromExtremaParamsDictTagged = typing.TypedDict('VolumeRoisFromExtremaParamsDictTagged', {
    "@type": typing.Literal["workbench/volume-rois-from-extrema"],
    "volume-in": InputPathType,
    "limit": float,
    "volume-out": str,
    "subvol": typing.NotRequired[str | None],
    "method": typing.NotRequired[str | None],
    "roi-volume": typing.NotRequired[InputPathType | None],
    "sigma": typing.NotRequired[float | None],
})
VolumeRoisFromExtremaParamsDict = _VolumeRoisFromExtremaParamsDictNoTag | VolumeRoisFromExtremaParamsDictTagged


class VolumeRoisFromExtremaOutputs(typing.NamedTuple):
    """
    Output object returned when calling `VolumeRoisFromExtremaParamsDict(...)`.
    """
    root: OutputPathType
    """Output root folder. This is the root folder for all outputs."""
    volume_out: OutputPathType
    """the output volume"""


def volume_rois_from_extrema_params(
    volume_in: InputPathType,
    limit: float,
    volume_out: str,
    subvol: str | None = None,
    method: str | None = None,
    roi_volume: InputPathType | None = None,
    sigma: float | None = None,
) -> VolumeRoisFromExtremaParamsDictTagged:
    """
    Build parameters.
    
    Args:
        volume_in: the input volume.
        limit: distance limit from voxel center, in mm.
        volume_out: the output volume.
        subvol: select a single subvolume to take the gradient of\
            \
            the subvolume number or name.
        method: how to handle overlapping ROIs, default ALLOW\
            \
            the method of resolving overlaps.
        roi_volume: select a region of interest to use\
            \
            the region to use.
        sigma: generate a gaussian kernel instead of a flat ROI\
            \
            the sigma for the gaussian kernel, in mm.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "workbench/volume-rois-from-extrema",
        "volume-in": volume_in,
        "limit": limit,
        "volume-out": volume_out,
    }
    if subvol is not None:
        params["subvol"] = subvol
    if method is not None:
        params["method"] = method
    if roi_volume is not None:
        params["roi-volume"] = roi_volume
    if sigma is not None:
        params["sigma"] = sigma
    return params


def volume_rois_from_extrema_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `VolumeRoisFromExtremaParamsDict` 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("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("volume-out", None) is None:
        raise StyxValidationError("`volume-out` must not be None")
    if not isinstance(params["volume-out"], str):
        raise StyxValidationError(f'`volume-out` has the wrong type: Received `{type(params.get("volume-out", None))}` expected `str`')
    if params.get("subvol", None) is not None:
        if not isinstance(params["subvol"], str):
            raise StyxValidationError(f'`subvol` has the wrong type: Received `{type(params.get("subvol", 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("roi-volume", None) is not 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 | 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 volume_rois_from_extrema_cargs(
    params: VolumeRoisFromExtremaParamsDict,
    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-rois-from-extrema"
    ])
    cargs.append(execution.input_file(params.get("volume-in", None)))
    cargs.append(str(params.get("limit", None)))
    cargs.append(params.get("volume-out", None))
    if params.get("subvol", None) is not None:
        cargs.extend([
            "-subvolume",
            params.get("subvol", None)
        ])
    if params.get("method", None) is not None:
        cargs.extend([
            "-overlap-logic",
            params.get("method", None)
        ])
    if params.get("roi-volume", None) is not None:
        cargs.extend([
            "-roi",
            execution.input_file(params.get("roi-volume", None))
        ])
    if params.get("sigma", None) is not None:
        cargs.extend([
            "-gaussian",
            str(params.get("sigma", None))
        ])
    return cargs


def volume_rois_from_extrema_outputs(
    params: VolumeRoisFromExtremaParamsDict,
    execution: Execution,
) -> VolumeRoisFromExtremaOutputs:
    """
    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 = VolumeRoisFromExtremaOutputs(
        root=execution.output_file("."),
        volume_out=execution.output_file(params.get("volume-out", None)),
    )
    return ret


def volume_rois_from_extrema_execute(
    params: VolumeRoisFromExtremaParamsDict,
    runner: Runner | None = None,
) -> VolumeRoisFromExtremaOutputs:
    """
    CREATE VOLUME ROI MAPS FROM EXTREMA MAPS.
    
    For each nonzero value in each map, make a map with an ROI around that
    location. If the -gaussian option is specified, then normalized gaussian
    kernels are output instead of ROIs. 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 `VolumeRoisFromExtremaOutputs`).
    """
    volume_rois_from_extrema_validate(params)
    runner = runner or get_global_runner()
    execution = runner.start_execution(VOLUME_ROIS_FROM_EXTREMA_METADATA)
    params = execution.params(params)
    cargs = volume_rois_from_extrema_cargs(params, execution)
    ret = volume_rois_from_extrema_outputs(params, execution)
    execution.run(cargs)
    return ret


def volume_rois_from_extrema(
    volume_in: InputPathType,
    limit: float,
    volume_out: str,
    subvol: str | None = None,
    method: str | None = None,
    roi_volume: InputPathType | None = None,
    sigma: float | None = None,
    runner: Runner | None = None,
) -> VolumeRoisFromExtremaOutputs:
    """
    CREATE VOLUME ROI MAPS FROM EXTREMA MAPS.
    
    For each nonzero value in each map, make a map with an ROI around that
    location. If the -gaussian option is specified, then normalized gaussian
    kernels are output instead of ROIs. 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:
        volume_in: the input volume.
        limit: distance limit from voxel center, in mm.
        volume_out: the output volume.
        subvol: select a single subvolume to take the gradient of\
            \
            the subvolume number or name.
        method: how to handle overlapping ROIs, default ALLOW\
            \
            the method of resolving overlaps.
        roi_volume: select a region of interest to use\
            \
            the region to use.
        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 `VolumeRoisFromExtremaOutputs`).
    """
    params = volume_rois_from_extrema_params(
        volume_in=volume_in,
        limit=limit,
        volume_out=volume_out,
        subvol=subvol,
        method=method,
        roi_volume=roi_volume,
        sigma=sigma,
    )
    return volume_rois_from_extrema_execute(params, runner)


__all__ = [
    "VOLUME_ROIS_FROM_EXTREMA_METADATA",
    "VolumeRoisFromExtremaOutputs",
    "VolumeRoisFromExtremaParamsDict",
    "VolumeRoisFromExtremaParamsDictTagged",
    "volume_rois_from_extrema",
    "volume_rois_from_extrema_execute",
    "volume_rois_from_extrema_params",
]
