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

import typing
import pathlib
from styxdefs import *

TCKGLOBAL_METADATA = Metadata(
    id="31e24266a6d4374cd9c0a8ed5d9d697b1c511208.boutiques",
    name="tckglobal",
    package="mrtrix",
    container_image_tag="mrtrix3/mrtrix3:3.0.4",
)


_TckglobalRisoParamsDictNoTag = typing.TypedDict('_TckglobalRisoParamsDictNoTag', {
    "response": InputPathType,
})
TckglobalRisoParamsDictTagged = typing.TypedDict('TckglobalRisoParamsDictTagged', {
    "@type": typing.Literal["riso"],
    "response": InputPathType,
})
TckglobalRisoParamsDict = _TckglobalRisoParamsDictNoTag | TckglobalRisoParamsDictTagged


_TckglobalConfigParamsDictNoTag = typing.TypedDict('_TckglobalConfigParamsDictNoTag', {
    "key": str,
    "value": str,
})
TckglobalConfigParamsDictTagged = typing.TypedDict('TckglobalConfigParamsDictTagged', {
    "@type": typing.Literal["config"],
    "key": str,
    "value": str,
})
TckglobalConfigParamsDict = _TckglobalConfigParamsDictNoTag | TckglobalConfigParamsDictTagged


_TckglobalParamsDictNoTag = typing.TypedDict('_TckglobalParamsDictNoTag', {
    "grad": typing.NotRequired[InputPathType | None],
    "mask": typing.NotRequired[InputPathType | None],
    "riso": typing.NotRequired[list[TckglobalRisoParamsDict] | None],
    "lmax": typing.NotRequired[int | None],
    "length": typing.NotRequired[float | None],
    "weight": typing.NotRequired[float | None],
    "ppot": typing.NotRequired[float | None],
    "cpot": typing.NotRequired[float | None],
    "t0": typing.NotRequired[float | None],
    "t1": typing.NotRequired[float | None],
    "niter": typing.NotRequired[int | None],
    "fod": typing.NotRequired[str | None],
    "noapo": bool,
    "fiso": typing.NotRequired[str | None],
    "eext": typing.NotRequired[str | None],
    "etrend": typing.NotRequired[str | None],
    "balance": typing.NotRequired[float | None],
    "density": typing.NotRequired[float | None],
    "prob": typing.NotRequired[list[float] | None],
    "beta": typing.NotRequired[float | None],
    "lambda": typing.NotRequired[float | None],
    "info": bool,
    "quiet": bool,
    "debug": bool,
    "force": bool,
    "nthreads": typing.NotRequired[int | None],
    "config": typing.NotRequired[list[TckglobalConfigParamsDict] | None],
    "help": bool,
    "version": bool,
    "source": InputPathType,
    "response": InputPathType,
    "tracks": str,
})
TckglobalParamsDictTagged = typing.TypedDict('TckglobalParamsDictTagged', {
    "@type": typing.Literal["mrtrix/tckglobal"],
    "grad": typing.NotRequired[InputPathType | None],
    "mask": typing.NotRequired[InputPathType | None],
    "riso": typing.NotRequired[list[TckglobalRisoParamsDict] | None],
    "lmax": typing.NotRequired[int | None],
    "length": typing.NotRequired[float | None],
    "weight": typing.NotRequired[float | None],
    "ppot": typing.NotRequired[float | None],
    "cpot": typing.NotRequired[float | None],
    "t0": typing.NotRequired[float | None],
    "t1": typing.NotRequired[float | None],
    "niter": typing.NotRequired[int | None],
    "fod": typing.NotRequired[str | None],
    "noapo": bool,
    "fiso": typing.NotRequired[str | None],
    "eext": typing.NotRequired[str | None],
    "etrend": typing.NotRequired[str | None],
    "balance": typing.NotRequired[float | None],
    "density": typing.NotRequired[float | None],
    "prob": typing.NotRequired[list[float] | None],
    "beta": typing.NotRequired[float | None],
    "lambda": typing.NotRequired[float | None],
    "info": bool,
    "quiet": bool,
    "debug": bool,
    "force": bool,
    "nthreads": typing.NotRequired[int | None],
    "config": typing.NotRequired[list[TckglobalConfigParamsDict] | None],
    "help": bool,
    "version": bool,
    "source": InputPathType,
    "response": InputPathType,
    "tracks": str,
})
TckglobalParamsDict = _TckglobalParamsDictNoTag | TckglobalParamsDictTagged


def tckglobal_riso(
    response: InputPathType,
) -> TckglobalRisoParamsDictTagged:
    """
    Build parameters.
    
    Args:
        response: set one or more isotropic response functions. (multiple\
            allowed).
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "riso",
        "response": response,
    }
    return params


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


def tckglobal_riso_cargs(
    params: TckglobalRisoParamsDict,
    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("-riso")
    cargs.append(execution.input_file(params.get("response", None)))
    return cargs


def tckglobal_config(
    key: str,
    value: str,
) -> TckglobalConfigParamsDictTagged:
    """
    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 tckglobal_config_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `TckglobalConfigParamsDict` 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 tckglobal_config_cargs(
    params: TckglobalConfigParamsDict,
    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 TckglobalOutputs(typing.NamedTuple):
    """
    Output object returned when calling `TckglobalParamsDict(...)`.
    """
    root: OutputPathType
    """Output root folder. This is the root folder for all outputs."""
    tracks: OutputPathType
    """the output file containing the tracks generated."""
    fod: OutputPathType | None
    """Predicted fibre orientation distribution function (fODF).
    This fODF is estimated as part of the global track optimization, and
    therefore incorporates the spatial regularization that it imposes.
    Internally, the fODF is represented as a discrete sum of apodized point
    spread functions (aPSF) oriented along the directions of all particles in
    the voxel, used to predict the DWI signal from the particle configuration.
    """
    fiso: OutputPathType | None
    """Predicted isotropic fractions of the tissues for which response functions
    were provided with -riso. Typically, these are CSF and GM. """
    eext: OutputPathType | None
    """Residual external energy in every voxel. """
    etrend: OutputPathType | None
    """internal and external energy trend and cooling statistics. """


def tckglobal_params(
    source: InputPathType,
    response: InputPathType,
    tracks: str,
    grad: InputPathType | None = None,
    mask: InputPathType | None = None,
    riso: list[TckglobalRisoParamsDict] | None = None,
    lmax: int | None = None,
    length: float | None = None,
    weight: float | None = None,
    ppot: float | None = None,
    cpot: float | None = None,
    t0: float | None = None,
    t1: float | None = None,
    niter: int | None = None,
    fod: str | None = None,
    noapo: bool = False,
    fiso: str | None = None,
    eext: str | None = None,
    etrend: str | None = None,
    balance: float | None = None,
    density: float | None = None,
    prob: list[float] | None = None,
    beta: float | None = None,
    lambda_: float | None = None,
    info: bool = False,
    quiet: bool = False,
    debug: bool = False,
    force: bool = False,
    nthreads: int | None = None,
    config: list[TckglobalConfigParamsDict] | None = None,
    help_: bool = False,
    version: bool = False,
) -> TckglobalParamsDictTagged:
    """
    Build parameters.
    
    Args:
        source: the image containing the raw DWI data.
        response: the response of a track segment on the DWI signal.
        tracks: the output file containing the tracks generated.
        grad: specify the diffusion encoding scheme (required if not supplied\
            in the header).
        mask: only reconstruct the tractogram within the specified brain mask\
            image.
        riso: set one or more isotropic response functions. (multiple allowed).
        lmax: set the maximum harmonic order for the output series. (default =\
            8).
        length: set the length of the particles (fibre segments). (default =\
            1mm).
        weight: set the weight by which particles contribute to the model.\
            (default = 0.1).
        ppot: set the particle potential, i.e., the cost of adding one segment,\
            relative to the particle weight. (default = 0.05).
        cpot: set the connection potential, i.e., the energy term that drives\
            two segments together. (default = 0.5).
        t0: set the initial temperature of the metropolis hastings optimizer.\
            (default = 0.1).
        t1: set the final temperature of the metropolis hastings optimizer.\
            (default = 0.001).
        niter: set the number of iterations of the metropolis hastings\
            optimizer. (default = 10M).
        fod: Predicted fibre orientation distribution function (fODF).\
            This fODF is estimated as part of the global track optimization,\
            and therefore incorporates the spatial regularization that it\
            imposes. Internally, the fODF is represented as a discrete sum of\
            apodized point spread functions (aPSF) oriented along the\
            directions of all particles in the voxel, used to predict the DWI\
            signal from the particle configuration.
        noapo: disable spherical convolution of fODF with apodized PSF, to\
            output a sum of delta functions rather than a sum of aPSFs.
        fiso: Predicted isotropic fractions of the tissues for which response\
            functions were provided with -riso. Typically, these are CSF and GM.
        eext: Residual external energy in every voxel.
        etrend: internal and external energy trend and cooling statistics.
        balance: balance internal and external energy. (default = 0)\
            Negative values give more weight to the internal energy, positive\
            to the external energy.
        density: set the desired density of the free Poisson process. (default\
            = 1).
        prob: set the probabilities of generating birth, death, randshift,\
            optshift and connect proposals respectively. (default =\
            0.25,0.05,0.25,0.1,0.35).
        beta: set the width of the Hanning interpolation window. (in [0, 1],\
            default = 0)\
            If used, a mask is required, and this mask must keep at least one\
            voxel distance to the image bounding box.
        lambda_: set the weight of the internal energy directly. (default = 1)\
            If provided, any value of -balance will be ignored.
        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/tckglobal",
        "noapo": noapo,
        "info": info,
        "quiet": quiet,
        "debug": debug,
        "force": force,
        "help": help_,
        "version": version,
        "source": source,
        "response": response,
        "tracks": tracks,
    }
    if grad is not None:
        params["grad"] = grad
    if mask is not None:
        params["mask"] = mask
    if riso is not None:
        params["riso"] = riso
    if lmax is not None:
        params["lmax"] = lmax
    if length is not None:
        params["length"] = length
    if weight is not None:
        params["weight"] = weight
    if ppot is not None:
        params["ppot"] = ppot
    if cpot is not None:
        params["cpot"] = cpot
    if t0 is not None:
        params["t0"] = t0
    if t1 is not None:
        params["t1"] = t1
    if niter is not None:
        params["niter"] = niter
    if fod is not None:
        params["fod"] = fod
    if fiso is not None:
        params["fiso"] = fiso
    if eext is not None:
        params["eext"] = eext
    if etrend is not None:
        params["etrend"] = etrend
    if balance is not None:
        params["balance"] = balance
    if density is not None:
        params["density"] = density
    if prob is not None:
        params["prob"] = prob
    if beta is not None:
        params["beta"] = beta
    if lambda_ is not None:
        params["lambda"] = lambda_
    if nthreads is not None:
        params["nthreads"] = nthreads
    if config is not None:
        params["config"] = config
    return params


def tckglobal_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `TckglobalParamsDict` 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("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("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("riso", None) is not None:
        if not isinstance(params["riso"], list):
            raise StyxValidationError(f'`riso` has the wrong type: Received `{type(params.get("riso", None))}` expected `list[TckglobalRisoParamsDict] | None`')
        for e in params["riso"]:
            tckglobal_riso_validate(e)
    if params.get("lmax", None) is not None:
        if not isinstance(params["lmax"], int):
            raise StyxValidationError(f'`lmax` has the wrong type: Received `{type(params.get("lmax", None))}` expected `int | None`')
    if params.get("length", None) is not None:
        if not isinstance(params["length"], (float, int)):
            raise StyxValidationError(f'`length` has the wrong type: Received `{type(params.get("length", None))}` expected `float | None`')
    if params.get("weight", None) is not None:
        if not isinstance(params["weight"], (float, int)):
            raise StyxValidationError(f'`weight` has the wrong type: Received `{type(params.get("weight", None))}` expected `float | None`')
    if params.get("ppot", None) is not None:
        if not isinstance(params["ppot"], (float, int)):
            raise StyxValidationError(f'`ppot` has the wrong type: Received `{type(params.get("ppot", None))}` expected `float | None`')
    if params.get("cpot", None) is not None:
        if not isinstance(params["cpot"], (float, int)):
            raise StyxValidationError(f'`cpot` has the wrong type: Received `{type(params.get("cpot", None))}` expected `float | None`')
    if params.get("t0", None) is not None:
        if not isinstance(params["t0"], (float, int)):
            raise StyxValidationError(f'`t0` has the wrong type: Received `{type(params.get("t0", None))}` expected `float | None`')
    if params.get("t1", None) is not None:
        if not isinstance(params["t1"], (float, int)):
            raise StyxValidationError(f'`t1` has the wrong type: Received `{type(params.get("t1", None))}` expected `float | None`')
    if params.get("niter", None) is not None:
        if not isinstance(params["niter"], int):
            raise StyxValidationError(f'`niter` has the wrong type: Received `{type(params.get("niter", None))}` expected `int | None`')
    if params.get("fod", None) is not None:
        if not isinstance(params["fod"], str):
            raise StyxValidationError(f'`fod` has the wrong type: Received `{type(params.get("fod", None))}` expected `str | None`')
    if params.get("noapo", False) is None:
        raise StyxValidationError("`noapo` must not be None")
    if not isinstance(params["noapo"], bool):
        raise StyxValidationError(f'`noapo` has the wrong type: Received `{type(params.get("noapo", False))}` expected `bool`')
    if params.get("fiso", None) is not None:
        if not isinstance(params["fiso"], str):
            raise StyxValidationError(f'`fiso` has the wrong type: Received `{type(params.get("fiso", None))}` expected `str | None`')
    if params.get("eext", None) is not None:
        if not isinstance(params["eext"], str):
            raise StyxValidationError(f'`eext` has the wrong type: Received `{type(params.get("eext", None))}` expected `str | None`')
    if params.get("etrend", None) is not None:
        if not isinstance(params["etrend"], str):
            raise StyxValidationError(f'`etrend` has the wrong type: Received `{type(params.get("etrend", None))}` expected `str | None`')
    if params.get("balance", None) is not None:
        if not isinstance(params["balance"], (float, int)):
            raise StyxValidationError(f'`balance` has the wrong type: Received `{type(params.get("balance", None))}` expected `float | None`')
    if params.get("density", None) is not None:
        if not isinstance(params["density"], (float, int)):
            raise StyxValidationError(f'`density` has the wrong type: Received `{type(params.get("density", None))}` expected `float | None`')
    if params.get("prob", None) is not None:
        if not isinstance(params["prob"], list):
            raise StyxValidationError(f'`prob` has the wrong type: Received `{type(params.get("prob", None))}` expected `list[float] | None`')
        for e in params["prob"]:
            if not isinstance(e, (float, int)):
                raise StyxValidationError(f'`prob` has the wrong type: Received `{type(params.get("prob", None))}` expected `list[float] | None`')
    if params.get("beta", None) is not None:
        if not isinstance(params["beta"], (float, int)):
            raise StyxValidationError(f'`beta` has the wrong type: Received `{type(params.get("beta", None))}` expected `float | None`')
    if params.get("lambda", None) is not None:
        if not isinstance(params["lambda"], (float, int)):
            raise StyxValidationError(f'`lambda` has the wrong type: Received `{type(params.get("lambda", None))}` expected `float | None`')
    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[TckglobalConfigParamsDict] | None`')
        for e in params["config"]:
            tckglobal_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("source", None) is None:
        raise StyxValidationError("`source` must not be None")
    if not isinstance(params["source"], (pathlib.Path, str)):
        raise StyxValidationError(f'`source` has the wrong type: Received `{type(params.get("source", None))}` expected `InputPathType`')
    if params.get("response", None) is None:
        raise StyxValidationError("`response` must not be None")
    if not isinstance(params["response"], (pathlib.Path, str)):
        raise StyxValidationError(f'`response` has the wrong type: Received `{type(params.get("response", None))}` expected `InputPathType`')
    if params.get("tracks", None) is None:
        raise StyxValidationError("`tracks` must not be None")
    if not isinstance(params["tracks"], str):
        raise StyxValidationError(f'`tracks` has the wrong type: Received `{type(params.get("tracks", None))}` expected `str`')


def tckglobal_cargs(
    params: TckglobalParamsDict,
    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("tckglobal")
    if params.get("grad", None) is not None:
        cargs.extend([
            "-grad",
            execution.input_file(params.get("grad", None))
        ])
    if params.get("mask", None) is not None:
        cargs.extend([
            "-mask",
            execution.input_file(params.get("mask", None))
        ])
    if params.get("riso", None) is not None:
        cargs.extend([a for c in [tckglobal_riso_cargs(s, execution) for s in params.get("riso", None)] for a in c])
    if params.get("lmax", None) is not None:
        cargs.extend([
            "-lmax",
            str(params.get("lmax", None))
        ])
    if params.get("length", None) is not None:
        cargs.extend([
            "-length",
            str(params.get("length", None))
        ])
    if params.get("weight", None) is not None:
        cargs.extend([
            "-weight",
            str(params.get("weight", None))
        ])
    if params.get("ppot", None) is not None:
        cargs.extend([
            "-ppot",
            str(params.get("ppot", None))
        ])
    if params.get("cpot", None) is not None:
        cargs.extend([
            "-cpot",
            str(params.get("cpot", None))
        ])
    if params.get("t0", None) is not None:
        cargs.extend([
            "-t0",
            str(params.get("t0", None))
        ])
    if params.get("t1", None) is not None:
        cargs.extend([
            "-t1",
            str(params.get("t1", None))
        ])
    if params.get("niter", None) is not None:
        cargs.extend([
            "-niter",
            str(params.get("niter", None))
        ])
    if params.get("fod", None) is not None:
        cargs.extend([
            "-fod",
            params.get("fod", None)
        ])
    if params.get("noapo", False):
        cargs.append("-noapo")
    if params.get("fiso", None) is not None:
        cargs.extend([
            "-fiso",
            params.get("fiso", None)
        ])
    if params.get("eext", None) is not None:
        cargs.extend([
            "-eext",
            params.get("eext", None)
        ])
    if params.get("etrend", None) is not None:
        cargs.extend([
            "-etrend",
            params.get("etrend", None)
        ])
    if params.get("balance", None) is not None:
        cargs.extend([
            "-balance",
            str(params.get("balance", None))
        ])
    if params.get("density", None) is not None:
        cargs.extend([
            "-density",
            str(params.get("density", None))
        ])
    if params.get("prob", None) is not None:
        cargs.extend([
            "-prob",
            *map(str, params.get("prob", None))
        ])
    if params.get("beta", None) is not None:
        cargs.extend([
            "-beta",
            str(params.get("beta", None))
        ])
    if params.get("lambda", None) is not None:
        cargs.extend([
            "-lambda",
            str(params.get("lambda", None))
        ])
    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 [tckglobal_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("source", None)))
    cargs.append(execution.input_file(params.get("response", None)))
    cargs.append(params.get("tracks", None))
    return cargs


def tckglobal_outputs(
    params: TckglobalParamsDict,
    execution: Execution,
) -> TckglobalOutputs:
    """
    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 = TckglobalOutputs(
        root=execution.output_file("."),
        tracks=execution.output_file(params.get("tracks", None)),
        fod=execution.output_file(params.get("fod", None)) if (params.get("fod") is not None) else None,
        fiso=execution.output_file(params.get("fiso", None)) if (params.get("fiso") is not None) else None,
        eext=execution.output_file(params.get("eext", None)) if (params.get("eext") is not None) else None,
        etrend=execution.output_file(params.get("etrend", None)) if (params.get("etrend") is not None) else None,
    )
    return ret


def tckglobal_execute(
    params: TckglobalParamsDict,
    runner: Runner | None = None,
) -> TckglobalOutputs:
    """
    tckglobal
    
    Multi-Shell Multi-Tissue Global Tractography.
    
    This command will reconstruct the global white matter fibre tractogram that
    best explains the input DWI data, using a multi-tissue spherical convolution
    model.
    
    Example use:
    
    $ tckglobal dwi.mif wmr.txt -riso csfr.txt -riso gmr.txt -mask mask.mif
    -niter 1e9 -fod fod.mif -fiso fiso.mif tracks.tck
    
    in which dwi.mif is the input image, wmr.txt is an anisotropic, multi-shell
    response function for WM, and csfr.txt and gmr.txt are isotropic response
    functions for CSF and GM. The output tractogram is saved to tracks.tck.
    Optional output images fod.mif and fiso.mif contain the predicted WM fODF
    and isotropic tissue fractions of CSF and GM respectively, estimated as part
    of the global optimization and thus affected by spatial regularization.
    
    References:
    
    Christiaens, D.; Reisert, M.; Dhollander, T.; Sunaert, S.; Suetens, P. &
    Maes, F. Global tractography of multi-shell diffusion-weighted imaging data
    using a multi-tissue model. NeuroImage, 2015, 123, 89-101.
    
    Author: MRTrix3 Developers
    
    URL: https://www.mrtrix.org/
    
    Args:
        params: The parameters.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `TckglobalOutputs`).
    """
    tckglobal_validate(params)
    runner = runner or get_global_runner()
    execution = runner.start_execution(TCKGLOBAL_METADATA)
    params = execution.params(params)
    cargs = tckglobal_cargs(params, execution)
    ret = tckglobal_outputs(params, execution)
    execution.run(cargs)
    return ret


def tckglobal(
    source: InputPathType,
    response: InputPathType,
    tracks: str,
    grad: InputPathType | None = None,
    mask: InputPathType | None = None,
    riso: list[TckglobalRisoParamsDict] | None = None,
    lmax: int | None = None,
    length: float | None = None,
    weight: float | None = None,
    ppot: float | None = None,
    cpot: float | None = None,
    t0: float | None = None,
    t1: float | None = None,
    niter: int | None = None,
    fod: str | None = None,
    noapo: bool = False,
    fiso: str | None = None,
    eext: str | None = None,
    etrend: str | None = None,
    balance: float | None = None,
    density: float | None = None,
    prob: list[float] | None = None,
    beta: float | None = None,
    lambda_: float | None = None,
    info: bool = False,
    quiet: bool = False,
    debug: bool = False,
    force: bool = False,
    nthreads: int | None = None,
    config: list[TckglobalConfigParamsDict] | None = None,
    help_: bool = False,
    version: bool = False,
    runner: Runner | None = None,
) -> TckglobalOutputs:
    """
    tckglobal
    
    Multi-Shell Multi-Tissue Global Tractography.
    
    This command will reconstruct the global white matter fibre tractogram that
    best explains the input DWI data, using a multi-tissue spherical convolution
    model.
    
    Example use:
    
    $ tckglobal dwi.mif wmr.txt -riso csfr.txt -riso gmr.txt -mask mask.mif
    -niter 1e9 -fod fod.mif -fiso fiso.mif tracks.tck
    
    in which dwi.mif is the input image, wmr.txt is an anisotropic, multi-shell
    response function for WM, and csfr.txt and gmr.txt are isotropic response
    functions for CSF and GM. The output tractogram is saved to tracks.tck.
    Optional output images fod.mif and fiso.mif contain the predicted WM fODF
    and isotropic tissue fractions of CSF and GM respectively, estimated as part
    of the global optimization and thus affected by spatial regularization.
    
    References:
    
    Christiaens, D.; Reisert, M.; Dhollander, T.; Sunaert, S.; Suetens, P. &
    Maes, F. Global tractography of multi-shell diffusion-weighted imaging data
    using a multi-tissue model. NeuroImage, 2015, 123, 89-101.
    
    Author: MRTrix3 Developers
    
    URL: https://www.mrtrix.org/
    
    Args:
        source: the image containing the raw DWI data.
        response: the response of a track segment on the DWI signal.
        tracks: the output file containing the tracks generated.
        grad: specify the diffusion encoding scheme (required if not supplied\
            in the header).
        mask: only reconstruct the tractogram within the specified brain mask\
            image.
        riso: set one or more isotropic response functions. (multiple allowed).
        lmax: set the maximum harmonic order for the output series. (default =\
            8).
        length: set the length of the particles (fibre segments). (default =\
            1mm).
        weight: set the weight by which particles contribute to the model.\
            (default = 0.1).
        ppot: set the particle potential, i.e., the cost of adding one segment,\
            relative to the particle weight. (default = 0.05).
        cpot: set the connection potential, i.e., the energy term that drives\
            two segments together. (default = 0.5).
        t0: set the initial temperature of the metropolis hastings optimizer.\
            (default = 0.1).
        t1: set the final temperature of the metropolis hastings optimizer.\
            (default = 0.001).
        niter: set the number of iterations of the metropolis hastings\
            optimizer. (default = 10M).
        fod: Predicted fibre orientation distribution function (fODF).\
            This fODF is estimated as part of the global track optimization,\
            and therefore incorporates the spatial regularization that it\
            imposes. Internally, the fODF is represented as a discrete sum of\
            apodized point spread functions (aPSF) oriented along the\
            directions of all particles in the voxel, used to predict the DWI\
            signal from the particle configuration.
        noapo: disable spherical convolution of fODF with apodized PSF, to\
            output a sum of delta functions rather than a sum of aPSFs.
        fiso: Predicted isotropic fractions of the tissues for which response\
            functions were provided with -riso. Typically, these are CSF and GM.
        eext: Residual external energy in every voxel.
        etrend: internal and external energy trend and cooling statistics.
        balance: balance internal and external energy. (default = 0)\
            Negative values give more weight to the internal energy, positive\
            to the external energy.
        density: set the desired density of the free Poisson process. (default\
            = 1).
        prob: set the probabilities of generating birth, death, randshift,\
            optshift and connect proposals respectively. (default =\
            0.25,0.05,0.25,0.1,0.35).
        beta: set the width of the Hanning interpolation window. (in [0, 1],\
            default = 0)\
            If used, a mask is required, and this mask must keep at least one\
            voxel distance to the image bounding box.
        lambda_: set the weight of the internal energy directly. (default = 1)\
            If provided, any value of -balance will be ignored.
        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 `TckglobalOutputs`).
    """
    params = tckglobal_params(
        grad=grad,
        mask=mask,
        riso=riso,
        lmax=lmax,
        length=length,
        weight=weight,
        ppot=ppot,
        cpot=cpot,
        t0=t0,
        t1=t1,
        niter=niter,
        fod=fod,
        noapo=noapo,
        fiso=fiso,
        eext=eext,
        etrend=etrend,
        balance=balance,
        density=density,
        prob=prob,
        beta=beta,
        lambda_=lambda_,
        info=info,
        quiet=quiet,
        debug=debug,
        force=force,
        nthreads=nthreads,
        config=config,
        help_=help_,
        version=version,
        source=source,
        response=response,
        tracks=tracks,
    )
    return tckglobal_execute(params, runner)


__all__ = [
    "TCKGLOBAL_METADATA",
    "TckglobalConfigParamsDict",
    "TckglobalConfigParamsDictTagged",
    "TckglobalOutputs",
    "TckglobalParamsDict",
    "TckglobalParamsDictTagged",
    "TckglobalRisoParamsDict",
    "TckglobalRisoParamsDictTagged",
    "tckglobal",
    "tckglobal_config",
    "tckglobal_execute",
    "tckglobal_params",
    "tckglobal_riso",
]
