Eye tracking experiments August 29th, 2014 Daniel Schreij VU Cognitive Psychology departement http://ems.psy.vu.nl/userpages/data-analysis-course Today • Creating eye tracking experiments using OpenSesame and PyGaze • Get from EDF (Eyelink Data Format) to other more easily usable data formats • Analyze data with Pandas and Python PyGaze • Download from http://www.pygaze.org • Standalone Python module to communicate with any Eyetracker, with a unified interface (so the code for each eye tracker is the same) • Has OpenSesame plug-in Pygaze | Items Initialize Eyetracker (connection & calibration) Drift correct Log message(s) Start recording Stop recording Pause recording PyGaze | Typical experiment Basic steps • Calibrate • Per trial/block – Drift correct • Per trial – Start recording – Log variables – Stop recording PyGaze | Another way • Start recording at beginning of experiment and stop at the end • Drift correct is done afterwards • Preferable for pupil dilation data, or similar experiments that require a constant dat stream (even in between trials) PyGaze | Initialize PyGaze | Logging messages Data files • After you have run your experiment you often get data files in proprietary formats (.EDF) • Developers like you to use their tools... • You can then either – Use proprietary tools to look at data – export them to a textual format • Working with the data in textual format enables you to use your own tool chain such as Python and all its modules Data Files | EDF • Eyelink data format • You can import them to Eyelink Data viewer and then create reports – Saccade, fixation, etc. • You can use the tool EDF2ASC to convert the EDF file to an ASCII format and then parse it yourself (or with available scripts https://github.com/tknapen/analysis_tools/ ) Data Files | EDF2ASC MSG 2436129 TRIALID T1Rg200 0 0 START 2436164 LEFT RIGHT EVENTS PRESCALER 1 VPRESCALER 1 EVENTS GAZE LEFT RIGHT SFIX L 2436164 SFIX R 2436164 MSG 2436678 SYNCTIME MSG 2436678 DRAWN NEW TARGET EFIX L 2436164 2436832 672 EFIX R 2436164 2436832 672 SSACC L 2436836 SSACC R 2436836 ESACC R 2436836 2436872 40 323.6 SFIX R 2436876 ESACC L 2436836 2436876 44 324.3 MSG 2436878 ERASED OLD TARGET SFIX L 2436880 EFIX R 2436876 2437000 128 492.7 SSACC R 2437004 EFIX L 2436880 2437004 128 499.8 SSACC L 2437008 ESACC L 2437008 2437028 24 506.6 ESACC R 2437004 2437028 28 493.9 220 200 321.7 321.7 246.8 242.1 1422 1683 247.4 496.5 250.2 6.75 276.4 251.6 500.5 247.4 6.93 273.3 249.2 1682 245.0 1323 242.2 248.5 565.4 551.7 251.1 258.4 2.35 2.29 151.4 147.2 Eyelink Data Viewer Eyelink Data Viewer | Fixations Eyelink Data Viewer | Saccades Eyelink Data Viewer | Samples Eyelink Data Viewer | Heatmap EDF | Saving variables • During the experiment, you can send trial variables to the Eyelink to be stored in the EDF file • If you use the appropriate syntax, the EDV will recognize them as variables (and not as random messages) • These variables can be included in reports which you subject to your analysis scripts later • ALWAYS SAVE AS MUCH OPENSESAME VARIABLE DATA AS POSSIBLE TO THE EDF FILE EDF | Variable syntax !V TRIAL_VAR <variable_name> <variable_value> In OpenSesame, send this with send_command() in script exp.eyetracker.send_command("!V TRIAL_VAR RespTime 350") • Alternatively, you can use the pygaze_log item Example experiment Example Experiment | log variables Setting background image: !V IMGLOAD FILL <path/to/image> Eyelink Data Viewer | Variables Eyelink Data Viewer | Variables Eyelink Data Viewer | Interest Periods • Example OpenSesame script for showing stimuli self.fix_canvas.show() self.sleep(1000) exp.eyetracker.send_command("SHOWING target display") self.target_canvas.show() • Right before target display is shown, Eyelink receives the message "SHOWING target display" Eyelink Data Viewer | Interest Periods Eyelink Data Viewer | Interest Periods Eyelink Data Viewer | Interest Periods Full trial period From Target presentation Eyelink Data Viewer | Interest Areas • Just like variables, you can send commands during your experiment to define interest areas in your display area • It is also possible to draw these interest areas after all data has been collected (but this is much more work) Eyelink Data Viewer | Interest Areas • Basic syntax !V IAREA <shape> <index> <left x> <top y> <right x> <bottom y> [label] • For a rectangle !V IAREA RECTANGLE 1 10 5 20 15 cue • For a circle !V IAREA ELLIPSE 2 300 200 400 300 target • For a custom shaped polygon !V IAREA FREEHAND <id> <x1, y1> <x2, y2 > ... <xn, yn> [label] Eyelink Data Viewer | Interest Areas Eyelink Data Viewer | Reports • EDV has options to export EDF data to other tabular formats as csv or Excel • You can create reports containing lists of – Saccades – Fixations – Interest areas – Samples – Trials Eyelink Data Viewer | Reports Eyelink Data Viewer | Reports Reports | Analysis • You can use your favorite software to read in and start analyzing these report files – Excel, MatLab, R, SPSS, Pandas, etc. • For pandas raw_data = pd.read_csv("SaccadeReport.csv") Analysis example try: raw_data except: raw_data = pd.read_csv("ExampleData.csv",sep=";") # Drop empty columns (don't know why these are there....) raw_data = raw_data.drop(raw_data.columns[-10:],axis=1) # Filter data to only contain real and correct trials work_data = raw_data.query("TRIAL_INDEX > 96 and correct==1") # Only get first saccades criteria = "CURRENT_SAC_INDEX == 1 and " criteria += "CURRENT_SAC_NEAREST_END_INTEREST_AREA_LABEL != '.'" first_saccades = work_data.query(criteria) # Create pivot table cols = ["onset","CURRENT_SAC_NEAREST_END_INTEREST_AREA_LABEL"] fs_pt = first_saccades.pivot_table("rt",index="cue", columns=cols, aggfunc="count") # Plot data (fs_pt/fs_pt.sum().sum()).plot(kind="bar") Analysis example # RT pivot table cols = ["onset","CURRENT_SAC_NEAREST_END_INTEREST_AREA_LABEL"] fs_pt = first_saccades.pivot_table("rt",index="cue", columns=cols,aggfunc="mean") fs_pt.plot(xlim=[-0.5,1.5],ylim=[650,1000],style="o-")