Skip to content

Code map

cwtool/
├── recording.py        Recording, DeviceProfile, Event: the device-independent data model
├── params.py           Parameters (signal pass), VideoSettings (video pass), DisplayPhotometry (its own file);
│                       JSON load/save, 1.x conversion, unused_parameters() for the GUI
├── devices/
│   ├── __init__.py     READERS, detect(), load()
│   ├── common.py       event logs, markers → events, binning, sample rate, field of view (pinhole and lens distortion)
│   ├── varjo.py        Varjo XR-4 (Varjo Base)
│   ├── pupil_core.py   Pupil Core (Pupil Player export)
│   ├── neon.py         Pupil Neon (Pupil Cloud export, native format), experimental
│   └── tobii_g3.py     Tobii Pro Glasses 3 (SD card recording folder), experimental
├── lux.py              lux log files (hourly 1.x files and the logger's lux.csv): find, read, smooth, lux → average luminance
├── sensors.py          the sensor logger's Shimmer and EmotiBit files (with their saved settings): find, read, cut, write
├── hrv.py              heart rate variability from a Shimmer's ECG: R peaks (NeuroKit2), trusted intervals, measures per window
├── trim.py             Trim: the part of a recording an export keeps (start, end, left-out segments)
├── video.py            scene video pass: frame clock, decoding (PyAV/OpenCV), parallel chunks, two-area
│                       measurement, gamma grid, gaze weighting (VideoResult.weighted), cache
├── luminance.py        code values → linear, relative and absolute luminance
├── model.py            Watson & Yellott, Stanley & Davies, delay, attack/release, transient
├── pipeline.py         prepare(), run(), export(): from recording + video pass + parameters to ΔPD
├── calibration.py      calibration sequences: built-in, CSV, locate in a recording
├── photometry.py       step 1 of the participant fit: light sensitivity and channel weights from step levels
├── fit.py              step 2: latency (from onsets), dynamics and transient (pupil offset optional)
├── logger/             the multi-sensor logger (no Qt except gui.py); see usage/logger.md
│   ├── base.py         Source (one sensor stream), ClockMapper (device clock → Unix time)
│   ├── session.py      Logger (sources, live buffers, session folder, writer thread), EventLog
│   ├── sinks.py        CsvSink
│   ├── protocol.py     protocol files (name,duration)
│   ├── clockcheck.py   timestamp checks of a recorded session (regularity, Shimmer drift, Shimmer vs EmotiBit offset)
│   ├── gui.py          the window (cwtool-logger), plot scaling, stall watchdog
│   └── sources/        lux (serial), shimmer (pyshimmer), lsl (EmotiBit via the Oscilloscope), simulated;
│                       rfcomm_mac.py + rfcomm_helper.py: direct Bluetooth channel on macOS
├── cli.py              the cwtool command
                        (gui/ and logger/ each have a __main__.py: python -m cwtool.gui, python -m cwtool.logger)
├── plot.py             matplotlib figure for exports
├── palette.py          project colours, shared by the app, its plots and the PDF plot
└── gui/
    ├── main_window.py  window, menus, recording/video/calibration panels, background tasks
    ├── param_panel.py  parameter editors (every Parameters field must have one)
    ├── plots.py        pyqtgraph plots, sequence overlay, cursor, sensor plots, export range overlay
    ├── side_panel.py   the rail of tabs, pills, numbered steps and the preview holder of the left column
    ├── trim_panel.py   the export range editor in the sidebar
    ├── errors.py       plain-language advice for errors and the gestures/shortcuts list of the Help menu (no Qt)
    ├── icons.py        the icon loader (Tabler outline SVGs in icons/, drawn in the palette's colours)
    ├── photometry_dialog.py  result window of the light sensitivity fit
    ├── video_preview.py      scene frame at the cursor with the analysis circles
    └── workers.py      QThread wrapper for the video pass and the fit

tools/
├── lux_logger.py       lux sensor over USB serial → hourly CSVs (1.x format; the sensor logger writes lux.csv)
├── event_logger.py     experiment phases → event_log CSV
└── example_protocol.csv

tests/                  pytest suite with synthetic recordings for every device (conftest.py); one file per area,
                        each with a header saying what it covers
docs/                   this site (MkDocs)
Lux Sensor/             lux logger firmware and 3D-printable mount

Main entry points

Function Does
devices.load(folder, device=None, **options) read a recording
video.analyse_video(video, time, gaze, settings, frame_times=...) video pass
video.VideoResult.load_cached(...) / .save(...) cache
pipeline.run(rec, video, params) signal pass, returns a Result
pipeline.export(result, rec, params, folder, trim=, sensors=) the export package: CSVs, sensor files, parameters, manifest; trimmed
sensors.load_sensors(folder, epoch_start, duration) the logger's sensor files, cut to a recording
calibration.locate(time, rgb, sequence, gamma) find the calibration sequence
photometry.fit_light_response(rec, video, params, start, sequence) participant fit, step 1: light response
fit.fit_calibration(rec, video, params, start, end, sequence=...) participant fit, step 2: latency and dynamics
pipeline.calibrate_camera(rec, video, params) full-scale luminance of a fixed-exposure scene camera
logger.Logger().add(source) / .start_recording(folder) / .stop_recording() record sensors into a session folder

The processing steps and the functions that carry them out are listed in order in Processing at a glance.