TRACKPixx Demo 4 – Recording and plotting eye position data from the TRACKPixx3¶
Note
This demo requires TRACKPixx Revision 18 or later. You can check for recent firmware updates at vpixx.com/whatsnew
Note
This demo assumes you have already calibrated the TRACKPixx3 for the session. You can calibrate using the PyPixx GUI, or run TPxTrackpixx3CalibrationTesting() in MATLAB. If the tracker is not calibrated, the eye positions returned by this demo will be NaN.
In this demo we display a series of squares. When the user presses “Enter”, the TRACKPixx3 records eye data for 4 seconds, and then plots the result. We trigger recording using the sequence Datapixx('SetupTPxSchedule');
, Datapixx('StartTPxSchedule');
, and when finished, Datapixx('StopTPxSchedule');
. Each of these commands must be followed by a Datapixx('RegWrRd');
to push them to the device register and initiate/finish recording.
To read the buffer of recorded data from the TRACKPixx, we call status = Datapixx('GetTPxStatus');
. New data is first isolated in toRead = status.newBufferFrames;
, and then interpreted using Datapixx('ReadTPxData', toRead);
.
TRACKPixx buffer 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.
Finally, we generate three figures, which plot X and Y position over time for the left eye, the right eye, and both eyes. By default, we plot the calibrated eye positions. Raw position can be plotted instead by changing the column of the buffer data used in plot()
. 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 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | function TPxRawRecordAndPlot()
%
% 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.
Datapixx('Open');
Datapixx('SetLedIntensity', 8);
Datapixx('SetTPxAwake');
Datapixx('SetExpectedIrisSizeInPixels', 115)
Datapixx('RegWrRd');
image = Datapixx('GetEyeImage');
[windowPtr, windowRect]=PsychImaging('OpenWindow', 2, 0);
KbName('UnifyKeyNames');
t = Datapixx('GetTime');
t2 = Datapixx('GetTime');
Screen('TextSize', windowPtr, 24);
i = 0;
while (1)
if ((t2 - t) > 1/60)
Datapixx('RegWrRd');
image = Datapixx('GetEyeImage');
textureIndex=Screen('MakeTexture', windowPtr, image');
Screen('DrawTexture', windowPtr, textureIndex);
DrawFormattedText(windowPtr, 'Press Enter once the Eye are Focused', 'center', 700, 255);
Screen('Flip', windowPtr);
t = t2;
else
Datapixx('RegWrRd');
t2 = Datapixx('GetTime');
end
% Keypress goes to next step of demo
[pressed dummy keycode] = KbCheck;
if pressed
if keycode(KbName('escape'))
Screen('CloseAll')
Datapixx('Close');
return;
else
break;
end
end
end
WaitSecs(1);
%% Step 2 -- Show screen squares
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;
while (1)
if ((t2 - t) > 1)
Datapixx('RegWrRd');
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);
t = t2;
else
Datapixx('RegWrRd');
t2 = Datapixx('GetTime');
end
% Keypress goes to next step of demo
[pressed dummy keycode] = KbCheck;
if pressed
if keycode(KbName('escape'))
Screen('CloseAll')
Datapixx('Close');
return;
else
recording = 1;
Datapixx('SetupTPxSchedule');
Datapixx('RegWrRd');
Datapixx('StartTPxSchedule');
Datapixx('RegWrRd');
start_time = Datapixx('GetTime');
end
end
if (recording == 1)
Datapixx('RegWrRd');
curr_time = Datapixx('GetTime');
if ((curr_time - start_time) > 5)
Datapixx('StopTPxSchedule');
Datapixx('RegWrRd');
finish_time = Datapixx('GetTime');
break;
end
end
end
% Screen('DrawDots', windowPtr, xy, size, color,[], 1);
% Screen('Flip', windowPtr);
WaitSecs(1.0);
%% Step 3 -- Recording
% Datapixx('SetupTPxSchedule');
% Datapixx('RegWrRd');
%
DrawFormattedText(windowPtr, 'Analyzing Data...Please wait', 'center', 80, 255);
Screen('Flip', windowPtr);
% Datapixx('GetTPxStatus')
% Datapixx('RegWrRd');
%
% Datapixx('StartTPxSchedule');
% Datapixx('RegWrRd');
% start_time = Datapixx('GetTime');
% % fprintf('Recording started at %f', l);
% % Datapixx('GetTPxStatus')
% WaitSecs(4.0);
% %
% Datapixx('StopTPxSchedule');
% Datapixx('RegWrRd');
% finish_time = Datapixx('GetTime');
fprintf('Recording lasted %f seconds', finish_time-start_time);
WaitSecs(2.0);
Datapixx('RegWrRd');
status = Datapixx('GetTPxStatus');
toRead = status.newBufferFrames;
%% Step 4 -- Get and Plot Data
[bufferData, underflow, overflow] = Datapixx('ReadTPxData', toRead);
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(:,17), 'r')
plot(bufferData(:,1)-bufferData(1,1), bufferData(:,18), '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(:,19), 'r')
plot(bufferData(:,1)-bufferData(1,1), bufferData(:,20), '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(:,17), 'r')
plot(bufferData(:,1)-bufferData(1,1), bufferData(:,18), 'b')
plot(bufferData(:,1)-bufferData(1,1), bufferData(:,19), 'c')
plot(bufferData(:,1)-bufferData(1,1), bufferData(:,20), 'm')
%% Close all!
Screen('CloseAll');
Datapixx('Close');
end
|