The vitaldb package's loading conventions¶
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.
| Date | 2026-10-17 |
| Status | current |
| Methods | Reading the source, Reading the stamps |
| Techniques | Predict, then test |
| Clocks | SNUADC sample clock, Recorder PC clock |
| Devices | Vital Recorder, SNUADC |
| Variables | ECG lead II (SNUADC), Arterial pressure (SNUADC), Plethysmogram (SNUADC) |
Data¶
vitaldb 1.7.2 (VitalFile and get_track_samples in utils.py); checked on 6 files and on the 482 arrhythmia database cases; device start delays across all 6,388 files. Work of the R-peak timing session, consolidated here.
Method¶
The loader's code was read for how it sets time zero and places samples, and each behaviour reproduced on files: subset against full loads, the stamp-minus-count error at each block, and the waveform rebuilt by sample count.
Results¶
- Time zero follows the loaded tracks. VitalFile(path, tracks) sets its start to the first record among those tracks; with all tracks it is the file's first record (the EVENT track in every file). Device start delays after the file's first record: SNUADC 1.56 s median (0.44–4.5 s; maximum 10,879 s), Primus 0.72 s, BIS 0.95 s.
- Blocks are placed by rounding up. Each wave record goes to sample index ceil((stamp − start) × rate). With the stamps running −0.95 ppm against the count (SNUADC stamp arithmetic), each time the error crosses a whole sample the next block is written one sample early and overwrites the last sample of the previous one: one real sample lost about every 35 minutes, and everything after it 2 ms early on the array index. Rebuilt by count, the 2 ms phase steps disappear.
- Overlaps overwrite. At each SNUADC reset the overlapping blocks are written over each other, discarding about 0.48 s of signal besides the time jump; sorting by stamp instead scrambles the order (Records out of order at SNUADC resets, and where the lost time goes).
| Parameter | Value | Status | From |
|---|---|---|---|
| SNUADC start after the file's first record | 1.56 s (5–95%: 0.44–4.5 s; 99th percentile 12 s; maximum 10,879 s) | measured | The vitaldb package's loading conventions |
Discussion¶
Clock rates measured on the package's array index read about +0.95 ppm high. Analyses that use the stamps directly are unaffected. The TimeNet import reads whole files, keeps every sample, places them by count and puts the reset records in sampling order.
Observations it supports¶
| Observation | Status | Summary |
|---|---|---|
| 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. |
| 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. |
| 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. |
Code¶
- vitaldb (Python package) (not published):
vitaldb/utils.py
References¶
- VitalLab. vitaldb [Python package]. PyPI. ↗