psychopy.org | Reference | Downloads | Github

Customize Force End Routine


#1

Hi,

I need to modify the force end routine option. I want the routine to last a minimum of 2 seconds, but all participants will have 4 seconds to respond.

If they respond before 2 seconds, the trial should end at exactly 2 s. If they respond after 2 seconds, I want the trial to force end at the time that they respond. I’ve tried:

if len(theseKeys) <= 2:
continueRoutine = False

Right now, I have two keypress responses, one where that ends at two seconds, and another that immediately follows and allows for the force end routine. The problem is that I want the routine to end at 2s, if a response is given before the 2s period.

Thanks,

Emily Hokett


#2

Dear Emily,

The tag says ‘Coding’ but it sounds like you’re actually using Builder. Can you confirm which?


#3

Hi Michael,

I’ve been primarily using the builder, but I tried to enter a code so that I could end the trial at 2s if a response had been given before the 2s minimum.


#4

Not tested but some nested if statements loops may work on thenevery frame tab in the code component

if t <= 4.0:
    if t<= 2.0:
         if len(theseKeys) == 2: #however many responses you need - in your example it has to be less than or equal to 2 which will
always be true
              continueRoutine = False
     if len(theseKeys) == 2:
         continueRoutine = False
else:
      continueRoutine = False
          

#5

Thanks Oli.

The code isn’t working for some reason.

Do you know if there is a way to say if the key has been pressed before 2s, end routine? Then, if the key is pressed after 2s force end routine. If there is no response, end routine at 4s.


#6

I would do the key checking entirely in code and not have a keyboard component.

In the begin routine tab of your component, put:

end_at_2s = False

In the Each frame tab, put something like:


# first check whether to end in response to an earlier keypress
if t >= 2.0 and end_at_2s: 
    continueRoutine = False
elif t >= 4.0: # all trials end at this stage
    continueRoutine = False

# otherwise, check for a new keypress:
keys = event.getKeys()

if keys: # if at least one key exists in the list,
    if 'escape' in keys: # now need to check for the quit key ourselves
        core.quit() 

    elif t < 2.0: # just remember this for later
        end_at_2s = True 
        thisExp.addData('RT', t) # but store the current time as the RT

    else: # we have a keypress between 2 and 4 s
        thisExp.addData('RT', t)
        continueRoutine = False



#7

Hi Michael,

Thanks, that helped. Now, the trials are all ending at 2s, regardless of it a key is pressed or not. I’m not sure what I’m missing here. Any suggestions?


#8

So now, I have the routine ending at 4s, but it is also acting as a force end routine. It is not waiting for at least 2s. This is the code that I’m using:
keys = event.getKeys( )
if keys: #at least one key
if t >= 2.0 and keys == ‘1’ or ‘2’ or ‘3’:
continueRoutine = False
else:
continueRoutine = True
if ‘escape’ in keys:
core.quit( )
elif t < 2.0:
continueRoutine = True
thisExp.addData(‘RT’, t)
elif t >= 4.0:
continueRoutine = False


#9

Hey Michael,

I tried running this again, and I think it’s working! Thanks!

Emily


#10

There was (at least) one error in my original code: The check for whether t >= 4.0 shouldn’t have been within the code that responds to keypresses. Have edited that accordingly.


#11

Okay, thanks. Is there a way that I can record no responses? How do I say if no keys, responses is “none”.


#12
# first check whether to end in response to an earlier keypress
if t >= 2.0 and end_at_2s: 
    continueRoutine = False
elif t >= 4.0: # all trials end at this stage
    continueRoutine = False

# otherwise, check for a new keypress:
keys = event.getKeys()

if keys: # if at least one key exists in the list,
    if 'escape' in keys: # now need to check for the quit key ourselves
        core.quit() 

    elif t < 2.0: # just remember this for later
        end_at_2s = True 
        thisExp.addData('RT', t) # but store the current time as the RT

    else: # we have a keypress between 2 and 4 s
        thisExp.addData('RT', t)
        continueRoutine = False
else: #add this 
      thisExp.addData('RT', None) #and this

Should do it


#13

Thanks! It works.


#14

It is actually only recording responses as “none” and when I change the positioning to align with the other code, it does not record any response as “none”.

if t >= 2.0 and end_at_2s:
continueRoutine = False
elif t >= 4.0: # all trials end at this stage
continueRoutine = False

otherwise, check for a new keypress:

keys = event.getKeys()

if keys: # if at least one key exists in the list,
if ‘escape’ in keys: # now need to check for the quit key ourselves
core.quit()

elif t < 2.0: # just remember this for later
    end_at_2s = True 
    thisExp.addData('RT', t)
    thisExp.addData('rating', keys)

elif t > 2:
    thisExp.addData('RT', t)
    thisExp.addData('rating', keys)
    continueRoutine = False

elif t <=4: # we have a keypress between 2 and 4 s
    thisExp.addData('RT', t)
    thisExp.addData('rating', keys)
    continueRoutine = False

else: # this hasn't been working if I tab it to the beginning of the line or move it with the other code
    thisExp.addData('rating', None)

#15

Hi Emily, we need to see all of the code fully formatted, i.e. surrounded by triple backticks ``` before and after.

Sometimes these issues are due to problems with code indenting and we can’t tell that without seeing all of the code in one properly formatted block.


#16

Here is the code with the backticks:

if t >= 2.0 and end_at_2s:

elif t >= 4.0: # all trials end at this stage
````continueRoutine = False

# otherwise, check for a new keypress:
keys = event.getKeys()

if keys: # if at least one key exists in the list,
````if 'escape' in keys: # now need to check for the quit key ourselves
````````core.quit() 

````elif t < 2.0: # just remember this for later
````````end_at_2s = True 
````````thisExp.addData('RT', t)
````````thisExp.addData('rating', keys)
    
````elif t > 2:
````````thisExp.addData('RT', t)
````````thisExp.addData('rating', keys)
````````continueRoutine = False

````elif t <=4: # we have a keypress between 2 and 4 s
````````thisExp.addData('RT', t)
````````thisExp.addData('rating', keys)
````````continueRoutine = False

else: #add this 
`````thisExp.addData('rating', None) #and this

With this format, it is only outputting the ratings as none, even when there is a responses. I'm not sure where to put these last two lines of code. I need the "rating" to output as "None" when there is no response given, and the "RT" column is fine remaining blank when no response is given.

Thanks for your help with this

#17

I added the backticks, but they didn’t show up. Each line of code is only tabbed either once or twice. I can try to repost it soon.


#18
#all code goes between the 
#two sets of back ticks
# it looks like you've got each
#line between backticks


#19

Okay, I found that I can analyze my data without it outputting missed responses as “none,” but I really do need to find a way to record all responses using a code. I tried using brackets instead of parentheses, thinking that it would output a list, rather than a single value. but it didn’t work. Here is the original code:

if t >= 2.0 and end_at_2s: 
continueRoutine = False # this didn't indent for some reason in the preview, but I'm not sure why
elif t >= 4.0: # all trials end at this stage
    continueRoutine = False

# otherwise, check for a new keypress:
keys = event.getKeys()

if keys: # if at least one key exists in the list,
    if 'escape' in keys: # now need to check for the quit key ourselves
        core.quit() 

    elif t < 2.0: # just remember this for later
        end_at_2s = True 
        thisExp.addData('RT', t)
        thisExp.addData('rating', keys)
    
    elif t > 2:
        thisExp.addData('RT', t)
        thisExp.addData('rating', keys)
        continueRoutine = False

    elif t <=4: # we have a keypress between 2 and 4 s
        thisExp.addData('RT', t)
        thisExp.addData('rating', keys)
        continueRoutine = False

    else: #record no response
        thisExp.addData('rating', None)


#20

I just want to include these screenshots for reference.