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.10.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 our ToyDataset and loading in its data:
[2]:
dataset = pm.Dataset('ToyDataset', path='data/ToyDataset')
dataset.download()
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, 25.0MB/s]
100%|██████████| 20/20 [00:00<00:00, 205.50it/s]
[2]:
<pymovements.dataset.dataset.Dataset at 0x7ff8cbf9a7f0>
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, 733.82it/s]
100%|██████████| 20/20 [00:00<00:00, 682.43it/s]
[3]:
| text_id | page_id | time | x_right_pix | y_right_pix | y_right_pos | x_right_pos | y_right_vel | x_right_vel |
|---|---|---|---|---|---|---|---|---|
| i64 | i64 | f64 | f64 | f64 | f64 | f64 | f64 | f64 |
| 0 | 1 | 1.988145e6 | 206.8 | 152.4 | -12.005591 | -7.528075 | -3.589697 | 1.221164 |
| 0 | 1 | 1.988146e6 | 206.9 | 152.1 | -12.01277 | -7.525633 | -7.179203 | 2.442343 |
| 0 | 1 | 1.988147e6 | 207.0 | 151.8 | -12.019949 | -7.52319 | -5.184827 | 1.628238 |
| 0 | 1 | 1.988148e6 | 207.1 | 151.7 | -12.022342 | -7.520748 | -4.386968 | 0.407059 |
| 0 | 1 | 1.988149e6 | 207.0 | 151.5 | -12.027128 | -7.52319 | -3.190445 | 0.407069 |
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, 368.13it/s]
[4]:
<pymovements.dataset.dataset.Dataset at 0x7ff8cbf9a7f0>
The detected events are added to the event dataframe:
[5]:
dataset.events[0].frame.head()
[5]:
| text_id | page_id | name | onset | offset | duration |
|---|---|---|---|---|---|
| i64 | i64 | str | i64 | i64 | i64 |
| 0 | 1 | "fixation" | 1988145 | 1988322 | 177 |
| 0 | 1 | "fixation" | 1988351 | 1988546 | 195 |
| 0 | 1 | "fixation" | 1988592 | 1988736 | 144 |
| 0 | 1 | "fixation" | 1988788 | 1989013 | 225 |
| 0 | 1 | "fixation" | 1989060 | 1989170 | 110 |
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, 74.41it/s]
[6]:
| text_id | page_id | name | onset | offset | duration |
|---|---|---|---|---|---|
| i64 | i64 | str | i64 | i64 | i64 |
| 0 | 1 | "saccade" | 1988323 | 1988337 | 14 |
| 0 | 1 | "saccade" | 1988547 | 1988567 | 20 |
| 0 | 1 | "saccade" | 1988737 | 1988760 | 23 |
| 0 | 1 | "saccade" | 1988765 | 1988777 | 12 |
| 0 | 1 | "saccade" | 1989014 | 1989031 | 17 |
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)