Millisecond Forums

Mouse coordinates and tracking

https://forums.millisecond.com/Topic18169.aspx

By Loukia - 1/24/2016

Hi, 

I have been trying to find a way around mouse tracking and while I was playing around with a script I realized that I get a lot of wrong coordinates for 'responsey'. I tried to figure out what -1 means and I have read other posts that have described problems with using two monitors or having the wrong canvas position, which needs to be set to 50%, 50%. I have controlled for both of these problems but the problem persists.

While I was thinking of possible reasons, I tried stopping the mouse at certain time points to see if the coordinates are accurate (i.e., don't change).The result was that I got a lot of -1 values in my data output. However, I am not 100% sure that this was caused by stopping. Do you think that makes sense? I mean, even if it stops we should still get the coordinates. Unless responsey differs from mouse.y in some way so that it needs some kind of response to be registered (i.e., mousemove). To elaborate more, my 'theory' is that if for the whole trial (=10 stimulus frames- 166.7 ms) the mouse did not move responsey would be -1 instead of the exact pixels.

In the script I am working on each trial event is equal to 10 stimulus frames (arbitrary number used for testing purposes). If a target is not reached the next trial event is loaded through the branch command. For each trial I record a value for the y coordinate (responsey) so that I can plot the trajectory of the mouse for let's say 1800 milliseconds (~108 frames). Of course if I tried to do that for every frame I would end up writing 108 trial events... 

That leads me to the second question. I know it has previously been stated that continuous mouse tracking is not possible with Inquisit yet, but if this is a potential solution to getting at least some coordinates for a mouse trajectory do you think there is a 'neater' way to do it so that I don't end up with a massive script!? 

P.S. The script is not very good at the moment, but if it would help to have a look at that I could attach it.

Thank you for any input,

Loukia

By Dave - 1/24/2016

> Unless responsey differs from mouse.y in some way so that it needs some kind of response to be registered (i.e., mousemove).

That's exactly right, they are different. If no response has ever occured in the given trial, mouse.responsey will return -1. mouse.y, on the other hand, should return the mouse's y position regardless of whether a response occured.

A way to make sense of that is the following:

responsey is a property of the <trial> element

trial.trialname.responsey

so it makes sense for it to reflect what did or did not happen with respect to that <trial> element.

mouse.y, however, is a property of the mouse-device, i.e., it isn't tied to what did or did not happen in a particular <trial> element, but rather reflects the state of the device itself.

Quick example:

<values>
/ mousey = 0
/ responsey = 0
</values>

<block myblock>
/ trials = [1-2 = mousetrial]
</block>

<trial mousetrial>
/ ontrialbegin = [values.mousey = 0; values.responsey = 0; ]
/ ontrialend = [values.mousey = mouse.y; values.responsey = trial.mousetrial.responsey; ]
/ stimulusframes = [1=mousetext]
/ inputdevice = mouse
/ validresponse = (mousemove)
/ timeout = 5000
/ branch = [trial.showcoordinates]
</trial>

<trial showcoordinates>
/ stimulusframes = [1=coordinates]
/ validresponse = (57)
</trial>

<text mousetext>
/ items = ("Don't move the mouse.", "Move the mouse.")
/ select = sequence
</text>

<text coordinates>
/ items = ("Response: <%trial.mousetrial.response%> | Response Y: <%values.responsey%> | Mouse Y: <%values.mousey%>")
</text>

Hope this helps.
By Loukia - 1/24/2016

Thank you Dave. This means I can use mouse.y for every trial event and not having to deal with missing values. So the only problem for mouse tracking then is just the fact that we cannot get mouse.x or mouse.y during a trial event? The /ontrialend will register the mouse coordinates after the trial has ended. I was looking for a way to do that with loading the expressions through /ontrialbegin but it didn't work. For example [if (mouse.y>=0.3 * display.height) values.mouse3y = mouse.y].

Would it be feasible you think to produce a script to track mouse coordinates for every 3 frames- it's an exhaustive list of trial events- would that cause any problems?

Thanks again :)

Loukia
By Loukia - 1/24/2016

Hi Dave, 

I run your example and I got some weird looking data. When there absolutely no stopping in a trial (mouse sits still) the responsey is not -1, but is equal to the coordinates of the previous trial. Now the problem appears for mouse.y that should be the same since the mouse did not move at all, but actually turns up different. I have attached the data (see rows 22, 34, 38, 42..). Post Reply

Do you know what could be causing this? Thanks a lot in advance.

By Dave - 1/24/2016

Within Inquisit's framework, it would be preferable to track mouse coordinates whenever an actual mouse event occurs (e.g. movement), not at specific intervals (e.g. every X frames). There are several ways to do this.

You can find one example here: https://www.millisecond.com/forums/FindPost4421.aspx (scripts are in the attached ZIP archive).

Another way would be to use /isvalidresponse to append event times and coordinates to a global variable. Building on the example in https://www.millisecond.com/forums/FindPost13217.aspx , I'm thinking of something along the following lines:

<expressions>
/ ismouseovera = (mouse.x > 0.05*display.width && mouse.x <  0.35*display.width && mouse.y > 0.35*display.height && mouse.y < 0.65*display.height)
/ ismouseoverb = (mouse.x > 0.65*display.width && mouse.x <  0.95*display.width && mouse.y > 0.35*display.height && mouse.y < 0.65*display.height)
</expressions>

<values>
/ times_and_coordinates = ""
</values>

<block myblock>
/ trials = [1-4=sequence(centermousetrial,mouseovertrial)]
</block>

<trial centermousetrial>
/ ontrialbegin = [values.times_and_coordinates = ""; ]
/ stimulusframes = [1=clickhere]
/ inputdevice = mouse
/ validresponse = (clickhere)
</trial>

<text clickhere>
/ items = ("Click here!")
/ position = (50%, 90%)
</text>

<trial mouseovertrial>
/ posttrialpause = 500
/ stimulusframes = [1=a,b]
/ inputdevice = mouse
/ isvalidresponse = [if (trial.mouseovertrial.response == "mousemove") {
    values.times_and_coordinates = concat(concat(concat(concat(concat(concat(values.times_and_coordinates, trial.mouseovertrial.latency), "ms:"), mouse.x), "|"), mouse.y), "; ");
    false; } ;
    expressions.ismouseovera || expressions.ismouseoverb]
</trial>

<text a>
/ items = ("A1", "A2", "A3", "A4")
/ txbgcolor = (red)
/ size = (30%,30%)
/ position = (20%,50%)
</text>

<text b>
/ items = ("B1", "B2", "B3", "B4")
/ txbgcolor = (green)
/ size = (30%,30%)
/ position = (80%,50%)
</text>

<data>
/ columns = [date time subject trialnum trialcode response latency expressions.ismouseovera expressions.ismouseoverb values.times_and_coordinates]
/ separatefiles = true
</data>



By Loukia - 1/24/2016

Yes object-based tracking (invisible objects on the screen) would help and especially if I form some kind of standard coordinate space grid.

I will give it a go and hopefully I won't have any more questions for you. The main reason behind such tracking is that I will need to calculate velocity and acceleration of the mouse, but I guess instead of having how much distance is between 'stimulus frame a' and 'stimulus frame y' we would have how much time has elapsed since 'distance x'  and 'distance b'. Thanks again Dave, you 've been really helpful!

If anyone else is interested in analysis for proximity towards a response (either A or B) and mouse velocity changes I would be happy to share my script when it is finished (and works of course).