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

import typing
import pathlib
from styxdefs import *
import dataclasses

VOLUME_RESAMPLE_METADATA = Metadata(
    id="8e0412fed997d47e43936d5bf5273ec321a5c58a.boutiques",
    name="volume-resample",
    package="workbench",
    container_image_tag="brainlife/connectome_workbench:1.5.0-freesurfer-update",
)


@dataclasses.dataclass
class VolumeResampleFlirt:
    """
    MUST be used if affine is a flirt affine.
    """
    source_volume: str
    """the source volume used when generating the affine"""
    target_volume: str
    """the target volume used when generating the affine"""
    
    def run(
        self,
        execution: Execution,
    ) -> list[str]:
        """
        Build command line arguments. This method is called by the main command.
        
        Args:
            execution: The execution object.
        Returns:
            Command line arguments
        """
        cargs = []
        cargs.append("-flirt")
        cargs.append(self.source_volume)
        cargs.append(self.target_volume)
        return cargs


@dataclasses.dataclass
class VolumeResampleAffine:
    """
    add an affine transform.
    """
    affine: str
    """the affine file to use"""
    flirt: VolumeResampleFlirt | None = None
    """MUST be used if affine is a flirt affine"""
    
    def run(
        self,
        execution: Execution,
    ) -> list[str]:
        """
        Build command line arguments. This method is called by the main command.
        
        Args:
            execution: The execution object.
        Returns:
            Command line arguments
        """
        cargs = []
        cargs.append("-affine")
        cargs.append(self.affine)
        if self.flirt is not None:
            cargs.extend(self.flirt.run(execution))
        return cargs


@dataclasses.dataclass
class VolumeResampleFlirt_:
    """
    MUST be used if the affines are flirt affines.
    """
    source_volume: str
    """the source volume used when generating the affine"""
    target_volume: str
    """the target volume used when generating the affine"""
    
    def run(
        self,
        execution: Execution,
    ) -> list[str]:
        """
        Build command line arguments. This method is called by the main command.
        
        Args:
            execution: The execution object.
        Returns:
            Command line arguments
        """
        cargs = []
        cargs.append("-flirt")
        cargs.append(self.source_volume)
        cargs.append(self.target_volume)
        return cargs


@dataclasses.dataclass
class VolumeResampleAffineSeries:
    """
    add an independent affine per-frame.
    """
    affine_series: str
    """text file containing 12 or 16 numbers per line, each being a row-major
    flattened affine"""
    flirt: VolumeResampleFlirt_ | None = None
    """MUST be used if the affines are flirt affines"""
    
    def run(
        self,
        execution: Execution,
    ) -> list[str]:
        """
        Build command line arguments. This method is called by the main command.
        
        Args:
            execution: The execution object.
        Returns:
            Command line arguments
        """
        cargs = []
        cargs.append("-affine-series")
        cargs.append(self.affine_series)
        if self.flirt is not None:
            cargs.extend(self.flirt.run(execution))
        return cargs


@dataclasses.dataclass
class VolumeResampleWarp:
    """
    add a nonlinear warpfield transform.
    """
    warpfield: str
    """the warpfield file"""
    opt_fnirt_source_volume: str | None = None
    """MUST be used if using a fnirt warpfield: the source volume used when
    generating the warpfield"""
    
    def run(
        self,
        execution: Execution,
    ) -> list[str]:
        """
        Build command line arguments. This method is called by the main command.
        
        Args:
            execution: The execution object.
        Returns:
            Command line arguments
        """
        cargs = []
        cargs.append("-warp")
        cargs.append(self.warpfield)
        if self.opt_fnirt_source_volume is not None:
            cargs.extend([
                "-fnirt",
                self.opt_fnirt_source_volume
            ])
        return cargs


class VolumeResampleOutputs(typing.NamedTuple):
    """
    Output object returned when calling `volume_resample(...)`.
    """
    root: OutputPathType
    """Output root folder. This is the root folder for all outputs."""
    volume_out: OutputPathType
    """the output volume"""


def volume_resample(
    volume_in: InputPathType,
    volume_space: str,
    method: str,
    volume_out: str,
    affine: list[VolumeResampleAffine] | None = None,
    affine_series: list[VolumeResampleAffineSeries] | None = None,
    warp: list[VolumeResampleWarp] | None = None,
    runner: Runner | None = None,
) -> VolumeResampleOutputs:
    """
    Transform and resample a volume file.
    
    Resample a volume file with an arbitrary list of transformations. You may
    specify -affine, -warp, and -affine-series multiple times each, and they
    will be used in the order specified. For instance, for rigid motion
    correction followed by nonlinear atlas registration, specify -affine-series
    first, then -warp. The recommended methods are CUBIC (cubic spline) for most
    data, and ENCLOSING_VOXEL for label data. The parameter <method> must be one
    of:
    
    CUBIC
    ENCLOSING_VOXEL
    TRILINEAR.
    
    Author: Connectome Workbench Developers
    
    URL: https://github.com/Washington-University/workbench
    
    Args:
        volume_in: volume to resample.
        volume_space: a volume file in the volume space you want for the output.
        method: the resampling method.
        volume_out: the output volume.
        affine: add an affine transform.
        affine_series: add an independent affine per-frame.
        warp: add a nonlinear warpfield transform.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `VolumeResampleOutputs`).
    """
    runner = runner or get_global_runner()
    execution = runner.start_execution(VOLUME_RESAMPLE_METADATA)
    cargs = []
    cargs.append("wb_command")
    cargs.append("-volume-resample")
    cargs.append(execution.input_file(volume_in))
    cargs.append(volume_space)
    cargs.append(method)
    cargs.append(volume_out)
    if affine is not None:
        cargs.extend([a for c in [s.run(execution) for s in affine] for a in c])
    if affine_series is not None:
        cargs.extend([a for c in [s.run(execution) for s in affine_series] for a in c])
    if warp is not None:
        cargs.extend([a for c in [s.run(execution) for s in warp] for a in c])
    ret = VolumeResampleOutputs(
        root=execution.output_file("."),
        volume_out=execution.output_file(volume_out),
    )
    execution.run(cargs)
    return ret


__all__ = [
    "VOLUME_RESAMPLE_METADATA",
    "VolumeResampleAffine",
    "VolumeResampleAffineSeries",
    "VolumeResampleFlirt",
    "VolumeResampleFlirt_",
    "VolumeResampleOutputs",
    "VolumeResampleWarp",
    "volume_resample",
]
