FAQ - Details about timestamps returned by Screen('Flip')


Q: What timing information does Screen('Flip') return?

A: Mario posted the following response to a question on the forum

> i need some clarification on the help for flip. it says:
>
> "Flip (optionally) returns a high-precision estimate of the
> system time (in seconds) when the actual flip has happened in the
> return argument 'VBLTimestamp'. An estimate of Stimulus-onset time is
> returned in 'StimulusOnsetTime'."
>
> i don't understand the difference between these two. what is the
> stimulus onset, if not when the flip happened?

VBLTimestamp is the estimated time when the vertical blanking interval
started. This is when the gfx-hardware does the buffer swap.

Psychtoolbox waits for the buffer swap to happen by asking the
operating system to pause its execution until the swap is finished.
This "sleeping" is important: The CPU is released to run a variety of
system tasks to keep your machine properly running, e.g., keyboard and
mouse queries, network communication, memory management...

After the bufferswap in sync with retrace has happened and PTB is
woken up by the operating system, it immediately does two things:

a) It queries the current beam position of the scanning beam of the
display. This is the value returned in 'beampos'.

b) It takes a high precision timestamp, i.e. it internally executes
GetSecs().

Any general purpose multitasking operating system like OS-X or Windows
usually has some scheduling jitter. This can cause a small random
delay between when the bufferswap really happened (onset of vertical
retrace aka VBL) and when PTB is woken up by the operating system. On
a well configured modern fast machine, this delay will be less than 1
millisecond on average (e.g., typically < 0.3 msecs on a 1.6 Ghz
single cpu G5 with a GeForce-FX5200 gfx card). However there can and
will be occasional spikes of multiple milliseconds. To compensate for
this random delay, Psychtoolbox uses the rasterbeam position as a
second, high resolution clock which is locked to the display cycle: If
one knows the height of the display in scanlines (including the height
of the vertical blank interval) and the duration of a single monitor
refresh interval, one can translate the current rasterbeamposition
into "elapsed time since onset of vertical retrace". By subtracting
this elapsed time from the timestamp taken in b), one can compute the
exact timestamp of when VBL onset happened -> the time when the
bufferswap happened. This is the timestamp returned as VBLTimeStamp -
the first return argument of Screen('Flip').

This timestamp is used by the internal timing tests and it should be
used by your own code if you want to perform own timing tests in
software or if you want to perform timed execution of Screen('Flip')
commands relative to each other.

The duration of the vertical blanking interval (VBL, vertical retrace)
depends on your display settings for screen resolution, refresh rate,
diverse timing parameters of the RAMDAC and the type of connected
display. If you want to take this into account, i.e. you don't want to
know when VBL aka bufferswap happened, but when the display actually
started to update the first scanline of your display with your new
stimulus, then you can use the second return argument of
Screen('Flip'), the 'StimulusOnsetTime'. It is simply VBLTimeStamp +
computed (constant) duration of VBL interval.

There is a script bundled with PTB, called VBLSyncTest.m . It performs
a very simple animation loop while recording all those timestamps. It
plots the curves at the end of execution. It has extensive help text
and lots of parameters to play with -- It doesn't have defaults, so
you have to read its help in order to use it, otherwise it'll simply
crash. Play around with it to get a feeling for how your machine performs.

Obviously this clever beamposition trick only works on operating
systems and gfx-hardware which support beamposition queries. As of
2007, all graphics cards on MacOS-X for PowerPC do support beamposition
queries. On Microsoft Windows, beamposition queries are supported for
NVidia and ATI graphics cards, but currently not on Intel onboard graphics
chips. Intel based Macintosh computers currently don't support beamposition
queries, but on these machines we access the low-level vertical retrace
interrupt handler of the system kernel to get timestamps of nearly the
same robustness and accuracy. Linux currently doesn't support beamposition
queries. If Psychtoolbox detects lack of beampos query support and of support
for low-level vbl interrupts, it will simply return the uncorrected timestamp which
it acquired in step b) - the best it can do in this case. Beamposition queries are
also needed to compute the duration of the VBL interval, that is why we can't return
a meaningful StimulusOnsetTimestamp in that case either, so we set
StimulusOnsetTimestamp = VBLTimeStamp and return beampos = -1 to
indicate lack of support for beampos queries.

>
> "Beampos is the position of the monitor scanning beam when
> the time measurement was taken (useful for correctness tests)."
>
> which measurement? what do you mean by correctness? something like
> the beam should always be in the upper left when the flip occurs?

Yes. See above. You can use the returned beampos to double-check this
if you want. It is probably most useful for development and debugging
of 'Flip' itself.

>
> "FlipTimestamp is a timestamp taken at the end of Flip's execution.
> Use the difference between FlipTimestamp and VBLTimestamp to get an
> estimate of how long Flips execution takes."
>
> so, does this mean that this timestamp is generated right before flip
> returns? how is this different than if i called my own GetSecs()
> right after flip? what does flip do after the actual flip (whose time
> is VBLTimestamp) that would make FlipTimestamp later?
>

Yes. FlipTimestamp is nearly the same value that you would get when
calling GetSecs() immediately after Screen('Flip'). It may be slightly
more accurate, because it is not affected by jitter introduced by
Matlabs interpreter and diverse helper threads, because it is still
executed in C code before control is returned to Matlab.

If you compare FlipTimestamp to VBLTimeStamp you can estimate the
amount of timing jitter in your system. High values indicate that
somethings screwed in your system setup. If you need to sync external
hardware to 'Flip' you get a per frame estimate of how much you are off.

> you've said in the past that flip's timestamps are more accurate than
> GetSecs(). why is this, and if so, then is it meaningless to ever
> compare a time from GetSecs() to a return value from flip? are they
> according to the same clock? why can't GetSecs() access the same
> clock with the same accuracy?

See above. GetSecs() and Flip() are both according to the same clock,
so all timestamps are comparable. The clock is the returned time of
the highest resolution time source on each operating system. The
resolution is better than 1 microsecond, accuracy should be around a
few microseconds. The absolute value depends on the operating system,
e.g., seconds since system bootup on OS-X and Windows, seconds since
1. January 1973 00:00:00 GMT on Linux.

>
> "This is useful to get a feeling for the timing error if you try to
> sync Matlabs execution to the retrace, e.g., for triggering
> acquisition devices like EEG, fMRI, or for starting playback of a
sound."
>
> i am sending a pulse out of the parallel port immediately after flip
> returns, in order to check for dropped frames, etc. so what you are
> saying is that the difference between FlipTimestamp and VBLTimestamp
> is an estimate of how long after the actual flip my pulse occurs? and
> that this is more accurate than taking a GetSecs() before and after
> flip, right before my pulse out?

Yes, it is the best estimate you can get. There will be a small
additional delay for writing to the parallel port of course, but at
least it is a lower bound on the delay ;)

>
> "The automatic detection of deadline-miss is not fool-proof - it
> can report false positives and also false negatives, although it
> should work fairly well with most experimental setups. If you are
> picky about timing, please use the provided timestamps or additional
> methods to exercise your own tests."
>
> can you give us an idea of what situations lead to false positives and
> negatives, and how the provided timestamps would be less prone to
> error?

The internal test for skipped frames works as follows:

It compares the VBLTimeStamp against the requested timestamp of 'when'
bufferswap should happen. If the difference is more than 1.05 monitor
refresh intervals, it concludes a deadline-miss.

If you provide an explicit 'when' time as argument to 'Flip', i.e.,
call it e.g. as vbl = Screen('Flip', windowPtr, when), then Flip knows
that bufferswap should happen at the first vertical retrace after
system time 'when'. It will try to optimize all drawing operations to
try as hard as possible to meet that deadline. After swap, it can
compare this 'when' deadline against the VBLTimeStamp.

If you call vbl=Screen('Flip',windowPtr); without providing 'when',
then 'Flip' only knows that it should try to flip at next vertical
retrace. From known earlier VBLTimeStamps and the known refresh
duration it will predict when the next vertical retrace should start
and will choose its deadline accordingly to set that as its deadline.

In any case, the sign of the return argument 'missed' of Flip
indicates if the wanted presentation deadline was met for that
invocation of 'Flip'. This way, your script can test on a per frame
basis if stimulus onset time was correct or not. At the end of your
script, Flip will print out a summary of the total number of missed
deadlines ("PTB-WARNING: Screen flip missed the requested deadline xxx
times during this session...").

The accuracy of the returned VBLTimeStamp depends on accurate
knowledge of the height of the display in scanlines (including
vertical blank interval) the exact monitor refresh interval duration
and the fact that PTB's execution doesn't get interrupted between the
beamposition query and taking the first timestamp. Obviously
beamposition queries and sync to retrace need to work properly as
well. Psychtoolbox performs a whole battery of tests and cross-checks
during execution of 'OpenWindow' to make sure that all needed
mechanisms work properly and to get fairly accurate estimates of the
required parameters. This is the "white welcome screen" phase. Its duration
depends on how noisy your system is - a well working system should
pass the tests in less than 2 seconds. Still the calibrated values
could have a small measurement error which would slightly bias the
calculated timestamps. And there is a very very small probability that
PTB's execution gets interrupted between beampos and time query,
although use of the Priority command and proper system setup should
minimize such events.

All in all, there will be still a bit of noise in the estimated
VBLTimeStamp which could lead to false positives or negatives in the
built-in timing test. However, all the calculations and the code is
written in a way to make false negatives unlikely. It is biased to
report false positives, so you'd rather reject a valid trial based on
the tests instead of falsely accepting an invalid trial.

You have multiple options of checking presentation timing:

1. Don't check, just read the printout at the end of your session to
see if an excessive number of deadlines was missed.

2. Rely on the 'missed' flag of Screen('Flip') to check on a per frame
basis if the deadline was met. This relies on the test mentioned above.

3. Perform your own tests on the returned VBLTimeStamp. These
timestamps should be pretty accurate and if you wrote your experiment
script, you should be able to formulate a simple model and tests in
Matlab to do timing checks. Btw. when looking at old code for MacOS-9
PTB, i realized that many PTB users seem to have rather strange
concepts on how to measure and check their presentation timing. Its
surprising how many studies seem to get it right just by chance and
luck instead of design ;)

> for our own external test, we plan to dedicate a corner of the
> screen to a square that will alternate between grey and white on every
> other frame. we'll measure this with an analog photodiode and record
> the trace with our ADC. is this the sort of additional test you had
> in mind?

This is of course the most advanced and water proof form of testing. I
would be very interested in hearing numbers from you when you've done
that so we can see how well the internal software-based timing checks
really hold up to reality.
Valid XHTML :: Valid CSS: :: Powered by WikkaWiki