# Physical units¶

Brian includes a system for defining physical units. These are defined by
their standard SI unit names: amp,
kilogram, second, metre/meter and the derived units coulomb, farad, gram/gramme,
hertz, joule, pascal, ohm, siemens, volt, watt, together with prefixed
versions (e.g. `msiemens = 0.001*siemens`) using the prefixes
p, n, u, m, k, M, G, T (two exceptions: kilogram is not imported with any
prefixes, metre and meter are additionaly defined with the “centi” prefix,
i.e. cmetre/cmeter). In addition a couple of useful standard abbreviations like
“cm” (instead of cmetre/cmeter), “nS” (instead of nsiemens),
“ms” (instead of msecond), “Hz” (instead of hertz), etc. are included.

## Using units¶

You can generate a physical quantity by multiplying a scalar or vector value with its physical unit:

```
>>> tau = 20*ms
>>> print tau
20. ms
>>> rates = [10, 20, 30] * Hz
>>> print rates
[ 10. 20. 30.] Hz
```

Brian will check the consistency of operations on units and raise an error for dimensionality mismatches:

```
>>> tau += 1 # ms? second?
Traceback (most recent call last):
...
DimensionMismatchError: Addition, dimensions were (s) (1)
>>> 3*gram + 3*amp
Traceback (most recent call last):
...
DimensionMismatchError: Addition, dimensions were (kg) (A)
Traceback (most recent call last):
...
DimensionMismatchError: Addition, dimensions were (kg) (A)
```

Most Brian functions will also complain about non-specified or incorrect units:

```
>>> G = NeuronGroup(10, 'dv/dt = -v/tau: volt', dt=0.5)
Traceback (most recent call last):
...
DimensionMismatchError: Function "__init__" variable "dt" has wrong dimensions, dimensions were (1) (s)
Traceback (most recent call last):
...
DimensionMismatchError: Function "__init__" variable "dt" has wrong dimensions, dimensions were (1) (s)
```

Numpy functions have been overwritten to correctly work with units (see the
*developer documentation* for more details):

```
>>> print mean(rates)
20. Hz
>>> print rates.repeat(2)
[ 10. 10. 20. 20. 30. 30.] Hz
```

## Removing units¶

There are various options to remove the units from a value (e.g. to use it with analysis functions that do not correctly work with units)

- Divide the value by its unit (most of the time the recommended option because it is clear about the scale)
- Transform it to a pure numpy array in the base unit by calling
`asarray()`(no copy) or`array`(copy) - Directly get the unitless value of a state variable by appending an underscore to the name

```
>>> tau/ms
array(20.0)
>> asarray(rates)
array([ 10., 20., 30.])
>>> G = NeuronGroup(5, 'dv/dt = -v/tau: volt')
>>> print G.v_[:]
[ 0., 0., 0., 0., 0.]
```

## Importing units¶

Brian generates standard names for units, combining the unit name (e.g.
“siemens”) with a prefixes (e.g. “m”), and also generates squared and cubed
versions by appending a number. For example, the units “msiemens”, “siemens2”,
“usiemens3” are all predefined. You can import these units from the package
`brian2.units.allunits` – accordingly, an
`from brian2.units.allunits import *` will result in everything from
`Ylumen3` (cubed yotta lumen) to `ymol` (yocto mole) being imported.

A better choice is normally to do an `from brian2.units import *` or import
everything `from brian2 import *`, this imports only the base units amp,
kilogram, second, metre/meter and the derived units coulomb, farad, gram/gramme,
hertz, joule, pascal, ohm, siemens, volt, watt, together with the prefixes
p, n, u, m, k, M, G, T (two exceptions: kilogram is not imported with any
prefixes, metre and meter are additionaly defined with the “centi” prefix,
i.e. cmetre/cmeter).

In addition a couple of useful standard abbreviations like
“cm” (instead of cmetre/cmeter), “nS” (instead of nsiemens),
“ms” (instead of msecond), “Hz” (instead of hertz), etc. are added (they can
be individually imported from `brian2.units.stdunits`).

## Comparison with Brian 1¶

Brian 1 did only support scalar quantities, units were not stored for arrays. Some expressions therefore have different values in Brian 1 and Brian 2:

Expression | Brian 1 | Brian 2 |
---|---|---|

1 * mV | 1.0 * mvolt | 1.0 * mvolt |

np.array(1) * mV | 0.001 | 1.0 * mvolt |

np.array([1]) * mV | array([ 0.001]) | array([1.]) * mvolt |

np.mean(np.arange(5) * mV) | 0.002 | 2.0 * mvolt |

np.arange(2) * mV | array([ 0. , 0.001]) | array([ 0., 1.]) * mvolt |

(np.arange(2) * mV) >= 1 * mV | array([False, True], dtype=bool) | array([False, True], dtype=bool) |

(np.arange(2) * mV)[0] >= 1 * mV | False | False |

(np.arange(2) * mV)[1] >= 1 * mV | DimensionMismatchError | True |