Confusion over maskParams GratingStim

659 views
Skip to first unread message

Andy S

unread,
Jan 24, 2015, 2:07:07 PM1/24/15
to psychop...@googlegroups.com
Hi,

I have a very minimal code example here for grating stim. This code sets the units to degrees and then displays a 10 degree-wide gabor patch for 3 seconds. Apolgies to anybody that runs the code but must adjust these settings for ease of visibility.

I need to control the standard deviation of the gaussian mask, but I'm confused about how this standard deviation behaves. The below code has a stimulus size of 10 degrees, and the mask has an sd of 1. Therefore, my expectation is that the central 2 degrees of the 10 degree patch would have relatively high, though progressively lower, contrast, and the contrast of the outer degrees would then rapidly decrease.The stimulus would then have 0 contrast well before the borders of the patch. However, what I actually see when I run this code appears to be a full square patch convolved with a slightly-opaque mask over it, something like a Gaussian with a *very* wide sd.

When I play with the sd parameter, it also behaves in a way that I do not expect. Increasing the sd makes the gabor appear smaller - almost as if the gaussian mask is actually getting narrower (with a smaller sd). Decreasing the sd has the opposite effect.

I'm confused by this behavior. What is the sd parameter doing here, and if I want a gabor patch with 2 degrees of good visibility (and a Gaussian drop-off afterwards) as described above, how would I go about doing this?
__________________________________________________________________________
from __future__ import division
from psychopy import visual
from psychopy import core, monitors


Mon = monitors.Monitor('NewExperiment', width = 31, distance = 100)
Mon.setSizePix((1024, 768))

patchColor = 255
groundColor = 255/2

mywin = visual.Window(size = [1024, 768], fullscr = False, color = groundColor, colorSpace = 'rgb255', units = 'deg',
                                        monitor = Mon, allowStencil = True)


gabor = visual.GratingStim(mywin, tex='sin', mask= 'gauss', units='deg',
                            pos=(0, 0), size=10, sf=2, ori=90,
                            phase=(0.0, 0.0), color=patchColor,
                            colorSpace='rgb255', contrast=1, maskParams = {'sd': 1})


gabor.draw(mywin)
mywin.flip()
core.wait(3)
core.quit()

__________________________________________________

Axel Kohler

unread,
Jan 25, 2015, 7:54:49 AM1/25/15
to psychop...@googlegroups.com

Hi Andy,

In the builder help section for the grating component (http://www.psychopy.org/builder/components/patch.html), you can find the following statement for the "size" parameter:

The size of the stimulus in the given units of the stimulus/window. If the mask is a Gaussian then the size refers to width at 3 standard deviations on either side of the mean (i.e. sd=size/6)

 From this, my best guess is that the maskParams actually corresponds to the value "6" in the equation. This would explain why the mask shrinks when you increase the "maskParams" value. And, in fact, when you set the value to "6" in your example, the grating is about the same size as when you create it in the Builder (where you cannot change "maskParams" directly, but where the default setting seems to be "6", see above). I hope this makes sense.

Maybe someone from the core team could confirm this behavior. In this case, a change of documentation might be considered. With an OK, I would volunteer to contribute those changes.

Best,

Axel

Jonathan Peirce

unread,
Jan 25, 2015, 8:24:59 AM1/25/15
to psychop...@googlegroups.com
It is strange that altering that sd value goes the 'wrong way'. I'll look into that.

But you shouldn't need to change the sd of the mask; it's best to leave that at its default, which allows the mask to fall to zero at the edge of the stimulus. To alter the size of your gaussian envelope just change the size parameter of the stimulus. The two operations are equivalent except that changing the size of the stimulus will better optimise resolution.

Possibly you're trying to increase the area of high contrast and use a smaller area where the contrast is dropping off. That isn't achieved with a Gaussian window though (you might be thinking of gaussian blurring rather than gaussian envelope). To control the width of the drop-off relative tot he width of the high-contrast region you should switch to using a raisedCos mask instead and set the fringeWidth
http://www.psychopy.org/api/visual/gratingstim.html#psychopy.visual.GratingStim.mask

cheers
Jon
--
You received this message because you are subscribed to the Google Groups "psychopy-users" group.
To unsubscribe from this group and stop receiving emails from it, 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/a133d71d-1a47-410a-b40d-54f8e58d6325%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



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.

Andy S

unread,
Jan 25, 2015, 11:07:16 AM1/25/15
to psychop...@googlegroups.com
Thank you both for responding to me.

I had no idea that the builder doc talks about the size parameter. I've never looked at that side of psychopy. Thanks Axel for pointing it out.

So, by changing the "size" parameter of grating stim in coder, I am functionally changing the sigma of the gaussian mask, and the size is defined as 6 sigmas.

The reason behind my question was that I wasn't sure what the size parameter was doing  (I do think explicitly explaining this in the coder doc would be good). However, I did see that one published work defined the "size" of their gabor as 2 sigmas, and I figured that even if I didn't put the correct value in the "size" parameter, it didn't matter as long as I put the sigma that corresponded to whatever size from the previous paper I was trying to match.

Jon, thanks for pointing out the raisedCos width. I do like it and it behaves as I would have expected. Thanks for looking into the "wrong way" behavior of the sd parameter.

Andy

Peter Claessens

unread,
Jul 31, 2017, 4:23:37 PM7/31/17
to psychopy-users
Dear Jon, and whoever has a similar issue,

I stumbled into this when trying to find out how broad my Gaussian blob really is - I think the 'wrong way' behavior of sd is still present in version 1.85.2, right? It seems that Axel Kohler was probably close to the reason, but in that case, using 'sd' as a name for the parameter should be documented with some explanation of this specific caveat. I found these lines in basevisual.py:

        elif tex == "gauss":
            rad = makeRadialMatrix(res)
            # 3sd.s by the edge of the stimulus
            invVar = (1.0 / allMaskParams['sd']) ** 2.0
            intensity = numpy.exp(-rad**2.0 / (2.0 * invVar)) * 2 - 1

those are lines 721-725. I did not look much into makeRadialMatrix(res) - I trust it scales everything just right considering the 'size' parameter. The invVar, inverse variance, is correctly defined. But look at how it is used in the line 'intensity = ': in the denominator of the argument to the exp function, while, if it is the inverse variance, it should be in the nominator. This must be the reason for the unexpected behavior of sd. Maybe you did look into it and decided not to change the code or the name of the parameter in order to avoid breaking written codes. But maybe it would be useful to specify more clearly that the 'sd' parameter relates to 'how many standard deviations fit in half the size', therefore, really is the inverse of the standard deviation. Maybe it should be called 'invSd' or even 'sds' would already be clearer. But I understand this change in code would break compatibility. A reasonable alternative would be to have 'sd' and a better alternative coexist for a while.  But I think the documentation could use a fix.

Kind regards,

Peter.
Reply all
Reply to author
Forward
0 new messages