Skip to main content

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.

ECGdeli delineation of the bundled record, lead II — P/QRS/T peaks as dots, on/off boundaries as dashed lines

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ecgdeli-1.0.0.tar.gz (587.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ecgdeli-1.0.0-py3-none-any.whl (154.5 kB view details)

Uploaded Python 3

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

Hashes for ecgdeli-1.0.0.tar.gz
Algorithm Hash digest
SHA256 056f8d8f3d1c30650587e5c9400b655785ed4a7e3e568a4d4f835c00990e4424
MD5 131bf58e5a9904b2f6d0964524d0b458
BLAKE2b-256 151beeab81e8a71fac12c77a149396e23fc87469391a279435dbc023571872f0

See more details on using hashes here.

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

Hashes for ecgdeli-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 04bebb90706e548cb7944d38ded21f97ba36a6dce40363c5d9fe5ba1b9982d49
MD5 255ed9d893c9af0db43da32592b90f31
BLAKE2b-256 4d80764995450802406797a88dd97755089e887a22b7f65bf5ff04c0167b37ca

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page