utils#
Modules#
Functions#
|
Transform luminance values into Munsell values. |
|
Transform Munsell values to luminance values. |
|
Applies a transparency to image at specified (mask) location if provided |
|
Adapt Michelson contrast of image |
|
Adapt rms contrast of image (std) |
|
Adapt normalized rms contrast of image (std divided by mean) |
|
Adapt intensity range of image |
|
Adapt Michelson contrast of image in dict |
|
Adapt rms contrast of image (std) |
|
Adapt normalized rms contrast of image (std divided by mean) |
|
Adapt intensity range of image |
|
Hash (md5) array values, and return hex-checksum |
|
Save a 2D numpy array as a grayscale image file. |
|
Save a numpy array to npy-file. |
|
Save a numpy array to a mat-file. |
|
Save a numpy array to a pickle-file. |
|
Hash (md5) values of arrays specified in keys, and save only the hex |
|
Save stimulus-dict(s) as (pretty) JSON |
|
Save stimulus-dict(s) as mat-file |
|
Save stimulus-dict(s) as pickle-file |
|
Convolve two N-dimensional arrays using FFT |
|
Function to create a 2d bandpass filter in the frequency domain |
|
Average pixel value in each target region of stimulus |
|
Average values of pixels in image, per target region in integer mask |
|
Isolate all image values/pixels, per target region specified in integer mask |
|
Isolate only image pixels specified by a binary mask |
|
Remove padding by c |
|
Remove padding by c |
|
Pad image by specified degrees of visual angle |
|
Pad image to specified visual size in degrees visual angle |
|
Pad image by specified amount(s) of pixels |
|
Pad image to a resulting specified shape in pixels |
|
Pad images in dictionary by specified degrees of visual angle |
|
Pad images in dictionary to specified visual size in degrees visual angle |
|
Pad images in dictionary by specified amount(s) of pixels Can specify different amount (before, after) each axis. |
|
Pad images in dictionary to a resulting specified shape in pixels |
|
Plot a stimulus |
|
Plot multiple stimuli |
|
Plots visual comparison of two image-arrays |
|
Resolves the full resolution, for 2 givens and 1 unknown |
|
Resolves the full resolution, for 2 givens and 1 unknown |
|
Resolves the full resolution ("shape", "ppd", "visual_size"), for 2 givens and 1 unknown in the input dictionary |
|
Calculate visual angle (degrees) from length (pixels) and pixels-per-degree |
|
Calculate visual sizes (degrees) from given shapes (pixels) and pixels-per-degree |
|
Calculate visual size (degrees) from given shape (pixels) and pixels-per-degree |
|
Calculate length (pixels) from visual angle (degrees) and pixels-per-degree |
|
Calculate lengths (pixels) from visual angles (degrees) and pixels-per-degree |
|
Calculate shape (pixels) from given visual size (degrees) and pixels-per-degree |
|
Calculate resolution (ppd) from given shape (pixels) and visual size (degrees) |
|
Calculate pixels-per-degree from length (pixels) and visual angle (degrees) |
|
Compute the pixels per degree in a presentation setup i.e., the number of pixels in the central one degree of visual angle |
|
Put specification of shape (in pixels) in canonical form, if possible |
|
Put specification of ppd in canonical form, if possible |
|
Put specification of visual size in canonical form, if possible |
|
Asserts that the combined specification of resolution is geometrically valid. |
|
Asserts that the combined specification of resolution is geometrically valid. |
|
Asserts that the combined specification of resolution in dict is geometrically valid. |
|
Round each element of array to closest match in provided values |
All integer factors of integer n |
|
Get all argument names for a given function |
|
|
Bessel function of the first kind of real order and complex argument. |
|
Return a copy of an array, resized by the given factor. |
|
Return a copy of an array, resized by the given factor. |
|
Return a dict with resized key-arrays by the given factor. |
|
Return a dict with key-arrays rotated by nrots*90 degrees. |
|
Return a dict with key-arrays rotated by nrots*90 degrees. |
|
Return a dict with key-arrays rolled by shift in axes. |
|
Create a dictionary by stripping it from all keys that are not also an argument to the provided function |
|
Create two-sided version of a stimulus function |
|
Generate all possible parameter combinations for a 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:
- 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:
- 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:
- 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
- stimupy.utils.adapt_michelson_contrast_dict(stim, michelson_contrast, mean_luminance=None)[source]#
Adapt Michelson contrast of image in dict
- Parameters:
- Returns:
dict with the stimulus (key: “img”), Michelson contrast (key: “michelson_contrast”), mean luminance (“mean_luminance”) and additional keys containing stimulus parameters
- Return type:
- stimupy.utils.adapt_rms_contrast_dict(stim, rms_contrast, mean_luminance=None)[source]#
Adapt rms contrast of image (std)
- Parameters:
- Returns:
dict with the stimulus (key: “img”), RMS contrast (key: “rms_contrast”), mean luminance (“mean_luminance”) and additional keys containing stimulus parameters
- Return type:
- 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:
- Returns:
dict with the stimulus (key: “img”), RMS contrast (key: “rms_contrast”), mean luminance (“mean_luminance”) and additional keys containing stimulus parameters
- Return type:
- stimupy.utils.adapt_intensity_range_dict(stim, intensity_min=0.0, intensity_max=1.0)[source]#
Adapt intensity range of image
- Parameters:
- Returns:
dict with the stimulus (key: “img”), intensity range (key: “intensity_range”), and additional keys containing stimulus parameters
- Return type:
- 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:
- 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
- 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:
- 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:
- 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:
- 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:
See also
- 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:
See also
- 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
- 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:
- stimupy.utils.add_padding(arr, c, val)[source]#
Remove padding by c
- Parameters:
arr (numpy.ndarray) – input array
c (int) – padding amount
val (float) – background value
- Returns:
arr – padded array
- Return type:
- stimupy.utils.remove_padding(arr, c)[source]#
Remove padding by c
- Parameters:
arr (numpy.ndarray) – input array
c (int) – padding amount.
- Returns:
arr – reduced array
- Return type:
- 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:
See also
- 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:
See also
- 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:
- 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:
- 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:
- 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:
- 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:
- 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:
- Returns:
same as input dict but with larger key-arrays and updated keys for “visual_size” and “shape”
- Return type:
- 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:
original_img (numpy.ndarray) – original image-array
new_img (numpy.ndarray) – new image-array
- 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
See also
- stimupy.utils.visual_angle_from_length_ppd(length, ppd)[source]#
Calculate visual angle (degrees) from length (pixels) and pixels-per-degree
- stimupy.utils.visual_angles_from_lengths_ppd(lengths, ppd)[source]#
Calculate visual sizes (degrees) from given shapes (pixels) and pixels-per-degree
- stimupy.utils.visual_size_from_shape_ppd(shape, ppd)[source]#
Calculate visual size (degrees) from given shape (pixels) and pixels-per-degree
- Parameters:
- 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
- stimupy.utils.lengths_from_visual_angles_ppd(visual_angles, ppd, round=True)[source]#
Calculate lengths (pixels) from visual angles (degrees) and pixels-per-degree
- stimupy.utils.shape_from_visual_size_ppd(visual_size, ppd)[source]#
Calculate shape (pixels) from given visual size (degrees) and pixels-per-degree
- Parameters:
- 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:
- 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)
- 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:
- 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
- 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.
- 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:
- 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:
- 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:
- 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:
- Returns:
same as input dict1 but with stacked key-arrays and updated keys for “visual_size” and “shape”
- Return type:
- stimupy.utils.rotate_dict(dct, nrots=1, keys=('img', '*mask'))[source]#
Return a dict with key-arrays rotated by nrots*90 degrees.
- Parameters:
- Returns:
same as input dict but with rotated key-arrays and updated keys for “visual_size” and “shape”
- Return type:
- stimupy.utils.flip_dict(dct, direction='lr', keys=('img', '*mask'))[source]#
Return a dict with key-arrays rotated by nrots*90 degrees.
- stimupy.utils.roll_dict(dct, shift, axes, keys=('img', '*mask'))[source]#
Return a dict with key-arrays rolled by shift in axes.
- Parameters:
- Returns:
same as input dict but with rolled key-arrays
- Return type:
- 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
- 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:
- 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:
- 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 ']