A faithful, numerically validated Python port of the KIT-IBT ECGdeli MATLAB ECG delineation toolbox
Project description
ecgdeli-py
A faithful, numerically validated Python port of ECGdeli (KIT-IBT) — the open-source ECG delineation toolbox for MATLAB. It covers the full filtering and processing pipeline: fiducial-point detection and wave delineation for P, QRS and T.
Unofficial community port. Not affiliated with, endorsed by, or maintained by KIT-IBT. The algorithms are theirs (see citation); the Python translation is independent. Please report issues with this port here — not against the upstream MATLAB repository.
import ecgdeli
filtered = ecgdeli.filter_ecg(signal, fs=1000) # band-pass → notch → isoline
ann = ecgdeli.annotate(filtered, fs=1000) # 1-D → single lead; 2-D (n, leads) → per lead
ann.n_beats # 197
lead = ann.leads[1] # per-lead FPT (0-based, indexes signal directly)
lead.r_peak, lead.qrs_on, lead.t_off, lead.p_on # np.ndarray[int] sample positions per beat
signal[lead.r_peak] # R-peak amplitudes — no ±1 shift needed
The figure above is produced by examples/annotate_example_ecg.py,
which filters, delineates, and plots ECGdeli's own bundled record using only the public API.
Status: stable (v1.0.0). The full filtering and P/QRS/T delineation pipeline, the 0-based
public API, and the p_morphology feature layer. Parity is validated bit-for-bit against MATLAB
R2026a across the corpus, and the delineation is validated clinically against the
QTDB and LUDB cardiologist annotations (see
docs/CLINICAL.md). The design decisions are in
docs/DESIGN.md and the full bug register in docs/PARITY.md.
What "faithful" means here
ECGdeli's MATLAB source contains dozens of real defects (B1–B48 in the register). This port replicates them bit-for-bit by default — that is what gives every result an objective MATLAB ground truth. Fixes are opt-in and individually documented:
ecgdeli.set_fidelity("matlab") # default: bug-for-bug compatible
ecgdeli.set_fidelity("fixed") # opt-in: documented corrections applied
Whether "fixed" is genuinely better is answered with evidence — delineation metrics against the
QTDB and LUDB cardiologist annotations in both modes (docs/CLINICAL.md).
The rationale is decision D1 in docs/DESIGN.md; the register is
docs/PARITY.md.
Indexing: the API is 0-based
signal[fpt.r_peak] works — that is the whole point. The subtlety is that 0 is ECGdeli's "not
detected" sentinel, so a naive −1 shift would turn it into -1, which NumPy reads as the last
sample: a loud failure quietly becomes a plausible number. The public FPT instead carries a
validity mask and safe accessors, and fpt.to_matlab() returns the raw 1-based table. See D4
and "Indexing and the FPT sentinels" in docs/DESIGN.md.
How it was validated
The port was validated bit-for-bit against ECGdeli MATLAB R2026a across the corpus and
clinically against QTDB/LUDB cardiologist annotations. The MATLAB generation rig has since been
retired; the permanent regression net is now a pure-Python characterization oracle — the
current pipeline output, frozen over one record per (db, fs) in both fidelity modes and
re-checked by tests/test_regression.py. Refresh it with make oracle. The committed Tier-1
goldens under tests/goldens/ remain as fast per-stage regression fixtures.
Quick start
git clone https://github.com/xdandys/ecgdeli-py
cd ecgdeli-py
uv sync
make ci # ruff + mypy --strict + pytest
Nothing above needs MATLAB or the network: the Tier-1 goldens and the example ECG the API tests
use (examples/data/) are committed.
Layout
The src/ecgdeli package layout (the faithful core/ transliteration, compat.py, fpt.py) is
documented in docs/DESIGN.md. The rest of the tree:
docs/
DESIGN.md the design decisions (D1, D3, D4, fidelity policy)
PARITY.md the bug register (B1-B48) and deviation log
CLINICAL.md the clinical-validation report
tools/
corpus.toml the human-reviewed corpus SPEC (which records, and why)
corpus.lock.toml the machine-written evidence (resolved IDs + SHA-256s)
freeze_oracle.py freezes the Python characterization oracle (the regression net)
examples/
data/ the bundled example ECG (ECGdeli's own `s0273lre` record)
The upstream ECGdeli MATLAB source is not vendored. The port was made from
KIT-IBT/ECGdeli at commit c3738612 (2025-05-27); clone it
separately if you want to cross-check against the original.
ecgdeli depends only on numpy, scipy and pywavelets. wfdb is a
dev dependency: it fetches the corpus and is never imported by the library.
Authorship
Most of this port was written by an AI model (Claude Opus 4.8), under human direction and review.
The parity gate and the docs/PARITY.md full-database comparison are how that work
was held to the MATLAB original.
License and citation
GPL-3.0-or-later, inherited from ECGdeli. The algorithms are KIT-IBT's — if you use this in research, please cite their paper:
Pilia N., Nagel C., Lenis G., Becker S., Dössel O., Loewe A. ECGdeli — An open source ECG delineation toolbox for MATLAB. SoftwareX 13:100639 (2021). doi:10.1016/j.softx.2020.100639
Test data is redistributed from open-access PhysioNet databases under ODC-BY 1.0
/ CC-BY 4.0; see tests/ATTRIBUTION.md.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ecgdeli-1.0.0.tar.gz.
File metadata
- Download URL: ecgdeli-1.0.0.tar.gz
- Upload date:
- Size: 587.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
056f8d8f3d1c30650587e5c9400b655785ed4a7e3e568a4d4f835c00990e4424
|
|
| MD5 |
131bf58e5a9904b2f6d0964524d0b458
|
|
| BLAKE2b-256 |
151beeab81e8a71fac12c77a149396e23fc87469391a279435dbc023571872f0
|
File details
Details for the file ecgdeli-1.0.0-py3-none-any.whl.
File metadata
- Download URL: ecgdeli-1.0.0-py3-none-any.whl
- Upload date:
- Size: 154.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
04bebb90706e548cb7944d38ded21f97ba36a6dce40363c5d9fe5ba1b9982d49
|
|
| MD5 |
255ed9d893c9af0db43da32592b90f31
|
|
| BLAKE2b-256 |
4d80764995450802406797a88dd97755089e887a22b7f65bf5ff04c0167b37ca
|