Data Models

Structured dataclasses for EyeLink calibration, validation, and session data.

Data structure definitions for EyeLink calibration and validation data.

These structures define what fields will be extracted from the raw ASC text.

class syelink.models.DisplayCoords(left, top, right, bottom)[source]

Bases: object

Display/screen coordinates from the EyeLink ASC file.

Parsed from: MSG <timestamp> DISPLAY_COORDS <left> <top> <right> <bottom> Example: MSG 228029 DISPLAY_COORDS 0 0 1279 1023

The values are 0-indexed, so width = right - left + 1, height = bottom - top + 1.

Parameters:
left: int
top: int
right: int
bottom: int
property width: int

Screen width in pixels.

property height: int

Screen height in pixels.

property center_x: float

Screen center X coordinate.

property center_y: float

Screen center Y coordinate.

classmethod from_dict(data)[source]

Create DisplayCoords from a dictionary.

Return type:

DisplayCoords

Parameters:

data (dict[str, Any])

class syelink.models.CalibrationPoint(point_number, pcr_href_x, pcr_href_y, href_x, href_y)[source]

Bases: object

Single calibration point: polynomial input and target HREF gaze, both in HREF space.

Naming convention used across syelink:
  • raw → camera-sensor pixel space (uncalibrated pupil/CR centres).

  • href → head-referenced angular space (~261.8 units per visual degree).

Both fields below are in HREF space:

pcr_href_x, pcr_href_y — P-CR feature in HREF angular units (polynomial input). href_x, href_y — target HREF gaze direction (polynomial output).

Parsed from MSG <ts> !CAL <pcr_href_x>, <pcr_href_y>  <href_x>, <href_y>.

Parameters:
point_number: int
pcr_href_x: float
pcr_href_y: float
href_x: float
href_y: float
classmethod from_dict(data)[source]

Create CalibrationPoint from a dictionary.

Return type:

CalibrationPoint

Parameters:

data (dict[str, Any])

class syelink.models.PolynomialCoefficients(const, x, y, xx, yy)[source]

Bases: object

5th-order polynomial coefficients for coordinate mapping.

Formula from EyeLink ASC file: X=a+bx+cy+dxx+eyy, Y=f+gx+hy+ixx+jyy (Note: “goaly” in the raw file is a typo for “hy”)

The input x,y must be PRENORMALIZED RAW coordinates:

x = raw_x - prenorm_x y = raw_y - prenorm_y

Output is in HREF (head-referenced angular) coordinates.

Parameters:
const: float
x: float
y: float
xx: float
yy: float
classmethod from_dict(data)[source]

Create PolynomialCoefficients from a dictionary.

Return type:

PolynomialCoefficients

Parameters:

data (dict[str, Any])

apply(raw_x, raw_y)[source]

Apply coefficients to prenormalized RAW coordinates to get HREF coordinate.

Formula: val = const + x*rx + y*ry + xx*rx*rx + yy*ry*ry

Return type:

float

Parameters:
class syelink.models.CalibrationGains(cx, lx, rx, cy, ty, by)[source]

Bases: object

Calibration gain values for each axis.

These represent the sensitivity/gain of the eye tracker in different screen regions. Large values (>1000) often indicate calibration issues.

cx, lx, rx: center, left, right x gains cy, ty, by: center, top, bottom y gains

Parameters:
cx: float
lx: float
rx: float
cy: float
ty: float
by: float
classmethod from_dict(data)[source]

Create CalibrationGains from a dictionary.

Return type:

CalibrationGains

Parameters:

data (dict[str, Any])

class syelink.models.CornerCorrection(q0_x, q0_y, q1_x, q1_y, q2_x, q2_y, q3_x, q3_y)[source]

Bases: object

Corner correction coefficients for the 4 screen quadrants.

The polynomial mapping (HREF -> screen coords) has residual errors at the screen corners. These coefficients provide a secondary correction:

final_x = poly_x + corner_x[quadrant] * poly_x * poly_y final_y = poly_y + corner_y[quadrant] * poly_x * poly_y

Where poly_x, poly_y are the polynomial outputs before corner correction.

Quadrant indices (based on polynomial output signs):

0 = top-left (screen_x < 0, screen_y < 0) 1 = top-right (screen_x > 0, screen_y < 0) 2 = bottom-left (screen_x < 0, screen_y > 0) 3 = bottom-right (screen_x > 0, screen_y > 0)

Note: screen_y < 0 = top of screen in EyeLink’s internal coordinate system.

Parameters:
q0_x: float
q0_y: float
q1_x: float
q1_y: float
q2_x: float
q2_y: float
q3_x: float
q3_y: float
classmethod from_dict(data)[source]

Create CornerCorrection from a dictionary.

Return type:

CornerCorrection

Parameters:

data (dict[str, Any])

static get_quadrant(screen_x, screen_y)[source]

Determine which quadrant a point is in based on polynomial output.

Return type:

int

Parameters:
apply(poly_x, poly_y)[source]

Apply corner correction to polynomial output.

Parameters:
  • poly_x (float) – X coordinate from polynomial (before correction)

  • poly_y (float) – Y coordinate from polynomial (before correction)

Return type:

tuple[float, float]

Returns:

(corrected_x, corrected_y) after applying corner correction

class syelink.models.EyeCalibration(eye, result, points, polynomial_x=None, polynomial_y=None, gains=None, corner_correction=None, prenorm_x=0.0, prenorm_y=0.0)[source]

Bases: object

Calibration data for a single eye (LEFT or RIGHT).

The calibration process maps RAW camera coordinates to HREF angular coordinates. The polynomial coefficients (polynomial_x, polynomial_y) with prenormalization offsets (prenorm_x, prenorm_y) define this mapping.

Usage:
  1. Normalize: x = raw_x - prenorm_x, y = raw_y - prenorm_y

  2. Apply polynomial_x to get href_x (angular units)

  3. Apply polynomial_y to get href_y (angular units)

Parameters:
eye: Literal['LEFT', 'RIGHT']
result: Literal['GOOD', 'POOR', 'FAILED', 'FAIR']
points: list[CalibrationPoint]
polynomial_x: PolynomialCoefficients | None = None
polynomial_y: PolynomialCoefficients | None = None
gains: CalibrationGains | None = None
corner_correction: CornerCorrection | None = None
prenorm_x: float = 0.0
prenorm_y: float = 0.0
classmethod from_dict(data)[source]

Create EyeCalibration from a dictionary.

Return type:

EyeCalibration

Parameters:

data (dict[str, Any])

raw_to_href(raw_x, raw_y, apply_corner_correction=True)[source]

Convert RAW camera coordinates to HREF coordinates using this calibration.

The full pipeline:
  1. Prenormalize: x = raw_x - prenorm_x, y = raw_y - prenorm_y

  2. Apply polynomial: href_x, href_y = polynomial(x, y)

  3. Apply corner correction (if available and enabled): final = poly + corner_coeff[quadrant] * poly_x * poly_y

Parameters:
  • raw_x (float) – RAW camera x coordinate

  • raw_y (float) – RAW camera y coordinate

  • apply_corner_correction (bool) – Whether to apply corner correction (default True)

Return type:

tuple[float, float]

Returns:

(href_x, href_y) in head-referenced angular coordinates

class syelink.models.TargetPresentation(index, xy, draw_ts, erase_ts)[source]

Bases: object

One TARGET → TARGET_ERASED presentation window during a cal/val phase.

Each entry corresponds to one display of a calibration / validation target. If the same screen position is shown twice (e.g. EyeLink re-shows the centre), two TargetPresentation entries are emitted with the same index but different draw_ts / erase_ts.

index is the layout-relative index (e.g. 0..8 for HV9: 0=centre, 1=top, 2=bottom, 3=left, 4=right, 5=top-left, 6=top-right, 7=bottom-left, 8=bottom-right). None if the layout name was not recognised.

Parameters:
index: int | None
xy: tuple[float, float]
draw_ts: int
erase_ts: int
classmethod from_dict(data)[source]

Create TargetPresentation from a dictionary.

Return type:

TargetPresentation

Parameters:

data (dict[str, Any])

class syelink.models.CalibrationTargets(calibration_type, targets)[source]

Bases: object

Calibration/validation target positions.

Stores the actual screen positions where calibration or validation targets were displayed. For validations, parsed from the “at X,Y” part of VALIDATE messages. For calibrations, can be extracted from validation data of the same session.

Calibration types: - H3: horizontal 3-point calibration - HV3: 3-point calibration - HV5: 5-point calibration - HV9: 9-point grid calibration (most common) - HV13: 13-point calibration

Parameters:
calibration_type: str
targets: list[tuple[float, float]]
classmethod from_dict(data)[source]

Create CalibrationTargets from a dictionary.

Return type:

CalibrationTargets

Parameters:

data (dict[str, Any])

class syelink.models.CalibrationData(timestamp, calibration_type, tracking_mode, targets=None, left_eye=None, right_eye=None, presentations=<factory>, content=None)[source]

Bases: object

Complete calibration segment data.

Parameters:
timestamp: int
calibration_type: str
tracking_mode: str
targets: CalibrationTargets | None = None
left_eye: EyeCalibration | None = None
right_eye: EyeCalibration | None = None
presentations: list[TargetPresentation]
content: str | None = None
classmethod from_dict(data)[source]

Create CalibrationData from a dictionary.

Return type:

CalibrationData

Parameters:

data (dict[str, Any])

class syelink.models.ValidationSummary(eye, result, error_avg_deg, error_max_deg, offset_deg, offset_pix_x, offset_pix_y, ppd=None)[source]

Bases: object

Validation summary metrics for one eye.

Parameters:
eye: Literal['LEFT', 'RIGHT']
result: Literal['GOOD', 'POOR', 'FAILED', 'FAIR']
error_avg_deg: float
error_max_deg: float
offset_deg: float
offset_pix_x: float
offset_pix_y: float
ppd: float | None = None
classmethod from_dict(data)[source]

Create ValidationSummary from a dictionary.

Return type:

ValidationSummary

Parameters:

data (dict[str, Any])

class syelink.models.ValidationPoint(point_number, eye, offset_deg, offset_pix_x, offset_pix_y, gaze_x, gaze_y)[source]

Bases: object

Validation offset data for a single point and eye.

Does NOT store target positions (those are in CalibrationTargets). Stores only the offset/error data and calculated gaze position.

The gaze position is where the participant actually looked: gaze_x = target_x + offset_pix_x gaze_y = target_y + offset_pix_y

Parameters:
point_number: int
eye: Literal['LEFT', 'RIGHT']
offset_deg: float
offset_pix_x: float
offset_pix_y: float
gaze_x: float
gaze_y: float
classmethod from_dict(data)[source]

Create ValidationPoint from a dictionary.

Return type:

ValidationPoint

Parameters:

data (dict[str, Any])

class syelink.models.ValidationData(timestamp, validation_type, tracking_mode, targets=None, summary_left=None, summary_right=None, points=<factory>, presentations=<factory>, content=None)[source]

Bases: object

Complete validation segment data.

Parameters:
timestamp: int
validation_type: str
tracking_mode: str
targets: CalibrationTargets | None = None
summary_left: ValidationSummary | None = None
summary_right: ValidationSummary | None = None
points: list[ValidationPoint]
presentations: list[TargetPresentation]
content: str | None = None
classmethod from_dict(data)[source]

Create ValidationData from a dictionary.

Return type:

ValidationData

Parameters:

data (dict[str, Any])

class syelink.models.RecordingData(start_time, end_time, content=None)[source]

Bases: object

Recording segment metadata.

Parameters:
  • start_time (int)

  • end_time (int | None)

  • content (str | None)

start_time: int
end_time: int | None
content: str | None = None
classmethod from_dict(data)[source]

Create RecordingData from a dictionary.

Return type:

RecordingData

Parameters:

data (dict[str, Any])

class syelink.models.RawPupilData(pupil_x, pupil_y, pupil_area, pupil_width, pupil_height, cr_x, cr_y, cr_area, cr2_x=None, cr2_y=None, cr2_area=None)[source]

Bases: object

Raw pupil and corneal reflection data from eye tracker camera.

This data is only available when raw recording is enabled (record_raw_data=True in pyelink). Data is recorded as MSG lines with format: MSG <msg_ts> L <sample_ts> <px> <py> <pa> <width> <height> <crx> <cry> <crarea> <cr2x> <cr2y> <crarea2> R …

Values of -32768.0 or 4294934528.0 indicate missing/invalid data.

Parameters:
pupil_x: float | None
pupil_y: float | None
pupil_area: float | None
pupil_width: float | None
pupil_height: float | None
cr_x: float | None
cr_y: float | None
cr_area: float | None
cr2_x: float | None = None
cr2_y: float | None = None
cr2_area: float | None = None
classmethod from_dict(data)[source]

Create RawPupilData from a dictionary.

Return type:

RawPupilData

Parameters:

data (dict[str, Any])

class syelink.models.GazeSample(timestamp, segment, mode, tracking_mode, sample_rate, eyes_tracked, left_gaze_x, left_gaze_y, left_pupil, right_gaze_x, right_gaze_y, right_pupil, status, left_raw=None, right_raw=None, left_href_x=None, left_href_y=None, right_href_x=None, right_href_y=None, cal_target_index=None)[source]

Bases: object

Single gaze sample with optional raw pupil/CR data.

In RECORD mode: gaze fields contain screen gaze coordinates; raw fields contain camera-sensor pupil/CR data (when raw recording is enabled via MSG lines).

In CALIBRATE/VALIDATE modes: gaze fields are None (no screen gaze available); raw fields contain pupil coordinates from the sample line (EyeLink reports raw pupil position in the “gaze” field during calibration). CR data is not available.

HREF fields are populated only when an HREF-format ASC export (edf2asc -sh) is passed alongside the gaze ASC to parse_asc_file. Units are HREF angular units (~261.8 units / deg of visual angle).

Parameters:
  • timestamp (int)

  • segment (int)

  • mode (Literal['RECORD', 'CALIBRATE', 'VALIDATE', 'OFFLINE'])

  • tracking_mode (str)

  • sample_rate (int)

  • eyes_tracked (str)

  • left_gaze_x (float | None)

  • left_gaze_y (float | None)

  • left_pupil (float | None)

  • right_gaze_x (float | None)

  • right_gaze_y (float | None)

  • right_pupil (float | None)

  • status (str)

  • left_raw (RawPupilData | None)

  • right_raw (RawPupilData | None)

  • left_href_x (float | None)

  • left_href_y (float | None)

  • right_href_x (float | None)

  • right_href_y (float | None)

  • cal_target_index (int | None)

timestamp: int
segment: int
mode: Literal['RECORD', 'CALIBRATE', 'VALIDATE', 'OFFLINE']
tracking_mode: str
sample_rate: int
eyes_tracked: str
left_gaze_x: float | None
left_gaze_y: float | None
left_pupil: float | None
right_gaze_x: float | None
right_gaze_y: float | None
right_pupil: float | None
status: str
left_raw: RawPupilData | None = None
right_raw: RawPupilData | None = None
left_href_x: float | None = None
left_href_y: float | None = None
right_href_x: float | None = None
right_href_y: float | None = None
cal_target_index: int | None = None
classmethod from_dict(data)[source]

Create GazeSample from a dictionary.

Return type:

GazeSample

Parameters:

data (dict[str, Any])

class syelink.models.Message(timestamp, text)[source]

Bases: object

One user-sent MSG <timestamp> <text> line from the asc file.

Each entry corresponds to one tracker.send_message(text) call during the experiment (e.g. STEP_3_CALIBRATE_DARK_START, TARGET x=960 y=540). EyeLink-internal MSG lines (calibration coefficients, validation results, display setup, recording-mode/config rows, raw pupil/CR data) are filtered out by the parser; they’re already represented as CalibrationData / ValidationData / DisplayCoords.

Parameters:
timestamp: int
text: str
classmethod from_dict(data)[source]

Create a Message from a dict (e.g. loaded from JSON).

Return type:

Message

Parameters:

data (dict[str, Any])

class syelink.models.SessionData(calibrations=<factory>, validations=<factory>, recordings=<factory>, gaze_samples=<factory>, messages=<factory>, display_coords=None)[source]

Bases: object

Container for all session data.

Parameters:
calibrations: list[CalibrationData]
validations: list[ValidationData]
recordings: list[RecordingData]
gaze_samples: list[GazeSample]
messages: list[Message]
display_coords: DisplayCoords | None = None
to_dict()[source]

Convert the session data to a dictionary.

Return type:

dict[str, Any]

to_json(indent=4)[source]

Convert the session data to a JSON string.

Return type:

str

Parameters:

indent (int)

save_json(filepath)[source]

Save the session data to a JSON file.

Return type:

None

Parameters:

filepath (str)

save_metadata(filepath)[source]

Save session metadata to a text file.

Includes raw messages for calibrations and validations, and start/end for recordings.

Return type:

None

Parameters:

filepath (str | Path)

save_recordings_text(output_dir, filename_prefix='')[source]

Save all recording blocks to a single text file with headers.

Parameters:
  • output_dir (str | Path) – Directory to save the text file in.

  • filename_prefix (str) – Optional prefix for the filename (e.g., “subject01”). If provided, output will be “{prefix}_recordings.txt”. If empty, output will be “recordings.txt”.

Return type:

Path

Returns:

Path to the saved file.

save_calibrations_text(output_dir, filename_prefix='')[source]

Save all calibration blocks to a single text file with headers.

Parameters:
  • output_dir (str | Path) – Directory to save the text file in.

  • filename_prefix (str) – Optional prefix for the filename (e.g., “subject01”). If provided, output will be “{prefix}_calibrations.txt”. If empty, output will be “calibrations.txt”.

Return type:

Path

Returns:

Path to the saved file.

save_validations_text(output_dir, filename_prefix='')[source]

Save all validation blocks to a single text file with headers.

Parameters:
  • output_dir (str | Path) – Directory to save the text file in.

  • filename_prefix (str) – Optional prefix for the filename (e.g., “subject01”). If provided, output will be “{prefix}_validations.txt”. If empty, output will be “validations.txt”.

Return type:

Path

Returns:

Path to the saved file.

save_samples_csv(filepath)[source]

Save gaze samples to CSV file.

CSV columns: - timestamp: Sample timestamp (ms) - segment: Segment number (1-based) - mode: Recording mode (RECORD/CALIBRATE/VALIDATE/OFFLINE) - tracking_mode: Tracking mode (e.g., CR, P-CR) - sample_rate: Sampling rate in Hz - eyes_tracked: Eyes tracked (L/R/LR) - left_gaze_x, left_gaze_y, left_pupil: Left eye gaze data - right_gaze_x, right_gaze_y, right_pupil: Right eye gaze data - status: Status flags - left_raw_*: Left eye raw pupil/CR data (11 columns, empty if not available) - right_raw_*: Right eye raw pupil/CR data (11 columns, empty if not available)

Parameters:

filepath (str | Path) – Path to save CSV file

Return type:

Path

Returns:

Path to the saved file

classmethod from_dict(data)[source]

Create a SessionData object from a dictionary.

Return type:

SessionData

Parameters:

data (dict[str, Any])

classmethod load_json(filepath)[source]

Load session data from a JSON file.

Return type:

SessionData

Parameters:

filepath (str)