While it is generally agreed that blinks need to be taken care of during preprocessing, most eye tracking software does not include this event information. This has lead to the development of several great blink algorithms. I decided to implement a velocity based one off Matĥot (2013) in gazeR.The code itself very simple and intuitive algorithm and does a nice job recovering the pupil data.
This vignette will show how you the steps involved in identifying blinks that underlie theblink_velocity function in gazeR.
For blink detection we are using a variation of Mathôt’s (2013) approach.I found some parts hard to follow. First the
uncorrected pupil signal for a single trial from a single subject is plotted as a continuous signal.
The signal is measured in arbitrary units as outputted by Eyelink’s software
(Please check your own data before using this). In the below figure, it is clear
to see that the participant blinked three times during the trial. Eye blinks are
characterized by a pronounced drop in the pupillary signal, followed by a full loss of signal,
and then usually a recovery artifact when the signal comes back online.
In order to detect these events systematically, I calculated a
velocity profile for each trace. However, the original signal is too noisy to create a reliable
profile. In order to detect blinks efficiently, I began by smoothing the signal using a weighted
moving window average of 10 samples (i.e., 20 ms; 250 Hz tracker).
Next I created a velocity profile by subtracting each sample from the immediately
preceding sample in the signal.
Blink onsets were subsequently identified as occurring when the velocity crossed
a predetermined negative threshold (I selected -5 based on Mathot’s (2013) recommendation.
This rapid decrease in pupil diameter corresponds to the
apparent decrease in size of the pupil as the eyelid closes. Likewise, when the eyelid reopens
there is a recovery artifact wherein pupil size rapidly gets larger. Thus, the algorithm detected the
recovery period by indexing the time since onset that velocity exceed some positive threshold (I
selected -5, again based off Matĥot (2013) recommendation). Finally, the offset was detected as the time at
which velocity fell back down to 0. In this way, a blink corresponds to an onset, recovery, and
offset index. According to Mathôt (2013), this detection algorithm underestimates the blink
period by several milliseconds, thus I selected a margin value (10 ms) which was subtracted from
the onset and added to the offset using the ’extend_blinks` function in gazeR.
Finally, the pupil signal was then linearly interpolated.
By looking at interpolated data plotted over the raw data we can see that the algo
did a pretty good job at finding the blinks and recovering the pupil signal.
These steps are all contained in the blink_mathot function.