This notebook is based on the 2016 AAS Python Units tutorial, though expanded and adapted
One very useful python package is the astropy units package. Astropy is a library of python functions specific to astronomy that we will use pretty frequently in this class. Astropy.units is a powerful module within astropy that allows users to attach units to scalars and arrays. These quantities can be manipulated or combined, keeping track of the units.
For more information about the features presented below, please see the astropy.units docs.
Because we may want to use units many times within one notebook, it is easiest and most concise to import the units module with a nickname like u so that we don't have to type "astropy.units" every time we want to use something within it.
In [ ]:
import astropy.units as u
However, note that this will conflict with any variable called u
.
Units can then be accessed as u."unit", e.g. with most of the typical abbreviations
In [ ]:
u.m #meters
Units have docstrings defining them. You can call up the docstring, data type and other ancillary information with ? as we've done before and it will pop up a separate frame at the bottom of the window that you close when done with it.
If you explicitly want to print the docstring to output inside the notebook (which can be quite useful so that you can use it later), you can do that with __doc__ for the docstring. The units functions in astropy have an additional property called physical type that will tell you what KIND of measurement they are (length, area, time, etc.). You call up this property with physical_type, as below.
In [ ]:
u.m?
In [ ]:
u.m.__doc__
In [ ]:
u.m.physical_type
Here are some astronomy specific units that we will be using often
In [ ]:
u.pc.__doc__
In [ ]:
u.pc.physical_type
In [ ]:
u.arcsec.__doc__
In [ ]:
u.arcsec.physical_type
In [ ]:
u.au.__doc__
In [ ]:
u.au.physical_type
Please see the complete list of available units.
Composite units are created using Python numeric operators, e.g. "*
" (multiplication), "/
" (division), and "**
" (power).
In [ ]:
u.km / u.s
In [ ]:
u.imperial.mile / u.h
In [ ]:
(u.eV * u.Mpc) / u.Gyr
In [ ]:
u.cm**3
In [ ]:
u.m / u.kg / u.s**2
In [ ]:
3. * u.au
A completely equivalent (but more verbose) way of doing the same thing is to use the Quantity
object's initializer, demonstrated below. In general, the simpler form (above) is preferred, as it is closer to how such a quantity would actually be written in text. The initalizer form has more options, though, which you can learn about from the astropy reference documentation on Quantity.
In [ ]:
u.Quantity(3, unit=u.au)
We can also generate a Quantity
array:
In [ ]:
import numpy as np
x = np.array([1.2, 2.2, 1.7]) * u.pc / u.year
x
In [ ]:
x * 3
The astropy.constants module also contains physical constants relevant for astronomy. They are defined as Quantity
objects using the astropy.units
framework.
In [ ]:
from astropy.constants import G, c, R_earth
There are a few subtelties to note here. First, both of the following methods for importing astropy.constants are perfectly legitimate:
1) from astropy import constants (or from astropy import constants as cst) Here, you would import all of the constant definitions in the module, but would have to refer to them with the constants. (or cst.) prefix. For example, G would now be constants.G.
2) from astropy.constants import * Here the * means "all", so this command will import all of the constants defintions from the module. The danger here is that you will overwrite any assigned variables with those names (e.g. "c") with the constants. Generally speaking, it's best to use the method shown and only import the constants that you need OR use 1) above.
In [ ]:
G
In [ ]:
c
There are also lots of great values that we don't typically think of as constants stored in this module. For example, the radius of the Earth. Some of these are also stored in the units module.
In [ ]:
R_earth
Please see the complete list of available physical constants. Additions are welcome!
In [ ]:
x = np.array([1, 2, -3, 4, 5])
In [ ]:
x.dtype
In [ ]:
x.ndim
In [ ]:
x.size
In [ ]:
x.
In [ ]:
x.
In [ ]:
x.min() #minimum array value
In [ ]:
x.max() #maximum array value
In [ ]:
x.std() #standard deviation
In [ ]:
x.mean()
In [ ]:
np.median(x)
In [ ]:
np.abs(x) #absolute value
The units and value of a Quantity
can be accessed separately via the value
and unit
attributes:
In [ ]:
q = 5. * u.Mpc
In [ ]:
q.value
In [ ]:
q.unit
In [ ]:
x = np.array([1.2, 2.2, 1.7]) * u.pc / u.year
In [ ]:
x.value
In [ ]:
x.unit
Quantities can also be combined using Python numeric operators:
In [ ]:
q1 = 3. * u.m / u.s
q1
In [ ]:
q2 = 5. * u.cm / u.s / u.g**2
q2
In [ ]:
q1 * q2
In [ ]:
q1 / q2
In [ ]:
q1 ** 2
Addition and subtraction require compatible unit types. The cells below provide some examples. Note that the units don't have to be the same they only have to be compatible (i.e. both lengths or both times)
In [ ]:
q1 = 3 * u.m
q1 + (5 * u.m)
In [ ]:
q1 + (5. * u.kpc)
In [ ]:
# this will fail because the units are not compatible
q1 + (10. * u.km / u.s)
Units can be converted using the syntax [quantity or variable name].to(unit), as below
In [ ]:
(2.5 * u.year).to(u.s)
In [ ]:
(7. * u.deg**2).to(u.sr)
In [ ]:
q1.to(u.au)
In [ ]:
(55. * u.imperial.mile / u.h).to(u.km / u.h)
In [ ]:
q1 * q2
In [ ]:
(q1 * q2).to(u.m**2 / u.kg**2 / u.s)
Constants are also quantities, thus they can be coverted to other units as well:
In [ ]:
R_earth.to(u.km)
However, note that converting the constant alone results in just the scale factor between the two and no units
In [ ]:
(u.Msun).to(u.kg)
In [ ]:
# to keep the units, use a Quantity (value and unit)
(1. * u.Msun).to(u.kg)
Python/astropy will NOT combine units unless you ask it to. For example, the following multiplication will preserve both units, even though they are both lengths.
In [ ]:
a = 8 * u.cm
b = 10* u.m
a*b
However, if you explicitly tell it to, the units module can decompose a quantity into a set of base units using the
decompose()
method. By default, units will be decomposed to S.I. units
In [ ]:
q = 3. * u.cm * u.pc / u.g / u.year**2
q
cm and pc are both units of length, so will be combined. The units provided will all also be converted to their SI equiavelents (length to m, mass to g, time to seconds)
In [ ]:
q.decompose()
To decompose into c.g.s. bases:
In [ ]:
q.decompose(u.cgs.bases)
Also convenient if you forget what cgs vs. si base units are is the bases attribute
In [ ]:
u.cgs.bases
In [ ]:
u.si.bases
If you want units other than the SI/ CGS standard, you can then convert the output using .to, as before
In [ ]:
v = np.sqrt(G * 1 * u.M_sun / (1 * u.au))
v
In [ ]:
v.decompose()
In [ ]:
v.to(u.km / u.s)
The James Webb Space Telescope (JWST) will be located at the second Sun-Earth Lagrange (L2) point, which is a special location in space where its orbital period will be equal to that of the Earth's, despite its greater distance from the Sun, so if it stays at this point, it will remain at a constant distance from Earth as both orbit the sun (see picture).
L2 is located opposite the Sun at a distance from the Earth of approximately:
$$ r \approx R \left(\frac{M_{earth}}{3 M_{sun}}\right) ^{(1/3)} $$where $R$ is the Sun-Earth distance.
Calculate the Earth-L2 distance in kilometers and miles:
u.imperial.mile
(see imperial units)
In [ ]:
# answer here (km)
In [ ]:
# answer here (mile)
The L2 point is about 1.5 million kilometers away from the Earth opposite the Sun. The total mass of the James Webb Space Telescope (JWST) is about 6500 kg.
Using the value you obtained above for the Earth-L2 distance, calculate the gravitational force in Newtons between
Hint: the gravitational force between two masses separated by a distance r is:
$$ F_g = \frac{G m_1 m_2}{r^2} $$
In [ ]:
# answer here (Earth)
In [ ]:
# answer here (Sun)
Most of the Numpy functions understand Quantity
objects:
In [ ]:
np.sin(30 * u.degree)
In [ ]:
q = 100 * u.km * u.km
q
In [ ]:
np.sqrt(q)
In [ ]:
np.exp(3 * u.m / (3 * u.km))
Care needs to be taken with dimensionless units. Passing dimensionless values to an inverse trigonometric function gives a result without units:
In [ ]:
np.arcsin(1.0)
u.dimensionless_unscaled
creates a Quantity
with a "dimensionless unit" and therefore gives a result with units:
In [ ]:
np.arcsin(1.0 * u.dimensionless_unscaled)
In [ ]:
np.arcsin(1.0 * u.dimensionless_unscaled).to(u.degree)
Quantities lose their units with some Numpy operations, e.g.:
See Quantity Known Issues for more details.
You can also define custom units for something that isn't built-in to astropy.
In [ ]:
# fundamental unit
chuckle = u.def_unit('chuckle')
In [ ]:
# compound unit
laugh = u.def_unit('laugh', 4 * chuckle)
In [ ]:
(3 * laugh).to(chuckle)
In [ ]:
bakers_fortnight = u.def_unit('bakers_fortnight', 13 * u.day)
In [ ]:
(3 * bakers_fortnight).to(u.s)
Define units equal to the following (which you should look up or justify an estimate for)
a) the circumference of the earth
b) the diameter of the Milky Way galaxy
c) the distance across the US
d) the distance between two people holding hands
e) the mass of an elephant
Then, convert the following physical quantities into these units
a) the distance to the moon in earth circumferences
b) 1 Mpc (Mega parsec) to Milky Way Diameters
c) the distance across the US to human armspans (how many people holding hands could fit across the width of the US?)
d) the mass of Jupiter in elephants
In [ ]:
Jupyter markdown cells also understand a commonly-used typesetting language called LaTeX. LaTeX is used to compose most scientific publications. In fact, most scientific journals have custom "style" files that contain all of the rules about how to format documents for their publication (e.g. font size, font type, margins, etc.). We won't be using a standalone LaTeX editor in this class, but we will use LaTeX "math mode" syntax to insert equations into markdown cells as needed. LaTeX formats equations beautifully, and if you know this you'll never have to use Microsoft Word's equation editor again!
The interpreter that reads Jupyter markdown cells is so-called "MathJax aware", which means it understands a subset of common LaTeX commands called MathJax.
Technically speaking, you shouldn't have to surround MathJax syntax with \$ symbols, but in practice, you should, particularly if you have an equation embedded in a long block of text. The \$ symbols tell the markdown cell explicitly that you want it to typeset an equation or symbol.
For example, typing \$ F = m \times a \$ in a markdown cell results in a nicely typeset $ F = m \times a $.
The \times is an example of a command telling MathJax to insert a certain symbol. A list of common LaTeX symbols is here for your reference, but note that MathJax is only a subset of LaTeX and may not recognize all of these.
Particularly useful are the greek letters, almost all of which are denoted with a \ plus their name, for example \alpha is $\alpha$ \omega is $\omega$
Some of the greek letters have both capital and lowercase versions, and you call the capital version just by capetalizing the first letter.
\lambda is $\lambda$, but \Lambda is $\Lambda$
Also useful and perhaps unfamiliar to you are the symbols used in astronomy for the sun and earth
\odot is the sun symbol $\odot$
\oplus is the earth symbol $\oplus$
superscripts and subscripts are relatively easy. You use the underscore (_) to denote a subscript and the carrot (\^) to denote a superscript.
So, F_G results in $F_G$ and e^x results in $e^x$
However, only the first letter following each symbol will be super or subscripted, so L_sun becomes $L_sun$, and, more dangerously e^2x becomes $e^2x$. So, if you want a multiletter sub- or super- script, then you should enclose the text with curly brackets. L_{sun} becomes $L_{sun}$ and e^{2x} becomes $e^{2x}$
Fractions are done with the command \frac{numerator}{denominator}, so \frac{GMm}{r^2} results in
$\frac{GMm}{r^2}$
With the \frac command, LaTeX will try to fit everything into one line height. If you'd like a full-sized numerator and denominator, use \dfrac instead
$\dfrac{GMm}{r^2}$
See the link above for a more complete reference, but here are a few more particularly useful LaTeX commands
\sqrt{} for square root $\sqrt{x}$
\int{} for integral $\int{x^2dx}$
\pm for plus or minus $8\pm2$
In [ ]:
a) Make a markdown cell showing the equation for the double slit diffraction pattern mentioned in class, and describe/define the variables in text.
b) Find a diagram of double slit diffraction on the internet with the distances/variables in the equation labeled, download it, and display it in the notebook together with the equation and description of variables.
c) write a function that returns that diffraction pattern (intensity as a function of angle theta) as a plot
* Hints:
i) I_0 is just a scaling factor. Set it equal to one or leave it out entirely
ii) use the astropy units module! Your default inputs should be 0.01cm for d, 0.001cm for a and 600nm (red light) for wavelength.
iii) any quantity for which you take a sin or cos should have an angle unit (u.radian or u.degree)
iv) start with a range of angles (theta) from -10 to 10 degrees
d) experiment with changing the input. Describe what happens when you change d, a and wavelength.
e) Create a visualization to describe what happens to the diffraction pattern if white rather than monochromatic light is used
In [1]:
from IPython.core.display import HTML
def css_styling():
styles = open("../custom.css", "r").read()
return HTML(styles)
css_styling()
Out[1]: