From 7e0cf7c321a81827e826760bb2f17a75963abc8f Mon Sep 17 00:00:00 2001 From: Joris Vincent Date: Fri, 25 Aug 2023 14:35:41 +0200 Subject: [PATCH] feat(stimuli): rings.circular_generalized --- stimupy/stimuli/rings.py | 70 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/stimupy/stimuli/rings.py b/stimupy/stimuli/rings.py index aa4753f..454bb4d 100644 --- a/stimupy/stimuli/rings.py +++ b/stimupy/stimuli/rings.py @@ -1,4 +1,5 @@ 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 @@ -6,6 +7,7 @@ __all__ = [ "circular", + "circular_generalized", "circular_two_sided", "rectangular", "rectangular_generalized", @@ -13,6 +15,74 @@ ] +def circular_generalized( + visual_size=None, + ppd=None, + shape=None, + radii=None, + intensity_rings=(1.0, 0.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 + + def circular_two_sided( visual_size=None, ppd=None,