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

import typing
import pathlib
from styxdefs import *
import dataclasses

CIFTI_CORRELATION_GRADIENT_METADATA = Metadata(
    id="4171e64612cc538935b4cf5882de626312159abb.boutiques",
    name="cifti-correlation-gradient",
    package="workbench",
    container_image_tag="brainlife/connectome_workbench:1.5.0-freesurfer-update",
)


@dataclasses.dataclass
class CiftiCorrelationGradientLeftSurface:
    """
    specify the left surface to use.
    """
    surface: InputPathType
    """the left surface file"""
    opt_left_corrected_areas_area_metric: InputPathType | None = None
    """vertex areas to use instead of computing them from the left surface: the
    corrected vertex areas, as a metric"""
    
    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("-left-surface")
        cargs.append(execution.input_file(self.surface))
        if self.opt_left_corrected_areas_area_metric is not None:
            cargs.extend([
                "-left-corrected-areas",
                execution.input_file(self.opt_left_corrected_areas_area_metric)
            ])
        return cargs


@dataclasses.dataclass
class CiftiCorrelationGradientRightSurface:
    """
    specify the right surface to use.
    """
    surface: InputPathType
    """the right surface file"""
    opt_right_corrected_areas_area_metric: InputPathType | None = None
    """vertex areas to use instead of computing them from the right surface: the
    corrected vertex areas, as a metric"""
    
    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("-right-surface")
        cargs.append(execution.input_file(self.surface))
        if self.opt_right_corrected_areas_area_metric is not None:
            cargs.extend([
                "-right-corrected-areas",
                execution.input_file(self.opt_right_corrected_areas_area_metric)
            ])
        return cargs


@dataclasses.dataclass
class CiftiCorrelationGradientCerebellumSurface:
    """
    specify the cerebellum surface to use.
    """
    surface: InputPathType
    """the cerebellum surface file"""
    opt_cerebellum_corrected_areas_area_metric: InputPathType | None = None
    """vertex areas to use instead of computing them from the cerebellum
    surface: the corrected vertex areas, as a metric"""
    
    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("-cerebellum-surface")
        cargs.append(execution.input_file(self.surface))
        if self.opt_cerebellum_corrected_areas_area_metric is not None:
            cargs.extend([
                "-cerebellum-corrected-areas",
                execution.input_file(self.opt_cerebellum_corrected_areas_area_metric)
            ])
        return cargs


@dataclasses.dataclass
class CiftiCorrelationGradientDoubleCorrelation:
    """
    do two correlations before taking the gradient.
    """
    opt_fisher_z_first: bool = False
    """after the FIRST correlation, apply fisher small z transform (ie,
    artanh)"""
    opt_no_demean_first: bool = False
    """instead of correlation for the FIRST operation, do dot product of rows,
    then normalize by diagonal"""
    opt_covariance_first: bool = False
    """instead of correlation for the FIRST operation, compute covariance"""
    
    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("-double-correlation")
        if self.opt_fisher_z_first:
            cargs.append("-fisher-z-first")
        if self.opt_no_demean_first:
            cargs.append("-no-demean-first")
        if self.opt_covariance_first:
            cargs.append("-covariance-first")
        return cargs


class CiftiCorrelationGradientOutputs(typing.NamedTuple):
    """
    Output object returned when calling `cifti_correlation_gradient(...)`.
    """
    root: OutputPathType
    """Output root folder. This is the root folder for all outputs."""
    cifti_out: OutputPathType
    """the output cifti"""


def cifti_correlation_gradient(
    cifti: InputPathType,
    cifti_out: str,
    left_surface: CiftiCorrelationGradientLeftSurface | None = None,
    right_surface: CiftiCorrelationGradientRightSurface | None = None,
    cerebellum_surface: CiftiCorrelationGradientCerebellumSurface | None = None,
    opt_surface_presmooth_surface_kernel: float | None = None,
    opt_volume_presmooth_volume_kernel: float | None = None,
    opt_presmooth_fwhm: bool = False,
    opt_undo_fisher_z: bool = False,
    opt_fisher_z: bool = False,
    opt_surface_exclude_distance: float | None = None,
    opt_volume_exclude_distance: float | None = None,
    opt_covariance: bool = False,
    opt_mem_limit_limit_gb: float | None = None,
    double_correlation: CiftiCorrelationGradientDoubleCorrelation | None = None,
    runner: Runner | None = None,
) -> CiftiCorrelationGradientOutputs:
    """
    Correlate cifti rows and take gradient.
    
    For each structure, compute the correlation of the rows in the structure,
    and take the gradients of the resulting rows, then average them. Memory
    limit does not need to be an integer, you may also specify 0 to use as
    little memory as possible (this may be very slow).
    
    Author: Washington University School of Medicin
    
    Args:
        cifti: the input cifti.
        cifti_out: the output cifti.
        left_surface: specify the left surface to use.
        right_surface: specify the right surface to use.
        cerebellum_surface: specify the cerebellum surface to use.
        opt_surface_presmooth_surface_kernel: smooth on the surface before\
            computing the gradient: the size of the gaussian surface smoothing\
            kernel in mm, as sigma by default.
        opt_volume_presmooth_volume_kernel: smooth the volume before computing\
            the gradient: the size of the gaussian volume smoothing kernel in mm,\
            as sigma by default.
        opt_presmooth_fwhm: smoothing kernel sizes are FWHM, not sigma.
        opt_undo_fisher_z: apply the inverse fisher small z transform to the\
            input.
        opt_fisher_z: apply the fisher small z transform to the correlations\
            before taking the gradient.
        opt_surface_exclude_distance: exclude vertices near each seed vertex\
            from computation: geodesic distance from seed vertex for the exclusion\
            zone, in mm.
        opt_volume_exclude_distance: exclude voxels near each seed voxel from\
            computation: distance from seed voxel for the exclusion zone, in mm.
        opt_covariance: compute covariance instead of correlation.
        opt_mem_limit_limit_gb: restrict memory usage: memory limit in\
            gigabytes.
        double_correlation: do two correlations before taking the gradient.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `CiftiCorrelationGradientOutputs`).
    """
    runner = runner or get_global_runner()
    execution = runner.start_execution(CIFTI_CORRELATION_GRADIENT_METADATA)
    cargs = []
    cargs.append("wb_command")
    cargs.append("-cifti-correlation-gradient")
    cargs.append(execution.input_file(cifti))
    cargs.append(cifti_out)
    if left_surface is not None:
        cargs.extend(left_surface.run(execution))
    if right_surface is not None:
        cargs.extend(right_surface.run(execution))
    if cerebellum_surface is not None:
        cargs.extend(cerebellum_surface.run(execution))
    if opt_surface_presmooth_surface_kernel is not None:
        cargs.extend([
            "-surface-presmooth",
            str(opt_surface_presmooth_surface_kernel)
        ])
    if opt_volume_presmooth_volume_kernel is not None:
        cargs.extend([
            "-volume-presmooth",
            str(opt_volume_presmooth_volume_kernel)
        ])
    if opt_presmooth_fwhm:
        cargs.append("-presmooth-fwhm")
    if opt_undo_fisher_z:
        cargs.append("-undo-fisher-z")
    if opt_fisher_z:
        cargs.append("-fisher-z")
    if opt_surface_exclude_distance is not None:
        cargs.extend([
            "-surface-exclude",
            str(opt_surface_exclude_distance)
        ])
    if opt_volume_exclude_distance is not None:
        cargs.extend([
            "-volume-exclude",
            str(opt_volume_exclude_distance)
        ])
    if opt_covariance:
        cargs.append("-covariance")
    if opt_mem_limit_limit_gb is not None:
        cargs.extend([
            "-mem-limit",
            str(opt_mem_limit_limit_gb)
        ])
    if double_correlation is not None:
        cargs.extend(double_correlation.run(execution))
    ret = CiftiCorrelationGradientOutputs(
        root=execution.output_file("."),
        cifti_out=execution.output_file(cifti_out),
    )
    execution.run(cargs)
    return ret


__all__ = [
    "CIFTI_CORRELATION_GRADIENT_METADATA",
    "CiftiCorrelationGradientCerebellumSurface",
    "CiftiCorrelationGradientDoubleCorrelation",
    "CiftiCorrelationGradientLeftSurface",
    "CiftiCorrelationGradientOutputs",
    "CiftiCorrelationGradientRightSurface",
    "cifti_correlation_gradient",
]
