Draft
Worked through on a few cases; numbers may change.
Pulse arrival time in two correction steps¶
The time from the ECG R wave to the pulse at the finger, as stored, after the PLETH's sawtooth is removed, and after its device offset is removed, smoothed by maximum likelihood, with the arterial line as the reference.
The question¶
How long does the pulse take to travel from the heart to the finger, and how does that change through an operation?
Inputs¶
Each input links to its measurement page: how it is timed, how its value was recorded, and how uncertain both are.
| Input | Unit | What it is |
|---|---|---|
| ECG lead II (SNUADC) | mV | Lead II of the ECG, sampled by SNUADC at 500 Hz from the monitor's analogue output. |
| Plethysmogram (SNUADC) | The pulse oximeter's plethysmogram, sampled by SNUADC at 500 Hz. It reaches SNUADC through the oximeter's own 30 Hz frame clock and a hardware delay of about 0.4 s. | |
| Arterial pressure (SNUADC) | mmHg | Invasive arterial pressure, sampled by SNUADC at 500 Hz from the monitor's analogue output. |
Why the atlas changes the answer¶
Pulse arrival time (PAT) is a difference of two event times taken from two signals, so any delay or drift between them goes straight into it. ECG and arterial pressure come through the same SNUADC converter and stay aligned (All SNUADC channels share one clock, Arterial pressure as a check on the PPG correction). The PLETH does not, in two ways:
- a sawtooth: its delay behind the ECG creeps at 18–52 ppm and jumps back by one 33.3 ms frame at each slip, every 11–31 minutes (The ECG→PPG delay is a sawtooth, The PPG sawtooth and its correction);
- an offset: the monitor delivers the PLETH about 0.4 s late (The PLETH arrives about 0.4 s late, The PPG hardware delay and the adopted pulse arrival time).
Both look like physiology in a raw PAT series: the sawtooth as slow drifts and sudden jumps of tens of milliseconds, the offset as a PAT almost three times too long, which also differs between recording setups.
Data¶
60 minutes per case, starting 10 minutes into the overlap of ECG lead II and PLETH. The cohort is a random 120 of the recordings with both signals (97% of recordings have them: 817 of 846 sampled), plus case 5975 for the figure; 66 of the 121 also have a pulsatile arterial line, which serves as the reference.
Steps¶
- Fiducials. R peaks in ECG lead II; the steepest upstroke after each R peak in the PLETH, and in the arterial pressure where there is a line.
- Step 1, remove the sawtooth (The ECG→PPG delay is a sawtooth).
physiosync.fit_ecg_ppg_delayfits the PLETH's delay as an offset plus a sawtooth (creep at a fixed rate, reset by one 30 Hz frame at each slip), with the arterial upstrokes as the reference where present. Each tooth gets a confidence tier; teeth below tier B are left as they are. Subtracting only the sawtooth leaves the PAT at its stored level. - Step 2, remove one global device delay (The PLETH arrives about 0.4 s late): 385 ms for every recording. The stored ECG-to-PLETH delay has one peak over the whole release, with no clusters by recording setup and no shift along the case order (One device delay for the PLETH across the release). The adopted mean finger PAT, 0.27 s (The PPG hardware delay and the adopted pulse arrival time), is measured to the foot of the pulse, so the delay is too: 655 ms (the stored delay to the foot) minus 270 ms. This example times the steepest upstroke, 59 ms after the foot, so its corrected PAT reads about 270 + 59 = 330 ms. Because the same delay comes off every case, differences in PAT between patients are kept; only the absolute level rests on the adopted 0.27 s.
- Smooth by maximum likelihood, after Ruffolo et al. 2025: per 30 s window, the latent PAT that
maximises the likelihood of the window's beats under the recording's per-beat error model
(
physiosync.pat_measurement_model: the PLETH fiducial's frame rounding or jitter, and the ECG's one-sample rounding), evaluated by Monte Carlo, with a 2% floor for mis-detected beats. A median gives every beat the same weight whatever its error; the likelihood weighs them by the error model and ignores outliers.
Results¶
One case. In case 5975 the stored PAT (grey) is about 0.68 s and jumps back by one frame three times in the hour (dotted). After step 1 (blue) the jumps and ramps are gone and the series has the same course as the arterial PAT (green): the spread of finger minus arterial PAT, minute by minute, falls from 10.7 to 2.7 ms. Step 2 (orange) moves the whole series down by the global 385 ms, without changing its shape; the corrected finger PAT (to the upstroke) then sits 116 ms above the arterial PAT in this case.
The cohort (121 cases).
- Global delay (step 2). The stored PAT's case median is 0.65–0.75 s; step 2 subtracts 385 ms from every case, so the corrected case medians keep their spread (median 333 ms to the upstroke, interquartile range 319–347 ms). Eight cases have a stored median of 0.44–0.54 s: their pulses were paired with the wrong beat (fast heart rates or doubled R peaks, with a 0.7 s delay longer than one RR interval; see One device delay for the PLETH across the release). They are left out of the cohort figures, leaving 113.
- Sawtooth (step 1). A median of 4 slips an hour. At least one tooth was corrected with confidence (tier A or B) in 46 of the 121 cases. Where there was also an arterial line (24 cases), the spread of finger minus arterial PAT fell from a median of 13.0 to 9.8 ms per case, and improved in 19 of the 24; pooled over their windows, from 13.7 to 9.8 ms. The within-case spread of PAT itself changes little (17.7 to 16.9 ms in the median case), because real changes in PAT, tens of milliseconds as blood pressure changes, are larger than the sawtooth.
Before and after, as PAT values. As stored, ECG-to-finger PAT is 718 ms in the median window (638–768 ms, 5th to 95th percentile), far beyond any physiological value: almost every window lies outside the 200–285 ms reported for awake adults, even allowing for the 59 ms from foot to upstroke. After both steps the median is 333 ms to the upstroke (253–382 ms), above the arterial-line PAT (223 ms), as a finger, further from the heart than the radial artery, should be. Where the orange peak sits overall rests on the adopted 0.27 s; its spread is measured, because one delay comes off every case. 1.9% of corrected windows come out negative, where beats were mis-paired; they are left out of the figure. The adult range is provisional and still has to be verified (see the open questions).
Against the arterial line, window by window. In the 60 cases with an arterial line, finger PAT as stored sits 496 ms above the arterial-line PAT in the median window; after both steps it sits 111 ms above it (upstroke to upstroke; about 90 ms foot to foot in the census), the order expected for a finger further from the heart than the radial artery. Both clouds slope with the arterial PAT: across cases, the corrected finger PAT follows the arterial PAT with a slope of 0.59 (correlation 0.53), exactly as the stored one does, because a single global delay keeps the differences between patients. (An earlier version of step 2 removed each case's own offset, which flattened the corrected cloud and threw those differences away.)
Population and individual
Systematic: does not cancel.
| The cohort | A device delay of about 0.39 s sits in every stored PAT: a cohort mean is wrong by that much until it is removed. |
| Each patient | The PLETH sawtooth adds slips of 33 ms within each patient; removing it lowers the spread against the arterial line from 13.0 to 9.8 ms. |
Takeaways¶
- Never read the absolute ECG-to-PLETH PAT in VitalDB as physiology: it carries a device delay of about 0.39 s. The delay is the same across recording setups and the case order, so one global value removes it and keeps differences between patients; the absolute level still rests on an adopted mean finger PAT.
- Pair each pulse with its own beat: the stored delay (about 0.7 s) is longer than one RR interval at fast heart rates, and a nearest-upstroke search then pairs one beat out.
- Within a case, remove the sawtooth (step 1) before reading changes over minutes; otherwise slips appear as sudden PAT changes of 33 ms.
- Check each tooth's tier: below B only the offset is removed, and the sawtooth is still there.
- Where an arterial line exists, ECG to arterial line is a PAT without either problem.
Limitations¶
- The beat detector is deliberately simple: 12% of 30 s windows lie more than 40 ms from their case's median, mostly from mis-detected beats.
- 60 minutes of 121 cases; a full run belongs in the runbook.
Open questions and future work¶
- Most teeth cannot be corrected with confidence (next step). In 75 of 121 cases no tooth reached tier B, so the sawtooth stays in them. The likeliest causes, in order: the example gives the fit no creep-rate prior, although the rate is fixed per setup (The ECG→PPG delay is a sawtooth, the Recording setups page), so a tooth reaches tier A only if the recording has two full teeth that agree; 60-minute windows hold few full teeth (on up to 3 hours, cases with a confident tooth rose from 47% to 57% and confident teeth from 21% to 33%); tier C teeth (the most common) are fitted but not applied; and a simple PLETH fiducial produces false slips (some cases show 24–46 an hour against about 4). Setup priors and longer windows come first; the tier rules were tuned on injected sawtooths, not on recordings.
- Where the sawtooth stops (unexplained phenomenon). In some stretches no slip comes although several were due, and the delay is flat (Where the PPG sawtooth stops). The model treats the stretch before and after a pause as creep then hold, of unknown length, which leaves up to one frame of uncertainty there.
- Pairing by the modal delay in the example itself (next step). Eight of 121 cases were paired one beat out (fast heart rates or doubled R peaks) and are left out of the cohort figures. The census pairs pulses by each segment's modal delay instead (One device delay for the PLETH across the release); using that pairing here would bring them back.
- The adopted 0.27 s (untestable assumption). The global delay is the release's median stored delay to the pulse foot (655 ms) minus 0.27 s, a mean R-to-foot finger PAT for anaesthetised adults from studies that sampled ECG and PPG on one clock (The PPG hardware delay and the adopted pulse arrival time). Differences between patients and changes within a case are measured; the absolute level of every case moves with the adopted value. It implies a finger-minus-radial difference of about 90 ms foot to foot, which a literature value could check.
- What plausible PAT range should be shown for anaesthetised adults? (untestable assumption). The figure shades 200–285 ms to the foot (shifted by 59 ms to the upstroke), the range of means in shared-clock studies of awake adults (The PPG hardware delay and the adopted pulse arrival time). That is a range of study averages, not of individual windows, and anaesthesia lengthens PAT by about 40 ms. A verified range for adults under anaesthesia, ideally of individual values, is still needed; Ruffolo et al. 2025 gives one for critically ill children.
- The maximum-likelihood smoother follows Ruffolo et al. in approach, not in detail (next step). The window length (30 s), the outlier floor (2%) and the error model's terms are this example's choices; the estimator has not been checked against the original implementation, or against injected PAT changes of known size.
Studies it relies on¶
| Study | Date | Status | Summary |
|---|---|---|---|
| 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. |
| Where the PPG sawtooth stops | 2026-10-11 | current | In some stretches no slip comes although several were due. The PPG delay there is flat, not hidden: the monitor keeps framing, and only the content's drift against the frames has stopped. |
| Arterial pressure as a check on the PPG correction | 2026-10-11 | current | Arterial pressure is sampled by the same converter but has no frame and no sawtooth, so every PPG slip leaves ECG→ABP unchanged. Against it, detected slips are 97–100% real and tier A leaves about 2 ms of drift mid-tooth. |
| The PPG sawtooth and its correction | 2026-10-10 | current | The ECG→PPG delay creeps at 18–52 ppm and jumps up by one 33.3 ms frame at each slip, every 11–31 minutes. A tooth-by-tooth model removes it; where the correction is confident it is essentially exact on injected test data. |
| The PPG's 30 Hz frame clock | 2026-10-10 | current | ECG and PPG fiducials resolve to one 2 ms sample, but PPG fiducials taken on raw samples lock to a hidden 33.3 ms frame grid. Scanning for it finds the oximeter's frame clock to about 1 ppm, a fixed fingerprint of each recording setup. |
Observations it relies on¶
| Observation | Status | Summary |
|---|---|---|
| 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. |
| The ECG→PPG delay is a sawtooth | established | Inside the oximeter the PPG content creeps 18–52 ppm against its 30 Hz frames; every 11–31 minutes a frame repeats and the delay jumps up by 33 ms. The rate is fixed per recording setup. |
| 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. |
| The PPG sawtooth sometimes stops | open | In some stretches, and some whole recordings, no frame slip comes although several were due. The delay there is flat and the frame clock keeps running; what stops the content's drift is not known. |
Reproduce it¶
- vitaldb-bench:
examples/pulse_arrival_time.py - physiosync:
physiosync/ecg_ppg.py,physiosync/measurement.py
python examples/pulse_arrival_time.py --root <VitalDB release> --cases 5975 --figure 5975 --out out/pat
python examples/pulse_arrival_time.py --root <VitalDB release> --cases <case ids> --out out/pat
python examples/pulse_arrival_time.py --out out/pat --cohort-figure
References¶
- Ruffolo I, Siddiqui A, Nguyen B, Dixon W, Assadi A, Greer R, Schwartz S, Brudno M, Mariakakis A, Goodwin A. High-fidelity measurement of pulse arrival time in critically ill children using standard bedside monitoring equipment. Physiol Meas. 2025;46(11):115006. ↗