pulse2percept.stimuli.Stimulus
- class pulse2percept.stimuli.Stimulus[source]
A stimulus is comprised of a labeled 2D NumPy array that contains the data, where the rows denote electrodes and the columns denote points in time. A stimulus can be created from a variety of source types (e.g., scalars, lists, NumPy arrays, and dictionaries).
The stimulus arrays (
data,time,electrodes) and the pulse parameters of a stimulus that has any are read-only. Arbitrary stimuli are kept as sampled waveforms only.See also
Basic Concepts > Electrical Stimuli <topics-stimuli>
Added in version 0.6.
Changed in version 0.10.0: Stimulus arrays and pulse parameters are read-only, and waveforms are generated lazily.
- Parameters:
source (source type) –
A valid source type is one of the following:
Scalar value: interpreted as the current amplitude delivered to a single electrode (no time component).
- NumPy array:
Nx1 array: interpreted as N current amplitudes delivered to N electrodes (no time component).
NxM array: interpreted as N electrodes each receiving M current amplitudes in time.
In addition, you can also pass a collection of source types. Each element must be a valid source type for a single electrode (e.g., scalar, 1-D array,
Stimulus).List or tuple: List elements will be assigned to electrodes in order.
Dictionary: Dictionary keys are used to address electrodes by name.
electrodes (int, string or list thereof; optional) –
Optionally, you can provide your own electrode names. If none are given, electrode names will be extracted from the source type (e.g., the keys from a dictionary). If a scalar or NumPy array is passed, electrode names will be numbered 0..N.
Note
The number of electrode names provided must match the number of electrodes extracted from the source type (i.e., N).
time (int, float or list thereof; optional) –
Optionally, you can provide the time points of the source data. If none are given, time steps will be numbered 0..M.
Note
The number of time points provided must match the number of time points extracted from the source type (i.e., M). Stimuli created from scalars or 1-D NumPy arrays will have no time componenet, in which case you cannot provide your own time points.
metadata (dict, optional) – Additional stimulus metadata can be stored in a dictionary.
compress (bool, optional) –
If True, will compress the source data in two ways:
Remove electrodes with all-zero activation.
Retain only the time points at which the stimulus changes.
For example, in a pulse train, only the signal edges are saved. This drastically reduces the memory footprint of the stimulus.
Notes
Depending on the source type, a stimulus might have a time component or not (e.g., scalars: time=None).
You can access the stimulus applied to electrode
eat timetby directly indexing intoStimulus[e, t]. In this case,tis not a column index but a time point.If the time point is not explicitly stored in the
datacontainer, its value will be automatically interpolated from neighboring values.If a requested time point lies outside the range of stored data, the value of its closest end point will be returned.
All transformations return a new stimulus, except for
compress()andremove().
Examples
Stimulate a single electrode with -13uA:
>>> from pulse2percept.stimuli import Stimulus >>> stim = Stimulus(-13)
Stimulate ten electrodes with 0uA:
>>> from pulse2percept.stimuli import Stimulus >>> stim = Stimulus(np.zeros(10))
Provide new electrode names for an existing Stimulus object:
>>> from pulse2percept.stimuli import Stimulus >>> old_stim = Stimulus([3, 5]) >>> new_stim = Stimulus(old_stim, electrodes=['new0', 'new1'])
Interpolate the stimulus value at some point in time. Here, the stimulus is a single-electrode ramp stimulus (stimulus value == point in time):
>>> from pulse2percept.stimuli import Stimulus >>> stim = Stimulus(np.arange(10).reshape((1, -1))) >>> stim[:, 3.45] 3.45...
- __init__(source, electrodes=None, time=None, metadata=None, compress=False)[source]
Methods
__init__(source[, electrodes, time, ...])append(other)Append another stimulus
compress()Compress the source data in place
pad(duration)Pad the stimulus with zeros up to a given time.
plot([electrodes, time, fmt, ax, kind])Plot the stimulus
remove(electrodes)Remove electrode(s)
shift(dt)Shift the stimulus in time.
times([unit])The stimulus time axis, expressed in
unitvalues([unit])The stimulus data, expressed in
unitAttributes
metadataStimulus data container
Sampling time step (duration of signal edge transitions)
Stimulus duration (ms)
Electrode names A list of electrode names, corresponding to the rows in the data container.
Flag indicating whether the stimulus is charge-balanced
Flag indicating whether the stimulus has been compressed
The stimulus data, with its unit attached
Data container shape
A list of time steps (i.e., the columns in the data container)
The stimulus time axis with its unit attached, or None
The unit
timeis expressed inThe unit
datais expressed in- compress()[source]
Compress the source data in place
- append(other)[source]
Append another stimulus
This method appends another stimulus (with matching electrodes) in time. The combined stimulus duration will be the sum of the two individual stimuli.
Added in version 0.7.
- remove(electrodes)[source]
Remove electrode(s)
Removes the stimulus of a certain electrode or list of electrodes.
Added in version 0.8.
- shift(dt)[source]
Shift the stimulus in time.
Added in version 0.10.0.
- Parameters:
dt (float or
Quantity) – Time shift. May be positive or negative. Bare values are interpreted in the stimulus’ time unit.- Returns:
shifted – Shifted copy of the stimulus.
- Return type:
Notes
stim >> dtandstim << dtare shorthand forstim.shift(dt)andstim.shift(-dt).
- pad(duration)[source]
Pad the stimulus with zeros up to a given time.
Adds zero-valued endpoints at
t=0andt=durationas needed.durationspecifies the final time, not the amount of padding to add.Added in version 0.10.0.
- Parameters:
duration (float or
Quantity) – Final time of the padded stimulus. Bare values are interpreted in the stimulus’ time unit.- Returns:
padded – Padded copy of the stimulus.
- Return type:
Notes
Padding requires existing boundary values to be zero; otherwise interpolation would create a ramp. It never truncates the stimulus or removes negative time points.
- plot(electrodes=None, time=None, fmt='k-', ax=None, kind=None)[source]
Plot the stimulus
Added in version 0.7.
Changed in version 0.10.0: Added
kind: a whole multi-electrode stimulus is now drawn as an electrode-by-time heatmap rather than as one subplot per electrode.- Parameters:
electrodes (int, string, or list thereof; optional, default: None) – The electrodes for which to plot the stimulus. If None, all electrodes are plotted.
time ((t_min, t_max) tuple, slice, or list of exact time points) – The time points at which to plot the stimulus. Specify a range of time points with a tuple or a slice, or specify the exact time points to interpolate. If None, all time points are plotted.
fmt (str, optional, default: 'k-') – A Matplotlib format string; e.g., ‘ro’ for red circles to use when
kind='traces'.ax (matplotlib.axes.Axes or list thereof; optional, default: None) – A Matplotlib Axes object.
kind='traces'also accepts a list thereof (one per electrode to plot);kind='heatmap'draws into a single Axes. If None, a new Axes object will be created.kind ({'traces', 'heatmap'}, optional, default: None) –
What to draw:
’traces’: the waveform of each electrode, one Axes per electrode. Good for a handful of electrodes.
’heatmap’: an electrode-by-time image in a single Axes. Good for a whole implant’s worth of electrodes.
If None, a whole stimulus of more than one electrode is drawn as a heatmap and everything else as traces.
- Returns:
ax – One Axes per electrode for
kind='traces', a single Axes forkind='heatmap'.- Return type:
matplotlib.axes.Axes or np.ndarray of them
- property data
Stimulus data container
A read-only 2-D NumPy array that contains the sampled waveform, where the rows denote electrodes and the columns denote points in time.
- property shape
Data container shape
- property unit
The unit
datais expressed inAdded in version 0.10.0.
- property time_unit
The unit
timeis expressed inAdded in version 0.10.0.
- property quantity
The stimulus data, with its unit attached
Added in version 0.10.0.
Examples
>>> from pulse2percept.stimuli import Stimulus >>> from pulse2percept.units import uA >>> Stimulus([500, 1000] * uA).quantity [[ 500.] [1000.]] uA
- property time_quantity
The stimulus time axis with its unit attached, or None
Added in version 0.10.0.
- values(unit=None)[source]
The stimulus data, expressed in
unitAdded in version 0.10.0.
- Parameters:
unit (
Unit, optional) – The unit to express the data in. Must be compatible withunit. If None, the stimulus’ own unit is used anddatais returned as it is stored.- Returns:
values – An ordinary NumPy array, never a
Quantity.- Return type:
np.ndarray
Examples
>>> from pulse2percept.stimuli import Stimulus >>> from pulse2percept.units import uA, mA >>> Stimulus([500, 1000] * uA).values(mA) array([[0.5], [1. ]], dtype=float32)
- times(unit=None)[source]
The stimulus time axis, expressed in
unitAdded in version 0.10.0.
- Parameters:
unit (
Unit, optional) – The unit to express the time axis in. If None,timeis returned as it is stored (milliseconds).- Returns:
times – An ordinary NumPy array, or None if the stimulus has no time component.
- Return type:
np.ndarray or None
- property electrodes
Electrode names A list of electrode names, corresponding to the rows in the data container.
- property time
A list of time steps (i.e., the columns in the data container)
- property is_compressed
Flag indicating whether the stimulus has been compressed
- property dt
Sampling time step (duration of signal edge transitions)
Added in version 0.7.
- property is_charge_balanced
Flag indicating whether the stimulus is charge-balanced
A stimulus with a time component is considered charge-balanced if its net current is smaller than 10 pico Amps. For the whole stimulus to be charge-balanced, every electrode must be charge-balanced as well.
Changed in version 0.10.0: Returns None for a stimulus that is not measured in units of current.
- property duration
Stimulus duration (ms)