import itertools
import numpy as np
from stimupy.components import combine_masks, draw_regions
from stimupy.components.shapes import rectangle
from stimupy.stimuli import mask_targets
from stimupy.stimuli.gratings import squarewave
from stimupy.stimuli.pinwheels import pinwheel as angular
from stimupy.stimuli.waves import square_radial as radial
from stimupy.stimuli.wedding_cakes import wedding_cake
__all__ = [
"generalized",
"white",
"white_two_rows",
"anderson",
"howe",
"yazdanbakhsh",
"angular",
"radial",
"wedding_cake",
]
[docs]def generalized(
visual_size=None,
ppd=None,
shape=None,
frequency=None,
n_bars=None,
bar_width=None,
period="ignore",
rotation=0.0,
intensity_bars=(0.0, 1.0),
target_indices=(),
intensity_target=0.5,
target_center_offsets=0,
target_heights=None,
origin="corner",
round_phase_width=True,
):
"""General function to create White's stimulus
Parameters
----------
visual_size : Sequence[Number, Number], Number, or None (default)
visual size [height, width] of image, in degrees
ppd : Sequence[Number, Number], Number, or None (default)
pixels per degree [vertical, horizontal]
shape : Sequence[Number, Number], Number, or None (default)
shape [height, width] of image, in pixels
frequency : Number, or None (default)
spatial frequency of grating, in cycles per degree visual angle
n_bars : int, or None (default)
number of bars in the grating
bar_width : Number, or None (default)
width of a single bar, in degrees visual angle
period : "even", "odd", "either" or "ignore" (default)
ensure whether the grating has "even" number of phases, "odd"
number of phases, either or whether not to round the number of
phases ("ignore")
rotation : float, optional
rotation (in degrees), counterclockwise, by default 0.0 (horizontal)
intensity_bars : Sequence[float, ...]
intensity value for each bar, by default (1.0, 0.0).
Can specify as many intensities as n_bars;
If fewer intensities are passed than n_bars, cycles through intensities
target_indices : int, or Sequence[int, ...]
indices segments where targets will be placed
intensity_target : float, or Sequence[float, ...], optional
intensity value for each target, by default 0.5.
Can specify as many intensities as number of target_indices;
If fewer intensities are passed than target_indices, cycles through intensities
target_center_offsets : float, or Sequence[float, ...]
center offset of targets in degrees visual angle (default: 0)
target_heights : float, or Sequence[float, ...]
height of targets in degrees visual angle
origin : "corner", "mean" or "center"
if "corner": set origin to upper left corner (default)
if "mean": set origin to hypothetical image center
if "center": set origin to real center (closest existing value to mean)
round_phase_width : Bool
if True (default), round phase width of grating
Returns
-------
dict[str, Any]
dict with the stimulus (key: "img"),
mask with integer index for each target (key: "mask"),
and additional keys containing stimulus parameters
References
----------
White, M. (1979).
A new effect of pattern on perceived lightness.
Perception, 8(4), 413-416.
https://doi.org/10.1068/p080413
"""
# Spatial square-wave grating
stim = squarewave(
visual_size=visual_size,
ppd=ppd,
shape=shape,
frequency=frequency,
n_bars=n_bars,
bar_width=bar_width,
rotation=rotation,
phase_shift=0,
period=period,
intensity_bars=intensity_bars,
origin=origin,
round_phase_width=round_phase_width,
)
# Mask target bars
target_bar_mask = mask_targets(
element_mask=stim["grating_mask"], target_indices=target_indices
)
if isinstance(target_indices, (int, float)):
target_indices = (target_indices,)
stim["target_indices"] = target_indices
# Mask rectangular regions
if isinstance(target_heights, (int, float)):
target_heights = (target_heights,)
if isinstance(target_center_offsets, (int, float)):
target_center_offsets = (target_center_offsets,)
if len(target_indices) != 0 and target_heights is None:
raise ValueError("generalized() missing argument 'target_heights' which is not 'None'")
if len(target_indices) == 0 and target_heights is None:
target_heights = (0,)
target_heights = tuple(itertools.islice(itertools.cycle(target_heights), len(target_indices)))
target_center_offsets = tuple(
itertools.islice(itertools.cycle(target_center_offsets), len(target_indices))
)
stim_center = stim["visual_size"].height / 2
target_rect_masks = []
for target_idx, (height, offset) in enumerate(zip(target_heights, target_center_offsets)):
# Draw a stripe of target_height x stim_width, at center + offset
rect = rectangle(
visual_size=stim["visual_size"],
ppd=stim["ppd"],
shape=stim["shape"],
rectangle_size=(height, stim["visual_size"].width),
rectangle_position=(stim_center + offset - (height / 2), 0),
intensity_rectangle=target_idx,
)
target_rect_masks.append(rect["rectangle_mask"])
stim["target_heights"] = target_heights
stim["target_center_offsets"] = target_center_offsets
# Combine rect & bar masks
target_masks = []
for target_idx, rect_mask in enumerate(target_rect_masks):
# Find where strip intersects with the target bar
target_mask = (target_bar_mask == target_idx + 1) & rect_mask
target_masks.append(target_mask)
# Combine masks
if len(target_masks) > 0:
target_mask = combine_masks(*target_masks)
else:
target_mask = np.zeros_like(stim["img"])
stim["target_mask"] = target_mask.astype(int)
# Draw targets
stim["img"] = np.where(
target_mask,
draw_regions(mask=target_mask, intensities=intensity_target, intensity_background=0.0),
stim["img"],
)
stim["intensity_target"] = intensity_target
return stim
[docs]def white(
visual_size=None,
ppd=None,
shape=None,
frequency=None,
n_bars=None,
bar_width=None,
period="ignore",
rotation=0.0,
intensity_bars=(0.0, 1.0),
target_indices=(),
intensity_target=0.5,
target_heights=None,
origin="corner",
round_phase_width=True,
):
"""White's stimulus where all targets are vertically aligned at half the stimulus height
Parameters
----------
visual_size : Sequence[Number, Number], Number, or None (default)
visual size [height, width] of image, in degrees
ppd : Sequence[Number, Number], Number, or None (default)
pixels per degree [vertical, horizontal]
shape : Sequence[Number, Number], Number, or None (default)
shape [height, width] of image, in pixels
frequency : Number, or None (default)
spatial frequency of grating, in cycles per degree visual angle
n_bars : int, or None (default)
number of bars in the grating
bar_width : Number, or None (default)
width of a single bar, in degrees visual angle
period : "even", "odd", "either" or "ignore" (default)
ensure whether the grating has "even" number of phases, "odd"
number of phases, either or whether not to round the number of
phases ("ignore")
rotation : float, optional
rotation (in degrees), counterclockwise, by default 0.0 (horizontal)
phase_shift : float
phase shift of grating in degrees
intensity_bars : Sequence[float, ...]
intensity value for each bar, by default (1.0, 0.0).
Can specify as many intensities as n_bars;
If fewer intensities are passed than n_bars, cycles through intensities
target_indices : int, or Sequence[int, ...]
indices segments where targets will be placed
intensity_target : float, or Sequence[float, ...], optional
intensity value for each target, by default 0.5.
Can specify as many intensities as number of target_indices;
If fewer intensities are passed than target_indices, cycles through intensities
target_heights : float, or Sequence[float, ...]
height of targets in degrees visual angle
origin : "corner", "mean" or "center"
if "corner": set origin to upper left corner (default)
if "mean": set origin to hypothetical image center
if "center": set origin to real center (closest existing value to mean)
round_phase_width : Bool
if True (default), round phase width of grating
Returns
-------
dict[str, Any]
dict with the stimulus (key: "img"),
mask with integer index for each target (key: "mask"),
and additional keys containing stimulus parameters
References
----------
White, M. (1979).
A new effect of pattern on perceived lightness.
Perception, 8(4), 413-416.
https://doi.org/10.1068/p080413
"""
stim = generalized(
visual_size=visual_size,
ppd=ppd,
shape=shape,
frequency=frequency,
n_bars=n_bars,
bar_width=bar_width,
period=period,
rotation=rotation,
intensity_bars=intensity_bars,
target_indices=target_indices,
intensity_target=intensity_target,
target_center_offsets=0,
target_heights=target_heights,
origin=origin,
round_phase_width=round_phase_width,
)
return stim
[docs]def white_two_rows(
visual_size=None,
ppd=None,
shape=None,
frequency=None,
n_bars=None,
bar_width=None,
period="ignore",
rotation=0.0,
intensity_bars=(0.0, 1.0),
intensity_target=0.5,
target_indices_top=(),
target_indices_bottom=(),
target_center_offset=None,
target_heights=None,
origin="corner",
round_phase_width=True,
):
"""White's stimulus where targets are placed in two rows (top, bottom) that have the same
distance from the center.
Parameters
----------
visual_size : Sequence[Number, Number], Number, or None (default)
visual size [height, width] of image, in degrees
ppd : Sequence[Number, Number], Number, or None (default)
pixels per degree [vertical, horizontal]
shape : Sequence[Number, Number], Number, or None (default)
shape [height, width] of image, in pixels
frequency : Number, or None (default)
spatial frequency of grating, in cycles per degree visual angle
n_bars : int, or None (default)
number of bars in the grating
bar_width : Number, or None (default)
width of a single bar, in degrees visual angle
period : "even", "odd", "either" or "ignore" (default)
ensure whether the grating has "even" number of phases, "odd"
number of phases, either or whether not to round the number of
phases ("ignore")
rotation : float, optional
rotation (in degrees), counterclockwise, by default 0.0 (horizontal)
intensity_bars : Sequence[float, ...]
intensity value for each bar, by default (1.0, 0.0).
Can specify as many intensities as n_bars;
If fewer intensities are passed than n_bars, cycles through intensities
intensity_target : float
intensity value of target
target_indices_top : int or tuple of ints
bar indices where top target(s) will be placed. As many targets as ints.
target_indices_bottom : int or tuple of ints
bar indices where bottom target(s) will be placed. As many targets as ints.
target_center_offset : float
offset from target centers to image center in degree visual angle.
target_heights : float, or Sequence[float, ...]
height of targets in degrees visual angle
origin : "corner", "mean" or "center"
if "corner": set origin to upper left corner (default)
if "mean": set origin to hypothetical image center
if "center": set origin to real center (closest existing value to mean)
round_phase_width : Bool
if True (default), round phase width of grating
Returns
-------
dict[str, Any]
dict with the stimulus (key: "img"),
mask with integer index for each target (key: "mask"),
and additional keys containing stimulus parameters
References
----------
White, M. (1979).
A new effect of pattern on perceived lightness.
Perception, 8(4), 413-416.
https://doi.org/10.1068/p080413
"""
if not isinstance(target_center_offset, (float, int)):
raise ValueError("target_center_offset should be a single float / int")
if isinstance(target_indices_top, (float, int)):
target_indices_top = (target_indices_top,)
if isinstance(target_indices_bottom, (float, int)):
target_indices_bottom = (target_indices_bottom,)
target_indices = target_indices_top + target_indices_bottom
offsets_top = (-target_center_offset,) * len(target_indices_top)
offsets_bottom = (target_center_offset,) * len(target_indices_bottom)
target_center_offsets = offsets_top + offsets_bottom
stim = generalized(
visual_size=visual_size,
ppd=ppd,
shape=shape,
frequency=frequency,
n_bars=n_bars,
bar_width=bar_width,
period=period,
rotation=rotation,
intensity_bars=intensity_bars,
target_indices=target_indices,
intensity_target=intensity_target,
target_center_offsets=target_center_offsets,
target_heights=target_heights,
origin=origin,
round_phase_width=round_phase_width,
)
stim["target_indices_top"] = target_indices_top
stim["target_indices_bottom"] = target_indices_bottom
return stim
[docs]def anderson(
visual_size=None,
ppd=None,
shape=None,
frequency=None,
n_bars=None,
bar_width=None,
period="ignore",
intensity_bars=(0.0, 1.0),
intensity_target=0.5,
target_indices_top=None,
target_indices_bottom=None,
target_center_offset=0,
target_height=None,
intensity_stripes=(0.0, 1.0),
stripe_center_offset=0,
stripe_height=None,
round_phase_width=True,
):
"""Anderson variation of White's stimulus
Parameters
----------
visual_size : Sequence[Number, Number], Number, or None (default)
visual size [height, width] of image, in degrees
ppd : Sequence[Number, Number], Number, or None (default)
pixels per degree [vertical, horizontal]
shape : Sequence[Number, Number], Number, or None (default)
shape [height, width] of image, in pixels
frequency : Number, or None (default)
spatial frequency of grating, in cycles per degree visual angle
n_bars : int, or None (default)
number of bars in the grating
bar_width : Number, or None (default)
width of a single bar, in degrees visual angle
period : "even", "odd", "either" or "ignore" (default)
ensure whether the grating has "even" number of phases, "odd"
number of phases, either or whether not to round the number of
phases ("ignore")
intensity_bars : (float, float)
intensity values of bars
intensity_target : float
intensity value of target
target_indices_top : int or tuple of ints
bar indices where top target(s) will be placed. As many targets as ints.
target_indices_bottom : int or tuple of ints
bar indices where bottom target(s) will be placed. As many targets as ints.
target_center_offset : float
offset from target centers to image center in degree visual angle.
target_height : float, or Sequence[float, ...]
height of targets in degrees visual angle
intensity_stripes : (float, float)
intensity values of horizontal stripes
stripe_center_offset : float
offset from stripe centers to image center in degree visual angle.
stripe_height = float
stripe height in degrees visual angle
round_phase_width : Bool
if True (default), round phase width of grating
Returns
-------
dict[str, Any]
dict with the stimulus (key: "img"),
mask with integer index for each target (key: "mask"),
and additional keys containing stimulus parameters
References
----------
Anderson, B. L. (2001).
Contrasting theories of White's illusion.
Perception, 30, 1499-1501.
Blakeslee, B., Pasieka, W., & McCourt, M. E. (2005).
Oriented multiscale spatial filtering and contrast normalization:
a parsimonious model of brightness induction in a continuum
of stimuli including White, Howe and simultaneous brightness contrast.
Vision Research, 45, 607-615.
"""
if target_height is None:
raise ValueError("anderson() missing argument 'target_height' which is not 'None'")
if stripe_height is None:
raise ValueError("anderson() missing argument 'stripe_height' which is not 'None'")
if isinstance(stripe_height, (int, float)):
stripe_height = (stripe_height, stripe_height)
# Generate White's stimulus with two rows of targets
stim = white_two_rows(
visual_size=visual_size,
ppd=ppd,
shape=shape,
frequency=frequency,
n_bars=n_bars,
bar_width=bar_width,
period=period,
rotation=0.0,
intensity_bars=intensity_bars,
intensity_target=intensity_target,
target_indices_top=target_indices_top,
target_indices_bottom=target_indices_bottom,
target_center_offset=target_center_offset,
target_heights=target_height,
origin="corner",
round_phase_width=round_phase_width,
)
# Masks for stripes (as rectangles)
stim_center = stim["visual_size"].height / 2
stripe_top = rectangle(
visual_size=stim["visual_size"],
ppd=stim["ppd"],
shape=stim["shape"],
rectangle_size=(stripe_height[0], stim["visual_size"].width),
rectangle_position=(stim_center - stripe_center_offset - (stripe_height[0] / 2), 0),
)
for bar_idx in stim["target_indices_top"]:
if bar_idx < 0:
bar_idx = int(stim["n_bars"]) + bar_idx
stripe_top["rectangle_mask"] = np.where(
stim["grating_mask"] == bar_idx, 0, stripe_top["rectangle_mask"]
)
stripe_bottom = rectangle(
visual_size=stim["visual_size"],
ppd=stim["ppd"],
shape=stim["shape"],
rectangle_size=(stripe_height[1], stim["visual_size"].width),
rectangle_position=(stim_center + stripe_center_offset - (stripe_height[1] / 2), 0),
)
for bar_idx in stim["target_indices_bottom"]:
if bar_idx < 0:
bar_idx = int(stim["n_bars"]) + bar_idx
stripe_bottom["rectangle_mask"] = np.where(
stim["grating_mask"] == bar_idx, 0, stripe_bottom["rectangle_mask"]
)
try:
stripes_mask = combine_masks(stripe_top["rectangle_mask"], stripe_bottom["rectangle_mask"])
except ValueError:
raise ValueError("Stripes overlap. Increase stripe offset or decrease stripe size.")
# Combine images
stripes_img = draw_regions(stripes_mask, intensities=intensity_stripes)
img = np.where(stripes_mask, stripes_img, stim["img"])
img = np.where(stim["target_mask"], stim["img"], img)
stim["img"] = img
# Output
stim["stripe_center_offset"] = stripe_center_offset
stim["stripe_height"] = stripe_height
stim["stripes_mask"] = stripes_mask
stim["intensity_stripes"] = intensity_stripes
return stim
[docs]def howe(
visual_size=None,
ppd=None,
shape=None,
frequency=None,
n_bars=None,
bar_width=None,
period="ignore",
intensity_bars=(0.0, 1.0),
intensity_target=0.5,
target_indices_top=None,
target_indices_bottom=None,
target_center_offset=0,
target_height=None,
intensity_stripes=(0.0, 1.0),
round_phase_width=True,
):
"""Howe variation of White's stimulus
Parameters
----------
visual_size : Sequence[Number, Number], Number, or None (default)
visual size [height, width] of image, in degrees
ppd : Sequence[Number, Number], Number, or None (default)
pixels per degree [vertical, horizontal]
shape : Sequence[Number, Number], Number, or None (default)
shape [height, width] of image, in pixels
frequency : Number, or None (default)
spatial frequency of grating, in cycles per degree visual angle
n_bars : int, or None (default)
number of bars in the grating
bar_width : Number, or None (default)
width of a single bar, in degrees visual angle
period : "even", "odd", "either" or "ignore" (default)
ensure whether the grating has "even" number of phases, "odd"
number of phases, either or whether not to round the number of
phases ("ignore")
intensity_bars : (float, float)
intensity values of bars
intensity_target : float
intensity value of target
target_indices_top : int or tuple of ints
bar indices where top target(s) will be placed. As many targets as ints.
target_indices_bottom : int or tuple of ints
bar indices where bottom target(s) will be placed. As many targets as ints.
target_center_offset : float
offset from target centers to image center in degree visual angle.
target_height : float, or Sequence[float, ...]
height of targets in degrees visual angle
intensity_stripes : (float, float)
intensity values of horizontal stripes
round_phase_width : Bool
if True (default), round phase width of grating
Returns
-------
dict[str, Any]
dict with the stimulus (key: "img"),
mask with integer index for each target (key: "mask"),
and additional keys containing stimulus parameters
References
----------
Blakeslee, B., Pasieka, W., & McCourt, M. E. (2005).
Oriented multiscale spatial filtering and contrast normalization:
a parsimonious model of brightness induction in a continuum
of stimuli including White, Howe and simultaneous brightness contrast.
Vision Research, 45, 607-615.
Howe, P. D. L. (2001).
A comment on the Anderson (1997), the Todorovic (1997),
and the Ross and Pessoa (2000) explanations of White's effect.
Perception, 30, 1023-1026
"""
return anderson(
visual_size=visual_size,
ppd=ppd,
shape=shape,
frequency=frequency,
n_bars=n_bars,
bar_width=bar_width,
period=period,
intensity_bars=intensity_bars,
intensity_target=intensity_target,
target_indices_top=target_indices_top,
target_indices_bottom=target_indices_bottom,
target_center_offset=target_center_offset,
target_height=target_height,
intensity_stripes=intensity_stripes,
stripe_center_offset=target_center_offset,
stripe_height=target_height,
round_phase_width=round_phase_width,
)
[docs]def yazdanbakhsh(
visual_size=None,
ppd=None,
shape=None,
frequency=None,
n_bars=None,
bar_width=None,
period="ignore",
intensity_bars=(0.0, 1.0),
intensity_target=0.5,
target_indices_top=None,
target_indices_bottom=None,
target_center_offset=0,
target_heights=None,
# intensity_stripes=(0.0, 1.0),
gap_size=None,
round_phase_width=True,
):
"""Yazsdanbakhsh variation of White's stimulus
Parameters
----------
visual_size : Sequence[Number, Number], Number, or None (default)
visual size [height, width] of image, in degrees
ppd : Sequence[Number, Number], Number, or None (default)
pixels per degree [vertical, horizontal]
shape : Sequence[Number, Number], Number, or None (default)
shape [height, width] of image, in pixels
frequency : Number, or None (default)
spatial frequency of grating, in cycles per degree visual angle
n_bars : int, or None (default)
number of bars in the grating
bar_width : Number, or None (default)
width of a single bar, in degrees visual angle
period : "even", "odd", "either" or "ignore" (default)
ensure whether the grating has "even" number of phases, "odd"
number of phases, either or whether not to round the number of
phases ("ignore")
intensity_bars : (float, float)
intensity values of bars
intensity_target : float
intensity value of target
target_indices_top : int or tuple of ints
bar indices where top target(s) will be placed. As many targets as ints.
target_indices_bottom : int or tuple of ints
bar indices where bottom target(s) will be placed. As many targets as ints.
target_center_offset : float
offset from target centers to image center in degree visual angle.
target_heights : float, or Sequence[float, ...]
height of targets in degrees visual angle
gap_size : float
size of gap between target and grating bar
round_phase_width : Bool
if True (default), round phase width of grating
Returns
-------
dict[str, Any]
dict with the stimulus (key: "img"),
mask with integer index for each target (key: "mask"),
and additional keys containing stimulus parameters
References
----------
Yazdanbakhsh, A., Arabzadeh, E., Babadi, B., and Fazl, A. (2002).
Munker-White-like illusions without T-junctions.
Perception 31, 711-715. https://doi.org/10.1068/p3348
"""
if target_heights is None:
raise ValueError("yazdanbakhsh() missing argument 'target_heights' which is not 'None'")
if gap_size is None:
raise ValueError("yazdanbakhsh() missing argument 'gap_size' which is not 'None'")
# Generate White's stimulus with two rows of targets
stim = white_two_rows(
visual_size=visual_size,
ppd=ppd,
shape=shape,
frequency=frequency,
n_bars=n_bars,
bar_width=bar_width,
period=period,
rotation=0.0,
intensity_bars=intensity_bars,
intensity_target=intensity_target,
target_indices_top=target_indices_top,
target_indices_bottom=target_indices_bottom,
target_center_offset=target_center_offset,
target_heights=target_heights,
origin="corner",
round_phase_width=round_phase_width,
)
# Masks for top gaps
stim_center = stim["visual_size"].height / 2
gap_top_masks = []
for t_idx, bar_idx in enumerate(stim["target_indices_top"]):
height = stim["target_heights"][t_idx]
# Mask for rectangle
rect = rectangle(
visual_size=stim["visual_size"],
ppd=stim["ppd"],
shape=stim["shape"],
rectangle_size=(height + 2 * gap_size, stim["visual_size"].width),
rectangle_position=(stim_center - target_center_offset - (height / 2) - gap_size, 0),
)
# Reduce to just this bar: intersection between rect mask and bar mask
if bar_idx < 0:
bar_idx = int(stim["n_bars"]) + bar_idx
stim["gap_mask"] = (stim["grating_mask"] == bar_idx) & rect["rectangle_mask"]
# Remove everywhere it intersects with target mask
stim["gap_mask"] = np.where(stim["target_mask"] == t_idx + 1, 0, stim["gap_mask"])
gap_top_masks.append(stim["gap_mask"])
# Masks for bottom gaps
gap_bottom_masks = []
for idx, bar_idx in enumerate(stim["target_indices_bottom"]):
t_idx = idx + len(stim["target_indices_top"])
height = stim["target_heights"][t_idx]
# Mask for rectangle
rect = rectangle(
visual_size=stim["visual_size"],
ppd=stim["ppd"],
shape=stim["shape"],
rectangle_size=(height + 2 * gap_size, stim["visual_size"].width),
rectangle_position=(stim_center + target_center_offset - (height / 2) - gap_size, 0),
)
# Reduce to just this bar: intersection between rect mask and bar mask
if bar_idx < 0:
bar_idx = int(stim["n_bars"]) + bar_idx
stim["gap_mask"] = (stim["grating_mask"] == bar_idx) & rect["rectangle_mask"]
# Remove everywhere it intersects with target mask
stim["gap_mask"] = np.where(stim["target_mask"] == t_idx + 1, 0, stim["gap_mask"])
gap_bottom_masks.append(stim["gap_mask"])
stim["gap_mask"] = combine_masks(*gap_top_masks, *gap_bottom_masks)
# Create stim without targets
stim_wo = white_two_rows(
visual_size=visual_size,
ppd=ppd,
shape=shape,
frequency=frequency,
n_bars=n_bars,
bar_width=bar_width,
period=period,
rotation=0.0,
intensity_bars=(intensity_bars[1], intensity_bars[0]),
intensity_target=intensity_target,
target_center_offset=target_center_offset,
target_heights=target_heights,
origin="corner",
round_phase_width=round_phase_width,
)
# Remove information at gaps:
stim["img"] = np.where(stim["gap_mask"], stim_wo["img"], stim["img"])
# Output
stim["gap_size"] = gap_size
return stim
def overview(**kwargs):
"""Generate example stimuli from this module
Returns
-------
stims : dict
dict with all stimuli containing individual stimulus dicts.
"""
default_params = {
"visual_size": 10,
"ppd": 30,
}
default_params.update(kwargs)
# fmt: off
stimuli = {
"white": white(**default_params, target_indices=(2, -3), target_heights=2, frequency=0.5,),
"white_general": generalized(
**default_params,
target_indices=(1, 3, 5),
target_center_offsets=(-1, -3, -1),
target_heights=(2, 3, 2),
frequency=0.5,),
"white_two_rows": white_two_rows(
**default_params,
target_indices_top=(2, 4),
target_indices_bottom=(-2, -4),
target_heights=1,
target_center_offset=2,
frequency=0.5,),
"white_anderson": anderson(
**default_params,
target_indices_top=3,
target_indices_bottom=-4,
target_center_offset=2,
target_height=2,
stripe_center_offset=1.5,
stripe_height=2,
frequency=0.5,),
"white_howe": howe(
**default_params,
target_indices_top=3,
target_indices_bottom=-4,
target_center_offset=2,
target_height=2,
frequency=0.5,),
"white_yazdanbakhsh": yazdanbakhsh(
**default_params,
target_indices_top=2,
target_indices_bottom=-3,
target_center_offset=2,
target_heights=2,
gap_size=0.5,
frequency=0.5,),
"white_angular": angular(
**default_params,
n_segments=10,
target_indices=(1, 6),
target_width=1,),
"white_radial": radial(
**default_params,
frequency=0.5,
target_indices=(1, 4),
clip=True),
"white_wedding_cake": wedding_cake(
**default_params,
L_size=(4, 2.5, 0.5),
target_height=2,
target_indices1=((1, 4), (1, 3)),
target_indices2=((1, 0), (1, 1)),)
}
# fmt: on
return stimuli
if __name__ == "__main__":
from stimupy.utils import plot_stimuli
stims = overview()
plot_stimuli(stims, mask=False, save=None)