ExperimentalSetup#
- class pypillometry.ExperimentalSetup(screen_resolution=None, physical_screen_size=None, screen_offset=None, eye_to_screen_center=None, screen_pitch=None, screen_yaw=None, camera_offset=None, camera_spherical=None, ipd=None)[source]#
Bases:
StatefulComplete geometric model of an eye-tracking experimental setup.
Encapsulates:
Screen geometry (resolution, physical size)
Eye position relative to screen (perpendicular distance and offset)
Screen orientation (pitch and yaw tilt angles)
Camera position (relative to screen or eye)
Inter-pupillary distance (for binocular setups)
Provides:
Coordinate conversion between pixels and mm
Transformation from screen coordinates to eye-centered 3D frame
Validation of parameter consistency
Visualization of the setup geometry
Serialization for saving/loading
All parameters are optional; an incomplete setup can be created and used for whatever is set (accessing a missing value raises
ValueError). Lengths and angles can be given as plain numbers, as strings with units (e.g.,"52 cm","-5 deg") or with a unit (e.g.,52 * pp.u.cm). Plain numbers are interpreted as mm (lengths) or radians (angles), with a one-time warning.- Parameters:
screen_resolution (
Optional[Tuple[int,int]]) – Screen resolution in pixels (width, height).physical_screen_size (
Optional[Tuple[Union[float,str],Union[float,str]]]) – Physical screen dimensions (width, height); each element a length (default unit mm), e.g.,("52 cm", "29 cm").screen_offset (
Optional[Tuple[Union[float,str],Union[float,str]]]) – Offset of screen center from the eye reference point (delta_x, delta_y); each element a length (default unit mm). Default (0, 0). Positive delta_x = screen center is to the right of eye. Positive delta_y = screen center is above eye. Note: For binocular setups, the reference is the midpoint between the two eyes (root of nose).eye_to_screen_center (
Union[float,str,None]) – Distance from eye to screen center (default unit mm), e.g.,"65 cm". The perpendicular distance d between eye and screen plane is computed fromd = sqrt(eye_to_screen_center**2 - delta_x**2 - delta_y**2). If screen_offset is (0, 0) or not set, d equals eye_to_screen_center. RaisesValueErrorif it is smaller than the screen offset. Note: For binocular setups, “eye” refers to the midpoint between the two eyes (root of nose).screen_pitch (
Union[float,str,None]) – Screen pitch angle (alpha_tilt; default unit radians), e.g.,"-5 deg". Rotation about horizontal axis. Positive = top of screen tilted away from eye. Default 0.screen_yaw (
Union[float,str,None]) – Screen yaw angle (beta_tilt; default unit radians), e.g.,"3 deg". Rotation about vertical axis. Positive = right side of screen closer to eye. Default 0.camera_offset (
Optional[Tuple[Union[float,str],Union[float,str],Union[float,str]]]) – Camera position as (x, y, z) offset from eye; each element a length (default unit mm). z-axis points toward screen center. Takes precedence over camera_spherical if both are given.camera_spherical (
Optional[Tuple[Union[float,str],Union[float,str],Union[float,str]]]) – Alternative: camera position in spherical coordinates (theta, phi, r) relative to eye: theta is the polar angle from the z-axis and phi the azimuthal angle in the x-y plane (angles, default unit radians); r is the distance from eye (length, default unit mm).ipd (
Union[float,str,None]) – Inter-pupillary distance for binocular setups (default unit mm), e.g.,"63 mm".
- Attributes:
screen_resolutiontupleScreen resolution (width, height) in pixels, or None if not set.
physical_screen_sizetuplePhysical screen size (width, height) in mm, or None if not set.
dfloatPerpendicular eye-to-screen distance in mm.
delta_xfloatScreen center x-offset from eye in mm (positive = screen right of eye).
delta_yfloatScreen center y-offset from eye in mm (positive = screen above eye).
alpha_tiltfloatScreen pitch angle in radians (positive = top tilted away).
beta_tiltfloatScreen yaw angle in radians (positive = right side closer).
rfloatEye-to-camera distance in mm.
thetafloatCamera polar angle from z-axis in eye-centered coords (radians).
phifloatCamera azimuthal angle in eye-centered coords (radians).
ipdfloat or NoneInter-pupillary distance in mm, or None if not set.
Notes
All coordinates are in an eye-centric reference frame where:
The origin is at the eye position
For binocular setups, this is the midpoint between the two eyes (root of nose)
z-axis points toward the screen center
x-axis points to the right
y-axis points upward
Examples
>>> # Basic setup with distance to screen center >>> setup = ExperimentalSetup( ... screen_resolution=(1920, 1080), ... physical_screen_size=("52 cm", "29 cm"), ... eye_to_screen_center="65 cm", ... camera_offset=("0 cm", "-30 cm", "0 cm"), # camera below screen ... ) >>> print(f"d = {setup.d} mm") d = 650.0 mm
>>> # Setup with screen offset and tilt >>> setup = ExperimentalSetup( ... screen_resolution=(1920, 1080), ... physical_screen_size=("52 cm", "29 cm"), ... eye_to_screen_center="65 cm", ... screen_offset=("3 cm", "-1.5 cm"), # screen right and below eye ... screen_pitch="-5 deg", # screen tilted back ... camera_offset=("0 cm", "-30 cm", "0 cm"), ... )
>>> # Visualize the setup >>> fig = setup.plot()
Methods
Convert visual angles to mm coordinates (relative to screen center).
Convert visual angles to pixel coordinates.
Create ExperimentalSetup from dictionary.
Check if camera position is set.
Check if eye-to-screen distance is set.
Check if screen resolution and physical size are set.
Check if setup has all parameters needed for foreshortening correction.
Convert mm coordinates (relative to screen center) to visual angles.
Convert mm coordinates to pixels.
Convert pixel coordinates to visual angles.
Convert pixel coordinates to mm.
Visualize the experimental setup geometry.
Transform screen point(s) from screen-centered mm to eye-centered 3D frame.
Return a summary of the experimental setup as a dictionary.
Export setup to dictionary for JSON serialization.
Validate parameter consistency.
Details
- classmethod from_dict(d)[source]#
Create ExperimentalSetup from dictionary.
- Parameters:
- Return type:
- degrees_to_mm(angle_x, angle_y)[source]#
Convert visual angles to mm coordinates (relative to screen center).
- Parameters:
angle_x (
Union[float,str,ndarray]) – Visual angles. Plain numbers and arrays are in degrees (like the output ofmm_to_degrees()). Strings with units, e.g.,"5 deg","0.087 rad", or quantities are converted. Positive x = right, positive y = up.angle_y (
Union[float,str,ndarray]) – Visual angles. Plain numbers and arrays are in degrees (like the output ofmm_to_degrees()). Strings with units, e.g.,"5 deg","0.087 rad", or quantities are converted. Positive x = right, positive y = up.
- Return type:
- Returns:
x_mm, y_mm (float or array) – Coordinates in mm relative to screen center. Positive x = right, positive y = up.
Notes
Inverse of mm_to_degrees: x_mm = d * tan(angle)
- degrees_to_pixels(angle_x, angle_y)[source]#
Convert visual angles to pixel coordinates.
- Parameters:
angle_x (
Union[float,str,ndarray]) – Visual angles, in the same forms as fordegrees_to_mm(): plain numbers and arrays are degrees, strings and Quantities carry their units. Positive x = right, positive y = up.angle_y (
Union[float,str,ndarray]) – Visual angles, in the same forms as fordegrees_to_mm(): plain numbers and arrays are degrees, strings and Quantities carry their units. Positive x = right, positive y = up.
- Return type:
- Returns:
x_px, y_px (float or array) – Coordinates in pixels (origin at upper-left, y increases downward).
Notes
Combines degrees_to_mm and mm_to_pixels (centered). The y-axis is flipped (in mm_to_pixels): visual angle y increases upward, but pixel y increases downward.
- has_camera_position()[source]#
Check if camera position is set.
- Return type:
- Returns:
True if camera_offset or camera_spherical was given.
- has_eye_distance()[source]#
Check if eye-to-screen distance is set.
- Return type:
- Returns:
True if the eye-to-screen distance (d) is set.
- has_screen_info()[source]#
Check if screen resolution and physical size are set.
- Return type:
- Returns:
True if both screen_resolution and physical_screen_size are set.
- is_complete()[source]#
Check if setup has all parameters needed for foreshortening correction.
- Return type:
- Returns:
True if d and camera position are set.
- mm_to_degrees(x_mm, y_mm)[source]#
Convert mm coordinates (relative to screen center) to visual angles.
- Parameters:
- Return type:
- Returns:
angle_x, angle_y (float or array) – Visual angles in degrees. Positive x = right, positive y = up.
Notes
Computes
angle = arctan(distance / d)separately for x and y, where d is the perpendicular eye-to-screen distance. This assumes the eye is opposite the screen center; screen_offset and screen tilt are not taken into account.
- mm_to_pixels(x_mm, y_mm, centered=True)[source]#
Convert mm coordinates to pixels.
- Parameters:
- Return type:
- Returns:
x_px, y_px (float or array) – Coordinates in pixels (origin at upper-left, y increases downward)
Notes
Requires screen_resolution and physical_screen_size. Inverse of
pixels_to_mm()(the y-axis is flipped).
- pixels_to_degrees(x_px, y_px)[source]#
Convert pixel coordinates to visual angles.
- Parameters:
- Return type:
- Returns:
angle_x, angle_y (float or array) – Visual angles in degrees relative to screen center. Positive x = right, positive y = up.
Notes
Combines pixels_to_mm (centered) and mm_to_degrees. The y-axis is flipped (in pixels_to_mm): pixel y increases downward, but visual angle y increases upward.
- pixels_to_mm(x_px, y_px, centered=True)[source]#
Convert pixel coordinates to mm.
- Parameters:
x_px (
Union[float,ndarray]) – Coordinates in pixels (origin at upper-left, y increases downward)y_px (
Union[float,ndarray]) – Coordinates in pixels (origin at upper-left, y increases downward)centered (
bool) – If True, output is relative to screen center. If False, output is relative to the lower-left screen corner.
- Return type:
- Returns:
x_mm, y_mm (float or array) – Coordinates in mm; positive x = right, positive y = up
Notes
Requires screen_resolution and physical_screen_size. The y-axis is flipped: pixel y increases downward, but mm y increases upward (as everywhere in the eye/screen geometry).
- plot(theta=None, phi=None, projection='2d', show_gaze_samples=True, n_gaze_samples=9, viewing_angle=None, title=None, axes=None, figsize=None)[source]#
Visualize the experimental setup geometry.
- Parameters:
theta (
float) – Camera polar angle in radians (plain number only). If None, uses setup’s theta. The camera distance is always taken from the setup (0 if no camera position is set).phi (
float) – Camera azimuthal angle in radians (plain number only). If None, uses setup’s phi.projection (
str) –Type of projection (case-insensitive):
’2d’: Three orthogonal 2D views (front, top, side)
’3d’: Interactive 3D view
show_gaze_samples (
bool) – Whether to show sample gaze vectors to screenn_gaze_samples (
int) – Number of sample gaze positions; drawn as a square grid withint(sqrt(n_gaze_samples))points per side.viewing_angle (
tuple) – Viewing angle for 3D projection (elev, azim) or (elev, azim, roll) in degrees. Default is (-49, 50, 45) for 3D.title (
str) – title of the figure; default: the camera anglesaxes (matplotlib Axes or list of Axes, optional) – axes to plot on: three axes (front, top, side view) for ‘2d’, one 3D axes for ‘3d’; default: a new figure
figsize (
tuple) – size of the new figure; default (15, 5) for ‘2d’, (10, 8) for ‘3d’
- Return type:
- Returns:
the figure (
fig.axesare the axes of the views)- Raises:
ValueError – If screen info or eye-to-screen distance is not set, if theta or phi is None and no camera position is set, or if projection is not ‘2d’ or ‘3d’.
Examples
>>> import pypillometry as pp >>> import matplotlib.pyplot as plt >>> setup = pp.ExperimentalSetup( ... screen_resolution=(1920, 1080), ... physical_screen_size=("52 cm", "29 cm"), ... eye_to_screen_center="60 cm", ... camera_spherical=("20 deg", "-90 deg", "70 cm"), ... ) >>> fig = setup.plot() # 2D views >>> fig = setup.plot(projection='3d') # 3D view
- screen_point_to_eye_frame(x_mm, y_mm)[source]#
Transform screen point(s) from screen-centered mm to eye-centered 3D frame.
Applies screen tilt rotation and eye offset translation.
- Parameters:
- Return type:
Tuple[Union[float,ndarray],Union[float,ndarray],Union[float,ndarray]]- Returns:
T_x, T_y, T_z (float or array) – 3D coordinates in eye-centered frame (mm)
Notes
Uses the transformation from algorithm document Section 10.7.3: T(x_s, y_s) = R(alpha, beta) @ [x_s, y_s, 0]^T + [delta_x, delta_y, d]^T, i.e., the screen center is at (delta_x, delta_y, d) for any tilt.
- validate()[source]#
Validate parameter consistency. Raises ValueError if invalid.
Only validates parameters that are set; incomplete setups are allowed.
- Return type:
- property camera_position: Optional[Tuple[float, float, float]]#
Camera position (cx, cy, cz) in eye-centered frame in mm.
Eye is at origin, z-axis points toward screen center. Returns Cartesian coordinates computed from either camera_offset or camera_spherical.
- property physical_screen_size: Optional[Tuple[float, float]]#
Physical screen size (width, height) in mm, or None if not set.
- property screen_offset: Tuple[float, float]#
Screen center offset from eye (delta_x, delta_y) in mm.