https://github.com/andyed/pupil-lfhf
Real-time LF/HF pupillometric cognitive load via Butterworth IIR filters (Duchowski 2026). Includes AdSERP validation on 2,719 eye-tracking trials.
https://github.com/andyed/pupil-lfhf
blink-artifact-removal butterworth-filter cognitive-load eye-tracking lhipa psychophysics pupillometry
Last synced: 17 days ago
JSON representation
Real-time LF/HF pupillometric cognitive load via Butterworth IIR filters (Duchowski 2026). Includes AdSERP validation on 2,719 eye-tracking trials.
- Host: GitHub
- URL: https://github.com/andyed/pupil-lfhf
- Owner: andyed
- License: mit
- Created: 2026-04-04T20:05:04.000Z (2 months ago)
- Default Branch: main
- Last Pushed: 2026-04-11T02:47:28.000Z (2 months ago)
- Last Synced: 2026-04-11T04:27:30.454Z (2 months ago)
- Topics: blink-artifact-removal, butterworth-filter, cognitive-load, eye-tracking, lhipa, psychophysics, pupillometry
- Language: Jupyter Notebook
- Homepage:
- Size: 450 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# pupil-lfhf
Real-time LF/HF pupillometric cognitive load measurement via Butterworth IIR filters.
Based on Duchowski (2026): two 4th-order Butterworth filters split the pupil diameter signal into low-frequency (0-1.6 Hz, tonic/autonomic) and high-frequency (1.6-4 Hz, phasic/cognitive) bands. The LF/HF power ratio indexes cognitive load with a 1-second minimum window — 7.5x shorter than DWT-based approaches.
## Usage
```python
from pupil_lfhf import PupilLFHF
# Batch processing (offline, zero-phase)
detector = PupilLFHF(fs=150)
ratio = detector.compute(pupil_signal) # single LF/HF value
# Per-segment (e.g., per-event cognitive load)
lf_signal, hf_signal = detector.filter(pupil_signal)
# Then compute variance ratio on any segment of interest
# Streaming (real-time, sample-by-sample)
detector = PupilLFHF(fs=150, mode='stream')
for sample in pupil_stream:
ratio = detector.update(sample) # None until buffer fills
```
## Validation
`validation/` contains empirical validation on the [AdSERP dataset](https://github.com/kayhan-latifzadeh/AdSERP) (2,719 eye-tracking trials, 150 Hz Gazepoint GP3 HD, Latifzadeh et al. SIGIR 2025):
- Three-method convergence (Butterworth, DWT, raw PD agree on direction)
- Per-position cognitive load trajectory during SERP evaluation
- Head-to-head sensitivity comparison against trial-level LHIPA on 5 known effects
See `validation/README.md` for details.
## Parameters
| Parameter | Default | Description |
|-----------|---------|-------------|
| `fs` | 60 | Sampling rate (Hz) |
| `order` | 4 | Butterworth filter order |
| `lf_cutoff` | 1.6 | LF band upper cutoff (Hz) |
| `hf_band` | (1.6, 4.0) | HF band (Hz) |
| `power_window` | 1.0 | Sliding window for variance (seconds, streaming mode) |
## Minimum windows
From Duchowski (2026), minimum signal duration for stable LF/HF estimation:
| Method | Minimum | At 60 Hz | At 150 Hz |
|--------|---------|----------|-----------|
| FFT | 10 s | 600 samples | 1,500 samples |
| DWT | 7.5 s | 450 samples | 1,125 samples |
| **Butterworth** | **1 s** | **60 samples** | **150 samples** |
## References
Duchowski, A. T. (2026). Real-Time Cognitive Load Measurement of Pupillary Oscillation. *Proc. ACM Comput. Graph. Interact. Tech.* 9, 2. https://doi.org/10.1145/3803537
Duchowski, A. T., Krejtz, K., Gehrer, N. A., Bafna, T., & Baekgaard, P. (2020). The Low/High Index of Pupillary Activity. *CHI '20*. https://doi.org/10.1145/3313831.3376394
## License
MIT