SpatialCalibration#

class pypillometry.SpatialCalibration(eye, model, points, measured, errors, screen_resolution=None)[source]#

Bases: Stateful

Store and analyze spatial calibration/validation data from eye-tracking.

Usually created from EyeLink data with from_eyelink().

Parameters:
  • eye (str) – Eye identifier (‘left’, ‘right’, ‘binocular’)

  • model (str) – Calibration model name (e.g., ‘HV9’, ‘HV13’)

  • points (ndarray) – Target points (N x 2): [x, y] in pixels

  • measured (ndarray) – Measured gaze points (N x 2): [x, y] in pixels

  • errors (ndarray) – Error values (N x 3): [offset, diff_x, diff_y], where offset is the error in degrees of visual angle and diff_x, diff_y are in pixels

  • screen_resolution (Optional[Tuple[int, int]]) – Screen resolution (width, height) in pixels; needed for the error surface in plot()

Attributes:
eyestr

Eye identifier (‘left’, ‘right’, ‘binocular’)

modelstr

Calibration model (e.g., ‘HV9’, ‘HV13’)

pointsnp.ndarray

Calibration target points (N x 2): [x, y] in pixels

measurednp.ndarray

Measured gaze points (N x 2): [x, y] in pixels

errorsnp.ndarray

Errors (N x 3): [offset (degrees), diff_x, diff_y (pixels)]

screen_resolutiontuple or None

Screen resolution (width, height) in pixels

Examples

>>> import numpy as np
>>> from pypillometry.eyedata.spatial_calibration import SpatialCalibration
>>> 
>>> # Create synthetic calibration data
>>> points = np.array([[640, 512], [640, 87], [640, 936]])
>>> errors = np.array([[0.3, -13.3, -1.6], [0.3, 13.2, -0.2], [0.42, 16.1, 9.2]])
>>> measured = points + errors[:, 1:]
>>> 
>>> cal = SpatialCalibration(
...     eye='left',
...     model='HV9',
...     points=points,
...     measured=measured,
...     errors=errors,
...     screen_resolution=(1920, 1080)
... )
>>> 
>>> print(cal.eye)
left
>>> print(cal.model)
HV9
>>> len(cal.points)
3

Methods

from_eyelink

Parse calibration data from eyelinkio format.

get_stats

Calculate calibration error statistics.

plot

Plot calibration accuracy with target points, measured points, and optional error surface.

Details

Parse calibration data from eyelinkio format.

Parameters:
  • calibration_data (dict) – Single calibration/validation entry from eyelinkio. Expected keys: ‘validation’ (required), ‘eye’ and ‘model’ (both default to ‘unknown’; ‘eye’ is lower-cased). ‘validation’ is a structured array with fields ‘point_x’, ‘point_y’ (target, pixels), ‘offset’ (error, degrees), ‘diff_x’ and ‘diff_y’ (error, pixels).

  • screen_resolution (Optional[Tuple[int, int]]) – Screen resolution (width, height) in pixels

Return type:

SpatialCalibration

Returns:

Parsed calibration object

Examples

>>> import numpy as np
>>> from pypillometry.eyedata.spatial_calibration import SpatialCalibration
>>> 
>>> # Create mock EyeLink validation data
>>> validation_array = np.array([
...     (640., 512., 0.3, -13.3, -1.6),
...     (640., 87., 0.3, 13.2, -0.2),
...     (640., 936., 0.42, 16.1, 9.2)
... ], dtype=[('point_x', '<f8'), ('point_y', '<f8'), ('offset', '<f8'),
...           ('diff_x', '<f8'), ('diff_y', '<f8')])
>>> 
>>> eyelink_data = {
...     'eye': 'left',
...     'model': 'HV9',
...     'validation': validation_array
... }
>>> 
>>> cal = SpatialCalibration.from_eyelink(eyelink_data, (1920, 1080))
>>> print(cal.eye)
left
>>> print(cal.model)
HV9
>>> len(cal.points)
3
>>> float(cal.points[0, 0])
640.0
get_stats()[source]#

Calculate calibration error statistics.

Return type:

Dict[str, float]

Returns:

Statistics including: n, mean, sd, max, min (errors in degrees)

Examples

>>> import numpy as np
>>> from pypillometry.eyedata.spatial_calibration import SpatialCalibration
>>> 
>>> points = np.array([[640, 512], [640, 87], [640, 936]])
>>> errors = np.array([[0.3, -13.3, -1.6], [0.5, 13.2, -0.2], [0.42, 16.1, 9.2]])
>>> measured = points + errors[:, 1:]
>>> 
>>> cal = SpatialCalibration('left', 'HV9', points, measured, errors)
>>> stats = cal.get_stats()
>>> stats['n']
3
>>> f"{stats['mean']:.2f}"
'0.41'
>>> f"{stats['max']:.2f}"
'0.50'
plot(show_surface=True, interpolation='rbf', title=None, ax=None)[source]#

Plot calibration accuracy with target points, measured points, and optional error surface.

Shows target points as black crosses, measured points as colored plus markers overlaid on an optional interpolated error surface (offset in degrees).

Parameters:
  • show_surface (bool, default True) – If True, show interpolated error surface as background (requires screen_resolution). If False, show only the calibration points.

  • interpolation (str, default 'rbf') –

    Interpolation method for surface (only used if show_surface=True). Options:

    • ’rbf’: Radial basis function (smooth, good for scattered data)

    • ’linear’, ‘cubic’, ‘nearest’: griddata methods

  • title (str, optional) – title of the plot; default: the eye and the calibration model

  • ax (matplotlib.axes.Axes, optional) – axes to plot on; default: the current axes

Return type:

matplotlib.axes.Axes

Returns:

the axes of the plot

Raises:

ValueError – If show_surface is True and screen_resolution is not set.

Examples

>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> from pypillometry.eyedata.spatial_calibration import SpatialCalibration
>>> 
>>> points = np.array([[640, 512], [640, 87], [640, 936],
...                    [96, 512], [1183, 512], [161, 138],
...                    [1118, 138], [161, 885], [1118, 885]])
>>> errors = np.array([[0.3, -13, -2], [0.3, 13, -0.2], [0.42, 16, 9],
...                    [0.79, -19, 30], [0.62, 13, 24], [0.69, 22, 22],
...                    [0.5, 22, 0.8], [0.05, -2, 0.6], [0.24, -9, -6]])
>>> measured = points + errors[:, 1:]
>>> 
>>> cal = SpatialCalibration('left', 'HV9', points, measured, errors, (1920, 1080))
>>> 
>>> # Plot with surface
>>> ax = cal.plot()
>>> 
>>> # Plot without surface
>>> fig, ax = plt.subplots()
>>> ax = cal.plot(show_surface=False, ax=ax)