Mouse.clickReset() does not zero the mouseTimes reported by getPressed(True)

305 views
Skip to first unread message

Robert Muil

unread,
Jan 5, 2012, 3:36:09 PM1/5/12
to psychop...@googlegroups.com
Dear all,

I suspect I'm doing something wrong here because all I'm trying to do is wait for a user to click a button.

I want to use the times instead of the buttons array because using the buttons array requires polling quickly enough to ensure no click is missed, whereas (at least in principle) times can be checked for non-zero values and should stay like that until reset.

This works for the first click, when the times array is all 0. Unfortunately, it fails to work when called again, because the times array returned by getPressed(True) is never reset to 0 even after clickReset().

The code I'm using is:

mouse.clickReset()
event.clearEvents()
buttonPressed = False
while not buttonPressed:
    (buttons, times) = mouse.getPressed(True);
    buttonPressed = any([el != 0 for el in times]);
    core.wait(0.05)

Am I misunderstanding something about how this works, or is there a bug in the clickReset() implementation?

Thanks kindly,
Rob.

Robert Muil

unread,
Jan 5, 2012, 3:59:40 PM1/5/12
to psychop...@googlegroups.com
In case it's of value to anyone in the meantime, I'm working around this by saving the times before the loop and comparing the times (instead of relying on 0):

mouse.clickReset()
event.clearEvents()
buttonPressed = False
(_buttons, times) = mouse.getPressed(True)
preTimes = times[:] #copy otherwise we have a reference which is updated by Mouse class
while not buttonPressed:
    (_buttons, times) = mouse.getPressed(True)
    if times != preTimes:
        buttonPressed = True
    core.wait(0.05)

Gary Lupyan

unread,
Jan 6, 2012, 3:16:23 PM1/6/12
to psychop...@googlegroups.com
Hi Robert, if all you're trying to do is detect a mouse-click, why not
just do this:


response = [0]*len(event.mouseButtons) #initializes it to a list of 0s
with the length equal to the number of active buttons.
mouse.clickReset()
while not any(response):
(response,rt) = mouse.getPressed(getTime=True)

Once the loop exits you'll have your response and RT.

You definitely do not want to put a core.wait(.05) inside the loop
because then you're only checking for responses every 50 ms (and thus
your RTs will all be rounded up <= 50 ms)

-----------------------------------------------------
Gary Lupyan - lup...@wisc.edu
Assistant Professor of Psychology
University of Wisconsin, Madison
http://sapir.psych.wisc.edu
-----------------------------------------------------

> --
> You received this message because you are subscribed to the Google Groups
> "psychopy-users" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/psychopy-users/-/-PLycKZMwlwJ.
>
> To post to this group, send email to psychop...@googlegroups.com.
> To unsubscribe from this group, send email to
> psychopy-user...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/psychopy-users?hl=en.

Michael Chow

unread,
Jan 6, 2012, 6:36:00 PM1/6/12
to psychopy-users
Hey Robert,
I think your solution works well if you want to respond to mouse
buttons pressed only after the loop initiates. Gary's definitely is
simpler if you're just trying to detect whether a button is being
pressed. This script is similar to the second you listed and might be
helpful if you want to get the cursor location (and do something with
it) after each mouse click, repeatedly. It only looks for left-
clicking.

done = False
lastTime = myMouse.getPressed(getTime=True)[1]
myMouse.clickReset()
while not done:
click, time = myMouse.getPressed(getTime=True)
if click[0] and time[0] != lastTime:
x,y = myMouse.getPos()
# Do stuff with it..
# .... set done after exit criteria (e.g. user clicks submit)
lastTime = time[0]
myMouse.clickReset()


Hope this helps,
Michael

On Jan 6, 3:16 pm, Gary Lupyan <glup...@gmail.com> wrote:
> Hi Robert, if all you're trying to do is detect a mouse-click, why not
> just do this:
>
> response = [0]*len(event.mouseButtons) #initializes it to a list of 0s
> with the length equal to the number of active buttons.
> mouse.clickReset()
> while not any(response):
>     (response,rt) = mouse.getPressed(getTime=True)
>
> Once the loop exits you'll have your response and RT.
>
> You definitely do not want to put a core.wait(.05) inside the loop
> because then you're only checking for responses every 50 ms (and thus
> your RTs will all be rounded up <= 50 ms)
>
> -----------------------------------------------------
> Gary Lupyan - lup...@wisc.edu
> Assistant Professor of Psychology
> University of Wisconsin, Madisonhttp://sapir.psych.wisc.edu

Robert Muil

unread,
Jan 9, 2012, 4:35:33 AM1/9/12
to psychop...@googlegroups.com
Hi Gary,

Thank you for your reply.

Your solution is using busy-waiting which I like to avoid as much as possible, firstly because it unnecessarily consumes 100% of at least 1 CPU core, but also because nothing else can be done while watching for the click. In my case, for example, I also want to poll for key presses. If the mouse click is fast and comes while I am looking for or processing key presses, I will miss the mouse click.

Also, the RTs returned by the getPressed() function should not be affected at all by the loop period. As far as I understand it, each button has its own free-running clock that is latched whenever a button is clicked, independent of calling of getPressed(). getPressed() simply returns the last latch of the clocks. @all: please correct me here if I err.

Rob.

Robert Muil

unread,
Jan 9, 2012, 4:41:25 AM1/9/12
to psychop...@googlegroups.com
Hi Michael,

Thank you also. As far as I can see, though, your solution is exactly the same as mine regarding button-click detection using a comparison of the times[] returned by getPressed(). Also, I think you initialise lastTime incorrectly to the full array and then compare it to only a single value on the first iteration of the loop. Should line 2 not read:
lastTime = myMouse.getPressed(getTime=True)[1][0] ?

Rob.

Gary Lupyan

unread,
Jan 9, 2012, 10:57:22 AM1/9/12
to psychop...@googlegroups.com
You're right about the busy-waiting: if you don't need something to
happen as soon as a mouse is pressed, there's no need for it.

I've just played around with clickReset / getTimes and yeah, it
doesn't seem to work as advertised in the current docs, but I'm
running an older version of Psychopy (1.70). What's happening for me
is that I need to keep checking getPressed() to get accurate times.

Are you running ver 1.73?


-----------------------------------------------------
Gary Lupyan - lup...@wisc.edu
Assistant Professor of Psychology
University of Wisconsin, Madison
http://sapir.psych.wisc.edu
-----------------------------------------------------

> --
> You received this message because you are subscribed to the Google Groups
> "psychopy-users" group.
> To view this discussion on the web visit

> https://groups.google.com/d/msg/psychopy-users/-/leyK2euduUQJ.

Gary Lupyan

unread,
Jan 9, 2012, 11:21:44 AM1/9/12
to psychop...@googlegroups.com
I am guessing that this is the very problem addressed in ver 1.72:
"FIXED: buglet with flushing mouse events (thanks Sebastiaan Mathot)"

Jon, how come 1.72 is still not in the official release?

-----------------------------------------------------
Gary Lupyan - lup...@wisc.edu
Assistant Professor of Psychology
University of Wisconsin, Madison
http://sapir.psych.wisc.edu
-----------------------------------------------------

Robert Muil

unread,
Jan 9, 2012, 11:34:09 AM1/9/12
to psychop...@googlegroups.com
Ah, this could indeed be.

I am running version 1.71.01.

Rob.

Jonathan Peirce

unread,
Jan 9, 2012, 12:40:57 PM1/9/12
to psychop...@googlegroups.com

On 09/01/2012 16:21, Gary Lupyan wrote:
> I am guessing that this is the very problem addressed in ver 1.72:
> "FIXED: buglet with flushing mouse events (thanks Sebastiaan Mathot)"
>
> Jon, how come 1.72 is still not in the official release?

Because while testing I added new features and ended up planning just to
go to v1.73 ;-)

I've just uploaded some test files for that, which will be a full binary
version including the beginnings of a new lib for support of further
hardware from CRS (currently the ColorCAL mkII). And a
psychopy.hardware.joystick submodule

I've just uploaded 1.73.00 for windows, mac version on its way. Have a
go and see if that fixes the problem. I think it's all working fine, but
be wary

Jon

--
Jonathan Peirce
Nottingham Visual Neuroscience

http://www.peirce.org.uk


This message and any attachment are intended solely for the addressee and may contain confidential information. If you have received this message in error, please send it back to me, and immediately delete it. Please do not use, copy or disclose the information contained in this message or in any attachment. Any views or opinions expressed by the author of this email do not necessarily reflect the views of the University of Nottingham.

This message has been checked for viruses but the contents of an attachment
may still contain software viruses which could damage your computer system:
you are advised to perform your own checks. Email communications with the
University of Nottingham may be monitored as permitted by UK legislation.

gilles

unread,
Jan 17, 2012, 9:33:35 AM1/17/12
to psychopy-users
I take this thread to ask a pretty basic question for which I don't
like to create its own thread:

What is the time that is saved in time in:

buttons, time = mouse.getPressed(getTime=True) ?

I don't understand relative to *what* this time is measured and in
which unit.

Sorry for hijacking the thread, and thanks in advance if someone can
tell the answer.

Gilles


On Jan 9, 6:40 pm, Jonathan Peirce <jonathan.pei...@nottingham.ac.uk>
wrote:

Jonathan Peirce

unread,
Feb 2, 2012, 9:03:24 AM2/2/12
to psychop...@googlegroups.com


On 17/01/2012 14:33, gilles wrote:
I take this thread to ask a pretty basic question for which I don't
like to create its own thread:

What is the time that is saved in time in:

buttons, time = mouse.getPressed(getTime=True) ?

I don't understand relative to *what* this time is measured and in
which unit.
Relative to the last clickReset(), as described in the reference documentation
    http://www.psychopy.org/api/event.html#psychopy.event.Mouse.getPressed
I can't remember if the clock is also implicitly reset by calling getPressed().

All times in psychopy use units of seconds. I know it's common in stimulus presentation applications to use ms, but I like seconds because it makes for easier switching to frequencies (Hz) when required.

Mario Reutter

unread,
Jan 21, 2015, 7:14:10 AM1/21/15
to psychop...@googlegroups.com
Hello,

I have a minor issue with the result of mouse.getPressed(getTime=True):
The result is a tuple of two lists. The first list codes whether a respective mouse button is being pressed at function call (accordingly to mouse.getPressed(getTime=False); PsychoPy v1.81.00) and the second list are the respective timestamps of the last click since the last call to mouse.clickReset. Hence, it is possible to get a result like ([0, 0, 0], [1.4363833676216018, 0.0, 0.0]) if the left mouse button was clicked but is released before function call (which I think should be the most common case). I think, it's a little bit counter-intuitive to have a time indication without a reported button press. Therefore, it might be advantageous to return a button press element as 1 if it's respective time is unequal 0.0.
If I read the documentation right, it is actually supposed to behave as I just described: "If getTime=True (False by default) then getPressed will return all buttons that have been pressed since the last call to mouse.clickReset as well as their time stamps". In PsychoPy v1.81.00, however, it doesn't.

A second concern is that only the time of the last mouse button press is considered. If subjects for some reason make a double click (or left, right, left) before getPressed(True) is called, the latest click time will be returned (reporting the left click to occur later than the right click in the second example). I think it would be better to either return the first press or a list of all click times.

[I know, the mouse is not the input device of choice when it comes to measuring reaction times but for an experiment where the mouse is used frequently, it might be advantageous to avoid homing (i.e. switching from mouse to keyboard and vice versa). In my case, I present auditive stimuli lateralized to one ear and let the subject indicate the sound's direction as a control. Afterwards, the stimulus is rated on several dimensions using the mouse only. I therefore concluded it would be best to let them indicate the direction of the stimulus with the mouse as well.]

Greetings
Mario
Reply all
Reply to author
Forward
0 new messages