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

import typing
import pathlib
from styxdefs import *

CIFTI_MATH_METADATA = Metadata(
    id="452fbf26e7e7dec769a52f1743e09cb940aeff81.boutiques",
    name="cifti-math",
    package="workbench",
    container_image_tag="brainlife/connectome_workbench:1.5.0-freesurfer-update",
)


CiftiMathSelectParameters = typing.TypedDict('CiftiMathSelectParameters', {
    "@type": typing.NotRequired[typing.Literal["select"]],
    "dim": int,
    "index": str,
    "opt_repeat": bool,
})
CiftiMathSelectParametersTagged = typing.TypedDict('CiftiMathSelectParametersTagged', {
    "@type": typing.Literal["select"],
    "dim": int,
    "index": str,
    "opt_repeat": bool,
})


CiftiMathVarParameters = typing.TypedDict('CiftiMathVarParameters', {
    "@type": typing.NotRequired[typing.Literal["var"]],
    "name": str,
    "cifti": InputPathType,
    "select": typing.NotRequired[list[CiftiMathSelectParameters] | None],
})
CiftiMathVarParametersTagged = typing.TypedDict('CiftiMathVarParametersTagged', {
    "@type": typing.Literal["var"],
    "name": str,
    "cifti": InputPathType,
    "select": typing.NotRequired[list[CiftiMathSelectParameters] | None],
})


CiftiMathParameters = typing.TypedDict('CiftiMathParameters', {
    "@type": typing.NotRequired[typing.Literal["workbench/cifti-math"]],
    "expression": str,
    "cifti_out": str,
    "opt_fixnan_replace": typing.NotRequired[float | None],
    "opt_override_mapping_check": bool,
    "var": typing.NotRequired[list[CiftiMathVarParameters] | None],
})
CiftiMathParametersTagged = typing.TypedDict('CiftiMathParametersTagged', {
    "@type": typing.Literal["workbench/cifti-math"],
    "expression": str,
    "cifti_out": str,
    "opt_fixnan_replace": typing.NotRequired[float | None],
    "opt_override_mapping_check": bool,
    "var": typing.NotRequired[list[CiftiMathVarParameters] | None],
})


def cifti_math_select_params(
    dim: int,
    index: str,
    opt_repeat: bool = False,
) -> CiftiMathSelectParametersTagged:
    """
    Build parameters.
    
    Args:
        dim: the dimension to select from (1-based).
        index: the index number (1-based) or map name to use.
        opt_repeat: repeat the selected values for each index of output in this\
            dimension.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "select",
        "dim": dim,
        "index": index,
        "opt_repeat": opt_repeat,
    }
    return params


def cifti_math_select_cargs(
    params: CiftiMathSelectParameters,
    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("-select")
    cargs.append(str(params.get("dim", None)))
    cargs.append(params.get("index", None))
    if params.get("opt_repeat", False):
        cargs.append("-repeat")
    return cargs


def cifti_math_var_params(
    name: str,
    cifti: InputPathType,
    select_: list[CiftiMathSelectParameters] | None = None,
) -> CiftiMathVarParametersTagged:
    """
    Build parameters.
    
    Args:
        name: the name of the variable, as used in the expression.
        cifti: the cifti file to use as this variable.
        select_: select a single index from a dimension.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "var",
        "name": name,
        "cifti": cifti,
    }
    if select_ is not None:
        params["select"] = select_
    return params


def cifti_math_var_cargs(
    params: CiftiMathVarParameters,
    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("-var")
    cargs.append(params.get("name", None))
    cargs.append(execution.input_file(params.get("cifti", None)))
    if params.get("select", None) is not None:
        cargs.extend([a for c in [cifti_math_select_cargs(s, execution) for s in params.get("select", None)] for a in c])
    return cargs


class CiftiMathOutputs(typing.NamedTuple):
    """
    Output object returned when calling `CiftiMathParameters(...)`.
    """
    root: OutputPathType
    """Output root folder. This is the root folder for all outputs."""
    cifti_out: OutputPathType
    """the output cifti file"""


def cifti_math_params(
    expression: str,
    cifti_out: str,
    opt_fixnan_replace: float | None = None,
    opt_override_mapping_check: bool = False,
    var: list[CiftiMathVarParameters] | None = None,
) -> CiftiMathParametersTagged:
    """
    Build parameters.
    
    Args:
        expression: the expression to evaluate, in quotes.
        cifti_out: the output cifti file.
        opt_fixnan_replace: replace NaN results with a value: value to replace\
            NaN with.
        opt_override_mapping_check: don't check the mappings for compatibility,\
            only check length.
        var: a cifti file to use as a variable.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "workbench/cifti-math",
        "expression": expression,
        "cifti_out": cifti_out,
        "opt_override_mapping_check": opt_override_mapping_check,
    }
    if opt_fixnan_replace is not None:
        params["opt_fixnan_replace"] = opt_fixnan_replace
    if var is not None:
        params["var"] = var
    return params


def cifti_math_cargs(
    params: CiftiMathParameters,
    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("wb_command")
    cargs.append("-cifti-math")
    cargs.append(params.get("expression", None))
    cargs.append(params.get("cifti_out", None))
    if params.get("opt_fixnan_replace", None) is not None:
        cargs.extend([
            "-fixnan",
            str(params.get("opt_fixnan_replace", None))
        ])
    if params.get("opt_override_mapping_check", False):
        cargs.append("-override-mapping-check")
    if params.get("var", None) is not None:
        cargs.extend([a for c in [cifti_math_var_cargs(s, execution) for s in params.get("var", None)] for a in c])
    return cargs


def cifti_math_outputs(
    params: CiftiMathParameters,
    execution: Execution,
) -> CiftiMathOutputs:
    """
    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 = CiftiMathOutputs(
        root=execution.output_file("."),
        cifti_out=execution.output_file(params.get("cifti_out", None)),
    )
    return ret


def cifti_math_execute(
    params: CiftiMathParameters,
    runner: Runner | None = None,
) -> CiftiMathOutputs:
    """
    cifti-math
    
    Evaluate expression on cifti files.
    
    This command evaluates <expression> at each matrix element independently.
    There must be at least one -var option (to get the output layout from), even
    if the <name> specified in it isn't used in <expression>.
    
    To select a single column from a 2D file (most cifti files are 2D), use
    -select 1 <index>, where <index> is 1-based. To select a single row from a
    2D file, use -select 2 <index>. Where -select is not used, the cifti files
    must have compatible mappings (e.g., brain models and parcels mappings must
    match exactly except for parcel names). Use -override-mapping-check to skip
    this checking.
    
    Filenames are not valid in <expression>, use a variable name and a -var
    option with matching <name> to specify an input file. The format of
    <expression> is as follows:
    
    Expressions consist of constants, variables, operators, parentheses, and
    functions, in infix notation, such as 'exp(-x + 3) * scale'. Variables are
    strings of any length, using the characters a-z, A-Z, 0-9, and _, but may
    not take the name of a named constant. Currently, there is only one named
    constant, PI. The operators are +, -, *, /, ^, >, <, >=, <=, ==, !=, !, &&,
    ||. These behave as in C, except that ^ is exponentiation, i.e. pow(x, y),
    and takes higher precedence than other binary operators (also, '-3^-4^-5'
    means '-(3^(-(4^-5)))'). The <=, >=, ==, and != operators are given a small
    amount of wiggle room, equal to one millionth of the smaller of the absolute
    values of the values being compared.
    
    Comparison and logical operators return 0 or 1, you can do masking with
    expressions like 'x * (mask > 0)'. For all logical operators, an input is
    considered true iff it is greater than 0. The expression '0 < x < 5' is not
    syntactically wrong, but it will NOT do what is desired, because it is
    evaluated left to right, i.e. '((0 < x) < 5)', which will always return 1,
    as both possible results of a comparison are less than 5. A warning is
    generated if an expression of this type is detected. Use something like 'x >
    0 && x < 5' to get the desired behavior.
    
    Whitespace between elements is ignored, ' sin ( 2 * x ) ' is equivalent to
    'sin(2*x)', but 's in(2*x)' is an error. Implied multiplication is not
    allowed, the expression '2x' will be parsed as a variable. Parentheses are
    (), do not use [] or {}. Functions require parentheses, the expression 'sin
    x' is an error.
    
    The following functions are supported:
    
    sin: 1 argument, the sine of the argument (units are radians)
    cos: 1 argument, the cosine of the argument (units are radians)
    tan: 1 argument, the tangent of the argument (units are radians)
    asin: 1 argument, the inverse of sine of the argument, in radians
    acos: 1 argument, the inverse of cosine of the argument, in radians
    atan: 1 argument, the inverse of tangent of the argument, in radians
    atan2: 2 arguments, atan2(y, x) returns the inverse of tangent of (y/x), in
    radians, determining quadrant by the sign of both arguments
    sinh: 1 argument, the hyperbolic sine of the argument
    cosh: 1 argument, the hyperbolic cosine of the argument
    tanh: 1 argument, the hyperbolic tangent of the argument
    asinh: 1 argument, the inverse hyperbolic sine of the argument
    acosh: 1 argument, the inverse hyperbolic cosine of the argument
    atanh: 1 argument, the inverse hyperbolic tangent of the argument
    sinc: 1 argument, sinc(0) = 1, sin(x) / x otherwise
    ln: 1 argument, the natural logarithm of the argument
    exp: 1 argument, the constant e raised to the power of the argument
    log: 1 argument, the base 10 logarithm of the argument
    log2: 1 argument, the base 2 logarithm of the argument
    sqrt: 1 argument, the square root of the argument
    abs: 1 argument, the absolute value of the argument
    floor: 1 argument, the largest integer not greater than the argument
    round: 1 argument, the nearest integer, with ties rounded away from zero
    ceil: 1 argument, the smallest integer not less than the argument
    min: 2 arguments, min(x, y) returns y if (x > y), x otherwise
    max: 2 arguments, max(x, y) returns y if (x < y), x otherwise
    mod: 2 arguments, mod(x, y) = x - y * floor(x / y), or 0 if y == 0
    clamp: 3 arguments, clamp(x, low, high) = min(max(x, low), high)
    .
    
    Author: Connectome Workbench Developers
    
    URL: https://github.com/Washington-University/workbench
    
    Args:
        params: The parameters.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `CiftiMathOutputs`).
    """
    runner = runner or get_global_runner()
    execution = runner.start_execution(CIFTI_MATH_METADATA)
    params = execution.params(params)
    cargs = cifti_math_cargs(params, execution)
    ret = cifti_math_outputs(params, execution)
    execution.run(cargs)
    return ret


def cifti_math(
    expression: str,
    cifti_out: str,
    opt_fixnan_replace: float | None = None,
    opt_override_mapping_check: bool = False,
    var: list[CiftiMathVarParameters] | None = None,
    runner: Runner | None = None,
) -> CiftiMathOutputs:
    """
    cifti-math
    
    Evaluate expression on cifti files.
    
    This command evaluates <expression> at each matrix element independently.
    There must be at least one -var option (to get the output layout from), even
    if the <name> specified in it isn't used in <expression>.
    
    To select a single column from a 2D file (most cifti files are 2D), use
    -select 1 <index>, where <index> is 1-based. To select a single row from a
    2D file, use -select 2 <index>. Where -select is not used, the cifti files
    must have compatible mappings (e.g., brain models and parcels mappings must
    match exactly except for parcel names). Use -override-mapping-check to skip
    this checking.
    
    Filenames are not valid in <expression>, use a variable name and a -var
    option with matching <name> to specify an input file. The format of
    <expression> is as follows:
    
    Expressions consist of constants, variables, operators, parentheses, and
    functions, in infix notation, such as 'exp(-x + 3) * scale'. Variables are
    strings of any length, using the characters a-z, A-Z, 0-9, and _, but may
    not take the name of a named constant. Currently, there is only one named
    constant, PI. The operators are +, -, *, /, ^, >, <, >=, <=, ==, !=, !, &&,
    ||. These behave as in C, except that ^ is exponentiation, i.e. pow(x, y),
    and takes higher precedence than other binary operators (also, '-3^-4^-5'
    means '-(3^(-(4^-5)))'). The <=, >=, ==, and != operators are given a small
    amount of wiggle room, equal to one millionth of the smaller of the absolute
    values of the values being compared.
    
    Comparison and logical operators return 0 or 1, you can do masking with
    expressions like 'x * (mask > 0)'. For all logical operators, an input is
    considered true iff it is greater than 0. The expression '0 < x < 5' is not
    syntactically wrong, but it will NOT do what is desired, because it is
    evaluated left to right, i.e. '((0 < x) < 5)', which will always return 1,
    as both possible results of a comparison are less than 5. A warning is
    generated if an expression of this type is detected. Use something like 'x >
    0 && x < 5' to get the desired behavior.
    
    Whitespace between elements is ignored, ' sin ( 2 * x ) ' is equivalent to
    'sin(2*x)', but 's in(2*x)' is an error. Implied multiplication is not
    allowed, the expression '2x' will be parsed as a variable. Parentheses are
    (), do not use [] or {}. Functions require parentheses, the expression 'sin
    x' is an error.
    
    The following functions are supported:
    
    sin: 1 argument, the sine of the argument (units are radians)
    cos: 1 argument, the cosine of the argument (units are radians)
    tan: 1 argument, the tangent of the argument (units are radians)
    asin: 1 argument, the inverse of sine of the argument, in radians
    acos: 1 argument, the inverse of cosine of the argument, in radians
    atan: 1 argument, the inverse of tangent of the argument, in radians
    atan2: 2 arguments, atan2(y, x) returns the inverse of tangent of (y/x), in
    radians, determining quadrant by the sign of both arguments
    sinh: 1 argument, the hyperbolic sine of the argument
    cosh: 1 argument, the hyperbolic cosine of the argument
    tanh: 1 argument, the hyperbolic tangent of the argument
    asinh: 1 argument, the inverse hyperbolic sine of the argument
    acosh: 1 argument, the inverse hyperbolic cosine of the argument
    atanh: 1 argument, the inverse hyperbolic tangent of the argument
    sinc: 1 argument, sinc(0) = 1, sin(x) / x otherwise
    ln: 1 argument, the natural logarithm of the argument
    exp: 1 argument, the constant e raised to the power of the argument
    log: 1 argument, the base 10 logarithm of the argument
    log2: 1 argument, the base 2 logarithm of the argument
    sqrt: 1 argument, the square root of the argument
    abs: 1 argument, the absolute value of the argument
    floor: 1 argument, the largest integer not greater than the argument
    round: 1 argument, the nearest integer, with ties rounded away from zero
    ceil: 1 argument, the smallest integer not less than the argument
    min: 2 arguments, min(x, y) returns y if (x > y), x otherwise
    max: 2 arguments, max(x, y) returns y if (x < y), x otherwise
    mod: 2 arguments, mod(x, y) = x - y * floor(x / y), or 0 if y == 0
    clamp: 3 arguments, clamp(x, low, high) = min(max(x, low), high)
    .
    
    Author: Connectome Workbench Developers
    
    URL: https://github.com/Washington-University/workbench
    
    Args:
        expression: the expression to evaluate, in quotes.
        cifti_out: the output cifti file.
        opt_fixnan_replace: replace NaN results with a value: value to replace\
            NaN with.
        opt_override_mapping_check: don't check the mappings for compatibility,\
            only check length.
        var: a cifti file to use as a variable.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `CiftiMathOutputs`).
    """
    params = cifti_math_params(
        expression=expression,
        cifti_out=cifti_out,
        opt_fixnan_replace=opt_fixnan_replace,
        opt_override_mapping_check=opt_override_mapping_check,
        var=var,
    )
    return cifti_math_execute(params, runner)


__all__ = [
    "CIFTI_MATH_METADATA",
    "CiftiMathOutputs",
    "cifti_math",
    "cifti_math_execute",
    "cifti_math_params",
    "cifti_math_select_params",
    "cifti_math_var_params",
]
