Extending pulse2percept¶
pulse2percept is designed to allow for implants, models, and stimuli to be customized through class inheritance, a concept from object-oriented programming.
Note
If you are unfamiliar with these concepts, have a look at this tutorial.
Creating your own implant¶
Objects in the implants
module are organized into the
following categories:
Electrodes are objects whose behavior is dictated by the
Electrode
base class.The base class provides:
- the 3D coordinates of the center of the electrode.
In addition, a custom electrode object must implement:
- a method called
electric_potential
that returns the electric potential at a point (x, y, z).
A small working example:
class MyElectrode(Electrode): """Named electrode with electric potential 0 everywhere""" def __init__(self, x, y, z, name): # Note: If you don't plan on adding any new variables, you can # omit the constructor entirely. In that case, your object will # inherit the constructor of the base class. self.x = x self.y = y self.z = z self.name = name def electric_potential(self, x, y, z): return 0.0
See also
Electrode arrays are collections of
Electrode
objects whose behavior is dictated by theElectrodeArray
base class.The base class provides:
electrodes
: an ordered dictionary of electrode objects (meaning it will remember the order in which electrodes were added),n_electrodes
: a property returning the number of electrodes in the array.add_electrode
: a method to add a single electrode to the collection,add_electrodes
: a method to add a multiple electrodes to the collection at once,- a way to access a single electrode either by index or by name,
- a way to iterate over all electrodes in the array.
A small working example:
class MyElectrodeArray(ElectrodeArray): """Array with a single disk electrode""" def __init__(self, name): self.electrodes = coll.OrderedDict() self.add_electrode(name, DiskElectrode(0, 0, 0, 100))
See also
Prosthesis systems (“retinal implants”) are comprised of an
ElectrodeArray
object and (optionally) aStimulus
. Their behavior is dictated by theProsthesisSystem
base class.The base class provides:
ElectrodeArray
: as described above,Stimulus
: as described above,check_stim
: a method that quality-checks the stimulus. By default this method does nothing, but its behavior might depend on the actual system, such asArgusII
orAlphaIMS
,eye
: a string indicating whether the system is implanted in the left or right eye,- a means to access and iterate over electrodes in the array, as described above.
A small working example:
class MyFovealArgusII(ProsthesisSystem): """An Argus II implant centered over the fovea""" def __init__(self, stim=None): self.earray = ElectrodeGrid((6, 10), x=0, y=0, z=0, rot=0, r=100, spacing=525, names=('A', '1')) self.stim = stim
Creating your own stimulus¶
All stimuli described in the stimuli
inherit their
functionality from the Stimulus
base class.
The base class provides:
data
: A 2-D NumPy array, where the rows denote electrodes and the columns denote points in time,shape
: the shape of the data array,compress
: a method to compress the data container so that only nonredundant values are kept.- a means to compare two stimuli with the
==
or!=
operators
A small working example:
class MyMonophasicPulse(Stimulus):
"""A monophasic pulse applied to a single electrode"""
def __init__(self, pulse_amp, pulse_dur, stim_dur, time_step):
# Provide only the time steps at which the signal changes. All
# other time steps will be interpolated:
time = [0, pulse_dur, pulse_dur + time_step, stim_dur]
data = [pulse_amp, pulse_amp, 0, 0]
# Call the constructor of the base class:
super().__init__(self, data, time=time)