From 2ac4162e25256cdec097c77f894237f1ba9fbe25 Mon Sep 17 00:00:00 2001 From: Joris Vincent Date: Thu, 23 Mar 2023 16:56:42 +0100 Subject: [PATCH 01/10] Demo: stimuli/SBCs --- docs/reference/demos/stimuli/sbcs.md | 602 +++++++++++++++++++++++++++ 1 file changed, 602 insertions(+) create mode 100644 docs/reference/demos/stimuli/sbcs.md diff --git a/docs/reference/demos/stimuli/sbcs.md b/docs/reference/demos/stimuli/sbcs.md new file mode 100644 index 0000000..650a955 --- /dev/null +++ b/docs/reference/demos/stimuli/sbcs.md @@ -0,0 +1,602 @@ +--- +jupytext: + formats: md:myst + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.14.5 +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +```{important} +[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/computational-psychology/stimupy/HEAD?urlpath=lab/tree/docs/reference/demos/stimuli/sbcs.md) + to get interactivity +``` + +# Stimuli - SBCs (Simultaneous Brightness Contrast) +{py:mod}`stimupy.stimuli.sbcs` + +```{code-cell} ipython3 +:tags: [remove-cell] + +import IPython +import ipywidgets as iw +from stimupy.utils import plot_stim +``` + +## Generalized +{py:func}`stimupy.stimuli.sbcs.generalized` + +```{code-cell} ipython3 +from stimupy.stimuli.sbcs import generalized + +# Define widgets +w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_t_height = iw.IntSlider(value=3, min=1, max=6, description="target height [deg]") +w_t_width = iw.IntSlider(value=3, min=1, max=6, description="target width [deg]") +w_rot = iw.IntSlider(value=0, min=0, max=360, description="rotation [deg]") + +w_t_posx = iw.FloatSlider(value=3.0, min=0, max=10.0, description="horz. position") +w_t_posy = iw.FloatSlider(value=3.0, min=0, max=10.0, description="vert. position") + +w_tint = iw.FloatSlider(value=0.5, min=0, max=1, description="intensity target") +w_int_back = iw.FloatSlider(value=0., min=0, max=1, description="intensity background") + +w_mask = iw.ToggleButton(value=False, disabled=False, description="add mask") + + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_t_size = iw.HBox([w_t_height, w_t_width, w_rot]) +b_post = iw.HBox([w_t_posx, w_t_posy]) +b_intensities = iw.HBox([w_tint, w_int_back]) +b_add = iw.HBox([w_mask]) +ui = iw.VBox([b_im_size, b_t_size, b_post, b_intensities, b_add]) + +# Function for showing stim +def show_generalized( + height=None, + width=None, + ppd=None, + target_height=None, + target_width=None, + target_x=None, + target_y=None, + intensity_background=None, + intensity_target=None, + add_mask=False, +): + stim = generalized( + visual_size=(height, width), + ppd=ppd, + target_size=(target_height,target_width), + target_position=(target_y,target_x), + intensity_background=intensity_background, + intensity_target=intensity_target, + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_generalized, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "target_height": w_t_height, + "target_width": w_t_width, + "target_x": w_t_posx, + "target_y": w_t_posy, + "intensity_background": w_int_back, + "intensity_target": w_tint, + "add_mask": w_mask, + }, +) + +# Show +display(ui, out) +``` + + +## Basic +{py:func}`stimupy.stimuli.sbcs.basic` + +```{code-cell} ipython3 +from stimupy.stimuli.sbcs import basic + +# Define widgets +w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_t_height = iw.IntSlider(value=3, min=1, max=6, description="target height [deg]") +w_t_width = iw.IntSlider(value=3, min=1, max=6, description="target width [deg]") + +w_tint = iw.FloatSlider(value=0.5, min=0, max=1, description="intensity target") +w_int_back = iw.FloatSlider(value=0., min=0, max=1, description="intensity background") + +w_mask = iw.ToggleButton(value=False, disabled=False, description="add mask") + + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_t_size = iw.HBox([w_t_height, w_t_width]) +b_intensities = iw.HBox([w_tint, w_int_back]) +b_add = iw.HBox([w_mask]) +ui = iw.VBox([b_im_size, b_t_size, b_intensities, b_add]) + +# Function for showing stim +def show_basic( + height=None, + width=None, + ppd=None, + target_height=None, + target_width=None, + intensity_background=None, + intensity_target=None, + add_mask=False, +): + stim = basic( + visual_size=(height, width), + ppd=ppd, + target_size=(target_height,target_width), + intensity_background=intensity_background, + intensity_target=intensity_target, + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_basic, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "target_height": w_t_height, + "target_width": w_t_width, + "intensity_background": w_int_back, + "intensity_target": w_tint, + "add_mask": w_mask, + }, +) + +# Show +display(ui, out) +``` + +## Two sided +{py:func}`stimupy.stimuli.sbcs.two_sided` + +```{code-cell} ipython3 +from stimupy.stimuli.sbcs import two_sided + +# Define widgets +w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_t_height = iw.IntSlider(value=3, min=1, max=6, description="target height [deg]") +w_t_width = iw.IntSlider(value=3, min=1, max=6, description="target width [deg]") + +w_tint = iw.FloatSlider(value=0.5, min=0, max=1, description="intensity target") +w_int_back_l = iw.FloatSlider(value=0., min=0, max=1, description="intensity left background") +w_int_back_r = iw.FloatSlider(value=1., min=0, max=1, description="intensity right background") + + +w_mask = iw.ToggleButton(value=False, disabled=False, description="add mask") + + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_t_size = iw.HBox([w_t_height, w_t_width, w_rot]) +b_intensities = iw.HBox([w_tint, w_int_back_l, w_int_back_r]) +b_add = iw.HBox([w_mask]) +ui = iw.VBox([b_im_size, b_t_size, b_intensities, b_add]) + +# Function for showing stim +def show_two_sided( + height=None, + width=None, + ppd=None, + target_height=None, + target_width=None, + intensity_background_l=None, + intensity_background_r=None, + intensity_target=None, + add_mask=False, +): + stim = two_sided( + visual_size=(height, width), + ppd=ppd, + target_size=(target_height,target_width), + intensity_backgrounds=(intensity_background_l, intensity_background_r), + intensity_target=intensity_target, + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_two_sided, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "target_height": w_t_height, + "target_width": w_t_width, + "intensity_background_l": w_int_back_l, + "intensity_background_r": w_int_back_r, + "intensity_target": w_tint, + "add_mask": w_mask, + }, +) + +# Show +display(ui, out) +``` + +## With dots +{py:func}`stimupy.stimuli.sbcs.with_dots` + +```{code-cell} ipython3 +from stimupy.stimuli.sbcs import with_dots + +# Define widgets +w_height = iw.IntSlider(value=15, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=15, min=1, max=20, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_t_height = iw.IntSlider(value=3, min=1, max=6, description="target height [deg]") +w_t_width = iw.IntSlider(value=3, min=1, max=6, description="target width [deg]") + +w_ndotsy = iw.IntSlider(value=5, min=1, max=10, description="n dots y") +w_ndotsx = iw.IntSlider(value=5, min=1, max=10, description="n dots x") +w_dotradius = iw.FloatSlider(value=.5, min=0.1, max=6.0, description="dot radius") +w_dotdist = iw.FloatSlider(value=0.25, min=0.1, max=3.0, description="dot distance") + +w_tint = iw.FloatSlider(value=0.5, min=0, max=1, description="intensity target") +w_idots = iw.FloatSlider(value=1.0, min=0., max=1.0, description="intensity dots") +w_int_back = iw.FloatSlider(value=0., min=0, max=1, description="intensity background") +w_mask = iw.ToggleButton(value=False, disabled=False, description="add mask") + + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_t_size = iw.HBox([w_t_height, w_t_width, w_rot]) +b_ndots = iw.HBox([w_ndotsy, w_ndotsx]) +b_dotsize = iw.HBox([w_dotradius, w_dotdist]) +b_intensities = iw.HBox([w_tint, w_int_back, w_idots]) +b_add = iw.HBox([w_mask]) +ui = iw.VBox([b_im_size, b_t_size, b_ndots, b_dotsize, b_intensities, b_add]) + +# Function for showing stim +def show_with_dots( + height=None, + width=None, + ppd=None, + target_height=None, + target_width=None, + ndotsy=None, + ndotsx=None, + dot_radius=None, + dot_distance=None, + intensity_background=None, + intensity_target=None, + intensity_dots=None, + add_mask=False, +): + stim = with_dots( + visual_size=(height, width), + ppd=ppd, + target_shape=(target_height, target_width), + n_dots=(ndotsy, ndotsx), + dot_radius=dot_radius, + distance=dot_distance, + intensity_background=intensity_background, + intensity_target=intensity_target, + intensity_dots=intensity_dots, + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_with_dots, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "target_height": w_t_height, + "target_width": w_t_width, + "ndotsy": w_ndotsy, + "ndotsx": w_ndotsx, + "dot_radius": w_dotradius, + "dot_distance": w_dotdist, + "intensity_background": w_int_back, + "intensity_target": w_tint, + "intensity_dots": w_idots, + "add_mask": w_mask, + }, +) + +# Show +display(ui, out) +``` +## With dots, two sided +{py:func}`stimupy.stimuli.sbcs.two_sided_with_dots` + +```{code-cell} ipython3 +from stimupy.stimuli.sbcs import two_sided_with_dots + +# Define widgets +w_height = iw.IntSlider(value=15, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=15, min=1, max=20, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_t_height = iw.IntSlider(value=3, min=1, max=6, description="target height [deg]") +w_t_width = iw.IntSlider(value=3, min=1, max=6, description="target width [deg]") + +w_ndotsy = iw.IntSlider(value=5, min=1, max=10, description="n dots y") +w_ndotsx = iw.IntSlider(value=5, min=1, max=10, description="n dots x") +w_dotradius = iw.FloatSlider(value=.5, min=0.1, max=6.0, description="dot radius") +w_dotdist = iw.FloatSlider(value=0.25, min=0.1, max=3.0, description="dot distance") + +w_tint = iw.FloatSlider(value=0.5, min=0, max=1, description="intensity target") +w_idots_l = iw.FloatSlider(value=1.0, min=0., max=1.0, description="intensity left dots") +w_idots_r = iw.FloatSlider(value=0.0, min=0., max=1.0, description="intensity right dots") +w_int_back_l = iw.FloatSlider(value=0., min=0, max=1, description="intensity left background") +w_int_back_r = iw.FloatSlider(value=1., min=0, max=1, description="intensity right background") +w_mask = iw.ToggleButton(value=False, disabled=False, description="add mask") + + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_t_size = iw.HBox([w_t_height, w_t_width, w_rot]) +b_ndots = iw.HBox([w_ndotsy, w_ndotsx]) +b_dotsize = iw.HBox([w_dotradius, w_dotdist]) +b_intensities = iw.HBox([w_tint, w_int_back_l, w_int_back_r, w_idots_l, w_idots_r]) +b_add = iw.HBox([w_mask]) +ui = iw.VBox([b_im_size, b_t_size, b_ndots, b_dotsize, b_intensities, b_add]) + +# Function for showing stim +def show_two_sided_with_dots( + height=None, + width=None, + ppd=None, + target_height=None, + target_width=None, + ndotsy=None, + ndotsx=None, + dot_radius=None, + dot_distance=None, + intensity_background_l=None, + intensity_background_r=None, + intensity_target=None, + intensity_dots_l=None, + intensity_dots_r=None, + add_mask=False, +): + stim = two_sided_with_dots( + visual_size=(height, width), + ppd=ppd, + target_shape=(target_height, target_width), + n_dots=(ndotsy, ndotsx), + dot_radius=dot_radius, + distance=dot_distance, + intensity_backgrounds=(intensity_background_l, intensity_background_r), + intensity_target=intensity_target, + intensity_dots=(intensity_dots_l, intensity_dots_r), + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_two_sided_with_dots, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "target_height": w_t_height, + "target_width": w_t_width, + "ndotsy": w_ndotsy, + "ndotsx": w_ndotsx, + "dot_radius": w_dotradius, + "dot_distance": w_dotdist, + "intensity_background_l": w_int_back_l, + "intensity_background_r": w_int_back_r, + "intensity_target": w_tint, + "intensity_dots_l": w_idots_l, + "intensity_dots_r": w_idots_r, + "add_mask": w_mask, + }, +) + +# Show +display(ui, out) +``` + +## Dotted +{py:func}`stimupy.stimuli.sbcs.dotted` + +```{code-cell} ipython3 +from stimupy.stimuli.sbcs import dotted + +# Define widgets +w_height = iw.IntSlider(value=15, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=15, min=1, max=20, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_t_height = iw.IntSlider(value=3, min=1, max=6, description="target height [deg]") +w_t_width = iw.IntSlider(value=3, min=1, max=6, description="target width [deg]") + +w_ndotsy = iw.IntSlider(value=5, min=1, max=10, description="n dots y") +w_ndotsx = iw.IntSlider(value=5, min=1, max=10, description="n dots x") +w_dotradius = iw.FloatSlider(value=.5, min=0.1, max=6.0, description="dot radius") +w_dotdist = iw.FloatSlider(value=0.25, min=0.1, max=3.0, description="dot distance") + +w_tint = iw.FloatSlider(value=0.5, min=0, max=1, description="intensity target") +w_idots = iw.FloatSlider(value=1.0, min=0., max=1.0, description="intensity dots") +w_int_back = iw.FloatSlider(value=0., min=0, max=1, description="intensity background") +w_mask = iw.ToggleButton(value=False, disabled=False, description="add mask") + + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_t_size = iw.HBox([w_t_height, w_t_width, w_rot]) +b_ndots = iw.HBox([w_ndotsy, w_ndotsx]) +b_dotsize = iw.HBox([w_dotradius, w_dotdist]) +b_intensities = iw.HBox([w_tint, w_int_back, w_idots]) +b_add = iw.HBox([w_mask]) +ui = iw.VBox([b_im_size, b_t_size, b_ndots, b_dotsize, b_intensities, b_add]) + +# Function for showing stim +def show_dotted( + height=None, + width=None, + ppd=None, + target_height=None, + target_width=None, + ndotsy=None, + ndotsx=None, + dot_radius=None, + dot_distance=None, + intensity_background=None, + intensity_target=None, + intensity_dots=None, + add_mask=False, +): + stim = dotted( + visual_size=(height, width), + ppd=ppd, + target_shape=(target_height, target_width), + n_dots=(ndotsy, ndotsx), + dot_radius=dot_radius, + distance=dot_distance, + intensity_background=intensity_background, + intensity_target=intensity_target, + intensity_dots=intensity_dots, + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_dotted, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "target_height": w_t_height, + "target_width": w_t_width, + "ndotsy": w_ndotsy, + "ndotsx": w_ndotsx, + "dot_radius": w_dotradius, + "dot_distance": w_dotdist, + "intensity_background": w_int_back, + "intensity_target": w_tint, + "intensity_dots": w_idots, + "add_mask": w_mask, + }, +) + +# Show +display(ui, out) +``` + + +## Dotted, two sided +{py:func}`stimupy.stimuli.sbcs.two_sided_dotted` + +```{code-cell} ipython3 +from stimupy.stimuli.sbcs import two_sided_dotted + +# Define widgets +w_height = iw.IntSlider(value=15, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=15, min=1, max=20, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_t_height = iw.IntSlider(value=3, min=1, max=6, description="target height [deg]") +w_t_width = iw.IntSlider(value=3, min=1, max=6, description="target width [deg]") + +w_ndotsy = iw.IntSlider(value=5, min=1, max=10, description="n dots y") +w_ndotsx = iw.IntSlider(value=5, min=1, max=10, description="n dots x") +w_dotradius = iw.FloatSlider(value=.5, min=0.1, max=6.0, description="dot radius") +w_dotdist = iw.FloatSlider(value=0.25, min=0.1, max=3.0, description="dot distance") + +w_tint = iw.FloatSlider(value=0.5, min=0, max=1, description="intensity target") +w_idots_l = iw.FloatSlider(value=1.0, min=0., max=1.0, description="intensity left dots") +w_idots_r = iw.FloatSlider(value=0.0, min=0., max=1.0, description="intensity right dots") +w_int_back_l = iw.FloatSlider(value=0., min=0, max=1, description="intensity left background") +w_int_back_r = iw.FloatSlider(value=1., min=0, max=1, description="intensity right background") +w_mask = iw.ToggleButton(value=False, disabled=False, description="add mask") + + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_t_size = iw.HBox([w_t_height, w_t_width, w_rot]) +b_ndots = iw.HBox([w_ndotsy, w_ndotsx]) +b_dotsize = iw.HBox([w_dotradius, w_dotdist]) +b_intensities = iw.HBox([w_tint, w_int_back_l, w_int_back_r, w_idots_l, w_idots_r]) +b_add = iw.HBox([w_mask]) +ui = iw.VBox([b_im_size, b_t_size, b_ndots, b_dotsize, b_intensities, b_add]) + +# Function for showing stim +def show_two_sided_dotted( + height=None, + width=None, + ppd=None, + target_height=None, + target_width=None, + ndotsy=None, + ndotsx=None, + dot_radius=None, + dot_distance=None, + intensity_background_l=None, + intensity_background_r=None, + intensity_target=None, + intensity_dots_l=None, + intensity_dots_r=None, + add_mask=False, +): + stim = two_sided_dotted( + visual_size=(height, width), + ppd=ppd, + target_shape=(target_height, target_width), + n_dots=(ndotsy, ndotsx), + dot_radius=dot_radius, + distance=dot_distance, + intensity_backgrounds=(intensity_background_l, intensity_background_r), + intensity_target=intensity_target, + intensity_dots=(intensity_dots_l, intensity_dots_r), + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_two_sided_dotted, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "target_height": w_t_height, + "target_width": w_t_width, + "ndotsy": w_ndotsy, + "ndotsx": w_ndotsx, + "dot_radius": w_dotradius, + "dot_distance": w_dotdist, + "intensity_background_l": w_int_back_l, + "intensity_background_r": w_int_back_r, + "intensity_target": w_tint, + "intensity_dots_l": w_idots_l, + "intensity_dots_r": w_idots_r, + "add_mask": w_mask, + }, +) + +# Show +display(ui, out) +``` \ No newline at end of file From a2c45a42bf8f6af04145d93bea91ea496a655cf1 Mon Sep 17 00:00:00 2001 From: Joris Vincent Date: Thu, 23 Mar 2023 17:20:45 +0100 Subject: [PATCH 02/10] Demo: stimuli/waves --- docs/reference/demos/stimuli/waves.md | 745 +++++++++++++++++++++++++- 1 file changed, 743 insertions(+), 2 deletions(-) diff --git a/docs/reference/demos/stimuli/waves.md b/docs/reference/demos/stimuli/waves.md index 493bbbf..ccdf5cd 100644 --- a/docs/reference/demos/stimuli/waves.md +++ b/docs/reference/demos/stimuli/waves.md @@ -30,6 +30,95 @@ from stimupy.utils import plot_stim ``` ## Sine, linear +{py:func}`stimupy.stimuli.waves.sine_linear` + +```{code-cell} ipython3 +from stimupy.stimuli.waves import sine_linear + +# Define widgets +w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_freq = iw.FloatSlider(value=1, min=0, max=2, description="frequency [cpd]") +w_phase = iw.FloatSlider(value=0, min=0, max=360, description="phase shift [deg]") +w_rot = iw.FloatSlider(value=0, min=0, max=360, description="rotation [deg]") + +w_int1 = iw.FloatSlider(value=1, min=0, max=1, description="int1") +w_int2 = iw.FloatSlider(value=0, min=0, max=1, description="int2") + +w_ori = iw.Dropdown(value="corner", options=['mean', 'corner', 'center'], description="origin") +w_period = iw.Dropdown(value="ignore", options=['ignore', 'even', 'odd', 'either'], description="period") +w_round = iw.ToggleButton(value=False, disabled=False, description="round phase") +w_mask = iw.Dropdown(value=None, options=[None, 'target_mask', 'grating_mask'], description="add mask") + +w_tidx = iw.IntSlider(value=1, min=1, max=10, description="target idx") +w_tint = iw.FloatSlider(value=0.5, min=0, max=1, description="target int") + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_geometry = iw.HBox([w_freq, w_phase, w_rot]) +b_intensities = iw.HBox([w_int1, w_int2]) +b_target = iw.HBox([w_tidx, w_tint]) +b_add = iw.HBox([w_ori, w_period, w_round, w_mask]) +ui = iw.VBox([b_im_size, b_geometry, b_intensities, b_target, b_add]) + +# Function for showing stim +def show_sine_linear( + height=None, + width=None, + ppd=None, + rotation=None, + frequency=None, + phase_shift=None, + int1=None, + int2=None, + origin=None, + round_phase_width=False, + period=None, + add_mask=False, + target_indices=None, + intensity_target=None, +): + stim = sine_linear( + visual_size=(height, width), + ppd=ppd, + rotation=rotation, + frequency=frequency, + phase_shift=phase_shift, + intensities=(int1, int2), + origin=origin, + round_phase_width=round_phase_width, + period=period, + target_indices=target_indices, + intensity_target=intensity_target, + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_sine_linear, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "rotation": w_rot, + "frequency": w_freq, + "phase_shift": w_phase, + "int1": w_int1, + "int2": w_int2, + "origin": w_ori, + "round_phase_width": w_round, + "period": w_period, + "add_mask": w_mask, + "target_indices": w_tidx, + "intensity_target": w_tint, + }, +) + +# Show +display(ui, out) +``` ## Square, linear {py:func}`stimupy.stimuli.waves.square_linear` @@ -122,13 +211,665 @@ out = iw.interactive_output( display(ui, out) ``` +## Staircase, linear +{py:func}`stimupy.stimuli.waves.staircase_linear` + +```{code-cell} ipython3 +from stimupy.stimuli.waves import staircase_linear + +# Define widgets +w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_freq = iw.FloatSlider(value=1, min=0, max=2, description="frequency [cpd]") +w_phase = iw.FloatSlider(value=0, min=0, max=360, description="phase shift [deg]") +w_rot = iw.FloatSlider(value=0, min=0, max=360, description="rotation [deg]") + +w_int1 = iw.FloatSlider(value=1, min=0, max=1, description="int1") +w_int2 = iw.FloatSlider(value=0, min=0, max=1, description="int2") + +w_ori = iw.Dropdown(value="corner", options=['mean', 'corner', 'center'], description="origin") +w_period = iw.Dropdown(value="ignore", options=['ignore', 'even', 'odd', 'either'], description="period") +w_round = iw.ToggleButton(value=False, disabled=False, description="round phase") +w_mask = iw.Dropdown(value=None, options=[None, 'target_mask', 'grating_mask'], description="add mask") + +w_tidx = iw.IntSlider(value=1, min=1, max=10, description="target idx") +w_tint = iw.FloatSlider(value=0.5, min=0, max=1, description="target int") + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_geometry = iw.HBox([w_freq, w_phase, w_rot]) +b_intensities = iw.HBox([w_int1, w_int2]) +b_target = iw.HBox([w_tidx, w_tint]) +b_add = iw.HBox([w_ori, w_period, w_round, w_mask]) +ui = iw.VBox([b_im_size, b_geometry, b_intensities, b_target, b_add]) + +# Function for showing stim +def show_staircase_linear( + height=None, + width=None, + ppd=None, + rotation=None, + frequency=None, + phase_shift=None, + int1=None, + int2=None, + origin=None, + round_phase_width=False, + period=None, + add_mask=False, + target_indices=None, + intensity_target=None, +): + stim = staircase_linear( + visual_size=(height, width), + ppd=ppd, + rotation=rotation, + frequency=frequency, + phase_shift=phase_shift, + intensity_bars=(int1, int2), + origin=origin, + round_phase_width=round_phase_width, + period=period, + target_indices=target_indices, + intensity_target=intensity_target, + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_staircase_linear, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "rotation": w_rot, + "frequency": w_freq, + "phase_shift": w_phase, + "int1": w_int1, + "int2": w_int2, + "origin": w_ori, + "round_phase_width": w_round, + "period": w_period, + "add_mask": w_mask, + "target_indices": w_tidx, + "intensity_target": w_tint, + }, +) + +# Show +display(ui, out) +``` + ## Sine, radial +{py:func}`stimupy.stimuli.waves.sine_radial` + +```{code-cell} ipython3 +from stimupy.stimuli.waves import sine_radial + +# Define widgets +w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_freq = iw.FloatSlider(value=1, min=0, max=2, description="frequency [cpd]") +w_phase = iw.FloatSlider(value=0, min=0, max=360, description="phase shift [deg]") +w_rot = iw.FloatSlider(value=0, min=0, max=360, description="rotation [deg]") + +w_int1 = iw.FloatSlider(value=1, min=0, max=1, description="int1") +w_int2 = iw.FloatSlider(value=0, min=0, max=1, description="int2") + +w_ori = iw.Dropdown(value="mean", options=['mean', 'corner', 'center'], description="origin") +w_period = iw.Dropdown(value="ignore", options=['ignore', 'even', 'odd', 'either'], description="period") +w_round = iw.ToggleButton(value=False, disabled=False, description="round phase") +w_clip = iw.ToggleButton(value=True, disabled=False, description="clip to aperature") +w_mask = iw.Dropdown(value=None, options=[None, 'target_mask', 'grating_mask'], description="add mask") + +w_tidx = iw.IntSlider(value=1, min=1, max=10, description="target idx") +w_tint = iw.FloatSlider(value=0.5, min=0, max=1, description="target int") + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_geometry = iw.HBox([w_freq, w_phase, w_rot]) +b_intensities = iw.HBox([w_int1, w_int2]) +b_target = iw.HBox([w_tidx, w_tint]) +b_add = iw.HBox([w_ori, w_period, w_round, w_clip, w_mask]) +ui = iw.VBox([b_im_size, b_geometry, b_intensities, b_target, b_add]) + +# Function for showing stim +def show_sine_radial( + height=None, + width=None, + ppd=None, + rotation=None, + frequency=None, + phase_shift=None, + int1=None, + int2=None, + origin=None, + round_phase_width=False, + period=None, + add_mask=False, + target_indices=None, + intensity_target=None, + clip=True, +): + stim = sine_radial( + visual_size=(height, width), + ppd=ppd, + rotation=rotation, + frequency=frequency, + phase_shift=phase_shift, + intensities=(int1, int2), + origin=origin, + round_phase_width=round_phase_width, + period=period, + target_indices=target_indices, + intensity_target=intensity_target, + clip=clip, + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_sine_radial, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "rotation": w_rot, + "frequency": w_freq, + "phase_shift": w_phase, + "int1": w_int1, + "int2": w_int2, + "origin": w_ori, + "round_phase_width": w_round, + "period": w_period, + "add_mask": w_mask, + "target_indices": w_tidx, + "intensity_target": w_tint, + }, +) + +# Show +display(ui, out) +``` ## Square, radial +{py:func}`stimupy.stimuli.waves.square_radial` -## Sine, rectilinear +```{code-cell} ipython3 +from stimupy.stimuli.waves import square_radial -## Square, rectilinear +# Define widgets +w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_freq = iw.FloatSlider(value=1, min=0, max=2, description="frequency [cpd]") +w_phase = iw.FloatSlider(value=0, min=0, max=360, description="phase shift [deg]") +w_rot = iw.FloatSlider(value=0, min=0, max=360, description="rotation [deg]") + +w_int1 = iw.FloatSlider(value=1, min=0, max=1, description="int1") +w_int2 = iw.FloatSlider(value=0, min=0, max=1, description="int2") + +w_ori = iw.Dropdown(value="mean", options=['mean', 'corner', 'center'], description="origin") +w_period = iw.Dropdown(value="ignore", options=['ignore', 'even', 'odd', 'either'], description="period") +w_round = iw.ToggleButton(value=False, disabled=False, description="round phase") +w_clip = iw.ToggleButton(value=True, disabled=False, description="clip to aperature") +w_mask = iw.Dropdown(value=None, options=[None, 'target_mask', 'grating_mask'], description="add mask") + +w_tidx = iw.IntSlider(value=1, min=1, max=10, description="target idx") +w_tint = iw.FloatSlider(value=0.5, min=0, max=1, description="target int") + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_geometry = iw.HBox([w_freq, w_phase, w_rot]) +b_intensities = iw.HBox([w_int1, w_int2]) +b_target = iw.HBox([w_tidx, w_tint]) +b_add = iw.HBox([w_ori, w_period, w_round, w_clip, w_mask]) +ui = iw.VBox([b_im_size, b_geometry, b_intensities, b_target, b_add]) + +# Function for showing stim +def show_square_radial( + height=None, + width=None, + ppd=None, + rotation=None, + frequency=None, + phase_shift=None, + int1=None, + int2=None, + origin=None, + round_phase_width=False, + period=None, + add_mask=False, + target_indices=None, + intensity_target=None, + clip=True, +): + stim = square_radial( + visual_size=(height, width), + ppd=ppd, + rotation=rotation, + frequency=frequency, + phase_shift=phase_shift, + intensity_rings=(int1, int2), + origin=origin, + round_phase_width=round_phase_width, + period=period, + target_indices=target_indices, + intensity_target=intensity_target, + clip=clip, + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_square_radial, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "rotation": w_rot, + "frequency": w_freq, + "phase_shift": w_phase, + "int1": w_int1, + "int2": w_int2, + "origin": w_ori, + "round_phase_width": w_round, + "period": w_period, + "add_mask": w_mask, + "target_indices": w_tidx, + "intensity_target": w_tint, + "clip": w_clip, + }, +) + +# Show +display(ui, out) +``` + +## Staircase, radial +{py:func}`stimupy.stimuli.waves.staircase_radial` + +```{code-cell} ipython3 +from stimupy.stimuli.waves import staircase_radial + +# Define widgets +w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_freq = iw.FloatSlider(value=1, min=0, max=2, description="frequency [cpd]") +w_phase = iw.FloatSlider(value=0, min=0, max=360, description="phase shift [deg]") +w_rot = iw.FloatSlider(value=0, min=0, max=360, description="rotation [deg]") + +w_int1 = iw.FloatSlider(value=1, min=0, max=1, description="int1") +w_int2 = iw.FloatSlider(value=0, min=0, max=1, description="int2") + +w_ori = iw.Dropdown(value="mean", options=['mean', 'corner', 'center'], description="origin") +w_period = iw.Dropdown(value="ignore", options=['ignore', 'even', 'odd', 'either'], description="period") +w_round = iw.ToggleButton(value=False, disabled=False, description="round phase") +w_clip = iw.ToggleButton(value=True, disabled=False, description="clip to aperature") +w_mask = iw.Dropdown(value=None, options=[None, 'target_mask', 'grating_mask'], description="add mask") + +w_tidx = iw.IntSlider(value=1, min=1, max=10, description="target idx") +w_tint = iw.FloatSlider(value=0.5, min=0, max=1, description="target int") + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_geometry = iw.HBox([w_freq, w_phase, w_rot]) +b_intensities = iw.HBox([w_int1, w_int2]) +b_target = iw.HBox([w_tidx, w_tint]) +b_add = iw.HBox([w_ori, w_period, w_round, w_clip, w_mask]) +ui = iw.VBox([b_im_size, b_geometry, b_intensities, b_target, b_add]) + +# Function for showing stim +def show_staircase_radial( + height=None, + width=None, + ppd=None, + rotation=None, + frequency=None, + phase_shift=None, + int1=None, + int2=None, + origin=None, + round_phase_width=False, + period=None, + add_mask=False, + target_indices=None, + intensity_target=None, +# clip=True, +): + stim = staircase_radial( + visual_size=(height, width), + ppd=ppd, + rotation=rotation, + frequency=frequency, + phase_shift=phase_shift, + intensity_rings=(int1, int2), + origin=origin, + round_phase_width=round_phase_width, + period=period, + target_indices=target_indices, + intensity_target=intensity_target, +# clip=clip, + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_staircase_radial, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "rotation": w_rot, + "frequency": w_freq, + "phase_shift": w_phase, + "int1": w_int1, + "int2": w_int2, + "origin": w_ori, + "round_phase_width": w_round, + "period": w_period, + "add_mask": w_mask, + "target_indices": w_tidx, + "intensity_target": w_tint, +# "clip": w_clip, + }, +) + +# Show +display(ui, out) +``` + +## Sine, rectilinear +{py:func}`stimupy.stimuli.waves.sine_rectilinear` + +```{code-cell} ipython3 +from stimupy.stimuli.waves import sine_rectilinear + +# Define widgets +w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_freq = iw.FloatSlider(value=1, min=0, max=2, description="frequency [cpd]") +w_phase = iw.FloatSlider(value=0, min=0, max=360, description="phase shift [deg]") +w_rot = iw.FloatSlider(value=0, min=0, max=360, description="rotation [deg]") + +w_int1 = iw.FloatSlider(value=1, min=0, max=1, description="int1") +w_int2 = iw.FloatSlider(value=0, min=0, max=1, description="int2") + +w_ori = iw.Dropdown(value="mean", options=['mean', 'corner', 'center'], description="origin") +w_period = iw.Dropdown(value="ignore", options=['ignore', 'even', 'odd', 'either'], description="period") +w_round = iw.ToggleButton(value=False, disabled=False, description="round phase") +w_clip = iw.ToggleButton(value=True, disabled=False, description="clip to aperature") +w_mask = iw.Dropdown(value=None, options=[None, 'target_mask', 'grating_mask'], description="add mask") + +w_tidx = iw.IntSlider(value=1, min=1, max=10, description="target idx") +w_tint = iw.FloatSlider(value=0.5, min=0, max=1, description="target int") + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_geometry = iw.HBox([w_freq, w_phase, w_rot]) +b_intensities = iw.HBox([w_int1, w_int2]) +b_target = iw.HBox([w_tidx, w_tint]) +b_add = iw.HBox([w_ori, w_period, w_round, w_clip, w_mask]) +ui = iw.VBox([b_im_size, b_geometry, b_intensities, b_target, b_add]) + +# Function for showing stim +def show_sine_rectilinear( + height=None, + width=None, + ppd=None, + rotation=None, + frequency=None, + phase_shift=None, + int1=None, + int2=None, + origin=None, + round_phase_width=False, + period=None, + add_mask=False, + target_indices=None, + intensity_target=None, + clip=True, +): + stim = sine_rectilinear( + visual_size=(height, width), + ppd=ppd, + rotation=rotation, + frequency=frequency, + phase_shift=phase_shift, + intensities=(int1, int2), + origin=origin, + round_phase_width=round_phase_width, + period=period, + target_indices=target_indices, + intensity_target=intensity_target, + clip=clip, + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_sine_rectilinear, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "rotation": w_rot, + "frequency": w_freq, + "phase_shift": w_phase, + "int1": w_int1, + "int2": w_int2, + "origin": w_ori, + "round_phase_width": w_round, + "period": w_period, + "add_mask": w_mask, + "target_indices": w_tidx, + "intensity_target": w_tint, + "clip": w_clip, + }, +) + +# Show +display(ui, out) +``` + +## Square, rectilinear +{py:func}`stimupy.stimuli.waves.square_rectilinear` + +```{code-cell} ipython3 +from stimupy.stimuli.waves import square_rectilinear + +# Define widgets +w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_freq = iw.FloatSlider(value=1, min=0, max=2, description="frequency [cpd]") +w_phase = iw.FloatSlider(value=0, min=0, max=360, description="phase shift [deg]") +w_rot = iw.FloatSlider(value=0, min=0, max=360, description="rotation [deg]") + +w_int1 = iw.FloatSlider(value=1, min=0, max=1, description="int1") +w_int2 = iw.FloatSlider(value=0, min=0, max=1, description="int2") + +w_ori = iw.Dropdown(value="mean", options=['mean', 'corner', 'center'], description="origin") +w_period = iw.Dropdown(value="ignore", options=['ignore', 'even', 'odd', 'either'], description="period") +w_round = iw.ToggleButton(value=False, disabled=False, description="round phase") +w_clip = iw.ToggleButton(value=True, disabled=False, description="clip to aperature") +w_mask = iw.Dropdown(value=None, options=[None, 'target_mask', 'grating_mask'], description="add mask") + +w_tidx = iw.IntSlider(value=1, min=1, max=10, description="target idx") +w_tint = iw.FloatSlider(value=0.5, min=0, max=1, description="target int") + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_geometry = iw.HBox([w_freq, w_phase, w_rot]) +b_intensities = iw.HBox([w_int1, w_int2]) +b_target = iw.HBox([w_tidx, w_tint]) +b_add = iw.HBox([w_ori, w_period, w_round, w_clip, w_mask]) +ui = iw.VBox([b_im_size, b_geometry, b_intensities, b_target, b_add]) + +# Function for showing stim +def show_square_rectilinear( + height=None, + width=None, + ppd=None, + rotation=None, + frequency=None, + phase_shift=None, + int1=None, + int2=None, + origin=None, + round_phase_width=False, + period=None, + add_mask=False, + target_indices=None, + intensity_target=None, + clip=True, +): + stim = square_rectilinear( + visual_size=(height, width), + ppd=ppd, + rotation=rotation, + frequency=frequency, + phase_shift=phase_shift, + intensity_frames=(int1, int2), + origin=origin, + round_phase_width=round_phase_width, + period=period, + target_indices=target_indices, + intensity_target=intensity_target, + clip=clip, + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_square_rectilinear, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "rotation": w_rot, + "frequency": w_freq, + "phase_shift": w_phase, + "int1": w_int1, + "int2": w_int2, + "origin": w_ori, + "round_phase_width": w_round, + "period": w_period, + "add_mask": w_mask, + "target_indices": w_tidx, + "intensity_target": w_tint, + "clip": w_clip, + }, +) + +# Show +display(ui, out) +``` + +## Staircase, rectilinear +{py:func}`stimupy.stimuli.waves.staircase_rectilinear` + +```{code-cell} ipython3 +from stimupy.stimuli.waves import staircase_rectilinear + +# Define widgets +w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_freq = iw.FloatSlider(value=1, min=0, max=2, description="frequency [cpd]") +w_phase = iw.FloatSlider(value=0, min=0, max=360, description="phase shift [deg]") +w_rot = iw.FloatSlider(value=0, min=0, max=360, description="rotation [deg]") + +w_int1 = iw.FloatSlider(value=1, min=0, max=1, description="int1") +w_int2 = iw.FloatSlider(value=0, min=0, max=1, description="int2") + +w_ori = iw.Dropdown(value="mean", options=['mean', 'corner', 'center'], description="origin") +w_period = iw.Dropdown(value="ignore", options=['ignore', 'even', 'odd', 'either'], description="period") +w_round = iw.ToggleButton(value=False, disabled=False, description="round phase") +w_clip = iw.ToggleButton(value=True, disabled=False, description="clip to aperature") +w_mask = iw.Dropdown(value=None, options=[None, 'target_mask', 'grating_mask'], description="add mask") + +w_tidx = iw.IntSlider(value=1, min=1, max=10, description="target idx") +w_tint = iw.FloatSlider(value=0.5, min=0, max=1, description="target int") + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_geometry = iw.HBox([w_freq, w_phase, w_rot]) +b_intensities = iw.HBox([w_int1, w_int2]) +b_target = iw.HBox([w_tidx, w_tint]) +b_add = iw.HBox([w_ori, w_period, w_round, w_clip, w_mask]) +ui = iw.VBox([b_im_size, b_geometry, b_intensities, b_target, b_add]) + +# Function for showing stim +def show_staircase_rectilinear( + height=None, + width=None, + ppd=None, + rotation=None, + frequency=None, + phase_shift=None, + int1=None, + int2=None, + origin=None, + round_phase_width=False, + period=None, + add_mask=False, + target_indices=None, + intensity_target=None, + clip=True, +): + stim = staircase_rectilinear( + visual_size=(height, width), + ppd=ppd, + rotation=rotation, + frequency=frequency, + phase_shift=phase_shift, + intensity_frames=(int1, int2), + origin=origin, + round_phase_width=round_phase_width, + period=period, + target_indices=target_indices, + intensity_target=intensity_target, +# clip=clip, + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_staircase_rectilinear, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "rotation": w_rot, + "frequency": w_freq, + "phase_shift": w_phase, + "int1": w_int1, + "int2": w_int2, + "origin": w_ori, + "round_phase_width": w_round, + "period": w_period, + "add_mask": w_mask, + "target_indices": w_tidx, + "intensity_target": w_tint, +# "clip": w_clip, + }, +) + +# Show +display(ui, out) +``` ## Sine, angular From 826e851027e001cae7da6c34c08f513afa191030 Mon Sep 17 00:00:00 2001 From: Joris Vincent Date: Thu, 23 Mar 2023 18:23:45 +0100 Subject: [PATCH 03/10] Demos: `stimupy.waves.angular` --- docs/reference/demos/stimuli/waves.md | 271 +++++++++++++++++++++++++- 1 file changed, 270 insertions(+), 1 deletion(-) diff --git a/docs/reference/demos/stimuli/waves.md b/docs/reference/demos/stimuli/waves.md index ccdf5cd..d63826b 100644 --- a/docs/reference/demos/stimuli/waves.md +++ b/docs/reference/demos/stimuli/waves.md @@ -872,5 +872,274 @@ display(ui, out) ``` ## Sine, angular +{py:func}`stimupy.stimuli.waves.sine_angular` -## Square, angular \ No newline at end of file +```{code-cell} ipython3 +from stimupy.stimuli.waves import sine_angular + +# Define widgets +w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_freq = iw.FloatSlider(value=1, min=0, max=10, description="frequency [cycles per circle]") +w_phase = iw.FloatSlider(value=0, min=0, max=360, description="phase shift [deg]") +w_rot = iw.FloatSlider(value=0, min=0, max=360, description="rotation [deg]") + +w_int1 = iw.FloatSlider(value=1, min=0, max=1, description="int1") +w_int2 = iw.FloatSlider(value=0, min=0, max=1, description="int2") + +w_ori = iw.Dropdown(value="mean", options=['mean', 'corner', 'center'], description="origin") +w_period = iw.Dropdown(value="ignore", options=['ignore', 'even', 'odd', 'either'], description="period") +w_round = iw.ToggleButton(value=False, disabled=False, description="round phase") +w_mask = iw.Dropdown(value=None, options=[None, 'target_mask', 'grating_mask'], description="add mask") + +w_tidx = iw.IntSlider(value=1, min=1, max=10, description="target idx") +w_tint = iw.FloatSlider(value=0.5, min=0, max=1, description="target int") + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_geometry = iw.HBox([w_freq, w_phase, w_rot]) +b_intensities = iw.HBox([w_int1, w_int2]) +b_target = iw.HBox([w_tidx, w_tint]) +b_add = iw.HBox([w_ori, w_period, w_round, w_mask]) +ui = iw.VBox([b_im_size, b_geometry, b_intensities, b_target, b_add]) + +# Function for showing stim +def show_sine_angular( + height=None, + width=None, + ppd=None, + rotation=None, + frequency=None, + phase_shift=None, + int1=None, + int2=None, + origin=None, + round_phase_width=False, + period=None, + add_mask=False, + target_indices=None, + intensity_target=None, +): + stim = sine_angular( + visual_size=(height, width), + ppd=ppd, + rotation=rotation, + frequency=frequency, + phase_shift=phase_shift, + intensities=(int1, int2), + origin=origin, + round_phase_width=round_phase_width, + period=period, + target_indices=target_indices, + intensity_target=intensity_target, + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_sine_angular, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "rotation": w_rot, + "frequency": w_freq, + "phase_shift": w_phase, + "int1": w_int1, + "int2": w_int2, + "origin": w_ori, + "round_phase_width": w_round, + "period": w_period, + "add_mask": w_mask, + "target_indices": w_tidx, + "intensity_target": w_tint, + }, +) + +# Show +display(ui, out) +``` + +## Square, angular +{py:func}`stimupy.stimuli.waves.square_angular` + +```{code-cell} ipython3 +from stimupy.stimuli.waves import square_angular + +# Define widgets +w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_freq = iw.FloatSlider(value=1, min=0, max=10, description="frequency [cycles per circle]") +w_phase = iw.FloatSlider(value=0, min=0, max=360, description="phase shift [deg]") +w_rot = iw.FloatSlider(value=0, min=0, max=360, description="rotation [deg]") + +w_int1 = iw.FloatSlider(value=1, min=0, max=1, description="int1") +w_int2 = iw.FloatSlider(value=0, min=0, max=1, description="int2") + +w_ori = iw.Dropdown(value="mean", options=['mean', 'corner', 'center'], description="origin") +w_period = iw.Dropdown(value="ignore", options=['ignore', 'even', 'odd', 'either'], description="period") +w_round = iw.ToggleButton(value=False, disabled=False, description="round phase") +w_mask = iw.Dropdown(value=None, options=[None, 'target_mask', 'grating_mask'], description="add mask") + +w_tidx = iw.IntSlider(value=1, min=1, max=10, description="target idx") +w_tint = iw.FloatSlider(value=0.5, min=0, max=1, description="target int") + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_geometry = iw.HBox([w_freq, w_phase, w_rot]) +b_intensities = iw.HBox([w_int1, w_int2]) +b_target = iw.HBox([w_tidx, w_tint]) +b_add = iw.HBox([w_ori, w_period, w_round, w_mask]) +ui = iw.VBox([b_im_size, b_geometry, b_intensities, b_target, b_add]) + +# Function for showing stim +def show_square_angular( + height=None, + width=None, + ppd=None, + rotation=None, + frequency=None, + phase_shift=None, + int1=None, + int2=None, + origin=None, + round_phase_width=False, + period=None, + add_mask=False, + target_indices=None, + intensity_target=None, +): + stim = square_angular( + visual_size=(height, width), + ppd=ppd, + rotation=rotation, + frequency=frequency, + phase_shift=phase_shift, + intensity_segments=(int1, int2), + origin=origin, + round_phase_width=round_phase_width, + period=period, + target_indices=target_indices, + intensity_target=intensity_target, + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_square_angular, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "rotation": w_rot, + "frequency": w_freq, + "phase_shift": w_phase, + "int1": w_int1, + "int2": w_int2, + "origin": w_ori, + "round_phase_width": w_round, + "period": w_period, + "add_mask": w_mask, + "target_indices": w_tidx, + "intensity_target": w_tint, + }, +) + +# Show +display(ui, out) +``` + +## Staircase, angular +{py:func}`stimupy.stimuli.waves.staircase_angular` + +```{code-cell} ipython3 +from stimupy.stimuli.waves import staircase_angular + +# Define widgets +w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_freq = iw.FloatSlider(value=1, min=0, max=10, description="frequency [cycles per circle]") +w_phase = iw.FloatSlider(value=0, min=0, max=360, description="phase shift [deg]") +w_rot = iw.FloatSlider(value=0, min=0, max=360, description="rotation [deg]") + +w_int1 = iw.FloatSlider(value=1, min=0, max=1, description="int1") +w_int2 = iw.FloatSlider(value=0, min=0, max=1, description="int2") + +w_ori = iw.Dropdown(value="mean", options=['mean', 'corner', 'center'], description="origin") +w_period = iw.Dropdown(value="ignore", options=['ignore', 'even', 'odd', 'either'], description="period") +w_round = iw.ToggleButton(value=False, disabled=False, description="round phase") +w_mask = iw.Dropdown(value=None, options=[None, 'target_mask', 'grating_mask'], description="add mask") + +w_tidx = iw.IntSlider(value=1, min=1, max=10, description="target idx") +w_tint = iw.FloatSlider(value=0.5, min=0, max=1, description="target int") + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_geometry = iw.HBox([w_freq, w_phase, w_rot]) +b_intensities = iw.HBox([w_int1, w_int2]) +b_target = iw.HBox([w_tidx, w_tint]) +b_add = iw.HBox([w_ori, w_period, w_round, w_mask]) +ui = iw.VBox([b_im_size, b_geometry, b_intensities, b_target, b_add]) + +# Function for showing stim +def show_staircase_angular( + height=None, + width=None, + ppd=None, + rotation=None, + frequency=None, + phase_shift=None, + int1=None, + int2=None, + origin=None, + round_phase_width=False, + period=None, + add_mask=False, + target_indices=None, + intensity_target=None, +): + stim = staircase_angular( + visual_size=(height, width), + ppd=ppd, + rotation=rotation, + frequency=frequency, + phase_shift=phase_shift, + intensity_segments=(int1, int2), + origin=origin, + round_phase_width=round_phase_width, + period=period, + target_indices=target_indices, + intensity_target=intensity_target, + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_staircase_angular, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "rotation": w_rot, + "frequency": w_freq, + "phase_shift": w_phase, + "int1": w_int1, + "int2": w_int2, + "origin": w_ori, + "round_phase_width": w_round, + "period": w_period, + "add_mask": w_mask, + "target_indices": w_tidx, + "intensity_target": w_tint, + }, +) + +# Show +display(ui, out) +``` \ No newline at end of file From 64925d4c6397aa304895cd19e103907602f42250 Mon Sep 17 00:00:00 2001 From: lynnschmittwilken Date: Thu, 23 Mar 2023 13:36:27 -0400 Subject: [PATCH 04/10] added todorovics-demos --- docs/reference/demos/stimuli/todorovics.md | 741 +++++++++++++++++++++ 1 file changed, 741 insertions(+) create mode 100644 docs/reference/demos/stimuli/todorovics.md diff --git a/docs/reference/demos/stimuli/todorovics.md b/docs/reference/demos/stimuli/todorovics.md new file mode 100644 index 0000000..2227421 --- /dev/null +++ b/docs/reference/demos/stimuli/todorovics.md @@ -0,0 +1,741 @@ +--- +jupytext: + formats: md:myst + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.14.5 +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +```{important} +[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/computational-psychology/stimupy/HEAD?urlpath=lab/tree/docs/reference/demos/stimuli/todorovics.md) + to get interactivity +``` + +# Stimuli - Todorovics +{py:mod}`stimupy.stimuli.todorovics` + +```{code-cell} ipython3 +:tags: [remove-cell] + +import IPython +import ipywidgets as iw +from stimupy.utils import plot_stim +``` + +## Rectangle generalized +{py:func}`stimupy.stimuli.todorovics.rectangle_generalized` + +```{code-cell} ipython3 +from stimupy.stimuli.todorovics import rectangle_generalized + +# Define widgets +w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_theight = iw.FloatSlider(value=2, min=0, max=4, description="target height [deg]") +w_twidth = iw.FloatSlider(value=2, min=0, max=4, description="target width [deg]") +w_tint = iw.FloatSlider(value=0.5, min=0, max=1, description="target int") + +w_tx = iw.FloatSlider(value=4, min=0, max=8, description="target x [deg]") +w_ty = iw.FloatSlider(value=4, min=0, max=8, description="target y [deg]") + +w_cheight = iw.FloatSlider(value=2, min=0, max=4, description="cover height [deg]") +w_cwidth = iw.FloatSlider(value=2, min=0, max=4, description="cover width [deg]") +w_cint = iw.FloatSlider(value=1, min=0, max=1, description="cover int") + +w_c1x = iw.FloatSlider(value=2, min=0, max=8, description="cover1 x [deg]") +w_c1y = iw.FloatSlider(value=2, min=0, max=8, description="cover1 y [deg]") + +w_c2x = iw.FloatSlider(value=6, min=0, max=8, description="cover2 x [deg]") +w_c2y = iw.FloatSlider(value=6, min=0, max=8, description="cover2 y [deg]") + +w_int_back = iw.FloatSlider(value=0., min=0, max=1, description="int background") +w_mask = iw.Dropdown(value=None, options=[None, 'target_mask'], description="add mask") + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_tsize = iw.HBox([w_theight, w_twidth, w_tint]) +b_tpos = iw.HBox([w_tx, w_ty]) +b_csize = iw.HBox([w_cheight, w_cwidth, w_cint]) +b_c1pos = iw.HBox([w_c1x, w_c1y]) +b_c2pos = iw.HBox([w_c2x, w_c2y]) +b_intensities = iw.HBox([w_int_back]) +b_add = iw.HBox([w_mask]) +ui = iw.VBox([b_im_size, b_tsize, b_tpos, b_csize, b_c1pos, b_c2pos, b_intensities, b_add]) + +# Function for showing stim +def show_rectangle_generalized( + height=None, + width=None, + ppd=None, + theight=None, + twidth=None, + tint=None, + tx=None, + ty=None, + cheight=None, + cwidth=None, + cint=None, + c1x=None, + c1y=None, + c2x=None, + c2y=None, + intback=None, + add_mask=False, +): + stim = rectangle_generalized( + visual_size=(height, width), + ppd=ppd, + target_size=(theight, twidth), + target_position=(ty, tx), + covers_size=(cheight, cwidth), + covers_x=(c1x, c2x), + covers_y=(c1y, c2y), + intensity_background=intback, + intensity_target=tint, + intensity_covers=cint, + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_rectangle_generalized, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "theight": w_theight, + "twidth": w_twidth, + "tint": w_tint, + "tx": w_tx, + "ty": w_ty, + "cheight": w_cheight, + "cwidth": w_cwidth, + "cint": w_cint, + "c1x": w_c1x, + "c2x": w_c2x, + "c1y": w_c1y, + "c2y": w_c2y, + "intback": w_int_back, + "add_mask": w_mask, + }, +) + +# Show +display(ui, out) +``` + +## Rectangle +{py:func}`stimupy.stimuli.todorovics.rectangle` + +```{code-cell} ipython3 +from stimupy.stimuli.todorovics import rectangle + +# Define widgets +w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_theight = iw.FloatSlider(value=2, min=0, max=4, description="target height [deg]") +w_twidth = iw.FloatSlider(value=2, min=0, max=4, description="target width [deg]") +w_tint = iw.FloatSlider(value=0.5, min=0, max=1, description="target int") + +w_tx = iw.FloatSlider(value=4, min=0, max=8, description="target x [deg]") +w_ty = iw.FloatSlider(value=4, min=0, max=8, description="target y [deg]") + +w_cheight = iw.FloatSlider(value=2, min=0, max=4, description="cover height [deg]") +w_cwidth = iw.FloatSlider(value=2, min=0, max=4, description="cover width [deg]") +w_cint = iw.FloatSlider(value=1, min=0, max=1, description="cover int") + +w_coffx = iw.FloatSlider(value=2, min=0, max=8, description="cover offset x [deg]") +w_coffy = iw.FloatSlider(value=2, min=0, max=8, description="cover offset y [deg]") + +w_int_back = iw.FloatSlider(value=0., min=0, max=1, description="int background") +w_mask = iw.Dropdown(value=None, options=[None, 'target_mask'], description="add mask") + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_tsize = iw.HBox([w_theight, w_twidth, w_tint]) +b_tpos = iw.HBox([w_tx, w_ty]) +b_csize = iw.HBox([w_cheight, w_cwidth, w_cint]) +b_c1pos = iw.HBox([w_coffx, w_coffy]) +b_intensities = iw.HBox([w_int_back]) +b_add = iw.HBox([w_mask]) +ui = iw.VBox([b_im_size, b_tsize, b_tpos, b_csize, b_c1pos, b_intensities, b_add]) + +# Function for showing stim +def show_rectangle( + height=None, + width=None, + ppd=None, + theight=None, + twidth=None, + tint=None, + tx=None, + ty=None, + cheight=None, + cwidth=None, + cint=None, + coffx=None, + coffy=None, + intback=None, + add_mask=False, +): + stim = rectangle( + visual_size=(height, width), + ppd=ppd, + target_size=(theight, twidth), + target_position=(ty, tx), + covers_size=(cheight, cwidth), + covers_offset=(coffy, coffx), + intensity_background=intback, + intensity_target=tint, + intensity_covers=cint, + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_rectangle, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "theight": w_theight, + "twidth": w_twidth, + "tint": w_tint, + "tx": w_tx, + "ty": w_ty, + "cheight": w_cheight, + "cwidth": w_cwidth, + "cint": w_cint, + "coffx": w_coffx, + "coffy": w_coffy, + "intback": w_int_back, + "add_mask": w_mask, + }, +) + +# Show +display(ui, out) +``` + +## Rectangle, two-sided +{py:func}`stimupy.stimuli.todorovics.two_sided_rectangle` + +```{code-cell} ipython3 +from stimupy.stimuli.todorovics import two_sided_rectangle + +# Define widgets +w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=20, min=1, max=40, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_theight = iw.FloatSlider(value=2, min=0, max=4, description="target height [deg]") +w_twidth = iw.FloatSlider(value=2, min=0, max=4, description="target width [deg]") +w_tint = iw.FloatSlider(value=0.5, min=0, max=1, description="target int") + +w_cheight = iw.FloatSlider(value=2, min=0, max=4, description="cover height [deg]") +w_cwidth = iw.FloatSlider(value=2, min=0, max=4, description="cover width [deg]") +w_cint1 = iw.FloatSlider(value=1, min=0, max=1, description="cover1 int") +w_cint2 = iw.FloatSlider(value=0, min=0, max=1, description="cover2 int") + +w_coffx = iw.FloatSlider(value=2, min=0, max=8, description="cover offset x [deg]") +w_coffy = iw.FloatSlider(value=2, min=0, max=8, description="cover offset y [deg]") + +w_int_back1 = iw.FloatSlider(value=0., min=0, max=1, description="int back1") +w_int_back2 = iw.FloatSlider(value=1., min=0, max=1, description="int back2") +w_mask = iw.Dropdown(value=None, options=[None, 'target_mask'], description="add mask") + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_tsize = iw.HBox([w_theight, w_twidth, w_tint]) +b_csize = iw.HBox([w_cheight, w_cwidth, w_cint1, w_cint2]) +b_c1pos = iw.HBox([w_coffx, w_coffy]) +b_intensities = iw.HBox([w_int_back]) +b_add = iw.HBox([w_mask]) +ui = iw.VBox([b_im_size, b_tsize, b_csize, b_c1pos, b_intensities, b_add]) + +# Function for showing stim +def show_two_sided_rectangle( + height=None, + width=None, + ppd=None, + theight=None, + twidth=None, + tint=None, + cheight=None, + cwidth=None, + cint1=None, + cint2=None, + coffx=None, + coffy=None, + intback1=None, + intback2=None, + add_mask=False, +): + stim = two_sided_rectangle( + visual_size=(height, width), + ppd=ppd, + target_size=(theight, twidth), + covers_size=(cheight, cwidth), + covers_offset=(coffy, coffx), + intensity_backgrounds=(intback1, intback2), + intensity_target=tint, + intensity_covers=(cint1, cint2), + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_two_sided_rectangle, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "theight": w_theight, + "twidth": w_twidth, + "tint": w_tint, + "cheight": w_cheight, + "cwidth": w_cwidth, + "cint1": w_cint1, + "cint2": w_cint2, + "coffx": w_coffx, + "coffy": w_coffy, + "intback1": w_int_back1, + "intback2": w_int_back2, + "add_mask": w_mask, + }, +) + +# Show +display(ui, out) +``` + +## Cross generalized +{py:func}`stimupy.stimuli.todorovics.cross_generalized` + +```{code-cell} ipython3 +from stimupy.stimuli.todorovics import cross_generalized + +# Define widgets +w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_theight = iw.FloatSlider(value=4, min=0, max=8, description="cross height [deg]") +w_twidth = iw.FloatSlider(value=4, min=0, max=8, description="cross width [deg]") +w_tthick = iw.FloatSlider(value=2, min=0, max=4, description="cross thickness [deg]") +w_tint = iw.FloatSlider(value=0.5, min=0, max=1, description="cross int") + +w_cheight = iw.FloatSlider(value=2, min=0, max=4, description="cover height [deg]") +w_cwidth = iw.FloatSlider(value=2, min=0, max=4, description="cover width [deg]") +w_cint = iw.FloatSlider(value=1, min=0, max=1, description="cover int") + +w_c1x = iw.FloatSlider(value=2, min=0, max=8, description="cover1 x [deg]") +w_c1y = iw.FloatSlider(value=2, min=0, max=8, description="cover1 y [deg]") + +w_c2x = iw.FloatSlider(value=6, min=0, max=8, description="cover2 x [deg]") +w_c2y = iw.FloatSlider(value=6, min=0, max=8, description="cover2 y [deg]") + +w_int_back = iw.FloatSlider(value=0., min=0, max=1, description="int background") +w_mask = iw.Dropdown(value=None, options=[None, 'target_mask'], description="add mask") + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_tsize = iw.HBox([w_theight, w_twidth, w_tthick, w_tint]) +b_csize = iw.HBox([w_cheight, w_cwidth, w_cint]) +b_c1pos = iw.HBox([w_c1x, w_c1y]) +b_c2pos = iw.HBox([w_c2x, w_c2y]) +b_intensities = iw.HBox([w_int_back]) +b_add = iw.HBox([w_mask]) +ui = iw.VBox([b_im_size, b_tsize, b_csize, b_c1pos, b_c2pos, b_intensities, b_add]) + +# Function for showing stim +def show_cross_generalized( + height=None, + width=None, + ppd=None, + theight=None, + twidth=None, + tint=None, + tthick=None, + cheight=None, + cwidth=None, + cint=None, + c1x=None, + c1y=None, + c2x=None, + c2y=None, + intback=None, + add_mask=False, +): + stim = cross_generalized( + visual_size=(height, width), + ppd=ppd, + cross_size=(theight, twidth), + cross_thickness=tthick, + covers_size=(cheight, cwidth), + covers_x=(c1x, c2x), + covers_y=(c1y, c2y), + intensity_background=intback, + intensity_target=tint, + intensity_covers=cint, + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_cross_generalized, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "theight": w_theight, + "twidth": w_twidth, + "tint": w_tint, + "tthick": w_tthick, + "cheight": w_cheight, + "cwidth": w_cwidth, + "cint": w_cint, + "c1x": w_c1x, + "c2x": w_c2x, + "c1y": w_c1y, + "c2y": w_c2y, + "intback": w_int_back, + "add_mask": w_mask, + }, +) + +# Show +display(ui, out) +``` + +## Cross +{py:func}`stimupy.stimuli.todorovics.cross` + +```{code-cell} ipython3 +from stimupy.stimuli.todorovics import cross + +# Define widgets +w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_theight = iw.FloatSlider(value=4, min=0, max=8, description="cross height [deg]") +w_twidth = iw.FloatSlider(value=4, min=0, max=8, description="cross width [deg]") +w_tthick = iw.FloatSlider(value=2, min=0, max=4, description="cross thickness [deg]") +w_tint = iw.FloatSlider(value=0.5, min=0, max=1, description="cross int") + +w_cheight = iw.FloatSlider(value=2, min=0, max=4, description="cover height [deg]") +w_cwidth = iw.FloatSlider(value=2, min=0, max=4, description="cover width [deg]") +w_cint = iw.FloatSlider(value=1, min=0, max=1, description="cover int") + +w_int_back = iw.FloatSlider(value=0., min=0, max=1, description="int background") +w_mask = iw.Dropdown(value=None, options=[None, 'target_mask'], description="add mask") + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_tsize = iw.HBox([w_theight, w_twidth, w_tthick, w_tint]) +b_csize = iw.HBox([w_cheight, w_cwidth, w_cint]) +b_intensities = iw.HBox([w_int_back]) +b_add = iw.HBox([w_mask]) +ui = iw.VBox([b_im_size, b_tsize, b_csize, b_intensities, b_add]) + +# Function for showing stim +def show_cross( + height=None, + width=None, + ppd=None, + theight=None, + twidth=None, + tint=None, + tthick=None, + cheight=None, + cwidth=None, + cint=None, + intback=None, + add_mask=False, +): + stim = cross( + visual_size=(height, width), + ppd=ppd, + cross_size=(theight, twidth), + cross_thickness=tthick, + covers_size=(cheight, cwidth), + intensity_background=intback, + intensity_target=tint, + intensity_covers=cint, + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_cross, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "theight": w_theight, + "twidth": w_twidth, + "tint": w_tint, + "tthick": w_tthick, + "cheight": w_cheight, + "cwidth": w_cwidth, + "cint": w_cint, + "intback": w_int_back, + "add_mask": w_mask, + }, +) + +# Show +display(ui, out) +``` + +## Cross, two-sided +{py:func}`stimupy.stimuli.todorovics.two_sided_cross` + +```{code-cell} ipython3 +from stimupy.stimuli.todorovics import two_sided_cross + +# Define widgets +w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=20, min=1, max=40, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_theight = iw.FloatSlider(value=4, min=0, max=8, description="cross height [deg]") +w_twidth = iw.FloatSlider(value=4, min=0, max=8, description="cross width [deg]") +w_tthick = iw.FloatSlider(value=2, min=0, max=4, description="cross thickness [deg]") +w_tint = iw.FloatSlider(value=0.5, min=0, max=1, description="cross int") + +w_cheight = iw.FloatSlider(value=2, min=0, max=4, description="cover height [deg]") +w_cwidth = iw.FloatSlider(value=2, min=0, max=4, description="cover width [deg]") +w_cint1 = iw.FloatSlider(value=1, min=0, max=1, description="cover int1") +w_cint2 = iw.FloatSlider(value=0, min=0, max=1, description="cover int2") + +w_int_back1 = iw.FloatSlider(value=0., min=0, max=1, description="int back1") +w_int_back2 = iw.FloatSlider(value=1., min=0, max=1, description="int back12") +w_mask = iw.Dropdown(value=None, options=[None, 'target_mask'], description="add mask") + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_tsize = iw.HBox([w_theight, w_twidth, w_tthick, w_tint]) +b_csize = iw.HBox([w_cheight, w_cwidth, w_cint1, w_cint2]) +b_intensities = iw.HBox([w_int_back1, w_int_back2]) +b_add = iw.HBox([w_mask]) +ui = iw.VBox([b_im_size, b_tsize, b_csize, b_intensities, b_add]) + +# Function for showing stim +def show_two_sided_cross( + height=None, + width=None, + ppd=None, + theight=None, + twidth=None, + tint=None, + tthick=None, + cheight=None, + cwidth=None, + cint1=None, + cint2=None, + intback1=None, + intback2=None, + add_mask=False, +): + stim = two_sided_cross( + visual_size=(height, width), + ppd=ppd, + cross_size=(theight, twidth), + cross_thickness=tthick, + covers_size=(cheight, cwidth), + intensity_backgrounds=(intback1, intback2), + intensity_target=tint, + intensity_covers=(cint1, cint2), + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_two_sided_cross, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "theight": w_theight, + "twidth": w_twidth, + "tint": w_tint, + "tthick": w_tthick, + "cheight": w_cheight, + "cwidth": w_cwidth, + "cint1": w_cint1, + "cint2": w_cint2, + "intback1": w_int_back1, + "intback2": w_int_back2, + "add_mask": w_mask, + }, +) + +# Show +display(ui, out) +``` + +## Equal +{py:func}`stimupy.stimuli.todorovics.equal` + +```{code-cell} ipython3 +from stimupy.stimuli.todorovics import equal + +# Define widgets +w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_theight = iw.FloatSlider(value=4, min=0, max=8, description="cross height [deg]") +w_twidth = iw.FloatSlider(value=4, min=0, max=8, description="cross width [deg]") +w_tthick = iw.FloatSlider(value=2, min=0, max=4, description="cross thickness [deg]") +w_tint = iw.FloatSlider(value=0.5, min=0, max=1, description="cross int") + +w_cint = iw.FloatSlider(value=1, min=0, max=1, description="cover int") + +w_int_back = iw.FloatSlider(value=0., min=0, max=1, description="int background") +w_mask = iw.Dropdown(value=None, options=[None, 'target_mask'], description="add mask") + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_tsize = iw.HBox([w_theight, w_twidth, w_tthick, w_tint]) +b_csize = iw.HBox([w_cint]) +b_intensities = iw.HBox([w_int_back]) +b_add = iw.HBox([w_mask]) +ui = iw.VBox([b_im_size, b_tsize, b_csize, b_intensities, b_add]) + +# Function for showing stim +def show_equal( + height=None, + width=None, + ppd=None, + theight=None, + twidth=None, + tint=None, + tthick=None, + cint=None, + intback=None, + add_mask=False, +): + stim = equal( + visual_size=(height, width), + ppd=ppd, + cross_size=(theight, twidth), + cross_thickness=tthick, + intensity_background=intback, + intensity_target=tint, + intensity_covers=cint, + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_equal, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "theight": w_theight, + "twidth": w_twidth, + "tint": w_tint, + "tthick": w_tthick, + "cint": w_cint, + "intback": w_int_back, + "add_mask": w_mask, + }, +) + +# Show +display(ui, out) +``` + +## Equal, two-sided +{py:func}`stimupy.stimuli.todorovics.two_sided_equal` + +```{code-cell} ipython3 +from stimupy.stimuli.todorovics import two_sided_equal + +# Define widgets +w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=20, min=1, max=20, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_theight = iw.FloatSlider(value=4, min=0, max=8, description="cross height [deg]") +w_twidth = iw.FloatSlider(value=4, min=0, max=8, description="cross width [deg]") +w_tthick = iw.FloatSlider(value=2, min=0, max=4, description="cross thickness [deg]") +w_tint = iw.FloatSlider(value=0.5, min=0, max=1, description="cross int") + +w_cint1 = iw.FloatSlider(value=1, min=0, max=1, description="cover1 int") +w_cint2 = iw.FloatSlider(value=0, min=0, max=1, description="cover2 int") + +w_int_back1 = iw.FloatSlider(value=0., min=0, max=1, description="int back1") +w_int_back2 = iw.FloatSlider(value=1., min=0, max=1, description="int back2") +w_mask = iw.Dropdown(value=None, options=[None, 'target_mask'], description="add mask") + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_tsize = iw.HBox([w_theight, w_twidth, w_tthick, w_tint]) +b_csize = iw.HBox([w_cint1, w_cint2]) +b_intensities = iw.HBox([w_int_back1, w_int_back2]) +b_add = iw.HBox([w_mask]) +ui = iw.VBox([b_im_size, b_tsize, b_csize, b_intensities, b_add]) + +# Function for showing stim +def show_two_sided_equal( + height=None, + width=None, + ppd=None, + theight=None, + twidth=None, + tint=None, + tthick=None, + cint1=None, + cint2=None, + intback1=None, + intback2=None, + add_mask=False, +): + stim = two_sided_equal( + visual_size=(height, width), + ppd=ppd, + cross_size=(theight, twidth), + cross_thickness=tthick, + intensity_backgrounds=(intback1, intback2), + intensity_target=tint, + intensity_covers=(cint1, cint2), + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_two_sided_equal, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "theight": w_theight, + "twidth": w_twidth, + "tint": w_tint, + "tthick": w_tthick, + "cint1": w_cint1, + "intback1": w_int_back1, + "cint2": w_cint2, + "intback2": w_int_back2, + "add_mask": w_mask, + }, +) + +# Show +display(ui, out) +``` From 067297441e57ae93df2c1b06ef2b6596ed6579d5 Mon Sep 17 00:00:00 2001 From: lynnschmittwilken Date: Thu, 23 Mar 2023 15:44:54 -0400 Subject: [PATCH 05/10] added demos for all three plaid stims --- docs/reference/demos/stimuli/plaids.md | 283 ++++++++++++++++++++++++- 1 file changed, 274 insertions(+), 9 deletions(-) diff --git a/docs/reference/demos/stimuli/plaids.md b/docs/reference/demos/stimuli/plaids.md index e4eea58..80c30b6 100644 --- a/docs/reference/demos/stimuli/plaids.md +++ b/docs/reference/demos/stimuli/plaids.md @@ -28,11 +28,11 @@ import ipywidgets as iw from stimupy.utils import plot_stim ``` -## Plaid -{py:func}`stimupy.stimuli.plaids.plaid` +## Gabors +{py:func}`stimupy.stimuli.plaids.gabors` ```{code-cell} ipython3 -from stimupy.stimuli.plaids import plaid +from stimupy.stimuli.plaids import gabors # Define widgets w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") @@ -79,7 +79,141 @@ b_intensities2 = iw.HBox([w_int21, w_int22]) ui = iw.VBox([b_im_size, b_weight, b_add, b_geometry1, b_intensities1, b_geometry2, b_intensities2]) # Function for showing stim -def show_plaid( +def show_gabors( + height=None, + width=None, + ppd=None, + sigma=None, + weight1=None, + weight2=None, + rotation1=None, + frequency1=None, + phase_shift1=None, + int11=None, + int12=None, + rotation2=None, + frequency2=None, + phase_shift2=None, + int21=None, + int22=None, + origin=None, + round_phase_width=False, + period=None, + add_mask=False, +): + p_common = { + "visual_size": (height, width), + "ppd": ppd, + "origin": origin, + "round_phase_width": round_phase_width, + "period": period, + "sigma": sigma, + } + + p_grating1 = { + "frequency": frequency1, + "rotation": rotation1, + "phase_shift": phase_shift1, + "intensity_bars": (int11, int12), + } + + p_grating2 = { + "frequency": frequency2, + "rotation": rotation2, + "phase_shift": phase_shift2, + "intensity_bars": (int21, int22), + } + + stim = gabors( + gabor_parameters1={**p_common, **p_grating1}, + gabor_parameters2={**p_common, **p_grating2}, + weight1=weight1, + weight2=weight2, + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_gabors, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "sigma": w_sigma, + "weight1": w_weight1, + "weight2": w_weight2, + "rotation1": w_rot1, + "frequency1": w_freq1, + "phase_shift1": w_phase1, + "int11": w_int11, + "int12": w_int12, + "rotation2": w_rot2, + "frequency2": w_freq2, + "phase_shift2": w_phase2, + "int21": w_int21, + "int22": w_int22, + "origin": w_ori, + "round_phase_width": w_round, + "period": w_period, + "add_mask": w_mask, + }, +) + +# Show +display(ui, out) +``` + +## Sine-waves +{py:func}`stimupy.stimuli.plaids.sine_waves` + +```{code-cell} ipython3 +from stimupy.stimuli.plaids import sine_waves + +# Define widgets +w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_ori = iw.Dropdown(value="mean", options=['mean', 'corner', 'center'], description="origin") +w_period = iw.Dropdown(value="ignore", options=['ignore', 'even', 'odd', 'either'], description="period") +w_round = iw.ToggleButton(value=False, disabled=False, description="round phase") +w_mask = iw.Dropdown(value=False, options=[False, 'gaussian_mask', 'grating_mask', 'grating_mask2'], description="add mask") + +w_weight1 = iw.FloatSlider(value=1, min=0, max=1, description="weight1") +w_weight2 = iw.FloatSlider(value=1, min=0, max=1, description="weight2") + +# Grating 1 +w_freq1 = iw.FloatSlider(value=1, min=0, max=2, description="frequency1 [cpd]") +w_phase1 = iw.FloatSlider(value=0, min=0, max=360, description="phase shift1 [deg]") +w_rot1 = iw.FloatSlider(value=0, min=0, max=360, description="rotation1 [deg]") + +w_int11 = iw.FloatSlider(value=1, min=0, max=1, description="int1-1") +w_int12 = iw.FloatSlider(value=0, min=0, max=1, description="int1_2") + +# Grating 2 +w_freq2 = iw.FloatSlider(value=1, min=0, max=2, description="frequency2 [cpd]") +w_phase2 = iw.FloatSlider(value=0, min=0, max=360, description="phase shift2 [deg]") +w_rot2 = iw.FloatSlider(value=90, min=0, max=360, description="rotation2 [deg]") + +w_int21 = iw.FloatSlider(value=1, min=0, max=1, description="int2-1") +w_int22 = iw.FloatSlider(value=0, min=0, max=1, description="int2_2") + + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_weight = iw.HBox([w_weight1, w_weight2]) +b_add = iw.HBox([w_ori, w_period, w_round, w_mask]) + +b_geometry1 = iw.HBox([w_freq1, w_phase1, w_rot1]) +b_intensities1 = iw.HBox([w_int11, w_int12]) + +b_geometry2 = iw.HBox([w_freq2, w_phase2, w_rot2]) +b_intensities2 = iw.HBox([w_int21, w_int22]) + +ui = iw.VBox([b_im_size, b_weight, b_add, b_geometry1, b_intensities1, b_geometry2, b_intensities2]) + +# Function for showing stim +def show_sine_waves( height=None, width=None, ppd=None, @@ -107,7 +241,6 @@ def show_plaid( "origin": origin, "round_phase_width": round_phase_width, "period": period, - "distance_metric": "oblique", } p_grating1 = { @@ -124,18 +257,17 @@ def show_plaid( "intensities": (int21, int22), } - stim = plaid( + stim = sine_waves( grating_parameters1={**p_common, **p_grating1}, grating_parameters2={**p_common, **p_grating2}, weight1=weight1, weight2=weight2, - sigma=sigma, ) plot_stim(stim, mask=add_mask) # Set interactivity out = iw.interactive_output( - show_plaid, + show_sine_waves, { "height": w_height, "width": w_width, @@ -162,4 +294,137 @@ out = iw.interactive_output( # Show display(ui, out) -``` \ No newline at end of file +``` + +## Square-waves +{py:func}`stimupy.stimuli.plaids.square_waves` + +```{code-cell} ipython3 +from stimupy.stimuli.plaids import square_waves + +# Define widgets +w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_ori = iw.Dropdown(value="mean", options=['mean', 'corner', 'center'], description="origin") +w_period = iw.Dropdown(value="ignore", options=['ignore', 'even', 'odd', 'either'], description="period") +w_round = iw.ToggleButton(value=False, disabled=False, description="round phase") +w_mask = iw.Dropdown(value=False, options=[False, 'gaussian_mask', 'grating_mask', 'grating_mask2'], description="add mask") + +w_weight1 = iw.FloatSlider(value=1, min=0, max=1, description="weight1") +w_weight2 = iw.FloatSlider(value=1, min=0, max=1, description="weight2") + +# Grating 1 +w_freq1 = iw.FloatSlider(value=1, min=0, max=2, description="frequency1 [cpd]") +w_phase1 = iw.FloatSlider(value=0, min=0, max=360, description="phase shift1 [deg]") +w_rot1 = iw.FloatSlider(value=0, min=0, max=360, description="rotation1 [deg]") + +w_int11 = iw.FloatSlider(value=1, min=0, max=1, description="int1-1") +w_int12 = iw.FloatSlider(value=0, min=0, max=1, description="int1_2") + +# Grating 2 +w_freq2 = iw.FloatSlider(value=1, min=0, max=2, description="frequency2 [cpd]") +w_phase2 = iw.FloatSlider(value=0, min=0, max=360, description="phase shift2 [deg]") +w_rot2 = iw.FloatSlider(value=90, min=0, max=360, description="rotation2 [deg]") + +w_int21 = iw.FloatSlider(value=1, min=0, max=1, description="int2-1") +w_int22 = iw.FloatSlider(value=0, min=0, max=1, description="int2_2") + + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_weight = iw.HBox([w_weight1, w_weight2]) +b_add = iw.HBox([w_ori, w_period, w_round, w_mask]) + +b_geometry1 = iw.HBox([w_freq1, w_phase1, w_rot1]) +b_intensities1 = iw.HBox([w_int11, w_int12]) + +b_geometry2 = iw.HBox([w_freq2, w_phase2, w_rot2]) +b_intensities2 = iw.HBox([w_int21, w_int22]) + +ui = iw.VBox([b_im_size, b_weight, b_add, b_geometry1, b_intensities1, b_geometry2, b_intensities2]) + +# Function for showing stim +def show_square_waves( + height=None, + width=None, + ppd=None, + sigma=None, + weight1=None, + weight2=None, + rotation1=None, + frequency1=None, + phase_shift1=None, + int11=None, + int12=None, + rotation2=None, + frequency2=None, + phase_shift2=None, + int21=None, + int22=None, + origin=None, + round_phase_width=False, + period=None, + add_mask=False, +): + p_common = { + "visual_size": (height, width), + "ppd": ppd, + "origin": origin, + "round_phase_width": round_phase_width, + "period": period, + } + + p_grating1 = { + "frequency": frequency1, + "rotation": rotation1, + "phase_shift": phase_shift1, + "intensity_bars": (int11, int12), + } + + p_grating2 = { + "frequency": frequency2, + "rotation": rotation2, + "phase_shift": phase_shift2, + "intensity_bars": (int21, int22), + } + + stim = square_waves( + grating_parameters1={**p_common, **p_grating1}, + grating_parameters2={**p_common, **p_grating2}, + weight1=weight1, + weight2=weight2, + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_square_waves, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "sigma": w_sigma, + "weight1": w_weight1, + "weight2": w_weight2, + "rotation1": w_rot1, + "frequency1": w_freq1, + "phase_shift1": w_phase1, + "int11": w_int11, + "int12": w_int12, + "rotation2": w_rot2, + "frequency2": w_freq2, + "phase_shift2": w_phase2, + "int21": w_int21, + "int22": w_int22, + "origin": w_ori, + "round_phase_width": w_round, + "period": w_period, + "add_mask": w_mask, + }, +) + +# Show +display(ui, out) +``` From 1d7246ac204b2cffe05c9ba29c32f7a94cd0b8b5 Mon Sep 17 00:00:00 2001 From: lynnschmittwilken Date: Thu, 23 Mar 2023 16:50:08 -0400 Subject: [PATCH 06/10] added whites demos --- docs/reference/demos/stimuli/whites.md | 1001 ++++++++++++++++++++++++ 1 file changed, 1001 insertions(+) create mode 100644 docs/reference/demos/stimuli/whites.md diff --git a/docs/reference/demos/stimuli/whites.md b/docs/reference/demos/stimuli/whites.md new file mode 100644 index 0000000..0ec6083 --- /dev/null +++ b/docs/reference/demos/stimuli/whites.md @@ -0,0 +1,1001 @@ +--- +jupytext: + formats: md:myst + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.14.5 +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +```{important} +[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/computational-psychology/stimupy/HEAD?urlpath=lab/tree/docs/reference/demos/stimuli/whites.md) + to get interactivity +``` + +# Stimuli - Whites +{py:mod}`stimupy.stimuli.whites` + +```{code-cell} ipython3 +:tags: [remove-cell] + +import IPython +import ipywidgets as iw +from stimupy.utils import plot_stim +``` + +## Generalized +{py:func}`stimupy.stimuli.whites.generalized` + +```{code-cell} ipython3 +from stimupy.stimuli.whites import generalized + +# Define widgets +w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_freq = iw.FloatSlider(value=1, min=0, max=2, description="frequency [cpd]") +w_phase = iw.FloatSlider(value=0, min=0, max=360, description="phase shift [deg]") +w_rot = iw.FloatSlider(value=0, min=0, max=360, description="rotation [deg]") + +w_int1 = iw.FloatSlider(value=1, min=0, max=1, description="int1") +w_int2 = iw.FloatSlider(value=0, min=0, max=1, description="int2") + +w_tidx = iw.IntSlider(value=1, min=0, max=20, description="target idx") +w_tint = iw.FloatSlider(value=0.5, min=0, max=1, description="target int") +w_toff = iw.FloatSlider(value=0, min=-5, max=5, description="target center offset [deg]") +w_theights = iw.FloatSlider(value=1, min=0, max=5, description="target heights [deg]") + +w_tidx2 = iw.IntSlider(value=-1, min=-20, max=0, description="target2 idx") +w_tint2 = iw.FloatSlider(value=0.5, min=0, max=1, description="target2 int") +w_toff2 = iw.FloatSlider(value=0, min=-5, max=5, description="target2 center offset [deg]") +w_theights2 = iw.FloatSlider(value=1, min=0, max=5, description="target2 heights [deg]") + +w_ori = iw.Dropdown(value="mean", options=['mean', 'corner', 'center'], description="origin") +w_period = iw.Dropdown(value="ignore", options=['ignore', 'even', 'odd', 'either'], description="period") +w_mask = iw.ToggleButton(value=False, disabled=False, description="add mask") + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_geometry = iw.HBox([w_freq, w_phase, w_rot]) +b_intensities = iw.HBox([w_int1, w_int2]) +b_target = iw.HBox([w_tidx, w_tint, w_toff, w_theights]) +b_target2 = iw.HBox([w_tidx2, w_tint2, w_toff2, w_theights2]) +b_add = iw.HBox([w_ori, w_period, w_mask]) +ui = iw.VBox([b_im_size, b_geometry, b_intensities, b_target, b_target2, b_add]) + +# Function for showing stim +def show_generalized( + height=None, + width=None, + ppd=None, + rotation=None, + frequency=None, + phase_shift=None, + sigma=None, + int1=None, + int2=None, + origin=None, + period=None, + add_mask=False, + target_idx=None, + intensity_target=None, + target_center_offsets=None, + target_heights=None, + target_idx2=None, + intensity_target2=None, + target_center_offsets2=None, + target_heights2=None, +): + stim = generalized( + visual_size=(height, width), + ppd=ppd, + rotation=rotation, + frequency=frequency, + phase_shift=phase_shift, + intensity_bars=(int1, int2), + origin=origin, + period=period, + target_indices=(target_idx, target_idx2), + intensity_target=(intensity_target, intensity_target2), + target_center_offsets=(target_center_offsets, target_center_offsets2), + target_heights=(target_heights, target_heights2), + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_generalized, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "rotation": w_rot, + "frequency": w_freq, + "phase_shift": w_phase, + "int1": w_int1, + "int2": w_int2, + "origin": w_ori, + "period": w_period, + "add_mask": w_mask, + "target_idx": w_tidx, + "intensity_target": w_tint, + "target_center_offsets": w_toff, + "target_heights": w_theights, + "target_idx2": w_tidx2, + "intensity_target2": w_tint2, + "target_center_offsets2": w_toff2, + "target_heights2": w_theights2, + }, +) + +# Show +display(ui, out) +``` + +## White +{py:func}`stimupy.stimuli.whites.white` + +```{code-cell} ipython3 +from stimupy.stimuli.whites import white + +# Define widgets +w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_freq = iw.FloatSlider(value=1, min=0, max=2, description="frequency [cpd]") +w_phase = iw.FloatSlider(value=0, min=0, max=360, description="phase shift [deg]") +w_rot = iw.FloatSlider(value=0, min=0, max=360, description="rotation [deg]") + +w_int1 = iw.FloatSlider(value=1, min=0, max=1, description="int1") +w_int2 = iw.FloatSlider(value=0, min=0, max=1, description="int2") + +w_tidx = iw.IntSlider(value=1, min=0, max=20, description="target idx") +w_tint = iw.FloatSlider(value=0.5, min=0, max=1, description="target int") +w_theights = iw.FloatSlider(value=1, min=0, max=5, description="target heights [deg]") + +w_tidx2 = iw.IntSlider(value=-1, min=-20, max=0, description="target2 idx") +w_tint2 = iw.FloatSlider(value=0.5, min=0, max=1, description="target2 int") +w_theights2 = iw.FloatSlider(value=1, min=0, max=5, description="target2 heights [deg]") + +w_ori = iw.Dropdown(value="mean", options=['mean', 'corner', 'center'], description="origin") +w_period = iw.Dropdown(value="ignore", options=['ignore', 'even', 'odd', 'either'], description="period") +w_mask = iw.ToggleButton(value=False, disabled=False, description="add mask") + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_geometry = iw.HBox([w_freq, w_phase, w_rot]) +b_intensities = iw.HBox([w_int1, w_int2]) +b_target = iw.HBox([w_tidx, w_tint, w_theights]) +b_target2 = iw.HBox([w_tidx2, w_tint2, w_theights2]) +b_add = iw.HBox([w_ori, w_period, w_mask]) +ui = iw.VBox([b_im_size, b_geometry, b_intensities, b_target, b_target2, b_add]) + +# Function for showing stim +def show_white( + height=None, + width=None, + ppd=None, + rotation=None, + frequency=None, + phase_shift=None, + sigma=None, + int1=None, + int2=None, + origin=None, + period=None, + add_mask=False, + target_idx=None, + intensity_target=None, + target_idx2=None, + intensity_target2=None, + target_heights=None, + target_heights2=None, +): + stim = white( + visual_size=(height, width), + ppd=ppd, + rotation=rotation, + frequency=frequency, + phase_shift=phase_shift, + intensity_bars=(int1, int2), + origin=origin, + period=period, + target_indices=(target_idx, target_idx2), + intensity_target=(intensity_target, intensity_target2), + target_height=(target_heights, target_heights2), + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_white, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "rotation": w_rot, + "frequency": w_freq, + "phase_shift": w_phase, + "int1": w_int1, + "int2": w_int2, + "origin": w_ori, + "period": w_period, + "add_mask": w_mask, + "target_idx": w_tidx, + "intensity_target": w_tint, + "target_heights": w_theights, + "target_idx2": w_tidx2, + "intensity_target2": w_tint2, + "target_heights2": w_theights2, + }, +) + +# Show +display(ui, out) +``` + +## White, two-rows +{py:func}`stimupy.stimuli.whites.white_two_rows` + +```{code-cell} ipython3 +from stimupy.stimuli.whites import white_two_rows + +# Define widgets +w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_freq = iw.FloatSlider(value=1, min=0, max=2, description="frequency [cpd]") +w_phase = iw.FloatSlider(value=0, min=0, max=360, description="phase shift [deg]") +w_rot = iw.FloatSlider(value=0, min=0, max=360, description="rotation [deg]") + +w_int1 = iw.FloatSlider(value=1, min=0, max=1, description="int1") +w_int2 = iw.FloatSlider(value=0, min=0, max=1, description="int2") + +w_toff = iw.FloatSlider(value=0, min=-5, max=5, description="target center offset [deg]") + +w_tidx = iw.IntSlider(value=1, min=0, max=20, description="target idx") +w_tint = iw.FloatSlider(value=0.5, min=0, max=1, description="target int") +w_theights = iw.FloatSlider(value=1, min=0, max=5, description="target heights [deg]") + +w_tidx2 = iw.IntSlider(value=-1, min=-20, max=0, description="target2 idx") +w_tint2 = iw.FloatSlider(value=0.5, min=0, max=1, description="target2 int") +w_theights2 = iw.FloatSlider(value=1, min=0, max=5, description="target2 heights [deg]") + +w_ori = iw.Dropdown(value="mean", options=['mean', 'corner', 'center'], description="origin") +w_period = iw.Dropdown(value="ignore", options=['ignore', 'even', 'odd', 'either'], description="period") +w_mask = iw.ToggleButton(value=False, disabled=False, description="add mask") + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_geometry = iw.HBox([w_freq, w_phase, w_rot]) +b_intensities = iw.HBox([w_int1, w_int2]) +b_toff = w_toff +b_target = iw.HBox([w_tidx, w_tint, w_theights]) +b_target2 = iw.HBox([w_tidx2, w_tint2, w_theights2]) +b_add = iw.HBox([w_ori, w_period, w_mask]) +ui = iw.VBox([b_im_size, b_geometry, b_intensities, b_toff, b_target, b_target2, b_add]) + +# Function for showing stim +def show_white_two_rows( + height=None, + width=None, + ppd=None, + rotation=None, + frequency=None, + phase_shift=None, + sigma=None, + int1=None, + int2=None, + origin=None, + period=None, + add_mask=False, + target_idx=None, + intensity_target=None, + target_center_offsets=None, + target_heights=None, + target_idx2=None, + intensity_target2=None, + target_heights2=None, +): + stim = white_two_rows( + visual_size=(height, width), + ppd=ppd, + rotation=rotation, + frequency=frequency, + phase_shift=phase_shift, + intensity_bars=(int1, int2), + origin=origin, + period=period, + target_indices_top=target_idx, + target_indices_bottom=target_idx2, + intensity_target=(intensity_target, intensity_target2), + target_center_offset=target_center_offsets, + target_height=(target_heights, target_heights2), + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_white_two_rows, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "rotation": w_rot, + "frequency": w_freq, + "phase_shift": w_phase, + "int1": w_int1, + "int2": w_int2, + "origin": w_ori, + "period": w_period, + "add_mask": w_mask, + "target_idx": w_tidx, + "intensity_target": w_tint, + "target_center_offsets": w_toff, + "target_heights": w_theights, + "target_idx2": w_tidx2, + "intensity_target2": w_tint2, + "target_heights2": w_theights2, + }, +) + +# Show +display(ui, out) +``` + +## Anderson +{py:func}`stimupy.stimuli.whites.anderson` + +```{code-cell} ipython3 +from stimupy.stimuli.whites import anderson + +# Define widgets +w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_freq = iw.FloatSlider(value=1, min=0, max=2, description="frequency [cpd]") +w_phase = iw.FloatSlider(value=0, min=0, max=360, description="phase shift [deg]") +w_rot = iw.FloatSlider(value=0, min=0, max=360, description="rotation [deg]") + +w_int1 = iw.FloatSlider(value=1, min=0, max=1, description="int1") +w_int2 = iw.FloatSlider(value=0, min=0, max=1, description="int2") + +w_toff = iw.FloatSlider(value=1.5, min=0, max=5, description="target center offset [deg]") + +w_tidx = iw.IntSlider(value=5, min=0, max=20, description="target idx") +w_tint = iw.FloatSlider(value=0.5, min=0, max=1, description="target int") +w_theights = iw.FloatSlider(value=1, min=0, max=5, description="target heights [deg]") + +w_tidx2 = iw.IntSlider(value=-4, min=-20, max=0, description="target2 idx") +w_tint2 = iw.FloatSlider(value=0.5, min=0, max=1, description="target2 int") +w_theights2 = iw.FloatSlider(value=1, min=0, max=5, description="target2 heights [deg]") + +w_sheight = iw.FloatSlider(value=1, min=0, max=5, description="stripe height [deg]") +w_soff = iw.FloatSlider(value=2, min=0, max=5, description="stripe center offset [deg]") +w_sint1 = iw.FloatSlider(value=1.0, min=0, max=1, description="stripe1 int") +w_sint2 = iw.FloatSlider(value=0.0, min=0, max=1, description="stripe2 int") + +w_ori = iw.Dropdown(value="mean", options=['mean', 'corner', 'center'], description="origin") +w_period = iw.Dropdown(value="ignore", options=['ignore', 'even', 'odd', 'either'], description="period") +w_mask = iw.ToggleButton(value=False, disabled=False, description="add mask") + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_geometry = iw.HBox([w_freq, w_phase, w_rot]) +b_intensities = iw.HBox([w_int1, w_int2]) +b_toff = w_toff +b_target = iw.HBox([w_tidx, w_tint, w_theights]) +b_target2 = iw.HBox([w_tidx2, w_tint2, w_theights2]) +b_stripe = iw.HBox([w_sheight, w_soff, w_sint1, w_sint2]) +b_add = iw.HBox([w_ori, w_period, w_mask]) +ui = iw.VBox([b_im_size, b_geometry, b_intensities, b_toff, b_target, b_target2, b_stripe, b_add]) + +# Function for showing stim +def show_anderson( + height=None, + width=None, + ppd=None, + rotation=None, + frequency=None, + phase_shift=None, + sigma=None, + int1=None, + int2=None, + origin=None, + period=None, + add_mask=False, + target_idx=None, + intensity_target=None, + target_center_offsets=None, + target_heights=None, + target_idx2=None, + intensity_target2=None, + target_heights2=None, + stripe_height=None, + stripe_center_offset=None, + stripe_int1=None, + stripe_int2=None, +): + stim = anderson( + visual_size=(height, width), + ppd=ppd, +# rotation=rotation, + frequency=frequency, +# phase_shift=phase_shift, + intensity_bars=(int1, int2), +# origin=origin, + period=period, + target_indices_top=target_idx, + target_indices_bottom=target_idx2, + intensity_target=(intensity_target, intensity_target2), + target_center_offset=target_center_offsets, + target_height=target_heights, + stripe_height=stripe_height, + stripe_center_offset=stripe_center_offset, + intensity_stripes=(stripe_int1, stripe_int2), + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_anderson, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "rotation": w_rot, + "frequency": w_freq, + "phase_shift": w_phase, + "int1": w_int1, + "int2": w_int2, + "origin": w_ori, + "period": w_period, + "add_mask": w_mask, + "target_idx": w_tidx, + "intensity_target": w_tint, + "target_center_offsets": w_toff, + "target_heights": w_theights, + "target_idx2": w_tidx2, + "intensity_target2": w_tint2, + "target_heights2": w_theights2, + "stripe_height": w_sheight, + "stripe_center_offset": w_soff, + "stripe_int1": w_sint1, + "stripe_int2": w_sint2, + }, +) + +# Show +display(ui, out) +``` + +## Howe +{py:func}`stimupy.stimuli.whites.howe` + +```{code-cell} ipython3 +from stimupy.stimuli.whites import howe + +# Define widgets +w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_freq = iw.FloatSlider(value=1, min=0, max=2, description="frequency [cpd]") +w_phase = iw.FloatSlider(value=0, min=0, max=360, description="phase shift [deg]") +w_rot = iw.FloatSlider(value=0, min=0, max=360, description="rotation [deg]") + +w_int1 = iw.FloatSlider(value=1, min=0, max=1, description="int1") +w_int2 = iw.FloatSlider(value=0, min=0, max=1, description="int2") + +w_toff = iw.FloatSlider(value=1.5, min=0, max=5, description="target center offset [deg]") + +w_tidx = iw.IntSlider(value=5, min=0, max=20, description="target idx") +w_tint = iw.FloatSlider(value=0.5, min=0, max=1, description="target int") +w_theights = iw.FloatSlider(value=1, min=0, max=5, description="target heights [deg]") + +w_tidx2 = iw.IntSlider(value=-4, min=-20, max=0, description="target2 idx") +w_tint2 = iw.FloatSlider(value=0.5, min=0, max=1, description="target2 int") +w_theights2 = iw.FloatSlider(value=1, min=0, max=5, description="target2 heights [deg]") + +w_sint1 = iw.FloatSlider(value=1.0, min=0, max=1, description="stripe1 int") +w_sint2 = iw.FloatSlider(value=0.0, min=0, max=1, description="stripe2 int") + +w_ori = iw.Dropdown(value="mean", options=['mean', 'corner', 'center'], description="origin") +w_period = iw.Dropdown(value="ignore", options=['ignore', 'even', 'odd', 'either'], description="period") +w_mask = iw.ToggleButton(value=False, disabled=False, description="add mask") + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_geometry = iw.HBox([w_freq, w_phase, w_rot]) +b_intensities = iw.HBox([w_int1, w_int2]) +b_toff = w_toff +b_target = iw.HBox([w_tidx, w_tint, w_theights]) +b_target2 = iw.HBox([w_tidx2, w_tint2, w_theights2]) +b_stripe = iw.HBox([w_sint1, w_sint2]) +b_add = iw.HBox([w_ori, w_period, w_mask]) +ui = iw.VBox([b_im_size, b_geometry, b_intensities, b_toff, b_target, b_target2, b_stripe, b_add]) + +# Function for showing stim +def show_howe( + height=None, + width=None, + ppd=None, + rotation=None, + frequency=None, + phase_shift=None, + sigma=None, + int1=None, + int2=None, + origin=None, + period=None, + add_mask=False, + target_idx=None, + intensity_target=None, + target_center_offsets=None, + target_heights=None, + target_idx2=None, + intensity_target2=None, + target_heights2=None, + stripe_int1=None, + stripe_int2=None, +): + stim = howe( + visual_size=(height, width), + ppd=ppd, +# rotation=rotation, + frequency=frequency, +# phase_shift=phase_shift, + intensity_bars=(int1, int2), +# origin=origin, + period=period, + target_indices_top=target_idx, + target_indices_bottom=target_idx2, + intensity_target=(intensity_target, intensity_target2), + target_center_offset=target_center_offsets, + target_height=target_heights, + intensity_stripes=(stripe_int1, stripe_int2), + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_howe, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "rotation": w_rot, + "frequency": w_freq, + "phase_shift": w_phase, + "int1": w_int1, + "int2": w_int2, + "origin": w_ori, + "period": w_period, + "add_mask": w_mask, + "target_idx": w_tidx, + "intensity_target": w_tint, + "target_center_offsets": w_toff, + "target_heights": w_theights, + "target_idx2": w_tidx2, + "intensity_target2": w_tint2, + "target_heights2": w_theights2, + "stripe_int1": w_sint1, + "stripe_int2": w_sint2, + }, +) + +# Show +display(ui, out) +``` + +## Yazdanbakhsh +{py:func}`stimupy.stimuli.whites.yazdanbakhsh` + +```{code-cell} ipython3 +from stimupy.stimuli.whites import yazdanbakhsh + +# Define widgets +w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_freq = iw.FloatSlider(value=1, min=0, max=2, description="frequency [cpd]") +w_phase = iw.FloatSlider(value=0, min=0, max=360, description="phase shift [deg]") +w_rot = iw.FloatSlider(value=0, min=0, max=360, description="rotation [deg]") + +w_int1 = iw.FloatSlider(value=1, min=0, max=1, description="int1") +w_int2 = iw.FloatSlider(value=0, min=0, max=1, description="int2") + +w_toff = iw.FloatSlider(value=1.5, min=0, max=5, description="target center offset [deg]") +w_gap = iw.FloatSlider(value=0.1, min=0, max=1, description="gap size [deg]") + +w_tidx = iw.IntSlider(value=5, min=0, max=20, description="target idx") +w_tint = iw.FloatSlider(value=0.5, min=0, max=1, description="target int") +w_theights = iw.FloatSlider(value=1, min=0, max=5, description="target heights [deg]") + +w_tidx2 = iw.IntSlider(value=-4, min=-20, max=0, description="target2 idx") +w_tint2 = iw.FloatSlider(value=0.5, min=0, max=1, description="target2 int") +w_theights2 = iw.FloatSlider(value=1, min=0, max=5, description="target2 heights [deg]") + +w_sint1 = iw.FloatSlider(value=1.0, min=0, max=1, description="stripe1 int") +w_sint2 = iw.FloatSlider(value=0.0, min=0, max=1, description="stripe2 int") + +w_ori = iw.Dropdown(value="mean", options=['mean', 'corner', 'center'], description="origin") +w_period = iw.Dropdown(value="ignore", options=['ignore', 'even', 'odd', 'either'], description="period") +w_mask = iw.ToggleButton(value=False, disabled=False, description="add mask") + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_geometry = iw.HBox([w_freq, w_phase, w_rot]) +b_intensities = iw.HBox([w_int1, w_int2]) +b_toff = iw.HBox([w_toff, w_gap]) +b_target = iw.HBox([w_tidx, w_tint, w_theights]) +b_target2 = iw.HBox([w_tidx2, w_tint2, w_theights2]) +b_stripe = iw.HBox([w_sint1, w_sint2]) +b_add = iw.HBox([w_ori, w_period, w_mask]) +ui = iw.VBox([b_im_size, b_geometry, b_intensities, b_toff, b_target, b_target2, b_stripe, b_add]) + +# Function for showing stim +def show_yazdanbakhsh( + height=None, + width=None, + ppd=None, + rotation=None, + frequency=None, + phase_shift=None, + sigma=None, + int1=None, + int2=None, + origin=None, + period=None, + add_mask=False, + target_idx=None, + intensity_target=None, + target_center_offsets=None, + target_heights=None, + target_idx2=None, + intensity_target2=None, + target_heights2=None, + gap_size=None, + stripe_int1=None, + stripe_int2=None, +): + stim = yazdanbakhsh( + visual_size=(height, width), + ppd=ppd, +# rotation=rotation, + frequency=frequency, +# phase_shift=phase_shift, + intensity_bars=(int1, int2), +# origin=origin, + period=period, + target_indices_top=target_idx, + target_indices_bottom=target_idx2, + intensity_target=(intensity_target, intensity_target2), + target_center_offset=target_center_offsets, + target_height=target_heights, + intensity_stripes=(stripe_int1, stripe_int2), + gap_size=gap_size, + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_yazdanbakhsh, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "rotation": w_rot, + "frequency": w_freq, + "phase_shift": w_phase, + "int1": w_int1, + "int2": w_int2, + "origin": w_ori, + "period": w_period, + "add_mask": w_mask, + "target_idx": w_tidx, + "intensity_target": w_tint, + "target_center_offsets": w_toff, + "target_heights": w_theights, + "target_idx2": w_tidx2, + "intensity_target2": w_tint2, + "target_heights2": w_theights2, + "stripe_int1": w_sint1, + "stripe_int2": w_sint2, + "gap_size": w_gap, + }, +) + +# Show +display(ui, out) +``` + +## Circular +{py:func}`stimupy.stimuli.whites.circular` + +```{code-cell} ipython3 +from stimupy.stimuli.whites import circular + +# Define widgets +w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_freq = iw.FloatSlider(value=1, min=0, max=2, description="frequency [cpd]") +w_phase = iw.FloatSlider(value=0, min=0, max=360, description="phase shift [deg]") +w_rot = iw.FloatSlider(value=0, min=0, max=360, description="rotation [deg]") + +w_int1 = iw.FloatSlider(value=1, min=0, max=1, description="int1") +w_int2 = iw.FloatSlider(value=0, min=0, max=1, description="int2") + +w_ori = iw.Dropdown(value="mean", options=['mean', 'corner', 'center'], description="origin") +w_period = iw.Dropdown(value="ignore", options=['ignore', 'even', 'odd', 'either'], description="period") +w_round = iw.ToggleButton(value=False, disabled=False, description="round phase") +w_clip = iw.ToggleButton(value=True, disabled=False, description="clip to aperature") +w_mask = iw.Dropdown(value=None, options=[None, 'target_mask', 'grating_mask'], description="add mask") + +w_tidx = iw.IntSlider(value=1, min=1, max=10, description="target idx") +w_tint = iw.FloatSlider(value=0.5, min=0, max=1, description="target int") + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_geometry = iw.HBox([w_freq, w_phase, w_rot]) +b_intensities = iw.HBox([w_int1, w_int2]) +b_target = iw.HBox([w_tidx, w_tint]) +b_add = iw.HBox([w_ori, w_period, w_round, w_clip, w_mask]) +ui = iw.VBox([b_im_size, b_geometry, b_intensities, b_target, b_add]) + +# Function for showing stim +def show_circular( + height=None, + width=None, + ppd=None, + rotation=None, + frequency=None, + phase_shift=None, + int1=None, + int2=None, + origin=None, + round_phase_width=False, + period=None, + add_mask=False, + target_indices=None, + intensity_target=None, + clip=True, +): + stim = circular( + visual_size=(height, width), + ppd=ppd, + rotation=rotation, + frequency=frequency, + phase_shift=phase_shift, + intensity_rings=(int1, int2), + origin=origin, + round_phase_width=round_phase_width, + period=period, + target_indices=target_indices, + intensity_target=intensity_target, + clip=clip, + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_circular, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "rotation": w_rot, + "frequency": w_freq, + "phase_shift": w_phase, + "int1": w_int1, + "int2": w_int2, + "origin": w_ori, + "round_phase_width": w_round, + "period": w_period, + "add_mask": w_mask, + "target_indices": w_tidx, + "intensity_target": w_tint, + "clip": w_clip, + }, +) + +# Show +display(ui, out) +``` + +## Radial +{py:func}`stimupy.stimuli.whites.radial` + +```{code-cell} ipython3 +from stimupy.stimuli.whites import radial + +# Define widgets +w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_nseg = iw.IntSlider(value=6, min=2, max=12, description="n_segments") +w_rot = iw.IntSlider(value=0, min=0, max=360, description="rotation [deg]") + +w_int1 = iw.FloatSlider(value=1, min=0, max=1, description="int1") +w_int2 = iw.FloatSlider(value=0., min=0, max=1, description="int2") +w_int_back = iw.FloatSlider(value=0.5, min=0, max=1, description="int background") + +w_tidx = iw.IntSlider(value=3, min=0, max=6, description="target idx") +w_twidth = iw.FloatSlider(value=2.5, min=0, max=5, description="target width") +w_tcent = iw.FloatSlider(value=2.5, min=0, max=5, description="target center") +w_tint = iw.FloatSlider(value=0.5, min=0, max=1, description="target int") + +w_ori = iw.Dropdown(value="mean", options=['mean', 'corner', 'center'], description="origin") +w_mask = iw.Dropdown(value=None, options=[None, 'target_mask', 'wedge_mask'], description="add mask") + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_geometry = iw.HBox([w_nseg, w_rot]) +b_intensities = iw.HBox([w_int1, w_int2, w_int_back]) +b_target = iw.HBox([w_tidx, w_twidth, w_tcent, w_tint]) +b_add = iw.HBox([w_ori, w_mask]) +ui = iw.VBox([b_im_size, b_geometry, b_intensities, b_target, b_add]) + +# Function for showing stim +def show_radial( + height=None, + width=None, + ppd=None, + n_segments=None, + rotation=None, + intensity1=None, + intensity2=None, + intensity_background=None, + target_indices=None, + target_width=None, + target_center=None, + intensity_target=None, + origin=None, + add_mask=False, +): + stim = radial( + visual_size=(height, width), + ppd=ppd, + rotation=rotation, + n_segments=n_segments, + intensity_segments=(intensity1, intensity2), + intensity_background=intensity_background, + origin=origin, + target_indices=target_indices, + target_width=target_width, + target_center=target_center, + intensity_target=intensity_target, + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_radial, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "n_segments": w_nseg, + "rotation": w_rot, + "intensity1": w_int1, + "intensity2": w_int2, + "intensity_background": w_int_back, + "origin": w_ori, + "add_mask": w_mask, + "target_indices": w_tidx, + "target_width": w_twidth, + "target_center": w_tcent, + "intensity_target": w_tint, + }, +) + +# Show +display(ui, out) +``` + +## Wedding-cake +{py:func}`stimupy.stimuli.whites.wedding_cake` + +```{code-cell} ipython3 +from stimupy.stimuli.whites import wedding_cake + +# Define widgets +w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") +w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") +w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") + +w_Lheight = iw.FloatSlider(value=2, min=0, max=5, description="L-height [deg]") +w_Lwidth = iw.FloatSlider(value=2, min=0, max=5, description="L-width [deg]") +w_Lthick = iw.FloatSlider(value=0.5, min=0, max=2, description="L-thickness [deg]") + +w_int1 = iw.FloatSlider(value=1, min=0, max=1, description="int1") +w_int2 = iw.FloatSlider(value=0., min=0, max=1, description="int2") + +w_tidx11 = iw.IntSlider(value=0, min=0, max=5, description="target1 idx1") +w_tidx12 = iw.IntSlider(value=0, min=-5, max=5, description="target1 idx2") +w_tidx21 = iw.IntSlider(value=0, min=0, max=5, description="target1 idx1") +w_tidx22 = iw.IntSlider(value=0, min=-5, max=5, description="target2 idx2") + +w_theight = iw.FloatSlider(value=0.5, min=0, max=2, description="target height [deg]") +w_tint = iw.FloatSlider(value=0.5, min=0, max=1, description="target int") + +w_mask = iw.Dropdown(value=None, options=[None, 'target_mask'], description="add mask") + +# Layout +b_im_size = iw.HBox([w_height, w_width, w_ppd]) +b_geometry = iw.HBox([w_Lheight, w_Lwidth, w_Lthick]) +b_intensities = iw.HBox([w_int1, w_int2]) +b_target = iw.HBox([w_theight, w_tint]) +b_target_idx = iw.HBox([w_tidx11, w_tidx12, w_tidx21, w_tidx22]) +b_add = iw.HBox([w_mask]) +ui = iw.VBox([b_im_size, b_geometry, b_intensities, b_target, b_target_idx, b_add]) + +# Function for showing stim +def show_wedding_cake( + height=None, + width=None, + ppd=None, + add_mask=False, + L_height=None, + L_width=None, + L_thick=None, + int1=None, + int2=None, + tidx11=None, + tidx12=None, + tidx21=None, + tidx22=None, + theight=None, + int_target=None, +): + stim = wedding_cake( + visual_size=(height, width), + ppd=ppd, + L_size=(L_height, L_width, L_thick), + target_height=theight, + intensity_target=int_target, + target_indices1=((tidx11, tidx12),), + target_indices2=((tidx21, tidx22),), + intensity_bars=(int1, int2), + ) + plot_stim(stim, mask=add_mask) + +# Set interactivity +out = iw.interactive_output( + show_wedding_cake, + { + "height": w_height, + "width": w_width, + "ppd": w_ppd, + "add_mask": w_mask, + "L_height": w_Lheight, + "L_width": w_Lwidth, + "L_thick": w_Lthick, + "int1": w_int1, + "int2": w_int2, + "tidx11": w_tidx11, + "tidx12": w_tidx12, + "tidx21": w_tidx21, + "tidx22": w_tidx22, + "theight": w_theight, + "int_target": w_tint, + + }, +) + +# Show +display(ui, out) +``` From b16215301fcd8b4343f3e4b9c0960dc22eb7dfdd Mon Sep 17 00:00:00 2001 From: lynnschmittwilken Date: Thu, 23 Mar 2023 17:31:06 -0400 Subject: [PATCH 07/10] closes #43; fixed all bugs in todorovics --- docs/reference/demos/stimuli/todorovics.md | 18 +- stimupy/stimuli/todorovics.py | 311 +++++++++++---------- 2 files changed, 180 insertions(+), 149 deletions(-) diff --git a/docs/reference/demos/stimuli/todorovics.md b/docs/reference/demos/stimuli/todorovics.md index 2227421..4e32b0e 100644 --- a/docs/reference/demos/stimuli/todorovics.md +++ b/docs/reference/demos/stimuli/todorovics.md @@ -228,10 +228,10 @@ display(ui, out) ``` ## Rectangle, two-sided -{py:func}`stimupy.stimuli.todorovics.two_sided_rectangle` +{py:func}`stimupy.stimuli.todorovics.rectangle_two_sided` ```{code-cell} ipython3 -from stimupy.stimuli.todorovics import two_sided_rectangle +from stimupy.stimuli.todorovics import rectangle_two_sided # Define widgets w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") @@ -281,7 +281,7 @@ def show_two_sided_rectangle( intback2=None, add_mask=False, ): - stim = two_sided_rectangle( + stim = rectangle_two_sided( visual_size=(height, width), ppd=ppd, target_size=(theight, twidth), @@ -500,10 +500,10 @@ display(ui, out) ``` ## Cross, two-sided -{py:func}`stimupy.stimuli.todorovics.two_sided_cross` +{py:func}`stimupy.stimuli.todorovics.cross_two_sided` ```{code-cell} ipython3 -from stimupy.stimuli.todorovics import two_sided_cross +from stimupy.stimuli.todorovics import cross_two_sided # Define widgets w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") @@ -549,7 +549,7 @@ def show_two_sided_cross( intback2=None, add_mask=False, ): - stim = two_sided_cross( + stim = cross_two_sided( visual_size=(height, width), ppd=ppd, cross_size=(theight, twidth), @@ -661,10 +661,10 @@ display(ui, out) ``` ## Equal, two-sided -{py:func}`stimupy.stimuli.todorovics.two_sided_equal` +{py:func}`stimupy.stimuli.todorovics.equal_two_sided` ```{code-cell} ipython3 -from stimupy.stimuli.todorovics import two_sided_equal +from stimupy.stimuli.todorovics import equal_two_sided # Define widgets w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") @@ -706,7 +706,7 @@ def show_two_sided_equal( intback2=None, add_mask=False, ): - stim = two_sided_equal( + stim = equal_two_sided( visual_size=(height, width), ppd=ppd, cross_size=(theight, twidth), diff --git a/stimupy/stimuli/todorovics.py b/stimupy/stimuli/todorovics.py index 0f1956f..ff01be4 100644 --- a/stimupy/stimuli/todorovics.py +++ b/stimupy/stimuli/todorovics.py @@ -1,3 +1,5 @@ +import itertools + import numpy as np from stimupy.components.shapes import cross as cross_shape @@ -7,12 +9,12 @@ __all__ = [ "rectangle_generalized", "rectangle", + "rectangle_two_sided", "cross_generalized", "cross", + "cross_two_sided", "equal", - "two_sided_rectangle", - "two_sided_cross", - "two_sided_equal", + "equal_two_sided", ] @@ -53,7 +55,7 @@ def rectangle_generalized( intensity value for background intensity_target : float intensity value for target - intensity_covers : float + intensity_covers : Sequence[Number, ...] or Number intensity value for covers Returns @@ -122,11 +124,16 @@ def rectangle_generalized( cx = np.round(cx).astype(int) cy = np.round(cy).astype(int) - if np.max(cx) < np.min(cx) + cwidth or np.max(cy) < np.min(cy) + cheight: - raise ValueError("Covers overlap") + if isinstance(intensity_covers, (float, int)): + int_cov = [ + intensity_covers, + ] + else: + int_cov = list(intensity_covers) + int_cov = itertools.cycle(int_cov) for i in range(len(covers_x)): - img[cy[i] : cy[i] + cheight, cx[i] : cx[i] + cwidth] = intensity_covers + img[cy[i] : cy[i] + cheight, cx[i] : cx[i] + cwidth] = next(int_cov) mask[cy[i] : cy[i] + cheight, cx[i] : cx[i] + cwidth] = 0 if cy[i] + cheight > shape[0] or cx[i] + cwidth > shape[1]: raise ValueError("Covers do not fully fit into stimulus") @@ -183,7 +190,7 @@ def rectangle( intensity value for background intensity_target : float intensity value for target - intensity_covers : float + intensity_covers : Sequence[Number, ...] or Number intensity value for covers Returns @@ -244,12 +251,103 @@ def rectangle( return stim +def rectangle_two_sided( + visual_size=None, + ppd=None, + shape=None, + target_size=None, + covers_size=None, + covers_offset=None, + intensity_backgrounds=(0.0, 1.0), + intensity_target=0.5, + intensity_covers=(1.0, 0.0), +): + """ + Two-sided Todorovic's illusion with rectangular target in the center and four + rectangular covers added symmetrically around target center + + Parameters + ---------- + visual_size : Sequence[Number, Number], Number, or None (default) + visual size [height, width] of grating, 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 grating, in pixels + target_size : float or (float, float) + size of the target in degrees of visual angle (height, width) + covers_size : float or (float, float) + size of covers in degrees of visual angle (height, width) + covers_offset : float or (float, float) + distance from cover center to target center in (y, x) + intensity_background : Sequence[Number, Number] + intensity values for backgrounds + intensity_target : float + intensity value for target + intensity_covers : Sequence[Number, Number] + intensity values for covers + + Returns + ------- + dict[str, Any] + dict with the stimulus (key: "img"), + mask with integer index for the target (key: "target_mask"), + and additional keys containing stimulus parameters + + References + ---------- + Blakeslee, B., & McCourt, M. E. (1999). + A multiscale spatial filtering account + of the White effect, simultaneous brightness contrast and grating induction. + Vision Research, 39, 4361-4377. + Pessoa, L., Baratoff, G., Neumann, H., & Todorovic, D. (1998). + Lightness and junctions: variations on White's display. + Investigative Ophthalmology and Visual Science (Supplement), 39, S159. + Todorovic, D. (1997). + Lightness and junctions. Perception, 26, 379-395. + """ + + # Resolve resolution + shape, visual_size, ppd = resolution.resolve(shape=shape, visual_size=visual_size, ppd=ppd) + + stim1 = rectangle( + visual_size=(visual_size[0], visual_size[1] / 2), + ppd=ppd, + target_size=target_size, + covers_size=covers_size, + covers_offset=covers_offset, + intensity_background=intensity_backgrounds[0], + intensity_target=intensity_target, + intensity_covers=intensity_covers[0], + ) + + stim2 = rectangle( + visual_size=(visual_size[0], visual_size[1] / 2), + ppd=ppd, + target_size=target_size, + covers_size=covers_size, + covers_offset=covers_offset, + intensity_background=intensity_backgrounds[1], + intensity_target=intensity_target, + intensity_covers=intensity_covers[1], + ) + + stim = stack_dicts(stim1, stim2) + del stim["intensity_background"] + del stim["target_position"] + stim["intensity_backgrounds"] = intensity_backgrounds + stim["intensity_covers"] = intensity_covers + stim["target_positions"] = (stim1["target_position"], stim2["target_position"]) + stim["shape"] = shape + stim["visual_size"] = visual_size + return stim + + def cross_generalized( visual_size=None, ppd=None, shape=None, cross_size=None, - cross_arm_ratios=1, cross_thickness=None, covers_size=None, covers_x=None, @@ -270,8 +368,6 @@ def cross_generalized( shape [height, width] of grating, in pixels cross_size : float or (float, float) size of target cross in visual angle - cross_arm_ratios : float or (float, float) - ratio used to create arms (up-down, left-right) cross_thickness : float thickness of target cross in visual angle covers_size : float or (float, float) @@ -284,7 +380,7 @@ def cross_generalized( intensity value for background intensity_target : float intensity value for target - intensity_covers : float + intensity_covers : Sequence[Number, ...] or Number intensity value for covers Returns @@ -338,7 +434,7 @@ def cross_generalized( visual_size=cross_size, ppd=ppd, cross_size=cross_size, - cross_arm_ratios=cross_arm_ratios, + cross_arm_ratios=1, cross_thickness=cross_thickness, intensity_background=intensity_background, intensity_cross=intensity_target, @@ -359,8 +455,16 @@ def cross_generalized( cx = np.round(cx).astype(int) cy = np.round(cy).astype(int) + if isinstance(intensity_covers, (float, int)): + int_cov = [ + intensity_covers, + ] + else: + int_cov = list(intensity_covers) + int_cov = itertools.cycle(int_cov) + for i in range(len(covers_x)): - img[cy[i] : cy[i] + cheight, cx[i] : cx[i] + cwidth] = intensity_covers + img[cy[i] : cy[i] + cheight, cx[i] : cx[i] + cwidth] = next(int_cov) mask[cy[i] : cy[i] + cheight, cx[i] : cx[i] + cwidth] = 0 if cy[i] + cheight > shape[0] or cx[i] + cwidth > shape[1]: raise ValueError("Covers do not fully fit into stimulus") @@ -411,7 +515,7 @@ def cross( intensity value for background intensity_target : float intensity value for target - intensity_covers : float + intensity_covers : Sequence[Number, ...] or Number intensity value for covers Returns @@ -464,7 +568,6 @@ def cross( visual_size=visual_size, ppd=ppd, cross_size=cross_size, - cross_arm_ratios=1.0, cross_thickness=ct, covers_size=covers_size, covers_x=(x1, x2, x2, x1), @@ -476,17 +579,18 @@ def cross( return stim -def equal( +def cross_two_sided( visual_size=None, ppd=None, shape=None, cross_size=None, cross_thickness=None, - intensity_background=0.0, + covers_size=None, + intensity_backgrounds=(0.0, 1.0), intensity_target=0.5, - intensity_covers=1.0, + intensity_covers=(1.0, 0.0), ): - """Cross target and four rectangular covers added at inner cross corners + """Two-sided with cross target and four rectangular covers added at inner cross corners Parameters ---------- @@ -500,86 +604,9 @@ def equal( size of target cross in visual angle cross_thickness : float thickness of target cross in visual angle - intensity_background : float - intensity value for background - intensity_target : float - intensity value for target - intensity_covers : float - intensity value for covers - - Returns - ------- - dict[str, Any] - dict with the stimulus (key: "img"), - mask with integer index for the target (key: "target_mask"), - and additional keys containing stimulus parameters - - References - ---------- - Blakeslee, B., & McCourt, M. E. (1999). - A multiscale spatial filtering account - of the White effect, simultaneous brightness contrast and grating induction. - Vision Research, 39, 4361-4377. - Pessoa, L., Baratoff, G., Neumann, H., & Todorovic, D. (1998). - Lightness and junctions: variations on White's display. - Investigative Ophthalmology and Visual Science (Supplement), 39, S159. - Todorovic, D. (1997). - Lightness and junctions. Perception, 26, 379-395. - """ - if cross_size is None: - raise ValueError("equal() missing argument 'cross_size' which is not 'None'") - if cross_thickness is None: - raise ValueError("equal() missing argument 'cross_thickness' which is not 'None'") - - if isinstance(cross_size, (float, int)): - cross_size = (cross_size, cross_size) - - covers_size = ((cross_size[0] - cross_thickness) / 2, (cross_size[1] - cross_thickness) / 2) - - stim = cross( - visual_size=visual_size, - ppd=ppd, - shape=shape, - cross_size=cross_size, - cross_thickness=cross_thickness, - covers_size=covers_size, - intensity_background=intensity_background, - intensity_target=intensity_target, - intensity_covers=intensity_covers, - ) - return stim - - -def two_sided_rectangle( - visual_size=None, - ppd=None, - shape=None, - target_size=None, - covers_size=None, - covers_offset=None, - intensity_backgrounds=(0.0, 1.0), - intensity_target=0.5, - intensity_covers=(1.0, 0.0), -): - """ - Two-sided Todorovic's illusion with rectangular target in the center and four - rectangular covers added symmetrically around target center - - Parameters - ---------- - visual_size : Sequence[Number, Number], Number, or None (default) - visual size [height, width] of grating, 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 grating, in pixels - target_size : float or (float, float) - size of the target in degrees of visual angle (height, width) covers_size : float or (float, float) size of covers in degrees of visual angle (height, width) - covers_offset : float or (float, float) - distance from cover center to target center in (y, x) - intensity_background : Sequence[Number, Number] + intensity_backgrounds : Sequence[Number, Number] intensity values for backgrounds intensity_target : float intensity value for target @@ -609,23 +636,23 @@ def two_sided_rectangle( # Resolve resolution shape, visual_size, ppd = resolution.resolve(shape=shape, visual_size=visual_size, ppd=ppd) - stim1 = rectangle( + stim1 = cross( visual_size=(visual_size[0], visual_size[1] / 2), ppd=ppd, - target_size=target_size, + cross_size=cross_size, + cross_thickness=cross_thickness, covers_size=covers_size, - covers_offset=covers_offset, intensity_background=intensity_backgrounds[0], intensity_target=intensity_target, intensity_covers=intensity_covers[0], ) - stim2 = rectangle( + stim2 = cross( visual_size=(visual_size[0], visual_size[1] / 2), ppd=ppd, - target_size=target_size, + cross_size=cross_size, + cross_thickness=cross_thickness, covers_size=covers_size, - covers_offset=covers_offset, intensity_background=intensity_backgrounds[1], intensity_target=intensity_target, intensity_covers=intensity_covers[1], @@ -633,27 +660,24 @@ def two_sided_rectangle( stim = stack_dicts(stim1, stim2) del stim["intensity_background"] - del stim["target_position"] stim["intensity_backgrounds"] = intensity_backgrounds stim["intensity_covers"] = intensity_covers - stim["target_positions"] = (stim1["target_position"], stim2["target_position"]) stim["shape"] = shape stim["visual_size"] = visual_size return stim -def two_sided_cross( +def equal( visual_size=None, ppd=None, shape=None, cross_size=None, cross_thickness=None, - covers_size=None, - intensity_backgrounds=(0.0, 1.0), + intensity_background=0.0, intensity_target=0.5, - intensity_covers=(1.0, 0.0), + intensity_covers=1.0, ): - """Two-sided with cross target and four rectangular covers added at inner cross corners + """Cross target and four rectangular covers added at inner cross corners Parameters ---------- @@ -667,14 +691,12 @@ def two_sided_cross( size of target cross in visual angle cross_thickness : float thickness of target cross in visual angle - covers_size : float or (float, float) - size of covers in degrees of visual angle (height, width) - intensity_backgrounds : Sequence[Number, Number] - intensity values for backgrounds + intensity_background : float + intensity value for background intensity_target : float intensity value for target - intensity_covers : Sequence[Number, Number] - intensity values for covers + intensity_covers : float + intensity value for covers Returns ------- @@ -695,42 +717,51 @@ def two_sided_cross( Todorovic, D. (1997). Lightness and junctions. Perception, 26, 379-395. """ + if cross_size is None: + raise ValueError("equal() missing argument 'cross_size' which is not 'None'") + if cross_thickness is None: + raise ValueError("equal() missing argument 'cross_thickness' which is not 'None'") + + if isinstance(cross_size, (float, int)): + cross_size = (cross_size, cross_size) # Resolve resolution shape, visual_size, ppd = resolution.resolve(shape=shape, visual_size=visual_size, ppd=ppd) + if len(np.unique(ppd)) > 1: + raise ValueError("ppd should be equal in x and y direction") - stim1 = cross( - visual_size=(visual_size[0], visual_size[1] / 2), + # Calculate placement of covers for generalized function: + ppd = np.unique(ppd)[0] + c1 = (np.ceil(cross_size[0] / 2 * ppd - cross_thickness / 2 * ppd + 1)) / ppd + c2 = (np.ceil(cross_size[1] / 2 * ppd - cross_thickness / 2 * ppd + 1)) / ppd + covers_size = (c1, c2) + + # covers_size = ((cross_size[0] - cross_thickness) / 2, (cross_size[1] - cross_thickness) / 2) + + stim = cross( + visual_size=visual_size, ppd=ppd, + shape=shape, cross_size=cross_size, cross_thickness=cross_thickness, covers_size=covers_size, - intensity_background=intensity_backgrounds[0], + intensity_background=intensity_background, intensity_target=intensity_target, - intensity_covers=intensity_covers[0], + intensity_covers=intensity_covers, ) - stim2 = cross( - visual_size=(visual_size[0], visual_size[1] / 2), + window = rectangle_shape( + visual_size=visual_size, ppd=ppd, - cross_size=cross_size, - cross_thickness=cross_thickness, - covers_size=covers_size, - intensity_background=intensity_backgrounds[1], - intensity_target=intensity_target, - intensity_covers=intensity_covers[1], + shape=shape, + rectangle_size=cross_size, ) - stim = stack_dicts(stim1, stim2) - del stim["intensity_background"] - stim["intensity_backgrounds"] = intensity_backgrounds - stim["intensity_covers"] = intensity_covers - stim["shape"] = shape - stim["visual_size"] = visual_size + stim["img"] = np.where(window["shape_mask"], stim["img"], intensity_background) return stim -def two_sided_equal( +def equal_two_sided( visual_size=None, ppd=None, shape=None, @@ -840,12 +871,12 @@ def overview(**kwargs): stimuli = { "todorovic_rectangle": rectangle(**default_params, **rectangle_params, covers_offset=1.5), "todorovic_rectangle_general": rectangle_generalized(**default_params, **rectangle_params, target_position=3.5, covers_x=(2, 6), covers_y=(2, 6)), + "todorovic_rectangle_2sided": rectangle_two_sided(**default_params, **rectangle_params, covers_offset=1), "todorovic_cross": cross(**default_params, **cross_params, covers_size=2), "todorovic_cross_general": cross_generalized(**default_params, **cross_params, covers_size=2, covers_x=(2, 6), covers_y=(2, 6)), + "todorovic_cross_2sided": cross_two_sided(**default_params, **cross_params, covers_size=1), "todorovic_equal": equal(**default_params, **cross_params,), - "todorovic_rectangle_2sided": two_sided_rectangle(**default_params, **rectangle_params, covers_offset=1), - "todorovic_cross_2sided": two_sided_cross(**default_params, **cross_params, covers_size=1), - "todorovic_equal_2sided": two_sided_equal(**default_params, **cross_params,), + "todorovic_equal_2sided": equal_two_sided(**default_params, **cross_params,), } # fmt: on @@ -856,4 +887,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) From 4d500d22b6ab8a63b03f62133281aae4edf51b77 Mon Sep 17 00:00:00 2001 From: lynnschmittwilken Date: Thu, 23 Mar 2023 22:37:11 -0400 Subject: [PATCH 08/10] also updated todo-equal-target-mask --- stimupy/stimuli/todorovics.py | 1 + 1 file changed, 1 insertion(+) diff --git a/stimupy/stimuli/todorovics.py b/stimupy/stimuli/todorovics.py index ff01be4..72f2fb1 100644 --- a/stimupy/stimuli/todorovics.py +++ b/stimupy/stimuli/todorovics.py @@ -758,6 +758,7 @@ def equal( ) stim["img"] = np.where(window["shape_mask"], stim["img"], intensity_background) + stim["target_mask"] = np.where(window["shape_mask"], stim["target_mask"], 0).astype(int) return stim From 5d49139a99be2b2ef8da8f92187b2747e4f3d7a7 Mon Sep 17 00:00:00 2001 From: Joris Vincent Date: Fri, 24 Mar 2023 14:06:44 +0100 Subject: [PATCH 09/10] Docs: update demos `whites.anderson`, `.howe` --- docs/reference/demos/stimuli/whites.md | 99 +++++++------------------- 1 file changed, 24 insertions(+), 75 deletions(-) diff --git a/docs/reference/demos/stimuli/whites.md b/docs/reference/demos/stimuli/whites.md index 0ec6083..248e0e7 100644 --- a/docs/reference/demos/stimuli/whites.md +++ b/docs/reference/demos/stimuli/whites.md @@ -40,7 +40,6 @@ w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") w_freq = iw.FloatSlider(value=1, min=0, max=2, description="frequency [cpd]") -w_phase = iw.FloatSlider(value=0, min=0, max=360, description="phase shift [deg]") w_rot = iw.FloatSlider(value=0, min=0, max=360, description="rotation [deg]") w_int1 = iw.FloatSlider(value=1, min=0, max=1, description="int1") @@ -62,7 +61,7 @@ w_mask = iw.ToggleButton(value=False, disabled=False, description="add mask") # Layout b_im_size = iw.HBox([w_height, w_width, w_ppd]) -b_geometry = iw.HBox([w_freq, w_phase, w_rot]) +b_geometry = iw.HBox([w_freq, w_rot]) b_intensities = iw.HBox([w_int1, w_int2]) b_target = iw.HBox([w_tidx, w_tint, w_toff, w_theights]) b_target2 = iw.HBox([w_tidx2, w_tint2, w_toff2, w_theights2]) @@ -76,7 +75,6 @@ def show_generalized( ppd=None, rotation=None, frequency=None, - phase_shift=None, sigma=None, int1=None, int2=None, @@ -97,7 +95,6 @@ def show_generalized( ppd=ppd, rotation=rotation, frequency=frequency, - phase_shift=phase_shift, intensity_bars=(int1, int2), origin=origin, period=period, @@ -117,7 +114,6 @@ out = iw.interactive_output( "ppd": w_ppd, "rotation": w_rot, "frequency": w_freq, - "phase_shift": w_phase, "int1": w_int1, "int2": w_int2, "origin": w_ori, @@ -150,7 +146,6 @@ w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") w_freq = iw.FloatSlider(value=1, min=0, max=2, description="frequency [cpd]") -w_phase = iw.FloatSlider(value=0, min=0, max=360, description="phase shift [deg]") w_rot = iw.FloatSlider(value=0, min=0, max=360, description="rotation [deg]") w_int1 = iw.FloatSlider(value=1, min=0, max=1, description="int1") @@ -170,7 +165,7 @@ w_mask = iw.ToggleButton(value=False, disabled=False, description="add mask") # Layout b_im_size = iw.HBox([w_height, w_width, w_ppd]) -b_geometry = iw.HBox([w_freq, w_phase, w_rot]) +b_geometry = iw.HBox([w_freq, w_rot]) b_intensities = iw.HBox([w_int1, w_int2]) b_target = iw.HBox([w_tidx, w_tint, w_theights]) b_target2 = iw.HBox([w_tidx2, w_tint2, w_theights2]) @@ -184,7 +179,6 @@ def show_white( ppd=None, rotation=None, frequency=None, - phase_shift=None, sigma=None, int1=None, int2=None, @@ -203,13 +197,12 @@ def show_white( ppd=ppd, rotation=rotation, frequency=frequency, - phase_shift=phase_shift, intensity_bars=(int1, int2), origin=origin, period=period, target_indices=(target_idx, target_idx2), intensity_target=(intensity_target, intensity_target2), - target_height=(target_heights, target_heights2), + target_heights=(target_heights, target_heights2), ) plot_stim(stim, mask=add_mask) @@ -222,7 +215,6 @@ out = iw.interactive_output( "ppd": w_ppd, "rotation": w_rot, "frequency": w_freq, - "phase_shift": w_phase, "int1": w_int1, "int2": w_int2, "origin": w_ori, @@ -253,7 +245,6 @@ w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") w_freq = iw.FloatSlider(value=1, min=0, max=2, description="frequency [cpd]") -w_phase = iw.FloatSlider(value=0, min=0, max=360, description="phase shift [deg]") w_rot = iw.FloatSlider(value=0, min=0, max=360, description="rotation [deg]") w_int1 = iw.FloatSlider(value=1, min=0, max=1, description="int1") @@ -275,7 +266,7 @@ w_mask = iw.ToggleButton(value=False, disabled=False, description="add mask") # Layout b_im_size = iw.HBox([w_height, w_width, w_ppd]) -b_geometry = iw.HBox([w_freq, w_phase, w_rot]) +b_geometry = iw.HBox([w_freq, w_rot]) b_intensities = iw.HBox([w_int1, w_int2]) b_toff = w_toff b_target = iw.HBox([w_tidx, w_tint, w_theights]) @@ -290,7 +281,6 @@ def show_white_two_rows( ppd=None, rotation=None, frequency=None, - phase_shift=None, sigma=None, int1=None, int2=None, @@ -310,7 +300,6 @@ def show_white_two_rows( ppd=ppd, rotation=rotation, frequency=frequency, - phase_shift=phase_shift, intensity_bars=(int1, int2), origin=origin, period=period, @@ -318,7 +307,7 @@ def show_white_two_rows( target_indices_bottom=target_idx2, intensity_target=(intensity_target, intensity_target2), target_center_offset=target_center_offsets, - target_height=(target_heights, target_heights2), + target_heights=(target_heights, target_heights2), ) plot_stim(stim, mask=add_mask) @@ -331,7 +320,6 @@ out = iw.interactive_output( "ppd": w_ppd, "rotation": w_rot, "frequency": w_freq, - "phase_shift": w_phase, "int1": w_int1, "int2": w_int2, "origin": w_ori, @@ -363,8 +351,6 @@ w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") w_freq = iw.FloatSlider(value=1, min=0, max=2, description="frequency [cpd]") -w_phase = iw.FloatSlider(value=0, min=0, max=360, description="phase shift [deg]") -w_rot = iw.FloatSlider(value=0, min=0, max=360, description="rotation [deg]") w_int1 = iw.FloatSlider(value=1, min=0, max=1, description="int1") w_int2 = iw.FloatSlider(value=0, min=0, max=1, description="int2") @@ -384,19 +370,18 @@ w_soff = iw.FloatSlider(value=2, min=0, max=5, description="stripe center offset w_sint1 = iw.FloatSlider(value=1.0, min=0, max=1, description="stripe1 int") w_sint2 = iw.FloatSlider(value=0.0, min=0, max=1, description="stripe2 int") -w_ori = iw.Dropdown(value="mean", options=['mean', 'corner', 'center'], description="origin") w_period = iw.Dropdown(value="ignore", options=['ignore', 'even', 'odd', 'either'], description="period") w_mask = iw.ToggleButton(value=False, disabled=False, description="add mask") # Layout b_im_size = iw.HBox([w_height, w_width, w_ppd]) -b_geometry = iw.HBox([w_freq, w_phase, w_rot]) +b_geometry = iw.HBox([w_freq]) b_intensities = iw.HBox([w_int1, w_int2]) b_toff = w_toff b_target = iw.HBox([w_tidx, w_tint, w_theights]) b_target2 = iw.HBox([w_tidx2, w_tint2, w_theights2]) b_stripe = iw.HBox([w_sheight, w_soff, w_sint1, w_sint2]) -b_add = iw.HBox([w_ori, w_period, w_mask]) +b_add = iw.HBox([w_period, w_mask]) ui = iw.VBox([b_im_size, b_geometry, b_intensities, b_toff, b_target, b_target2, b_stripe, b_add]) # Function for showing stim @@ -404,13 +389,9 @@ def show_anderson( height=None, width=None, ppd=None, - rotation=None, frequency=None, - phase_shift=None, - sigma=None, int1=None, int2=None, - origin=None, period=None, add_mask=False, target_idx=None, @@ -428,17 +409,14 @@ def show_anderson( stim = anderson( visual_size=(height, width), ppd=ppd, -# rotation=rotation, frequency=frequency, -# phase_shift=phase_shift, intensity_bars=(int1, int2), -# origin=origin, period=period, target_indices_top=target_idx, target_indices_bottom=target_idx2, intensity_target=(intensity_target, intensity_target2), target_center_offset=target_center_offsets, - target_height=target_heights, + target_height=(target_heights, target_heights2), stripe_height=stripe_height, stripe_center_offset=stripe_center_offset, intensity_stripes=(stripe_int1, stripe_int2), @@ -452,12 +430,9 @@ out = iw.interactive_output( "height": w_height, "width": w_width, "ppd": w_ppd, - "rotation": w_rot, "frequency": w_freq, - "phase_shift": w_phase, "int1": w_int1, "int2": w_int2, - "origin": w_ori, "period": w_period, "add_mask": w_mask, "target_idx": w_tidx, @@ -490,8 +465,6 @@ w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") w_freq = iw.FloatSlider(value=1, min=0, max=2, description="frequency [cpd]") -w_phase = iw.FloatSlider(value=0, min=0, max=360, description="phase shift [deg]") -w_rot = iw.FloatSlider(value=0, min=0, max=360, description="rotation [deg]") w_int1 = iw.FloatSlider(value=1, min=0, max=1, description="int1") w_int2 = iw.FloatSlider(value=0, min=0, max=1, description="int2") @@ -509,13 +482,12 @@ w_theights2 = iw.FloatSlider(value=1, min=0, max=5, description="target2 heights w_sint1 = iw.FloatSlider(value=1.0, min=0, max=1, description="stripe1 int") w_sint2 = iw.FloatSlider(value=0.0, min=0, max=1, description="stripe2 int") -w_ori = iw.Dropdown(value="mean", options=['mean', 'corner', 'center'], description="origin") w_period = iw.Dropdown(value="ignore", options=['ignore', 'even', 'odd', 'either'], description="period") w_mask = iw.ToggleButton(value=False, disabled=False, description="add mask") # Layout b_im_size = iw.HBox([w_height, w_width, w_ppd]) -b_geometry = iw.HBox([w_freq, w_phase, w_rot]) +b_geometry = iw.HBox([w_freq, w_rot]) b_intensities = iw.HBox([w_int1, w_int2]) b_toff = w_toff b_target = iw.HBox([w_tidx, w_tint, w_theights]) @@ -529,13 +501,9 @@ def show_howe( height=None, width=None, ppd=None, - rotation=None, frequency=None, - phase_shift=None, - sigma=None, int1=None, int2=None, - origin=None, period=None, add_mask=False, target_idx=None, @@ -551,17 +519,14 @@ def show_howe( stim = howe( visual_size=(height, width), ppd=ppd, -# rotation=rotation, frequency=frequency, -# phase_shift=phase_shift, intensity_bars=(int1, int2), -# origin=origin, period=period, target_indices_top=target_idx, target_indices_bottom=target_idx2, intensity_target=(intensity_target, intensity_target2), target_center_offset=target_center_offsets, - target_height=target_heights, + target_height=(target_heights, target_heights2), intensity_stripes=(stripe_int1, stripe_int2), ) plot_stim(stim, mask=add_mask) @@ -573,12 +538,9 @@ out = iw.interactive_output( "height": w_height, "width": w_width, "ppd": w_ppd, - "rotation": w_rot, "frequency": w_freq, - "phase_shift": w_phase, "int1": w_int1, "int2": w_int2, - "origin": w_ori, "period": w_period, "add_mask": w_mask, "target_idx": w_tidx, @@ -609,8 +571,6 @@ w_width = iw.IntSlider(value=10, min=1, max=20, description="width [deg]") w_ppd = iw.IntSlider(value=20, min=1, max=40, description="ppd") w_freq = iw.FloatSlider(value=1, min=0, max=2, description="frequency [cpd]") -w_phase = iw.FloatSlider(value=0, min=0, max=360, description="phase shift [deg]") -w_rot = iw.FloatSlider(value=0, min=0, max=360, description="rotation [deg]") w_int1 = iw.FloatSlider(value=1, min=0, max=1, description="int1") w_int2 = iw.FloatSlider(value=0, min=0, max=1, description="int2") @@ -629,19 +589,18 @@ w_theights2 = iw.FloatSlider(value=1, min=0, max=5, description="target2 heights w_sint1 = iw.FloatSlider(value=1.0, min=0, max=1, description="stripe1 int") w_sint2 = iw.FloatSlider(value=0.0, min=0, max=1, description="stripe2 int") -w_ori = iw.Dropdown(value="mean", options=['mean', 'corner', 'center'], description="origin") w_period = iw.Dropdown(value="ignore", options=['ignore', 'even', 'odd', 'either'], description="period") w_mask = iw.ToggleButton(value=False, disabled=False, description="add mask") # Layout b_im_size = iw.HBox([w_height, w_width, w_ppd]) -b_geometry = iw.HBox([w_freq, w_phase, w_rot]) +b_geometry = iw.HBox([w_freq]) b_intensities = iw.HBox([w_int1, w_int2]) b_toff = iw.HBox([w_toff, w_gap]) b_target = iw.HBox([w_tidx, w_tint, w_theights]) b_target2 = iw.HBox([w_tidx2, w_tint2, w_theights2]) b_stripe = iw.HBox([w_sint1, w_sint2]) -b_add = iw.HBox([w_ori, w_period, w_mask]) +b_add = iw.HBox([w_period, w_mask]) ui = iw.VBox([b_im_size, b_geometry, b_intensities, b_toff, b_target, b_target2, b_stripe, b_add]) # Function for showing stim @@ -649,13 +608,9 @@ def show_yazdanbakhsh( height=None, width=None, ppd=None, - rotation=None, frequency=None, - phase_shift=None, - sigma=None, int1=None, int2=None, - origin=None, period=None, add_mask=False, target_idx=None, @@ -672,11 +627,8 @@ def show_yazdanbakhsh( stim = yazdanbakhsh( visual_size=(height, width), ppd=ppd, -# rotation=rotation, frequency=frequency, -# phase_shift=phase_shift, intensity_bars=(int1, int2), -# origin=origin, period=period, target_indices_top=target_idx, target_indices_bottom=target_idx2, @@ -695,12 +647,9 @@ out = iw.interactive_output( "height": w_height, "width": w_width, "ppd": w_ppd, - "rotation": w_rot, "frequency": w_freq, - "phase_shift": w_phase, "int1": w_int1, "int2": w_int2, - "origin": w_ori, "period": w_period, "add_mask": w_mask, "target_idx": w_tidx, @@ -720,11 +669,11 @@ out = iw.interactive_output( display(ui, out) ``` -## Circular -{py:func}`stimupy.stimuli.whites.circular` +## Radial +{py:func}`stimupy.stimuli.whites.radial` ```{code-cell} ipython3 -from stimupy.stimuli.whites import circular +from stimupy.stimuli.whites import radial # Define widgets w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") @@ -756,7 +705,7 @@ b_add = iw.HBox([w_ori, w_period, w_round, w_clip, w_mask]) ui = iw.VBox([b_im_size, b_geometry, b_intensities, b_target, b_add]) # Function for showing stim -def show_circular( +def show_radial( height=None, width=None, ppd=None, @@ -773,7 +722,7 @@ def show_circular( intensity_target=None, clip=True, ): - stim = circular( + stim = radial( visual_size=(height, width), ppd=ppd, rotation=rotation, @@ -791,7 +740,7 @@ def show_circular( # Set interactivity out = iw.interactive_output( - show_circular, + show_radial, { "height": w_height, "width": w_width, @@ -815,11 +764,11 @@ out = iw.interactive_output( display(ui, out) ``` -## Radial -{py:func}`stimupy.stimuli.whites.radial` +## Angular +{py:func}`stimupy.stimuli.whites.angular` ```{code-cell} ipython3 -from stimupy.stimuli.whites import radial +from stimupy.stimuli.whites import angular # Define widgets w_height = iw.IntSlider(value=10, min=1, max=20, description="height [deg]") @@ -850,7 +799,7 @@ b_add = iw.HBox([w_ori, w_mask]) ui = iw.VBox([b_im_size, b_geometry, b_intensities, b_target, b_add]) # Function for showing stim -def show_radial( +def show_angular( height=None, width=None, ppd=None, @@ -866,7 +815,7 @@ def show_radial( origin=None, add_mask=False, ): - stim = radial( + stim = angular( visual_size=(height, width), ppd=ppd, rotation=rotation, @@ -883,7 +832,7 @@ def show_radial( # Set interactivity out = iw.interactive_output( - show_radial, + show_angular, { "height": w_height, "width": w_width, From a44d58f298b7f1f266ba2750e7dc21ae19ae8bd1 Mon Sep 17 00:00:00 2001 From: Joris Vincent Date: Fri, 24 Mar 2023 14:00:40 +0100 Subject: [PATCH 10/10] Docs: update demo `whites.yazdanbakhsh` --- docs/reference/demos/stimuli/whites.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reference/demos/stimuli/whites.md b/docs/reference/demos/stimuli/whites.md index 248e0e7..6f18670 100644 --- a/docs/reference/demos/stimuli/whites.md +++ b/docs/reference/demos/stimuli/whites.md @@ -634,7 +634,7 @@ def show_yazdanbakhsh( target_indices_bottom=target_idx2, intensity_target=(intensity_target, intensity_target2), target_center_offset=target_center_offsets, - target_height=target_heights, + target_heights=(target_heights, target_heights2), intensity_stripes=(stripe_int1, stripe_int2), gap_size=gap_size, )