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

import typing
import pathlib
from styxdefs import *

ANTS_REGISTRATION_SY_N_SH_METADATA = Metadata(
    id="b8b4732301023521da1f1ecab58942846288f659.boutiques",
    name="antsRegistrationSyN.sh",
    package="ants",
    container_image_tag="antsx/ants:v2.5.3",
)


_AntsRegistrationSyNShParamsDictNoTag = typing.TypedDict('_AntsRegistrationSyNShParamsDictNoTag', {
    "image_dimension": typing.Literal[2, 3],
    "fixed_image": InputPathType,
    "moving_image": InputPathType,
    "output_prefix": str,
    "threads": typing.NotRequired[int | None],
    "initial_transform": typing.NotRequired[list[str] | None],
    "transform_type": typing.NotRequired[typing.Literal["t", "r", "a", "s", "sr", "so", "b", "br", "bo"] | None],
    "radius": typing.NotRequired[int | None],
    "spline_distance": typing.NotRequired[int | None],
    "gradient_step": typing.NotRequired[float | None],
    "masks": typing.NotRequired[str | None],
    "precision_type": typing.NotRequired[typing.Literal["f", "d"] | None],
    "use_histogram_matching": typing.NotRequired[bool | None],
    "use_repro_mode": typing.NotRequired[bool | None],
    "collapse_output_transforms": typing.NotRequired[bool | None],
    "random_seed": typing.NotRequired[int | None],
})
AntsRegistrationSyNShParamsDictTagged = typing.TypedDict('AntsRegistrationSyNShParamsDictTagged', {
    "@type": typing.Literal["ants/antsRegistrationSyN.sh"],
    "image_dimension": typing.Literal[2, 3],
    "fixed_image": InputPathType,
    "moving_image": InputPathType,
    "output_prefix": str,
    "threads": typing.NotRequired[int | None],
    "initial_transform": typing.NotRequired[list[str] | None],
    "transform_type": typing.NotRequired[typing.Literal["t", "r", "a", "s", "sr", "so", "b", "br", "bo"] | None],
    "radius": typing.NotRequired[int | None],
    "spline_distance": typing.NotRequired[int | None],
    "gradient_step": typing.NotRequired[float | None],
    "masks": typing.NotRequired[str | None],
    "precision_type": typing.NotRequired[typing.Literal["f", "d"] | None],
    "use_histogram_matching": typing.NotRequired[bool | None],
    "use_repro_mode": typing.NotRequired[bool | None],
    "collapse_output_transforms": typing.NotRequired[bool | None],
    "random_seed": typing.NotRequired[int | None],
})
AntsRegistrationSyNShParamsDict = _AntsRegistrationSyNShParamsDictNoTag | AntsRegistrationSyNShParamsDictTagged


class AntsRegistrationSyNShOutputs(typing.NamedTuple):
    """
    Output object returned when calling `AntsRegistrationSyNShParamsDict(...)`.
    """
    root: OutputPathType
    """Output root folder. This is the root folder for all outputs."""
    affine_transform: OutputPathType
    """Affine transformation matrix for registration"""
    inverse_warp: OutputPathType
    """Inverse warp field for registration"""
    forward_warp: OutputPathType
    """Forward warp field for registration"""


def ants_registration_sy_n_sh_params(
    image_dimension: typing.Literal[2, 3],
    fixed_image: InputPathType,
    moving_image: InputPathType,
    output_prefix: str,
    threads: int | None = None,
    initial_transform: list[str] | None = None,
    transform_type: typing.Literal["t", "r", "a", "s", "sr", "so", "b", "br", "bo"] | None = None,
    radius: int | None = None,
    spline_distance: int | None = None,
    gradient_step: float | None = None,
    masks: str | None = None,
    precision_type: typing.Literal["f", "d"] | None = None,
    use_histogram_matching: bool | None = None,
    use_repro_mode: bool | None = None,
    collapse_output_transforms: bool | None = None,
    random_seed: int | None = None,
) -> AntsRegistrationSyNShParamsDictTagged:
    """
    Build parameters.
    
    Args:
        image_dimension: Image dimension: 2 or 3 (for 2 or 3-dimensional\
            registration of a single volume).
        fixed_image: Fixed image(s) or source image(s) or reference image(s).
        moving_image: Moving image(s) or target image(s).
        output_prefix: A prefix that is prepended to all output files.
        threads: Number of threads (default =\
            ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS if defined, otherwise 1).
        initial_transform: Initial transform(s) --- order specified on the\
            command line matters.
        transform_type: Transform type (default = 's'). Options:\
            - t: translation (1 stage)\
            - r: rigid (1 stage)\
            - a: rigid + affine (2 stages)\
            - s: rigid + affine + deformable syn (3 stages)\
            - sr: rigid + deformable syn (2 stages)\
            - so: deformable syn only (1 stage)\
            - b: rigid + affine + deformable b-spline syn (3 stages)\
            - br: rigid + deformable b-spline syn (2 stages)\
            - bo: deformable b-spline syn only (1 stage).
        radius: Radius for cross correlation metric used during SyN stage\
            (default = 4).
        spline_distance: Spline distance for deformable B-spline SyN transform\
            (default = 26).
        gradient_step: Gradient step size for SyN and B-spline SyN (default =\
            0.1).
        masks: Mask(s) for the fixed image space, or for the fixed and moving\
            image space in the format 'fixedMask,MovingMask'. Use -x once to\
            specify mask(s) to be used for all stages or use -x for each 'stage'\
            (cf -t option). If no mask is to be used for a particular stage, the\
            keyword 'NULL' should be used in place of file names.
        precision_type: Precision type (default = 'd'). Options:\
            - f: float\
            - d: double.
        use_histogram_matching: Use histogram matching (default = 0). Options:\
            - 0: false\
            - 1: true.
        use_repro_mode: Use 'repro' mode for exact reproducibility of output.\
            Uses GC metric for linear stages and a fixed random seed (default = 0).\
            Options:\
            - 0: false\
            - 1: true.
        collapse_output_transforms: Collapse output transforms (default = 1).\
            Options:\
            - 0: false\
            - 1: true.
        random_seed: Fix random seed to an int value.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "ants/antsRegistrationSyN.sh",
        "image_dimension": image_dimension,
        "fixed_image": fixed_image,
        "moving_image": moving_image,
        "output_prefix": output_prefix,
    }
    if threads is not None:
        params["threads"] = threads
    if initial_transform is not None:
        params["initial_transform"] = initial_transform
    if transform_type is not None:
        params["transform_type"] = transform_type
    if radius is not None:
        params["radius"] = radius
    if spline_distance is not None:
        params["spline_distance"] = spline_distance
    if gradient_step is not None:
        params["gradient_step"] = gradient_step
    if masks is not None:
        params["masks"] = masks
    if precision_type is not None:
        params["precision_type"] = precision_type
    if use_histogram_matching is not None:
        params["use_histogram_matching"] = use_histogram_matching
    if use_repro_mode is not None:
        params["use_repro_mode"] = use_repro_mode
    if collapse_output_transforms is not None:
        params["collapse_output_transforms"] = collapse_output_transforms
    if random_seed is not None:
        params["random_seed"] = random_seed
    return params


def ants_registration_sy_n_sh_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `AntsRegistrationSyNShParamsDict` 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 `typing.Literal[2, 3]`')
    if params["image_dimension"] not in [2, 3]:
        raise StyxValidationError("Parameter `image_dimension` must be one of [2, 3]")
    if params.get("fixed_image", None) is None:
        raise StyxValidationError("`fixed_image` must not be None")
    if not isinstance(params["fixed_image"], (pathlib.Path, str)):
        raise StyxValidationError(f'`fixed_image` has the wrong type: Received `{type(params.get("fixed_image", None))}` expected `InputPathType`')
    if params.get("moving_image", None) is None:
        raise StyxValidationError("`moving_image` must not be None")
    if not isinstance(params["moving_image"], (pathlib.Path, str)):
        raise StyxValidationError(f'`moving_image` has the wrong type: Received `{type(params.get("moving_image", None))}` expected `InputPathType`')
    if params.get("output_prefix", None) is None:
        raise StyxValidationError("`output_prefix` must not be None")
    if not isinstance(params["output_prefix"], str):
        raise StyxValidationError(f'`output_prefix` has the wrong type: Received `{type(params.get("output_prefix", None))}` expected `str`')
    if params.get("threads", None) is not None:
        if not isinstance(params["threads"], int):
            raise StyxValidationError(f'`threads` has the wrong type: Received `{type(params.get("threads", None))}` expected `int | None`')
    if params.get("initial_transform", None) is not None:
        if not isinstance(params["initial_transform"], list):
            raise StyxValidationError(f'`initial_transform` has the wrong type: Received `{type(params.get("initial_transform", None))}` expected `list[str] | None`')
        for e in params["initial_transform"]:
            if not isinstance(e, str):
                raise StyxValidationError(f'`initial_transform` has the wrong type: Received `{type(params.get("initial_transform", None))}` expected `list[str] | None`')
    if params.get("transform_type", None) is not None:
        if not isinstance(params["transform_type"], str):
            raise StyxValidationError(f'`transform_type` has the wrong type: Received `{type(params.get("transform_type", None))}` expected `typing.Literal["t", "r", "a", "s", "sr", "so", "b", "br", "bo"] | None`')
        if params["transform_type"] not in ["t", "r", "a", "s", "sr", "so", "b", "br", "bo"]:
            raise StyxValidationError("Parameter `transform_type` must be one of [\"t\", \"r\", \"a\", \"s\", \"sr\", \"so\", \"b\", \"br\", \"bo\"]")
    if params.get("radius", None) is not None:
        if not isinstance(params["radius"], int):
            raise StyxValidationError(f'`radius` has the wrong type: Received `{type(params.get("radius", None))}` expected `int | None`')
    if params.get("spline_distance", None) is not None:
        if not isinstance(params["spline_distance"], int):
            raise StyxValidationError(f'`spline_distance` has the wrong type: Received `{type(params.get("spline_distance", None))}` expected `int | None`')
    if params.get("gradient_step", None) is not None:
        if not isinstance(params["gradient_step"], (float, int)):
            raise StyxValidationError(f'`gradient_step` has the wrong type: Received `{type(params.get("gradient_step", None))}` expected `float | None`')
    if params.get("masks", None) is not None:
        if not isinstance(params["masks"], str):
            raise StyxValidationError(f'`masks` has the wrong type: Received `{type(params.get("masks", None))}` expected `str | None`')
    if params.get("precision_type", None) is not None:
        if not isinstance(params["precision_type"], str):
            raise StyxValidationError(f'`precision_type` has the wrong type: Received `{type(params.get("precision_type", None))}` expected `typing.Literal["f", "d"] | None`')
        if params["precision_type"] not in ["f", "d"]:
            raise StyxValidationError("Parameter `precision_type` must be one of [\"f\", \"d\"]")
    if params.get("use_histogram_matching", None) is not None:
        if not isinstance(params["use_histogram_matching"], bool):
            raise StyxValidationError(f'`use_histogram_matching` has the wrong type: Received `{type(params.get("use_histogram_matching", None))}` expected `bool | None`')
    if params.get("use_repro_mode", None) is not None:
        if not isinstance(params["use_repro_mode"], bool):
            raise StyxValidationError(f'`use_repro_mode` has the wrong type: Received `{type(params.get("use_repro_mode", None))}` expected `bool | None`')
    if params.get("collapse_output_transforms", None) is not None:
        if not isinstance(params["collapse_output_transforms"], bool):
            raise StyxValidationError(f'`collapse_output_transforms` has the wrong type: Received `{type(params.get("collapse_output_transforms", None))}` expected `bool | None`')
    if params.get("random_seed", None) is not None:
        if not isinstance(params["random_seed"], int):
            raise StyxValidationError(f'`random_seed` has the wrong type: Received `{type(params.get("random_seed", None))}` expected `int | None`')


def ants_registration_sy_n_sh_cargs(
    params: AntsRegistrationSyNShParamsDict,
    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("antsRegistrationSyN.sh")
    cargs.extend([
        "-d",
        str(params.get("image_dimension", None))
    ])
    cargs.extend([
        "-f",
        execution.input_file(params.get("fixed_image", None))
    ])
    cargs.extend([
        "-m",
        execution.input_file(params.get("moving_image", None))
    ])
    cargs.extend([
        "-o",
        params.get("output_prefix", None)
    ])
    if params.get("threads", None) is not None:
        cargs.extend([
            "-n",
            str(params.get("threads", None))
        ])
    if params.get("initial_transform", None) is not None:
        cargs.extend([
            "-i",
            "[" + ",".join(params.get("initial_transform", None)) + "]"
        ])
    if params.get("transform_type", None) is not None:
        cargs.extend([
            "-t",
            params.get("transform_type", None)
        ])
    if params.get("radius", None) is not None:
        cargs.extend([
            "-r",
            str(params.get("radius", None))
        ])
    if params.get("spline_distance", None) is not None:
        cargs.extend([
            "-s",
            str(params.get("spline_distance", None))
        ])
    if params.get("gradient_step", None) is not None:
        cargs.extend([
            "-g",
            str(params.get("gradient_step", None))
        ])
    if params.get("masks", None) is not None:
        cargs.extend([
            "-x",
            params.get("masks", None)
        ])
    if params.get("precision_type", None) is not None:
        cargs.extend([
            "-p",
            params.get("precision_type", None)
        ])
    if params.get("use_histogram_matching", None) is not None:
        cargs.extend([
            "-j",
            ("1" if params.get("use_histogram_matching", None) else "0")
        ])
    if params.get("use_repro_mode", None) is not None:
        cargs.extend([
            "-y",
            ("1" if params.get("use_repro_mode", None) else "0")
        ])
    if params.get("collapse_output_transforms", None) is not None:
        cargs.extend([
            "-z",
            ("1" if params.get("collapse_output_transforms", None) else "0")
        ])
    if params.get("random_seed", None) is not None:
        cargs.extend([
            "-e",
            str(params.get("random_seed", None))
        ])
    return cargs


def ants_registration_sy_n_sh_outputs(
    params: AntsRegistrationSyNShParamsDict,
    execution: Execution,
) -> AntsRegistrationSyNShOutputs:
    """
    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 = AntsRegistrationSyNShOutputs(
        root=execution.output_file("."),
        affine_transform=execution.output_file(params.get("output_prefix", None) + "0GenericAffine.mat"),
        inverse_warp=execution.output_file(params.get("output_prefix", None) + "1InverseWarp.nii.gz"),
        forward_warp=execution.output_file(params.get("output_prefix", None) + "1Warp.nii.gz"),
    )
    return ret


def ants_registration_sy_n_sh_execute(
    params: AntsRegistrationSyNShParamsDict,
    runner: Runner | None = None,
) -> AntsRegistrationSyNShOutputs:
    """
    antsRegistrationSyN.sh
    
    Script for simplified symmetric image registration using ANTs.
    
    Author: ANTs Developers
    
    URL: https://github.com/ANTsX/ANTs
    
    Args:
        params: The parameters.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `AntsRegistrationSyNShOutputs`).
    """
    ants_registration_sy_n_sh_validate(params)
    runner = runner or get_global_runner()
    execution = runner.start_execution(ANTS_REGISTRATION_SY_N_SH_METADATA)
    params = execution.params(params)
    cargs = ants_registration_sy_n_sh_cargs(params, execution)
    ret = ants_registration_sy_n_sh_outputs(params, execution)
    execution.run(cargs)
    return ret


def ants_registration_sy_n_sh(
    image_dimension: typing.Literal[2, 3],
    fixed_image: InputPathType,
    moving_image: InputPathType,
    output_prefix: str,
    threads: int | None = None,
    initial_transform: list[str] | None = None,
    transform_type: typing.Literal["t", "r", "a", "s", "sr", "so", "b", "br", "bo"] | None = None,
    radius: int | None = None,
    spline_distance: int | None = None,
    gradient_step: float | None = None,
    masks: str | None = None,
    precision_type: typing.Literal["f", "d"] | None = None,
    use_histogram_matching: bool | None = None,
    use_repro_mode: bool | None = None,
    collapse_output_transforms: bool | None = None,
    random_seed: int | None = None,
    runner: Runner | None = None,
) -> AntsRegistrationSyNShOutputs:
    """
    antsRegistrationSyN.sh
    
    Script for simplified symmetric image registration using ANTs.
    
    Author: ANTs Developers
    
    URL: https://github.com/ANTsX/ANTs
    
    Args:
        image_dimension: Image dimension: 2 or 3 (for 2 or 3-dimensional\
            registration of a single volume).
        fixed_image: Fixed image(s) or source image(s) or reference image(s).
        moving_image: Moving image(s) or target image(s).
        output_prefix: A prefix that is prepended to all output files.
        threads: Number of threads (default =\
            ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS if defined, otherwise 1).
        initial_transform: Initial transform(s) --- order specified on the\
            command line matters.
        transform_type: Transform type (default = 's'). Options:\
            - t: translation (1 stage)\
            - r: rigid (1 stage)\
            - a: rigid + affine (2 stages)\
            - s: rigid + affine + deformable syn (3 stages)\
            - sr: rigid + deformable syn (2 stages)\
            - so: deformable syn only (1 stage)\
            - b: rigid + affine + deformable b-spline syn (3 stages)\
            - br: rigid + deformable b-spline syn (2 stages)\
            - bo: deformable b-spline syn only (1 stage).
        radius: Radius for cross correlation metric used during SyN stage\
            (default = 4).
        spline_distance: Spline distance for deformable B-spline SyN transform\
            (default = 26).
        gradient_step: Gradient step size for SyN and B-spline SyN (default =\
            0.1).
        masks: Mask(s) for the fixed image space, or for the fixed and moving\
            image space in the format 'fixedMask,MovingMask'. Use -x once to\
            specify mask(s) to be used for all stages or use -x for each 'stage'\
            (cf -t option). If no mask is to be used for a particular stage, the\
            keyword 'NULL' should be used in place of file names.
        precision_type: Precision type (default = 'd'). Options:\
            - f: float\
            - d: double.
        use_histogram_matching: Use histogram matching (default = 0). Options:\
            - 0: false\
            - 1: true.
        use_repro_mode: Use 'repro' mode for exact reproducibility of output.\
            Uses GC metric for linear stages and a fixed random seed (default = 0).\
            Options:\
            - 0: false\
            - 1: true.
        collapse_output_transforms: Collapse output transforms (default = 1).\
            Options:\
            - 0: false\
            - 1: true.
        random_seed: Fix random seed to an int value.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `AntsRegistrationSyNShOutputs`).
    """
    params = ants_registration_sy_n_sh_params(
        image_dimension=image_dimension,
        fixed_image=fixed_image,
        moving_image=moving_image,
        output_prefix=output_prefix,
        threads=threads,
        initial_transform=initial_transform,
        transform_type=transform_type,
        radius=radius,
        spline_distance=spline_distance,
        gradient_step=gradient_step,
        masks=masks,
        precision_type=precision_type,
        use_histogram_matching=use_histogram_matching,
        use_repro_mode=use_repro_mode,
        collapse_output_transforms=collapse_output_transforms,
        random_seed=random_seed,
    )
    return ants_registration_sy_n_sh_execute(params, runner)


__all__ = [
    "ANTS_REGISTRATION_SY_N_SH_METADATA",
    "AntsRegistrationSyNShOutputs",
    "AntsRegistrationSyNShParamsDict",
    "AntsRegistrationSyNShParamsDictTagged",
    "ants_registration_sy_n_sh",
    "ants_registration_sy_n_sh_execute",
    "ants_registration_sy_n_sh_params",
]
