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

import typing
import pathlib
from styxdefs import *

SMOOTH_DISPLACEMENT_FIELD_METADATA = Metadata(
    id="430313dde82351b7e8ca1893a4a8efe15e5d3c98.boutiques",
    name="SmoothDisplacementField",
    package="ants",
    container_image_tag="antsx/ants:v2.5.3",
)


_SmoothDisplacementFieldParamsDictNoTag = typing.TypedDict('_SmoothDisplacementFieldParamsDictNoTag', {
    "image_dimension": int,
    "input_field": InputPathType,
    "output_field": str,
    "variance_or_mesh_size_base_level": float,
    "number_of_levels": typing.NotRequired[int | None],
    "spline_order": typing.NotRequired[int | None],
    "estimate_inverse": typing.NotRequired[bool | None],
    "confidence_image": typing.NotRequired[InputPathType | None],
})
SmoothDisplacementFieldParamsDictTagged = typing.TypedDict('SmoothDisplacementFieldParamsDictTagged', {
    "@type": typing.Literal["ants/SmoothDisplacementField"],
    "image_dimension": int,
    "input_field": InputPathType,
    "output_field": str,
    "variance_or_mesh_size_base_level": float,
    "number_of_levels": typing.NotRequired[int | None],
    "spline_order": typing.NotRequired[int | None],
    "estimate_inverse": typing.NotRequired[bool | None],
    "confidence_image": typing.NotRequired[InputPathType | None],
})
SmoothDisplacementFieldParamsDict = _SmoothDisplacementFieldParamsDictNoTag | SmoothDisplacementFieldParamsDictTagged


class SmoothDisplacementFieldOutputs(typing.NamedTuple):
    """
    Output object returned when calling `SmoothDisplacementFieldParamsDict(...)`.
    """
    root: OutputPathType
    """Output root folder. This is the root folder for all outputs."""
    smoothed_field: OutputPathType
    """The output file containing the smoothed displacement field."""
    confidence_image_out: OutputPathType | None
    """The output file containing confidence information from the smoothing
    process."""


def smooth_displacement_field_params(
    image_dimension: int,
    input_field: InputPathType,
    output_field: str,
    variance_or_mesh_size_base_level: float,
    number_of_levels: int | None = None,
    spline_order: int | None = None,
    estimate_inverse: bool | None = None,
    confidence_image: InputPathType | None = None,
) -> SmoothDisplacementFieldParamsDictTagged:
    """
    Build parameters.
    
    Args:
        image_dimension: The dimensionality of the input displacement field.
        input_field: The input displacement field file.
        output_field: The output file for the smoothed displacement field.
        variance_or_mesh_size_base_level: The variance for Gaussian smoothing\
            or mesh size at the base level for B-spline smoothing.
        number_of_levels: The number of levels for multi-resolution smoothing.
        spline_order: The order of the spline for B-spline smoothing.
        estimate_inverse: Estimate the inverse of the displacement field if set\
            to 1.
        confidence_image: Optional confidence image output of the smoothing\
            process.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "ants/SmoothDisplacementField",
        "image_dimension": image_dimension,
        "input_field": input_field,
        "output_field": output_field,
        "variance_or_mesh_size_base_level": variance_or_mesh_size_base_level,
    }
    if number_of_levels is not None:
        params["number_of_levels"] = number_of_levels
    if spline_order is not None:
        params["spline_order"] = spline_order
    if estimate_inverse is not None:
        params["estimate_inverse"] = estimate_inverse
    if confidence_image is not None:
        params["confidence_image"] = confidence_image
    return params


def smooth_displacement_field_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `SmoothDisplacementFieldParamsDict` 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("input_field", None) is None:
        raise StyxValidationError("`input_field` must not be None")
    if not isinstance(params["input_field"], (pathlib.Path, str)):
        raise StyxValidationError(f'`input_field` has the wrong type: Received `{type(params.get("input_field", None))}` expected `InputPathType`')
    if params.get("output_field", None) is None:
        raise StyxValidationError("`output_field` must not be None")
    if not isinstance(params["output_field"], str):
        raise StyxValidationError(f'`output_field` has the wrong type: Received `{type(params.get("output_field", None))}` expected `str`')
    if params.get("variance_or_mesh_size_base_level", None) is None:
        raise StyxValidationError("`variance_or_mesh_size_base_level` must not be None")
    if not isinstance(params["variance_or_mesh_size_base_level"], (float, int)):
        raise StyxValidationError(f'`variance_or_mesh_size_base_level` has the wrong type: Received `{type(params.get("variance_or_mesh_size_base_level", None))}` expected `float`')
    if params.get("number_of_levels", None) is not None:
        if not isinstance(params["number_of_levels"], int):
            raise StyxValidationError(f'`number_of_levels` has the wrong type: Received `{type(params.get("number_of_levels", None))}` expected `int | None`')
    if params.get("spline_order", None) is not None:
        if not isinstance(params["spline_order"], int):
            raise StyxValidationError(f'`spline_order` has the wrong type: Received `{type(params.get("spline_order", None))}` expected `int | None`')
    if params.get("estimate_inverse", None) is not None:
        if not isinstance(params["estimate_inverse"], bool):
            raise StyxValidationError(f'`estimate_inverse` has the wrong type: Received `{type(params.get("estimate_inverse", None))}` expected `bool | None`')
    if params.get("confidence_image", None) is not None:
        if not isinstance(params["confidence_image"], (pathlib.Path, str)):
            raise StyxValidationError(f'`confidence_image` has the wrong type: Received `{type(params.get("confidence_image", None))}` expected `InputPathType | None`')


def smooth_displacement_field_cargs(
    params: SmoothDisplacementFieldParamsDict,
    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("SmoothDisplacementField")
    cargs.append(str(params.get("image_dimension", None)))
    cargs.append(execution.input_file(params.get("input_field", None)))
    cargs.append(params.get("output_field", None))
    cargs.append(str(params.get("variance_or_mesh_size_base_level", None)))
    if params.get("number_of_levels", None) is not None:
        cargs.append(str(params.get("number_of_levels", None)))
    if params.get("spline_order", None) is not None:
        cargs.append(str(params.get("spline_order", None)))
    if params.get("estimate_inverse", None) is not None:
        cargs.append(("1" if params.get("estimate_inverse", None) else "0"))
    if params.get("confidence_image", None) is not None:
        cargs.append(execution.input_file(params.get("confidence_image", None)))
    return cargs


def smooth_displacement_field_outputs(
    params: SmoothDisplacementFieldParamsDict,
    execution: Execution,
) -> SmoothDisplacementFieldOutputs:
    """
    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 = SmoothDisplacementFieldOutputs(
        root=execution.output_file("."),
        smoothed_field=execution.output_file(params.get("output_field", None)),
        confidence_image_out=execution.output_file(pathlib.Path(params.get("confidence_image", None)).name) if (params.get("confidence_image") is not None) else None,
    )
    return ret


def smooth_displacement_field_execute(
    params: SmoothDisplacementFieldParamsDict,
    runner: Runner | None = None,
) -> SmoothDisplacementFieldOutputs:
    """
    SmoothDisplacementField
    
    SmoothDisplacementField applies smoothing to a displacement field over a
    specified number of levels with optional parameters for spline order,
    inverse estimation, and confidence image output.
    
    Author: ANTs Developers
    
    URL: https://github.com/ANTsX/ANTs
    
    Args:
        params: The parameters.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `SmoothDisplacementFieldOutputs`).
    """
    smooth_displacement_field_validate(params)
    runner = runner or get_global_runner()
    execution = runner.start_execution(SMOOTH_DISPLACEMENT_FIELD_METADATA)
    params = execution.params(params)
    cargs = smooth_displacement_field_cargs(params, execution)
    ret = smooth_displacement_field_outputs(params, execution)
    execution.run(cargs)
    return ret


def smooth_displacement_field(
    image_dimension: int,
    input_field: InputPathType,
    output_field: str,
    variance_or_mesh_size_base_level: float,
    number_of_levels: int | None = None,
    spline_order: int | None = None,
    estimate_inverse: bool | None = None,
    confidence_image: InputPathType | None = None,
    runner: Runner | None = None,
) -> SmoothDisplacementFieldOutputs:
    """
    SmoothDisplacementField
    
    SmoothDisplacementField applies smoothing to a displacement field over a
    specified number of levels with optional parameters for spline order,
    inverse estimation, and confidence image output.
    
    Author: ANTs Developers
    
    URL: https://github.com/ANTsX/ANTs
    
    Args:
        image_dimension: The dimensionality of the input displacement field.
        input_field: The input displacement field file.
        output_field: The output file for the smoothed displacement field.
        variance_or_mesh_size_base_level: The variance for Gaussian smoothing\
            or mesh size at the base level for B-spline smoothing.
        number_of_levels: The number of levels for multi-resolution smoothing.
        spline_order: The order of the spline for B-spline smoothing.
        estimate_inverse: Estimate the inverse of the displacement field if set\
            to 1.
        confidence_image: Optional confidence image output of the smoothing\
            process.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `SmoothDisplacementFieldOutputs`).
    """
    params = smooth_displacement_field_params(
        image_dimension=image_dimension,
        input_field=input_field,
        output_field=output_field,
        variance_or_mesh_size_base_level=variance_or_mesh_size_base_level,
        number_of_levels=number_of_levels,
        spline_order=spline_order,
        estimate_inverse=estimate_inverse,
        confidence_image=confidence_image,
    )
    return smooth_displacement_field_execute(params, runner)


__all__ = [
    "SMOOTH_DISPLACEMENT_FIELD_METADATA",
    "SmoothDisplacementFieldOutputs",
    "SmoothDisplacementFieldParamsDict",
    "SmoothDisplacementFieldParamsDictTagged",
    "smooth_displacement_field",
    "smooth_displacement_field_execute",
    "smooth_displacement_field_params",
]
