Skip to content

The Science

NoopApp edited this page Jun 10, 2026 · 1 revision

The Science

NOOP computes recovery, strain, HRV, and sleep locally on your device using transparent, published physiological methods. Every metric is an approximation of common exercise-science and cardiology literature — not a reproduction of any proprietary algorithm, and not a medical device or medical advice.

Not affiliated with WHOOP. NOOP is independent interoperability software for your own device and your own data. The methods described here are grounded in peer-reviewed literature and are the same class of tools used in sports-science research labs — they are estimates, not clinical measurements. Do not use them to diagnose, treat, or make health decisions. Consult a qualified professional.


Overview: The analytics pipeline

All mathematics in NOOP is pure, deterministic, and database-free: same inputs always produce the same outputs, which makes every analyzer straightforward to unit-test. The analytics live in the cross-platform StrandAnalytics Swift package, and they run on-device against:

  • Live BLE streams (heart rate, R-R intervals, respiration, gravity/accelerometer) arriving from the strap in real time.
  • Imported history from WHOOP CSV exports and Apple Health exports.
  • Historical offload from the strap's on-device store (~14 days) each time you connect.

The computed metrics are persisted in SQLite under the "<deviceId>-noop" source, but WHOOP's own imports (when you import a CSV) always take precedence — NOOP's approximations win only for data WHOOP doesn't cover.


Heart-Rate Variability (HRV)

RMSSD — the root-mean-square of successive differences

HRV is the beat-to-beat variation in your heart rate, measured as R-R intervals (the time between consecutive heartbeats in milliseconds). NOOP computes RMSSD — the classic Task Force (1996) metric:

RMSSD = sqrt( (1/(N-1)) · Σ(NN[i+1] − NN[i])² )

Where NN is a sequence of normal R-R intervals (in ms), and each term is the squared difference between consecutive intervals.

Why RMSSD? It captures the parasympathetic tone (vagal activity) of your autonomic nervous system — the "rest and digest" branch that keeps you calm and recovered. Higher RMSSD means more variability, which usually correlates with better recovery and lower stress.

Cleaning: removing noise and ectopic beats

Raw R-R data can contain artifacts — missed beats, extra beats (ectopics), electrical noise. NOOP applies a deterministic cleaning pipeline:

  1. Range filter — drop intervals outside the plausible [300, 2000] ms band (~30–200 bpm).
  2. Ectopic rejection (Malik et al., 1989) — drop any beat deviating more than 20% from a local median over a 5-beat centered window. This is a simpler substitute for the Kubios algorithm (which isn't available on-device) and catches physiologically impossible jumps.
  3. Sufficiency gate — require at least 20 clean intervals before returning a result; otherwise return nil rather than guessing.

Honest substitution: The reference method used neurokit2's Kubios/Lipponen–Tarvainen artifact classifier, which requires external Python libraries. NOOP substitutes the classical Malik local-median rule — fully deterministic, works on-device, and achieves the same intent: removing impossible beat-to-beat swings before computing HRV.

Other HRV metrics

  • SDNN — the sample standard deviation of NN intervals (Task Force 1996). A broader measure of variability over the whole recording.
  • pNN50 — the percentage of successive differences > 50 ms. A marker of parasympathetic dominance.

Recovery Scoring

The 0–100 composite

NOOP's recovery score is an HRV-dominant, baseline-normalized composite that blends several drivers into a single 0–100 number. It is explicitly approximate — the key insight is that recovery is personal: your good recovery looks different from someone else's, so comparing you to yourself matters more than comparing to a population average.

Driver Direction Weight
HRV vs your baseline Higher → better recovery 60% (dominant)
Resting HR vs your baseline Lower → better 20%
Respiration rate vs your baseline Lower → better 5%
Sleep performance Better sleep → better recovery 15%

Baseline normalization: z-scores

Each metric is standardized against your personal baseline using a robust z-score:

z = (value − mean) / (1.253 · spread)

The 1.253 factor converts an EWMA mean-absolute-deviation (MAD) into an approximate Gaussian standard deviation (E[|X−μ|] ≈ σ / 1.253). For "lower is better" metrics (resting HR, respiration), the z is inverted so high values still push recovery down.

Sleep performance is centered directly: (sleepPerf − 0.85) / 0.12 — anchoring on 85% efficiency as a typical target.

The logistic squash to 0–100

The weighted-mean z-score is then squashed to 0–100 with a logistic curve:

score = 100 / (1 + exp(−k · (z − z0)))
  where k = 1.6, z0 = −0.20

The z = 0 point (your personal baseline, across all metrics) maps to approximately 58% — matching WHOOP's published population-average recovery. This anchoring means: when your HRV, RHR, and respiration are all exactly at your typical baseline, your score is ~58%, not 50%. Z = +2 drives toward 95%; Z = −2 drives toward 5%.

Bands

Band Range
Red (needs recovery) < 34
Yellow (balanced) 34–67
Green (ready to push) ≥ 67

Cold-start: when you don't have a baseline yet

If your HRV baseline isn't trustworthy yet (fewer than 4 valid nights), NOOP returns nil rather than a fabricated number. This is intentionally honest — more painful than a guess, but more truthful. Callers can fall back to the population mean (58%), but the screen flags it as provisional.

Once you have 4+ nights, the baseline becomes "provisional" (4–13 nights), then "trusted" (14+).


Strain Scoring

The 0–21 cardiovascular load scale

Strain is the cumulative physiological load from exercise during a day. NOOP uses a published, scalable method: the Heart-Rate Reserve (Karvonen) intensity model combined with TRIMP (Training Impulse) accumulation, mapped to a 0–21 logarithmic scale.

Step 1: Heart-Rate Reserve (HRR)

HRR = HRmax − Resting HR
%HRR = (HR − RHR) / HRR × 100, clamped [0, 100]

This expresses your current heart rate as a fraction of your reserve — what percentage of your maximum capacity you're using right now.

Step 2: TRIMP accumulation

NOOP supports two methods; the default is Edwards (1993):

Edwards 5-zone summation (default)

Each heart-rate sample contributes its zone weight multiplied by duration:

Zone %HRR range Weight
Zone 1 < 50% 1
Zone 2 50–60% 2
Zone 3 60–70% 3
Zone 4 70–80% 4
Zone 5 ≥ 80% 5
TRIMP = Σ(duration_in_zone × weight)

Banister exponential (alternative)

An older but well-cited model: duration × x × 0.64 × e^(b·x) where x = %HRR/100 and b = 1.92 (men) or 1.67 (women).

Step 3: Logarithmic compression to 0–21

strain = 21 · ln(TRIMP + 1) / ln(D)
  where D = 7201

The denominator D is calibrated so that the Edwards daily ceiling — maximum zone weight (5) sustained for 24 hours = 5 × 1440 = 7200 — maps to exactly 21.0. This makes 21 a true physiological ceiling for the day: you'd need to stay in zone 5 all night to reach it.

HRmax estimation

NOOP estimates your maximum heart rate using two methods:

  • Observed (if you have ≥600 HR samples on record): the 99.5th percentile of your recorded HR, used as the starting point.
  • Tanaka (2001): HRmax = 208 − 0.7 × age. A gender-independent population estimate that serves as a floor — if Tanaka is higher than your observed max, Tanaka is used (to avoid underestimating if you haven't hit your true max yet).
  • Manual override: you can set your own max HR in Settings.

If you supply no age and have no data, the scorer returns nil.


Sleep Staging

The 4-class hypnogram

NOOP detects sleep/wake and attempts to classify four stages: Wake, Light, Deep (slow-wave), and REM (rapid eye movement). This is the same classification used in clinical sleep studies, but without EEG — the ceiling for 4-class accuracy (without brain waves) is ~65–73% epoch-by-epoch agreement (Walch et al., 2019).

Honest hedging: These stages are approximations, not validated against polysomnography (PSG, the clinical gold standard). Light/deep separation is the weakest link. Deep-minute estimates are the least reliable output. Use these trends over time, not individual-night predictions.

Stage 0: Gravity-based sleep/wake spine

The foundation is stillness. NOOP tracks the magnitude of gravity changes (accelerometer) and identifies periods where motion is minimal:

  1. Per-sample motion proxy = L2 norm of the gravity-vector change from the previous sample.
  2. A sample is "still" if this delta is < 0.01 g.
  3. Roll forward in a 15-minute window: if ≥70% of samples are still, the center is marked "sleep".
  4. Contiguous still runs ≥60 minutes (merging gaps < 15 min) are candidates.
  5. HR confirmation: the run's mean HR must be ≤1.05× the day's median HR (the sleep baseline). This rejects false sleep from long stillness at rest.

Additionally, NOOP computes the te Lindert 30-second Cole–Kripke sleep index per epoch as a cross-check:

SI = 0.001 · Σ w_i · A_i    (sleep iff SI < 1)
weights = [106, 54, 58, 76, 230, 74, 67]

(This is a classical 7-channel electroencephalographic index adapted for actigraphy.)

Stage 1: Cardiorespiratory features per 30-second epoch

Over a rolling 5-minute window, NOOP extracts:

  • Mean heart rate — averaged over the window.
  • HR variability (Walch difference-of-Gaussians) — two Gaussian convolutions of HR (σ = 120 s and 600 s) subtracted; this captures medium-scale HRV oscillations.
  • RMSSD and SDNN — computed from range-filtered R-R intervals (cleaned via HRVAnalyzer).
  • Respiration rate and RRV — extracted from the raw 1 Hz respiration channel via a peak detector (detrend → find local maxima ≥2 s apart → bin into breath intervals 1.5–12 s → median interval → rate = 60 / interval).

Omission: Frequency-domain HRV (high-frequency HRV, LF/HF ratio) is not computed because FFT and signal processing require libraries unavailable on-device. The parasympathetic-tone signal is RMSSD only. The respiration peak-finder is a faithful port of the reference method (which also avoided scipy).

Stage 2: Percentile-band classifier

The session's sleep-period epochs (Cole–Kripke = sleep) define reference distributions for each feature. Each epoch is then classified by comparing its features to these percentiles:

Class Rule
Wake Sustained motion (≥15% of epoch) AND activated cardiac (high HR or high DoG-HR), OR no HR data
Deep Still (≤10% motion) AND high parasympathetic tone (RMSSD ≥70th percentile) AND low HR (≤25th percentile) AND regular respiration
REM Still body AND activated cardiac AND irregular respiration (RRV ≥65th percentile); fallback requires both cardiac signals if respiration is unavailable
Light Everything else (the default)

Stage 3: Smoothing and physiology re-imposition

  1. 5-epoch median smoothing of the label sequence — smooths out single-epoch noise.
  2. No REM in the first 15 minutes — REM sleep doesn't appear right at sleep onset; demote to light.
  3. No deep after the first third — deep sleep is front-loaded; demote later deep epochs to light.
  4. Force pre-onset and post-final-wake to wake.

Consecutive same-stage epochs are merged into segments tiling the session.

Outputs

  • SleepSession: start, end, in-bed efficiency (asleep / in-bed), per-session resting HR, average HRV (RMSSD over 5-min windows), and a reconstructed hypnogram (stage durations).
  • AASM-style roll-up: time-in-bed (TIB), total sleep time (TST), sleep-period time (SPT), sleep onset latency (SOL), REM latency, wake after sleep onset (WASO), efficiency, disturbances, and deep/REM/light minutes.

Baselines: Your personal rolling averages

Recovery and strain scoring depend on personal baselines — your own typical HRV, resting HR, and respiration — so NOOP learns them as you wear the strap. Two interchangeable approaches produce the same result:

Winsorized EWMA (production)

A robust, recency-weighted center with exponential-moving-average spread tracking:

  • Half-life → smoothing factor: HRV center uses 14-night half-life; spread uses 21-night (slower, more conservative).
  • Sanity gate: values outside the per-metric range (e.g., HRV 5–250 ms) are skipped and held.
  • Hard outlier rejection: values > 5× spread away are recorded but not folded into the baseline.
  • Winsor clamp: fold only within ±3× spread of the current baseline, so a single exceptional night can't yank the center. The spread itself uses the unclamped deviation so real physiological change is still tracked.
let clamped = max(lo, min(hi, value))                    // ±3·spread
let newBaseline = lb * clamped + (1 - lb) * state.baseline
let newSpread   = max(floorSpread, ls * abs(value - newBaseline) + (1 - ls) * state.spread)

Trailing-window mean (auditable alternative)

Plain mean and sample SD (ddof = 1) over the last 30 valid nights. The σ floor is applied and converted back to absolute-deviation space so the two methods recover the same Gaussian σ.

Baseline status lifecycle

Status Condition
calibrating Fewer than 4 valid nights (no score yet)
provisional 4–13 valid nights (usable, higher uncertainty)
trusted 14+ valid nights
stale Trusted but no update for > 14 days

Workouts and Exercise Detection

Automatic detection from HR and motion

NOOP detects exercise periods without manual logging — a sustained window (≥5 minutes) where both gates hold:

  1. Elevated HR: above RHR + 15 bpm (the resting HR of your session + margin).
  2. Sustained motion: gravity-derived intensity (10-second trailing mean) above 0.20.

Active samples are grouped into runs, merged if gaps are < 150 seconds, then qualified: ≥50% of the bout must be in Edwards zone 2+ to count.

Metrics per bout

Per workout, NOOP reports:

  • Average and peak heart rate.
  • Duration, Edwards zone distribution, mean %HRR.
  • Strain (computed via the same StrainScorer as daily strain).
  • Calories (see below).

Calories: Keytel + revised Harris–Benedict

Per-second blend with sex-specific coefficients:

  • Below RHR + 0.30 × HRR: use revised Harris–Benedict (resting metabolic rate).
  • Above: use Keytel (2005) active expenditure model, sex-specific.

The blend provides a smooth transition. Approximate — not laboratory calorimetry.


Interactive: Correlations, Behavior Effects, and Comparisons

NOOP provides three on-device interrogation engines for your own data:

Correlation analysis (Pearson r)

r = Σ(x−x̄)(y−ȳ) / sqrt( Σ(x−x̄)² · Σ(y−ȳ)² )
slope = Σ(x−x̄)(y−ȳ) / Σ(x−x̄)²
t-statistic = r · sqrt( (n−2) / (1−r²) )
p-value ≈ 2·(1 − Φ(|t|))    [normal approximation]
  • Returns nil for fewer than 3 pairs or zero variance.
  • The normal approximation slightly understates p for small n (true Student-t tails are heavier), but is fully deterministic on-device.
  • Supports lagged correlations (e.g., today's strain vs tomorrow's recovery) via day-aligned and shifted series.

Behavior effects (Welch t-test)

Splits days where you logged a behavior (Alcohol, Meditation, etc.) from days you didn't, and compares an outcome (Recovery, HRV, Sleep) between groups:

sp = sqrt( ((n1−1)·s1² + (n2−1)·s2²) / (n1+n2−2) )     [pooled SD]
d = (m1 − m2) / sp                                      [Cohen's d]
t = (m1 − m2) / sqrt(s1²/n1 + s2²/n2)                  [Welch t]
  • significant requires p < 0.05 and min(nWith, nWithout) ≥ 5 (guards against spurious significance from a handful of days).
  • Results are ranked by effect size (|d|), significant findings first.
  • Plain-English summary: "On days you logged 'Alcohol', Recovery was 12% lower (avg 61 vs 69, n=140 vs 498)."

Period comparison

Month-over-month, quarter-over-quarter, or custom window comparison of a single metric:

SeriesStat: mean, median, min, max, sample SD (ddof=1), n, and OLS slope-per-day
PeriodComparison: signed delta, % change, direction (-1/0/+1)

Advanced: Readiness and Training Load

NOOP's Readiness screen synthesizes several sports-science signals from your own history into a single readout ("Primed / Balanced / Strained / Run down"):

Drivers

  • HRV vs baseline (Plews/Buchheit) — parasympathetic tone shift.
  • Resting-HR drift (Lamberts) — orthostatic stress rising.
  • Respiratory-rate drift — autonomic load indicator.
  • Acute:chronic workload ratio (ACWR) (Gabbett) — training volume balanced against your typical load.
  • Training monotony (Foster) — variability of your training over the past week.

All signals are z-scored against your own baselines and combined with a logistic curve into a single readiness band. Approximate, not medical advice — this is the same class of analysis used in sports-science labs for coaching, not a clinical screen.


Illness and Strain Early-Warning

NOOP watches for the classic early-illness/elevated-strain signature on-device by comparing your last ~2 days against a ~28-day baseline (ending 3 days ago, to avoid contamination):

Signal Baseline shift Anomaly condition
Resting HR ↑ Elevated Recent mean ≥ baseline mean + 5 bpm
HRV ↓ Depressed Recent mean ≤ baseline mean × 0.80 (−20%)
Skin temp ↑ Elevated Recent mean deviation ≥ +0.6 °C
Respiration ↑ Elevated Recent mean ≥ baseline mean + 1.5 bpm

A banner appears only when two or more anomalies fire together (e.g., RHR up + HRV down + skin-temp up), the classic early-illness signature. Requires at least 14 days of history.

Important: This is a wellness nudge from your own baselines, not a clinical screen. It is informational only — not medical advice, not a diagnosis.


Design principles & honesty notes

Approximate by design

Every metric — recovery, strain, sleep stages, workout intensity, calories — is an explicit approximation of published methods. The source code documents exactly where it substitutes (Malik local-median instead of Kubios, RMSSD-only parasympathetic tone instead of frequency-domain HRV, normal-approximation p-values instead of Student-t tabled values).

Deterministic and testable

No randomness, no wall-clock dependence inside the math, no database access. Same inputs always produce the same outputs, making the whole package unit-testable against fixed vectors.

Robust statistics

  • Z-scores use EWMA mean-absolute-deviation (×1.253 to Gaussian σ); rounding resistant.
  • Resting HR uses 5-minute bin minima; single-beat dips are rejected.
  • Heart-rate display uses windowed medians; outliers don't spike the plot.
  • Baselines use Winsor clamping; a single exceptional night doesn't yanked the center.

Cold-start honesty

When a baseline isn't trustworthy yet, the scorer returns nil rather than a fabricated number. More painful than guessing, but more truthful.

Not a medical device, not medical advice

None of this is diagnostic or medically actionable. HRV, recovery, strain, sleep stages, and the illness early-warning are wellness approximations, not clinical measurements. Consult a qualified professional for health decisions.


References and further reading

The methods implemented in NOOP draw from peer-reviewed literature:

  • Task Force (1996). Heart rate variability: standards of measurement, physiological interpretation and clinical use. Circulation, 93(5), 1043–1065.
  • Karvonen, M. J. (1957). Effects of vigorous exercise on the heart. Work and Stress, 9, 3–9.
  • Edwards, S. (1993). The heart rate monitor book. Polar Electro (Oy).
  • Banister, E. W. (1991). Modeling elite athletic performance. In Physiological testing of the high-performance athlete (pp. 403–424). Human Kinetics.
  • Tanaka, H., Monahan, K. D., & Seals, D. R. (2001). Age-predicted maximal heart rate revisited. Journal of the American College of Cardiology, 37(1), 153–156.
  • Keytel, L. R., et al. (2005). Prediction of energy expenditure from heart rate monitoring during submaximal exercise. Journal of Sports Sciences, 23(3), 289–297.
  • Walch, O., et al. (2019). Sleep stage prediction with raw acceleration and photoplethysmography heart rate data derived from a consumer wearable device. Sleep, 42(12), zsz180.
  • Plews, D. J., Laursen, P. B., & Buchheit, M. (2017). Training adaptation and heart-rate variability: A systematic review. Sports Medicine, 47(8), 1521–1538.
  • Gabbett, T. J. (2016). The training-injury prevention paradox: should athletes be training smarter and harder? British Journal of Sports Medicine, 50(5), 273–280.
  • Foster, C., et al. (1995). A new approach to monitoring exercise training. Journal of Strength and Conditioning Research, 12(3), 109–115.

See also

Clone this wiki locally