Metadata-Version: 2.2
Name: py-mea-axion
Version: 0.1.0
Summary: End-to-end MEA data analysis for Axion Biosystems instruments
Author: George (Zhuang) Han
License: MIT
Keywords: MEA,electrophysiology,Axion,spike,burst,neuroscience
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
Classifier: Intended Audience :: Science/Research
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.26
Requires-Dist: scipy>=1.11
Requires-Dist: pandas>=2.1
Requires-Dist: matplotlib>=3.8
Requires-Dist: seaborn>=0.13
Requires-Dist: pingouin>=0.5.4
Requires-Dist: statsmodels>=0.14
Provides-Extra: interactive
Requires-Dist: plotly>=5.18; extra == "interactive"
Provides-Extra: dev
Requires-Dist: pytest>=7.4; extra == "dev"
Requires-Dist: pytest-cov>=4.1; extra == "dev"
Provides-Extra: docs
Requires-Dist: sphinx>=7.2; extra == "docs"
Requires-Dist: nbsphinx>=0.9; extra == "docs"

# py-mea-axion

End-to-end analysis of multi-electrode array (MEA) recordings from
**Axion Biosystems** instruments, in Python.

`py-mea-axion` reads raw `.spk` binary files and carries the analysis
through spike metrics, burst detection, network burst detection, and
synchrony measurement — all the way to statistical comparisons and
publication-ready figures.

---

## Installation

> **Note:** the package is not yet on PyPI.  Install directly from GitHub.

### Recommended: new conda environment

```bash
conda create -n mea python=3.11
conda activate mea
pip install git+https://github.com/Molecularbiologyworld/py-mea-axion.git
```

### Or into an existing environment

```bash
pip install git+https://github.com/Molecularbiologyworld/py-mea-axion.git
```

### For development (editable install from a local clone)

```bash
git clone https://github.com/Molecularbiologyworld/py-mea-axion.git
cd py-mea-axion
pip install -e .
```

**Requirements:** Python ≥ 3.10, numpy, scipy, pandas, matplotlib, pingouin, statsmodels.

---

## Quickstart

### Command-line interface

The fastest way to get results without writing any Python:

```bash
# Quick per-well summary printed to the terminal
mea-axion summary recording.spk --fs-override 12500

# Full pipeline — writes CSVs + figures to results/
mea-axion run recording.spk --out results/ --fs-override 12500

# With a plate map (adds condition labels to outputs)
mea-axion run recording.spk --metadata plate_map.csv --out results/ --fs-override 12500

# Only CSVs, skip figure generation
mea-axion run recording.spk --out results/ --no-figures --fs-override 12500

# Restrict to specific wells
mea-axion summary recording.spk --wells A1 B1 C1 --fs-override 12500
```

Run `mea-axion --help` or `mea-axion run --help` for the full option list.

---

### Python API

```python
from py_mea_axion import MEAExperiment

exp = MEAExperiment(
    "recording.spk",
    metadata="plate_map.csv",   # optional: well_id, condition, DIV, replicate_id
    fs_override=12500,
    active_threshold_hz=5/60,   # 5 spikes/min, matching NeuralMetric Tools default
).run()

# Tabular results
exp.spike_metrics      # per-electrode: MFR, ISI stats, active flag
exp.burst_table        # per-burst: start/end time, duration, spike count
exp.well_summary       # per-well: n_active, mean MFR, burst rate, STTC
exp.excluded_wells     # wells dropped for having too few active electrodes

# One-liner export
exp.to_csv("results.csv")        # well_summary merged with metadata

# Statistics
res  = exp.compare("mean_mfr_active_hz")        # Mann-Whitney / Kruskal-Wallis
coef = exp.longitudinal("mean_mfr_active_hz")   # mixed-effects model

# Figures
exp.plot_heatmap("A1")                       # electrode MFR heatmap
exp.plot_raster("A1")                        # spike raster + burst overlays
exp.plot_sttc("A1")                          # pairwise STTC matrix
exp.plot_network_timeline("A1")              # network burst Gantt chart
exp.plot_trajectory("mean_mfr_active_hz")    # longitudinal mean ± SEM
```

### Plate-map CSV format

```
well_id,condition,DIV,replicate_id
A1,WT,14,rep1
A2,KD,14,rep1
B1,WT,14,rep2
B2,KD,14,rep2
```

---

## Key parameters

### Burst detection (`burst_kwargs`)

| Parameter | Default | Description |
|---|---|---|
| `algorithm` | `isi_threshold` | Detection algorithm |
| `max_isi_s` | 0.1 s | Maximum within-burst ISI |
| `min_spikes` | 5 | Minimum spikes per burst |
| `min_ibi_s` | 0.0 s | Minimum inter-burst interval (0 = no merging) |

### Network burst detection (`network_kwargs`)

| Parameter | Default | Description |
|---|---|---|
| `algorithm` | `combined_isi` | Merges all electrode spike trains, matches NeuralMetric Tools |
| `max_isi_s` | 0.1 s | Maximum within-network-burst ISI |
| `min_spikes` | 50 | Minimum spikes in combined train |
| `participation_threshold` | 0.35 | Minimum fraction of electrodes that must fire |

Pass these via `burst_kwargs` / `network_kwargs` in `MEAExperiment`.

---

## Note on Axion .spk files

Some recordings lack a `BlockVectorHeader` (common with certain firmware versions).
In this case the sampling frequency is inferred automatically; a warning is printed.
If the inferred frequency is wrong, override it explicitly:

```python
exp = MEAExperiment("recording.spk", fs_override=12500)
```

```bash
mea-axion run recording.spk --fs-override 12500
```

---

## Running the tests

```bash
pip install -e ".[dev]"
pytest
```

397 tests covering all modules.

---

## Citing

If you use `py-mea-axion` in your research, please cite:

> [manuscript in preparation]

[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.19350375.svg)](https://doi.org/10.5281/zenodo.19350375)

---

## License

MIT — see [LICENSE](LICENSE).
