psychopy.org | Reference | Downloads | Github

Get key press before, during and after visual.ImageStim()

#1

Hey everyone,

I use the Coder in Psychopy v1.90.3 to implement a simple tapping task.

During the task, participants are required to tap a key synchronous to a visual stimulus (60 trials; Inter-Stimulus-Interval:1.8 sec; stimulus-duration: 0.2 sec). I want to analyse asynchronies between stimulus-onset and tapping-onset afterwards.

So at the start of every trial I set a timer that corresponds to the trial duration (1.8 sec). Then I present the stimulus after 0.3 sec (because I also want to assess early responses, prior to stimulus onset, as well) and I flip the window after 0.2 sec, corresponding to stimulus-duration. During the entire trial duration, I want to collect the keyPress, thats why I implemented the getKeys() function in the while-loop that is true until the timer is 0. In my output I now see that the program won’t collect keypresses prior stimulus onset.

Has anyone an idea how I could recode my trial loop?

‘’’

trial_clock = core.Clock()
timer = core.CountdownTimer()

def doTrial(stimuli_per_block):

for x in range(len(stimuli_per_block)):
    
    event.clearEvents()
    trial_clock.reset()
    timer.add(1.8)
    
    core.wait(.2)
    stimuli_per_block[x].draw()
    win.flip()
    stim_time = trial_clock.getTime()
    core.wait(.2)
    win.flip()
    
    while timer.getTime() > 0:
        
        for key in event.getKeys():
            if key == 'space':
                tap_time=trial_clock.getTime()
                
                stim_tap_deviation = tap_time - stim_time

'''
#2

It’s core.wait: https://www.psychopy.org/api/core.html#psychopy.core.wait

It messes with the keyboard buffer. Simplest solution: Replace each instance of core.wait during the period you want to record responses with the following

keys=event.waitKeys(maxWait=.2,timeStamped=trial_clock)
for key in keys:
    if key[0] == 'space':
        tap_time=key[1]
                

Not sure what you want to do with stim_tap_deviation given that stim_time hasn’t been set at that point, but that will at least record the tap time for you. You’ll want to make sure to do something with that information so it isn’t overwritten if they press a key again later, though.

Basically, by using timeStamped you’re getting a list of [key,time] tuples back from waitKeys, which gets around the problem that you won’t actually be checking when the key was pressed until after the waiting period (as opposed to later, when it’s happening immediately when getKeys is checked).

#3

Thanks for your reply,

eventually I managed to get around this problem by combining your snippet with the additional argument “hogCPUperiod” to capture keypresses also during wait periods (see https://www.psychopy.org/api/core.html --> " If you want to obtain key-presses during the wait, be sure to use pyglet and to hogCPU for the entire time, and then call psychopy.event.getKeys() after calling wait() ")

‘’’

trial_clock = core.Clock()

def visualSyncTap_doTrial(stimuli_per_block):

for x in range(len(stimuli_per_block)):

    event.clearEvents()
    trial_clock.reset()
    tap_time = 0
    stim_time = 0
    
    core.wait(.2, hogCPUperiod=.2) # wait 0.2 sec before stimulus presentation to capture early onset taps
    
    key = event.getKeys(timeStamped=trial_clock)
    
    for y in key:
        if y[0]=='b':
            tap_time=y[1]
    
    # for visual stimuli:

    stimuli_per_block[x].draw()
    win.flip()
    stim_time=trial_clock.getTime() # get precise time of stimulus presentation to compute onset interval later 

    core.wait(.2, hogCPUperiod=.2) # present stimulus for 0.2 sec
    
    key = event.getKeys(timeStamped=trial_clock)
    
    for y in key:
        if y[0]=='b':
            tap_time=y[1]

    win.flip()
    
    core.wait(1.4, hogCPUperiod=1.4) # wait for additional 1.4 sec -> ISI = 1.6 sec
    
    key = event.getKeys(timeStamped=trial_clock)
    
    for y in key:
        if y[0]=='b':
            tap_time=y[1]

    stim_tap_interval = tap_time - stim_time # compute temporal interval between stimulus and tap

    logfile.write(out_string % (int(subject[0]),int(subject[1]),subject[2],int(subject[3]), subject[4], stim_time, tap_time, stim_tap_interval))
    logfile.flush()
    event.clearEvents()

‘’’

Thanks for your help!