Detecting Gaze Events#

What you will learn in this tutorial:#

  • how to detect fixations using the I-VT algorithm

  • how to detect saccades using the microsaccades algorithm

Preparations#

We import pymovements as the alias pm for convenience.

[1]:
import polars as pl

import pymovements as pm
/home/docs/checkouts/readthedocs.org/user_builds/pymovements/envs/v0.7.0/lib/python3.9/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
  from .autonotebook import tqdm as notebook_tqdm

Let’s start by downloading and extracting our ToyDataset:

[2]:
dataset = pm.datasets.ToyDataset(root='data/')
dataset.download()
dataset.extract()
dataset.load()
Downloading http://github.com/aeye-lab/pymovements-toy-dataset/zipball/6cb5d663317bf418cec0c9abe1dde5085a8a8ebd/ to data/ToyDataset/downloads/pymovements-toy-dataset.zip
pymovements-toy-dataset.zip: 100%|██████████| 3.06M/3.06M [00:00<00:00, 23.9MB/s]
100%|██████████| 20/20 [00:00<00:00, 201.82it/s]

Now let’s do some basic preprocessing:

[3]:
dataset.pix2deg()
dataset.pos2vel('smooth')

dataset.gaze[0].frame.head()
100%|██████████| 20/20 [00:00<00:00, 813.32it/s]
100%|██████████| 20/20 [00:00<00:00, 675.57it/s]
[3]:
shape: (5, 9)
text_idpage_idtimex_right_pixy_right_pixy_right_posx_right_posx_right_vely_right_vel
i64i64f64f64f64f64f64f64f64
011.988145e6206.8152.4-12.005591-7.5280751.221164-3.589697
011.988146e6206.9152.1-12.01277-7.5256332.442343-7.179203
011.988147e6207.0151.8-12.019949-7.523191.628238-5.184827
011.988148e6207.1151.7-12.022342-7.5207480.407059-4.386968
011.988149e6207.0151.5-12.027128-7.523190.407069-3.190445

Detecting Events#

pymovements provides a range of event detection methods for several types of gaze events.

See the reference for pymovements.events to get an overview of all the supported methods.

For this tutorial we will use the I-VT algorithm for detecting fixations and the microsaccades algorithm for detecting saccades.

We start with the I-VT algorithm to detect fixations using the default parameteres:

[4]:
dataset.detect_events(pm.events.ivt)
20it [00:00, 263.53it/s]

The detected events are added to the event dataframe:

[5]:
dataset.events[0].frame.head()
[5]:
shape: (5, 6)
text_idpage_idnameonsetoffsetduration
i64i64stri64i64i64
01"fixation"19881451988322177
01"fixation"19883511988546195
01"fixation"19885921988736144
01"fixation"19887881989013225
01"fixation"19890601989170110

Next we detect some saccades. This time we don’t use the default parameters but specify our own:

[6]:
dataset.detect_events(pm.events.microsaccades, minimum_duration=12)

dataset.events[0].frame.filter(pl.col('name') == 'saccade').head()
20it [00:00, 66.91it/s]
[6]:
shape: (5, 6)
text_idpage_idnameonsetoffsetduration
i64i64stri64i64i64
01"saccade"1988323198833714
01"saccade"1988547198856720
01"saccade"1988737198876023
01"saccade"1988765198877712
01"saccade"1989014198903117

This has added new rows with the saccade events to the event dataframe.

What you have learned in this tutorial:#

  • detecting fixations by using Dataset.detect_events(pm.events.fixations)

  • detecting saccades by using Dataset.detect_events(pm.events.microsaccades)