Skip to content

Commit

Permalink
closes #22; closes #26; fixed problem with (angular) waves
Browse files Browse the repository at this point in the history
  • Loading branch information
LynnSchmittwilken committed Mar 23, 2023
1 parent 2621ebf commit 418458a
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 44 deletions.
73 changes: 54 additions & 19 deletions stimupy/components/angulars.py
Expand Up @@ -5,7 +5,7 @@

__all__ = [
"wedge",
"angular_segments",
"segments",
]


Expand Down Expand Up @@ -60,7 +60,7 @@ def wedge(
visual_size=None,
ppd=None,
shape=None,
width=None,
angle=None,
radius=None,
rotation=0.0,
inner_radius=0.0,
Expand All @@ -78,7 +78,7 @@ def wedge(
pixels per degree [vertical, horizontal]
shape : Sequence[Number, Number], Number, or None (default)
shape [height, width] of image, in pixels
width : float
angle : float
angular-width (in degrees) of segment
radius : float
radius of disc, in degrees visual angle
Expand All @@ -103,13 +103,13 @@ def wedge(
mask with integer index for each segment (key: "wedge_mask"),
and additional keys containing stimulus parameters
"""
if width is None:
raise ValueError("wedge() missing argument 'width' which is not 'None'")
if angle is None:
raise ValueError("wedge() missing argument 'angle' which is not 'None'")
if radius is None:
raise ValueError("wedge() missing argument 'radius' which is not 'None'")

# Convert to inner-, outer-angle
angles = [0, width]
angles = [0, angle]

# Draw disc
stim = ring(
Expand Down Expand Up @@ -189,37 +189,39 @@ def mask_segments(
return stim


def angular_segments(
angles,
intensity_segments,
rotation=0.0,
def segments(
visual_size=None,
ppd=None,
shape=None,
angles=None,
rotation=0.0,
intensity_background=0.5,
intensity_segments=(0, 1),
origin="mean",
):
"""Generate mask with integer indices for sequential angular segments
Parameters
----------
angles : Sequence[Number]
upper-limit of each segment, in angular degrees 0-360
intensities : Sequence[Number, ...]
intensity value for each segment, from inside to out.
If fewer intensities are passed than number of radii, cycles through intensities
rotation : float, optional
angle of rotation (in degrees) of segments,
counterclockwise away from 3 o'clock, by default 0.0
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
angles : Sequence[Number] or None (default)
upper-limit of each segment, in angular degrees 0-360
rotation : float, optional
angle of rotation (in degrees) of segments,
counterclockwise away from 3 o'clock, by default 0.0angles
intensity_background : Number
intensity value for background; default is 0.5.
intensity_segments : Sequence[Number, ...]
intensity value for each segment, from inside to out.
If fewer intensities are passed than number of radii, cycles through intensity_segments
origin : "corner", "mean" or "center"
if "corner": set origin to upper left corner
if "mean": set origin to hypothetical image center (default)
if "mean": set origin to hypothetical image center (default)angles
if "center": set origin to real center (closest existing value to mean)
Returns
Expand All @@ -229,6 +231,8 @@ def angular_segments(
mask with integer index for each segment (key: "wedge_mask"),
and additional keys containing stimulus parameters
"""
if angles is None:
raise ValueError("segments() missing argument 'angles' which is not 'None'")

# Get mask
stim = mask_segments(
Expand All @@ -247,3 +251,34 @@ def angular_segments(
intensity_background=intensity_background,
)
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, 10),
"ppd": 20,
}
default_params.update(kwargs)

# fmt: off
stimuli = {
"angulars_wedge": wedge(**default_params, angle=30, radius=4),
"angulars_segments": segments(**default_params, angles=(30, 120, 300)),
}
# fmt: on

return stimuli


if __name__ == "__main__":
from stimupy.utils import plot_stimuli

stims = overview()
plot_stimuli(stims, mask=False, save=None)
35 changes: 24 additions & 11 deletions stimupy/components/waves.py
Expand Up @@ -351,16 +351,27 @@ def sine(
warnings.warn("Period ignored for oblique gratings")

# Resolve params
params = resolve_grating_params(
length=length,
visual_angle=visual_angle,
n_phases=n_phases,
phase_width=phase_width,
ppd=ppd_1D,
frequency=frequency,
period=period,
round_phase_width=round_phase_width,
)
if distance_metric == "angular":
params = resolve_grating_params(
visual_angle=360,
n_phases=n_phases,
phase_width=phase_width,
ppd=1,
frequency=frequency,
period=period,
round_phase_width=round_phase_width,
)
else:
params = resolve_grating_params(
length=length,
visual_angle=visual_angle,
n_phases=n_phases,
phase_width=phase_width,
ppd=ppd_1D,
frequency=frequency,
period=period,
round_phase_width=round_phase_width,
)
length = params["length"]
ppd_1D = params["ppd"]
visual_angle = params["visual_angle"]
Expand Down Expand Up @@ -402,7 +413,9 @@ def sine(
)

if distance_metric == "angular":
distances = adapt_intensity_range(distances, 0, n_phases * phase_width)
distances = adapt_intensity_range(
distances, distances.min() - 1e-05, n_phases * phase_width - 1e-05
)

# Draw image
img = np.sin(frequency * 2 * np.pi * distances + np.deg2rad(phase_shift))
Expand Down
8 changes: 4 additions & 4 deletions stimupy/stimuli/pinwheels.py
Expand Up @@ -2,8 +2,8 @@

import numpy as np

from stimupy.components.shapes import circle
from stimupy.components.shapes import ring as ring_shape
from stimupy.components.shapes import circle
from stimupy.stimuli import waves

__all__ = [
Expand Down Expand Up @@ -169,7 +169,6 @@ def pinwheel(

def overview(**kwargs):
"""Generate example stimuli from this module
Returns
-------
stims : dict
Expand All @@ -183,7 +182,8 @@ def overview(**kwargs):

# fmt: off
stimuli = {
"pinwheel": pinwheel(**default_params, n_segments=10, target_width=1, target_indices=3),
"pinwheel": pinwheel(**default_params, n_segments=10, target_width=2, target_indices=3),

}
# fmt: on

Expand All @@ -194,4 +194,4 @@ def overview(**kwargs):
from stimupy.utils import plot_stimuli

stims = overview()
plot_stimuli(stims, mask=True, save=None)
plot_stimuli(stims, mask=False, save=None)
12 changes: 6 additions & 6 deletions stimupy/stimuli/waves.py
Expand Up @@ -1439,34 +1439,34 @@ def overview(**kwargs):
"sine_wave_linear": sine_linear(**default_params, **grating_params, bar_width=1, rotation=45),
"sine_wave_radial": sine_radial(**default_params, **grating_params, ring_width=1),
"sine_wave_rectilinear": sine_rectilinear(**default_params, **grating_params, frame_width=1),
"sine_wave_angular": sine_angular(**default_params, **grating_params, segment_width=10),
"sine_wave_angular": sine_angular(**default_params, **grating_params, n_segments=10),


"square_wave_linear": square_linear(**default_params, **grating_params, bar_width=1, rotation=45),
"square_wave_radial": square_radial(**default_params, **grating_params, ring_width=1),
"square_wave_rectilinear": square_rectilinear(**default_params, **grating_params, frame_width=1, clip=True),
"square_wave_angular": square_angular(**default_params, **grating_params, segment_width=10),
"square_wave_angular": square_angular(**default_params, **grating_params, n_segments=10),

"staircase_linear": staircase_linear(**default_params, **grating_params, frequency=0.4),
"staircase_radial": staircase_radial(**default_params, **grating_params, frequency=0.4),
"staircase_rectilinear": staircase_rectilinear(**default_params, **grating_params, frequency=0.4),
"staircase_angular": staircase_angular(**default_params, **grating_params, frequency=0.4),
"staircase_angular": staircase_angular(**default_params, **grating_params, n_segments=10),

"sine_wave_linear_with_targets": sine_linear(**default_params, **grating_params2, bar_width=1, rotation=45),
"sine_wave_radial_with_targets": sine_radial(**default_params, **grating_params2, ring_width=1),
"sine_wave_rectilinear_with_targets": sine_rectilinear(**default_params, **grating_params2, frame_width=1),
"sine_wave_angular_with_targets": sine_angular(**default_params, **grating_params2, segment_width=10),
"sine_wave_angular_with_targets": sine_angular(**default_params, **grating_params2, n_segments=10),


"square_wave_linear_with_targets": square_linear(**default_params, **grating_params2, bar_width=1, rotation=45),
"square_wave_radial_with_targets": square_radial(**default_params, **grating_params2, ring_width=1),
"square_wave_rectilinear_with_targets": square_rectilinear(**default_params, **grating_params2, frame_width=1, clip=True),
"square_wave_angular_with_targets": square_angular(**default_params, **grating_params2, segment_width=10),
"square_wave_angular_with_targets": square_angular(**default_params, **grating_params2, n_segments=10),

"staircase_linear_with_targets": staircase_linear(**default_params, **grating_params2, frequency=0.4),
"staircase_radial_with_targets": staircase_radial(**default_params, **grating_params2, frequency=0.4),
"staircase_rectilinear_with_targets": staircase_rectilinear(**default_params, **grating_params2, frequency=0.4),
"staircase_angular_with_targets": staircase_angular(**default_params, **grating_params2, frequency=0.4),
"staircase_angular_with_targets": staircase_angular(**default_params, **grating_params2, n_segments=10),
}
# fmt: on

Expand Down
8 changes: 4 additions & 4 deletions tests/papers/RHS2007.json
Expand Up @@ -24,19 +24,19 @@
"mask": "9ecd24302fd639a3b1d88bc8d2473384"
},
"WE_radial_thick_small": {
"img": "83941ace718997aaa0ef0da5fd776c3a",
"img": "3358a7ee8baea343c183c672c91b80c0",
"mask": "9dfa712381dad3c534d9d122bceac93a"
},
"WE_radial_thick": {
"img": "28ede29485d08bc66b27cd11365739eb",
"img": "42db484da7509847c1073e8581948165",
"mask": "773b67ccbfbc66f3e980745554d090d9"
},
"WE_radial_thin_small": {
"img": "aec1e23dd76a54eec9baa011d8700b1d",
"img": "4e971a779c6f63b904891018c4418b64",
"mask": "5194ec93724d6ce281c08a823e3faaa6"
},
"WE_radial_thin": {
"img": "0776b637e53df7eeddeb9cdc0830bb70",
"img": "fa8393974017920557cd0b7a79b6d21c",
"mask": "c22efa605c5f51a1f9185dc6f7f5c5b4"
},
"WE_circular1": {
Expand Down

0 comments on commit 418458a

Please sign in to comment.