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

import typing
import pathlib
from styxdefs import *
import dataclasses

OPTSEQ2_METADATA = Metadata(
    id="0f4e820b7a3fa22c2de66e83252857cc8c403a78.boutiques",
    name="optseq2",
    package="freesurfer",
    container_image_tag="freesurfer/freesurfer:7.4.1",
)


class Optseq2Outputs(typing.NamedTuple):
    """
    Output object returned when calling `optseq2(...)`.
    """
    root: OutputPathType
    """Output root folder. This is the root folder for all outputs."""
    output_schedules: OutputPathType | None
    """Output schedules"""
    output_design_matrices: OutputPathType | None
    """Output FIR design matrices"""
    output_contrast_matrix: OutputPathType | None
    """Output contrast matrix"""
    output_summary: OutputPathType | None
    """Output search summary"""
    output_log: OutputPathType | None
    """Output log file"""
    output_sviter: OutputPathType | None
    """Output per-iteration information"""


def optseq2(
    ntp: float,
    tr: float,
    tprescan: float,
    psdwin: list[float],
    event: list[str] | None = None,
    repvar: str | None = None,
    polyfit: float | None = None,
    tnullmin: float | None = None,
    tnullmax: float | None = None,
    nsearch: float | None = None,
    tsearch: float | None = None,
    first_order_cb: float | None = None,
    ar1: float | None = None,
    penalize: list[float] | None = None,
    evc: list[float] | None = None,
    cmtx: InputPathType | None = None,
    cost: str | None = None,
    sumdelays: bool = False,
    seed: float | None = None,
    nkeep: float | None = None,
    outstem: str | None = None,
    mtxstem: str | None = None,
    cmtxfile: str | None = None,
    summaryfile: str | None = None,
    logfile: str | None = None,
    pctupdate: float | None = None,
    sviterfile: str | None = None,
    instem: str | None = None,
    input_schedule: list[str] | None = None,
    nosearch: bool = False,
    help_: bool = False,
    version: bool = False,
    runner: Runner | None = None,
) -> Optseq2Outputs:
    """
    Optseq2 is a tool for automatically scheduling events for rapid-presentation
    event-related (RPER) fMRI experiments.
    
    Author: FreeSurfer Developers
    
    URL: https://github.com/freesurfer/freesurfer
    
    Args:
        ntp: Number of time points to be acquired during the scan.
        tr: Temporal resolution of acquisition in seconds.
        tprescan: Start events t seconds before first acquisition.
        psdwin: Post-stimulus window specifications: minimum PSD, maximum PSD,\
            and optional dPSD.
        event: Event type specification with label, duration, and number of\
            repetitions.
        repvar: Allow number of repetitions of event types to vary by\
            percentage, optionally per event.
        polyfit: Add polynomial regressors as nuisance variables of specified\
            order.
        tnullmin: Minimum duration of null time between stimuli in seconds.
        tnullmax: Maximum duration of null time between stimuli in seconds.
        nsearch: Search over a specified number of iterations for schedules.
        tsearch: Search for schedules over a specified number of hours.
        first_order_cb: Pre-optimize first order counter-balancing.
        ar1: Optimize assuming whitening with AR1 parameter.
        penalize: Penalize for presentations being too close with parameters\
            alpha, T, and dtmin.
        evc: Contrast of event types with weights.
        cmtx: Load contrast from ASCII matrix file.
        cost: Specify cost function and its parameters.
        sumdelays: Sum delays when forming contrast matrix.
        seed: Initialize random number generator with seed value.
        nkeep: Number of best schedules to keep.
        outstem: Output stem for saved schedules.
        mtxstem: Output stem for saved design matrices.
        cmtxfile: File for saving contrast matrix.
        summaryfile: File for saving search summary.
        logfile: File for saving log information.
        pctupdate: Percentage interval after which progress is logged.
        sviterfile: File to save information from each iteration.
        instem: Initialize with input schedules that match instem-RRR.par.
        input_schedule: Input schedule files.
        nosearch: Do not perform search for optimal schedules.
        help_: Print help page.
        version: Print version string.
        runner: Command runner.
    Returns:
        NamedTuple of outputs (described in `Optseq2Outputs`).
    """
    if event is not None and (len(event) != 3): 
        raise ValueError(f"Length of 'event' must be 3 but was {len(event)}")
    if ar1 is not None and not (-1 <= ar1 <= 1): 
        raise ValueError(f"'ar1' must be between -1 <= x <= 1 but was {ar1}")
    runner = runner or get_global_runner()
    execution = runner.start_execution(OPTSEQ2_METADATA)
    cargs = []
    cargs.append("optseq2")
    cargs.extend([
        "--ntp",
        str(ntp)
    ])
    cargs.extend([
        "--tr",
        str(tr)
    ])
    cargs.extend([
        "--tprescan",
        str(tprescan)
    ])
    cargs.extend([
        "--psdwin",
        *map(str, psdwin)
    ])
    if event is not None:
        cargs.extend([
            "--ev",
            *event
        ])
    if repvar is not None:
        cargs.extend([
            "--repvar",
            repvar
        ])
    if polyfit is not None:
        cargs.extend([
            "--polyfit",
            str(polyfit)
        ])
    if tnullmin is not None:
        cargs.extend([
            "--tnullmin",
            str(tnullmin)
        ])
    if tnullmax is not None:
        cargs.extend([
            "--tnullmax",
            str(tnullmax)
        ])
    if nsearch is not None:
        cargs.extend([
            "--nsearch",
            str(nsearch)
        ])
    if tsearch is not None:
        cargs.extend([
            "--tsearch",
            str(tsearch)
        ])
    if first_order_cb is not None:
        cargs.extend([
            "--focb",
            str(first_order_cb)
        ])
    if ar1 is not None:
        cargs.extend([
            "--ar1",
            str(ar1)
        ])
    if penalize is not None:
        cargs.extend([
            "--pen",
            *map(str, penalize)
        ])
    if evc is not None:
        cargs.extend([
            "--evc",
            *map(str, evc)
        ])
    if cmtx is not None:
        cargs.extend([
            "--C",
            execution.input_file(cmtx)
        ])
    if cost is not None:
        cargs.extend([
            "--cost",
            cost
        ])
    if sumdelays:
        cargs.append("--sumdelays")
    if seed is not None:
        cargs.extend([
            "--seed",
            str(seed)
        ])
    if nkeep is not None:
        cargs.extend([
            "--nkeep",
            str(nkeep)
        ])
    if outstem is not None:
        cargs.extend([
            "--o",
            outstem
        ])
    if mtxstem is not None:
        cargs.extend([
            "--mtx",
            mtxstem
        ])
    if cmtxfile is not None:
        cargs.extend([
            "--cmtx",
            cmtxfile
        ])
    if summaryfile is not None:
        cargs.extend([
            "--sum",
            summaryfile
        ])
    if logfile is not None:
        cargs.extend([
            "--log",
            logfile
        ])
    if pctupdate is not None:
        cargs.extend([
            "--pctupdate",
            str(pctupdate)
        ])
    if sviterfile is not None:
        cargs.extend([
            "--sviter",
            sviterfile
        ])
    if instem is not None:
        cargs.extend([
            "--i",
            instem
        ])
    if input_schedule is not None:
        cargs.extend([
            "--in",
            *input_schedule
        ])
    if nosearch:
        cargs.append("--nosearch")
    if help_:
        cargs.append("--help")
    if version:
        cargs.append("--version")
    ret = Optseq2Outputs(
        root=execution.output_file("."),
        output_schedules=execution.output_file(outstem + "-RRR.par") if (outstem is not None) else None,
        output_design_matrices=execution.output_file(mtxstem + "_RRR.mat") if (mtxstem is not None) else None,
        output_contrast_matrix=execution.output_file(cmtxfile) if (cmtxfile is not None) else None,
        output_summary=execution.output_file(summaryfile) if (summaryfile is not None) else None,
        output_log=execution.output_file(logfile) if (logfile is not None) else None,
        output_sviter=execution.output_file(sviterfile) if (sviterfile is not None) else None,
    )
    execution.run(cargs)
    return ret


__all__ = [
    "OPTSEQ2_METADATA",
    "Optseq2Outputs",
    "optseq2",
]
