{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Units\n", "\n", "Testing a couple of different packages for handling units: `astropy.units`, `quantities`, and `pint`.\n", "\n", "## `astropy.units`\n", "\n", "Replicating the handy [online tutorial](http://astropy.readthedocs.org/en/latest/units/)." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "ename": "ModuleNotFoundError", "evalue": "No module named 'astropy'", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mimport\u001b[0m \u001b[0mastropy\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0munits\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mu\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mnumpy\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'astropy'" ] } ], "source": [ "import astropy.units as u\n", "import numpy as np" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$42 \\; \\mathrm{m}$" ], "text/plain": [ "" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "42.0 * u.meter" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$[1,~2,~3] \\; \\mathrm{m}$" ], "text/plain": [ "" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[1., 2., 3.] * u.m" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$[1,~2,~3] \\; \\mathrm{m}$" ], "text/plain": [ "" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.array([1., 2., 3.]) * u.m" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [], "source": [ "w = 42.0 * u.kilogram" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "42.0" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "w.value" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$\\mathrm{kg}$" ], "text/plain": [ "Unit(\"kg\")" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "w.unit" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['T',\n", " '__abs__',\n", " '__add__',\n", " '__and__',\n", " '__array__',\n", " '__array_finalize__',\n", " '__array_interface__',\n", " '__array_prepare__',\n", " '__array_priority__',\n", " '__array_struct__',\n", " '__array_wrap__',\n", " '__class__',\n", " '__contains__',\n", " '__copy__',\n", " '__deepcopy__',\n", " '__delattr__',\n", " '__delitem__',\n", " '__delslice__',\n", " '__dict__',\n", " '__dir__',\n", " '__div__',\n", " '__divmod__',\n", " '__doc__',\n", " '__eq__',\n", " '__float__',\n", " '__floordiv__',\n", " '__format__',\n", " '__ge__',\n", " '__getattr__',\n", " '__getattribute__',\n", " '__getitem__',\n", " '__getslice__',\n", " '__gt__',\n", " '__hash__',\n", " '__hex__',\n", " '__iadd__',\n", " '__iand__',\n", " '__idiv__',\n", " '__ifloordiv__',\n", " '__ilshift__',\n", " '__imod__',\n", " '__imul__',\n", " '__index__',\n", " '__init__',\n", " '__int__',\n", " '__invert__',\n", " '__ior__',\n", " '__ipow__',\n", " '__irshift__',\n", " '__isub__',\n", " '__iter__',\n", " '__itruediv__',\n", " '__ixor__',\n", " '__le__',\n", " '__len__',\n", " '__long__',\n", " '__lshift__',\n", " '__lt__',\n", " '__mod__',\n", " '__module__',\n", " '__mul__',\n", " '__ne__',\n", " '__neg__',\n", " '__new__',\n", " '__nonzero__',\n", " '__oct__',\n", " '__or__',\n", " '__pos__',\n", " '__pow__',\n", " '__quantity_subclass__',\n", " '__radd__',\n", " '__rand__',\n", " '__rdiv__',\n", " '__rdivmod__',\n", " '__reduce__',\n", " '__reduce_ex__',\n", " '__repr__',\n", " '__rfloordiv__',\n", " '__rlshift__',\n", " '__rmod__',\n", " '__rmul__',\n", " '__ror__',\n", " '__rpow__',\n", " '__rrshift__',\n", " '__rshift__',\n", " '__rsub__',\n", " '__rtruediv__',\n", " '__rxor__',\n", " '__setattr__',\n", " '__setitem__',\n", " '__setslice__',\n", " '__setstate__',\n", " '__sizeof__',\n", " '__str__',\n", " '__sub__',\n", " '__subclasshook__',\n", " '__truediv__',\n", " '__xor__',\n", " '_decompose',\n", " '_equivalencies',\n", " '_include_easy_conversion_members',\n", " '_new_view',\n", " '_repr_latex_',\n", " '_to_own_unit',\n", " '_unit',\n", " '_unitstr',\n", " '_wrap_function',\n", " 'all',\n", " 'any',\n", " 'argmax',\n", " 'argmin',\n", " 'argpartition',\n", " 'argsort',\n", " 'astype',\n", " 'base',\n", " 'byteswap',\n", " 'cgs',\n", " 'choose',\n", " 'clip',\n", " 'compress',\n", " 'conj',\n", " 'conjugate',\n", " 'copy',\n", " 'ctypes',\n", " 'cumprod',\n", " 'cumsum',\n", " 'data',\n", " 'decompose',\n", " 'diagonal',\n", " 'diff',\n", " 'dot',\n", " 'dtype',\n", " 'dump',\n", " 'dumps',\n", " 'ediff1d',\n", " 'equivalencies',\n", " 'fill',\n", " 'flags',\n", " 'flat',\n", " 'flatten',\n", " 'getfield',\n", " 'imag',\n", " 'insert',\n", " 'isscalar',\n", " 'item',\n", " 'itemset',\n", " 'itemsize',\n", " 'max',\n", " 'mean',\n", " 'min',\n", " 'nansum',\n", " 'nbytes',\n", " 'ndim',\n", " 'newbyteorder',\n", " 'nonzero',\n", " 'partition',\n", " 'prod',\n", " 'ptp',\n", " 'put',\n", " 'ravel',\n", " 'real',\n", " 'repeat',\n", " 'reshape',\n", " 'resize',\n", " 'round',\n", " 'searchsorted',\n", " 'setfield',\n", " 'setflags',\n", " 'shape',\n", " 'si',\n", " 'size',\n", " 'sort',\n", " 'squeeze',\n", " 'std',\n", " 'strides',\n", " 'sum',\n", " 'swapaxes',\n", " 'take',\n", " 'to',\n", " 'tobytes',\n", " 'tofile',\n", " 'tolist',\n", " 'tostring',\n", " 'trace',\n", " 'transpose',\n", " 'unit',\n", " 'value',\n", " 'var',\n", " 'view']" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dir(w)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Variables and attributes:" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [], "source": [ "d = 2300. * u.kg/u.m**3" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$2300 \\; \\mathrm{\\frac{kg}{m^{3}}}$" ], "text/plain": [ "" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$\\mathrm{\\frac{kg}{m^{3}}}$" ], "text/plain": [ "Unit(\"kg / m3\")" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d.unit" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [], "source": [ "vp = 2500 * u.m/u.s" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [], "source": [ "z = vp * d" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$5750000 \\; \\mathrm{\\frac{kg}{s\\,m^{2}}}$" ], "text/plain": [ "" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "z" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$\\mathrm{\\frac{kg}{s\\,m^{2}}}$" ], "text/plain": [ "Unit(\"kg / (m2 s)\")" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "z.unit" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[Unit(\"10 P / m\")]" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "z.unit.compose()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Convert velocity to ft/s: " ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [], "source": [ "from astropy.units import imperial" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$8202.0997 \\; \\mathrm{\\frac{ft}{s}}$" ], "text/plain": [ "" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "vp.to(imperial.foot/u.s)" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$8202.1 \\; \\mathrm{\\frac{ft}{s}}$" ], "text/plain": [ "" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# To put it another way:\n", "vp * 3.28084 * (imperial.foot/u.m)" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [], "source": [ "fps = imperial.foot/u.second" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$8202.0997 \\; \\mathrm{\\frac{ft}{s}}$" ], "text/plain": [ "" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "vp_imperial = vp.to(fps)\n", "vp_imperial" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$250000 \\; \\mathrm{\\frac{cm}{s}}$" ], "text/plain": [ "" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "vp.cgs" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$2500 \\; \\mathrm{\\frac{m}{s}}$" ], "text/plain": [ "" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "vp_imperial.si" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "I think we could define a unit system, `oilfield` or `oil` perhaps, that has feet, g/cm^3, seconds, degF, etc.\n", "\n", "We would also have to define various units like barrel, boe, cubic foot, etc." ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$245 \\; \\mathrm{{}^{\\circ}C}$" ], "text/plain": [ "" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t = 245 * u.deg_C\n", "t" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[(Unit(\"K\"),\n", " Unit(\"deg_C\"),\n", " >,\n", " >),\n", " (Unit(\"deg_C\"),\n", " Unit(\"deg_F\"),\n", " >,\n", " >),\n", " (Unit(\"K\"),\n", " Unit(\"deg_F\"),\n", " >,\n", " >)]" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "u.equivalencies.temperature()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "I do like how IPython plays so nicely with the formatting. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## `quantities`\n", "\n", "Potentially nice because it can also handle uncertainties. Following [the tutorial](https://pythonhosted.org/quantities/user/tutorial.html)..." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import quantities as pq" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array(2.5) * km/s" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "vel = 2.5 * pq.km/pq.s\n", "vel" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array(8202.099737532808) * ft/s" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "vel.units = pq.ft/pq.s\n", "vel" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "I think I prefer having a `to` method on the quantity object, rather than setting an attribute.\n", "\n", "Uncertainties are quite cool, though, if rather deterministic..." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "UncertainQuantity(array(2850.0), kg/m**3, array(75.0))" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "den = pq.UncertainQuantity(2850., pq.kg/pq.m**3, 75.)\n", "den" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "UncertainQuantity(array(23375984.251968503), kg*ft/(m**3*s), array(615157.4803149606))" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "imp = vel * den\n", "imp" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## `pint`" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "from pint import UnitRegistry" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "ureg = UnitRegistry()" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "vs = 1200. * ureg.meter/ureg.second" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/html": [ "1200.0 meter/second" ], "text/latex": [ "$1200.0 \\frac{meter}{second}$" ], "text/plain": [ "" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "vs" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "vs.units" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1200.0" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "vs.magnitude" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "vs.dimensionality" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "data": { "text/html": [ "2760000.0 kg / m3 meter/second" ], "text/latex": [ "$2760000.0 kg / m3 \\frac{meter}{second}$" ], "text/plain": [ "" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "zs = vs * d\n", "zs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Not sure if this is good or bad, but `pint` knows about aliases and alternate spellings:" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "data": { "text/html": [ "3937.00787402 foot/second" ], "text/latex": [ "$3937.00787402 \\frac{foot}{second}$" ], "text/plain": [ "" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "vs.to(ureg.feet/ureg.s)" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "data": { "text/html": [ "3937.00787402 foot/second" ], "text/latex": [ "$3937.00787402 \\frac{foot}{second}$" ], "text/plain": [ "" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "vs.to(ureg.foot/ureg.s)" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "data": { "text/html": [ "5.0 meter" ], "text/latex": [ "$5.0 meter$" ], "text/plain": [ "" ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "5.0 * ureg.metres" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As with astropy, we can define units:" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "data": { "text/html": [ "3937.00787402 foot/second" ], "text/latex": [ "$3937.00787402 \\frac{foot}{second}$" ], "text/plain": [ "" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ftps = ureg.foot/ureg.second\n", "vs.to(ftps)" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "data": { "text/html": [ "2245.0 degR" ], "text/latex": [ "$2245.0 degR$" ], "text/plain": [ "" ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t = 2245.0 * ureg.rankine\n", "t" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [ { "data": { "text/html": [ "974.072222222 degC" ], "text/latex": [ "$974.072222222 degC$" ], "text/plain": [ "" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t.to(ureg.degC)" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [], "source": [ "p = 4500. * ureg.psi" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "data": { "text/html": [ "31.0264078193 megapascal" ], "text/latex": [ "$31.0264078193 megapascal$" ], "text/plain": [ "" ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p.to(ureg.MPa)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## `pint` with `numpy`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Need to see how the units respond to being differenced, convolved, etc. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "geocomp", "language": "python", "name": "geocomp" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.2" } }, "nbformat": 4, "nbformat_minor": 1 }