Sampling problems

Hello,

I am currently programming an experiment with Eyelink toolbox and Matlab 7.0.
I need to have the online information about the eye velocity. Since Eyelink('NewestFloatSample?') returns the x and y position of the eye and the timestamp of the sample, I can calculate the online velocity. I store all this information in an array and I plot it at the end of the trial to check if everything is right.
However, whenever I double check this stored information and the saved .edf file, it is clear that some samples from the online computation are missing, and that the sampling is not at regular time steps. Neverthless, the .edf file contains all the missing information.
I cannot really think of why this is happening.
Furthermore, do you know how the .edf file is generated? Is it possible to have access to those codes?

Thanks
Giulia
To add to Erik's comment: I presume you are calling NewestFloatSample in a rather tight loop, like in most cases I've seen? Furthermore, I think the samples are also buffered, although the buffer does not seem to be very large. So the question is either why does the buffer sometimes overrun, or why are you polling less frequently than the sampling rate on average.

Two candidate reasons come to mind:
(1) You might be growing your array inside the loop, i.e., you are using something like "vel = [vel; vx];" inside the loop instead of preallocating vel outside the loop ("vel = NaN * ones(samplingRate * estimatedRecordingDuration + padding)") and then using "vel(k) = vx;" inside. Remember that memory allocation is costly.
(2) The operating system kicks in at unpredictable intervals and does some cleanup task. I don't know if this can be avoided, but chances can be minimized by disabling things like virus scanners and unused network connections, and generally running as few background tasks as possible.

jochen

On Jun 29, 2010, at 21:07 , e_flister wrote:

> NewestFloatSample just gives you the latest sample -- if you call it less frequently than the sampling rate, you will not get all the samples (but they do get stored in the edf file). GetQueuedData will give you all the samples.
>
> SR Research's proprietary code that runs on the computer that hosts the tracker is what makes the edf file -- eyelink toolbox only sucks that file over the link. you would have to check with them, tho i doubt they will publish the source, and it isn't at all necessary for what you describe...
>
> -e
>
> --- In psychtoolbox@yahoogroups.com, "Giulia" <manca.giuli@...> wrote:
> >
> > Hello,
> >
> > I am currently programming an experiment with Eyelink toolbox and Matlab 7.0.
> > I need to have the online information about the eye velocity. Since Eyelink('NewestFloatSample?') returns the x and y position of the eye and the timestamp of the sample, I can calculate the online velocity. I store all this information in an array and I plot it at the end of the trial to check if everything is right.
> > However, whenever I double check this stored information and the saved .edf file, it is clear that some samples from the online computation are missing, and that the sampling is not at regular time steps. Neverthless, the .edf file contains all the missing information.
> > I cannot really think of why this is happening.
> > Furthermore, do you know how the .edf file is generated? Is it possible to have access to those codes?
> >
> > Thanks
> > Giulia
> >
>
>
> To add to Erik's comment: I presume you are calling NewestFloatSample in a rather tight loop, like in most cases I've seen?

don't most people only poll once per screen refresh? which is often a lot slower than the eyetracker runs. that's how EyelinkExample works.

> Furthermore, I think the samples are also buffered, although the buffer does not seem to be very large. So the question is either why does the buffer sometimes overrun, or why are you polling less frequently than the sampling rate on average.

i'm certain NewestFloatSample only returns the most recent sample, so this is definitely not the buffer filling up (though it surely is, because no one is emptying it, only the oldest samples are removed to make more room). GetQueuedData and GetFloatData are the only ways to see into/empty the buffer.

> (1) You might be growing your array inside the loop, i.e., you are using something like "vel = [vel; vx];" inside the loop instead of preallocating vel outside the loop ("vel = NaN * ones(samplingRate * estimatedRecordingDuration + padding)") and then using "vel(k) = vx;" inside. Remember that memory allocation is costly.

this would result in increasing time diffs as the trial goes on -- not only is memory allocation expensive, but the copy of all the previous data into the new memory location takes longer and longer.

EyelinkQueuedDataDemo uses preallocation.

-e
On Jun 30, 2010, at 2:31 , e_flister wrote:

> > To add to Erik's comment: I presume you are calling NewestFloatSample in a rather tight loop, like in most cases I've seen?
>
> don't most people only poll once per screen refresh? which is often a lot slower than the eyetracker runs. that's how EyelinkExample works.

Agreed, that is probably the reason for Giulia's observation.

> > (1) You might be growing your array inside the loop, i.e., you are using something like "vel = [vel; vx];" inside the loop instead of preallocating vel outside the loop ("vel = NaN * ones(samplingRate * estimatedRecordingDuration + padding)") and then using "vel(k) = vx;" inside. Remember that memory allocation is costly.
>
> this would result in increasing time diffs as the trial goes on -- not only is memory allocation expensive, but the copy of all the previous data into the new memory location takes longer and longer.

Yes, but on a given trial length you may see only a few spikes (the chance of observing such spikes increases with the size of the array). In general, what do we know about Matlab's or the OS's memory allocation policy--maybe it allocates chunks of increasing size? The increase clearly shows some steps in addition to a linear trend and the occasional peak. Even if the increase in time diffs scales with the size of the array, most of the time it seems to be fast enough on current hardware. However, with larger array (probably not relevant for most recording durations) the peak times can become quite long.


% illustration of the above, will take a lot of time to execute
N = 1e6/2;

clear x;
x = [];
for k = 1:N
tic;
x = [x;toc];
end;

% some smoothing
w = 1000;
fx = filter(ones(w,1)/w, 1, x);

N2 = round(length(x)/2);

figure
subplot(3,1,1)
loglog(fx(w:end-w));
subplot(3,1,2);
hist(log10(x(1:N2)), 1000);
xlim(xl);
subplot(3,1,3);
hist(log10(x(N2:end)), 1000);
xlim(xl);

sum(log10(x(1:N2)) >= -3.5)
sum(log10(x(N2:end)) >= -3.5)
> NewestFloatSample just gives you the latest sample -- if you call it less frequently than the sampling rate, you will not get all the samples (but they do get stored in the edf file). GetQueuedData will give you all the samples.

I also thought that might have been the problem, and in a second version of my script I used GetQueuedData, but it still produced data velocity which were very different from the .edf file. One possibility is that the recorded velocity in the .edf file is already filtered, is that the case?

What I can't really explain is why GetQueuedData shows me many more sample than the one I am missing. Using NewestFloatSample I am missing max 20 samples, but using GetQueuedData I always have at least 40 samples per cicle. Is that normal?

I was also concerned with another issue about GetQueuedData, since everytime I call it I receive quite a few sample and calculations of velocities is done after calling it, don't I lose the "real time" criterium? If it is really the case that I calculate velocity after 50 samples, that means that I will know the eye velocity between the 1 and 2 sample only much later.

Sorry if those questions are trivial, but you are really much appreciate your help, thanks!

Giulia