Inconsistent timing between keyboard.getKeys and keyboard.clock.getTime

I want to record response times, but I get inconsistent times with keyboard.getKeys and keyboard.clock.getTime, even though they are called simultaneously.
I would appreciate any help :slight_smile:

stim = visual.TextStim(win, color = "black", pos=[0,0], units="pix", height=100, text="+")

kb.clearEvents() # clear any early responses
kb.clock.reset() # reset clock

for n_stim in range(20): # for 20 frames
            time1 = kb.clock.getTime()
            keys = kb.getKeys(['c', 'm', 'escape'])
            time2 = kb.clock.getTime()
            if len(keys) > 0:

for thisKey in keys:
        RT = thisKey.rt

print("time1 = ", time1, " time2 = ", time2, " RT = ", RT)

# Output:   time1 = 0.759238800033927  time2 =  0.7613077000714839 RT = 0.6095231000799686

Even though I measure the time with kb.clock.getTime() just before and just after kb.getKeys([‘c’, ‘m’, ‘escape’]), the time measured by the former is about 100-200ms longer than the time measured by the latter. time1 and time2 do not differ substantially (< 1ms).

Which of the response times is correct? Why do they differ? Thanks for helping me with this!

From the PsychoPy API, I understand that using the kb.getKeys function (and the associated .rt property of any keys that were pressed), should be the more accurate one.

I am not an expert on all the low level stuff, but I think the main idea is as follows: If you use the kb.clock.getTime() function, you get a timestamp that corresponds to the time this function call was executed. However, a participant might have pressed a key before that function call is executed (e.g., while the win.flip() command is waiting for the refresh). The Keyboard() class does its own internal timekeeping so you do expect these recorded times to be shorter.

Using your script I get similar time differences on my computer. I must admit that I am somewhat surprised by the size of the difference, which I would expect to be in the order of a few frames (~32 to ~48 ms).

Thanks a lot for thinking about this riddle and for testing the script on your computer!

I also read that kb.getKeys() should be more precise. However, what I did not expect is…

  1. that the time difference is so big. I expected the max time lag to be one frame, since getTime is called on every frame.
  2. and especially that the time1, which was recorded just BEFORE the getKeys call, gives a longer time measure.

Hi There, is it possible the key was pressed earlier than that call? clock.getTime gets the current time ont he keyboard clock whereas kb.getKeys gets the time of keypress, which in theory isn’t the current time on the clock - so I think it is ok for them to be different (the getKeys is more accurate) - does that help?


Thanks for your response!
I see, why the time measured with getKeys could be earlier/shorter than that measured with getTime before the getKeys call.
However, I would expect only a small time difference. If I understand itcorrectly, in this case that would mean that 100-200ms elapsed between kb.clearEvents() and kb.getKeys (in the first cycle of the loop, or between two calls of kb.getKeys in all later cycles). To me, this does not seem probable given that there are only a few function calls in between?

My PI found a solution to the mysterious time lag :slight_smile:

The default of kb.getKeys() is waitRelease = True and setting it to False eliminates the problem.
To me the documentation of this argument is not totally clear, but it seems that with waitRelease = True the RT is the starting time of the key press. time1 and time2, measured with kb.clock.getTime() is about the sum of the RT and the duration saved with kb.getKeys(). The execution of the kb.clock.getTime() seems to wait until the key is released.

With waitRelease = False the RT of kb.getKeys() seems to be the starting time of the key press.

Here Jon explains the meaning of waitRelease and I think it is more comprehensible than the documentation.

Thank you all for the discussion and help!!