Timing precision

PsychBench is built on Psychtoolbox, which is designed with timing precision as a priority. The same goes for PsychBench. Below is a technical summary of timing processes and precision. If you need more information, please contact us.

Note the timing precision of PsychBench is bounded by the timing precision of Psychtoolbox functions, which in turn depends on your operating system, hardware, and setup. For more information on this level, see for example psychtoolbox.org/requirements.

Timing precision versus Compatibility settings

Some screen object properties set tradeoffs between visual timing precision and compatibility: doSyncTests, syncTestsParams, useCompositor. On systems where the high precision defaults cause problems in opening or closing the experiment window (especially on Mac, sometimes on Windows), you can switch to compatibility instead. Note Psychtoolbox recommends not running precise timing experiments on such systems. You can still develop and test precise timing experiments and/or run experiments that don’t need precise timing. Usually the easiest way to set these properties is with pb_prefs.

Frames

Internally PsychBench divides time during trials into short increments called frames. Frames are locked to refresh of the screen the experiment is running on: frame transition is always at screen refresh, and nominal frame rate = screen refresh rate. A common screen refresh / frame rate is 60 frames/sec (interval = 1/60 ≈ 17 msec). See screen object record properties refreshRate, refreshInterval.

Frames define the timing resolution for most events during trials. For example, PsychBench checks to start/end elements once per frame, dynamic displays change on screen up to once per frame at screen refresh, response handlers often poll for input at their devices once per frame, etc.

Dropped frames

If a frame is too short for the processing that needs to run in it, it will extend to multiple screen refresh intervals. The other frames that would have run in those intervals are then “dropped”. This results in one iteration of all frame-based events where multiple were expected. For example, element start/end is delayed for one or more screen refreshes, animated element displays pause (but don’t disappear), etc. A record of actual frame rates and intervals achieved in each trial is available in trial object record properties frameRates, frameIntervals.

PsychBench generally recovers timing after dropped frames. e.g. if frames are dropped during an element running and before it ends, its end time later doesn’t change and its synchronization with other elements is not affected. (An exception is if the dropped frames occur at element start and so delay its start time, and it has an end condition like duration set. But this is because by definition end.duration goes off the element's actual start time.)

Element start/end

PsychBench checks to start/end elements once per frame, and element start/end aims to occur at the nearest frame transition. This is regardless of modality (visual, auditory, etc.). However, note visual elements in particular are further constrained physically to start or end at frame transition (screen refresh).

Element synchronization

If you set the same start or end condition for different elements, they aim to start or end at the same nearest frame transition. This synchronizes them to the best precision Psychtoolbox allows.

Element start/end timing deviation

There are various potential sources of deviation between expected element times and actual times you get during an experiment. There are also ways to avoid some of them if precise timing is important.

  • Timing in general may be less precise in trial 1 due to MATLAB loading functions into memory on first use. If timing precision is important, consider discounting the results of trial 1.
  • The fact that element start/end snaps to frame transition causes a base deviation from expected start/end times of up to ±1/2 frame interval. This deviation averages to zero.
  • If frames are dropped due to processing at an element start/end, the start/end is delayed by that many screen refresh intervals (Dropped frames above). If this occurs and it matters in your experiment, you may be able to reduce or eliminate it by setting a start/end “buffer” for the element. This tells PsychBench to begin preparing the element start/end early. However, it essentially shifts the dropped frames from after the target start/end time to before it, so it can require careful use. Buffering is only possible for start/end conditions that have definite times so PsychBench knows when they are coming ahead of time. See element properties startBuffer, endBuffer.
  • If an element is set to start/end at an event that occurs spontaneously (e.g. response, trigger conditions), there is an additional delay of 2 frames average (1–3 frames) from time of event. This doesn’t apply to conditions that have definite times so PsychBench can plan ahead (t conditions, duration conditions > 2 frames, any condition with a wait time timeFrom > 2 frames). So, using t conditions or adding even small timeFrom can avoid this type of delay.
  • All element start/end conditions go off the actual times of the events they listen for, including any deviation from expected times. i.e. they go off the literal events. See example below...

Example: Timing conditions go off literal events

element.start.t = 2
element.end.t = 2.5

element.start.t = 2
element.end.duration = 0.5

→ Both these elements aim to start at 2 sec from trial start. Now suppose the time both actually start at is 2.017 sec (1 dropped frame at 60 frames/sec). Then the end.t condition (relative to trial start) would still aim to end the element at 2.500 sec, but the end.duration condition (relative to element start) would aim to end it at 2.517 sec. So for example you could use end.t to prioritize absolute end time of the element and end.duration to prioritize actual duration.

Time measurements

Element start/end times

Element record properties startTime, endTime, duration record element times. Here are some common cases for how PsychBench gets these times:

  • Element presents a visual stimulus: Start/end times are frame transitions (screen refreshes) when the display starts/ends, measured by Psychtoolbox Screen('Flip').
  • Element presents an auditory stimulus: Start/end times are sound start/end times, measured by Psychtoolbox PsychPortAudio('GetStatus').
  • Element listens for input from a device: Start/end times are frame transitions that are the earliest and latest times input could be received, measured by Psychtoolbox Screen('Flip').

Input times

Response, trigger, and other input times are measured by Psychtoolbox GetSecs, KbCheck, KbQueueCheck, and similar functions depending on the device and method. In the case of an element that checks for input once per frame (e.g. KbCheck), PsychBench measures input time as the average of time of check where the input was received and time of check in the previous frame, with a basic uncertainty of 1/2 the interval between checks (≈ 8 msec at 60 frames/sec with no dropped frames). In other cases where a background process is used to listen for input (e.g. KbQueueCheck), input time is measured directly by the process. See response handler record properties responseTime, responseLatency, d_responseTime, and element record properties triggerTime, d_triggerTime.