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

import typing
import pathlib
from styxdefs import *

CIFTI_GRADIENT_METADATA = Metadata(
    id="d2460b1cd46e52f13e61657937e6834a86e13b49.workbench",
    name="cifti-gradient",
    package="workbench",
    container_image_tag="nx10x/workbench:2.1.0",
)


_CiftiGradientLeftSurfaceParamsDictNoTag = typing.TypedDict('_CiftiGradientLeftSurfaceParamsDictNoTag', {
    "surface": InputPathType,
    "area-metric": typing.NotRequired[InputPathType | None],
})
CiftiGradientLeftSurfaceParamsDictTagged = typing.TypedDict('CiftiGradientLeftSurfaceParamsDictTagged', {
    "@type": typing.Literal["left-surface"],
    "surface": InputPathType,
    "area-metric": typing.NotRequired[InputPathType | None],
})
CiftiGradientLeftSurfaceParamsDict = _CiftiGradientLeftSurfaceParamsDictNoTag | CiftiGradientLeftSurfaceParamsDictTagged


_CiftiGradientRightSurfaceParamsDictNoTag = typing.TypedDict('_CiftiGradientRightSurfaceParamsDictNoTag', {
    "surface": InputPathType,
    "area-metric": typing.NotRequired[InputPathType | None],
})
CiftiGradientRightSurfaceParamsDictTagged = typing.TypedDict('CiftiGradientRightSurfaceParamsDictTagged', {
    "@type": typing.Literal["right-surface"],
    "surface": InputPathType,
    "area-metric": typing.NotRequired[InputPathType | None],
})
CiftiGradientRightSurfaceParamsDict = _CiftiGradientRightSurfaceParamsDictNoTag | CiftiGradientRightSurfaceParamsDictTagged


_CiftiGradientCerebellumSurfaceParamsDictNoTag = typing.TypedDict('_CiftiGradientCerebellumSurfaceParamsDictNoTag', {
    "surface": InputPathType,
    "area-metric": typing.NotRequired[InputPathType | None],
})
CiftiGradientCerebellumSurfaceParamsDictTagged = typing.TypedDict('CiftiGradientCerebellumSurfaceParamsDictTagged', {
    "@type": typing.Literal["cerebellum-surface"],
    "surface": InputPathType,
    "area-metric": typing.NotRequired[InputPathType | None],
})
CiftiGradientCerebellumSurfaceParamsDict = _CiftiGradientCerebellumSurfaceParamsDictNoTag | CiftiGradientCerebellumSurfaceParamsDictTagged


_CiftiGradientVectorsParamsDictNoTag = typing.TypedDict('_CiftiGradientVectorsParamsDictNoTag', {
    "vectors-out": str,
})
CiftiGradientVectorsParamsDictTagged = typing.TypedDict('CiftiGradientVectorsParamsDictTagged', {
    "@type": typing.Literal["vectors"],
    "vectors-out": str,
})
CiftiGradientVectorsParamsDict = _CiftiGradientVectorsParamsDictNoTag | CiftiGradientVectorsParamsDictTagged


_CiftiGradientSurfaceParamsDictNoTag = typing.TypedDict('_CiftiGradientSurfaceParamsDictNoTag', {
    "structure": str,
    "surface": InputPathType,
    "area-metric": typing.NotRequired[InputPathType | None],
})
CiftiGradientSurfaceParamsDictTagged = typing.TypedDict('CiftiGradientSurfaceParamsDictTagged', {
    "@type": typing.Literal["surface"],
    "structure": str,
    "surface": InputPathType,
    "area-metric": typing.NotRequired[InputPathType | None],
})
CiftiGradientSurfaceParamsDict = _CiftiGradientSurfaceParamsDictNoTag | CiftiGradientSurfaceParamsDictTagged


_CiftiGradientParamsDictNoTag = typing.TypedDict('_CiftiGradientParamsDictNoTag', {
    "cifti": InputPathType,
    "direction": str,
    "cifti-out": str,
    "left-surface": typing.NotRequired[CiftiGradientLeftSurfaceParamsDict | None],
    "right-surface": typing.NotRequired[CiftiGradientRightSurfaceParamsDict | None],
    "cerebellum-surface": typing.NotRequired[CiftiGradientCerebellumSurfaceParamsDict | None],
    "vectors": typing.NotRequired[CiftiGradientVectorsParamsDict | None],
    "surface": typing.NotRequired[list[CiftiGradientSurfaceParamsDict] | None],
    "volume-kernel": typing.NotRequired[float | None],
    "surface-kernel": typing.NotRequired[float | None],
    "average-output": bool,
    "presmooth-fwhm": bool,
})
CiftiGradientParamsDictTagged = typing.TypedDict('CiftiGradientParamsDictTagged', {
    "@type": typing.Literal["workbench/cifti-gradient"],
    "cifti": InputPathType,
    "direction": str,
    "cifti-out": str,
    "left-surface": typing.NotRequired[CiftiGradientLeftSurfaceParamsDict | None],
    "right-surface": typing.NotRequired[CiftiGradientRightSurfaceParamsDict | None],
    "cerebellum-surface": typing.NotRequired[CiftiGradientCerebellumSurfaceParamsDict | None],
    "vectors": typing.NotRequired[CiftiGradientVectorsParamsDict | None],
    "surface": typing.NotRequired[list[CiftiGradientSurfaceParamsDict] | None],
    "volume-kernel": typing.NotRequired[float | None],
    "surface-kernel": typing.NotRequired[float | None],
    "average-output": bool,
    "presmooth-fwhm": bool,
})
CiftiGradientParamsDict = _CiftiGradientParamsDictNoTag | CiftiGradientParamsDictTagged


def cifti_gradient_left_surface(
    surface: InputPathType,
    area_metric: InputPathType | None = None,
) -> CiftiGradientLeftSurfaceParamsDictTagged:
    """
    Build parameters.
    
    Args:
        surface: the left surface file.
        area_metric: vertex areas to use instead of computing them from the\
            left surface\
            \
            the corrected vertex areas, as a metric.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "left-surface",
        "surface": surface,
    }
    if area_metric is not None:
        params["area-metric"] = area_metric
    return params


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


def cifti_gradient_left_surface_cargs(
    params: CiftiGradientLeftSurfaceParamsDict,
    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([
        "-left-surface",
        execution.input_file(params.get("surface", None))
    ])
    if params.get("area-metric", None) is not None:
        cargs.extend([
            "-left-corrected-areas",
            execution.input_file(params.get("area-metric", None))
        ])
    return cargs


def cifti_gradient_right_surface(
    surface: InputPathType,
    area_metric: InputPathType | None = None,
) -> CiftiGradientRightSurfaceParamsDictTagged:
    """
    Build parameters.
    
    Args:
        surface: the right surface file.
        area_metric: vertex areas to use instead of computing them from the\
            right surface\
            \
            the corrected vertex areas, as a metric.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "right-surface",
        "surface": surface,
    }
    if area_metric is not None:
        params["area-metric"] = area_metric
    return params


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


def cifti_gradient_right_surface_cargs(
    params: CiftiGradientRightSurfaceParamsDict,
    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([
        "-right-surface",
        execution.input_file(params.get("surface", None))
    ])
    if params.get("area-metric", None) is not None:
        cargs.extend([
            "-right-corrected-areas",
            execution.input_file(params.get("area-metric", None))
        ])
    return cargs


def cifti_gradient_cerebellum_surface(
    surface: InputPathType,
    area_metric: InputPathType | None = None,
) -> CiftiGradientCerebellumSurfaceParamsDictTagged:
    """
    Build parameters.
    
    Args:
        surface: the cerebellum surface file.
        area_metric: vertex areas to use instead of computing them from the\
            cerebellum surface\
            \
            the corrected vertex areas, as a metric.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "cerebellum-surface",
        "surface": surface,
    }
    if area_metric is not None:
        params["area-metric"] = area_metric
    return params


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


def cifti_gradient_cerebellum_surface_cargs(
    params: CiftiGradientCerebellumSurfaceParamsDict,
    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([
        "-cerebellum-surface",
        execution.input_file(params.get("surface", None))
    ])
    if params.get("area-metric", None) is not None:
        cargs.extend([
            "-cerebellum-corrected-areas",
            execution.input_file(params.get("area-metric", None))
        ])
    return cargs


class CiftiGradientVectorsOutputs(typing.NamedTuple):
    """
    Output object returned when calling `CiftiGradientVectorsParamsDict | None(...)`.
    """
    root: OutputPathType
    """Output root folder. This is the root folder for all outputs."""
    vectors_out: OutputPathType
    """the vectors, as a dscalar file"""


def cifti_gradient_vectors(
    vectors_out: str,
) -> CiftiGradientVectorsParamsDictTagged:
    """
    Build parameters.
    
    Args:
        vectors_out: the vectors, as a dscalar file.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "vectors",
        "vectors-out": vectors_out,
    }
    return params


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


def cifti_gradient_vectors_cargs(
    params: CiftiGradientVectorsParamsDict,
    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([
        "-vectors",
        params.get("vectors-out", None)
    ])
    return cargs


def cifti_gradient_vectors_outputs(
    params: CiftiGradientVectorsParamsDict,
    execution: Execution,
) -> CiftiGradientVectorsOutputs:
    """
    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 = CiftiGradientVectorsOutputs(
        root=execution.output_file("."),
        vectors_out=execution.output_file(params.get("vectors-out", None)),
    )
    return ret


def cifti_gradient_surface(
    structure: str,
    surface: InputPathType,
    area_metric: InputPathType | None = None,
) -> CiftiGradientSurfaceParamsDictTagged:
    """
    Build parameters.
    
    Args:
        structure: the surface structure name.
        surface: the surface file.
        area_metric: vertex areas to use instead of computing them from the\
            surface\
            \
            the corrected vertex areas, as a metric.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "surface",
        "structure": structure,
        "surface": surface,
    }
    if area_metric is not None:
        params["area-metric"] = area_metric
    return params


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


def cifti_gradient_surface_cargs(
    params: CiftiGradientSurfaceParamsDict,
    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([
        "-surface",
        params.get("structure", None),
        execution.input_file(params.get("surface", None))
    ])
    if params.get("area-metric", None) is not None:
        cargs.extend([
            "-corrected-areas",
            execution.input_file(params.get("area-metric", None))
        ])
    return cargs


class CiftiGradientOutputs(typing.NamedTuple):
    """
    Output object returned when calling `CiftiGradientParamsDict(...)`.
    """
    root: OutputPathType
    """Output root folder. This is the root folder for all outputs."""
    cifti_out: OutputPathType
    """the output cifti"""
    vectors: CiftiGradientVectorsOutputs | None
    """Outputs from `cifti_gradient_vectors_outputs`."""


def cifti_gradient_params(
    cifti: InputPathType,
    direction: str,
    cifti_out: str,
    left_surface: CiftiGradientLeftSurfaceParamsDict | None = None,
    right_surface: CiftiGradientRightSurfaceParamsDict | None = None,
    cerebellum_surface: CiftiGradientCerebellumSurfaceParamsDict | None = None,
    vectors: CiftiGradientVectorsParamsDict | None = None,
    surface: list[CiftiGradientSurfaceParamsDict] | None = None,
    volume_kernel: float | None = None,
    surface_kernel: float | None = None,
    average_output: bool = False,
    presmooth_fwhm: bool = False,
) -> CiftiGradientParamsDictTagged:
    """
    Build parameters.
    
    Args:
        cifti: the input cifti.
        direction: which dimension to take the gradient along, ROW or COLUMN.
        cifti_out: the output cifti.
        left_surface: specify the left surface to use.
        right_surface: specify the right surface to use.
        cerebellum_surface: specify the cerebellum surface to use.
        vectors: output gradient vectors.
        surface: specify a surface by structure name.
        volume_kernel: smooth on the surface before computing the gradient\
            \
            the size of the gaussian volume smoothing kernel in mm, as sigma by\
            default.
        surface_kernel: smooth on the surface before computing the gradient\
            \
            the size of the gaussian surface smoothing kernel in mm, as sigma\
            by default.
        average_output: output the average of the gradient magnitude maps\
            instead of each gradient map separately.
        presmooth_fwhm: smoothing kernel sizes are FWHM, not sigma.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "workbench/cifti-gradient",
        "cifti": cifti,
        "direction": direction,
        "cifti-out": cifti_out,
        "average-output": average_output,
        "presmooth-fwhm": presmooth_fwhm,
    }
    if left_surface is not None:
        params["left-surface"] = left_surface
    if right_surface is not None:
        params["right-surface"] = right_surface
    if cerebellum_surface is not None:
        params["cerebellum-surface"] = cerebellum_surface
    if vectors is not None:
        params["vectors"] = vectors
    if surface is not None:
        params["surface"] = surface
    if volume_kernel is not None:
        params["volume-kernel"] = volume_kernel
    if surface_kernel is not None:
        params["surface-kernel"] = surface_kernel
    return params


def cifti_gradient_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `CiftiGradientParamsDict` 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("cifti", None) is None:
        raise StyxValidationError("`cifti` must not be None")
    if not isinstance(params["cifti"], (pathlib.Path, str)):
        raise StyxValidationError(f'`cifti` has the wrong type: Received `{type(params.get("cifti", None))}` expected `InputPathType`')
    if params.get("direction", None) is None:
        raise StyxValidationError("`direction` must not be None")
    if not isinstance(params["direction"], str):
        raise StyxValidationError(f'`direction` has the wrong type: Received `{type(params.get("direction", None))}` expected `str`')
    if params.get("cifti-out", None) is None:
        raise StyxValidationError("`cifti-out` must not be None")
    if not isinstance(params["cifti-out"], str):
        raise StyxValidationError(f'`cifti-out` has the wrong type: Received `{type(params.get("cifti-out", None))}` expected `str`')
    if params.get("left-surface", None) is not None:
        cifti_gradient_left_surface_validate(params["left-surface"])
    if params.get("right-surface", None) is not None:
        cifti_gradient_right_surface_validate(params["right-surface"])
    if params.get("cerebellum-surface", None) is not None:
        cifti_gradient_cerebellum_surface_validate(params["cerebellum-surface"])
    if params.get("vectors", None) is not None:
        cifti_gradient_vectors_validate(params["vectors"])
    if params.get("surface", None) is not None:
        if not isinstance(params["surface"], list):
            raise StyxValidationError(f'`surface` has the wrong type: Received `{type(params.get("surface", None))}` expected `list[CiftiGradientSurfaceParamsDict] | None`')
        for e in params["surface"]:
            cifti_gradient_surface_validate(e)
    if params.get("volume-kernel", None) is not None:
        if not isinstance(params["volume-kernel"], (float, int)):
            raise StyxValidationError(f'`volume-kernel` has the wrong type: Received `{type(params.get("volume-kernel", None))}` expected `float | None`')
    if params.get("surface-kernel", None) is not None:
        if not isinstance(params["surface-kernel"], (float, int)):
            raise StyxValidationError(f'`surface-kernel` has the wrong type: Received `{type(params.get("surface-kernel", None))}` expected `float | None`')
    if params.get("average-output", False) is None:
        raise StyxValidationError("`average-output` must not be None")
    if not isinstance(params["average-output"], bool):
        raise StyxValidationError(f'`average-output` has the wrong type: Received `{type(params.get("average-output", False))}` expected `bool`')
    if params.get("presmooth-fwhm", False) is None:
        raise StyxValidationError("`presmooth-fwhm` must not be None")
    if not isinstance(params["presmooth-fwhm"], bool):
        raise StyxValidationError(f'`presmooth-fwhm` has the wrong type: Received `{type(params.get("presmooth-fwhm", False))}` expected `bool`')


def cifti_gradient_cargs(
    params: CiftiGradientParamsDict,
    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",
        "-cifti-gradient"
    ])
    cargs.append(execution.input_file(params.get("cifti", None)))
    cargs.append(params.get("direction", None))
    cargs.append(params.get("cifti-out", None))
    if params.get("left-surface", None) is not None or params.get("right-surface", None) is not None or params.get("cerebellum-surface", None) is not None or params.get("vectors", None) is not None or params.get("surface", None) is not None:
        cargs.extend([
            *(cifti_gradient_left_surface_cargs(params.get("left-surface", None), execution) if (params.get("left-surface", None) is not None) else []),
            *(cifti_gradient_right_surface_cargs(params.get("right-surface", None), execution) if (params.get("right-surface", None) is not None) else []),
            *(cifti_gradient_cerebellum_surface_cargs(params.get("cerebellum-surface", None), execution) if (params.get("cerebellum-surface", None) is not None) else []),
            *(cifti_gradient_vectors_cargs(params.get("vectors", None), execution) if (params.get("vectors", None) is not None) else []),
            *([a for c in [cifti_gradient_surface_cargs(s, execution) for s in params.get("surface", None)] for a in c] if (params.get("surface", None) is not None) else [])
        ])
    if params.get("volume-kernel", None) is not None:
        cargs.extend([
            "-volume-presmooth",
            str(params.get("volume-kernel", None))
        ])
    if params.get("surface-kernel", None) is not None:
        cargs.extend([
            "-surface-presmooth",
            str(params.get("surface-kernel", None))
        ])
    if params.get("average-output", False):
        cargs.append("-average-output")
    if params.get("presmooth-fwhm", False):
        cargs.append("-presmooth-fwhm")
    return cargs


def cifti_gradient_outputs(
    params: CiftiGradientParamsDict,
    execution: Execution,
) -> CiftiGradientOutputs:
    """
    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 = CiftiGradientOutputs(
        root=execution.output_file("."),
        cifti_out=execution.output_file(params.get("cifti-out", None)),
        vectors=cifti_gradient_vectors_outputs(params.get("vectors"), execution) if params.get("vectors") else None,
    )
    return ret


def cifti_gradient_execute(
    params: CiftiGradientParamsDict,
    runner: Runner | None = None,
) -> CiftiGradientOutputs:
    """
    TAKE GRADIENT OF A CIFTI FILE.
    
    Performs gradient calculation on each component of the cifti file, and
    optionally averages the resulting gradients. The -vectors and
    -average-output options may not be used together. You must specify a surface
    for each surface structure in the cifti file. The COLUMN direction should be
    faster, and is the direction that works on dtseries. For dconn, you probably
    want ROW, unless you are using -average-output.
    
    The <structure> argument to -surface must be one of the following strings:
    
    CORTEX_LEFT
    CORTEX_RIGHT
    CEREBELLUM
    ACCUMBENS_LEFT
    ACCUMBENS_RIGHT
    ALL_GREY_MATTER
    ALL_WHITE_MATTER
    AMYGDALA_LEFT
    AMYGDALA_RIGHT
    BRAIN_STEM
    CAUDATE_LEFT
    CAUDATE_RIGHT
    CEREBELLAR_WHITE_MATTER_LEFT
    CEREBELLAR_WHITE_MATTER_RIGHT
    CEREBELLUM_LEFT
    CEREBELLUM_RIGHT
    CEREBRAL_WHITE_MATTER_LEFT
    CEREBRAL_WHITE_MATTER_RIGHT
    CORTEX
    DIENCEPHALON_VENTRAL_LEFT
    DIENCEPHALON_VENTRAL_RIGHT
    HIPPOCAMPUS_LEFT
    HIPPOCAMPUS_RIGHT
    HIPPOCAMPUS_DENTATE_LEFT
    HIPPOCAMPUS_DENTATE_RIGHT
    INVALID
    OTHER
    OTHER_GREY_MATTER
    OTHER_WHITE_MATTER
    PALLIDUM_LEFT
    PALLIDUM_RIGHT
    PUTAMEN_LEFT
    PUTAMEN_RIGHT
    THALAMUS_LEFT
    THALAMUS_RIGHT.
    
    Args:
        params: The parameters.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `CiftiGradientOutputs`).
    """
    cifti_gradient_validate(params)
    runner = runner or get_global_runner()
    execution = runner.start_execution(CIFTI_GRADIENT_METADATA)
    params = execution.params(params)
    cargs = cifti_gradient_cargs(params, execution)
    ret = cifti_gradient_outputs(params, execution)
    execution.run(cargs)
    return ret


def cifti_gradient(
    cifti: InputPathType,
    direction: str,
    cifti_out: str,
    left_surface: CiftiGradientLeftSurfaceParamsDict | None = None,
    right_surface: CiftiGradientRightSurfaceParamsDict | None = None,
    cerebellum_surface: CiftiGradientCerebellumSurfaceParamsDict | None = None,
    vectors: CiftiGradientVectorsParamsDict | None = None,
    surface: list[CiftiGradientSurfaceParamsDict] | None = None,
    volume_kernel: float | None = None,
    surface_kernel: float | None = None,
    average_output: bool = False,
    presmooth_fwhm: bool = False,
    runner: Runner | None = None,
) -> CiftiGradientOutputs:
    """
    TAKE GRADIENT OF A CIFTI FILE.
    
    Performs gradient calculation on each component of the cifti file, and
    optionally averages the resulting gradients. The -vectors and
    -average-output options may not be used together. You must specify a surface
    for each surface structure in the cifti file. The COLUMN direction should be
    faster, and is the direction that works on dtseries. For dconn, you probably
    want ROW, unless you are using -average-output.
    
    The <structure> argument to -surface must be one of the following strings:
    
    CORTEX_LEFT
    CORTEX_RIGHT
    CEREBELLUM
    ACCUMBENS_LEFT
    ACCUMBENS_RIGHT
    ALL_GREY_MATTER
    ALL_WHITE_MATTER
    AMYGDALA_LEFT
    AMYGDALA_RIGHT
    BRAIN_STEM
    CAUDATE_LEFT
    CAUDATE_RIGHT
    CEREBELLAR_WHITE_MATTER_LEFT
    CEREBELLAR_WHITE_MATTER_RIGHT
    CEREBELLUM_LEFT
    CEREBELLUM_RIGHT
    CEREBRAL_WHITE_MATTER_LEFT
    CEREBRAL_WHITE_MATTER_RIGHT
    CORTEX
    DIENCEPHALON_VENTRAL_LEFT
    DIENCEPHALON_VENTRAL_RIGHT
    HIPPOCAMPUS_LEFT
    HIPPOCAMPUS_RIGHT
    HIPPOCAMPUS_DENTATE_LEFT
    HIPPOCAMPUS_DENTATE_RIGHT
    INVALID
    OTHER
    OTHER_GREY_MATTER
    OTHER_WHITE_MATTER
    PALLIDUM_LEFT
    PALLIDUM_RIGHT
    PUTAMEN_LEFT
    PUTAMEN_RIGHT
    THALAMUS_LEFT
    THALAMUS_RIGHT.
    
    Args:
        cifti: the input cifti.
        direction: which dimension to take the gradient along, ROW or COLUMN.
        cifti_out: the output cifti.
        left_surface: specify the left surface to use.
        right_surface: specify the right surface to use.
        cerebellum_surface: specify the cerebellum surface to use.
        vectors: output gradient vectors.
        surface: specify a surface by structure name.
        volume_kernel: smooth on the surface before computing the gradient\
            \
            the size of the gaussian volume smoothing kernel in mm, as sigma by\
            default.
        surface_kernel: smooth on the surface before computing the gradient\
            \
            the size of the gaussian surface smoothing kernel in mm, as sigma\
            by default.
        average_output: output the average of the gradient magnitude maps\
            instead of each gradient map separately.
        presmooth_fwhm: smoothing kernel sizes are FWHM, not sigma.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `CiftiGradientOutputs`).
    """
    params = cifti_gradient_params(
        cifti=cifti,
        direction=direction,
        cifti_out=cifti_out,
        left_surface=left_surface,
        right_surface=right_surface,
        cerebellum_surface=cerebellum_surface,
        vectors=vectors,
        surface=surface,
        volume_kernel=volume_kernel,
        surface_kernel=surface_kernel,
        average_output=average_output,
        presmooth_fwhm=presmooth_fwhm,
    )
    return cifti_gradient_execute(params, runner)


__all__ = [
    "CIFTI_GRADIENT_METADATA",
    "CiftiGradientCerebellumSurfaceParamsDict",
    "CiftiGradientCerebellumSurfaceParamsDictTagged",
    "CiftiGradientLeftSurfaceParamsDict",
    "CiftiGradientLeftSurfaceParamsDictTagged",
    "CiftiGradientOutputs",
    "CiftiGradientParamsDict",
    "CiftiGradientParamsDictTagged",
    "CiftiGradientRightSurfaceParamsDict",
    "CiftiGradientRightSurfaceParamsDictTagged",
    "CiftiGradientSurfaceParamsDict",
    "CiftiGradientSurfaceParamsDictTagged",
    "CiftiGradientVectorsOutputs",
    "CiftiGradientVectorsParamsDict",
    "CiftiGradientVectorsParamsDictTagged",
    "cifti_gradient",
    "cifti_gradient_cerebellum_surface",
    "cifti_gradient_execute",
    "cifti_gradient_left_surface",
    "cifti_gradient_params",
    "cifti_gradient_right_surface",
    "cifti_gradient_surface",
    "cifti_gradient_vectors",
]
