How it's wired GanglioR
← the -Dex suite · validation & analysis

🔬Experiments

The experiments run the real Dex detectors headless, at scale, on synthetic (and optional real) data — to validate them and produce the papers’ figures. The trick that makes it possible: each node’s plain-global DSP collides on shared names, so each runs in its own iframe realm and answers over postMessage.

Kind
validation harness + analysesreal DSP, headless
Realm trick
per-node iframecohort-harness.html?node=
Parallelism
Web Workersby node-kind
Output
figures + sample-size+ pass/fail gate
01 — WHAT IT’S FOR

Validate the real detectors at scale

A spot-check on one file proves little. The experiments push thousands of synthetic patients through the actual shipped DSP — not a reimplementation — to measure how the detectors behave across severity, age, artifact and missingness, and to fit the corrections the papers report.

🧩
The iframe-realm trick. The node DSP files are plain globals that collide on parseCSV / parseTimestamp / mean / std. So each node loads in its own cohort-harness.html?node=… iframe (one realm, one node), exposing runNode(payload) over postMessage — real DSP, zero global clash.
02 — THE WIRING

The file stack

One realm per node, fanned across CPU cores by workers, scored on the main thread. The analysis tools sit on top of the same harness.

Engine
cohort-harness.htmlNode realm
A single-node real-DSP iframe, parameterized by ?node=oxydex|pulsedex|glucodex. Loads only that node’s real modules, then exposes runNode(payload) → minimal ganglior.node-export over postMessage.
Core
cohort-gen.jsPatient source
The seeded synthetic-patient sampler (see SynthGen) — pure, runs fine off-DOM inside a worker.
nsrr-adapter.jsReal-PSG bridge
Bridges user-supplied NSRR/PhysioNet PSG (EDF SpO₂ + annotation XML) into the real OxyDex pipeline for the ODI-4-vs-AHI bias study. Reuses CpapEdf.readEDF; honors the Clock Contract.
Render · UI
cohort-runner.htmlPilot UI
The pilot harness: generate N patients, run them through the real per-node iframe pipelines, normalize every envelope through the Integrator, and score.
App · glue
cohort-worker.jsParallel lane
One Web Worker per node-KIND realm (oxy · rr+gluco) so the colliding globals never share scope and the heavy CSV/RR strings aren’t double-rendered. Returns minimal envelopes.
cohort-full.jsFULL lane
The ≤500 lane: renders the 176 Hz PPG + int16 µV ECG window so PpgDex and ECGDex morphology pipelines actually execute.
Harness · gate
cohort-regression.htmlRegression gate
Runs the 5 canonical SubjectA nights through the same harness and diffs against committed ground truth — the regression gate for the corpus + harness, mirroring Dex-Test-Suite’s summary pill.
03 — HOW IT’S ACHIEVED

From patients to figures

The same path every experiment takes: generate, fan out to real DSP, normalize to the bus envelope, fuse, then score or fit.

Generate the patients

cohort-gen draws N seeded patients over the parameter space and renders each into the device formats — deterministic, reproducible.

cohort-gen.js (reuses SYNTH)

Fan out to real DSP

Patients are dispatched to per-kind workers, each driving the node’s real DSP in its own iframe realm. No reimplementation — the shipped detectors run.

cohort-worker.js → cohort-harness.html

Normalize to the bus

Each node returns a minimal ganglior.node-export envelope; the Integrator fuses both kinds’ envelopes per patient on the main thread.

→ ganglior.node-export → Integrator

Score or fit

Outputs are diffed against ground truth (regression gate) or fed to a calibration / confound / reliability model, then rendered as figures and exported (CSV/JSON/PNG).

per-experiment scoring
04 — THE EXPERIMENTS

What’s on the harness

Each tool is a self-contained browser page over the shared harness. The first three feed published drafts; the last is a gate.

ODI-4 vs AHI biasodi-bias-analysis.html

Collects {ODI-4, scored AHI} from synthetic, SubjectA and optional real NSRR nights; fits calibration + a corrected surrogate; renders four figures and a closed-form power analysis. Reuses real OxyDex + CpapEdf + the NSRR adapter.

real detector+ NSRR bridge→ paper
HRV age-confoundhrv-confound-analysis.html

Generates N synthetic patients, measures rMSSD per night via the real PulseDex harness, then quantifies the age confound in a single-metric HRV screen and the AUC recovery from an age-adjustment.

simulationreal detector→ paper
How many nights? (test-retest ICC)nights-icc-analysis.html

Over the 1–12-night longitudinal lane, measures ODI-4 / rMSSD / CGM-CV per occasion with the real detectors, estimates ICC(1,1) by ANOVA, and applies Spearman–Brown for the minimum reliable recording length per metric.

simulationreal detectorbacklog → paper
Real-corpus regressioncohort-regression.html

The harness’s own gate: runs the 5 SubjectA nights through the real OxyDex + PulseDex harness and diffs against committed ground truth, with a headline pass/fail pill. Catches corpus or DSP drift.

regression gate
Cohort validation harness (pilot)cohort-runner.html

The pilot lane itself: generate a cohort, run every patient through the real headless pipeline, fuse in the Integrator, and aggregate — the substrate the analyses build on.

real DSPFAST + FULL lanes
05 — LIMITATIONS & CONSIDERATIONS

What the harness can and can’t claim

The experiments are powerful because they run the real code — and bounded because most of their data is synthetic. The constraints are deliberate.

Synthetic-driven by defaultcaution

Most runs use the synthetic corpus. Real-data validation needs user-supplied NSRR/PhysioNet PSG under a signed DUA — not bundled, not fetchable. The synthetic lane is the scalable pre-check, not the proof.

Realms exist for a reasonnote

The per-node iframe realm is not architecture astronautics — it is the only clean way to run colliding plain-global DSP files side by side without editing shipped code (which would trip the gates).

FULL lane is boundedlimitation

Waveform pipelines (PPG/ECG) are expensive, so the FULL lane runs one representative window per patient and is capped at ≤500 — enough to exercise morphology, not a population study.

Never edit DSP to fit the harnessby design

When the harness needs something the shipped DSP doesn’t expose, it adapts in the harness layer (e.g. rendering ECG µV from RR) — the regression + provenance gates stay the arbiter of truth.