Fixations and Saccades

Fixations are periods where the gaze remains relatively stable on a point of interest, while saccades are rapid eye movements between fixation points.

The threshold time in Sightlab is used to calculate the dwell time. This value represents the duration for which the gaze must remain "fixated" on a target object or a region of interest to start recording dwell time. You can adjust this threshold to suit the specifics of your experiment.

For detecting saccades and fixations, SightLab uses a dispersion method that relies on angular distances. 

There are two ways to measure fixations and saccades using angular distance. For either one saccades are also shown as red lines on the scan path in the session replay. Both of these can be used alongside one another. 

First way:

As of version 1.9.5 fixation and saccade status are saved by default in the experiment_data.csv file. 

These values can be adjusted in the settings.py file

#Fixation/ Gaze Time threshold

THRESHOLD = 0.5

#Angles in degree for fixation detection

FIXATION_ANGLE = 1

#Set to true if using time duration and spatial degree for fixations

USE_SPATIAL_PLUS_THRESHOLD = False

For 1.9.4 and earlier: In the ExampleScripts folder you can find in the folder Fixation_Saccade a script called "SightLabVR_fixations.py". This will then save the fixation status in the data file called "experiment_data.csv" in utils/data. 

The FIXATION_ANGLE is a value that determines the maximum amount of change (in gaze direction, specifically yaw and pitch) that is still considered a fixation. If the change in yaw and pitch from the previous gaze position to the current one is less than or equal to this threshold, it's treated as a fixation. If the change is greater than this threshold, it's treated as a saccade, indicating the eye is moving and not fixated.

The current setting is to be 1 degree of Euler rotation

Additionally, if you set USE_SPATIAL_PLUS_THRESHOLD = True, you can add the THRESHOLD time as another check for fixations to account for noise. This will only detect fixations if they meet the angular distance the time duration.  

This can be adjusted post session with some script that are found in ExampleScripts- Adjusting_Gaze_Data_Post_Session

Second way:

This method can check for fixations and saccades on the replay side. You can find the relevant parameters in the “settings.py” file. You will see the following values:

LINEFREQUENCY = 1 SACCADE_ANGLE1 = 10

SACCADE_ANGLE12 = 100

LINEFREQUENCY controls the frequency at which gaze points are sampled. You can modify this to change the sampling rate. SACCADE_ANGLE1 and SACCADE_ANGLE12 are the thresholds used in saccade detection. These values represent the minimum and maximum angular distances (in degrees) that define a saccade. Adjusting these values will change the sensitivity of the saccade detection.

Lowering the minimum angle (SACCADEANGLE1) would increase sensitivity to smaller saccades, while raising the maximum angle (SACCADEANGLE12) would allow the detection of larger saccades.

To help you track the state of the eye (fixation or saccade) during a session, you could add print statements in the session_replay module (located in the utils folder). On line 664, you can modify the code as follows:

if saccadeAngle > SACCADEANGLE1 and saccadeAngle < SACCADEANGLE12:

    viz.startLayer(viz.LINES)

   viz.lineWidth(2)

    viz.vertexColor(viz.RED)

    viz.vertex(begin)

    viz.vertex(end)

    print('saccade') # Prints when a saccade is detected

    lineLayer = viz.endLayer()

    self.gazePath["LINE_LAYERS"].append(lineLayer)

else:

    print('fixation') # Prints when a fixation is detected

This will print 'saccade' when a saccade is detected and 'fixation' when a fixation is detected.

Note that the angle between the gaze vectors is calculated using the vizmat.AngleBetweenVector(endVector, beginVector) function. These are in degrees. 


Default Dwell Time and Fixation Collection

Here's the information that is the default with Sightlab if you don't add the dispersion method for measuring fixations mentioned above:

When a user's gaze remains on a specific object or point in the virtual environment for a predetermined duration, the onGazeTime function is triggered. This function is part of a system of gaze event handlers, which also include onGazeBegin and onGazeEnd, to manage the start and end of gaze interactions. Specifically, onGazeTime is responsible for capturing events where the gaze duration meets or exceeds a set threshold, indicating a fixation.