PulseDex · ECGDex · PpgDex nodes, Tepna physiological-signal suite
Background. The suite derives the same time-domain HRV metric, rMSSD, from three different inputs — recorded RR intervals (PulseDex), the raw ECG (ECGDex, Pan–Tompkins), and the optical pulse (PpgDex). Whether those numbers are interchangeable determines whether they can be pooled, substituted, or fused. Methods. On the FULL-lane waveform harness, one ~9-minute apnea-cluster window per synthetic patient (240 patients, 220 valid windows) was scored for rMSSD by all three production detectors on the same co-generated beats: PulseDex reads the ground-truth RR (the reference), ECGDex re-derives it from the raw int16 ECG at 130 Hz, and PpgDex from the 176 Hz optical pulse. We report pairwise Bland–Altman agreement. Results. ECGDex and PulseDex were statistically interchangeable: bias −0.02 ms (−0.04%), 95% limits of agreement −0.4…+0.3 ms, Pearson r 0.9999 [re-measured 2026-10-27: −0.011 ms, LoA −0.37…+0.35, r 0.9998 — reproduces] — two detectors sharing no code, signal, or sampling rate recover the identical tachogram, the 130 Hz + QRS-detection floor adding only ≈0.18 ms SD. PpgDex was biased high and several-fold noisier: bias +3.30 ms (+8.1%), limits −9.3…+15.9 ms (≈35× wider than the electrical floor), r 0.81 [re-measured 2026-10-27; the +0.3 ms / ≈22× / r 0.93 first published here is superseded, and the 2026-09-17 re-cut’s +7.8% / r 0.82 has drifted further]. The optical-only dispersion — the quadrature excess over the electrical floor — was ≈6.4 ms, i.e. essentially all of the PPG disagreement is pulse-arrival-time jitter, which inflates the scatter of the optical estimate and, on current code, also shifts its centre. Conclusion. RR- and ECG-derived rMSSD are interchangeable and may be pooled or cross-validated; optical rMSSD is neither: it runs ≈8% high with limits of agreement ≈35× wider, so an individual optical reading is both offset and materially less precise — it should be down-weighted (not equally averaged) in fusion, its offset reported rather than assumed away, and its per-window uncertainty carried through. Synthetic ground truth: this certifies cross-detector agreement and quantifies each modality's intrinsic dispersion — it is not a real-patient equivalence study.
Keywords: heart-rate variability · rMSSD · pulse-rate variability · photoplethysmography · QRS detection · Bland–Altman · pulse-arrival-time · method comparison · sensor fusion
The app calculates the same heart-rhythm score (“rMSSD”) from three different sources: a recorded list of heartbeat intervals, a raw ECG trace, and the optical (blood-flow) pulse. The question: are those three numbers the same number, so they can be mixed and matched?
Answer: the ECG and the interval-list agree almost perfectly — different code, different signal, yet essentially identical results, so they're interchangeable. The optical pulse was reported to land on the same average number — within about 1% — but that figure is SUPERSEDED: re-measured on 2026-10-27 the optical score runs about 8% high (+3.30 ms), and it has moved further in the same direction at each of the last three re-cuts. It is also much shakier reading to reading: the time it takes blood to reach your arm wobbles beat to beat, which spreads its score out — its beat-to-beat error band is roughly 35 times wider than the ECG’s. An earlier draft reported that a more realistically textured simulated rhythm stopped the optical score reading too high; on current code it reads high again, and why is not established here. The takeaway for the software: the optical heart-rhythm number is usable as an HRV estimate, but because a single reading is noisier, give it less weight when combining sensors and carry its wider uncertainty through. (Simulation with shared, known beats — it proves which detectors agree and why, not exact human magnitudes.)
rMSSD — the root mean square of successive RR differences — is the suite's workhorse short-term HRV metric, and three nodes compute it from three different front ends: PulseDex from a recorded RR series, ECGDex from the raw electrocardiogram, and PpgDex from the wrist/finger optical pulse. Downstream code routinely treats these as one number: pooling them across a cohort, substituting whichever is available, or fusing them into a single autonomic estimate. That is only valid if the three agree. Two of them recover beats electrically or from the interval stream; the third recovers them from a peripheral pressure wave whose timing, relative to the heartbeat, varies beat to beat (pulse-arrival-time, a function of blood pressure and vascular tone). rMSSD is by construction maximally sensitive to exactly that beat-to-beat timing jitter, so the optical estimate may not be interchangeable with the electrical ones even when both detectors are working perfectly.
We test interchangeability directly. Because all three detectors here score the same underlying beats, any disagreement is attributable to the front end — sampling rate, detector behaviour, or (for the optical arm) pulse-arrival-time jitter — rather than to different recordings. Bland–Altman quantifies the bias and the limits of agreement for each pair, and contrasting the optical pair against the electrical pair isolates the pulse-arrival-time component.
The FULL lane renders, per patient, one ~9-minute window centred on an apnea cluster, in each modality's native raw form, from one shared master event timeline — so the RR beat train is identical across modalities. PulseDex is given the window's ground-truth RR (artifact-cleaned) and serves as the reference. ECGDex re-derives beats from a raw int16 µV ECG at 130 Hz with its production Pan–Tompkins pipeline; the renderer places each R-peak at its true beat time, so detected R-to-R intervals equal the true RR up to 130 Hz quantization. PpgDex re-derives beats from the 176 Hz optical pulse with its production foot/peak detector. No detector parameters were altered; timestamps follow the suite Clock Contract. Each detector is loaded in its own realm (PulseDex in the shipped single-node harness; ECGDex and PpgDex in a FULL-lane worker) so the plain-global DSP files never share scope.
For each detector pair we compute Bland–Altman agreement on the per-window rMSSD: the mean difference (bias), its standard deviation, the 95% limits of agreement (bias ± 1.96 SD), the percentage bias relative to the reference mean, and the Pearson correlation. The optical-only dispersion is the quadrature excess of the PPG−Pulse standard deviation over the ECG−Pulse standard deviation, √(SD²₍PPG−Pulse₎ − SD²₍ECG−Pulse₎), which removes the sampling-plus-detection floor common to both and leaves the pulse-arrival-time component. The run reported here covers 240 sampled patients (220 valid windows with all three rMSSD values).
| Pair | n | Bias (ms) | Bias (%) | SD (ms) | 95% LoA (ms) | Pearson r |
|---|---|---|---|---|---|---|
| ECGDex − PulseDex | 220 | −0.011 | −0.03% | 0.18 | −0.37 … +0.35 | 0.9998 |
| PpgDex − PulseDex | 220 | +3.298 | +8.15% | 6.44 | −9.32 … +15.92 | 0.806 |
| PpgDex − ECGDex | 220 | +3.310 | +8.18% | 6.45 | −9.33 … +15.95 | 0.804 |
| Published 2026-07-07 optical values were +0.29 ms | +0.71% | SD 3.96 | −7.48 … +8.06 | r 0.925 (both optical rows), and the electrical row read −0.02 | −0.04% | −0.37 … +0.34 | r 0.9999 — see the 2026-10-27 revision note. PAT-jitter SD: 6.435 ms measured, ≈4.0 ms published. | ||||||
ECGDex and PulseDex agreed almost exactly: a bias of −0.02 ms (−0.04% of the reference mean), 95% limits of agreement of just −0.4 to +0.3 ms, and a Pearson correlation of 0.9999. These are two detectors that share no source code, no input signal (raw ECG vs an RR list), and no sampling model, yet they recover the identical tachogram; the 130 Hz sampling and the Pan–Tompkins detection together inject only ≈0.18 ms of beat-to-beat dispersion. RR- and ECG-derived rMSSD are, for practical purposes, the same number — they can be pooled across the two nodes and used to cross-validate one another.
qrs-equiv-analysis.html, synth-gen 2.1 / cohort-gen 1.9). Top: each detector's rMSSD vs the PulseDex reference — ECGDex (blue) lies on the identity line, PpgDex (amber) is drawn scattering symmetrically about it; as re-measured 2026-10-27 it sits systematically above the line again (+3.30 ms), so this panel does not reproduce either. Middle: Bland–Altman PpgDex − PulseDex — as rendered, bias +0.3 ms centred on zero with wide limits (−7.5…+8.1 ms). This panel NO LONGER REPRODUCES: the same tool on commit 39cfafdc4 measures +3.30 ms with limits −9.3…+15.9 ms (2026-10-27). The figure is an externally assembled composite with no recorded layout, so it was not regenerated. Bottom: Bland–Altman ECGDex − PulseDex on a much finer axis — a tight cluster on zero (±0.4 ms), the sampling-plus-detection floor. The ≈22× difference in limit width between the two panels is the optical-only dispersion. Dark theme is the tool's native rendering.PpgDex no longer agrees with the electrical detectors in the mean (it stands in the same relation to either arm, since those two agree with each other): a bias of +3.30 ms (+8.1%) and a correlation of 0.81, both re-measured 2026-10-27. Scatter separates it further: its 95% limits of agreement were −9.3 to +15.9 ms, roughly thirty-five times wider than the ECG–RR limits. The optical-only dispersion, after removing the sampling-plus-detection floor in quadrature, was ≈6.4 ms: essentially the entire PPG disagreement is pulse-arrival-time jitter. Beat-to-beat variation in how long the pulse takes to reach the periphery adds real per-beat timing noise to the optical inter-beat series that is absent from the electrical one; it widens the optical rMSSD distribution and shifts its centre upward. The “unbiased, variance-only” reading this section carried until 2026-09-17 is withdrawn as a current measurement; the three dated optical biases (≈+1%, +7.8%, +8.15%) are each retained as the measurement they were.
The practical rule is asymmetric. RR- and ECG-derived rMSSD are interchangeable: a fusion layer can treat them as one measurement, pool them, or use either to validate the other (the 0.9999 agreement is, in effect, a cross-node regression test for the HRV pipeline). Optical rMSSD is offset and weakly correlated on current code (bias ≈+8%, r 0.81, re-measured 2026-10-27), so it is usable as a trend estimate rather than as a substitute: it is not equivalent in centre or in precision, and its limits of agreement are ≈35× wider, so a single optical reading carries materially more uncertainty. In fusion it should therefore be down-weighted relative to an available electrical arm (weighted by its wider variance, not averaged in as an equal), and its per-window uncertainty propagated rather than discarded; and because the label matters, it should still be reported as pulse-rate variability. The earlier finding that the optical arm also mildly over-detects and loses beats under apnea (companion preprint, qrs-yield.html) adds a second, yield-driven error term on top of the PAT-jitter dispersion, so the electrical arm remains the clean HRV reference.
qrs-equiv-analysis.html → set patients → "Run cohort". The agreement scatter, both Bland–Altman panels, the headline cards and Table 1 populate live. Export rmssd-equivalence-results.csv (per-window), rmssd-equivalence-stats.json (pairwise), rmssd-equivalence-figures.png.pulsedex-dsp.js (parseRRInput → artifactClean → rmssd, in cohort-harness.html?node=pulsedex), ecgdex-dsp.js and ppgdex-dsp.js (analyze().rmssd, in the FULL-lane worker qrs-equiv-worker.js).SYNTH.pickWindow) of one cardiac night; ECG via cohort-full.js renderECGInt16 (R at true beat times), PPG via synth-gen.js renderPPG, the reference RR from SYNTH.buildRR in-window.Like its companion, this is a FULL-lane waveform pilot — raw ECG + optical rendered and scored per patient — so runtime, not statistics, is the constraint and 100k-scale is impractical. The agreement estimates (bias, limits of agreement, Pearson r) are per-window comparisons; their precision improves as ~1/√N_windows. Because the RR–ECG agreement is near-perfect and the optical precision penalty (its several-fold wider limits) is large, both conclusions are unmistakable at modest N.
| Tier | Patients | What it buys |
|---|---|---|
| Minimum (acceptable) | ~30 | Both verdicts clear: RR–ECG limits of agreement <±1 ms, optical bias ≈+8% with ≈35× wider limits. Pearson r stable to ≈±0.03. |
| Recommended | ~100–240 | Bland–Altman limits and r to ≈±0.01; clean three-panel agreement figure. This run used 240 (220 valid shared-beat windows). |
| This run | 240 | 220 windows with all three rMSSD values; RR–ECG r = 0.9999, optical r = 0.81 (2026-10-27). |
| Diminishing returns | > ~200 | The two limits-of-agreement bands are already separated by ~35×; more single windows only add FULL-lane hours. Greater value comes from varying autonomic state / window length than from more patients. |
Practical reading: ~30 patients to settle interchangeability, ~60–100 for tight published limits of agreement; beyond ~200 the FULL-lane cost dominates — vary autonomic state and window length rather than adding patients.
CLAUDE.md (Clock Contract, evidence-grade system), COHORT-VALIDATION-README.md, PAPERS-AND-FIXES-BRIEF.md, Tepna suite.qrs-yield.html (modality-asymmetric beat-yield), cgm-hrv-coupling.html (cross-node coherence), Tepna working preprint series.