PyGaze (eye tracking)
- About
- Supported eye trackers
- Installing PyGaze
- pip install (all platform)
- PyGaze OpenSesame plugins
- Example
- Function overview
- class eyetracker
- function eyetracker.calibrate()
- function eyetracker.close()
- function eyetracker.connected()
- function eyetracker.draw_calibration_target(x, y)
- function eyetracker.draw_drift_correction_target(x, y)
- function eyetracker.drift_correction(pos=None, fix_triggered=False)
- function eyetracker.fix_triggered_drift_correction(pos=None, min_samples=30, max_dev=60, reset_threshold=10)
- function eyetracker.get_eyetracker_clock_async()
- function eyetracker.log(msg)
- function eyetracker.log_var(var, val)
- function eyetracker.pupil_size()
- function eyetracker.sample()
- function eyetracker.send_command(cmd)
- function eyetracker.set_detection_type(eventdetection)
- function eyetracker.set_draw_calibration_target_func(func)
- function eyetracker.set_draw_drift_correction_target_func(func)
- function eyetracker.set_eye_used()
- function eyetracker.start_recording()
- function eyetracker.status_msg(msg)
- function eyetracker.stop_recording()
- function eyetracker.wait_for_blink_end()
- function eyetracker.wait_for_blink_start()
- function eyetracker.wait_for_event(event)
- function eyetracker.wait_for_fixation_end()
- function eyetracker.wait_for_fixation_start()
- function eyetracker.wait_for_saccade_end()
- function eyetracker.wait_for_saccade_start()
About
PyGaze is a Python library for eye tracking. A set of plugins allow you to use PyGaze from within OpenSesame. For more information on PyGaze, visit:
Please cite PyGaze as:
Dalmaijer, E., Mathôt, S., & Van der Stigchel, S. (2014). PyGaze: An open-source, cross-platform toolbox for minimal-effort programming of eyetracking experiments. Behavior Research Methods. doi:10.3758/s13428-013-0422-2
Supported eye trackers
PyGaze supports the following eye trackers:
- EyeLink — For information on how to run OpenSesame with PyLink support, see this page.
- EyeTribe — Works out of the box.
For the following eye trackers, there is experimental support:
PyGaze also includes two dummy eye trackers for testing purposes:
- Simple dummy — Does nothing.
- Advanced dummy — Mouse simulation of eye movements.
Installing PyGaze
Windows
If you use the official Windows package of OpenSesame, PyGaze is already installed.
Ubuntu
If you use Ubuntu, you can get PyGaze from the Cogsci.nl PPA:
sudo add-apt-repository ppa:smathot/cogscinl
sudo apt-get update
sudo apt-get install python-pygaze
pip install (all platform)
You can install PyGaze with pip
:
pip install python-pygaze
Install from source
On other systems, you can install PyGaze as follows:
- Download the PyGaze source code (
.zip
) from https://github.com/esdalmaijer/PyGaze.- Do not download the standalone Windows packages provided on the PyGaze website.
- Verify that the version of PyGaze is compatible with your version of OpenSesame, as described here.
- Extract the
.zip
archive somewhere. - Inside, you will find these folders:
opensesame_plugins
: As the name suggests, this folder contains the OpenSesame plugins, which need to be copied to (one of) the plugin folders, as described here.pygaze
: This is the PyGaze Python library. You need to copy this to a folder in the Python path. On Windows, you can copy this folder to the OpenSesame program folder.
- Done!
PyGaze OpenSesame plugins
The following PyGaze plugins are available:
- pygaze_init — Initializes PyGaze. This plugin is generally inserted at the start of the experiment.
- pygaze_drift_correct — Implements a drift correction procedure.
- pygaze_start_recording — Puts PyGaze in recording mode.
- pygaze_stop_recording — Puts PyGaze out of recording mode.
- pygaze_wait — Pauses until an event occurs, such as a saccade start.
- pygaze_log — Logs experimental variables and arbitrary text.
Example
For an example of how to use the PyGaze plugins, see the PyGaze template that is included with OpenSesame.
Below is an example of how to use PyGaze in a Python inline_script:
# Create a keyboard and a canvas object
my_keyboard = Keyboard(timeout=0)
my_canvas = Canvas()
my_canvas['dot'] = Circle(x=0, y=0, r=10, fill=True)
# Loop ...
while True:
# ... until space is pressed
key, timestamp = my_keyboard.get_key()
if key == 'space':
break
# Get gaze position from pygaze ...
x, y = eyetracker.sample()
# ... and draw a gaze-contingent fixation dot!
my_canvas['dot'].x = x + my_canvas.left
my_canvas['dot'].y = y + my_canvas.top
my_canvas.show()
Function overview
To initialize PyGaze in OpenSesame, insert the pygaze_init plugin into your experiment. Once you have done this, an eyetracker
object will be available, which offers the following functions:
class eyetracker
A generic Python library for eye tracking.
function eyetracker.calibrate()
Calibrates the eye tracking system. The actual behavior of this function depends on the type of eye tracker and is described below.
EyeLink:
This function will activate the camera-setup screen, which allows you to adjust the camera, and peform a calibration/ validation procedure. Pressing 'q' will exit the setup routine. Pressing 'escape' will first trigger a confirmation dialog and then, upon confirmation, raises an Exception.
EyeTribe:
Activates a simple calibration routine.
Returns:
Returns True if calibration succeeded, or False if not; in addition a calibration log is added to the log file and some properties are updated (i.e. the thresholds for detection algorithms).
- Type: bool
function eyetracker.close()
Neatly closes connection to tracker. Saves data and sets
self.connected
to False.
function eyetracker.connected()
Checks if the tracker is connected.
Returns:
True if connection is established, False if not; sets
self.connected
to the same value.
- Type: bool
function eyetracker.draw_calibration_target(x, y)
Draws a calibration target.
Arguments:
x
-- The X coordinate- Type: int
y
-- The Y coordinate- Type: int
function eyetracker.draw_drift_correction_target(x, y)
Draws a drift-correction target.
Arguments:
x
-- The X coordinate- Type: int
y
-- The Y coordinate- Type: int
function eyetracker.drift_correction(pos=None, fix_triggered=False)
Performs a drift-correction procedure. The exact behavior of this function on the type of eye tracker and is described below. Because drift correction may fail, you will generally call this function in a loop.
EyeLink:
Pressing 'q' during drift-correction will activate the camera-setup screen. From there, pressing 'q' again will cause drift correction to fail immediately. Pressing 'escape' will give the option to abort the experiment, in which case an Exception is raised.
Keywords:
pos
-- (x, y) position of the fixation dot or None for a central fixation.- Type: tuple, NoneType
- Default: None
fix_triggered
-- Boolean indicating if drift check should be performed based on gaze position (True) or on spacepress (False).- Type: bool
- Default: False
Returns:
A boolean indicating if drift check is ok (True) or not (False).
- Type: bool
function eyetracker.fix_triggered_drift_correction(pos=None, min_samples=30, max_dev=60, reset_threshold=10)
Performs a fixation triggered drift correction by collecting a number of samples and calculating the average distance from the fixation position
Keywords:
pos
-- (x, y) position of the fixation dot or None for a central fixation.- Type: tuple, NoneType
- Default: None
min_samples
-- The minimal amount of samples after which an average deviation is calculated.- Type: int
- Default: 30
max_dev
-- The maximal deviation from fixation in pixels.- Type: int
- Default: 60
reset_threshold
-- If the horizontal or vertical distance in pixels between two consecutive samples is larger than this threshold, the sample collection is reset.- Type: int
- Default: 10
Returns:
A boolean indicating if drift check is ok (True) or not (False).
- Type: bool
function eyetracker.get_eyetracker_clock_async()
Returns the difference between tracker time and PyGaze time, which can be used to synchronize timing
Returns:
The difference between eyetracker time and PyGaze time.
- Type: int, float
function eyetracker.log(msg)
Writes a message to the log file.
Arguments:
msg
-- A message.- Type: str, unicode
function eyetracker.log_var(var, val)
Writes a variable's name and value to the log file
Arguments:
var
-- A variable name.- Type: str, unicode
val
-- A variable value
function eyetracker.pupil_size()
Returns the newest pupil size sample; size may be measured as the diameter or the area of the pupil, depending on your setup (note that pupil size mostly is given in an arbitrary units).
Returns:
Returns pupil size for the eye that is currently being tracked (as specified by self.eye_used) or -1 when no data is obtainable.
- Type: int, float
function eyetracker.sample()
Returns newest available gaze position.
Returns:
An (x,y) tuple or a (-1,-1) on an error.
- Type: tuple
function eyetracker.send_command(cmd)
Directly sends a command to the eye tracker (not supported for all brands; might produce a warning message if your setup does not support direct commands).
Arguments:
cmd
-- The command to be sent to the eye tracker.- Type: str, unicode
function eyetracker.set_detection_type(eventdetection)
Set the event detection type to either PyGaze algorithms, or native algorithms as provided by the manufacturer (only if available: detection type will default to PyGaze if no native functions are available)
Arguments:
eventdetection
-- A string indicating which detection type should be employed: either 'pygaze' for PyGaze event detection algorithms or 'native' for manufacturers algorithms (only if available; will default to 'pygaze' if no native event detection is available)- Type: str, unicode
Returns:
Detection type for saccades, fixations and blinks in a tuple, e.g. ('pygaze','native','native') when 'native' was passed, but native detection was not available for saccade detection.
- Type: tuple
function eyetracker.set_draw_calibration_target_func(func)
Specifies a custom function to draw the calibration target. This will function will override the default [draw_calibration_target].
Arguments:
func
-- The function to draw a calibration target. This function should accept two parameters, for the x and y coordinate of the target.- Type: function
function eyetracker.set_draw_drift_correction_target_func(func)
Specifies a custom function to draw the drift-correction target. This function will override the default [draw_drift_correction_target].
Arguments:
func
-- The function to draw a drift-correction target. This function should accept two parameters, for the x and y coordinate of the target.- Type: function
function eyetracker.set_eye_used()
Logs the eye_used
variable, based on which eye was specified (if both eyes are being tracked, the left eye is used). Does not return anything.
function eyetracker.start_recording()
Starts recording. Sets self.recording
to True
when recording is successfully started.
function eyetracker.status_msg(msg)
Sends a status message to the eye tracker, which is displayed in the tracker's GUI (only available for EyeLink setups).
Arguments:
msg
-- A string that is to be displayed on the experimenter PC, e.g.: "current trial: %d" % trialnr.- Type: str, unicode
function eyetracker.stop_recording()
Stops recording. Sets self.recording
to False
when recording is successfully stopped.
function eyetracker.wait_for_blink_end()
Waits for a blink end and returns the blink ending time. Detection based on Dalmaijer et al. (2013) if EVENTDETECTION is set to 'pygaze', or using native detection functions if EVENTDETECTION is set to 'native' (NOTE: not every system has native functionality; will fall back to ;pygaze' if 'native' is not available!)
Returns:
Blink ending time in milliseconds, as measured from experiment begin time.
- Type: int, float
function eyetracker.wait_for_blink_start()
Waits for a blink start and returns the blink starting time. Detection based on Dalmaijer et al. (2013) if EVENTDETECTION is set to 'pygaze', or using native detection functions if EVENTDETECTION is set to 'native' (NOTE: not every system has native functionality; will fall back to ;pygaze' if 'native' is not available!)
Returns:
Blink starting time in milliseconds, as measured from experiment begin time
- Type: int, float
function eyetracker.wait_for_event(event)
Waits for an event.
Arguments:
-
event
-- An integer event code, one of the following: -
3 = STARTBLINK
- 4 = ENDBLINK
- 5 = STARTSACC
- 6 = ENDSACC
- 7 = STARTFIX
- 8 = ENDFIX
- Type: int
Returns:
A self.wait_for_*
method is called, depending on the specified event; the return value of corresponding method is returned.
function eyetracker.wait_for_fixation_end()
Returns time and gaze position when a fixation has ended; function assumes that a 'fixation' has ended when a deviation of more than self.pxfixtresh from the initial fixation position has been detected (self.pxfixtresh is created in self.calibration, based on self.fixtresh, a property defined in self.init). Detection based on Dalmaijer et al. (2013) if EVENTDETECTION is set to 'pygaze', or using native detection functions if EVENTDETECTION is set to 'native' (NOTE: not every system has native functionality; will fall back to ;pygaze' if 'native' is not available!)
Returns:
A time, gazepos
tuple. Time is the end time in milliseconds (from expstart), gazepos is a (x,y) gaze position tuple of the position from which the fixation was initiated.
- Type: tuple
function eyetracker.wait_for_fixation_start()
Returns starting time and position when a fixation is started; function assumes a 'fixation' has started when gaze position remains reasonably stable (i.e. when most deviant samples are within self.pxfixtresh) for five samples in a row (self.pxfixtresh is created in self.calibration, based on self.fixtresh, a property defined in self.init). Detection based on Dalmaijer et al. (2013) if EVENTDETECTION is set to 'pygaze', or using native detection functions if EVENTDETECTION is set to 'native' (NOTE: not every system has native functionality; will fall back to ;pygaze' if 'native' is not available!)
Returns:
A time, gazepos
tuple. Time is the starting time in milliseconds (from expstart), gazepos is a (x,y) gaze position tuple of the position from which the fixation was initiated.
- Type: tuple
function eyetracker.wait_for_saccade_end()
Returns ending time, starting and end position when a saccade is ended; based on Dalmaijer et al. (2013) online saccade detection algorithm if EVENTDETECTION is set to 'pygaze', or using native detection functions if EVENTDETECTION is set to 'native' (NOTE: not every system has native functionality; will fall back to ;pygaze' if 'native' is not available!)
Returns:
An endtime, startpos, endpos
tuple. Endtime in milliseconds (from expbegintime); startpos and endpos are (x,y) gaze position tuples.
- Type: tuple
function eyetracker.wait_for_saccade_start()
Returns starting time and starting position when a saccade is started; based on Dalmaijer et al. (2013) online saccade detection algorithm if EVENTDETECTION is set to 'pygaze', or using native detection functions if EVENTDETECTION is set to 'native' (NOTE: not every system has native functionality; will fall back to ;pygaze' if 'native' is not available!)
Returns:
An endtime, startpos
tuple. Endtime in milliseconds (from expbegintime); startpos is an (x,y) gaze position tuple.
- Type: tuple