Skip to main content

Step-by-step clinical ECG interpretation library

Project description

ecg-interpreter

A Python library for step-by-step clinical ECG interpretation.

Given a raw ECG signal (CSV, NumPy array, or PhysioNet WFDB file), the library extracts all clinically relevant parameters and produces a structured diagnosis — rate, rhythm, intervals, blocks, ischemia, and more.


Installation

pip install ecg-interpreter

For PhysioNet WFDB file support:

pip install "ecg-interpreter[wfdb]"

Quick Start

From a CSV file

from ecg_interpreter import ECGSignalProcessor, ECGInterpreter

processor = ECGSignalProcessor(sampling_rate=500)
params    = processor.process_csv("ecg.csv", signal_col="lead_II")

interpreter = ECGInterpreter()
result      = interpreter.interpret(params, patient_sex="male")

interpreter.print_full_report(result)

From a NumPy array

import numpy as np
from ecg_interpreter import ECGSignalProcessor, ECGInterpreter

signal = np.loadtxt("ecg_raw.txt")   # 1D array of voltage samples

processor = ECGSignalProcessor(sampling_rate=360)
params    = processor.process_array(signal)

interpreter = ECGInterpreter()
result      = interpreter.interpret(params)
interpreter.print_full_report(result)

From a PhysioNet WFDB record

import wfdb
from ecg_interpreter import ECGSignalProcessor, ECGInterpreter

# Download MIT-BIH record 100
wfdb.dl_database('mitdb', './data', records=['100'])

processor = ECGSignalProcessor()
params    = processor.process_wfdb('./data/100', channel=0)

interpreter = ECGInterpreter()
result      = interpreter.interpret(params)
interpreter.print_full_report(result)

Sample Output

════════════════════════════════════════════════════════════
  ECG INTERPRETATION
════════════════════════════════════════════════════════════
[Step 1] Heart Rate
  → Heart rate = 90 bpm
  → Normal Rate (90 bpm) ✓

[Step 2] Rhythm
  → RR mean = 666 ms, std = 5 ms, CV = 0.75%
  → Regular rhythm ✓

[Step 3] PR Interval
  → PR interval = 160 ms  (normal: 120–200 ms)
  → Normal PR (160 ms) ✓

[Step 4] QRS Duration
  → QRS duration = 80 ms  (normal: 60–100 ms)
  → Normal QRS duration (80 ms) ✓

[Step 5] QTc Interval
  → QTc = 420 ms  (threshold: ≤440 ms for male)
  → Normal QTc (420 ms) ✓

[Step 6] AV Blocks
  → No AV block detected ✓

[Step 7] Bundle Branch Block
  → No bundle branch block ✓

[Step 8] ST Segment & Ischemia
  → Mean ST level = +0.148 mV  (normal: -0.05 to +0.1 mV)
  → ST Elevation (+0.148 mV) 🔴 — STEMI suspect!
    Confirm with 12-lead ECG immediately

[Step 9] Other Patterns
  → No additional patterns detected ✓

[Overall] CRITICAL: STEMI
[Urgency] CRITICAL

════════════════════════════════════════════════════════════
  ECG INTERPRETATION SUMMARY
════════════════════════════════════════════════════════════
  Heart Rate   : 90 bpm
  PR interval  : 160 ms
  QRS duration : 80 ms
  QTc          : 420 ms
  ST level     : +0.148 mV
────────────────────────────────────────────────────────────
  Rate         : Normal Rate (90 bpm) ✓
  Rhythm       : Regular rhythm ✓
  PR           : Normal PR (160 ms) ✓
  QRS          : Normal QRS duration (80 ms) ✓
  QTc          : Normal QTc (420 ms) ✓
  AV Block     : No AV block detected ✓
  BBB          : No bundle branch block ✓
  ST/Ischemia  : ST Elevation (+0.148 mV) 🔴 — STEMI suspect!
  Other        : No additional patterns detected ✓
────────────────────────────────────────────────────────────
  OVERALL      : CRITICAL: STEMI
  URGENCY      : CRITICAL
════════════════════════════════════════════════════════════

Accessing Individual Fields

print(result.heart_rate)               # 90.0
print(result.rate_interpretation)      # "Normal Rate (90 bpm) ✓"
print(result.rhythm_interpretation)    # "Regular rhythm ✓"
print(result.pr_interpretation)        # "Normal PR (160 ms) ✓"
print(result.qrs_interpretation)       # "Normal QRS duration (80 ms) ✓"
print(result.qtc_interpretation)       # "Normal QTc (420 ms) ✓"
print(result.av_block)                 # "No AV block detected ✓"
print(result.bundle_branch_block)      # "No bundle branch block ✓"
print(result.st_interpretation)        # "ST Elevation (+0.148 mV) 🔴 ..."
print(result.stemi_flag)               # True
print(result.ischemia_flag)            # True
print(result.urgency)                  # "critical"
print(result.overall_interpretation)   # "CRITICAL: STEMI"
print(result.summary)                  # full formatted summary string

Normal Reference Ranges

Parameter Normal Range
Heart Rate 60 – 100 bpm
PR interval 120 – 200 ms
QRS duration 60 – 100 ms
QTc (male) ≤ 440 ms
QTc (female) ≤ 460 ms
ST level -0.05 to +0.10 mV

What It Detects

Rate

Finding Threshold
Severe Bradycardia < 40 bpm 🔴
Moderate Bradycardia 40 – 49 bpm ⚠⚠
Mild Bradycardia 50 – 59 bpm ⚠
Normal 60 – 100 bpm ✓
Mild Tachycardia 101 – 120 bpm ⚠
Moderate Tachycardia 121 – 150 bpm ⚠⚠
Severe Tachycardia > 150 bpm 🔴

Rhythm

Finding Detection Method
Regular RR CV < 10%
Mildly irregular RR CV 10–20%
Atrial Fibrillation RR CV > 20%
Atrial Flutter Regular rate ~150 bpm

Intervals

Finding Criteria
1st degree AV block PR > 200 ms
Short PR / WPW PR < 120 ms
Incomplete BBB QRS 100–119 ms
Complete BBB QRS ≥ 120 ms
Prolonged QTc QTc > 440/460 ms
Critical QTc QTc > 500 ms 🔴

AV Blocks

Block Detection Criteria
1st degree PR > 200 ms
2nd degree Mobitz II PR > 200 ms + dropped beats + slow rate
2nd degree Mobitz I (Wenckebach) PR > 200 ms + mildly irregular RR
3rd degree (Complete) HR < 45 bpm + wide QRS escape rhythm

ST Segment / Ischemia

Finding ST Level
Normal -0.05 to +0.10 mV
ST Depression / Ischemia ≤ -0.05 mV ⚠⚠
ST Elevation / STEMI suspect ≥ +0.10 mV 🔴

Other Patterns

Pattern Criteria
WPW Short PR (< 120 ms) + Wide QRS (≥ 120 ms)
Long QT Syndrome QTc > 440/460 ms
Short QT Syndrome QTc < 340 ms

Signal Processing Pipeline

Raw Signal
    ↓
Bandpass Filter (0.5 – 40 Hz)
    ↓
R-peak Detection (Pan-Tompkins)
    ↓
Fiducial Points (P, Q, S, T)
    ↓
Interval Calculation (PR, QRS, QT, QTc)
    ↓
ST Segment Measurement
    ↓
ECGParameters
    ↓
ECGInterpreter (9 steps)
    ↓
ECGResult

Key algorithms

Bandpass filter: 4th-order Butterworth (0.5–40 Hz)

  • 0.5 Hz highpass → removes baseline wander
  • 40 Hz lowpass → removes EMG and high-frequency noise

R-peak detection: Pan-Tompkins inspired

  • Differentiate + Square → amplifies steep QRS slopes
  • Moving window integration → smooths QRS complex
  • Adaptive threshold (50% of signal max) + 200 ms refractory period

QTc correction: Bazett formula

QTc = QT / √(RR in seconds)

A-a gradient (if PaO2 available):

PAO2 = FiO2 × (760 - 47) - PaCO2 / 0.8
A-a  = PAO2 - PaO2

CSV Format

The library accepts any CSV with at least one voltage column:

time,    lead_II
0.000,   0.12
0.002,   0.15
0.004,   0.23
...

If a time column is provided, the sampling rate is inferred automatically.


Supported Input Formats

Format Method Notes
NumPy array process_array(signal) Raw voltage samples
CSV file process_csv(path, signal_col) Any column name
PhysioNet WFDB process_wfdb(path, channel) Requires pip install wfdb

Requirements

  • Python ≥ 3.8
  • numpy ≥ 1.21
  • pandas ≥ 1.3
  • scipy ≥ 1.7

Optional:

  • wfdb ≥ 4.0 — for PhysioNet WFDB file support

Limitations

  • Designed for single-lead analysis. Multi-lead features (axis calculation, STEMI territory localization, LBBB vs RBBB morphology) require 12-lead input — planned for v0.2.
  • R-peak detection works best on clean signals. Very noisy or artifact-heavy recordings may need pre-processing.
  • This library is for research and educational purposes only. It is not a medical device and should not be used as the sole basis for clinical decisions.

Roadmap

  • v0.2 — 12-lead support (axis, STEMI territory, LBBB vs RBBB)
  • v0.3 — Anion Gap + Delta-Delta integration with ABG interpreter
  • v0.4 — ML-based arrhythmia classification (AF, VT, VF)
  • v0.5 — REST API wrapper

License

MIT

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

ecg_interpreter-0.1.0.tar.gz (19.7 kB view details)

Uploaded Source

Built Distribution

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

ecg_interpreter-0.1.0-py3-none-any.whl (16.0 kB view details)

Uploaded Python 3

File details

Details for the file ecg_interpreter-0.1.0.tar.gz.

File metadata

  • Download URL: ecg_interpreter-0.1.0.tar.gz
  • Upload date:
  • Size: 19.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.9

File hashes

Hashes for ecg_interpreter-0.1.0.tar.gz
Algorithm Hash digest
SHA256 8e8f8a6603ff7dde93e433a0fcd58b9b2be2f091f85a28c085caac1042cea1bd
MD5 f64682775073f4b47e7663133dd06700
BLAKE2b-256 0a88de4575dd6d7044ef070736b02c58db18ac3bce4d95e8f6036ddff6f6fa6e

See more details on using hashes here.

File details

Details for the file ecg_interpreter-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for ecg_interpreter-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9eec9933b52258b616fb31aafad17dab4568bef020ca33687bada4481fee1d90
MD5 ced25b78ccec0ca1ead434945097240a
BLAKE2b-256 059e1db5e1226b5705b754f9d4f4c040d5f809702cc1b0709c8606120ed7fe8a

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