# -*- coding: utf-8 -*- """ Small function to convert any quantity (typically, numpy array) from unit A to unit B. Uses `pint` internally but output a dimensionless array not to impact performances in downstream calculations Use ---------- conv2(141131064, 'erg/s', 'W') Prerequisite ---------- pint module is installed (`pip install pint`) """ from pint import UnitRegistry ureg = UnitRegistry() # ureg.load_definitions('units.txt') # >>> define your own units Q_ = ureg.Quantity def conv2(quantity, fromunit, tounit): ''' Converts `quantity` from unit `fromunit` to unit `tounit` Note that the output is still non dimensional. We don't transform `quantity` into a pint array (or neq.phys.uarray) because this may create a performance drop in computationaly-expensive task. Instead, we assume we know for sure the units in which some of our quantities will be created, and just want to let the users choose another output unit Input ------ quantity: array, float, etc. fromunit: str tounit: str ''' a = Q_(quantity,fromunit) a = a.to(tounit) return a.magnitude # %% Test if __name__ == '__main__': # Test convtable = [ (500, 'nm', 0.5, 'µm'), (1, 'erg/s', 1e-7, 'W'), (1, 'm^2',10000,'cm^2') ] for a, f, r, t in convtable: cr = conv2(a, f, t) print('{0} {1} = {2} {3}'.format(a, f, cr, t)) # Typically, I use it whenever I have quantities shared among different codes, # but that may call it with different units: # # For instance Planck's equilibrium radiance below: def planck(lmbda, T, eps=1, unit='mW/sr/cm^2/nm'): ''' Planck function for blackbody radiation Input --------- λ: np.array (nm) wavelength T: float (K) equilibrium temperature eps: grey-body emissivity default 1 Output --------- planck: np.array (mW.sr-1.cm-2/nm) equilibrium radiance ''' k = k_b lbd = lmbda * 1e-9 planck = eps*(2*h*c**2/lbd**5) * 1/(exp(h*c/(lbd*k*T)) - 1) # S.I (W.sr-1.m-3) planck *= 1e-10 # W.sr-1.m-3 >>> mW.sr-1.cm-2.nm-1 if unit != 'mW/sr/cm^2/nm': planck = conv2(planck, 'mW/sr/cm^2/nm', unit) return planck