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

import typing
import pathlib
from styxdefs import *

VOLUME_SET_SPACE_METADATA = Metadata(
    id="39cfd66daa80ee755b48163f61a64435ef0a12be.workbench",
    name="volume-set-space",
    package="workbench",
    container_image_tag="nx10x/workbench:2.1.0",
)


_VolumeSetSpacePlumbParamsDictNoTag = typing.TypedDict('_VolumeSetSpacePlumbParamsDictNoTag', {
    "axis-order": str,
    "x-spacing": float,
    "y-spacing": float,
    "z-spacing": float,
    "x-offset": float,
    "y-offset": float,
    "z-offset": float,
})
VolumeSetSpacePlumbParamsDictTagged = typing.TypedDict('VolumeSetSpacePlumbParamsDictTagged', {
    "@type": typing.Literal["plumb"],
    "axis-order": str,
    "x-spacing": float,
    "y-spacing": float,
    "z-spacing": float,
    "x-offset": float,
    "y-offset": float,
    "z-offset": float,
})
VolumeSetSpacePlumbParamsDict = _VolumeSetSpacePlumbParamsDictNoTag | VolumeSetSpacePlumbParamsDictTagged


_VolumeSetSpaceSformParamsDictNoTag = typing.TypedDict('_VolumeSetSpaceSformParamsDictNoTag', {
    "xi-spacing": float,
    "xj-spacing": float,
    "xk-spacing": float,
    "x-offset": float,
    "yi-spacing": float,
    "yj-spacing": float,
    "yk-spacing": float,
    "y-offset": float,
    "zi-spacing": float,
    "zj-spacing": float,
    "zk-spacing": float,
    "z-offset": float,
})
VolumeSetSpaceSformParamsDictTagged = typing.TypedDict('VolumeSetSpaceSformParamsDictTagged', {
    "@type": typing.Literal["sform"],
    "xi-spacing": float,
    "xj-spacing": float,
    "xk-spacing": float,
    "x-offset": float,
    "yi-spacing": float,
    "yj-spacing": float,
    "yk-spacing": float,
    "y-offset": float,
    "zi-spacing": float,
    "zj-spacing": float,
    "zk-spacing": float,
    "z-offset": float,
})
VolumeSetSpaceSformParamsDict = _VolumeSetSpaceSformParamsDictNoTag | VolumeSetSpaceSformParamsDictTagged


_VolumeSetSpaceFileParamsDictNoTag = typing.TypedDict('_VolumeSetSpaceFileParamsDictNoTag', {
    "volume-ref": str,
    "ignore-dims": bool,
})
VolumeSetSpaceFileParamsDictTagged = typing.TypedDict('VolumeSetSpaceFileParamsDictTagged', {
    "@type": typing.Literal["file"],
    "volume-ref": str,
    "ignore-dims": bool,
})
VolumeSetSpaceFileParamsDict = _VolumeSetSpaceFileParamsDictNoTag | VolumeSetSpaceFileParamsDictTagged


_VolumeSetSpaceParamsDictNoTag = typing.TypedDict('_VolumeSetSpaceParamsDictNoTag', {
    "volume-in": InputPathType,
    "volume-out": str,
    "plumb": typing.NotRequired[VolumeSetSpacePlumbParamsDict | None],
    "sform": typing.NotRequired[VolumeSetSpaceSformParamsDict | None],
    "file": typing.NotRequired[VolumeSetSpaceFileParamsDict | None],
})
VolumeSetSpaceParamsDictTagged = typing.TypedDict('VolumeSetSpaceParamsDictTagged', {
    "@type": typing.Literal["workbench/volume-set-space"],
    "volume-in": InputPathType,
    "volume-out": str,
    "plumb": typing.NotRequired[VolumeSetSpacePlumbParamsDict | None],
    "sform": typing.NotRequired[VolumeSetSpaceSformParamsDict | None],
    "file": typing.NotRequired[VolumeSetSpaceFileParamsDict | None],
})
VolumeSetSpaceParamsDict = _VolumeSetSpaceParamsDictNoTag | VolumeSetSpaceParamsDictTagged


def volume_set_space_plumb(
    axis_order: str,
    x_spacing: float,
    y_spacing: float,
    z_spacing: float,
    x_offset: float,
    y_offset: float,
    z_offset: float,
) -> VolumeSetSpacePlumbParamsDictTagged:
    """
    Build parameters.
    
    Args:
        axis_order: a string like 'XYZ' that specifies which index is along\
            which spatial dimension.
        x_spacing: change in x-coordinate from incrementing the relevant index.
        y_spacing: change in y-coordinate from incrementing the relevant index.
        z_spacing: change in z-coordinate from incrementing the relevant index.
        x_offset: the x-coordinate of the first voxel.
        y_offset: the y-coordinate of the first voxel.
        z_offset: the z-coordinate of the first voxel.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "plumb",
        "axis-order": axis_order,
        "x-spacing": x_spacing,
        "y-spacing": y_spacing,
        "z-spacing": z_spacing,
        "x-offset": x_offset,
        "y-offset": y_offset,
        "z-offset": z_offset,
    }
    return params


def volume_set_space_plumb_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `VolumeSetSpacePlumbParamsDict` 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("axis-order", None) is None:
        raise StyxValidationError("`axis-order` must not be None")
    if not isinstance(params["axis-order"], str):
        raise StyxValidationError(f'`axis-order` has the wrong type: Received `{type(params.get("axis-order", None))}` expected `str`')
    if params.get("x-spacing", None) is None:
        raise StyxValidationError("`x-spacing` must not be None")
    if not isinstance(params["x-spacing"], (float, int)):
        raise StyxValidationError(f'`x-spacing` has the wrong type: Received `{type(params.get("x-spacing", None))}` expected `float`')
    if params.get("y-spacing", None) is None:
        raise StyxValidationError("`y-spacing` must not be None")
    if not isinstance(params["y-spacing"], (float, int)):
        raise StyxValidationError(f'`y-spacing` has the wrong type: Received `{type(params.get("y-spacing", None))}` expected `float`')
    if params.get("z-spacing", None) is None:
        raise StyxValidationError("`z-spacing` must not be None")
    if not isinstance(params["z-spacing"], (float, int)):
        raise StyxValidationError(f'`z-spacing` has the wrong type: Received `{type(params.get("z-spacing", None))}` expected `float`')
    if params.get("x-offset", None) is None:
        raise StyxValidationError("`x-offset` must not be None")
    if not isinstance(params["x-offset"], (float, int)):
        raise StyxValidationError(f'`x-offset` has the wrong type: Received `{type(params.get("x-offset", None))}` expected `float`')
    if params.get("y-offset", None) is None:
        raise StyxValidationError("`y-offset` must not be None")
    if not isinstance(params["y-offset"], (float, int)):
        raise StyxValidationError(f'`y-offset` has the wrong type: Received `{type(params.get("y-offset", None))}` expected `float`')
    if params.get("z-offset", None) is None:
        raise StyxValidationError("`z-offset` must not be None")
    if not isinstance(params["z-offset"], (float, int)):
        raise StyxValidationError(f'`z-offset` has the wrong type: Received `{type(params.get("z-offset", None))}` expected `float`')


def volume_set_space_plumb_cargs(
    params: VolumeSetSpacePlumbParamsDict,
    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.extend([
        "-plumb",
        params.get("axis-order", None),
        str(params.get("x-spacing", None)),
        str(params.get("y-spacing", None)),
        str(params.get("z-spacing", None)),
        str(params.get("x-offset", None)),
        str(params.get("y-offset", None)),
        str(params.get("z-offset", None))
    ])
    return cargs


def volume_set_space_sform(
    xi_spacing: float,
    xj_spacing: float,
    xk_spacing: float,
    x_offset: float,
    yi_spacing: float,
    yj_spacing: float,
    yk_spacing: float,
    y_offset: float,
    zi_spacing: float,
    zj_spacing: float,
    zk_spacing: float,
    z_offset: float,
) -> VolumeSetSpaceSformParamsDictTagged:
    """
    Build parameters.
    
    Args:
        xi_spacing: increase in x coordinate from incrementing the i index.
        xj_spacing: increase in x coordinate from incrementing the j index.
        xk_spacing: increase in x coordinate from incrementing the k index.
        x_offset: x coordinate of first voxel.
        yi_spacing: increase in y coordinate from incrementing the i index.
        yj_spacing: increase in y coordinate from incrementing the j index.
        yk_spacing: increase in y coordinate from incrementing the k index.
        y_offset: y coordinate of first voxel.
        zi_spacing: increase in z coordinate from incrementing the i index.
        zj_spacing: increase in z coordinate from incrementing the j index.
        zk_spacing: increase in z coordinate from incrementing the k index.
        z_offset: z coordinate of first voxel.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "sform",
        "xi-spacing": xi_spacing,
        "xj-spacing": xj_spacing,
        "xk-spacing": xk_spacing,
        "x-offset": x_offset,
        "yi-spacing": yi_spacing,
        "yj-spacing": yj_spacing,
        "yk-spacing": yk_spacing,
        "y-offset": y_offset,
        "zi-spacing": zi_spacing,
        "zj-spacing": zj_spacing,
        "zk-spacing": zk_spacing,
        "z-offset": z_offset,
    }
    return params


def volume_set_space_sform_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `VolumeSetSpaceSformParamsDict` 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("xi-spacing", None) is None:
        raise StyxValidationError("`xi-spacing` must not be None")
    if not isinstance(params["xi-spacing"], (float, int)):
        raise StyxValidationError(f'`xi-spacing` has the wrong type: Received `{type(params.get("xi-spacing", None))}` expected `float`')
    if params.get("xj-spacing", None) is None:
        raise StyxValidationError("`xj-spacing` must not be None")
    if not isinstance(params["xj-spacing"], (float, int)):
        raise StyxValidationError(f'`xj-spacing` has the wrong type: Received `{type(params.get("xj-spacing", None))}` expected `float`')
    if params.get("xk-spacing", None) is None:
        raise StyxValidationError("`xk-spacing` must not be None")
    if not isinstance(params["xk-spacing"], (float, int)):
        raise StyxValidationError(f'`xk-spacing` has the wrong type: Received `{type(params.get("xk-spacing", None))}` expected `float`')
    if params.get("x-offset", None) is None:
        raise StyxValidationError("`x-offset` must not be None")
    if not isinstance(params["x-offset"], (float, int)):
        raise StyxValidationError(f'`x-offset` has the wrong type: Received `{type(params.get("x-offset", None))}` expected `float`')
    if params.get("yi-spacing", None) is None:
        raise StyxValidationError("`yi-spacing` must not be None")
    if not isinstance(params["yi-spacing"], (float, int)):
        raise StyxValidationError(f'`yi-spacing` has the wrong type: Received `{type(params.get("yi-spacing", None))}` expected `float`')
    if params.get("yj-spacing", None) is None:
        raise StyxValidationError("`yj-spacing` must not be None")
    if not isinstance(params["yj-spacing"], (float, int)):
        raise StyxValidationError(f'`yj-spacing` has the wrong type: Received `{type(params.get("yj-spacing", None))}` expected `float`')
    if params.get("yk-spacing", None) is None:
        raise StyxValidationError("`yk-spacing` must not be None")
    if not isinstance(params["yk-spacing"], (float, int)):
        raise StyxValidationError(f'`yk-spacing` has the wrong type: Received `{type(params.get("yk-spacing", None))}` expected `float`')
    if params.get("y-offset", None) is None:
        raise StyxValidationError("`y-offset` must not be None")
    if not isinstance(params["y-offset"], (float, int)):
        raise StyxValidationError(f'`y-offset` has the wrong type: Received `{type(params.get("y-offset", None))}` expected `float`')
    if params.get("zi-spacing", None) is None:
        raise StyxValidationError("`zi-spacing` must not be None")
    if not isinstance(params["zi-spacing"], (float, int)):
        raise StyxValidationError(f'`zi-spacing` has the wrong type: Received `{type(params.get("zi-spacing", None))}` expected `float`')
    if params.get("zj-spacing", None) is None:
        raise StyxValidationError("`zj-spacing` must not be None")
    if not isinstance(params["zj-spacing"], (float, int)):
        raise StyxValidationError(f'`zj-spacing` has the wrong type: Received `{type(params.get("zj-spacing", None))}` expected `float`')
    if params.get("zk-spacing", None) is None:
        raise StyxValidationError("`zk-spacing` must not be None")
    if not isinstance(params["zk-spacing"], (float, int)):
        raise StyxValidationError(f'`zk-spacing` has the wrong type: Received `{type(params.get("zk-spacing", None))}` expected `float`')
    if params.get("z-offset", None) is None:
        raise StyxValidationError("`z-offset` must not be None")
    if not isinstance(params["z-offset"], (float, int)):
        raise StyxValidationError(f'`z-offset` has the wrong type: Received `{type(params.get("z-offset", None))}` expected `float`')


def volume_set_space_sform_cargs(
    params: VolumeSetSpaceSformParamsDict,
    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.extend([
        "-sform",
        str(params.get("xi-spacing", None)),
        str(params.get("xj-spacing", None)),
        str(params.get("xk-spacing", None)),
        str(params.get("x-offset", None)),
        str(params.get("yi-spacing", None)),
        str(params.get("yj-spacing", None)),
        str(params.get("yk-spacing", None)),
        str(params.get("y-offset", None)),
        str(params.get("zi-spacing", None)),
        str(params.get("zj-spacing", None)),
        str(params.get("zk-spacing", None)),
        str(params.get("z-offset", None))
    ])
    return cargs


def volume_set_space_file(
    volume_ref: str,
    ignore_dims: bool = False,
) -> VolumeSetSpaceFileParamsDictTagged:
    """
    Build parameters.
    
    Args:
        volume_ref: volume file to use for reference space.
        ignore_dims: copy the spacing info even if the dimensions don't match.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "file",
        "volume-ref": volume_ref,
        "ignore-dims": ignore_dims,
    }
    return params


def volume_set_space_file_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `VolumeSetSpaceFileParamsDict` 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("volume-ref", None) is None:
        raise StyxValidationError("`volume-ref` must not be None")
    if not isinstance(params["volume-ref"], str):
        raise StyxValidationError(f'`volume-ref` has the wrong type: Received `{type(params.get("volume-ref", None))}` expected `str`')
    if params.get("ignore-dims", False) is None:
        raise StyxValidationError("`ignore-dims` must not be None")
    if not isinstance(params["ignore-dims"], bool):
        raise StyxValidationError(f'`ignore-dims` has the wrong type: Received `{type(params.get("ignore-dims", False))}` expected `bool`')


def volume_set_space_file_cargs(
    params: VolumeSetSpaceFileParamsDict,
    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.extend([
        "-file",
        params.get("volume-ref", None)
    ])
    if params.get("ignore-dims", False):
        cargs.append("-ignore-dims")
    return cargs


class VolumeSetSpaceOutputs(typing.NamedTuple):
    """
    Output object returned when calling `VolumeSetSpaceParamsDict(...)`.
    """
    root: OutputPathType
    """Output root folder. This is the root folder for all outputs."""


def volume_set_space_params(
    volume_in: InputPathType,
    volume_out: str,
    plumb: VolumeSetSpacePlumbParamsDict | None = None,
    sform: VolumeSetSpaceSformParamsDict | None = None,
    file: VolumeSetSpaceFileParamsDict | None = None,
) -> VolumeSetSpaceParamsDictTagged:
    """
    Build parameters.
    
    Args:
        volume_in: the input volume.
        volume_out: output - the output volume.
        plumb: set via axis order and spacing/offset.
        sform: set via a nifti sform.
        file: copy spacing info from volume file with matching dimensions.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "workbench/volume-set-space",
        "volume-in": volume_in,
        "volume-out": volume_out,
    }
    if plumb is not None:
        params["plumb"] = plumb
    if sform is not None:
        params["sform"] = sform
    if file is not None:
        params["file"] = file
    return params


def volume_set_space_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `VolumeSetSpaceParamsDict` 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("volume-in", None) is None:
        raise StyxValidationError("`volume-in` must not be None")
    if not isinstance(params["volume-in"], (pathlib.Path, str)):
        raise StyxValidationError(f'`volume-in` has the wrong type: Received `{type(params.get("volume-in", None))}` expected `InputPathType`')
    if params.get("volume-out", None) is None:
        raise StyxValidationError("`volume-out` must not be None")
    if not isinstance(params["volume-out"], str):
        raise StyxValidationError(f'`volume-out` has the wrong type: Received `{type(params.get("volume-out", None))}` expected `str`')
    if params.get("plumb", None) is not None:
        volume_set_space_plumb_validate(params["plumb"])
    if params.get("sform", None) is not None:
        volume_set_space_sform_validate(params["sform"])
    if params.get("file", None) is not None:
        volume_set_space_file_validate(params["file"])


def volume_set_space_cargs(
    params: VolumeSetSpaceParamsDict,
    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.extend([
        "wb_command",
        "-volume-set-space"
    ])
    cargs.append(execution.input_file(params.get("volume-in", None)))
    cargs.append(params.get("volume-out", None))
    if params.get("plumb", None) is not None or params.get("sform", None) is not None or params.get("file", None) is not None:
        cargs.extend([
            *(volume_set_space_plumb_cargs(params.get("plumb", None), execution) if (params.get("plumb", None) is not None) else []),
            *(volume_set_space_sform_cargs(params.get("sform", None), execution) if (params.get("sform", None) is not None) else []),
            *(volume_set_space_file_cargs(params.get("file", None), execution) if (params.get("file", None) is not None) else [])
        ])
    return cargs


def volume_set_space_outputs(
    params: VolumeSetSpaceParamsDict,
    execution: Execution,
) -> VolumeSetSpaceOutputs:
    """
    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 = VolumeSetSpaceOutputs(
        root=execution.output_file("."),
    )
    return ret


def volume_set_space_execute(
    params: VolumeSetSpaceParamsDict,
    runner: Runner | None = None,
) -> VolumeSetSpaceOutputs:
    """
    CHANGE VOLUME SPACE INFORMATION.
    
    Writes a copy of the volume file, with the spacing information changed as
    specified. No reordering of the voxel data occurs, see -volume-reorient to
    change the volume indexing order and reorder the voxels to match. Exactly
    one of -plumb, -sform, or -file must be specified.
    
    Args:
        params: The parameters.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `VolumeSetSpaceOutputs`).
    """
    volume_set_space_validate(params)
    runner = runner or get_global_runner()
    execution = runner.start_execution(VOLUME_SET_SPACE_METADATA)
    params = execution.params(params)
    cargs = volume_set_space_cargs(params, execution)
    ret = volume_set_space_outputs(params, execution)
    execution.run(cargs)
    return ret


def volume_set_space(
    volume_in: InputPathType,
    volume_out: str,
    plumb: VolumeSetSpacePlumbParamsDict | None = None,
    sform: VolumeSetSpaceSformParamsDict | None = None,
    file: VolumeSetSpaceFileParamsDict | None = None,
    runner: Runner | None = None,
) -> VolumeSetSpaceOutputs:
    """
    CHANGE VOLUME SPACE INFORMATION.
    
    Writes a copy of the volume file, with the spacing information changed as
    specified. No reordering of the voxel data occurs, see -volume-reorient to
    change the volume indexing order and reorder the voxels to match. Exactly
    one of -plumb, -sform, or -file must be specified.
    
    Args:
        volume_in: the input volume.
        volume_out: output - the output volume.
        plumb: set via axis order and spacing/offset.
        sform: set via a nifti sform.
        file: copy spacing info from volume file with matching dimensions.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `VolumeSetSpaceOutputs`).
    """
    params = volume_set_space_params(
        volume_in=volume_in,
        volume_out=volume_out,
        plumb=plumb,
        sform=sform,
        file=file,
    )
    return volume_set_space_execute(params, runner)


__all__ = [
    "VOLUME_SET_SPACE_METADATA",
    "VolumeSetSpaceFileParamsDict",
    "VolumeSetSpaceFileParamsDictTagged",
    "VolumeSetSpaceOutputs",
    "VolumeSetSpaceParamsDict",
    "VolumeSetSpaceParamsDictTagged",
    "VolumeSetSpacePlumbParamsDict",
    "VolumeSetSpacePlumbParamsDictTagged",
    "VolumeSetSpaceSformParamsDict",
    "VolumeSetSpaceSformParamsDictTagged",
    "volume_set_space",
    "volume_set_space_execute",
    "volume_set_space_file",
    "volume_set_space_params",
    "volume_set_space_plumb",
    "volume_set_space_sform",
]
