pulse2percept.utils

Various utility and helper functions.

base

PrettyPrint, Frozen, Parametrized, Data, bijective26_name, cached, gamma, unique

constants

DT, MIN_AMP, MS_PER_S, UM_PER_MM, VIDEO_BLOCK_SIZE, ZORDER

geometry

cart2pol, pol2cart, delta_angle

array

is_strictly_increasing, sample, unique, radial_mask

animation

HTMLAnimation

images

center_image, scale_image, shift_image, trim_image

convolution

conv, center_vector

optimize

bisect

stats

r2_score, circ_r2_score

deprecation

deprecated, deprecate_parameter, deprecated_alias, rename_parameter, 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 – Alphabetic number

Return type:

string

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.

Added in version 0.7.

Parameters:
  • y_target (float) – Target y value

  • func (optional) – The function to call along with its positional and keyword arguments

  • args (optional) – The function to call along with its positional and keyword arguments

  • kwargs (optional) – The function to call along with its positional and keyword arguments

  • x_lo (float, optional) – Lower and upper bounds on x

  • x_hi (float, optional) – 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 – The x value such that func(x_opt) $approx$ y_target

Return type:

float

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.

Added in version 0.7.

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

Convert Cartesian to polar coordinates

Parameters:
  • x (scalar or array-like) – The x,y Cartesian coordinates

  • y (scalar or array-like) – The x,y Cartesian coordinates

Returns:

theta, rho – The transformed polar coordinates

Return type:

scalar or array-like

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).

Added 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 – A copy of the image centered at loc

Return type:

ndarray

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.

Added in version 0.7.

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

  • y_pred (array-like) – Estimated target values.

Returns:

z – The R² score

Return type:

float

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

Added 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.

Added in version 0.7.

Parameters:
  • source_angle (array_like) – Input arrays with circular data in the range [0, hi]

  • target_angle (array_like) – 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

Return type:

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

class pulse2percept.utils.deprecate_parameter(name, deprecated_version=None, removed_version=None, addendum=None)[source]

Decorator to mark a single function or method parameter as deprecated

The decorated callable keeps accepting the parameter, so that existing code does not break, but the value is ignored. A DeprecationWarning is raised whenever the parameter is passed explicitly, whether by keyword or by position.

Use this when a parameter is going away but the callable itself stays. To deprecate an entire function, class, or property, use deprecated instead. To keep a parameter that is merely being renamed working under its old name, use rename_parameter instead.

Added in version 0.9.1.

Note

This decorator only produces the warning. Document the parameter itself by adding a .. deprecated:: directive to its entry in the docstring’s Parameters section, which is where numpydoc expects it.

See also

Modeled on matplotlib’s matplotlib._api.delete_parameter.

Parameters:
  • name (str) – Name of the deprecated parameter. Must appear in the signature of the decorated callable, otherwise a ValueError is raised at decoration time (which catches the parameter being renamed or dropped).

  • deprecated_version (float or str) – The package version in which the parameter was first marked as deprecated.

  • removed_version (float or str) – The package version in which the parameter will be removed.

  • addendum (str, optional) – Text appended to the warning, e.g. to spell out what the parameter used to do or how the behavior differs now that it is ignored.

Examples

>>> from pulse2percept.utils import deprecate_parameter
>>> @deprecate_parameter('engine', deprecated_version='0.9.1',
...                      removed_version='0.10.0')
... def predict(data, engine=None):
...     return data
>>> predict([1, 2])  # no warning
[1, 2]
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.

class pulse2percept.utils.deprecated_alias(new_name, deprecated_version=None, removed_version=None)[source]

Class attribute that keeps a renamed parameter usable under its old name

Assign one in the class body, under the old name, to a Parametrized subclass whose parameters live in get_default_params rather than in a signature:

class MyModel(BaseModel):

    axlambda = deprecated_alias('lam', deprecated_version='0.10.0')

    def get_default_params(self):
        return {'lam': 500}

Reading or writing model.axlambda then reads or writes model.lam and raises a DeprecationWarning. The alias also registers itself in the owner’s _renamed_params, which is what lets the constructor, set_params and build keep accepting the old name as a keyword argument (see rename_deprecated_params()).

To rename a parameter that is declared in a signature, use rename_parameter instead.

Added in version 0.10.0.

Note

Document the rename by adding a .. versionchanged:: directive to the new parameter’s entry in the docstring’s Parameters section. The old name has no entry of its own, since nothing should be written against it any more.

Parameters:
  • new_name (str) – Name of the parameter that replaces the alias.

  • deprecated_version (float or str) – The package version in which the old name was first marked as deprecated.

  • removed_version (float or str) – The package version in which the old name will stop working.

pulse2percept.utils.frame_interval(time, fps=None, tol=0.01)[source]

Determine the delay between two frames of an animation

Added in version 0.10.0.

Parameters:
  • time (array_like) – The time points of the animation (in ms)

  • fps (float or None) – Frames per second. If None, the interval is inferred from time, which is not supported for a non-homogeneous time axis.

  • tol (float, optional) – Tolerance within which two time steps count as equal

Returns:

interval – The delay between two frames (in ms). A single-frame animation has no time step of its own and falls back on SINGLE_FRAME_INTERVAL.

Return type:

float

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.

add_note()

Exception.add_note(note) – add a note to the exception

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.

class pulse2percept.utils.HTMLAnimation(fig, func, frames=None, *args, image=None, frame_data=None, labels=None, fmt='jpg', **kwargs)[source]

A FuncAnimation with a fast player

Behaves exactly like FuncAnimation (including save and to_html5_video), but renders to HTML through a self-contained JavaScript player instead of Matplotlib’s to_jshtml. Instead of re-rendering the whole figure once per frame, the static parts of the figure are rendered once and all frames are shipped as a single color-mapped sprite sheet.

Added in version 0.10.0.

Parameters:
  • fig – Passed to FuncAnimation

  • func – Passed to FuncAnimation

  • frames – Passed to FuncAnimation

  • *args – Passed to FuncAnimation

  • **kwargs – Passed to FuncAnimation

  • image (matplotlib.image.AxesImage) – The image artist that is updated by func. Its position, colormap, and normalization determine how the frames are drawn

  • frame_data (ndarray) – Either (Y, X, T) scalar data, (Y, X, 3, T) RGB data, or (Y, X, 4, T) RGBA data, matching what func displays in image

  • labels (list of str or None) – Per-frame titles. If None, the title is left alone

  • fmt ({'jpg', 'png'}, optional) – Whether to encode the frames as JPEG or PNG. JPEG is typically an order of magnitude smaller, PNG is lossless

Notes

  • Frames are quantized to 256 levels and embedded at most at the size at which they are displayed, exactly like Matplotlib would rasterize them.

  • The per-frame title is drawn by the browser, so it uses DejaVu Sans if available and falls back to the default sans-serif font otherwise.

to_jshtml(fps=None, embed_frames=True, default_mode=None)[source]

Generate an HTML representation of the animation

Parameters:
  • fps (float or None) – Frames per second. If None, uses the animation’s interval.

  • embed_frames (bool) – Unused; frames are always embedded.

  • default_mode ({'loop', 'once', 'reflect'} or None) – What the animation should do once it has played through. If None, uses ‘loop’ or ‘once’, depending on repeat.

new_frame_seq()[source]

Return a new sequence of frame information.

new_saved_frame_seq()[source]

Return a new sequence of saved/cached frame information.

pause()[source]

Pause the animation.

resume()[source]

Resume the animation.

save(filename, writer=None, fps=None, dpi=None, codec=None, bitrate=None, extra_args=None, metadata=None, extra_anim=None, savefig_kwargs=None, *, progress_callback=None)[source]

Save the animation as a movie file by drawing every frame.

Parameters:
  • filename (str) – The output filename, e.g., mymovie.mp4.

  • writer (MovieWriter or str, default: :rc:`animation.writer`) – A MovieWriter instance to use or a key that identifies a class to use, such as ‘ffmpeg’.

  • fps (int, optional) – Movie frame rate (per second). If not set, the frame rate from the animation’s frame interval.

  • dpi (float, default: :rc:`savefig.dpi`) – Controls the dots per inch for the movie frames. Together with the figure’s size in inches, this controls the size of the movie.

  • codec (str, default: :rc:`animation.codec`.) – The video codec to use. Not all codecs are supported by a given MovieWriter.

  • bitrate (int, default: :rc:`animation.bitrate`) – The bitrate of the movie, in kilobits per second. Higher values means higher quality movies, but increase the file size. A value of -1 lets the underlying movie encoder select the bitrate.

  • extra_args (list of str or None, optional) – Extra command-line arguments passed to the underlying movie encoder. These arguments are passed last to the encoder, just before the output filename. The default, None, means to use :rc:`animation.[name-of-encoder]_args` for the builtin writers.

  • metadata (dict[str, str], default: {}) – Dictionary of keys and values for metadata to include in the output file. Some keys that may be of use include: title, artist, genre, subject, copyright, srcform, comment.

  • extra_anim (list, default: []) – Additional Animation objects that should be included in the saved movie file. These need to be from the same .Figure instance. Also, animation frames will just be simply combined, so there should be a 1:1 correspondence between the frames from the different animations.

  • savefig_kwargs (dict, default: {}) – Keyword arguments passed to each ~.Figure.savefig call used to save the individual frames.

  • progress_callback (function, optional) –

    A callback function that will be called for every frame to notify the saving progress. It must have the signature

    def func(current_frame: int, total_frames: int) -> Any
    

    where current_frame is the current frame number and total_frames is the total number of frames to be saved. total_frames is set to None, if the total number of frames cannot be determined. Return values may exist but are ignored.

    Example code to write the progress to stdout:

    progress_callback = lambda i, n: print(f'Saving frame {i}/{n}')
    

Notes

fps, codec, bitrate, extra_args and metadata are used to construct a .MovieWriter instance and can only be passed if writer is a string. If they are passed as non-None and writer is a .MovieWriter, a RuntimeError will be raised.

to_html5_video(embed_limit=None)[source]

Convert the animation to an HTML5 <video> tag.

This saves the animation as an h264 video, encoded in base64 directly into the HTML5 video tag. This respects :rc:`animation.writer` and :rc:`animation.bitrate`. This also makes use of the interval to control the speed, and uses the repeat parameter to decide whether to loop.

Parameters:

embed_limit (float, optional) – Limit, in MB, of the returned animation. No animation is created if the limit is exceeded. Defaults to :rc:`animation.embed_limit` = 20.0.

Returns:

An HTML5 video tag with the animation embedded as base64 encoded h264 video. If the embed_limit is exceeded, this returns the string “Video too large to embed.”

Return type:

str

class pulse2percept.utils.Parametrized(**params)[source]

Abstract base class for objects with user-settable parameters

Provides the following functionality:

  • Pretty-print class attributes (via _pprint_params and PrettyPrint)

  • User-settable parameters must be listed in get_default_params

  • New class attributes can only be added in the constructor (enforced via Frozen and FreezeError)

  • Value-based equality and deep copying that understand NumPy arrays

  • Parameters can declare the physical unit they are stored in (via get_param_units), so that a unitful value assigned to one is converted before it is stored

Added in version 0.10.0.

abstract get_default_params()[source]

Return a dict of user-settable parameters

get_param_units()[source]

Return a dict of the units that parameters are stored in

Maps a parameter name to the Unit that the implementation assumes it is expressed in. A Quantity assigned to such a parameter is checked against that unit and rescaled to it, so that

FadingTemporal(tau=100)
FadingTemporal(tau=100 * ms)
FadingTemporal(tau=0.1 * s)

all store the same float. Bare numbers keep their documented meaning and are passed through untouched.

Parameters absent from this dict take plain numbers: they are either dimensionless (thresh_percept) or empirical fit parameters whose dimension the implementation does not actually commit to. Declaring a unit is a statement about what the equations assume, so a parameter should only appear here when that is documented or unambiguous.

This dict is not restricted to the names in get_default_params: it describes every physical attribute this object normalizes. A constructor argument assigned straight to selfDefaultSizeModel takes rho that way – belongs here too, and is converted like any other.

Subclasses extend rather than replace it:

def get_param_units(self):
    return {**super().get_param_units(), 'dt': ms, 'tau': ms}

Added in version 0.10.0.

set_params(**params)[source]

Set the parameters of this object

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:
  • theta (scalar or array-like) – The polar coordinates

  • rho (scalar or array-like) – The polar coordinates

Returns:

x, y – The transformed Cartesian coordinates

Return type:

scalar or array-like

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.

Added in version 0.7.

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

  • y_pred (array-like) – Estimated target values.

Returns:

z – The R² score

Return type:

float

Notes

  • If the ground-truth data has zero variance, R² will be zero.

  • This is not a symmetric function

pulse2percept.utils.rename_deprecated_params(obj_name, params, specs)[source]

Rewrite renamed model parameters that were supplied by their old name

The counterpart of warn_deprecated_params() for parameters that were renamed rather than retired: the value is kept, but moves to the new name, and the warning names the replacement.

Handing the caller a rewritten dict, rather than letting the assignment fall through to the deprecated_alias descriptor, keeps the warning to one per parameter and lets it name the model the user actually called.

Added in version 0.10.0.

Parameters:
  • obj_name (str) – Name of the model, as it should appear in the warning.

  • params (dict) – Parameters the caller supplied. Names that were not renamed are left alone, so it is fine to pass all of them.

  • specs (dict) – Maps a renamed parameter’s old name to the deprecated_alias describing it.

Returns:

paramsparams with every renamed key replaced by its new name. The original dict is returned untouched if none of the keys were renamed.

Return type:

dict

Raises:

TypeError – If both names of the same parameter were supplied. Which one won would otherwise come down to the order they were passed in.

class pulse2percept.utils.rename_parameter(old_name, new_name, deprecated_version=None, removed_version=None)[source]

Decorator to rename a single function or method parameter

Calls that use the old name keep working: the value is forwarded to the new parameter, so the callable behaves exactly as it did before, but a DeprecationWarning is raised. Use this when a parameter is only being renamed; when its value is no longer read at all, use deprecate_parameter instead.

Only keyword use of the old name is forwarded, which is the only way it can be recognized: a positional argument is bound by position and never mentions either name.

Added in version 0.10.0.

Note

Models take their parameters as **params, validated against get_default_params rather than declared in a signature, so this decorator cannot see them. Rename those with a deprecated_alias instead.

Parameters:
  • old_name (str) – The name being retired. Must not appear in the signature of the decorated callable, otherwise a ValueError is raised at decoration time (which catches the rename never having been made).

  • new_name (str) – The name that replaces it. Must appear in the signature, otherwise a ValueError is raised at decoration time.

  • deprecated_version (float or str) – The package version in which the old name was first marked as deprecated.

  • removed_version (float or str) – The package version in which the old name will stop working.

Examples

>>> from pulse2percept.utils import rename_parameter
>>> @rename_parameter('axlambda', 'lam', deprecated_version='0.10.0',
...                   removed_version='0.11.0')
... def decay(lam=1):
...     return lam
>>> decay(lam=3)  # no warning
3
pulse2percept.utils.sample(sequence, k=1)[source]

Randomly selects k elements from a sequence

Added 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 of randomly chosen elements from the sequence

Return type:

list

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).

Added 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 – A copy of the scaled image

Return type:

ndarray

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).

Added 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 – A copy of the shifted image

Return type:

ndarray

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

Remove any black border around the image

Added 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.

Added 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.

pulse2percept.utils.warn_deprecated_params(obj_name, supplied, specs, stacklevel=3)[source]

Warn about deprecated model parameters that were supplied by name

pulse2percept models take their parameters as **params, validated against get_default_params rather than declared in a signature, so deprecate_parameter cannot see them. This is the equivalent for that path: hand it the names the caller actually supplied, and it warns for the deprecated ones.

Added in version 0.9.1.

Parameters:
  • obj_name (str) – Name of the model, as it should appear in the warning.

  • supplied (iterable of str) – Parameter names the caller passed explicitly. Names that are not deprecated are skipped, so it is fine to pass all of them.

  • specs (dict) – Maps a deprecated parameter name to the deprecate_parameter describing it, so that signature-level and model-level deprecations word alike.

  • stacklevel (int, optional) – Passed to warnings.warn. Exact attribution is not possible through a chain of super().__init__ calls of varying depth, so the message names the parameter and the model rather than relying on it.