diff --git a/src/wrf/cape.py b/src/wrf/cape.py index e86872d..f7daf65 100755 --- a/src/wrf/cape.py +++ b/src/wrf/cape.py @@ -4,22 +4,12 @@ from __future__ import (absolute_import, division, print_function, import numpy as np import numpy.ma as ma -#from .extension import computetk,computecape from .extension import _tk, _cape from .destag import destagger from .constants import Constants, ConversionFactors from .util import extract_vars from .metadecorators import set_cape_metadata - -#@copy_and_set_metadata(copy_varname="T", -# name="cape_2d", -# dimnames=combine_with("T", remove_dims=("bottom_top",), -# insert_before="south_north", -# new_dimnames=["mcape_mcin_lcl_lfc"]), -# description="mcape ; mcin ; lcl ; lfc", -# units="J/kg ; J/kg ; m ; m", -# MemoryOrder="XY") @set_cape_metadata(is2d=True) def get_2dcape(wrfnc, timeidx=0, method="cat", squeeze=True, cache=None, meta=True, _key=None, missing=Constants.DEFAULT_FILL): @@ -74,13 +64,6 @@ def get_2dcape(wrfnc, timeidx=0, method="cat", squeeze=True, cache=None, return ma.masked_values(result, missing) -#@copy_and_set_metadata(copy_varname="T", name="cape_3d", -# dimnames=combine_with("T", -# insert_before="bottom_top", -# new_dimnames=["cape_cin"]), -# description="cape ; cin", -# units="J kg-1 ; J kg-1", -# MemoryOrder="XY") @set_cape_metadata(is2d=False) def get_3dcape(wrfnc, timeidx=0, method="cat", squeeze=True, cache=None, meta=True, diff --git a/src/wrf/computation.py b/src/wrf/computation.py index 7cd1408..3fe0b5c 100644 --- a/src/wrf/computation.py +++ b/src/wrf/computation.py @@ -38,7 +38,7 @@ def interpz3d(field3d, z, desiredloc, missingval=Constants.DEFAULT_FILL, return _interpz3d(field3d, z, desiredloc, missingval) -@set_alg_metadata(2, "pres", refvarndims=3, units="hpa", +@set_alg_metadata(2, "pres", refvarndims=3, units="hPa", description="sea level pressure") def slp(height, tkel, pres, qv, meta=True): return _slp(height, tkel, pres, qv) @@ -139,8 +139,8 @@ def ctt(pres_hpa, tkel, qv, qcld, height, terrain, qice=None, meta=True): @set_alg_metadata(3, "pres", units="dBZ", description="radar reflectivity") -def dbz(pres, tkel, qv, qr, qs=None, qg=None, use_varint=False, use_liqskin=False, - meta=True): +def dbz(pres, tkel, qv, qr, qs=None, qg=None, use_varint=False, + use_liqskin=False, meta=True): if qs is None: qs = np.zeros(qv.shape, qv.dtype) @@ -155,7 +155,7 @@ def dbz(pres, tkel, qv, qr, qs=None, qg=None, use_varint=False, use_liqskin=Fals return _dbz(pres, tkel, qv, qr, qs, qg, sn0, ivarint, iliqskin) -@set_alg_metadata(2, "terrain", units="m-2/s-2", +@set_alg_metadata(2, "terrain", units="m2 s-2", description="storm relative helicity") def srhel(u, v, z, terrain, top=3000.0, meta=True): # u, v get swapped in vertical @@ -166,7 +166,7 @@ def srhel(u, v, z, terrain, top=3000.0, meta=True): return _srhel(_u, _v, _z, terrain, top) -@set_alg_metadata(2, "u", refvarndims=3, units="m-2/s-2", +@set_alg_metadata(2, "u", refvarndims=3, units="m2 s-2", description="updraft helicity") def udhel(zstag, mapfct, u, v, wstag, dx, dy, bottom=2000.0, top=5000.0, meta=True): @@ -205,7 +205,7 @@ def tvirtual(tkel, qv, meta=True): return _tv(tkel, qv) -@set_alg_metadata(3, "qv", units="Pa/s", +@set_alg_metadata(3, "qv", units="Pa s-1", description="omega") def omega(qv, tkel, w, pres, meta=True): return _omega(qv, tkel, w, pres) diff --git a/src/wrf/ctt.py b/src/wrf/ctt.py index 3e4f8a5..f0d671b 100644 --- a/src/wrf/ctt.py +++ b/src/wrf/ctt.py @@ -19,7 +19,7 @@ from .util import extract_vars @convert_units("temp", "c") def get_ctt(wrfnc, timeidx=0, method="cat", squeeze=True, cache=None, meta=True, _key=None, - units="c"): + units="degC"): """Return the cloud top temperature. """ diff --git a/src/wrf/dbz.py b/src/wrf/dbz.py index 4f75d53..8315557 100755 --- a/src/wrf/dbz.py +++ b/src/wrf/dbz.py @@ -12,7 +12,7 @@ from .metadecorators import copy_and_set_metadata @copy_and_set_metadata(copy_varname="T", name="dbz", description="radar reflectivity", - units="dBz") + units="dBZ") def get_dbz(wrfnc, timeidx=0, method="cat", squeeze=True, cache=None, meta=True, _key=None, use_varint=False, use_liqskin=False): @@ -68,7 +68,7 @@ def get_dbz(wrfnc, timeidx=0, method="cat", @copy_and_set_metadata(copy_varname="T", name="max_dbz", remove_dims=("bottom_top",), description="maximum radar reflectivity", - units="dBz", + units="dBZ", MemoryOrder="XY") def get_max_dbz(wrfnc, timeidx=0, method="cat", squeeze=True, cache=None, meta=True, _key=None, diff --git a/src/wrf/decorators.py b/src/wrf/decorators.py index 2ab3979..c13af3b 100644 --- a/src/wrf/decorators.py +++ b/src/wrf/decorators.py @@ -7,7 +7,7 @@ import wrapt import numpy as np import numpy.ma as ma -from .units import do_conversion, check_units +from .units import do_conversion, check_units, dealias_and_clean_unit from .util import iter_left_indexes, from_args, npvalues, combine_dims from .py3compat import viewitems, viewvalues, isstr from .config import xarray_enabled @@ -29,7 +29,8 @@ def convert_units(unit_type, alg_unit): def func_wrapper(wrapped, instance, args, kwargs): desired_units = from_args(wrapped, "units", *args, **kwargs)["units"] - check_units(desired_units, unit_type) + u_cleaned = dealias_and_clean_unit(desired_units) + check_units(u_cleaned, unit_type) # Unit conversion done here return do_conversion(wrapped(*args, **kwargs), unit_type, diff --git a/src/wrf/dewpoint.py b/src/wrf/dewpoint.py index 67187dc..95bc4b9 100755 --- a/src/wrf/dewpoint.py +++ b/src/wrf/dewpoint.py @@ -12,7 +12,7 @@ from .util import extract_vars description="dew point temperature") @convert_units("temp", "c") def get_dp(wrfnc, timeidx=0, method="cat", squeeze=True, - cache=None, meta=True, _key=None, units="c"): + cache=None, meta=True, _key=None, units="degC"): varnames=("P", "PB", "QVAPOR") ncvars = extract_vars(wrfnc, timeidx, varnames, method, squeeze, cache, @@ -33,7 +33,7 @@ def get_dp(wrfnc, timeidx=0, method="cat", squeeze=True, description="2m dew point temperature") @convert_units("temp", "c") def get_dp_2m(wrfnc, timeidx=0, method="cat", squeeze=True, - cache=None, meta=True, _key=None, units="c"): + cache=None, meta=True, _key=None, units="degC"): varnames=("PSFC", "Q2") ncvars = extract_vars(wrfnc, timeidx, varnames, method, squeeze, cache, meta=False, _key=_key) diff --git a/src/wrf/helicity.py b/src/wrf/helicity.py index 0ab45bc..67335ff 100755 --- a/src/wrf/helicity.py +++ b/src/wrf/helicity.py @@ -11,7 +11,7 @@ from .metadecorators import copy_and_set_metadata @copy_and_set_metadata(copy_varname="HGT", name="srh", description="storm relative helicity", - units="m-2/s-2") + units="m2 s-2") def get_srh(wrfnc, timeidx=0, method="cat", squeeze=True, cache=None, meta=True, _key=None, top=3000.0): # Top can either be 3000 or 1000 (for 0-1 srh or 0-3 srh) @@ -51,7 +51,7 @@ def get_srh(wrfnc, timeidx=0, method="cat", squeeze=True, @copy_and_set_metadata(copy_varname="MAPFAC_M", name="updraft_helicity", description="updraft helicity", - units="m-2/s-2") + units="m2 s-2") def get_uh(wrfnc, timeidx=0, method="cat", squeeze=True, cache=None, meta=True, _key=None, bottom=2000.0, top=5000.0): diff --git a/src/wrf/metadecorators.py b/src/wrf/metadecorators.py index c4fbba7..996e1ce 100644 --- a/src/wrf/metadecorators.py +++ b/src/wrf/metadecorators.py @@ -286,7 +286,7 @@ def set_cape_metadata(is2d): outdimnames[0] = "mcape_mcin_lcl_lfc" outattrs["description"] = "mcape ; mcin ; lcl ; lfc" outattrs["MemoryOrder"] = "XY" - outattrs["units"] = "J/kg ; J/kg ; m ; m" + outattrs["units"] = "J kg-1 ; J kg-1 ; m ; m" outname = "cape_2d" else: # Right dims @@ -1215,7 +1215,7 @@ def set_alg_metadata(alg_ndims, refvarname, return func_wrapper -def set_uvmet_alg_metadata(units="mps", description="earth rotated u,v", +def set_uvmet_alg_metadata(units="m s-1", description="earth rotated u,v", latarg="lat", windarg="u"): @wrapt.decorator @@ -1287,7 +1287,7 @@ def set_cape_alg_metadata(is2d, copyarg="pres_hpa"): if is2d: outname = "cape_2d" outattrs["description"] = "mcape ; mcin ; lcl ; lfc" - outattrs["units"] = "J/kg ; J/kg ; m ; m" + outattrs["units"] = "J kg-1 ; J kg-1 ; m ; m" outattrs["MemoryOrder"] = "XY" else: outname = "cape_3d" diff --git a/src/wrf/omega.py b/src/wrf/omega.py index 61dccb7..f602c69 100755 --- a/src/wrf/omega.py +++ b/src/wrf/omega.py @@ -10,7 +10,7 @@ from .metadecorators import copy_and_set_metadata @copy_and_set_metadata(copy_varname="T", name="omega", description="omega", - units="Pa/s") + units="Pa s-1") def get_omega(wrfnc, timeidx=0, method="cat", squeeze=True, cache=None, meta=True, _key=None): varnames=("T", "P", "W", "PB", "QVAPOR") diff --git a/src/wrf/pressure.py b/src/wrf/pressure.py index 0cc19bf..4d960b1 100755 --- a/src/wrf/pressure.py +++ b/src/wrf/pressure.py @@ -11,7 +11,7 @@ from .util import extract_vars, either @convert_units("pressure", "pa") def get_pressure(wrfnc, timeidx=0, method="cat", squeeze=True, cache=None, meta=True, _key=None, - units="pa"): + units="Pa"): varname = either("P", "PRES")(wrfnc) if varname == "P": @@ -30,7 +30,7 @@ def get_pressure(wrfnc, timeidx=0, method="cat", squeeze=True, def get_pressure_hpa(wrfnc, timeidx=0, method="cat", squeeze=True, cache=None, meta=True, _key=None, - units="hpa"): + units="hPa"): return get_pressure(wrfnc, timeidx, method, squeeze, cache, meta, _key, units) diff --git a/src/wrf/rh.py b/src/wrf/rh.py index e2d8c5f..fc2292b 100755 --- a/src/wrf/rh.py +++ b/src/wrf/rh.py @@ -10,7 +10,7 @@ from .metadecorators import copy_and_set_metadata @copy_and_set_metadata(copy_varname="T", name="rh", description="relative humidity", - delete_attrs=("units",)) + units="%") def get_rh(wrfnc, timeidx=0, method="cat", squeeze=True, cache=None, meta=True, _key=None): varnames=("T", "P", "PB", "QVAPOR") @@ -32,7 +32,7 @@ def get_rh(wrfnc, timeidx=0, method="cat", squeeze=True, cache=None, @copy_and_set_metadata(copy_varname="T2", name="rh2", description="2m relative humidity", - delete_attrs=("units",)) + units="%") def get_rh_2m(wrfnc, timeidx=0, method="cat", squeeze=True, cache=None, meta=True, _key=None): varnames=("T2", "PSFC", "Q2") diff --git a/src/wrf/slp.py b/src/wrf/slp.py index e585a94..d0263f2 100755 --- a/src/wrf/slp.py +++ b/src/wrf/slp.py @@ -17,7 +17,7 @@ from .util import extract_vars @convert_units("pressure", "hpa") def get_slp(wrfnc, timeidx=0, method="cat", squeeze=True, cache=None, meta=True, _key=None, - units="hpa"): + units="hPa"): varnames=("T", "P", "PB", "QVAPOR", "PH", "PHB") ncvars = extract_vars(wrfnc, timeidx, varnames, method, squeeze, cache, meta=False, _key=_key) diff --git a/src/wrf/temp.py b/src/wrf/temp.py index fa0776f..029bf1a 100755 --- a/src/wrf/temp.py +++ b/src/wrf/temp.py @@ -13,7 +13,7 @@ from .util import extract_vars @convert_units("temp", "k") def get_theta(wrfnc, timeidx=0, method="cat", squeeze=True, cache=None, meta=True, _key=None, - units="k"): + units="K"): varnames = ("T",) ncvars = extract_vars(wrfnc, timeidx, varnames, method, squeeze, cache, @@ -29,7 +29,7 @@ def get_theta(wrfnc, timeidx=0, method="cat", squeeze=True, @convert_units("temp", "k") def get_temp(wrfnc, timeidx=0, method="cat", squeeze=True, cache=None, meta=True, _key=None, - units="k"): + units="K"): """Return the temperature in Kelvin or Celsius""" varnames=("T", "P", "PB") @@ -48,10 +48,10 @@ def get_temp(wrfnc, timeidx=0, method="cat", squeeze=True, @copy_and_set_metadata(copy_varname="T", name="theta_e", description="equivalent potential temperature") -@convert_units("temp", "k") +@convert_units("temp", "K") def get_eth(wrfnc, timeidx=0, method="cat", squeeze=True, cache=None, meta=True, _key=None, - units="k"): + units="K"): "Return equivalent potential temperature (Theta-e) in Kelvin" varnames=("T", "P", "PB", "QVAPOR") @@ -76,7 +76,7 @@ def get_eth(wrfnc, timeidx=0, method="cat", squeeze=True, @convert_units("temp", "k") def get_tv(wrfnc, timeidx=0, method="cat", squeeze=True, cache=None, meta=True, _key=None, - units="k"): + units="K"): "Return the virtual temperature (tv) in Kelvin or Celsius" varnames=("T", "P", "PB", "QVAPOR") @@ -102,7 +102,7 @@ def get_tv(wrfnc, timeidx=0, method="cat", squeeze=True, @convert_units("temp", "k") def get_tw(wrfnc, timeidx=0, method="cat", squeeze=True, cache=None, meta=True, _key=None, - units="k"): + units="K"): "Return the wetbulb temperature (tw)" varnames=("T", "P", "PB", "QVAPOR") @@ -125,13 +125,13 @@ def get_tw(wrfnc, timeidx=0, method="cat", squeeze=True, def get_tk(wrfnc, timeidx=0, method="cat", squeeze=True, cache=None, meta=True, _key=None): return get_temp(wrfnc, timeidx, method, squeeze, cache, meta, _key, - units="k") + units="K") def get_tc(wrfnc, timeidx=0, method="cat", squeeze=True, cache=None, meta=True, _key=None): return get_temp(wrfnc, timeidx, method, squeeze, cache, meta, _key, - units="c") + units="degC") diff --git a/src/wrf/units.py b/src/wrf/units.py index 153a4bd..b0a0734 100755 --- a/src/wrf/units.py +++ b/src/wrf/units.py @@ -12,7 +12,7 @@ def _apply_conv_fact(var, vartype, var_unit, dest_unit): # Note, case where var_unit and dest_unit are base unit, should be # handled above if var_unit == _BASE_UNITS[vartype]: - return var * _CONV_FACTORS[vartype]["to_dest"][dest_unit] + return var*(_CONV_FACTORS[vartype]["to_dest"][dest_unit]) else: if dest_unit == _BASE_UNITS[vartype]: return var*(_CONV_FACTORS[vartype]["to_base"][var_unit]) @@ -21,51 +21,149 @@ def _apply_conv_fact(var, vartype, var_unit, dest_unit): _CONV_FACTORS[vartype]["to_dest"][dest_unit]) -def _to_celsius(var, var_unit): - if var_unit == "k": - return var - Constants.CELKEL +def _to_kelvin(var, var_unit): + if var_unit == "c": + return var + Constants.CELKEL elif var_unit == "f": - return (var - 32.0) * (5.0/9.0) + return (var - 32.0) * (5.0/9.0) + Constants.CELKEL -def _c_to_k(var): - return var + Constants.TCK0 +def _k_to_c(var): + return var - Constants.CELKEL -def _c_to_f(var): - return 1.8 * var + 32.0 +def _k_to_f(var): + return 1.8 * _k_to_c(var) + 32.0 -# Temperature is a more complicated operation so requres functions +# Temperature is a more complicated operation so requires functions def _apply_temp_conv(var, var_unit, dest_unit): if dest_unit == var_unit: return var if var_unit != _BASE_UNITS["temp"]: - tc = _to_celsius(var, var_unit) + tk = _to_kelvin(var, var_unit) if dest_unit == _BASE_UNITS["temp"]: - return tc + return tk else: - return (_TEMP_CONV_METHODS[dest_unit])(tc) + return (_TEMP_CONV_METHODS[dest_unit])(tk) else: return (_TEMP_CONV_METHODS[dest_unit])(var) + + +_UNIT_ALIASES = {"mps" : "m s-1", + "m/s" : "m s-1", + "ms-1" : "m s-1", + "meters_per_second" : "m s-1", + "metres_per_second" : "m s-1", + "knots" : "kt", + "knot" : "kt", + "kts" : "kt", + "kn" : "kt", + "miles_per_hour" : "mi h-1", + "mih-1" : "mi h-1", + "mph" : "mi h-1", + "mi/h" : "mi h-1", + "kmph" : "km h-1", + "kmh-1" : "km h-1", + "km/h" : "km h-1", + "kilometers_per_hour" : "km h-1", + "kilometres_per_hour" : "km h-1", + "ft/s" : "ft s-1", + "ft/sec" : "ft s-1", + "fps" : "ft s-1", + "fs-1" : "ft s-1", + "feet_per_second" : "ft s-1", + + "pascal" : "pa", + "pascals" : "pa", + "hecto_pascal" : "hpa", + "hecto_pascals" : "hpa", + "millibar" : "mb", + "millibars" : "mb", + "mbar" : "mb", + + "kelvin" : "k", + "degree_kelvin" : "k", + "degrees_kelvin" : "k", + "degree_k" : "k", + "degrees_k" : "k", + "degreek" : "k", + "degreesk" : "k", + "degk" : "k", + "degsk" : "k", + "deg_k" : "k", + "degs_k" : "k", + "deg k" : "k", + "degs k" : "k", + + "celsius" : "c", + "degree_celsius" : "c", + "degrees_celsius" : "c", + "degree_c" : "c", + "degrees_c" : "c", + "degreec" : "c", + "degreesc" : "c", + "degc" : "c", + "degsc" : "c", + "deg_c" : "c", + "degs_c" : "c", + "deg c" : "c", + "degs c" : "c", + + "fahrenheit" : "f", + "degree_fahrenheit" : "f", + "degrees_fahrenheit" : "f", + "degree_f" : "f", + "degrees_f" : "f", + "degreef" : "f", + "degreesf" : "f", + "degf" : "f", + "degsf" : "f", + "deg_f" : "f", + "degs_f" : "f", + "deg f" : "f", + "degs f" : "f", + + "meter" : "m", + "meters" : "m", + "metre" : "m", + "metres" : "m", + "kilometer" : "km", + "kilometers" : "km", + "dekameter" : "dm", + "dekameters" : "dm", + "decameter" : "dm", + "decameters" : "dm", + "dekametre" : "dm", + "dekametres" : "dm", + "decametre" : "dm", + "decametres" : "dm", + "dam" : "dm", + "dkm" : "dm", + "feet" : "ft", + "foot" : "ft", + "mile" : "mi", + "miles" : "mi" + + } -_VALID_UNITS = {"wind" : ["mps", "kts", "mph", "kmph", "fps"], +_VALID_UNITS = {"wind" : ["m s-1", "kt", "mi h-1", "km h-1", "ft s-1"], "pressure" : ["pa", "hpa", "mb", "torr", "mmhg", "atm"], "temp" : ["k", "f", "c"], - "height" : ["m", "km", "dm", "ft", "miles"] + "height" : ["m", "km", "dm", "ft", "mi"] } -_WIND_BASE_FACTORS = {"kts" : ConversionFactors.MPS_TO_KTS, - "kmph" : ConversionFactors.MPS_TO_KMPH, - "mph" : ConversionFactors.MPS_TO_MPH, - "fps" : ConversionFactors.MPS_TO_FPS +_WIND_BASE_FACTORS = {"kt" : ConversionFactors.MPS_TO_KTS, + "km h-1" : ConversionFactors.MPS_TO_KMPH, + "mi h-1" : ConversionFactors.MPS_TO_MPH, + "ft s-1" : ConversionFactors.MPS_TO_FPS } -_WIND_TOBASE_FACTORS = {"kts" : 1.0/ConversionFactors.MPS_TO_KTS, - "kmph" : 1.0/ConversionFactors.MPS_TO_KMPH, - "mph" : 1.0/ConversionFactors.MPS_TO_MPH, - "fps" : 1.0/ConversionFactors.MPS_TO_FPS +_WIND_TOBASE_FACTORS = {"kt" : 1.0/ConversionFactors.MPS_TO_KTS, + "km h-1" : 1.0/ConversionFactors.MPS_TO_KMPH, + "mi h-1" : 1.0/ConversionFactors.MPS_TO_MPH, + "ft s-1" : 1.0/ConversionFactors.MPS_TO_FPS } _PRES_BASE_FACTORS = {"hpa" : ConversionFactors.PA_TO_HPA, @@ -85,19 +183,18 @@ _PRES_TOBASE_FACTORS = {"hpa" : 1.0/ConversionFactors.PA_TO_HPA, _HEIGHT_BASE_FACTORS = {"km" : ConversionFactors.M_TO_KM, "dm" : ConversionFactors.M_TO_DM, "ft" : ConversionFactors.M_TO_FT, - "miles" : ConversionFactors.M_TO_MILES + "mi" : ConversionFactors.M_TO_MILES } _HEIGHT_TOBASE_FACTORS = {"km" : 1.0/ConversionFactors.M_TO_KM, "dm" : 1.0/ConversionFactors.M_TO_DM, "ft" : 1.0/ConversionFactors.M_TO_FT, - "miles" : 1.0/ConversionFactors.M_TO_MILES - + "mi" : 1.0/ConversionFactors.M_TO_MILES } -_BASE_UNITS = {"wind" : "mps", +_BASE_UNITS = {"wind" : "m s-1", "pressure" : "pa", - "temp" : "c", + "temp" : "k", "height" : "m" } @@ -109,23 +206,29 @@ _CONV_FACTORS = {"wind" : {"to_dest" : _WIND_BASE_FACTORS, "to_base" : _HEIGHT_TOBASE_FACTORS} } -_TEMP_CONV_METHODS = {"k" : _c_to_k, - "f" : _c_to_f +_TEMP_CONV_METHODS = {"c" : _k_to_c, + "f" : _k_to_f } +def dealias_and_clean_unit(unit): + cleaned_unit = " ".join(unit.lower().split()) + dealiased = _UNIT_ALIASES.get(cleaned_unit, None) + + return cleaned_unit if dealiased is None else dealiased + def check_units(unit, unit_type): - unitl = unit.lower() - if unitl not in _VALID_UNITS[unit_type]: + u_cleaned = dealias_and_clean_unit(unit) + if u_cleaned not in _VALID_UNITS[unit_type]: raise ValueError("invalid unit type '%s'" % unit) def do_conversion(var, vartype, var_unit, dest_unit): + u_cleaned = dealias_and_clean_unit(dest_unit) if vartype != "temp": - return _apply_conv_fact(var, vartype, - var_unit.lower(), dest_unit.lower()) + return _apply_conv_fact(var, vartype, var_unit.lower(), u_cleaned) else: - return _apply_temp_conv(var, var_unit.lower(), dest_unit.lower()) + return _apply_temp_conv(var, var_unit.lower(), u_cleaned) diff --git a/src/wrf/uvmet.py b/src/wrf/uvmet.py index 362844b..0007e82 100755 --- a/src/wrf/uvmet.py +++ b/src/wrf/uvmet.py @@ -15,10 +15,10 @@ from .metadecorators import set_wind_metadata from .util import extract_vars, extract_global_attrs, either -@convert_units("wind", "mps") +@convert_units("wind", "m s-1") def _get_uvmet(wrfnc, timeidx=0, method="cat", squeeze=True, cache=None, meta=True, _key=None, - ten_m=False, units ="mps"): + ten_m=False, units ="m s-1"): """ Return a tuple of u,v with the winds rotated in to earth space""" if not ten_m: @@ -135,7 +135,7 @@ def _get_uvmet(wrfnc, timeidx=0, method="cat", squeeze=True, wspd_wdir=False) def get_uvmet(wrfnc, timeidx=0, method="cat", squeeze=True, cache=None, meta=True, _key=None, - units="mps"): + units="m s-1"): return _get_uvmet(wrfnc, timeidx, method, squeeze, cache, meta, _key, False, units) @@ -148,7 +148,7 @@ def get_uvmet(wrfnc, timeidx=0, method="cat", squeeze=True, wspd_wdir=False) def get_uvmet10(wrfnc, timeidx=0, method="cat", squeeze=True, cache=None, meta=True, _key=None, - units="mps"): + units="m s-1"): return _get_uvmet(wrfnc, timeidx, method, squeeze, cache, meta, _key, True, units) @@ -161,7 +161,7 @@ def get_uvmet10(wrfnc, timeidx=0, method="cat", squeeze=True, wspd_wdir=True) def get_uvmet_wspd_wdir(wrfnc, timeidx=0, method="cat", squeeze=True, cache=None, meta=True, _key=None, - units="mps"): + units="m s-1"): uvmet = _get_uvmet(wrfnc, timeidx, method, squeeze, cache, meta, _key, False, units) @@ -177,7 +177,7 @@ def get_uvmet_wspd_wdir(wrfnc, timeidx=0, method="cat", squeeze=True, wspd_wdir=True) def get_uvmet10_wspd_wdir(wrfnc, timeidx=0, method="cat", squeeze=True, cache=None, meta=True, _key=None, - units="mps"): + units="m s-1"): uvmet10 = _get_uvmet(wrfnc, timeidx, method, squeeze, cache, meta, _key, True, units) diff --git a/src/wrf/wind.py b/src/wrf/wind.py index 22de953..c5dd57f 100755 --- a/src/wrf/wind.py +++ b/src/wrf/wind.py @@ -10,8 +10,8 @@ from .decorators import convert_units from .metadecorators import set_wind_metadata -@convert_units("wind", "mps") -def _calc_wspd(u, v, units="mps"): +@convert_units("wind", "m s-1") +def _calc_wspd(u, v, units="m s-1"): return np.sqrt(u**2 + v**2) @@ -50,10 +50,10 @@ def _calc_wspd_wdir(u, v, two_d, units): wind_ncvar=True, two_d=False, wspd_wdir=False) -@convert_units("wind", "mps") +@convert_units("wind", "m s-1") def get_u_destag(wrfnc, timeidx=0, method="cat", squeeze=True, cache=None, meta=True, _key=None, - units="mps"): + units="m s-1"): varname = either("U", "UU")(wrfnc) u_vars = extract_vars(wrfnc, timeidx, varname, method, squeeze, cache, meta=False, _key=_key) @@ -68,10 +68,10 @@ def get_u_destag(wrfnc, timeidx=0, method="cat", squeeze=True, two_d=False, wind_ncvar=True, wspd_wdir=False) -@convert_units("wind", "mps") +@convert_units("wind", "m s-1") def get_v_destag(wrfnc, timeidx=0, method="cat", squeeze=True, cache=None, meta=True, _key=None, - units="mps"): + units="m s-1"): varname = either("V", "VV")(wrfnc) v_vars = extract_vars(wrfnc, timeidx, varname, method, squeeze, cache, meta=False, _key=_key) @@ -86,10 +86,10 @@ def get_v_destag(wrfnc, timeidx=0, method="cat", squeeze=True, two_d=False, wind_ncvar=True, wspd_wdir=False) -@convert_units("wind", "mps") +@convert_units("wind", "m s-1") def get_w_destag(wrfnc, timeidx=0, method="cat", squeeze=True, cache=None, meta=True, _key=None, - units="mps"): + units="m s-1"): w_vars = extract_vars(wrfnc, timeidx, "W", method, squeeze, cache, meta=False, _key=_key) w = destagger(w_vars["W"], -3) @@ -103,7 +103,7 @@ def get_w_destag(wrfnc, timeidx=0, method="cat", squeeze=True, wspd_wdir=True) def get_destag_wspd_wdir(wrfnc, timeidx=0, method="cat", squeeze=True, cache=None, meta=True, _key=None, - units="mps"): + units="m s-1"): varname = either("U", "UU")(wrfnc) u_vars = extract_vars(wrfnc, timeidx, varname, method, squeeze, cache, meta=False, _key=_key) @@ -124,7 +124,7 @@ def get_destag_wspd_wdir(wrfnc, timeidx=0, method="cat", wspd_wdir=True) def get_destag_wspd_wdir10(wrfnc, timeidx=0, method="cat", squeeze=True, cache=None, meta=True, _key=None, - units="mps"): + units="m s-1"): varname = either("U10", "UU")(wrfnc) u_vars = extract_vars(wrfnc, timeidx, varname, method, squeeze, cache, diff --git a/test/test_units.py b/test/test_units.py new file mode 100644 index 0000000..40c07eb --- /dev/null +++ b/test/test_units.py @@ -0,0 +1,56 @@ +import sys +import unittest as ut + +import numpy.testing as nt +import numpy as np +import numpy.ma as ma +from netCDF4 import Dataset as nc + +from wrf import getvar + +TEST_FILE = "/Users/ladwig/Documents/wrf_files/wrfout_d01_2010-06-13_21:00:00" + +# Python 3 +if sys.version_info > (3,): + xrange = range + + +class TestUnits(ut.TestCase): + longMessage = True + + def test_temp_units(self): + wrfnc = nc(TEST_FILE) + + for units in ("K", "degC", "degF"): + var = getvar(wrfnc, "temp", units=units) + + self.assertEqual(var.attrs["units"], units) + + def test_wind_units(self): + wrfnc = nc(TEST_FILE) + + for units in ("m s-1", "kt", "mi h-1", "km h-1", "ft s-1"): + var = getvar(wrfnc, "uvmet", units=units) + + self.assertEqual(var.attrs["units"], units) + + def test_pres_units(self): + wrfnc = nc(TEST_FILE) + + for units in ("Pa", "hPa", "mb", "torr", "mmHg", "atm"): + var = getvar(wrfnc, "slp", units=units) + + self.assertEqual(var.attrs["units"], units) + + def test_height_units(self): + wrfnc = nc(TEST_FILE) + + for units in ("m", "km", "dam", "ft", "mi"): + var = getvar(wrfnc, "z", units=units) + + self.assertEqual(var.attrs["units"], units) + + + +if __name__ == "__main__": + ut.main() \ No newline at end of file