Units

Basics

Brian has a system for physical quantities with units built in, and most of the library functions require that variables have the right units. This restriction is useful in catching hard to find errors based on using incorrect units, and ensures that simulated models are physically meaningful. For example, running the following code causes an error:

>>> from brian import *
>>> c = Clock(t=0)

Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    c = Clock(t=0)
  File "C:\Documents and Settings\goodman\Mes documents\Programming\Python simulator\Brian\units.py", line 1126, in new_f
    raise DimensionMismatchError("Function " + f.__name__ + " variable " + k + " should have dimensions of " + str(au[k]), getDimensions(newkeyset[k]))
DimensionMismatchError: Function __init__ variable t should have dimensions of s, dimensions were (1)

You can see that Brian raises a DimensionMismatchError exception, because the Clock object expects t to have units of time. The correct thing to write is:

>>> from brian import *
>>> c = Clock(t=0*second)

Similarly, attempting to do numerical operations with inconsistent units will raise an error:

>>> from brian import *
>>> 3*second+2*metre

Traceback (most recent call last):
  File "<pyshell#38>", line 1, in <module>
    3*second+2*metre
  File "C:\Documents and Settings\goodman\Mes documents\Programming\Python simulator\Brian\units.py", line 600, in __add__
    if dim==self.dim:
DimensionMismatchError: Addition, dimensions were (s) (m)

Units defined in Brian

The following fundamental SI unit names are defined:

metre, meter (US spelling), kilogram, second, amp, kelvin, mole, candle

These derived SI unit names are also defined:

radian, steradian, hertz, newton, pascal, joule, watt, coulomb, volt, farad, ohm, siemens, weber, tesla, henry, celsius, lumen, lux, becquerel, gray, sievert, katal

In addition, you can form scaled versions of these units with any of the standard SI prefixes:

Factor Name Symbol Factor Name Symbol
10^24 yotta Y 10^-24 yocto y
10^21 zetta Z 10^-21 zepto z
10^18 exa E 10^-21 zepto z
10^15 peta P 10^-15 femto f
10^12 tera T 10^-12 pico p
10^9 giga G 10^-9 nano n
10^6 mega M 10^-6 micro u (mu in SI)
10^3 kilo k 10^-3 milli m
10^2 hecto h 10^-2 centi c
10^1 deka da 10^-1 deci d

So for example, you could write fnewton for femto-newtons, Mwatt for megawatt, etc.

There are also units for 2nd and 3rd powers of each of the above units, for example metre3 = metre**3, watt2 = watt*watt, etc.

You can optionally use short names for some units derived from volts, amps, farads, siemens, seconds, hertz and metres: mV, mA, uA, nA, pA, mF, uF, nF, mS, uS, ms, Hz, kHz, MHz, cm, cm2, cm3, mm, mm2, mm3, um, um2, um3. Since these names are so short, there is a danger that they might clash with your own variables names, so watch out for that.

Arrays and units

Versions of Brian before 1.0 had a system for allowing arrays to have units, this has been removed for the 1.0 release because of stability problems - as new releases of NumPy, SciPy and PyLab came out it required changes to the units code. Now all arrays used by Brian are standard NumPy arrays and have no units.

Checking units

Units are automatically checked when arithmetic operations are performed, and when a neuron group is initialised (the consistency of the differential equations is checked). They can also be checked explictly when a user-defined function is called by using the decorator @check_units, which can be used as follows:

@check_units(I=amp,R=ohm,wibble=metre,result=volt)
def getvoltage(I,R,**k):
    return I*R

Remarks:

  • not all arguments need to be checked
  • keyword arguments may be checked
  • the result can optionnally be checked
  • no error is raised if the values are strings.

Disabling units

Unit checking can slow down the simulations. The units system can be disabled by inserting import brian_no_units as the first line of the script, e.g.:

import brian_no_units
from brian import *
# etc

Internally, physical quantities are floats with an additional units information. The float value is the value in the SI system. For example, float(mV) returns 0.001. After importing brian_no_units, all units are converted to their float values. For example, mV is simply the number 0.001. This may also be a solution when using external libraries which are not compatible with units (but see next section).

Unit checking can also be turned down locally when initializing a neuron group by passing the argument check_units=False. In that case, no error is raised if the differential equations are not homogeneous.

A good practice is to develop the script with units on, then switch them off once the script runs correctly.

Converting quantities

In many situations, physical quantities need to be expressed with given units. For example, one might want to plot a graph of the membrane potential in mV as a function of time in ms. The following code:

plot(t,V)

displays the trace with time in seconds and potential in volts. The simplest solution to have time in ms and potential in mV is to use units operations:

plot(t/ms,V/mV)

Here, t/ms is a unitless array containing the values of t in ms. The same trick may be applied to use external functions which do not work with units (convert the arguments to unitless quantities as above).