psychopy.org | Reference | Downloads | Github

Missing key press inputs with kb.getKeys (around 5% of the trials)

Hello,

I am running an experiment using key presses; so I use keyboard from psychopy.
The problem is, around 5% of the trials, key press inputs are missed. I know it is not due to connectivity nor material, it has to be about software or code. It does it also when I change the computer.

The experimental pc is windows 7, Python version : 3.6.12, Psychopy : 2020.2.10

In the experiment, participants have a 800ms deadline to answer to a trial, so when the key press input is absent, it says that the participants did not answer on time… This leads to many trials that must be done again… I really don’t understand why, it works well 95% of the time, but there are many trials where the keyboard input is missed.

Here is the concerned part of the code (it’s double interleaved psychometric staircases ):


kb = keyboard.Keyboard()
...
for trialN in range(info['nTrials']):
    if trialN == 30:
        core.wait(1)
        pausetext="you can do a break now, press to continue"
        ask(text=pausetext)
    shuffle(stairs)
    for thisStair in stairs:
        try:
            delta = thisStair.next()
        except StopIteration:
            continue

        ## trial parameters
        ori_i = np.random.choice(orientation)
        gabor.ori = ori_i
        gabor.contrast = 0+delta

        ## draw black fixation
        blackCross.draw()
        win.flip()
        core.wait(.5)

        ## draw gabor
        for i in range(0,3): #3 frames with 60HZ
                gabor.draw()
                circle1.draw()
                win.flip()
        win.flip()
        kb.clearEvents(eventType = "Keyboard")
        kb.clock.reset()

        ## Gabor response
        while True:
            t = kb.clock.getTime()
            if t > deadline:
                too_late.draw()
                win.flip()
                core.wait(1)
                break
            theseKeys = kb.getKeys(keyList=['3', '4'], waitRelease=False)
            if kb.getKeys(keyList=["escape"], waitRelease=False):
                core.quit()
            if len(theseKeys):
                theseKeys_gabor = theseKeys[0] 
                pressed_gabor = theseKeys_gabor.name
                rt_gabor = theseKeys_gabor.rt
                if ori_i == 90:
                    if conditionGAB == "A":
                        expected_gabor = '3'
                    else:
                        expected_gabor = '4'
                elif ori_i == 0:
                    if conditionGAB == "A":
                        expected_gabor = '4'
                    else:
                        expected_gabor = '3'
                if pressed_gabor == expected_gabor:
                    accuracy_gabor = 1
                elif pressed_gabor != expected_gabor:
                    accuracy_gabor = 0
                thisStair.addResponse(accuracy_gabor)
                thisExp.nextEntry()
                trial += 1
                break

        win.flip()  # clean screen
        ITI = np.random.choice(ITIarray) # random inter trial interval
        core.wait(ITI)

## End of the trials
kb.clearEvents(eventType = "Keyboard")
core.wait(1.0)
ask(text=instr_end)
win.flip()

Thank you for reading :slight_smile:

You have two successive calls to .getKeys(), meaning that there is a (very small) chance that a response would come after the first call but then also get missed by the second, as it will only accept the escape key. So you should change it to something like this, to check the keyboard only once per cycle:

theseKeys = kb.getKeys(keyList=['3', '4', 'escape'], waitRelease=False)

if 'escape' in theseKeys:
    core.quit()

But the likelihood of this causing your issue at a rate as high as 5% of trials is very small… More likely is that it is something to do with the call to kb.clearEvents(). I’m not sure of the temporal structure of your trials. Perhaps just try removing that call - you should be able to filter out any keypresses that have negative timestamps so collecting out-of-range keypresses shouldn’t be too much of a concern.

1 Like

I see ! I will try your solutions; thank you for your answer :slight_smile:

Still the issue, I removed the second call to getkeys as suggested, and then I tried :

  • removing kb.clearEvents and filter out keypresses with negative timestamp with kb.clock.reset() before the response

  • kb.getKeys(keyList=[“escape”], waitRelease=False, clear = False) with kb.clearEvents

nothing works, 5% of the keypresses are missed