Hello,
I am studying code generated from the PsychoPy builder (as a practice exercise) and just noticed something strange. I 'd like to present a stimulus 0.5s after the beggining of a given trial. The builder generates the following piece of code:
t = trialClock.getTime()
if t >= 0.5 and stim.status == NOT_STARTED:
# keep track of start time/frame for later
stim.tStart = t
stim.frameNStart = frameN # exact frame index
stim.setAutoDraw(True)
if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
win.flip()
On LCD monitors, the refresh is a flood fill from top to bottom. Does the flip() method correspond to top (onset of refresh cycle, which I suspect) or bottom (end of refresh cycle)?
In a second exercise, I chose to present the stimulus at t = 0.2s during 0.2s. The builder then generates the following:
if t >= 0.2 and stim.status == NOT_STARTED:
# keep track of start time/frame for later
stim.tStart = t
stim.frameNStart = frameN # exact frame index
stim.setAutoDraw(True)
frameRemains = 0.2 + 0.2- win.monitorFramePeriod * 0.75 # most of one frame period left
if stim.status == STARTED and t >= frameRemains:
stim.setAutoDraw(False)
I am confused. Why is ā-win.monitorFramePeriod * 0.75ā added in this case?
So the flip() method returns the end of the refresh cycle? In other words, the code continues after a flip() call when the refresh cycle is finished? @Michael could you then clarify what the code generated by the Builder is doing? Many thanks and happy new year PsychoPy folks!
The time between the physical refresh and the flip returning depends on the monitor, which can take additional time after the graphics card has finished its work (and the graphics card and PsychoPy would never know). To know the lag between flip() returning and the screen updating you have to use a physical device (e.g. blackboxtoolkit). As an example, I have 144Hz Iiyama lcd gaming monitor. In āDirect Driveā mode it flood fills from top and hs minimal lag behind the flip() call (photodiode detects stimulus 2.5ms after flip finishes). BUT in Game mode or Movie mode thereās a roughly 1 frame delay and (bizarrely) the screen fills from the bottom! No software package can tell what post-processing your monitor does so you need to measure it.
The book by me and Mike has more info about monitors and timing.
The code about subtracting win.monitorFramePeriod * 0.75 is just PsychoPy deciding whether or not it should try and squeeze in another frame given a time-based stimulus duration. If we have a 16.67ms refresh period and weāre 14ms from the deadline time then present another frame, but if weāre at 2ms remaining then donāt.
Thanks Jon for this clarification and for pointing out the crazy effects of different monitor modes! I currently donāt have the material (photodiode) to measure this. If I understand correctly, the flip() is returned by the GPU, and should thus correspond to the onset of a refresh cycle (disregarding any post-processing of the monitor). Am I correct?