utils#

Modules#

Functions#

luminance2munsell(lum_values, reference_white)

Transform luminance values into Munsell values.

munsell2luminance(munsell_values, ...)

Transform Munsell values to luminance values.

transparency(img[, mask, alpha, tau])

Applies a transparency to image at specified (mask) location if provided

adapt_michelson_contrast(img, michelson_contrast)

Adapt Michelson contrast of image

adapt_rms_contrast(img, rms_contrast[, ...])

Adapt rms contrast of image (std)

adapt_normalized_rms_contrast(img, rms_contrast)

Adapt normalized rms contrast of image (std divided by mean)

adapt_intensity_range(img[, intensity_min, ...])

Adapt intensity range of image

adapt_michelson_contrast_dict(stim, ...[, ...])

Adapt Michelson contrast of image in dict

adapt_rms_contrast_dict(stim, rms_contrast)

Adapt rms contrast of image (std)

adapt_normalized_rms_contrast_dict(stim, ...)

Adapt normalized rms contrast of image (std divided by mean)

adapt_intensity_range_dict(stim[, ...])

Adapt intensity range of image

array_to_checksum(arr)

Hash (md5) array values, and return hex-checksum

array_to_image(arr, filename[, format, norm])

Save a 2D numpy array as a grayscale image file.

array_to_npy(arr, filename)

Save a numpy array to npy-file.

array_to_mat(arr, filename)

Save a numpy array to a mat-file.

array_to_pickle(arr, filename)

Save a numpy array to a pickle-file.

arrays_to_checksum(stim[, keys])

Hash (md5) values of arrays specified in keys, and save only the hex

to_json(stim, filename)

Save stimulus-dict(s) as (pretty) JSON

to_mat(stim, filename)

Save stimulus-dict(s) as mat-file

to_pickle(stim, filename)

Save stimulus-dict(s) as pickle-file

convolve(arr1, arr2[, mode, axes, padding])

Convolve two N-dimensional arrays using FFT

bandpass([visual_size, ppd, shape, ...])

Function to create a 2d bandpass filter in the frequency domain

avg_target_values(stim[, mask_key, f_average])

Average pixel value in each target region of stimulus

avg_img_values(image, mask[, f_average])

Average values of pixels in image, per target region in integer mask

all_img_values(img, mask)

Isolate all image values/pixels, per target region specified in integer mask

img_values(img, mask)

Isolate only image pixels specified by a binary mask

add_padding(arr, c, val)

Remove padding by c

remove_padding(arr, c)

Remove padding by c

pad_by_visual_size(img, padding, ppd[, ...])

Pad image by specified degrees of visual angle

pad_to_visual_size(img, visual_size, ppd[, ...])

Pad image to specified visual size in degrees visual angle

pad_by_shape(img, padding[, pad_value])

Pad image by specified amount(s) of pixels

pad_to_shape(img, shape[, pad_value])

Pad image to a resulting specified shape in pixels

pad_dict_by_visual_size(dct, padding, ppd[, ...])

Pad images in dictionary by specified degrees of visual angle

pad_dict_to_visual_size(dct, visual_size, ppd)

Pad images in dictionary to specified visual size in degrees visual angle

pad_dict_by_shape(dct, padding[, pad_value, ...])

Pad images in dictionary by specified amount(s) of pixels Can specify different amount (before, after) each axis.

pad_dict_to_shape(dct, shape[, pad_value, keys])

Pad images in dictionary to a resulting specified shape in pixels

plot_stim(stim[, mask, stim_name, ax, vmin, ...])

Plot a stimulus

plot_stimuli(stims[, mask, vmin, vmax, ...])

Plot multiple stimuli

plot_comparison(original_img, new_img)

Plots visual comparison of two image-arrays

resolve([shape, visual_size, ppd])

Resolves the full resolution, for 2 givens and 1 unknown

resolve_1D([length, visual_angle, ppd, round])

Resolves the full resolution, for 2 givens and 1 unknown

resolve_dict(dct)

Resolves the full resolution ("shape", "ppd", "visual_size"), for 2 givens and 1 unknown in the input dictionary

visual_angle_from_length_ppd(length, ppd)

Calculate visual angle (degrees) from length (pixels) and pixels-per-degree

visual_angles_from_lengths_ppd(lengths, ppd)

Calculate visual sizes (degrees) from given shapes (pixels) and pixels-per-degree

visual_size_from_shape_ppd(shape, ppd)

Calculate visual size (degrees) from given shape (pixels) and pixels-per-degree

length_from_visual_angle_ppd(visual_angle, ppd)

Calculate length (pixels) from visual angle (degrees) and pixels-per-degree

lengths_from_visual_angles_ppd(...[, round])

Calculate lengths (pixels) from visual angles (degrees) and pixels-per-degree

shape_from_visual_size_ppd(visual_size, ppd)

Calculate shape (pixels) from given visual size (degrees) and pixels-per-degree

ppd_from_shape_visual_size(shape, visual_size)

Calculate resolution (ppd) from given shape (pixels) and visual size (degrees)

ppd_from_length_visual_angle(length, ...)

Calculate pixels-per-degree from length (pixels) and visual angle (degrees)

compute_ppd(screen_size, resolution, distance)

Compute the pixels per degree in a presentation setup i.e., the number of pixels in the central one degree of visual angle

validate_shape(shape)

Put specification of shape (in pixels) in canonical form, if possible

validate_ppd(ppd)

Put specification of ppd in canonical form, if possible

validate_visual_size(visual_size)

Put specification of visual size in canonical form, if possible

valid_1D(length, visual_angle, ppd)

Asserts that the combined specification of resolution is geometrically valid.

valid_resolution(shape, visual_size, ppd)

Asserts that the combined specification of resolution is geometrically valid.

valid_dict(dct)

Asserts that the combined specification of resolution in dict is geometrically valid.

round_to_vals(arr, vals[, mode])

Round each element of array to closest match in provided values

int_factorize(n)

All integer factors of integer n

get_function_argument_names(func)

Get all argument names for a given function

apply_bessel(arr[, order])

Bessel function of the first kind of real order and complex argument.

resize_array(arr, factor)

Return a copy of an array, resized by the given factor.

resize_dict(dct, factor[, keys])

Return a copy of an array, resized by the given factor.

stack_dicts(dct1, dct2[, direction, keys, ...])

Return a dict with resized key-arrays by the given factor.

rotate_dict(dct[, nrots, keys])

Return a dict with key-arrays rotated by nrots*90 degrees.

flip_dict(dct[, direction, keys])

Return a dict with key-arrays rotated by nrots*90 degrees.

roll_dict(dct, shift, axes[, keys])

Return a dict with key-arrays rolled by shift in axes.

strip_dict(dct, func)

Create a dictionary by stripping it from all keys that are not also an argument to the provided function

make_two_sided(func, two_sided_params)

Create two-sided version of a stimulus function

permutate_params(params)

Generate all possible parameter combinations for a stimulus function.

create_stimspace_stimuli(stimulus_function, ...)

Generate stimuli for all parameter combinations in a stimspace.

stimupy.utils.luminance2munsell(lum_values, reference_white)[source]#

Transform luminance values into Munsell values. The luminance values do not have to correspond to specific units, as long as they are in the same unit as the reference white, because Munsell values are a perceptually uniform scale of relative luminances.

Parameters:
  • lum_values (numpy-array)

  • reference_white (number)

Returns:

  • munsell_values (numpy-array)

  • Reference (H. Pauli, “Proposed extension of the CIE recommendation)

  • on ‘Uniform color spaces, color difference equations, and metric color

  • terms’,” J. Opt. Soc. Am. 66, 866-867 (1976)

stimupy.utils.munsell2luminance(munsell_values, reference_white)[source]#

Transform Munsell values to luminance values. The luminance values will be in the same unit as the reference white, which can be arbitrary as long as the scale is linear.

Parameters:
  • munsell_values (numpy-array)

  • reference_white (number)

Returns:

  • lum_values (numpy-array)

  • Reference (H. Pauli, “Proposed extension of the CIE recommendation)

  • on ‘Uniform color spaces, color difference equations, and metric color

  • terms’,” J. Opt. Soc. Am. 66, 866-867 (1976)

stimupy.utils.transparency(img, mask=None, alpha=0.5, tau=0.2)[source]#

Applies a transparency to image at specified (mask) location if provided

Parameters:
  • img (np.array) – image to which transparency will be applied

  • mask (np.array or None (default)) – if not None, transparency will be provided at non-zero locations provided in this mask

  • alpha (Number) – alpha of transparency (i.e. how transparent the medium is), default 0.2

  • tau (Number) – tau of transparency (i.e. value of transparent medium), default 0.5

Return type:

img with the applied transparency

stimupy.utils.adapt_michelson_contrast(img, michelson_contrast, mean_luminance=None)[source]#

Adapt Michelson contrast of image

Parameters:
  • img (np.ndarray) – stimulus array

  • michelson_contrast (float) – desired Michelson contrast

  • mean_luminance (float) – desired mean luminance; if None (default), dont change mean luminance

Returns:

img – image with adapted michelson contrast and mean luminance if passed

Return type:

np.ndarray

stimupy.utils.adapt_rms_contrast(img, rms_contrast, mean_luminance=None)[source]#

Adapt rms contrast of image (std)

Parameters:
  • img (np.ndarray) – stimulus array

  • rms_contrast (float) – desired rms contrast (std divided by mean intensity)

  • mean_luminance (float) – desired mean luminance; if None (default), dont change mean luminance

Returns:

img – image with adapted rms contrast and mean luminance if passed

Return type:

np.ndarray

stimupy.utils.adapt_normalized_rms_contrast(img, rms_contrast, mean_luminance=None)[source]#

Adapt normalized rms contrast of image (std divided by mean)

Parameters:
  • img (np.ndarray) – stimulus array

  • rms_contrast (float) – desired rms contrast (std divided by mean intensity)

  • mean_luminance (float) – desired mean luminance; if None (default), dont change mean luminance

Returns:

img – image with adapted rms contrast and mean luminance if passed

Return type:

np.ndarray

stimupy.utils.adapt_intensity_range(img, intensity_min=0.0, intensity_max=1.0)[source]#

Adapt intensity range of image

Parameters:
  • img (np.ndarray) – stimulus array

  • intensity_min (float) – new minimal intensity value

  • intensity_max (float) – new maximal intensity value

Returns:

img – image with adapted intensity range

Return type:

np.ndarray

stimupy.utils.adapt_michelson_contrast_dict(stim, michelson_contrast, mean_luminance=None)[source]#

Adapt Michelson contrast of image in dict

Parameters:
  • stim (dict) – stimulus dictionary containing at least key “img”

  • michelson_contrast (float) – desired Michelson contrast

  • mean_luminance (float) – desired mean luminance; if None (default), dont change mean luminance

Returns:

dict with the stimulus (key: “img”), Michelson contrast (key: “michelson_contrast”), mean luminance (“mean_luminance”) and additional keys containing stimulus parameters

Return type:

dict[str, Any]

stimupy.utils.adapt_rms_contrast_dict(stim, rms_contrast, mean_luminance=None)[source]#

Adapt rms contrast of image (std)

Parameters:
  • stim (dict) – stimulus dictionary containing at least key “img”

  • rms_contrast (float) – desired rms contrast (std divided by mean intensity)

  • mean_luminance (float) – desired mean luminance; if None (default), dont change mean luminance

Returns:

dict with the stimulus (key: “img”), RMS contrast (key: “rms_contrast”), mean luminance (“mean_luminance”) and additional keys containing stimulus parameters

Return type:

dict[str, Any]

stimupy.utils.adapt_normalized_rms_contrast_dict(stim, rms_contrast, mean_luminance=None)[source]#

Adapt normalized rms contrast of image (std divided by mean)

Parameters:
  • stim (dict) – stimulus dictionary containing at least key “img”

  • rms_contrast (float) – desired rms contrast (std divided by mean intensity)

  • mean_luminance (float) – desired mean luminance; if None (default), dont change mean luminance

Returns:

dict with the stimulus (key: “img”), RMS contrast (key: “rms_contrast”), mean luminance (“mean_luminance”) and additional keys containing stimulus parameters

Return type:

dict[str, Any]

stimupy.utils.adapt_intensity_range_dict(stim, intensity_min=0.0, intensity_max=1.0)[source]#

Adapt intensity range of image

Parameters:
  • stim (dict) – stimulus dictionary containing at least key “img”

  • intensity_min (float) – new minimal intensity value

  • intensity_max (float) – new maximal intensity value

Returns:

dict with the stimulus (key: “img”), intensity range (key: “intensity_range”), and additional keys containing stimulus parameters

Return type:

dict[str, Any]

stimupy.utils.array_to_checksum(arr)[source]#

Hash (md5) array values, and return hex-checksum

Parameters:

arr (numpy.ndarray) – array to be hashed.

Returns:

hex-string representation of hash (MD5) of given array

Return type:

str

stimupy.utils.array_to_image(arr, filename, format=None, norm=True)[source]#

Save a 2D numpy array as a grayscale image file.

Parameters:
  • arr (numpy.ndarray) – array to be exported. Values will be cropped to [0,255].

  • filename (Path or str) – (full) path to the file to be created.

  • norm (bool) – multiply array by 255, by default True

stimupy.utils.array_to_npy(arr, filename)[source]#

Save a numpy array to npy-file.

Parameters:
  • arr (numpy.ndarray) – array to be exported.

  • filename (Path or str) – (full) path to the file to be created.

stimupy.utils.array_to_mat(arr, filename)[source]#

Save a numpy array to a mat-file.

Parameters:
  • arr (numpy.ndarray) – array to be exported.

  • filename (Path or str) – (full) path to the file to be created.

stimupy.utils.array_to_pickle(arr, filename)[source]#

Save a numpy array to a pickle-file.

Parameters:
  • arr (numpy.ndarray) – array to be exported.

  • filename (Path or str) – (full) path to the file to be created.

stimupy.utils.arrays_to_checksum(stim, keys=['img', 'mask'])[source]#

Hash (md5) values of arrays specified in keys, and save only the hex

Parameters:
  • stim (dict) – stimulus dictionary to export.

  • keys (str of list of str) – keys of dict for which the hashing should be performed

Returns:

same as input dict but keys now only contain the hex

Return type:

dict[str, Any]

stimupy.utils.to_json(stim, filename)[source]#

Save stimulus-dict(s) as (pretty) JSON

Parameters:
  • stim (dict) – stimulus dictionary to export.

  • filename (Path or str) – (full) path to the file to be created.

stimupy.utils.to_mat(stim, filename)[source]#

Save stimulus-dict(s) as mat-file

Parameters:
  • stim (dict) – stimulus dictionary to export.

  • filename (Path or str) – (full) path to the file to be created.

stimupy.utils.to_pickle(stim, filename)[source]#

Save stimulus-dict(s) as pickle-file

Parameters:
  • stim (dict) – stimulus dictionary to export.

  • filename (Path or str) – (full) path to the file to be created.

stimupy.utils.convolve(arr1, arr2, mode='same', axes=None, padding=False)[source]#

Convolve two N-dimensional arrays using FFT

Parameters:
  • arr1 (numpy.ndarray) – Input array 1

  • arr2 (numpy.ndarray) – Input array 2

  • mode (str {"full", "valid", "same"}, optional) – String which indicates the size of the output. The default is “same”.

  • axes (int or None (default), optional) – Axes over which to convolve. The default is over all axes

  • padding (Bool) – if True, pad array before convolving

Returns:

out – Output array

Return type:

numpy.ndarray

stimupy.utils.bandpass(visual_size=None, ppd=None, shape=None, center_frequency=None, bandwidth=None)[source]#

Function to create a 2d bandpass filter in the frequency domain

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

  • center_frequency (float) – center frequency of filter in cpd

  • bandwidth (float) – bandwidth of filter in octaves

Returns:

dict with the filter (key: “img”), and additional keys containing filter parameters

Return type:

dict[str, Any]

stimupy.utils.avg_target_values(stim, mask_key='target_mask', f_average=np.median)[source]#

Average pixel value in each target region of stimulus

Parameters:
  • stim (dict[str: Any]) – stimulus-dict with at least “img” and “mask” containing the stimulus image and integer-mask, respectively.

  • mask_key (str) – string with mask-key name

  • f_average (function, default=numpy.median) – How to average/summarise the pixels in each target region

Returns:

each entry in the list is the average value of pixels in target region, index in the list is the integer index in the mask

Return type:

list[float]

See also

avg_img_values

stimupy.utils.avg_img_values(image, mask, f_average=np.median)[source]#

Average values of pixels in image, per target region in integer mask

Values are calculated as means or medians, depending on the mode.

Parameters:
  • image (2D numpy array) – 2D numpy array containing pixel values of the image

  • mask (2D numpy array) – 2D numpy array of same size as image. Each target patch has an integer value. Each pixel inside this patch has this integer value. Patches do not need to be continuous.

  • f_average (function, default=numpy.median) – How to average/summarise the pixels in each target region

Returns:

each entry in the list is the average value of pixels in target region, index in the list is the integer index in the mask

Return type:

list[float]

See also

all_img_values

stimupy.utils.all_img_values(img, mask)[source]#

Isolate all image values/pixels, per target region specified in integer mask

Parameters:
  • img (numpy.ndarray) – Image-array of pixel values to be masked

  • mask (numpy.ndarray) – Array of same size as img. Each region-of-interest in mask is represented by an integer index. Each pixel inside this patch has this integer value. Patches do not need to be contiguous.

Returns:

Each image/element of the list is a numpy.ndarray representing an image. There is one image for each target patch in the integer mask. In each image all values are set to NaN except the ones corresponding to the target values of the respective target patch.

Return type:

list[numpy.arrays]

See also

img_values

stimupy.utils.img_values(img, mask)[source]#

Isolate only image pixels specified by a binary mask

Parameters:
  • img (numpy.ndarray) – Image-array of pixel values to be masked

  • mask (numpy.ndarray) – Array of same size as img. All non-zero pixels/values are treated as ones in a binary bit mask.

Returns:

numpy.ndarray of same size as img. All bits corresponding to zero bits in the mask are set to NaN.

Return type:

numpy.ndarray

stimupy.utils.add_padding(arr, c, val)[source]#

Remove padding by c

Parameters:
Returns:

arr – padded array

Return type:

numpy.ndarray

stimupy.utils.remove_padding(arr, c)[source]#

Remove padding by c

Parameters:
Returns:

arr – reduced array

Return type:

numpy.ndarray

stimupy.utils.pad_by_visual_size(img, padding, ppd, pad_value=0.0)[source]#

Pad image by specified degrees of visual angle

Can specify different amount (before, after) each axis.

Parameters:
  • img (numpy.ndarray) – image-array to be padded

  • padding (float, or Sequence[float, float], or Sequence[Sequence[float, float], ...]) – amount of padding, in degrees visual angle, in each direction: ((before_1, after_1), … (before_N, after_N)) unique pad widths for each axis (float,) or float is a shortcut for before = after = pad width for all axes.

  • ppd (Sequence[Number] or Sequence[Number, Number]) – pixels per degree

  • pad_value (Numeric, optional) – value to pad with, by default 0.0

Returns:

img padded by the specified amount(s)

Return type:

numpy.ndarray

stimupy.utils.pad_to_visual_size(img, visual_size, ppd, pad_value=0)[source]#

Pad image to specified visual size in degrees visual angle

Parameters:
  • img (numpy.ndarray) – image-array to be padded

  • visual_size (Sequence[int, int, ...]) – desired visual size (in degrees visual angle) of img after padding

  • ppd (Sequence[Number] or Sequence[Number, Number]) – pixels per degree

  • pad_value (Numeric, optional) – value to pad with, by default 0.0

Returns:

img padded by the specified amount(s)

Return type:

numpy.ndarray

stimupy.utils.pad_by_shape(img, padding, pad_value=0)[source]#

Pad image by specified amount(s) of pixels

Can specify different amount (before, after) each axis.

Parameters:
  • img (numpy.ndarray) – image-array to be padded

  • padding (int, or Sequence[int, int], or Sequence[Sequence[int, int], ...]) – amount of padding, in pixels, in each direction: ((before_1, after_1), … (before_N, after_N)) unique pad widths for each axis (int,) or int is a shortcut for before = after = pad width for all axes.

  • pad_val (float, optional) – value to pad with, by default 0.0

Returns:

img padded by the specified amount(s)

Return type:

numpy.ndarray

stimupy.utils.pad_to_shape(img, shape, pad_value=0)[source]#

Pad image to a resulting specified shape in pixels

Parameters:
  • img (numpy.ndarray) – image-array to be padded

  • shape (Sequence[int, int, ...]) – desired shape of img after padding

  • pad_value (float, optional) – value to pad with, by default 0.0

Returns:

img padded to specified shape

Return type:

numpy.ndarray

Raises:

ValueError – if img.shape already exceeds shape

stimupy.utils.pad_dict_by_visual_size(dct, padding, ppd, pad_value=0.0, keys=('img', '*mask'))[source]#

Pad images in dictionary by specified degrees of visual angle

Can specify different amount (before, after) each axis.

Parameters:
  • dct (dict) – dict containing image-arrays to be padded

  • padding (float, or Sequence[float, float], or Sequence[Sequence[float, float], ...]) – amount of padding, in degrees visual angle, in each direction: ((before_1, after_1), … (before_N, after_N)) unique pad widths for each axis (float,) or float is a shortcut for before = after = pad width for all axes.

  • ppd (Sequence[Number] or Sequence[Number, Number]) – pixels per degree

  • pad_value (Numeric, optional) – value to pad with, by default 0.0

  • keys (Sequence[String, String] or String) – keys in dict for images to be padded

Returns:

same as input dict but with larger key-arrays and updated keys for “visual_size” and “shape”

Return type:

dict[str, Any]

stimupy.utils.pad_dict_to_visual_size(dct, visual_size, ppd, pad_value=0, keys=('img', '*mask'))[source]#

Pad images in dictionary to specified visual size in degrees visual angle

Parameters:
  • dct (dict) – dict containing image-arrays to be padded

  • visual_size (Sequence[int, int, ...]) – desired visual size (in degrees visual angle) of img after padding

  • ppd (Sequence[Number] or Sequence[Number, Number]) – pixels per degree

  • pad_value (Numeric, optional) – value to pad with, by default 0.0

  • keys (Sequence[String, String] or String) – keys in dict for images to be padded

Returns:

same as input dict but with larger key-arrays and updated keys for “visual_size” and “shape”

Return type:

dict[str, Any]

stimupy.utils.pad_dict_by_shape(dct, padding, pad_value=0, keys=('img', '*mask'))[source]#

Pad images in dictionary by specified amount(s) of pixels Can specify different amount (before, after) each axis.

Parameters:
  • dct (dict) – dict containing image-arrays to be padded

  • padding (int, or Sequence[int, int], or Sequence[Sequence[int, int], ...]) – amount of padding, in pixels, in each direction: ((before_1, after_1), … (before_N, after_N)) unique pad widths for each axis (int,) or int is a shortcut for before = after = pad width for all axes.

  • pad_val (float, optional) – value to pad with, by default 0.0

  • keys (Sequence[String, String] or String) – keys in dict for images to be padded

Returns:

same as input dict but with larger key-arrays and updated keys for “visual_size” and “shape”

Return type:

dict[str, Any]

stimupy.utils.pad_dict_to_shape(dct, shape, pad_value=0, keys=('img', '*mask'))[source]#

Pad images in dictionary to a resulting specified shape in pixels

Parameters:
  • dct (dict) – dict containing image-arrays to be padded

  • shape (Sequence[int, int, ...]) – desired shape of img after padding

  • pad_value (float, optional) – value to pad with, by default 0.0

  • keys (Sequence[String, String] or String) – keys in dict for images to be padded

Returns:

same as input dict but with larger key-arrays and updated keys for “visual_size” and “shape”

Return type:

dict[str, Any]

Raises:

ValueError – if img.shape already exceeds shape

stimupy.utils.plot_stim(stim, mask=False, stim_name='stim', ax=None, vmin=0, vmax=1, save=None, units='deg', origin='mean')[source]#

Plot a stimulus

Plots the stimulus-array (key: “img”) directly from stim dict. Optionally also plots mask.

Parameters:
  • stim (dict) – stimulus dict containing stimulus-array (key: “img”)

  • mask (bool or str, optional) – If True, plot mask on top of stimulus image (default: False). If string is provided, plot this key from stimulus dictionary as mask

  • stim_name (str, optional) – Stimulus name used for plotting (default: “stim”)

  • ax (Axis object, optional) – If not None (default), plot in the specified Axis object

  • vmin (float, optional) – Minimal intensity value for plotting. The default is 0.

  • vmax (float, optional) – Minimal intensity value for plotting. The default is 1.

  • save (None or str, optional) – If None (default), do not save the plot. If string is provided, save plot under this name.

  • units ("px", "deg" (default), or str) – what units to put on the axes, by default degrees visual angle (“deg”). If a str other than “deg”(/”degrees”) or “px”(/”pix”/”pixels”) is passed, it must be the key to a tuple in stim

Returns:

ax – If ax was passed and plotting is None, returns updated Axis object.

Return type:

Axis object

stimupy.utils.plot_stimuli(stims, mask=False, vmin=0, vmax=1, save=None, units='deg', ncols=None, nrows=None)[source]#

Plot multiple stimuli

Plots the stimulus-arrays (keys: “img”) directly from stim dicts. Arranges stimuli in a grid. Optionally also plots masks.

Parameters:
  • stims (dict of dicts) – dictionary composed of stimulus dicts containing stimulus-array (key: “img”)

  • mask (bool or str, optional) – If True, plot mask on top of stimulus image (default: False). If string is provided, plot this key from stimulus dictionary as mask

  • vmin (float, optional) – Minimal intensity value for plotting. The default is 0.

  • vmax (float, optional) – Minimal intensity value for plotting. The default is 1.

  • save (None or str, optional) – If None (default), do not save the plot. If string is provided, save plot under this name.

  • units ("px", "deg" (default), or str) – what units to put on the axes, by default degrees visual angle (“deg”). If a str other than “deg”(/”degrees”) or “px”(/”pix”/”pixels”) is passed, it must be the key to a tuple in stim

  • ncols (int or None, optional) – number of columns in gridspec, or figure it out (default)

  • nrows (int or None, optional) – number of rows in gridspec, or figure it out (default)

stimupy.utils.plot_comparison(original_img, new_img)[source]#

Plots visual comparison of two image-arrays

Parameters:
Returns:

Figure containing plots of images, and their comparison(s)

Return type:

matplotlib.Figure

stimupy.utils.resolve(shape=None, visual_size=None, ppd=None)[source]#

Resolves the full resolution, for 2 givens and 1 unknown

A resolution consists of a visual size in degrees, a shape in pixels, and specification of the number of pixels per degree. Since there is a strict geometric relation between these, shape = visual_size * ppd, if two are given, the third can be calculated using this function.

This function resolves the resolution in both dimensions.

Parameters:
  • shape (Sequence[Number, Number], Number, or None (default)) – shape [height, width] in pixels

  • visual_size (Sequence[Number, Number], Number, or None (default)) – visual size [height, width] in degrees

  • ppd (Sequence[Number, Number], Number, or None (default)) – pixels per degree [vertical, horizontal]

Returns:

  • Shape NamedTuple, with two attributes – .height: int, height in pixels .width: int, width in pixels See validate_shape

  • Visual_size NamedTuple, with two attributes – .height: float, height in degrees visual angle .width: float, width in degrees visual angle See validate_visual_size

  • ppd NamedTuple, with two attributes – .vertical: int, vertical pixels per degree (ppd) .horizontal: int, horizontal pixels per degree (ppd) see validate_ppd

stimupy.utils.resolve_1D(length=None, visual_angle=None, ppd=None, round=True)[source]#

Resolves the full resolution, for 2 givens and 1 unknown

A resolution consists of a visual size in degrees, a shape in pixels, and specification of the number of pixels per degree. Since there is a strict geometric relation between these, shape = visual_size * ppd, if two are given, the third can be calculated using this function.

This function resolves the resolution in a single dimension.

Parameters:
  • length (Number, length in pixels, or None (default))

  • visual_angle (Number, length in degrees, or None (default))

  • ppd (Number, pixels per degree, or None (default))

Returns:

  • length (int, length in pixels)

  • visual_angle (float, length in degrees)

  • ppd (float, pixels per degree)

stimupy.utils.resolve_dict(dct)[source]#

Resolves the full resolution (“shape”, “ppd”, “visual_size”), for 2 givens and 1 unknown in the input dictionary

A resolution consists of a visual size in degrees, a shape in pixels, and specification of the number of pixels per degree. Since there is a strict geometric relation between these, shape = visual_size * ppd, if two are given, the third can be calculated using this function.

This function resolves the resolution in both dimensions.

Parameters:

dct (dict) – dictionary with at least two out the three keys: “shape”, “ppd”, “visual_size”

Return type:

Resolved dict

stimupy.utils.visual_angle_from_length_ppd(length, ppd)[source]#

Calculate visual angle (degrees) from length (pixels) and pixels-per-degree

Parameters:
  • length (int or None) – length in pixels

  • ppd (int or None) – pixels per degree

Return type:

Length (pixels) translated to visual angle (degrees)

stimupy.utils.visual_angles_from_lengths_ppd(lengths, ppd)[source]#

Calculate visual sizes (degrees) from given shapes (pixels) and pixels-per-degree

Parameters:
  • lengths (Sequence[int, int, ...] or None) – list of lengths

  • ppd (int or None) – pixels per degree

Return type:

List with lengths (pixels) translated to visual angles (degrees)

stimupy.utils.visual_size_from_shape_ppd(shape, ppd)[source]#

Calculate visual size (degrees) from given shape (pixels) and pixels-per-degree

Parameters:
  • shape (Sequence[int, int]; or int, or None) – each element has to be of type that can be cast to int, or None. See validate_shape

  • ppd (Sequence[int, int]; or int, or None) – each element has to be of type that can be cast to int, or None. See validate_ppd

Returns:

.height: float, height in degrees visual angle .width: float, width in degrees visual angle See validate_visual_size

Return type:

Visual_size NamedTuple, with two attributes

stimupy.utils.length_from_visual_angle_ppd(visual_angle, ppd, round=True)[source]#

Calculate length (pixels) from visual angle (degrees) and pixels-per-degree

Parameters:
  • visual_angle (float or None) – visual angle in degrees

  • ppd (int or None) – pixels per degree

  • round (bool) – if True, round output length to full pixels

Return type:

visual angle (degrees) translated to length (pixels)

stimupy.utils.lengths_from_visual_angles_ppd(visual_angles, ppd, round=True)[source]#

Calculate lengths (pixels) from visual angles (degrees) and pixels-per-degree

Parameters:
  • visual_angles (Sequence[float, float, ...] or None) – list of visual angles

  • ppd (int or None) – pixels per degree

  • round (bool) – if True, round output length to full pixels

Return type:

List with visual angles (degrees) translated to lengths (pixels)

stimupy.utils.shape_from_visual_size_ppd(visual_size, ppd)[source]#

Calculate shape (pixels) from given visual size (degrees) and pixels-per-degree

Parameters:
  • visual_size (Sequence[Number, Number]; or Number; or None) – each element has to be of type that can be cast to float, or None.

  • ppd (Sequence[int, int]; or int, or None) – each element has to be of type that can be cast to int, or None. See validate_ppd

Returns:

.height: int, height in pixels .width: int, width in pixels See validate_shape

Return type:

Shape NamedTuple, with two attributes

stimupy.utils.ppd_from_shape_visual_size(shape, visual_size)[source]#

Calculate resolution (ppd) from given shape (pixels) and visual size (degrees)

Parameters:
  • shape (Sequence[int, int]; or int, or None) – each element has to be of type that can be cast to int, or None. See validate_shape

  • visual_size (Sequence[Number, Number]; or Number; or None) – each element has to be of type that can be cast to float, or None. See validate_visual_size

Returns:

.vertical: int, vertical pixels per degree (ppd) .horizontal: int, horizontal pixels per degree (ppd) see validate_ppd

Return type:

ppd NamedTuple, with two attributes

stimupy.utils.ppd_from_length_visual_angle(length, visual_angle)[source]#

Calculate pixels-per-degree from length (pixels) and visual angle (degrees)

Parameters:
  • length (int or None) – length in pixels

  • visual_angle (float or None) – visual angle in degrees

Return type:

visual angle (degrees) translated to length (pixels)

stimupy.utils.compute_ppd(screen_size, resolution, distance)[source]#

Compute the pixels per degree in a presentation setup i.e., the number of pixels in the central one degree of visual angle

Parameters:
  • screen_size ((float, float)) – physical size, in whatever units you prefer, of the presentation screen

  • resolution ((float, float)) – screen resolution, in pixels, in the same direction that screen size was measured in

  • distance (float) – physical distance between the observer and the screen, in the same unit as screen_size

Returns:

ppd, the number of pixels in one degree of visual angle

Return type:

float

stimupy.utils.validate_shape(shape)[source]#

Put specification of shape (in pixels) in canonical form, if possible

Parameters:

shape (Sequence of length 1 or 2; or None) – if 2 elements: interpret as (height, width) if 1 element: use as both height and width if None: return (None, None) each element has to be of type that can be cast to int, or None.

Returns:

.height: int, height in pixels .width: int, width in pixels

Return type:

Shape NamedTuple, with two attributes

Raises:
  • ValueError – if input does not have at least 1 element

  • TypeError – if input is not a Sequence(int, int) and cannot be cast to one

  • ValueError – if input has more than 2 elements

stimupy.utils.validate_ppd(ppd)[source]#

Put specification of ppd in canonical form, if possible

Parameters:

ppd (Sequence of length 1 or 2; or None) – if 2 elements: interpret as (vertical, horizontal) if 1 element: use as both vertical and horizontal if None: return (None, None) each element has to be of type that can be cast to int, or None.

Returns:

.vertical: int, vertical pixels per degree (ppd) .horizontal: int, horizontal pixels per degree (ppd)

Return type:

ppd NamedTuple, with two attributes

Raises:
  • ValueError – if input does not have at least 1 element

  • TypeError – if input is not a Sequence(int, int) and cannot be cast to one

  • ValueError – if input has more than 2 elements

stimupy.utils.validate_visual_size(visual_size)[source]#

Put specification of visual size in canonical form, if possible

Parameters:

visual_size (Sequence of length 1 or 2; or None) – if 2 elements: interpret as (height, width) if 1 element: use as both height and width if None: return (None, None) each element has to be of type that can be cast to float, or None.

Returns:

.height: float, height in degrees visual angle .width: float, width in degrees visual angle

Return type:

Visual_size NamedTuple, with two attributes

Raises:
  • ValueError – if input does not have at least 1 element

  • TypeError – if input is not a Sequence(float, float) and cannot be cast to one

  • ValueError – if input has more than 2 elements

stimupy.utils.valid_1D(length, visual_angle, ppd)[source]#

Asserts that the combined specification of resolution is geometrically valid.

Asserts the combined specification of shape (in pixels), visual_size (deg) and ppd. If this makes sense, i.e. (roughly), int(visual_size * ppd) == shape, this function passes without output. If the specification does not make sense, raises a ResolutionError.

Note that the resolution specification has to be fully resolved, i.e., none of the parameters can be None

Parameters:
  • length (int, length in pixels)

  • visual_angle (float, size in degrees)

  • ppd (int, resolution in pixels-per-degree)

Raises:

ResolutionError – if resolution specification is invalid, i.e. (roughly), if int(visual_angle * ppd) != length

stimupy.utils.valid_resolution(shape, visual_size, ppd)[source]#

Asserts that the combined specification of resolution is geometrically valid.

Asserts the combined specification of shape (in pixels), visual_size (deg) and ppd. If this makes sense, i.e. (roughly), int(visual_size * ppd) == shape, this function passes without output. If the specification does not make sense, raises a ResolutionError.

Note that the resolution specification has to be fully resolved, i.e., none of the parameters can be/contain None

Parameters:
  • shape (2-tuple (height, width), or something that can be cast (see validate_shape))

  • visual_size (2-tuple (height, width), or something that can be cast (see validate_visual_size))

  • ppd (2-tuple (vertical, horizontal), or something that can be cast (see validate_ppd))

Raises:

ResolutionError – if resolution specification is invalid, i.e. (roughly), if int(visual_size * ppd) != shape

stimupy.utils.valid_dict(dct)[source]#

Asserts that the combined specification of resolution in dict is geometrically valid.

Asserts the combined specification of shape (in pixels), visual_size (deg) and ppd. If this makes sense, i.e. (roughly), int(visual_size * ppd) == shape, this function passes without output. If the specification does not make sense, raises a ResolutionError.

Note that the resolution specification has to be fully resolved, i.e., none of the parameters can be/contain None

Parameters:

dct (dict) – dictionary with at least the keys “shape”, “ppd”, “visual_size”

Raises:

ResolutionError – if resolution specification is invalid, i.e. (roughly), if int(visual_size * ppd) != shape

stimupy.utils.round_to_vals(arr, vals, mode='nearest')[source]#

Round each element of array to closest match in provided values

For each element in the input arr, find the closest value from the provided vals and replace the element with this closest value. If the element is equidistant to two values, the smaller value is chosen.

Parameters:
  • arr (np.ndarray) – array to be rounded

  • vals (Sequence(float, ...)) – values to which array will be rounded

  • mode (["nearest", "floor", "ceil"], optional) – rounding mode. Default is “nearest”.

Returns:

out_arr – Rounded output array

Return type:

np.ndarray

Raises:

ValueError – If mode is not one of [“nearest”, “floor”, “ceil”]. If arr contains values outside the bounds of vals when mode is “floor” or “ceil”.

Examples

>>> arr = np.array([1.1, 2.2, 3.3, 4.4, 5.5])
>>> vals = [1, 3, 5]
>>> round_to_vals(arr, vals)
array([1., 3., 3., 5., 5.])
stimupy.utils.int_factorize(n)[source]#

All integer factors of integer n

All integer factors, i.e., all integers that n is integer-divisible by. Also not a very efficient algorithm (brute force trial division), so should only be used as a helpter function.

Parameters:

n (int) – number to factorize

Returns:

set of all integer factors of n

Return type:

set

stimupy.utils.get_function_argument_names(func)[source]#

Get all argument names for a given function

Parameters:

func (function) – Get argument names from this function

Returns:

names – Tuple containing all argument names of given function

Return type:

tuple

stimupy.utils.apply_bessel(arr, order=0)[source]#

Bessel function of the first kind of real order and complex argument.

Parameters:
  • arr (np.ndarray) – Input array

  • order (float) – Order of the bessel function. Default is 0.

Returns:

out – Output array

Return type:

np.ndarray

stimupy.utils.resize_array(arr, factor)[source]#

Return a copy of an array, resized by the given factor. Every value is repeated factor[d] times along dimension d.

Parameters:
  • arr (2D array) – the array to be resized

  • factor (tuple of 2 ints) – the resize factor in the y and x dimensions

Return type:

An array of shape (arr.shape[0] * factor[0], arr.shape[1] * factor[1])

stimupy.utils.resize_dict(dct, factor, keys=('img', '*mask'))[source]#

Return a copy of an array, resized by the given factor. Every value is repeated factor[d] times along dimension d.

Parameters:
  • dct (dict) – dict containing arrays to be resized

  • factor (tuple of 2 ints) – the resize factor in the y and x dimensions

  • keys (Sequence[String, String] or String) – keys in dict for images to be padded

Returns:

same as input dict but with larger key-arrays according to “(arr.shape[0] * factor[0], arr.shape[1] * factor[1])” and updated keys for “visual_size” and “shape”

Return type:

dict[str, Any]

stimupy.utils.stack_dicts(dct1, dct2, direction='horizontal', keys=('img', '*mask'), keep_mask_indices=False)[source]#

Return a dict with resized key-arrays by the given factor. Every value is repeated factor[d] times along dimension d.

Parameters:
  • dct1 (dict) – dict containing arrays to be stacked

  • dct2 (dict) – dict containing arrays to be stacked

  • direction (str) – stack horizontal(ly) or vertical(ly) (default: horizontal)

  • keys (Sequence[String, String] or String) – keys in dict for images to be padded

Returns:

same as input dict1 but with stacked key-arrays and updated keys for “visual_size” and “shape”

Return type:

dict[str, Any]

stimupy.utils.rotate_dict(dct, nrots=1, keys=('img', '*mask'))[source]#

Return a dict with key-arrays rotated by nrots*90 degrees.

Parameters:
  • dct (dict) – dict containing arrays to be stacked

  • nrot (int) – number of rotations by 90 degrees

  • keys (Sequence[String, String] or String) – keys in dict for images to be padded

Returns:

same as input dict but with rotated key-arrays and updated keys for “visual_size” and “shape”

Return type:

dict[str, Any]

stimupy.utils.flip_dict(dct, direction='lr', keys=('img', '*mask'))[source]#

Return a dict with key-arrays rotated by nrots*90 degrees.

Parameters:
  • dct (dict) – dict containing arrays to be stacked

  • direction (str) – “lr” for left-right, “ud” for up-down flipping

  • keys (Sequence[String, String] or String) – keys in dict for images to be padded

Returns:

same as input dict but with flipped key-arrays

Return type:

dict[str, Any]

stimupy.utils.roll_dict(dct, shift, axes, keys=('img', '*mask'))[source]#

Return a dict with key-arrays rolled by shift in axes.

Parameters:
  • dct (dict) – dict containing arrays to be stacked

  • shift (int) – number of pixels by which to shift

  • axes (Number or Sequence[Number, ...]) – axes in which to shift

  • keys (Sequence[String, String] or String) – keys in dict for images to be padded

Returns:

same as input dict but with rolled key-arrays

Return type:

dict[str, Any]

stimupy.utils.strip_dict(dct, func)[source]#

Create a dictionary by stripping it from all keys that are not also an argument to the provided function

Parameters:
  • dct (dict) – dict which will be stripped

  • func (function) – Get argument names from this function

Returns:

same as input dict but stripped from all keys which are not also an argument to the provided function

Return type:

dict[str, Any]

stimupy.utils.make_two_sided(func, two_sided_params)[source]#

Create two-sided version of a stimulus function

Where (some) parameters can be specified separately for each side. These parameters should then be specified as a 2-Sequence (2-ple, list of len=2), where entry [0] is the parameter value for left side, and [1] for right side. This means that if the kwarg takes a Sequence itself, e.g., intensities, then the two-sided specification must be, e.g., ((int_left_0, int_left_1), (int_right_0, int_right_1))

Will be left- and right-sided.

Parameters:
  • func (function) – stimulus function to double

  • two_sided_params (Sequence[str]) – names of parameters (kwargs) of func that can be specified separately for each side of the display.

Returns:

two-sided version of stimulus function

Return type:

function

stimupy.utils.permutate_params(params)[source]#

Generate all possible parameter combinations for a stimulus function.

Takes a dictionary of stimulus parameters, where each parameter value is provided as a sequence (e.g., list, tuple). Returns a list of dictionaries, each representing one unique combination of parameter values. This is useful for systematically exploring a stimulus parameter space (e.g., in 1D, 2D, or higher dimensions).

Parameters:

params (dict) –

Dictionary mapping parameter names (str) to sequences of possible values. Each sequence will be iterated over to form combinations. Example:

{
    "frequency": [1, 2, 4],
    "sigma": [0.05, 0.1]
}

Returns:

A list where each element is a dictionary mapping parameter names to specific values, corresponding to one combination from the Cartesian product of all provided sequences. Example output:

[
    {"frequency": 1, "sigma": 0.05},
    {"frequency": 1, "sigma": 0.1},
    {"frequency": 2, "sigma": 0.05},
    ...
]

Return type:

list of dict

Raises:

ValueError – If params is not a dictionary.

stimupy.utils.create_stimspace_stimuli(stimulus_function, permutations_dicts, title_params=None)[source]#

Generate stimuli for all parameter combinations in a stimspace.

Given a callable stimulus_function and a list of parameter combinations (as produced by [utils.permutate_params](utils.permutate_params)), this function generates and returns all corresponding stimulus images. Optionally, specific parameters can be included in the stimulus names for easier identification in plots or debugging.

Parameters:
  • stimulus_function (callable) – A stimulus-generating function that accepts keyword arguments matching the keys in permutations_dicts.

  • permutations_dicts (list of dict) – A list of parameter dictionaries, each representing one combination of stimulus parameters to be passed to stimulus_function. Typically obtained from [utils.permutate_params](utils.permutate_params).

  • title_params (str or list of str, optional) – Name(s) of parameters to display in the dictionary keys for the output. - If a string, it is interpreted as a single parameter name. - If a list, multiple parameter values will be included in the name. - If None (default), keys will be simple integer indices.

Returns:

Dictionary mapping descriptive keys to the generated stimulus outputs. Keys are either: - String representations of selected title_params and their values. - Sequential integer strings if title_params is None.

Return type:

dict

Raises:

ValueError – If stimulus_function is not callable.

Examples

>>> from stimupy.stimuli.gabors import gabor
>>> from stimupy.utils import permutate_params, create_stimspace_stimuli
>>> params = {
...     "visual_size": [1.],
...     "ppd": [50],
...     "sigma": [0.1, 0.2],
...     "frequency": [2, 4]
... }
>>> permuted = permutate_params(params)
>>> stimspace = create_stimspace_stimuli(
...     stimulus_function=gabor,
...     permutations_dicts=permuted,
...     title_params=["sigma", "frequency"]
... )
>>> list(stimspace.keys())
['sigma=0.1 frequency=2 ', 'sigma=0.1 frequency=4 ',
 'sigma=0.2 frequency=2 ', 'sigma=0.2 frequency=4 ']