pulse2percept.models.granley2021
BiphasicAxonMapModel,
BiphasicAxonMapSpatial [Granley2021]
Classes
|
BiphasicAxonMapModel of [Granley2021] (standalone model) |
|
BiphasicAxonMapModel of [Granley2021] (spatial model) |
|
Default model to be used for brightness scaling in BiphasicAxonMapModel Implements Eq 4 from [Granley2021] Fit using data from [Nanduri2012] and [Weitz2015] |
|
Default model to be used for size (rho) scaling in BiphasicAxonMapModel Implements Eq 5 from [Granley2021] Fit using data from [Nanduri2012] and [Weitz2015] |
|
Default model to be used for streak length (lambda) scaling in BiphasicAxonMapModel Implements Eq 6 from [Granley2021] Fit using data from [Weitz2015] |
- class pulse2percept.models.granley2021.DefaultBrightModel(**params)[source]
Default model to be used for brightness scaling in BiphasicAxonMapModel Implements Eq 4 from [Granley2021] Fit using data from [Nanduri2012] and [Weitz2015]
Parameters:
- do_thresholdingbool, optional
Set to true to enable probabilistic phosphene appearance at near-threshold amplitudes
- a0, a1float, optional
Linear regression coefficients (slope and intercept) of pulse_duration vs threshold curve (Eq 3). Amplitude factor will be scaled by a0*pdur + a1.
- a2, a3, a4: float, optional
Linear regression coefficients for brightness vs amplitude and frequency (Eq 4) F_bright = a2*scaled_amp + a3*freq + a4
- scale_threshold(pdur)[source]
Based on eq 3 in paper, this function produces the factor that amplitude will be scaled by to produce a_tilde. Computes A_0 * t + A_1 (1/threshold) .. note:
This equation has been updated from the original paper, and has been refit to data from Argus II users from Horsager et al. 2009.
- build(**build_params)[source]
Build the model
Every model must have a
`buildmethod, which is meant to perform all expensive one-time calculations. You must callbuildbefore callingpredict_percept.Important
Don’t override this method if you are building your own model. Customize
_buildinstead.- Parameters:
build_params (additional parameters to set) – You can overwrite parameters that are listed in
get_default_params. Trying to add new class attributes outside of that will cause aFreezeError. Example:model.build(param1=val)
- get_param_units()[source]
Return a dict of the units that parameters are stored in
Maps a parameter name to the
Unitthat the implementation assumes it is expressed in. AQuantityassigned to such a parameter is checked against that unit and rescaled to it, so thatFadingTemporal(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 toself–DefaultSizeModeltakesrhothat 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.
- property is_built
A flag indicating whether the model has been built
- class pulse2percept.models.granley2021.DefaultSizeModel(rho, **params)[source]
Default model to be used for size (rho) scaling in BiphasicAxonMapModel Implements Eq 5 from [Granley2021] Fit using data from [Nanduri2012] and [Weitz2015]
Parameters:
- rhofloat32
Rho parameter of BiphasicAxonMapModel (spatial decay rate)
- a0, a1float, optional
Linear regression coefficients (slope and intercept) of pulse_duration vs threshold curve (Eq 3). Amplitude factor will be scaled by a0*pdur + a1.
- a5, a6float, optional
Linear regression coefficients for size vs amplitude (Eq 5) F_size = a5*scaled_amp + a6
- scale_threshold(pdur)[source]
Based on eq 3 in paper, this function produces the factor that amplitude will be scaled by to produce a_tilde. Computes A_0 * t + A_1 (1/threshold) .. note:
This equation has been updated from the original paper, and has been refit to data from Argus II users from Horsager et al. 2009.
- build(**build_params)[source]
Build the model
Every model must have a
`buildmethod, which is meant to perform all expensive one-time calculations. You must callbuildbefore callingpredict_percept.Important
Don’t override this method if you are building your own model. Customize
_buildinstead.- Parameters:
build_params (additional parameters to set) – You can overwrite parameters that are listed in
get_default_params. Trying to add new class attributes outside of that will cause aFreezeError. Example:model.build(param1=val)
- property is_built
A flag indicating whether the model has been built
- class pulse2percept.models.granley2021.DefaultStreakModel(lam, **params)[source]
Default model to be used for streak length (lambda) scaling in BiphasicAxonMapModel Implements Eq 6 from [Granley2021] Fit using data from [Weitz2015]
Parameters:
- lamfloat32
lamparameter of BiphasicAxonMapModel (axonal decay rate)Changed in version 0.10.0: Renamed from
axlambda. The old name still works as a keyword argument, but is deprecated and will be removed in v0.11.0.- a7, a8, a9: float, optional
Regression coefficients for streak length vs pulse duration (Eq 6) F_streak = -a7*pdur^a8 + a9
- build(**build_params)[source]
Build the model
Every model must have a
`buildmethod, which is meant to perform all expensive one-time calculations. You must callbuildbefore callingpredict_percept.Important
Don’t override this method if you are building your own model. Customize
_buildinstead.- Parameters:
build_params (additional parameters to set) – You can overwrite parameters that are listed in
get_default_params. Trying to add new class attributes outside of that will cause aFreezeError. Example:model.build(param1=val)
- property is_built
A flag indicating whether the model has been built
- class pulse2percept.models.granley2021.BiphasicAxonMapSpatial(**params)[source]
BiphasicAxonMapModel of [Granley2021] (spatial model)
An AxonMapModel where phosphene brightness, size, and streak length scale according to amplitude, frequency, and pulse duration
All stimuli must be BiphasicPulseTrains.
This model is different than other spatial models in that it calculates one representative percept from all time steps of the stimulus.
Brightness, size, and streak length scaling are controlled by the effects models bright_model, size_model, and streak model respectively. By default, these are set to classes that implement Eqs 3-6 from Granley 2021. These models can be individually customized by setting the bright_model, size_model, or streak_model to any python callable with signature f(freq, amp, pdur)
Important
Using this model in combination with a temporal model is not currently supported and will give unexpected results
- Parameters:
bright_model (callable, optional) – Model used to modulate percept brightness with amplitude, frequency, and pulse duration
size_model (callable, optional) – Model used to modulate percept size with amplitude, frequency, and pulse duration
streak_model (callable, optional) – Model used to modulate percept streak length with amplitude, frequency, and pulse duration
**params (optional) –
Additional params for AxonMapModel.
- lam: double, optional
Exponential decay constant along the axon(microns).
Changed in version 0.10.0: Renamed from
axlambda, which reads poorly next torho. The old name still works, but is deprecated and will be removed in v0.11.0.- rho: double, optional
Exponential decay constant away from the axon(microns).
- min_current_spread: float, optional
An electrode is skipped at axon segments where its current spread has decayed below this fraction of its peak. The decay is scaled per electrode by that electrode’s
F_size. The default (1e-8) is a deliberate approximation: what gets dropped is the exponential times that electrode’sF_bright, summed over the skipped electrodes, so the error at a point is bounded bymin_current_spreadtimes the summedF_brightacross electrodes.- eye: {‘RE’, LE’}, optional
Eye for which to generate the axon map.
- xrange(x_min, x_max), optional
A tuple indicating the range of x values to simulate (in degrees of visual angle). In a right eye, negative x values correspond to the temporal retina, and positive x values to the nasal retina. In a left eye, the opposite is true.
- yrangetuple, (y_min, y_max)
A tuple indicating the range of y values to simulate (in degrees of visual angle). Negative y values correspond to the superior retina, and positive y values to the inferior retina.
- stepint, double, tuple
Step size for the range of (x,y) values to simulate (in degrees of visual angle). For example, to create a grid with x values [0, 0.5, 1] use
xrange=(0, 1)andstep=0.5. Pass a tuple to give the x and y axes different step sizes.Changed in version 0.10.0: Renamed from
xystep, which suggested that one step size applies to both axes. The old name still works, but is deprecated and will be removed in v0.11.0.- grid_type{‘rectangular’, ‘hexagonal’}
Whether to simulate points on a rectangular or hexagonal grid
- vfmap
VisualFieldMap, optional An instance of a
VisualFieldMapobject that provides retinotopic mappings. By default,Watson2014Mapis used.- n_grayint, optional
The number of gray levels to use. If an integer is given, k-means clustering is used to compress the color space of the percept into
n_graybins. If None, no compression is performed.- noisefloat or int, optional
Adds salt-and-pepper noise to each percept frame. An integer will be interpreted as the number of pixels to subject to noise in each frame. A float between 0 and 1 will be interpreted as a ratio of pixels to subject to noise in each frame.
- loc_od, loc_od: (x,y), optional
Location of the optic disc in degrees of visual angle. Note that the optic disc in a left eye will be corrected to have a negative x coordinate.
- n_axons: int, optional
Number of axons to generate.
- axons_range: (min, max), optional
The range of angles(in degrees) at which axons exit the optic disc. This corresponds to the range of $phi_0$ values used in [Jansonius2009].
- n_ax_segments: int, optional
Number of segments an axon is made of.
- ax_segments_range: (min, max), optional
Lower and upper bounds for the radial position values(polar coords) for each axon.
- min_ax_sensitivity: float, optional
Axon segments whose contribution to brightness is smaller than this value will be pruned to improve computational efficiency. Set to a value between 0 and 1.
- axon_pickle: str, optional
File name in which to store precomputed axon maps.
- ignore_pickle: bool, optional
A flag whether to ignore the pickle file in future calls to
model.build().- n_threadsint, optional
Number of CPU threads to use during parallelization using OpenMP. Defaults to max number of user CPU cores.
- n_jobsint, optional
Alias for
n_threads;Noneor-1uses every core.
- predict_percept(implant, t_percept=None)[source]
Predicts the spatial response Override base predict percept to have desired timesteps and remove unneccesary computation
- Parameters:
implant (
ProsthesisSystem) – A valid prosthesis system. A stimulus can be passed viastim().t_percept (float or list of floats, optional) – The time points at which to output a percept (ms). This model’s numerical contract is fixed to milliseconds. If None,
implant.stim.timeis used. May be given as a unitful quantity (e.g.[0, 20] * ms); seepulse2percept.units.
- Returns:
percept – A Percept object whose
datacontainer has dimensions Y x X x 1. Will return None ifimplant.stimis None.- Return type:
Percept
- find_threshold(implant, bright_th, amp_range=(0, 999), amp_tol=1, bright_tol=0.1, max_iter=100)[source]
Not supported by this model
- Raises:
- axlambda[source]
lamused to be calledaxlambda. The old name still reads and writeslam, with aDeprecationWarning:
- build(**build_params)[source]
Build the model
Performs expensive one-time calculations, such as building the spatial grid used to predict a percept. You must call
buildbefore callingpredict_percept.Important
Don’t override this method if you are building your own model. Customize
_buildinstead.- Parameters:
build_params (additional parameters to set) – You can overwrite parameters that are listed in
get_default_params. Trying to add new class attributes outside of that will cause aFreezeError. Example:model.build(param1=val)
- calc_axon_sensitivity(bundles)[source]
Calculate the sensitivity of each axon segment to electrical current
This function combines the x,y coordinates of each bundle segment with a sensitivity value that depends on the distance of the segment to the cell body and
self.lam.The number of
bundlesmust equal the number of points on self.grid`. The function will then assume that the i-th bundle passes through the i-th point on the grid. This is used to determine the bundle segment that is closest to the i-th point on the grid, and to cut off all segments that extend beyond the soma. This effectively transforms a bundle into an axon, where the first axon segment now corresponds with the i-th location of the grid.After that, each axon segment gets a sensitivity value that depends on the distance of the segment to the soma (with decay rate
self.lam). This is typically done during the build process, so that the only work left to do during run time is to multiply the sensitivity value with the current applied to each segment.- Parameters:
bundles (list of Nx2 arrays) – A list of bundles, where every bundle is an Nx2 array consisting of the x,y coordinates of each axon segment (retinal coords, microns). Note that each bundle will most likely have a different N
- Returns:
axon_contrib – A list with one entry per point on
self.grid. Each entry is a Nx3 array, where the first two columns contain the retinal coordinates of each axon segment (microns), and the third column contains the sensitivity of the segment to electrical current. The latter depends onself.lam. Note that each axon will most likely have a different N, since segments whose sensitivity falls belowmin_ax_sensitivityare trimmed.- Return type:
list of Nx3 arrays
- calc_bundle_tangent_fast(xc, yc, bundles=None)[source]
Calculates orientation of fiber bundle tangent at (xc, yc) This function supports multiple queries (xc and yc can be arrays), without requiring growing the axon bundles again for each point (like calc_bundle_tangent). It uses a ckdtree, which will be slower for single points, but significantly faster for multiple points.
- Parameters:
xc (array of floats) – (x, y) retinal location of point at which to calculate bundle orientation in microns.
yc (array of floats) – (x, y) retinal location of point at which to calculate bundle orientation in microns.
- Returns:
tangent – Angles in radians
- Return type:
array of floats
- find_closest_axon(bundles, xret=None, yret=None, return_index=False, return_segment=False)[source]
Finds the closest axon segment for a point on the retina
This function will search a number of nerve fiber bundles (
bundles) and return the bundle that is closest to a particular point (or list of points) on the retinal surface (xret,yret).- Parameters:
bundles (list of Nx2 arrays) – A list of bundles, where every bundle is an Nx2 array consisting of the x,y coordinates of each axon segment (retinal coords, microns). Note that each bundle will most likely have a different N
xret (scalar or list of scalars) – The x,y location on the retina (in microns, where the fovea is the origin) for which to find the closests axon.
yret (scalar or list of scalars) – The x,y location on the retina (in microns, where the fovea is the origin) for which to find the closests axon.
return_index (bool, optional) – If True, the function will also return the index into
bundlesthat represents the closest axonreturn_segment (bool, optional) – If True, the function will also return the row index, within the closest bundle, of the segment nearest the point. The search already determines this, so asking for it here saves
calc_axon_sensitivity()from working it out again.
- Returns:
axon (Nx2 array or list of Nx2 arrays) – For each point in (xret, yret), returns an Nx2 array that represents the closest axon to that point. Each row in the array contains the x,y retinal coordinates (microns) of a particular axon segment.
idx_axon (scalar or list of scalars, optional) – If
return_indexis True, also returns the index inbundlesof the closest axon (or list of closest axons).idx_segment (scalar or list of scalars, optional) – If
return_segmentis True, also returns the row index of the closest segment within that axon.
- grow_axon_bundles(n_bundles=None, prune=True)[source]
Grow a number of axon bundles
This method generates the trajectory of a number of nerve fiber bundles based on the mathematical model described in [Beyeler2019], which is based on [Jansonius2009].
Bundles originate at the optic nerve head with initial angle
phi0. The method generatesn_bundlesaxon bundles whosephi0values are linearly sampled fromself.axons_range(polar coords). Each axon will consist ofself.n_ax_segmentssegments that spanself.ax_segments_rangedistance from the optic nerve head (polar coords).- Parameters:
- Returns:
bundles – A list of bundles, where every bundle is an Nx2 array consisting of the x,y coordinates of each axon segment (retinal coords, microns). Note that each bundle will most likely have a different N
- Return type:
list of Nx2 arrays
- property is_built
A flag indicating whether the model has been built
- property n_jobs
both names read and write the same value.
- Type:
Number of OpenMP threads to use during parallelization. An alias for
n_threads
- plot(use_dva=False, style='hull', annotate=True, autoscale=True, ax=None, figsize=None)[source]
Plot the axon map
- Parameters:
use_dva (bool, optional) – Uses degrees of visual angle (dva) if True, else retinal coordinates (microns)
style ({'hull', 'scatter', 'cell'}, optional) –
Grid plotting style:
’hull’: Show the convex hull of the grid (that is, the outline of the smallest convex set that contains all grid points).
’scatter’: Scatter plot all grid points
’cell’: Show the outline of each grid cell as a polygon. Note that this can be costly for a high-resolution grid.
annotate (bool, optional) – Flag whether to label the four retinal quadrants
autoscale (bool, optional) – Whether to adjust the x,y limits of the plot
ax (matplotlib.axes._subplots.AxesSubplot, optional) – A Matplotlib axes object. If None, will either use the current axes (if exists) or create a new Axes object
figsize ((float, float), optional) – Desired (width, height) of the figure in inches
- class pulse2percept.models.granley2021.BiphasicAxonMapModel(**params)[source]
BiphasicAxonMapModel of [Granley2021] (standalone model)
An AxonMapModel where phosphene brightness, size, and streak length scale according to amplitude, frequency, and pulse duration.
All stimuli must be BiphasicPulseTrains.
This model is different than other spatial models in that it calculates one representative percept from all time steps of the stimulus.
Brightness, size, and streak length scaling are controlled by the parameters bright_model, size_model, and streak model respectively. By default, these are set to classes that implement Eqs 3-6 from Granley 2021. These models can be individually customized by setting the bright_model, size_model, or streak_model to any python callable with signature f(freq, amp, pdur).
Important
Stimuli should pass amplitude as a factor of threshold, NOT as raw amplitude in microamps.
This model interacts with Stimulus objects by reading the intended amplitude, frequency, and pulse duration from their metadata, not from the raw stimulus data. The arithmetic operators keep that metadata in sync, so scaling a pulse train (
pt * 2) or the stimulus assembled from one (implant.stim * 2) does change the percept, while editing the data array in place does not.- Parameters:
bright_model (callable, optional) – Model used to modulate percept brightness with amplitude, frequency, and pulse duration
size_model (callable, optional) – Model used to modulate percept size with amplitude, frequency, and pulse duration
streak_model (callable, optional) – Model used to modulate percept streak length with amplitude, frequency, and pulse duration
do_thresholding (boolean) – Use probabilistic sigmoid thresholding, default: False
**params (dict, optional) –
Arguments to be passed to AxonMapSpatial
- lam: double, optional
Exponential decay constant along the axon(microns).
Changed in version 0.10.0: Renamed from
axlambda, which reads poorly next torho. The old name still works, but is deprecated and will be removed in v0.11.0.- rho: double, optional
Exponential decay constant away from the axon(microns).
- min_current_spread: float, optional
An electrode is skipped at axon segments where its current spread has decayed below this fraction of its peak. The decay is scaled per electrode by that electrode’s
F_size. The default (1e-8) is a deliberate approximation: what gets dropped is the exponential times that electrode’sF_bright, summed over the skipped electrodes, so the error at a point is bounded bymin_current_spreadtimes the summedF_brightacross electrodes. That is negligible for a typical array, but it grows with both array size and brightness scaling, and it can zero out points that are merely dim. Set to 0 to sum over every electrode and get the exact result.- eye: {‘RE’, LE’}, optional
Eye for which to generate the axon map.
- xrange(x_min, x_max), optional
A tuple indicating the range of x values to simulate (in degrees of visual angle). In a right eye, negative x values correspond to the temporal retina, and positive x values to the nasal retina. In a left eye, the opposite is true.
- yrangetuple, (y_min, y_max)
A tuple indicating the range of y values to simulate (in degrees of visual angle). Negative y values correspond to the superior retina, and positive y values to the inferior retina.
- stepint, double, tuple
Step size for the range of (x,y) values to simulate (in degrees of visual angle). For example, to create a grid with x values [0, 0.5, 1] use
xrange=(0, 1)andstep=0.5. Pass a tuple to give the x and y axes different step sizes.Changed in version 0.10.0: Renamed from
xystep, which suggested that one step size applies to both axes. The old name still works, but is deprecated and will be removed in v0.11.0.- grid_type{‘rectangular’, ‘hexagonal’}
Whether to simulate points on a rectangular or hexagonal grid
- vfmap
VisualFieldMap, optional An instance of a
VisualFieldMapobject that provides retinotopic mappings. By default,Watson2014Mapis used.- n_grayint, optional
The number of gray levels to use. If an integer is given, k-means clustering is used to compress the color space of the percept into
n_graybins. If None, no compression is performed.- noisefloat or int, optional
Adds salt-and-pepper noise to each percept frame. An integer will be interpreted as the number of pixels to subject to noise in each frame. A float between 0 and 1 will be interpreted as a ratio of pixels to subject to noise in each frame.
- loc_od, loc_od: (x,y), optional
Location of the optic disc in degrees of visual angle. Note that the optic disc in a left eye will be corrected to have a negative x coordinate.
- n_axons: int, optional
Number of axons to generate.
- axons_range: (min, max), optional
The range of angles(in degrees) at which axons exit the optic disc. This corresponds to the range of $phi_0$ values used in [Jansonius2009].
- n_ax_segments: int, optional
Number of segments an axon is made of.
- ax_segments_range: (min, max), optional
Lower and upper bounds for the radial position values(polar coords) for each axon.
- min_ax_sensitivity: float, optional
Axon segments whose contribution to brightness is smaller than this value will be pruned to improve computational efficiency. Set to a value between 0 and 1.
- axon_pickle: str, optional
File name in which to store precomputed axon maps.
- ignore_pickle: bool, optional
A flag whether to ignore the pickle file in future calls to
model.build().- n_threadsint, optional
Number of CPU threads to use during parallelization using OpenMP. Defaults to max number of user CPU cores.
- n_jobsint, optional
Alias for
n_threads;Noneor-1uses every core.
- predict_percept(implant, t_percept=None)[source]
Predict a percept.
Overrides base predict percept to keep desired time axes
Note
You must call
buildbefore callingpredict_percept.Important
Stimuli should pass amplitude as a factor of threshold, NOT as raw amplitude in microamps.
The model interacts with Stimulus objects by reading the intended amplitude, frequency, and pulse duration from their metadata, not from the raw stimulus data. Editing the data array in place will not change the predicted percept.
- Parameters:
implant (
ProsthesisSystem) – A valid prosthesis system. A stimulus can be passed viastim().t_percept (float or list of floats, optional) – The time points at which to output a percept (ms). This model’s numerical contract is fixed to milliseconds. If None,
implant.stim.timeis used. May be given as a unitful quantity (e.g.[0, 20] * ms); seepulse2percept.units.
- Returns:
percept – A Percept object whose
datacontainer has dimensions Y x X x T. Will return None ifimplant.stimis None.- Return type:
Percept
- find_threshold(implant, bright_th, amp_range=(0, 999), amp_tol=1, bright_tol=0.1, max_iter=100, t_percept=None)[source]
Not supported by this model
- Raises:
- build(**build_params)[source]
Build the model
Performs expensive one-time calculations, such as building the spatial grid used to predict a percept.
- Parameters:
build_params (additional parameters to set) – You can overwrite parameters that are listed in
get_default_params. Trying to add new class attributes outside of that will cause aFreezeError. Example:model.build(param1=val)- Return type:
self
- property has_space
Returns True if the model has a spatial component
- property has_time
Returns True if the model has a temporal component
- property is_built
Returns True if the
buildmodel has been called
- set_params(params)[source]
Set model parameters
This is a convenience function to set parameters that might be part of the spatial model, the temporal model, or both.
Alternatively, you can set the parameter directly, e.g.
model.spatial.verbose = True.Note
If a parameter exists in both spatial and temporal models(e.g.,
verbose), both models will be updated.- Parameters:
params (dict) – A dictionary of parameters to set.
- property space_unit
The unit spatial coordinates are expressed in
The temporal model never sees a coordinate.
- property stimulus_unit
The unit stimulus values are expressed in
The stimulus goes to the spatial model if there is one, and straight to the temporal model otherwise.
- property time_unit
The unit time is expressed in
t_perceptis read in, and the resultingPerceptis written in, the unit of the last stage of the pipeline: the temporal model if there is one, the spatial model otherwise. The two need not agree – a spatial model counting in seconds hands its percept to a temporal model counting in milliseconds and the time axis is converted on the way across.