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

import typing
import pathlib
from styxdefs import *

VOLUME_DILATE_METADATA = Metadata(
    id="c7cf27ddf3bd9107f4ebe78ae6eb1975ae7f12ba.boutiques",
    name="volume-dilate",
    package="workbench",
    container_image_tag="brainlife/connectome_workbench:1.5.0-freesurfer-update",
)


VolumeDilatePresmoothParameters = typing.TypedDict('VolumeDilatePresmoothParameters', {
    "@type": typing.NotRequired[typing.Literal["presmooth"]],
    "kernel": float,
    "opt_fwhm": bool,
})
VolumeDilatePresmoothParametersTagged = typing.TypedDict('VolumeDilatePresmoothParametersTagged', {
    "@type": typing.Literal["presmooth"],
    "kernel": float,
    "opt_fwhm": bool,
})


VolumeDilateGradExtrapolateParameters = typing.TypedDict('VolumeDilateGradExtrapolateParameters', {
    "@type": typing.NotRequired[typing.Literal["grad_extrapolate"]],
    "presmooth": typing.NotRequired[VolumeDilatePresmoothParameters | None],
})
VolumeDilateGradExtrapolateParametersTagged = typing.TypedDict('VolumeDilateGradExtrapolateParametersTagged', {
    "@type": typing.Literal["grad_extrapolate"],
    "presmooth": typing.NotRequired[VolumeDilatePresmoothParameters | None],
})


VolumeDilateParameters = typing.TypedDict('VolumeDilateParameters', {
    "@type": typing.NotRequired[typing.Literal["workbench/volume-dilate"]],
    "volume": InputPathType,
    "distance": float,
    "method": str,
    "volume_out": str,
    "opt_exponent_exponent": typing.NotRequired[float | None],
    "opt_bad_voxel_roi_roi_volume": typing.NotRequired[InputPathType | None],
    "opt_data_roi_roi_volume": typing.NotRequired[InputPathType | None],
    "opt_subvolume_subvol": typing.NotRequired[str | None],
    "opt_legacy_cutoff": bool,
    "grad_extrapolate": typing.NotRequired[VolumeDilateGradExtrapolateParameters | None],
})
VolumeDilateParametersTagged = typing.TypedDict('VolumeDilateParametersTagged', {
    "@type": typing.Literal["workbench/volume-dilate"],
    "volume": InputPathType,
    "distance": float,
    "method": str,
    "volume_out": str,
    "opt_exponent_exponent": typing.NotRequired[float | None],
    "opt_bad_voxel_roi_roi_volume": typing.NotRequired[InputPathType | None],
    "opt_data_roi_roi_volume": typing.NotRequired[InputPathType | None],
    "opt_subvolume_subvol": typing.NotRequired[str | None],
    "opt_legacy_cutoff": bool,
    "grad_extrapolate": typing.NotRequired[VolumeDilateGradExtrapolateParameters | None],
})


def volume_dilate_presmooth_params(
    kernel: float,
    opt_fwhm: bool = False,
) -> VolumeDilatePresmoothParametersTagged:
    """
    Build parameters.
    
    Args:
        kernel: the size of gaussian smoothing kernel in mm, as sigma by\
            default.
        opt_fwhm: kernel size is FWHM, not sigma.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "presmooth",
        "kernel": kernel,
        "opt_fwhm": opt_fwhm,
    }
    return params


def volume_dilate_presmooth_cargs(
    params: VolumeDilatePresmoothParameters,
    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("-presmooth")
    cargs.append(str(params.get("kernel", None)))
    if params.get("opt_fwhm", False):
        cargs.append("-fwhm")
    return cargs


def volume_dilate_grad_extrapolate_params(
    presmooth: VolumeDilatePresmoothParameters | None = None,
) -> VolumeDilateGradExtrapolateParametersTagged:
    """
    Build parameters.
    
    Args:
        presmooth: apply presmoothing before computing gradient vectors, not\
            recommended.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "grad_extrapolate",
    }
    if presmooth is not None:
        params["presmooth"] = presmooth
    return params


def volume_dilate_grad_extrapolate_cargs(
    params: VolumeDilateGradExtrapolateParameters,
    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("-grad-extrapolate")
    if params.get("presmooth", None) is not None:
        cargs.extend(volume_dilate_presmooth_cargs(params.get("presmooth", None), execution))
    return cargs


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


def volume_dilate_params(
    volume: InputPathType,
    distance: float,
    method: str,
    volume_out: str,
    opt_exponent_exponent: float | None = None,
    opt_bad_voxel_roi_roi_volume: InputPathType | None = None,
    opt_data_roi_roi_volume: InputPathType | None = None,
    opt_subvolume_subvol: str | None = None,
    opt_legacy_cutoff: bool = False,
    grad_extrapolate: VolumeDilateGradExtrapolateParameters | None = None,
) -> VolumeDilateParametersTagged:
    """
    Build parameters.
    
    Args:
        volume: the volume to dilate.
        distance: distance in mm to dilate.
        method: dilation method to use.
        volume_out: the output volume.
        opt_exponent_exponent: use a different exponent in the weighting\
            function: exponent 'n' to use in (1 / (distance ^ n)) as the weighting\
            function (default 7).
        opt_bad_voxel_roi_roi_volume: specify an roi of voxels to overwrite,\
            rather than voxels with value zero: volume file, positive values denote\
            voxels to have their values replaced.
        opt_data_roi_roi_volume: specify an roi of where there is data: volume\
            file, positive values denote voxels that have data.
        opt_subvolume_subvol: select a single subvolume to dilate: the\
            subvolume number or name.
        opt_legacy_cutoff: use the v1.3.2 method of excluding voxels further\
            than the dilation distance when calculating the dilated value.
        grad_extrapolate: additionally use the gradient to extrapolate,\
            intended to be used with WEIGHTED.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "workbench/volume-dilate",
        "volume": volume,
        "distance": distance,
        "method": method,
        "volume_out": volume_out,
        "opt_legacy_cutoff": opt_legacy_cutoff,
    }
    if opt_exponent_exponent is not None:
        params["opt_exponent_exponent"] = opt_exponent_exponent
    if opt_bad_voxel_roi_roi_volume is not None:
        params["opt_bad_voxel_roi_roi_volume"] = opt_bad_voxel_roi_roi_volume
    if opt_data_roi_roi_volume is not None:
        params["opt_data_roi_roi_volume"] = opt_data_roi_roi_volume
    if opt_subvolume_subvol is not None:
        params["opt_subvolume_subvol"] = opt_subvolume_subvol
    if grad_extrapolate is not None:
        params["grad_extrapolate"] = grad_extrapolate
    return params


def volume_dilate_cargs(
    params: VolumeDilateParameters,
    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("wb_command")
    cargs.append("-volume-dilate")
    cargs.append(execution.input_file(params.get("volume", None)))
    cargs.append(str(params.get("distance", None)))
    cargs.append(params.get("method", None))
    cargs.append(params.get("volume_out", None))
    if params.get("opt_exponent_exponent", None) is not None:
        cargs.extend([
            "-exponent",
            str(params.get("opt_exponent_exponent", None))
        ])
    if params.get("opt_bad_voxel_roi_roi_volume", None) is not None:
        cargs.extend([
            "-bad-voxel-roi",
            execution.input_file(params.get("opt_bad_voxel_roi_roi_volume", None))
        ])
    if params.get("opt_data_roi_roi_volume", None) is not None:
        cargs.extend([
            "-data-roi",
            execution.input_file(params.get("opt_data_roi_roi_volume", None))
        ])
    if params.get("opt_subvolume_subvol", None) is not None:
        cargs.extend([
            "-subvolume",
            params.get("opt_subvolume_subvol", None)
        ])
    if params.get("opt_legacy_cutoff", False):
        cargs.append("-legacy-cutoff")
    if params.get("grad_extrapolate", None) is not None:
        cargs.extend(volume_dilate_grad_extrapolate_cargs(params.get("grad_extrapolate", None), execution))
    return cargs


def volume_dilate_outputs(
    params: VolumeDilateParameters,
    execution: Execution,
) -> VolumeDilateOutputs:
    """
    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 = VolumeDilateOutputs(
        root=execution.output_file("."),
        volume_out=execution.output_file(params.get("volume_out", None)),
    )
    return ret


def volume_dilate_execute(
    params: VolumeDilateParameters,
    runner: Runner | None = None,
) -> VolumeDilateOutputs:
    """
    volume-dilate
    
    Dilate a volume file.
    
    For all voxels that are designated as bad, if they neighbor a non-bad voxel
    with data or are within the specified distance of such a voxel, replace the
    value in the bad voxel with a value calculated from nearby non-bad voxels
    that have data, otherwise set the value to zero. No matter how small
    <distance> is, dilation will always use at least the face neighbor voxels.
    
    By default, voxels that have data with the value 0 are bad, specify
    -bad-voxel-roi to only count voxels as bad if they are selected by the roi.
    If -data-roi is not specified, all voxels are assumed to have data.
    
    To get the behavior of version 1.3.2 or earlier, use '-legacy-cutoff
    -exponent 2'.
    
    Valid values for <method> are:
    
    NEAREST - use the value from the nearest good voxel
    WEIGHTED - use a weighted average based on distance.
    
    Author: Connectome Workbench Developers
    
    URL: https://github.com/Washington-University/workbench
    
    Args:
        params: The parameters.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `VolumeDilateOutputs`).
    """
    runner = runner or get_global_runner()
    execution = runner.start_execution(VOLUME_DILATE_METADATA)
    params = execution.params(params)
    cargs = volume_dilate_cargs(params, execution)
    ret = volume_dilate_outputs(params, execution)
    execution.run(cargs)
    return ret


def volume_dilate(
    volume: InputPathType,
    distance: float,
    method: str,
    volume_out: str,
    opt_exponent_exponent: float | None = None,
    opt_bad_voxel_roi_roi_volume: InputPathType | None = None,
    opt_data_roi_roi_volume: InputPathType | None = None,
    opt_subvolume_subvol: str | None = None,
    opt_legacy_cutoff: bool = False,
    grad_extrapolate: VolumeDilateGradExtrapolateParameters | None = None,
    runner: Runner | None = None,
) -> VolumeDilateOutputs:
    """
    volume-dilate
    
    Dilate a volume file.
    
    For all voxels that are designated as bad, if they neighbor a non-bad voxel
    with data or are within the specified distance of such a voxel, replace the
    value in the bad voxel with a value calculated from nearby non-bad voxels
    that have data, otherwise set the value to zero. No matter how small
    <distance> is, dilation will always use at least the face neighbor voxels.
    
    By default, voxels that have data with the value 0 are bad, specify
    -bad-voxel-roi to only count voxels as bad if they are selected by the roi.
    If -data-roi is not specified, all voxels are assumed to have data.
    
    To get the behavior of version 1.3.2 or earlier, use '-legacy-cutoff
    -exponent 2'.
    
    Valid values for <method> are:
    
    NEAREST - use the value from the nearest good voxel
    WEIGHTED - use a weighted average based on distance.
    
    Author: Connectome Workbench Developers
    
    URL: https://github.com/Washington-University/workbench
    
    Args:
        volume: the volume to dilate.
        distance: distance in mm to dilate.
        method: dilation method to use.
        volume_out: the output volume.
        opt_exponent_exponent: use a different exponent in the weighting\
            function: exponent 'n' to use in (1 / (distance ^ n)) as the weighting\
            function (default 7).
        opt_bad_voxel_roi_roi_volume: specify an roi of voxels to overwrite,\
            rather than voxels with value zero: volume file, positive values denote\
            voxels to have their values replaced.
        opt_data_roi_roi_volume: specify an roi of where there is data: volume\
            file, positive values denote voxels that have data.
        opt_subvolume_subvol: select a single subvolume to dilate: the\
            subvolume number or name.
        opt_legacy_cutoff: use the v1.3.2 method of excluding voxels further\
            than the dilation distance when calculating the dilated value.
        grad_extrapolate: additionally use the gradient to extrapolate,\
            intended to be used with WEIGHTED.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `VolumeDilateOutputs`).
    """
    params = volume_dilate_params(
        volume=volume,
        distance=distance,
        method=method,
        volume_out=volume_out,
        opt_exponent_exponent=opt_exponent_exponent,
        opt_bad_voxel_roi_roi_volume=opt_bad_voxel_roi_roi_volume,
        opt_data_roi_roi_volume=opt_data_roi_roi_volume,
        opt_subvolume_subvol=opt_subvolume_subvol,
        opt_legacy_cutoff=opt_legacy_cutoff,
        grad_extrapolate=grad_extrapolate,
    )
    return volume_dilate_execute(params, runner)


__all__ = [
    "VOLUME_DILATE_METADATA",
    "VolumeDilateOutputs",
    "volume_dilate",
    "volume_dilate_execute",
    "volume_dilate_grad_extrapolate_params",
    "volume_dilate_params",
    "volume_dilate_presmooth_params",
]
