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

import typing
import pathlib
from styxdefs import *

CREATE_DISPLACEMENT_FIELD_METADATA = Metadata(
    id="be9ee3bddb712bf6b85e065f4aae1b6cbcda8c5e.boutiques",
    name="CreateDisplacementField",
    package="ants",
    container_image_tag="antsx/ants:v2.5.3",
)


_CreateDisplacementFieldParamsDictNoTag = typing.TypedDict('_CreateDisplacementFieldParamsDictNoTag', {
    "image_dimension": int,
    "enforce_zero_boundary_flag": bool,
    "component_images": list[InputPathType],
    "output_image": str,
})
CreateDisplacementFieldParamsDictTagged = typing.TypedDict('CreateDisplacementFieldParamsDictTagged', {
    "@type": typing.Literal["ants/CreateDisplacementField"],
    "image_dimension": int,
    "enforce_zero_boundary_flag": bool,
    "component_images": list[InputPathType],
    "output_image": str,
})
CreateDisplacementFieldParamsDict = _CreateDisplacementFieldParamsDictNoTag | CreateDisplacementFieldParamsDictTagged


class CreateDisplacementFieldOutputs(typing.NamedTuple):
    """
    Output object returned when calling `CreateDisplacementFieldParamsDict(...)`.
    """
    root: OutputPathType
    """Output root folder. This is the root folder for all outputs."""
    output_displacement_field: OutputPathType
    """The generated itkImage of itkVector pixels representing the displacement
    field."""


def create_displacement_field_params(
    image_dimension: int,
    enforce_zero_boundary_flag: bool,
    component_images: list[InputPathType],
    output_image: str,
) -> CreateDisplacementFieldParamsDictTagged:
    """
    Build parameters.
    
    Args:
        image_dimension: The dimension of the image, typically 2 or 3.
        enforce_zero_boundary_flag: Create zero-valued vectors along the\
            borders when enabled (pass 1), recommended for better displacement\
            field behavior.
        component_images: Input component images, each used for a vector\
            component. All component images must have the same size, offset,\
            origin, and spacing.
        output_image: The output displacement field image with itkVector\
            pixels.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "ants/CreateDisplacementField",
        "image_dimension": image_dimension,
        "enforce_zero_boundary_flag": enforce_zero_boundary_flag,
        "component_images": component_images,
        "output_image": output_image,
    }
    return params


def create_displacement_field_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `CreateDisplacementFieldParamsDict` 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("image_dimension", None) is None:
        raise StyxValidationError("`image_dimension` must not be None")
    if not isinstance(params["image_dimension"], int):
        raise StyxValidationError(f'`image_dimension` has the wrong type: Received `{type(params.get("image_dimension", None))}` expected `int`')
    if params.get("enforce_zero_boundary_flag", None) is None:
        raise StyxValidationError("`enforce_zero_boundary_flag` must not be None")
    if not isinstance(params["enforce_zero_boundary_flag"], bool):
        raise StyxValidationError(f'`enforce_zero_boundary_flag` has the wrong type: Received `{type(params.get("enforce_zero_boundary_flag", None))}` expected `bool`')
    if params.get("component_images", None) is None:
        raise StyxValidationError("`component_images` must not be None")
    if not isinstance(params["component_images"], list):
        raise StyxValidationError(f'`component_images` has the wrong type: Received `{type(params.get("component_images", None))}` expected `list[InputPathType]`')
    if not (1 <= len(params["component_images"]) <= 8):
        raise StyxValidationError("Parameter `component_images` must contain between 1 and 8 elements (inclusive)")
    for e in params["component_images"]:
        if not isinstance(e, (pathlib.Path, str)):
            raise StyxValidationError(f'`component_images` has the wrong type: Received `{type(params.get("component_images", None))}` expected `list[InputPathType]`')
    if params.get("output_image", None) is None:
        raise StyxValidationError("`output_image` must not be None")
    if not isinstance(params["output_image"], str):
        raise StyxValidationError(f'`output_image` has the wrong type: Received `{type(params.get("output_image", None))}` expected `str`')


def create_displacement_field_cargs(
    params: CreateDisplacementFieldParamsDict,
    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("CreateDisplacementField")
    cargs.append(str(params.get("image_dimension", None)))
    cargs.append(("1" if params.get("enforce_zero_boundary_flag", None) else "0"))
    cargs.extend([execution.input_file(f) for f in params.get("component_images", None)])
    cargs.append(params.get("output_image", None))
    return cargs


def create_displacement_field_outputs(
    params: CreateDisplacementFieldParamsDict,
    execution: Execution,
) -> CreateDisplacementFieldOutputs:
    """
    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 = CreateDisplacementFieldOutputs(
        root=execution.output_file("."),
        output_displacement_field=execution.output_file(params.get("output_image", None)),
    )
    return ret


def create_displacement_field_execute(
    params: CreateDisplacementFieldParamsDict,
    runner: Runner | None = None,
) -> CreateDisplacementFieldOutputs:
    """
    CreateDisplacementField
    
    Create an itkImage of itkVector pixels (NOT an itkVectorImage), using each
    scalar input component image for each vector component. An itkImage of
    itkVectors is the standard type for displacement fields in ITK. All
    component images (up to 8) are assumed to have the same size, offset,
    origin, and spacing. The 'EnforceZeroBoundaryFlag' option will create
    zero-valued vectors along the borders when enabled (pass 1), and is
    recommended for better displacement field behavior.
    
    Author: ANTs Developers
    
    URL: https://github.com/ANTsX/ANTs
    
    Args:
        params: The parameters.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `CreateDisplacementFieldOutputs`).
    """
    create_displacement_field_validate(params)
    runner = runner or get_global_runner()
    execution = runner.start_execution(CREATE_DISPLACEMENT_FIELD_METADATA)
    params = execution.params(params)
    cargs = create_displacement_field_cargs(params, execution)
    ret = create_displacement_field_outputs(params, execution)
    execution.run(cargs)
    return ret


def create_displacement_field(
    image_dimension: int,
    enforce_zero_boundary_flag: bool,
    component_images: list[InputPathType],
    output_image: str,
    runner: Runner | None = None,
) -> CreateDisplacementFieldOutputs:
    """
    CreateDisplacementField
    
    Create an itkImage of itkVector pixels (NOT an itkVectorImage), using each
    scalar input component image for each vector component. An itkImage of
    itkVectors is the standard type for displacement fields in ITK. All
    component images (up to 8) are assumed to have the same size, offset,
    origin, and spacing. The 'EnforceZeroBoundaryFlag' option will create
    zero-valued vectors along the borders when enabled (pass 1), and is
    recommended for better displacement field behavior.
    
    Author: ANTs Developers
    
    URL: https://github.com/ANTsX/ANTs
    
    Args:
        image_dimension: The dimension of the image, typically 2 or 3.
        enforce_zero_boundary_flag: Create zero-valued vectors along the\
            borders when enabled (pass 1), recommended for better displacement\
            field behavior.
        component_images: Input component images, each used for a vector\
            component. All component images must have the same size, offset,\
            origin, and spacing.
        output_image: The output displacement field image with itkVector\
            pixels.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `CreateDisplacementFieldOutputs`).
    """
    params = create_displacement_field_params(
        image_dimension=image_dimension,
        enforce_zero_boundary_flag=enforce_zero_boundary_flag,
        component_images=component_images,
        output_image=output_image,
    )
    return create_displacement_field_execute(params, runner)


__all__ = [
    "CREATE_DISPLACEMENT_FIELD_METADATA",
    "CreateDisplacementFieldOutputs",
    "CreateDisplacementFieldParamsDict",
    "CreateDisplacementFieldParamsDictTagged",
    "create_displacement_field",
    "create_displacement_field_execute",
    "create_displacement_field_params",
]
