Problem with matching pupil samples and time samples

Hi,

Im currently preparing an experiment which records the pupil diameter when the eyelink is recording. I store the pupil area in an array as the experiment proceeds. I take it from the sample structure returned from

sample = Eyelink('NewestFloatSample');


I also take the time from this sample structure.

I have a questions relating to timing in Psychtoolbox. I have a small script at the beginning of my experiment to find the baseline pupil diameter. Its a simple script that takes samples for five seconds and then plots the pupil diamter versus time.

Here is the loop i use

...
tic;
while(time <= 5)
%Draw the fixation cross
drawFixationCross(win,centrex,centrey);
[targetFlipstart,targetStimOnset]=Screen('Flip', win);
sample = Eyelink('NewestFloatSample');
t = sample.time;
pa= sample.pa;
trialPA=[trialPA,pa];
trialTimes=[trialTimes,t];
%Update the clock
time=toc;
end;
...

This code works fine but when i run it I seem to only get roughly 500 samples.

I use and Eyelink 2. Should it not give me more samples? Should i be using tic and toc to act as guards for the while loop?

Forgive if this question has been asked before.

Patrick
There's multiple problems with this code, which explain your only 500 samples in 5 seconds, or 100 samples/second:

1. Don't use tic and toc, but GetSecs: GetSecs uses PTB's clock, which is consistent with all other clocks and times used in PTB. tic and toc are Matlab functions with unknown resolution, accuracy and reliability. They differ in behaviour across matlab versions and operating systems, and some can give wrong results on broken hardware, whereas ptb's functions try to compensate for broken clocks.

-> Use tic toc for quick & dirty checks if you want, but get into the habit of using GetSecs whenever precision/reliablity matter.

2. trialPA=[trialPA,pa]; --> This is bad for performance, as the warning messages from matlabs editor will tell you. Preallocate arrays instead of "growing" them on runtime. Growing works for short arrays, but can create drastic performance loss, once the arrays grow a bit bigger.

3. The main reason for only 100 samples/sec is that you use 'NewestFloatSample'. This will provide you with the most recent sample from the tracker, discarding older samples. It provides minimal latency for gaze contingent experiments etc., but will discard many samples if your code can't keep up with the trackers speed. In your case, your monitor is probably running at 100 Hz refresh, so your whole loop only runs at 100 Hz. If you remove the 'flip', you'll probably observe a much higher sample rate.

-mario


--- In psychtoolbox@yahoogroups.com, "hynespm_23" <hynespm_23@...> wrote:
>
> Hi,
>
> Im currently preparing an experiment which records the pupil diameter when the eyelink is recording. I store the pupil area in an array as the experiment proceeds. I take it from the sample structure returned from
>
> sample = Eyelink('NewestFloatSample');
>
>
> I also take the time from this sample structure.
>
> I have a questions relating to timing in Psychtoolbox. I have a small script at the beginning of my experiment to find the baseline pupil diameter. Its a simple script that takes samples for five seconds and then plots the pupil diamter versus time.
>
> Here is the loop i use
>
> ...
> tic;
> while(time <= 5)
> %Draw the fixation cross
> drawFixationCross(win,centrex,centrey);
> [targetFlipstart,targetStimOnset]=Screen('Flip', win);
> sample = Eyelink('NewestFloatSample');
> t = sample.time;
> pa= sample.pa;
> trialPA=[trialPA,pa];
> trialTimes=[trialTimes,t];
> %Update the clock
> time=toc;
> end;
> ...
>
> This code works fine but when i run it I seem to only get roughly 500 samples.
>
> I use and Eyelink 2. Should it not give me more samples? Should i be using tic and toc to act as guards for the while loop?
>
> Forgive if this question has been asked before.
>
> Patrick
>
> 3. The main reason for only 100 samples/sec is that you use 'NewestFloatSample'. This will provide you with the most recent sample from the tracker, discarding older samples. It provides minimal latency for gaze contingent experiments etc., but will discard many samples if your code can't keep up with the trackers speed. In your case, your monitor is probably running at 100 Hz refresh, so your whole loop only runs at 100 Hz. If you remove the 'flip', you'll probably observe a much higher sample rate.

i added GetQueuedData awhile ago to address this situation. it will return matrices containing all the acquired samples and events since the last call. it allows you to avoid having to fuss with GetNextDataType and GetFloatData manually in a slow matlab loop, and you don't need NewFloatSampleAvailable. another advantage is that you eliminate the ugly process of extracting items at a particular index of a field in a struct array. ie, the following is no longer necessary:

%s is a struct array of results from NewestFloatSample
tmp=cell2mat({s.px}'); %the px's are rows (better than a loop, but yuck!)
tmp(:,1) %a vector of the left px's (thanks matlab for requiring a temp variable to index)
-e
> trialPA=zeros(1,2500);
> trialTimes=zeros(1,2500);
> count=1;
> startTime=GetSecs;
> drawFixationCross(win,centrex,centrey);
> % drawTime(win,time,centrex,centrey);
> [targetFlipstart,targetStimOnset]=Screen('Flip', win);
> nextTime=0;
> while(nextTime<5.0)
> %Draw the fixation cross
> sample = Eyelink('NewestFloatSample');
> x = sample.gx(eyeused+1); % get gaze position from sample
> y = sample.gy(eyeused+1);
> t =GetSecs;
> tmp=cell2mat({sample.pa(eyeused+1)});
> if (x~=el.MISSING_DATA & y~=el.MISSING_DATA & sample.pa(eyeused+1)>0)
> trialPA(1,count)= tmp(:,1);
> trialTimes(1,count)=t;
> count=count+1;
> end;
> nextTime=GetSecs-startTime;
> end;
> finishTime=GetSecs;
> elaspsedTime=finishTime-startTime;
>
>
> I had a problem upgrading my version of psychtoolbox so that I could use the GetQueuedData command so I thre in the code sample

you should get this fixed. was it an svn error? see recent discussions on this list for how to fix, or send the details if it's a new problem.

> tmp=cell2mat({sample.pa(eyeused+1)});

you don't need the cell stuff here -- that was for quickly extracting a vector of values from a particular index of an array field in a struct array of samples. you only have one sample here.

> Why is the trialPA and trialTimes array exceeding its size and how am i getting 7000 samples?

since you removed the flip, you are now extracting samples as fast as this code can loop, which is probably faster than the tracker can create them (at least until you fall off the preallocated part). if you do it this way, you need to call 'NewFloatSampleAvailable' to avoid getting duplicates. you should be following the example in EyelinkDemos/EyelinkShortDemos/EyelinkExample.m, which does this.

you are getting more than 2500 samples because you never check that your index is not larger than that. once you are over 2500, matlab starts (slowly) growing the array again.
-e