PPG pigmentation audit: synthetic worked example¶
What the example is constructed to show¶
The synthetic data deliberately create a case in which:
- the optical waveform becomes harder to retain at lower synthetic ITA values;
- motion makes both waveform quality and candidate-HR retention worse;
- the candidate HR error distribution depends on activity;
- ITA is not part of the candidate-HR error equation.
That gives the audit a known target: it should be able to reveal a retention difference without converting that result into a claim that reference accuracy is pigmentation-driven.
1. Pigmentation measurement¶
The example generates CIELAB \(L^*\) and \(b^*\) values and derives Individual Typology Angle (ITA) using the same public helper used by the audit:
The inverse relationship used only to construct internally consistent synthetic CIELAB values is
The continuous ITA value is the analytical variable. Presentation bins are secondary and are never treated as interchangeable with Monk, Fitzpatrick, race, or ethnicity.
2. Reference heart rate¶
For participant \(i\), activity \(a\), and sample \(t\), the synthetic reference heart rate is
where \(b_i\) is a participant-specific baseline and \(\delta_a\) is an activity effect. In the default generator:
| Activity | \(\delta_a\) |
|---|---|
| Rest | 0 bpm |
| Typing | 8 bpm |
| Walk | 34 bpm |
The pulse frequency is
The phase of the synthetic waveform accumulates this instantaneous frequency over the sampling grid.
3. Synthetic PPG waveform¶
The recorded optical waveform is generated as
where the amplitude term \(A_i\) is deliberately allowed to vary with the synthetic ITA value. This is only a software stress mechanism. The package does not claim that this equation describes human tissue optics.
Motion increases the waveform noise term during walking. The resulting traces are used to exercise finite-data proportion, AC amplitude, DC level, AC/DC ratio, spectral SNR, flatness, and beat-template correlation.
4. Retention mechanism¶
The probability that a synthetic waveform sample is missing is created from a logistic model:
The signs are chosen so lower synthetic ITA and more motion produce more missing observations. The candidate-HR measurement has a similar retention mechanism.
The audit does not fit this exact generating model. Instead, when an objective pigmentation metric is supplied it estimates a participant-clustered descriptive association such as
with participant-level bootstrap resampling. Here \(R_{ij}=1\) means the reference is available and the candidate measurement is retained.
5. Accuracy mechanism¶
Candidate HR is generated as
with
Crucially, \(ITA_i\) is not included in \(\sigma_a\) or in the mean error. Activity drives the synthetic error distribution. This creates the intended demonstration: retention can vary even when the accuracy-generating mechanism is ITA-neutral.
For paired measurements the audit reports
and Bland--Altman limits
Lin's concordance correlation coefficient is also reported:
These error statistics use paired observations. Retention uses all rows for which the reference measurement is available, so missing candidate values cannot silently disappear from the denominator.
6. PPG signal-quality indicators¶
The Python-native audit extends the existing waveform-quality path with PPG-specific descriptive SQIs.
A robust AC amplitude is constructed from the central waveform range:
with
The spectral SNR is
where the pulse band is centered on the dominant component within the 0.5--5 Hz analysis region and remaining in-band power forms the noise term.
No individual SQI automatically determines whether a participant is scientifically valid. The retained/not-retained status reuses the package's declared waveform-QC rules.
7. Participant-cluster bootstrap¶
Rows from the same participant are not independent. The uncertainty calculations therefore resample participants rather than individual signal samples.
For bootstrap replicate \(b\):
where the participant IDs are sampled with replacement. Every row belonging to a sampled participant is carried into that replicate. The 2.5th and 97.5th percentiles of the bootstrap distribution form the default 95% interval.
This matters because treating tens of thousands of waveform rows as independent would create unrealistically narrow intervals.
8. Run the complete example¶
From a repository checkout:
python scripts/generate_ppg_equity_synthetic_demo.py \
--output-dir docs/assets/ppg-equity \
--seed 20261003 \
--participants 36 \
--n-boot 400
The script generates the synthetic data in memory, runs ppg_pigmentation_audit(), writes manuscript-ready derived tables, and regenerates the SVG figures shown on this page. Row-level synthetic data are not written unless --write-data is explicitly supplied.
For a fast figure-only rebuild:
python scripts/generate_ppg_equity_synthetic_demo.py \
--output-dir docs/assets/ppg-equity \
--render-only
9. Equivalent direct API workflow¶
from gpbiometricspy.ppg_equity import ppg_pigmentation_audit
result = ppg_pigmentation_audit(
data,
participant_col="participant",
ppg_col="HRP",
pigmentation_metric="cielab",
l_star_col="skin_L_star",
a_star_col="skin_a_star",
b_star_col="skin_b_star",
pigmentation_method="synthetic_colorimetry",
pigmentation_site="pigmentation_site",
sensor_site="sensor_site",
instrument_manufacturer="instrument_vendor",
instrument_model="instrument_model",
time_col="time_s",
group_cols=["activity"],
sampling_rate_hz=60,
reference_col="ecg_hr",
candidate_col="ppg_hr",
metric_name="heart_rate",
device_col="device",
condition_col="activity",
n_boot=1000,
random_state=20261003,
)
The principal result objects are:
The most important reading order is:
- metadata provenance;
- raw acquisition quality;
- retention/missingness;
- paired reference agreement;
- only then, any pigmentation-associated descriptive model.
10. What a correct conclusion looks like¶
The synthetic example is intentionally constructed so a statement like this can be correct:
Candidate-HR retention varied across the synthetic ITA range, while the generating mechanism for paired HR error depended on activity rather than ITA.
That is very different from:
Pigmentation caused inaccurate heart-rate measurements.
The second statement is not supported by this synthetic design and is not generated by the package.
Reproducibility assets¶
The page uses deterministic SVG and CSV outputs generated by scripts/generate_ppg_equity_synthetic_demo.py:
ppg-equity-synthetic-retention.svgppg-equity-synthetic-reference-error.svgppg-equity-synthetic-waveforms.svgppg-equity-synthetic-bin-summary.csvppg-equity-synthetic-participant-summary.csv
Continue with the external-evidence protocol for the STEP and ENCoDE adapters and with the method note for the scientific interpretation boundary.