pynbody.units#

units#

The pynbody units module consists of a set of classes for tracking units.

It relates closely to the array module, which defines an extension to numpy arrays which carries unit information.

Making units#

Units are generated and used at various points through the pynbody framework. Quite often the functions where users interact with units simply accept strings.

You can also make units yourself in two ways. Either you can create a string, and instantiate a Unit like this:

>>> units.Unit("Msol kpc**-3")
>>> units.Unit("2.1e12 m_p cm**-2/3")

Or you can do it within python, using the named Unit objects

>>> units.Msol * units.kpc**-3
>>> 2.1e12 * units.m_p * units.cm**(-2,3)

In the last example, either a tuple describing a fraction or a Fraction instance (from the standard python module fractions) is acceptable.

Getting conversion ratios#

To convert one unit to another, use the ratio member function:

>>> units.Msol.ratio(units.kg)
1.99e30
>>> (units.Msol / units.kpc**3).ratio(units.m_p/units.cm**3)
4.04e-8

If the units cannot be converted, a UnitsException is raised:

>>> units.Msol.ratio(units.kpc)
UnitsException

Specifying numerical values#

Sometimes it’s necessary to specify a numerical value in the course of a conversion. For instance, consider a comoving distance; this can be specified in pynbody units as follows:

>>> comoving_kpc = units.kpc * units.a

where units.a represents the scalefactor. We can attempt to convert this to a physical distance as follows

>>> comoving_kpc.ratio(units.kpc)

but this fails, throwing a UnitsException. On the other hand we can specify a value for the scalefactor when we request the conversion

>>> comoving_kpc.ratio(units.kpc, a=0.5)
0.5

and the conversion completes with the expected result. The units module also defines units.h for the dimensionless hubble constant, which can be used similarly. By default, all conversions happening within a specific simulation context should pass in values for a and h as a matter of routine.

Any IrreducibleUnit (see below) can have a value specified in this way, but a and h are envisaged to be the most useful applications.

Defining new base units#

The units module is fully extensible: you can define and name your own units which then integrate with all the standard functions.

litre = units.NamedUnit("litre",0.001*units.m**3)
gallon = units.NamedUnit("gallon",0.004546*units.m**3)
gallon.ratio(litre) # 4.546
(units.pc**3).ratio(litre) # 2.94e52

You can even define completely new dimensions.

V = units.IrreducibleUnit("V") # define a volt
C = units.NamedUnit("C", units.J/V) # define a coulomb
q = units.NamedUnit("q", 1.60217646e-19*C) # elementary charge
F = units.NamedUnit("F", C/V) # Farad
epsilon0 = 8.85418e-12 *F/units.m
>>> (q*V).ratio("eV")
1.000
>>> ((q**2)/(4*math.pi*epsilon0*units.m**2)).ratio("N")
2.31e-28

Functions

Unit(s)

Class factory for units.

get_item_with_unit(array, item)

has_unit(obj)

Returns True if the specified object has a meaningful units attribute

has_units(obj)

Returns True if the specified object has a meaningful units attribute

is_unit(obj)

Returns True if the specified object represents a unit

is_unit_like(obj)

Returns True if the specified object is itself a unit or otherwise exposes unit information

takes_arg_in_units(*args, **orig_kwargs)

Returns a decorator to create a function which auto-converts input to given units.

Classes

CompositeUnit(scale, bases, powers)

Methods

IrreducibleUnit(st)

Methods

NamedUnit(st, represents)

Methods

NoUnit()

Methods

UnitBase()

Base class for units.

Exceptions

UnitsException