pulse2percept.utils

Various utility and helper functions.

base PrettyPrint, Frozen, Data, bijective26_name, cached, gamma, unique
constants DT, MIN_AMP, VIDEO_BLOCK_SIZE, ZORDER
geometry cart2pol, pol2cart, delta_angle
array is_strictly_increasing, sample, unique, radial_mask
images center_image, scale_image, shift_image, trim_image
convolution conv, center_vector
optimize bisect
stats r2_score, circ_r2_score
parallel parfor
deprecation deprecated, is_deprecated
three_dim parse_3d_orient
pulse2percept.utils.bijective26_name(i)[source]

Bijective base-26 numeration

Creates the “alphabetic number” for a given integer i following bijective base-26 numeration: A-Z, AA-AZ, BA-BZ, … ZA-ZZ, AAA-AAZ, ABA-ABZ, …

Parameters:i (int) – Regular number to be translated into an alphabetic number
Returns:name (string) – Alphabetic number

Examples

>>> bijective26_name(0)
'A'
>>> bijective26_name(26)
'AA'
pulse2percept.utils.bisect(y_target, func, args=None, kwargs=None, x_lo=0, x_hi=1, x_tol=1e-06, y_tol=0.001, max_iter=100)[source]

Binary search (bisection method) to find x value that gives y_target

For a function y = func(x, *args, **kwargs), returns x_opt for which func(x_opt, *args, **kwargs) is approximately equal to y_target.

New in version 0.7.

Parameters:
  • y_target (float) – Target y value
  • args, kwargs (func,) – The function to call along with its positional and keyword arguments
  • x_hi (x_lo,) – Lower and upper bounds on x
  • x_tol (float, optional) – Search will stop if the range of candidate x values is smaller than x_tol
  • y_tol (float, optional) – Search will stop if y is within y_tol of y_target
  • max_iter (int, optional) – Maximum number of iterations to run
Returns:

x_opt (float) – The x value such that func(x_opt) $approx$ y_target

Notes

  • Assumes func is a monotonously increasing function of x.
  • Does not require x_lo and x_hi to have opposite signs as in the conventional bisection method.
pulse2percept.utils.cached(f)[source]

Cached property decorator

Decorator can be added to the property of a class to maintain a cache. This is useful when computing the property is computationall expensive. The property will only be computed on first call, and subsequent calls will refer to the cached result.

Important

When making use of a cached property, the class should also maintain a _cache_active flag set to True or False.

New in version 0.7.

pulse2percept.utils.cart2pol(x, y)[source]

Convert Cartesian to polar coordinates

Parameters:y (x,) – The x,y Cartesian coordinates
Returns:theta, rho (scalar or array-like) – The transformed polar coordinates
pulse2percept.utils.center_image(img, loc=None)[source]

Center the image foreground

This function shifts the center of mass (CoM) to the image center. The background of the image is assumed to be black (0 grayscale).

New in version 0.7.

Parameters:
  • img (ndarray) – A 2D NumPy array representing a (height, width) grayscale image, or a 3D NumPy array representing a (height, width, channels) RGB image
  • loc ((col, row), optional) – The pixel location at which to center the CoM. By default, shifts the CoM to the image center.
Returns:

img (ndarray) – A copy of the image centered at loc

pulse2percept.utils.center_vector(vec, newlen)[source]

Returns the center newlen portion of a vector.

Adapted from scipy.signal.signaltools._centered: github.com/scipy/scipy/blob/v0.18.0/scipy/signal/signaltools.py#L236-L243

pulse2percept.utils.circ_r2_score(y_true, y_pred)[source]

Calculate circular R² (the coefficient of determination)

The best possible score is 1.0, lower values are worse.

New in version 0.7.

Parameters:
  • y_true (array-like) – Ground truth (correct) target values.
  • y_pred (array-like) – Estimated target values.
Returns:

z (float) – The R² score

Notes

  • If the ground-truth data has zero variance, R² will be zero.
  • This is not a symmetric function
pulse2percept.utils.conv(data, kernel, mode='full', method='fft')[source]

Convoles data with a kernel using either FFT or sparse convolution

This function convolves data with a kernel, relying either on the fast Fourier transform (FFT) or a sparse convolution function.

Parameters:
  • data (array_like) – First input, typically the data array
  • kernel (array_like) – Second input, typically the kernel
  • mode (str {'full', 'valid', 'same'}, optional, default: 'full') –

    A string indicating the size of the output:

    • full:
      The output is the full discrete linear convolution of the inputs.
    • valid:
      The output consists only of those elements that do not rely on zero-padding.
    • same:
      The output is the same size as data, centered with respect to the ‘full’ output.
  • method (str {'fft', 'sparse'}, optional, default: 'fft') –

    A string indicating the convolution method:

    • fft:
      Use the fast Fourier transform (FFT).
    • sparse:
      Use the sparse convolution.
class pulse2percept.utils.Data(data, axes=None, metadata=None)[source]

N-dimensional data container

New in version 0.6.

Parameters:
  • data (np.ndarray) – An N-dimensional NumPy array containing the data to store
  • axes (dict or tuple, optional) – For each dimension in data, specify axis name and labels.
  • metadata (dict, optional) – A dictionary that can store arbitrary metadata
pulse2percept.utils.delta_angle(source_angle, target_angle, hi=6.283185307179586)[source]

Returns the signed difference between two angles (rad)

The difference is calculated as target_angle - source_angle. The difference will thus be positive if target_angle > source_angle.

New in version 0.7.

Parameters:
  • target_angle (source_angle,) – Input arrays with circular data in the range [0, hi]
  • hi (float, optional) – Sets the upper bounds of the range (e.g., 2*np.pi or 360). Lower bound is always 0
Returns:

The signed difference target_angle - source_angle in [0, hi]

class pulse2percept.utils.deprecated(alt_func=None, deprecated_version=None, removed_version=None)[source]

Decorator to mark deprecated functions and classes with a warning.

Parameters:
  • alt_func (str) – If given, tell user what function to use instead.
  • deprecated_version (float or str) – The package version in which the function/class was first marked as deprecated.
  • removed_version (float or str) – The package version in which the deprecated function/class will be removed.
exception pulse2percept.utils.FreezeError[source]

Exception class used to raise when trying to add attributes to Frozen Classes of type Frozen do not allow for new attributes to be set outside the constructor.

name

attribute name

obj

object

with_traceback()

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

class pulse2percept.utils.Frozen[source]

“Frozen” classes (and subclasses) do not allow for new class attributes to be set outside the constructor. On attempting to add a new attribute, the class will raise a FreezeError.

pulse2percept.utils.gamma(n, tau, tsample, tol=0.01)[source]

Returns the impulse response of n cascaded leaky integrators

This function calculates the impulse response of n cascaded leaky integrators with constant of proportionality 1/tau: y = (t/theta).^(n-1).*exp(-t/theta)/(theta*factorial(n-1))

Parameters:
  • n (int) – Number of cascaded leaky integrators
  • tau (float) – Decay constant of leaky integration (seconds). Equivalent to the inverse of the constant of proportionality.
  • tsample (float) – Sampling time step (seconds).
  • tol (float) – Cut the kernel to size by ignoring function values smaller than a fraction tol of the peak value.
pulse2percept.utils.parfor(func, in_list, out_shape=None, n_jobs=-1, engine=None, scheduler='threading', func_args=[], func_kwargs={})[source]

Parallel for loop for NumPy arrays

Parameters:
  • func (callable) – The function to apply to each item in the array. Must have the form: func(arr, idx, *args, *kwargs) where arr is an ndarray and idx is an index into that array (a tuple). The Return of func needs to be one item (e.g. float, int) per input item.
  • in_list (list) – All legitimate inputs to the function to operate over.
  • out_shape (int or tuple of ints, optional) – If set, output will be reshaped accordingly. The new shape should be compatible with the original shape. If an integer, then the result will be a 1-D array of that length. One shape dimension can be -1. In this case, the value is inferred from the length of the array and remaining dimensions.
  • n_jobs (integer, optional, default: 1) – The number of jobs to perform in parallel. -1 to use all cpus
  • engine (str, optional, default: JobLib or Dask (if available), else serial) – {‘dask’, ‘joblib’, ‘serial’} The last one is useful for debugging – runs the code without any parallelization.
  • scheduler (str, optional, default: 'threading') – Which scheduler to use (irrelevant for ‘serial’ engine): - ‘threading’: a scheduler backed by a thread pool - ‘multiprocessing’: a scheduler backed by a process pool
  • *func_args (list, optional) – Positional arguments to func
  • **func_kwargs (dict, optional) – Keyword arguments to func
Returns:

ndarray – NumPy array of identical shape to arr

Note

Equivalent to pyAFQ version (blob e20eaa0 from June 3, 2016): https://github.com/arokem/pyAFQ/blob/master/AFQ/utils/parallel.py

pulse2percept.utils.parse_3d_orient(orient, orient_mode='direction')[source]

Parse the orient parameter Given either a 3D rotation matrix, vector of angles of rotation, or direction vector, this function will calculate and return the all three representations.

Parameters:
  • orient (np.ndarray with shape (3) or (3, 3)) –

    Orientation of the electrode in 3D space. orient can be:

    • A length 3 vector specifying the direction that the thread should extend in (if orient_mode == ‘direction’)
    • A list of 3 angles, (r_x, r_y, r_z), specifying the rotation in degrees about each axis (x rotation performed first). (If orient_mode == ‘angle’)
    • 3D rotation matrix, specifying the direction that the thread should extend in (i.e. a unit vector in the z direction will point in the direction after being rotated by this matrix)
  • orient_mode (str) – If ‘direction’, orient is a vector specifying the direction that the electrode should extend in. If ‘angle’, orient is a vector of 3 angles, (r_x, r_y, r_z), specifying the rotation in degrees about each axis (starting with x). Does not apply if orient is a 3D rotation matrix.
Returns:

  • rot (np.ndarray with shape (3, 3)) – Rotation matrix
  • angles (np.ndarray with shape (3)) – Angles of rotation (degrees) about each axis (x, y, z). Note that this mapping is not unique. This function will always set the rotation about the x axis to be 0, meaning that the returned coordinates will match spherical coordinates (i.e. r_y is phi and r_z is theta).
  • direction (np.ndarray with shape (3)) – Unit vector specifying the direction of the orientation.

pulse2percept.utils.pol2cart(theta, rho)[source]

Convert polar to Cartesian coordinates

Parameters:rho (theta,) – The polar coordinates
Returns:x, y (scalar or array-like) – The transformed Cartesian coordinates
class pulse2percept.utils.PrettyPrint[source]

An abstract class that provides a way to prettyprint all class attributes, inspired by scikit-learn.

Classes deriving from PrettyPrint are required to implement a _pprint_params method that returns a dictionary containing all the attributes to prettyprint.

Examples

>>> from pulse2percept.utils import PrettyPrint
>>> class MyClass(PrettyPrint):
...     def __init__(self, a, b):
...         self.a = a
...         self.b = b
...
...     def _pprint_params(self):
...         return {'a': self.a, 'b': self.b}
>>> MyClass(1, 2)
MyClass(a=1, b=2)
pulse2percept.utils.r2_score(y_true, y_pred)[source]

Calculate R² (the coefficient of determination)

The r2_score function computes the coefficient of determination, usually denoted as R².

The best possible score is 1.0, lower values are worse.

It represents the proportion of variance (of y) that has been explained by the independent variables in the model. It provides an indication of goodness of fit and therefore a measure of how well unseen samples are likely to be predicted by the model.

If \(\hat{y}_i\) is the predicted value of the \(i\)-th sample and \(y_i\) is the corresponding true value for total \(n\) samples, the estimated R² is defined as:

\[R^2(y, \hat{y}) = 1 - \frac{\sum_{i=1}^{n} (y_i - \hat{y}_i)^2}{\sum_{i=1}^{n} (y_i - \bar{y})^2}\]

where \(\bar{y} = \frac{1}{n} \sum_{i=1}^{n} y_i\) and \(\sum_{i=1}^{n} (y_i - \hat{y}_i)^2 = \sum_{i=1}^{n} \epsilon_i^2\).

Note that r2_score calculates unadjusted R² without correcting for bias in sample variance of y.

New in version 0.7.

Parameters:
  • y_true (array-like) – Ground truth (correct) target values.
  • y_pred (array-like) – Estimated target values.
Returns:

z (float) – The R² score

Notes

  • If the ground-truth data has zero variance, R² will be zero.
  • This is not a symmetric function
pulse2percept.utils.sample(sequence, k=1)[source]

Randomly selects k elements from a sequence

New in version 0.8.

Parameters:
  • sequence (list, tuple, np.ndarray) – A sequence like a list, a tuple, an array, etc.
  • k (int or float, optional) – If an integer, the number of elements to pick If a float between 0 and 1, the fraction of elements to pick
Returns:

sample (list) – List of randomly chosen elements from the sequence

pulse2percept.utils.scale_image(img, scaling_factor)[source]

Scale the image foreground

This function scales the image foreground by a factor. The background of the image is assumed to be black (0 grayscale).

New in version 0.7.

Parameters:
  • img (ndarray) – A 2D NumPy array representing a (height, width) grayscale image, or a 3D NumPy array representing a (height, width, channels) RGB image
  • scaling_factor (float) – Factory by which to scale the image
Returns:

img (ndarray) – A copy of the scaled image

pulse2percept.utils.shift_image(img, shift_cols, shift_rows)[source]

Shift the image foreground

This function shifts the center of mass (CoM) of the image by the specified number of rows and columns. The background of the image is assumed to be black (0 grayscale).

New in version 0.7.

Parameters:
  • img (ndarray) – A 2D NumPy array representing a (height, width) grayscale image, or a 3D NumPy array representing a (height, width, channels) RGB image
  • shift_cols (float) – Number of columns by which to shift the CoM. Positive: to the right, negative: to the left
  • shift_rows (float) – Number of rows by which to shift the CoM. Positive: downward, negative: upward
Returns:

img (ndarray) – A copy of the shifted image

pulse2percept.utils.trim_image(img, tol=0, return_coords=False)[source]

Remove any black border around the image

New in version 0.7.

Parameters:
  • img (ndarray) – A 2D NumPy array representing a (height, width) grayscale image, or a 3D NumPy array representing a (height, width, channels) RGB image. If an alpha channel is present, the image will first be blended with black.
  • tol (float, optional) – Any pixels with gray levels > tol will be trimmed.
  • return_coords (bool, optional) – If True, will also return the row and column coordinates of the retained image
Returns:

  • img (ndarray) – A copy of the image with trimmed borders.
  • (row_start, row_end) (tuple, optional) – The range of row indices in the trimmed image (returned only if return_coords is True)
  • (col_start, col_end) (tuple, optional) – The range of column indices in the trimmed image (returned only if return_coords is True)

pulse2percept.utils.unique(a, tol=1e-06, return_index=False)[source]

Find the unique elements of a sorted 1D array

Special case of numpy.unique (array is flat, sortened) with a tolerance level tol.

New in version 0.7.

Parameters:
  • a (array_like) – Input array: must be sorted, and will be flattened if it is not already 1-D.
  • tol (float, optional) – If the difference between two elements in the array is smaller than tol, the two elements are considered equal.
  • return_index (bool, optional) – If True, also return the indices of a that result in the unique array.
Returns:

  • unique (ndarray) – The sorted unique values
  • unique_indices (ndarray, optional) – The indices of the first occurrences of the unique values in the original array. Only provided if return_index is True.