# Astropy: Unit Conversion¶

## Representing units and quantities¶

Astropy includes a powerful framework for units that allows users to attach units to scalars and arrays, and manipulate/combine these, keeping track of the units.

Since we may want to use a number of units in expressions, it is easiest and most concise to import the units module with:

In [1]:
from astropy import units as u


though note that this will conflict with any variable called u.

Units can then be accessed with:

In [2]:
u.m

Out[2]:
$\mathrm{m}$
In [3]:
u.pc

Out[3]:
$\mathrm{pc}$
In [4]:
u.s

Out[4]:
$\mathrm{s}$
In [5]:
u.kg

Out[5]:
$\mathrm{kg}$

We can create composite units:

In [6]:
u.m / u.kg / u.s**2

Out[6]:
$\mathrm{\frac{m}{kg\,s^{2}}}$
In [7]:
repr(u.m / u.kg / u.s**2)

Out[7]:
'Unit("m / (kg s2)")'

The most useful feature about the units is the ability to attach them to scalars or arrays, creating Quantity objects:

In [8]:
3. * u.m

Out[8]:
$3 \; \mathrm{m}$
In [9]:
import numpy as np

In [10]:
np.array([1.2, 2.2, 1.7]) * u.pc / u.year

Out[10]:
$[1.2,~2.2,~1.7] \; \mathrm{\frac{pc}{yr}}$

## Combining and converting units¶

Quantities can then be combined:

In [11]:
q1 = 3. * u.m

In [12]:
q2 = 5. * u.cm / u.s / u.g**2

In [13]:
q1 * q2

Out[13]:
$15 \; \mathrm{\frac{cm\,m}{s\,g^{2}}}$

and converted to different units:

In [14]:
(q1 * q2).to(u.m**2 / u.kg**2 / u.s)

Out[14]:
$150000 \; \mathrm{\frac{m^{2}}{s\,kg^{2}}}$

The units and value of a quantity can be accessed separately via the value and unit attributes:

In [15]:
q = 5. * u.pc

In [16]:
q.value

Out[16]:
5.0
In [17]:
q.unit

Out[17]:
$\mathrm{pc}$

The units of a quantity can be decomposed into a set of base units using the decompose() method. By default, units will be decomposed to S.I.:

In [18]:
(3. * u.cm * u.pc / u.g / u.year**2).decompose()

Out[18]:
$929.53097 \; \mathrm{\frac{m^{2}}{kg\,s^{2}}}$

To decompose into c.g.s. units, one can do:

In [19]:
(3. * u.cm * u.pc / u.g / u.year**2).decompose(u.cgs.bases)

Out[19]:
$9295.3097 \; \mathrm{\frac{cm^{2}}{g\,s^{2}}}$

## Using physical constants¶

The astropy.constants module contains physical constants relevant for Astronomy, and these are defined with units attached to them using the astropy.units framework.

If we want to compute the Gravitational force felt by a 100. * u.kg space probe by the Sun, at a distance of 3.2au, we can do:

In [20]:
from astropy.constants import G

In [21]:
F = (G * 1. * u.M_sun * 100. * u.kg) / (3.2 * u.au)**2

In [22]:
F

Out[22]:
$6.5174219 \times 10^{-10} \; \mathrm{\frac{m^{3}\,M_{\odot}}{AU^{2}\,s^{2}}}$
In [23]:
F.to(u.N)

Out[23]:
$0.057927079 \; \mathrm{N}$

The full list of available physical constants is shown here (and additions are welcome!).

## Equivalencies¶

Equivalencies can be used to convert quantities that are not strictly the same physical type:

In [24]:
(450. * u.nm).to(u.GHz)

---------------------------------------------------------------------------
UnitConversionError                       Traceback (most recent call last)
/sw/lib/python3.4/site-packages/astropy/units/core.py in _get_converter(self, other, equivalencies)
865         try:
--> 866             scale = self._to(other)
867         except UnitsError:

/sw/lib/python3.4/site-packages/astropy/units/core.py in _to(self, other)
934         raise UnitConversionError(
--> 935             "'{0!r}' is not a scaled version of '{1!r}'".format(self, other))
936

UnitConversionError: 'Unit("nm")' is not a scaled version of 'Unit("GHz")'

During handling of the above exception, another exception occurred:

UnitConversionError                       Traceback (most recent call last)
<ipython-input-24-e4fbcb033257> in <module>()
----> 1 (450. * u.nm).to(u.GHz)

/sw/lib/python3.4/site-packages/astropy/units/quantity.py in to(self, unit, equivalencies)
632         unit = Unit(unit)
633         new_val = self.unit.to(unit, self.view(np.ndarray),
--> 634                                equivalencies=equivalencies)
635         return self._new_view(new_val, unit)
636

/sw/lib/python3.4/site-packages/astropy/units/core.py in to(self, other, value, equivalencies)
966             If units are inconsistent
967         """
--> 968         return self._get_converter(other, equivalencies=equivalencies)(value)
969
970     def in_units(self, other, value=1.0, equivalencies=[]):

/sw/lib/python3.4/site-packages/astropy/units/core.py in _get_converter(self, other, equivalencies)
867         except UnitsError:
868             return self._apply_equivalencies(
--> 869                 self, other, self._normalize_equivalencies(equivalencies))
870         return lambda val: scale * _condition_arg(val)
871

/sw/lib/python3.4/site-packages/astropy/units/core.py in _apply_equivalencies(self, unit, other, equivalencies)
858         raise UnitConversionError(
859             "{0} and {1} are not convertible".format(
--> 860                 unit_str, other_str))
861
862     def _get_converter(self, other, equivalencies=[]):

UnitConversionError: 'nm' (length) and 'GHz' (frequency) are not convertible
In [25]:
(450. * u.nm).to(u.GHz, equivalencies=u.spectral())

Out[25]:
$666205.46 \; \mathrm{GHz}$
In [26]:
(450. * u.eV).to(u.nm, equivalencies=u.spectral())

Out[26]:
$2.7552043 \; \mathrm{nm}$
In [27]:
q = (1e-18 * u.erg / u.cm**2 / u.s / u.AA)
q.to(u.Jy, equivalencies=u.spectral_density(u.mm, 1))

Out[27]:
$3.335641 \; \mathrm{Jy}$

## Integration with Numpy Functions¶

Some of the Numpy functions understand Quantity objects:

In [28]:
np.sin(30 * u.degree)

Out[28]:
$0.5 \; \mathrm{}$
In [29]:
np.exp(3 * u.m/ (3 * u.km))

Out[29]:
$1.0010005 \; \mathrm{}$

## Practical Exercises¶

### Level 1¶

What is 1 barn megaparsecs in teaspoons? Note that teaspoons are not part of the standard set of units, but it can be found in:

In [30]:
from astropy.units import imperial
imperial.tsp

Out[30]:
$\mathrm{tsp}$
In [31]:
# Your solution here


### Level 2¶

What is 3 nm^2 Mpc / m^3 in dimensionless units?

In [32]:
# Your solution here


### Level 3¶

Try and use equivalencies to find the doppler shifted wavelength of a line at 454.4nm if the object is moving at a velocity of 510km/s. You will need to read up more about the available equivalencies here

In [33]:
# Your solution here