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

import typing
import pathlib
from styxdefs import *

CIFTI_PARCELLATE_METADATA = Metadata(
    id="7b2f49ca19798d787ca04a1e72ba218c146a3ab4.workbench",
    name="cifti-parcellate",
    package="workbench",
    container_image_tag="nx10x/workbench:2.1.0",
)


_CiftiParcellateSpatialWeightsParamsDictNoTag = typing.TypedDict('_CiftiParcellateSpatialWeightsParamsDictNoTag', {
    "cerebellum-metric": typing.NotRequired[InputPathType | None],
    "right-metric": typing.NotRequired[InputPathType | None],
    "left-metric": typing.NotRequired[InputPathType | None],
    "cerebellum-surf": typing.NotRequired[InputPathType | None],
    "right-surf": typing.NotRequired[InputPathType | None],
    "left-surf": typing.NotRequired[InputPathType | None],
})
CiftiParcellateSpatialWeightsParamsDictTagged = typing.TypedDict('CiftiParcellateSpatialWeightsParamsDictTagged', {
    "@type": typing.Literal["spatial-weights"],
    "cerebellum-metric": typing.NotRequired[InputPathType | None],
    "right-metric": typing.NotRequired[InputPathType | None],
    "left-metric": typing.NotRequired[InputPathType | None],
    "cerebellum-surf": typing.NotRequired[InputPathType | None],
    "right-surf": typing.NotRequired[InputPathType | None],
    "left-surf": typing.NotRequired[InputPathType | None],
})
CiftiParcellateSpatialWeightsParamsDict = _CiftiParcellateSpatialWeightsParamsDictNoTag | CiftiParcellateSpatialWeightsParamsDictTagged


_CiftiParcellateExcludeOutliersParamsDictNoTag = typing.TypedDict('_CiftiParcellateExcludeOutliersParamsDictNoTag', {
    "sigma-below": float,
    "sigma-above": float,
})
CiftiParcellateExcludeOutliersParamsDictTagged = typing.TypedDict('CiftiParcellateExcludeOutliersParamsDictTagged', {
    "@type": typing.Literal["exclude-outliers"],
    "sigma-below": float,
    "sigma-above": float,
})
CiftiParcellateExcludeOutliersParamsDict = _CiftiParcellateExcludeOutliersParamsDictNoTag | CiftiParcellateExcludeOutliersParamsDictTagged


_CiftiParcellateNonemptyMaskOutParamsDictNoTag = typing.TypedDict('_CiftiParcellateNonemptyMaskOutParamsDictNoTag', {
    "mask-out": str,
})
CiftiParcellateNonemptyMaskOutParamsDictTagged = typing.TypedDict('CiftiParcellateNonemptyMaskOutParamsDictTagged', {
    "@type": typing.Literal["nonempty-mask-out"],
    "mask-out": str,
})
CiftiParcellateNonemptyMaskOutParamsDict = _CiftiParcellateNonemptyMaskOutParamsDictNoTag | CiftiParcellateNonemptyMaskOutParamsDictTagged


_CiftiParcellateParamsDictNoTag = typing.TypedDict('_CiftiParcellateParamsDictNoTag', {
    "cifti-in": InputPathType,
    "cifti-label": InputPathType,
    "direction": str,
    "cifti-out": str,
    "spatial-weights": typing.NotRequired[CiftiParcellateSpatialWeightsParamsDict | None],
    "exclude-outliers": typing.NotRequired[CiftiParcellateExcludeOutliersParamsDict | None],
    "nonempty-mask-out": typing.NotRequired[CiftiParcellateNonemptyMaskOutParamsDict | None],
    "value": typing.NotRequired[float | None],
    "method": typing.NotRequired[str | None],
    "weight-cifti": typing.NotRequired[InputPathType | None],
    "include-empty": bool,
    "legacy-mode": bool,
    "only-numeric": bool,
})
CiftiParcellateParamsDictTagged = typing.TypedDict('CiftiParcellateParamsDictTagged', {
    "@type": typing.Literal["workbench/cifti-parcellate"],
    "cifti-in": InputPathType,
    "cifti-label": InputPathType,
    "direction": str,
    "cifti-out": str,
    "spatial-weights": typing.NotRequired[CiftiParcellateSpatialWeightsParamsDict | None],
    "exclude-outliers": typing.NotRequired[CiftiParcellateExcludeOutliersParamsDict | None],
    "nonempty-mask-out": typing.NotRequired[CiftiParcellateNonemptyMaskOutParamsDict | None],
    "value": typing.NotRequired[float | None],
    "method": typing.NotRequired[str | None],
    "weight-cifti": typing.NotRequired[InputPathType | None],
    "include-empty": bool,
    "legacy-mode": bool,
    "only-numeric": bool,
})
CiftiParcellateParamsDict = _CiftiParcellateParamsDictNoTag | CiftiParcellateParamsDictTagged


def cifti_parcellate_spatial_weights(
    cerebellum_metric: InputPathType | None = None,
    right_metric: InputPathType | None = None,
    left_metric: InputPathType | None = None,
    cerebellum_surf: InputPathType | None = None,
    right_surf: InputPathType | None = None,
    left_surf: InputPathType | None = None,
) -> CiftiParcellateSpatialWeightsParamsDictTagged:
    """
    Build parameters.
    
    Args:
        cerebellum_metric: use a metric file for cerebellum vertex weights\
            \
            metric file containing cerebellum vertex weights.
        right_metric: use a metric file for right vertex weights\
            \
            metric file containing right vertex weights.
        left_metric: use a metric file for left vertex weights\
            \
            metric file containing left vertex weights.
        cerebellum_surf: use a surface for cerebellum vertex areas\
            \
            the cerebellum surface to use, areas are in mm^2.
        right_surf: use a surface for right vertex areas\
            \
            the right surface to use, areas are in mm^2.
        left_surf: use a surface for left vertex areas\
            \
            the left surface to use, areas are in mm^2.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "spatial-weights",
    }
    if cerebellum_metric is not None:
        params["cerebellum-metric"] = cerebellum_metric
    if right_metric is not None:
        params["right-metric"] = right_metric
    if left_metric is not None:
        params["left-metric"] = left_metric
    if cerebellum_surf is not None:
        params["cerebellum-surf"] = cerebellum_surf
    if right_surf is not None:
        params["right-surf"] = right_surf
    if left_surf is not None:
        params["left-surf"] = left_surf
    return params


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


def cifti_parcellate_spatial_weights_cargs(
    params: CiftiParcellateSpatialWeightsParamsDict,
    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("-spatial-weights")
    if params.get("cerebellum-metric", None) is not None:
        cargs.extend([
            "-cerebellum-area-metric",
            execution.input_file(params.get("cerebellum-metric", None))
        ])
    if params.get("right-metric", None) is not None:
        cargs.extend([
            "-right-area-metric",
            execution.input_file(params.get("right-metric", None))
        ])
    if params.get("left-metric", None) is not None:
        cargs.extend([
            "-left-area-metric",
            execution.input_file(params.get("left-metric", None))
        ])
    if params.get("cerebellum-surf", None) is not None:
        cargs.extend([
            "-cerebellum-area-surf",
            execution.input_file(params.get("cerebellum-surf", None))
        ])
    if params.get("right-surf", None) is not None:
        cargs.extend([
            "-right-area-surf",
            execution.input_file(params.get("right-surf", None))
        ])
    if params.get("left-surf", None) is not None:
        cargs.extend([
            "-left-area-surf",
            execution.input_file(params.get("left-surf", None))
        ])
    return cargs


def cifti_parcellate_exclude_outliers(
    sigma_below: float,
    sigma_above: float,
) -> CiftiParcellateExcludeOutliersParamsDictTagged:
    """
    Build parameters.
    
    Args:
        sigma_below: number of standard deviations below the mean to include.
        sigma_above: number of standard deviations above the mean to include.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "exclude-outliers",
        "sigma-below": sigma_below,
        "sigma-above": sigma_above,
    }
    return params


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


def cifti_parcellate_exclude_outliers_cargs(
    params: CiftiParcellateExcludeOutliersParamsDict,
    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([
        "-exclude-outliers",
        str(params.get("sigma-below", None)),
        str(params.get("sigma-above", None))
    ])
    return cargs


class CiftiParcellateNonemptyMaskOutOutputs(typing.NamedTuple):
    """
    Output object returned when calling `CiftiParcellateNonemptyMaskOutParamsDict | None(...)`.
    """
    root: OutputPathType
    """Output root folder. This is the root folder for all outputs."""
    mask_out: OutputPathType
    """the output mask file"""


def cifti_parcellate_nonempty_mask_out(
    mask_out: str,
) -> CiftiParcellateNonemptyMaskOutParamsDictTagged:
    """
    Build parameters.
    
    Args:
        mask_out: the output mask file.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "nonempty-mask-out",
        "mask-out": mask_out,
    }
    return params


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


def cifti_parcellate_nonempty_mask_out_cargs(
    params: CiftiParcellateNonemptyMaskOutParamsDict,
    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([
        "-nonempty-mask-out",
        params.get("mask-out", None)
    ])
    return cargs


def cifti_parcellate_nonempty_mask_out_outputs(
    params: CiftiParcellateNonemptyMaskOutParamsDict,
    execution: Execution,
) -> CiftiParcellateNonemptyMaskOutOutputs:
    """
    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 = CiftiParcellateNonemptyMaskOutOutputs(
        root=execution.output_file("."),
        mask_out=execution.output_file(params.get("mask-out", None)),
    )
    return ret


class CiftiParcellateOutputs(typing.NamedTuple):
    """
    Output object returned when calling `CiftiParcellateParamsDict(...)`.
    """
    root: OutputPathType
    """Output root folder. This is the root folder for all outputs."""
    cifti_out: OutputPathType
    """output cifti file"""
    nonempty_mask_out: CiftiParcellateNonemptyMaskOutOutputs | None
    """Outputs from `cifti_parcellate_nonempty_mask_out_outputs`."""


def cifti_parcellate_params(
    cifti_in: InputPathType,
    cifti_label: InputPathType,
    direction: str,
    cifti_out: str,
    spatial_weights: CiftiParcellateSpatialWeightsParamsDict | None = None,
    exclude_outliers: CiftiParcellateExcludeOutliersParamsDict | None = None,
    nonempty_mask_out: CiftiParcellateNonemptyMaskOutParamsDict | None = None,
    value: float | None = None,
    method: str | None = None,
    weight_cifti: InputPathType | None = None,
    include_empty: bool = False,
    legacy_mode: bool = False,
    only_numeric: bool = False,
) -> CiftiParcellateParamsDictTagged:
    """
    Build parameters.
    
    Args:
        cifti_in: the cifti file to parcellate.
        cifti_label: a cifti label file to use for the parcellation.
        direction: which mapping to parcellate (integer, ROW, or COLUMN).
        cifti_out: output cifti file.
        spatial_weights: use voxel volume and either vertex areas or metric\
            files as weights.
        exclude_outliers: exclude non-numeric values and outliers from each\
            parcel by standard deviation.
        nonempty_mask_out: output a matching pscalar file that has 0s in empty\
            parcels, and 1s elsewhere.
        value: specify value to use in empty parcels (default 0)\
            \
            the value to fill empty parcels with.
        method: specify method of parcellation (default MEAN, or MODE if label\
            data)\
            \
            the method to use to assign parcel values from the values of member\
            brainordinates.
        weight_cifti: use a cifti file containing weights\
            \
            the weights to use, as a cifti file.
        include_empty: deprecated: now the default behavior.
        legacy_mode: use the old behavior, parcels are defined by the\
            intersection between labels and valid data, and empty parcels are\
            discarded.
        only_numeric: exclude non-numeric values.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "workbench/cifti-parcellate",
        "cifti-in": cifti_in,
        "cifti-label": cifti_label,
        "direction": direction,
        "cifti-out": cifti_out,
        "include-empty": include_empty,
        "legacy-mode": legacy_mode,
        "only-numeric": only_numeric,
    }
    if spatial_weights is not None:
        params["spatial-weights"] = spatial_weights
    if exclude_outliers is not None:
        params["exclude-outliers"] = exclude_outliers
    if nonempty_mask_out is not None:
        params["nonempty-mask-out"] = nonempty_mask_out
    if value is not None:
        params["value"] = value
    if method is not None:
        params["method"] = method
    if weight_cifti is not None:
        params["weight-cifti"] = weight_cifti
    return params


def cifti_parcellate_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `CiftiParcellateParamsDict` 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-in", None) is None:
        raise StyxValidationError("`cifti-in` must not be None")
    if not isinstance(params["cifti-in"], (pathlib.Path, str)):
        raise StyxValidationError(f'`cifti-in` has the wrong type: Received `{type(params.get("cifti-in", None))}` expected `InputPathType`')
    if params.get("cifti-label", None) is None:
        raise StyxValidationError("`cifti-label` must not be None")
    if not isinstance(params["cifti-label"], (pathlib.Path, str)):
        raise StyxValidationError(f'`cifti-label` has the wrong type: Received `{type(params.get("cifti-label", 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("spatial-weights", None) is not None:
        cifti_parcellate_spatial_weights_validate(params["spatial-weights"])
    if params.get("exclude-outliers", None) is not None:
        cifti_parcellate_exclude_outliers_validate(params["exclude-outliers"])
    if params.get("nonempty-mask-out", None) is not None:
        cifti_parcellate_nonempty_mask_out_validate(params["nonempty-mask-out"])
    if params.get("value", None) is not None:
        if not isinstance(params["value"], (float, int)):
            raise StyxValidationError(f'`value` has the wrong type: Received `{type(params.get("value", None))}` expected `float | None`')
    if params.get("method", None) is not None:
        if not isinstance(params["method"], str):
            raise StyxValidationError(f'`method` has the wrong type: Received `{type(params.get("method", None))}` expected `str | None`')
    if params.get("weight-cifti", None) is not None:
        if not isinstance(params["weight-cifti"], (pathlib.Path, str)):
            raise StyxValidationError(f'`weight-cifti` has the wrong type: Received `{type(params.get("weight-cifti", None))}` expected `InputPathType | None`')
    if params.get("include-empty", False) is None:
        raise StyxValidationError("`include-empty` must not be None")
    if not isinstance(params["include-empty"], bool):
        raise StyxValidationError(f'`include-empty` has the wrong type: Received `{type(params.get("include-empty", False))}` expected `bool`')
    if params.get("legacy-mode", False) is None:
        raise StyxValidationError("`legacy-mode` must not be None")
    if not isinstance(params["legacy-mode"], bool):
        raise StyxValidationError(f'`legacy-mode` has the wrong type: Received `{type(params.get("legacy-mode", False))}` expected `bool`')
    if params.get("only-numeric", False) is None:
        raise StyxValidationError("`only-numeric` must not be None")
    if not isinstance(params["only-numeric"], bool):
        raise StyxValidationError(f'`only-numeric` has the wrong type: Received `{type(params.get("only-numeric", False))}` expected `bool`')


def cifti_parcellate_cargs(
    params: CiftiParcellateParamsDict,
    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-parcellate"
    ])
    cargs.append(execution.input_file(params.get("cifti-in", None)))
    cargs.append(execution.input_file(params.get("cifti-label", None)))
    cargs.append(params.get("direction", None))
    cargs.append(params.get("cifti-out", None))
    if params.get("spatial-weights", None) is not None or params.get("exclude-outliers", None) is not None or params.get("nonempty-mask-out", None) is not None:
        cargs.extend([
            *(cifti_parcellate_spatial_weights_cargs(params.get("spatial-weights", None), execution) if (params.get("spatial-weights", None) is not None) else []),
            *(cifti_parcellate_exclude_outliers_cargs(params.get("exclude-outliers", None), execution) if (params.get("exclude-outliers", None) is not None) else []),
            *(cifti_parcellate_nonempty_mask_out_cargs(params.get("nonempty-mask-out", None), execution) if (params.get("nonempty-mask-out", None) is not None) else [])
        ])
    if params.get("value", None) is not None:
        cargs.extend([
            "-fill-value",
            str(params.get("value", None))
        ])
    if params.get("method", None) is not None:
        cargs.extend([
            "-method",
            params.get("method", None)
        ])
    if params.get("weight-cifti", None) is not None:
        cargs.extend([
            "-cifti-weights",
            execution.input_file(params.get("weight-cifti", None))
        ])
    if params.get("include-empty", False):
        cargs.append("-include-empty")
    if params.get("legacy-mode", False):
        cargs.append("-legacy-mode")
    if params.get("only-numeric", False):
        cargs.append("-only-numeric")
    return cargs


def cifti_parcellate_outputs(
    params: CiftiParcellateParamsDict,
    execution: Execution,
) -> CiftiParcellateOutputs:
    """
    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 = CiftiParcellateOutputs(
        root=execution.output_file("."),
        cifti_out=execution.output_file(params.get("cifti-out", None)),
        nonempty_mask_out=cifti_parcellate_nonempty_mask_out_outputs(params.get("nonempty-mask-out"), execution) if params.get("nonempty-mask-out") else None,
    )
    return ret


def cifti_parcellate_execute(
    params: CiftiParcellateParamsDict,
    runner: Runner | None = None,
) -> CiftiParcellateOutputs:
    """
    PARCELLATE A CIFTI FILE.
    
    Each label (other than the unlabeled key) in the cifti label file will be
    treated as a parcel, and all rows or columns of data within the parcel are
    averaged together to form the parcel's output row or column. If -legacy-mode
    is specified, parcels will be defined as the overlap between a label and the
    data, with no errors for missing data vertices or voxels, and empty parcels
    discarded. The direction can be either an integer starting from 1, or the
    strings 'ROW' or 'COLUMN'. For dtseries or dscalar, use COLUMN. If you are
    parcellating a dconn in both directions, parcellating by ROW first will use
    much less memory.
    
    NOTE: the parcels in the output file are sorted by the numeric label keys,
    in ascending order.
    
    The parameter to the -method option must be one of the following:
    
    MAX: the maximum value
    MIN: the minimum value
    INDEXMAX: the 1-based index of the maximum value
    INDEXMIN: the 1-based index of the minimum value
    SUM: add all values
    PRODUCT: multiply all values
    MEAN: the mean of the data
    STDEV: the standard deviation (N denominator)
    SAMPSTDEV: the sample standard deviation (N-1 denominator)
    VARIANCE: the variance of the data
    TSNR: mean divided by sample standard deviation (N-1 denominator)
    COV: sample standard deviation (N-1 denominator) divided by mean
    L2NORM: square root of sum of squares
    MEDIAN: the median of the data
    MODE: the mode of the data
    COUNT_NONZERO: the number of nonzero elements in the data
    
    The -*-weights options are mutually exclusive and may only be used with MEAN
    (default), SUM, STDEV, SAMPSTDEV, VARIANCE, MEDIAN, or MODE (default for
    label data).
    
    Args:
        params: The parameters.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `CiftiParcellateOutputs`).
    """
    cifti_parcellate_validate(params)
    runner = runner or get_global_runner()
    execution = runner.start_execution(CIFTI_PARCELLATE_METADATA)
    params = execution.params(params)
    cargs = cifti_parcellate_cargs(params, execution)
    ret = cifti_parcellate_outputs(params, execution)
    execution.run(cargs)
    return ret


def cifti_parcellate(
    cifti_in: InputPathType,
    cifti_label: InputPathType,
    direction: str,
    cifti_out: str,
    spatial_weights: CiftiParcellateSpatialWeightsParamsDict | None = None,
    exclude_outliers: CiftiParcellateExcludeOutliersParamsDict | None = None,
    nonempty_mask_out: CiftiParcellateNonemptyMaskOutParamsDict | None = None,
    value: float | None = None,
    method: str | None = None,
    weight_cifti: InputPathType | None = None,
    include_empty: bool = False,
    legacy_mode: bool = False,
    only_numeric: bool = False,
    runner: Runner | None = None,
) -> CiftiParcellateOutputs:
    """
    PARCELLATE A CIFTI FILE.
    
    Each label (other than the unlabeled key) in the cifti label file will be
    treated as a parcel, and all rows or columns of data within the parcel are
    averaged together to form the parcel's output row or column. If -legacy-mode
    is specified, parcels will be defined as the overlap between a label and the
    data, with no errors for missing data vertices or voxels, and empty parcels
    discarded. The direction can be either an integer starting from 1, or the
    strings 'ROW' or 'COLUMN'. For dtseries or dscalar, use COLUMN. If you are
    parcellating a dconn in both directions, parcellating by ROW first will use
    much less memory.
    
    NOTE: the parcels in the output file are sorted by the numeric label keys,
    in ascending order.
    
    The parameter to the -method option must be one of the following:
    
    MAX: the maximum value
    MIN: the minimum value
    INDEXMAX: the 1-based index of the maximum value
    INDEXMIN: the 1-based index of the minimum value
    SUM: add all values
    PRODUCT: multiply all values
    MEAN: the mean of the data
    STDEV: the standard deviation (N denominator)
    SAMPSTDEV: the sample standard deviation (N-1 denominator)
    VARIANCE: the variance of the data
    TSNR: mean divided by sample standard deviation (N-1 denominator)
    COV: sample standard deviation (N-1 denominator) divided by mean
    L2NORM: square root of sum of squares
    MEDIAN: the median of the data
    MODE: the mode of the data
    COUNT_NONZERO: the number of nonzero elements in the data
    
    The -*-weights options are mutually exclusive and may only be used with MEAN
    (default), SUM, STDEV, SAMPSTDEV, VARIANCE, MEDIAN, or MODE (default for
    label data).
    
    Args:
        cifti_in: the cifti file to parcellate.
        cifti_label: a cifti label file to use for the parcellation.
        direction: which mapping to parcellate (integer, ROW, or COLUMN).
        cifti_out: output cifti file.
        spatial_weights: use voxel volume and either vertex areas or metric\
            files as weights.
        exclude_outliers: exclude non-numeric values and outliers from each\
            parcel by standard deviation.
        nonempty_mask_out: output a matching pscalar file that has 0s in empty\
            parcels, and 1s elsewhere.
        value: specify value to use in empty parcels (default 0)\
            \
            the value to fill empty parcels with.
        method: specify method of parcellation (default MEAN, or MODE if label\
            data)\
            \
            the method to use to assign parcel values from the values of member\
            brainordinates.
        weight_cifti: use a cifti file containing weights\
            \
            the weights to use, as a cifti file.
        include_empty: deprecated: now the default behavior.
        legacy_mode: use the old behavior, parcels are defined by the\
            intersection between labels and valid data, and empty parcels are\
            discarded.
        only_numeric: exclude non-numeric values.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `CiftiParcellateOutputs`).
    """
    params = cifti_parcellate_params(
        cifti_in=cifti_in,
        cifti_label=cifti_label,
        direction=direction,
        cifti_out=cifti_out,
        spatial_weights=spatial_weights,
        exclude_outliers=exclude_outliers,
        nonempty_mask_out=nonempty_mask_out,
        value=value,
        method=method,
        weight_cifti=weight_cifti,
        include_empty=include_empty,
        legacy_mode=legacy_mode,
        only_numeric=only_numeric,
    )
    return cifti_parcellate_execute(params, runner)


__all__ = [
    "CIFTI_PARCELLATE_METADATA",
    "CiftiParcellateExcludeOutliersParamsDict",
    "CiftiParcellateExcludeOutliersParamsDictTagged",
    "CiftiParcellateNonemptyMaskOutOutputs",
    "CiftiParcellateNonemptyMaskOutParamsDict",
    "CiftiParcellateNonemptyMaskOutParamsDictTagged",
    "CiftiParcellateOutputs",
    "CiftiParcellateParamsDict",
    "CiftiParcellateParamsDictTagged",
    "CiftiParcellateSpatialWeightsParamsDict",
    "CiftiParcellateSpatialWeightsParamsDictTagged",
    "cifti_parcellate",
    "cifti_parcellate_exclude_outliers",
    "cifti_parcellate_execute",
    "cifti_parcellate_nonempty_mask_out",
    "cifti_parcellate_params",
    "cifti_parcellate_spatial_weights",
]
