pulse2percept.units
Physical units.
A deliberately small unit system, inspired by Brian2, that lets p2p’s public API accept unitful values:
import pulse2percept.units as u
pulse = BiphasicPulse(50 * u.uA, 0.45 * u.ms)
implant = Orion(x=15 * u.mm)
For just a few units, importing them directly is also convenient:
from pulse2percept.units import uA, ms
Three rules describe the whole system:
Bare numbers keep working, and keep their documented meaning. p2p never warns about them.
Unitful values are dimension-checked and rescaled to the unit the code expects, so
50 * uAand0.05 * mAare the same input (up to floating-point precision).Units are stripped at the API boundary, before any numerical work. Cython kernels and NumPy arrays never see a
Quantity.
Available units
Quantity |
Units |
|---|---|
time |
|
frequency |
|
length |
|
current |
|
voltage |
|
charge |
|
visual angle |
|
dimensionless |
|
|
- pulse2percept.units.as_value(value, unit, name=None)[source]
Convert a value to a bare number expressed in
unitThis is p2p’s standard Python-to-numerics boundary. A
Quantityis dimension-checked and rescaled tounit; a bare number is assumed to already be expressed inunitand is passed through untouched (includingNone).- Parameters:
- Returns:
value – The bare numerical value, expressed in
unit.- Return type:
float, np.ndarray, or None
Examples
>>> from pulse2percept.units import as_value, ms, s >>> as_value(20, ms) 20 >>> as_value(0.02 * s, ms) 20.0
- class pulse2percept.units.Dimension(**exponents)[source]
Physical dimensionality of a unit or quantity
A dimension is a vector of integer exponents over the primitive dimensions in
BASE_DIMENSIONS. Dimensions are immutable, hashable, and support multiplication, division, and integer powers.Added in version 0.10.0.
- Parameters:
**exponents (int) – Exponent for each primitive dimension, e.g.
Dimension(current=1, length=-2)for a current density. Omitted dimensions have exponent 0.
Examples
>>> from pulse2percept.units import Dimension >>> Dimension(current=1) * Dimension(time=1) Dimension('charge') >>> Dimension(time=-1).name 'frequency'
- property exponents
Tuple of exponents, aligned with
BASE_DIMENSIONS
- property is_dimensionless
Whether all exponents are zero
- property name
Human-readable name, e.g.
'electric current'
- exception pulse2percept.units.DimensionMismatchError[source]
Raised when quantities of incompatible dimensions are combined
Subclasses
TypeErrorbecause a dimension mismatch is a type error in the physical sense: microamps are simply not a kind of millisecond.Added in version 0.10.0.
- add_note()
Exception.add_note(note) – add a note to the exception
- with_traceback()
Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.
- class pulse2percept.units.Quantity(magnitude, unit)[source]
A number (or array of numbers) with a unit
Quantities are what users build by multiplying a number by a unit, and they exist to be checked and converted at p2p’s public API boundaries. They are deliberately not NumPy arrays: p2p strips units before any numerical work, so quantities never reach a Cython kernel and never impose per-element overhead on a simulation.
For the same reason,
np.asarray(5 * uA)does not silently yield5. Removing a unit is something you write down, usingto_value().Equivalent unit choices convert consistently up to floating-point precision, and quantities compare accordingly:
0.0041 * mA == 4.1 * uAis True even though rescaling the former gives4.1000000000000005.Added in version 0.10.0.
- Parameters:
Examples
>>> from pulse2percept.units import uA, mA >>> 500 * uA == 0.5 * mA True >>> (500 * uA).to(mA) 0.5 mA >>> (500 * uA).to_value(mA) 0.5
- property magnitude
The numerical value(s), expressed in
self.unit
- class pulse2percept.units.Unit(dimension, scale, symbol)[source]
A unit of measurement
A unit is a dimension plus a scale factor relative to the base unit of that dimension (seconds, meters, amperes, volts, or degrees of visual angle) plus a symbol used for display.
Multiplying a number, list, or NumPy array by a unit produces a
Quantity. Multiplying, dividing, or exponentiating units produces another unit, so derived units such asuA / mm ** 2need not be predefined.Units are immutable. p2p does not maintain a unit registry, parse unit strings, or generate SI prefixes automatically: the vocabulary exported by
pulse2percept.unitsis the whole of it.Added in version 0.10.0.
- Parameters:
Examples
>>> from pulse2percept.units import uA, mm, ms >>> uA / mm ** 2 uA/mm^2 >>> 50 * uA 50 uA
- property scale
Size of this unit relative to the base unit of its dimension
- property symbol
Short symbol used for display