Metadata-Version: 2.5
Name: biosqi
Version: 0.1.0
Summary: Transparent, calibrated signal-quality assessment for biomedical recordings
Project-URL: Homepage, https://github.com/akshajbachu/biosqi
Project-URL: Documentation, https://akshajbachu.github.io/biosqi
Project-URL: Source, https://github.com/akshajbachu/biosqi
Project-URL: Issues, https://github.com/akshajbachu/biosqi/issues
Project-URL: Changelog, https://github.com/akshajbachu/biosqi/blob/main/CHANGELOG.md
Author: Akshaj Bachu
Maintainer: Akshaj Bachu
License-Expression: MIT
License-File: LICENSE
Keywords: biosignals,ecg,eeg,physionet,ppg,signal-quality
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Healthcare Industry
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.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Information Analysis
Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: numpy>=1.26
Requires-Dist: rich>=13.7
Requires-Dist: scikit-learn>=1.4
Requires-Dist: scipy>=1.12
Requires-Dist: typer>=0.12
Provides-Extra: data
Requires-Dist: neurokit2>=0.2.10; extra == 'data'
Requires-Dist: pyedflib>=0.1.39; extra == 'data'
Requires-Dist: wfdb>=4.1; extra == 'data'
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == 'dev'
Requires-Dist: fastapi>=0.115; extra == 'dev'
Requires-Dist: hatchling>=1.27; extra == 'dev'
Requires-Dist: httpx>=0.27; extra == 'dev'
Requires-Dist: hypothesis>=6.100; extra == 'dev'
Requires-Dist: mkdocs-material>=9.5; extra == 'dev'
Requires-Dist: mkdocstrings[python]>=0.25; extra == 'dev'
Requires-Dist: mypy>=1.11; extra == 'dev'
Requires-Dist: neurokit2>=0.2.10; extra == 'dev'
Requires-Dist: pyedflib>=0.1.39; extra == 'dev'
Requires-Dist: pytest-cov>=5; extra == 'dev'
Requires-Dist: pytest>=8.2; extra == 'dev'
Requires-Dist: python-multipart>=0.0.12; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Requires-Dist: uvicorn[standard]>=0.30; extra == 'dev'
Requires-Dist: wfdb>=4.1; extra == 'dev'
Provides-Extra: docs
Requires-Dist: mkdocs-material>=9.5; extra == 'docs'
Requires-Dist: mkdocstrings[python]>=0.25; extra == 'docs'
Provides-Extra: ui
Requires-Dist: fastapi>=0.115; extra == 'ui'
Requires-Dist: python-multipart>=0.0.12; extra == 'ui'
Requires-Dist: uvicorn[standard]>=0.30; extra == 'ui'
Description-Content-Type: text/markdown

# biosqi

[![CI](https://github.com/akshajbachu/biosqi/actions/workflows/ci.yml/badge.svg)](https://github.com/akshajbachu/biosqi/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/biosqi)](https://pypi.org/project/biosqi/)
[![Python 3.10-3.13](https://img.shields.io/badge/python-3.10--3.13-blue)](https://www.python.org/)
[![Docs](https://img.shields.io/badge/docs-online-blue)](https://akshajbachu.github.io/biosqi/)
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)

Transparent, calibrated biomedical signal-quality assessment for ECG, PPG, and
EEG recordings.

biosqi turns a long waveform into a window-aligned quality score, a mask a
downstream pipeline can consume, and explicit evidence about what may be wrong.
Instead of returning an unexplained “bad signal” flag, it exposes the spectral,
amplitude, drift, distribution, and periodicity indicators behind each
decision.

> [!IMPORTANT]
> biosqi is research software, not a medical device. It measures recording
> properties; it does not diagnose patients or determine clinical safety.

## What makes it useful

- **Explainable attribution:** identifies evidence consistent with mains
  interference, baseline wander/motion, clipping, flatline/dropout, unusual
  amplitude, and poor beat consistency.
- **Calibrated, versioned models:** logistic fusion followed by a monotone
  isotonic map. Model name and analysis settings travel with every result.
- **Multiple entry points:** typed Python library, scriptable CLI,
  self-contained HTML reports, and a polished local dashboard.
- **Research formats:** NumPy/NPZ and CSV in the base install; WFDB and EDF/BDF
  through an optional data extra.
- **Reproducible validation:** one command downloads public datasets,
  recomputes nested-CV metrics, fits the release model, and regenerates this
  README’s result block.

## Install

```bash
pip install "biosqi[data,ui]"
```

For development:

```bash
git clone https://github.com/akshajbachu/biosqi.git
cd biosqi
uv sync --extra dev
```

## Use the dashboard

```bash
biosqi view
```

Drop a recording into the browser, select ECG/PPG/EEG and its sample rate, then
inspect aligned waveform and quality timelines. Selecting a window reveals its
power spectrum, indicator evidence, and artifact attribution. Processing stays
on the local machine.

![biosqi dashboard](docs/assets/dashboard.png)

## Use the CLI

```bash
# Human-readable window table
biosqi score recording.csv --sample-rate 250 --signal-type ecg

# Complete machine-readable report
biosqi score recording.npz --signal-type ppg --json > result.json

# Sample-level mask and standalone HTML report
biosqi mask recording.hea --signal-type ecg --output mask.csv
biosqi report recording.hea --signal-type ecg --output report.html
```

## Use Python

```python
from biosqi.analysis import analyze
from biosqi.io import read_recording
from biosqi.types import SignalType

recording = read_recording("recording.npz", signal_type=SignalType.ECG)
result = analyze(recording, threshold=0.70)

print(result.scores)  # calibrated score for each window
print(result.mask)  # boolean window mask
print(result.windows[0].artifacts)
```

<!-- benchmark-results:start -->
## Reproducible validation

Numbers below are generated by `python benchmarks/run_all.py`; they are not
hand-entered. The Challenge metric uses nested calibration inside each outer
fold. Set B/C labels remain withheld and are not claimed as test results.

| Benchmark | Result |
| --- | ---: |
| CinC 2011 Set A records | 998 |
| 5-fold ROC AUC (95% bootstrap CI) | 0.819 (0.782-0.855) |
| Balanced accuracy | 0.758 |
| Brier score | 0.101 |
| NSTDB score/SNR correlation | 0.982 |
<!-- benchmark-results:end -->

## Reproduce every number

```bash
# Fast pipeline check on a balanced subset
uv run python benchmarks/run_all.py --quick

# Full Set A + all MIT-BIH NSTDB conditions
uv run python benchmarks/run_all.py
```

Public data is cached under `~/.cache/biosqi` (override with `BIOSQI_CACHE`).
The runner records provenance, uses nested calibration inside each outer
validation fold, writes JSON and SVG plots, updates this result block, and
stores the fitted model.

## Documentation

Full documentation is at
[akshajbachu.github.io/biosqi](https://akshajbachu.github.io/biosqi/),
including the [methodology](docs/methodology.md), [indicator
definitions](docs/indicators.md), [validation protocol](docs/validation.md),
limitations, and API reference.

## Contributing

Contributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for
development setup and checks, and the [Code of Conduct](CODE_OF_CONDUCT.md).
Report security issues privately as described in [SECURITY.md](SECURITY.md).
Release history is in [CHANGELOG.md](CHANGELOG.md).

## Citation

If you use biosqi in research, please cite it. GitHub's **Cite this
repository** button (from [`CITATION.cff`](CITATION.cff)) provides APA and
BibTeX entries.

## License

biosqi is released under the [MIT License](LICENSE). Dataset licenses remain
with their original providers.
