How to get absolute timing of keypresses?

I would like to get the absolute time of key presses (using the newer getkeys function of the keyboard class). From the documentation, I was expecting tDown attribute to give me the time of each key press in a similar format to core.getAbsTime() i.e in Unix Time. I can easily convert Unix time to a more readable format (‘hh-mm-ss.ms’).

However, tDown is not working as expected. It gives me a value much smaller than those given by core.getAbsTime (954583.507475888 vs 1647009937).

Please advise me on how I can use the keyboard class to return the absolute time of keypresses. Thanks.

Hi There,

by “absolute” timing are you referring to time since the start of the routine, since the start of the experiment or in global “wall clock” time?

Thanks,
Becca

Hi Becca,

Apologies, my terminology is incorrect. I am looking to return the global “wall clock” time. If you have any ideas of how to do this, that would be much appreciated.

While we are on the subject, I would love to get some more clarity regarding the value returned by tDown. I expected it to be similar to the Unix time (since the start of 1970 epoch) returned by getAbsTime. Instead, it’s a number like 1647009937, which makes little sense to be right now. If you could clarify this value, and how it can be made usable, both as a global time and absolute time (since start of routine) that would be extremely helpful.

I have been researching this for about 2 weeks now with little luck so any advice is very welcome.

Thank you in advance!

Will

As an example, here’s the dictionary output from multiple keypresses. I pressed the keys 2, then 3, then 4, around a second after each other (see the response times). I notice how part of the tDown attribute recognises these seconds ‘…83.94…, …85.08…, …86.28…’, however i’m confused how I’m meant to interpret the numbers before that.

combined_response_dict = {'key_name': [['2'], ['3'], ['4']], 'key_RT': [[1.18], [2.318], [3.526]], 'key_tDown': [[977283.942945941], [977285.080978345], [977286.288909974]]}

Hi Will,

To get the local “wall clock” time you’ll need a code component, in the begin experiment tab use:

import time

this imports the python time module so you can fetch local time in a variety of formats. You could save the wall clock time at any point using:

thisExp.addData('wall_time_local', time.localtime())
thisExp.addData('wall_time', time.time())

For example

What I actually suggest doing is getting the timestamp at the start of the routine and then setting your keyboard to save time relative to start of routine, then you can calculate the wall clock time of the keypress later on - this will be a bit more specific because it will use PsychoPy’s inbuilt method for fetching time but you also know what the “zero point” was in wall time.

I believe tDown refers to the time the key was pressed down relative to the last time the Keyboard objects internal clock was created or, if relevant, reset. So, in the below, you’ll notice kb.clock.getLastResetTime()+thisKey.rt is the same pretty much as thisKey.tDown.

from psychopy.hardware import keyboard
from psychopy import core, visual
import time 

win = visual.Window(fullscr=False)
kb = keyboard.Keyboard()
clock = core.Clock() 
mclock = core.MonotonicClock()
while clock.getTime() < 5:
    win.flip()
    # wait for keypresses here
    keys = kb.getKeys()
    for thisKey in keys:
        if thisKey=='q':  # it is equivalent to the string 'q'
            core.quit()
        else:
            print(thisKey.name, thisKey.tDown, thisKey.rt, kb.clock.getLastResetTime(), kb.clock.getLastResetTime()+thisKey.rt)

Hope this helps,
Becca

Hi Becca,

Thanks a lot for this. It was very insightful and i’m happy with my current solution.

Take care