Source code for stimupy.stimuli.rings

from stimupy.components.frames import frames
from stimupy.components.radials import rings
from stimupy.stimuli import place_targets
from stimupy.stimuli.waves import square_radial as circular
from stimupy.stimuli.waves import square_rectilinear as rectangular
from stimupy.utils import make_two_sided

__all__ = [
    "circular",
    "circular_generalized",
    "circular_two_sided",
    "rectangular",
    "rectangular_generalized",
    "rectangular_two_sided",
]


[docs]def circular_generalized( visual_size=None, ppd=None, shape=None, radii=None, intensity_rings=(0.0, 1.0), intensity_background=0.5, target_indices=(), intensity_target=0.5, origin="mean", ): """Sequential set of circular rings with specified radii and targets 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 radii : Sequence[Number] or None (default) radii of each ring, in degrees visual angle intensity_rings : Sequence[float, float] intensities of rings, by default (1.0, 0.0) intensity_background : float (optional) intensity value of background, by default 0.5 target_indices : int, or Sequence[int, ...] indices rings 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 origin : "corner", "mean" or "center" if "corner": set origin to upper left corner if "mean": set origin to hypothetical image center (default) if "center": set origin to real center (closest existing value to mean) Returns ------- dict[str, Any] dict with the stimulus (key: "img"), mask with integer index for each ring (key: "target_mask"), and additional keys containing stimulus parameters """ # Rings component stim = rings( radii=radii, visual_size=visual_size, ppd=ppd, shape=shape, intensity_rings=intensity_rings, intensity_background=intensity_background, origin=origin, ) # Place target(s) stim = place_targets( stim=stim, element_mask_key="ring_mask", target_indices=target_indices, intensity_target=intensity_target, ) return stim
circular_two_sided = make_two_sided( circular, two_sided_params=("intensity_rings", "intensity_target", "target_indices") )
[docs]def rectangular_generalized( visual_size=None, ppd=None, shape=None, radii=None, intensity_frames=(0.0, 1.0), intensity_background=0.5, target_indices=(), intensity_target=0.5, origin="mean", rotation=0.0, ): """Draw sequential set of square frames with specified radii and targets 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 radii : Sequence[Number] or None (default) radii of each frame, in degrees visual angle intensity_frames : Sequence[float, float] min and max intensity of square-wave, by default (0.0, 1.0) intensity_background : float (optional) intensity value of background, by default 0.5 target_indices : int, or Sequence[int, ...] indices frames 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 origin : "corner", "mean" or "center" if "corner": set origin to upper left corner if "mean": set origin to hypothetical image center (default) if "center": set origin to real center (closest existing value to mean) rotation : float, optional rotation (in degrees), counterclockwise, by default 0.0 (horizontal) Returns ------- dict[str, Any] dict with the stimulus (key: "img"), mask with integer index for each frame (key: "target_mask"), and additional keys containing stimulus parameters """ # Frames component stim = frames( radii=radii, visual_size=visual_size, ppd=ppd, shape=shape, intensity_frames=intensity_frames, intensity_background=intensity_background, origin=origin, rotation=rotation, ) stim["intensity_target"] = intensity_target # Place target(s) stim = place_targets( stim=stim, element_mask_key="frame_mask", target_indices=target_indices, intensity_target=intensity_target, ) return stim
rectangular_two_sided = make_two_sided( rectangular, two_sided_params=("intensity_frames", "intensity_target", "target_indices") ) 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, 10), "ppd": 30, } default_params.update(kwargs) # fmt: off stimuli = { "rings_circular": circular(**default_params, frequency=1.0), "rings_circular_with_targets": circular(**default_params, frequency=1.0, target_indices=3), "rings_circular_clipped": circular(**default_params, frequency=1.0, clip=True), "rings_circular_2sided": circular_two_sided(**default_params, frequency=1.0, intensity_rings=((0.0, 1.0), (1.0, 0.0)), clip=True, target_indices=2), "rings_rectangular": rectangular(**default_params, frequency=1.0), "rings_rectangular_with_targets": rectangular(**default_params, frequency=1.0, target_indices=3), "rings_rectangular_clipped": rectangular(**default_params, frequency=1.0, clip=True), "rings_rectangular_2sided": rectangular_two_sided(**default_params, frequency=1.0, intensity_frames=((0.0, 1.0), (1.0, 0.0)), clip=True, target_indices=2), } # fmt: on return stimuli if __name__ == "__main__": from stimupy.utils import plot_stimuli stims = overview() plot_stimuli(stims, mask=False, save=None)