Reading the source¶
Read firmware, manuals and loader code to explain a timing behaviour seen in the data, or to predict one to test.
| Techniques | Predict, then test |
Studies¶
| Study | Date | Status | Summary |
|---|---|---|---|
| The vitaldb package's loading conventions | 2026-10-17 | current | The vitaldb Python package sets time zero from the tracks loaded, places waveform blocks by rounding their stamps up to a sample, and lets overlapping blocks overwrite each other. Each choice moves or loses samples. |
| Time zeros and loaded subsets | 2026-10-16 | current | A VitalDB time "from the start" depends on which tracks were loaded: loading a subset moves the zero to that subset's first record, seconds or hours later. The arrhythmia database's annotations count from the full file's zero. |
| What a BIS-mimic project says about the index's smoothing | 2026-10-13 | current | The openeeg project reproduces the BIS index from the raw EEG and infers each case's smoothing setting: about 80% of its cases come out at 15 s. Its alignment cannot serve as a timing reference. |
| The SNUADC firmware | 2026-10-13 | current | The public SNUADC firmware explains the board's timing: it sends no time stamps, samples on its 16 MHz crystal, loses time rather than bunching samples after a stall, reads its channels one after another, and truncates its values. A predicted fault at the microsecond counter's wrap was not found in the data. |
| The PPG hardware delay and the adopted pulse arrival time | 2026-10-12 | current | VitalDB's raw ECG→PPG pulse arrival time is about 0.4 s longer than physiology. Splitting it into a hardware delay (one value for the release; One device delay for the PLETH across the release) and a physiological part needs an adopted value from studies that sampled ECG and PPG on one clock: about 270 ms for anaesthetised adults. |
Observations from these studies¶
| Observation | Status | Summary |
|---|---|---|
| About 20 ms of signal lost at every SNUADC reset | established | At each step-mode reset the acquisition pauses for about 20 ms inside the last record before the new timing, and that time is never sampled: 17.7 ms on the sample count (Signal lost at a SNUADC step-mode correction), once the filler sample is counted. Every record still holds 100 samples, so nothing in the file shows it. |
| All SNUADC channels share one clock | established | Every SNUADC waveform track of a case (ECG leads, ART, PLETH, CVP) has the same first stamp, the same record timing and the same corrections. They are stamped together. |
| Every time is quantised, and fiducials inherit it | established | A time on a grid of step Δ carries an error of Δ/√12 (1 SD). In VitalDB that is 0.58 ms for a 500 Hz sample, 2.3 ms for BIS EEG, 0.8 ms for the arrhythmia annotations' 1/360 s grid, and up to ±17 ms for PPG fiducials taken on raw samples, which lock to the 33.3 ms frame. |
| SNUADC sends no time; the recorder stamps by count | established | The SNUADC board streams samples with no time stamps. Every SNUADC time in VitalDB is the recorder's model of the board's clock: the sample count at the nominal rate, pulled back when it drifts too far. |
| SNUADC stamps run −0.95 ppm against the sample count | established | Between corrections each 0.2 s record stamp increment is about 0.19 µs short: stamps run −0.95 ppm from the sample count in 88% of files (both SNUADC modes). It is arithmetic, not clock drift. The other 12% sit between −0.90 and −0.55 ppm. |
| The BIS index is slow | established | The BIS index averages 15–60 s of EEG ending about 3 s before its stamp, with half its weight older than 30 s. It cannot time anything faster than about a minute. |
| The PLETH arrives about 0.4 s late | established | Raw R-to-PPG-foot pulse arrival time in VitalDB has a median of 0.64–0.71 s, about 0.4 s more than physiology: the monitor's buffering and filtering. One delay fits the whole release: no clusters by setup, SNUADC port or case order (One device delay for the PLETH across the release). |
| The plethysmogram is built in 30 Hz frames | established | The SNUADC PLETH waveform comes from the oximeter in 33.3 ms frames, smoothed to 500 Hz. Its content changes once per frame, on the oximeter's own clock, about 0.4 s after the finger. |
| Time zero depends on the tracks loaded | established | A file's time zero is its first record of any track. Loading only some tracks moves the zero to their first record: seconds later, and up to hours. |
| SNUADC channels are read one after another | likely | The SNUADC firmware reads its 8 channels in turn, about 0.1 ms each, so within one sample the last channel is read up to about 0.8 ms after the first. The channel order is not known. |
| SNUADC values are truncated to the count below | likely | The SNUADC firmware truncates each calibrated value instead of rounding it, so every value sits half a count low on average (about 0.5 mmHg for arterial pressure). Values clamp at counts 0 and 1023. |
| Stamp-based loaders lose samples at overlaps | likely | Loaders that place samples by their stamps onto a grid overwrite samples where stamps overlap: about 0.48 s at every SNUADC reset, and one sample about every 35 minutes from the stamp arithmetic. |
| SNUADC has two event inputs | open | The firmware sends two event-jack flags with every sample. If any case used them, they would be markers on the SNUADC's own clock. |
The approach¶
The idea. Some timing behaviour is written down: in a device's firmware, a manual, or the code that loads the data. Reading it explains a measurement and predicts the next test.
What it gives. Mechanisms: why time is lost at a stall, why channels are skewed, why a loader moves time zero.
How. Find the code path that produces or consumes the time stamps, state what it predicts, and test the prediction in the data.
Pitfalls. The source may not be the version that was deployed, and documentation may describe settings rather than what was used. A source is a hypothesis until the data agree.
Techniques¶
- Predict, then test: Turn what a source says into a prediction about the data (a step every 4,295 s, a skew between two channels, a sample lost every 35 minutes) and look for it, with a control; a source that is not borne out is set aside.