TRACKPixx /Mini Demo 1 – Recording eye tracking data with the TRACKPixx /Mini

Note

This demo requires TRACKPixx Revision 16 or later. You can check for recent firmware updates at vpixx.com/whatsnew

In this demo we record the eye position data from the TRACKPixx Mini for 4 seconds, and then plot the result.

We capture images of the eye and display them on the screen to ensure the camera is positioned well. We then display a series of squares for the subject to fixate. Recording of eye movements starts when the “Enter” key is pressed, and continues for 4 seconds. On the TRACKPixx Mini, we read tracker data directly from the device using Datapixx('ReadTPxMiniData') and save it to an array.

TRACKPixx Mini data has the following format:

Timetag, Left Eye X, Left Eye Y, Left Pupil Diameter, Right Eye X, Right Eye Y, Right Pupil Diameter, Digital Input Values (24 bits), Left Blink Detection, Right Blink Detection, Digital Output Values (24 bits), Left Eye Fixation Flag, Right Eye Fixation Flag, Left Eye Saccade Flag, Right Eye Saccade Flag, Message code, Left Eye Raw X, Left Eye Raw Y, Right Eye Raw X, Right Eye Raw Y.

As a last step we generate 4 figures. The first 3 figures plot X and Y position over time for the left eye, the right eye, and both eyes. The last figure plots left and right pupil diameter over time. Data points where the X and Y positions equal 9000 are frames in which the eye position was lost (i.e., the participant blinked).

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
function TPxMiniRecordAndPlot()
%
% This demo will start the required things to start the TPx schedule to record data
% and it will show points for 4 secs and record raw or calibrated data.
% After the four seconds, the data will be plotted.
%
%
% Dec 22, 2017  dml written

Screen('Preference', 'SkipSyncTests', 1);

%% Step 1 -- Open the screen and show the eye.

        %Ensure that the TPx/m has no open session before using it.
        Datapixx('CloseTPxMini');

        %'Initialize' opens a TPx/m session and determines the
        %filter mode and screen margin to use for calibration.  We 
        %recommend using filter mode 0 (no filtering).
%-->    %It is mandatory to call 'Initialize' before using the 
        %TPx/m.
        Datapixx('OpenTPxMini', 80);
        %'GetEyeImageTPxMini' returns the image coming from the TPx/m
        image = Datapixx('GetEyeImageTPxMini');
        
[windowPtr, windowRect]=PsychImaging('OpenWindow', 1 , 0);
KbName('UnifyKeyNames');

Screen('TextSize', windowPtr, 24);
i = 0;
% Display camera live stream.
while (1)
    image = Datapixx('GetEyeImageTPxMini');
    textureIndex=Screen('MakeTexture', windowPtr, image');
    Screen('DrawTexture', windowPtr, textureIndex);
    DrawFormattedText(windowPtr, 'Press Enter once the Eye are Focused', 'center', 700, 255); 
    Screen('Flip', windowPtr);

    % Keypress goes to next step of demo
    [pressed dummy keycode] = KbCheck;
    if pressed
        if keycode(KbName('escape'))
            Screen('CloseAll');
            Datapixx('CloseTPxMini');
            return;
        else
            break;
        end
    end
end

WaitSecs(1);
%% Step 2 -- Show screen squares and record


cx = 1920/2;
cy = 1080/2;
dx = 400;
dy = 250;
xy = [cx+dx cy+dy; cx-dx cy+dy; cx-dx cy-dy; cx+dx cy-dy];
xy = [xy;xy]';
size = [30; 30; 30; 30; 10; 10; 10; 10]';
color = [255 255 255; 255 255 255; 255 255 255; 255 255 255; 0 0 0; 0 0 0; 0 0 0; 0 0 0]';
i = 0;
Screen('BlendFunction', windowPtr, 'GL_SRC_ALPHA', 'GL_ONE_MINUS_SRC_ALPHA');
recording = 0;
start_time = 0;
u = 1;
start_rec = 0;
start_time = GetSecs;
bufferData = zeros(120*20, 8);
bufferSecs = zeros(120*20, 1);
while (1)

time_now = GetSecs;
if (((time_now - start_time) > 1))% && ~recording)
    i = i + 1;
    %Screen('DrawDots', windowPtr, xy, size, color,[], 0);
    Screen('DrawDots', windowPtr, [xy(:,mod(i,4)+1) xy(:,mod(i,4)+1)], [30;10]', [255 255 255; 0 0 0]', [], 0);
    if ~recording
        DrawFormattedText(windowPtr, 'Press enter when ready to record', 'center', 80, 255); 
    end
    Screen('Flip', windowPtr);
    start_time = time_now;   
end
    % Keypress goes to next step of demo
    [pressed dummy keycode] = KbCheck;
    if pressed
        fprintf('Recording Data now');
        if keycode(KbName('escape'))
            Screen('CloseAll')
            Datapixx('CloseTPxMini');
            return;
        else
            recording = 1;
            start_rec = GetSecs;
            %break;
        end
    end
    
    if (recording == 1)
        %break;
        [bufferData(u, :)] = Datapixx('ReadTPxMiniData');
        u = u + 1;
        curr_time = GetSecs;
        if ((curr_time - start_rec) > 4)
            finish_time = curr_time;
            break;
        end
    end
end
    
WaitSecs(1.0);
%% Step 3 -- Analysis


DrawFormattedText(windowPtr, 'Analyzing Data...Please wait', 'center', 80, 255); 
Screen('Flip', windowPtr);


fprintf('\nRecording lasted %f seconds\n I got %d frames (should have gotten: %d) \n', finish_time-start_rec, u-1, round((finish_time-start_rec)*120) );

% tt, leftx, lefty, leftpp, rightx, righty, rightpp, distance
bufferData = bufferData(1:(u-1),:);
figure;
hold on;
grid on;
title('Left Eye (Red: X, Blue: Y)');
xlabel('Timetags (seconds)');
ylabel('Gaze information (pixels)');
plot(bufferData(:,1)-bufferData(1,1), bufferData(:,2), 'r')
plot(bufferData(:,1)-bufferData(1,1), bufferData(:,3), 'b')

figure;
hold on;
grid on;
title('Right Eye (Red: X, Blue: Y)');
xlabel('Timetags (seconds)');
ylabel('Gaze information (pixels)');
plot(bufferData(:,1)-bufferData(1,1), bufferData(:,5), 'r')
plot(bufferData(:,1)-bufferData(1,1), bufferData(:,6), 'b')

figure;
hold on;
grid on;
title('Both Eyes (Red: Left X, Blue:  Left Y, Black: Right X, Magenta: Right Y)');
xlabel('Timetags (seconds)');
ylabel('Gaze information (pixels)');
plot(bufferData(:,1)-bufferData(1,1), bufferData(:,2), 'r')
plot(bufferData(:,1)-bufferData(1,1), bufferData(:,3), 'b')
plot(bufferData(:,1)-bufferData(1,1), bufferData(:,5), 'c')
plot(bufferData(:,1)-bufferData(1,1), bufferData(:,6), 'm')

figure;
hold on;
grid on;
title('Pupil over time (Red: Left, Blue: Right)');
xlabel('Timetags (seconds)');
ylabel('Pupil Size (pixels)');
plot(bufferData(:,1)-bufferData(1,1), bufferData(:,4), 'r')
plot(bufferData(:,1)-bufferData(1,1), bufferData(:,7), 'b')
save bufferData

%% Close all!
Screen('CloseAll');

Datapixx('CloseTPxMini');

end