esdalmaijer / PyGaze

an open-source, cross-platform toolbox for minimal-effort programming of eye tracking experiments
www.pygaze.org
GNU General Public License v3.0
670 stars 211 forks source link

Eyelink fixations map to unexpected values with 2560x1440p display #149

Closed higher-bridge closed 3 years ago

higher-bridge commented 3 years ago

Hello, I'm running into an issue, as described below. Any help with solving this would be appreciated.

Issue & expected behaviour

I am setting up for an experiment with an Eyelink1000 on a 27" 2560x1440 display, using pygaze. However, the eyetracker does not map fixations from 0 to 2560/1440, nor does it center to (0, 0), either of which would be expected behaviour to me.

Example

Here is an example of a 20 sec test I ran, after calibration and validation (which gave a successful message). As you can see, I fixated around the center and corners to get an idea of the boundaries. Overall, this seems to correspond well to where I looked, it's just that the numbers are off.

(min(fixations['gavx']), max(fixations['gavx']))
Out[0]: (-558.0999755859375, 2031.199951171875)

(min(fixations['gavy']), max(fixations['gavy']))
Out[1]: (-277.20001220703125, 1230.300048828125)

afbeelding

Code

Below is the code I use to record and calibrate

from pygaze import libscreen
from pygaze.eyetracker import EyeTracker
import time

disp = libscreen.Display()

tracker = EyeTracker(disp)
tracker.calibrate()

disp.close()

start = time.time()
tracker.start_recording()

while time.time() - start < 20:
    pass

tracker.stop_recording()

tracker.close()

And after converting the .edf to .csv (using pyedfread), this is how I extract/plot the fixations

events = pd.read_csv('default-events.csv')

# Filter only fixations
fixations = events.loc[events['type'] == 'fixation']

# Create scatterplot
sns.scatterplot('gavx', 'gavy', data=fixations)

Additional info

I am using the latest pygaze commit with python 3.6 and all the appropriate eyelink dependencies/devkit/api for 3.6.

I should note that it does seem to recognize the display resolution, evidenced by the fact that the mapping still approx. adds up to 2560x1440, and by the warning User requested fullscreen with size [1280, 1024], but screen is actually [2560, 1440]. Using actual size.

Please let me know if more info is required. Thanks in advance!

esdalmaijer commented 3 years ago

Heya!

The warning message suggests that you do not overwrite the default display size. I would recommend you do the following:

1) Create a file named constants.py 2) In that file, write the following: DISPSIZE = (2560, 1440) 3) Load the constants in your script by adding from constants import *

That would be the cleanest way to do it. PyGaze automatically detects the constants file, so it's a great way to separate your experiment script from your experiment settings.

Cheers, Edwin

PS: In the EyeLink coordinate system, (0,0) is the bottom-left corner of the monitor, and (2560,1440) in your case would be the top-right. Values outside (including negative values) are possible if you look beyond the edges of the monitor.

higher-bridge commented 3 years ago

That totally did the trick, thanks Edwin! afbeelding