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

import typing
import pathlib
from styxdefs import *

FOCI_RESAMPLE_METADATA = Metadata(
    id="6683a0cb7080f4729048697e248762fc138498eb.workbench",
    name="foci-resample",
    package="workbench",
    container_image_tag="nx10x/workbench:2.1.0",
)


_FociResampleLeftSurfacesParamsDictNoTag = typing.TypedDict('_FociResampleLeftSurfacesParamsDictNoTag', {
    "current-surf": InputPathType,
    "new-surf": InputPathType,
})
FociResampleLeftSurfacesParamsDictTagged = typing.TypedDict('FociResampleLeftSurfacesParamsDictTagged', {
    "@type": typing.Literal["left-surfaces"],
    "current-surf": InputPathType,
    "new-surf": InputPathType,
})
FociResampleLeftSurfacesParamsDict = _FociResampleLeftSurfacesParamsDictNoTag | FociResampleLeftSurfacesParamsDictTagged


_FociResampleRightSurfacesParamsDictNoTag = typing.TypedDict('_FociResampleRightSurfacesParamsDictNoTag', {
    "current-surf": InputPathType,
    "new-surf": InputPathType,
})
FociResampleRightSurfacesParamsDictTagged = typing.TypedDict('FociResampleRightSurfacesParamsDictTagged', {
    "@type": typing.Literal["right-surfaces"],
    "current-surf": InputPathType,
    "new-surf": InputPathType,
})
FociResampleRightSurfacesParamsDict = _FociResampleRightSurfacesParamsDictNoTag | FociResampleRightSurfacesParamsDictTagged


_FociResampleCerebellumSurfacesParamsDictNoTag = typing.TypedDict('_FociResampleCerebellumSurfacesParamsDictNoTag', {
    "current-surf": InputPathType,
    "new-surf": InputPathType,
})
FociResampleCerebellumSurfacesParamsDictTagged = typing.TypedDict('FociResampleCerebellumSurfacesParamsDictTagged', {
    "@type": typing.Literal["cerebellum-surfaces"],
    "current-surf": InputPathType,
    "new-surf": InputPathType,
})
FociResampleCerebellumSurfacesParamsDict = _FociResampleCerebellumSurfacesParamsDictNoTag | FociResampleCerebellumSurfacesParamsDictTagged


_FociResampleParamsDictNoTag = typing.TypedDict('_FociResampleParamsDictNoTag', {
    "foci-in": InputPathType,
    "foci-out": str,
    "left-surfaces": typing.NotRequired[FociResampleLeftSurfacesParamsDict | None],
    "right-surfaces": typing.NotRequired[FociResampleRightSurfacesParamsDict | None],
    "cerebellum-surfaces": typing.NotRequired[FociResampleCerebellumSurfacesParamsDict | None],
    "restore-xyz": bool,
    "discard-distance-from-surface": bool,
})
FociResampleParamsDictTagged = typing.TypedDict('FociResampleParamsDictTagged', {
    "@type": typing.Literal["workbench/foci-resample"],
    "foci-in": InputPathType,
    "foci-out": str,
    "left-surfaces": typing.NotRequired[FociResampleLeftSurfacesParamsDict | None],
    "right-surfaces": typing.NotRequired[FociResampleRightSurfacesParamsDict | None],
    "cerebellum-surfaces": typing.NotRequired[FociResampleCerebellumSurfacesParamsDict | None],
    "restore-xyz": bool,
    "discard-distance-from-surface": bool,
})
FociResampleParamsDict = _FociResampleParamsDictNoTag | FociResampleParamsDictTagged


def foci_resample_left_surfaces(
    current_surf: InputPathType,
    new_surf: InputPathType,
) -> FociResampleLeftSurfacesParamsDictTagged:
    """
    Build parameters.
    
    Args:
        current_surf: the surface the foci are currently projected on.
        new_surf: the surface to project the foci onto.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "left-surfaces",
        "current-surf": current_surf,
        "new-surf": new_surf,
    }
    return params


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


def foci_resample_left_surfaces_cargs(
    params: FociResampleLeftSurfacesParamsDict,
    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([
        "-left-surfaces",
        execution.input_file(params.get("current-surf", None)),
        execution.input_file(params.get("new-surf", None))
    ])
    return cargs


def foci_resample_right_surfaces(
    current_surf: InputPathType,
    new_surf: InputPathType,
) -> FociResampleRightSurfacesParamsDictTagged:
    """
    Build parameters.
    
    Args:
        current_surf: the surface the foci are currently projected on.
        new_surf: the surface to project the foci onto.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "right-surfaces",
        "current-surf": current_surf,
        "new-surf": new_surf,
    }
    return params


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


def foci_resample_right_surfaces_cargs(
    params: FociResampleRightSurfacesParamsDict,
    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([
        "-right-surfaces",
        execution.input_file(params.get("current-surf", None)),
        execution.input_file(params.get("new-surf", None))
    ])
    return cargs


def foci_resample_cerebellum_surfaces(
    current_surf: InputPathType,
    new_surf: InputPathType,
) -> FociResampleCerebellumSurfacesParamsDictTagged:
    """
    Build parameters.
    
    Args:
        current_surf: the surface the foci are currently projected on.
        new_surf: the surface to project the foci onto.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "cerebellum-surfaces",
        "current-surf": current_surf,
        "new-surf": new_surf,
    }
    return params


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


def foci_resample_cerebellum_surfaces_cargs(
    params: FociResampleCerebellumSurfacesParamsDict,
    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([
        "-cerebellum-surfaces",
        execution.input_file(params.get("current-surf", None)),
        execution.input_file(params.get("new-surf", None))
    ])
    return cargs


class FociResampleOutputs(typing.NamedTuple):
    """
    Output object returned when calling `FociResampleParamsDict(...)`.
    """
    root: OutputPathType
    """Output root folder. This is the root folder for all outputs."""
    foci_out: OutputPathType
    """the output foci file"""


def foci_resample_params(
    foci_in: InputPathType,
    foci_out: str,
    left_surfaces: FociResampleLeftSurfacesParamsDict | None = None,
    right_surfaces: FociResampleRightSurfacesParamsDict | None = None,
    cerebellum_surfaces: FociResampleCerebellumSurfacesParamsDict | None = None,
    restore_xyz: bool = False,
    discard_distance_from_surface: bool = False,
) -> FociResampleParamsDictTagged:
    """
    Build parameters.
    
    Args:
        foci_in: the input foci file.
        foci_out: the output foci file.
        left_surfaces: the left surfaces for resampling.
        right_surfaces: the right surfaces for resampling.
        cerebellum_surfaces: the cerebellum surfaces for resampling.
        restore_xyz: put the original xyz coordinates into the foci, rather\
            than the coordinates obtained from unprojection.
        discard_distance_from_surface: ignore the distance the foci are above\
            or below the current surface.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "workbench/foci-resample",
        "foci-in": foci_in,
        "foci-out": foci_out,
        "restore-xyz": restore_xyz,
        "discard-distance-from-surface": discard_distance_from_surface,
    }
    if left_surfaces is not None:
        params["left-surfaces"] = left_surfaces
    if right_surfaces is not None:
        params["right-surfaces"] = right_surfaces
    if cerebellum_surfaces is not None:
        params["cerebellum-surfaces"] = cerebellum_surfaces
    return params


def foci_resample_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `FociResampleParamsDict` 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("foci-in", None) is None:
        raise StyxValidationError("`foci-in` must not be None")
    if not isinstance(params["foci-in"], (pathlib.Path, str)):
        raise StyxValidationError(f'`foci-in` has the wrong type: Received `{type(params.get("foci-in", None))}` expected `InputPathType`')
    if params.get("foci-out", None) is None:
        raise StyxValidationError("`foci-out` must not be None")
    if not isinstance(params["foci-out"], str):
        raise StyxValidationError(f'`foci-out` has the wrong type: Received `{type(params.get("foci-out", None))}` expected `str`')
    if params.get("left-surfaces", None) is not None:
        foci_resample_left_surfaces_validate(params["left-surfaces"])
    if params.get("right-surfaces", None) is not None:
        foci_resample_right_surfaces_validate(params["right-surfaces"])
    if params.get("cerebellum-surfaces", None) is not None:
        foci_resample_cerebellum_surfaces_validate(params["cerebellum-surfaces"])
    if params.get("restore-xyz", False) is None:
        raise StyxValidationError("`restore-xyz` must not be None")
    if not isinstance(params["restore-xyz"], bool):
        raise StyxValidationError(f'`restore-xyz` has the wrong type: Received `{type(params.get("restore-xyz", False))}` expected `bool`')
    if params.get("discard-distance-from-surface", False) is None:
        raise StyxValidationError("`discard-distance-from-surface` must not be None")
    if not isinstance(params["discard-distance-from-surface"], bool):
        raise StyxValidationError(f'`discard-distance-from-surface` has the wrong type: Received `{type(params.get("discard-distance-from-surface", False))}` expected `bool`')


def foci_resample_cargs(
    params: FociResampleParamsDict,
    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",
        "-foci-resample"
    ])
    cargs.append(execution.input_file(params.get("foci-in", None)))
    cargs.append(params.get("foci-out", None))
    if params.get("left-surfaces", None) is not None or params.get("right-surfaces", None) is not None or params.get("cerebellum-surfaces", None) is not None:
        cargs.extend([
            *(foci_resample_left_surfaces_cargs(params.get("left-surfaces", None), execution) if (params.get("left-surfaces", None) is not None) else []),
            *(foci_resample_right_surfaces_cargs(params.get("right-surfaces", None), execution) if (params.get("right-surfaces", None) is not None) else []),
            *(foci_resample_cerebellum_surfaces_cargs(params.get("cerebellum-surfaces", None), execution) if (params.get("cerebellum-surfaces", None) is not None) else [])
        ])
    if params.get("restore-xyz", False):
        cargs.append("-restore-xyz")
    if params.get("discard-distance-from-surface", False):
        cargs.append("-discard-distance-from-surface")
    return cargs


def foci_resample_outputs(
    params: FociResampleParamsDict,
    execution: Execution,
) -> FociResampleOutputs:
    """
    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 = FociResampleOutputs(
        root=execution.output_file("."),
        foci_out=execution.output_file(params.get("foci-out", None)),
    )
    return ret


def foci_resample_execute(
    params: FociResampleParamsDict,
    runner: Runner | None = None,
) -> FociResampleOutputs:
    """
    PROJECT FOCI TO A DIFFERENT SURFACE.
    
    Unprojects foci from the <current-surf> for the structure, then projects
    them to <new-surf>. If the foci have meaningful distances above or below the
    surface, use anatomical surfaces. If the foci should be on the surface, use
    registered spheres and the options -discard-distance-from-surface and
    -restore-xyz.
    
    Args:
        params: The parameters.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `FociResampleOutputs`).
    """
    foci_resample_validate(params)
    runner = runner or get_global_runner()
    execution = runner.start_execution(FOCI_RESAMPLE_METADATA)
    params = execution.params(params)
    cargs = foci_resample_cargs(params, execution)
    ret = foci_resample_outputs(params, execution)
    execution.run(cargs)
    return ret


def foci_resample(
    foci_in: InputPathType,
    foci_out: str,
    left_surfaces: FociResampleLeftSurfacesParamsDict | None = None,
    right_surfaces: FociResampleRightSurfacesParamsDict | None = None,
    cerebellum_surfaces: FociResampleCerebellumSurfacesParamsDict | None = None,
    restore_xyz: bool = False,
    discard_distance_from_surface: bool = False,
    runner: Runner | None = None,
) -> FociResampleOutputs:
    """
    PROJECT FOCI TO A DIFFERENT SURFACE.
    
    Unprojects foci from the <current-surf> for the structure, then projects
    them to <new-surf>. If the foci have meaningful distances above or below the
    surface, use anatomical surfaces. If the foci should be on the surface, use
    registered spheres and the options -discard-distance-from-surface and
    -restore-xyz.
    
    Args:
        foci_in: the input foci file.
        foci_out: the output foci file.
        left_surfaces: the left surfaces for resampling.
        right_surfaces: the right surfaces for resampling.
        cerebellum_surfaces: the cerebellum surfaces for resampling.
        restore_xyz: put the original xyz coordinates into the foci, rather\
            than the coordinates obtained from unprojection.
        discard_distance_from_surface: ignore the distance the foci are above\
            or below the current surface.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `FociResampleOutputs`).
    """
    params = foci_resample_params(
        foci_in=foci_in,
        foci_out=foci_out,
        left_surfaces=left_surfaces,
        right_surfaces=right_surfaces,
        cerebellum_surfaces=cerebellum_surfaces,
        restore_xyz=restore_xyz,
        discard_distance_from_surface=discard_distance_from_surface,
    )
    return foci_resample_execute(params, runner)


__all__ = [
    "FOCI_RESAMPLE_METADATA",
    "FociResampleCerebellumSurfacesParamsDict",
    "FociResampleCerebellumSurfacesParamsDictTagged",
    "FociResampleLeftSurfacesParamsDict",
    "FociResampleLeftSurfacesParamsDictTagged",
    "FociResampleOutputs",
    "FociResampleParamsDict",
    "FociResampleParamsDictTagged",
    "FociResampleRightSurfacesParamsDict",
    "FociResampleRightSurfacesParamsDictTagged",
    "foci_resample",
    "foci_resample_cerebellum_surfaces",
    "foci_resample_execute",
    "foci_resample_left_surfaces",
    "foci_resample_params",
    "foci_resample_right_surfaces",
]
