Skip to content

Pipeline overview

flowchart TD
    REC[Recording<br/>pupil, gaze, scene video, lux] --> VID[Scene video analysis<br/>gaze circle + background, per gaze sample]
    VID --> CACHE[(cwtool_video.csv<br/>cache)]
    CACHE --> LUM[Luminance<br/>display photometry or lux sensor]
    REC --> PUP[Pupil signal<br/>scale, range, artefacts, eyes, resample, smooth]
    LUM --> MOD[Expected pupil<br/>Watson & Yellott + delay + dynamics]
    PUP --> ALN[Scale and alignment]
    MOD --> ALN
    ALN --> DPD[ΔPD<br/>windowed measured − expected]
    DPD --> OUT[Plots, CSV export, per-event means]
    MOD -.-> FIT[Calibration fit<br/>light sensitivity, channel weights,<br/>latency, dynamics, scale, offset]
    PUP -.-> FIT

The analysis runs in two passes with very different costs:

  1. Video pass (cwtool/video.py), seconds to minutes: decodes the scene video and measures, for every valid gaze sample, the colour inside a circle around the gaze point and over the background. Colours are stored for a grid of gamma values, so nothing in the second pass needs the video again. The result is cached next to the recording.
  2. Signal pass (cwtool/pipeline.py), a fraction of a second: everything else. It re-runs on every parameter change, which is what makes the app's plots live.

Steps and where to read about them

Every step with its parameters, defaults and functions is listed in order on one page: Processing at a glance.

Step Module Page
Read the device's files into a Recording devices/ Devices
Measure gaze circle and background colours video.py Scene video analysis
Turn colours into cd/m² luminance.py, lux.py, pipeline.prepare Luminance
Clean and resample the pupil pipeline.prepare Pupil signal
Expected pupil for that luminance model.py, pipeline.expected_pupil Expected pupil model
Offset, ΔPD, statistics, events pipeline.run ΔPD and alignment
Participant parameters from the calibration sequence calibration.py, photometry.py, fit.py Calibration fit

Clocks

Everything runs on the recording's relative clock: seconds from the first scene video frame. Lux readings are moved onto it with epoch_start, and the time lag parameter shifts the luminance signal (video and lux) to correct a known offset. Exports carry both the relative and the Unix time.