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

import typing
import pathlib
from styxdefs import *

CONVERT_WARPFIELD_METADATA = Metadata(
    id="4f9d440378d5e5e478898e11b30a204baa1a8db9.workbench",
    name="convert-warpfield",
    package="workbench",
    container_image_tag="nx10x/workbench:2.1.0",
)


_ConvertWarpfieldFromWorldParamsDictNoTag = typing.TypedDict('_ConvertWarpfieldFromWorldParamsDictNoTag', {
    "input": str,
    "absolute": bool,
})
ConvertWarpfieldFromWorldParamsDictTagged = typing.TypedDict('ConvertWarpfieldFromWorldParamsDictTagged', {
    "@type": typing.Literal["from-world"],
    "input": str,
    "absolute": bool,
})
ConvertWarpfieldFromWorldParamsDict = _ConvertWarpfieldFromWorldParamsDictNoTag | ConvertWarpfieldFromWorldParamsDictTagged


_ConvertWarpfieldFromFnirtParamsDictNoTag = typing.TypedDict('_ConvertWarpfieldFromFnirtParamsDictNoTag', {
    "input": str,
    "source-volume": str,
    "absolute": bool,
})
ConvertWarpfieldFromFnirtParamsDictTagged = typing.TypedDict('ConvertWarpfieldFromFnirtParamsDictTagged', {
    "@type": typing.Literal["from-fnirt"],
    "input": str,
    "source-volume": str,
    "absolute": bool,
})
ConvertWarpfieldFromFnirtParamsDict = _ConvertWarpfieldFromFnirtParamsDictNoTag | ConvertWarpfieldFromFnirtParamsDictTagged


_ConvertWarpfieldToFnirtParamsDictNoTag = typing.TypedDict('_ConvertWarpfieldToFnirtParamsDictNoTag', {
    "output": str,
    "source-volume": str,
})
ConvertWarpfieldToFnirtParamsDictTagged = typing.TypedDict('ConvertWarpfieldToFnirtParamsDictTagged', {
    "@type": typing.Literal["to-fnirt"],
    "output": str,
    "source-volume": str,
})
ConvertWarpfieldToFnirtParamsDict = _ConvertWarpfieldToFnirtParamsDictNoTag | ConvertWarpfieldToFnirtParamsDictTagged


_ConvertWarpfieldParamsDictNoTag = typing.TypedDict('_ConvertWarpfieldParamsDictNoTag', {
    "from-world": typing.NotRequired[ConvertWarpfieldFromWorldParamsDict | None],
    "from-fnirt": typing.NotRequired[ConvertWarpfieldFromFnirtParamsDict | None],
    "to-fnirt": typing.NotRequired[list[ConvertWarpfieldToFnirtParamsDict] | None],
    "output": typing.NotRequired[str | None],
    "output": typing.NotRequired[str | None],
    "input": typing.NotRequired[str | None],
})
ConvertWarpfieldParamsDictTagged = typing.TypedDict('ConvertWarpfieldParamsDictTagged', {
    "@type": typing.Literal["workbench/convert-warpfield"],
    "from-world": typing.NotRequired[ConvertWarpfieldFromWorldParamsDict | None],
    "from-fnirt": typing.NotRequired[ConvertWarpfieldFromFnirtParamsDict | None],
    "to-fnirt": typing.NotRequired[list[ConvertWarpfieldToFnirtParamsDict] | None],
    "output": typing.NotRequired[str | None],
    "output": typing.NotRequired[str | None],
    "input": typing.NotRequired[str | None],
})
ConvertWarpfieldParamsDict = _ConvertWarpfieldParamsDictNoTag | ConvertWarpfieldParamsDictTagged


def convert_warpfield_from_world(
    input_: str,
    absolute: bool = False,
) -> ConvertWarpfieldFromWorldParamsDictTagged:
    """
    Build parameters.
    
    Args:
        input_: the input warpfield.
        absolute: warpfield was written in absolute convention, rather than\
            relative.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "from-world",
        "input": input_,
        "absolute": absolute,
    }
    return params


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


def convert_warpfield_from_world_cargs(
    params: ConvertWarpfieldFromWorldParamsDict,
    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([
        "-from-world",
        params.get("input", None)
    ])
    if params.get("absolute", False):
        cargs.append("-absolute")
    return cargs


def convert_warpfield_from_fnirt(
    input_: str,
    source_volume: str,
    absolute: bool = False,
) -> ConvertWarpfieldFromFnirtParamsDictTagged:
    """
    Build parameters.
    
    Args:
        input_: the input warpfield.
        source_volume: the source volume used when generating the input\
            warpfield.
        absolute: warpfield was written in absolute convention, rather than\
            relative.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "from-fnirt",
        "input": input_,
        "source-volume": source_volume,
        "absolute": absolute,
    }
    return params


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


def convert_warpfield_from_fnirt_cargs(
    params: ConvertWarpfieldFromFnirtParamsDict,
    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([
        "-from-fnirt",
        params.get("input", None),
        params.get("source-volume", None)
    ])
    if params.get("absolute", False):
        cargs.append("-absolute")
    return cargs


def convert_warpfield_to_fnirt(
    output: str,
    source_volume: str,
) -> ConvertWarpfieldToFnirtParamsDictTagged:
    """
    Build parameters.
    
    Args:
        output: output - the output warpfield.
        source_volume: the volume you want to apply the warpfield to.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "to-fnirt",
        "output": output,
        "source-volume": source_volume,
    }
    return params


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


def convert_warpfield_to_fnirt_cargs(
    params: ConvertWarpfieldToFnirtParamsDict,
    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([
        "-to-fnirt",
        params.get("output", None),
        params.get("source-volume", None)
    ])
    return cargs


class ConvertWarpfieldOutputs(typing.NamedTuple):
    """
    Output object returned when calling `ConvertWarpfieldParamsDict(...)`.
    """
    root: OutputPathType
    """Output root folder. This is the root folder for all outputs."""


def convert_warpfield_params(
    from_world: ConvertWarpfieldFromWorldParamsDict | None = None,
    from_fnirt: ConvertWarpfieldFromFnirtParamsDict | None = None,
    to_fnirt: list[ConvertWarpfieldToFnirtParamsDict] | None = None,
    output: str | None = None,
    output_: str | None = None,
    input_: str | None = None,
) -> ConvertWarpfieldParamsDictTagged:
    """
    Build parameters.
    
    Args:
        from_world: input is a NIFTI 'world' warpfield.
        from_fnirt: input is a fnirt warpfield.
        to_fnirt: write output as a fnirt warpfield.
        output: write output as an ITK warpfield\
            \
            output - the output warpfield.
        output_: write output as a NIFTI 'world' warpfield\
            \
            output - the output warpfield.
        input_: input is an ITK warpfield\
            \
            the input warpfield.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "workbench/convert-warpfield",
    }
    if from_world is not None:
        params["from-world"] = from_world
    if from_fnirt is not None:
        params["from-fnirt"] = from_fnirt
    if to_fnirt is not None:
        params["to-fnirt"] = to_fnirt
    if output is not None:
        params["output"] = output
    if output_ is not None:
        params["output"] = output_
    if input_ is not None:
        params["input"] = input_
    return params


def convert_warpfield_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `ConvertWarpfieldParamsDict` 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("from-world", None) is not None:
        convert_warpfield_from_world_validate(params["from-world"])
    if params.get("from-fnirt", None) is not None:
        convert_warpfield_from_fnirt_validate(params["from-fnirt"])
    if params.get("to-fnirt", None) is not None:
        if not isinstance(params["to-fnirt"], list):
            raise StyxValidationError(f'`to-fnirt` has the wrong type: Received `{type(params.get("to-fnirt", None))}` expected `list[ConvertWarpfieldToFnirtParamsDict] | None`')
        for e in params["to-fnirt"]:
            convert_warpfield_to_fnirt_validate(e)
    if params.get("output", None) is not None:
        if not isinstance(params["output"], str):
            raise StyxValidationError(f'`output` has the wrong type: Received `{type(params.get("output", None))}` expected `str | None`')
    if params.get("output", None) is not None:
        if not isinstance(params["output"], str):
            raise StyxValidationError(f'`output` has the wrong type: Received `{type(params.get("output", None))}` expected `str | None`')
    if params.get("input", None) is not None:
        if not isinstance(params["input"], str):
            raise StyxValidationError(f'`input` has the wrong type: Received `{type(params.get("input", None))}` expected `str | None`')


def convert_warpfield_cargs(
    params: ConvertWarpfieldParamsDict,
    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-warpfield"
    ])
    if params.get("from-world", None) is not None or params.get("from-fnirt", None) is not None or params.get("to-fnirt", None) is not None:
        cargs.extend([
            *(convert_warpfield_from_world_cargs(params.get("from-world", None), execution) if (params.get("from-world", None) is not None) else []),
            *(convert_warpfield_from_fnirt_cargs(params.get("from-fnirt", None), execution) if (params.get("from-fnirt", None) is not None) else []),
            *([a for c in [convert_warpfield_to_fnirt_cargs(s, execution) for s in params.get("to-fnirt", None)] for a in c] if (params.get("to-fnirt", None) is not None) else [])
        ])
    if params.get("output", None) is not None:
        cargs.extend([
            "-to-itk",
            params.get("output", None)
        ])
    if params.get("output", None) is not None:
        cargs.extend([
            "-to-world",
            params.get("output", None)
        ])
    if params.get("input", None) is not None:
        cargs.extend([
            "-from-itk",
            params.get("input", None)
        ])
    return cargs


def convert_warpfield_outputs(
    params: ConvertWarpfieldParamsDict,
    execution: Execution,
) -> ConvertWarpfieldOutputs:
    """
    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 = ConvertWarpfieldOutputs(
        root=execution.output_file("."),
    )
    return ret


def convert_warpfield_execute(
    params: ConvertWarpfieldParamsDict,
    runner: Runner | None = None,
) -> ConvertWarpfieldOutputs:
    """
    CONVERT A WARPFIELD BETWEEN CONVENTIONS.
    
    NIFTI world warpfields can be used directly on mm coordinates via sampling
    the three subvolumes at the coordinate and adding the sampled values to the
    coordinate vector. They use the NIFTI coordinate system, that is, X is left
    to right, Y is posterior to anterior, and Z is inferior to superior.
    
    NOTE: this command does not invert the warpfield, and to warp a surface, you
    must use the inverse of the warpfield that warps the corresponding volume.
    
    The ITK format is used by ANTS.
    
    You must specify exactly one -from option, but you may specify multiple -to
    options, and -to-fnirt may be specified more than once.
    
    Args:
        params: The parameters.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `ConvertWarpfieldOutputs`).
    """
    convert_warpfield_validate(params)
    runner = runner or get_global_runner()
    execution = runner.start_execution(CONVERT_WARPFIELD_METADATA)
    params = execution.params(params)
    cargs = convert_warpfield_cargs(params, execution)
    ret = convert_warpfield_outputs(params, execution)
    execution.run(cargs)
    return ret


def convert_warpfield(
    from_world: ConvertWarpfieldFromWorldParamsDict | None = None,
    from_fnirt: ConvertWarpfieldFromFnirtParamsDict | None = None,
    to_fnirt: list[ConvertWarpfieldToFnirtParamsDict] | None = None,
    output: str | None = None,
    output_: str | None = None,
    input_: str | None = None,
    runner: Runner | None = None,
) -> ConvertWarpfieldOutputs:
    """
    CONVERT A WARPFIELD BETWEEN CONVENTIONS.
    
    NIFTI world warpfields can be used directly on mm coordinates via sampling
    the three subvolumes at the coordinate and adding the sampled values to the
    coordinate vector. They use the NIFTI coordinate system, that is, X is left
    to right, Y is posterior to anterior, and Z is inferior to superior.
    
    NOTE: this command does not invert the warpfield, and to warp a surface, you
    must use the inverse of the warpfield that warps the corresponding volume.
    
    The ITK format is used by ANTS.
    
    You must specify exactly one -from option, but you may specify multiple -to
    options, and -to-fnirt may be specified more than once.
    
    Args:
        from_world: input is a NIFTI 'world' warpfield.
        from_fnirt: input is a fnirt warpfield.
        to_fnirt: write output as a fnirt warpfield.
        output: write output as an ITK warpfield\
            \
            output - the output warpfield.
        output_: write output as a NIFTI 'world' warpfield\
            \
            output - the output warpfield.
        input_: input is an ITK warpfield\
            \
            the input warpfield.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `ConvertWarpfieldOutputs`).
    """
    params = convert_warpfield_params(
        from_world=from_world,
        from_fnirt=from_fnirt,
        to_fnirt=to_fnirt,
        output=output,
        output_=output_,
        input_=input_,
    )
    return convert_warpfield_execute(params, runner)


__all__ = [
    "CONVERT_WARPFIELD_METADATA",
    "ConvertWarpfieldFromFnirtParamsDict",
    "ConvertWarpfieldFromFnirtParamsDictTagged",
    "ConvertWarpfieldFromWorldParamsDict",
    "ConvertWarpfieldFromWorldParamsDictTagged",
    "ConvertWarpfieldOutputs",
    "ConvertWarpfieldParamsDict",
    "ConvertWarpfieldParamsDictTagged",
    "ConvertWarpfieldToFnirtParamsDict",
    "ConvertWarpfieldToFnirtParamsDictTagged",
    "convert_warpfield",
    "convert_warpfield_execute",
    "convert_warpfield_from_fnirt",
    "convert_warpfield_from_world",
    "convert_warpfield_params",
    "convert_warpfield_to_fnirt",
]
