streamsim.src.features.heart_rate module
R-Peak Detection and Heart Rate Calculation for ECG Signals
This module provides a streaming feature deriver that detects R-peaks in electrocardiogram (ECG) signals and calculates instantaneous heart rate. It implements a complete signal processing pipeline inspired by the Pan-Tompkins algorithm, adapted for real-time streaming applications.
- Signal Processing Pipeline:
Raw ECG → Bandpass Filter → Derivative → Squaring → Moving Average → Thresholding → Peak Detection
- Heart Rate Calculation:
Measures RR intervals between consecutive R-peaks
Computes instantaneous heart rate: HR = 60 / RR_interval (BPM)
Applies moving average smoothing over recent intervals for stability
Validates intervals against physiological bounds (30-220 BPM)
- Features:
Adaptive thresholding for robust peak detection in varying signal conditions
Refractory period enforcement to prevent double-counting peaks
Physiological validation of RR intervals
Configurable smoothing window for heart rate stability
Comprehensive state reset capability for multi-segment analysis
- Important Dependencies:
collections.deque: Efficient circular buffers for streaming data
streamsim.src.core.interfaces.StreamingFeatureDeriver: Base interface
Author: F.Feenstra with inspiration from Pan-Tompkins algorithm
Example
>>> from streamsim.src.features.heart_rate import HRFeatureDeriver
>>> deriver = HRFeatureDeriver(fs=360.0, threshold_factor=0.7)
- class streamsim.src.features.heart_rate.HRFeatureDeriver(fs: float = 360.0, min_rr_sec: float = 0.2, threshold_factor: float = 0.7, rr_window_size: int = 5, min_hr: float = 30.0, max_hr: float = 220.0)[source]
Bases:
StreamingFeatureDeriverFeature deriver that detects R-peaks in ECG signals and calculates heart rate.
- Signal Processing Pipeline:
Raw ECG → Bandpass → Derivative → Square → Moving Average → Threshold
- Heart Rate Calculation:
Measures RR intervals between consecutive R-peaks
Computes instantaneous heart rate: HR = 60 / RR_interval (BPM)
Optionally smooths using a moving average of recent intervals
- add_sample(sample: float, timestamp: float = None) None[source]
Process a new ECG sample through the detection pipeline.
Executes the full signal processing chain: bandpass filtering, differentiation, squaring, moving average integration, and adaptive thresholding. If an R-peak is detected, updates the heart rate calculation.
- Parameters:
sample (float) – The raw ECG signal sample value.
timestamp (float, optional) – Timestamp of the sample in seconds. If None, calculates based on sample count and fs. Default: None.
Note
The first ~200ms of data (depending on fs) will not produce valid detections as the buffers fill up. The get_heart_rate() method returns None until sufficient RR intervals are collected.
- get_features() Tuple[float | None, float | None][source]
Get both the peak timestamp and heart rate.
Convenience method for retrieving all derived features at once.
- Returns:
(peak_timestamp, heart_rate)
- Return type:
Tuple[Optional[float], Optional[float]]
- get_heart_rate() float | None[source]
Get the current heart rate in beats per minute (BPM).
The heart rate is calculated as a moving average of the last N RR intervals, where N is determined by rr_window_size.
- Returns:
Heart rate in BPM, or None if insufficient data.
- Return type:
Optional[float]