The MCO MIB has determined that the root cause for the loss of the MCO spacecraft was the failure to use metric units in the coding of a ground software file, “Small Forces,” used in trajectory models. Specifically, thruster performance data in English units instead of metric units was used in the software application code titled SM_FORCES (small forces).
astropy.units
quantities
cf_units
import metpy.calc as mpcalc
from metpy.units import units
temperature = 75 * units.degF
relative_humidity = 70 * units.percent
mpcalc.dewpoint_rh(temperature, relative_humidity).to('degF')
from scipy.constants import convert_temperature
temperature = convert_temperature(75, 'F', 'C')
relative_humidity = 0.7
convert_temperature(mpcalc.dewpoint_rh(temperature,
relative_humidity), 'C', 'F')
from metpy.constants import Rd
import numpy as np
t_diff = (np.random.randn(10) * units.degC -
np.random.randn(10) * units.degC)
np.trapz(t_diff)
6.0560018454768532
astropy.units
a = np.array([3.])
b = np.array([4.])
np.concatenate((a, b))
array([ 3., 4.])
a = np.array([3.]) * units.m
b = np.array([4.]) * units.m
np.concatenate((a, b))
array([ 3., 4.])
import numpy as np
a = np.arange(5)
np.gradient(a, 0.1)
array([ 10., 10., 10., 10., 10.])
With units?
a = np.arange(5) * units.degC
np.gradient(a, 0.1 * units.m)
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-7-6af9099bae25> in <module>() 1 a = np.arange(5) * units.degC ----> 2 np.gradient(a, 0.1 * units.m) ~/miniconda3/envs/py36/lib/python3.6/site-packages/numpy/lib/function_base.py in gradient(f, *varargs, **kwargs) 1692 if np.isscalar(distances): 1693 continue -> 1694 if len(distances) != f.shape[axes[i]]: 1695 raise ValueError("distances must be either scalars or match " 1696 "the length of the corresponding dimension") ~/miniconda3/envs/py36/lib/python3.6/site-packages/pint/quantity.py in __len__(self) 1246 1247 def __len__(self): -> 1248 return len(self._magnitude) 1249 1250 def __iter__(self): TypeError: object of type 'float' has no len()
np.isscalar()
for a float with units attached returns False
numpy.interp()
¶x = np.arange(5)
y = x
np.interp(1.5, x, y)
1.5
With units?
x = np.arange(5) * units.m
y = x
np.interp(1.5 * units.m, x, y)
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-9-03a96250bbae> in <module>() 1 x = np.arange(5) * units.m 2 y = x ----> 3 np.interp(1.5 * units.m, x, y) ~/miniconda3/envs/py36/lib/python3.6/site-packages/numpy/lib/function_base.py in interp(x, xp, fp, left, right, period) 2037 return interp_func([x], xp, fp, left, right).item() 2038 else: -> 2039 return interp_func(x, xp, fp, left, right) 2040 else: 2041 if period == 0: ValueError: object of too small depth for desired array
scipy.optimize.fixed_point
from scipy.optimize import fixed_point
def step(p, p0, w, t):
td = dewpoint(vapor_pressure(p, w))
return (p0 * (td / t) ** (1. / kappa))
fp = so.fixed_point(step, pressure,
args=(pressure, w, temperature))
Nope, that doesn't work...
from scipy.optimize import fixed_point
def step(p, p0, w, t):
td = dewpoint(vapor_pressure(units.Quantity(p, pressure.units), w))
return (p0 * (td / t) ** (1. / kappa)).magnitude
fp = so.fixed_point(step, pressure.magnitude,
args=(pressure.magnitude, w, temperature))
Plot()
¶First with units:
import matplotlib.pyplot as plt
temp_data = np.random.randn(50)
temp_units = temp_data * units.degC
t = np.linspace(0, 5, 50)
plt.plot(t, temp_units)
[<matplotlib.lines.Line2D at 0x10f2f35f8>]
Now masked arrays, no units:
temp_masked = np.ma.masked_array(temp_data, mask=temp_data<0)
plt.plot(t, temp_masked)
[<matplotlib.lines.Line2D at 0x10f40df60>]
Now what about masked and units?
temp_units_masked = temp_masked * units.degC
plt.plot(t, temp_units_masked)
[<matplotlib.lines.Line2D at 0x10f501cc0>]
axhline()
/axvline()
¶plt.axhline(0 * units.degC)
ValueError: Cannot compare Quantity and <class 'numpy.float64'>
import xarray as xr
data = xr.DataArray([1, 2, 3], dims=('x',), coords={'x':[1, 2, 3]})
units.m * data
data * units.m
<xarray.DataArray (x: 3)> array([1, 2, 3]) Coordinates: * x (x) int64 1 2 3
pint.Quantity.__add__
xarray.DataArray.__add__
np.(as)array
== "Please silently discard my units"np.asanyarray
only helps for subclasses__array_ufunc__
supportnumpy.asarray
can perform isinstance
check with (one) ABCasarray
for other ABCs