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

import typing
import pathlib
from styxdefs import *

CONVERT_MATRIX4_TO_MATRIX2_METADATA = Metadata(
    id="6b1c39b77ea63d80e9eaa7d762e583b3aa47688b.workbench",
    name="convert-matrix4-to-matrix2",
    package="workbench",
    container_image_tag="nx10x/workbench:2.1.0",
)


_ConvertMatrix4ToMatrix2DistancesParamsDictNoTag = typing.TypedDict('_ConvertMatrix4ToMatrix2DistancesParamsDictNoTag', {
    "distance-out": str,
})
ConvertMatrix4ToMatrix2DistancesParamsDictTagged = typing.TypedDict('ConvertMatrix4ToMatrix2DistancesParamsDictTagged', {
    "@type": typing.Literal["distances"],
    "distance-out": str,
})
ConvertMatrix4ToMatrix2DistancesParamsDict = _ConvertMatrix4ToMatrix2DistancesParamsDictNoTag | ConvertMatrix4ToMatrix2DistancesParamsDictTagged


_ConvertMatrix4ToMatrix2IndividualFibersParamsDictNoTag = typing.TypedDict('_ConvertMatrix4ToMatrix2IndividualFibersParamsDictNoTag', {
    "fiber-1": str,
    "fiber-2": str,
    "fiber-3": str,
})
ConvertMatrix4ToMatrix2IndividualFibersParamsDictTagged = typing.TypedDict('ConvertMatrix4ToMatrix2IndividualFibersParamsDictTagged', {
    "@type": typing.Literal["individual-fibers"],
    "fiber-1": str,
    "fiber-2": str,
    "fiber-3": str,
})
ConvertMatrix4ToMatrix2IndividualFibersParamsDict = _ConvertMatrix4ToMatrix2IndividualFibersParamsDictNoTag | ConvertMatrix4ToMatrix2IndividualFibersParamsDictTagged


_ConvertMatrix4ToMatrix2ParamsDictNoTag = typing.TypedDict('_ConvertMatrix4ToMatrix2ParamsDictNoTag', {
    "matrix4-wbsparse": str,
    "counts-out": str,
    "distances": typing.NotRequired[ConvertMatrix4ToMatrix2DistancesParamsDict | None],
    "individual-fibers": typing.NotRequired[ConvertMatrix4ToMatrix2IndividualFibersParamsDict | None],
})
ConvertMatrix4ToMatrix2ParamsDictTagged = typing.TypedDict('ConvertMatrix4ToMatrix2ParamsDictTagged', {
    "@type": typing.Literal["workbench/convert-matrix4-to-matrix2"],
    "matrix4-wbsparse": str,
    "counts-out": str,
    "distances": typing.NotRequired[ConvertMatrix4ToMatrix2DistancesParamsDict | None],
    "individual-fibers": typing.NotRequired[ConvertMatrix4ToMatrix2IndividualFibersParamsDict | None],
})
ConvertMatrix4ToMatrix2ParamsDict = _ConvertMatrix4ToMatrix2ParamsDictNoTag | ConvertMatrix4ToMatrix2ParamsDictTagged


class ConvertMatrix4ToMatrix2DistancesOutputs(typing.NamedTuple):
    """
    Output object returned when calling `ConvertMatrix4ToMatrix2DistancesParamsDict | None(...)`.
    """
    root: OutputPathType
    """Output root folder. This is the root folder for all outputs."""
    distance_out: OutputPathType
    """the distances, as a cifti file"""


def convert_matrix4_to_matrix2_distances(
    distance_out: str,
) -> ConvertMatrix4ToMatrix2DistancesParamsDictTagged:
    """
    Build parameters.
    
    Args:
        distance_out: the distances, as a cifti file.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "distances",
        "distance-out": distance_out,
    }
    return params


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


def convert_matrix4_to_matrix2_distances_cargs(
    params: ConvertMatrix4ToMatrix2DistancesParamsDict,
    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([
        "-distances",
        params.get("distance-out", None)
    ])
    return cargs


def convert_matrix4_to_matrix2_distances_outputs(
    params: ConvertMatrix4ToMatrix2DistancesParamsDict,
    execution: Execution,
) -> ConvertMatrix4ToMatrix2DistancesOutputs:
    """
    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 = ConvertMatrix4ToMatrix2DistancesOutputs(
        root=execution.output_file("."),
        distance_out=execution.output_file(params.get("distance-out", None)),
    )
    return ret


class ConvertMatrix4ToMatrix2IndividualFibersOutputs(typing.NamedTuple):
    """
    Output object returned when calling `ConvertMatrix4ToMatrix2IndividualFibersParamsDict | None(...)`.
    """
    root: OutputPathType
    """Output root folder. This is the root folder for all outputs."""
    fiber_1: OutputPathType
    """output file for first fiber"""
    fiber_2: OutputPathType
    """output file for second fiber"""
    fiber_3: OutputPathType
    """output file for third fiber"""


def convert_matrix4_to_matrix2_individual_fibers(
    fiber_1: str,
    fiber_2: str,
    fiber_3: str,
) -> ConvertMatrix4ToMatrix2IndividualFibersParamsDictTagged:
    """
    Build parameters.
    
    Args:
        fiber_1: output file for first fiber.
        fiber_2: output file for second fiber.
        fiber_3: output file for third fiber.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "individual-fibers",
        "fiber-1": fiber_1,
        "fiber-2": fiber_2,
        "fiber-3": fiber_3,
    }
    return params


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


def convert_matrix4_to_matrix2_individual_fibers_cargs(
    params: ConvertMatrix4ToMatrix2IndividualFibersParamsDict,
    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([
        "-individual-fibers",
        params.get("fiber-1", None),
        params.get("fiber-2", None),
        params.get("fiber-3", None)
    ])
    return cargs


def convert_matrix4_to_matrix2_individual_fibers_outputs(
    params: ConvertMatrix4ToMatrix2IndividualFibersParamsDict,
    execution: Execution,
) -> ConvertMatrix4ToMatrix2IndividualFibersOutputs:
    """
    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 = ConvertMatrix4ToMatrix2IndividualFibersOutputs(
        root=execution.output_file("."),
        fiber_1=execution.output_file(params.get("fiber-1", None)),
        fiber_2=execution.output_file(params.get("fiber-2", None)),
        fiber_3=execution.output_file(params.get("fiber-3", None)),
    )
    return ret


class ConvertMatrix4ToMatrix2Outputs(typing.NamedTuple):
    """
    Output object returned when calling `ConvertMatrix4ToMatrix2ParamsDict(...)`.
    """
    root: OutputPathType
    """Output root folder. This is the root folder for all outputs."""
    counts_out: OutputPathType
    """the total fiber counts, as a cifti file"""
    distances: ConvertMatrix4ToMatrix2DistancesOutputs | None
    """Outputs from `convert_matrix4_to_matrix2_distances_outputs`."""
    individual_fibers: ConvertMatrix4ToMatrix2IndividualFibersOutputs | None
    """Outputs from `convert_matrix4_to_matrix2_individual_fibers_outputs`."""


def convert_matrix4_to_matrix2_params(
    matrix4_wbsparse: str,
    counts_out: str,
    distances: ConvertMatrix4ToMatrix2DistancesParamsDict | None = None,
    individual_fibers: ConvertMatrix4ToMatrix2IndividualFibersParamsDict | None = None,
) -> ConvertMatrix4ToMatrix2ParamsDictTagged:
    """
    Build parameters.
    
    Args:
        matrix4_wbsparse: a wbsparse matrix4 file.
        counts_out: the total fiber counts, as a cifti file.
        distances: output average trajectory distance.
        individual_fibers: output files for each fiber direction.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "workbench/convert-matrix4-to-matrix2",
        "matrix4-wbsparse": matrix4_wbsparse,
        "counts-out": counts_out,
    }
    if distances is not None:
        params["distances"] = distances
    if individual_fibers is not None:
        params["individual-fibers"] = individual_fibers
    return params


def convert_matrix4_to_matrix2_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `ConvertMatrix4ToMatrix2ParamsDict` 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("matrix4-wbsparse", None) is None:
        raise StyxValidationError("`matrix4-wbsparse` must not be None")
    if not isinstance(params["matrix4-wbsparse"], str):
        raise StyxValidationError(f'`matrix4-wbsparse` has the wrong type: Received `{type(params.get("matrix4-wbsparse", None))}` expected `str`')
    if params.get("counts-out", None) is None:
        raise StyxValidationError("`counts-out` must not be None")
    if not isinstance(params["counts-out"], str):
        raise StyxValidationError(f'`counts-out` has the wrong type: Received `{type(params.get("counts-out", None))}` expected `str`')
    if params.get("distances", None) is not None:
        convert_matrix4_to_matrix2_distances_validate(params["distances"])
    if params.get("individual-fibers", None) is not None:
        convert_matrix4_to_matrix2_individual_fibers_validate(params["individual-fibers"])


def convert_matrix4_to_matrix2_cargs(
    params: ConvertMatrix4ToMatrix2ParamsDict,
    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",
        "-convert-matrix4-to-matrix2"
    ])
    cargs.append(params.get("matrix4-wbsparse", None))
    cargs.append(params.get("counts-out", None))
    if params.get("distances", None) is not None or params.get("individual-fibers", None) is not None:
        cargs.extend([
            *(convert_matrix4_to_matrix2_distances_cargs(params.get("distances", None), execution) if (params.get("distances", None) is not None) else []),
            *(convert_matrix4_to_matrix2_individual_fibers_cargs(params.get("individual-fibers", None), execution) if (params.get("individual-fibers", None) is not None) else [])
        ])
    return cargs


def convert_matrix4_to_matrix2_outputs(
    params: ConvertMatrix4ToMatrix2ParamsDict,
    execution: Execution,
) -> ConvertMatrix4ToMatrix2Outputs:
    """
    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 = ConvertMatrix4ToMatrix2Outputs(
        root=execution.output_file("."),
        counts_out=execution.output_file(params.get("counts-out", None)),
        distances=convert_matrix4_to_matrix2_distances_outputs(params.get("distances"), execution) if params.get("distances") else None,
        individual_fibers=convert_matrix4_to_matrix2_individual_fibers_outputs(params.get("individual-fibers"), execution) if params.get("individual-fibers") else None,
    )
    return ret


def convert_matrix4_to_matrix2_execute(
    params: ConvertMatrix4ToMatrix2ParamsDict,
    runner: Runner | None = None,
) -> ConvertMatrix4ToMatrix2Outputs:
    """
    GENERATES A MATRIX2 CIFTI FROM MATRIX4 WBSPARSE.
    
    This command makes a cifti file from the fiber counts in a matrix4 wbsparse
    file, and optionally a second cifti file from the distances. Note that while
    the total count is stored exactly, the per-fiber counts are stored as
    approximate fractions, so the output of -individual-fibers will contain
    nonintegers.
    
    Args:
        params: The parameters.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `ConvertMatrix4ToMatrix2Outputs`).
    """
    convert_matrix4_to_matrix2_validate(params)
    runner = runner or get_global_runner()
    execution = runner.start_execution(CONVERT_MATRIX4_TO_MATRIX2_METADATA)
    params = execution.params(params)
    cargs = convert_matrix4_to_matrix2_cargs(params, execution)
    ret = convert_matrix4_to_matrix2_outputs(params, execution)
    execution.run(cargs)
    return ret


def convert_matrix4_to_matrix2(
    matrix4_wbsparse: str,
    counts_out: str,
    distances: ConvertMatrix4ToMatrix2DistancesParamsDict | None = None,
    individual_fibers: ConvertMatrix4ToMatrix2IndividualFibersParamsDict | None = None,
    runner: Runner | None = None,
) -> ConvertMatrix4ToMatrix2Outputs:
    """
    GENERATES A MATRIX2 CIFTI FROM MATRIX4 WBSPARSE.
    
    This command makes a cifti file from the fiber counts in a matrix4 wbsparse
    file, and optionally a second cifti file from the distances. Note that while
    the total count is stored exactly, the per-fiber counts are stored as
    approximate fractions, so the output of -individual-fibers will contain
    nonintegers.
    
    Args:
        matrix4_wbsparse: a wbsparse matrix4 file.
        counts_out: the total fiber counts, as a cifti file.
        distances: output average trajectory distance.
        individual_fibers: output files for each fiber direction.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `ConvertMatrix4ToMatrix2Outputs`).
    """
    params = convert_matrix4_to_matrix2_params(
        matrix4_wbsparse=matrix4_wbsparse,
        counts_out=counts_out,
        distances=distances,
        individual_fibers=individual_fibers,
    )
    return convert_matrix4_to_matrix2_execute(params, runner)


__all__ = [
    "CONVERT_MATRIX4_TO_MATRIX2_METADATA",
    "ConvertMatrix4ToMatrix2DistancesOutputs",
    "ConvertMatrix4ToMatrix2DistancesParamsDict",
    "ConvertMatrix4ToMatrix2DistancesParamsDictTagged",
    "ConvertMatrix4ToMatrix2IndividualFibersOutputs",
    "ConvertMatrix4ToMatrix2IndividualFibersParamsDict",
    "ConvertMatrix4ToMatrix2IndividualFibersParamsDictTagged",
    "ConvertMatrix4ToMatrix2Outputs",
    "ConvertMatrix4ToMatrix2ParamsDict",
    "ConvertMatrix4ToMatrix2ParamsDictTagged",
    "convert_matrix4_to_matrix2",
    "convert_matrix4_to_matrix2_distances",
    "convert_matrix4_to_matrix2_execute",
    "convert_matrix4_to_matrix2_individual_fibers",
    "convert_matrix4_to_matrix2_params",
]
