Models and Percepts
A model converts delivered stimulation into a predicted
Percept. A model with a spatial component
is bound to an implant; a temporal-only model describes one location’s
response over time and needs none.
import pulse2percept as p2p
implant = p2p.implants.retina.ArgusII()
model = p2p.models.retina.ScoreboardModel(implant=implant, rho=200)
percept = model.predict_percept({'A8': 30})
predict_percept calls implant.prepare_stim(source) first (see
Stimulation). Models build on first prediction and rebuild the
affected component when a parameter or the implant changes.
The simulated visual field is a grid set by xrange, yrange (dva) and
step (dva per pixel). Retinal models default to 30 x 30 dva at 0.25 dva,
cortical models to 10 x 10 dva, both centered on the fovea. Widen the grid if
a percept touches its edge; refine step for small phosphenes.
Choosing a model
Models live under the tissue they stimulate,
pulse2percept.models.retina and
pulse2percept.models.cortex. The root namespace holds generic
temporal models and the base classes. Each model’s API page lists its
assumptions, parameters, and units.
Retinal models
Model |
Reference |
Type |
Use it for |
|---|---|---|---|
spatial |
A round phosphene per electrode; the simplest spatial baseline |
||
spatial |
Elongated phosphenes that follow retinal nerve fiber bundles |
||
derived from [Granley2021] |
spatiotemporal |
Round phosphenes whose brightness and size depend on the pulse train |
|
spatiotemporal |
Pulse-dependent phosphenes with axonal elongation |
||
spatial + temporal |
Brightness and size as a function of amplitude and frequency |
||
temporal |
Single-electrode threshold as a function of pulse timing |
||
spatial |
Early scoreboard-style simulation with electrode dropout |
||
spatiotemporal |
Photovoltaic subretinal stimulation (see below) |
rho(um) in the scoreboard and axon map models is an effective perceptual spread fitted to subject reports, not a physical current-spread constant. Axon map models addlam(um), the spread along an axon.The Biphasic models require a biphasic pulse train with amplitude in
xTh, orimplant.thresholdsto convert uA. Amplitude scales phosphene brightness and size; frequency scales brightness; phase duration shortens axonal streaks.Retinal spatial models derive from
RetinalSpatialand place electrodes through a retinotopic map (see Coordinates and Visual Field Maps).xrange/yrangemay also be given as retinal lengths.
Photovoltaic stimulation
Two models accept the near-infrared schedule of a photovoltaic array:
ScoreboardModelShows normalized optical drive: where the light lands, relative to a fully lit pixel. No retinal response.
Ho2018ModelPredicts a phenomenological network-mediated retinal response. Each pulse period’s radiant exposure (irradiance x ON duration) drives a Gaussian with default
rhoof half the median pixel pitch. A difference of low-pass cascades filters the result, so a static image at a fixed pulse rate gives an onset response that adapts.
Warning
Ho2018Model reconstructs the
structure and timing of [Ho2018], not validated PRIMA percepts:
pON center response of degenerate (RCS) rat retina only; no antagonistic surround and no pOFF pathway.
rho = pitch / 2is a pulse2percept convention, not a measured point-spread function or the receptive-field size of [Ho2018].Activation is linear in radiant exposure, normalized to the 9 mW/mm^2, 4 ms reference pulse of [Ho2018], with no fitted irradiance, pulse-duration, or frequency nonlinearity.
No photovoltaic circuit, electric field, electrode-retina distance, or wavelength dependence: an 880 nm PRIMA pixel and a 915 nm pixel of another design respond identically to the same radiant exposure.
Temporal coefficients are matched to the Table 1 timing landmarks of [Ho2018], not published by it, and are not calibrated to human brightness or contrast perception.
Cortical models
Model |
Reference |
Type |
Use it for |
|---|---|---|---|
[Beyeler2019], adapted |
spatial |
A spatial baseline where phosphene size follows cortical magnification |
|
spatiotemporal |
Charge accumulation, thresholds, and phosphene dynamics over time |
Cortical spatial models derive from
CortexSpatial, simulate one or more
of 'v1', 'v2', 'v3' (regions), and map them through cortical
retinotopy. The cortical rho (um) is a spread on cortex, so phosphene
size in dva grows with eccentricity.
Generic temporal models
FadingTemporal and
AlphaTemporal describe how one location’s
response decays after a pulse. They combine with retinal or cortical spatial
components (see Combining components).
Limitations
ScoreboardModel,AxonMapModelandThompson2003Modelignore electrodezand emit a warning if it is nonzero. Electrode-retina distance is expected to affect threshold and spread, but the psychophysical evidence is insufficient to parameterize it.Models are monocular: a prediction is about one eye (see Visual Input and Simulated Vision).
Percept timing
Spatial-only models return one frame per stimulus time point (one frame for
a timeless stimulus or an image). For temporal models, t_percept sets the
output times (ms):
Given explicitly, it returns those exact instants.
Omitted, output frames follow the encoder’s frame clock for encoded video, and are 20 ms apart (50 Hz) otherwise.
reducesets what each frame reports:'last'(default) the brightness at the end of its interval,'peak'the maximum within it.
import numpy as np
percept = model.predict_percept(stim, t_percept=np.arange(0, 500, 10))
Percepts
A Percept stores data with time as
the last axis, the grid coordinates xdva and ydva, and time (in
time_unit, ms by default; None for a single timeless frame):
(Y, X, T) perceived brightness, arbitrary units
(Y, X, 3, T) RGB display intensities in [0, 1]
percept.plot() # brightest frame
percept.play() # animation
percept.save('percept.mp4') # image or video, by extension
Prosthesis models produce brightness percepts.
render() returns an RGB percept (see
Visual Input and Simulated Vision). RGB values must be finite and lie in [0, 1];
anything else is rejected at construction with a ValueError.
Brightness-only operations (n_gray, argmax, max, vmin,
vmax, and plot() of a multi-frame percept) are rejected for RGB
percepts with a ValueError, because ranking colors needs a color metric.
Use play() or percept.data instead.
Measuring a percept
Added in version 0.11.0.
measure() reports brightness and
geometry of the phosphenes in each frame. It is post-processing, not part of
the model:
metrics = percept.measure()
metrics.peak.diameter # dva
metrics.peak.centroid # (x, y) in dva
metrics.peak.integrated_brightness # brightness units x dva^2
Negative values are clipped to zero. Geometry is measured on the support:
pixels at or above threshold (default 0.5) times that frame’s own
maximum. The threshold is relative, so scaling brightness does not change
measured shape. Lower it to include more of the falloff:
percept.measure(threshold=0.25).
max_brightnessLargest pixel value (model units).
integrated_brightnessPixel sum times pixel area (brightness units x dva^2); approximately independent of grid resolution.
areaSupport area (dva^2).
diameterDiameter (dva) of the circle of equal area. At
threshold=0.5this approximates the FWHM of a well-sampled circular Gaussian.centroidMean
(x, y)of the support pixels (dva).major_axis,minor_axis,elongationAxes (dva) of the ellipse with the support’s second moments, and their ratio (1 for a circle).
n_componentsNumber of disconnected suprathreshold regions. Other measurements describe their union, so an
elongationof 4 can be one elongated phosphene or two round ones;n_componentsdistinguishes them.touches_edgeWhether the support reaches the grid border. If so, measurements cover only the part inside the grid; widen
xrangeandyrange.
A frame without positive brightness has zero brightness, area, and
components, and NaN position and shape.
For a temporal percept, each measurement is also an array over frames.
metrics.peak_frame is the frame with the largest integrated brightness
(earliest on a tie), and metrics.peak its measurements. No time
integration or duration metrics are computed.
measure() requires a brightness percept on a
Grid2D; RGB percepts and percepts
without dva coordinates are rejected. The measurements describe the percept
image only, not acuity, discriminability, or task performance.
Combining components
Classes ending in Model are complete models. Classes ending in
Spatial or Temporal are components, which
Model combines:
spatial = p2p.models.retina.AxonMapSpatial(implant, rho=300, lam=500)
temporal = p2p.models.FadingTemporal(tau=100)
model = p2p.models.Model(spatial, temporal)
model.spatial.rho = 250 # rebuilds the spatial component
model.temporal.tau = 50
One of the two may be None. Components must be constructed before they
are passed. The implant belongs to the spatial component. Parameters declared by
both components, such as thresh_percept, stay independent.