Metadata-Version: 2.4
Name: ecg-interpreter
Version: 0.1.0
Summary: Step-by-step clinical ECG interpretation library
License: MIT
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Requires-Dist: numpy>=1.21
Requires-Dist: pandas>=1.3
Requires-Dist: scipy>=1.7
Provides-Extra: wfdb
Requires-Dist: wfdb>=4.0; extra == "wfdb"

# 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

```bash
pip install ecg-interpreter
```

For PhysioNet WFDB file support:
```bash
pip install "ecg-interpreter[wfdb]"
```

---

## Quick Start

### From a CSV file
```python
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
```python
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
```python
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

```python
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
