An end-to-end electrophysiological signal processing and visualization platform. This project implements the classical Pan-Tompkins algorithm (1985) for real-time QRS complex detection from electrocardiogram (ECG) signals, coupled with dynamic heart rate variability (HRV) metrics, arrhythmia classification, and an interactive 3D cardiac conduction visualizer.
- 1. Overview
- 2. System Architecture
- 3. Methodology: Pan-Tompkins Algorithm
- 4. Clinical Metrics & Arrhythmia Analysis
- 5. Interactive 3D Cardiac Visualizer
- 6. How to Run the Project
- 7. API Reference
- 8. In-Depth Discussion & Engineering Trade-offs
- 9. References
Accurate detection of the QRS complex is the foundation for automated ECG interpretation, heart rate variability (HRV) tracking, and diagnosis of cardiac arrhythmias (such as ventricular tachycardia, fibrillation, or bundle branch blocks). The QRS complex represents electrical depolarization of the ventricular myocardium and constitutes the most prominent feature in a cardiac cycle.
This repository combines:
- Algorithmic Signal Processing Engine: A modular Python/FastAPI backend executing the multistage Pan-Tompkins filtering pipeline and real-time arrhythmia diagnostics on PhysioNet MIT-BIH Arrhythmia database records.
- Interactive Clinical Dashboard: A modern React + Vite frontend featuring dual signal inspection (raw, bandpass, derivative, squared, and integrated waves), real-time animated playhead, and a synchronized 3D cardiac conduction model powered by Three.js / React Three Fiber.
MIT-BIH Database (PhysioNet)
│
▼
┌─────────────────────────────────┐
│ FastAPI Backend (:8000) │
│ ─────────────────────────────── │
│ • DataLoader (WFDB) │
│ • Pan-Tompkins Pipeline │
│ • Metrics & Arrhythmia Engine │
└────────────────┬────────────────┘
│ REST API (JSON)
▼
┌─────────────────────────────────┐
│ React + Vite Client (:5173) │
│ ─────────────────────────────── │
│ • Interactive Stage Inspector │
│ • Dynamic Parameter Tuning │
│ • Synchronized Playback Engine │
│ • 3D WebGL Conduction Model │
└───────────────────────────────┘
-
backend/pan_tompkins/: Object-oriented implementation adhering to the Strategy pattern. Each filter (BandpassFilter,DerivativeFilter,SquaringFilter,MovingWindowIntegration) acts as an interchangeable strategy unified underPanTompkinsDetector. -
backend/data_loader.py: Automated download and caching of MIT-BIH recordings usingwfdb. -
backend/analysis.py: Extraction of RR intervals, time-domain HRV indices ($SDNN$ ,$RMSSD$ ), rhythm classification, and blood pressure estimation heuristics. -
frontend/src/: Interactive dashboard utilizing React 19, Plotly.js for high-fidelity waveform rendering, and React Three Fiber for spatial heart animations.
The Pan-Tompkins algorithm isolates QRS complexes by attenuating physiological and non-physiological noise (baseline wander from respiration, 50/60 Hz power-line interference, electromyographic / muscle artifacts, and tall peaked T-waves).
Raw ECG [x(n)]
│
▼
┌──────────────┐ Passband: 5 - 15 Hz
│ Bandpass │ ───► Attenuates baseline drift & high-frequency muscle noise
└──────┬───────┘
▼
┌──────────────┐ Filter: (1/8T) * [-x(n-2) - 2x(n-1) + 2x(n+1) + x(n+2)]
│ Derivative │ ───► Amplifies steep slopes of QRS complexes
└──────┬───────┘
▼
┌──────────────┐ Equation: y(n) = [x(n)]²
│ Squaring │ ───► Enforces non-linear amplification and positive polarity
└──────┬───────┘
▼
┌──────────────┐ Window width: ~150 ms
│ Moving-Window│ ───► Integrates energy; creates distinct unified pulses
│ Integration │
└──────┬───────┘
▼
┌──────────────┐ Adaptive thresholding & physiological refractory period (300 ms)
│ Peak Search │ ───► Aligns integrated peaks back to exact R-peaks in original signal
└──────────────┘
The energy of the QRS complex is primarily concentrated between 5 Hz and 15 Hz.
- Low frequencies (< 5 Hz) caused by respiratory baseline drift and P/T wave fluctuations are attenuated.
- High frequencies (> 15 Hz) corresponding to powerline interference, 60 Hz hum, and electromyographic (EMG) noise are eliminated. Implemented using a cascaded Butterworth bandpass filter.
To emphasize the steep slope of the QRS onset and downstroke over slower P and T wave transitions, a five-point central difference derivative filter is applied:
where
Pointwise squaring:
This non-linear transformation:
- Yields strictly positive values.
- Quadratically amplifies larger values (high derivative steepness from QRS complexes) relative to noise and residual T-wave peaks.
A moving average window accumulates energy information over the approximate duration of an average QRS complex:
Where
- If
$N$ is too narrow, a single QRS event could trigger multiple peaks. - If
$N$ is too wide, the QRS complex merges with the following T-wave.
-
Dynamic Threshold: The threshold adapts to local signal energy:
$$\text{Threshold} = \mu_{\text{integrated}} + 0.5 \times \sigma_{\text{integrated}}$$ -
Refractory Blanking Window: A minimum distance constraint (
$d_{\min} = 0.3 \times f_s$ , or 300 ms) guarantees the detector complies with human physiological refractory periods (preventing double detections up to 200 BPM). - Delay Correction & Fiducial R-Peak Mapping: The moving window introduces a phase delay. Candidate peaks in the integrated wave are back-propagated to the original raw ECG within a localized 150 ms window to isolate the exact maximum voltage point (the true R-peak).
Once the R-peak indices are isolated, consecutive differences define the RR interval series:
From
-
Heart Rate (HR):
$$\text{HR} = \frac{60}{\overline{RR}} \quad (\text{BPM})$$ -
Standard Deviation of NN intervals (
$SDNN$ ): Quantifies total autonomic variability over the recorded window.$$SDNN = \sqrt{\frac{1}{M-1} \sum_{i=1}^M (RR_i - \overline{RR})^2} \times 1000 \quad (\text{ms})$$ -
Root Mean Square of Successive Differences (
$RMSSD$ ): Reflects high-frequency vagal / parasympathetic modulation.$$RMSSD = \sqrt{\frac{1}{M-1} \sum_{i=1}^{M-1} (RR_{i+1} - RR_i)^2} \times 1000 \quad (\text{ms})$$ -
Automated Arrhythmia Classification:
-
Bradycardia: Mean
$\text{HR} < 60\text{ BPM}$ -
Tachycardia: Mean
$\text{HR} > 100\text{ BPM}$ -
Irregular Rhythm: Marked variance in RR intervals (
$SDNN > 100\text{ ms}$ )
-
Bradycardia: Mean
The frontend correlates the electrical time domain with anatomical electrophysiology:
- Playhead Tracking: Scrubbing or playing the ECG signal moves a 60 FPS playhead synchronized with the detected R-peaks.
- P-QRS-T Conduction Simulation: As the timeline advances through each detected cardiac cycle, the 3D heart model activates its myocardial chambers:
- Atrial depolarization (P-wave) -> SA to AV node delay.
- Ventricular depolarization (QRS) -> Bundle of His to Purkinje activation with chamber contraction impulse.
- Ventricular repolarization (T-wave) -> Myocardial relaxation.
- Python 3.10+ (Homebrew Python on macOS works seamlessly via the bundled virtual environment setup)
- Node.js 18+ and npm
- Git
The repository includes run_main.sh, which automatically builds an isolated Python virtual environment, installs backend and frontend packages, and boots both servers:
chmod +x run_main.sh
./run_main.sh- Backend API: http://localhost:8000
- Frontend Dashboard: http://localhost:5173
- Press
Ctrl + Cin the terminal to terminate both processes cleanly.
# Navigate to backend directory
cd backend
# Create and activate a virtual environment
# On macOS / Linux:
python3 -m venv venv
source venv/bin/activate
# On Windows (PowerShell):
# python -m venv venv
# .\venv\Scripts\Activate.ps1
# Install dependencies
pip install -r requirements.txt
# Start FastAPI server
python app.pyThe backend starts at http://localhost:8000.
# Navigate to frontend directory
cd frontend
# Install node packages
npm install
# Start Vite development server
npm run devOpen http://localhost:5173 in your web browser.
On Windows machines, double-click or run:
run_main.batReturns the list of available MIT-BIH Arrhythmia Database record IDs.
Sample Response:
{
"records": ["100", "101", "103", "105", "111", "119", "200", "212"]
}Executes the Pan-Tompkins pipeline and arrhythmia diagnostic engine on a specific record.
Request Payload:
{
"record_id": "100",
"window_size_ms": 150,
"lowcut": 5.0,
"highcut": 15.0
}Response Payload:
{
"record_id": "100",
"fs": 360,
"stages": {
"original": [...],
"bandpass": [...],
"derivative": [...],
"squared": [...],
"integrated": [...],
"peaks_integrated": [342, 701],
"peaks_original": [340, 698],
"threshold": 0.42
},
"analysis": {
"hr_bpm": 74.5,
"rmssd_ms": 28.4,
"sdnn_ms": 35.1,
"abnormalities": ["Normal Sinus Rhythm"],
"simulated_bp": "112/71 mmHg (Est.)",
"rr_intervals_ms": [805.5, 810.0]
}
}- Computational Efficiency: The Pan-Tompkins algorithm relies exclusively on finite impulse response (FIR) / infinite impulse response (IIR) filtering, integer-friendly differentiation, squaring, and moving-average convolutions. It delivers sub-millisecond execution times without needing heavy neural networks, making it ideal for battery-powered wearable Holter monitors and embedded microcontrollers.
- Noise Rejection: The tandem of bandpass filtering and window integration makes the detector remarkably resilient to respiratory wander and high-frequency muscle trembling.
- Morphological Variability: In patients with severe bundle branch block (BBB) or premature ventricular contractions (PVCs), the QRS complex may be abnormally wide and biphasic. The fixed 150 ms integration window can split wide complexes into multi-peak outputs.
-
Fixed vs. Adaptive Thresholding: The baseline threshold used in this implementation is computed across the 10-second window (
$\mu + 0.5\sigma$ ). In clinical Holter environments with non-stationary background noise, Pan & Tompkins' original dual dual-threshold system (which dynamically updates separate signal peakSPKIand noise peakNPKIregisters beat-by-beat) offers superior noise tracking. - Deep Learning Comparison: While modern Transformer (e.g., 1D-CNN + BiLSTM) models achieve slightly higher F1-scores on complex multi-lead arrhythmia benchmarks, Pan-Tompkins remains the clinical baseline due to its full interpretability, deterministic behavior, and zero training overhead.
- Pan, J., & Tompkins, W. J. (1985). A Real-Time QRS Detection Algorithm. IEEE Transactions on Biomedical Engineering, BME-32(3), 230–236.
- Moody, G. B., & Mark, R. G. (2001). The impact of the MIT-BIH Arrhythmia Database. IEEE Engineering in Medicine and Biology Magazine, 20(3), 45–50.
- Goldberger, A. L., et al. (2000). PhysioBank, PhysioToolkit, and PhysioNet: Components of a new research resource for complex physiologic signals. Circulation, 101(23), e215–e220.
- Abid Mahbub Bari
- Shadman Shahriar Shuvo