pulse2percept.implants

Different prosthetic implants, such as Argus II, Alpha-IMS, BVT-24, PRIMA, Cortivis, etc.

cortex

Cortical implants such as Orion, ICVP, and Neuralink

base

ProsthesisSystem, RectangleImplant

electrodes

Electrode, PointSource, DiskElectrode, SquareElectrode, HexElectrode

electrode_arrays

ElectrodeArray, ElectrodeGrid

rasters

Raster, SequentialRaster, CheckerboardRaster, CustomRaster

argus

ArgusI, ArgusII

alpha

AlphaIMS, AlphaAMS

bvt

BVT24, BVT44

imie

IMIE

prima

PhotovoltaicPixel, PRIMA, PRIMA75, PRIMA55, PRIMA40

ensemble

EnsembleImplant

class pulse2percept.implants.AlphaAMS(x=0, y=0, z=0, rot=0, eye='RE', stim=None, preprocess=True, safe_mode=False)[source]

Alpha-AMS

This class creates an Alpha-AMS array with 1600 photovoltaic pixels (each 30um in diameter) as described in [Stingl2017], and places it in the subretinal space, such that the center of the array is located at (x,y,z), given in microns, and the array is rotated by rotation angle rot, given in degrees.

The device consists of 1600 30um-wide round pixels, arranged on a 40x40 rectangular grid with 70um pixel pitch.

The array is oriented upright in the visual field, such that an array with center (0,0) has the top three rows lie in the lower retina (upper visual field), as shown below:

An electrode can be addressed by name, row/column index, or integer index (into the flattened array).

Note

Column order is reversed in a left-eye implant.

Parameters:
  • x/y/z (double) – 3D location (um) of the center of the electrode array. The coordinate system is centered over the fovea. Positive x values move the electrode into the nasal retina. Positive y values move the electrode into the superior retina. Positive z values move the electrode away from the retina into the vitreous humor (sometimes called electrode-retina distance). z can either be a list with 1600 entries or a scalar that is applied to all electrodes. May be given as unitful quantities (e.g. z=100 * um); see pulse2percept.units.

  • rot (float) – Rotation angle of the array (deg). Positive values denote counter-clock-wise (CCW) rotations in the retinal coordinate system.

  • eye ({'RE', 'LE'}, optional) – Eye in which array is implanted.

  • preprocess (bool or callable, optional) – Either True/False to indicate whether to execute the implant’s default preprocessing method whenever a new stimulus is assigned, or a custom function (callable).

  • safe_mode (bool, optional) – If safe mode is enabled, only charge-balanced stimuli are allowed.

Examples

Create an AlphaAMS array centered on the fovea, at 100um distance from the retina, rotated counter-clockwise by 5 degrees:

>>> from pulse2percept.implants import AlphaAMS
>>> AlphaAMS(x=0, y=0, z=100, rot=5)
AlphaAMS(earray=ElectrodeGrid, eye='RE', preprocess=True,
         safe_mode=False, shape=(40, 40), stim=None)

Get access to the third electrode in the top row (by name or by row/column index):

>>> alpha_ims = AlphaAMS(x=0, y=0, z=100, rot=0)
>>> alpha_ims['A3']
DiskElectrode(activated=True, name='A3', r=15.0, x=-1225.0,
              y=-1365.0, z=100.0)
>>> alpha_ims[0, 2]
DiskElectrode(activated=True, name='A3', r=15.0, x=-1225.0,
              y=-1365.0, z=100.0)
property eye

Implanted eye

A ProsthesisSystem can be implanted either in a left eye (‘LE’) or right eye (‘RE’). Models such as AxonMapModel will treat left and right eyes differently (for example, adjusting the location of the optic disc).

Examples

Implant Argus II in a left eye:

>>> from pulse2percept.implants import ArgusII
>>> implant = ArgusII(eye='LE')
property earray

Electrode array

property stim

Stimulus

A stimulus can be created from many source types, such as scalars, NumPy arrays, and dictionaries (see Stimulus for a complete list).

A stimulus can be assigned either in the ProsthesisSystem constructor or later by assigning a value to stim.

Note

Unless when using dictionary notation, the number of stimuli must equal the number of electrodes in earray.

Examples

Send a biphasic pulse (30uA, 0.45ms phase duration) to an implant made from a single DiskElectrode:

>>> from pulse2percept.implants import DiskElectrode, ProsthesisSystem
>>> from pulse2percept.stimuli import BiphasicPulse
>>> implant = ProsthesisSystem(DiskElectrode(0, 0, 0, 100))
>>> implant.stim = BiphasicPulse(30, 0.45)

Stimulate Electrode B7 in Argus II with 13 uA:

>>> from pulse2percept.implants import ArgusII
>>> implant = ArgusII(stim={'B7': 13})
check_stim(stim)[source]

Quality-check the stimulus

This method is executed every time a new value is assigned to stim.

If safe_mode is set to True, this function will only allow stimuli that are charge-balanced. If max_current is set, it will only allow stimuli whose total instantaneous current stays within it.

Both are questions about electricity, and neither can be answered about a stimulus that is not a current, so each raises a DimensionMismatchError on one. An implant that asks for neither does not run either check, which is why a dimensionless stimulus may still be assigned to one – preprocess has already had its chance to turn it into current, and if it did not, no safety claim is being made about it either.

The user can define their own checks in implants that inherit from ProsthesisSystem.

Parameters:

stim (Stimulus source type) – A valid source type for the Stimulus object (e.g., scalar, NumPy array, pulse train).

Raises:
  • DimensionMismatchError – If an electrical check was requested and stim is not measured in units of current.

  • .. versionchanged: – 0.10.0: The electrical checks verify that the stimulus really is electrical, instead of reading whatever numbers it holds as microamps.

property electrode_names

Return a list of all electrode names in the electrode array

property electrode_objects

Return a list of all electrode objects in the array

property electrodes

Return all electrode names and objects in the electrode array

Internally, electrodes are stored in an ordered dictionary. You can iterate over different electrodes in the array as follows:

for name, electrode in implant.electrodes.items():
    print(name, electrode)

You can access an individual electrode by indexing directly into the prosthesis system object, e.g. implant['A1'] or implant[0].

property max_current

Total instantaneous current (uA) the stimulator can source

property n_electrodes

Number of electrodes in the array

This is equivalent to calling earray.n_electrodes.

plot(annotate=False, autoscale=True, ax=None, stim_cmap=False)[source]

Plot

Parameters:
  • annotate (bool, optional) – Whether to scale the axes view to the data

  • autoscale (bool, optional) – Whether to adjust the x,y limits of the plot to fit the implant

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

  • stim_cmap (bool, str, or matplotlib colormap, optional) – If not false, the fill color of the plotted electrodes will vary based on maximum stimulus amplitude on each electrode. The chosen colormap will be used if provided

Returns:

ax – Returns the axis object of the plot

Return type:

matplotlib.axes.Axes

preprocess_stim(stim)[source]

Preprocess the stimulus

This methods is executed every time a new value is assigned to stim.

No preprocessing is performed by default, but the user can define their own method in implants that inherit from return stim ProsthesisSystem.

A custom method must return a Stimulus object with the correct number of electrodes for the implant.

Parameters:

stim (Stimulus source type) – A valid source type for the Stimulus object (e.g., scalar, NumPy array, pulse train).

Returns:

stim_out

Return type:

Stimulus object

property raster

Raster pattern

Most implants do not set this in their constructor, so the slot backing it may never have been written to; an unset raster means all electrodes may fire at once.

class pulse2percept.implants.AlphaIMS(x=0, y=0, z=-100, rot=0, eye='RE', stim=None, preprocess=True, safe_mode=False)[source]

Alpha-IMS

This class creates an Alpha-IMS array with 1500 photovoltaic pixels (each 50um in diameter) as described in [Stingl2013], and places it in the subretinal space, such that the center of the array is located at (x,y,z), given in microns, and the array is rotated by rotation angle rot, given in degrees.

The device consists of 1500 50um-wide square pixels, arranged on a 39x39 rectangular grid with 72um pixel pitch.

The array is oriented upright in the visual field, such that an array with center (0,0) has the top three rows lie in the lower retina (upper visual field).

An electrode can be addressed by name, row/column index, or integer index (into the flattened array).

Note

Column order is reversed in a left-eye implant.

Parameters:
  • x/y/z (double) – 3D location (um) of the center of the electrode array. The coordinate system is centered over the fovea. Positive x values move the electrode into the nasal retina. Positive y values move the electrode into the superior retina. Positive z values move the electrode away from the retina into the vitreous humor (sometimes called electrode-retina distance). z can either be a list with 1500 entries or a scalar that is applied to all electrodes. May be given as unitful quantities (e.g. z=100 * um); see pulse2percept.units.

  • rot (float) – Rotation angle of the array (deg). Positive values denote counter-clock-wise (CCW) rotations in the retinal coordinate system.

  • eye ({'RE', 'LE'}, optional) – Eye in which array is implanted.

  • preprocess (bool or callable, optional) – Either True/False to indicate whether to execute the implant’s default preprocessing method whenever a new stimulus is assigned, or a custom function (callable).

  • safe_mode (bool, optional) – If safe mode is enabled, only charge-balanced stimuli are allowed.

Examples

Create an Alpha-IMS array centered on the fovea, at 100um distance from the retina, rotated counter-clockwise by 5 degrees:

>>> from pulse2percept.implants import AlphaIMS
>>> AlphaIMS(x=0, y=0, z=100, rot=5)
AlphaIMS(earray=ElectrodeGrid, eye='RE', preprocess=True,
         safe_mode=False, shape=(39, 39), stim=None)

Get access to the third electrode in the top row (by name or by row/column index):

>>> alpha_ims = AlphaIMS(x=0, y=0, z=100, rot=0)
>>> alpha_ims['A3']
SquareElectrode(a=50.0, activated=True, name='A3',
                x=-1224.0, y=-1368.0, z=100.0)
>>> alpha_ims[0, 2]
SquareElectrode(a=50.0, activated=True, name='A3',
                x=-1224.0, y=-1368.0, z=100.0)
property eye

Implanted eye

A ProsthesisSystem can be implanted either in a left eye (‘LE’) or right eye (‘RE’). Models such as AxonMapModel will treat left and right eyes differently (for example, adjusting the location of the optic disc).

Examples

Implant Argus II in a left eye:

>>> from pulse2percept.implants import ArgusII
>>> implant = ArgusII(eye='LE')
property earray

Electrode array

property stim

Stimulus

A stimulus can be created from many source types, such as scalars, NumPy arrays, and dictionaries (see Stimulus for a complete list).

A stimulus can be assigned either in the ProsthesisSystem constructor or later by assigning a value to stim.

Note

Unless when using dictionary notation, the number of stimuli must equal the number of electrodes in earray.

Examples

Send a biphasic pulse (30uA, 0.45ms phase duration) to an implant made from a single DiskElectrode:

>>> from pulse2percept.implants import DiskElectrode, ProsthesisSystem
>>> from pulse2percept.stimuli import BiphasicPulse
>>> implant = ProsthesisSystem(DiskElectrode(0, 0, 0, 100))
>>> implant.stim = BiphasicPulse(30, 0.45)

Stimulate Electrode B7 in Argus II with 13 uA:

>>> from pulse2percept.implants import ArgusII
>>> implant = ArgusII(stim={'B7': 13})
check_stim(stim)[source]

Quality-check the stimulus

This method is executed every time a new value is assigned to stim.

If safe_mode is set to True, this function will only allow stimuli that are charge-balanced. If max_current is set, it will only allow stimuli whose total instantaneous current stays within it.

Both are questions about electricity, and neither can be answered about a stimulus that is not a current, so each raises a DimensionMismatchError on one. An implant that asks for neither does not run either check, which is why a dimensionless stimulus may still be assigned to one – preprocess has already had its chance to turn it into current, and if it did not, no safety claim is being made about it either.

The user can define their own checks in implants that inherit from ProsthesisSystem.

Parameters:

stim (Stimulus source type) – A valid source type for the Stimulus object (e.g., scalar, NumPy array, pulse train).

Raises:
  • DimensionMismatchError – If an electrical check was requested and stim is not measured in units of current.

  • .. versionchanged: – 0.10.0: The electrical checks verify that the stimulus really is electrical, instead of reading whatever numbers it holds as microamps.

property electrode_names

Return a list of all electrode names in the electrode array

property electrode_objects

Return a list of all electrode objects in the array

property electrodes

Return all electrode names and objects in the electrode array

Internally, electrodes are stored in an ordered dictionary. You can iterate over different electrodes in the array as follows:

for name, electrode in implant.electrodes.items():
    print(name, electrode)

You can access an individual electrode by indexing directly into the prosthesis system object, e.g. implant['A1'] or implant[0].

property max_current

Total instantaneous current (uA) the stimulator can source

property n_electrodes

Number of electrodes in the array

This is equivalent to calling earray.n_electrodes.

plot(annotate=False, autoscale=True, ax=None, stim_cmap=False)[source]

Plot

Parameters:
  • annotate (bool, optional) – Whether to scale the axes view to the data

  • autoscale (bool, optional) – Whether to adjust the x,y limits of the plot to fit the implant

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

  • stim_cmap (bool, str, or matplotlib colormap, optional) – If not false, the fill color of the plotted electrodes will vary based on maximum stimulus amplitude on each electrode. The chosen colormap will be used if provided

Returns:

ax – Returns the axis object of the plot

Return type:

matplotlib.axes.Axes

preprocess_stim(stim)[source]

Preprocess the stimulus

This methods is executed every time a new value is assigned to stim.

No preprocessing is performed by default, but the user can define their own method in implants that inherit from return stim ProsthesisSystem.

A custom method must return a Stimulus object with the correct number of electrodes for the implant.

Parameters:

stim (Stimulus source type) – A valid source type for the Stimulus object (e.g., scalar, NumPy array, pulse train).

Returns:

stim_out

Return type:

Stimulus object

property raster

Raster pattern

Most implants do not set this in their constructor, so the slot backing it may never have been written to; an unset raster means all electrodes may fire at once.

class pulse2percept.implants.ArgusI(x=0, y=0, z=0, rot=0, eye='RE', stim=None, preprocess=True, safe_mode=False, use_legacy_names=False)[source]

Create an Argus I array on the retina

This function creates an Argus I array and places it on the retina such that the center of the array is located at 3D location (x,y,z), given in microns, and the array is rotated by rotation angle rot, given in degrees.

Argus I is a modified cochlear implant containing 16 electrodes in a 4x4 array with a center-to-center separation of 800 um, and two electrode diameters (250 um and 500 um) arranged in a checkerboard pattern [Yue2020].

The array is oriented in the visual field as shown in Fig. 1 of [Horsager2009]; that is, if placed in (0,0), the top two rows will lie in the lower retina (upper visual field):

  -->x    A1 B1 C1 D1                     260 520 260 520
  |       A2 B2 C2 D2   where electrode   520 260 520 260
  v       A3 B3 C3 D3   diameters are:    260 520 260 520
   y      A4 B4 C4 D4                     520 260 520 260

Electrode order is: A1, B1, C1, D1, A2, B2, …, D4.

If use_legacy_names is True, electrode order is: L6, L2, M8, M4, …

An electrode can be addressed by name, row/column index, or integer index (into the flattened array).

Note

Column order is reversed in a left-eye implant.

Parameters:
  • x/y/z (double) – 3D location of the center of the electrode array. The coordinate system is centered over the fovea. Positive x values move the electrode into the nasal retina. Positive y values move the electrode into the superior retina. Positive z values move the electrode away from the retina into the vitreous humor (sometimes called electrode-retina distance). z can either be a list with 16 entries or a scalar that is applied to all electrodes.

  • rot (float, optional) – Rotation angle of the array (deg). Positive values denote counter-clock-wise (CCW) rotations in the retinal coordinate system.

  • eye ({'RE', 'LE'}, optional) – Eye in which array is implanted.

  • preprocess (bool or callable, optional) – Either True/False to indicate whether to execute the implant’s default preprocessing method whenever a new stimulus is assigned, or a custom function (callable).

  • safe_mode (bool, optional) – If safe mode is enabled, only charge-balanced stimuli are allowed.

  • use_legacy_names (bool, optional) – If True, uses L/M based electrode names from older papers (e.g., L6, L2) instead of A1-A16.

Examples

Create an Argus I array centered on the fovea, at 100um distance from the retina, rotated counter-clockwise by 5 degrees:

>>> from pulse2percept.implants import ArgusI
>>> ArgusI(x=0, y=0, z=100, rot=5)
ArgusI(earray=ElectrodeGrid, eye='RE', preprocess=True,
       safe_mode=False, shape=(4, 4), stim=None)

Get access to electrode ‘B1’, either by name or by row/column index:

>>> argus = ArgusI(x=0, y=0, z=100, rot=0)
>>> argus['B1']
DiskElectrode(activated=True, name='B1', r=250.0, x=-400.0,
              y=-1200.0, z=100.0)
>>> argus[0, 1]
DiskElectrode(activated=True, name='B1', r=250.0, x=-400.0,
              y=-1200.0, z=100.0)
property earray

Electrode array

property stim

Stimulus

A stimulus can be created from many source types, such as scalars, NumPy arrays, and dictionaries (see Stimulus for a complete list).

A stimulus can be assigned either in the ProsthesisSystem constructor or later by assigning a value to stim.

Note

Unless when using dictionary notation, the number of stimuli must equal the number of electrodes in earray.

Examples

Send a biphasic pulse (30uA, 0.45ms phase duration) to an implant made from a single DiskElectrode:

>>> from pulse2percept.implants import DiskElectrode, ProsthesisSystem
>>> from pulse2percept.stimuli import BiphasicPulse
>>> implant = ProsthesisSystem(DiskElectrode(0, 0, 0, 100))
>>> implant.stim = BiphasicPulse(30, 0.45)

Stimulate Electrode B7 in Argus II with 13 uA:

>>> from pulse2percept.implants import ArgusII
>>> implant = ArgusII(stim={'B7': 13})
property eye

Implanted eye

A ProsthesisSystem can be implanted either in a left eye (‘LE’) or right eye (‘RE’). Models such as AxonMapModel will treat left and right eyes differently (for example, adjusting the location of the optic disc).

Examples

Implant Argus II in a left eye:

>>> from pulse2percept.implants import ArgusII
>>> implant = ArgusII(eye='LE')
check_stim(stim)[source]

Quality-check the stimulus

This method is executed every time a new value is assigned to stim.

If safe_mode is set to True, this function will only allow stimuli that are charge-balanced. If max_current is set, it will only allow stimuli whose total instantaneous current stays within it.

Both are questions about electricity, and neither can be answered about a stimulus that is not a current, so each raises a DimensionMismatchError on one. An implant that asks for neither does not run either check, which is why a dimensionless stimulus may still be assigned to one – preprocess has already had its chance to turn it into current, and if it did not, no safety claim is being made about it either.

The user can define their own checks in implants that inherit from ProsthesisSystem.

Parameters:

stim (Stimulus source type) – A valid source type for the Stimulus object (e.g., scalar, NumPy array, pulse train).

Raises:
  • DimensionMismatchError – If an electrical check was requested and stim is not measured in units of current.

  • .. versionchanged: – 0.10.0: The electrical checks verify that the stimulus really is electrical, instead of reading whatever numbers it holds as microamps.

property electrode_names

Return a list of all electrode names in the electrode array

property electrode_objects

Return a list of all electrode objects in the array

property electrodes

Return all electrode names and objects in the electrode array

Internally, electrodes are stored in an ordered dictionary. You can iterate over different electrodes in the array as follows:

for name, electrode in implant.electrodes.items():
    print(name, electrode)

You can access an individual electrode by indexing directly into the prosthesis system object, e.g. implant['A1'] or implant[0].

property max_current

Total instantaneous current (uA) the stimulator can source

property n_electrodes

Number of electrodes in the array

This is equivalent to calling earray.n_electrodes.

plot(annotate=False, autoscale=True, ax=None, stim_cmap=False)[source]

Plot

Parameters:
  • annotate (bool, optional) – Whether to scale the axes view to the data

  • autoscale (bool, optional) – Whether to adjust the x,y limits of the plot to fit the implant

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

  • stim_cmap (bool, str, or matplotlib colormap, optional) – If not false, the fill color of the plotted electrodes will vary based on maximum stimulus amplitude on each electrode. The chosen colormap will be used if provided

Returns:

ax – Returns the axis object of the plot

Return type:

matplotlib.axes.Axes

preprocess_stim(stim)[source]

Preprocess the stimulus

This methods is executed every time a new value is assigned to stim.

No preprocessing is performed by default, but the user can define their own method in implants that inherit from return stim ProsthesisSystem.

A custom method must return a Stimulus object with the correct number of electrodes for the implant.

Parameters:

stim (Stimulus source type) – A valid source type for the Stimulus object (e.g., scalar, NumPy array, pulse train).

Returns:

stim_out

Return type:

Stimulus object

property raster

Raster pattern

Most implants do not set this in their constructor, so the slot backing it may never have been written to; an unset raster means all electrodes may fire at once.

class pulse2percept.implants.ArgusII(x=0, y=0, z=0, rot=0, eye='RE', stim=None, preprocess=True, safe_mode=False)[source]

Create an Argus II array on the retina

This function creates an Argus II array and places it on the retina such that the center of the array is located at (x,y,z), given in microns, and the array is rotated by rotation angle rot, given in degrees.

Argus II contains 60 electrodes of 225 um diameter arranged in a 6 x 10 grid (575 um center-to-center separation) [Yue2020].

The array is oriented upright in the visual field, such that an array with center (0,0) has the top three rows lie in the lower retina (upper visual field), as shown below:

          A1 A2 A3 A4 A5 A6 A7 A8 A9 A10
  -- x    B1 B2 B3 B4 B5 B6 B7 B8 B9 B10
  |       C1 C2 C3 C4 C5 C6 C7 C8 C9 C10
  v       D1 D2 D3 D4 D5 D6 D7 D8 D9 D10
   y      E1 E2 E3 E4 E5 E6 E7 E8 E9 E10
          F1 F2 F3 F4 F5 F6 F7 F8 F9 F10

Electrode order is: A1, A2, …, A10, B1, B2, …, F10.

An electrode can be addressed by name, row/column index, or integer index (into the flattened array).

Note

Column order is reversed in a left-eye implant.

Parameters:
  • x/y/z (double) – 3D location of the center of the electrode array. The coordinate system is centered over the fovea. Positive x values move the electrode into the nasal retina. Positive y values move the electrode into the superior retina. Positive z values move the electrode away from the retina into the vitreous humor (sometimes called electrode-retina distance). z can either be a list with 60 entries or a scalar that is applied to all electrodes.

  • rot (float) – Rotation angle of the array (deg). Positive values denote counter-clock-wise (CCW) rotations in the retinal coordinate system.

  • eye ({'RE', 'LE'}, optional) – Eye in which array is implanted.

  • preprocess (bool or callable, optional) – Either True/False to indicate whether to execute the implant’s default preprocessing method whenever a new stimulus is assigned, or a custom function (callable).

  • safe_mode (bool, optional) – If safe mode is enabled, only charge-balanced stimuli are allowed.

Examples

Create an ArgusII array centered on the fovea, at 100um distance from the retina, rotated counter-clockwise by 5 degrees:

>>> from pulse2percept.implants import ArgusII
>>> ArgusII(x=0, y=0, z=100, rot=5)
ArgusII(earray=ElectrodeGrid, eye='RE', preprocess=True,
        safe_mode=False, shape=(6, 10), stim=None)

Get access to electrode ‘E7’, either by name or by row/column index:

>>> argus = ArgusII(x=0, y=0, z=100, rot=0)
>>> argus['E7']
DiskElectrode(activated=True, name='E7', r=112.5, x=862.5,
              y=862.5, z=100.0)
>>> argus[4, 6]
DiskElectrode(activated=True, name='E7', r=112.5, x=862.5,
              y=862.5, z=100.0)
property earray

Electrode array

property stim

Stimulus

A stimulus can be created from many source types, such as scalars, NumPy arrays, and dictionaries (see Stimulus for a complete list).

A stimulus can be assigned either in the ProsthesisSystem constructor or later by assigning a value to stim.

Note

Unless when using dictionary notation, the number of stimuli must equal the number of electrodes in earray.

Examples

Send a biphasic pulse (30uA, 0.45ms phase duration) to an implant made from a single DiskElectrode:

>>> from pulse2percept.implants import DiskElectrode, ProsthesisSystem
>>> from pulse2percept.stimuli import BiphasicPulse
>>> implant = ProsthesisSystem(DiskElectrode(0, 0, 0, 100))
>>> implant.stim = BiphasicPulse(30, 0.45)

Stimulate Electrode B7 in Argus II with 13 uA:

>>> from pulse2percept.implants import ArgusII
>>> implant = ArgusII(stim={'B7': 13})
property eye

Implanted eye

A ProsthesisSystem can be implanted either in a left eye (‘LE’) or right eye (‘RE’). Models such as AxonMapModel will treat left and right eyes differently (for example, adjusting the location of the optic disc).

Examples

Implant Argus II in a left eye:

>>> from pulse2percept.implants import ArgusII
>>> implant = ArgusII(eye='LE')
check_stim(stim)[source]

Quality-check the stimulus

This method is executed every time a new value is assigned to stim.

If safe_mode is set to True, this function will only allow stimuli that are charge-balanced. If max_current is set, it will only allow stimuli whose total instantaneous current stays within it.

Both are questions about electricity, and neither can be answered about a stimulus that is not a current, so each raises a DimensionMismatchError on one. An implant that asks for neither does not run either check, which is why a dimensionless stimulus may still be assigned to one – preprocess has already had its chance to turn it into current, and if it did not, no safety claim is being made about it either.

The user can define their own checks in implants that inherit from ProsthesisSystem.

Parameters:

stim (Stimulus source type) – A valid source type for the Stimulus object (e.g., scalar, NumPy array, pulse train).

Raises:
  • DimensionMismatchError – If an electrical check was requested and stim is not measured in units of current.

  • .. versionchanged: – 0.10.0: The electrical checks verify that the stimulus really is electrical, instead of reading whatever numbers it holds as microamps.

property electrode_names

Return a list of all electrode names in the electrode array

property electrode_objects

Return a list of all electrode objects in the array

property electrodes

Return all electrode names and objects in the electrode array

Internally, electrodes are stored in an ordered dictionary. You can iterate over different electrodes in the array as follows:

for name, electrode in implant.electrodes.items():
    print(name, electrode)

You can access an individual electrode by indexing directly into the prosthesis system object, e.g. implant['A1'] or implant[0].

property max_current

Total instantaneous current (uA) the stimulator can source

property n_electrodes

Number of electrodes in the array

This is equivalent to calling earray.n_electrodes.

plot(annotate=False, autoscale=True, ax=None, stim_cmap=False)[source]

Plot

Parameters:
  • annotate (bool, optional) – Whether to scale the axes view to the data

  • autoscale (bool, optional) – Whether to adjust the x,y limits of the plot to fit the implant

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

  • stim_cmap (bool, str, or matplotlib colormap, optional) – If not false, the fill color of the plotted electrodes will vary based on maximum stimulus amplitude on each electrode. The chosen colormap will be used if provided

Returns:

ax – Returns the axis object of the plot

Return type:

matplotlib.axes.Axes

preprocess_stim(stim)[source]

Preprocess the stimulus

This methods is executed every time a new value is assigned to stim.

No preprocessing is performed by default, but the user can define their own method in implants that inherit from return stim ProsthesisSystem.

A custom method must return a Stimulus object with the correct number of electrodes for the implant.

Parameters:

stim (Stimulus source type) – A valid source type for the Stimulus object (e.g., scalar, NumPy array, pulse train).

Returns:

stim_out

Return type:

Stimulus object

property raster

Raster pattern

Most implants do not set this in their constructor, so the slot backing it may never have been written to; an unset raster means all electrodes may fire at once.

class pulse2percept.implants.BVT24(x=0, y=0, z=0, rot=0, eye='RE', stim=None, preprocess=False, safe_mode=False)[source]

24-channel suprachoroidal retinal prosthesis

This class creates a 24-channel suprachoroidal retinal prosthesis [Layton2014], which was developed by the Bionic Vision Australia Consortium and commercialized by Bionic Vision Technologies (BVT). The center of the array is located at (x,y,z), given in microns, and the array is rotated counter-clockwise by rotation angle rot, given in degrees.

The array consists of:

  • 33 platinum stimulating electrodes:

    • 30 electrodes with 600um diameter (Electrodes C1-20 (except C9, C17, C19) and Electrodes C21a-m),

    • 3 electrodes with 400um diameter (Electrodes C9, C17, C19)

  • 2 return electrodes with 2000um diameter (Electrodes R1, R2)

Electrodes C21a-m are typically being ganged to provide an external ring for common ground. The center of the array is assumed to lie between Electrodes C7, C8, C9, and C13.

Note

Column order for electrode numbering is reversed in a left-eye implant.

Added in version 0.6.

Parameters:
  • x/y/z (double) – 3D location (um) of the center of the electrode array. The coordinate system is centered over the fovea. Positive x values move the electrode into the nasal retina. Positive y values move the electrode into the superior retina. Positive z values move the electrode away from the retina into the vitreous humor (sometimes called electrode-retina distance). z can either be a list with 35 entries or a scalar that is applied to all electrodes. May be given as unitful quantities (e.g. z=100 * um); see pulse2percept.units.

  • rot (float) – Rotation angle of the array (deg). Positive values denote counter-clock-wise (CCW) rotations in the retinal coordinate system.

  • eye ({'RE', 'LE'}, optional) – Eye in which array is implanted.

  • preprocess (bool or callable, optional) – Either True/False to indicate whether to execute the implant’s default preprocessing method whenever a new stimulus is assigned, or a custom function (callable).

  • safe_mode (bool, optional) – If safe mode is enabled, only charge-balanced stimuli are allowed.

property eye

Implanted eye

A ProsthesisSystem can be implanted either in a left eye (‘LE’) or right eye (‘RE’). Models such as AxonMapModel will treat left and right eyes differently (for example, adjusting the location of the optic disc).

Examples

Implant Argus II in a left eye:

>>> from pulse2percept.implants import ArgusII
>>> implant = ArgusII(eye='LE')
property earray

Electrode array

property stim

Stimulus

A stimulus can be created from many source types, such as scalars, NumPy arrays, and dictionaries (see Stimulus for a complete list).

A stimulus can be assigned either in the ProsthesisSystem constructor or later by assigning a value to stim.

Note

Unless when using dictionary notation, the number of stimuli must equal the number of electrodes in earray.

Examples

Send a biphasic pulse (30uA, 0.45ms phase duration) to an implant made from a single DiskElectrode:

>>> from pulse2percept.implants import DiskElectrode, ProsthesisSystem
>>> from pulse2percept.stimuli import BiphasicPulse
>>> implant = ProsthesisSystem(DiskElectrode(0, 0, 0, 100))
>>> implant.stim = BiphasicPulse(30, 0.45)

Stimulate Electrode B7 in Argus II with 13 uA:

>>> from pulse2percept.implants import ArgusII
>>> implant = ArgusII(stim={'B7': 13})
check_stim(stim)[source]

Quality-check the stimulus

This method is executed every time a new value is assigned to stim.

If safe_mode is set to True, this function will only allow stimuli that are charge-balanced. If max_current is set, it will only allow stimuli whose total instantaneous current stays within it.

Both are questions about electricity, and neither can be answered about a stimulus that is not a current, so each raises a DimensionMismatchError on one. An implant that asks for neither does not run either check, which is why a dimensionless stimulus may still be assigned to one – preprocess has already had its chance to turn it into current, and if it did not, no safety claim is being made about it either.

The user can define their own checks in implants that inherit from ProsthesisSystem.

Parameters:

stim (Stimulus source type) – A valid source type for the Stimulus object (e.g., scalar, NumPy array, pulse train).

Raises:
  • DimensionMismatchError – If an electrical check was requested and stim is not measured in units of current.

  • .. versionchanged: – 0.10.0: The electrical checks verify that the stimulus really is electrical, instead of reading whatever numbers it holds as microamps.

property electrode_names

Return a list of all electrode names in the electrode array

property electrode_objects

Return a list of all electrode objects in the array

property electrodes

Return all electrode names and objects in the electrode array

Internally, electrodes are stored in an ordered dictionary. You can iterate over different electrodes in the array as follows:

for name, electrode in implant.electrodes.items():
    print(name, electrode)

You can access an individual electrode by indexing directly into the prosthesis system object, e.g. implant['A1'] or implant[0].

property max_current

Total instantaneous current (uA) the stimulator can source

property n_electrodes

Number of electrodes in the array

This is equivalent to calling earray.n_electrodes.

plot(annotate=False, autoscale=True, ax=None, stim_cmap=False)[source]

Plot

Parameters:
  • annotate (bool, optional) – Whether to scale the axes view to the data

  • autoscale (bool, optional) – Whether to adjust the x,y limits of the plot to fit the implant

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

  • stim_cmap (bool, str, or matplotlib colormap, optional) – If not false, the fill color of the plotted electrodes will vary based on maximum stimulus amplitude on each electrode. The chosen colormap will be used if provided

Returns:

ax – Returns the axis object of the plot

Return type:

matplotlib.axes.Axes

preprocess_stim(stim)[source]

Preprocess the stimulus

This methods is executed every time a new value is assigned to stim.

No preprocessing is performed by default, but the user can define their own method in implants that inherit from return stim ProsthesisSystem.

A custom method must return a Stimulus object with the correct number of electrodes for the implant.

Parameters:

stim (Stimulus source type) – A valid source type for the Stimulus object (e.g., scalar, NumPy array, pulse train).

Returns:

stim_out

Return type:

Stimulus object

property raster

Raster pattern

Most implants do not set this in their constructor, so the slot backing it may never have been written to; an unset raster means all electrodes may fire at once.

class pulse2percept.implants.BVT44(x=0, y=0, z=0, rot=0, eye='LE', stim=None, preprocess=False, safe_mode=False)[source]

44-channel suprachoroidal retinal prosthesis

This class creates a 44-channel suprachoroidal retinal prosthesis [Petoe2021], which was developed by the Bionic Vision Australia Consortium and commercialized by Bionic Vision Technologies (BVT).

The center of the array (x,y,z) is located at the center of electrodes D4, D5, C4, and E4, and the array is rotated counter-clockwise by rotation angle rot, given in degrees.

The array consists of:

  • 44 platinum stimulating electrodes with 1000um exposed diameter

  • 2 return electrodes with 2000um diameter (Electrodes R1, R2)

The position of each electrode is measured from Figure 7 in [Petoe2021].

Note

Column order for electrode numbering is reversed in a left-eye implant.

Added in version 0.8.

Parameters:
  • x/y/z (double) – 3D location (um) of the center of the electrode array. The coordinate system is centered over the fovea. Positive x values move the electrode into the nasal retina. Positive y values move the electrode into the superior retina. Positive z values move the electrode away from the retina into the vitreous humor (sometimes called electrode-retina distance). z can either be a list with 35 entries or a scalar that is applied to all electrodes. May be given as unitful quantities (e.g. z=100 * um); see pulse2percept.units.

  • rot (float) – Rotation angle of the array (deg). Positive values denote counter-clock-wise (CCW) rotations in the retinal coordinate system.

  • eye ({'RE', 'LE'}, optional) – Eye in which array is implanted.

  • preprocess (bool or callable, optional) – Either True/False to indicate whether to execute the implant’s default preprocessing method whenever a new stimulus is assigned, or a custom function (callable).

  • safe_mode (bool, optional) – If safe mode is enabled, only charge-balanced stimuli are allowed.

property eye

Implanted eye

A ProsthesisSystem can be implanted either in a left eye (‘LE’) or right eye (‘RE’). Models such as AxonMapModel will treat left and right eyes differently (for example, adjusting the location of the optic disc).

Examples

Implant Argus II in a left eye:

>>> from pulse2percept.implants import ArgusII
>>> implant = ArgusII(eye='LE')
property earray

Electrode array

property stim

Stimulus

A stimulus can be created from many source types, such as scalars, NumPy arrays, and dictionaries (see Stimulus for a complete list).

A stimulus can be assigned either in the ProsthesisSystem constructor or later by assigning a value to stim.

Note

Unless when using dictionary notation, the number of stimuli must equal the number of electrodes in earray.

Examples

Send a biphasic pulse (30uA, 0.45ms phase duration) to an implant made from a single DiskElectrode:

>>> from pulse2percept.implants import DiskElectrode, ProsthesisSystem
>>> from pulse2percept.stimuli import BiphasicPulse
>>> implant = ProsthesisSystem(DiskElectrode(0, 0, 0, 100))
>>> implant.stim = BiphasicPulse(30, 0.45)

Stimulate Electrode B7 in Argus II with 13 uA:

>>> from pulse2percept.implants import ArgusII
>>> implant = ArgusII(stim={'B7': 13})
check_stim(stim)[source]

Quality-check the stimulus

This method is executed every time a new value is assigned to stim.

If safe_mode is set to True, this function will only allow stimuli that are charge-balanced. If max_current is set, it will only allow stimuli whose total instantaneous current stays within it.

Both are questions about electricity, and neither can be answered about a stimulus that is not a current, so each raises a DimensionMismatchError on one. An implant that asks for neither does not run either check, which is why a dimensionless stimulus may still be assigned to one – preprocess has already had its chance to turn it into current, and if it did not, no safety claim is being made about it either.

The user can define their own checks in implants that inherit from ProsthesisSystem.

Parameters:

stim (Stimulus source type) – A valid source type for the Stimulus object (e.g., scalar, NumPy array, pulse train).

Raises:
  • DimensionMismatchError – If an electrical check was requested and stim is not measured in units of current.

  • .. versionchanged: – 0.10.0: The electrical checks verify that the stimulus really is electrical, instead of reading whatever numbers it holds as microamps.

property electrode_names

Return a list of all electrode names in the electrode array

property electrode_objects

Return a list of all electrode objects in the array

property electrodes

Return all electrode names and objects in the electrode array

Internally, electrodes are stored in an ordered dictionary. You can iterate over different electrodes in the array as follows:

for name, electrode in implant.electrodes.items():
    print(name, electrode)

You can access an individual electrode by indexing directly into the prosthesis system object, e.g. implant['A1'] or implant[0].

property max_current

Total instantaneous current (uA) the stimulator can source

property n_electrodes

Number of electrodes in the array

This is equivalent to calling earray.n_electrodes.

plot(annotate=False, autoscale=True, ax=None, stim_cmap=False)[source]

Plot

Parameters:
  • annotate (bool, optional) – Whether to scale the axes view to the data

  • autoscale (bool, optional) – Whether to adjust the x,y limits of the plot to fit the implant

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

  • stim_cmap (bool, str, or matplotlib colormap, optional) – If not false, the fill color of the plotted electrodes will vary based on maximum stimulus amplitude on each electrode. The chosen colormap will be used if provided

Returns:

ax – Returns the axis object of the plot

Return type:

matplotlib.axes.Axes

preprocess_stim(stim)[source]

Preprocess the stimulus

This methods is executed every time a new value is assigned to stim.

No preprocessing is performed by default, but the user can define their own method in implants that inherit from return stim ProsthesisSystem.

A custom method must return a Stimulus object with the correct number of electrodes for the implant.

Parameters:

stim (Stimulus source type) – A valid source type for the Stimulus object (e.g., scalar, NumPy array, pulse train).

Returns:

stim_out

Return type:

Stimulus object

property raster

Raster pattern

Most implants do not set this in their constructor, so the slot backing it may never have been written to; an unset raster means all electrodes may fire at once.

class pulse2percept.implants.CheckerboardRaster(implant, n_groups, balance=0.05, group_dur=None)[source]

Split electrodes into groups that are spread as far apart as possible

Implements a generalized form of the checkerboard raster pattern tested in [Kasowski2025], which found that scattering raster groups over the whole array beat horizontal, vertical, and random rasters at letter recognition and motion discrimination, and matched not rastering at all.

Mathematically speaking, a raster group is a coset of a sublattice of the electrode grid. Within a group, electrodes sit as far from one another as the electrode count allows. Each group is a coarser copy of the grid. Between groups, the order is chosen so the pattern doubles back rather than marching on (to reduce apparent motion). For example: Five groups on a square grid come out one over, two over, one back, two over, so that the percept steps right, down, left, down, and back rather than sliding across the array.

The grid does not have to be rectangular: hexagonal grids, rotated grids, grids with unequal row and column spacing, and grids with electrodes trimmed off are all handled, since the pattern is derived from where the electrodes actually are. Arrays whose electrodes do not lie on a grid at all raise NotImplementedError.

Note

Not every n_groups fits a given grid, and one that does not raises a ValueError and specifies counts that do.

Both halves of the pattern are searched for when the raster is built, and the order the groups fire in is settled exactly only up to eight groups; beyond that a heuristic stands in for it, and the search grows with the group count.

It is worth checking min_spacing on the ones that do fit, because a count can be accepted and still leave neighbors in the same group. The standard example is two groups on a hex grid, which degenerates to a line raster. In other words, implants like PRIMA cannot be two-colored; they want 3, 4, or 7 raster groups instead.

Added in version 0.10.0.

Parameters:
  • implant (ProsthesisSystem) – The implant to build the pattern for, or its ElectrodeArray. The electrodes have to lie on a grid, and their names are how the raster recognizes them later, so this has to be the implant the stimulus will be applied to.

  • n_groups (int) – Number of groups to split the electrodes into.

  • balance (float, optional) – How much bigger the largest group may be than an even split would make it, as a fraction of it. The largest group is what sets the current the stimulator has to source, so this is the price being paid; what it buys is spacing, because the patterns that spread furthest do not always land evenly on a grid whose edges have been trimmed. Pass 0 to add no imbalance beyond the rounding an uneven electrode count forces anyway – 378 electrodes in 5 groups are 76, 76, 75, 75, 76 at balance=0, never 76 apiece – and take whatever spacing comes with it.

  • group_dur (float, optional) – See Raster.

Examples

Five groups of twelve on Argus II, as in [Kasowski2025]:

>>> from pulse2percept.implants import ArgusII, CheckerboardRaster
>>> implant = ArgusII()
>>> implant.raster = CheckerboardRaster(implant, 5)
>>> implant.raster.n_groups
5

No two electrodes of a group are closer than sqrt(5) pitches, where a line raster would have them adjacent:

>>> round(implant.raster.min_spacing / 575, 3)  # 575 um pitch
2.236

The pattern is easiest to check by eye (plot()), and the electrodes that fire together are members():

>>> implant.raster.members(implant.electrode_names, 0)[:4].tolist()
['A1', 'A6', 'B3', 'B8']
property n_groups

Number of raster groups

property min_spacing

Distance (um) between the closest two electrodes of a group

How much the checkerboard bought over a line raster, which leaves neighboring electrodes in the same group and so would report the electrode pitch. Measured between electrodes the implant actually has, so a small or trimmed array can come out better spaced than the pattern it was cut from. Infinite when no group holds more than one electrode, since then no two electrodes ever fire together.

groups(electrodes)[source]

Assign each electrode to a raster group

members(electrodes, group)[source]

The electrodes that take their turn together in one group

The inverse of groups(), which says what group each electrode is in. This says which electrodes are in a group.

Parameters:
  • electrodes (array_like) – Electrode names, in the order they appear in the stimulus.

  • group (int) – Which group to look up, in 0..n_groups-1. Groups take their turns in index order, so group 0 is the one that goes first.

Returns:

members – The entries of electrodes belonging to group, in the order they were given: names in, names out.

Return type:

array

Examples

>>> from pulse2percept.implants import ArgusII, SequentialRaster
>>> names = ArgusII().electrode_names
>>> SequentialRaster(6).members(names, 0)[:4]
array(['A1', 'A2', 'A3', 'A4'], dtype='<U3')
offsets(electrodes, period)[source]

How far behind group 0 each electrode’s slot begins

Parameters:
  • electrodes (array_like) – Electrode names, in the order they appear in the stimulus.

  • period (float) – The pulse period (ms) a sweep has to fit into.

Returns:

offset – Time (ms) between the start of a sweep and the start of this electrode’s slot.

Return type:

(n_electrodes,) float array

plot(implant, annotate=None, ax=None, cmap='viridis', autoscale=True)[source]

Plot the electrode array, colored by raster group

What a raster does is spatial, so the quickest way to tell whether it does what was wanted is to look at it. Colors run in the order the groups take their turns, so the picture shows the schedule as well as the pattern: with CheckerboardRaster a group’s electrodes should be scattered over the whole array rather than gathered into a line, and neighboring colors should not lie next to one another in a consistent direction.

Parameters:
  • implant (ProsthesisSystem) – The implant to draw, or its ElectrodeArray. Its electrodes are the ones the raster is asked about, so this has to be an implant the raster covers.

  • annotate (bool, optional) – Whether to write the group index into each electrode. If None, they are written whenever there are few enough electrodes (at most 120) for the numbers to be readable.

  • ax (matplotlib.axes.Axes, optional) – Axes to draw on. If None, uses the current axes.

  • cmap (str, optional) – Matplotlib colormap the group colors are taken from, evenly spaced. A sequential map is the useful default, since the order the colors run in is the order the groups fire in.

  • autoscale (bool, optional) – Whether to fit the x/y limits to the implant.

Returns:

ax – The axes drawn on.

Return type:

matplotlib.axes.Axes

slot_dur(period)[source]

Duration (ms) of one group’s slot

Parameters:

period (float) – The pulse period (ms) a sweep has to fit into, so that every group gets its turn before the first one comes round again.

Returns:

slot_durgroup_dur if one was given, else the period split evenly between the groups.

Return type:

float

class pulse2percept.implants.CustomRaster(groups, group_dur=None)[source]

Assign electrodes to raster groups by name

Added in version 0.10.0.

Parameters:
  • groups (list of lists, or dict) – Either a list whose i-th element holds the names of the electrodes in group i, or a dict mapping each electrode name onto its group index. Every electrode in the stimulus must be accounted for, and no electrode may appear in two groups.

  • group_dur (float, optional) – See Raster.

Examples

Fire the four corners of Argus II before everything else. Every other electrode has to be given a group too, or the current limit that the raster exists to respect could be violated without anyone noticing:

>>> from pulse2percept.implants import ArgusII, CustomRaster
>>> corners = ['A1', 'A10', 'F1', 'F10']
>>> rest = [e for e in ArgusII().electrode_names if e not in corners]
>>> raster = CustomRaster([corners, rest])
>>> raster.n_groups
2
property n_groups

Number of raster groups

groups(electrodes)[source]

Assign each electrode to a raster group

members(electrodes, group)[source]

The electrodes that take their turn together in one group

The inverse of groups(), which says what group each electrode is in. This says which electrodes are in a group.

Parameters:
  • electrodes (array_like) – Electrode names, in the order they appear in the stimulus.

  • group (int) – Which group to look up, in 0..n_groups-1. Groups take their turns in index order, so group 0 is the one that goes first.

Returns:

members – The entries of electrodes belonging to group, in the order they were given: names in, names out.

Return type:

array

Examples

>>> from pulse2percept.implants import ArgusII, SequentialRaster
>>> names = ArgusII().electrode_names
>>> SequentialRaster(6).members(names, 0)[:4]
array(['A1', 'A2', 'A3', 'A4'], dtype='<U3')
offsets(electrodes, period)[source]

How far behind group 0 each electrode’s slot begins

Parameters:
  • electrodes (array_like) – Electrode names, in the order they appear in the stimulus.

  • period (float) – The pulse period (ms) a sweep has to fit into.

Returns:

offset – Time (ms) between the start of a sweep and the start of this electrode’s slot.

Return type:

(n_electrodes,) float array

plot(implant, annotate=None, ax=None, cmap='viridis', autoscale=True)[source]

Plot the electrode array, colored by raster group

What a raster does is spatial, so the quickest way to tell whether it does what was wanted is to look at it. Colors run in the order the groups take their turns, so the picture shows the schedule as well as the pattern: with CheckerboardRaster a group’s electrodes should be scattered over the whole array rather than gathered into a line, and neighboring colors should not lie next to one another in a consistent direction.

Parameters:
  • implant (ProsthesisSystem) – The implant to draw, or its ElectrodeArray. Its electrodes are the ones the raster is asked about, so this has to be an implant the raster covers.

  • annotate (bool, optional) – Whether to write the group index into each electrode. If None, they are written whenever there are few enough electrodes (at most 120) for the numbers to be readable.

  • ax (matplotlib.axes.Axes, optional) – Axes to draw on. If None, uses the current axes.

  • cmap (str, optional) – Matplotlib colormap the group colors are taken from, evenly spaced. A sequential map is the useful default, since the order the colors run in is the order the groups fire in.

  • autoscale (bool, optional) – Whether to fit the x/y limits to the implant.

Returns:

ax – The axes drawn on.

Return type:

matplotlib.axes.Axes

slot_dur(period)[source]

Duration (ms) of one group’s slot

Parameters:

period (float) – The pulse period (ms) a sweep has to fit into, so that every group gets its turn before the first one comes round again.

Returns:

slot_durgroup_dur if one was given, else the period split evenly between the groups.

Return type:

float

class pulse2percept.implants.DiskElectrode(x, y, z, r, name=None, activated=True)[source]

Circular disk electrode

Parameters:
  • x/y/z (double) – 3D location of the electrode. The coordinate system is centered over the fovea. Positive x values move the electrode into the nasal retina. Positive y values move the electrode into the superior retina. Positive z values move the electrode away from the retina into the vitreous humor (sometimes called electrode-retina distance).

  • r (double) – Disk radius (um) in the x,y plane

  • name (str, optional) – Electrode name

  • activated (bool) – To deactivate, set to False. Deactivated electrodes cannot receive stimuli.

Notes

  • Lengths may be given as plain numbers of microns or as unitful quantities (e.g. DiskElectrode(1 * mm, 0, 0.1 * mm, 200 * um)). See pulse2percept.units.

electric_potential(x, y, z, v0)[source]

Calculate electric potential at (x, y, z)

Parameters:
  • x/y/z (double) – 3D location (um) at which to evaluate the electric potential. May be given as a unitful quantity, e.g. 0.2 * mm.

  • v0 (double) – The quasi-static disk potential relative to a ground electrode at infinity

Returns:

pot – The electric potential at (x, y, z).

Return type:

double

The electric potential \(V(r,z)\) of a disk electrode is given by [WileyWebster1982]:

\[V(r,z) = \sin^{-1} \bigg\{ \frac{2a}{\sqrt{(r-a)^2 + z^2} + \sqrt{(r+a)^2 + z^2}} \bigg\} \times \frac{2 V_0}{\pi},\]

for \(z \neq 0\), where \(r\) and \(z\) are the radial and axial distances from the center of the disk, \(V_0\) is the disk potential, \(\sigma\) is the medium conductivity, and \(a\) is the disk radius.

coordinate_unit = um[source]

The unit electrode coordinates are stored in. Electrodes hold plain numbers, which is what every kernel downstream of them expects; this says what those numbers mean.

coordinates(unit=None)[source]

3D position of the electrode

Added in version 0.10.0.

Parameters:

unit (Unit, optional) – Length unit to express the position in. If None, the position is returned as it is stored (microns).

Returns:

coords – An ordinary NumPy array [x, y, z], never a Quantity.

Return type:

(3,) np.ndarray

Examples

>>> from pulse2percept.implants import DiskElectrode
>>> from pulse2percept.units import mm
>>> DiskElectrode(1000, 0, 100, 200).coordinates(mm)
array([1. , 0. , 0.1])
plot(autoscale=False, ax=None)[source]

Plot

Parameters:
  • 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 given, a new one will be created.

Returns:

ax – Returns the axis object of the plot

Return type:

matplotlib.axes.Axes

class pulse2percept.implants.Electrode[source]

Abstract base class for all electrodes.

Parameters:
  • x/y/z (double) – 3D location of the electrode (um). The coordinate system is centered over the fovea. Positive x values move the electrode into the right visual field. Positive y values move the electrode into the left visual field. Positive z values move the electrode either into the cortex or into the vitreos humor.

  • name (str, optional) – Electrode name

  • activated (bool) – To deactivate, set to False. Deactivated electrodes cannot receive stimuli.

Notes

  • Coordinates may be given as plain numbers of microns or as unitful quantities (e.g. 1.2 * mm), which are converted to microns. See pulse2percept.units. Electrodes always store plain numbers in microns: x, y and z are ordinary floats, and so is everything downstream of them.

coordinate_unit = um[source]

The unit electrode coordinates are stored in. Electrodes hold plain numbers, which is what every kernel downstream of them expects; this says what those numbers mean.

coordinates(unit=None)[source]

3D position of the electrode

Added in version 0.10.0.

Parameters:

unit (Unit, optional) – Length unit to express the position in. If None, the position is returned as it is stored (microns).

Returns:

coords – An ordinary NumPy array [x, y, z], never a Quantity.

Return type:

(3,) np.ndarray

Examples

>>> from pulse2percept.implants import DiskElectrode
>>> from pulse2percept.units import mm
>>> DiskElectrode(1000, 0, 100, 200).coordinates(mm)
array([1. , 0. , 0.1])
plot(autoscale=False, ax=None)[source]

Plot

Parameters:
  • 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 given, a new one will be created.

Returns:

ax – Returns the axis object of the plot

Return type:

matplotlib.axes.Axes

class pulse2percept.implants.ElectrodeArray(electrodes)[source]

Electrode array

A collection of Electrode objects.

Parameters:

electrodes (array-like) –

Either a single Electrode object or a dict, list, or NumPy array thereof. The keys of the dict will serve as electrode names. Otherwise electrodes will be indexed 0..N.

Note

If you pass multiple electrodes in a dictionary, the keys of the dictionary will automatically be sorted. Thus the original order of electrodes might not be preserved.

Examples

Electrode array made from a single DiskElectrode:

>>> from pulse2percept.implants import ElectrodeArray, DiskElectrode
>>> earray = ElectrodeArray(DiskElectrode(0, 0, 0, 100))
>>> earray.electrodes
OrderedDict([(0,
              DiskElectrode(activated=True, name=None, r=100..., x=0..., y=0...,
              z=0...))])

Electrode array made from a single DiskElectrode with name ‘A1’:

>>> from pulse2percept.implants import ElectrodeArray, DiskElectrode
>>> earray = ElectrodeArray({'A1': DiskElectrode(0, 0, 0, 100)})
>>> earray.electrodes
OrderedDict([('A1',
              DiskElectrode(activated=True, name=None, r=100..., x=0..., y=0...,
              z=0...))])
coordinate_unit = um[source]

The unit electrode coordinates are stored in, i.e. what the plain numbers returned by coordinates() mean by default.

coordinates(unit=None, electrodes=None)[source]

Positions of the electrodes in the array

The one place to ask an implant where its electrodes are. Code that needs the coordinates in a particular unit says so here, instead of reading electrode.x and knowing that electrodes happen to store microns.

Added in version 0.10.0.

Parameters:
  • unit (Unit, optional) – Length unit to express the coordinates in. If None, they are returned as they are stored (microns).

  • electrodes (optional) –

    Which electrodes to return. Three things name a single electrode, looked up as earray[...] looks one up: a name, an index into the flattened array, and a (row, col) pair on an ElectrodeGrid. Anything else iterable – a list, an array, or the ElectrodeNames a stimulus reports – is a collection, taken in the order given. If None, every electrode in the array, in array order.

    A model passes stim.electrodes here: a stimulus need not name every electrode of the implant, and need not name them in array order, so the coordinates it wants are a reordered subset.

Returns:

coords – One [x, y, z] row per electrode – always two-dimensional, so a single-electrode selection comes back as (1, 3). (For one electrode’s position as a flat triple, see coordinates().) An ordinary NumPy array, never a Quantity: this is the boundary a numerical implementation should take the geometry across.

Return type:

(n_electrodes, 3) np.ndarray

Examples

>>> from pulse2percept.implants import ArgusII
>>> from pulse2percept.units import mm
>>> ArgusII().earray.coordinates(mm)[0]
array([-2.5875, -1.4375,  0.    ])
>>> ArgusII().earray.coordinates(electrodes=['F10', 'A1'])
array([[ 2587.5,  1437.5,     0. ],
       [-2587.5, -1437.5,     0. ]])
add_electrode(name, electrode)[source]

Add an electrode to the array

Parameters:
  • name (int|str|...) – Electrode name or index

  • electrode (implants.Electrode) – An Electrode object, such as a PointSource or a DiskElectrode.

remove_electrode(name)[source]

Remove an electrode from the array

Parameter

name: int|str|…

Electrode name or index

plot(annotate=False, autoscale=True, ax=None, color_stim=None, cmap='OrRd')[source]

Plot the electrode array

Parameters:
  • annotate (bool, optional) – Flag whether to label electrodes in the implant.

  • autoscale (bool, optional) – Whether to adjust the x,y limits of the plot to fit the implant

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

  • color_stim (pulse2percept.stimuli.Stimulus, or None) – If provided, colors the earray based on the stimulus amplitudes

  • cmap (str) – Matplotlib colormap to use for stimulus coloring.

Returns:

ax – Returns the axis object of the plot

Return type:

matplotlib.axes.Axes

property electrodes

Return all electrode names and objects in the electrode array

Internally, electrodes are stored in an ordered dictionary. You can iterate over different electrodes in the array as follows:

for name, electrode in earray.electrodes.items():
    print(name, electrode)

You can access an individual electrode by indexing directly into the electrode array object, e.g. earray['A1'] or earray[0].

property electrode_names

Return a list of all electrode names in the array

property electrode_objects

Return a list of all electrode objects in the array

class pulse2percept.implants.ElectrodeGrid(shape, spacing, x=0, y=0, z=0, rot=0, names=('A', '1'), type='rect', orientation='horizontal', etype=<class 'pulse2percept.implants.electrodes.PointSource'>, **kwargs)[source]

2D grid of electrodes

Parameters:
  • shape ((rows, cols)) – A tuple containing the number of rows x columns in the grid

  • spacing (double or (x_spacing, y_spacing)) – Electrode-to-electrode spacing in microns. Must be either a tuple specifying the spacing in x and y directions or a float (assuming the same spacing in x and y). If a tuple is specified for a horizontal hex grid, x_spacing will define the electrode-to-electrode distance, and y_spacing will define the vertical distance between adjacent hexagon centers. In a vertical hex grid, the order is reversed.

  • type ({'rect', 'hex'}, optional) – Grid type (‘rect’: rectangular, ‘hex’: hexagonal).

  • orientation ({'horizontal', 'vertical'}, optional) – In a hex grid, ‘horizontal’ orientation will shift every other row to the right, whereas ‘vertical’ will shift every other column up.

  • x/y/z (double) – 3D location (um) of the center of the grid. The coordinate system is centered over the fovea. Positive x values move the electrode into the nasal retina. Positive y values move the electrode into the superior retina. Positive z values move the electrode away from the retina into the vitreous humor (sometimes called electrode-retina distance).

  • rot (double, optional) – Rotation of the grid in degrees (positive angle: counter-clockwise rotation on the retinal surface). A plain angle, not a unitful one: dva means visual angle, which is a different thing.

  • names ((name_rows, name_cols), each of which either 'A' or '1') –

    Naming convention for rows and columns, respectively. If ‘A’, rows or columns will be labeled alphabetically: A-Z, AA-AZ, BA-BZ, CA-CZ, etc. ‘-A’ will reverse the order. If ‘1’, rows or columns will be labeled numerically. ‘-1’ will reverse. Letters will always precede numbers in electrode names. For example (‘1’, ‘A’) will number rows numerically and columns alphabetically; first row: ‘A1’, ‘B1’, ‘C1’, NOT ‘1A’, ‘1B’, ‘1C’.

    The default, ('A', '1'), is the same convention that ElectrodeNames uses to name the pixels of an ImageStimulus, and is generated by it. The other combinations exist to reproduce the naming of specific published implants and are not otherwise recommended.

    Alternatively, pass a list or NumPy array with one name per electrode to name them all explicitly. On a grid with exactly two electrodes the two readings collide, and only something that could be a scheme is read as one: names=('A', '1') gives ‘A1’, ‘A2’, whereas names=('C1', '4') names the two electrodes ‘C1’ and ‘4’. Pass a list (names=['A', '1']) to name two electrodes ‘A’ and ‘1’.

    Changed in version 0.10.0: On a grid with exactly two electrodes, ('A', '1') now yields ‘A1’, ‘A2’ (was: ‘A’, ‘1’), consistent with every other shape.

  • etype (Electrode, optional) – A valid Electrode class. By default, PointSource is used.

  • **kwargs – Any additional arguments that should be passed to the Electrode constructor, such as radius r for DiskElectrode. See examples below.

Notes

  • spacing, x, y, z and r may be given as plain numbers of microns or as unitful quantities, and may be mixed freely: spacing=(0.5 * mm, 600 * um) and z=[0 * um, 0.1 * mm, ...] both work. Any other electrode keyword is normalized by the electrode class it is passed to. See pulse2percept.units.

Examples

A hexagonal electrode grid with 3 rows and 4 columns, made of disk electrodes with 10um radius spaced 20um apart, centered at (10, 20)um, and located 500um away from the retinal surface, with names like this:

A1 A2 A3 A4 B1 B2 B3 B4 C1 C2 C3 C4
>>> from pulse2percept.implants import ElectrodeGrid, DiskElectrode
>>> ElectrodeGrid((3, 4), 20, x=10, y=20, z=500, names=('A', '1'), r=10,
...               type='hex', etype=DiskElectrode)
ElectrodeGrid(rot=0, shape=(3, 4), spacing=20, type='hex')

A rectangular electrode grid with 2 rows and 4 columns, made of disk electrodes with 10um radius spaced 20um apart, centered at (10, 20)um, and located 500um away from the retinal surface, with names like this:

A1 A2 A3 A4 B1 B2 B3 B4
>>> from pulse2percept.implants import ElectrodeGrid, DiskElectrode
>>> ElectrodeGrid((2, 4), 20, x=10, y=20, z=500, names=('A', '1'), r=10,
...               type='rect', etype=DiskElectrode)
ElectrodeGrid(rot=0, shape=(2, 4), spacing=20, type='rect')

There are three ways to access (e.g.) the last electrode in the grid, either by name (grid['C3']), by row/column index (grid[2, 2]), or by index into the flattened array (grid[8]):

>>> from pulse2percept.implants import ElectrodeGrid
>>> grid = ElectrodeGrid((3, 3), 20, names=('A', '1'))
>>> grid['C3']
PointSource(activated=True, name='C3', x=20..., y=20...,
            z=0...)
>>> grid['C3'] == grid[8] == grid[2, 2]
True

You can also access multiple electrodes at the same time by passing a list of indices/names (it’s ok to mix-and-match):

>>> from pulse2percept.implants import ElectrodeGrid, DiskElectrode
>>> grid = ElectrodeGrid((3, 3), 20, etype=DiskElectrode, r=10)
>>> grid[['A1', 1, (0, 2)]]
[DiskElectrode(activated=True, name='A1', r=10..., x=-20.0,
               y=-20.0, z=0...),
 DiskElectrode(activated=True, name='A2', r=10..., x=0.0,
               y=-20.0, z=0...),
 DiskElectrode(activated=True, name='A3', r=10..., x=20.0,
               y=-20.0, z=0...)]
add_electrode(name, electrode)[source]

Add an electrode to the array

Parameters:
  • name (int|str|...) – Electrode name or index

  • electrode (implants.Electrode) – An Electrode object, such as a PointSource or a DiskElectrode.

coordinate_unit = um[source]

The unit electrode coordinates are stored in, i.e. what the plain numbers returned by coordinates() mean by default.

coordinates(unit=None, electrodes=None)[source]

Positions of the electrodes in the array

The one place to ask an implant where its electrodes are. Code that needs the coordinates in a particular unit says so here, instead of reading electrode.x and knowing that electrodes happen to store microns.

Added in version 0.10.0.

Parameters:
  • unit (Unit, optional) – Length unit to express the coordinates in. If None, they are returned as they are stored (microns).

  • electrodes (optional) –

    Which electrodes to return. Three things name a single electrode, looked up as earray[...] looks one up: a name, an index into the flattened array, and a (row, col) pair on an ElectrodeGrid. Anything else iterable – a list, an array, or the ElectrodeNames a stimulus reports – is a collection, taken in the order given. If None, every electrode in the array, in array order.

    A model passes stim.electrodes here: a stimulus need not name every electrode of the implant, and need not name them in array order, so the coordinates it wants are a reordered subset.

Returns:

coords – One [x, y, z] row per electrode – always two-dimensional, so a single-electrode selection comes back as (1, 3). (For one electrode’s position as a flat triple, see coordinates().) An ordinary NumPy array, never a Quantity: this is the boundary a numerical implementation should take the geometry across.

Return type:

(n_electrodes, 3) np.ndarray

Examples

>>> from pulse2percept.implants import ArgusII
>>> from pulse2percept.units import mm
>>> ArgusII().earray.coordinates(mm)[0]
array([-2.5875, -1.4375,  0.    ])
>>> ArgusII().earray.coordinates(electrodes=['F10', 'A1'])
array([[ 2587.5,  1437.5,     0. ],
       [-2587.5, -1437.5,     0. ]])
property electrode_names

Return a list of all electrode names in the array

property electrode_objects

Return a list of all electrode objects in the array

property electrodes

Return all electrode names and objects in the electrode array

Internally, electrodes are stored in an ordered dictionary. You can iterate over different electrodes in the array as follows:

for name, electrode in earray.electrodes.items():
    print(name, electrode)

You can access an individual electrode by indexing directly into the electrode array object, e.g. earray['A1'] or earray[0].

plot(annotate=False, autoscale=True, ax=None, color_stim=None, cmap='OrRd')[source]

Plot the electrode array

Parameters:
  • annotate (bool, optional) – Flag whether to label electrodes in the implant.

  • autoscale (bool, optional) – Whether to adjust the x,y limits of the plot to fit the implant

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

  • color_stim (pulse2percept.stimuli.Stimulus, or None) – If provided, colors the earray based on the stimulus amplitudes

  • cmap (str) – Matplotlib colormap to use for stimulus coloring.

Returns:

ax – Returns the axis object of the plot

Return type:

matplotlib.axes.Axes

remove_electrode(name)[source]

Remove an electrode from the array

Parameter

name: int|str|…

Electrode name or index

class pulse2percept.implants.EnsembleImplant(implants, stim=None, preprocess=False, safe_mode=False)[source]
classmethod from_cortical_map(implant_type, vfmap, locs=None, xrange=None, yrange=None, xystep=None, region='v1')[source]

Create an ensemble implant from a cortical visual field map.

The implant will be created by creating an implant of type implant_type for each visual field location specified either by locs or by xrange, yrange, and xystep. Each implant will be centered at the given location.

Parameters:
  • vfmap (p2p.topography.CorticalMap) – Visual field map to create implant from.

  • implant_type (type) – Type of implant to create for the ensemble. Must subclass p2p.implants.ProsthesisSystem

  • locs (np.ndarray with shape (n, 2), optional) – Array of visual field locations to create implants at (dva). Not needed if using xrange, yrange, and xystep.

  • xrange (tuple of floats, optional) – Range of x and y coordinates (dva) to create implants at.

  • yrange (tuple of floats, optional) – Range of x and y coordinates (dva) to create implants at.

  • xystep (float, optional) – Spacing (dva) between implant centers.

  • region (str, optional) – Region of cortex to create implant in.

Returns:

ensemble – Ensemble implant created from the cortical visual field map.

Return type:

p2p.implants.EnsembleImplant

Notes

  • These are visual field coordinates, so they may be given as plain numbers of degrees or as unitful quantities (e.g. xrange=(-3 * dva, 3 * dva)). Contrast from_coords(), which places implants by their physical position in microns. See pulse2percept.units.

classmethod from_coords(implant_type, locs=None, xrange=None, yrange=None, xystep=None)[source]

Create an ensemble implant using physical (cortical or retinal) coordinates.

Parameters:
  • implant_type (type) – The type of implant to create for the ensemble.

  • locs (np.ndarray with shape (n, 2), optional) – Array of physical locations (um) to create implants at. Not needed if using xrange, yrange, and xystep.

  • xrange (tuple of floats, optional) – Range of x and y coordinates (um) to create implants at. Required (together with xystep) if locs is not given.

  • yrange (tuple of floats, optional) – Range of x and y coordinates (um) to create implants at. Required (together with xystep) if locs is not given.

  • xystep (float, optional) – Spacing (um) between implant centers.

Raises:

ValueError – If neither locs nor all three of xrange, yrange and xystep are given.

Notes

  • Lengths may be given as plain numbers of microns or as unitful quantities (e.g. xrange=(-1 * mm, 1 * mm)). See pulse2percept.units.

Changed in version 0.10.0: The grid arguments no longer have defaults. They used to fall back on (-3, 3) and 1, which are the degrees of visual angle from_cortical_map() works in; here they are microns, so the default laid every implant out inside a 6 um square.

property stim

Stimulus

A stimulus can be created from many source types, such as scalars, NumPy arrays, and dictionaries (see Stimulus for a complete list).

A stimulus can be assigned either in the ProsthesisSystem constructor or later by assigning a value to stim.

Note

Unless when using dictionary notation, the number of stimuli must equal the number of electrodes in earray.

Examples

Send a biphasic pulse (30uA, 0.45ms phase duration) to an implant made from a single DiskElectrode:

>>> from pulse2percept.implants import DiskElectrode, ProsthesisSystem
>>> from pulse2percept.stimuli import BiphasicPulse
>>> implant = ProsthesisSystem(DiskElectrode(0, 0, 0, 100))
>>> implant.stim = BiphasicPulse(30, 0.45)

Stimulate Electrode B7 in Argus II with 13 uA:

>>> from pulse2percept.implants import ArgusII
>>> implant = ArgusII(stim={'B7': 13})
check_stim(stim)[source]

Quality-check the stimulus

This method is executed every time a new value is assigned to stim.

If safe_mode is set to True, this function will only allow stimuli that are charge-balanced. If max_current is set, it will only allow stimuli whose total instantaneous current stays within it.

Both are questions about electricity, and neither can be answered about a stimulus that is not a current, so each raises a DimensionMismatchError on one. An implant that asks for neither does not run either check, which is why a dimensionless stimulus may still be assigned to one – preprocess has already had its chance to turn it into current, and if it did not, no safety claim is being made about it either.

The user can define their own checks in implants that inherit from ProsthesisSystem.

Parameters:

stim (Stimulus source type) – A valid source type for the Stimulus object (e.g., scalar, NumPy array, pulse train).

Raises:
  • DimensionMismatchError – If an electrical check was requested and stim is not measured in units of current.

  • .. versionchanged: – 0.10.0: The electrical checks verify that the stimulus really is electrical, instead of reading whatever numbers it holds as microamps.

property earray

Electrode array

property electrode_names

Return a list of all electrode names in the electrode array

property electrode_objects

Return a list of all electrode objects in the array

property electrodes

Return all electrode names and objects in the electrode array

Internally, electrodes are stored in an ordered dictionary. You can iterate over different electrodes in the array as follows:

for name, electrode in implant.electrodes.items():
    print(name, electrode)

You can access an individual electrode by indexing directly into the prosthesis system object, e.g. implant['A1'] or implant[0].

property eye

Implanted eye

A ProsthesisSystem can be implanted either in a left eye (‘LE’) or right eye (‘RE’). Models such as AxonMapModel will treat left and right eyes differently (for example, adjusting the location of the optic disc).

Examples

Implant Argus II in a left eye:

>>> from pulse2percept.implants import ArgusII
>>> implant = ArgusII(eye='LE')
property implants

Dict of implants

property max_current

Total instantaneous current (uA) the stimulator can source

property n_electrodes

Number of electrodes in the array

This is equivalent to calling earray.n_electrodes.

plot(annotate=False, autoscale=True, ax=None, stim_cmap=False)[source]

Plot

Parameters:
  • annotate (bool, optional) – Whether to scale the axes view to the data

  • autoscale (bool, optional) – Whether to adjust the x,y limits of the plot to fit the implant

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

  • stim_cmap (bool, str, or matplotlib colormap, optional) – If not false, the fill color of the plotted electrodes will vary based on maximum stimulus amplitude on each electrode. The chosen colormap will be used if provided

Returns:

ax – Returns the axis object of the plot

Return type:

matplotlib.axes.Axes

preprocess_stim(stim)[source]

Preprocess the stimulus

This methods is executed every time a new value is assigned to stim.

No preprocessing is performed by default, but the user can define their own method in implants that inherit from return stim ProsthesisSystem.

A custom method must return a Stimulus object with the correct number of electrodes for the implant.

Parameters:

stim (Stimulus source type) – A valid source type for the Stimulus object (e.g., scalar, NumPy array, pulse train).

Returns:

stim_out

Return type:

Stimulus object

property raster

Raster pattern

Most implants do not set this in their constructor, so the slot backing it may never have been written to; an unset raster means all electrodes may fire at once.

merge_stimuli()[source]

Constructs the combined stimulus for all implants in self._implants

class pulse2percept.implants.HexElectrode(x, y, z, a, name=None, activated=True)[source]

Hexagonal electrode

Added in version 0.7.

Parameters:
  • x/y/z (double) – 3D location of the electrode. The coordinate system is centered over the fovea. Positive x values move the electrode into the nasal retina. Positive y values move the electrode into the superior retina. Positive z values move the electrode away from the retina into the vitreous humor (sometimes called electrode-retina distance).

  • a (double) – Length (um) of line drawn from the center of the hexagon to the midpoint of one of its sides.

  • name (str, optional) – Electrode name

  • activated (bool) – To deactivate, set to False. Deactivated electrodes cannot receive stimuli.

Notes

  • Lengths may be given as plain numbers of microns or as unitful quantities (e.g. 50 * um). See pulse2percept.units.

coordinate_unit = um[source]

The unit electrode coordinates are stored in. Electrodes hold plain numbers, which is what every kernel downstream of them expects; this says what those numbers mean.

coordinates(unit=None)[source]

3D position of the electrode

Added in version 0.10.0.

Parameters:

unit (Unit, optional) – Length unit to express the position in. If None, the position is returned as it is stored (microns).

Returns:

coords – An ordinary NumPy array [x, y, z], never a Quantity.

Return type:

(3,) np.ndarray

Examples

>>> from pulse2percept.implants import DiskElectrode
>>> from pulse2percept.units import mm
>>> DiskElectrode(1000, 0, 100, 200).coordinates(mm)
array([1. , 0. , 0.1])
plot(autoscale=False, ax=None)[source]

Plot

Parameters:
  • 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 given, a new one will be created.

Returns:

ax – Returns the axis object of the plot

Return type:

matplotlib.axes.Axes

class pulse2percept.implants.PhotovoltaicPixel(x, y, z, r, a, name=None, activated=True)[source]

Photovoltaic pixel

Added in version 0.7.

Parameters:
  • x/y/z (double) – 3D location of the electrode. The coordinate system is centered over the fovea. Positive x values move the electrode into the nasal retina. Positive y values move the electrode into the superior retina. Positive z values move the electrode away from the retina into the vitreous humor (sometimes called electrode-retina distance).

  • r (double) – Disk radius (um) in the x,y plane

  • a (double) – Length (um) of line drawn from the center of the hexagon to the midpoint of one of its sides.

  • activated (bool) – To deactivate, set to False. Deactivated electrodes cannot receive stimuli.

Notes

  • Lengths may be given as plain numbers of microns or as unitful quantities (e.g. 14 * um). See pulse2percept.units.

coordinate_unit = um[source]

The unit electrode coordinates are stored in. Electrodes hold plain numbers, which is what every kernel downstream of them expects; this says what those numbers mean.

coordinates(unit=None)[source]

3D position of the electrode

Added in version 0.10.0.

Parameters:

unit (Unit, optional) – Length unit to express the position in. If None, the position is returned as it is stored (microns).

Returns:

coords – An ordinary NumPy array [x, y, z], never a Quantity.

Return type:

(3,) np.ndarray

Examples

>>> from pulse2percept.implants import DiskElectrode
>>> from pulse2percept.units import mm
>>> DiskElectrode(1000, 0, 100, 200).coordinates(mm)
array([1. , 0. , 0.1])
plot(autoscale=False, ax=None)[source]

Plot

Parameters:
  • 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 given, a new one will be created.

Returns:

ax – Returns the axis object of the plot

Return type:

matplotlib.axes.Axes

class pulse2percept.implants.PointSource(x, y, z, name=None, activated=True)[source]

Idealized current point source

Parameters:
  • x/y/z (double) – 3D location of the electrode. The coordinate system is centered over the fovea. Positive x values move the electrode into the nasal retina. Positive y values move the electrode into the superior retina. Positive z values move the electrode away from the retina into the vitreous humor (sometimes called electrode-retina distance).

  • name (str, optional) – Electrode name

  • activated (bool) – To deactivate, set to False. Deactivated electrodes cannot receive stimuli.

electric_potential(x, y, z, amp, sigma)[source]

Calculate electric potential at (x, y, z)

Parameters:
  • x/y/z (double) – 3D location (um) at which to evaluate the electric potential. May be given as a unitful quantity, e.g. 0.2 * mm.

  • amp (double) – amplitude of the constant current pulse

  • sigma (double) – resistivity of the extracellular solution

Returns:

  • pot (double) – The electric potential at (x, y, z)

  • The electric potential \(V(r)\) of a point source is given by

  • .. math:: – V(r) = frac{sigma I}{4 pi r},

  • where \(\sigma\) is the resistivity of the extracellular solution

  • (typically Ames medium, \(\sigma = 110 \Ohm cm\)),

  • \(I\) is the amplitude of the constant current pulse,

  • and \(r\) is the distance from the stimulating electrode to the

  • point at which the voltage is being computed.

coordinate_unit = um[source]

The unit electrode coordinates are stored in. Electrodes hold plain numbers, which is what every kernel downstream of them expects; this says what those numbers mean.

coordinates(unit=None)[source]

3D position of the electrode

Added in version 0.10.0.

Parameters:

unit (Unit, optional) – Length unit to express the position in. If None, the position is returned as it is stored (microns).

Returns:

coords – An ordinary NumPy array [x, y, z], never a Quantity.

Return type:

(3,) np.ndarray

Examples

>>> from pulse2percept.implants import DiskElectrode
>>> from pulse2percept.units import mm
>>> DiskElectrode(1000, 0, 100, 200).coordinates(mm)
array([1. , 0. , 0.1])
plot(autoscale=False, ax=None)[source]

Plot

Parameters:
  • 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 given, a new one will be created.

Returns:

ax – Returns the axis object of the plot

Return type:

matplotlib.axes.Axes

class pulse2percept.implants.PRIMA(x=0, y=0, z=-100, rot=0, eye='RE', stim=None, preprocess=False, safe_mode=False)[source]

Create a PRIMA-100 array on the retina

This class creates a PRIMA array with 378 photovoltaic pixels (each 100um in diameter) as used in the clinical trial [Palanker2020], and places it in the subretinal space such that the center of the array is located at 3D location (x,y,z), given in microns, and the array is rotated by rotation angle rot, given in degrees.

The device consists of 378 85um-wide pixels separated by 15um trenches, arranged in a 2-mm wide hexagonal pattern.

This corresponds to a 100um pitch, with adjacent rows separated by 87um. The active electrode is a disk with 28um diameter.

Added in version 0.7.

Parameters:
  • x/y/z (double) – 3D location (um) of the center of the electrode array. The coordinate system is centered over the fovea. Positive x values move the electrode into the nasal retina. Positive y values move the electrode into the superior retina. Positive z values move the electrode away from the retina into the vitreous humor (sometimes called electrode-retina distance). z can either be a list with 378 entries or a scalar that is applied to all electrodes. May be given as unitful quantities (e.g. z=100 * um); see pulse2percept.units.

  • rot (float, optional) – Rotation angle of the array (deg). Positive values denote counter-clock-wise (CCW) rotations in the retinal coordinate system.

  • eye ({'RE', 'LE'}, optional) – Eye in which array is implanted.

  • preprocess (bool or callable, optional) – Either True/False to indicate whether to execute the implant’s default preprocessing method whenever a new stimulus is assigned, or a custom function (callable).

  • safe_mode (bool, optional) – If safe mode is enabled, only charge-balanced stimuli are allowed.

Notes

  • The diameter of the active electrode and the trench width were estimated from Fig.1 in [Palanker2020].

property eye

Implanted eye

A ProsthesisSystem can be implanted either in a left eye (‘LE’) or right eye (‘RE’). Models such as AxonMapModel will treat left and right eyes differently (for example, adjusting the location of the optic disc).

Examples

Implant Argus II in a left eye:

>>> from pulse2percept.implants import ArgusII
>>> implant = ArgusII(eye='LE')
property earray

Electrode array

property stim

Stimulus

A stimulus can be created from many source types, such as scalars, NumPy arrays, and dictionaries (see Stimulus for a complete list).

A stimulus can be assigned either in the ProsthesisSystem constructor or later by assigning a value to stim.

Note

Unless when using dictionary notation, the number of stimuli must equal the number of electrodes in earray.

Examples

Send a biphasic pulse (30uA, 0.45ms phase duration) to an implant made from a single DiskElectrode:

>>> from pulse2percept.implants import DiskElectrode, ProsthesisSystem
>>> from pulse2percept.stimuli import BiphasicPulse
>>> implant = ProsthesisSystem(DiskElectrode(0, 0, 0, 100))
>>> implant.stim = BiphasicPulse(30, 0.45)

Stimulate Electrode B7 in Argus II with 13 uA:

>>> from pulse2percept.implants import ArgusII
>>> implant = ArgusII(stim={'B7': 13})
check_stim(stim)[source]

Quality-check the stimulus

This method is executed every time a new value is assigned to stim.

If safe_mode is set to True, this function will only allow stimuli that are charge-balanced. If max_current is set, it will only allow stimuli whose total instantaneous current stays within it.

Both are questions about electricity, and neither can be answered about a stimulus that is not a current, so each raises a DimensionMismatchError on one. An implant that asks for neither does not run either check, which is why a dimensionless stimulus may still be assigned to one – preprocess has already had its chance to turn it into current, and if it did not, no safety claim is being made about it either.

The user can define their own checks in implants that inherit from ProsthesisSystem.

Parameters:

stim (Stimulus source type) – A valid source type for the Stimulus object (e.g., scalar, NumPy array, pulse train).

Raises:
  • DimensionMismatchError – If an electrical check was requested and stim is not measured in units of current.

  • .. versionchanged: – 0.10.0: The electrical checks verify that the stimulus really is electrical, instead of reading whatever numbers it holds as microamps.

property electrode_names

Return a list of all electrode names in the electrode array

property electrode_objects

Return a list of all electrode objects in the array

property electrodes

Return all electrode names and objects in the electrode array

Internally, electrodes are stored in an ordered dictionary. You can iterate over different electrodes in the array as follows:

for name, electrode in implant.electrodes.items():
    print(name, electrode)

You can access an individual electrode by indexing directly into the prosthesis system object, e.g. implant['A1'] or implant[0].

property max_current

Total instantaneous current (uA) the stimulator can source

property n_electrodes

Number of electrodes in the array

This is equivalent to calling earray.n_electrodes.

plot(annotate=False, autoscale=True, ax=None, stim_cmap=False)[source]

Plot

Parameters:
  • annotate (bool, optional) – Whether to scale the axes view to the data

  • autoscale (bool, optional) – Whether to adjust the x,y limits of the plot to fit the implant

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

  • stim_cmap (bool, str, or matplotlib colormap, optional) – If not false, the fill color of the plotted electrodes will vary based on maximum stimulus amplitude on each electrode. The chosen colormap will be used if provided

Returns:

ax – Returns the axis object of the plot

Return type:

matplotlib.axes.Axes

preprocess_stim(stim)[source]

Preprocess the stimulus

This methods is executed every time a new value is assigned to stim.

No preprocessing is performed by default, but the user can define their own method in implants that inherit from return stim ProsthesisSystem.

A custom method must return a Stimulus object with the correct number of electrodes for the implant.

Parameters:

stim (Stimulus source type) – A valid source type for the Stimulus object (e.g., scalar, NumPy array, pulse train).

Returns:

stim_out

Return type:

Stimulus object

property raster

Raster pattern

Most implants do not set this in their constructor, so the slot backing it may never have been written to; an unset raster means all electrodes may fire at once.

class pulse2percept.implants.PRIMA75(x=0, y=0, z=-100, rot=0, eye='RE', stim=None, preprocess=False, safe_mode=False)[source]

Create a PRIMA-75 array on the retina

This class creates a PRIMA array with 142 photovoltaic pixels (each 75um in diameter) as described in [Lorach2015], and places it in the subretinal space, such that that the center of the array is located at 3D location (x,y,z), given in microns, and the array is rotated by rotation angle rot, given in degrees.

The device consists of 142 70um-wide pixels separated by 5um trenches, arranged in a 1-mm wide hexagonal pattern.

This corresponds to a 75um pitch, with adjacent rows separated by 65um. The active electrode is a disk with 20um diameter.

Added in version 0.7.

Parameters:
  • x/y/z (double) – 3D location (um) of the center of the electrode array. The coordinate system is centered over the fovea. Positive x values move the electrode into the nasal retina. Positive y values move the electrode into the superior retina. Positive z values move the electrode away from the retina into the vitreous humor (sometimes called electrode-retina distance). z can either be a list with 142 entries or a scalar that is applied to all electrodes. May be given as unitful quantities (e.g. z=100 * um); see pulse2percept.units.

  • rot (float, optional) – Rotation angle of the array (deg). Positive values denote counter-clock-wise (CCW) rotations in the retinal coordinate system.

  • eye ({'RE', 'LE'}, optional) – Eye in which array is implanted.

  • preprocess (bool or callable, optional) – Either True/False to indicate whether to execute the implant’s default preprocessing method whenever a new stimulus is assigned, or a custom function (callable).

  • safe_mode (bool, optional) – If safe mode is enabled, only charge-balanced stimuli are allowed.

property eye

Implanted eye

A ProsthesisSystem can be implanted either in a left eye (‘LE’) or right eye (‘RE’). Models such as AxonMapModel will treat left and right eyes differently (for example, adjusting the location of the optic disc).

Examples

Implant Argus II in a left eye:

>>> from pulse2percept.implants import ArgusII
>>> implant = ArgusII(eye='LE')
property earray

Electrode array

property stim

Stimulus

A stimulus can be created from many source types, such as scalars, NumPy arrays, and dictionaries (see Stimulus for a complete list).

A stimulus can be assigned either in the ProsthesisSystem constructor or later by assigning a value to stim.

Note

Unless when using dictionary notation, the number of stimuli must equal the number of electrodes in earray.

Examples

Send a biphasic pulse (30uA, 0.45ms phase duration) to an implant made from a single DiskElectrode:

>>> from pulse2percept.implants import DiskElectrode, ProsthesisSystem
>>> from pulse2percept.stimuli import BiphasicPulse
>>> implant = ProsthesisSystem(DiskElectrode(0, 0, 0, 100))
>>> implant.stim = BiphasicPulse(30, 0.45)

Stimulate Electrode B7 in Argus II with 13 uA:

>>> from pulse2percept.implants import ArgusII
>>> implant = ArgusII(stim={'B7': 13})
check_stim(stim)[source]

Quality-check the stimulus

This method is executed every time a new value is assigned to stim.

If safe_mode is set to True, this function will only allow stimuli that are charge-balanced. If max_current is set, it will only allow stimuli whose total instantaneous current stays within it.

Both are questions about electricity, and neither can be answered about a stimulus that is not a current, so each raises a DimensionMismatchError on one. An implant that asks for neither does not run either check, which is why a dimensionless stimulus may still be assigned to one – preprocess has already had its chance to turn it into current, and if it did not, no safety claim is being made about it either.

The user can define their own checks in implants that inherit from ProsthesisSystem.

Parameters:

stim (Stimulus source type) – A valid source type for the Stimulus object (e.g., scalar, NumPy array, pulse train).

Raises:
  • DimensionMismatchError – If an electrical check was requested and stim is not measured in units of current.

  • .. versionchanged: – 0.10.0: The electrical checks verify that the stimulus really is electrical, instead of reading whatever numbers it holds as microamps.

property electrode_names

Return a list of all electrode names in the electrode array

property electrode_objects

Return a list of all electrode objects in the array

property electrodes

Return all electrode names and objects in the electrode array

Internally, electrodes are stored in an ordered dictionary. You can iterate over different electrodes in the array as follows:

for name, electrode in implant.electrodes.items():
    print(name, electrode)

You can access an individual electrode by indexing directly into the prosthesis system object, e.g. implant['A1'] or implant[0].

property max_current

Total instantaneous current (uA) the stimulator can source

property n_electrodes

Number of electrodes in the array

This is equivalent to calling earray.n_electrodes.

plot(annotate=False, autoscale=True, ax=None, stim_cmap=False)[source]

Plot

Parameters:
  • annotate (bool, optional) – Whether to scale the axes view to the data

  • autoscale (bool, optional) – Whether to adjust the x,y limits of the plot to fit the implant

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

  • stim_cmap (bool, str, or matplotlib colormap, optional) – If not false, the fill color of the plotted electrodes will vary based on maximum stimulus amplitude on each electrode. The chosen colormap will be used if provided

Returns:

ax – Returns the axis object of the plot

Return type:

matplotlib.axes.Axes

preprocess_stim(stim)[source]

Preprocess the stimulus

This methods is executed every time a new value is assigned to stim.

No preprocessing is performed by default, but the user can define their own method in implants that inherit from return stim ProsthesisSystem.

A custom method must return a Stimulus object with the correct number of electrodes for the implant.

Parameters:

stim (Stimulus source type) – A valid source type for the Stimulus object (e.g., scalar, NumPy array, pulse train).

Returns:

stim_out

Return type:

Stimulus object

property raster

Raster pattern

Most implants do not set this in their constructor, so the slot backing it may never have been written to; an unset raster means all electrodes may fire at once.

class pulse2percept.implants.PRIMA55(x=0, y=0, z=-100, rot=0, eye='RE', stim=None, preprocess=False, safe_mode=False)[source]

Create a PRIMA-55 array on the retina

This class creates a PRIMA array with 273 photovoltaic pixels (each 55um in diameter), and places it in the subretinal space, such that that the center of the array is located at 3D location (x,y,z), given in microns, and the array is rotated by rotation angle rot, given in degrees.

The device consists of 273 50um-wide pixels separated by 5um trenches, arranged in a 1-mm wide hexagonal pattern.

This corresponds to a 55um pitch, with adjacent rows separated by 48um. The active electrode is a disk with 16um diameter.

Warning

The exact shape of the device has not been published yet. We assume the array fits on a circular 1mm-diameter substrate, which leaves us with 273 electrodes.

Added in version 0.7.

Parameters:
  • x/y/z (double) – 3D location (um) of the center of the electrode array. The coordinate system is centered over the fovea. Positive x values move the electrode into the nasal retina. Positive y values move the electrode into the superior retina. Positive z values move the electrode away from the retina into the vitreous humor (sometimes called electrode-retina distance). z can either be a list with 378 entries or a scalar that is applied to all electrodes. May be given as unitful quantities (e.g. z=100 * um); see pulse2percept.units.

  • rot (float, optional) – Rotation angle of the array (deg). Positive values denote counter-clock-wise (CCW) rotations in the retinal coordinate system.

  • eye ({'RE', 'LE'}, optional) – Eye in which array is implanted.

  • preprocess (bool or callable, optional) – Either True/False to indicate whether to execute the implant’s default preprocessing method whenever a new stimulus is assigned, or a custom function (callable).

  • safe_mode (bool, optional) – If safe mode is enabled, only charge-balanced stimuli are allowed.

property eye

Implanted eye

A ProsthesisSystem can be implanted either in a left eye (‘LE’) or right eye (‘RE’). Models such as AxonMapModel will treat left and right eyes differently (for example, adjusting the location of the optic disc).

Examples

Implant Argus II in a left eye:

>>> from pulse2percept.implants import ArgusII
>>> implant = ArgusII(eye='LE')
property earray

Electrode array

property stim

Stimulus

A stimulus can be created from many source types, such as scalars, NumPy arrays, and dictionaries (see Stimulus for a complete list).

A stimulus can be assigned either in the ProsthesisSystem constructor or later by assigning a value to stim.

Note

Unless when using dictionary notation, the number of stimuli must equal the number of electrodes in earray.

Examples

Send a biphasic pulse (30uA, 0.45ms phase duration) to an implant made from a single DiskElectrode:

>>> from pulse2percept.implants import DiskElectrode, ProsthesisSystem
>>> from pulse2percept.stimuli import BiphasicPulse
>>> implant = ProsthesisSystem(DiskElectrode(0, 0, 0, 100))
>>> implant.stim = BiphasicPulse(30, 0.45)

Stimulate Electrode B7 in Argus II with 13 uA:

>>> from pulse2percept.implants import ArgusII
>>> implant = ArgusII(stim={'B7': 13})
check_stim(stim)[source]

Quality-check the stimulus

This method is executed every time a new value is assigned to stim.

If safe_mode is set to True, this function will only allow stimuli that are charge-balanced. If max_current is set, it will only allow stimuli whose total instantaneous current stays within it.

Both are questions about electricity, and neither can be answered about a stimulus that is not a current, so each raises a DimensionMismatchError on one. An implant that asks for neither does not run either check, which is why a dimensionless stimulus may still be assigned to one – preprocess has already had its chance to turn it into current, and if it did not, no safety claim is being made about it either.

The user can define their own checks in implants that inherit from ProsthesisSystem.

Parameters:

stim (Stimulus source type) – A valid source type for the Stimulus object (e.g., scalar, NumPy array, pulse train).

Raises:
  • DimensionMismatchError – If an electrical check was requested and stim is not measured in units of current.

  • .. versionchanged: – 0.10.0: The electrical checks verify that the stimulus really is electrical, instead of reading whatever numbers it holds as microamps.

property electrode_names

Return a list of all electrode names in the electrode array

property electrode_objects

Return a list of all electrode objects in the array

property electrodes

Return all electrode names and objects in the electrode array

Internally, electrodes are stored in an ordered dictionary. You can iterate over different electrodes in the array as follows:

for name, electrode in implant.electrodes.items():
    print(name, electrode)

You can access an individual electrode by indexing directly into the prosthesis system object, e.g. implant['A1'] or implant[0].

property max_current

Total instantaneous current (uA) the stimulator can source

property n_electrodes

Number of electrodes in the array

This is equivalent to calling earray.n_electrodes.

plot(annotate=False, autoscale=True, ax=None, stim_cmap=False)[source]

Plot

Parameters:
  • annotate (bool, optional) – Whether to scale the axes view to the data

  • autoscale (bool, optional) – Whether to adjust the x,y limits of the plot to fit the implant

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

  • stim_cmap (bool, str, or matplotlib colormap, optional) – If not false, the fill color of the plotted electrodes will vary based on maximum stimulus amplitude on each electrode. The chosen colormap will be used if provided

Returns:

ax – Returns the axis object of the plot

Return type:

matplotlib.axes.Axes

preprocess_stim(stim)[source]

Preprocess the stimulus

This methods is executed every time a new value is assigned to stim.

No preprocessing is performed by default, but the user can define their own method in implants that inherit from return stim ProsthesisSystem.

A custom method must return a Stimulus object with the correct number of electrodes for the implant.

Parameters:

stim (Stimulus source type) – A valid source type for the Stimulus object (e.g., scalar, NumPy array, pulse train).

Returns:

stim_out

Return type:

Stimulus object

property raster

Raster pattern

Most implants do not set this in their constructor, so the slot backing it may never have been written to; an unset raster means all electrodes may fire at once.

class pulse2percept.implants.PRIMA40(x=0, y=0, z=-100, rot=0, eye='RE', stim=None, preprocess=False, safe_mode=False)[source]

Create a PRIMA-40 array on the retina

This class creates a PRIMA array with 532 photovoltaic pixels (each 40um in diameter), and places it in the subretinal space, such that that the center of the array is located at 3D location (x,y,z), given in microns, and the array is rotated by rotation angle rot, given in degrees.

The device consists of 532 35um-wide pixels separated by 5um trenches, arranged in a 1-mm wide hexagonal pattern.

This corresponds to a 40um pitch, with adjacent rows separated by 48um. The active electrode is a disk with 16um diameter.

Important

The exact shape of the device has not been published yet. We assume the array fits on a circular 1mm-diameter substrate, which leaves us with 532 electrodes.

Added in version 0.7.

Parameters:
  • x/y/z (double) – 3D location (um) of the center of the electrode array. The coordinate system is centered over the fovea. Positive x values move the electrode into the nasal retina. Positive y values move the electrode into the superior retina. Positive z values move the electrode away from the retina into the vitreous humor (sometimes called electrode-retina distance). z can either be a list with 532 entries or a scalar that is applied to all electrodes. May be given as unitful quantities (e.g. z=100 * um); see pulse2percept.units.

  • rot (float, optional) – Rotation angle of the array (deg). Positive values denote counter-clock-wise (CCW) rotations in the retinal coordinate system.

  • eye ({'LE', 'RE'}, optional) – Eye in which array is implanted.

  • preprocess (bool or callable, optional) – Either True/False to indicate whether to execute the implant’s default preprocessing method whenever a new stimulus is assigned, or a custom function (callable).

  • safe_mode (bool, optional) – If safe mode is enabled, only charge-balanced stimuli are allowed.

property eye

Implanted eye

A ProsthesisSystem can be implanted either in a left eye (‘LE’) or right eye (‘RE’). Models such as AxonMapModel will treat left and right eyes differently (for example, adjusting the location of the optic disc).

Examples

Implant Argus II in a left eye:

>>> from pulse2percept.implants import ArgusII
>>> implant = ArgusII(eye='LE')
property earray

Electrode array

property stim

Stimulus

A stimulus can be created from many source types, such as scalars, NumPy arrays, and dictionaries (see Stimulus for a complete list).

A stimulus can be assigned either in the ProsthesisSystem constructor or later by assigning a value to stim.

Note

Unless when using dictionary notation, the number of stimuli must equal the number of electrodes in earray.

Examples

Send a biphasic pulse (30uA, 0.45ms phase duration) to an implant made from a single DiskElectrode:

>>> from pulse2percept.implants import DiskElectrode, ProsthesisSystem
>>> from pulse2percept.stimuli import BiphasicPulse
>>> implant = ProsthesisSystem(DiskElectrode(0, 0, 0, 100))
>>> implant.stim = BiphasicPulse(30, 0.45)

Stimulate Electrode B7 in Argus II with 13 uA:

>>> from pulse2percept.implants import ArgusII
>>> implant = ArgusII(stim={'B7': 13})
check_stim(stim)[source]

Quality-check the stimulus

This method is executed every time a new value is assigned to stim.

If safe_mode is set to True, this function will only allow stimuli that are charge-balanced. If max_current is set, it will only allow stimuli whose total instantaneous current stays within it.

Both are questions about electricity, and neither can be answered about a stimulus that is not a current, so each raises a DimensionMismatchError on one. An implant that asks for neither does not run either check, which is why a dimensionless stimulus may still be assigned to one – preprocess has already had its chance to turn it into current, and if it did not, no safety claim is being made about it either.

The user can define their own checks in implants that inherit from ProsthesisSystem.

Parameters:

stim (Stimulus source type) – A valid source type for the Stimulus object (e.g., scalar, NumPy array, pulse train).

Raises:
  • DimensionMismatchError – If an electrical check was requested and stim is not measured in units of current.

  • .. versionchanged: – 0.10.0: The electrical checks verify that the stimulus really is electrical, instead of reading whatever numbers it holds as microamps.

property electrode_names

Return a list of all electrode names in the electrode array

property electrode_objects

Return a list of all electrode objects in the array

property electrodes

Return all electrode names and objects in the electrode array

Internally, electrodes are stored in an ordered dictionary. You can iterate over different electrodes in the array as follows:

for name, electrode in implant.electrodes.items():
    print(name, electrode)

You can access an individual electrode by indexing directly into the prosthesis system object, e.g. implant['A1'] or implant[0].

property max_current

Total instantaneous current (uA) the stimulator can source

property n_electrodes

Number of electrodes in the array

This is equivalent to calling earray.n_electrodes.

plot(annotate=False, autoscale=True, ax=None, stim_cmap=False)[source]

Plot

Parameters:
  • annotate (bool, optional) – Whether to scale the axes view to the data

  • autoscale (bool, optional) – Whether to adjust the x,y limits of the plot to fit the implant

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

  • stim_cmap (bool, str, or matplotlib colormap, optional) – If not false, the fill color of the plotted electrodes will vary based on maximum stimulus amplitude on each electrode. The chosen colormap will be used if provided

Returns:

ax – Returns the axis object of the plot

Return type:

matplotlib.axes.Axes

preprocess_stim(stim)[source]

Preprocess the stimulus

This methods is executed every time a new value is assigned to stim.

No preprocessing is performed by default, but the user can define their own method in implants that inherit from return stim ProsthesisSystem.

A custom method must return a Stimulus object with the correct number of electrodes for the implant.

Parameters:

stim (Stimulus source type) – A valid source type for the Stimulus object (e.g., scalar, NumPy array, pulse train).

Returns:

stim_out

Return type:

Stimulus object

property raster

Raster pattern

Most implants do not set this in their constructor, so the slot backing it may never have been written to; an unset raster means all electrodes may fire at once.

class pulse2percept.implants.ProsthesisSystem(earray, stim=None, eye='RE', preprocess=False, safe_mode=False, raster=None, max_current=None)[source]

Visual prosthesis system

A visual prosthesis combines an electrode array and (optionally) a stimulus. This is the base class for prosthesis systems such as ArgusII and AlphaIMS.

Added in version 0.6.

Parameters:
  • earray (ElectrodeArray or) – Electrode The electrode array used to deliver electrical stimuli to the retina.

  • stim (Stimulus source type) – A valid source type for the Stimulus object (e.g., scalar, NumPy array, pulse train).

  • eye ('LE' or 'RE') – A string indicating whether the system is implanted in the left (‘LE’) or right eye (‘RE’)

  • preprocess (bool or callable, optional) – Either True/False to indicate whether to execute the implant’s default preprocessing method whenever a new stimulus is assigned, or a custom function (callable).

  • safe_mode (bool, optional) – If safe mode is enabled, only charge-balanced stimuli are allowed. Safety is an electrical property, so this also requires the stimulus to be measured in units of current.

  • raster (Raster, optional) –

    How the stimulator takes turns between electrodes that it cannot drive at the same time. If None, every electrode may fire at once.

    Added in version 0.10.0.

  • max_current (float, optional) –

    The total current (uA) the stimulator can source at any one instant, summed over all electrodes. If given, assigning a stimulus that exceeds it raises. If None, no such check is performed.

    May be given as a plain number of microamps or as a unitful quantity (e.g. 0.1 * mA); see pulse2percept.units.

    Added in version 0.10.0.

Examples

A system in the left eye made from a single DiskElectrode with radius r=100um sitting at x=200um, y=-50um, z=10um:

>>> from pulse2percept.implants import DiskElectrode, ProsthesisSystem
>>> implant = ProsthesisSystem(DiskElectrode(200, -50, 10, 100), eye='LE')

Note

A stimulus can also be assigned later (see stim).

property raster

Raster pattern

Most implants do not set this in their constructor, so the slot backing it may never have been written to; an unset raster means all electrodes may fire at once.

property max_current

Total instantaneous current (uA) the stimulator can source

check_stim(stim)[source]

Quality-check the stimulus

This method is executed every time a new value is assigned to stim.

If safe_mode is set to True, this function will only allow stimuli that are charge-balanced. If max_current is set, it will only allow stimuli whose total instantaneous current stays within it.

Both are questions about electricity, and neither can be answered about a stimulus that is not a current, so each raises a DimensionMismatchError on one. An implant that asks for neither does not run either check, which is why a dimensionless stimulus may still be assigned to one – preprocess has already had its chance to turn it into current, and if it did not, no safety claim is being made about it either.

The user can define their own checks in implants that inherit from ProsthesisSystem.

Parameters:

stim (Stimulus source type) – A valid source type for the Stimulus object (e.g., scalar, NumPy array, pulse train).

Raises:
  • DimensionMismatchError – If an electrical check was requested and stim is not measured in units of current.

  • .. versionchanged: – 0.10.0: The electrical checks verify that the stimulus really is electrical, instead of reading whatever numbers it holds as microamps.

preprocess_stim(stim)[source]

Preprocess the stimulus

This methods is executed every time a new value is assigned to stim.

No preprocessing is performed by default, but the user can define their own method in implants that inherit from return stim ProsthesisSystem.

A custom method must return a Stimulus object with the correct number of electrodes for the implant.

Parameters:

stim (Stimulus source type) – A valid source type for the Stimulus object (e.g., scalar, NumPy array, pulse train).

Returns:

stim_out

Return type:

Stimulus object

plot(annotate=False, autoscale=True, ax=None, stim_cmap=False)[source]

Plot

Parameters:
  • annotate (bool, optional) – Whether to scale the axes view to the data

  • autoscale (bool, optional) – Whether to adjust the x,y limits of the plot to fit the implant

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

  • stim_cmap (bool, str, or matplotlib colormap, optional) – If not false, the fill color of the plotted electrodes will vary based on maximum stimulus amplitude on each electrode. The chosen colormap will be used if provided

Returns:

ax – Returns the axis object of the plot

Return type:

matplotlib.axes.Axes

property earray

Electrode array

property stim

Stimulus

A stimulus can be created from many source types, such as scalars, NumPy arrays, and dictionaries (see Stimulus for a complete list).

A stimulus can be assigned either in the ProsthesisSystem constructor or later by assigning a value to stim.

Note

Unless when using dictionary notation, the number of stimuli must equal the number of electrodes in earray.

Examples

Send a biphasic pulse (30uA, 0.45ms phase duration) to an implant made from a single DiskElectrode:

>>> from pulse2percept.implants import DiskElectrode, ProsthesisSystem
>>> from pulse2percept.stimuli import BiphasicPulse
>>> implant = ProsthesisSystem(DiskElectrode(0, 0, 0, 100))
>>> implant.stim = BiphasicPulse(30, 0.45)

Stimulate Electrode B7 in Argus II with 13 uA:

>>> from pulse2percept.implants import ArgusII
>>> implant = ArgusII(stim={'B7': 13})
property eye

Implanted eye

A ProsthesisSystem can be implanted either in a left eye (‘LE’) or right eye (‘RE’). Models such as AxonMapModel will treat left and right eyes differently (for example, adjusting the location of the optic disc).

Examples

Implant Argus II in a left eye:

>>> from pulse2percept.implants import ArgusII
>>> implant = ArgusII(eye='LE')
property n_electrodes

Number of electrodes in the array

This is equivalent to calling earray.n_electrodes.

property electrodes

Return all electrode names and objects in the electrode array

Internally, electrodes are stored in an ordered dictionary. You can iterate over different electrodes in the array as follows:

for name, electrode in implant.electrodes.items():
    print(name, electrode)

You can access an individual electrode by indexing directly into the prosthesis system object, e.g. implant['A1'] or implant[0].

property electrode_names

Return a list of all electrode names in the electrode array

property electrode_objects

Return a list of all electrode objects in the array

class pulse2percept.implants.Raster(group_dur=None)[source]

Abstract base class for all raster patterns

A stimulator usually cannot drive every electrode at once, because the total current it can source at any instant is limited. Electrodes are therefore split into raster groups that take turns.

A raster is a scheduling constraint, not a hardware state machine. What it has to deliver is one property: no two groups are ever active at the same instant, so that the stimulator sources at most one group’s worth of current however the video is modulated. It is not a switch that cyclically enables group 0, then group 1, then group 0 again forever, and a group’s pulses do not have to land at the same phase of a repeating cycle.

Taking turns is described by a raster sweep: group g starts its pulse g * group_dur after group 0 does, so a sweep spans n_groups * group_dur. Two things then keep groups apart for good (see Encoder):

  1. A pulse has to be short enough to finish before the next group’s turn begins.

  2. Electrodes on different pulse periods drift relative to one another, and would eventually collide however they started out. Their periods are therefore pinned to whole numbers of the sweep, which fixes their relative phase. Pinning rounds the period up, so multiplexing never drives an electrode faster – and so never delivers more charge – than asked.

    Electrodes that share one period cannot drift in the first place: their onsets stay group_dur apart forever, whatever that period is. Nothing is quantized in that case and the requested rate is delivered exactly, even when the period is not a whole number of sweeps. This is the usual case under amplitude modulation, and it is why rastering costs no frequency there.

    So with two groups 1.5 ms apart on a common 10 ms period, group 0 pulses at 0, 10, 20, … and group 1 at 1.5, 11.5, 21.5, … – collision-free, but not a repeating 3 ms schedule, and the 10 ms period is left alone.

The sweep belongs to the stimulation schedule, not to the video: it is tied to the pulse period, not to the frame rate. Two rules settle how long it is and what it costs:

  • With group_dur=None the groups divide the shortest pulse period between them, so the sweep is exactly that period. Under frequency modulation that means the fastest electrode pulses once per sweep and slower ones every m-th sweep.

  • With an explicit group_dur the sweep is n_groups * group_dur whatever rate the electrodes run at – six groups of 1 ms sweep in 6 ms. It is then generally much shorter than a pulse period, so even the fastest electrode may pulse only every m-th sweep.

Either way, only periods that differ from one another are rounded up onto the sweep; a period they all share is delivered exactly, since fixed group offsets cannot drift into one another.

Subclasses only implement groups.

Added in version 0.10.0.

Parameters:

group_dur (float, optional) –

Duration (ms) of a single group’s slot, and hence the spacing between one group’s turn and the next. If None, the groups are spread evenly over the pulse period, so that a sweep takes exactly one period to complete – which is what an encoder wants whenever every electrode pulses at the same rate.

Setting it explicitly makes the sweep n_groups * group_dur regardless of the pulse period, which is how you buy back frequency resolution under frequency modulation: a shorter slot means a shorter sweep, and the periods that have to be pinned are pinned onto a finer grid. It cannot be shorter than a single pulse.

An encoder with a clock rounds the slot onto it and rebuilds the sweep from the result, so every group keeps a turn of the same length.

May be given as a plain number of milliseconds or as a unitful quantity (e.g. 1000 * us); the same goes for the period argument of slot_dur() and offsets(). See pulse2percept.units.

abstract property n_groups

Number of raster groups

abstractmethod groups(electrodes)[source]

Assign each electrode to a raster group

Parameters:

electrodes (array_like) – Electrode names, in the order they appear in the stimulus.

Returns:

group – The group each electrode belongs to, in 0..n_groups-1.

Return type:

(n_electrodes,) int array

members(electrodes, group)[source]

The electrodes that take their turn together in one group

The inverse of groups(), which says what group each electrode is in. This says which electrodes are in a group.

Parameters:
  • electrodes (array_like) – Electrode names, in the order they appear in the stimulus.

  • group (int) – Which group to look up, in 0..n_groups-1. Groups take their turns in index order, so group 0 is the one that goes first.

Returns:

members – The entries of electrodes belonging to group, in the order they were given: names in, names out.

Return type:

array

Examples

>>> from pulse2percept.implants import ArgusII, SequentialRaster
>>> names = ArgusII().electrode_names
>>> SequentialRaster(6).members(names, 0)[:4]
array(['A1', 'A2', 'A3', 'A4'], dtype='<U3')
plot(implant, annotate=None, ax=None, cmap='viridis', autoscale=True)[source]

Plot the electrode array, colored by raster group

What a raster does is spatial, so the quickest way to tell whether it does what was wanted is to look at it. Colors run in the order the groups take their turns, so the picture shows the schedule as well as the pattern: with CheckerboardRaster a group’s electrodes should be scattered over the whole array rather than gathered into a line, and neighboring colors should not lie next to one another in a consistent direction.

Parameters:
  • implant (ProsthesisSystem) – The implant to draw, or its ElectrodeArray. Its electrodes are the ones the raster is asked about, so this has to be an implant the raster covers.

  • annotate (bool, optional) – Whether to write the group index into each electrode. If None, they are written whenever there are few enough electrodes (at most 120) for the numbers to be readable.

  • ax (matplotlib.axes.Axes, optional) – Axes to draw on. If None, uses the current axes.

  • cmap (str, optional) – Matplotlib colormap the group colors are taken from, evenly spaced. A sequential map is the useful default, since the order the colors run in is the order the groups fire in.

  • autoscale (bool, optional) – Whether to fit the x/y limits to the implant.

Returns:

ax – The axes drawn on.

Return type:

matplotlib.axes.Axes

slot_dur(period)[source]

Duration (ms) of one group’s slot

Parameters:

period (float) – The pulse period (ms) a sweep has to fit into, so that every group gets its turn before the first one comes round again.

Returns:

slot_durgroup_dur if one was given, else the period split evenly between the groups.

Return type:

float

offsets(electrodes, period)[source]

How far behind group 0 each electrode’s slot begins

Parameters:
  • electrodes (array_like) – Electrode names, in the order they appear in the stimulus.

  • period (float) – The pulse period (ms) a sweep has to fit into.

Returns:

offset – Time (ms) between the start of a sweep and the start of this electrode’s slot.

Return type:

(n_electrodes,) float array

class pulse2percept.implants.RectangleImplant(x=0, y=0, z=0, rot=0, shape=(15, 15), r=75.0, spacing=400.0, eye='RE', stim=None, preprocess=True, safe_mode=False)[source]

A generic rectangular implant

Parameters:
  • x (float, optional) – The x, y, z coordinates (um) of the center of the implant

  • y (float, optional) – The x, y, z coordinates (um) of the center of the implant

  • z (float, optional) – The x, y, z coordinates (um) of the center of the implant

  • rot (float, optional) – The rotation of the implant in degrees

  • shape (tuple, optional) – The number of rows and columns in the implant

  • r (float, optional) – The electrode radius (um)

  • spacing (float, optional) – The distance (um) between electrodes in the implant

  • eye (str, optional) – The eye in which the implant is implanted

  • stim (Stimulus source type) – A valid source type for a stimulus

  • preprocess (bool, optional) – Whether to preprocess the stimulus

  • safe_mode (bool, optional) – Whether to enforce charge balance

Notes

  • Lengths may be given as plain numbers of microns or as unitful quantities (e.g. spacing=0.4 * mm). See pulse2percept.units.

check_stim(stim)[source]

Quality-check the stimulus

This method is executed every time a new value is assigned to stim.

If safe_mode is set to True, this function will only allow stimuli that are charge-balanced. If max_current is set, it will only allow stimuli whose total instantaneous current stays within it.

Both are questions about electricity, and neither can be answered about a stimulus that is not a current, so each raises a DimensionMismatchError on one. An implant that asks for neither does not run either check, which is why a dimensionless stimulus may still be assigned to one – preprocess has already had its chance to turn it into current, and if it did not, no safety claim is being made about it either.

The user can define their own checks in implants that inherit from ProsthesisSystem.

Parameters:

stim (Stimulus source type) – A valid source type for the Stimulus object (e.g., scalar, NumPy array, pulse train).

Raises:
  • DimensionMismatchError – If an electrical check was requested and stim is not measured in units of current.

  • .. versionchanged: – 0.10.0: The electrical checks verify that the stimulus really is electrical, instead of reading whatever numbers it holds as microamps.

property electrode_names

Return a list of all electrode names in the electrode array

property electrode_objects

Return a list of all electrode objects in the array

property electrodes

Return all electrode names and objects in the electrode array

Internally, electrodes are stored in an ordered dictionary. You can iterate over different electrodes in the array as follows:

for name, electrode in implant.electrodes.items():
    print(name, electrode)

You can access an individual electrode by indexing directly into the prosthesis system object, e.g. implant['A1'] or implant[0].

property max_current

Total instantaneous current (uA) the stimulator can source

property n_electrodes

Number of electrodes in the array

This is equivalent to calling earray.n_electrodes.

plot(annotate=False, autoscale=True, ax=None, stim_cmap=False)[source]

Plot

Parameters:
  • annotate (bool, optional) – Whether to scale the axes view to the data

  • autoscale (bool, optional) – Whether to adjust the x,y limits of the plot to fit the implant

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

  • stim_cmap (bool, str, or matplotlib colormap, optional) – If not false, the fill color of the plotted electrodes will vary based on maximum stimulus amplitude on each electrode. The chosen colormap will be used if provided

Returns:

ax – Returns the axis object of the plot

Return type:

matplotlib.axes.Axes

preprocess_stim(stim)[source]

Preprocess the stimulus

This methods is executed every time a new value is assigned to stim.

No preprocessing is performed by default, but the user can define their own method in implants that inherit from return stim ProsthesisSystem.

A custom method must return a Stimulus object with the correct number of electrodes for the implant.

Parameters:

stim (Stimulus source type) – A valid source type for the Stimulus object (e.g., scalar, NumPy array, pulse train).

Returns:

stim_out

Return type:

Stimulus object

property raster

Raster pattern

Most implants do not set this in their constructor, so the slot backing it may never have been written to; an unset raster means all electrodes may fire at once.

property earray

Electrode array

property stim

Stimulus

A stimulus can be created from many source types, such as scalars, NumPy arrays, and dictionaries (see Stimulus for a complete list).

A stimulus can be assigned either in the ProsthesisSystem constructor or later by assigning a value to stim.

Note

Unless when using dictionary notation, the number of stimuli must equal the number of electrodes in earray.

Examples

Send a biphasic pulse (30uA, 0.45ms phase duration) to an implant made from a single DiskElectrode:

>>> from pulse2percept.implants import DiskElectrode, ProsthesisSystem
>>> from pulse2percept.stimuli import BiphasicPulse
>>> implant = ProsthesisSystem(DiskElectrode(0, 0, 0, 100))
>>> implant.stim = BiphasicPulse(30, 0.45)

Stimulate Electrode B7 in Argus II with 13 uA:

>>> from pulse2percept.implants import ArgusII
>>> implant = ArgusII(stim={'B7': 13})
property eye

Implanted eye

A ProsthesisSystem can be implanted either in a left eye (‘LE’) or right eye (‘RE’). Models such as AxonMapModel will treat left and right eyes differently (for example, adjusting the location of the optic disc).

Examples

Implant Argus II in a left eye:

>>> from pulse2percept.implants import ArgusII
>>> implant = ArgusII(eye='LE')
class pulse2percept.implants.SequentialRaster(n_groups, interleave=False, group_dur=None)[source]

Split electrodes into groups that fire one after another

Electrodes are assigned to groups by their position in the stimulus, which for an ElectrodeGrid runs row by row. So on a 6x10 array such as ArgusII, SequentialRaster(6) puts each row in its own group – a line raster.

Added in version 0.10.0.

Parameters:
  • n_groups (int) – Number of groups to split the electrodes into.

  • interleave (bool, optional) – If False (the default), each group is a contiguous block of electrodes. If True, groups are interleaved, so that consecutive electrodes end up in different groups. Interleaving spreads each group’s current further across the array.

  • group_dur (float, optional) – See Raster.

Examples

A line raster for Argus II, one row of ten electrodes at a time:

>>> from pulse2percept.implants import ArgusII, SequentialRaster
>>> implant = ArgusII()
>>> implant.raster = SequentialRaster(6)
property n_groups

Number of raster groups

groups(electrodes)[source]

Assign each electrode to a raster group

members(electrodes, group)[source]

The electrodes that take their turn together in one group

The inverse of groups(), which says what group each electrode is in. This says which electrodes are in a group.

Parameters:
  • electrodes (array_like) – Electrode names, in the order they appear in the stimulus.

  • group (int) – Which group to look up, in 0..n_groups-1. Groups take their turns in index order, so group 0 is the one that goes first.

Returns:

members – The entries of electrodes belonging to group, in the order they were given: names in, names out.

Return type:

array

Examples

>>> from pulse2percept.implants import ArgusII, SequentialRaster
>>> names = ArgusII().electrode_names
>>> SequentialRaster(6).members(names, 0)[:4]
array(['A1', 'A2', 'A3', 'A4'], dtype='<U3')
offsets(electrodes, period)[source]

How far behind group 0 each electrode’s slot begins

Parameters:
  • electrodes (array_like) – Electrode names, in the order they appear in the stimulus.

  • period (float) – The pulse period (ms) a sweep has to fit into.

Returns:

offset – Time (ms) between the start of a sweep and the start of this electrode’s slot.

Return type:

(n_electrodes,) float array

plot(implant, annotate=None, ax=None, cmap='viridis', autoscale=True)[source]

Plot the electrode array, colored by raster group

What a raster does is spatial, so the quickest way to tell whether it does what was wanted is to look at it. Colors run in the order the groups take their turns, so the picture shows the schedule as well as the pattern: with CheckerboardRaster a group’s electrodes should be scattered over the whole array rather than gathered into a line, and neighboring colors should not lie next to one another in a consistent direction.

Parameters:
  • implant (ProsthesisSystem) – The implant to draw, or its ElectrodeArray. Its electrodes are the ones the raster is asked about, so this has to be an implant the raster covers.

  • annotate (bool, optional) – Whether to write the group index into each electrode. If None, they are written whenever there are few enough electrodes (at most 120) for the numbers to be readable.

  • ax (matplotlib.axes.Axes, optional) – Axes to draw on. If None, uses the current axes.

  • cmap (str, optional) – Matplotlib colormap the group colors are taken from, evenly spaced. A sequential map is the useful default, since the order the colors run in is the order the groups fire in.

  • autoscale (bool, optional) – Whether to fit the x/y limits to the implant.

Returns:

ax – The axes drawn on.

Return type:

matplotlib.axes.Axes

slot_dur(period)[source]

Duration (ms) of one group’s slot

Parameters:

period (float) – The pulse period (ms) a sweep has to fit into, so that every group gets its turn before the first one comes round again.

Returns:

slot_durgroup_dur if one was given, else the period split evenly between the groups.

Return type:

float

class pulse2percept.implants.SquareElectrode(x, y, z, a, name=None, activated=True)[source]

Square electrode

Added in version 0.7.

Parameters:
  • x/y/z (double) – 3D location of the electrode. The coordinate system is centered over the fovea. Positive x values move the electrode into the nasal retina. Positive y values move the electrode into the superior retina. Positive z values move the electrode away from the retina into the vitreous humor (sometimes called electrode-retina distance).

  • a (double) – Side length (um) of the square

  • name (str, optional) – Electrode name

  • activated (bool) – To deactivate, set to False. Deactivated electrodes cannot receive stimuli.

Notes

  • Lengths may be given as plain numbers of microns or as unitful quantities (e.g. 50 * um). See pulse2percept.units.

coordinate_unit = um[source]

The unit electrode coordinates are stored in. Electrodes hold plain numbers, which is what every kernel downstream of them expects; this says what those numbers mean.

coordinates(unit=None)[source]

3D position of the electrode

Added in version 0.10.0.

Parameters:

unit (Unit, optional) – Length unit to express the position in. If None, the position is returned as it is stored (microns).

Returns:

coords – An ordinary NumPy array [x, y, z], never a Quantity.

Return type:

(3,) np.ndarray

Examples

>>> from pulse2percept.implants import DiskElectrode
>>> from pulse2percept.units import mm
>>> DiskElectrode(1000, 0, 100, 200).coordinates(mm)
array([1. , 0. , 0.1])
plot(autoscale=False, ax=None)[source]

Plot

Parameters:
  • 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 given, a new one will be created.

Returns:

ax – Returns the axis object of the plot

Return type:

matplotlib.axes.Axes

class pulse2percept.implants.IMIE(x=0, y=0, z=0, rot=0, eye='RE', stim=None, preprocess=True, safe_mode=False)[source]

The 256-channel epiretinal prosthesis system (IMIE 256)

This class implements a 256-channel Intelligent Micro Implant Eye epiretinal prosthesis system (IMIE 256) [Xu2021]. It was co-developed by Golden Eye Bionic, LLC (Pasadena CA) and IntelliMicro Medical Co., Ltd. (Changsha, Hunan Province, China) and is manufactured by IntelliMicro.

IMIE contains 248 large electrodes (210 µm in diameter) and 8 smaller electrodes (160 µm in diameter) arranged in a 4.75mm×6.50mm area.

The array is oriented upright in the visual field, such that an array with center (0,0) has the top three rows lie in the lower retina (upper visual field):

Parameters:
  • x/y/z (double) – 3D location of the center of the electrode array. The coordinate system is centered over the fovea. Positive x values move the electrode into the nasal retina. Positive y values move the electrode into the superior retina. Positive z values move the electrode away from the retina into the vitreous humor (sometimes called electrode-retina distance). z can either be a list with 35 entries or a scalar that is applied to all electrodes.

  • rot (float) – Rotation angle of the array (deg). Positive values denote counter-clock-wise (CCW) rotations in the retinal coordinate system.

  • eye ({'RE', 'LE'}, optional) – Eye in which array is implanted.

  • preprocess (bool or callable, optional) – Either True/False to indicate whether to execute the implant’s default preprocessing method whenever a new stimulus is assigned, or a custom function (callable).

  • safe_mode (bool, optional) – If safe mode is enabled, only charge-balanced stimuli are allowed.

property earray

Electrode array

property eye

Implanted eye

A ProsthesisSystem can be implanted either in a left eye (‘LE’) or right eye (‘RE’). Models such as AxonMapModel will treat left and right eyes differently (for example, adjusting the location of the optic disc).

Examples

Implant Argus II in a left eye:

>>> from pulse2percept.implants import ArgusII
>>> implant = ArgusII(eye='LE')
property stim

Stimulus

A stimulus can be created from many source types, such as scalars, NumPy arrays, and dictionaries (see Stimulus for a complete list).

A stimulus can be assigned either in the ProsthesisSystem constructor or later by assigning a value to stim.

Note

Unless when using dictionary notation, the number of stimuli must equal the number of electrodes in earray.

Examples

Send a biphasic pulse (30uA, 0.45ms phase duration) to an implant made from a single DiskElectrode:

>>> from pulse2percept.implants import DiskElectrode, ProsthesisSystem
>>> from pulse2percept.stimuli import BiphasicPulse
>>> implant = ProsthesisSystem(DiskElectrode(0, 0, 0, 100))
>>> implant.stim = BiphasicPulse(30, 0.45)

Stimulate Electrode B7 in Argus II with 13 uA:

>>> from pulse2percept.implants import ArgusII
>>> implant = ArgusII(stim={'B7': 13})
check_stim(stim)[source]

Quality-check the stimulus

This method is executed every time a new value is assigned to stim.

If safe_mode is set to True, this function will only allow stimuli that are charge-balanced. If max_current is set, it will only allow stimuli whose total instantaneous current stays within it.

Both are questions about electricity, and neither can be answered about a stimulus that is not a current, so each raises a DimensionMismatchError on one. An implant that asks for neither does not run either check, which is why a dimensionless stimulus may still be assigned to one – preprocess has already had its chance to turn it into current, and if it did not, no safety claim is being made about it either.

The user can define their own checks in implants that inherit from ProsthesisSystem.

Parameters:

stim (Stimulus source type) – A valid source type for the Stimulus object (e.g., scalar, NumPy array, pulse train).

Raises:
  • DimensionMismatchError – If an electrical check was requested and stim is not measured in units of current.

  • .. versionchanged: – 0.10.0: The electrical checks verify that the stimulus really is electrical, instead of reading whatever numbers it holds as microamps.

property electrode_names

Return a list of all electrode names in the electrode array

property electrode_objects

Return a list of all electrode objects in the array

property electrodes

Return all electrode names and objects in the electrode array

Internally, electrodes are stored in an ordered dictionary. You can iterate over different electrodes in the array as follows:

for name, electrode in implant.electrodes.items():
    print(name, electrode)

You can access an individual electrode by indexing directly into the prosthesis system object, e.g. implant['A1'] or implant[0].

property max_current

Total instantaneous current (uA) the stimulator can source

property n_electrodes

Number of electrodes in the array

This is equivalent to calling earray.n_electrodes.

plot(annotate=False, autoscale=True, ax=None, stim_cmap=False)[source]

Plot

Parameters:
  • annotate (bool, optional) – Whether to scale the axes view to the data

  • autoscale (bool, optional) – Whether to adjust the x,y limits of the plot to fit the implant

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

  • stim_cmap (bool, str, or matplotlib colormap, optional) – If not false, the fill color of the plotted electrodes will vary based on maximum stimulus amplitude on each electrode. The chosen colormap will be used if provided

Returns:

ax – Returns the axis object of the plot

Return type:

matplotlib.axes.Axes

preprocess_stim(stim)[source]

Preprocess the stimulus

This methods is executed every time a new value is assigned to stim.

No preprocessing is performed by default, but the user can define their own method in implants that inherit from return stim ProsthesisSystem.

A custom method must return a Stimulus object with the correct number of electrodes for the implant.

Parameters:

stim (Stimulus source type) – A valid source type for the Stimulus object (e.g., scalar, NumPy array, pulse train).

Returns:

stim_out

Return type:

Stimulus object

property raster

Raster pattern

Most implants do not set this in their constructor, so the slot backing it may never have been written to; an unset raster means all electrodes may fire at once.