# autocleaneeg-sl

Statistical Learning EEG analysis package - epoch extraction, configuration wizard, and Z-scored Inter-Trial Coherence (ZITC) computation.

## Features

- **Configuration Wizard** - Infer paradigm parameters from event sequences using heuristics or LLM assistance
- **Epoch Extraction** - Extract word-locked epochs from continuous EEG with jitter detection
- **ZITC Computation** - Z-scored ITC using surrogate distributions for statistical validity
- **Built-in Presets** - Ready-to-use configurations for common SL experiments

## Installation

```bash
pip install autocleaneeg-sl
```

## Quick Start

### Full Pipeline

```bash
# 1. Infer configuration from event sequence
autocleaneeg-sl wizard --events-file events.txt --soa 300 --output config.yaml

# 2. Extract epochs using the config
autocleaneeg-sl epoch raw_eeg.set --config config.yaml --output epochs.fif

# 3. Compute ZITC
autocleaneeg-sl zitc epochs.fif --config config.yaml --output results.csv
```

### Python API

```python
from autocleaneeg_sl import (
    infer_config,
    load_events_from_file,
    extract_sl_epochs,
    compute_zitc,
)

# Step 1: Infer paradigm configuration
events = load_events_from_file("events.txt")
result = infer_config(events, soa_ms=300.0)

print(f"Word onset codes: {result.word_onset_codes}")
print(f"Words: {result.words}")

# Save validated YAML config
with open("config.yaml", "w") as f:
    f.write(result.to_yaml())

# Step 2: Extract epochs
epochs = extract_sl_epochs(
    "raw_eeg.set",
    word_onset_codes=result.word_onset_codes,
    syllable_soa_ms=300.0,
)

# Step 3: Compute ZITC
zitc_result = compute_zitc(epochs, freq_range=(0.5, 5.0), n_surrogates=200)

# Get ZITC at target frequencies
word_zitc = zitc_result.get_zitc_at_freq(1.111)  # Word rate
syllable_zitc = zitc_result.get_zitc_at_freq(3.333)  # Syllable rate

print(f"Word-rate ZITC: {word_zitc:.2f}")
print(f"Syllable-rate ZITC: {syllable_zitc:.2f}")
```

## Configuration Wizard

The wizard analyzes event sequences to identify word structure in Statistical Learning paradigms.

### Heuristic Inference

```bash
# From event file
autocleaneeg-sl wizard --events-file events.txt --soa 300

# From string
autocleaneeg-sl wizard --events "11 2 4 8 3 5 9 7 6 1 12 10" --soa 300

# Save to file
autocleaneeg-sl wizard --events-file events.txt --soa 300 --output config.yaml
```

### LLM-Assisted Inference

For complex paradigms with non-sequential syllable codes, LLM assistance provides better accuracy:

```bash
# Using OpenCode server (start with: opencode serve)
autocleaneeg-sl wizard --events-file events.txt --provider opencode

# Using Anthropic API
export ANTHROPIC_API_KEY=your-key
autocleaneeg-sl wizard --events-file events.txt --provider anthropic

# Using local Ollama
autocleaneeg-sl wizard --events-file events.txt --provider ollama
```

### Python API

```python
from autocleaneeg_sl import infer_config, run_wizard, load_events_from_file

events = load_events_from_file("events.txt")

# Heuristic only
result = infer_config(events, soa_ms=300.0)

# LLM-assisted
result = run_wizard(events, provider="opencode", soa_ms=300.0)

# Access results
print(result.word_onset_codes)  # [11, 8, 9, 1]
print(result.words)             # [[11, 2, 4], [8, 3, 5], [9, 7, 6], [1, 12, 10]]
print(result.confidence)        # 0.95

# Get config object or YAML
config = result.to_config()
yaml_str = result.to_yaml()
```

## Epoch Extraction

Extract word-locked epochs from continuous EEG:

```bash
autocleaneeg-sl epoch raw_eeg.set --config config.yaml --output epochs.fif
autocleaneeg-sl epoch raw_eeg.set --preset adult-sl-2017 --subject 001re
```

```python
from autocleaneeg_sl import extract_sl_epochs, get_preset

# Using config
epochs, result = extract_sl_epochs(
    "raw_eeg.set",
    word_onset_codes=[11, 8, 9, 1],
    syllable_soa_ms=300.0,
)

# Using preset
config = get_preset("adult-sl-2017")
word_onsets = config.get_word_onset_codes("001re")
epochs, result = extract_sl_epochs("raw_eeg.set", word_onset_codes=word_onsets)
```

## ZITC Computation

Compute Z-scored Inter-Trial Coherence:

```bash
autocleaneeg-sl zitc epochs.fif --freq-range 0.5 5.0 --surrogates 200
autocleaneeg-sl zitc epochs.fif --target-freqs 1.111 3.333 --output results.csv
```

```python
from autocleaneeg_sl import compute_zitc

result = compute_zitc(
    epochs,
    freq_range=(0.5, 5.0),
    n_surrogates=200,
    seed=42,
)

# Access results
print(result.frequencies)      # Frequency bins
print(result.zitc)            # Z-scored ITC values
print(result.raw_itc)         # Raw PLV values

# Export
df = result.to_dataframe()
df.to_csv("zitc_results.csv")
```

### Method

ZITC is computed as:

```
ZITC = (True PLV - Surrogate Mean) / Surrogate Std
```

Where surrogates are generated by circular time-shifting each epoch, destroying phase-locking while preserving spectral properties.

## Configuration Format

```yaml
paradigm:
  name: my-sl-paradigm
  syllable_soa_ms: 300.0
  syllables_per_epoch: 36
  jitter_threshold_ms: 320.0

syllable_codes: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

languages:
  stream1:
    word_onset_codes: [11, 8, 9, 1]
    words:
      - "11-2-4"
      - "8-3-5"
      - "9-7-6"
      - "1-12-10"

analysis:
  freq_range: [0.5, 10.0]
  target_freqs:
    word: 1.111
    syllable: 3.333
```

## Built-in Presets

```python
from autocleaneeg_sl import list_presets, get_preset

print(list_presets())  # ['adult-sl-2017', 'infant-sl']

config = get_preset("adult-sl-2017")
print(config.paradigm.syllable_soa_ms)  # 300.0
```

## CLI Reference

```
autocleaneeg-sl wizard   # Infer config from events
autocleaneeg-sl epoch    # Extract epochs from raw EEG
autocleaneeg-sl zitc     # Compute ZITC from epochs
autocleaneeg-sl --help   # Show help
```

## Requirements

- Python >= 3.9
- NumPy >= 1.20
- MNE-Python >= 1.0
- Pandas >= 1.3
- PyYAML >= 6.0
- requests (for LLM providers)

## License

MIT
