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

import typing
import pathlib
from styxdefs import *

MRTHRESHOLD_METADATA = Metadata(
    id="c55432e6110a1d139e985a99eec2382bb7a91c6e.boutiques",
    name="mrthreshold",
    package="mrtrix",
    container_image_tag="mrtrix3/mrtrix3:3.0.4",
)


_MrthresholdConfigParamsDictNoTag = typing.TypedDict('_MrthresholdConfigParamsDictNoTag', {
    "key": str,
    "value": str,
})
MrthresholdConfigParamsDictTagged = typing.TypedDict('MrthresholdConfigParamsDictTagged', {
    "@type": typing.Literal["config"],
    "key": str,
    "value": str,
})
MrthresholdConfigParamsDict = _MrthresholdConfigParamsDictNoTag | MrthresholdConfigParamsDictTagged


_MrthresholdParamsDictNoTag = typing.TypedDict('_MrthresholdParamsDictNoTag', {
    "abs": typing.NotRequired[float | None],
    "percentile": typing.NotRequired[float | None],
    "top": typing.NotRequired[int | None],
    "bottom": typing.NotRequired[int | None],
    "allvolumes": bool,
    "ignorezero": bool,
    "mask": typing.NotRequired[InputPathType | None],
    "comparison": typing.NotRequired[str | None],
    "invert": bool,
    "out_masked": bool,
    "nan": bool,
    "info": bool,
    "quiet": bool,
    "debug": bool,
    "force": bool,
    "nthreads": typing.NotRequired[int | None],
    "config": typing.NotRequired[list[MrthresholdConfigParamsDict] | None],
    "help": bool,
    "version": bool,
    "input": InputPathType,
    "output": typing.NotRequired[str | None],
})
MrthresholdParamsDictTagged = typing.TypedDict('MrthresholdParamsDictTagged', {
    "@type": typing.Literal["mrtrix/mrthreshold"],
    "abs": typing.NotRequired[float | None],
    "percentile": typing.NotRequired[float | None],
    "top": typing.NotRequired[int | None],
    "bottom": typing.NotRequired[int | None],
    "allvolumes": bool,
    "ignorezero": bool,
    "mask": typing.NotRequired[InputPathType | None],
    "comparison": typing.NotRequired[str | None],
    "invert": bool,
    "out_masked": bool,
    "nan": bool,
    "info": bool,
    "quiet": bool,
    "debug": bool,
    "force": bool,
    "nthreads": typing.NotRequired[int | None],
    "config": typing.NotRequired[list[MrthresholdConfigParamsDict] | None],
    "help": bool,
    "version": bool,
    "input": InputPathType,
    "output": typing.NotRequired[str | None],
})
MrthresholdParamsDict = _MrthresholdParamsDictNoTag | MrthresholdParamsDictTagged


def mrthreshold_config(
    key: str,
    value: str,
) -> MrthresholdConfigParamsDictTagged:
    """
    Build parameters.
    
    Args:
        key: temporarily set the value of an MRtrix config file entry.
        value: temporarily set the value of an MRtrix config file entry.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "config",
        "key": key,
        "value": value,
    }
    return params


def mrthreshold_config_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `MrthresholdConfigParamsDict` 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("key", None) is None:
        raise StyxValidationError("`key` must not be None")
    if not isinstance(params["key"], str):
        raise StyxValidationError(f'`key` has the wrong type: Received `{type(params.get("key", None))}` expected `str`')
    if params.get("value", None) is None:
        raise StyxValidationError("`value` must not be None")
    if not isinstance(params["value"], str):
        raise StyxValidationError(f'`value` has the wrong type: Received `{type(params.get("value", None))}` expected `str`')


def mrthreshold_config_cargs(
    params: MrthresholdConfigParamsDict,
    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.append("-config")
    cargs.append(params.get("key", None))
    cargs.append(params.get("value", None))
    return cargs


class MrthresholdOutputs(typing.NamedTuple):
    """
    Output object returned when calling `MrthresholdParamsDict(...)`.
    """
    root: OutputPathType
    """Output root folder. This is the root folder for all outputs."""
    output: OutputPathType | None
    """the (optional) output binary image mask"""


def mrthreshold_params(
    input_: InputPathType,
    abs_: float | None = None,
    percentile: float | None = None,
    top: int | None = None,
    bottom: int | None = None,
    allvolumes: bool = False,
    ignorezero: bool = False,
    mask: InputPathType | None = None,
    comparison: str | None = None,
    invert: bool = False,
    out_masked: bool = False,
    nan: bool = False,
    info: bool = False,
    quiet: bool = False,
    debug: bool = False,
    force: bool = False,
    nthreads: int | None = None,
    config: list[MrthresholdConfigParamsDict] | None = None,
    help_: bool = False,
    version: bool = False,
    output: str | None = None,
) -> MrthresholdParamsDictTagged:
    """
    Build parameters.
    
    Args:
        input_: the input image to be thresholded.
        abs_: specify threshold value as absolute intensity.
        percentile: determine threshold based on some percentile of the image\
            intensity distribution.
        top: determine threshold that will result in selection of some number\
            of top-valued voxels.
        bottom: determine & apply threshold resulting in selection of some\
            number of bottom-valued voxels (note: implies threshold application\
            operator of "le" unless otherwise specified).
        allvolumes: compute a single threshold for all image volumes, rather\
            than an individual threshold per volume.
        ignorezero: ignore zero-valued input values during threshold\
            determination.
        mask: compute the threshold based only on values within an input mask\
            image.
        comparison: comparison operator to use when applying the threshold;\
            options are: lt,le,ge,gt (default = "le" for -bottom; "ge" otherwise).
        invert: invert the output binary mask (equivalent to flipping the\
            operator; provided for backwards compatibility).
        out_masked: mask the output image based on the provided input mask\
            image.
        nan: set voxels that fail the threshold to NaN rather than zero (output\
            image will be floating-point rather than binary).
        info: display information messages.
        quiet: do not display information messages or progress status;\
            alternatively, this can be achieved by setting the MRTRIX_QUIET\
            environment variable to a non-empty string.
        debug: display debugging messages.
        force: force overwrite of output files (caution: using the same file as\
            input and output might cause unexpected behaviour).
        nthreads: use this number of threads in multi-threaded applications\
            (set to 0 to disable multi-threading).
        config: temporarily set the value of an MRtrix config file entry.
        help_: display this information page and exit.
        version: display version information and exit.
        output: the (optional) output binary image mask.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "mrtrix/mrthreshold",
        "allvolumes": allvolumes,
        "ignorezero": ignorezero,
        "invert": invert,
        "out_masked": out_masked,
        "nan": nan,
        "info": info,
        "quiet": quiet,
        "debug": debug,
        "force": force,
        "help": help_,
        "version": version,
        "input": input_,
    }
    if abs_ is not None:
        params["abs"] = abs_
    if percentile is not None:
        params["percentile"] = percentile
    if top is not None:
        params["top"] = top
    if bottom is not None:
        params["bottom"] = bottom
    if mask is not None:
        params["mask"] = mask
    if comparison is not None:
        params["comparison"] = comparison
    if nthreads is not None:
        params["nthreads"] = nthreads
    if config is not None:
        params["config"] = config
    if output is not None:
        params["output"] = output
    return params


def mrthreshold_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `MrthresholdParamsDict` 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("abs", None) is not None:
        if not isinstance(params["abs"], (float, int)):
            raise StyxValidationError(f'`abs` has the wrong type: Received `{type(params.get("abs", None))}` expected `float | None`')
    if params.get("percentile", None) is not None:
        if not isinstance(params["percentile"], (float, int)):
            raise StyxValidationError(f'`percentile` has the wrong type: Received `{type(params.get("percentile", None))}` expected `float | None`')
    if params.get("top", None) is not None:
        if not isinstance(params["top"], int):
            raise StyxValidationError(f'`top` has the wrong type: Received `{type(params.get("top", None))}` expected `int | None`')
    if params.get("bottom", None) is not None:
        if not isinstance(params["bottom"], int):
            raise StyxValidationError(f'`bottom` has the wrong type: Received `{type(params.get("bottom", None))}` expected `int | None`')
    if params.get("allvolumes", False) is None:
        raise StyxValidationError("`allvolumes` must not be None")
    if not isinstance(params["allvolumes"], bool):
        raise StyxValidationError(f'`allvolumes` has the wrong type: Received `{type(params.get("allvolumes", False))}` expected `bool`')
    if params.get("ignorezero", False) is None:
        raise StyxValidationError("`ignorezero` must not be None")
    if not isinstance(params["ignorezero"], bool):
        raise StyxValidationError(f'`ignorezero` has the wrong type: Received `{type(params.get("ignorezero", False))}` expected `bool`')
    if params.get("mask", None) is not None:
        if not isinstance(params["mask"], (pathlib.Path, str)):
            raise StyxValidationError(f'`mask` has the wrong type: Received `{type(params.get("mask", None))}` expected `InputPathType | None`')
    if params.get("comparison", None) is not None:
        if not isinstance(params["comparison"], str):
            raise StyxValidationError(f'`comparison` has the wrong type: Received `{type(params.get("comparison", None))}` expected `str | None`')
    if params.get("invert", False) is None:
        raise StyxValidationError("`invert` must not be None")
    if not isinstance(params["invert"], bool):
        raise StyxValidationError(f'`invert` has the wrong type: Received `{type(params.get("invert", False))}` expected `bool`')
    if params.get("out_masked", False) is None:
        raise StyxValidationError("`out_masked` must not be None")
    if not isinstance(params["out_masked"], bool):
        raise StyxValidationError(f'`out_masked` has the wrong type: Received `{type(params.get("out_masked", False))}` expected `bool`')
    if params.get("nan", False) is None:
        raise StyxValidationError("`nan` must not be None")
    if not isinstance(params["nan"], bool):
        raise StyxValidationError(f'`nan` has the wrong type: Received `{type(params.get("nan", False))}` expected `bool`')
    if params.get("info", False) is None:
        raise StyxValidationError("`info` must not be None")
    if not isinstance(params["info"], bool):
        raise StyxValidationError(f'`info` has the wrong type: Received `{type(params.get("info", False))}` expected `bool`')
    if params.get("quiet", False) is None:
        raise StyxValidationError("`quiet` must not be None")
    if not isinstance(params["quiet"], bool):
        raise StyxValidationError(f'`quiet` has the wrong type: Received `{type(params.get("quiet", False))}` expected `bool`')
    if params.get("debug", False) is None:
        raise StyxValidationError("`debug` must not be None")
    if not isinstance(params["debug"], bool):
        raise StyxValidationError(f'`debug` has the wrong type: Received `{type(params.get("debug", False))}` expected `bool`')
    if params.get("force", False) is None:
        raise StyxValidationError("`force` must not be None")
    if not isinstance(params["force"], bool):
        raise StyxValidationError(f'`force` has the wrong type: Received `{type(params.get("force", False))}` expected `bool`')
    if params.get("nthreads", None) is not None:
        if not isinstance(params["nthreads"], int):
            raise StyxValidationError(f'`nthreads` has the wrong type: Received `{type(params.get("nthreads", None))}` expected `int | None`')
    if params.get("config", None) is not None:
        if not isinstance(params["config"], list):
            raise StyxValidationError(f'`config` has the wrong type: Received `{type(params.get("config", None))}` expected `list[MrthresholdConfigParamsDict] | None`')
        for e in params["config"]:
            mrthreshold_config_validate(e)
    if params.get("help", False) is None:
        raise StyxValidationError("`help` must not be None")
    if not isinstance(params["help"], bool):
        raise StyxValidationError(f'`help` has the wrong type: Received `{type(params.get("help", False))}` expected `bool`')
    if params.get("version", False) is None:
        raise StyxValidationError("`version` must not be None")
    if not isinstance(params["version"], bool):
        raise StyxValidationError(f'`version` has the wrong type: Received `{type(params.get("version", False))}` expected `bool`')
    if params.get("input", None) is None:
        raise StyxValidationError("`input` must not be None")
    if not isinstance(params["input"], (pathlib.Path, str)):
        raise StyxValidationError(f'`input` has the wrong type: Received `{type(params.get("input", None))}` expected `InputPathType`')
    if params.get("output", None) is not None:
        if not isinstance(params["output"], str):
            raise StyxValidationError(f'`output` has the wrong type: Received `{type(params.get("output", None))}` expected `str | None`')


def mrthreshold_cargs(
    params: MrthresholdParamsDict,
    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.append("mrthreshold")
    if params.get("abs", None) is not None:
        cargs.extend([
            "-abs",
            str(params.get("abs", None))
        ])
    if params.get("percentile", None) is not None:
        cargs.extend([
            "-percentile",
            str(params.get("percentile", None))
        ])
    if params.get("top", None) is not None:
        cargs.extend([
            "-top",
            str(params.get("top", None))
        ])
    if params.get("bottom", None) is not None:
        cargs.extend([
            "-bottom",
            str(params.get("bottom", None))
        ])
    if params.get("allvolumes", False):
        cargs.append("-allvolumes")
    if params.get("ignorezero", False):
        cargs.append("-ignorezero")
    if params.get("mask", None) is not None:
        cargs.extend([
            "-mask",
            execution.input_file(params.get("mask", None))
        ])
    if params.get("comparison", None) is not None:
        cargs.extend([
            "-comparison",
            params.get("comparison", None)
        ])
    if params.get("invert", False):
        cargs.append("-invert")
    if params.get("out_masked", False):
        cargs.append("-out_masked")
    if params.get("nan", False):
        cargs.append("-nan")
    if params.get("info", False):
        cargs.append("-info")
    if params.get("quiet", False):
        cargs.append("-quiet")
    if params.get("debug", False):
        cargs.append("-debug")
    if params.get("force", False):
        cargs.append("-force")
    if params.get("nthreads", None) is not None:
        cargs.extend([
            "-nthreads",
            str(params.get("nthreads", None))
        ])
    if params.get("config", None) is not None:
        cargs.extend([a for c in [mrthreshold_config_cargs(s, execution) for s in params.get("config", None)] for a in c])
    if params.get("help", False):
        cargs.append("-help")
    if params.get("version", False):
        cargs.append("-version")
    cargs.append(execution.input_file(params.get("input", None)))
    if params.get("output", None) is not None:
        cargs.append(params.get("output", None))
    return cargs


def mrthreshold_outputs(
    params: MrthresholdParamsDict,
    execution: Execution,
) -> MrthresholdOutputs:
    """
    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 = MrthresholdOutputs(
        root=execution.output_file("."),
        output=execution.output_file(params.get("output", None)) if (params.get("output") is not None) else None,
    )
    return ret


def mrthreshold_execute(
    params: MrthresholdParamsDict,
    runner: Runner | None = None,
) -> MrthresholdOutputs:
    """
    mrthreshold
    
    Create bitwise image by thresholding image intensity.
    
    The threshold value to be applied can be determined in one of a number of
    ways:
    
    - If no relevant command-line option is used, the command will automatically
    determine an optimal threshold;
    
    - The -abs option provides the threshold value explicitly;
    
    - The -percentile, -top and -bottom options enable more fine-grained control
    over how the threshold value is determined.
    
    The -mask option only influences those image values that contribute toward
    the determination of the threshold value; once the threshold is determined,
    it is applied to the entire image, irrespective of use of the -mask option.
    If you wish for the voxels outside of the specified mask to additionally be
    excluded from the output mask, this can be achieved by providing the
    -out_masked option.
    
    The four operators available through the "-comparison" option ("lt", "le",
    "ge" and "gt") correspond to "less-than" (<), "less-than-or-equal" (<=),
    "greater-than-or-equal" (>=) and "greater-than" (>). This offers
    fine-grained control over how the thresholding operation will behave in the
    presence of values equivalent to the threshold. By default, the command will
    select voxels with values greater than or equal to the determined threshold
    ("ge"); unless the -bottom option is used, in which case after a threshold
    is determined from the relevant lowest-valued image voxels, those voxels
    with values less than or equal to that threshold ("le") are selected. This
    provides more fine-grained control than the -invert option; the latter is
    provided for backwards compatibility, but is equivalent to selection of the
    opposite comparison within this selection.
    
    If no output image path is specified, the command will instead write to
    standard output the determined threshold value.
    
    References:
    
    * If not using any explicit thresholding mechanism:
    Ridgway, G. R.; Omar, R.; Ourselin, S.; Hill, D. L.; Warren, J. D. & Fox, N.
    C. Issues with threshold masking in voxel-based morphometry of atrophied
    brains. NeuroImage, 2009, 44, 99-111.
    
    Author: MRTrix3 Developers
    
    URL: https://www.mrtrix.org/
    
    Args:
        params: The parameters.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `MrthresholdOutputs`).
    """
    mrthreshold_validate(params)
    runner = runner or get_global_runner()
    execution = runner.start_execution(MRTHRESHOLD_METADATA)
    params = execution.params(params)
    cargs = mrthreshold_cargs(params, execution)
    ret = mrthreshold_outputs(params, execution)
    execution.run(cargs)
    return ret


def mrthreshold(
    input_: InputPathType,
    abs_: float | None = None,
    percentile: float | None = None,
    top: int | None = None,
    bottom: int | None = None,
    allvolumes: bool = False,
    ignorezero: bool = False,
    mask: InputPathType | None = None,
    comparison: str | None = None,
    invert: bool = False,
    out_masked: bool = False,
    nan: bool = False,
    info: bool = False,
    quiet: bool = False,
    debug: bool = False,
    force: bool = False,
    nthreads: int | None = None,
    config: list[MrthresholdConfigParamsDict] | None = None,
    help_: bool = False,
    version: bool = False,
    output: str | None = None,
    runner: Runner | None = None,
) -> MrthresholdOutputs:
    """
    mrthreshold
    
    Create bitwise image by thresholding image intensity.
    
    The threshold value to be applied can be determined in one of a number of
    ways:
    
    - If no relevant command-line option is used, the command will automatically
    determine an optimal threshold;
    
    - The -abs option provides the threshold value explicitly;
    
    - The -percentile, -top and -bottom options enable more fine-grained control
    over how the threshold value is determined.
    
    The -mask option only influences those image values that contribute toward
    the determination of the threshold value; once the threshold is determined,
    it is applied to the entire image, irrespective of use of the -mask option.
    If you wish for the voxels outside of the specified mask to additionally be
    excluded from the output mask, this can be achieved by providing the
    -out_masked option.
    
    The four operators available through the "-comparison" option ("lt", "le",
    "ge" and "gt") correspond to "less-than" (<), "less-than-or-equal" (<=),
    "greater-than-or-equal" (>=) and "greater-than" (>). This offers
    fine-grained control over how the thresholding operation will behave in the
    presence of values equivalent to the threshold. By default, the command will
    select voxels with values greater than or equal to the determined threshold
    ("ge"); unless the -bottom option is used, in which case after a threshold
    is determined from the relevant lowest-valued image voxels, those voxels
    with values less than or equal to that threshold ("le") are selected. This
    provides more fine-grained control than the -invert option; the latter is
    provided for backwards compatibility, but is equivalent to selection of the
    opposite comparison within this selection.
    
    If no output image path is specified, the command will instead write to
    standard output the determined threshold value.
    
    References:
    
    * If not using any explicit thresholding mechanism:
    Ridgway, G. R.; Omar, R.; Ourselin, S.; Hill, D. L.; Warren, J. D. & Fox, N.
    C. Issues with threshold masking in voxel-based morphometry of atrophied
    brains. NeuroImage, 2009, 44, 99-111.
    
    Author: MRTrix3 Developers
    
    URL: https://www.mrtrix.org/
    
    Args:
        input_: the input image to be thresholded.
        abs_: specify threshold value as absolute intensity.
        percentile: determine threshold based on some percentile of the image\
            intensity distribution.
        top: determine threshold that will result in selection of some number\
            of top-valued voxels.
        bottom: determine & apply threshold resulting in selection of some\
            number of bottom-valued voxels (note: implies threshold application\
            operator of "le" unless otherwise specified).
        allvolumes: compute a single threshold for all image volumes, rather\
            than an individual threshold per volume.
        ignorezero: ignore zero-valued input values during threshold\
            determination.
        mask: compute the threshold based only on values within an input mask\
            image.
        comparison: comparison operator to use when applying the threshold;\
            options are: lt,le,ge,gt (default = "le" for -bottom; "ge" otherwise).
        invert: invert the output binary mask (equivalent to flipping the\
            operator; provided for backwards compatibility).
        out_masked: mask the output image based on the provided input mask\
            image.
        nan: set voxels that fail the threshold to NaN rather than zero (output\
            image will be floating-point rather than binary).
        info: display information messages.
        quiet: do not display information messages or progress status;\
            alternatively, this can be achieved by setting the MRTRIX_QUIET\
            environment variable to a non-empty string.
        debug: display debugging messages.
        force: force overwrite of output files (caution: using the same file as\
            input and output might cause unexpected behaviour).
        nthreads: use this number of threads in multi-threaded applications\
            (set to 0 to disable multi-threading).
        config: temporarily set the value of an MRtrix config file entry.
        help_: display this information page and exit.
        version: display version information and exit.
        output: the (optional) output binary image mask.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `MrthresholdOutputs`).
    """
    params = mrthreshold_params(
        abs_=abs_,
        percentile=percentile,
        top=top,
        bottom=bottom,
        allvolumes=allvolumes,
        ignorezero=ignorezero,
        mask=mask,
        comparison=comparison,
        invert=invert,
        out_masked=out_masked,
        nan=nan,
        info=info,
        quiet=quiet,
        debug=debug,
        force=force,
        nthreads=nthreads,
        config=config,
        help_=help_,
        version=version,
        input_=input_,
        output=output,
    )
    return mrthreshold_execute(params, runner)


__all__ = [
    "MRTHRESHOLD_METADATA",
    "MrthresholdConfigParamsDict",
    "MrthresholdConfigParamsDictTagged",
    "MrthresholdOutputs",
    "MrthresholdParamsDict",
    "MrthresholdParamsDictTagged",
    "mrthreshold",
    "mrthreshold_config",
    "mrthreshold_execute",
    "mrthreshold_params",
]
