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

import typing
import pathlib
from styxdefs import *

SCCAN_METADATA = Metadata(
    id="231aefef222d26c3ea09014dbf8d6f3d8b7ad5cf.boutiques",
    name="sccan",
    package="ants",
    container_image_tag="antsx/ants:v2.5.3",
)


_SccanParamsDictNoTag = typing.TypedDict('_SccanParamsDictNoTag', {
    "output": typing.NotRequired[str | None],
    "n_permutations": typing.NotRequired[int | None],
    "smoother": typing.NotRequired[int | None],
    "row_sparseness": typing.NotRequired[int | None],
    "iterations": typing.NotRequired[int | None],
    "n_eigenvectors": typing.NotRequired[int | None],
    "robustify": typing.NotRequired[int | None],
    "covering": typing.NotRequired[int | None],
    "uselong": typing.NotRequired[int | None],
    "l1": typing.NotRequired[float | None],
    "pclusterthresh": typing.NotRequired[float | None],
    "qclusterthresh": typing.NotRequired[float | None],
    "ridge_cca": typing.NotRequired[float | None],
    "initialization": typing.NotRequired[str | None],
    "initialization2": typing.NotRequired[str | None],
    "mask": typing.NotRequired[InputPathType | None],
    "mask2": typing.NotRequired[InputPathType | None],
    "partial_scca_option": typing.NotRequired[str | None],
    "prior_weight": typing.NotRequired[float | None],
    "get_small": typing.NotRequired[float | None],
    "verbose": typing.NotRequired[float | None],
    "imageset_to_matrix": typing.NotRequired[str | None],
    "timeseriesimage_to_matrix": typing.NotRequired[str | None],
    "vector_to_image": typing.NotRequired[str | None],
    "imageset_to_projections": typing.NotRequired[str | None],
    "scca": typing.NotRequired[str | None],
    "svd": typing.NotRequired[str | None],
})
SccanParamsDictTagged = typing.TypedDict('SccanParamsDictTagged', {
    "@type": typing.Literal["ants/sccan"],
    "output": typing.NotRequired[str | None],
    "n_permutations": typing.NotRequired[int | None],
    "smoother": typing.NotRequired[int | None],
    "row_sparseness": typing.NotRequired[int | None],
    "iterations": typing.NotRequired[int | None],
    "n_eigenvectors": typing.NotRequired[int | None],
    "robustify": typing.NotRequired[int | None],
    "covering": typing.NotRequired[int | None],
    "uselong": typing.NotRequired[int | None],
    "l1": typing.NotRequired[float | None],
    "pclusterthresh": typing.NotRequired[float | None],
    "qclusterthresh": typing.NotRequired[float | None],
    "ridge_cca": typing.NotRequired[float | None],
    "initialization": typing.NotRequired[str | None],
    "initialization2": typing.NotRequired[str | None],
    "mask": typing.NotRequired[InputPathType | None],
    "mask2": typing.NotRequired[InputPathType | None],
    "partial_scca_option": typing.NotRequired[str | None],
    "prior_weight": typing.NotRequired[float | None],
    "get_small": typing.NotRequired[float | None],
    "verbose": typing.NotRequired[float | None],
    "imageset_to_matrix": typing.NotRequired[str | None],
    "timeseriesimage_to_matrix": typing.NotRequired[str | None],
    "vector_to_image": typing.NotRequired[str | None],
    "imageset_to_projections": typing.NotRequired[str | None],
    "scca": typing.NotRequired[str | None],
    "svd": typing.NotRequired[str | None],
})
SccanParamsDict = _SccanParamsDictNoTag | SccanParamsDictTagged


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


def sccan_params(
    output: str | None = None,
    n_permutations: int | None = None,
    smoother: int | None = None,
    row_sparseness: int | None = None,
    iterations: int | None = None,
    n_eigenvectors: int | None = None,
    robustify: int | None = None,
    covering: int | None = None,
    uselong: int | None = None,
    l1: float | None = None,
    pclusterthresh: float | None = None,
    qclusterthresh: float | None = None,
    ridge_cca: float | None = None,
    initialization: str | None = None,
    initialization2: str | None = None,
    mask: InputPathType | None = None,
    mask2: InputPathType | None = None,
    partial_scca_option: str | None = None,
    prior_weight: float | None = None,
    get_small: float | None = None,
    verbose: float | None = None,
    imageset_to_matrix: str | None = None,
    timeseriesimage_to_matrix: str | None = None,
    vector_to_image: str | None = None,
    imageset_to_projections: str | None = None,
    scca: str | None = None,
    svd: str | None = None,
) -> SccanParamsDictTagged:
    """
    Build parameters.
    
    Args:
        output: Output dependent on which option is called.
        n_permutations: Number of permutations to use in scca.
        smoother: Smoothing function for variates.
        row_sparseness: Row sparseness - if (+) then keep values (+) otherwise\
            allow +/- values --- always L1.
        iterations: Max iterations for scca optimization (min 20).
        n_eigenvectors: Number of eigenvectors to compute in scca/spca.
        robustify: Rank-based scca.
        covering: Try to make the decomposition cover the whole domain, if\
            possible.
        uselong: Use longitudinal formulation (> 0) or not (<= 0).
        l1: Use l1 (> 0) or l0 (< 0) penalty, also sets gradient step size.
        pclusterthresh: Cluster threshold on view P.
        qclusterthresh: Cluster threshold on view Q.
        ridge_cca: Ridge cca.
        initialization: Initialization file list for Eigenanatomy - must also\
            pass mask option.
        initialization2: Initialization file list for SCCAN-Eigenanatomy - must\
            also pass mask option.
        mask: Mask file for Eigenanatomy initialization.
        mask2: Mask file for Eigenanatomy initialization 2.
        partial_scca_option: Choices for pscca: PQ, PminusRQ, PQminusR,\
            PminusRQminusR.
        prior_weight: Scalar value weight on prior between 0 (prior is weak)\
            and 1 (prior is strong). Only engaged if initialization is used.
        get_small: Find smallest eigenvectors.
        verbose: Set whether output is verbose.
        imageset_to_matrix: Takes a list of image files names (one per line)\
            and converts it to a 2D matrix/image in binary or csv format.
        timeseriesimage_to_matrix: Takes a timeseries (4D) image and converts\
            it to a 2D matrix csv format.
        vector_to_image: Converts the 1st column vector in a csv file back to\
            an image.
        imageset_to_projections: Takes a list of image and projection files\
            names and writes them to a csv file.
        scca: Matrix-based scca operations for 2 and 3 views.
        svd: A sparse SVD implementation.
    Returns:
        Parameter dictionary
    """
    params = {
        "@type": "ants/sccan",
    }
    if output is not None:
        params["output"] = output
    if n_permutations is not None:
        params["n_permutations"] = n_permutations
    if smoother is not None:
        params["smoother"] = smoother
    if row_sparseness is not None:
        params["row_sparseness"] = row_sparseness
    if iterations is not None:
        params["iterations"] = iterations
    if n_eigenvectors is not None:
        params["n_eigenvectors"] = n_eigenvectors
    if robustify is not None:
        params["robustify"] = robustify
    if covering is not None:
        params["covering"] = covering
    if uselong is not None:
        params["uselong"] = uselong
    if l1 is not None:
        params["l1"] = l1
    if pclusterthresh is not None:
        params["pclusterthresh"] = pclusterthresh
    if qclusterthresh is not None:
        params["qclusterthresh"] = qclusterthresh
    if ridge_cca is not None:
        params["ridge_cca"] = ridge_cca
    if initialization is not None:
        params["initialization"] = initialization
    if initialization2 is not None:
        params["initialization2"] = initialization2
    if mask is not None:
        params["mask"] = mask
    if mask2 is not None:
        params["mask2"] = mask2
    if partial_scca_option is not None:
        params["partial_scca_option"] = partial_scca_option
    if prior_weight is not None:
        params["prior_weight"] = prior_weight
    if get_small is not None:
        params["get_small"] = get_small
    if verbose is not None:
        params["verbose"] = verbose
    if imageset_to_matrix is not None:
        params["imageset_to_matrix"] = imageset_to_matrix
    if timeseriesimage_to_matrix is not None:
        params["timeseriesimage_to_matrix"] = timeseriesimage_to_matrix
    if vector_to_image is not None:
        params["vector_to_image"] = vector_to_image
    if imageset_to_projections is not None:
        params["imageset_to_projections"] = imageset_to_projections
    if scca is not None:
        params["scca"] = scca
    if svd is not None:
        params["svd"] = svd
    return params


def sccan_validate(
    params: typing.Any,
) -> None:
    """
    Validate parameters. Throws an error if `params` is not a valid
    `SccanParamsDict` 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("output", None) is not None:
        if not isinstance(params["output"], str):
            raise StyxValidationError(f'`output` has the wrong type: Received `{type(params.get("output", None))}` expected `str | None`')
    if params.get("n_permutations", None) is not None:
        if not isinstance(params["n_permutations"], int):
            raise StyxValidationError(f'`n_permutations` has the wrong type: Received `{type(params.get("n_permutations", None))}` expected `int | None`')
    if params.get("smoother", None) is not None:
        if not isinstance(params["smoother"], int):
            raise StyxValidationError(f'`smoother` has the wrong type: Received `{type(params.get("smoother", None))}` expected `int | None`')
    if params.get("row_sparseness", None) is not None:
        if not isinstance(params["row_sparseness"], int):
            raise StyxValidationError(f'`row_sparseness` has the wrong type: Received `{type(params.get("row_sparseness", None))}` expected `int | None`')
    if params.get("iterations", None) is not None:
        if not isinstance(params["iterations"], int):
            raise StyxValidationError(f'`iterations` has the wrong type: Received `{type(params.get("iterations", None))}` expected `int | None`')
        if params["iterations"] < 20:
            raise StyxValidationError("Parameter `iterations` must be at least 20")
    if params.get("n_eigenvectors", None) is not None:
        if not isinstance(params["n_eigenvectors"], int):
            raise StyxValidationError(f'`n_eigenvectors` has the wrong type: Received `{type(params.get("n_eigenvectors", None))}` expected `int | None`')
    if params.get("robustify", None) is not None:
        if not isinstance(params["robustify"], int):
            raise StyxValidationError(f'`robustify` has the wrong type: Received `{type(params.get("robustify", None))}` expected `int | None`')
    if params.get("covering", None) is not None:
        if not isinstance(params["covering"], int):
            raise StyxValidationError(f'`covering` has the wrong type: Received `{type(params.get("covering", None))}` expected `int | None`')
    if params.get("uselong", None) is not None:
        if not isinstance(params["uselong"], int):
            raise StyxValidationError(f'`uselong` has the wrong type: Received `{type(params.get("uselong", None))}` expected `int | None`')
    if params.get("l1", None) is not None:
        if not isinstance(params["l1"], (float, int)):
            raise StyxValidationError(f'`l1` has the wrong type: Received `{type(params.get("l1", None))}` expected `float | None`')
    if params.get("pclusterthresh", None) is not None:
        if not isinstance(params["pclusterthresh"], (float, int)):
            raise StyxValidationError(f'`pclusterthresh` has the wrong type: Received `{type(params.get("pclusterthresh", None))}` expected `float | None`')
    if params.get("qclusterthresh", None) is not None:
        if not isinstance(params["qclusterthresh"], (float, int)):
            raise StyxValidationError(f'`qclusterthresh` has the wrong type: Received `{type(params.get("qclusterthresh", None))}` expected `float | None`')
    if params.get("ridge_cca", None) is not None:
        if not isinstance(params["ridge_cca"], (float, int)):
            raise StyxValidationError(f'`ridge_cca` has the wrong type: Received `{type(params.get("ridge_cca", None))}` expected `float | None`')
    if params.get("initialization", None) is not None:
        if not isinstance(params["initialization"], str):
            raise StyxValidationError(f'`initialization` has the wrong type: Received `{type(params.get("initialization", None))}` expected `str | None`')
    if params.get("initialization2", None) is not None:
        if not isinstance(params["initialization2"], str):
            raise StyxValidationError(f'`initialization2` has the wrong type: Received `{type(params.get("initialization2", None))}` expected `str | None`')
    if params.get("mask", None) is not None:
        if not isinstance(params["mask"], (pathlib.Path, str)):
            raise StyxValidationError(f'`mask` has the wrong type: Received `{type(params.get("mask", None))}` expected `InputPathType | None`')
    if params.get("mask2", None) is not None:
        if not isinstance(params["mask2"], (pathlib.Path, str)):
            raise StyxValidationError(f'`mask2` has the wrong type: Received `{type(params.get("mask2", None))}` expected `InputPathType | None`')
    if params.get("partial_scca_option", None) is not None:
        if not isinstance(params["partial_scca_option"], str):
            raise StyxValidationError(f'`partial_scca_option` has the wrong type: Received `{type(params.get("partial_scca_option", None))}` expected `str | None`')
    if params.get("prior_weight", None) is not None:
        if not isinstance(params["prior_weight"], (float, int)):
            raise StyxValidationError(f'`prior_weight` has the wrong type: Received `{type(params.get("prior_weight", None))}` expected `float | None`')
    if params.get("get_small", None) is not None:
        if not isinstance(params["get_small"], (float, int)):
            raise StyxValidationError(f'`get_small` has the wrong type: Received `{type(params.get("get_small", None))}` expected `float | None`')
    if params.get("verbose", None) is not None:
        if not isinstance(params["verbose"], (float, int)):
            raise StyxValidationError(f'`verbose` has the wrong type: Received `{type(params.get("verbose", None))}` expected `float | None`')
    if params.get("imageset_to_matrix", None) is not None:
        if not isinstance(params["imageset_to_matrix"], str):
            raise StyxValidationError(f'`imageset_to_matrix` has the wrong type: Received `{type(params.get("imageset_to_matrix", None))}` expected `str | None`')
    if params.get("timeseriesimage_to_matrix", None) is not None:
        if not isinstance(params["timeseriesimage_to_matrix"], str):
            raise StyxValidationError(f'`timeseriesimage_to_matrix` has the wrong type: Received `{type(params.get("timeseriesimage_to_matrix", None))}` expected `str | None`')
    if params.get("vector_to_image", None) is not None:
        if not isinstance(params["vector_to_image"], str):
            raise StyxValidationError(f'`vector_to_image` has the wrong type: Received `{type(params.get("vector_to_image", None))}` expected `str | None`')
    if params.get("imageset_to_projections", None) is not None:
        if not isinstance(params["imageset_to_projections"], str):
            raise StyxValidationError(f'`imageset_to_projections` has the wrong type: Received `{type(params.get("imageset_to_projections", None))}` expected `str | None`')
    if params.get("scca", None) is not None:
        if not isinstance(params["scca"], str):
            raise StyxValidationError(f'`scca` has the wrong type: Received `{type(params.get("scca", None))}` expected `str | None`')
    if params.get("svd", None) is not None:
        if not isinstance(params["svd"], str):
            raise StyxValidationError(f'`svd` has the wrong type: Received `{type(params.get("svd", None))}` expected `str | None`')


def sccan_cargs(
    params: SccanParamsDict,
    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("sccan")
    if params.get("output", None) is not None:
        cargs.extend([
            "-o",
            params.get("output", None)
        ])
    if params.get("n_permutations", None) is not None:
        cargs.extend([
            "-p",
            str(params.get("n_permutations", None))
        ])
    if params.get("smoother", None) is not None:
        cargs.extend([
            "-s",
            str(params.get("smoother", None))
        ])
    if params.get("row_sparseness", None) is not None:
        cargs.extend([
            "-z",
            str(params.get("row_sparseness", None))
        ])
    if params.get("iterations", None) is not None:
        cargs.extend([
            "-i",
            str(params.get("iterations", None))
        ])
    if params.get("n_eigenvectors", None) is not None:
        cargs.extend([
            "-n",
            str(params.get("n_eigenvectors", None))
        ])
    if params.get("robustify", None) is not None:
        cargs.extend([
            "-r",
            str(params.get("robustify", None))
        ])
    if params.get("covering", None) is not None:
        cargs.extend([
            "-c",
            str(params.get("covering", None))
        ])
    if params.get("uselong", None) is not None:
        cargs.extend([
            "-g",
            str(params.get("uselong", None))
        ])
    if params.get("l1", None) is not None:
        cargs.extend([
            "-l",
            str(params.get("l1", None))
        ])
    if params.get("pclusterthresh", None) is not None:
        cargs.extend([
            "--PClusterThresh",
            str(params.get("pclusterthresh", None))
        ])
    if params.get("qclusterthresh", None) is not None:
        cargs.extend([
            "--QClusterThresh",
            str(params.get("qclusterthresh", None))
        ])
    if params.get("ridge_cca", None) is not None:
        cargs.extend([
            "-e",
            str(params.get("ridge_cca", None))
        ])
    if params.get("initialization", None) is not None:
        cargs.extend([
            "--initialization",
            params.get("initialization", None)
        ])
    if params.get("initialization2", None) is not None:
        cargs.extend([
            "--initialization2",
            params.get("initialization2", None)
        ])
    if params.get("mask", None) is not None:
        cargs.extend([
            "--mask",
            execution.input_file(params.get("mask", None))
        ])
    if params.get("mask2", None) is not None:
        cargs.extend([
            "--mask2",
            execution.input_file(params.get("mask2", None))
        ])
    if params.get("partial_scca_option", None) is not None:
        cargs.extend([
            "--partial-scca-option",
            params.get("partial_scca_option", None)
        ])
    if params.get("prior_weight", None) is not None:
        cargs.extend([
            "--prior-weight",
            str(params.get("prior_weight", None))
        ])
    if params.get("get_small", None) is not None:
        cargs.extend([
            "--get-small",
            str(params.get("get_small", None))
        ])
    if params.get("verbose", None) is not None:
        cargs.extend([
            "-v",
            str(params.get("verbose", None))
        ])
    if params.get("imageset_to_matrix", None) is not None:
        cargs.extend([
            "--imageset-to-matrix",
            params.get("imageset_to_matrix", None)
        ])
    if params.get("timeseriesimage_to_matrix", None) is not None:
        cargs.extend([
            "--timeseriesimage-to-matrix",
            params.get("timeseriesimage_to_matrix", None)
        ])
    if params.get("vector_to_image", None) is not None:
        cargs.extend([
            "--vector-to-image",
            params.get("vector_to_image", None)
        ])
    if params.get("imageset_to_projections", None) is not None:
        cargs.extend([
            "--imageset-to-projections",
            params.get("imageset_to_projections", None)
        ])
    if params.get("scca", None) is not None:
        cargs.extend([
            "--scca",
            params.get("scca", None)
        ])
    if params.get("svd", None) is not None:
        cargs.extend([
            "--svd",
            params.get("svd", None)
        ])
    return cargs


def sccan_outputs(
    params: SccanParamsDict,
    execution: Execution,
) -> SccanOutputs:
    """
    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 = SccanOutputs(
        root=execution.output_file("."),
    )
    return ret


def sccan_execute(
    params: SccanParamsDict,
    runner: Runner | None = None,
) -> SccanOutputs:
    """
    sccan
    
    A tool for sparse statistical analysis on images : scca, pscca (with
    options), mscca. Can also convert an imagelist/mask pair to a binary matrix
    image.
    
    Author: ANTs Developers
    
    URL: https://github.com/ANTsX/ANTs
    
    Args:
        params: The parameters.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `SccanOutputs`).
    """
    sccan_validate(params)
    runner = runner or get_global_runner()
    execution = runner.start_execution(SCCAN_METADATA)
    params = execution.params(params)
    cargs = sccan_cargs(params, execution)
    ret = sccan_outputs(params, execution)
    execution.run(cargs)
    return ret


def sccan(
    output: str | None = None,
    n_permutations: int | None = None,
    smoother: int | None = None,
    row_sparseness: int | None = None,
    iterations: int | None = None,
    n_eigenvectors: int | None = None,
    robustify: int | None = None,
    covering: int | None = None,
    uselong: int | None = None,
    l1: float | None = None,
    pclusterthresh: float | None = None,
    qclusterthresh: float | None = None,
    ridge_cca: float | None = None,
    initialization: str | None = None,
    initialization2: str | None = None,
    mask: InputPathType | None = None,
    mask2: InputPathType | None = None,
    partial_scca_option: str | None = None,
    prior_weight: float | None = None,
    get_small: float | None = None,
    verbose: float | None = None,
    imageset_to_matrix: str | None = None,
    timeseriesimage_to_matrix: str | None = None,
    vector_to_image: str | None = None,
    imageset_to_projections: str | None = None,
    scca: str | None = None,
    svd: str | None = None,
    runner: Runner | None = None,
) -> SccanOutputs:
    """
    sccan
    
    A tool for sparse statistical analysis on images : scca, pscca (with
    options), mscca. Can also convert an imagelist/mask pair to a binary matrix
    image.
    
    Author: ANTs Developers
    
    URL: https://github.com/ANTsX/ANTs
    
    Args:
        output: Output dependent on which option is called.
        n_permutations: Number of permutations to use in scca.
        smoother: Smoothing function for variates.
        row_sparseness: Row sparseness - if (+) then keep values (+) otherwise\
            allow +/- values --- always L1.
        iterations: Max iterations for scca optimization (min 20).
        n_eigenvectors: Number of eigenvectors to compute in scca/spca.
        robustify: Rank-based scca.
        covering: Try to make the decomposition cover the whole domain, if\
            possible.
        uselong: Use longitudinal formulation (> 0) or not (<= 0).
        l1: Use l1 (> 0) or l0 (< 0) penalty, also sets gradient step size.
        pclusterthresh: Cluster threshold on view P.
        qclusterthresh: Cluster threshold on view Q.
        ridge_cca: Ridge cca.
        initialization: Initialization file list for Eigenanatomy - must also\
            pass mask option.
        initialization2: Initialization file list for SCCAN-Eigenanatomy - must\
            also pass mask option.
        mask: Mask file for Eigenanatomy initialization.
        mask2: Mask file for Eigenanatomy initialization 2.
        partial_scca_option: Choices for pscca: PQ, PminusRQ, PQminusR,\
            PminusRQminusR.
        prior_weight: Scalar value weight on prior between 0 (prior is weak)\
            and 1 (prior is strong). Only engaged if initialization is used.
        get_small: Find smallest eigenvectors.
        verbose: Set whether output is verbose.
        imageset_to_matrix: Takes a list of image files names (one per line)\
            and converts it to a 2D matrix/image in binary or csv format.
        timeseriesimage_to_matrix: Takes a timeseries (4D) image and converts\
            it to a 2D matrix csv format.
        vector_to_image: Converts the 1st column vector in a csv file back to\
            an image.
        imageset_to_projections: Takes a list of image and projection files\
            names and writes them to a csv file.
        scca: Matrix-based scca operations for 2 and 3 views.
        svd: A sparse SVD implementation.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `SccanOutputs`).
    """
    params = sccan_params(
        output=output,
        n_permutations=n_permutations,
        smoother=smoother,
        row_sparseness=row_sparseness,
        iterations=iterations,
        n_eigenvectors=n_eigenvectors,
        robustify=robustify,
        covering=covering,
        uselong=uselong,
        l1=l1,
        pclusterthresh=pclusterthresh,
        qclusterthresh=qclusterthresh,
        ridge_cca=ridge_cca,
        initialization=initialization,
        initialization2=initialization2,
        mask=mask,
        mask2=mask2,
        partial_scca_option=partial_scca_option,
        prior_weight=prior_weight,
        get_small=get_small,
        verbose=verbose,
        imageset_to_matrix=imageset_to_matrix,
        timeseriesimage_to_matrix=timeseriesimage_to_matrix,
        vector_to_image=vector_to_image,
        imageset_to_projections=imageset_to_projections,
        scca=scca,
        svd=svd,
    )
    return sccan_execute(params, runner)


__all__ = [
    "SCCAN_METADATA",
    "SccanOutputs",
    "SccanParamsDict",
    "SccanParamsDictTagged",
    "sccan",
    "sccan_execute",
    "sccan_params",
]
