Setting up your code to collect good ET data
calling eye-tracker and sending messages
For eye-tracking timing is of the essence! Even if you do not care about exact stimulus timing, you really should care about logging the time relevant events happen as accurately as possible!
Here's some example code for how to define and send messages in Matlab.
Note
Matlab example contributed by Romy Froemer.
%% setting ET via console prompt at the start of the task
novalidinput =1;
while novalidinput == 1
p.SessionInfo.isET = (input('Do eye-tracking? y or n: ','s'));
if isstrprop(p.SessionInfo.isET,'upper')
p.SessionInfo.isET = lower(p.SessionInfo.isET);
end
if strcmp(p.SessionInfo.isET, 'y')
p.SessionInfo.isET = 1;
novalidinput =0;
elseif strcmp(p.SessionInfo.isET, 'n')
p.SessionInfo.isET=0;
novalidinput =0;
end
end
%% initializing file and eye-tracker
% set file name
p.TaskParams.ET.edfFile = strcat('MPRD',p.SubID); % define filename for edf file
%here, initialize a structure corresponding to the parameters of the
%display where stimuli are being created, for use in calculating the
%DVA of eye position location. The argument to pass is the screen
%number that corresponds to where the already opened window pointer is. (see function below)
p = initializeEyetrackingParams(p.screenParams.screenNum,p);
%% example for sending messages:
if (p.SessionInfo.isET && ~p.SessionInfo.isPractice)
Eyelink('Message', 'DotsOn');
end
%% cali instructions %%%%
showETInstruction(p, p.SessionInfo.Instructions.CaliInstruction, 'to start the calibration. While doing so, please look at the + above.')
p = EyelinkSetup(1,p);
save(fullfile(p.SessionInfo.filePath,['MPRDM_v', p.Version, '_',p.SubID,'_',p.SessionInfo.date,'.mat']),'p');
Eyelink('IsConnected');
if p.TaskParams.ET.recordContinuous ==1
Eyelink('Command', 'set_idle_mode');
WaitSecs(0.05);
Eyelink('StartRecording');
% record a few samples before we actually start displaying
% otherwise you may lose a few msec of data
WaitSecs(0.1);
end
%% shut down eyeLink
if p.SessionInfo.isET
% End of Experiment;
%% when adding EEG add start trigger here
%% add end message:
Eyelink('Message', 'ExpEnd');
% close the file firsts
% close graphics window, close data file and shut down tracker
Eyelink('Command', 'set_idle_mode');
WaitSecs(0.5);
Eyelink('CloseFile');
EyelinkSetup(0,p) % receiving (any) files and shutting down eyelink
end
%% function to start/stop eye-tracking which saves and pulls file
function [p] = EyelinkSetup(startOrStop, p)
%Local function to set up defaults for each Eyelink and start recording.
%Designed to be called before starting each block. Requires previous call
%to EyelinkInitDefaults to work appropriately
%startOrStop is a binary variable, where 1 = 'start up the Eyelink and
%initialize', and 0 = 'turn off Eyelink'
if startOrStop==1 %starting up the Eyelink
p.TaskParams.ET.el=EyelinkInitDefaults(p.screenParams.wPtr); %initialize the Eyelink default settings
% Initialize Eyelink connection (real or dummy). The flag '1' requests
% use of callback function and eye camera image display:
if ~EyelinkInit([], 1)
fprintf('Eyelink Init aborted.\n');
cleanup;
return;
end
if p.TaskParams.ET.save_edf
i = Eyelink('Openfile', p.TaskParams.ET.edfFile);
if i~=0
fprintf('Cannot create EDF file ''%s'' ', p.TaskParams.ET.edfFile);
Eyelink( 'Shutdown');
Screen('CloseAll');
return;
end
Eyelink('command', 'add_file_preamble_text ''Recorded by EyelinkToolbox MPRDM experiment''');
end
if ~isfield(p.TaskParams.ET,'eye_used')
p.TaskParams.ET.eye_used=0;
end
% Send any additional setup commands to the tracker
Eyelink('Command','calibration_type = HV5'); % calibration type changed 12/01/2023 from HV9 due to issues with corners
Eyelink('Command','recording_parse_type = GAZE');
if p.TaskParams.ET.save_edf
% set EDF file contents using the file_sample_data and
% file-event_filter commands
% set link data thtough link_sample_data and link_event_filter
Eyelink('command', 'file_event_filter = LEFT,RIGHT,FIXATION,SACCADE,BLINK,MESSAGE,BUTTON,INPUT');
Eyelink('command', 'link_event_filter = LEFT,RIGHT,FIXATION,SACCADE,BLINK,MESSAGE,BUTTON,INPUT');
else
Eyelink('Command','link_event_filter = LEFT,RIGHT,FIXATION,SACCADE,BLINK');
end
%perform calls to the Eyelink host to get the correct queued eye data
Eyelink('command','link_sample_data = LEFT,RIGHT,GAZE,AREA,GAZERES,HREF,PUPIL,STATUS,INPUT,HMARKER');
% HH Settings
Eyelink('command', 'file_sample_data = LEFT,RIGHT,GAZE,HREF,AREA,GAZERES,STATUS,INPUT');
% Eyelink('command', 'link_sample_data = LEFT,RIGHT,GAZE,GAZERES,AREA,STATUS,INPUT');
Eyelink('command','inputword_is_window = ON');
Eyelink('Command','sample_rate = 1000');
% changed 01/2022: we read in the coordinates from display params (like HH)
Eyelink('command','screen_pixel_coords = %ld %ld %ld %ld', 0, 0, p.TaskParams.ET.dp.w_width-1, p.TaskParams.ET.dp.w_height-1);
Eyelink('message', 'DISPLAY_COORDS %ld %ld %ld %ld', 0, 0, p.TaskParams.ET.dp.w_width-1, p.TaskParams.ET.dp.w_height-1);
%Eyelink('Command','screen_pixel_coords = 0 0 1024 768');
%Eyelink('Command','screen_pixel_coords = 0 0 1151 863'); %need to fix the resolution input thing here
Eyelink('Command','draw_line = x1, y1, x2, y2, 0');
Eyelink('Command','file_event_data = GAZE,VELOCITY');
Eyelink('Command','link_event_data = GAZE,VELOCITY');
Eyelink('Command','saccade_velocity_threshold = 200');
Eyelink('Command','saccade_motion_threshold = 0.15');
% what is that and what does it do?
%result = Eyelink('StartSetup',1);
result = EyelinkDoTrackerSetup(p.TaskParams.ET.el); % do calibration
%Eyelink('StartRecording');
disp('Eyelink up and running!');
elseif startOrStop==0 %done with Eyelink for now, shut it down
if p.TaskParams.ET.save_edf
try
fprintf('Receiving data file ''%s''\n', p.TaskParams.ET.edfFile );
status=Eyelink('ReceiveFile');
if status > 0
fprintf('ReceiveFile status %d\n', status);
end
if 2==exist([p.TaskParams.ET.edfFile, '.edf'], 'file')
fprintf('Data file ''%s'' can be found in ''%s''\n', p.TaskParams.ET.edfFile, pwd);
movefile([p.TaskParams.ET.edfFile, '.edf'], 'data/ET_Results')
end
catch
fprintf('Problem receiving data file ''%s''\n', p.TaskParams.ET.edfFile );
end
end
%reset sampling rate for other experimenter's use and shutdown the Eyelink
if p.TaskParams.ET.resetParams
Eyelink('Command','sample_rate = 250');
Eyelink('Command','calibration_type = HV9');
end
disp('....now clearing eyelink! :)');
Eyelink('Shutdown');
p.TaskParams.ET.el=-1;
end