Skip to content

Commit

Permalink
Extract disc, rings, to separate components.circular
Browse files Browse the repository at this point in the history
  • Loading branch information
JorisVincent committed Nov 11, 2022
1 parent d70b13f commit 97aaeef
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 89 deletions.
89 changes: 89 additions & 0 deletions stimuli/components/circular.py
@@ -0,0 +1,89 @@
import numpy as np
from stimuli.utils import degrees_to_pixels, resize_array


def disc_and_rings(
ppd=20,
radii=(3, 6, 9),
vback=0.0,
vdiscs=(1.0, 0.0, 1.0),
ssf=5,
):
"""
Create a central disc with rings
Parameters
----------
ppd : int
pixels per degree (visual angle)
radii : tuple of floats
radii of disc in degree visual angle
vback : float
value of background
vdiscs : tuple of floats
values of discs
ssf : int (optional)
the supersampling-factor used for anti-aliasing. Default is 5.
Returns
-------
A 2d-array with a disc
"""
radii_px = degrees_to_pixels(radii, ppd) * ssf

# create stimulus at 5 times size to allow for supersampling antialiasing
img = np.ones([radii_px.max() * 2, radii_px.max() * 2]) * vback

# compute distance from center of array for every point, cap at 1.0
x = np.linspace(-img.shape[1] / 2.0, img.shape[1] / 2.0, img.shape[1])
y = np.linspace(-img.shape[0] / 2.0, img.shape[0] / 2.0, img.shape[0])
dist = np.sqrt(x[np.newaxis, :] ** 2 + y[:, np.newaxis] ** 2)

radii_px = radii_px[::-1]
vdiscs = vdiscs[::-1]
for radius, value in zip(radii_px, vdiscs):
img[dist < radius] = value

# downsample the stimulus by local averaging along rows and columns
sampler = resize_array(np.eye(img.shape[0] // ssf), (1, ssf))
img = np.dot(sampler, np.dot(img, sampler.T)) / ssf**2
return img


def disc(
ppd=20,
radius=3,
vback=0.0,
vdisc=1.0,
ssf=5,
):
"""
Create a central disc
Parameters
----------
ppd : int
pixels per degree (visual angle)
radius : float
radius of disc in degree visual angle
vback : float
value of background
vdisc : float
value of disc
ssf : int (optional)
the supersampling-factor used for anti-aliasing. Default is 5.
Returns
-------
A 2d-array with a disc
"""
radius = [radius]
vdisc = [vdisc]

if len(radius) > 1:
raise ValueError("Too many radii passed")
if len(vdisc) > 1:
raise ValueError("Too many values for discs passed")

img = disc_and_rings(ppd, radius, vback, vdisc, ssf)
return img
87 changes: 0 additions & 87 deletions stimuli/components/components.py
Expand Up @@ -223,93 +223,6 @@ def square_wave(
return stim


def disc_and_rings(
ppd=20,
radii=(3, 6, 9),
intensity_background=0.0,
intensity_discs=(1.0, 0.0, 1.0),
ssf=5,
):
"""
Create a central disc with rings
Parameters
----------
ppd : int
pixels per degree (visual angle)
radii : tuple of floats
radii of disc in degree visual angle
intensity_background : float
intensity value for background
intensity_discs : tuple of floats
intensity values for discs
ssf : int (optional)
the supersampling-factor used for anti-aliasing. Default is 5.
Returns
-------
A 2d-array with a disc
"""
radii_px = degrees_to_pixels(radii, ppd) * ssf

# create stimulus at 5 times size to allow for supersampling antialiasing
img = np.ones([radii_px.max() * 2, radii_px.max() * 2]) * intensity_background

# compute distance from center of array for every point, cap at 1.0
x = np.linspace(-img.shape[1] / 2.0, img.shape[1] / 2.0, img.shape[1])
y = np.linspace(-img.shape[0] / 2.0, img.shape[0] / 2.0, img.shape[0])
dist = np.sqrt(x[np.newaxis, :] ** 2 + y[:, np.newaxis] ** 2)

radii_px = radii_px[::-1]
intensity_discs = intensity_discs[::-1]
for radius, value in zip(radii_px, intensity_discs):
img[dist < radius] = value

# downsample the stimulus by local averaging along rows and columns
sampler = resize_array(np.eye(img.shape[0] // ssf), (1, ssf))
img = np.dot(sampler, np.dot(img, sampler.T)) / ssf**2
return img


def disc(
ppd=20,
radius=3,
intensity_background=0.0,
intensity_disc=1.0,
ssf=5,
):
"""
Create a central disc
Parameters
----------
ppd : int
pixels per degree (visual angle)
radius : float
radius of disc in degree visual angle
intensity_background : float
intensity value for background
intensity_disc : float
intensity value for disc
ssf : int (optional)
the supersampling-factor used for anti-aliasing. Default is 5.
Returns
-------
A 2d-array with a disc
"""
radius = [radius]
intensity_disc = [intensity_disc]

if len(radius) > 1:
raise ValueError("Too many radii passed")
if len(intensity_disc) > 1:
raise ValueError("Too many values for discs passed")

img = disc_and_rings(ppd, radius, intensity_background, intensity_disc, ssf)
return img


def square_wave_grating(
ppd=10,
n_bars=8,
Expand Down
2 changes: 1 addition & 1 deletion stimuli/illusions/circular.py
@@ -1,6 +1,6 @@
import numpy as np

from stimuli.components import disc_and_rings
from stimuli.components.circular import disc_and_rings
from stimuli.utils import degrees_to_pixels, pad_to_visual_size, resize_array


Expand Down
3 changes: 2 additions & 1 deletion stimuli/illusions/sbc.py
@@ -1,6 +1,7 @@
import numpy as np

from stimuli.components import disc, rectangle
from stimuli.components import rectangle
from stimuli.components.circular import disc
from stimuli.utils import pad_by_visual_size, resolution


Expand Down

0 comments on commit 97aaeef

Please sign in to comment.