Browse Source

Added new unit aliases to better match udunits, if we ever go down that route. Changed temperature to use Kelvin as base unit, so speed should improve. Added unit test for units to make sure they all run

main
Bill Ladwig 9 years ago
parent
commit
c2fa5405fb
  1. 17
      src/wrf/cape.py
  2. 12
      src/wrf/computation.py
  3. 2
      src/wrf/ctt.py
  4. 4
      src/wrf/dbz.py
  5. 5
      src/wrf/decorators.py
  6. 4
      src/wrf/dewpoint.py
  7. 4
      src/wrf/helicity.py
  8. 6
      src/wrf/metadecorators.py
  9. 2
      src/wrf/omega.py
  10. 4
      src/wrf/pressure.py
  11. 4
      src/wrf/rh.py
  12. 2
      src/wrf/slp.py
  13. 16
      src/wrf/temp.py
  14. 173
      src/wrf/units.py
  15. 12
      src/wrf/uvmet.py
  16. 20
      src/wrf/wind.py
  17. 56
      test/test_units.py

17
src/wrf/cape.py

@ -4,22 +4,12 @@ from __future__ import (absolute_import, division, print_function, @@ -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, @@ -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,

12
src/wrf/computation.py

@ -38,7 +38,7 @@ def interpz3d(field3d, z, desiredloc, missingval=Constants.DEFAULT_FILL, @@ -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): @@ -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 @@ -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): @@ -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): @@ -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)

2
src/wrf/ctt.py

@ -19,7 +19,7 @@ from .util import extract_vars @@ -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.
"""

4
src/wrf/dbz.py

@ -12,7 +12,7 @@ from .metadecorators import copy_and_set_metadata @@ -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", @@ -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,

5
src/wrf/decorators.py

@ -7,7 +7,7 @@ import wrapt @@ -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): @@ -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,

4
src/wrf/dewpoint.py

@ -12,7 +12,7 @@ from .util import extract_vars @@ -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, @@ -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)

4
src/wrf/helicity.py

@ -11,7 +11,7 @@ from .metadecorators import copy_and_set_metadata @@ -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, @@ -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):

6
src/wrf/metadecorators.py

@ -286,7 +286,7 @@ def set_cape_metadata(is2d): @@ -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, @@ -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"): @@ -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"

2
src/wrf/omega.py

@ -10,7 +10,7 @@ from .metadecorators import copy_and_set_metadata @@ -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")

4
src/wrf/pressure.py

@ -11,7 +11,7 @@ from .util import extract_vars, either @@ -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, @@ -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)

4
src/wrf/rh.py

@ -10,7 +10,7 @@ from .metadecorators import copy_and_set_metadata @@ -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, @@ -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")

2
src/wrf/slp.py

@ -17,7 +17,7 @@ from .util import extract_vars @@ -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)

16
src/wrf/temp.py

@ -13,7 +13,7 @@ from .util import extract_vars @@ -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, @@ -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, @@ -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, @@ -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, @@ -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, @@ -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")

173
src/wrf/units.py

@ -12,7 +12,7 @@ def _apply_conv_fact(var, vartype, var_unit, dest_unit): @@ -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): @@ -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, @@ -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, @@ -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)

12
src/wrf/uvmet.py

@ -15,10 +15,10 @@ from .metadecorators import set_wind_metadata @@ -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, @@ -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, @@ -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, @@ -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, @@ -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)

20
src/wrf/wind.py

@ -10,8 +10,8 @@ from .decorators import convert_units @@ -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): @@ -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, @@ -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, @@ -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, @@ -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", @@ -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,

56
test/test_units.py

@ -0,0 +1,56 @@ @@ -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()
Loading…
Cancel
Save