Metadata-Version: 2.1
Name: dda-py
Version: 0.4.0
Summary: Python bindings for DDA (Delay Differential Analysis)
Project-URL: Homepage, https://github.com/sdraeger/dda-py
Project-URL: Repository, https://github.com/sdraeger/dda-py
Project-URL: Issues, https://github.com/sdraeger/dda-py/issues
Author-email: Simon Draeger <sdraeger@salk.edu>
License: MIT
License-File: LICENSE
Keywords: dda,delay-differential-analysis,eeg,neurophysiology,neuroscience,signal-processing
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering
Requires-Python: >=3.9
Requires-Dist: numpy>=1.20
Provides-Extra: all
Requires-Dist: matplotlib>=3.5; extra == 'all'
Requires-Dist: mne-bids>=0.12; extra == 'all'
Requires-Dist: mne>=1.0; extra == 'all'
Requires-Dist: pandas>=1.3; extra == 'all'
Requires-Dist: scipy>=1.7; extra == 'all'
Provides-Extra: dev
Requires-Dist: matplotlib>=3.5; extra == 'dev'
Requires-Dist: mne>=1.0; extra == 'dev'
Requires-Dist: pandas>=1.3; extra == 'dev'
Requires-Dist: pytest-cov>=4.0; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: scipy>=1.7; extra == 'dev'
Provides-Extra: matplotlib
Requires-Dist: matplotlib>=3.5; extra == 'matplotlib'
Provides-Extra: mne
Requires-Dist: mne>=1.0; extra == 'mne'
Provides-Extra: mne-bids
Requires-Dist: mne-bids>=0.12; extra == 'mne-bids'
Requires-Dist: mne>=1.0; extra == 'mne-bids'
Provides-Extra: pandas
Requires-Dist: pandas>=1.3; extra == 'pandas'
Provides-Extra: scipy
Requires-Dist: scipy>=1.7; extra == 'scipy'
Description-Content-Type: text/markdown

# dda-py

Python bindings for DDA (Delay Differential Analysis).

The [DDA binary](https://snl.salk.edu/~sfdraeger/dda/) is required. Please download the most recent version from the file server.

## Installation

```bash
pip install dda-py
```

Optional dependencies:

```bash
pip install dda-py[mne]     # MNE-Python integration
pip install dda-py[pandas]  # DataFrame export
pip install dda-py[all]     # All optional deps
```

## Quick Start (High-Level API)

```python
import numpy as np
from dda_py import run_st

# Analyze a numpy array (n_channels x n_samples)
data = np.random.randn(3, 10000)
result = run_st(data, sfreq=256.0, delays=(7, 10), wl=200, ws=100)

print(result.coefficients.shape)   # (3, n_windows, 3)
print(result.n_channels)           # 3
print(result.n_windows)            # depends on data length
print(result.to_dataframe().head())
```

### MNE-Python Integration

```python
import mne
from dda_py import run_st

raw = mne.io.read_raw_edf("data.edf", preload=True)
result = run_st(raw, delays=(7, 10), wl=200, ws=100)
# sfreq is extracted automatically from the MNE Raw object
```

### Cross-Timeseries Analysis

```python
from dda_py import run_ct

data = np.random.randn(4, 10000)  # 4 channels
result = run_ct(data, sfreq=256.0, delays=(7, 10), wl=200, ws=100)
print(result.n_pairs)              # 6 (all unique pairs)
print(result.pair_labels)          # ['ch0-ch1', 'ch0-ch2', ...]
```

### Dynamical Ergodicity

```python
from dda_py import run_de

data = np.random.randn(2, 10000)
result = run_de(data, sfreq=256.0, delays=(7, 10), wl=200, ws=100)
print(result.ergodicity.shape)     # (n_windows,)
```

## Low-Level API

For full control over the DDA binary:

```python
from dda_py import DDARequest, DDARunner

runner = DDARunner()  # auto-discovers binary
request = DDARequest(
    file_path="data.edf",
    channels=[0, 1, 2],
    variants=["ST"],
    window_length=200,
    window_step=100,
    delays=[7, 10],
)
results = runner.run(request)
```

## Model Encoding

Visualize what DDA model indices mean:

```python
from dda_py import visualize_model_space, decode_model_encoding

# Show all monomials for 2 delays, polynomial order 4
print(visualize_model_space(2, 4, highlight_encoding=[1, 2, 10]))

# Decode model [1, 2, 10] to equation
print(decode_model_encoding([1, 2, 10], num_delays=2, polynomial_order=4, format="text"))
# dx/dt = a_1 x_1 + a_2 x_2 + a_3 x_1^4
```

## CLI

```bash
dda --file data.edf --channels 0 1 2 --variants ST --wl 200 --ws 100
dda --file data.edf --channels 0 1 2 --variants ST CT --delays 7 10 -o results.json
```

## Variants

- **ST** - Single Timeseries
- **CT** - Cross Timeseries
- **CD** - Cross Dynamical
- **DE** - Dynamical Ergodicity
- **SY** - Synchrony

## License

MIT
