Signal Processing Pipeline
How a raw biosignal stream becomes time-aligned features.
This guide explains the DSP architecture - generic primitives, modality extractors, and how they compose. You don't need to know any of this to consume the output (see Getting Started), but it helps when reasoning about latency, fidelity, or extending the platform.
Pipeline at a glance
raw stream ─┐
├─► modality extractor ─► feature series ─► observations
device meta ─┘ (qmask attached) (FHIR-aligned)A waveform stream lands at the platform via the ingest endpoint. The platform routes the stream to the modality extractor that matches its signal type (ECG, PPG, etc.). The extractor produces one or more named feature series, each at its own cadence, each with a quality mask. Feature series are persisted as observations on the same biosignal catalog you query elsewhere.
Generic primitives
Modality extractors are built on a small set of generic primitives. These are reusable across signal types.
Butterworth filters
Zero-phase bidirectional Butterworth filters for both bandpass and lowpass. Zero-phase means the filter is applied forward and backward, so the output has no phase distortion - important when downstream stages do peak detection or alignment.
Typical bands:
- ECG: 5-20 Hz bandpass (isolates the QRS complex while suppressing baseline wander and high-frequency noise).
- PPG: 0.5-4 Hz bandpass (covers the cardiac component while rejecting respiration and motion).
Peak detection
Adaptive-threshold peak finder. The threshold tracks the local signal envelope, so it works across changing amplitudes (different subjects, electrode placements, perfusion levels). Used for R-peaks (ECG) and pulse feet (PPG).
A refractory period prevents double-counting: 400 ms for ECG, 250 ms for PPG. These map to physiological upper bounds on heart rate (~150 bpm and ~240 bpm respectively, leaving headroom).
Spectral analysis
FFT-based primitives for periodogram and band-power calculations. Used selectively where time-domain methods aren't appropriate (e.g., respiratory rate estimation from waveform modulation).
Modality extractors
A modality extractor is a pipeline that consumes one signal type and emits a fixed set of features.
ECG extractor
ECG (250-500 Hz)
→ Butterworth 5-20 Hz bandpass
→ Pan-Tompkins R-peak detection
→ R-R intervals
├→ hr_ecg (1 Hz)
├→ hrv_rmssd (0.2 Hz, 5s rolling window)
└→ hrv_sdnn_5min (0.2 Hz, 5min rolling window)Pan-Tompkins is the standard production algorithm for QRS detection. Output features are time-stamped at the centroid of their window, so they align cleanly with the original waveform.
PPG extractor
PPG (100-250 Hz)
→ Butterworth 0.5-4 Hz bandpass
→ Pulse-foot detection (adaptive peak finder, inverted)
→ Pulse-to-pulse intervals
├→ hr_ppg (1 Hz)
├→ prv_rmssd (0.2 Hz, 5s rolling)
└→ prv_sdnn_5min (0.2 Hz, 5min rolling)PPG pulse foot - the trough preceding the systolic upstroke - is the most stable fiducial under varying perfusion. Output structure mirrors ECG so the two can be cross-validated when both are available on the same subject.
Quality mask propagation
Every feature value carries a qmask byte (0 = good, 1 = suspect, 2 = bad). The mask is computed from:
- Per-sample QA events during ingest (lead-off detection, motion-artifact flags from the device).
- Window-level checks in the extractor (insufficient peaks, RR intervals outside physiological range, sustained signal noise).
Suspect or bad values are still emitted - downstream consumers can choose whether to filter them - but they're never silently dropped.
Output format
Every modality extractor emits one or more FeatureSeries:
type FeatureSeries = {
name: string; // unique per extractor (e.g., "hr_ecg")
ts_ns: number[]; // nanosecond timestamps
values: number[]; // feature values
cadence_hz: number; // output rate
qmask: number[]; // quality mask
};Plus optional event series (e.g., rpeaks, pulse_feet) - timestamped events without a continuous value. Useful for overlaying markers on a waveform plot.
Plus algorithm metadata recording the algorithm name, version, and parameters used for the run. This is what becomes method_code on the resulting observations.
Latency
The pipeline is windowed but streaming. End-to-end latency from a sample arriving at ingest to the corresponding feature value being available depends on the largest window the feature uses:
hr_ecg,hr_ppg(1 Hz): ~1-2 seconds.*_rmssd(5s window): ~5-7 seconds.*_sdnn_5min(5 min window): ~5-6 minutes after stream start; rolling thereafter.
Rolling windows continue to update at the cadence shown above once their warm-up period is complete.
Extending the pipeline
The catalog of biosignals and the set of modality extractors are intentionally extensible. New biosignals are added through the catalog; new extractors are wired into the platform when we onboard a new signal type. See Custom Algorithms for the customer-side perspective on running custom DSP against your streams.