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

import typing
import pathlib
from styxdefs import *

DIRSTAT_METADATA = Metadata(
    id="369098dbdbd016bf94682e0106a2f2e1711f2a5b.boutiques",
    name="dirstat",
    package="mrtrix",
    container_image_tag="mrtrix3/mrtrix3:3.0.4",
)


_DirstatFslgradParamsDictNoTag = typing.TypedDict('_DirstatFslgradParamsDictNoTag', {
    "bvecs": InputPathType,
    "bvals": InputPathType,
})
DirstatFslgradParamsDictTagged = typing.TypedDict('DirstatFslgradParamsDictTagged', {
    "@type": typing.Literal["fslgrad"],
    "bvecs": InputPathType,
    "bvals": InputPathType,
})
DirstatFslgradParamsDict = _DirstatFslgradParamsDictNoTag | DirstatFslgradParamsDictTagged


_DirstatConfigParamsDictNoTag = typing.TypedDict('_DirstatConfigParamsDictNoTag', {
    "key": str,
    "value": str,
})
DirstatConfigParamsDictTagged = typing.TypedDict('DirstatConfigParamsDictTagged', {
    "@type": typing.Literal["config"],
    "key": str,
    "value": str,
})
DirstatConfigParamsDict = _DirstatConfigParamsDictNoTag | DirstatConfigParamsDictTagged


_DirstatParamsDictNoTag = typing.TypedDict('_DirstatParamsDictNoTag', {
    "output": typing.NotRequired[str | None],
    "shells": typing.NotRequired[list[float] | None],
    "grad": typing.NotRequired[InputPathType | None],
    "fslgrad": typing.NotRequired[DirstatFslgradParamsDict | None],
    "info": bool,
    "quiet": bool,
    "debug": bool,
    "force": bool,
    "nthreads": typing.NotRequired[int | None],
    "config": typing.NotRequired[list[DirstatConfigParamsDict] | None],
    "help": bool,
    "version": bool,
    "dirs": InputPathType,
})
DirstatParamsDictTagged = typing.TypedDict('DirstatParamsDictTagged', {
    "@type": typing.Literal["mrtrix/dirstat"],
    "output": typing.NotRequired[str | None],
    "shells": typing.NotRequired[list[float] | None],
    "grad": typing.NotRequired[InputPathType | None],
    "fslgrad": typing.NotRequired[DirstatFslgradParamsDict | None],
    "info": bool,
    "quiet": bool,
    "debug": bool,
    "force": bool,
    "nthreads": typing.NotRequired[int | None],
    "config": typing.NotRequired[list[DirstatConfigParamsDict] | None],
    "help": bool,
    "version": bool,
    "dirs": InputPathType,
})
DirstatParamsDict = _DirstatParamsDictNoTag | DirstatParamsDictTagged


def dirstat_fslgrad(
    bvecs: InputPathType,
    bvals: InputPathType,
) -> DirstatFslgradParamsDictTagged:
    """
    Build parameters.
    
    Args:
        bvecs: Provide the diffusion-weighted gradient scheme used in the\
            acquisition in FSL bvecs/bvals format files. If a diffusion gradient\
            scheme is present in the input image header, the data provided with\
            this option will be instead used.
        bvals: Provide the diffusion-weighted gradient scheme used in the\
            acquisition in FSL bvecs/bvals format files. If a diffusion gradient\
            scheme is present in the input image header, the data provided with\
            this option will be instead used.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "fslgrad",
        "bvecs": bvecs,
        "bvals": bvals,
    }
    return params


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


def dirstat_fslgrad_cargs(
    params: DirstatFslgradParamsDict,
    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("-fslgrad")
    cargs.append(execution.input_file(params.get("bvecs", None)))
    cargs.append(execution.input_file(params.get("bvals", None)))
    return cargs


def dirstat_config(
    key: str,
    value: str,
) -> DirstatConfigParamsDictTagged:
    """
    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 dirstat_config_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `DirstatConfigParamsDict` 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 dirstat_config_cargs(
    params: DirstatConfigParamsDict,
    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 DirstatOutputs(typing.NamedTuple):
    """
    Output object returned when calling `DirstatParamsDict(...)`.
    """
    root: OutputPathType
    """Output root folder. This is the root folder for all outputs."""


def dirstat_params(
    dirs: InputPathType,
    output: str | None = None,
    shells: list[float] | None = None,
    grad: InputPathType | None = None,
    fslgrad: DirstatFslgradParamsDict | None = None,
    info: bool = False,
    quiet: bool = False,
    debug: bool = False,
    force: bool = False,
    nthreads: int | None = None,
    config: list[DirstatConfigParamsDict] | None = None,
    help_: bool = False,
    version: bool = False,
) -> DirstatParamsDictTagged:
    """
    Build parameters.
    
    Args:
        dirs: the text file or image containing the directions.
        output: output selected metrics as a space-delimited list, suitable for\
            use in scripts. This will produce one line of values per selected\
            shell. Valid metrics are as specified in the description above.
        shells: specify one or more b-values to use during processing, as a\
            comma-separated list of the desired approximate b-values (b-values are\
            clustered to allow for small deviations). Note that some commands are\
            incompatible with multiple b-values, and will report an error if more\
            than one b-value is provided.\
            WARNING: note that, even though the b=0 volumes are never referred\
            to as shells in the literature, they still have to be explicitly\
            included in the list of b-values as provided to the -shell option!\
            Several algorithms which include the b=0 volumes in their\
            computations may otherwise return an undesired result.
        grad: Provide the diffusion-weighted gradient scheme used in the\
            acquisition in a text file. This should be supplied as a 4xN text file\
            with each line is in the format [ X Y Z b ], where [ X Y Z ] describe\
            the direction of the applied gradient, and b gives the b-value in units\
            of s/mm^2. If a diffusion gradient scheme is present in the input image\
            header, the data provided with this option will be instead used.
        fslgrad: Provide the diffusion-weighted gradient scheme used in the\
            acquisition in FSL bvecs/bvals format files. If a diffusion gradient\
            scheme is present in the input image header, the data provided with\
            this option will be instead used.
        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.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "mrtrix/dirstat",
        "info": info,
        "quiet": quiet,
        "debug": debug,
        "force": force,
        "help": help_,
        "version": version,
        "dirs": dirs,
    }
    if output is not None:
        params["output"] = output
    if shells is not None:
        params["shells"] = shells
    if grad is not None:
        params["grad"] = grad
    if fslgrad is not None:
        params["fslgrad"] = fslgrad
    if nthreads is not None:
        params["nthreads"] = nthreads
    if config is not None:
        params["config"] = config
    return params


def dirstat_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `DirstatParamsDict` 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("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`')
    if params.get("shells", None) is not None:
        if not isinstance(params["shells"], list):
            raise StyxValidationError(f'`shells` has the wrong type: Received `{type(params.get("shells", None))}` expected `list[float] | None`')
        for e in params["shells"]:
            if not isinstance(e, (float, int)):
                raise StyxValidationError(f'`shells` has the wrong type: Received `{type(params.get("shells", None))}` expected `list[float] | None`')
    if params.get("grad", None) is not None:
        if not isinstance(params["grad"], (pathlib.Path, str)):
            raise StyxValidationError(f'`grad` has the wrong type: Received `{type(params.get("grad", None))}` expected `InputPathType | None`')
    if params.get("fslgrad", None) is not None:
        dirstat_fslgrad_validate(params["fslgrad"])
    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[DirstatConfigParamsDict] | None`')
        for e in params["config"]:
            dirstat_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("dirs", None) is None:
        raise StyxValidationError("`dirs` must not be None")
    if not isinstance(params["dirs"], (pathlib.Path, str)):
        raise StyxValidationError(f'`dirs` has the wrong type: Received `{type(params.get("dirs", None))}` expected `InputPathType`')


def dirstat_cargs(
    params: DirstatParamsDict,
    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("dirstat")
    if params.get("output", None) is not None:
        cargs.extend([
            "-output",
            params.get("output", None)
        ])
    if params.get("shells", None) is not None:
        cargs.extend([
            "-shells",
            ",".join(map(str, params.get("shells", None)))
        ])
    if params.get("grad", None) is not None:
        cargs.extend([
            "-grad",
            execution.input_file(params.get("grad", None))
        ])
    if params.get("fslgrad", None) is not None:
        cargs.extend(dirstat_fslgrad_cargs(params.get("fslgrad", None), execution))
    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 [dirstat_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("dirs", None)))
    return cargs


def dirstat_outputs(
    params: DirstatParamsDict,
    execution: Execution,
) -> DirstatOutputs:
    """
    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 = DirstatOutputs(
        root=execution.output_file("."),
    )
    return ret


def dirstat_execute(
    params: DirstatParamsDict,
    runner: Runner | None = None,
) -> DirstatOutputs:
    """
    dirstat
    
    Report statistics on a direction set.
    
    This command will accept as inputs:
    
    - directions file in spherical coordinates (ASCII text, [ az el ]
    space-separated values, one per line);
    
    - directions file in Cartesian coordinates (ASCII text, [ x y z ]
    space-separated values, one per line);
    
    - DW gradient files (MRtrix format: ASCII text, [ x y z b ] space-separated
    values, one per line);
    
    - image files, using the DW gradient scheme found in the header (or provided
    using the appropriate command line options below).
    
    By default, this produces all relevant metrics for the direction set
    provided. If the direction set contains multiple shells, metrics are
    provided for each shell separately.
    
    Metrics are produced assuming a unipolar or bipolar electrostatic repulsion
    model, producing the potential energy (total, mean, min & max), and the
    nearest-neighbour angles (mean, min & max). The condition number is also
    produced for the spherical harmonic fits up to the highest harmonic order
    supported by the number of volumes. Finally, the norm of the mean direction
    vector is provided as a measure of the overall symmetry of the direction set
    (important with respect to eddy-current resilience).
    
    Specific metrics can also be queried independently via the "-output" option,
    using these shorthands:
    U/B for unipolar/bipolar model,
    E/N for energy and nearest-neighbour respectively,
    t/-/+ for total/min/max respectively (mean implied otherwise);
    SHn for condition number of SH fit at order n (with n an even integer);
    ASYM for asymmetry index (norm of mean direction vector);
    N for the number of directions.
    
    References:
    
    .
    
    Author: MRTrix3 Developers
    
    URL: https://www.mrtrix.org/
    
    Args:
        params: The parameters.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `DirstatOutputs`).
    """
    dirstat_validate(params)
    runner = runner or get_global_runner()
    execution = runner.start_execution(DIRSTAT_METADATA)
    params = execution.params(params)
    cargs = dirstat_cargs(params, execution)
    ret = dirstat_outputs(params, execution)
    execution.run(cargs)
    return ret


def dirstat(
    dirs: InputPathType,
    output: str | None = None,
    shells: list[float] | None = None,
    grad: InputPathType | None = None,
    fslgrad: DirstatFslgradParamsDict | None = None,
    info: bool = False,
    quiet: bool = False,
    debug: bool = False,
    force: bool = False,
    nthreads: int | None = None,
    config: list[DirstatConfigParamsDict] | None = None,
    help_: bool = False,
    version: bool = False,
    runner: Runner | None = None,
) -> DirstatOutputs:
    """
    dirstat
    
    Report statistics on a direction set.
    
    This command will accept as inputs:
    
    - directions file in spherical coordinates (ASCII text, [ az el ]
    space-separated values, one per line);
    
    - directions file in Cartesian coordinates (ASCII text, [ x y z ]
    space-separated values, one per line);
    
    - DW gradient files (MRtrix format: ASCII text, [ x y z b ] space-separated
    values, one per line);
    
    - image files, using the DW gradient scheme found in the header (or provided
    using the appropriate command line options below).
    
    By default, this produces all relevant metrics for the direction set
    provided. If the direction set contains multiple shells, metrics are
    provided for each shell separately.
    
    Metrics are produced assuming a unipolar or bipolar electrostatic repulsion
    model, producing the potential energy (total, mean, min & max), and the
    nearest-neighbour angles (mean, min & max). The condition number is also
    produced for the spherical harmonic fits up to the highest harmonic order
    supported by the number of volumes. Finally, the norm of the mean direction
    vector is provided as a measure of the overall symmetry of the direction set
    (important with respect to eddy-current resilience).
    
    Specific metrics can also be queried independently via the "-output" option,
    using these shorthands:
    U/B for unipolar/bipolar model,
    E/N for energy and nearest-neighbour respectively,
    t/-/+ for total/min/max respectively (mean implied otherwise);
    SHn for condition number of SH fit at order n (with n an even integer);
    ASYM for asymmetry index (norm of mean direction vector);
    N for the number of directions.
    
    References:
    
    .
    
    Author: MRTrix3 Developers
    
    URL: https://www.mrtrix.org/
    
    Args:
        dirs: the text file or image containing the directions.
        output: output selected metrics as a space-delimited list, suitable for\
            use in scripts. This will produce one line of values per selected\
            shell. Valid metrics are as specified in the description above.
        shells: specify one or more b-values to use during processing, as a\
            comma-separated list of the desired approximate b-values (b-values are\
            clustered to allow for small deviations). Note that some commands are\
            incompatible with multiple b-values, and will report an error if more\
            than one b-value is provided.\
            WARNING: note that, even though the b=0 volumes are never referred\
            to as shells in the literature, they still have to be explicitly\
            included in the list of b-values as provided to the -shell option!\
            Several algorithms which include the b=0 volumes in their\
            computations may otherwise return an undesired result.
        grad: Provide the diffusion-weighted gradient scheme used in the\
            acquisition in a text file. This should be supplied as a 4xN text file\
            with each line is in the format [ X Y Z b ], where [ X Y Z ] describe\
            the direction of the applied gradient, and b gives the b-value in units\
            of s/mm^2. If a diffusion gradient scheme is present in the input image\
            header, the data provided with this option will be instead used.
        fslgrad: Provide the diffusion-weighted gradient scheme used in the\
            acquisition in FSL bvecs/bvals format files. If a diffusion gradient\
            scheme is present in the input image header, the data provided with\
            this option will be instead used.
        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.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `DirstatOutputs`).
    """
    params = dirstat_params(
        output=output,
        shells=shells,
        grad=grad,
        fslgrad=fslgrad,
        info=info,
        quiet=quiet,
        debug=debug,
        force=force,
        nthreads=nthreads,
        config=config,
        help_=help_,
        version=version,
        dirs=dirs,
    )
    return dirstat_execute(params, runner)


__all__ = [
    "DIRSTAT_METADATA",
    "DirstatConfigParamsDict",
    "DirstatConfigParamsDictTagged",
    "DirstatFslgradParamsDict",
    "DirstatFslgradParamsDictTagged",
    "DirstatOutputs",
    "DirstatParamsDict",
    "DirstatParamsDictTagged",
    "dirstat",
    "dirstat_config",
    "dirstat_execute",
    "dirstat_fslgrad",
    "dirstat_params",
]
