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

import typing
import pathlib
from styxdefs import *

ANTS_ATROPOS_N4_SH_METADATA = Metadata(
    id="3902130432999f1a99133857c02c3377a225b17e.boutiques",
    name="antsAtroposN4.sh",
    package="ants",
    container_image_tag="antsx/ants:v2.5.3",
)


_AntsAtroposN4ShSegmentationPriorsParamsDictNoTag = typing.TypedDict('_AntsAtroposN4ShSegmentationPriorsParamsDictNoTag', {
    "segmentation_priors_pattern": typing.NotRequired[str | None],
    "segmentation_priors_folder": typing.NotRequired[InputPathType | None],
})
AntsAtroposN4ShSegmentationPriorsParamsDictTagged = typing.TypedDict('AntsAtroposN4ShSegmentationPriorsParamsDictTagged', {
    "@type": typing.Literal["segmentation_priors"],
    "segmentation_priors_pattern": typing.NotRequired[str | None],
    "segmentation_priors_folder": typing.NotRequired[InputPathType | None],
})
AntsAtroposN4ShSegmentationPriorsParamsDict = _AntsAtroposN4ShSegmentationPriorsParamsDictNoTag | AntsAtroposN4ShSegmentationPriorsParamsDictTagged


_AntsAtroposN4ShParamsDictNoTag = typing.TypedDict('_AntsAtroposN4ShParamsDictNoTag', {
    "image_dimension": typing.Literal[2, 3],
    "input_image": InputPathType,
    "mask_image": InputPathType,
    "number_of_classes": int,
    "output_prefix": str,
    "max_n4_atropos_iterations": typing.NotRequired[int | None],
    "max_atropos_iterations": typing.NotRequired[int | None],
    "segmentation_priors": AntsAtroposN4ShSegmentationPriorsParamsDict,
    "mrf": typing.NotRequired[str | None],
    "denoise_anatomical_images": typing.NotRequired[bool | None],
    "posterior_formulation": typing.NotRequired[typing.Literal["Socrates[ 1 ]", "Aristotle[ 1 ]"] | None],
    "label_propagation": typing.NotRequired[str | None],
    "posterior_label_for_n4_weight_mask": typing.NotRequired[str | None],
    "image_file_suffix": typing.NotRequired[str | None],
    "keep_temporary_files": typing.NotRequired[bool | None],
    "use_random_seeding": typing.NotRequired[bool | None],
    "atropos_segmentation_prior_weight": typing.NotRequired[float | None],
    "n4_convergence": typing.NotRequired[str | None],
    "n4_shrink_factor": typing.NotRequired[int | None],
    "n4_bspline_params": typing.NotRequired[str | None],
    "atropos_segmentation_icm": typing.NotRequired[str | None],
    "atropos_segmentation_use_euclidean_distance": typing.NotRequired[bool | None],
    "test_debug_mode": typing.NotRequired[int | None],
})
AntsAtroposN4ShParamsDictTagged = typing.TypedDict('AntsAtroposN4ShParamsDictTagged', {
    "@type": typing.Literal["ants/antsAtroposN4.sh"],
    "image_dimension": typing.Literal[2, 3],
    "input_image": InputPathType,
    "mask_image": InputPathType,
    "number_of_classes": int,
    "output_prefix": str,
    "max_n4_atropos_iterations": typing.NotRequired[int | None],
    "max_atropos_iterations": typing.NotRequired[int | None],
    "segmentation_priors": AntsAtroposN4ShSegmentationPriorsParamsDict,
    "mrf": typing.NotRequired[str | None],
    "denoise_anatomical_images": typing.NotRequired[bool | None],
    "posterior_formulation": typing.NotRequired[typing.Literal["Socrates[ 1 ]", "Aristotle[ 1 ]"] | None],
    "label_propagation": typing.NotRequired[str | None],
    "posterior_label_for_n4_weight_mask": typing.NotRequired[str | None],
    "image_file_suffix": typing.NotRequired[str | None],
    "keep_temporary_files": typing.NotRequired[bool | None],
    "use_random_seeding": typing.NotRequired[bool | None],
    "atropos_segmentation_prior_weight": typing.NotRequired[float | None],
    "n4_convergence": typing.NotRequired[str | None],
    "n4_shrink_factor": typing.NotRequired[int | None],
    "n4_bspline_params": typing.NotRequired[str | None],
    "atropos_segmentation_icm": typing.NotRequired[str | None],
    "atropos_segmentation_use_euclidean_distance": typing.NotRequired[bool | None],
    "test_debug_mode": typing.NotRequired[int | None],
})
AntsAtroposN4ShParamsDict = _AntsAtroposN4ShParamsDictNoTag | AntsAtroposN4ShParamsDictTagged


def ants_atropos_n4_sh_segmentation_priors(
    segmentation_priors_pattern: str | None = None,
    segmentation_priors_folder: InputPathType | None = None,
) -> AntsAtroposN4ShSegmentationPriorsParamsDictTagged:
    """
    Build parameters.
    
    Args:
        segmentation_priors_pattern: Prior probability images initializing the\
            segmentation. Specified using c-style formatting, e.g. -p\
            labelsPriors%02d.nii.gz. If this is not specified, k-means\
            initialization is used instead.
        segmentation_priors_folder: Included so.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "segmentation_priors",
    }
    if segmentation_priors_pattern is not None:
        params["segmentation_priors_pattern"] = segmentation_priors_pattern
    if segmentation_priors_folder is not None:
        params["segmentation_priors_folder"] = segmentation_priors_folder
    return params


def ants_atropos_n4_sh_segmentation_priors_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `AntsAtroposN4ShSegmentationPriorsParamsDict` 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("segmentation_priors_pattern", None) is not None:
        if not isinstance(params["segmentation_priors_pattern"], str):
            raise StyxValidationError(f'`segmentation_priors_pattern` has the wrong type: Received `{type(params.get("segmentation_priors_pattern", None))}` expected `str | None`')
    if params.get("segmentation_priors_folder", None) is not None:
        if not isinstance(params["segmentation_priors_folder"], (pathlib.Path, str)):
            raise StyxValidationError(f'`segmentation_priors_folder` has the wrong type: Received `{type(params.get("segmentation_priors_folder", None))}` expected `InputPathType | None`')


def ants_atropos_n4_sh_segmentation_priors_cargs(
    params: AntsAtroposN4ShSegmentationPriorsParamsDict,
    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 = []
    if params.get("segmentation_priors_pattern", None) is not None or params.get("segmentation_priors_folder", None) is not None:
        cargs.append((params.get("segmentation_priors_pattern", None) if (params.get("segmentation_priors_pattern", None) is not None) else "") + "/" + (execution.input_file(params.get("segmentation_priors_folder", None)) if (params.get("segmentation_priors_folder", None) is not None) else ""))
    return cargs


class AntsAtroposN4ShOutputs(typing.NamedTuple):
    """
    Output object returned when calling `AntsAtroposN4ShParamsDict(...)`.
    """
    root: OutputPathType
    """Output root folder. This is the root folder for all outputs."""
    n4_corrected: OutputPathType
    """N4 corrected image."""
    segmentation: OutputPathType
    """Segmentation image."""
    segmentation_posteriors: OutputPathType
    """Segmentation posteriors image."""


def ants_atropos_n4_sh_params(
    image_dimension: typing.Literal[2, 3],
    input_image: InputPathType,
    mask_image: InputPathType,
    number_of_classes: int,
    output_prefix: str,
    segmentation_priors: AntsAtroposN4ShSegmentationPriorsParamsDict,
    max_n4_atropos_iterations: int | None = None,
    max_atropos_iterations: int | None = None,
    mrf: str | None = None,
    denoise_anatomical_images: bool | None = None,
    posterior_formulation: typing.Literal["Socrates[ 1 ]", "Aristotle[ 1 ]"] | None = None,
    label_propagation: str | None = None,
    posterior_label_for_n4_weight_mask: str | None = None,
    image_file_suffix: str | None = None,
    keep_temporary_files: bool | None = None,
    use_random_seeding: bool | None = None,
    atropos_segmentation_prior_weight: float | None = None,
    n4_convergence: str | None = None,
    n4_shrink_factor: int | None = None,
    n4_bspline_params: str | None = None,
    atropos_segmentation_icm: str | None = None,
    atropos_segmentation_use_euclidean_distance: bool | None = None,
    test_debug_mode: int | None = None,
) -> AntsAtroposN4ShParamsDictTagged:
    """
    Build parameters.
    
    Args:
        image_dimension: 2 or 3, for 2- or 3-dimensional image.
        input_image: Anatomical image, typically T1. If more than one\
            anatomical image is specified, subsequent images are also used during\
            the segmentation process.
        mask_image: Binary mask defining the region of interest.
        number_of_classes: Number of classes defining the segmentation.
        output_prefix: The following images are created:\
            {output_prefix}N4Corrected.{output_suffix},\
            {output_prefix}Segmentation.{output_suffix},\
            {output_prefix}SegmentationPosteriors.{output_suffix}.
        segmentation_priors: Prior probability images initializing the\
            segmentation. Specified using c-style formatting, e.g. -p\
            labelsPriors%02d.nii.gz. If this is not specified, k-means\
            initialization is used instead.
        max_n4_atropos_iterations: Maximum number of (outer loop) iterations\
            between N4 <-> Atropos (default = 15).
        max_atropos_iterations: Maximum number of (inner loop) iterations in\
            Atropos (default = 3).
        mrf: Specifies MRF prior (of the form '[ weight,neighborhood ]', e.g.\
            '[ 0.1,1x1x1 ]' which is default).
        denoise_anatomical_images: Denoise anatomical images (1) or not (0)\
            (default = 1).
        posterior_formulation: Posterior formulation and whether or not to use\
            mixture model proportions. e.g 'Socrates[ 1 ]' (default) or 'Aristotle[\
            1 ]'. Choose the latter if you want to use the distance priors, see\
            also the -l option for label propagation control (default = 'Socrates[\
            1 ]').
        label_propagation: Incorporate a distance prior into the 'Aristotle'\
            posterior formulation. Should be of the form 'label[\
            lambda,boundaryProbability ]' where label is a value of 1,2,3,...\
            denoting label ID. The label probability for anything outside the\
            current label\
            \
            = boundaryProbability * exp( -lambda * distanceFromBoundary )\
            \
            Intuitively, smaller lambda values will increase the spatial\
            capture range of the distance prior. To apply to all label values,\
            simply omit specifying the label, i.e. -l '[\
            lambda,boundaryProbability ]'.
        posterior_label_for_n4_weight_mask: Which posterior probability image\
            should be used to define the N4 weight mask. Can also specify multiple\
            posteriors in which case the chosen posteriors are combined.
        image_file_suffix: Any of the standard ITK IO formats e.g. nrrd, nii.gz\
            (default), mhd.
        keep_temporary_files: Keep temporary files on disk (1) or delete them\
            (0) (default = 0).
        use_random_seeding: Use random number generated from system clock in\
            Atropos (default = 1).
        atropos_segmentation_prior_weight: Atropos spatial prior probability\
            weight for the segmentation (default = 0.25).
        n4_convergence: Convergence parameters for N4, see '-c' option in\
            N4BiasFieldCorrection (default = [50x50x50x50,0.0000001]).
        n4_shrink_factor: Shrink factor for N4 (default = 4).
        n4_bspline_params: N4 b-spline specification, see '-b' option in\
            N4BiasFieldCorrection (default = [200,0,0,0]).
        atropos_segmentation_icm: ICM parameters for segmentation, see '-g'\
            option in Atropos (default = [1,1]).
        atropos_segmentation_use_euclidean_distance: Use euclidean distances in\
            distance prior formulation (1) or not (0), see Atropos usage for\
            details (default = 1).
        test_debug_mode: If > 0, attempts to continue after errors.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "ants/antsAtroposN4.sh",
        "image_dimension": image_dimension,
        "input_image": input_image,
        "mask_image": mask_image,
        "number_of_classes": number_of_classes,
        "output_prefix": output_prefix,
        "segmentation_priors": segmentation_priors,
    }
    if max_n4_atropos_iterations is not None:
        params["max_n4_atropos_iterations"] = max_n4_atropos_iterations
    if max_atropos_iterations is not None:
        params["max_atropos_iterations"] = max_atropos_iterations
    if mrf is not None:
        params["mrf"] = mrf
    if denoise_anatomical_images is not None:
        params["denoise_anatomical_images"] = denoise_anatomical_images
    if posterior_formulation is not None:
        params["posterior_formulation"] = posterior_formulation
    if label_propagation is not None:
        params["label_propagation"] = label_propagation
    if posterior_label_for_n4_weight_mask is not None:
        params["posterior_label_for_n4_weight_mask"] = posterior_label_for_n4_weight_mask
    if image_file_suffix is not None:
        params["image_file_suffix"] = image_file_suffix
    if keep_temporary_files is not None:
        params["keep_temporary_files"] = keep_temporary_files
    if use_random_seeding is not None:
        params["use_random_seeding"] = use_random_seeding
    if atropos_segmentation_prior_weight is not None:
        params["atropos_segmentation_prior_weight"] = atropos_segmentation_prior_weight
    if n4_convergence is not None:
        params["n4_convergence"] = n4_convergence
    if n4_shrink_factor is not None:
        params["n4_shrink_factor"] = n4_shrink_factor
    if n4_bspline_params is not None:
        params["n4_bspline_params"] = n4_bspline_params
    if atropos_segmentation_icm is not None:
        params["atropos_segmentation_icm"] = atropos_segmentation_icm
    if atropos_segmentation_use_euclidean_distance is not None:
        params["atropos_segmentation_use_euclidean_distance"] = atropos_segmentation_use_euclidean_distance
    if test_debug_mode is not None:
        params["test_debug_mode"] = test_debug_mode
    return params


def ants_atropos_n4_sh_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `AntsAtroposN4ShParamsDict` 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("input_image", None) is None:
        raise StyxValidationError("`input_image` must not be None")
    if not isinstance(params["input_image"], (pathlib.Path, str)):
        raise StyxValidationError(f'`input_image` has the wrong type: Received `{type(params.get("input_image", None))}` expected `InputPathType`')
    if params.get("mask_image", None) is None:
        raise StyxValidationError("`mask_image` must not be None")
    if not isinstance(params["mask_image"], (pathlib.Path, str)):
        raise StyxValidationError(f'`mask_image` has the wrong type: Received `{type(params.get("mask_image", None))}` expected `InputPathType`')
    if params.get("number_of_classes", None) is None:
        raise StyxValidationError("`number_of_classes` must not be None")
    if not isinstance(params["number_of_classes"], int):
        raise StyxValidationError(f'`number_of_classes` has the wrong type: Received `{type(params.get("number_of_classes", None))}` expected `int`')
    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("max_n4_atropos_iterations", None) is not None:
        if not isinstance(params["max_n4_atropos_iterations"], int):
            raise StyxValidationError(f'`max_n4_atropos_iterations` has the wrong type: Received `{type(params.get("max_n4_atropos_iterations", None))}` expected `int | None`')
        if params["max_n4_atropos_iterations"] < 1:
            raise StyxValidationError("Parameter `max_n4_atropos_iterations` must be at least 1")
    if params.get("max_atropos_iterations", None) is not None:
        if not isinstance(params["max_atropos_iterations"], int):
            raise StyxValidationError(f'`max_atropos_iterations` has the wrong type: Received `{type(params.get("max_atropos_iterations", None))}` expected `int | None`')
        if params["max_atropos_iterations"] < 1:
            raise StyxValidationError("Parameter `max_atropos_iterations` must be at least 1")
    if params.get("segmentation_priors", None) is None:
        raise StyxValidationError("`segmentation_priors` must not be None")
    ants_atropos_n4_sh_segmentation_priors_validate(params["segmentation_priors"])
    if params.get("mrf", None) is not None:
        if not isinstance(params["mrf"], str):
            raise StyxValidationError(f'`mrf` has the wrong type: Received `{type(params.get("mrf", None))}` expected `str | None`')
    if params.get("denoise_anatomical_images", None) is not None:
        if not isinstance(params["denoise_anatomical_images"], bool):
            raise StyxValidationError(f'`denoise_anatomical_images` has the wrong type: Received `{type(params.get("denoise_anatomical_images", None))}` expected `bool | None`')
    if params.get("posterior_formulation", None) is not None:
        if not isinstance(params["posterior_formulation"], str):
            raise StyxValidationError(f'`posterior_formulation` has the wrong type: Received `{type(params.get("posterior_formulation", None))}` expected `typing.Literal["Socrates[ 1 ]", "Aristotle[ 1 ]"] | None`')
        if params["posterior_formulation"] not in ["Socrates[ 1 ]", "Aristotle[ 1 ]"]:
            raise StyxValidationError("Parameter `posterior_formulation` must be one of [\"Socrates[ 1 ]\", \"Aristotle[ 1 ]\"]")
    if params.get("label_propagation", None) is not None:
        if not isinstance(params["label_propagation"], str):
            raise StyxValidationError(f'`label_propagation` has the wrong type: Received `{type(params.get("label_propagation", None))}` expected `str | None`')
    if params.get("posterior_label_for_n4_weight_mask", None) is not None:
        if not isinstance(params["posterior_label_for_n4_weight_mask"], str):
            raise StyxValidationError(f'`posterior_label_for_n4_weight_mask` has the wrong type: Received `{type(params.get("posterior_label_for_n4_weight_mask", None))}` expected `str | None`')
    if params.get("image_file_suffix", None) is not None:
        if not isinstance(params["image_file_suffix"], str):
            raise StyxValidationError(f'`image_file_suffix` has the wrong type: Received `{type(params.get("image_file_suffix", None))}` expected `str | None`')
    if params.get("keep_temporary_files", None) is not None:
        if not isinstance(params["keep_temporary_files"], bool):
            raise StyxValidationError(f'`keep_temporary_files` has the wrong type: Received `{type(params.get("keep_temporary_files", None))}` expected `bool | None`')
    if params.get("use_random_seeding", None) is not None:
        if not isinstance(params["use_random_seeding"], bool):
            raise StyxValidationError(f'`use_random_seeding` has the wrong type: Received `{type(params.get("use_random_seeding", None))}` expected `bool | None`')
    if params.get("atropos_segmentation_prior_weight", None) is not None:
        if not isinstance(params["atropos_segmentation_prior_weight"], (float, int)):
            raise StyxValidationError(f'`atropos_segmentation_prior_weight` has the wrong type: Received `{type(params.get("atropos_segmentation_prior_weight", None))}` expected `float | None`')
    if params.get("n4_convergence", None) is not None:
        if not isinstance(params["n4_convergence"], str):
            raise StyxValidationError(f'`n4_convergence` has the wrong type: Received `{type(params.get("n4_convergence", None))}` expected `str | None`')
    if params.get("n4_shrink_factor", None) is not None:
        if not isinstance(params["n4_shrink_factor"], int):
            raise StyxValidationError(f'`n4_shrink_factor` has the wrong type: Received `{type(params.get("n4_shrink_factor", None))}` expected `int | None`')
    if params.get("n4_bspline_params", None) is not None:
        if not isinstance(params["n4_bspline_params"], str):
            raise StyxValidationError(f'`n4_bspline_params` has the wrong type: Received `{type(params.get("n4_bspline_params", None))}` expected `str | None`')
    if params.get("atropos_segmentation_icm", None) is not None:
        if not isinstance(params["atropos_segmentation_icm"], str):
            raise StyxValidationError(f'`atropos_segmentation_icm` has the wrong type: Received `{type(params.get("atropos_segmentation_icm", None))}` expected `str | None`')
    if params.get("atropos_segmentation_use_euclidean_distance", None) is not None:
        if not isinstance(params["atropos_segmentation_use_euclidean_distance"], bool):
            raise StyxValidationError(f'`atropos_segmentation_use_euclidean_distance` has the wrong type: Received `{type(params.get("atropos_segmentation_use_euclidean_distance", None))}` expected `bool | None`')
    if params.get("test_debug_mode", None) is not None:
        if not isinstance(params["test_debug_mode"], int):
            raise StyxValidationError(f'`test_debug_mode` has the wrong type: Received `{type(params.get("test_debug_mode", None))}` expected `int | None`')


def ants_atropos_n4_sh_cargs(
    params: AntsAtroposN4ShParamsDict,
    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("antsAtroposN4.sh")
    cargs.extend([
        "-d",
        str(params.get("image_dimension", None))
    ])
    cargs.extend([
        "-a",
        execution.input_file(params.get("input_image", None))
    ])
    cargs.extend([
        "-x",
        execution.input_file(params.get("mask_image", None))
    ])
    cargs.extend([
        "-c",
        str(params.get("number_of_classes", None))
    ])
    cargs.extend([
        "-o",
        params.get("output_prefix", None)
    ])
    if params.get("max_n4_atropos_iterations", None) is not None:
        cargs.extend([
            "-m",
            str(params.get("max_n4_atropos_iterations", None))
        ])
    if params.get("max_atropos_iterations", None) is not None:
        cargs.extend([
            "-n",
            str(params.get("max_atropos_iterations", None))
        ])
    cargs.extend([
        "-p",
        *ants_atropos_n4_sh_segmentation_priors_cargs(params.get("segmentation_priors", None), execution)
    ])
    if params.get("mrf", None) is not None:
        cargs.extend([
            "-r",
            params.get("mrf", None)
        ])
    if params.get("denoise_anatomical_images", None) is not None:
        cargs.extend([
            "-g",
            ("1" if params.get("denoise_anatomical_images", None) else "0")
        ])
    if params.get("posterior_formulation", None) is not None:
        cargs.extend([
            "-b",
            params.get("posterior_formulation", None)
        ])
    if params.get("label_propagation", None) is not None:
        cargs.extend([
            "-l",
            params.get("label_propagation", None)
        ])
    if params.get("posterior_label_for_n4_weight_mask", None) is not None:
        cargs.extend([
            "-y",
            params.get("posterior_label_for_n4_weight_mask", None)
        ])
    if params.get("image_file_suffix", None) is not None:
        cargs.extend([
            "-s",
            params.get("image_file_suffix", None)
        ])
    if params.get("keep_temporary_files", None) is not None:
        cargs.extend([
            "-k",
            ("1" if params.get("keep_temporary_files", None) else "0")
        ])
    if params.get("use_random_seeding", None) is not None:
        cargs.extend([
            "-u",
            ("1" if params.get("use_random_seeding", None) else "0")
        ])
    if params.get("atropos_segmentation_prior_weight", None) is not None:
        cargs.extend([
            "-w",
            str(params.get("atropos_segmentation_prior_weight", None))
        ])
    if params.get("n4_convergence", None) is not None:
        cargs.extend([
            "-e",
            params.get("n4_convergence", None)
        ])
    if params.get("n4_shrink_factor", None) is not None:
        cargs.extend([
            "-f",
            str(params.get("n4_shrink_factor", None))
        ])
    if params.get("n4_bspline_params", None) is not None:
        cargs.extend([
            "-q",
            params.get("n4_bspline_params", None)
        ])
    if params.get("atropos_segmentation_icm", None) is not None:
        cargs.extend([
            "-i",
            params.get("atropos_segmentation_icm", None)
        ])
    if params.get("atropos_segmentation_use_euclidean_distance", None) is not None:
        cargs.extend([
            "-j",
            ("1" if params.get("atropos_segmentation_use_euclidean_distance", None) else "0")
        ])
    if params.get("test_debug_mode", None) is not None:
        cargs.extend([
            "-z",
            str(params.get("test_debug_mode", None))
        ])
    return cargs


def ants_atropos_n4_sh_outputs(
    params: AntsAtroposN4ShParamsDict,
    execution: Execution,
) -> AntsAtroposN4ShOutputs:
    """
    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 = AntsAtroposN4ShOutputs(
        root=execution.output_file("."),
        n4_corrected=execution.output_file(params.get("output_prefix", None) + "N4Corrected.[OUTPUT_SUFFIX]"),
        segmentation=execution.output_file(params.get("output_prefix", None) + "Segmentation.[OUTPUT_SUFFIX]"),
        segmentation_posteriors=execution.output_file(params.get("output_prefix", None) + "SegmentationPosteriors.[OUTPUT_SUFFIX]"),
    )
    return ret


def ants_atropos_n4_sh_execute(
    params: AntsAtroposN4ShParamsDict,
    runner: Runner | None = None,
) -> AntsAtroposN4ShOutputs:
    """
    antsAtroposN4.sh
    
    antsAtroposN4.sh iterates between N4 <-> Atropos to improve segmentation
    results.
    
    Author: ANTs Developers
    
    URL: https://github.com/ANTsX/ANTs
    
    Args:
        params: The parameters.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `AntsAtroposN4ShOutputs`).
    """
    ants_atropos_n4_sh_validate(params)
    runner = runner or get_global_runner()
    execution = runner.start_execution(ANTS_ATROPOS_N4_SH_METADATA)
    params = execution.params(params)
    cargs = ants_atropos_n4_sh_cargs(params, execution)
    ret = ants_atropos_n4_sh_outputs(params, execution)
    execution.run(cargs)
    return ret


def ants_atropos_n4_sh(
    image_dimension: typing.Literal[2, 3],
    input_image: InputPathType,
    mask_image: InputPathType,
    number_of_classes: int,
    output_prefix: str,
    segmentation_priors: AntsAtroposN4ShSegmentationPriorsParamsDict,
    max_n4_atropos_iterations: int | None = None,
    max_atropos_iterations: int | None = None,
    mrf: str | None = None,
    denoise_anatomical_images: bool | None = None,
    posterior_formulation: typing.Literal["Socrates[ 1 ]", "Aristotle[ 1 ]"] | None = None,
    label_propagation: str | None = None,
    posterior_label_for_n4_weight_mask: str | None = None,
    image_file_suffix: str | None = None,
    keep_temporary_files: bool | None = None,
    use_random_seeding: bool | None = None,
    atropos_segmentation_prior_weight: float | None = None,
    n4_convergence: str | None = None,
    n4_shrink_factor: int | None = None,
    n4_bspline_params: str | None = None,
    atropos_segmentation_icm: str | None = None,
    atropos_segmentation_use_euclidean_distance: bool | None = None,
    test_debug_mode: int | None = None,
    runner: Runner | None = None,
) -> AntsAtroposN4ShOutputs:
    """
    antsAtroposN4.sh
    
    antsAtroposN4.sh iterates between N4 <-> Atropos to improve segmentation
    results.
    
    Author: ANTs Developers
    
    URL: https://github.com/ANTsX/ANTs
    
    Args:
        image_dimension: 2 or 3, for 2- or 3-dimensional image.
        input_image: Anatomical image, typically T1. If more than one\
            anatomical image is specified, subsequent images are also used during\
            the segmentation process.
        mask_image: Binary mask defining the region of interest.
        number_of_classes: Number of classes defining the segmentation.
        output_prefix: The following images are created:\
            {output_prefix}N4Corrected.{output_suffix},\
            {output_prefix}Segmentation.{output_suffix},\
            {output_prefix}SegmentationPosteriors.{output_suffix}.
        segmentation_priors: Prior probability images initializing the\
            segmentation. Specified using c-style formatting, e.g. -p\
            labelsPriors%02d.nii.gz. If this is not specified, k-means\
            initialization is used instead.
        max_n4_atropos_iterations: Maximum number of (outer loop) iterations\
            between N4 <-> Atropos (default = 15).
        max_atropos_iterations: Maximum number of (inner loop) iterations in\
            Atropos (default = 3).
        mrf: Specifies MRF prior (of the form '[ weight,neighborhood ]', e.g.\
            '[ 0.1,1x1x1 ]' which is default).
        denoise_anatomical_images: Denoise anatomical images (1) or not (0)\
            (default = 1).
        posterior_formulation: Posterior formulation and whether or not to use\
            mixture model proportions. e.g 'Socrates[ 1 ]' (default) or 'Aristotle[\
            1 ]'. Choose the latter if you want to use the distance priors, see\
            also the -l option for label propagation control (default = 'Socrates[\
            1 ]').
        label_propagation: Incorporate a distance prior into the 'Aristotle'\
            posterior formulation. Should be of the form 'label[\
            lambda,boundaryProbability ]' where label is a value of 1,2,3,...\
            denoting label ID. The label probability for anything outside the\
            current label\
            \
            = boundaryProbability * exp( -lambda * distanceFromBoundary )\
            \
            Intuitively, smaller lambda values will increase the spatial\
            capture range of the distance prior. To apply to all label values,\
            simply omit specifying the label, i.e. -l '[\
            lambda,boundaryProbability ]'.
        posterior_label_for_n4_weight_mask: Which posterior probability image\
            should be used to define the N4 weight mask. Can also specify multiple\
            posteriors in which case the chosen posteriors are combined.
        image_file_suffix: Any of the standard ITK IO formats e.g. nrrd, nii.gz\
            (default), mhd.
        keep_temporary_files: Keep temporary files on disk (1) or delete them\
            (0) (default = 0).
        use_random_seeding: Use random number generated from system clock in\
            Atropos (default = 1).
        atropos_segmentation_prior_weight: Atropos spatial prior probability\
            weight for the segmentation (default = 0.25).
        n4_convergence: Convergence parameters for N4, see '-c' option in\
            N4BiasFieldCorrection (default = [50x50x50x50,0.0000001]).
        n4_shrink_factor: Shrink factor for N4 (default = 4).
        n4_bspline_params: N4 b-spline specification, see '-b' option in\
            N4BiasFieldCorrection (default = [200,0,0,0]).
        atropos_segmentation_icm: ICM parameters for segmentation, see '-g'\
            option in Atropos (default = [1,1]).
        atropos_segmentation_use_euclidean_distance: Use euclidean distances in\
            distance prior formulation (1) or not (0), see Atropos usage for\
            details (default = 1).
        test_debug_mode: If > 0, attempts to continue after errors.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `AntsAtroposN4ShOutputs`).
    """
    params = ants_atropos_n4_sh_params(
        image_dimension=image_dimension,
        input_image=input_image,
        mask_image=mask_image,
        number_of_classes=number_of_classes,
        output_prefix=output_prefix,
        max_n4_atropos_iterations=max_n4_atropos_iterations,
        max_atropos_iterations=max_atropos_iterations,
        segmentation_priors=segmentation_priors,
        mrf=mrf,
        denoise_anatomical_images=denoise_anatomical_images,
        posterior_formulation=posterior_formulation,
        label_propagation=label_propagation,
        posterior_label_for_n4_weight_mask=posterior_label_for_n4_weight_mask,
        image_file_suffix=image_file_suffix,
        keep_temporary_files=keep_temporary_files,
        use_random_seeding=use_random_seeding,
        atropos_segmentation_prior_weight=atropos_segmentation_prior_weight,
        n4_convergence=n4_convergence,
        n4_shrink_factor=n4_shrink_factor,
        n4_bspline_params=n4_bspline_params,
        atropos_segmentation_icm=atropos_segmentation_icm,
        atropos_segmentation_use_euclidean_distance=atropos_segmentation_use_euclidean_distance,
        test_debug_mode=test_debug_mode,
    )
    return ants_atropos_n4_sh_execute(params, runner)


__all__ = [
    "ANTS_ATROPOS_N4_SH_METADATA",
    "AntsAtroposN4ShOutputs",
    "AntsAtroposN4ShParamsDict",
    "AntsAtroposN4ShParamsDictTagged",
    "AntsAtroposN4ShSegmentationPriorsParamsDict",
    "AntsAtroposN4ShSegmentationPriorsParamsDictTagged",
    "ants_atropos_n4_sh",
    "ants_atropos_n4_sh_execute",
    "ants_atropos_n4_sh_params",
    "ants_atropos_n4_sh_segmentation_priors",
]
