Key Release Events

727 views
Skip to first unread message

Jeremy Hogeveen

unread,
Nov 24, 2013, 1:51:48 PM11/24/13
to psychop...@googlegroups.com
Hello all,

I'm sure this is easy to figure out from some of the more complex coding requests on here, but here is my problem: participants in my task will be holding down two keys (v & b) and I want PsychoPy to record the onset of a finger lift movement (i.e. to report the key release time on each routine). I would also like to let the routine run to completion rather than end when the response is made, but would prefer if PsychoPy did not record the subsequent key press (i.e. holding the keys down for the next trial).

Any help would be much appreciated!

Cheers,

Jeremy 

PS In case it makes it easier, Here is the code for the current response component:

        # *key_resp_2* updates
        if t >= ONSET+1 and key_resp_2.status == NOT_STARTED:
            # keep track of start time/frame for later
            key_resp_2.tStart = t  # underestimates by a little under one frame
            key_resp_2.frameNStart = frameN  # exact frame index
            key_resp_2.status = STARTED
            # keyboard checking is just starting
            key_resp_2.clock.reset()  # now t=0
        elif key_resp_2.status == STARTED and t >= (ONSET+1 + ONSET+3.068):
            key_resp_2.status = STOPPED
        if key_resp_2.status == STARTED:
            theseKeys = event.getKeys(keyList=['v', 'b'])
            if len(theseKeys) > 0:  # at least one key was pressed
                if key_resp_2.keys == []:  # then this was the first keypress
                    key_resp_2.keys = theseKeys[0]  # just the first key pressed
                    key_resp_2.rt = key_resp_2.clock.getTime()
                    # was this 'correct'?
                    if (key_resp_2.keys == str(corrAns)): key_resp_2.corr = 1
                    else: key_resp_2.corr=0

Richard Höchenberger

unread,
Nov 28, 2013, 4:58:14 AM11/28/13
to psychop...@googlegroups.com
Hello Jeremy,

I don't have time for an extensive answer right now; but since there's not been any response so far, I just wanted to give you some hints.

As far as I know, keyboard release events can only be captured via ioHub's keyboard component. ioHub runs as a separate process dedicated to capture and process hardware events of any kind. A 'preview' of ioHub is included in PsychoPy 1.77.00 [1]. An example for using ioHub to handle keyboard events can be found at [2].

To capture a keyboard release event of the 'v' and 'b' keys, you would probably do something like this:

--------------------
for event in keyboard.getEvents(event_type=EventConstants=KEYBOARD_RELEASE):
    if event.key.lower() in ['b', 'v']:
        ...
        break
--------------------

I hope this help a bit.

    Richard

Richard Höchenberger

unread,
Nov 28, 2013, 5:45:40 AM11/28/13
to psychop...@googlegroups.com
On Thursday, November 28, 2013 10:58:14 AM UTC+1, Richard Höchenberger wrote:
for event in keyboard.getEvents(event_type=EventConstants=KEYBOARD_RELEASE):

Of course that's supposed to read:
for event in keyboard.getEvents(event_type=EventConstants.KEYBOARD_RELEASE):

Sol Simpson

unread,
Nov 28, 2013, 4:52:25 PM11/28/13
to psychop...@googlegroups.com
Jeremy emailed me soon after posting this question and we ended up exchanging some emails instead of some posts. ;)

For others reference in case a similar question comes up again, I first suggested this post as a good starting point showing how iohub can be used within Builder via Custom Code . The follow up correspondence can be found below.

###############

Hi Jeremy,

 I am unsure about how to modify the .yaml file to enable full screen,

Currently the builder creates the pyglet window before it calls any "Begin Experiment" custom code; so when iohub gets initialized the window has already been created. Therefore to set fullscreen mode you would do so in the Builder Experiment Settings itself. You should still make sure that the Display Device in the iohub_config.yaml has the same monitor information as you have defined in the Builder (i.e. the same width, height, display number).

in this task participants are already holding down the response buttons at the start of the trial, and then .... cues participants to lift one of two fingers.

In this case, assuming that the custom code is within the routine which presents the cue and you want to collect the key release from, then I think these are the only changes you would need to make to use code like that in the example:

1) Each Frame Code Section:  If the routine starts by showing the cue, and the persons finger is already pressed, then in the 'Each Frame' section of the custom code you would want to change the code to wait for key release events, not key press or key_char events.:

if frameN == 0:
    # This clears all events that have been detected,
    #  but not requested by the experiment script, from the iohub server. 
    io.clearEvents('all')
    trial_start=core.getTime()
else:
    #  A KEYBOARD_CHAR event is generated when a key press
    #  is followed by a key release of the same key.This means that 
    #  if a key has been pressed prior to the start of this routine and is 
    #  released during the routine, only the KEYBOARD_RELEASE event will         
    #  be received.    
    #
    key_releases=iokeyboard.getEvents(EventConstants.KEYBOARD_RELEASE)
    
    # However, we should also check for KEYBOARD_CHAR events 
    # to make sure the key release event we got was not based on a 
    # key press event since the start of this routine.
    #
    key_chars=iokeyboard.getEvents(EventConstants.KEYBOARD_CHAR)
    
    # Filter out key releases that had were from a key press event that 
    # occurred within this routine
    #
    release_keys = [evt.key for evt in key_releases]
    char_keys = [evt.key for evt in key_chars]
    valid_key_releases = [evt for evt in key_releases if evt.key not in char_keys ]

    # check the valid key release events found for a key value equal to 
    # one of the two valid response keys
    # set 'response_event' variable to equal the first match found.
    #
    for iok in valid_key_releases :
        if iok.key in [u'LEFT',u'RIGHT']:
            response_event=iok
            continueRoutine = False 
            break

2) End Experiment Code Section:  The only change is to remove setting the
 'duration' result variables, since we do not have the key char or key press
 event that is associated with the key release.

I hope that helps, let me know if you have any more questions.

Jeremy Hogeveen

unread,
Dec 2, 2013, 10:29:55 AM12/2/13
to psychop...@googlegroups.com
Apologies, I stopped checking the board after the revelatory e-mail exchange (thanks again Sol), but thank you for your response as well Richard! The final program differs slightly from Sol's suggestion, but the custom code outlined below definitely pointed me in the right direction. 

A collaborator who will need to use the program as well will be doing so in Windows whereas I created it in OS X, so my final question is: Are there any known issues with flipping between operating systems when the program calls on ioHub, or should this be fine as long as both CPUs are running PsychoPy v. 1.77 or later?

Sol Simpson

unread,
Dec 2, 2013, 3:42:27 PM12/2/13
to psychop...@googlegroups.com
Hi Jeremy,

There is no issue technically with running an experiment that uses ioHub and switching between OS's; the same is true of PsychoPy in general. I guess, in theory, there are considerations (depending on how paranoid you want or need to be) in terms of collecting data for the same experiment on two different OS's and computer specifications, and combining the results when doing an analysis. I have not heard of any such issues in practice (assuming somewhat similar hardware is being used), but if paranoid you could treat OS type as an independent variable in your analysis to make sure there is no significant effect of OS type on your results. ;)

Sol

Idalmis

unread,
Nov 10, 2014, 5:43:45 AM11/10/14
to psychop...@googlegroups.com
Hi Sol,

I'm running a similar version of the experiment that Jeremy talks about in this old post, where I need to capture key releases. I installed the iohub code you suggested to him and it works fine in Windows 7 but it doesn't work at all in Mac OS X Yosemite. I'm aware (from previous posts) there has been iohub issues with Mac OS X before, so I wonder if there is a fix/ work around it. I'm using the code in Builder using the latest standalone version of Psychopy (v1.81.02). Any help or advice would be great. 

Thanks!

Idalmis

Sol Simpson

unread,
Nov 11, 2014, 12:53:51 PM11/11/14
to psychop...@googlegroups.com
If using the PsychoPy2 Builder, you need to add PsychoPy2 to the list of apps that can use the accessibility API.  Here is a link to instructions on how to add an app to this list: 


The instructions are for a different app, but the process is the same, so when following the instructions just replace the app that is mentioned with Psychopy2.

Then restart PsychoPy and you should be able to get keyboard access.

I suggest you use the demos/coder/iohub/keyboard.py demo to do testing / debugging.

Thanks,

Sol 

Idalmis

unread,
Nov 12, 2014, 4:37:24 AM11/12/14
to psychop...@googlegroups.com
Thank you Sol! I'll give it a go. 

Idalmis

Idalmis

unread,
Nov 13, 2014, 10:27:04 AM11/13/14
to psychop...@googlegroups.com
Hi Sol,

Thanks for your help. I added PsychoPy2 to the list of apps that can use the accessibility API in the mac and the iohub is now working - at least for one version of my experiment. So, I have a different problem now. I hope you can help. 

One version of my experiment uses just one frame to present a finger lifting action (finger up), that's similar to the version that Jeremy (from the older posts here) was using. In that version, the iohub seems to be working fine now in both Windows 7 and Mac OS X Yosemite. However, I prefer to use several frames (simulating a video) for the finger lifting action. Therefore, I created 4 different inner loops (one for each condition, inside the main trials loop) which are not trials (the 'is trials' option is unticked) and I have a custom code to choose the order of these conditions. So far, the experiment works as intended. The problem is that the key release responses are not being recorded at all in the Mac (in this version of the experiment) and I wonder whether this is to do with the placement of the iohub codes. 

The code to load the iohub ('Begin Experiment' tab) is within a routine called 'trial' just before each of the inner loops that contain the conditions. Then in the 'Each Frame' tab of a new code in each of the conditions routine (inner loops containing the videos) I added the code you posted here (28/11/2013). And in the 'End Routine' of each condition, I have the capture responses code as below:

trials.addData("trial_start_time", trial_start)
if response_event:
    trials.addData("resp.time", response_event.time)
    trials.addData("resp.rt", response_event.time-trial_start)
    trials.addData('resp.keys',response_event.key)
    trials.addData('resp.corr', response_event.key.lower()==corrAns)
else:
    trials.addData("resp.time",-1.0)
    trials.addData("resp.rt", -1.0)
    trials.addData('resp.keys','None')
    trials.addData('resp.corr', False)

I tried creating a new routine at the end of the inner loops (but still within the main trials loop) and added the above code instead of having it in each condition, but still this doesn't work in the mac. Strangely, in Windows 7  the responses are recorded regardless of whether I have the above code in each condition routine or in a separate routine after the condition loops. But the responses are out of sync, i.e. the first recorded response is trial 2 and the last trial is not recorded.  One more thing, these responses are recorded only if I remove the code for Each Frame you posted above and place it within the first iohub code before the conditions loop. As soon as I have that code in each frame of the condition routines (inner loops), the responses are not recorded in Windows either. 

Sorry to take so much of your time, I do hope the solution is an easy one.

thanks again,

Idalmis

Sol Simpson

unread,
Nov 13, 2014, 1:16:35 PM11/13/14
to psychop...@googlegroups.com

I'm not sure I am following exactly what custom code you have in each custom code component and this is definitely going to be the source of the issue; likely the keyboard events are being cleared too soon or frequently so when you actually check for them to get 'response_event', none are available anymore. 

Can you post your builder project so I can see the actual custom code? 

Also, the code from 2013 is likely not what you want anymore anyhow if using psychopy 1.81.x, as the keyboard device had a facelift in that version that is not backwards compatible.


Idalmis

unread,
Nov 13, 2014, 3:38:17 PM11/13/14
to psychop...@googlegroups.com
Thanks for looking into it Sol. Below is a link to the project files:


One more thing, I would like to add a code to check that the two keys ('v' and 'b') are pressed at the same time before the beginning of each trial, could you help with that? 

Thanks again,

Idalmis

Sol Simpson

unread,
Nov 17, 2014, 9:29:10 AM11/17/14
to psychop...@googlegroups.com
Thanks for the projects. Can you confirm the one I should be looking at is the ImitTest_iohub builder project? I ask because I could not even start this project before fixing the following issues:
  • 'StaticHand.jpeg' did not exist, 'StaticHand.png' did, so changed that in the project
  • None of the  .bmp images were in the stimuli subfolder; all were in the main project folder. The project was expecting them in the stimuli folder. Copied them to that folder.
Once these 2 issues where fixed, the project would atleast start without an error.

Can you please clarify:
   1) What do you consider the start and end of each trial in this experiment? Is the start when 'Neutral_Hand' stim is displayed, when the 'trial' component is run, ....?
   2) When within each trial loop do you want to use as the start and end times that keyboard events should be considered as valid, resulting in a 'response_event' value? 

Providing this info in terms of the actual builder component names used in the experiment would be great. I can then look into your original question.

One more thing, I would like to add a code to check that the two keys ('v' and 'b') are pressed at the same time before the beginning of each trial, could you help with that? 

I edited the ImitTest_iohub project to change it to what I think may be what you are after, making the assumption that the fixation stim is where you would want both keys 'v' and 'b' to be pressed at the same time. See attached builder project. Changes made: 

1) Created a 'fixation' routine prior to the 'blue_hand' routine.
2) Moved the fixation text stim from blue_hand to the new fixation. Set it to have a very small duration (0.1 sec)
3) Added a custom code component to the fixation routine that does the logic of waiting for both 'v' and 'b' to be pressed at the same time, then waits for them both to be released prior to continuing to the next routine.

The project crashes after the first blue_hand routine though, because of an error stating 'trials' was not defined in this line of code:

 trials.addData("trial_start_time", trial_start)

Did not try to fix this, as again I wonder if I am using the wrong project anyhow, so will wait to hear back from you before helping with the original question. Perhaps you could send a folder containing only the files needed to help with your question; i.e. a single builder project that does not crash due to image path issues, etc. ;)  

Thank you
ImitTest_iohub_v2.psyexp

Idalmis Santiesteban

unread,
Nov 17, 2014, 11:39:20 AM11/17/14
to psychop...@googlegroups.com
Oh, I'm sorry. The version of the project you looked at was an old one I had actually removed all the irrelevant files from that folder but after sending the link I open Dropbox from a different machine which had the older version and these were uploaded. Really sorry about the confusion. 

The  file I meant you to look at is called 'ImitInhib_v0'.  I have now moved the irrelevant files and only left what is needed to run the experiment.  Here's the link again:


To answer your questions:

1) Each trial starts with the static (neutral) hand and ends with the blue screen. 
2) Within each trial loop the start time is when the first image of the loop (e.g. 'i2con.jpg') is presented. This is the cue for the participant to make a response. The end time is when the participant releases one of the two keys (either v or b), which would result in a 'response_event' value. 

Thanks for your work on the previous file, I will use the code you added to check for the key presses at fixation stage. 

Sorry about the confusion again. 

Idalmis







--
You received this message because you are subscribed to a topic in the Google Groups "psychopy-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/psychopy-users/A4BQY-GIpS8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to psychopy-user...@googlegroups.com.
To post to this group, send email to psychop...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/psychopy-users/745541bc-5b62-4a5a-940a-cb9b7af3add9%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Sol Simpson

unread,
Nov 18, 2014, 2:00:41 PM11/18/14
to psychop...@googlegroups.com
Thanks for the updated experiment.

I ran though the experiment just to get a sense of the flow of each trial. It seems that each trial is very short, maybe around 1-2 seconds total, before the blue screen appears and then the next trial starts right away.

Is your intent to:

1) For each trial, when the + screen is presented, wait until both 'v' and 'b' are pressed before continuing.
2) Since both  both 'v' and 'b' are pressed, then you want to use the first one of these 2 key releases as the response during the short trial period? (so the presses must occur during the + screen, which will therefore only allow for a release of one of the 2 keys during the fast trial duration.
3) If nether 'v' and 'b' have been released by the subject when the trial end blue screen is displayed, do you want the blue screen to stay on until one of the 2 keys is released, or timeout and record a trial with no response?
4) If you want a timeout, then that means when the next trial starts and the + screen is displayed,  both 'v' and 'b' keys may already still be pressed. Do you want the trial to immediately just start then? This would seem odd to me, so I assume you want to wait at the end of each trial until at least one of the two keys has been released?

Can you correct any of the above. I'll then have a clear enough understanding of your paradigm to suggest the code to actual do what you want. ;)

Thanks. 

Idalmis

unread,
Nov 18, 2014, 6:01:04 PM11/18/14
to psychop...@googlegroups.com
Hi Sol,

Thanks for looking at this. Yes, the trials are vey fast. From my experience on running this task in the past (programmed in VB) the RTs range between 400 and 600 ms. 

To answer your questions:

 
1) For each trial, when the + screen is presented, wait until both 'v' and 'b' are pressed before continuing.

Yes, that's correct. 
 
2) Since both  both 'v' and 'b' are pressed, then you want to use the first one of these 2 key releases as the response during the short trial period? (so the presses must occur during the + screen, which will therefore only allow for a release of one of the 2 keys during the fast trial duration.

Yes, that's the idea.
 
3) If nether 'v' and 'b' have been released by the subject when the trial end blue screen is displayed, do you want the blue screen to stay on until one of the 2 keys is released, or timeout and record a trial with no response?

The blue screen stays on until a response has been made.  

 
4) If you want a timeout, then that means when the next trial starts and the + screen is displayed,  both 'v' and 'b' keys may already still be pressed. Do you want the trial to immediately just start then? This would seem odd to me, so I assume you want to wait at the end of each trial until at least one of the two keys has been released?

Yes, as above.  

Thanks again. I really appreciate your help. 

Idalmis

Sol Simpson

unread,
Nov 21, 2014, 1:55:50 PM11/21/14
to psychop...@googlegroups.com
The attached project (archived using 7zip) has the keyboard press - release type functionality we discussed.

Note that both the v and b key must not be pressed before pressing both keys at the same time makes the + stim stage continue. I hope this is what you wanted.

Thanks,

Sol 
imit_inhib taskv2.7z

Idalmis Santiesteban

unread,
Nov 21, 2014, 2:14:33 PM11/21/14
to psychop...@googlegroups.com

Thank you Sol! I really appreciate your help.  Will test it and let you know how I get on.

Idalmis

--
You received this message because you are subscribed to a topic in the Google Groups "psychopy-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/psychopy-users/A4BQY-GIpS8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to psychopy-user...@googlegroups.com.
To post to this group, send email to psychop...@googlegroups.com.

Idalmis Santiesteban

unread,
Nov 25, 2014, 6:03:03 AM11/25/14
to psychop...@googlegroups.com
Sorry to bother you again Sol, but when you run your latest version of the experiment,are the key release events (and RT) for each trial recorded in your data file? They are not recorded when I run it here, which was my original problem. I add the code below to the end routine tab of my cond routines and still the responses are not recorded.

Thanks,

Idalmis 

Idalmis Santiesteban

unread,
Nov 25, 2014, 9:58:39 AM11/25/14
to psychop...@googlegroups.com
Just to follow up from my previous post, the code I intended to copy was the one at the end routine tab that you placed in the blue routine. When I print the  response_event, rather than the key that was released, this is what I get:

[<psychopy.iohub.client.keyboard.KeyboardRelease object at 0x04CF78F0>]

Thanks again,

Idalmis

Sol Simpson

unread,
Nov 25, 2014, 11:09:25 AM11/25/14
to psychop...@googlegroups.com
To get the key that the as pressed from the object you are currently printing, add '.key', for the time, add '.time', for the duration the key was pressed, add '.duration'.

During each trial in your experiment, you are setting values to the current trial of the trial handler multiple times / in multiple routines. I am not sure if this is valid to do or not in Builder.

If you are still running into issues, let me know, but understand I know very little about how builder works and can only really be of help with the custom code stuff. :)

Thanks

Idalmis Santiesteban

unread,
Nov 25, 2014, 1:04:06 PM11/25/14
to psychop...@googlegroups.com

I'm trying to print  response_event.key  &  response_event.time to find out why / at what point the key release responses and RT are not recorded, but after the first trial I get an  error message saying that the object response_event has no attribute 'key' / 'time'.

However,  the response_event object has already been defined as:

response_event = iokeyboard.getReleases (keys = ['v', 'b'])

--
You received this message because you are subscribed to a topic in the Google Groups "psychopy-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/psychopy-users/A4BQY-GIpS8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to psychopy-user...@googlegroups.com.
To post to this group, send email to psychop...@googlegroups.com.

Sol Simpson

unread,
Nov 25, 2014, 2:20:26 PM11/25/14
to psychop...@googlegroups.com
What is the object type when it says those attributes are missing? 'None' ?

I can not check the code I sent you until tomorrow sometime, am travelling right now.

Thanks,

Sol
Message has been deleted

Sol Simpson

unread,
Nov 25, 2014, 7:11:02 PM11/25/14
to psychop...@googlegroups.com
OK, I was able to run the project I sent you and see what you mean. The issue seems to be related to how I setup the builder project to end the blue screen routine, or at least I thought that is what I was doing:

  1. the 'blue' routine that shows the blue screen stim has a stop condition set to $vb_keys_released==True.
  2. In the same routine there is the custom code that
    1. sets vb_keys_released=False in 'Begin Routine',
    2. checks for a release event in 'Each Frame', only setting vb_keys_released=True when a key has been found. The response_event variable is also set here. 
    3. The 'End Routine' then assumes that a response_event must contain an event, but ....
  3. it seems that the 'End Routine' code is being reached before this is the case. I do not know why it is doing this; perhaps I do not understand how builder uses stop conditions or something. 
Anyhow, a solution to work around this is attached. Basically, if response_event is None when the End Routine code runs for the blue screen, it waits to get a key release event. This way you always get a 'v' or 'b' keyboard response before the blue screen routine exits.

I have attached the updated example and a sample cvs output file, showing that a response is now received for each trial.

ImitInhib_v0.psyexp
hh_2014_Nov_25_1848.csv

Idalmis Santiesteban

unread,
Nov 26, 2014, 7:22:32 AM11/26/14
to psychop...@googlegroups.com
This is great! Thank you Sol, it works just the way I wanted.

Best wishes,

Idalmis

--
You received this message because you are subscribed to a topic in the Google Groups "psychopy-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/psychopy-users/A4BQY-GIpS8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to psychopy-user...@googlegroups.com.
To post to this group, send email to psychop...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages