Error when setting the stimulus size to 152 pixels

Hello everbody,

right now we try to replicate a yes-no visual contrast detection task.
For this we have all the needed specifications about how the noise and the stimulus (a vertical grating signal) need to look like. Since PsychoPy offers the useful classes GratingStim and RadialStim creating these kinds of signals was not the problem:

X = 256; # width of the gabor patch in pixels
sf = 0.02; # spatial frequency, cycles per pixel

gabortexture = (
    visual.filters.makeGrating(res=X, cycles=X * sf) *
    visual.filters.makeMask(matrixSize=X, shape="circle", range=[0, 1])
)

# a X-by-X array of random numbers in [-1,1]
noisetexture = random([Y,Y])*2.-1.

signal = visual.GratingStim(
    win = window, tex = gabortexture, mask = 'circle', pos=[0 + xoffset,0],
    size = X, contrast = 1.0, opacity = threshold
)

noise = visual.RadialStim(
    win = window, mask='none', tex = noisetexture, pos=[0 + xoffset,0],
    size = X, contrast = 1.0, opacity = 1.0
)

The problem we are facing right now is the correct size of the signals (noise and stimulus) which need to be 152 pixels and not 256 pixels. But when we change it to 152 pixels we get the error “Requiring a square power of two (e.g. 16 x 16, 256 x 256) texture but didn’t receive one”.
Is there a way to create the signals with the correct size?

I hope you can help.
Thanks in advance,
Franca

1 Like

Hi. I am facing a similar kind of issue currently. I am using a custom defined mask and it gives “Requiring a square power of two (e.g. 16 x 16, 256 x 256) texture but didn’t receive one“.If I fix this error then I am not getting the stimulus size that I require. Kindly let me know if you have already found a solution to your problem.
Below is my code:
import numpy as np
gabor_size_deg = surround_outer_diameter
ppd = 58
size_px = int(np.ceil(gabor_size_deg * ppd)) # texture size matches Gabor

def ring_mask_deg(size_px=256, r_deg=1.0, R_deg=3.0, ppd=58):
“”"
Create a ring mask for PsychoPy’s [-1, 1] range with parameters in degrees.

- size_px: full texture size (square)
- r_deg: inner radius in degrees – stimulus invisible inside
- R_deg: outer radius in degrees – stimulus invisible outside
- ppd: pixels per degree
"""
# convert degrees to pixels
r_px = r_deg * ppd
R_px = R_deg * ppd

# coordinate grid centered at 0
x = np.linspace(-size_px/2, size_px/2, size_px)
X, Y = np.meshgrid(x, x)
r = np.sqrt(X**2 + Y**2)

# initialize mask fully transparent
mask = -1 * np.ones_like(r)

# make pixels within [r_px, R_px] visible
mask[(r >= r_px) & (r <= R_px)] = 1

return mask

Example usage

ppd = 58 # pixels per degree (adjust for your screen)
mask_ring = ring_mask_deg(size_px = size_px, r_deg=surround_inner_radius, R_deg=surround_outer_radius, ppd=ppd)
surround_gabor.setMask(mask_ring)

def gaussian_circular_mask_deg(size_px=256, sigma_deg=0.9, radius_deg= 1, ppd=58):
“”"
Create a circular Gaussian mask in PsychoPy’s [-1, 1] range using degrees.

- size_px: full texture size in pixels (square)
- sigma_deg: std dev of Gaussian falloff in degrees
- radius_deg: hard cut-off radius in degrees
- ppd: pixels per degree (depends on screen size and viewing distance)
"""
# convert degrees to pixels
sigma_px = sigma_deg * ppd
radius_px = radius_deg * ppd

# coordinate grid centered at 0
x = np.linspace(-size_px/2, size_px/2, size_px)
X, Y = np.meshgrid(x, x)
r = np.sqrt(X**2 + Y**2)

# Gaussian inside the circle
mask = np.exp(-r**2 / (2 * sigma_px**2))

# everything outside the circle is transparent (-1)
#mask[r > radius_px] = -1

# rescale to PsychoPy's expected [-1, 1] range
mask = 2*mask - 1
return mask

Example usage

ppd = 58 # pixels per degree (adjust based on your setup)
mask1 = gaussian_circular_mask_deg(size_px=size_px, sigma_deg=center_sigma * 1.5, radius_deg=center_radius, ppd=ppd)

center_gabor.setMask(mask1)

So original OP had the wrong code I think?

noisetexture = random([Y,Y])*2.-1.

And Y is not defined in their code, so that needed to be X, not Y.

For yourself @mpandiri, what is the fix you are applying that removes that error, but changes the stimuli size to be different than what you want? Is it the first function or the seconds function?

AFAIK when it comes to gaussian filters, values being a “square power of 2” is a fundamental property of the gaussian function.

Issac