Skip to main content

PyEtSimul: An Open-Source Python Software Framework for Eye Tracking Simulation

PyPI version Downloads License Documentation DOI

PyEtSimul is an open-source Python framework for simulating video-based eye trackers by generating synthetic eye features through geometric modeling. The framework allows flexible positioning of eyes, cameras, and light sources in 3D space, with controlled variation of eye anatomical features and camera properties. For full documentation, see pyetsimul.readthedocs.io.

About

Core functionalities are based on "A Software Framework for Simulating Eye Trackers" by Böhme et al. (2008), ported from the original MATLAB codebase. This Python implementation includes enhancements, improvements, bug fixes, and additional features.

[!WARNING] Note: There is no guarantee that this code works exactly like the original MATLAB implementation.

Features

PyEtSimul represents a video-based eye tracker as a 3D scene of eyes, cameras and lights, and renders the pupil and corneal reflections (glints) each camera would see.

  • Eye models — named models ("PyEtSimul", "et_simul", "gkaModelEye") selected by name, or your own via the immutable EyeModel.
  • Cornea — spherical, conic and toric surfaces, with an optional posterior surface.
  • Pupil — elliptical and realistic (Wyatt, 1995) shapes, plus pupil-size decentration (the pupil centre shifts as pupil size changes).
  • Eyelids — an adjustable lid that occludes the pupil.
  • Glints — corneal reflections of one or more lights, with optional detection noise.
  • Camera — a pinhole model, or a full OpenCV camera with intrinsics and lens distortion.
  • Gaze models — polynomial, Stampe (1993), homography-normalization, and custom mappings.
  • Datasets and evaluation — generate labelled pupil/glint observations across gaze targets and parameter variations, and score calibration and gaze accuracy.

Installation

Requirements

  • Python ≥3.11

From PyPI

pip install pyetsimul

Using uv

uv pip install pyetsimul

From source

git clone https://github.com/mh-salari/pyetsimul.git
cd pyetsimul
uv sync

Or with pip:

git clone https://github.com/mh-salari/pyetsimul.git
cd pyetsimul
python3 -m pip install .

For development:

git clone https://github.com/mh-salari/pyetsimul.git
cd pyetsimul
python3 -m pip install -e .

Quickstart

Distances are in millimetres, in a right-handed frame: +x right, +y depth (away from the camera), +z up.

from pyetsimul.core import Camera, Eye, Light
from pyetsimul.types import Position3D

eye = Eye()  # a bare Eye() uses the default "PyEtSimul" model
eye.position = Position3D(0, 250, 100)
eye.look_at(Position3D(-50, 0, 50))  # fixate a point in the world

camera = Camera()
camera.point_at(eye.position)  # aim the camera at the eye

light = Light(position=Position3D(100, 0, 0))  # the glint is this light's reflection on the cornea

image = camera.take_image(eye, [light])
print(image.pupil_center)             # pupil centre in image pixels
print(image.corneal_reflections[0])   # glint in image pixels

Examples

The examples/ directory is an ordered, self-contained series. Start at 01, or open the one you need — each script runs top to bottom.

Example What you learn
01_hello_PyEtSimul build a scene (Eye, Camera, Light) and read the pupil centre + glint
02_visualize_setup interactive 3D scene + camera view (move the eye and target live)
03_eye_models the named models "PyEtSimul" / "et_simul" / "gkaModelEye" side by side
04_cornea_models spherical vs conic vs toric cornea
05_pupil_models elliptical vs realistic pupil across sizes, with pupil-size decentration
06_eyelid eyelid openness and its occlusion of the pupil
07_glint_noise glint detection-noise models
08_camera_distortion pinhole vs a real OpenCV lens (intrinsics + distortion)
09_two_eyes_one_camera a binocular pair imaged by one camera
10_two_eyes_two_cameras a binocular pair imaged by two cameras
11_generate_dataset render a gaze grid and save/load a labelled dataset
12_calibrate calibrate a gaze model on an HV9 grid and measure accuracy (interactive)
13_validate gaze accuracy across the screen and as the head moves
14_custom_eye_model build a custom EyeModel from scratch (cornea, kappa, look-at, rotation centre), then derive a variant with copy()
15_custom_gaze_model register a custom polynomial gaze model
16_custom_variation sweep any eye parameter (built-in or a custom GenericEyeVariation)

Validation

PyEtSimul reproduces two independent eye models 1:1: the original et_simul (this is a Python port of it) and the gkaModelEye schematic eye. The validation/ directory holds the MATLAB references and the tests that assert the simulated pupil centre and glint match them at each gaze target.

Citation

Cite as:

Salari, M., Niehorster, D. C., Hansen, D. W., & Bednarik, R. (2026).
PyEtSimul: An Open-Source Python Framework for Eye-Tracking Simulation.
Proceedings of the ACM on Human-Computer Interaction (PACMHCI), ETRA 2026. ACM.
DOI: 10.1145/3806023

Also cite the original work:

Martin Böhme, Michael Dorr, Mathis Graw, Thomas Martinetz, and Erhardt Barth.
"A software framework for simulating eye trackers."
In Proceedings of the 2008 Symposium on Eye Tracking Research & Applications (ETRA '08),
pages 251-258, ACM, 2008.

Original MATLAB Implementation

For the original MATLAB version and detailed background, visit: https://github.com/mh-salari/et_simul-1.01

Acknowledgments

This project has received funding from the European Union's Horizon Europe research and innovation funding program under grant agreement No 101072410, Eyes4ICU project.

Funded by EU Eyes4ICU

License

GPL-3.0-or-later

Release files for pyetsimul 5.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pyetsimul 5.1.0
File Size Uploaded
pyetsimul-5.1.0.tar.gz 1.0 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for pyetsimul 5.1.0
File Interpreter ABI Platform
pyetsimul-5.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 1.2 MB

Release files / pyetsimul-5.1.0.tar.gz

Download URL pyetsimul-5.1.0.tar.gz
Size 1.0 MB
Tags Source
SHA-256 checksum
How to use checksums
20dd20953eda43e494227426a9376e4ef8e844f5fd9bfab89def822b13a32b1f
BLAKE2b-256 checksum
How to use checksums
a9470b706adba0a2b08bc8280ffb52d554266782a2f394014a56e6b5124b3df6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release files / pyetsimul-5.1.0-py3-none-any.whl

Download URL pyetsimul-5.1.0-py3-none-any.whl
Size 217.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9eb30dbe97cb684d88e49d92906e55ea8c3ca243f7124c1bd0230442675c1041
BLAKE2b-256 checksum
How to use checksums
8c0462942b872b4cede0567d5570ae619d87ef05a0b098f1227dd33d0874e5ca
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release history Release notifications | RSS feed

This release

5.1.0 This release

2 release files

5.0.1

2 release files

5.0.0

2 release files

4.0.0

2 release files

3.6.0

2 release files

3.5.0

2 release files

3.4.0

2 release files

3.3.0

2 release files

3.2.5

2 release files

3.2.4

2 release files

3.2.3

2 release files

3.2.2

2 release files

3.2.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page