MotionDex (inertial) · CPAPDex (therapy) nodes, Tepna physiological-signal suite
Problem. Validating a wearable respiratory algorithm requires a breath-by-breath reference. The accepted references — polysomnography with respiratory inductance plethysmography (RIP) belts, or a pneumotachograph — are lab instruments. Consequently almost every consumer-sensor respiratory algorithm is validated either on a handful of lab hours or not at all. Observation. Millions of people with sleep-disordered breathing sleep every night beside a machine that already records a calibrated 25 Hz flow signal to a removable SD card. A ResMed CPAP writes Flow.40ms (25 Hz, L/s) and Press.40ms into a standard EDF per session, alongside device-scored respiratory events. Contribution. A complete recipe for promoting that signal to a working reference standard: breath detection from the flow trace; an internal validation of the reference itself before anything is scored against it; and — the step that actually makes it usable — recovery of the clock relationship between an independent wearable and the CPAP, which is neither known nor stable. Results. On 26 nights (172 h) of co-recorded chest accelerometry, two independent flow-derived rate estimators (median-breath-period vs breath-count) agree to a median MAE 0.74 brpm (range 0.56–1.19 across nights), which we propose as the reference's own noise floor — no algorithm scored against it can honestly claim better. The wearable and CPAP clocks differed by ≈ −39.4 min, recovered by cross-correlating the band-passed accelerometer against flow: the correlation peak is ±4 s wide and ~5× the p95 noise floor. That offset drifts linearly at +0.589 s/day; a weighted fit predicts every night's offset with residual SD 1.03 s (max 2.12 s) over 37 days. Crucially, drift-consistency is a better validity test than correlation magnitude: four nights whose blind search returned weak correlation (r < 0.25) nevertheless landed within 0.0–3.2 s of the drift prediction, and a correlation gate would have discarded them as failures. Caveats. Single subject; the flow signal is leak- and pressure-dependent; and the therapy itself alters the physiology being measured, so this is a reference for algorithm agreement, not for untreated respiratory physiology.
Keywords: reference standard · CPAP · EDF · respiratory rate · wearable validation · clock synchronisation · Bland–Altman · n-of-1
To find out whether a fitness gadget measures your breathing correctly, you normally need a sleep laboratory. Almost nobody has one. But a lot of people do have a CPAP machine — and it turns out that machine is quietly recording a very good measurement of every breath you take, all night, onto a memory card.
This paper is the instruction manual for using that recording as your "truth" to test anything else. Two things turned out to matter more than expected. First, you must check how good the truth itself is before trusting it — we measure it two different ways and see how much they disagree (about 0.7 breaths per minute), which is the best any gadget could ever score. Second, the two devices' clocks disagree — by 39 minutes — and that gap slowly grows by about half a second per day. If you don't fix that, you are comparing one device's 2 a.m. to another's 1:20 a.m., and everything looks like noise.
A respiratory-rate algorithm without a reference standard is an opinion. The references the literature accepts are a pneumotachograph or spirometer [7], or thoracic/abdominal RIP belts scored during polysomnography [1,4,6]. Both are lab instruments, and the resulting validations are correspondingly small: Schipper et al. validated a chest accelerometer against RIP over ~90 min per subject in 20 healthy volunteers [1]; Ryser et al. managed 89.4 h across 12 subjects [4]; Doheny et al. used 11 clinical PSG nights [5].
Meanwhile, positive-airway-pressure therapy is delivered to a very large population by devices that continuously measure and record flow, because flow measurement is how the therapy works. A ResMed device writes, per session, a set of EDF files including BRP (Flow.40ms at 25 Hz in L/s, and Press.40ms), PLD (2 s summaries including the device's own RespRate.2s, Leak.2s, TidVol.2s), SA2 (oximetry, if attached) and EVE (EDF+ annotations carrying AASM-typed scored events). This is a calibrated respiratory signal, recorded nightly, for years, at home, at no marginal cost.
The obvious objection — that CPAP alters the physiology — is real but does not disqualify the signal as a reference for algorithm agreement. If the question is "does this wearable recover the breathing that actually happened", the flow signal answers it regardless of what is causing the breathing. The genuine difficulties are elsewhere: the reference's own error is unknown, and the two devices do not share a clock. This note addresses both.
Sessions are stored per night under a date-stamped directory; a night may contain several sessions (a mask-off interruption starts a new one). All are standard EDF: 256-byte header, per-signal headers, then 2-byte little-endian digital samples scaled by the physical/digital min–max pairs. The EVE file is EDF+ with time-stamped annotation lists (TALs) rather than sampled data, and must be parsed as such — a naive EDF reader divides by a zero record duration and fails.
RespRate.2s is available at 0.5 Hz and is tempting. Measured against breath-by-breath detection on the same file's raw flow, it agrees at only r = 0.05–0.43 per 60 s epoch, improving to r = 0.14–0.75 at 5–10 min blocks — i.e. it is a heavily smoothed, lagged estimate. It is a useful cross-check and a poor ground truth. Use the 25 Hz flow.Inspiratory onsets are positive-going zero crossings of the leak-corrected flow. Concretely: a 2nd-order Butterworth high-pass at 0.05 Hz (removes slow leak and baseline drift without touching breath periods of 1.5–10 s), then a 4th-order low-pass at 3.0 Hz (suppresses cardiogenic oscillation and turbulence), both applied forward–backward for zero phase. Positive-going zero crossings are then taken with a 1.0 s refractory period. Per-epoch rate is 60 / median(breath period) over a 60 s window requiring ≥4 breaths — the median makes it robust to a single missed or doubled breath, which a plain count is not.
This step is the one most often skipped, and it bounds every downstream claim. Two estimators are derived from the same flow signal but with different failure modes — (a) 60/median(period) and (b) a plain breath count over the epoch — and compared to each other. Agreement between them is an upper bound on the reference's precision.
The wearable (here, a Polar H10 logged by an Android phone) stamps phone civil time; the CPAP stamps its own RTC. Neither is disciplined to the other. The offset is recovered by cross-correlation: band-pass both the accelerometer channels and the flow to the respiratory band, project the accelerometer to its first principal component over a 20–25 min chunk, and scan the lag that maximises |r| over ±90 min at 1 s resolution. Because respiration is quasi-periodic, a spurious lag would produce a broad, low correlation ridge; a true lock produces a narrow spike. Three chunks per night vote.
The offsets are then modelled across nights as a linear drift, weighted by each night's correlation strength, and the fit is used to validate individual locks (§3.3).
Across all 26 nights the two independent flow-derived estimators agree at a median MAE 0.74 brpm (range 0.56–1.19; on three representative nights 0.69, 0.77 and 0.75, with r = 0.805, 0.792, 0.864). Breath-period distributions are tight and unimodal (median 3.60–3.68 s; IQR 3.20–4.08 s), and the fraction of consecutive-period ratios below 0.6 or above 1.67 — the signature of a doubled or missed detection — is 2.6–4.5%.
The waveform cross-correlation produces an unambiguous lock: peak |r| up to 0.89, a peak ±4 s wide, and a peak-to-p95 ratio of ~5 (the |r| distribution across 10,801 candidate lags has median 0.015, p95 0.044, max 0.218 on the weakest night tested). The recovered offset was −2365 s on 2026-06-06 and −2344 s on 2026-07-13, moving monotonically.
A correlation-weighted linear fit over the confidently-aligned nights gives +0.589 s/day, with residual SD 1.03 s and maximum residual 2.12 s across 37 days.
resp-acc-analysis.js, which correlates from the raw stream, gives the same slope (+0.791 s/day on its own fitted subset) but a residual SD of 6.87 s (max 16.65 s). The drift is real and reproducible; its precision depends on how the respiratory channel is built. Any validity tolerance must therefore be derived from the fitted residual (we use 3σ), never hardcoded — a fixed 5 s gate rejected 15 of 26 genuinely-good nights when applied to the noisier locks.Two independent facts make this convincing: the drift is monotone, which a spurious alignment would not be; and the residual is of the order of the epoch-boundary quantisation, not of the search range.
This is the practically important result. Four of 26 nights returned a weak blind-search correlation (r < 0.25) and would be discarded by a correlation-strength gate. Their recovered offsets nonetheless landed within 0.0, 0.2, 2.7 and 0.0 s of the drift-model prediction. Their locks were correct; the correlation was low because the respiratory signal was weak that night, which is a statement about the wearable, not about the alignment.
Applying the correlation gate would have removed 15% of the corpus for the wrong reason, and — worse — would have removed it non-randomly, biased toward the nights on which the algorithm under test performs worst.
The three ingredients that make CPAP flow usable are, in order of how often they are neglected: (1) measuring the reference's own error first; (2) recovering the clock relationship rather than assuming it; (3) validating each lock against a drift model rather than against a correlation threshold. None is specific to accelerometry or to ResMed — the same recipe applies to any wearable respiratory signal and any therapy device that logs flow.
The approach also yields, for free, a device-scored event list (EVE) with AASM types. That is a weaker label than expert PSG scoring — it is the manufacturer's algorithm — but it is nightly, longitudinal, and typed, which no lab study can be.
A single subject contributed all 26 nights, so the reference's noise floor is characterised on one respiratory pattern, one mask, one machine and one leak profile; the 0.70 brpm figure should be re-derived per setup rather than quoted. The flow signal is affected by mask leak, and although a leak channel is recorded, no leak-conditioned analysis was performed here. Therapy alters the physiology under measurement: rates observed are rates under positive pressure, so this reference cannot support claims about untreated breathing. The device-scored events are the manufacturer's algorithm rather than expert AASM scoring, and their central/obstructive discrimination in particular rests on forced-oscillation airway-patency testing whose accuracy is not independently established here. Finally, the clock drift was linear over 37 days on one phone–machine pair; longer spans, daylight-saving transitions or a device clock reset would each break the linear model, and the drift-consistency test would then correctly flag those nights rather than silently mis-aligning them.
All processing is local. Inputs are the unmodified ResMed EDF set and the wearable's raw logger output. The EDF reader, breath detector, reference-validation and drift-model steps are each independently runnable, and the reference-noise-floor figure is regenerated by comparing the two estimators on any night without reference to any wearable.
resp-acc-analysis.html, which runs the shipped MOTIONDSP.respiratoryRate rather than a reimplementation. It has been verified against the original harness on four nights: recovered clock offsets agree to within 8 s (−2365/−2373/−2351/−2361 s vs −2362/−2365/−2353/−2360 s) and per-night MAE to within 0.06 br/min (0.85/0.87/0.95/1.29 vs 0.91/0.82/1.01/1.35). What remains: the full 26-night corpus has not yet been re-run end-to-end through the tool, so the headline figures above still trace to the original harness. Until that regeneration is done and the figures are emitted into papers/figures/, this paper stays a DRAFT. See briefs/MOTIONDEX-RESPIRATORY-RATE-2026-07-21-BRIEF.md §4.Tepna is not a medical device and is not intended to diagnose, treat, cure or prevent any disease. Research and personal-analysis use only.