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

import typing
import pathlib
from styxdefs import *

ANTS_MULTIVARIATE_TEMPLATE_CONSTRUCTION2_SH_METADATA = Metadata(
    id="dcd5ca5151722ef03dfc3e47fb8b190e2c1c0932.boutiques",
    name="antsMultivariateTemplateConstruction2.sh",
    package="ants",
    container_image_tag="antsx/ants:v2.5.3",
)


_AntsMultivariateTemplateConstruction2ShParamsDictNoTag = typing.TypedDict('_AntsMultivariateTemplateConstruction2ShParamsDictNoTag', {
    "dimension": typing.Literal[2, 3, 4],
    "output_prefix": typing.NotRequired[str | None],
    "image_statistic": typing.NotRequired[typing.Literal[0, 1, 2] | None],
    "sharpening": typing.NotRequired[typing.Literal[0, 1, 2] | None],
    "backup_images": typing.NotRequired[bool | None],
    "parallel_control": typing.NotRequired[typing.Literal[0, 1, 2, 3, 4, 5] | None],
    "single_precision": typing.NotRequired[bool | None],
    "gradient_step": typing.NotRequired[float | None],
    "iterations": typing.NotRequired[int | None],
    "cpu_cores": typing.NotRequired[int | None],
    "num_modalities": typing.NotRequired[int | None],
    "modality_weights": typing.NotRequired[str | None],
    "max_iterations": typing.NotRequired[str | None],
    "shrink_factors": typing.NotRequired[str | None],
    "smoothing_kernels": typing.NotRequired[str | None],
    "n4_bias_correction": typing.NotRequired[bool | None],
    "prepend_commands": typing.NotRequired[str | None],
    "rigid_registration": typing.NotRequired[bool | None],
    "linear_registration": typing.NotRequired[bool | None],
    "similarity_metric": typing.NotRequired[str | None],
    "transformation_type": typing.NotRequired[str | None],
    "walltime": typing.NotRequired[str | None],
    "memory_limit": typing.NotRequired[str | None],
    "xgrid_args": typing.NotRequired[str | None],
    "update_template": typing.NotRequired[bool | None],
    "target_volume": typing.NotRequired[list[InputPathType] | None],
    "input_images": list[InputPathType],
})
AntsMultivariateTemplateConstruction2ShParamsDictTagged = typing.TypedDict('AntsMultivariateTemplateConstruction2ShParamsDictTagged', {
    "@type": typing.Literal["ants/antsMultivariateTemplateConstruction2.sh"],
    "dimension": typing.Literal[2, 3, 4],
    "output_prefix": typing.NotRequired[str | None],
    "image_statistic": typing.NotRequired[typing.Literal[0, 1, 2] | None],
    "sharpening": typing.NotRequired[typing.Literal[0, 1, 2] | None],
    "backup_images": typing.NotRequired[bool | None],
    "parallel_control": typing.NotRequired[typing.Literal[0, 1, 2, 3, 4, 5] | None],
    "single_precision": typing.NotRequired[bool | None],
    "gradient_step": typing.NotRequired[float | None],
    "iterations": typing.NotRequired[int | None],
    "cpu_cores": typing.NotRequired[int | None],
    "num_modalities": typing.NotRequired[int | None],
    "modality_weights": typing.NotRequired[str | None],
    "max_iterations": typing.NotRequired[str | None],
    "shrink_factors": typing.NotRequired[str | None],
    "smoothing_kernels": typing.NotRequired[str | None],
    "n4_bias_correction": typing.NotRequired[bool | None],
    "prepend_commands": typing.NotRequired[str | None],
    "rigid_registration": typing.NotRequired[bool | None],
    "linear_registration": typing.NotRequired[bool | None],
    "similarity_metric": typing.NotRequired[str | None],
    "transformation_type": typing.NotRequired[str | None],
    "walltime": typing.NotRequired[str | None],
    "memory_limit": typing.NotRequired[str | None],
    "xgrid_args": typing.NotRequired[str | None],
    "update_template": typing.NotRequired[bool | None],
    "target_volume": typing.NotRequired[list[InputPathType] | None],
    "input_images": list[InputPathType],
})
AntsMultivariateTemplateConstruction2ShParamsDict = _AntsMultivariateTemplateConstruction2ShParamsDictNoTag | AntsMultivariateTemplateConstruction2ShParamsDictTagged


class AntsMultivariateTemplateConstruction2ShOutputs(typing.NamedTuple):
    """
    Output object returned when calling `AntsMultivariateTemplateConstruction2ShParamsDict(...)`.
    """
    root: OutputPathType
    """Output root folder. This is the root folder for all outputs."""
    intermediate_templates_dir: OutputPathType
    """Directory containing intermediate templates and shape update warps from
    each iteration"""


def ants_multivariate_template_construction2_sh_params(
    dimension: typing.Literal[2, 3, 4],
    input_images: list[InputPathType],
    output_prefix: str | None = None,
    image_statistic: typing.Literal[0, 1, 2] | None = None,
    sharpening: typing.Literal[0, 1, 2] | None = None,
    backup_images: bool | None = None,
    parallel_control: typing.Literal[0, 1, 2, 3, 4, 5] | None = None,
    single_precision: bool | None = None,
    gradient_step: float | None = None,
    iterations: int | None = None,
    cpu_cores: int | None = None,
    num_modalities: int | None = None,
    modality_weights: str | None = None,
    max_iterations: str | None = None,
    shrink_factors: str | None = None,
    smoothing_kernels: str | None = None,
    n4_bias_correction: bool | None = None,
    prepend_commands: str | None = None,
    rigid_registration: bool | None = None,
    linear_registration: bool | None = None,
    similarity_metric: str | None = None,
    transformation_type: str | None = None,
    walltime: str | None = None,
    memory_limit: str | None = None,
    xgrid_args: str | None = None,
    update_template: bool | None = None,
    target_volume: list[InputPathType] | None = None,
) -> AntsMultivariateTemplateConstruction2ShParamsDictTagged:
    """
    Build parameters.
    
    Args:
        dimension: ImageDimension: 2 or 3 (for 2 or 3 dimensional registration\
            of single volume), 4 (for template generation of time-series data).
        input_images: List of images in the current directory, eg *_t1.nii.gz.\
            Should be at the end of the command. Optionally, one can specify a .csv\
            or .txt file where each line is the location of the input image. One\
            can also specify more than one file for each image for multi-modal\
            template construction (e.g. t1 and t2). For the multi-modal case, the\
            templates will be consecutively numbered.
        output_prefix: A prefix that is prepended to all output files (default\
            = "antsBTP").
        image_statistic: Image statistic used to summarize images (default 1):\
            0 = mean, 1 = mean of normalized intensities, 2 = median. Normalization\
            here means dividing each image by its mean intensity.
        sharpening: Sharpening applied to template at each iteration (default\
            1): 0 = none, 1 = Laplacian, 2 = Unsharp mask.
        backup_images: Backup images and results from all iterations (default =\
            0): Boolean to save the transform files, bias corrected inputs,\
            templates, transforms, and warped images for each iteration. By\
            default, only the templates and the shape update warp field are saved.
        parallel_control: Control for parallel computation (default 0): 0 = run\
            serially, 1 = SGE qsub, 2 = use PEXEC (localhost), 3 = Apple XGrid, 4 =\
            PBS qsub, 5 = SLURM.
        single_precision: Use single precision (default 1).
        gradient_step: Gradient step size (default 0.25): smaller in magnitude\
            results in more cautious steps. Use smaller steps to refine template\
            details. 0.25 is an upper (aggressive) limit for this parameter.
        iterations: Iteration limit (default 4): iterations of the template\
            construction (Iteration limit)*NumImages registrations.
        cpu_cores: Number of cpu cores to use locally for pexec option (default\
            2; requires "-c 2").
        num_modalities: Number of modalities used to construct the template\
            (default 1): For example, if one wanted to create a multimodal template\
            consisting of T1,T2,and FA components ("-k 3").
        modality_weights: Modality weights used in the similarity metric\
            (default = 1): specified as e.g. 1x0.5x0.75.
        max_iterations: Max iterations for each pairwise registration (default\
            = 100x100x70x20): specified in the form JxK...xF where J = max\
            iterations at first (coarsest) resolution, K = max iterations at next\
            resolution, F = max iterations at the final resolution.
        shrink_factors: Shrink factors in pairwise registration (default =\
            6x4x2x1): in the same form as max iterations. Must have the same number\
            of components as the iterations and smoothing. The shrink factors are\
            integer factors for downsampling the virtual space (usually the\
            template image) during registration.
        smoothing_kernels: Smoothing kernels in pairwise registration (default\
            = 3x2x1x0): also in the same form as max iterations and shrink factors,\
            with the same number of components. Standard deviation of a Gaussian\
            smoothing kernel applied to the images before downsampling at each\
            level. The kernel may be specified in mm units or voxels with "AxBxCmm"\
            or "AxBxCvox". Missing units implies vox.
        n4_bias_correction: N4BiasFieldCorrection of moving image: 0 off, 1 on\
            (default 1).
        prepend_commands: Commands to prepend to job scripts (e.g., change into\
            appropriate directory, set paths, etc).
        rigid_registration: Do rigid-body registration of inputs to the initial\
            template, before doing the main pairwise registration. 0 off 1 on\
            (default 0). If you are trying to refine or update an existing\
            template, you would use '-r 0'. Rigid initialization is useful when you\
            do not have an initial template, or you want to use a single image as a\
            reference for rigid alignment only.
        linear_registration: Use linear image registration stages during the\
            pairwise (template/subject) deformable registration. Otherwise,\
            registration is limited to SyN or B-spline SyN (see '-t' option). This\
            is '1' by default.
        similarity_metric: Type of similarity metric used for pairwise\
            registration (default = CC). Options are case sensitive. CC =\
            cross-correlation, MI = mutual information, MSQ = mean square\
            difference, DEMONS = demon's metric. A similarity metric per modality\
            can be specified. If the CC metric is chosen, one can also specify the\
            radius in brackets, e.g. '-m "CC[4]"'.
        transformation_type: Type of transformation model used for registration\
            (default = SyN): Options are case sensitive. SyN = Greedy SyN,\
            BSplineSyN = Greedy B-spline SyN, TimeVaryingVelocityField =\
            Time-varying velocity field, TimeVaryingBSplineVelocityField =\
            Time-varying B-spline velocity field. Transformation parameters may be\
            specified with brackets, eg '-t "SyN[0.1,3,0]"'. To use linear\
            registration only, options are: Affine = Affine (runs Rigid + Affine),\
            Rigid = Rigid (runs Rigid only).
        walltime: Walltime (default = 20:00:00): Option for PBS/SLURM qsub\
            specifying requested time per pairwise registration.
        memory_limit: Memory limit (default = 8gb): Option for PBS/SLURM qsub\
            specifying requested memory per pairwise registration.
        xgrid_args: XGrid arguments (e.g., -x "-p password -h controlhost").
        update_template: Update the template with the full affine transform\
            (default 1). If 0, the rigid component of the affine transform will not\
            be used to update the template. If your template drifts in translation\
            or orientation try "-y 0".
        target_volume: Use this this volume as the target of all inputs. When\
            not used, the script will create an unbiased starting point by\
            averaging all inputs, then aligning the center of mass of all inputs to\
            that of the initial average. If you do not use -z, it is recommended to\
            use "-r 1". Use the full path. For multiple modalities, specify -z\
            modality1.nii.gz -z modality2.nii.gz ... in the same modality order as\
            the input images.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "ants/antsMultivariateTemplateConstruction2.sh",
        "dimension": dimension,
        "input_images": input_images,
    }
    if output_prefix is not None:
        params["output_prefix"] = output_prefix
    if image_statistic is not None:
        params["image_statistic"] = image_statistic
    if sharpening is not None:
        params["sharpening"] = sharpening
    if backup_images is not None:
        params["backup_images"] = backup_images
    if parallel_control is not None:
        params["parallel_control"] = parallel_control
    if single_precision is not None:
        params["single_precision"] = single_precision
    if gradient_step is not None:
        params["gradient_step"] = gradient_step
    if iterations is not None:
        params["iterations"] = iterations
    if cpu_cores is not None:
        params["cpu_cores"] = cpu_cores
    if num_modalities is not None:
        params["num_modalities"] = num_modalities
    if modality_weights is not None:
        params["modality_weights"] = modality_weights
    if max_iterations is not None:
        params["max_iterations"] = max_iterations
    if shrink_factors is not None:
        params["shrink_factors"] = shrink_factors
    if smoothing_kernels is not None:
        params["smoothing_kernels"] = smoothing_kernels
    if n4_bias_correction is not None:
        params["n4_bias_correction"] = n4_bias_correction
    if prepend_commands is not None:
        params["prepend_commands"] = prepend_commands
    if rigid_registration is not None:
        params["rigid_registration"] = rigid_registration
    if linear_registration is not None:
        params["linear_registration"] = linear_registration
    if similarity_metric is not None:
        params["similarity_metric"] = similarity_metric
    if transformation_type is not None:
        params["transformation_type"] = transformation_type
    if walltime is not None:
        params["walltime"] = walltime
    if memory_limit is not None:
        params["memory_limit"] = memory_limit
    if xgrid_args is not None:
        params["xgrid_args"] = xgrid_args
    if update_template is not None:
        params["update_template"] = update_template
    if target_volume is not None:
        params["target_volume"] = target_volume
    return params


def ants_multivariate_template_construction2_sh_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `AntsMultivariateTemplateConstruction2ShParamsDict` 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("dimension", None) is None:
        raise StyxValidationError("`dimension` must not be None")
    if not isinstance(params["dimension"], int):
        raise StyxValidationError(f'`dimension` has the wrong type: Received `{type(params.get("dimension", None))}` expected `typing.Literal[2, 3, 4]`')
    if params["dimension"] not in [2, 3, 4]:
        raise StyxValidationError("Parameter `dimension` must be one of [2, 3, 4]")
    if params.get("output_prefix", None) is not 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 | None`')
    if params.get("image_statistic", None) is not None:
        if not isinstance(params["image_statistic"], int):
            raise StyxValidationError(f'`image_statistic` has the wrong type: Received `{type(params.get("image_statistic", None))}` expected `typing.Literal[0, 1, 2] | None`')
        if params["image_statistic"] not in [0, 1, 2]:
            raise StyxValidationError("Parameter `image_statistic` must be one of [0, 1, 2]")
    if params.get("sharpening", None) is not None:
        if not isinstance(params["sharpening"], int):
            raise StyxValidationError(f'`sharpening` has the wrong type: Received `{type(params.get("sharpening", None))}` expected `typing.Literal[0, 1, 2] | None`')
        if params["sharpening"] not in [0, 1, 2]:
            raise StyxValidationError("Parameter `sharpening` must be one of [0, 1, 2]")
    if params.get("backup_images", None) is not None:
        if not isinstance(params["backup_images"], bool):
            raise StyxValidationError(f'`backup_images` has the wrong type: Received `{type(params.get("backup_images", None))}` expected `bool | None`')
    if params.get("parallel_control", None) is not None:
        if not isinstance(params["parallel_control"], int):
            raise StyxValidationError(f'`parallel_control` has the wrong type: Received `{type(params.get("parallel_control", None))}` expected `typing.Literal[0, 1, 2, 3, 4, 5] | None`')
        if params["parallel_control"] not in [0, 1, 2, 3, 4, 5]:
            raise StyxValidationError("Parameter `parallel_control` must be one of [0, 1, 2, 3, 4, 5]")
    if params.get("single_precision", None) is not None:
        if not isinstance(params["single_precision"], bool):
            raise StyxValidationError(f'`single_precision` has the wrong type: Received `{type(params.get("single_precision", None))}` expected `bool | 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["gradient_step"] > 0.25:
            raise StyxValidationError("Parameter `gradient_step` must be at most 0.25")
    if params.get("iterations", None) is not None:
        if not isinstance(params["iterations"], int):
            raise StyxValidationError(f'`iterations` has the wrong type: Received `{type(params.get("iterations", None))}` expected `int | None`')
    if params.get("cpu_cores", None) is not None:
        if not isinstance(params["cpu_cores"], int):
            raise StyxValidationError(f'`cpu_cores` has the wrong type: Received `{type(params.get("cpu_cores", None))}` expected `int | None`')
    if params.get("num_modalities", None) is not None:
        if not isinstance(params["num_modalities"], int):
            raise StyxValidationError(f'`num_modalities` has the wrong type: Received `{type(params.get("num_modalities", None))}` expected `int | None`')
    if params.get("modality_weights", None) is not None:
        if not isinstance(params["modality_weights"], str):
            raise StyxValidationError(f'`modality_weights` has the wrong type: Received `{type(params.get("modality_weights", None))}` expected `str | None`')
    if params.get("max_iterations", None) is not None:
        if not isinstance(params["max_iterations"], str):
            raise StyxValidationError(f'`max_iterations` has the wrong type: Received `{type(params.get("max_iterations", None))}` expected `str | None`')
    if params.get("shrink_factors", None) is not None:
        if not isinstance(params["shrink_factors"], str):
            raise StyxValidationError(f'`shrink_factors` has the wrong type: Received `{type(params.get("shrink_factors", None))}` expected `str | None`')
    if params.get("smoothing_kernels", None) is not None:
        if not isinstance(params["smoothing_kernels"], str):
            raise StyxValidationError(f'`smoothing_kernels` has the wrong type: Received `{type(params.get("smoothing_kernels", None))}` expected `str | None`')
    if params.get("n4_bias_correction", None) is not None:
        if not isinstance(params["n4_bias_correction"], bool):
            raise StyxValidationError(f'`n4_bias_correction` has the wrong type: Received `{type(params.get("n4_bias_correction", None))}` expected `bool | None`')
    if params.get("prepend_commands", None) is not None:
        if not isinstance(params["prepend_commands"], str):
            raise StyxValidationError(f'`prepend_commands` has the wrong type: Received `{type(params.get("prepend_commands", None))}` expected `str | None`')
    if params.get("rigid_registration", None) is not None:
        if not isinstance(params["rigid_registration"], bool):
            raise StyxValidationError(f'`rigid_registration` has the wrong type: Received `{type(params.get("rigid_registration", None))}` expected `bool | None`')
    if params.get("linear_registration", None) is not None:
        if not isinstance(params["linear_registration"], bool):
            raise StyxValidationError(f'`linear_registration` has the wrong type: Received `{type(params.get("linear_registration", None))}` expected `bool | None`')
    if params.get("similarity_metric", None) is not None:
        if not isinstance(params["similarity_metric"], str):
            raise StyxValidationError(f'`similarity_metric` has the wrong type: Received `{type(params.get("similarity_metric", None))}` expected `str | None`')
    if params.get("transformation_type", None) is not None:
        if not isinstance(params["transformation_type"], str):
            raise StyxValidationError(f'`transformation_type` has the wrong type: Received `{type(params.get("transformation_type", None))}` expected `str | None`')
    if params.get("walltime", None) is not None:
        if not isinstance(params["walltime"], str):
            raise StyxValidationError(f'`walltime` has the wrong type: Received `{type(params.get("walltime", None))}` expected `str | None`')
    if params.get("memory_limit", None) is not None:
        if not isinstance(params["memory_limit"], str):
            raise StyxValidationError(f'`memory_limit` has the wrong type: Received `{type(params.get("memory_limit", None))}` expected `str | None`')
    if params.get("xgrid_args", None) is not None:
        if not isinstance(params["xgrid_args"], str):
            raise StyxValidationError(f'`xgrid_args` has the wrong type: Received `{type(params.get("xgrid_args", None))}` expected `str | None`')
    if params.get("update_template", None) is not None:
        if not isinstance(params["update_template"], bool):
            raise StyxValidationError(f'`update_template` has the wrong type: Received `{type(params.get("update_template", None))}` expected `bool | None`')
    if params.get("target_volume", None) is not None:
        if not isinstance(params["target_volume"], list):
            raise StyxValidationError(f'`target_volume` has the wrong type: Received `{type(params.get("target_volume", None))}` expected `list[InputPathType] | None`')
        for e in params["target_volume"]:
            if not isinstance(e, (pathlib.Path, str)):
                raise StyxValidationError(f'`target_volume` has the wrong type: Received `{type(params.get("target_volume", None))}` expected `list[InputPathType] | None`')
    if params.get("input_images", None) is None:
        raise StyxValidationError("`input_images` must not be None")
    if not isinstance(params["input_images"], list):
        raise StyxValidationError(f'`input_images` has the wrong type: Received `{type(params.get("input_images", None))}` expected `list[InputPathType]`')
    for e in params["input_images"]:
        if not isinstance(e, (pathlib.Path, str)):
            raise StyxValidationError(f'`input_images` has the wrong type: Received `{type(params.get("input_images", None))}` expected `list[InputPathType]`')


def ants_multivariate_template_construction2_sh_cargs(
    params: AntsMultivariateTemplateConstruction2ShParamsDict,
    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("antsMultivariateTemplateConstruction2.sh")
    cargs.extend([
        "-d",
        str(params.get("dimension", None))
    ])
    if params.get("output_prefix", None) is not None:
        cargs.extend([
            "-o",
            params.get("output_prefix", None)
        ])
    if params.get("image_statistic", None) is not None:
        cargs.extend([
            "-a",
            str(params.get("image_statistic", None))
        ])
    if params.get("sharpening", None) is not None:
        cargs.extend([
            "-A",
            str(params.get("sharpening", None))
        ])
    if params.get("backup_images", None) is not None:
        cargs.extend([
            "-b",
            ("1" if params.get("backup_images", None) else "0")
        ])
    if params.get("parallel_control", None) is not None:
        cargs.extend([
            "-c",
            str(params.get("parallel_control", None))
        ])
    if params.get("single_precision", None) is not None:
        cargs.extend([
            "-e",
            ("1" if params.get("single_precision", None) else "0")
        ])
    if params.get("gradient_step", None) is not None:
        cargs.extend([
            "-g",
            str(params.get("gradient_step", None))
        ])
    if params.get("iterations", None) is not None:
        cargs.extend([
            "-i",
            str(params.get("iterations", None))
        ])
    if params.get("cpu_cores", None) is not None:
        cargs.extend([
            "-j",
            str(params.get("cpu_cores", None))
        ])
    if params.get("num_modalities", None) is not None:
        cargs.extend([
            "-k",
            str(params.get("num_modalities", None))
        ])
    if params.get("modality_weights", None) is not None:
        cargs.extend([
            "-w",
            params.get("modality_weights", None)
        ])
    if params.get("max_iterations", None) is not None:
        cargs.extend([
            "-q",
            params.get("max_iterations", None)
        ])
    if params.get("shrink_factors", None) is not None:
        cargs.extend([
            "-f",
            params.get("shrink_factors", None)
        ])
    if params.get("smoothing_kernels", None) is not None:
        cargs.extend([
            "-s",
            params.get("smoothing_kernels", None)
        ])
    if params.get("n4_bias_correction", None) is not None:
        cargs.extend([
            "-n",
            ("1" if params.get("n4_bias_correction", None) else "0")
        ])
    if params.get("prepend_commands", None) is not None:
        cargs.extend([
            "-p",
            params.get("prepend_commands", None)
        ])
    if params.get("rigid_registration", None) is not None:
        cargs.extend([
            "-r",
            ("1" if params.get("rigid_registration", None) else "0")
        ])
    if params.get("linear_registration", None) is not None:
        cargs.extend([
            "-l",
            ("1" if params.get("linear_registration", None) else "0")
        ])
    if params.get("similarity_metric", None) is not None:
        cargs.extend([
            "-m",
            params.get("similarity_metric", None)
        ])
    if params.get("transformation_type", None) is not None:
        cargs.extend([
            "-t",
            params.get("transformation_type", None)
        ])
    if params.get("walltime", None) is not None:
        cargs.extend([
            "-u",
            params.get("walltime", None)
        ])
    if params.get("memory_limit", None) is not None:
        cargs.extend([
            "-v",
            params.get("memory_limit", None)
        ])
    if params.get("xgrid_args", None) is not None:
        cargs.extend([
            "-x",
            params.get("xgrid_args", None)
        ])
    if params.get("update_template", None) is not None:
        cargs.extend([
            "-y",
            ("1" if params.get("update_template", None) else "0")
        ])
    if params.get("target_volume", None) is not None:
        cargs.extend([
            "-z",
            *[execution.input_file(f) for f in params.get("target_volume", None)]
        ])
    cargs.extend([execution.input_file(f) for f in params.get("input_images", None)])
    return cargs


def ants_multivariate_template_construction2_sh_outputs(
    params: AntsMultivariateTemplateConstruction2ShParamsDict,
    execution: Execution,
) -> AntsMultivariateTemplateConstruction2ShOutputs:
    """
    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 = AntsMultivariateTemplateConstruction2ShOutputs(
        root=execution.output_file("."),
        intermediate_templates_dir=execution.output_file("intermediateTemplates"),
    )
    return ret


def ants_multivariate_template_construction2_sh_execute(
    params: AntsMultivariateTemplateConstruction2ShParamsDict,
    runner: Runner | None = None,
) -> AntsMultivariateTemplateConstruction2ShOutputs:
    """
    antsMultivariateTemplateConstruction2.sh
    
    Multivariate template construction using ANTs registration tools (version
    2). All images to be added to the template should be in the same directory,
    and this script should be invoked from that directory.
    
    Author: Brian B. Avants, Nick Tustison and Gang Song
    
    URL: https://github.com/ANTsX/ANTs
    
    Args:
        params: The parameters.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `AntsMultivariateTemplateConstruction2ShOutputs`).
    """
    ants_multivariate_template_construction2_sh_validate(params)
    runner = runner or get_global_runner()
    execution = runner.start_execution(ANTS_MULTIVARIATE_TEMPLATE_CONSTRUCTION2_SH_METADATA)
    params = execution.params(params)
    cargs = ants_multivariate_template_construction2_sh_cargs(params, execution)
    ret = ants_multivariate_template_construction2_sh_outputs(params, execution)
    execution.run(cargs)
    return ret


def ants_multivariate_template_construction2_sh(
    dimension: typing.Literal[2, 3, 4],
    input_images: list[InputPathType],
    output_prefix: str | None = None,
    image_statistic: typing.Literal[0, 1, 2] | None = None,
    sharpening: typing.Literal[0, 1, 2] | None = None,
    backup_images: bool | None = None,
    parallel_control: typing.Literal[0, 1, 2, 3, 4, 5] | None = None,
    single_precision: bool | None = None,
    gradient_step: float | None = None,
    iterations: int | None = None,
    cpu_cores: int | None = None,
    num_modalities: int | None = None,
    modality_weights: str | None = None,
    max_iterations: str | None = None,
    shrink_factors: str | None = None,
    smoothing_kernels: str | None = None,
    n4_bias_correction: bool | None = None,
    prepend_commands: str | None = None,
    rigid_registration: bool | None = None,
    linear_registration: bool | None = None,
    similarity_metric: str | None = None,
    transformation_type: str | None = None,
    walltime: str | None = None,
    memory_limit: str | None = None,
    xgrid_args: str | None = None,
    update_template: bool | None = None,
    target_volume: list[InputPathType] | None = None,
    runner: Runner | None = None,
) -> AntsMultivariateTemplateConstruction2ShOutputs:
    """
    antsMultivariateTemplateConstruction2.sh
    
    Multivariate template construction using ANTs registration tools (version
    2). All images to be added to the template should be in the same directory,
    and this script should be invoked from that directory.
    
    Author: Brian B. Avants, Nick Tustison and Gang Song
    
    URL: https://github.com/ANTsX/ANTs
    
    Args:
        dimension: ImageDimension: 2 or 3 (for 2 or 3 dimensional registration\
            of single volume), 4 (for template generation of time-series data).
        input_images: List of images in the current directory, eg *_t1.nii.gz.\
            Should be at the end of the command. Optionally, one can specify a .csv\
            or .txt file where each line is the location of the input image. One\
            can also specify more than one file for each image for multi-modal\
            template construction (e.g. t1 and t2). For the multi-modal case, the\
            templates will be consecutively numbered.
        output_prefix: A prefix that is prepended to all output files (default\
            = "antsBTP").
        image_statistic: Image statistic used to summarize images (default 1):\
            0 = mean, 1 = mean of normalized intensities, 2 = median. Normalization\
            here means dividing each image by its mean intensity.
        sharpening: Sharpening applied to template at each iteration (default\
            1): 0 = none, 1 = Laplacian, 2 = Unsharp mask.
        backup_images: Backup images and results from all iterations (default =\
            0): Boolean to save the transform files, bias corrected inputs,\
            templates, transforms, and warped images for each iteration. By\
            default, only the templates and the shape update warp field are saved.
        parallel_control: Control for parallel computation (default 0): 0 = run\
            serially, 1 = SGE qsub, 2 = use PEXEC (localhost), 3 = Apple XGrid, 4 =\
            PBS qsub, 5 = SLURM.
        single_precision: Use single precision (default 1).
        gradient_step: Gradient step size (default 0.25): smaller in magnitude\
            results in more cautious steps. Use smaller steps to refine template\
            details. 0.25 is an upper (aggressive) limit for this parameter.
        iterations: Iteration limit (default 4): iterations of the template\
            construction (Iteration limit)*NumImages registrations.
        cpu_cores: Number of cpu cores to use locally for pexec option (default\
            2; requires "-c 2").
        num_modalities: Number of modalities used to construct the template\
            (default 1): For example, if one wanted to create a multimodal template\
            consisting of T1,T2,and FA components ("-k 3").
        modality_weights: Modality weights used in the similarity metric\
            (default = 1): specified as e.g. 1x0.5x0.75.
        max_iterations: Max iterations for each pairwise registration (default\
            = 100x100x70x20): specified in the form JxK...xF where J = max\
            iterations at first (coarsest) resolution, K = max iterations at next\
            resolution, F = max iterations at the final resolution.
        shrink_factors: Shrink factors in pairwise registration (default =\
            6x4x2x1): in the same form as max iterations. Must have the same number\
            of components as the iterations and smoothing. The shrink factors are\
            integer factors for downsampling the virtual space (usually the\
            template image) during registration.
        smoothing_kernels: Smoothing kernels in pairwise registration (default\
            = 3x2x1x0): also in the same form as max iterations and shrink factors,\
            with the same number of components. Standard deviation of a Gaussian\
            smoothing kernel applied to the images before downsampling at each\
            level. The kernel may be specified in mm units or voxels with "AxBxCmm"\
            or "AxBxCvox". Missing units implies vox.
        n4_bias_correction: N4BiasFieldCorrection of moving image: 0 off, 1 on\
            (default 1).
        prepend_commands: Commands to prepend to job scripts (e.g., change into\
            appropriate directory, set paths, etc).
        rigid_registration: Do rigid-body registration of inputs to the initial\
            template, before doing the main pairwise registration. 0 off 1 on\
            (default 0). If you are trying to refine or update an existing\
            template, you would use '-r 0'. Rigid initialization is useful when you\
            do not have an initial template, or you want to use a single image as a\
            reference for rigid alignment only.
        linear_registration: Use linear image registration stages during the\
            pairwise (template/subject) deformable registration. Otherwise,\
            registration is limited to SyN or B-spline SyN (see '-t' option). This\
            is '1' by default.
        similarity_metric: Type of similarity metric used for pairwise\
            registration (default = CC). Options are case sensitive. CC =\
            cross-correlation, MI = mutual information, MSQ = mean square\
            difference, DEMONS = demon's metric. A similarity metric per modality\
            can be specified. If the CC metric is chosen, one can also specify the\
            radius in brackets, e.g. '-m "CC[4]"'.
        transformation_type: Type of transformation model used for registration\
            (default = SyN): Options are case sensitive. SyN = Greedy SyN,\
            BSplineSyN = Greedy B-spline SyN, TimeVaryingVelocityField =\
            Time-varying velocity field, TimeVaryingBSplineVelocityField =\
            Time-varying B-spline velocity field. Transformation parameters may be\
            specified with brackets, eg '-t "SyN[0.1,3,0]"'. To use linear\
            registration only, options are: Affine = Affine (runs Rigid + Affine),\
            Rigid = Rigid (runs Rigid only).
        walltime: Walltime (default = 20:00:00): Option for PBS/SLURM qsub\
            specifying requested time per pairwise registration.
        memory_limit: Memory limit (default = 8gb): Option for PBS/SLURM qsub\
            specifying requested memory per pairwise registration.
        xgrid_args: XGrid arguments (e.g., -x "-p password -h controlhost").
        update_template: Update the template with the full affine transform\
            (default 1). If 0, the rigid component of the affine transform will not\
            be used to update the template. If your template drifts in translation\
            or orientation try "-y 0".
        target_volume: Use this this volume as the target of all inputs. When\
            not used, the script will create an unbiased starting point by\
            averaging all inputs, then aligning the center of mass of all inputs to\
            that of the initial average. If you do not use -z, it is recommended to\
            use "-r 1". Use the full path. For multiple modalities, specify -z\
            modality1.nii.gz -z modality2.nii.gz ... in the same modality order as\
            the input images.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `AntsMultivariateTemplateConstruction2ShOutputs`).
    """
    params = ants_multivariate_template_construction2_sh_params(
        dimension=dimension,
        output_prefix=output_prefix,
        image_statistic=image_statistic,
        sharpening=sharpening,
        backup_images=backup_images,
        parallel_control=parallel_control,
        single_precision=single_precision,
        gradient_step=gradient_step,
        iterations=iterations,
        cpu_cores=cpu_cores,
        num_modalities=num_modalities,
        modality_weights=modality_weights,
        max_iterations=max_iterations,
        shrink_factors=shrink_factors,
        smoothing_kernels=smoothing_kernels,
        n4_bias_correction=n4_bias_correction,
        prepend_commands=prepend_commands,
        rigid_registration=rigid_registration,
        linear_registration=linear_registration,
        similarity_metric=similarity_metric,
        transformation_type=transformation_type,
        walltime=walltime,
        memory_limit=memory_limit,
        xgrid_args=xgrid_args,
        update_template=update_template,
        target_volume=target_volume,
        input_images=input_images,
    )
    return ants_multivariate_template_construction2_sh_execute(params, runner)


__all__ = [
    "ANTS_MULTIVARIATE_TEMPLATE_CONSTRUCTION2_SH_METADATA",
    "AntsMultivariateTemplateConstruction2ShOutputs",
    "AntsMultivariateTemplateConstruction2ShParamsDict",
    "AntsMultivariateTemplateConstruction2ShParamsDictTagged",
    "ants_multivariate_template_construction2_sh",
    "ants_multivariate_template_construction2_sh_execute",
    "ants_multivariate_template_construction2_sh_params",
]
