Dear Psychopy,
We would like to be able to launch a keyboard ‘queue’ , do some stimulation, and check after that stimulation whether a key was pressed and recorded in the queue (and gather timing of the key press since initiating the queue). I wonder whether this is something that already exists in psychopy, or whether we would have to program this ourselves (perhaps using pyglet).
e.g. trial in a pseudo experiment
queue listen for keys
…
draw stuff
…
query whether anything happened with the keyboard during … draw stuff …
a similar procedure exists in PTB3:
http://psychtoolbox.org/docs/KbQueueCreate
This would allow more flexibility in gathering responses from participants in more complex tasks, where many things happen during a trial, and a traditional event.waitKeys wouldn’t be possible.
many thanks for your help,
ian
Are you talking about event.getkeys and event.waitkeys? http://www.psychopy.org/api/event.html bottom of the page.
getkeys lets you specify certain kb press, and records whatever are being pressed, while waitkeys is the same, but holds the operation until certain keypress is made. You can use logging to record all the events happening too.
1 Like
Hi Jin_Jeon,
Thanks for your reply. I don’t believe that event.getkeys and event.waitkeys can do what I am after.
with event.getkeys, you still have to implement something like:
def get_keypress(class_obj):
keys = event.getKeys()
if keys:
return keys[0]
else:
return None
while True:
# key logger
if not response_made and self.trial_start.getTime() < tp['max response time']:
key = get_keypress(self)
if key and key in tp['possible responses']:
self.rt = self.trial_start.getTime()
self.response = key
response_made = True
# if trial is over here
if self.trial_start.getTime() > tp['trial length']:
break
# Only draw the image during the defined image duration
if self.trial_start.getTime() < tp['img duration']:
im = tp['target image']
im.setPos((0, 0))
im.draw()
# otherwise draw a fixation
else:
fixation.draw()
self.win.flip()
Now this is useful but really what I would like to do is more:
queue = listen_keys()
for frame in frames:
im = frame
im.setPos((0, 0))
im.draw()
self.win.flip()
fixation.draw()
self.win.flip()
# or do anything here that can't rely on a while loop
keypress = collect_any_response(queue)
rt = keypress['time']
answer = keypress['key']
...
I hope this makes more sense now? Is this something that event.getKeys() can achieve?
Thanks for your help,
best wishes,
ian
Hey Ian,
Yeah, I think you are going in the right direction. I’ll try to write an example code. Hopefully the code makes sense:
exampleClock = core.Clock() #creates a clock time
time1_trial = exampleClock.getTime() # gets time at this point
keyPressed = event.getKeys(keyList=['period','slash'], modifiers=False, timeStamped=exampleClock)
if keyPressed:
#any other stuff you want
time2_trial = exampleClock.getTime()
reaction_time = time2_trial - time1_trial
self.rt = reaction_time
# or
self.rt = event.getKeys[0][1]
If we have something like the above,
event.getKeys[0][0]
would give you the first key press info, while
event.getKeys[0][1]
return the reaction time of that first key.
So then you can set something like self.rt = event.getKeys[0][1]
for reaction time.
Also, there is self.rt = reaction_time
. I think the code itself is direct by itself, but basically I measure timing before the keypress, then measure the time again once the key is pressed. Then I subtract the two to get the timing difference, and add it into the data frame. But yeah, if you have multiple keys you want to record, I think you might want to create a helper function or otherwise list them all individually.
I hope this helps!
Hi
Thanks again for your quick reply.
I am not sure we are thinking about the same thing. Maybe my question wasn’t asked clearly enough.
What you are refering to I think I already know how to do. I’ll try and better explain what I am after.
queue = listen_keys()
# from this moment on, if the user presses the keyboard, it gets recorded in the background
# now we draw stuff in a trial, yet we don't actively monitor for key presses here
for frame in frames:
# the user can still press a key here
im = frame
im.setPos((0, 0))
im.draw()
self.win.flip()
#the user can respond here too, as it is on an independent process.
fixation.draw()
self.win.flip()
# or do anything here that can't rely on a while loop
# now my trial is over and I want to see if any key has been pressed in the queue
keypress = collect_any_response(queue)
rt = keypress['time']
answer = keypress['key']
In Psychtoolbox, what you are describing is the equivalent of KbCheck.
http://psychtoolbox.org/docs/KbCheck
Another way of doing things is by starting a parallel queue that listens for keys in the background:
http://psychtoolbox.org/docs/KbQueueCreate
I would like to know if there is an equivalent in PsychoPy to KbQueueCreate, KbQueueStart KbQueueStop and KbQueueCheck.
many thanks!
ian
Hey Ian,
Oops sorry I might have misunderstood. As far as I know, I don’t think there is something equivalent in PsychoPy to KbQueueCreate specifically. One thing I can think of implementing such would be just using getKeys at the beginning, and let it sit to register any keys being pressed to a separate list or data frame while certain tasks are being performed? For example:
for loop:
exampleClock = core.Clock() #creates a clock time
time1_trial = exampleClock.getTime() # gets time at this point
keyPressed = event.getKeys(keyList=['period','slash'], modifiers=False, timeStamped=exampleClock)
if keyPressed:
sampleList.append = keyPressed[0][0]
#any other stuff you want
time2_trial = exampleClock.getTime()
reaction_time = time2_trial - time1_trial
and use sampleList to get all the list of keys pressed?
This is an old thread, but as it came up in a Google search for me, I thought I’d note that since this was posted, Mario Kleiner has ported the Psychtoolbox keyboard handling to PsychoPy. That Keyboard
class should now be used instead of the event
module:
https://www.psychopy.org/api/hardware/keyboard.html
So the sort of functionality sought here should be directly accessible in PsychoPy now.