Bill Ladwig 6 years ago
parent
commit
9d35d87ae6
  1. 55
      src/wrf/api.py
  2. 139
      src/wrf/cache.py
  3. 2349
      src/wrf/computation.py
  4. 104
      src/wrf/config.py
  5. 43
      src/wrf/constants.py
  6. 243
      src/wrf/coordpair.py
  7. 456
      src/wrf/decorators.py
  8. 56
      src/wrf/destag.py
  9. 1263
      src/wrf/extension.py
  10. 809
      src/wrf/g_cape.py
  11. 688
      src/wrf/g_cloudfrac.py
  12. 149
      src/wrf/g_ctt.py
  13. 228
      src/wrf/g_dbz.py
  14. 191
      src/wrf/g_dewpoint.py
  15. 465
      src/wrf/g_geoht.py
  16. 223
      src/wrf/g_helicity.py
  17. 816
      src/wrf/g_latlon.py
  18. 87
      src/wrf/g_omega.py
  19. 12
      src/wrf/g_precip.py
  20. 183
      src/wrf/g_pressure.py
  21. 95
      src/wrf/g_pw.py
  22. 176
      src/wrf/g_rh.py
  23. 106
      src/wrf/g_slp.py
  24. 623
      src/wrf/g_temp.py
  25. 97
      src/wrf/g_terrain.py
  26. 161
      src/wrf/g_times.py
  27. 1007
      src/wrf/g_uvmet.py
  28. 179
      src/wrf/g_vorticity.py
  29. 989
      src/wrf/g_wind.py

55
src/wrf/api.py

@ -3,24 +3,24 @@ from .config import (xarray_enabled, disable_xarray, enable_xarray,
basemap_enabled, disable_basemap, enable_basemap, basemap_enabled, disable_basemap, enable_basemap,
pyngl_enabled, enable_pyngl, disable_pyngl, pyngl_enabled, enable_pyngl, disable_pyngl,
set_cache_size, get_cache_size, omp_enabled) set_cache_size, get_cache_size, omp_enabled)
from .constants import (ALL_TIMES, Constants, ConversionFactors, from .constants import (ALL_TIMES, Constants, ConversionFactors,
ProjectionTypes, default_fill, ProjectionTypes, default_fill,
OMP_SCHED_STATIC, OMP_SCHED_DYNAMIC, OMP_SCHED_STATIC, OMP_SCHED_DYNAMIC,
OMP_SCHED_GUIDED, OMP_SCHED_AUTO) OMP_SCHED_GUIDED, OMP_SCHED_AUTO)
from .destag import destagger from .destag import destagger
from .routines import getvar from .routines import getvar
from .computation import (xy, interp1d, interp2dxy, interpz3d, slp, tk, td, rh, from .computation import (xy, interp1d, interp2dxy, interpz3d, slp, tk, td, rh,
uvmet, smooth2d, cape_2d, cape_3d, cloudfrac, ctt, uvmet, smooth2d, cape_2d, cape_3d, cloudfrac, ctt,
dbz, srhel, udhel, avo, pvo, eth, wetbulb, tvirtual, dbz, srhel, udhel, avo, pvo, eth, wetbulb, tvirtual,
omega, pw) omega, pw)
from .extension import (DiagnosticError, omp_set_num_threads, from .extension import (DiagnosticError, omp_set_num_threads,
omp_get_num_threads, omp_get_num_threads,
omp_get_max_threads, omp_get_thread_num, omp_get_max_threads, omp_get_thread_num,
omp_get_num_procs, omp_in_parallel, omp_get_num_procs, omp_in_parallel,
omp_set_dynamic, omp_get_dynamic, omp_set_nested, omp_set_dynamic, omp_get_dynamic, omp_set_nested,
omp_get_nested, omp_set_schedule, omp_get_nested, omp_set_schedule,
omp_get_schedule, omp_get_thread_limit, omp_get_schedule, omp_get_thread_limit,
omp_set_max_active_levels, omp_set_max_active_levels,
omp_get_max_active_levels, omp_get_level, omp_get_max_active_levels, omp_get_level,
omp_get_ancestor_thread_num, omp_get_team_size, omp_get_ancestor_thread_num, omp_get_team_size,
omp_get_active_level, omp_in_final, omp_get_active_level, omp_in_final,
@ -32,23 +32,23 @@ from .extension import (DiagnosticError, omp_set_num_threads,
omp_get_wtime, omp_get_wtick) omp_get_wtime, omp_get_wtick)
from .interp import (interplevel, vertcross, interpline, vinterp) from .interp import (interplevel, vertcross, interpline, vinterp)
from .g_latlon import (xy_to_ll, ll_to_xy, xy_to_ll_proj, ll_to_xy_proj) from .g_latlon import (xy_to_ll, ll_to_xy, xy_to_ll_proj, ll_to_xy_proj)
from .py3compat import (viewitems, viewkeys, viewvalues, isstr, py2round, from .py3compat import (viewitems, viewkeys, viewvalues, isstr, py2round,
py3range, ucode) py3range, ucode)
from .util import (to_np, extract_global_attrs, is_standard_wrf_var, from .util import (to_np, extract_global_attrs, is_standard_wrf_var,
extract_dim, extract_vars, extract_times, combine_files, extract_dim, extract_vars, extract_times, combine_files,
extract_times, npbytes_to_str, is_moving_domain, extract_times, npbytes_to_str, is_moving_domain,
is_staggered, get_left_indexes, iter_left_indexes, is_staggered, get_left_indexes, iter_left_indexes,
get_right_slices, get_proj_params, from_args, get_right_slices, get_proj_params, from_args,
args_to_list, arg_location, psafilepath, get_id, args_to_list, arg_location, psafilepath, get_id,
from_var, combine_dims, either, get_iterable, from_var, combine_dims, either, get_iterable,
IterWrapper, is_coordvar, latlon_coordvars, is_mapping, IterWrapper, is_coordvar, latlon_coordvars, is_mapping,
has_time_coord, is_multi_file, is_multi_time_req, has_time_coord, is_multi_file, is_multi_time_req,
get_coord_pairs, is_time_coord_var, geo_bounds, get_coord_pairs, is_time_coord_var, geo_bounds,
get_cartopy, get_basemap, get_pyngl, cartopy_xlim, get_cartopy, get_basemap, get_pyngl, cartopy_xlim,
cartopy_ylim, latlon_coords, ll_points, pairs_to_latlon) cartopy_ylim, latlon_coords, ll_points, pairs_to_latlon)
from .geobnds import GeoBounds, NullGeoBounds from .geobnds import GeoBounds, NullGeoBounds
from .projection import (WrfProj, NullProjection, LambertConformal, Mercator, from .projection import (WrfProj, NullProjection, LambertConformal, Mercator,
PolarStereographic, LatLon, RotatedLatLon, PolarStereographic, LatLon, RotatedLatLon,
getproj) getproj)
from .coordpair import CoordPair from .coordpair import CoordPair
from .interputils import to_xy_coords from .interputils import to_xy_coords
@ -62,22 +62,22 @@ __all__ += ["xarray_enabled", "disable_xarray", "enable_xarray",
"pyngl_enabled", "enable_pyngl", "disable_pyngl", "pyngl_enabled", "enable_pyngl", "disable_pyngl",
"set_cache_size", "get_cache_size", "omp_enabled"] "set_cache_size", "get_cache_size", "omp_enabled"]
__all__ += ["ALL_TIMES", "Constants", "ConversionFactors", "ProjectionTypes", __all__ += ["ALL_TIMES", "Constants", "ConversionFactors", "ProjectionTypes",
"default_fill", "OMP_SCHED_STATIC", "OMP_SCHED_DYNAMIC", "default_fill", "OMP_SCHED_STATIC", "OMP_SCHED_DYNAMIC",
"OMP_SCHED_GUIDED", "OMP_SCHED_AUTO"] "OMP_SCHED_GUIDED", "OMP_SCHED_AUTO"]
__all__ += ["destagger"] __all__ += ["destagger"]
__all__ += ["getvar"] __all__ += ["getvar"]
__all__ += ["xy", "interp1d", "interp2dxy", "interpz3d", "slp", "tk", "td", __all__ += ["xy", "interp1d", "interp2dxy", "interpz3d", "slp", "tk", "td",
"rh", "uvmet", "smooth2d", "cape_2d", "cape_3d", "cloudfrac", "rh", "uvmet", "smooth2d", "cape_2d", "cape_3d", "cloudfrac",
"ctt", "dbz", "srhel", "udhel", "avo", "pvo", "eth", "wetbulb", "ctt", "dbz", "srhel", "udhel", "avo", "pvo", "eth", "wetbulb",
"tvirtual", "omega", "pw"] "tvirtual", "omega", "pw"]
__all__ += ["DiagnosticError", "omp_set_num_threads", __all__ += ["DiagnosticError", "omp_set_num_threads",
"omp_get_num_threads", "omp_get_num_threads",
"omp_get_max_threads", "omp_get_thread_num", "omp_get_max_threads", "omp_get_thread_num",
"omp_get_num_procs", "omp_in_parallel", "omp_get_num_procs", "omp_in_parallel",
"omp_set_dynamic", "omp_get_dynamic", "omp_set_nested", "omp_set_dynamic", "omp_get_dynamic", "omp_set_nested",
"omp_get_nested", "omp_set_schedule", "omp_get_nested", "omp_set_schedule",
"omp_get_schedule", "omp_get_thread_limit", "omp_get_schedule", "omp_get_thread_limit",
"omp_set_max_active_levels", "omp_set_max_active_levels",
"omp_get_max_active_levels", "omp_get_level", "omp_get_max_active_levels", "omp_get_level",
"omp_get_ancestor_thread_num", "omp_get_team_size", "omp_get_ancestor_thread_num", "omp_get_team_size",
"omp_get_active_level", "omp_in_final", "omp_get_active_level", "omp_in_final",
@ -89,18 +89,18 @@ __all__ += ["DiagnosticError", "omp_set_num_threads",
"omp_get_wtime", "omp_get_wtick"] "omp_get_wtime", "omp_get_wtick"]
__all__ += ["interplevel", "vertcross", "interpline", "vinterp"] __all__ += ["interplevel", "vertcross", "interpline", "vinterp"]
__all__ += ["xy_to_ll", "ll_to_xy", "xy_to_ll_proj", "ll_to_xy_proj"] __all__ += ["xy_to_ll", "ll_to_xy", "xy_to_ll_proj", "ll_to_xy_proj"]
__all__ += ["viewitems", "viewkeys", "viewvalues", "isstr", "py2round", __all__ += ["viewitems", "viewkeys", "viewvalues", "isstr", "py2round",
"py3range", "ucode"] "py3range", "ucode"]
__all__ += ["to_np", "extract_global_attrs", "is_standard_wrf_var", __all__ += ["to_np", "extract_global_attrs", "is_standard_wrf_var",
"extract_dim", "extract_vars", "extract_times", "combine_files", "extract_dim", "extract_vars", "extract_times", "combine_files",
"extract_times", "npbytes_to_str", "is_moving_domain", "extract_times", "npbytes_to_str", "is_moving_domain",
"is_staggered", "get_left_indexes", "iter_left_indexes", "is_staggered", "get_left_indexes", "iter_left_indexes",
"get_right_slices", "get_proj_params", "from_args", "get_right_slices", "get_proj_params", "from_args",
"args_to_list", "arg_location", "psafilepath", "get_id", "args_to_list", "arg_location", "psafilepath", "get_id",
"from_var", "combine_dims", "either", "get_iterable", "from_var", "combine_dims", "either", "get_iterable",
"IterWrapper", "is_coordvar", "latlon_coordvars", "is_mapping", "IterWrapper", "is_coordvar", "latlon_coordvars", "is_mapping",
"has_time_coord", "is_multi_file", "is_multi_time_req", "has_time_coord", "is_multi_file", "is_multi_time_req",
"get_coord_pairs", "is_time_coord_var", "geo_bounds", "get_coord_pairs", "is_time_coord_var", "geo_bounds",
"get_cartopy", "get_basemap", "get_pyngl", "cartopy_xlim", "get_cartopy", "get_basemap", "get_pyngl", "cartopy_xlim",
"cartopy_ylim", "latlon_coords", "ll_points", "pairs_to_latlon"] "cartopy_ylim", "latlon_coords", "ll_points", "pairs_to_latlon"]
__all__ += ["GeoBounds", "NullGeoBounds"] __all__ += ["GeoBounds", "NullGeoBounds"]
@ -110,4 +110,3 @@ __all__ += ["CoordPair"]
__all__ += ["to_xy_coords"] __all__ += ["to_xy_coords"]
__all__ += ["cache_item", "get_cached_item"] __all__ += ["cache_item", "get_cached_item"]
__all__ += ["__version__"] __all__ += ["__version__"]

139
src/wrf/cache.py

@ -11,158 +11,153 @@ _local_storage = local()
def _shrink_cache(): def _shrink_cache():
"""Shrink the cache if applicable. """Shrink the cache if applicable.
This only applies if a user has modified the cache size, otherwise it This only applies if a user has modified the cache size, otherwise it
just returns. just returns.
Returns: Returns:
None None
""" """
global _local_storage global _local_storage
try: try:
cache = _local_storage.cache cache = _local_storage.cache
except AttributeError: except AttributeError:
return return
diff = len(cache) - get_cache_size() diff = len(cache) - get_cache_size()
if diff > 0: if diff > 0:
for _ in py3range(diff): for _ in py3range(diff):
cache.popitem(last=False) cache.popitem(last=False)
def cache_item(key, product, value): def cache_item(key, product, value):
"""Store an item in the threadlocal cache. """Store an item in the threadlocal cache.
The cache should be viewed as two nested dictionaries. The outer key is The cache should be viewed as two nested dictionaries. The outer key is
usually the id for the sequence where the cached item was generated. The usually the id for the sequence where the cached item was generated. The
inner key is the product type. inner key is the product type.
Storing a cached item behaves like: Storing a cached item behaves like:
cache[key][product] = value cache[key][product] = value
The cache is thread local, so stored items are only available in The cache is thread local, so stored items are only available in
the thread that cached them. the thread that cached them.
Args: Args:
key (:obj:`int`): The outer dictionary cache key, which is typically key (:obj:`int`): The outer dictionary cache key, which is typically
the id of the sequence where the cached item was generated. the id of the sequence where the cached item was generated.
product (:obj:`str`): The inner dictionary cache key, which is a product (:obj:`str`): The inner dictionary cache key, which is a
string for the product type. string for the product type.
value (:obj:`object`): The object to store in the cache. value (:obj:`object`): The object to store in the cache.
Returns: Returns:
None. None.
See Also: See Also:
:meth:`get_cached_item` :meth:`get_cached_item`
""" """
global _local_storage global _local_storage
_shrink_cache() _shrink_cache()
if key is None or get_cache_size() == 0: if key is None or get_cache_size() == 0:
return return
try: try:
cache = _local_storage.cache cache = _local_storage.cache
except AttributeError: except AttributeError:
_local_storage.cache = OrderedDict() _local_storage.cache = OrderedDict()
cache = _local_storage.cache cache = _local_storage.cache
try: try:
_ = cache[key] _ = cache[key]
except KeyError: except KeyError:
if len(cache) >= get_cache_size(): if len(cache) >= get_cache_size():
cache.popitem(last=False) # Remove the oldest dataset cache.popitem(last=False) # Remove the oldest dataset
cache[key] = OrderedDict() cache[key] = OrderedDict()
cache[key][product] = value cache[key][product] = value
def get_cached_item(key, product): def get_cached_item(key, product):
"""Return an item from the threadlocal cache. """Return an item from the threadlocal cache.
The cache should be viewed as two nested dictionaries. The outer key is The cache should be viewed as two nested dictionaries. The outer key is
usually the id for the sequence where the cached item was generated. The usually the id for the sequence where the cached item was generated. The
inner key is the product type. inner key is the product type.
Retrieving a cached item behaves like: Retrieving a cached item behaves like:
value = cache[key][product] value = cache[key][product]
The cache is thread local, so stored items are only available in The cache is thread local, so stored items are only available in
the thread that cached them. the thread that cached them.
Args: Args:
key (:obj:`int`): The outer dictionary cache key, which is typically key (:obj:`int`): The outer dictionary cache key, which is typically
the id of the sequence where the cached item was generated. the id of the sequence where the cached item was generated.
product (:obj:`str`): The inner dictionary cache key, which is a product (:obj:`str`): The inner dictionary cache key, which is a
string for the product type. string for the product type.
Returns: Returns:
:obj:`object`: The cached object. :obj:`object`: The cached object.
See Also: See Also:
:meth:`cache_item` :meth:`cache_item`
""" """
global _local_storage global _local_storage
_shrink_cache() _shrink_cache()
if key is None or get_cache_size == 0: if key is None or get_cache_size == 0:
return None return None
cache = getattr(_local_storage, "cache", None) cache = getattr(_local_storage, "cache", None)
if cache is None: if cache is None:
return None return None
if len(cache) == 0: if len(cache) == 0:
return None return None
prod_dict = cache.get(key, None) prod_dict = cache.get(key, None)
if prod_dict is None: if prod_dict is None:
return None return None
result = prod_dict.get(product, None) result = prod_dict.get(product, None)
return result return result
def _get_cache(): def _get_cache():
"""Return the threadlocal cache. """Return the threadlocal cache.
This is primarily used for testing. This is primarily used for testing.
Returns: Returns:
:class:`threading.local` :class:`threading.local`
""" """
global _local_storage global _local_storage
_shrink_cache() _shrink_cache()
return getattr(_local_storage, "cache", None) return getattr(_local_storage, "cache", None)

2349
src/wrf/computation.py

File diff suppressed because it is too large Load Diff

104
src/wrf/config.py

@ -3,42 +3,43 @@ from __future__ import (absolute_import, division, print_function)
from threading import local from threading import local
import wrapt import wrapt
from ._wrffortran import (fomp_enabled, fomp_set_num_threads, from ._wrffortran import (fomp_enabled, fomp_set_num_threads,
fomp_set_schedule, fomp_set_dynamic, fomp_set_schedule, fomp_set_dynamic,
omp_constants) omp_constants)
_local_config = local() _local_config = local()
def _init_local(): def _init_local():
global _local_config global _local_config
_local_config.xarray_enabled = True _local_config.xarray_enabled = True
_local_config.cartopy_enabled = True _local_config.cartopy_enabled = True
_local_config.basemap_enabled = True _local_config.basemap_enabled = True
_local_config.pyngl_enabled = True _local_config.pyngl_enabled = True
_local_config.cache_size = 20 _local_config.cache_size = 20
_local_config.initialized = True _local_config.initialized = True
try: try:
from xarray import DataArray from xarray import DataArray
except ImportError: except ImportError:
_local_config.xarray_enabled = False _local_config.xarray_enabled = False
try: try:
from cartopy import crs from cartopy import crs
except ImportError: except ImportError:
_local_config.cartopy_enabled = False _local_config.cartopy_enabled = False
try: try:
from mpl_toolkits.basemap import Basemap from mpl_toolkits.basemap import Basemap
except ImportError: except ImportError:
_local_config.basemap_enabled = False _local_config.basemap_enabled = False
try: try:
from Ngl import Resources from Ngl import Resources
except ImportError: except ImportError:
_local_config.pyngl_enabled = False _local_config.pyngl_enabled = False
# Initialize the main thread's configuration # Initialize the main thread's configuration
_init_local() _init_local()
@ -55,21 +56,21 @@ def init_local():
_init_local() _init_local()
else: else:
if not init: if not init:
_init_local() _init_local()
return wrapped(*args, **kwargs) return wrapped(*args, **kwargs)
return func_wrapper return func_wrapper
@init_local() @init_local()
def xarray_enabled(): def xarray_enabled():
"""Return True if xarray is installed and enabled. """Return True if xarray is installed and enabled.
Returns: Returns:
:obj:`bool`: True if xarray is installed and enabled. :obj:`bool`: True if xarray is installed and enabled.
""" """
global _local_config global _local_config
return _local_config.xarray_enabled return _local_config.xarray_enabled
@ -80,23 +81,23 @@ def disable_xarray():
"""Disable xarray.""" """Disable xarray."""
global _local_config global _local_config
_local_config.xarray_enabled = False _local_config.xarray_enabled = False
@init_local() @init_local()
def enable_xarray(): def enable_xarray():
"""Enable xarray.""" """Enable xarray."""
global _local_config global _local_config
_local_config.xarray_enabled = True _local_config.xarray_enabled = True
@init_local() @init_local()
def cartopy_enabled(): def cartopy_enabled():
"""Return True if cartopy is installed and enabled. """Return True if cartopy is installed and enabled.
Returns: Returns:
:obj:`bool`: True if cartopy is installed and enabled. :obj:`bool`: True if cartopy is installed and enabled.
""" """
global _local_config global _local_config
return _local_config.cartopy_enabled return _local_config.cartopy_enabled
@ -107,23 +108,23 @@ def enable_cartopy():
"""Enable cartopy.""" """Enable cartopy."""
global _local_config global _local_config
_local_config.cartopy_enabled = True _local_config.cartopy_enabled = True
@init_local() @init_local()
def disable_cartopy(): def disable_cartopy():
"""Disable cartopy.""" """Disable cartopy."""
global _local_config global _local_config
_local_config.cartopy_enabled = True _local_config.cartopy_enabled = True
@init_local() @init_local()
def basemap_enabled(): def basemap_enabled():
"""Return True if basemap is installed and enabled. """Return True if basemap is installed and enabled.
Returns: Returns:
:obj:`bool`: True if basemap is installed and enabled. :obj:`bool`: True if basemap is installed and enabled.
""" """
global _local_config global _local_config
return _local_config.basemap_enabled return _local_config.basemap_enabled
@ -134,7 +135,7 @@ def enable_basemap():
"""Enable basemap.""" """Enable basemap."""
global _local_config global _local_config
_local_config.basemap_enabled = True _local_config.basemap_enabled = True
@init_local() @init_local()
def disable_basemap(): def disable_basemap():
@ -146,11 +147,11 @@ def disable_basemap():
@init_local() @init_local()
def pyngl_enabled(): def pyngl_enabled():
"""Return True if pyngl is installed and enabled. """Return True if pyngl is installed and enabled.
Returns: Returns:
:obj:`bool`: True if pyngl is installed and enabled. :obj:`bool`: True if pyngl is installed and enabled.
""" """
global _local_config global _local_config
return _local_config.pyngl_enabled return _local_config.pyngl_enabled
@ -161,63 +162,64 @@ def enable_pyngl():
"""Enable pyngl.""" """Enable pyngl."""
global _local_config global _local_config
_local_config.pyngl_enabled = True _local_config.pyngl_enabled = True
@init_local()
@init_local()
def disable_pyngl(): def disable_pyngl():
"""Disable pyngl.""" """Disable pyngl."""
global _local_config global _local_config
_local_config.pyngl_enabled = True _local_config.pyngl_enabled = True
@init_local()
@init_local()
def set_cache_size(size): def set_cache_size(size):
"""Set the maximum number of items that the threadlocal cache can retain. """Set the maximum number of items that the threadlocal cache can retain.
This cache is primarily used for coordinate variables. This cache is primarily used for coordinate variables.
Args: Args:
size (:obj:`int`): The number of items to retain in the cache. size (:obj:`int`): The number of items to retain in the cache.
Returns: Returns:
None None
""" """
global _local_config global _local_config
_local_config.cache_size = size _local_config.cache_size = size
@init_local()
@init_local()
def get_cache_size(): def get_cache_size():
"""Return the maximum number of items that the threadlocal cache can retain. """Return the maximum number of items that the threadlocal cache can
retain.
Returns: Returns:
:obj:`int`: The maximum number of items the cache can retain. :obj:`int`: The maximum number of items the cache can retain.
""" """
global _local_config global _local_config
return int(_local_config.cache_size) return int(_local_config.cache_size)
def omp_enabled(): def omp_enabled():
"""Return True if OpenMP is enabled. """Return True if OpenMP is enabled.
OpenMP is only enabled if compiled with OpenMP features. OpenMP is only enabled if compiled with OpenMP features.
Returns: Returns:
:obj:`bool`: True if OpenMP is enabled, otherwise False. :obj:`bool`: True if OpenMP is enabled, otherwise False.
""" """
return True if fomp_enabled() else False return True if fomp_enabled() else False
# Set OpenMP to use 1 thread, static scheduler, and no dynamic # Set OpenMP to use 1 thread, static scheduler, and no dynamic
# Note: Using the raw extension functions here to prevent possible # Note: Using the raw extension functions here to prevent possible
# circular import problems in the future. # circular import problems in the future.
fomp_set_num_threads(1) fomp_set_num_threads(1)
fomp_set_schedule(omp_constants.fomp_sched_static, 0) fomp_set_schedule(omp_constants.fomp_sched_static, 0)

43
src/wrf/constants.py

@ -10,10 +10,12 @@ from ._wrffortran import wrf_constants, omp_constants
#: Indicates that all times should be used in a diagnostic routine. #: Indicates that all times should be used in a diagnostic routine.
ALL_TIMES = None ALL_TIMES = None
class Constants(object): class Constants(object):
pass pass
for key,val in viewitems(wrf_constants.__dict__):
for key, val in viewitems(wrf_constants.__dict__):
setattr(Constants, key.upper(), np.asscalar(val)) setattr(Constants, key.upper(), np.asscalar(val))
OMP_SCHED_STATIC = omp_constants.fomp_sched_static OMP_SCHED_STATIC = omp_constants.fomp_sched_static
@ -35,7 +37,7 @@ class ConversionFactors(object):
M_TO_DM = 1.0/10.0 M_TO_DM = 1.0/10.0
M_TO_FT = 3.28084 M_TO_FT = 3.28084
M_TO_MILES = .000621371 M_TO_MILES = .000621371
class ProjectionTypes(object): class ProjectionTypes(object):
ZERO = 0 ZERO = 0
@ -44,21 +46,22 @@ class ProjectionTypes(object):
MERCATOR = 3 MERCATOR = 3
LAT_LON = 6 LAT_LON = 6
# Create the default fill mapping based on type.
# Create the default fill mapping based on type.
_DEFAULT_FILL_MAP = {None: Constants.DEFAULT_FILL, _DEFAULT_FILL_MAP = {None: Constants.DEFAULT_FILL,
np.dtype(np.bool_) : False, np.dtype(np.bool_): False,
np.dtype(np.intc) : Constants.DEFAULT_FILL_INT32, # Usually true np.dtype(np.intc): Constants.DEFAULT_FILL_INT32,
np.dtype(np.int8) : Constants.DEFAULT_FILL_INT8, np.dtype(np.int8): Constants.DEFAULT_FILL_INT8,
np.dtype(np.uint8) : 255, np.dtype(np.uint8): 255,
np.dtype(np.int16) : Constants.DEFAULT_FILL_INT16, np.dtype(np.int16): Constants.DEFAULT_FILL_INT16,
np.dtype(np.uint16) : 65535, np.dtype(np.uint16): 65535,
np.dtype(np.int32) : Constants.DEFAULT_FILL_INT32, np.dtype(np.int32): Constants.DEFAULT_FILL_INT32,
np.dtype(np.uint32) : 4294967295, np.dtype(np.uint32): 4294967295,
np.dtype(np.int64) : Constants.DEFAULT_FILL_INT64, np.dtype(np.int64): Constants.DEFAULT_FILL_INT64,
np.dtype(np.uint64) : 18446744073709551614, np.dtype(np.uint64): 18446744073709551614,
np.dtype(np.float_) : Constants.DEFAULT_FILL_DOUBLE, np.dtype(np.float_): Constants.DEFAULT_FILL_DOUBLE,
np.dtype(np.float32) : Constants.DEFAULT_FILL_FLOAT, np.dtype(np.float32): Constants.DEFAULT_FILL_FLOAT,
np.dtype(np.float64) : Constants.DEFAULT_FILL_DOUBLE np.dtype(np.float64): Constants.DEFAULT_FILL_DOUBLE
} }
if version_info >= (3, ): if version_info >= (3, ):
@ -76,9 +79,3 @@ else:
def default_fill(dtype=None): def default_fill(dtype=None):
dt = np.dtype(dtype) if dtype is not None else None dt = np.dtype(dtype) if dtype is not None else None
return _DEFAULT_FILL_MAP.get(dt, Constants.DEFAULT_FILL) return _DEFAULT_FILL_MAP.get(dt, Constants.DEFAULT_FILL)

243
src/wrf/coordpair.py

@ -1,265 +1,254 @@
from __future__ import (absolute_import, division, print_function) from __future__ import (absolute_import, division, print_function)
from .py3compat import py2round from .py3compat import py2round
def _binary_operator(operator): def _binary_operator(operator):
"""Function wrapper for binary operators. """Function wrapper for binary operators.
Args: Args:
operator (method): The operator to wrap. operator (method): The operator to wrap.
Returns: Returns:
method: An implementation for the *operator* type. method: An implementation for the *operator* type.
""" """
def func(self, other): def func(self, other):
"""Operator implementation. """Operator implementation.
Operator action is performed across the same class attributes when Operator action is performed across the same class attributes when
the *other* object is a :class:`CoordPair`. If the *other* object is the *other* object is a :class:`CoordPair`. If the *other* object is
a scalar value, the operator action is performed across all a scalar value, the operator action is performed across all
attributes with the scalar value. attributes with the scalar value.
Args: Args:
other (:class:`CoordPair` or scalar): A separate :class:`CoordPair` other (:class:`CoordPair` or scalar): A separate :class:`CoordPair`
object or scalar value. object or scalar value.
Returns: Returns:
:class:`CoordPair`: A new :class:`CoordPair` object that is the :class:`CoordPair`: A new :class:`CoordPair` object that is the
result of the operator action. result of the operator action.
""" """
if isinstance(other, CoordPair): if isinstance(other, CoordPair):
args = [ args = [None if getattr(self, attr) is None or
None if getattr(self, attr) is None or getattr(other, attr) is None getattr(other, attr) is None else
else getattr(getattr(self, attr), operator)(getattr(other, attr)) getattr(getattr(self, attr), operator)(getattr(other,
for attr in ("x", "y", "lat", "lon")] attr))
for attr in ("x", "y", "lat", "lon")]
else: else:
args = [ args = [None if getattr(self, attr) is None
None if getattr(self, attr) is None else getattr(getattr(self, attr), operator)(other)
else getattr(getattr(self, attr), operator)(other) for attr in ("x", "y", "lat", "lon")]
for attr in ("x", "y", "lat", "lon")]
return CoordPair(*args) return CoordPair(*args)
return func return func
def _unary_operator(operator): def _unary_operator(operator):
"""Function wrapper for unary operators. """Function wrapper for unary operators.
Args: Args:
operator (method): The operator to wrap. operator (method): The operator to wrap.
Returns: Returns:
method: An implementation for the *operator* type. method: An implementation for the *operator* type.
""" """
def func(self): def func(self):
"""Operator implementation. """Operator implementation.
Operator action is performed across all class attributes. Operator action is performed across all class attributes.
Returns: Returns:
:class:`CoordPair`: A new :class:`CoordPair` object that is the :class:`CoordPair`: A new :class:`CoordPair` object that is the
result of the operator action. result of the operator action.
""" """
args = [None if getattr(self, attr) is None args = [None if getattr(self, attr) is None
else getattr(getattr(self, attr), operator)() else getattr(getattr(self, attr), operator)()
for attr in ("x", "y", "lat", "lon")] for attr in ("x", "y", "lat", "lon")]
return CoordPair(*args) return CoordPair(*args)
return func return func
def _cmp_operator(operator): def _cmp_operator(operator):
"""Function wrapper for comparison operators. """Function wrapper for comparison operators.
Args: Args:
operator (method): The operator to wrap. operator (method): The operator to wrap.
Returns: Returns:
method: An implementation for the *operator* type. method: An implementation for the *operator* type.
""" """
def func(self, other): def func(self, other):
"""Operator implementation. """Operator implementation.
Performs a comparison operation across all of the same class Performs a comparison operation across all of the same class
attributes, and returns True if all these operations are True. attributes, and returns True if all these operations are True.
Returns: Returns:
:obj:`boot`: Returns True if all comparisons across class :obj:`boot`: Returns True if all comparisons across class
attributes returns True, otherwise False. attributes returns True, otherwise False.
""" """
vals = [getattr(getattr(self, attr), operator)(getattr(other, attr)) vals = [getattr(getattr(self, attr), operator)(getattr(other, attr))
for attr in ("x", "y", "lat", "lon") for attr in ("x", "y", "lat", "lon")
if getattr(self, attr) is not None] if getattr(self, attr) is not None]
return all(vals) return all(vals)
return func return func
class CoordPair(object): class CoordPair(object):
"""A class that stores (x, y) and/or (latitude, longitude) """A class that stores (x, y) and/or (latitude, longitude)
coordinate pairs. coordinate pairs.
Most math operators are supplied. When the other operand is a Most math operators are supplied. When the other operand is a
:class:`CoordPair`, the operation is performed with the same attribute. :class:`CoordPair`, the operation is performed with the same attribute.
When a math operation uses a scalar as the other operand, the When a math operation uses a scalar as the other operand, the
operation is applied across all attributes. operation is applied across all attributes.
Attributes: Attributes:
x (:obj:`float`): The x-coordinate. x (:obj:`float`): The x-coordinate.
y (:obj:`float`): The y-coordinate. y (:obj:`float`): The y-coordinate.
lat (:obj:`float`): The latitude coordinate. lat (:obj:`float`): The latitude coordinate.
lon (:obj:`float`): The longitude coordinate. lon (:obj:`float`): The longitude coordinate.
""" """
def __init__(self, x=None, y=None, lat=None, lon=None): def __init__(self, x=None, y=None, lat=None, lon=None):
"""Initialize a :class:`CoordPair` object. """Initialize a :class:`CoordPair` object.
Args: Args:
x (:obj:`float`, optional): The x-coordinate. x (:obj:`float`, optional): The x-coordinate.
y (:obj:`float`, optional): The y-coordinate. y (:obj:`float`, optional): The y-coordinate.
lat (:obj:`float`, optional): The latitude coordinate. lat (:obj:`float`, optional): The latitude coordinate.
lon (:obj:`float`, optional): The longitude coordinate. lon (:obj:`float`, optional): The longitude coordinate.
""" """
self.x = x self.x = x
self.y = y self.y = y
self.lat = lat self.lat = lat
self.lon = lon self.lon = lon
def __repr__(self): def __repr__(self):
args = [] args = []
if self.x is not None: if self.x is not None:
args.append("x={}".format(self.x)) args.append("x={}".format(self.x))
args.append("y={}".format(self.y)) args.append("y={}".format(self.y))
if self.lat is not None: if self.lat is not None:
args.append("lat={}".format(self.lat)) args.append("lat={}".format(self.lat))
args.append("lon={}".format(self.lon)) args.append("lon={}".format(self.lon))
argstr = ", ".join(args) argstr = ", ".join(args)
return "{}({})".format(self.__class__.__name__, argstr) return "{}({})".format(self.__class__.__name__, argstr)
def __str__(self): def __str__(self):
return self.__repr__() return self.__repr__()
def xy_str(self, fmt="{:.4f}, {:.4f}"): def xy_str(self, fmt="{:.4f}, {:.4f}"):
"""Return a :obj:`str` for the (x,y) coordinate pair. """Return a :obj:`str` for the (x,y) coordinate pair.
Args: Args:
fmt (:obj:`str`): The format string. Default is '{:.4f}, {:.4f}' fmt (:obj:`str`): The format string. Default is '{:.4f}, {:.4f}'
Returns: Returns:
:obj:`str`: A string for the (x,y) coordinate pair :obj:`str`: A string for the (x,y) coordinate pair
""" """
if self.x is None or self.y is None: if self.x is None or self.y is None:
return None return None
return fmt.format(self.x, self.y) return fmt.format(self.x, self.y)
def latlon_str(self, fmt="{:.4f}, {:.4f}"): def latlon_str(self, fmt="{:.4f}, {:.4f}"):
"""Return a :obj:`str` for the (latitude, longitude) coordinate pair. """Return a :obj:`str` for the (latitude, longitude) coordinate pair.
Args: Args:
fmt (:obj:`str`): The format string. Default is '{:.4f}, {:.4f}' fmt (:obj:`str`): The format string. Default is '{:.4f}, {:.4f}'
Returns: Returns:
:obj:`str`: A string for the (latitude, longitude) coordinate pair :obj:`str`: A string for the (latitude, longitude) coordinate pair
""" """
if self.lat is None or self.lon is None: if self.lat is None or self.lon is None:
return None return None
return fmt.format(self.lat, self.lon) return fmt.format(self.lat, self.lon)
def __round__(self, ndigits=None): def __round__(self, ndigits=None):
"""Return a new :class:`CoordPair` object with all coordinate values """Return a new :class:`CoordPair` object with all coordinate values
rounded to the nearest integer. rounded to the nearest integer.
Args: Args:
ndigits (:obj:`int`): The number of digits. ndigits (:obj:`int`): The number of digits.
Returns: Returns:
:class:`CoordPair`: A CoordPair object. :class:`CoordPair`: A CoordPair object.
""" """
args = [None if getattr(self, attr) is None args = [None if getattr(self, attr) is None
else py2round(getattr(self, attr), ndigits) else py2round(getattr(self, attr), ndigits)
for attr in ("x", "y", "lat", "lon")] for attr in ("x", "y", "lat", "lon")]
return CoordPair(*args) return CoordPair(*args)
def __pow__(self, other, modulo=None): def __pow__(self, other, modulo=None):
if isinstance(other, CoordPair): if isinstance(other, CoordPair):
args = [ args = [None if getattr(self, attr) is None or
None if getattr(self, attr) is None or getattr(other, attr) is None getattr(other, attr) is None
else getattr(getattr(self, attr), "__pow__")(getattr(other, attr), else getattr(getattr(self, attr), "__pow__")(
modulo) getattr(other, attr), modulo)
for attr in ("x", "y", "lat", "lon")] for attr in ("x", "y", "lat", "lon")]
else: else:
args = [ args = [None if getattr(self, attr) is None
None if getattr(self, attr) is None else getattr(getattr(self, attr), "__pow__")(other, modulo)
else getattr(getattr(self, attr), "__pow__")(other, modulo) for attr in ("x", "y", "lat", "lon")]
for attr in ("x", "y", "lat", "lon")]
return CoordPair(*args) return CoordPair(*args)
def __rpow__(self, other): def __rpow__(self, other):
return self.__pow__(other) return self.__pow__(other)
for operator in ("__add__", "__divmod__", "__floordiv__", "__mod__", for operator in ("__add__", "__divmod__", "__floordiv__", "__mod__",
"__mul__", "__sub__", "__truediv__", "__radd__", "__mul__", "__sub__", "__truediv__", "__radd__",
"__rdivmod__", "__rsub__", "__rmul__", "__rtruediv__", "__rdivmod__", "__rsub__", "__rmul__", "__rtruediv__",
"__rfloordiv__", "__rmod__"): "__rfloordiv__", "__rmod__"):
setattr(CoordPair, operator, _binary_operator(operator)) setattr(CoordPair, operator, _binary_operator(operator))
for operator in ("__neg__", "__pos__", "__abs__", "__invert__"): for operator in ("__neg__", "__pos__", "__abs__", "__invert__"):
setattr(CoordPair, operator, _unary_operator(operator)) setattr(CoordPair, operator, _unary_operator(operator))
for operator in ("__lt__", "__le__", "__eq__", "__ne__", "__gt__", "__ge__"): for operator in ("__lt__", "__le__", "__eq__", "__ne__", "__gt__", "__ge__"):
setattr(CoordPair, operator, _cmp_operator(operator)) setattr(CoordPair, operator, _cmp_operator(operator))

456
src/wrf/decorators.py

@ -2,7 +2,7 @@ from __future__ import (absolute_import, division, print_function)
from collections import Iterable, OrderedDict from collections import Iterable, OrderedDict
import wrapt import wrapt
import numpy as np import numpy as np
import numpy.ma as ma import numpy.ma as ma
@ -14,188 +14,177 @@ from .constants import default_fill
if xarray_enabled(): if xarray_enabled():
from xarray import DataArray from xarray import DataArray
def convert_units(unit_type, alg_unit): def convert_units(unit_type, alg_unit):
"""A decorator that converts the units from the wrapped function's output. """A decorator that converts the units from the wrapped function's output.
The desired units are determined from the wrapped function's arguments. The desired units are determined from the wrapped function's arguments.
Args: Args:
unit_type (:obj:`str`): The unit type. Choices are: 'wind', unit_type (:obj:`str`): The unit type. Choices are: 'wind',
'pressure', 'temp', or 'height'. 'pressure', 'temp', or 'height'.
alg_unit (:obj:`str`): The units returned by the wrapped function, alg_unit (:obj:`str`): The units returned by the wrapped function,
which is usually the units returned by the Fortran routine. which is usually the units returned by the Fortran routine.
Returns: Returns:
:class:`numpy.ndarray`: The wrapped function's output in the desired :class:`numpy.ndarray`: The wrapped function's output in the desired
units. units.
""" """
@wrapt.decorator @wrapt.decorator
def func_wrapper(wrapped, instance, args, kwargs): def func_wrapper(wrapped, instance, args, kwargs):
desired_units = from_args(wrapped, "units", *args, **kwargs)["units"] desired_units = from_args(wrapped, "units", *args, **kwargs)["units"]
u_cleaned = dealias_and_clean_unit(desired_units) u_cleaned = dealias_and_clean_unit(desired_units)
check_units(u_cleaned, unit_type) check_units(u_cleaned, unit_type)
# Unit conversion done here # Unit conversion done here
return do_conversion(wrapped(*args, **kwargs), unit_type, return do_conversion(wrapped(*args, **kwargs), unit_type,
alg_unit, desired_units) alg_unit, desired_units)
return func_wrapper
return func_wrapper
#def _calc_out_dims(outvar, left_dims):
# """
#
# """
# #left_dims = [x for x in left_dims]
# #right_dims = [x for x in outvar.shape]
# #return left_dims + right_dims
#
# return left_dims + outvar.shape
def left_iteration(ref_var_expected_dims, def left_iteration(ref_var_expected_dims,
ref_var_right_ndims, ref_var_right_ndims,
insert_dims=None, insert_dims=None,
ref_var_idx=None, ref_var_idx=None,
ref_var_name=None, ref_var_name=None,
ignore_args=None, ignore_args=None,
ignore_kargs=None, ignore_kargs=None,
outviews="outview", outviews="outview",
alg_dtype=np.float64, alg_dtype=np.float64,
cast_output=True): cast_output=True):
"""A decorator to handle iterating over the leftmost dimensions. """A decorator to handle iterating over the leftmost dimensions.
For example, if a wrapped function works with three-dimensional arrays, but For example, if a wrapped function works with three-dimensional arrays, but
the variables include a 4th leftmost dimension for 'Time', this decorator the variables include a 4th leftmost dimension for 'Time', this decorator
will iterate over all times, call the 3D Fortran routine, and aggregate the will iterate over all times, call the 3D Fortran routine, and aggregate the
results in to a 4D output array. results in to a 4D output array.
It is also important to note that the final output array is allocated It is also important to note that the final output array is allocated
first, and then views are passed to the wrapped function so that values first, and then views are passed to the wrapped function so that values
do not need to get copied in to the final output array. do not need to get copied in to the final output array.
Args: Args:
ref_var_expected_dims (:obj:`int`): The number of dimensions that the ref_var_expected_dims (:obj:`int`): The number of dimensions that the
Fortran routine is expecting for the reference variable. Fortran routine is expecting for the reference variable.
ref_var_right_ndims (:obj:`int`): The number of dimensions from the ref_var_right_ndims (:obj:`int`): The number of dimensions from the
right to keep for the reference variable when making the output. right to keep for the reference variable when making the output.
Can also be a :class:`combine_dims` object if the sizes are Can also be a :class:`combine_dims` object if the sizes are
determined from multiple variables. determined from multiple variables.
insert_dims (sequence of :obj:`int`, optional): A sequence of insert_dims (sequence of :obj:`int`, optional): A sequence of
dimensions to insert between the left dimensions (e.g. time) and dimensions to insert between the left dimensions (e.g. time) and
the kept right dimensions. Default is None. the kept right dimensions. Default is None.
ref_var_idx (:obj:`int`, optional): The index in the wrapped function's ref_var_idx (:obj:`int`, optional): The index in the wrapped function's
positional arguments to be used as the reference variable for positional arguments to be used as the reference variable for
determining the leftmost dimensions. Must be specified if determining the leftmost dimensions. Must be specified if
*ref_var_name* is None. Default is None. *ref_var_name* is None. Default is None.
ref_var_name (:obj:`str`, optional): The keyword argument name for the ref_var_name (:obj:`str`, optional): The keyword argument name for the
wrapped function's keyword arguments to be used as the reference wrapped function's keyword arguments to be used as the reference
variable for calculating the leftmost dimensions. Must be variable for calculating the leftmost dimensions. Must be
specified if *ref_var_idx* is None. Default is None. specified if *ref_var_idx* is None. Default is None.
ignore_args (sequence of :obj:`int`): Indexes of any arguments that ignore_args (sequence of :obj:`int`): Indexes of any arguments that
should be ignored when creating the sliced views that are should be ignored when creating the sliced views that are
passed to the Fortran routine. passed to the Fortran routine.
ignore_kargs (sequence of :obj:`str`): Keys of any keyword arguments ignore_kargs (sequence of :obj:`str`): Keys of any keyword arguments
that should be ignored when creating the sliced views that are that should be ignored when creating the sliced views that are
passed to the Fortran routine. passed to the Fortran routine.
outviews (:obj:`str` or a sequence): A single key or sequence of keys outviews (:obj:`str` or a sequence): A single key or sequence of keys
that indicate the wrapped function's keyword argument to use that indicate the wrapped function's keyword argument to use
as the output variable(s) in the wrapped function. as the output variable(s) in the wrapped function.
alg_dtype (:class:`numpy.dtype` or :obj:`str`): The numpy data type alg_dtype (:class:`numpy.dtype` or :obj:`str`): The numpy data type
used in the wrapped function. used in the wrapped function.
cast_output (:obj:`bool`): Set to True to cast the wrapped function's cast_output (:obj:`bool`): Set to True to cast the wrapped function's
output to the same type as the reference variable. output to the same type as the reference variable.
Returns: Returns:
:class:`numpy.ndarray`: The aggregated output array that includes :class:`numpy.ndarray`: The aggregated output array that includes
all extra leftmost dimensions found in the reference variable. all extra leftmost dimensions found in the reference variable.
""" """
@wrapt.decorator @wrapt.decorator
def func_wrapper(wrapped, instance, args, kwargs): def func_wrapper(wrapped, instance, args, kwargs):
_ignore_args = ignore_args if ignore_args is not None else () _ignore_args = ignore_args if ignore_args is not None else ()
_ignore_kargs = ignore_kargs if ignore_kargs is not None else () _ignore_kargs = ignore_kargs if ignore_kargs is not None else ()
_outkeys = [outviews] if isstr(outviews) else outviews _outkeys = [outviews] if isstr(outviews) else outviews
if ref_var_idx is not None: if ref_var_idx is not None:
ref_var = args[ref_var_idx] ref_var = args[ref_var_idx]
else: else:
ref_var = kwargs[ref_var_name] ref_var = kwargs[ref_var_name]
ref_var_dtype = ref_var.dtype ref_var_dtype = ref_var.dtype
ref_var_shape = ref_var.shape ref_var_shape = ref_var.shape
extra_dim_num = ref_var.ndim - ref_var_expected_dims extra_dim_num = ref_var.ndim - ref_var_expected_dims
# No special left side iteration, return the function result # No special left side iteration, return the function result
if (extra_dim_num == 0): if (extra_dim_num == 0):
return wrapped(*args, **kwargs) return wrapped(*args, **kwargs)
# Start by getting the left-most 'extra' dims # Start by getting the left-most 'extra' dims
extra_dims = ref_var_shape[0:extra_dim_num] extra_dims = ref_var_shape[0:extra_dim_num]
mid_dims = () if insert_dims is None else tuple(insert_dims) mid_dims = () if insert_dims is None else tuple(insert_dims)
if not isinstance(ref_var_right_ndims, combine_dims): if not isinstance(ref_var_right_ndims, combine_dims):
right_dims = ref_var_shape[-ref_var_right_ndims:] right_dims = ref_var_shape[-ref_var_right_ndims:]
else: else:
right_dims = ref_var_right_ndims(*args) right_dims = ref_var_right_ndims(*args)
left_dims = extra_dims left_dims = extra_dims
outdims = left_dims + mid_dims + right_dims outdims = left_dims + mid_dims + right_dims
if "outview" not in kwargs: if "outview" not in kwargs:
outd = OrderedDict((outkey, np.empty(outdims, alg_dtype)) outd = OrderedDict((outkey, np.empty(outdims, alg_dtype))
for outkey in _outkeys) for outkey in _outkeys)
mask_output = False mask_output = False
for left_idxs in iter_left_indexes(extra_dims): for left_idxs in iter_left_indexes(extra_dims):
# Make the left indexes plus a single slice object # Make the left indexes plus a single slice object
# The single slice will handle all the dimensions to # The single slice will handle all the dimensions to
# the right (e.g. [1,1,:]) # the right (e.g. [1,1,:])
left_and_slice_idxs = left_idxs + (slice(None), ) left_and_slice_idxs = left_idxs + (slice(None), )
# Slice the args if applicable # Slice the args if applicable
new_args = [arg[left_and_slice_idxs] new_args = [arg[left_and_slice_idxs]
if i not in _ignore_args else arg if i not in _ignore_args else arg
for i,arg in enumerate(args)] for i, arg in enumerate(args)]
# Slice the kwargs if applicable # Slice the kwargs if applicable
new_kargs = {key:(val[left_and_slice_idxs] new_kargs = {key: (val[left_and_slice_idxs]
if key not in _ignore_kargs else val) if key not in _ignore_kargs else val)
for key,val in viewitems(kwargs)} for key, val in viewitems(kwargs)}
# Skip the possible empty/missing arrays for the join method # Skip the possible empty/missing arrays for the join method
skip_missing = False skip_missing = False
for arg in new_args: for arg in new_args:
try: try:
_ = arg.ndim _ = arg.ndim
except AttributeError: except AttributeError:
continue # Not an array object continue # Not an array object
else: else:
arr = to_np(arg) arr = to_np(arg)
try: try:
all_masked = arr.mask.all() all_masked = arr.mask.all()
except AttributeError: except AttributeError:
pass # Not a masked array pass # Not a masked array
else: else:
if all_masked: if all_masked:
for output in viewvalues(outd): for output in viewvalues(outd):
@ -204,261 +193,257 @@ def left_iteration(ref_var_expected_dims,
skip_missing = True skip_missing = True
mask_output = True mask_output = True
break break
if skip_missing: if skip_missing:
continue continue
# Insert the output views if one hasn't been provided # Insert the output views if one hasn't been provided
if "outview" not in new_kargs: if "outview" not in new_kargs:
for outkey,output in viewitems(outd): for outkey, output in viewitems(outd):
outview = output[left_and_slice_idxs] outview = output[left_and_slice_idxs]
new_kargs[outkey] = outview new_kargs[outkey] = outview
result = wrapped(*new_args, **new_kargs) result = wrapped(*new_args, **new_kargs)
# Make sure the result is the same data as what got passed in # Make sure the result is the same data as what got passed in
# Can delete this once everything works # Can delete this once everything works
if (result.__array_interface__["data"][0] != if (result.__array_interface__["data"][0] !=
outview.__array_interface__["data"][0]): outview.__array_interface__["data"][0]):
raise RuntimeError("output array was copied") raise RuntimeError("output array was copied")
if len(outd) == 1: if len(outd) == 1:
output = next(iter(viewvalues(outd))) output = next(iter(viewvalues(outd)))
else: else:
output = tuple(arr for arr in viewvalues(outd)) output = tuple(arr for arr in viewvalues(outd))
if cast_output: if cast_output:
if isinstance(output, np.ndarray): if isinstance(output, np.ndarray):
output = output.astype(ref_var_dtype) output = output.astype(ref_var_dtype)
else: else:
output = tuple(arr.astype(ref_var_dtype) for arr in output) output = tuple(arr.astype(ref_var_dtype) for arr in output)
# Mostly when used with join # Mostly when used with join
if mask_output: if mask_output:
if isinstance(output, np.ndarray): if isinstance(output, np.ndarray):
output = ma.masked_values(output, default_fill(np.float64)) output = ma.masked_values(output, default_fill(np.float64))
else: else:
output = tuple(ma.masked_values(arr, default_fill(np.float64)) output = tuple(ma.masked_values(arr, default_fill(np.float64))
for arr in output) for arr in output)
return output return output
return func_wrapper return func_wrapper
def cast_type(ref_idx=0, arg_idxs=None, karg_names=None, def cast_type(ref_idx=0, arg_idxs=None, karg_names=None,
alg_dtype=np.float64, outviews="outview"): alg_dtype=np.float64, outviews="outview"):
"""A decorator to handle type casting. """A decorator to handle type casting.
This decorator is used to cast variables to and from the required This decorator is used to cast variables to and from the required
:class:`numpy.dtype` used in the wrapped function. :class:`numpy.dtype` used in the wrapped function.
Args: Args:
ref_idx (:obj:`int`, optional): The index in the wrapped function's ref_idx (:obj:`int`, optional): The index in the wrapped function's
positional arguments to be used as the reference variable for positional arguments to be used as the reference variable for
determining the :class:`numpy.dtype` to return. Default is 0. determining the :class:`numpy.dtype` to return. Default is 0.
arg_idxs (sequence of :obj:`int`, optional): A sequence of indexes in the arg_idxs (sequence of :obj:`int`, optional): A sequence of indexes in
wrapped function's positional arguments that indicate which the wrapped function's positional arguments that indicate which
arguments to cast. Must be specified if *karg_names* is None. arguments to cast. Must be specified if *karg_names* is None.
Default is None. Default is None.
karg_names (sequence of :obj:`str`): A sequence of keyword arguments karg_names (sequence of :obj:`str`): A sequence of keyword arguments
in the wrapped function's keyword arguments that indicate the in the wrapped function's keyword arguments that indicate the
arguments to cast. Must be specified if *arg_idxs* is None. arguments to cast. Must be specified if *arg_idxs* is None.
Default is None. Default is None.
alg_dtype (:class:`numpy.dtype` or :obj:`str`): The numpy data type used alg_dtype (:class:`numpy.dtype` or :obj:`str`): The numpy data type
in the wrapped function. used in the wrapped function.
outviews (:obj:`str` or a sequence): A single key or sequence of keys outviews (:obj:`str` or a sequence): A single key or sequence of keys
that indicate the wrapped function's keyword argument to use that indicate the wrapped function's keyword argument to use
as the output variable(s) in the wrapped function. as the output variable(s) in the wrapped function.
Returns: Returns:
:class:`numpy.ndarray`: The wrapped function's output cast to the :class:`numpy.ndarray`: The wrapped function's output cast to the
same :class:`numpy.dtype` as the reference variable. same :class:`numpy.dtype` as the reference variable.
""" """
@wrapt.decorator @wrapt.decorator
def func_wrapper(wrapped, instance, args, kwargs): def func_wrapper(wrapped, instance, args, kwargs):
_arg_idxs = arg_idxs if arg_idxs is not None else () _arg_idxs = arg_idxs if arg_idxs is not None else ()
_karg_names = karg_names if karg_names is not None else () _karg_names = karg_names if karg_names is not None else ()
# Handle output views if applicable # Handle output views if applicable
_outkeys = [outviews] if isstr(outviews) else outviews _outkeys = [outviews] if isstr(outviews) else outviews
_outviews = from_args(wrapped, _outkeys, *args, **kwargs) _outviews = from_args(wrapped, _outkeys, *args, **kwargs)
has_outview = False has_outview = False
for outkey in _outkeys: for outkey in _outkeys:
_outview = _outviews[outkey] _outview = _outviews[outkey]
if _outview is not None: if _outview is not None:
has_outview = True has_outview = True
orig_type = args[ref_idx].dtype orig_type = args[ref_idx].dtype
new_args = [arg.astype(alg_dtype) new_args = [arg.astype(alg_dtype)
if i in _arg_idxs else arg if i in _arg_idxs else arg
for i,arg in enumerate(args)] for i, arg in enumerate(args)]
new_kargs = {key:(val.astype(alg_dtype) new_kargs = {key: (val.astype(alg_dtype)
if key in _karg_names else val) if key in _karg_names else val)
for key,val in viewitems(kwargs)} for key, val in viewitems(kwargs)}
result = wrapped(*new_args, **new_kargs) result = wrapped(*new_args, **new_kargs)
# Do nothing for supplied output views # Do nothing for supplied output views
if not has_outview: if not has_outview:
if isinstance(result, np.ndarray): if isinstance(result, np.ndarray):
if result.dtype == orig_type: if result.dtype == orig_type:
return result return result
return result.astype(orig_type) return result.astype(orig_type)
elif isinstance(result, Iterable): # got back a sequence of arrays elif isinstance(result, Iterable): # got back a sequence of arrays
return tuple(arr.astype(orig_type) return tuple(arr.astype(orig_type)
if arr.dtype != orig_type else arr if arr.dtype != orig_type else arr
for arr in result) for arr in result)
return result return result
return func_wrapper return func_wrapper
def _extract_and_transpose(arg, do_transpose): def _extract_and_transpose(arg, do_transpose):
"""Return a transposed view of the :class:`numpy.ndarray` inside of a """Return a transposed view of the :class:`numpy.ndarray` inside of a
:class:`xarray.DataArray` object. :class:`xarray.DataArray` object.
If the *arg* parameter is not a :class:`xarray.DataArray` object, then If the *arg* parameter is not a :class:`xarray.DataArray` object, then
*arg* is returned. *arg* is returned.
Args: Args:
arg (:class:`xarray.DataArray` or :obj:`object`): Can be any object arg (:class:`xarray.DataArray` or :obj:`object`): Can be any object
type. type.
do_transpose: Set to False to only extract the variable. When True, do_transpose: Set to False to only extract the variable. When True,
the extracted array will also be transposed to a Fortran view if the extracted array will also be transposed to a Fortran view if
it is not already Fortran contiguous. it is not already Fortran contiguous.
Returns: Returns:
:class:`numpy.ndarray`: A numpy array. If *do_transpose* is True, :class:`numpy.ndarray`: A numpy array. If *do_transpose* is True,
the numpy array will also be a Fortran contiguous view. the numpy array will also be a Fortran contiguous view.
""" """
if xarray_enabled(): if xarray_enabled():
if isinstance(arg, DataArray): if isinstance(arg, DataArray):
arg = to_np(arg) arg = to_np(arg)
if do_transpose: if do_transpose:
if isinstance(arg, np.ndarray): if isinstance(arg, np.ndarray):
if not arg.flags.f_contiguous and arg.ndim > 1: if not arg.flags.f_contiguous and arg.ndim > 1:
return arg.T return arg.T
return arg return arg
def extract_and_transpose(do_transpose=True, outviews="outview"): def extract_and_transpose(do_transpose=True, outviews="outview"):
"""A decorator to extract the data array from a :class:`xarray.DataArray` """A decorator to extract the data array from a :class:`xarray.DataArray`
This decorator also transposes the view of the data to Fortran This decorator also transposes the view of the data to Fortran
contiguous if *do_transpose* is True. contiguous if *do_transpose* is True.
Args: Args:
do_transpose: Set to False to only extract the variable. When True, do_transpose: Set to False to only extract the variable. When True,
the extracted array will also be transposed to a Fortran view if the extracted array will also be transposed to a Fortran view if
it is not already Fortran contiguous. it is not already Fortran contiguous.
outviews (:obj:`str` or a sequence): A single key or sequence of keys outviews (:obj:`str` or a sequence): A single key or sequence of keys
that indicate the wrapped function's keyword argument to use that indicate the wrapped function's keyword argument to use
as the output variable(s) in the wrapped function. as the output variable(s) in the wrapped function.
Returns: Returns:
:class:`numpy.ndarray`: A numpy array. If *do_transpose* is True, :class:`numpy.ndarray`: A numpy array. If *do_transpose* is True,
the numpy array will also be a Fortran contiguous view. the numpy array will also be a Fortran contiguous view.
""" """
@wrapt.decorator @wrapt.decorator
def func_wrapper(wrapped, instance, args, kwargs): def func_wrapper(wrapped, instance, args, kwargs):
# Handle output views if applicable # Handle output views if applicable
_outkeys = [outviews] if isstr(outviews) else outviews _outkeys = [outviews] if isstr(outviews) else outviews
_outviews = from_args(wrapped, _outkeys, *args, **kwargs) _outviews = from_args(wrapped, _outkeys, *args, **kwargs)
has_outview = False has_outview = False
for outkey in _outkeys: for outkey in _outkeys:
_outview = _outviews[outkey] _outview = _outviews[outkey]
if _outview is not None: if _outview is not None:
has_outview = True has_outview = True
new_args = [_extract_and_transpose(arg, do_transpose) for arg in args] new_args = [_extract_and_transpose(arg, do_transpose) for arg in args]
new_kargs = {key:_extract_and_transpose(val, do_transpose) new_kargs = {key: _extract_and_transpose(val, do_transpose)
for key,val in viewitems(kwargs)} for key, val in viewitems(kwargs)}
result = wrapped(*new_args, **new_kargs) result = wrapped(*new_args, **new_kargs)
# Do nothing for supplied output views # Do nothing for supplied output views
if has_outview: if has_outview:
return result return result
if isinstance(result, np.ndarray): if isinstance(result, np.ndarray):
if result.flags.f_contiguous and result.ndim > 1: if result.flags.f_contiguous and result.ndim > 1:
return result.T return result.T
elif isinstance(result, Iterable): elif isinstance(result, Iterable):
return tuple(x.T if x.flags.f_contiguous and x.ndim > 1 else x return tuple(x.T if x.flags.f_contiguous and x.ndim > 1 else x
for x in result) for x in result)
return result return result
return func_wrapper return func_wrapper
def check_args(refvaridx, refvarndim, rightdims, stagger=None, def check_args(refvaridx, refvarndim, rightdims, stagger=None,
refstagdim=None): refstagdim=None):
"""A decorator to check that the wrapped function's arguments are valid. """A decorator to check that the wrapped function's arguments are valid.
An exception is raised when an invalid argument is found. An exception is raised when an invalid argument is found.
Args: Args:
refvaridx (:obj:`int`): The wrapped function's positional argument refvaridx (:obj:`int`): The wrapped function's positional argument
index to use as the reference variable. index to use as the reference variable.
refvarndim (:obj:`int`): The number of dimensions for the reference refvarndim (:obj:`int`): The number of dimensions for the reference
variable that is expected by the wrapped function. variable that is expected by the wrapped function.
rightdims (sequence of :obj:`int`): The expected number of right rightdims (sequence of :obj:`int`): The expected number of right
dimensions for each argument. dimensions for each argument.
stagger (sequence of :obj:`int` or :obj:`None`, optional): The stagger (sequence of :obj:`int` or :obj:`None`, optional): The
dimension that is staggered for each argument in the wrapped dimension that is staggered for each argument in the wrapped
function. Use :obj:`None` in the sequence to indicate no function. Use :obj:`None` in the sequence to indicate no
staggering for that argument. Default is None. staggering for that argument. Default is None.
refstagdim (:obj:`int`, optional): The staggered dimension for the refstagdim (:obj:`int`, optional): The staggered dimension for the
reference variable, if applicable. Default is None. reference variable, if applicable. Default is None.
Returns: Returns:
None None
Raises: Raises:
:class:`ValueError`: Raised when an invalid argument is detected. :class:`ValueError`: Raised when an invalid argument is detected.
""" """
@wrapt.decorator @wrapt.decorator
def func_wrapper(wrapped, instance, args, kwargs): def func_wrapper(wrapped, instance, args, kwargs):
refvar = args[refvaridx] refvar = args[refvaridx]
try: try:
_ndim = refvar.ndim _ndim = refvar.ndim
@ -467,7 +452,7 @@ def check_args(refvaridx, refvarndim, rightdims, stagger=None,
"object".format(refvaridx)) "object".format(refvaridx))
else: else:
extra_dims = refvar.ndim - refvarndim extra_dims = refvar.ndim - refvarndim
# Always use unstaggered as the basis of comparison # Always use unstaggered as the basis of comparison
if refstagdim is not None: if refstagdim is not None:
_refshape = list(refvar.shape) _refshape = list(refvar.shape)
@ -475,33 +460,34 @@ def check_args(refvaridx, refvarndim, rightdims, stagger=None,
_refshape = tuple(_refshape) _refshape = tuple(_refshape)
else: else:
_refshape = refvar.shape _refshape = refvar.shape
if stagger is None: if stagger is None:
_stagger = [None]*len(rightdims) _stagger = [None]*len(rightdims)
else: else:
_stagger = stagger _stagger = stagger
for i,ndim in enumerate(rightdims): for i, ndim in enumerate(rightdims):
if ndim is None: if ndim is None:
continue continue
var = args[i] var = args[i]
try: try:
_ = var.ndim _ = var.ndim
except AttributeError: except AttributeError:
raise ValueError("argument {} is not an arraylike " raise ValueError("argument {} is not an arraylike "
"object".format(i)) "object".format(i))
right_var_ndims = rightdims[i] right_var_ndims = rightdims[i]
# Check that the number of dims is correct # Check that the number of dims is correct
if (var.ndim - extra_dims != right_var_ndims): if (var.ndim - extra_dims != right_var_ndims):
raise ValueError("invalid number of dimensions for argument " raise ValueError("invalid number of dimensions for argument "
"{} (got {}, expected {}).".format(i, "{} (got {}, expected {}).".format(
var.ndim, i,
right_var_ndims + extra_dims)) var.ndim,
right_var_ndims + extra_dims))
# Add 1 to the reference staggered dim index before doing the check # Add 1 to the reference staggered dim index before doing the check
if _stagger[i] is not None: if _stagger[i] is not None:
ref_shape = list(_refshape) ref_shape = list(_refshape)
@ -509,27 +495,19 @@ def check_args(refvaridx, refvarndim, rightdims, stagger=None,
ref_shape = tuple(ref_shape) ref_shape = tuple(ref_shape)
else: else:
ref_shape = _refshape ref_shape = _refshape
ref_right_sizes = ref_shape[extra_dims:]
# Check that right dimensions are lined up
if (var.shape[-right_var_ndims:] !=
ref_right_sizes[-right_var_ndims:]):
raise ValueError("invalid shape for argument "
"{} (got {}, expected {})".format(i,
var.shape[-right_var_ndims:],
ref_right_sizes[-right_var_ndims:]))
return wrapped(*args, **kwargs)
return func_wrapper
ref_right_sizes = ref_shape[extra_dims:]
# Check that right dimensions are lined up
if (var.shape[-right_var_ndims:] !=
ref_right_sizes[-right_var_ndims:]):
raise ValueError("invalid shape for argument "
"{} (got {}, expected {})".format(
i,
var.shape[-right_var_ndims:],
ref_right_sizes[-right_var_ndims:]))
return wrapped(*args, **kwargs)
return func_wrapper

56
src/wrf/destag.py

@ -8,57 +8,55 @@ from .metadecorators import set_destag_metadata
@extract_and_transpose(do_transpose=False) @extract_and_transpose(do_transpose=False)
def destagger(var, stagger_dim, meta=False): def destagger(var, stagger_dim, meta=False):
"""Return the variable on the unstaggered grid. """Return the variable on the unstaggered grid.
This function destaggers the variable by taking the average of the This function destaggers the variable by taking the average of the
values located on either side of the grid box. values located on either side of the grid box.
Args: Args:
var (:class:`xarray.DataArray` or :class:`numpy.ndarray`): A variable var (:class:`xarray.DataArray` or :class:`numpy.ndarray`): A variable
on a staggered grid. on a staggered grid.
stagger_dim (:obj:`int`): The dimension index to destagger. stagger_dim (:obj:`int`): The dimension index to destagger.
Negative values can be used to choose dimensions referenced Negative values can be used to choose dimensions referenced
from the right hand side (-1 is the rightmost dimension). from the right hand side (-1 is the rightmost dimension).
meta (:obj:`bool`, optional): Set to False to disable metadata and meta (:obj:`bool`, optional): Set to False to disable metadata and
return :class:`numpy.ndarray` instead of return :class:`numpy.ndarray` instead of
:class:`xarray.DataArray`. Default is False. :class:`xarray.DataArray`. Default is False.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: :class:`xarray.DataArray` or :class:`numpy.ndarray`:
The destaggered variable. If xarray is enabled and The destaggered variable. If xarray is enabled and
the *meta* parameter is True, then the result will be a the *meta* parameter is True, then the result will be a
:class:`xarray.DataArray` object. Otherwise, the result will be a :class:`xarray.DataArray` object. Otherwise, the result will be a
:class:`numpy.ndarray` object with no metadata. :class:`numpy.ndarray` object with no metadata.
""" """
var_shape = var.shape var_shape = var.shape
num_dims = var.ndim num_dims = var.ndim
stagger_dim_size = var_shape[stagger_dim] stagger_dim_size = var_shape[stagger_dim]
# Dynamically building the range slices to create the appropriate # Dynamically building the range slices to create the appropriate
# number of ':'s in the array accessor lists. # number of ':'s in the array accessor lists.
# For example, for a 3D array, the calculation would be # For example, for a 3D array, the calculation would be
# result = .5 * (var[:,:,0:stagger_dim_size-2] # result = .5 * (var[:,:,0:stagger_dim_size-2]
# + var[:,:,1:stagger_dim_size-1]) # + var[:,:,1:stagger_dim_size-1])
# for stagger_dim=2. So, full slices would be used for dims 0 and 1, but # for stagger_dim=2. So, full slices would be used for dims 0 and 1, but
# dim 2 needs the special slice. # dim 2 needs the special slice.
full_slice = slice(None) full_slice = slice(None)
slice1 = slice(0, stagger_dim_size - 1, 1) slice1 = slice(0, stagger_dim_size - 1, 1)
slice2 = slice(1, stagger_dim_size, 1) slice2 = slice(1, stagger_dim_size, 1)
# default to full slices # default to full slices
dim_ranges_1 = [full_slice] * num_dims dim_ranges_1 = [full_slice] * num_dims
dim_ranges_2 = [full_slice] * num_dims dim_ranges_2 = [full_slice] * num_dims
# for the stagger dim, insert the appropriate slice range # for the stagger dim, insert the appropriate slice range
dim_ranges_1[stagger_dim] = slice1 dim_ranges_1[stagger_dim] = slice1
dim_ranges_2[stagger_dim] = slice2 dim_ranges_2[stagger_dim] = slice2
result = .5*(var[tuple(dim_ranges_1)] + var[tuple(dim_ranges_2)]) result = .5*(var[tuple(dim_ranges_1)] + var[tuple(dim_ranges_2)])
return result
return result

1263
src/wrf/extension.py

File diff suppressed because it is too large Load Diff

809
src/wrf/g_cape.py

File diff suppressed because it is too large Load Diff

688
src/wrf/g_cloudfrac.py

@ -11,142 +11,142 @@ from .g_geoht import _get_geoht
@set_cloudfrac_metadata() @set_cloudfrac_metadata()
def get_cloudfrac(wrfin, timeidx=0, method="cat", squeeze=True, def get_cloudfrac(wrfin, timeidx=0, method="cat", squeeze=True,
cache=None, meta=True, _key=None, cache=None, meta=True, _key=None,
vert_type="height_agl", low_thresh=None, mid_thresh=None, vert_type="height_agl", low_thresh=None, mid_thresh=None,
high_thresh=None, missing=default_fill(np.float64)): high_thresh=None, missing=default_fill(np.float64)):
"""Return the cloud fraction for low, mid, and high level clouds. """Return the cloud fraction for low, mid, and high level clouds.
The leftmost dimension of the returned array represents three different The leftmost dimension of the returned array represents three different
quantities: quantities:
- return_val[0,...] will contain LOW level cloud fraction - return_val[0,...] will contain LOW level cloud fraction
- return_val[1,...] will contain MID level cloud fraction - return_val[1,...] will contain MID level cloud fraction
- return_val[2,...] will contain HIGH level cloud fraction - return_val[2,...] will contain HIGH level cloud fraction
If the vertical coordinate type is 'height_agl' or 'height_msl', the If the vertical coordinate type is 'height_agl' or 'height_msl', the
default cloud levels are defined as: default cloud levels are defined as:
300 m <= low_cloud < 2000 m 300 m <= low_cloud < 2000 m
2000 m <= mid_cloud < 6000 m 2000 m <= mid_cloud < 6000 m
6000 m <= high_cloud 6000 m <= high_cloud
For 'pressure', the default cloud levels are defined as: For 'pressure', the default cloud levels are defined as:
97000 Pa <= low_cloud < 80000 Pa 97000 Pa <= low_cloud < 80000 Pa
80000 Pa <= mid_cloud < 45000 Pa 80000 Pa <= mid_cloud < 45000 Pa
45000 Pa <= high_cloud 45000 Pa <= high_cloud
Note that the default low cloud levels are chosen to Note that the default low cloud levels are chosen to
exclude clouds near the surface (fog). If you want fog included, set exclude clouds near the surface (fog). If you want fog included, set
*low_thresh* to ~99500 Pa if *vert_type* is set to 'pressure', or 15 m if *low_thresh* to ~99500 Pa if *vert_type* is set to 'pressure', or 15 m if
using 'height_msl' or 'height_agl'. Keep in mind that the lowest mass grid using 'height_msl' or 'height_agl'. Keep in mind that the lowest mass grid
points are slightly above the ground, and in order to find clouds, the points are slightly above the ground, and in order to find clouds, the
*low_thresh* needs to be set to values that are slightly greater than *low_thresh* needs to be set to values that are slightly greater than
(less than) the lowest height (pressure) values. (less than) the lowest height (pressure) values.
When using 'pressure' or 'height_agl' for *vert_type*, there is a When using 'pressure' or 'height_agl' for *vert_type*, there is a
possibility that the lowest WRF level will be higher than the low_cloud or possibility that the lowest WRF level will be higher than the low_cloud or
mid_cloud threshold, particularly for mountainous regions. When this mid_cloud threshold, particularly for mountainous regions. When this
happens, a fill value will be used in the output. happens, a fill value will be used in the output.
This functions extracts the necessary variables from the NetCDF file This functions extracts the necessary variables from the NetCDF file
object in order to perform the calculation. object in order to perform the calculation.
Args: Args:
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \
iterable): WRF-ARW NetCDF iterable): WRF-ARW NetCDF
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile`
or an iterable sequence of the aforementioned types. or an iterable sequence of the aforementioned types.
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The
desired time index. This value can be a positive integer, desired time index. This value can be a positive integer,
negative integer, or negative integer, or
:data:`wrf.ALL_TIMES` (an alias for None) to return :data:`wrf.ALL_TIMES` (an alias for None) to return
all times in the file or sequence. The default is 0. all times in the file or sequence. The default is 0.
method (:obj:`str`, optional): The aggregation method to use for method (:obj:`str`, optional): The aggregation method to use for
sequences. Must be either 'cat' or 'join'. sequences. Must be either 'cat' or 'join'.
'cat' combines the data along the Time dimension. 'cat' combines the data along the Time dimension.
'join' creates a new dimension for the file index. 'join' creates a new dimension for the file index.
The default is 'cat'. The default is 'cat'.
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions squeeze (:obj:`bool`, optional): Set to False to prevent dimensions
with a size of 1 from being automatically removed from the shape with a size of 1 from being automatically removed from the shape
of the output. Default is True. of the output. Default is True.
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) cache (:obj:`dict`, optional): A dictionary of (varname, ndarray)
that can be used to supply pre-extracted NetCDF variables to the that can be used to supply pre-extracted NetCDF variables to the
computational routines. It is primarily used for internal computational routines. It is primarily used for internal
purposes, but can also be used to improve performance by purposes, but can also be used to improve performance by
eliminating the need to repeatedly extract the same variables eliminating the need to repeatedly extract the same variables
used in multiple diagnostics calculations, particularly when using used in multiple diagnostics calculations, particularly when using
large sequences of files. large sequences of files.
Default is None. Default is None.
meta (:obj:`bool`, optional): Set to False to disable metadata and meta (:obj:`bool`, optional): Set to False to disable metadata and
return :class:`numpy.ndarray` instead of return :class:`numpy.ndarray` instead of
:class:`xarray.DataArray`. Default is True. :class:`xarray.DataArray`. Default is True.
_key (:obj:`int`, optional): A caching key. This is used for internal _key (:obj:`int`, optional): A caching key. This is used for internal
purposes only. Default is None. purposes only. Default is None.
vert_type (:obj:`str`, optional): The type of vertical coordinate used vert_type (:obj:`str`, optional): The type of vertical coordinate used
to determine cloud type thresholds. Must be 'height_agl', to determine cloud type thresholds. Must be 'height_agl',
'height_msl', or 'pres'. The default is 'height_agl'. 'height_msl', or 'pres'. The default is 'height_agl'.
low_thresh (:obj:`float`, optional): The lower bound for what is low_thresh (:obj:`float`, optional): The lower bound for what is
considered a low cloud. If *vert_type* is 'pres', the default is considered a low cloud. If *vert_type* is 'pres', the default is
97000 Pa. If *vert_type* is 'height_agl' or 'height_msl', then the 97000 Pa. If *vert_type* is 'height_agl' or 'height_msl', then the
default is 300 m. default is 300 m.
mid_thresh (:obj:`float`, optional): The lower bound for what is mid_thresh (:obj:`float`, optional): The lower bound for what is
considered a mid level cloud. If *vert_type* is 'pres', the considered a mid level cloud. If *vert_type* is 'pres', the
default is 80000 Pa. If *vert_type* is 'height_agl' or default is 80000 Pa. If *vert_type* is 'height_agl' or
'height_msl', then the default is 2000 m. 'height_msl', then the default is 2000 m.
high_thresh (:obj:`float`, optional): The lower bound for what is high_thresh (:obj:`float`, optional): The lower bound for what is
considered a high level cloud. If *vert_type* is 'pres', the considered a high level cloud. If *vert_type* is 'pres', the
default is 45000 Pa. If *vert_type* is 'height_agl' or default is 45000 Pa. If *vert_type* is 'height_agl' or
'height_msl', then the default is 6000 m. 'height_msl', then the default is 6000 m.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The :class:`xarray.DataArray` or :class:`numpy.ndarray`: The
cloud fraction array whose leftmost dimension is 3 (LOW=0, MID=1, cloud fraction array whose leftmost dimension is 3 (LOW=0, MID=1,
HIGH=2). HIGH=2).
If xarray is enabled and the *meta* parameter is True, then the result If xarray is enabled and the *meta* parameter is True, then the result
will be a :class:`xarray.DataArray` object. Otherwise, the result will will be a :class:`xarray.DataArray` object. Otherwise, the result will
be a :class:`numpy.ndarray` object with no metadata. be a :class:`numpy.ndarray` object with no metadata.
""" """
ncvars = extract_vars(wrfin, timeidx, ("P", "PB", "QVAPOR", "T"), ncvars = extract_vars(wrfin, timeidx, ("P", "PB", "QVAPOR", "T"),
method, squeeze, cache, meta=False, method, squeeze, cache, meta=False,
_key=_key) _key=_key)
p = ncvars["P"] p = ncvars["P"]
pb = ncvars["PB"] pb = ncvars["PB"]
qv = ncvars["QVAPOR"] qv = ncvars["QVAPOR"]
t = ncvars["T"] t = ncvars["T"]
full_p = p + pb full_p = p + pb
full_t = t + Constants.T_BASE full_t = t + Constants.T_BASE
tk = _tk(full_p, full_t) tk = _tk(full_p, full_t)
rh = _rh(qv, full_p, tk) rh = _rh(qv, full_p, tk)
if vert_type.lower() == "pres" or vert_type.lower() == "pressure": if vert_type.lower() == "pres" or vert_type.lower() == "pressure":
v_coord = full_p v_coord = full_p
_low_thresh = 97000. if low_thresh is None else low_thresh _low_thresh = 97000. if low_thresh is None else low_thresh
_mid_thresh = 80000. if mid_thresh is None else mid_thresh _mid_thresh = 80000. if mid_thresh is None else mid_thresh
_high_thresh = 45000. if high_thresh is None else high_thresh _high_thresh = 45000. if high_thresh is None else high_thresh
vert_inc_w_height = 0 vert_inc_w_height = 0
elif (vert_type.lower() == "height_msl" elif (vert_type.lower() == "height_msl"
or vert_type.lower() == "height_agl"): or vert_type.lower() == "height_agl"):
is_msl = vert_type.lower() == "height_msl" is_msl = vert_type.lower() == "height_msl"
v_coord = _get_geoht(wrfin, timeidx, method, squeeze, v_coord = _get_geoht(wrfin, timeidx, method, squeeze,
cache, meta=False, _key=_key, height=True, cache, meta=False, _key=_key, height=True,
msl=is_msl) msl=is_msl)
_low_thresh = 300. if low_thresh is None else low_thresh _low_thresh = 300. if low_thresh is None else low_thresh
_mid_thresh = 2000. if mid_thresh is None else mid_thresh _mid_thresh = 2000. if mid_thresh is None else mid_thresh
@ -155,344 +155,346 @@ def get_cloudfrac(wrfin, timeidx=0, method="cat", squeeze=True,
else: else:
raise ValueError("'vert_type' must be 'pres', 'height_msl', " raise ValueError("'vert_type' must be 'pres', 'height_msl', "
"or 'height_agl'") "or 'height_agl'")
cfrac = _cloudfrac(v_coord, rh, vert_inc_w_height, cfrac = _cloudfrac(v_coord, rh, vert_inc_w_height,
_low_thresh, _mid_thresh, _high_thresh, missing) _low_thresh, _mid_thresh, _high_thresh, missing)
return ma.masked_values(cfrac, missing) return ma.masked_values(cfrac, missing)
def get_low_cloudfrac(wrfin, timeidx=0, method="cat", squeeze=True, def get_low_cloudfrac(wrfin, timeidx=0, method="cat", squeeze=True,
cache=None, meta=True, _key=None, cache=None, meta=True, _key=None,
vert_type="height_agl", low_thresh=None, mid_thresh=None, vert_type="height_agl", low_thresh=None,
high_thresh=None, missing=default_fill(np.float64)): mid_thresh=None, high_thresh=None,
missing=default_fill(np.float64)):
"""Return the cloud fraction for the low level clouds. """Return the cloud fraction for the low level clouds.
If the vertical coordinate type is 'height_agl' or 'height_msl', the If the vertical coordinate type is 'height_agl' or 'height_msl', the
default cloud levels are defined as: default cloud levels are defined as:
300 m <= low_cloud < 2000 m 300 m <= low_cloud < 2000 m
2000 m <= mid_cloud < 6000 m 2000 m <= mid_cloud < 6000 m
6000 m <= high_cloud 6000 m <= high_cloud
For 'pressure', the default cloud levels are defined as: For 'pressure', the default cloud levels are defined as:
97000 Pa <= low_cloud < 80000 Pa 97000 Pa <= low_cloud < 80000 Pa
80000 Pa <= mid_cloud < 45000 Pa 80000 Pa <= mid_cloud < 45000 Pa
45000 Pa <= high_cloud 45000 Pa <= high_cloud
Note that the default low cloud levels are chosen to Note that the default low cloud levels are chosen to
exclude clouds near the surface (fog). If you want fog included, set exclude clouds near the surface (fog). If you want fog included, set
*low_thresh* to ~99500 Pa if *vert_type* is set to 'pressure', or 15 m if *low_thresh* to ~99500 Pa if *vert_type* is set to 'pressure', or 15 m if
using 'height_msl' or 'height_agl'. Keep in mind that the lowest mass grid using 'height_msl' or 'height_agl'. Keep in mind that the lowest mass grid
points are slightly above the ground, and in order to find clouds, the points are slightly above the ground, and in order to find clouds, the
*low_thresh* needs to be set to values that are slightly greater than *low_thresh* needs to be set to values that are slightly greater than
(less than) the lowest height (pressure) values. (less than) the lowest height (pressure) values.
When using 'pressure' or 'height_agl' for *vert_type*, there is a When using 'pressure' or 'height_agl' for *vert_type*, there is a
possibility that the lowest WRF level will be higher than the low_cloud or possibility that the lowest WRF level will be higher than the low_cloud or
mid_cloud threshold, particularly for mountainous regions. When this mid_cloud threshold, particularly for mountainous regions. When this
happens, a fill value will be used in the output. happens, a fill value will be used in the output.
This functions extracts the necessary variables from the NetCDF file This functions extracts the necessary variables from the NetCDF file
object in order to perform the calculation. object in order to perform the calculation.
Args: Args:
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \
iterable): WRF-ARW NetCDF iterable): WRF-ARW NetCDF
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile`
or an iterable sequence of the aforementioned types. or an iterable sequence of the aforementioned types.
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The
desired time index. This value can be a positive integer, desired time index. This value can be a positive integer,
negative integer, or negative integer, or
:data:`wrf.ALL_TIMES` (an alias for None) to return :data:`wrf.ALL_TIMES` (an alias for None) to return
all times in the file or sequence. The default is 0. all times in the file or sequence. The default is 0.
method (:obj:`str`, optional): The aggregation method to use for method (:obj:`str`, optional): The aggregation method to use for
sequences. Must be either 'cat' or 'join'. sequences. Must be either 'cat' or 'join'.
'cat' combines the data along the Time dimension. 'cat' combines the data along the Time dimension.
'join' creates a new dimension for the file index. 'join' creates a new dimension for the file index.
The default is 'cat'. The default is 'cat'.
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions squeeze (:obj:`bool`, optional): Set to False to prevent dimensions
with a size of 1 from being automatically removed from the shape with a size of 1 from being automatically removed from the shape
of the output. Default is True. of the output. Default is True.
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) cache (:obj:`dict`, optional): A dictionary of (varname, ndarray)
that can be used to supply pre-extracted NetCDF variables to the that can be used to supply pre-extracted NetCDF variables to the
computational routines. It is primarily used for internal computational routines. It is primarily used for internal
purposes, but can also be used to improve performance by purposes, but can also be used to improve performance by
eliminating the need to repeatedly extract the same variables eliminating the need to repeatedly extract the same variables
used in multiple diagnostics calculations, particularly when using used in multiple diagnostics calculations, particularly when using
large sequences of files. large sequences of files.
Default is None. Default is None.
meta (:obj:`bool`, optional): Set to False to disable metadata and meta (:obj:`bool`, optional): Set to False to disable metadata and
return :class:`numpy.ndarray` instead of return :class:`numpy.ndarray` instead of
:class:`xarray.DataArray`. Default is True. :class:`xarray.DataArray`. Default is True.
_key (:obj:`int`, optional): A caching key. This is used for internal _key (:obj:`int`, optional): A caching key. This is used for internal
purposes only. Default is None. purposes only. Default is None.
vert_type (:obj:`str`, optional): The type of vertical coordinate used vert_type (:obj:`str`, optional): The type of vertical coordinate used
to determine cloud type thresholds. Must be 'height_agl', to determine cloud type thresholds. Must be 'height_agl',
'height_msl', or 'pres'. The default is 'height_agl'. 'height_msl', or 'pres'. The default is 'height_agl'.
low_thresh (:obj:`float`, optional): The lower bound for what is low_thresh (:obj:`float`, optional): The lower bound for what is
considered a low cloud. If *vert_type* is 'pres', the default is considered a low cloud. If *vert_type* is 'pres', the default is
97000 Pa. If *vert_type* is 'height_agl' or 'height_msl', then the 97000 Pa. If *vert_type* is 'height_agl' or 'height_msl', then the
default is 300 m. default is 300 m.
mid_thresh (:obj:`float`, optional): The lower bound for what is mid_thresh (:obj:`float`, optional): The lower bound for what is
considered a mid level cloud. If *vert_type* is 'pres', the considered a mid level cloud. If *vert_type* is 'pres', the
default is 80000 Pa. If *vert_type* is 'height_agl' or default is 80000 Pa. If *vert_type* is 'height_agl' or
'height_msl', then the default is 2000 m. 'height_msl', then the default is 2000 m.
high_thresh (:obj:`float`, optional): The lower bound for what is high_thresh (:obj:`float`, optional): The lower bound for what is
considered a high level cloud. If *vert_type* is 'pres', the considered a high level cloud. If *vert_type* is 'pres', the
default is 45000 Pa. If *vert_type* is 'height_agl' or default is 45000 Pa. If *vert_type* is 'height_agl' or
'height_msl', then the default is 6000 m. 'height_msl', then the default is 6000 m.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The :class:`xarray.DataArray` or :class:`numpy.ndarray`: The
cloud fraction array for low level clouds. cloud fraction array for low level clouds.
If xarray is enabled and the *meta* parameter is True, then the result If xarray is enabled and the *meta* parameter is True, then the result
will be a :class:`xarray.DataArray` object. Otherwise, the result will will be a :class:`xarray.DataArray` object. Otherwise, the result will
be a :class:`numpy.ndarray` object with no metadata. be a :class:`numpy.ndarray` object with no metadata.
""" """
result = get_cloudfrac(wrfin, timeidx, method, squeeze, result = get_cloudfrac(wrfin, timeidx, method, squeeze,
cache, meta, _key, cache, meta, _key, vert_type, low_thresh,
vert_type, low_thresh, mid_thresh, mid_thresh, high_thresh, missing)[0, :]
high_thresh, missing)[0,:]
if meta: if meta:
result.attrs["description"] = "low clouds" result.attrs["description"] = "low clouds"
return result return result
def get_mid_cloudfrac(wrfin, timeidx=0, method="cat", squeeze=True, def get_mid_cloudfrac(wrfin, timeidx=0, method="cat", squeeze=True,
cache=None, meta=True, _key=None, cache=None, meta=True, _key=None,
vert_type="height_agl", low_thresh=None, mid_thresh=None, vert_type="height_agl", low_thresh=None,
high_thresh=None, missing=default_fill(np.float64)): mid_thresh=None, high_thresh=None,
missing=default_fill(np.float64)):
"""Return the cloud fraction for the mid level clouds. """Return the cloud fraction for the mid level clouds.
If the vertical coordinate type is 'height_agl' or 'height_msl', the If the vertical coordinate type is 'height_agl' or 'height_msl', the
default cloud levels are defined as: default cloud levels are defined as:
300 m <= low_cloud < 2000 m 300 m <= low_cloud < 2000 m
2000 m <= mid_cloud < 6000 m 2000 m <= mid_cloud < 6000 m
6000 m <= high_cloud 6000 m <= high_cloud
For 'pressure', the default cloud levels are defined as: For 'pressure', the default cloud levels are defined as:
97000 Pa <= low_cloud < 80000 Pa 97000 Pa <= low_cloud < 80000 Pa
80000 Pa <= mid_cloud < 45000 Pa 80000 Pa <= mid_cloud < 45000 Pa
45000 Pa <= high_cloud 45000 Pa <= high_cloud
Note that the default low cloud levels are chosen to Note that the default low cloud levels are chosen to
exclude clouds near the surface (fog). If you want fog included, set exclude clouds near the surface (fog). If you want fog included, set
*low_thresh* to ~99500 Pa if *vert_type* is set to 'pressure', or 15 m if *low_thresh* to ~99500 Pa if *vert_type* is set to 'pressure', or 15 m if
using 'height_msl' or 'height_agl'. Keep in mind that the lowest mass grid using 'height_msl' or 'height_agl'. Keep in mind that the lowest mass grid
points are slightly above the ground, and in order to find clouds, the points are slightly above the ground, and in order to find clouds, the
*low_thresh* needs to be set to values that are slightly greater than *low_thresh* needs to be set to values that are slightly greater than
(less than) the lowest height (pressure) values. (less than) the lowest height (pressure) values.
When using 'pressure' or 'height_agl' for *vert_type*, there is a When using 'pressure' or 'height_agl' for *vert_type*, there is a
possibility that the lowest WRF level will be higher than the low_cloud or possibility that the lowest WRF level will be higher than the low_cloud or
mid_cloud threshold, particularly for mountainous regions. When this mid_cloud threshold, particularly for mountainous regions. When this
happens, a fill value will be used in the output. happens, a fill value will be used in the output.
This functions extracts the necessary variables from the NetCDF file This functions extracts the necessary variables from the NetCDF file
object in order to perform the calculation. object in order to perform the calculation.
Args: Args:
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \
iterable): WRF-ARW NetCDF iterable): WRF-ARW NetCDF
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile`
or an iterable sequence of the aforementioned types. or an iterable sequence of the aforementioned types.
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The
desired time index. This value can be a positive integer, desired time index. This value can be a positive integer,
negative integer, or negative integer, or
:data:`wrf.ALL_TIMES` (an alias for None) to return :data:`wrf.ALL_TIMES` (an alias for None) to return
all times in the file or sequence. The default is 0. all times in the file or sequence. The default is 0.
method (:obj:`str`, optional): The aggregation method to use for method (:obj:`str`, optional): The aggregation method to use for
sequences. Must be either 'cat' or 'join'. sequences. Must be either 'cat' or 'join'.
'cat' combines the data along the Time dimension. 'cat' combines the data along the Time dimension.
'join' creates a new dimension for the file index. 'join' creates a new dimension for the file index.
The default is 'cat'. The default is 'cat'.
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions squeeze (:obj:`bool`, optional): Set to False to prevent dimensions
with a size of 1 from being automatically removed from the shape with a size of 1 from being automatically removed from the shape
of the output. Default is True. of the output. Default is True.
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) cache (:obj:`dict`, optional): A dictionary of (varname, ndarray)
that can be used to supply pre-extracted NetCDF variables to the that can be used to supply pre-extracted NetCDF variables to the
computational routines. It is primarily used for internal computational routines. It is primarily used for internal
purposes, but can also be used to improve performance by purposes, but can also be used to improve performance by
eliminating the need to repeatedly extract the same variables eliminating the need to repeatedly extract the same variables
used in multiple diagnostics calculations, particularly when using used in multiple diagnostics calculations, particularly when using
large sequences of files. large sequences of files.
Default is None. Default is None.
meta (:obj:`bool`, optional): Set to False to disable metadata and meta (:obj:`bool`, optional): Set to False to disable metadata and
return :class:`numpy.ndarray` instead of return :class:`numpy.ndarray` instead of
:class:`xarray.DataArray`. Default is True. :class:`xarray.DataArray`. Default is True.
_key (:obj:`int`, optional): A caching key. This is used for internal _key (:obj:`int`, optional): A caching key. This is used for internal
purposes only. Default is None. purposes only. Default is None.
vert_type (:obj:`str`, optional): The type of vertical coordinate used vert_type (:obj:`str`, optional): The type of vertical coordinate used
to determine cloud type thresholds. Must be 'height_agl', to determine cloud type thresholds. Must be 'height_agl',
'height_msl', or 'pres'. The default is 'height_agl'. 'height_msl', or 'pres'. The default is 'height_agl'.
low_thresh (:obj:`float`, optional): The lower bound for what is low_thresh (:obj:`float`, optional): The lower bound for what is
considered a low cloud. If *vert_type* is 'pres', the default is considered a low cloud. If *vert_type* is 'pres', the default is
97000 Pa. If *vert_type* is 'height_agl' or 'height_msl', then the 97000 Pa. If *vert_type* is 'height_agl' or 'height_msl', then the
default is 300 m. default is 300 m.
mid_thresh (:obj:`float`, optional): The lower bound for what is mid_thresh (:obj:`float`, optional): The lower bound for what is
considered a mid level cloud. If *vert_type* is 'pres', the considered a mid level cloud. If *vert_type* is 'pres', the
default is 80000 Pa. If *vert_type* is 'height_agl' or default is 80000 Pa. If *vert_type* is 'height_agl' or
'height_msl', then the default is 2000 m. 'height_msl', then the default is 2000 m.
high_thresh (:obj:`float`, optional): The lower bound for what is high_thresh (:obj:`float`, optional): The lower bound for what is
considered a high level cloud. If *vert_type* is 'pres', the considered a high level cloud. If *vert_type* is 'pres', the
default is 45000 Pa. If *vert_type* is 'height_agl' or default is 45000 Pa. If *vert_type* is 'height_agl' or
'height_msl', then the default is 6000 m. 'height_msl', then the default is 6000 m.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The :class:`xarray.DataArray` or :class:`numpy.ndarray`: The
cloud fraction array for mid level clouds. cloud fraction array for mid level clouds.
If xarray is enabled and the *meta* parameter is True, then the result If xarray is enabled and the *meta* parameter is True, then the result
will be a :class:`xarray.DataArray` object. Otherwise, the result will will be a :class:`xarray.DataArray` object. Otherwise, the result will
be a :class:`numpy.ndarray` object with no metadata. be a :class:`numpy.ndarray` object with no metadata.
""" """
result = get_cloudfrac(wrfin, timeidx, method, squeeze, result = get_cloudfrac(wrfin, timeidx, method, squeeze,
cache, meta, _key, cache, meta, _key,
vert_type, low_thresh, mid_thresh, vert_type, low_thresh, mid_thresh,
high_thresh, missing)[1,:] high_thresh, missing)[1, :]
if meta: if meta:
result.attrs["description"] = "mid clouds" result.attrs["description"] = "mid clouds"
return result return result
def get_high_cloudfrac(wrfin, timeidx=0, method="cat", squeeze=True, def get_high_cloudfrac(wrfin, timeidx=0, method="cat", squeeze=True,
cache=None, meta=True, _key=None, cache=None, meta=True, _key=None,
vert_type="height_agl", low_thresh=None, mid_thresh=None, vert_type="height_agl", low_thresh=None,
high_thresh=None, missing=default_fill(np.float64)): mid_thresh=None, high_thresh=None,
missing=default_fill(np.float64)):
"""Return the cloud fraction for the high level clouds. """Return the cloud fraction for the high level clouds.
If the vertical coordinate type is 'height_agl' or 'height_msl', the If the vertical coordinate type is 'height_agl' or 'height_msl', the
default cloud levels are defined as: default cloud levels are defined as:
300 m <= low_cloud < 2000 m 300 m <= low_cloud < 2000 m
2000 m <= mid_cloud < 6000 m 2000 m <= mid_cloud < 6000 m
6000 m <= high_cloud 6000 m <= high_cloud
For 'pressure', the default cloud levels are defined as: For 'pressure', the default cloud levels are defined as:
97000 Pa <= low_cloud < 80000 Pa 97000 Pa <= low_cloud < 80000 Pa
80000 Pa <= mid_cloud < 45000 Pa 80000 Pa <= mid_cloud < 45000 Pa
45000 Pa <= high_cloud 45000 Pa <= high_cloud
Note that the default low cloud levels are chosen to Note that the default low cloud levels are chosen to
exclude clouds near the surface (fog). If you want fog included, set exclude clouds near the surface (fog). If you want fog included, set
*low_thresh* to ~99500 Pa if *vert_type* is set to 'pressure', or 15 m if *low_thresh* to ~99500 Pa if *vert_type* is set to 'pressure', or 15 m if
using 'height_msl' or 'height_agl'. Keep in mind that the lowest mass grid using 'height_msl' or 'height_agl'. Keep in mind that the lowest mass grid
points are slightly above the ground, and in order to find clouds, the points are slightly above the ground, and in order to find clouds, the
*low_thresh* needs to be set to values that are slightly greater than *low_thresh* needs to be set to values that are slightly greater than
(less than) the lowest height (pressure) values. (less than) the lowest height (pressure) values.
When using 'pressure' or 'height_agl' for *vert_type*, there is a When using 'pressure' or 'height_agl' for *vert_type*, there is a
possibility that the lowest WRF level will be higher than the low_cloud or possibility that the lowest WRF level will be higher than the low_cloud or
mid_cloud threshold, particularly for mountainous regions. When this mid_cloud threshold, particularly for mountainous regions. When this
happens, a fill value will be used in the output. happens, a fill value will be used in the output.
This functions extracts the necessary variables from the NetCDF file This functions extracts the necessary variables from the NetCDF file
object in order to perform the calculation. object in order to perform the calculation.
Args: Args:
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \
iterable): WRF-ARW NetCDF iterable): WRF-ARW NetCDF
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile`
or an iterable sequence of the aforementioned types. or an iterable sequence of the aforementioned types.
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The
desired time index. This value can be a positive integer, desired time index. This value can be a positive integer,
negative integer, or negative integer, or
:data:`wrf.ALL_TIMES` (an alias for None) to return :data:`wrf.ALL_TIMES` (an alias for None) to return
all times in the file or sequence. The default is 0. all times in the file or sequence. The default is 0.
method (:obj:`str`, optional): The aggregation method to use for method (:obj:`str`, optional): The aggregation method to use for
sequences. Must be either 'cat' or 'join'. sequences. Must be either 'cat' or 'join'.
'cat' combines the data along the Time dimension. 'cat' combines the data along the Time dimension.
'join' creates a new dimension for the file index. 'join' creates a new dimension for the file index.
The default is 'cat'. The default is 'cat'.
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions squeeze (:obj:`bool`, optional): Set to False to prevent dimensions
with a size of 1 from being automatically removed from the shape with a size of 1 from being automatically removed from the shape
of the output. Default is True. of the output. Default is True.
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) cache (:obj:`dict`, optional): A dictionary of (varname, ndarray)
that can be used to supply pre-extracted NetCDF variables to the that can be used to supply pre-extracted NetCDF variables to the
computational routines. It is primarily used for internal computational routines. It is primarily used for internal
purposes, but can also be used to improve performance by purposes, but can also be used to improve performance by
eliminating the need to repeatedly extract the same variables eliminating the need to repeatedly extract the same variables
used in multiple diagnostics calculations, particularly when using used in multiple diagnostics calculations, particularly when using
large sequences of files. large sequences of files.
Default is None. Default is None.
meta (:obj:`bool`, optional): Set to False to disable metadata and meta (:obj:`bool`, optional): Set to False to disable metadata and
return :class:`numpy.ndarray` instead of return :class:`numpy.ndarray` instead of
:class:`xarray.DataArray`. Default is True. :class:`xarray.DataArray`. Default is True.
_key (:obj:`int`, optional): A caching key. This is used for internal _key (:obj:`int`, optional): A caching key. This is used for internal
purposes only. Default is None. purposes only. Default is None.
vert_type (:obj:`str`, optional): The type of vertical coordinate used vert_type (:obj:`str`, optional): The type of vertical coordinate used
to determine cloud type thresholds. Must be 'height_agl', to determine cloud type thresholds. Must be 'height_agl',
'height_msl', or 'pres'. The default is 'height_agl'. 'height_msl', or 'pres'. The default is 'height_agl'.
low_thresh (:obj:`float`, optional): The lower bound for what is low_thresh (:obj:`float`, optional): The lower bound for what is
considered a low cloud. If *vert_type* is 'pres', the default is considered a low cloud. If *vert_type* is 'pres', the default is
97000 Pa. If *vert_type* is 'height_agl' or 'height_msl', then the 97000 Pa. If *vert_type* is 'height_agl' or 'height_msl', then the
default is 300 m. default is 300 m.
mid_thresh (:obj:`float`, optional): The lower bound for what is mid_thresh (:obj:`float`, optional): The lower bound for what is
considered a mid level cloud. If *vert_type* is 'pres', the considered a mid level cloud. If *vert_type* is 'pres', the
default is 80000 Pa. If *vert_type* is 'height_agl' or default is 80000 Pa. If *vert_type* is 'height_agl' or
'height_msl', then the default is 2000 m. 'height_msl', then the default is 2000 m.
high_thresh (:obj:`float`, optional): The lower bound for what is high_thresh (:obj:`float`, optional): The lower bound for what is
considered a high level cloud. If *vert_type* is 'pres', the considered a high level cloud. If *vert_type* is 'pres', the
default is 45000 Pa. If *vert_type* is 'height_agl' or default is 45000 Pa. If *vert_type* is 'height_agl' or
'height_msl', then the default is 6000 m. 'height_msl', then the default is 6000 m.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The :class:`xarray.DataArray` or :class:`numpy.ndarray`: The
cloud fraction array for high level clouds. cloud fraction array for high level clouds.
If xarray is enabled and the *meta* parameter is True, then the result If xarray is enabled and the *meta* parameter is True, then the result
will be a :class:`xarray.DataArray` object. Otherwise, the result will will be a :class:`xarray.DataArray` object. Otherwise, the result will
be a :class:`numpy.ndarray` object with no metadata. be a :class:`numpy.ndarray` object with no metadata.
""" """
result = get_cloudfrac(wrfin, timeidx, method, squeeze, result = get_cloudfrac(wrfin, timeidx, method, squeeze,
cache, meta, _key, cache, meta, _key,
vert_type, low_thresh, mid_thresh, vert_type, low_thresh, mid_thresh,
high_thresh, missing)[2,:] high_thresh, missing)[2, :]
if meta: if meta:
result.attrs["description"] = "high clouds" result.attrs["description"] = "high clouds"
return result return result

149
src/wrf/g_ctt.py

@ -3,11 +3,10 @@ from __future__ import (absolute_import, division, print_function)
import numpy as np import numpy as np
import numpy.ma as ma import numpy.ma as ma
#from .extension import computectt, computetk
from .extension import _ctt, _tk from .extension import _ctt, _tk
from .constants import Constants, ConversionFactors, default_fill from .constants import Constants, ConversionFactors, default_fill
from .destag import destagger from .destag import destagger
from .decorators import convert_units from .decorators import convert_units
from .metadecorators import copy_and_set_metadata from .metadecorators import copy_and_set_metadata
from .util import extract_vars from .util import extract_vars
@ -17,86 +16,86 @@ from .util import extract_vars
description="cloud top temperature", description="cloud top temperature",
MemoryOrder="XY") MemoryOrder="XY")
@convert_units("temp", "c") @convert_units("temp", "c")
def get_ctt(wrfin, timeidx=0, method="cat", def get_ctt(wrfin, timeidx=0, method="cat",
squeeze=True, cache=None, meta=True, _key=None, squeeze=True, cache=None, meta=True, _key=None,
fill_nocloud=False, missing=default_fill(np.float64), fill_nocloud=False, missing=default_fill(np.float64),
opt_thresh=1.0, units="degC"): opt_thresh=1.0, units="degC"):
"""Return the cloud top temperature. """Return the cloud top temperature.
This functions extracts the necessary variables from the NetCDF file This functions extracts the necessary variables from the NetCDF file
object in order to perform the calculation. object in order to perform the calculation.
Args: Args:
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \
iterable): WRF-ARW NetCDF iterable): WRF-ARW NetCDF
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile`
or an iterable sequence of the aforementioned types. or an iterable sequence of the aforementioned types.
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The
desired time index. This value can be a positive integer, desired time index. This value can be a positive integer,
negative integer, or negative integer, or
:data:`wrf.ALL_TIMES` (an alias for None) to return :data:`wrf.ALL_TIMES` (an alias for None) to return
all times in the file or sequence. The default is 0. all times in the file or sequence. The default is 0.
method (:obj:`str`, optional): The aggregation method to use for method (:obj:`str`, optional): The aggregation method to use for
sequences. Must be either 'cat' or 'join'. sequences. Must be either 'cat' or 'join'.
'cat' combines the data along the Time dimension. 'cat' combines the data along the Time dimension.
'join' creates a new dimension for the file index. 'join' creates a new dimension for the file index.
The default is 'cat'. The default is 'cat'.
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions squeeze (:obj:`bool`, optional): Set to False to prevent dimensions
with a size of 1 from being automatically removed from the shape with a size of 1 from being automatically removed from the shape
of the output. Default is True. of the output. Default is True.
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) cache (:obj:`dict`, optional): A dictionary of (varname, ndarray)
that can be used to supply pre-extracted NetCDF variables to the that can be used to supply pre-extracted NetCDF variables to the
computational routines. It is primarily used for internal computational routines. It is primarily used for internal
purposes, but can also be used to improve performance by purposes, but can also be used to improve performance by
eliminating the need to repeatedly extract the same variables eliminating the need to repeatedly extract the same variables
used in multiple diagnostics calculations, particularly when using used in multiple diagnostics calculations, particularly when using
large sequences of files. large sequences of files.
Default is None. Default is None.
meta (:obj:`bool`, optional): Set to False to disable metadata and meta (:obj:`bool`, optional): Set to False to disable metadata and
return :class:`numpy.ndarray` instead of return :class:`numpy.ndarray` instead of
:class:`xarray.DataArray`. Default is True. :class:`xarray.DataArray`. Default is True.
_key (:obj:`int`, optional): A caching key. This is used for internal _key (:obj:`int`, optional): A caching key. This is used for internal
purposes only. Default is None. purposes only. Default is None.
fill_nocloud (:obj:`bool`, optional): Set to True to use fill values in fill_nocloud (:obj:`bool`, optional): Set to True to use fill values in
regions where clouds are not detected (optical depth less than 1). regions where clouds are not detected (optical depth less than 1).
Otherwise, the output will contain the surface temperature for Otherwise, the output will contain the surface temperature for
areas without clouds. Default is False. areas without clouds. Default is False.
missing (:obj:`float`, optional): The fill value to use for areas missing (:obj:`float`, optional): The fill value to use for areas
where no clouds are detected. Only used if *fill_nocloud* is where no clouds are detected. Only used if *fill_nocloud* is
True. Default is True. Default is
:data:`wrf.default_fill(numpy.float64)`. :data:`wrf.default_fill(numpy.float64)`.
opt_thresh (:obj:`float`, optional): The amount of optical opt_thresh (:obj:`float`, optional): The amount of optical
depth (integrated from top down) required to trigger a cloud top depth (integrated from top down) required to trigger a cloud top
temperature calculation. The cloud top temperature is calculated at temperature calculation. The cloud top temperature is calculated at
the vertical level where this threshold is met. Vertical columns the vertical level where this threshold is met. Vertical columns
with less than this threshold will be treated as cloud free areas. with less than this threshold will be treated as cloud free areas.
In general, the larger the value is for this In general, the larger the value is for this
threshold, the lower the altitude will be for the cloud top threshold, the lower the altitude will be for the cloud top
temperature calculation, and therefore higher cloud top temperature calculation, and therefore higher cloud top
temperature values. Default is 1.0, which should be sufficient for temperature values. Default is 1.0, which should be sufficient for
most users. most users.
units (:obj:`str`): The desired units. Refer to the :meth:`getvar` units (:obj:`str`): The desired units. Refer to the :meth:`getvar`
product table for a list of available units for 'ctt'. Default product table for a list of available units for 'ctt'. Default
is 'degC'. is 'degC'.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The :class:`xarray.DataArray` or :class:`numpy.ndarray`: The
cloud top temperature. cloud top temperature.
If xarray is enabled and the *meta* parameter is True, then the result If xarray is enabled and the *meta* parameter is True, then the result
will be a :class:`xarray.DataArray` object. Otherwise, the result will will be a :class:`xarray.DataArray` object. Otherwise, the result will
be a :class:`numpy.ndarray` object with no metadata. be a :class:`numpy.ndarray` object with no metadata.
""" """
varnames = ("T", "P", "PB", "PH", "PHB", "HGT", "QVAPOR") varnames = ("T", "P", "PB", "PH", "PHB", "HGT", "QVAPOR")
ncvars = extract_vars(wrfin, timeidx, varnames, method, squeeze, cache, ncvars = extract_vars(wrfin, timeidx, varnames, method, squeeze, cache,
@ -107,40 +106,40 @@ def get_ctt(wrfin, timeidx=0, method="cat",
ph = ncvars["PH"] ph = ncvars["PH"]
phb = ncvars["PHB"] phb = ncvars["PHB"]
ter = ncvars["HGT"] ter = ncvars["HGT"]
qv = ncvars["QVAPOR"] * 1000.0 # g/kg qv = ncvars["QVAPOR"] * 1000.0 # g/kg
haveqci = 1 haveqci = 1
try: try:
icevars = extract_vars(wrfin, timeidx, "QICE", icevars = extract_vars(wrfin, timeidx, "QICE",
method, squeeze, cache, meta=False, method, squeeze, cache, meta=False,
_key=_key) _key=_key)
except KeyError: except KeyError:
qice = np.zeros(qv.shape, qv.dtype) qice = np.zeros(qv.shape, qv.dtype)
haveqci = 0 haveqci = 0
else: else:
qice = icevars["QICE"] * 1000.0 #g/kg qice = icevars["QICE"] * 1000.0 # g/kg
try: try:
cldvars = extract_vars(wrfin, timeidx, "QCLOUD", cldvars = extract_vars(wrfin, timeidx, "QCLOUD",
method, squeeze, cache, meta=False, method, squeeze, cache, meta=False,
_key=_key) _key=_key)
except KeyError: except KeyError:
raise RuntimeError("'QCLOUD' not found in NetCDF file") raise RuntimeError("'QCLOUD' not found in NetCDF file")
else: else:
qcld = cldvars["QCLOUD"] * 1000.0 #g/kg qcld = cldvars["QCLOUD"] * 1000.0 # g/kg
full_p = p + pb full_p = p + pb
p_hpa = full_p * ConversionFactors.PA_TO_HPA p_hpa = full_p * ConversionFactors.PA_TO_HPA
full_t = t + Constants.T_BASE full_t = t + Constants.T_BASE
tk = _tk(full_p, full_t) tk = _tk(full_p, full_t)
geopt = ph + phb geopt = ph + phb
geopt_unstag = destagger(geopt, -3) geopt_unstag = destagger(geopt, -3)
ght = geopt_unstag / Constants.G ght = geopt_unstag / Constants.G
_fill_nocloud = 1 if fill_nocloud else 0 _fill_nocloud = 1 if fill_nocloud else 0
ctt = _ctt(p_hpa, tk, qice, qcld, qv, ght, ter, haveqci, _fill_nocloud, ctt = _ctt(p_hpa, tk, qice, qcld, qv, ght, ter, haveqci, _fill_nocloud,
missing, opt_thresh) missing, opt_thresh)
return ma.masked_values(ctt, missing) return ma.masked_values(ctt, missing)

228
src/wrf/g_dbz.py

@ -2,82 +2,81 @@ from __future__ import (absolute_import, division, print_function)
import numpy as np import numpy as np
#from .extension import computedbz,computetk
from .extension import _dbz, _tk from .extension import _dbz, _tk
from .constants import Constants from .constants import Constants
from .util import extract_vars, to_np from .util import extract_vars, to_np
from .metadecorators import copy_and_set_metadata from .metadecorators import copy_and_set_metadata
@copy_and_set_metadata(copy_varname="T", name="dbz", @copy_and_set_metadata(copy_varname="T", name="dbz",
description="radar reflectivity", description="radar reflectivity",
units="dBZ") units="dBZ")
def get_dbz(wrfin, timeidx=0, method="cat", def get_dbz(wrfin, timeidx=0, method="cat",
squeeze=True, cache=None, meta=True, _key=None, squeeze=True, cache=None, meta=True, _key=None,
use_varint=False, use_liqskin=False): use_varint=False, use_liqskin=False):
"""Return the simulated radar reflectivity. """Return the simulated radar reflectivity.
This functions extracts the necessary variables from the NetCDF file This functions extracts the necessary variables from the NetCDF file
object in order to perform the calculation. object in order to perform the calculation.
Args: Args:
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \
iterable): WRF-ARW NetCDF iterable): WRF-ARW NetCDF
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile`
or an iterable sequence of the aforementioned types. or an iterable sequence of the aforementioned types.
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The
desired time index. This value can be a positive integer, desired time index. This value can be a positive integer,
negative integer, or negative integer, or
:data:`wrf.ALL_TIMES` (an alias for None) to return :data:`wrf.ALL_TIMES` (an alias for None) to return
all times in the file or sequence. The default is 0. all times in the file or sequence. The default is 0.
method (:obj:`str`, optional): The aggregation method to use for method (:obj:`str`, optional): The aggregation method to use for
sequences. Must be either 'cat' or 'join'. sequences. Must be either 'cat' or 'join'.
'cat' combines the data along the Time dimension. 'cat' combines the data along the Time dimension.
'join' creates a new dimension for the file index. 'join' creates a new dimension for the file index.
The default is 'cat'. The default is 'cat'.
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions squeeze (:obj:`bool`, optional): Set to False to prevent dimensions
with a size of 1 from being automatically removed from the shape with a size of 1 from being automatically removed from the shape
of the output. Default is True. of the output. Default is True.
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) cache (:obj:`dict`, optional): A dictionary of (varname, ndarray)
that can be used to supply pre-extracted NetCDF variables to the that can be used to supply pre-extracted NetCDF variables to the
computational routines. It is primarily used for internal computational routines. It is primarily used for internal
purposes, but can also be used to improve performance by purposes, but can also be used to improve performance by
eliminating the need to repeatedly extract the same variables eliminating the need to repeatedly extract the same variables
used in multiple diagnostics calculations, particularly when using used in multiple diagnostics calculations, particularly when using
large sequences of files. large sequences of files.
Default is None. Default is None.
meta (:obj:`bool`, optional): Set to False to disable metadata and meta (:obj:`bool`, optional): Set to False to disable metadata and
return :class:`numpy.ndarray` instead of return :class:`numpy.ndarray` instead of
:class:`xarray.DataArray`. Default is True. :class:`xarray.DataArray`. Default is True.
_key (:obj:`int`, optional): A caching key. This is used for internal _key (:obj:`int`, optional): A caching key. This is used for internal
purposes only. Default is None. purposes only. Default is None.
use_varint (:obj:`bool`, optional): When set to False, use_varint (:obj:`bool`, optional): When set to False,
the intercept parameters are assumed constant the intercept parameters are assumed constant
(as in MM5's Reisner-2 bulk microphysical scheme). (as in MM5's Reisner-2 bulk microphysical scheme).
When set to True, the variable intercept When set to True, the variable intercept
parameters are used as in the more recent version of Reisner-2 parameters are used as in the more recent version of Reisner-2
(based on Thompson, Rasmussen, and Manning, 2004, Monthly weather (based on Thompson, Rasmussen, and Manning, 2004, Monthly weather
Review, Vol. 132, No. 2, pp. 519-542.). Review, Vol. 132, No. 2, pp. 519-542.).
use_liqskin (:obj:`bool`, optional): When set to True, frozen particles use_liqskin (:obj:`bool`, optional): When set to True, frozen particles
that are at a temperature above freezing are assumed to scatter that are at a temperature above freezing are assumed to scatter
as a liquid particle. Set to False to disable. as a liquid particle. Set to False to disable.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The simulated :class:`xarray.DataArray` or :class:`numpy.ndarray`: The simulated
radar reflectivity. radar reflectivity.
If xarray is enabled and the *meta* parameter is True, then the result If xarray is enabled and the *meta* parameter is True, then the result
will be a :class:`xarray.DataArray` object. Otherwise, the result will will be a :class:`xarray.DataArray` object. Otherwise, the result will
be a :class:`numpy.ndarray` object with no metadata. be a :class:`numpy.ndarray` object with no metadata.
""" """
varnames = ("T", "P", "PB", "QVAPOR", "QRAIN") varnames = ("T", "P", "PB", "QVAPOR", "QRAIN")
ncvars = extract_vars(wrfin, timeidx, varnames, method, squeeze, cache, ncvars = extract_vars(wrfin, timeidx, varnames, method, squeeze, cache,
@ -87,113 +86,112 @@ def get_dbz(wrfin, timeidx=0, method="cat",
pb = ncvars["PB"] pb = ncvars["PB"]
qv = ncvars["QVAPOR"] qv = ncvars["QVAPOR"]
qr = ncvars["QRAIN"] qr = ncvars["QRAIN"]
try: try:
snowvars = extract_vars(wrfin, timeidx, "QSNOW", snowvars = extract_vars(wrfin, timeidx, "QSNOW",
method, squeeze, cache, meta=False, method, squeeze, cache, meta=False,
_key=_key) _key=_key)
except KeyError: except KeyError:
qs = np.zeros(qv.shape, qv.dtype) qs = np.zeros(qv.shape, qv.dtype)
else: else:
qs = snowvars["QSNOW"] qs = snowvars["QSNOW"]
try: try:
graupvars = extract_vars(wrfin, timeidx, "QGRAUP", graupvars = extract_vars(wrfin, timeidx, "QGRAUP",
method, squeeze, cache, meta=False, method, squeeze, cache, meta=False,
_key=_key) _key=_key)
except KeyError: except KeyError:
qg = np.zeros(qv.shape, qv.dtype) qg = np.zeros(qv.shape, qv.dtype)
else: else:
qg = graupvars["QGRAUP"] qg = graupvars["QGRAUP"]
full_t = t + Constants.T_BASE full_t = t + Constants.T_BASE
full_p = p + pb full_p = p + pb
tk = _tk(full_p, full_t) tk = _tk(full_p, full_t)
# If qsnow is not all 0, set sn0 to 1 # If qsnow is not all 0, set sn0 to 1
sn0 = 1 if qs.any() else 0 sn0 = 1 if qs.any() else 0
ivarint = 1 if use_varint else 0 ivarint = 1 if use_varint else 0
iliqskin = 1 if use_liqskin else 0 iliqskin = 1 if use_liqskin else 0
return _dbz(full_p, tk, qv, qr, qs, qg, sn0, ivarint, iliqskin) return _dbz(full_p, tk, qv, qr, qs, qg, sn0, ivarint, iliqskin)
@copy_and_set_metadata(copy_varname="T", name="max_dbz", @copy_and_set_metadata(copy_varname="T", name="max_dbz",
remove_dims=("bottom_top",), remove_dims=("bottom_top",),
description="maximum radar reflectivity", description="maximum radar reflectivity",
units="dBZ", units="dBZ",
MemoryOrder="XY") MemoryOrder="XY")
def get_max_dbz(wrfin, timeidx=0, method="cat", def get_max_dbz(wrfin, timeidx=0, method="cat",
squeeze=True, cache=None, meta=True, _key=None, squeeze=True, cache=None, meta=True, _key=None,
use_varint=False, use_liqskin=False): use_varint=False, use_liqskin=False):
"""Return the maximum simulated radar reflectivity. """Return the maximum simulated radar reflectivity.
This function returns the maximum reflectivity found in the column for This function returns the maximum reflectivity found in the column for
each grid point. each grid point.
This functions extracts the necessary variables from the NetCDF file This functions extracts the necessary variables from the NetCDF file
object in order to perform the calculation. object in order to perform the calculation.
Args: Args:
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \
iterable): WRF-ARW NetCDF iterable): WRF-ARW NetCDF
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile`
or an iterable sequence of the aforementioned types. or an iterable sequence of the aforementioned types.
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The
desired time index. This value can be a positive integer, desired time index. This value can be a positive integer,
negative integer, or negative integer, or
:data:`wrf.ALL_TIMES` (an alias for None) to return :data:`wrf.ALL_TIMES` (an alias for None) to return
all times in the file or sequence. The default is 0. all times in the file or sequence. The default is 0.
method (:obj:`str`, optional): The aggregation method to use for method (:obj:`str`, optional): The aggregation method to use for
sequences. Must be either 'cat' or 'join'. sequences. Must be either 'cat' or 'join'.
'cat' combines the data along the Time dimension. 'cat' combines the data along the Time dimension.
'join' creates a new dimension for the file index. 'join' creates a new dimension for the file index.
The default is 'cat'. The default is 'cat'.
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions squeeze (:obj:`bool`, optional): Set to False to prevent dimensions
with a size of 1 from being automatically removed from the shape with a size of 1 from being automatically removed from the shape
of the output. Default is True. of the output. Default is True.
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) cache (:obj:`dict`, optional): A dictionary of (varname, ndarray)
that can be used to supply pre-extracted NetCDF variables to the that can be used to supply pre-extracted NetCDF variables to the
computational routines. It is primarily used for internal computational routines. It is primarily used for internal
purposes, but can also be used to improve performance by purposes, but can also be used to improve performance by
eliminating the need to repeatedly extract the same variables eliminating the need to repeatedly extract the same variables
used in multiple diagnostics calculations, particularly when using used in multiple diagnostics calculations, particularly when using
large sequences of files. large sequences of files.
Default is None. Default is None.
meta (:obj:`bool`, optional): Set to False to disable metadata and meta (:obj:`bool`, optional): Set to False to disable metadata and
return :class:`numpy.ndarray` instead of return :class:`numpy.ndarray` instead of
:class:`xarray.DataArray`. Default is True. :class:`xarray.DataArray`. Default is True.
_key (:obj:`int`, optional): A caching key. This is used for internal _key (:obj:`int`, optional): A caching key. This is used for internal
purposes only. Default is None. purposes only. Default is None.
use_varint (:obj:`bool`, optional): When set to False, use_varint (:obj:`bool`, optional): When set to False,
the intercept parameters are assumed constant the intercept parameters are assumed constant
(as in MM5's Reisner-2 bulk microphysical scheme). (as in MM5's Reisner-2 bulk microphysical scheme).
When set to True, the variable intercept When set to True, the variable intercept
parameters are used as in the more recent version of Reisner-2 parameters are used as in the more recent version of Reisner-2
(based on Thompson, Rasmussen, and Manning, 2004, Monthly weather (based on Thompson, Rasmussen, and Manning, 2004, Monthly weather
Review, Vol. 132, No. 2, pp. 519-542.). Review, Vol. 132, No. 2, pp. 519-542.).
use_liqskin (:obj:`bool`, optional): When set to True, frozen particles use_liqskin (:obj:`bool`, optional): When set to True, frozen particles
that are at a temperature above freezing are assumed to scatter that are at a temperature above freezing are assumed to scatter
as a liquid particle. Set to False to disable. as a liquid particle. Set to False to disable.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The maximum :class:`xarray.DataArray` or :class:`numpy.ndarray`: The maximum
simulated radar reflectivity. simulated radar reflectivity.
If xarray is enabled and the *meta* parameter is True, then the result If xarray is enabled and the *meta* parameter is True, then the result
will be a :class:`xarray.DataArray` object. Otherwise, the result will will be a :class:`xarray.DataArray` object. Otherwise, the result will
be a :class:`numpy.ndarray` object with no metadata. be a :class:`numpy.ndarray` object with no metadata.
""" """
return np.amax(to_np(get_dbz(wrfin, timeidx, method, squeeze, cache, meta, return np.amax(to_np(get_dbz(wrfin, timeidx, method, squeeze, cache, meta,
_key, use_varint, use_liqskin)), _key, use_varint, use_liqskin)),
axis=-3) axis=-3)

191
src/wrf/g_dewpoint.py

@ -1,164 +1,163 @@
from __future__ import (absolute_import, division, print_function) from __future__ import (absolute_import, division, print_function)
#from .extension import computetd
from .extension import _td from .extension import _td
from .decorators import convert_units from .decorators import convert_units
from .metadecorators import copy_and_set_metadata from .metadecorators import copy_and_set_metadata
from .util import extract_vars from .util import extract_vars
@copy_and_set_metadata(copy_varname="QVAPOR", name="td", @copy_and_set_metadata(copy_varname="QVAPOR", name="td",
description="dew point temperature") description="dew point temperature")
@convert_units("temp", "c") @convert_units("temp", "c")
def get_dp(wrfin, timeidx=0, method="cat", squeeze=True, def get_dp(wrfin, timeidx=0, method="cat", squeeze=True,
cache=None, meta=True, _key=None, units="degC"): cache=None, meta=True, _key=None, units="degC"):
"""Return the dewpoint temperature. """Return the dewpoint temperature.
This functions extracts the necessary variables from the NetCDF file This functions extracts the necessary variables from the NetCDF file
object in order to perform the calculation. object in order to perform the calculation.
Args: Args:
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \
iterable): WRF-ARW NetCDF iterable): WRF-ARW NetCDF
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile`
or an iterable sequence of the aforementioned types. or an iterable sequence of the aforementioned types.
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The
desired time index. This value can be a positive integer, desired time index. This value can be a positive integer,
negative integer, or negative integer, or
:data:`wrf.ALL_TIMES` (an alias for None) to return :data:`wrf.ALL_TIMES` (an alias for None) to return
all times in the file or sequence. The default is 0. all times in the file or sequence. The default is 0.
method (:obj:`str`, optional): The aggregation method to use for method (:obj:`str`, optional): The aggregation method to use for
sequences. Must be either 'cat' or 'join'. sequences. Must be either 'cat' or 'join'.
'cat' combines the data along the Time dimension. 'cat' combines the data along the Time dimension.
'join' creates a new dimension for the file index. 'join' creates a new dimension for the file index.
The default is 'cat'. The default is 'cat'.
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions squeeze (:obj:`bool`, optional): Set to False to prevent dimensions
with a size of 1 from being automatically removed from the shape with a size of 1 from being automatically removed from the shape
of the output. Default is True. of the output. Default is True.
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) cache (:obj:`dict`, optional): A dictionary of (varname, ndarray)
that can be used to supply pre-extracted NetCDF variables to the that can be used to supply pre-extracted NetCDF variables to the
computational routines. It is primarily used for internal computational routines. It is primarily used for internal
purposes, but can also be used to improve performance by purposes, but can also be used to improve performance by
eliminating the need to repeatedly extract the same variables eliminating the need to repeatedly extract the same variables
used in multiple diagnostics calculations, particularly when using used in multiple diagnostics calculations, particularly when using
large sequences of files. large sequences of files.
Default is None. Default is None.
meta (:obj:`bool`, optional): Set to False to disable metadata and meta (:obj:`bool`, optional): Set to False to disable metadata and
return :class:`numpy.ndarray` instead of return :class:`numpy.ndarray` instead of
:class:`xarray.DataArray`. Default is True. :class:`xarray.DataArray`. Default is True.
_key (:obj:`int`, optional): A caching key. This is used for internal _key (:obj:`int`, optional): A caching key. This is used for internal
purposes only. Default is None. purposes only. Default is None.
units (:obj:`str`): The desired units. Refer to the :meth:`getvar` units (:obj:`str`): The desired units. Refer to the :meth:`getvar`
product table for a list of available units for 'td'. Default product table for a list of available units for 'td'. Default
is 'degC'. is 'degC'.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The :class:`xarray.DataArray` or :class:`numpy.ndarray`: The
dewpoint temperature. dewpoint temperature.
If xarray is enabled and the *meta* parameter is True, then the result If xarray is enabled and the *meta* parameter is True, then the result
will be a :class:`xarray.DataArray` object. Otherwise, the result will will be a :class:`xarray.DataArray` object. Otherwise, the result will
be a :class:`numpy.ndarray` object with no metadata. be a :class:`numpy.ndarray` object with no metadata.
""" """
varnames=("P", "PB", "QVAPOR") varnames = ("P", "PB", "QVAPOR")
ncvars = extract_vars(wrfin, timeidx, varnames, method, squeeze, cache, ncvars = extract_vars(wrfin, timeidx, varnames, method, squeeze, cache,
meta=False, _key=_key) meta=False, _key=_key)
p = ncvars["P"] p = ncvars["P"]
pb = ncvars["PB"] pb = ncvars["PB"]
# Copy needed for the mmap nonsense of scipy.io.netcdf, which seems to # Copy needed for the mmap nonsense of scipy.io.netcdf, which seems to
# break with every release # break with every release
qvapor = ncvars["QVAPOR"].copy() qvapor = ncvars["QVAPOR"].copy()
# Algorithm requires hPa # Algorithm requires hPa
full_p = .01*(p + pb) full_p = .01*(p + pb)
qvapor[qvapor < 0] = 0 qvapor[qvapor < 0] = 0
td = _td(full_p, qvapor) td = _td(full_p, qvapor)
return td return td
@copy_and_set_metadata(copy_varname="Q2", name="td2",
@copy_and_set_metadata(copy_varname="Q2", name="td2",
description="2m dew point temperature") description="2m dew point temperature")
@convert_units("temp", "c") @convert_units("temp", "c")
def get_dp_2m(wrfin, timeidx=0, method="cat", squeeze=True, def get_dp_2m(wrfin, timeidx=0, method="cat", squeeze=True,
cache=None, meta=True, _key=None, units="degC"): cache=None, meta=True, _key=None, units="degC"):
"""Return the 2m dewpoint temperature. """Return the 2m dewpoint temperature.
This functions extracts the necessary variables from the NetCDF file This functions extracts the necessary variables from the NetCDF file
object in order to perform the calculation. object in order to perform the calculation.
Args: Args:
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \
iterable): WRF-ARW NetCDF iterable): WRF-ARW NetCDF
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile`
or an iterable sequence of the aforementioned types. or an iterable sequence of the aforementioned types.
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The
desired time index. This value can be a positive integer, desired time index. This value can be a positive integer,
negative integer, or negative integer, or
:data:`wrf.ALL_TIMES` (an alias for None) to return :data:`wrf.ALL_TIMES` (an alias for None) to return
all times in the file or sequence. The default is 0. all times in the file or sequence. The default is 0.
method (:obj:`str`, optional): The aggregation method to use for method (:obj:`str`, optional): The aggregation method to use for
sequences. Must be either 'cat' or 'join'. sequences. Must be either 'cat' or 'join'.
'cat' combines the data along the Time dimension. 'cat' combines the data along the Time dimension.
'join' creates a new dimension for the file index. 'join' creates a new dimension for the file index.
The default is 'cat'. The default is 'cat'.
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions squeeze (:obj:`bool`, optional): Set to False to prevent dimensions
with a size of 1 from being automatically removed from the shape with a size of 1 from being automatically removed from the shape
of the output. Default is True. of the output. Default is True.
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) cache (:obj:`dict`, optional): A dictionary of (varname, ndarray)
that can be used to supply pre-extracted NetCDF variables to the that can be used to supply pre-extracted NetCDF variables to the
computational routines. It is primarily used for internal computational routines. It is primarily used for internal
purposes, but can also be used to improve performance by purposes, but can also be used to improve performance by
eliminating the need to repeatedly extract the same variables eliminating the need to repeatedly extract the same variables
used in multiple diagnostics calculations, particularly when using used in multiple diagnostics calculations, particularly when using
large sequences of files. large sequences of files.
Default is None. Default is None.
meta (:obj:`bool`, optional): Set to False to disable metadata and meta (:obj:`bool`, optional): Set to False to disable metadata and
return :class:`numpy.ndarray` instead of return :class:`numpy.ndarray` instead of
:class:`xarray.DataArray`. Default is True. :class:`xarray.DataArray`. Default is True.
_key (:obj:`int`, optional): A caching key. This is used for internal _key (:obj:`int`, optional): A caching key. This is used for internal
purposes only. Default is None. purposes only. Default is None.
units (:obj:`str`): The desired units. Refer to the :meth:`getvar` units (:obj:`str`): The desired units. Refer to the :meth:`getvar`
product table for a list of available units for 'td2'. Default product table for a list of available units for 'td2'. Default
is 'degC'. is 'degC'.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The :class:`xarray.DataArray` or :class:`numpy.ndarray`: The
2m dewpoint temperature. 2m dewpoint temperature.
If xarray is enabled and the *meta* parameter is True, then the result If xarray is enabled and the *meta* parameter is True, then the result
will be a :class:`xarray.DataArray` object. Otherwise, the result will will be a :class:`xarray.DataArray` object. Otherwise, the result will
be a :class:`numpy.ndarray` object with no metadata. be a :class:`numpy.ndarray` object with no metadata.
""" """
varnames=("PSFC", "Q2") varnames = ("PSFC", "Q2")
ncvars = extract_vars(wrfin, timeidx, varnames, method, squeeze, cache, ncvars = extract_vars(wrfin, timeidx, varnames, method, squeeze, cache,
meta=False, _key=_key) meta=False, _key=_key)
# Algorithm requires hPa # Algorithm requires hPa
psfc = .01*(ncvars["PSFC"]) psfc = .01*(ncvars["PSFC"])
# Copy needed for the mmap nonsense of scipy.io.netcdf, which seems to # Copy needed for the mmap nonsense of scipy.io.netcdf, which seems to
# break with every release # break with every release
q2 = ncvars["Q2"].copy() q2 = ncvars["Q2"].copy()
q2[q2 < 0] = 0 q2[q2 < 0] = 0
td = _td(psfc, q2) td = _td(psfc, q2)
return td
return td

465
src/wrf/g_geoht.py

@ -8,79 +8,80 @@ from .decorators import convert_units
from .metadecorators import set_height_metadata from .metadecorators import set_height_metadata
from .util import extract_vars, either from .util import extract_vars, either
def _get_geoht(wrfin, timeidx, method="cat", squeeze=True,
def _get_geoht(wrfin, timeidx, method="cat", squeeze=True,
cache=None, meta=True, _key=None, cache=None, meta=True, _key=None,
height=True, msl=True, stag=False): height=True, msl=True, stag=False):
"""Return the geopotential or geopotential height. """Return the geopotential or geopotential height.
If *height* is False, then geopotential is returned in units of If *height* is False, then geopotential is returned in units of
[m2 s-2]. If *height* is True, then geopotential height is [m2 s-2]. If *height* is True, then geopotential height is
returned in units of [m]. If *msl* is True, then geopotential height returned in units of [m]. If *msl* is True, then geopotential height
is return as Mean Sea Level (MSL). If *msl* is False, then geopotential is return as Mean Sea Level (MSL). If *msl* is False, then geopotential
height is returned as Above Ground Level (AGL). height is returned as Above Ground Level (AGL).
This functions extracts the necessary variables from the NetCDF file This functions extracts the necessary variables from the NetCDF file
object in order to perform the calculation. object in order to perform the calculation.
Args: Args:
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \
iterable): WRF-ARW NetCDF iterable): WRF-ARW NetCDF
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile`
or an iterable sequence of the aforementioned types. or an iterable sequence of the aforementioned types.
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The
desired time index. This value can be a positive integer, desired time index. This value can be a positive integer,
negative integer, or negative integer, or
:data:`wrf.ALL_TIMES` (an alias for None) to return :data:`wrf.ALL_TIMES` (an alias for None) to return
all times in the file or sequence. The default is 0. all times in the file or sequence. The default is 0.
method (:obj:`str`, optional): The aggregation method to use for method (:obj:`str`, optional): The aggregation method to use for
sequences. Must be either 'cat' or 'join'. sequences. Must be either 'cat' or 'join'.
'cat' combines the data along the Time dimension. 'cat' combines the data along the Time dimension.
'join' creates a new dimension for the file index. 'join' creates a new dimension for the file index.
The default is 'cat'. The default is 'cat'.
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions squeeze (:obj:`bool`, optional): Set to False to prevent dimensions
with a size of 1 from being automatically removed from the shape with a size of 1 from being automatically removed from the shape
of the output. Default is True. of the output. Default is True.
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) cache (:obj:`dict`, optional): A dictionary of (varname, ndarray)
that can be used to supply pre-extracted NetCDF variables to the that can be used to supply pre-extracted NetCDF variables to the
computational routines. It is primarily used for internal computational routines. It is primarily used for internal
purposes, but can also be used to improve performance by purposes, but can also be used to improve performance by
eliminating the need to repeatedly extract the same variables eliminating the need to repeatedly extract the same variables
used in multiple diagnostics calculations, particularly when using used in multiple diagnostics calculations, particularly when using
large sequences of files. large sequences of files.
Default is None. Default is None.
meta (:obj:`bool`, optional): Set to False to disable metadata and meta (:obj:`bool`, optional): Set to False to disable metadata and
return :class:`numpy.ndarray` instead of return :class:`numpy.ndarray` instead of
:class:`xarray.DataArray`. Default is True. :class:`xarray.DataArray`. Default is True.
_key (:obj:`int`, optional): A caching key. This is used for internal _key (:obj:`int`, optional): A caching key. This is used for internal
purposes only. Default is None. purposes only. Default is None.
height (:obj:`bool`, optional): Set to True to return geopotential height (:obj:`bool`, optional): Set to True to return geopotential
height instead of geopotential. Default is True. height instead of geopotential. Default is True.
msl (:obj:`bool`, optional): Set to True to return geopotential height msl (:obj:`bool`, optional): Set to True to return geopotential height
as Mean Sea Level (MSL). Set to False to return the as Mean Sea Level (MSL). Set to False to return the
geopotential height as Above Ground Level (AGL) by subtracting geopotential height as Above Ground Level (AGL) by subtracting
the terrain height. Default is True. the terrain height. Default is True.
stag (:obj:`bool`, optional): Set to True to use the vertical stag (:obj:`bool`, optional): Set to True to use the vertical
staggered grid, rather than the mass grid. Default is False. staggered grid, rather than the mass grid. Default is False.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The :class:`xarray.DataArray` or :class:`numpy.ndarray`: The
geopotential or geopotential height. geopotential or geopotential height.
If xarray is enabled and the *meta* parameter is True, then the result If xarray is enabled and the *meta* parameter is True, then the result
will be a :class:`xarray.DataArray` object. Otherwise, the result will will be a :class:`xarray.DataArray` object. Otherwise, the result will
be a :class:`numpy.ndarray` object with no metadata. be a :class:`numpy.ndarray` object with no metadata.
""" """
varname = either("PH", "GHT")(wrfin) varname = either("PH", "GHT")(wrfin)
if varname == "PH": if varname == "PH":
ph_vars = extract_vars(wrfin, timeidx, ("PH", "PHB", "HGT"), ph_vars = extract_vars(wrfin, timeidx, ("PH", "PHB", "HGT"),
@ -100,11 +101,11 @@ def _get_geoht(wrfin, timeidx, method="cat", squeeze=True,
_key=_key) _key=_key)
geopt_unstag = ght_vars["GHT"] * Constants.G geopt_unstag = ght_vars["GHT"] * Constants.G
hgt = ght_vars["HGT_M"] hgt = ght_vars["HGT_M"]
if stag: if stag:
warnings.warn("file contains no vertically staggered geopotential " warnings.warn("file contains no vertically staggered geopotential "
"height variable, returning unstaggered result " "height variable, returning unstaggered result "
"instead" ) "instead")
if height: if height:
if msl: if msl:
return geopt_unstag / Constants.G return geopt_unstag / Constants.G
@ -113,70 +114,70 @@ def _get_geoht(wrfin, timeidx, method="cat", squeeze=True,
# array needs to be reshaped to a 3D array so the right dims # array needs to be reshaped to a 3D array so the right dims
# line up # line up
new_dims = list(hgt.shape) new_dims = list(hgt.shape)
new_dims.insert(-2,1) new_dims.insert(-2, 1)
hgt = hgt.reshape(new_dims) hgt = hgt.reshape(new_dims)
return (geopt_unstag / Constants.G) - hgt return (geopt_unstag / Constants.G) - hgt
else: else:
return geopt_unstag return geopt_unstag
@set_height_metadata(geopt=True, stag=False) @set_height_metadata(geopt=True, stag=False)
def get_geopt(wrfin, timeidx=0, method="cat", squeeze=True, cache=None, def get_geopt(wrfin, timeidx=0, method="cat", squeeze=True, cache=None,
meta=True, _key=None): meta=True, _key=None):
"""Return the geopotential. """Return the geopotential.
The geopotential is returned in units of [m2 s-2]. The geopotential is returned in units of [m2 s-2].
This functions extracts the necessary variables from the NetCDF file This functions extracts the necessary variables from the NetCDF file
object in order to perform the calculation. object in order to perform the calculation.
Args: Args:
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \
iterable): WRF-ARW NetCDF iterable): WRF-ARW NetCDF
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile`
or an iterable sequence of the aforementioned types. or an iterable sequence of the aforementioned types.
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The
desired time index. This value can be a positive integer, desired time index. This value can be a positive integer,
negative integer, or negative integer, or
:data:`wrf.ALL_TIMES` (an alias for None) to return :data:`wrf.ALL_TIMES` (an alias for None) to return
all times in the file or sequence. The default is 0. all times in the file or sequence. The default is 0.
method (:obj:`str`, optional): The aggregation method to use for method (:obj:`str`, optional): The aggregation method to use for
sequences. Must be either 'cat' or 'join'. sequences. Must be either 'cat' or 'join'.
'cat' combines the data along the Time dimension. 'cat' combines the data along the Time dimension.
'join' creates a new dimension for the file index. 'join' creates a new dimension for the file index.
The default is 'cat'. The default is 'cat'.
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions squeeze (:obj:`bool`, optional): Set to False to prevent dimensions
with a size of 1 from being automatically removed from the shape with a size of 1 from being automatically removed from the shape
of the output. Default is True. of the output. Default is True.
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) cache (:obj:`dict`, optional): A dictionary of (varname, ndarray)
that can be used to supply pre-extracted NetCDF variables to the that can be used to supply pre-extracted NetCDF variables to the
computational routines. It is primarily used for internal computational routines. It is primarily used for internal
purposes, but can also be used to improve performance by purposes, but can also be used to improve performance by
eliminating the need to repeatedly extract the same variables eliminating the need to repeatedly extract the same variables
used in multiple diagnostics calculations, particularly when using used in multiple diagnostics calculations, particularly when using
large sequences of files. large sequences of files.
Default is None. Default is None.
meta (:obj:`bool`, optional): Set to False to disable metadata and meta (:obj:`bool`, optional): Set to False to disable metadata and
return :class:`numpy.ndarray` instead of return :class:`numpy.ndarray` instead of
:class:`xarray.DataArray`. Default is True. :class:`xarray.DataArray`. Default is True.
_key (:obj:`int`, optional): A caching key. This is used for internal _key (:obj:`int`, optional): A caching key. This is used for internal
purposes only. Default is None. purposes only. Default is None.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The :class:`xarray.DataArray` or :class:`numpy.ndarray`: The
geopotential. geopotential.
If xarray is enabled and the *meta* parameter is True, then the result If xarray is enabled and the *meta* parameter is True, then the result
will be a :class:`xarray.DataArray` object. Otherwise, the result will will be a :class:`xarray.DataArray` object. Otherwise, the result will
be a :class:`numpy.ndarray` object with no metadata. be a :class:`numpy.ndarray` object with no metadata.
""" """
return _get_geoht(wrfin, timeidx, method, squeeze, cache, meta, _key, return _get_geoht(wrfin, timeidx, method, squeeze, cache, meta, _key,
False, True) False, True)
@ -184,135 +185,135 @@ def get_geopt(wrfin, timeidx=0, method="cat", squeeze=True, cache=None,
@set_height_metadata(geopt=False, stag=False) @set_height_metadata(geopt=False, stag=False)
@convert_units("height", "m") @convert_units("height", "m")
def get_height(wrfin, timeidx=0, method="cat", squeeze=True, def get_height(wrfin, timeidx=0, method="cat", squeeze=True,
cache=None, meta=True, _key=None, cache=None, meta=True, _key=None,
msl=True, units="m"): msl=True, units="m"):
"""Return the geopotential height. """Return the geopotential height.
If *msl* is True, then geopotential height is returned as Mean Sea Level If *msl* is True, then geopotential height is returned as Mean Sea Level
(MSL). If *msl* is False, then geopotential height is returned as (MSL). If *msl* is False, then geopotential height is returned as
Above Ground Level (AGL) by subtracting the terrain height. Above Ground Level (AGL) by subtracting the terrain height.
This functions extracts the necessary variables from the NetCDF file This functions extracts the necessary variables from the NetCDF file
object in order to perform the calculation. object in order to perform the calculation.
Args: Args:
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \
iterable): WRF-ARW NetCDF iterable): WRF-ARW NetCDF
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile`
or an iterable sequence of the aforementioned types. or an iterable sequence of the aforementioned types.
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The
desired time index. This value can be a positive integer, desired time index. This value can be a positive integer,
negative integer, or negative integer, or
:data:`wrf.ALL_TIMES` (an alias for None) to return :data:`wrf.ALL_TIMES` (an alias for None) to return
all times in the file or sequence. The default is 0. all times in the file or sequence. The default is 0.
method (:obj:`str`, optional): The aggregation method to use for method (:obj:`str`, optional): The aggregation method to use for
sequences. Must be either 'cat' or 'join'. sequences. Must be either 'cat' or 'join'.
'cat' combines the data along the Time dimension. 'cat' combines the data along the Time dimension.
'join' creates a new dimension for the file index. 'join' creates a new dimension for the file index.
The default is 'cat'. The default is 'cat'.
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions squeeze (:obj:`bool`, optional): Set to False to prevent dimensions
with a size of 1 from being automatically removed from the shape with a size of 1 from being automatically removed from the shape
of the output. Default is True. of the output. Default is True.
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) cache (:obj:`dict`, optional): A dictionary of (varname, ndarray)
that can be used to supply pre-extracted NetCDF variables to the that can be used to supply pre-extracted NetCDF variables to the
computational routines. It is primarily used for internal computational routines. It is primarily used for internal
purposes, but can also be used to improve performance by purposes, but can also be used to improve performance by
eliminating the need to repeatedly extract the same variables eliminating the need to repeatedly extract the same variables
used in multiple diagnostics calculations, particularly when using used in multiple diagnostics calculations, particularly when using
large sequences of files. large sequences of files.
Default is None. Default is None.
meta (:obj:`bool`, optional): Set to False to disable metadata and meta (:obj:`bool`, optional): Set to False to disable metadata and
return :class:`numpy.ndarray` instead of return :class:`numpy.ndarray` instead of
:class:`xarray.DataArray`. Default is True. :class:`xarray.DataArray`. Default is True.
_key (:obj:`int`, optional): A caching key. This is used for internal _key (:obj:`int`, optional): A caching key. This is used for internal
purposes only. Default is None. purposes only. Default is None.
msl (:obj:`bool`, optional): Set to True to return geopotential height msl (:obj:`bool`, optional): Set to True to return geopotential height
as Mean Sea Level (MSL). Set to False to return the as Mean Sea Level (MSL). Set to False to return the
geopotential height as Above Ground Level (AGL) by subtracting geopotential height as Above Ground Level (AGL) by subtracting
the terrain height. Default is True. the terrain height. Default is True.
units (:obj:`str`): The desired units. Refer to the :meth:`getvar` units (:obj:`str`): The desired units. Refer to the :meth:`getvar`
product table for a list of available units for 'z'. Default product table for a list of available units for 'z'. Default
is 'm'. is 'm'.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The :class:`xarray.DataArray` or :class:`numpy.ndarray`: The
geopotential height. geopotential height.
If xarray is enabled and the *meta* parameter is True, then the result If xarray is enabled and the *meta* parameter is True, then the result
will be a :class:`xarray.DataArray` object. Otherwise, the result will will be a :class:`xarray.DataArray` object. Otherwise, the result will
be a :class:`numpy.ndarray` object with no metadata. be a :class:`numpy.ndarray` object with no metadata.
""" """
return _get_geoht(wrfin, timeidx, method, squeeze, cache, meta, _key, return _get_geoht(wrfin, timeidx, method, squeeze, cache, meta, _key,
True, msl) True, msl)
@set_height_metadata(geopt=True, stag=True) @set_height_metadata(geopt=True, stag=True)
def get_stag_geopt(wrfin, timeidx=0, method="cat", squeeze=True, cache=None, def get_stag_geopt(wrfin, timeidx=0, method="cat", squeeze=True, cache=None,
meta=True, _key=None): meta=True, _key=None):
"""Return the geopotential for the vertically staggered grid. """Return the geopotential for the vertically staggered grid.
The geopotential is returned in units of [m2 s-2]. The geopotential is returned in units of [m2 s-2].
This functions extracts the necessary variables from the NetCDF file This functions extracts the necessary variables from the NetCDF file
object in order to perform the calculation. object in order to perform the calculation.
Args: Args:
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \
iterable): WRF-ARW NetCDF iterable): WRF-ARW NetCDF
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile`
or an iterable sequence of the aforementioned types. or an iterable sequence of the aforementioned types.
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The
desired time index. This value can be a positive integer, desired time index. This value can be a positive integer,
negative integer, or negative integer, or
:data:`wrf.ALL_TIMES` (an alias for None) to return :data:`wrf.ALL_TIMES` (an alias for None) to return
all times in the file or sequence. The default is 0. all times in the file or sequence. The default is 0.
method (:obj:`str`, optional): The aggregation method to use for method (:obj:`str`, optional): The aggregation method to use for
sequences. Must be either 'cat' or 'join'. sequences. Must be either 'cat' or 'join'.
'cat' combines the data along the Time dimension. 'cat' combines the data along the Time dimension.
'join' creates a new dimension for the file index. 'join' creates a new dimension for the file index.
The default is 'cat'. The default is 'cat'.
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions squeeze (:obj:`bool`, optional): Set to False to prevent dimensions
with a size of 1 from being automatically removed from the shape with a size of 1 from being automatically removed from the shape
of the output. Default is True. of the output. Default is True.
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) cache (:obj:`dict`, optional): A dictionary of (varname, ndarray)
that can be used to supply pre-extracted NetCDF variables to the that can be used to supply pre-extracted NetCDF variables to the
computational routines. It is primarily used for internal computational routines. It is primarily used for internal
purposes, but can also be used to improve performance by purposes, but can also be used to improve performance by
eliminating the need to repeatedly extract the same variables eliminating the need to repeatedly extract the same variables
used in multiple diagnostics calculations, particularly when using used in multiple diagnostics calculations, particularly when using
large sequences of files. large sequences of files.
Default is None. Default is None.
meta (:obj:`bool`, optional): Set to False to disable metadata and meta (:obj:`bool`, optional): Set to False to disable metadata and
return :class:`numpy.ndarray` instead of return :class:`numpy.ndarray` instead of
:class:`xarray.DataArray`. Default is True. :class:`xarray.DataArray`. Default is True.
_key (:obj:`int`, optional): A caching key. This is used for internal _key (:obj:`int`, optional): A caching key. This is used for internal
purposes only. Default is None. purposes only. Default is None.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The :class:`xarray.DataArray` or :class:`numpy.ndarray`: The
geopotential. geopotential.
If xarray is enabled and the *meta* parameter is True, then the result If xarray is enabled and the *meta* parameter is True, then the result
will be a :class:`xarray.DataArray` object. Otherwise, the result will will be a :class:`xarray.DataArray` object. Otherwise, the result will
be a :class:`numpy.ndarray` object with no metadata. be a :class:`numpy.ndarray` object with no metadata.
""" """
return _get_geoht(wrfin, timeidx, method, squeeze, cache, meta, _key, return _get_geoht(wrfin, timeidx, method, squeeze, cache, meta, _key,
False, True, stag=True) False, True, stag=True)
@ -320,75 +321,73 @@ def get_stag_geopt(wrfin, timeidx=0, method="cat", squeeze=True, cache=None,
@set_height_metadata(geopt=False, stag=True) @set_height_metadata(geopt=False, stag=True)
@convert_units("height", "m") @convert_units("height", "m")
def get_stag_height(wrfin, timeidx=0, method="cat", squeeze=True, def get_stag_height(wrfin, timeidx=0, method="cat", squeeze=True,
cache=None, meta=True, _key=None, cache=None, meta=True, _key=None, msl=True, units="m"):
msl=True, units="m"):
"""Return the geopotential height for the vertically staggered grid. """Return the geopotential height for the vertically staggered grid.
If *msl* is True, then geopotential height is returned as Mean Sea Level If *msl* is True, then geopotential height is returned as Mean Sea Level
(MSL). If *msl* is False, then geopotential height is returned as (MSL). If *msl* is False, then geopotential height is returned as
Above Ground Level (AGL) by subtracting the terrain height. Above Ground Level (AGL) by subtracting the terrain height.
This functions extracts the necessary variables from the NetCDF file This functions extracts the necessary variables from the NetCDF file
object in order to perform the calculation. object in order to perform the calculation.
Args: Args:
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \
iterable): WRF-ARW NetCDF iterable): WRF-ARW NetCDF
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile`
or an iterable sequence of the aforementioned types. or an iterable sequence of the aforementioned types.
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The
desired time index. This value can be a positive integer, desired time index. This value can be a positive integer,
negative integer, or negative integer, or
:data:`wrf.ALL_TIMES` (an alias for None) to return :data:`wrf.ALL_TIMES` (an alias for None) to return
all times in the file or sequence. The default is 0. all times in the file or sequence. The default is 0.
method (:obj:`str`, optional): The aggregation method to use for method (:obj:`str`, optional): The aggregation method to use for
sequences. Must be either 'cat' or 'join'. sequences. Must be either 'cat' or 'join'.
'cat' combines the data along the Time dimension. 'cat' combines the data along the Time dimension.
'join' creates a new dimension for the file index. 'join' creates a new dimension for the file index.
The default is 'cat'. The default is 'cat'.
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions squeeze (:obj:`bool`, optional): Set to False to prevent dimensions
with a size of 1 from being automatically removed from the shape with a size of 1 from being automatically removed from the shape
of the output. Default is True. of the output. Default is True.
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) cache (:obj:`dict`, optional): A dictionary of (varname, ndarray)
that can be used to supply pre-extracted NetCDF variables to the that can be used to supply pre-extracted NetCDF variables to the
computational routines. It is primarily used for internal computational routines. It is primarily used for internal
purposes, but can also be used to improve performance by purposes, but can also be used to improve performance by
eliminating the need to repeatedly extract the same variables eliminating the need to repeatedly extract the same variables
used in multiple diagnostics calculations, particularly when using used in multiple diagnostics calculations, particularly when using
large sequences of files. large sequences of files.
Default is None. Default is None.
meta (:obj:`bool`, optional): Set to False to disable metadata and meta (:obj:`bool`, optional): Set to False to disable metadata and
return :class:`numpy.ndarray` instead of return :class:`numpy.ndarray` instead of
:class:`xarray.DataArray`. Default is True. :class:`xarray.DataArray`. Default is True.
_key (:obj:`int`, optional): A caching key. This is used for internal _key (:obj:`int`, optional): A caching key. This is used for internal
purposes only. Default is None. purposes only. Default is None.
msl (:obj:`bool`, optional): Set to True to return geopotential height msl (:obj:`bool`, optional): Set to True to return geopotential height
as Mean Sea Level (MSL). Set to False to return the as Mean Sea Level (MSL). Set to False to return the
geopotential height as Above Ground Level (AGL) by subtracting geopotential height as Above Ground Level (AGL) by subtracting
the terrain height. Default is True. the terrain height. Default is True.
units (:obj:`str`): The desired units. Refer to the :meth:`getvar` units (:obj:`str`): The desired units. Refer to the :meth:`getvar`
product table for a list of available units for 'z'. Default product table for a list of available units for 'z'. Default
is 'm'. is 'm'.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The :class:`xarray.DataArray` or :class:`numpy.ndarray`: The
geopotential height. geopotential height.
If xarray is enabled and the *meta* parameter is True, then the result If xarray is enabled and the *meta* parameter is True, then the result
will be a :class:`xarray.DataArray` object. Otherwise, the result will will be a :class:`xarray.DataArray` object. Otherwise, the result will
be a :class:`numpy.ndarray` object with no metadata. be a :class:`numpy.ndarray` object with no metadata.
""" """
return _get_geoht(wrfin, timeidx, method, squeeze, cache, meta, _key, return _get_geoht(wrfin, timeidx, method, squeeze, cache, meta, _key,
True, msl, stag=True) True, msl, stag=True)

223
src/wrf/g_helicity.py

@ -9,87 +9,88 @@ from .util import extract_vars, extract_global_attrs, either
from .metadecorators import copy_and_set_metadata from .metadecorators import copy_and_set_metadata
from .g_latlon import get_lat from .g_latlon import get_lat
@copy_and_set_metadata(copy_varname="HGT", name="srh",
@copy_and_set_metadata(copy_varname="HGT", name="srh",
description="storm relative helicity", description="storm relative helicity",
units="m2 s-2") units="m2 s-2")
def get_srh(wrfin, timeidx=0, method="cat", squeeze=True, def get_srh(wrfin, timeidx=0, method="cat", squeeze=True,
cache=None, meta=True, _key=None, top=3000.0): cache=None, meta=True, _key=None, top=3000.0):
"""Return the storm relative helicity. """Return the storm relative helicity.
The *top* argument specifies the top of the integration in [m]. The *top* argument specifies the top of the integration in [m].
This functions extracts the necessary variables from the NetCDF file This functions extracts the necessary variables from the NetCDF file
object in order to perform the calculation. object in order to perform the calculation.
Args: Args:
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \
iterable): WRF-ARW NetCDF iterable): WRF-ARW NetCDF
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile`
or an iterable sequence of the aforementioned types. or an iterable sequence of the aforementioned types.
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The
desired time index. This value can be a positive integer, desired time index. This value can be a positive integer,
negative integer, or negative integer, or
:data:`wrf.ALL_TIMES` (an alias for None) to return :data:`wrf.ALL_TIMES` (an alias for None) to return
all times in the file or sequence. The default is 0. all times in the file or sequence. The default is 0.
method (:obj:`str`, optional): The aggregation method to use for method (:obj:`str`, optional): The aggregation method to use for
sequences. Must be either 'cat' or 'join'. sequences. Must be either 'cat' or 'join'.
'cat' combines the data along the Time dimension. 'cat' combines the data along the Time dimension.
'join' creates a new dimension for the file index. 'join' creates a new dimension for the file index.
The default is 'cat'. The default is 'cat'.
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions squeeze (:obj:`bool`, optional): Set to False to prevent dimensions
with a size of 1 from being automatically removed from the shape with a size of 1 from being automatically removed from the shape
of the output. Default is True. of the output. Default is True.
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) cache (:obj:`dict`, optional): A dictionary of (varname, ndarray)
that can be used to supply pre-extracted NetCDF variables to the that can be used to supply pre-extracted NetCDF variables to the
computational routines. It is primarily used for internal computational routines. It is primarily used for internal
purposes, but can also be used to improve performance by purposes, but can also be used to improve performance by
eliminating the need to repeatedly extract the same variables eliminating the need to repeatedly extract the same variables
used in multiple diagnostics calculations, particularly when using used in multiple diagnostics calculations, particularly when using
large sequences of files. large sequences of files.
Default is None. Default is None.
meta (:obj:`bool`, optional): Set to False to disable metadata and meta (:obj:`bool`, optional): Set to False to disable metadata and
return :class:`numpy.ndarray` instead of return :class:`numpy.ndarray` instead of
:class:`xarray.DataArray`. Default is True. :class:`xarray.DataArray`. Default is True.
_key (:obj:`int`, optional): A caching key. This is used for internal _key (:obj:`int`, optional): A caching key. This is used for internal
purposes only. Default is None. purposes only. Default is None.
top (:obj:`float`, optional): The top of the integration in [m]. top (:obj:`float`, optional): The top of the integration in [m].
Default is 3000.0. Default is 3000.0.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The :class:`xarray.DataArray` or :class:`numpy.ndarray`: The
storm relative helicity. storm relative helicity.
If xarray is enabled and the *meta* parameter is True, then the result If xarray is enabled and the *meta* parameter is True, then the result
will be a :class:`xarray.DataArray` object. Otherwise, the result will will be a :class:`xarray.DataArray` object. Otherwise, the result will
be a :class:`numpy.ndarray` object with no metadata. be a :class:`numpy.ndarray` object with no metadata.
""" """
# Top can either be 3000 or 1000 (for 0-1 srh or 0-3 srh) # Top can either be 3000 or 1000 (for 0-1 srh or 0-3 srh)
lats = get_lat(wrfin, timeidx, method, squeeze, lats = get_lat(wrfin, timeidx, method, squeeze,
cache, meta=False, _key=_key, stagger=None) cache, meta=False, _key=_key, stagger=None)
ncvars = extract_vars(wrfin, timeidx, ("HGT", "PH", "PHB"), ncvars = extract_vars(wrfin, timeidx, ("HGT", "PH", "PHB"),
method, squeeze, cache, meta=False, method, squeeze, cache, meta=False,
_key=_key) _key=_key)
ter = ncvars["HGT"] ter = ncvars["HGT"]
ph = ncvars["PH"] ph = ncvars["PH"]
phb = ncvars["PHB"] phb = ncvars["PHB"]
# As coded in NCL, but not sure this is possible # As coded in NCL, but not sure this is possible
varname = either("U", "UU")(wrfin) varname = either("U", "UU")(wrfin)
u_vars = extract_vars(wrfin, timeidx, varname, method, squeeze, cache, u_vars = extract_vars(wrfin, timeidx, varname, method, squeeze, cache,
meta=False, _key=_key) meta=False, _key=_key)
u = destagger(u_vars[varname], -1) u = destagger(u_vars[varname], -1)
varname = either("V", "VV")(wrfin) varname = either("V", "VV")(wrfin)
v_vars = extract_vars(wrfin, timeidx, varname, method, squeeze, cache, v_vars = extract_vars(wrfin, timeidx, varname, method, squeeze, cache,
meta=False, _key=_key) meta=False, _key=_key)
@ -97,117 +98,113 @@ def get_srh(wrfin, timeidx=0, method="cat", squeeze=True,
geopt = ph + phb geopt = ph + phb
geopt_unstag = destagger(geopt, -3) geopt_unstag = destagger(geopt, -3)
z = geopt_unstag / Constants.G z = geopt_unstag / Constants.G
# Re-ordering from high to low # Re-ordering from high to low
u1 = np.ascontiguousarray(u[...,::-1,:,:]) u1 = np.ascontiguousarray(u[...,::-1,:,:])
v1 = np.ascontiguousarray(v[...,::-1,:,:]) v1 = np.ascontiguousarray(v[...,::-1,:,:])
z1 = np.ascontiguousarray(z[...,::-1,:,:]) z1 = np.ascontiguousarray(z[...,::-1,:,:])
srh = _srhel(u1, v1, z1, ter, lats, top) srh = _srhel(u1, v1, z1, ter, lats, top)
return srh return srh
@copy_and_set_metadata(copy_varname="MAPFAC_M", name="updraft_helicity", @copy_and_set_metadata(copy_varname="MAPFAC_M", name="updraft_helicity",
description="updraft helicity", description="updraft helicity",
units="m2 s-2") units="m2 s-2")
def get_uh(wrfin, timeidx=0, method="cat", squeeze=True, def get_uh(wrfin, timeidx=0, method="cat", squeeze=True,
cache=None, meta=True, _key=None, cache=None, meta=True, _key=None,
bottom=2000.0, top=5000.0): bottom=2000.0, top=5000.0):
"""Return the updraft helicity. """Return the updraft helicity.
The *bottom* and *top* arguments specify the bottom and top limits The *bottom* and *top* arguments specify the bottom and top limits
for the integration in [m]. for the integration in [m].
This functions extracts the necessary variables from the NetCDF file This functions extracts the necessary variables from the NetCDF file
object in order to perform the calculation. object in order to perform the calculation.
Args: Args:
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \
iterable): WRF-ARW NetCDF iterable): WRF-ARW NetCDF
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile`
or an iterable sequence of the aforementioned types. or an iterable sequence of the aforementioned types.
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The
desired time index. This value can be a positive integer, desired time index. This value can be a positive integer,
negative integer, or negative integer, or
:data:`wrf.ALL_TIMES` (an alias for None) to return :data:`wrf.ALL_TIMES` (an alias for None) to return
all times in the file or sequence. The default is 0. all times in the file or sequence. The default is 0.
method (:obj:`str`, optional): The aggregation method to use for method (:obj:`str`, optional): The aggregation method to use for
sequences. Must be either 'cat' or 'join'. sequences. Must be either 'cat' or 'join'.
'cat' combines the data along the Time dimension. 'cat' combines the data along the Time dimension.
'join' creates a new dimension for the file index. 'join' creates a new dimension for the file index.
The default is 'cat'. The default is 'cat'.
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions squeeze (:obj:`bool`, optional): Set to False to prevent dimensions
with a size of 1 from being automatically removed from the shape with a size of 1 from being automatically removed from the shape
of the output. Default is True. of the output. Default is True.
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) cache (:obj:`dict`, optional): A dictionary of (varname, ndarray)
that can be used to supply pre-extracted NetCDF variables to the that can be used to supply pre-extracted NetCDF variables to the
computational routines. It is primarily used for internal computational routines. It is primarily used for internal
purposes, but can also be used to improve performance by purposes, but can also be used to improve performance by
eliminating the need to repeatedly extract the same variables eliminating the need to repeatedly extract the same variables
used in multiple diagnostics calculations, particularly when using used in multiple diagnostics calculations, particularly when using
large sequences of files. large sequences of files.
Default is None. Default is None.
meta (:obj:`bool`, optional): Set to False to disable metadata and meta (:obj:`bool`, optional): Set to False to disable metadata and
return :class:`numpy.ndarray` instead of return :class:`numpy.ndarray` instead of
:class:`xarray.DataArray`. Default is True. :class:`xarray.DataArray`. Default is True.
_key (:obj:`int`, optional): A caching key. This is used for internal _key (:obj:`int`, optional): A caching key. This is used for internal
purposes only. Default is None. purposes only. Default is None.
bottom (:obj:`float`, optional): The bottom limit for the integration bottom (:obj:`float`, optional): The bottom limit for the integration
in [m]. Default is 2000.0. in [m]. Default is 2000.0.
top (:obj:`float`, optional): The top limit for the integration in [m]. top (:obj:`float`, optional): The top limit for the integration in [m].
Default is 5000.0. Default is 5000.0.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The :class:`xarray.DataArray` or :class:`numpy.ndarray`: The
updraft helicity. updraft helicity.
If xarray is enabled and the *meta* parameter is True, then the result If xarray is enabled and the *meta* parameter is True, then the result
will be a :class:`xarray.DataArray` object. Otherwise, the result will will be a :class:`xarray.DataArray` object. Otherwise, the result will
be a :class:`numpy.ndarray` object with no metadata. be a :class:`numpy.ndarray` object with no metadata.
""" """
ncvars = extract_vars(wrfin, timeidx, ("W", "PH", "PHB", "MAPFAC_M"), ncvars = extract_vars(wrfin, timeidx, ("W", "PH", "PHB", "MAPFAC_M"),
method, squeeze, cache, meta=False, _key=_key) method, squeeze, cache, meta=False, _key=_key)
wstag = ncvars["W"] wstag = ncvars["W"]
ph = ncvars["PH"] ph = ncvars["PH"]
phb = ncvars["PHB"] phb = ncvars["PHB"]
mapfct = ncvars["MAPFAC_M"] mapfct = ncvars["MAPFAC_M"]
attrs = extract_global_attrs(wrfin, attrs=("DX", "DY")) attrs = extract_global_attrs(wrfin, attrs=("DX", "DY"))
dx = attrs["DX"] dx = attrs["DX"]
dy = attrs["DY"] dy = attrs["DY"]
# As coded in NCL, but not sure this is possible # As coded in NCL, but not sure this is possible
varname = either("U", "UU")(wrfin) varname = either("U", "UU")(wrfin)
u_vars = extract_vars(wrfin, timeidx, varname, method, squeeze, cache, u_vars = extract_vars(wrfin, timeidx, varname, method, squeeze, cache,
meta=False, _key=_key) meta=False, _key=_key)
u = destagger(u_vars[varname], -1) u = destagger(u_vars[varname], -1)
varname = either("V", "VV")(wrfin) varname = either("V", "VV")(wrfin)
v_vars = extract_vars(wrfin, timeidx, varname, method, squeeze, cache, v_vars = extract_vars(wrfin, timeidx, varname, method, squeeze, cache,
meta=False, _key=_key) meta=False, _key=_key)
v = destagger(v_vars[varname], -2) v = destagger(v_vars[varname], -2)
zp = (ph + phb) / Constants.G zp = (ph + phb) / Constants.G
uh = _udhel(zp, mapfct, u, v, wstag, dx, dy, bottom, top) uh = _udhel(zp, mapfct, u, v, wstag, dx, dy, bottom, top)
return uh
return uh

816
src/wrf/g_latlon.py

File diff suppressed because it is too large Load Diff

87
src/wrf/g_omega.py

@ -7,64 +7,64 @@ from .util import extract_vars
from .metadecorators import copy_and_set_metadata from .metadecorators import copy_and_set_metadata
@copy_and_set_metadata(copy_varname="T", name="omega", @copy_and_set_metadata(copy_varname="T", name="omega",
description="omega", description="omega",
units="Pa s-1") units="Pa s-1")
def get_omega(wrfin, timeidx=0, method="cat", squeeze=True, cache=None, def get_omega(wrfin, timeidx=0, method="cat", squeeze=True, cache=None,
meta=True, _key=None): meta=True, _key=None):
"""Return Omega. """Return Omega.
This functions extracts the necessary variables from the NetCDF file This functions extracts the necessary variables from the NetCDF file
object in order to perform the calculation. object in order to perform the calculation.
Args: Args:
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \
iterable): WRF-ARW NetCDF iterable): WRF-ARW NetCDF
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile`
or an iterable sequence of the aforementioned types. or an iterable sequence of the aforementioned types.
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The
desired time index. This value can be a positive integer, desired time index. This value can be a positive integer,
negative integer, or negative integer, or
:data:`wrf.ALL_TIMES` (an alias for None) to return :data:`wrf.ALL_TIMES` (an alias for None) to return
all times in the file or sequence. The default is 0. all times in the file or sequence. The default is 0.
method (:obj:`str`, optional): The aggregation method to use for method (:obj:`str`, optional): The aggregation method to use for
sequences. Must be either 'cat' or 'join'. sequences. Must be either 'cat' or 'join'.
'cat' combines the data along the Time dimension. 'cat' combines the data along the Time dimension.
'join' creates a new dimension for the file index. 'join' creates a new dimension for the file index.
The default is 'cat'. The default is 'cat'.
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions squeeze (:obj:`bool`, optional): Set to False to prevent dimensions
with a size of 1 from being automatically removed from the shape with a size of 1 from being automatically removed from the shape
of the output. Default is True. of the output. Default is True.
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) cache (:obj:`dict`, optional): A dictionary of (varname, ndarray)
that can be used to supply pre-extracted NetCDF variables to the that can be used to supply pre-extracted NetCDF variables to the
computational routines. It is primarily used for internal computational routines. It is primarily used for internal
purposes, but can also be used to improve performance by purposes, but can also be used to improve performance by
eliminating the need to repeatedly extract the same variables eliminating the need to repeatedly extract the same variables
used in multiple diagnostics calculations, particularly when using used in multiple diagnostics calculations, particularly when using
large sequences of files. large sequences of files.
Default is None. Default is None.
meta (:obj:`bool`, optional): Set to False to disable metadata and meta (:obj:`bool`, optional): Set to False to disable metadata and
return :class:`numpy.ndarray` instead of return :class:`numpy.ndarray` instead of
:class:`xarray.DataArray`. Default is True. :class:`xarray.DataArray`. Default is True.
_key (:obj:`int`, optional): A caching key. This is used for internal _key (:obj:`int`, optional): A caching key. This is used for internal
purposes only. Default is None. purposes only. Default is None.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: Omega. :class:`xarray.DataArray` or :class:`numpy.ndarray`: Omega.
If xarray is If xarray is
enabled and the *meta* parameter is True, then the result will be a enabled and the *meta* parameter is True, then the result will be a
:class:`xarray.DataArray` object. Otherwise, the result will be a :class:`xarray.DataArray` object. Otherwise, the result will be a
:class:`numpy.ndarray` object with no metadata. :class:`numpy.ndarray` object with no metadata.
""" """
varnames=("T", "P", "W", "PB", "QVAPOR") varnames = ("T", "P", "W", "PB", "QVAPOR")
ncvars = extract_vars(wrfin, timeidx, varnames, method, squeeze, cache, ncvars = extract_vars(wrfin, timeidx, varnames, method, squeeze, cache,
meta=False, _key=_key) meta=False, _key=_key)
t = ncvars["T"] t = ncvars["T"]
@ -72,13 +72,12 @@ def get_omega(wrfin, timeidx=0, method="cat", squeeze=True, cache=None,
w = ncvars["W"] w = ncvars["W"]
pb = ncvars["PB"] pb = ncvars["PB"]
qv = ncvars["QVAPOR"] qv = ncvars["QVAPOR"]
wa = destagger(w, -3) wa = destagger(w, -3)
full_t = t + Constants.T_BASE full_t = t + Constants.T_BASE
full_p = p + pb full_p = p + pb
tk = _tk(full_p, full_t) tk = _tk(full_p, full_t)
omega = _omega(qv, tk, wa, full_p) omega = _omega(qv, tk, wa, full_p)
return omega return omega

12
src/wrf/g_precip.py

@ -2,29 +2,29 @@ from __future__ import (absolute_import, division, print_function)
from .util import extract_vars from .util import extract_vars
__all__ = ["get_accum_precip", "get_precip_diff"]
def get_accum_precip(wrfin, timeidx=0): def get_accum_precip(wrfin, timeidx=0):
ncvars = extract_vars(wrfin, timeidx, varnames=("RAINC", "RAINNC")) ncvars = extract_vars(wrfin, timeidx, varnames=("RAINC", "RAINNC"))
rainc = ncvars["RAINC"] rainc = ncvars["RAINC"]
rainnc = ncvars["RAINNC"] rainnc = ncvars["RAINNC"]
rainsum = rainc + rainnc rainsum = rainc + rainnc
return rainsum return rainsum
def get_precip_diff(wrfin1, wrfin2, timeidx=0): def get_precip_diff(wrfin1, wrfin2, timeidx=0):
vars1 = extract_vars(wrfin1, timeidx, varnames=("RAINC", "RAINNC")) vars1 = extract_vars(wrfin1, timeidx, varnames=("RAINC", "RAINNC"))
vars2 = extract_vars(wrfin2, timeidx, varnames=("RAINC", "RAINNC")) vars2 = extract_vars(wrfin2, timeidx, varnames=("RAINC", "RAINNC"))
rainc1 = vars1["RAINC"] rainc1 = vars1["RAINC"]
rainnc1 = vars1["RAINNC"] rainnc1 = vars1["RAINNC"]
rainc2 = vars2["RAINC"] rainc2 = vars2["RAINC"]
rainnc2 = vars2["RAINNC"] rainnc2 = vars2["RAINNC"]
rainsum1 = rainc1 + rainnc1 rainsum1 = rainc1 + rainnc1
rainsum2 = rainc2 + rainnc2 rainsum2 = rainc2 + rainnc2
return (rainsum1 - rainsum2) return (rainsum1 - rainsum2)
# TODO: Handle bucket flipping # TODO: Handle bucket flipping

183
src/wrf/g_pressure.py

@ -5,144 +5,141 @@ from .metadecorators import copy_and_set_metadata
from .util import extract_vars, either from .util import extract_vars, either
@copy_and_set_metadata(copy_varname=either("P", "PRES"), name="pressure", @copy_and_set_metadata(copy_varname=either("P", "PRES"), name="pressure",
description="pressure") description="pressure")
@convert_units("pressure", "pa") @convert_units("pressure", "pa")
def get_pressure(wrfin, timeidx=0, method="cat", squeeze=True, def get_pressure(wrfin, timeidx=0, method="cat", squeeze=True,
cache=None, meta=True, _key=None, cache=None, meta=True, _key=None,
units="Pa"): units="Pa"):
"""Return the pressure in the specified units. """Return the pressure in the specified units.
This functions extracts the necessary variables from the NetCDF file This functions extracts the necessary variables from the NetCDF file
object in order to perform the calculation. object in order to perform the calculation.
Args: Args:
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \
iterable): WRF-ARW NetCDF iterable): WRF-ARW NetCDF
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile`
or an iterable sequence of the aforementioned types. or an iterable sequence of the aforementioned types.
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The
desired time index. This value can be a positive integer, desired time index. This value can be a positive integer,
negative integer, or negative integer, or
:data:`wrf.ALL_TIMES` (an alias for None) to return :data:`wrf.ALL_TIMES` (an alias for None) to return
all times in the file or sequence. The default is 0. all times in the file or sequence. The default is 0.
method (:obj:`str`, optional): The aggregation method to use for method (:obj:`str`, optional): The aggregation method to use for
sequences. Must be either 'cat' or 'join'. sequences. Must be either 'cat' or 'join'.
'cat' combines the data along the Time dimension. 'cat' combines the data along the Time dimension.
'join' creates a new dimension for the file index. 'join' creates a new dimension for the file index.
The default is 'cat'. The default is 'cat'.
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions squeeze (:obj:`bool`, optional): Set to False to prevent dimensions
with a size of 1 from being automatically removed from the shape with a size of 1 from being automatically removed from the shape
of the output. Default is True. of the output. Default is True.
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) cache (:obj:`dict`, optional): A dictionary of (varname, ndarray)
that can be used to supply pre-extracted NetCDF variables to the that can be used to supply pre-extracted NetCDF variables to the
computational routines. It is primarily used for internal computational routines. It is primarily used for internal
purposes, but can also be used to improve performance by purposes, but can also be used to improve performance by
eliminating the need to repeatedly extract the same variables eliminating the need to repeatedly extract the same variables
used in multiple diagnostics calculations, particularly when using used in multiple diagnostics calculations, particularly when using
large sequences of files. large sequences of files.
Default is None. Default is None.
meta (:obj:`bool`, optional): Set to False to disable metadata and meta (:obj:`bool`, optional): Set to False to disable metadata and
return :class:`numpy.ndarray` instead of return :class:`numpy.ndarray` instead of
:class:`xarray.DataArray`. Default is True. :class:`xarray.DataArray`. Default is True.
_key (:obj:`int`, optional): A caching key. This is used for internal _key (:obj:`int`, optional): A caching key. This is used for internal
purposes only. Default is None. purposes only. Default is None.
units (:obj:`str`): The desired units. Refer to the :meth:`getvar` units (:obj:`str`): The desired units. Refer to the :meth:`getvar`
product table for a list of available units for 'pres'. Default product table for a list of available units for 'pres'. Default
is 'Pa'. is 'Pa'.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The pressure in :class:`xarray.DataArray` or :class:`numpy.ndarray`: The pressure in
the specified units. the specified units.
If xarray is If xarray is
enabled and the *meta* parameter is True, then the result will be a enabled and the *meta* parameter is True, then the result will be a
:class:`xarray.DataArray` object. Otherwise, the result will be a :class:`xarray.DataArray` object. Otherwise, the result will be a
:class:`numpy.ndarray` object with no metadata. :class:`numpy.ndarray` object with no metadata.
""" """
varname = either("P", "PRES")(wrfin) varname = either("P", "PRES")(wrfin)
if varname == "P": if varname == "P":
p_vars = extract_vars(wrfin, timeidx, ("P", "PB"), p_vars = extract_vars(wrfin, timeidx, ("P", "PB"),
method, squeeze, cache, meta=False, method, squeeze, cache, meta=False,
_key=_key) _key=_key)
p = p_vars["P"] p = p_vars["P"]
pb = p_vars["PB"] pb = p_vars["PB"]
pres = p + pb pres = p + pb
else: else:
pres = extract_vars(wrfin, timeidx, "PRES", pres = extract_vars(wrfin, timeidx, "PRES",
method, squeeze, cache, meta=False, method, squeeze, cache, meta=False,
_key=_key)["PRES"] _key=_key)["PRES"]
return pres return pres
def get_pressure_hpa(wrfin, timeidx=0, method="cat", squeeze=True,
def get_pressure_hpa(wrfin, timeidx=0, method="cat", squeeze=True,
cache=None, meta=True, _key=None): cache=None, meta=True, _key=None):
"""Return the pressure in [hPa]. """Return the pressure in [hPa].
This functions extracts the necessary variables from the NetCDF file This functions extracts the necessary variables from the NetCDF file
object in order to perform the calculation. object in order to perform the calculation.
Args: Args:
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \
iterable): WRF-ARW NetCDF iterable): WRF-ARW NetCDF
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile`
or an iterable sequence of the aforementioned types. or an iterable sequence of the aforementioned types.
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The
desired time index. This value can be a positive integer, desired time index. This value can be a positive integer,
negative integer, or negative integer, or
:data:`wrf.ALL_TIMES` (an alias for None) to return :data:`wrf.ALL_TIMES` (an alias for None) to return
all times in the file or sequence. The default is 0. all times in the file or sequence. The default is 0.
method (:obj:`str`, optional): The aggregation method to use for method (:obj:`str`, optional): The aggregation method to use for
sequences. Must be either 'cat' or 'join'. sequences. Must be either 'cat' or 'join'.
'cat' combines the data along the Time dimension. 'cat' combines the data along the Time dimension.
'join' creates a new dimension for the file index. 'join' creates a new dimension for the file index.
The default is 'cat'. The default is 'cat'.
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions squeeze (:obj:`bool`, optional): Set to False to prevent dimensions
with a size of 1 from being automatically removed from the shape with a size of 1 from being automatically removed from the shape
of the output. Default is True. of the output. Default is True.
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) cache (:obj:`dict`, optional): A dictionary of (varname, ndarray)
that can be used to supply pre-extracted NetCDF variables to the that can be used to supply pre-extracted NetCDF variables to the
computational routines. It is primarily used for internal computational routines. It is primarily used for internal
purposes, but can also be used to improve performance by purposes, but can also be used to improve performance by
eliminating the need to repeatedly extract the same variables eliminating the need to repeatedly extract the same variables
used in multiple diagnostics calculations, particularly when using used in multiple diagnostics calculations, particularly when using
large sequences of files. large sequences of files.
Default is None. Default is None.
meta (:obj:`bool`, optional): Set to False to disable metadata and meta (:obj:`bool`, optional): Set to False to disable metadata and
return :class:`numpy.ndarray` instead of return :class:`numpy.ndarray` instead of
:class:`xarray.DataArray`. Default is True. :class:`xarray.DataArray`. Default is True.
_key (:obj:`int`, optional): A caching key. This is used for internal _key (:obj:`int`, optional): A caching key. This is used for internal
purposes only. Default is None. purposes only. Default is None.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The pressure in :class:`xarray.DataArray` or :class:`numpy.ndarray`: The pressure in
[hPa]. [hPa].
If xarray is If xarray is
enabled and the *meta* parameter is True, then the result will be a enabled and the *meta* parameter is True, then the result will be a
:class:`xarray.DataArray` object. Otherwise, the result will be a :class:`xarray.DataArray` object. Otherwise, the result will be a
:class:`numpy.ndarray` object with no metadata. :class:`numpy.ndarray` object with no metadata.
""" """
return get_pressure(wrfin, timeidx, method, squeeze, cache, meta, _key, return get_pressure(wrfin, timeidx, method, squeeze, cache, meta, _key,
units="hPa") units="hPa")

95
src/wrf/g_pw.py

@ -1,91 +1,86 @@
from __future__ import (absolute_import, division, print_function) from __future__ import (absolute_import, division, print_function)
#from .extension import computepw,computetv,computetk
from .extension import _pw, _tv, _tk from .extension import _pw, _tv, _tk
from .constants import Constants from .constants import Constants
from .util import extract_vars from .util import extract_vars
from .metadecorators import copy_and_set_metadata from .metadecorators import copy_and_set_metadata
@copy_and_set_metadata(copy_varname="T", name="pw", @copy_and_set_metadata(copy_varname="T", name="pw",
remove_dims=("bottom_top",), remove_dims=("bottom_top",),
description="precipitable water", description="precipitable water",
MemoryOrder="XY", MemoryOrder="XY",
units="kg m-2") units="kg m-2")
def get_pw(wrfin, timeidx=0, method="cat", squeeze=True, cache=None, def get_pw(wrfin, timeidx=0, method="cat", squeeze=True, cache=None,
meta=True, _key=None): meta=True, _key=None):
"""Return the preciptiable water. """Return the preciptiable water.
This functions extracts the necessary variables from the NetCDF file This functions extracts the necessary variables from the NetCDF file
object in order to perform the calculation. object in order to perform the calculation.
Args: Args:
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \
iterable): WRF-ARW NetCDF iterable): WRF-ARW NetCDF
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile`
or an iterable sequence of the aforementioned types. or an iterable sequence of the aforementioned types.
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The
desired time index. This value can be a positive integer, desired time index. This value can be a positive integer,
negative integer, or negative integer, or
:data:`wrf.ALL_TIMES` (an alias for None) to return :data:`wrf.ALL_TIMES` (an alias for None) to return
all times in the file or sequence. The default is 0. all times in the file or sequence. The default is 0.
method (:obj:`str`, optional): The aggregation method to use for method (:obj:`str`, optional): The aggregation method to use for
sequences. Must be either 'cat' or 'join'. sequences. Must be either 'cat' or 'join'.
'cat' combines the data along the Time dimension. 'cat' combines the data along the Time dimension.
'join' creates a new dimension for the file index. 'join' creates a new dimension for the file index.
The default is 'cat'. The default is 'cat'.
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions squeeze (:obj:`bool`, optional): Set to False to prevent dimensions
with a size of 1 from being automatically removed from the shape with a size of 1 from being automatically removed from the shape
of the output. Default is True. of the output. Default is True.
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) cache (:obj:`dict`, optional): A dictionary of (varname, ndarray)
that can be used to supply pre-extracted NetCDF variables to the that can be used to supply pre-extracted NetCDF variables to the
computational routines. It is primarily used for internal computational routines. It is primarily used for internal
purposes, but can also be used to improve performance by purposes, but can also be used to improve performance by
eliminating the need to repeatedly extract the same variables eliminating the need to repeatedly extract the same variables
used in multiple diagnostics calculations, particularly when using used in multiple diagnostics calculations, particularly when using
large sequences of files. large sequences of files.
Default is None. Default is None.
meta (:obj:`bool`, optional): Set to False to disable metadata and meta (:obj:`bool`, optional): Set to False to disable metadata and
return :class:`numpy.ndarray` instead of return :class:`numpy.ndarray` instead of
:class:`xarray.DataArray`. Default is True. :class:`xarray.DataArray`. Default is True.
_key (:obj:`int`, optional): A caching key. This is used for internal _key (:obj:`int`, optional): A caching key. This is used for internal
purposes only. Default is None. purposes only. Default is None.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The preciptable :class:`xarray.DataArray` or :class:`numpy.ndarray`: The preciptable
water. If xarray is water. If xarray is
enabled and the *meta* parameter is True, then the result will be a enabled and the *meta* parameter is True, then the result will be a
:class:`xarray.DataArray` object. Otherwise, the result will be a :class:`xarray.DataArray` object. Otherwise, the result will be a
:class:`numpy.ndarray` object with no metadata. :class:`numpy.ndarray` object with no metadata.
""" """
varnames=("T", "P", "PB", "PH", "PHB", "QVAPOR") varnames = ("T", "P", "PB", "PH", "PHB", "QVAPOR")
ncvars = extract_vars(wrfin, timeidx, varnames, method, squeeze, cache, ncvars = extract_vars(wrfin, timeidx, varnames, method, squeeze, cache,
meta=False, _key=_key) meta=False, _key=_key)
t = ncvars["T"] t = ncvars["T"]
p = ncvars["P"] p = ncvars["P"]
pb = ncvars["PB"] pb = ncvars["PB"]
ph = ncvars["PH"] ph = ncvars["PH"]
phb = ncvars["PHB"] phb = ncvars["PHB"]
qv = ncvars["QVAPOR"] qv = ncvars["QVAPOR"]
full_p = p + pb full_p = p + pb
ht = (ph + phb)/Constants.G ht = (ph + phb)/Constants.G
full_t = t + Constants.T_BASE full_t = t + Constants.T_BASE
tk = _tk(full_p, full_t) tk = _tk(full_p, full_t)
tv = _tv(tk, qv) tv = _tv(tk, qv)
return _pw(full_p, tv, qv, ht) return _pw(full_p, tv, qv, ht)

176
src/wrf/g_rh.py

@ -1,156 +1,154 @@
from __future__ import (absolute_import, division, print_function) from __future__ import (absolute_import, division, print_function)
from .constants import Constants from .constants import Constants
#from .extension import computerh, computetk
from .extension import _rh, _tk from .extension import _rh, _tk
from .util import extract_vars from .util import extract_vars
from .metadecorators import copy_and_set_metadata from .metadecorators import copy_and_set_metadata
@copy_and_set_metadata(copy_varname="T", name="rh", @copy_and_set_metadata(copy_varname="T", name="rh",
description="relative humidity", description="relative humidity",
units="%") units="%")
def get_rh(wrfin, timeidx=0, method="cat", squeeze=True, cache=None, def get_rh(wrfin, timeidx=0, method="cat", squeeze=True, cache=None,
meta=True, _key=None): meta=True, _key=None):
"""Return the relative humidity. """Return the relative humidity.
This functions extracts the necessary variables from the NetCDF file This functions extracts the necessary variables from the NetCDF file
object in order to perform the calculation. object in order to perform the calculation.
Args: Args:
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \
iterable): WRF-ARW NetCDF iterable): WRF-ARW NetCDF
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile`
or an iterable sequence of the aforementioned types. or an iterable sequence of the aforementioned types.
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The
desired time index. This value can be a positive integer, desired time index. This value can be a positive integer,
negative integer, or negative integer, or
:data:`wrf.ALL_TIMES` (an alias for None) to return :data:`wrf.ALL_TIMES` (an alias for None) to return
all times in the file or sequence. The default is 0. all times in the file or sequence. The default is 0.
method (:obj:`str`, optional): The aggregation method to use for method (:obj:`str`, optional): The aggregation method to use for
sequences. Must be either 'cat' or 'join'. sequences. Must be either 'cat' or 'join'.
'cat' combines the data along the Time dimension. 'cat' combines the data along the Time dimension.
'join' creates a new dimension for the file index. 'join' creates a new dimension for the file index.
The default is 'cat'. The default is 'cat'.
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions squeeze (:obj:`bool`, optional): Set to False to prevent dimensions
with a size of 1 from being automatically removed from the shape with a size of 1 from being automatically removed from the shape
of the output. Default is True. of the output. Default is True.
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) cache (:obj:`dict`, optional): A dictionary of (varname, ndarray)
that can be used to supply pre-extracted NetCDF variables to the that can be used to supply pre-extracted NetCDF variables to the
computational routines. It is primarily used for internal computational routines. It is primarily used for internal
purposes, but can also be used to improve performance by purposes, but can also be used to improve performance by
eliminating the need to repeatedly extract the same variables eliminating the need to repeatedly extract the same variables
used in multiple diagnostics calculations, particularly when using used in multiple diagnostics calculations, particularly when using
large sequences of files. large sequences of files.
Default is None. Default is None.
meta (:obj:`bool`, optional): Set to False to disable metadata and meta (:obj:`bool`, optional): Set to False to disable metadata and
return :class:`numpy.ndarray` instead of return :class:`numpy.ndarray` instead of
:class:`xarray.DataArray`. Default is True. :class:`xarray.DataArray`. Default is True.
_key (:obj:`int`, optional): A caching key. This is used for internal _key (:obj:`int`, optional): A caching key. This is used for internal
purposes only. Default is None. purposes only. Default is None.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The relative :class:`xarray.DataArray` or :class:`numpy.ndarray`: The relative
humidity. If xarray is humidity. If xarray is
enabled and the *meta* parameter is True, then the result will be a enabled and the *meta* parameter is True, then the result will be a
:class:`xarray.DataArray` object. Otherwise, the result will be a :class:`xarray.DataArray` object. Otherwise, the result will be a
:class:`numpy.ndarray` object with no metadata. :class:`numpy.ndarray` object with no metadata.
""" """
varnames=("T", "P", "PB", "QVAPOR") varnames = ("T", "P", "PB", "QVAPOR")
ncvars = extract_vars(wrfin, timeidx, varnames, method, squeeze, cache, ncvars = extract_vars(wrfin, timeidx, varnames, method, squeeze, cache,
meta=False, _key=_key) meta=False, _key=_key)
t = ncvars["T"] t = ncvars["T"]
p = ncvars["P"] p = ncvars["P"]
pb = ncvars["PB"] pb = ncvars["PB"]
# Copy needed for the mmap nonsense of scipy.io.netcdf, which seems to # Copy needed for the mmap nonsense of scipy.io.netcdf, which seems to
# break with every release # break with every release
qvapor = ncvars["QVAPOR"].copy() qvapor = ncvars["QVAPOR"].copy()
full_t = t + Constants.T_BASE full_t = t + Constants.T_BASE
full_p = p + pb full_p = p + pb
qvapor[qvapor < 0] = 0 qvapor[qvapor < 0] = 0
tk = _tk(full_p, full_t) tk = _tk(full_p, full_t)
rh = _rh(qvapor, full_p, tk) rh = _rh(qvapor, full_p, tk)
return rh return rh
@copy_and_set_metadata(copy_varname="T2", name="rh2", @copy_and_set_metadata(copy_varname="T2", name="rh2",
description="2m relative humidity", description="2m relative humidity",
units="%") units="%")
def get_rh_2m(wrfin, timeidx=0, method="cat", squeeze=True, cache=None, def get_rh_2m(wrfin, timeidx=0, method="cat", squeeze=True, cache=None,
meta=True, _key=None): meta=True, _key=None):
"""Return the 2m relative humidity. """Return the 2m relative humidity.
This functions extracts the necessary variables from the NetCDF file This functions extracts the necessary variables from the NetCDF file
object in order to perform the calculation. object in order to perform the calculation.
Args: Args:
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \
iterable): WRF-ARW NetCDF iterable): WRF-ARW NetCDF
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile`
or an iterable sequence of the aforementioned types. or an iterable sequence of the aforementioned types.
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The
desired time index. This value can be a positive integer, desired time index. This value can be a positive integer,
negative integer, or negative integer, or
:data:`wrf.ALL_TIMES` (an alias for None) to return :data:`wrf.ALL_TIMES` (an alias for None) to return
all times in the file or sequence. The default is 0. all times in the file or sequence. The default is 0.
method (:obj:`str`, optional): The aggregation method to use for method (:obj:`str`, optional): The aggregation method to use for
sequences. Must be either 'cat' or 'join'. sequences. Must be either 'cat' or 'join'.
'cat' combines the data along the Time dimension. 'cat' combines the data along the Time dimension.
'join' creates a new dimension for the file index. 'join' creates a new dimension for the file index.
The default is 'cat'. The default is 'cat'.
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions squeeze (:obj:`bool`, optional): Set to False to prevent dimensions
with a size of 1 from being automatically removed from the shape with a size of 1 from being automatically removed from the shape
of the output. Default is True. of the output. Default is True.
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) cache (:obj:`dict`, optional): A dictionary of (varname, ndarray)
that can be used to supply pre-extracted NetCDF variables to the that can be used to supply pre-extracted NetCDF variables to the
computational routines. It is primarily used for internal computational routines. It is primarily used for internal
purposes, but can also be used to improve performance by purposes, but can also be used to improve performance by
eliminating the need to repeatedly extract the same variables eliminating the need to repeatedly extract the same variables
used in multiple diagnostics calculations, particularly when using used in multiple diagnostics calculations, particularly when using
large sequences of files. large sequences of files.
Default is None. Default is None.
meta (:obj:`bool`, optional): Set to False to disable metadata and meta (:obj:`bool`, optional): Set to False to disable metadata and
return :class:`numpy.ndarray` instead of return :class:`numpy.ndarray` instead of
:class:`xarray.DataArray`. Default is True. :class:`xarray.DataArray`. Default is True.
_key (:obj:`int`, optional): A caching key. This is used for internal _key (:obj:`int`, optional): A caching key. This is used for internal
purposes only. Default is None. purposes only. Default is None.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The 2m relative :class:`xarray.DataArray` or :class:`numpy.ndarray`: The 2m relative
humidity. If xarray is humidity. If xarray is
enabled and the *meta* parameter is True, then the result will be a enabled and the *meta* parameter is True, then the result will be a
:class:`xarray.DataArray` object. Otherwise, the result will be a :class:`xarray.DataArray` object. Otherwise, the result will be a
:class:`numpy.ndarray` object with no metadata. :class:`numpy.ndarray` object with no metadata.
""" """
varnames=("T2", "PSFC", "Q2") varnames = ("T2", "PSFC", "Q2")
ncvars = extract_vars(wrfin, timeidx, varnames, method, squeeze, cache, ncvars = extract_vars(wrfin, timeidx, varnames, method, squeeze, cache,
meta=False, _key=_key) meta=False, _key=_key)
t2 = ncvars["T2"] t2 = ncvars["T2"]
psfc = ncvars["PSFC"] psfc = ncvars["PSFC"]
# Copy needed for the mmap nonsense of scipy.io.netcdf, which seems to # Copy needed for the mmap nonsense of scipy.io.netcdf, which seems to
# break with every release # break with every release
q2 = ncvars["Q2"].copy() q2 = ncvars["Q2"].copy()
q2[q2 < 0] = 0 q2[q2 < 0] = 0
rh = _rh(q2, psfc, t2) rh = _rh(q2, psfc, t2)
return rh
return rh

106
src/wrf/g_slp.py

@ -1,6 +1,5 @@
from __future__ import (absolute_import, division, print_function) from __future__ import (absolute_import, division, print_function)
#from .extension import computeslp, computetk
from .extension import _slp, _tk from .extension import _slp, _tk
from .constants import Constants from .constants import Constants
from .destag import destagger from .destag import destagger
@ -10,94 +9,93 @@ from .util import extract_vars
@copy_and_set_metadata(copy_varname="T", name="slp", @copy_and_set_metadata(copy_varname="T", name="slp",
remove_dims=("bottom_top",), remove_dims=("bottom_top",),
description="sea level pressure", description="sea level pressure",
MemoryOrder="XY") MemoryOrder="XY")
@convert_units("pressure", "hpa") @convert_units("pressure", "hpa")
def get_slp(wrfin, timeidx=0, method="cat", squeeze=True, def get_slp(wrfin, timeidx=0, method="cat", squeeze=True,
cache=None, meta=True, _key=None, cache=None, meta=True, _key=None,
units="hPa"): units="hPa"):
"""Return the sea level pressure in the specified units. """Return the sea level pressure in the specified units.
This function extracts the necessary variables from the NetCDF file This function extracts the necessary variables from the NetCDF file
object in order to perform the calculation. object in order to perform the calculation.
Args: Args:
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \
iterable): WRF-ARW NetCDF iterable): WRF-ARW NetCDF
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile`
or an iterable sequence of the aforementioned types. or an iterable sequence of the aforementioned types.
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The
desired time index. This value can be a positive integer, desired time index. This value can be a positive integer,
negative integer, or negative integer, or
:data:`wrf.ALL_TIMES` (an alias for None) to return :data:`wrf.ALL_TIMES` (an alias for None) to return
all times in the file or sequence. The default is 0. all times in the file or sequence. The default is 0.
method (:obj:`str`, optional): The aggregation method to use for method (:obj:`str`, optional): The aggregation method to use for
sequences. Must be either 'cat' or 'join'. sequences. Must be either 'cat' or 'join'.
'cat' combines the data along the Time dimension. 'cat' combines the data along the Time dimension.
'join' creates a new dimension for the file index. 'join' creates a new dimension for the file index.
The default is 'cat'. The default is 'cat'.
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions squeeze (:obj:`bool`, optional): Set to False to prevent dimensions
with a size of 1 from being automatically removed from the shape with a size of 1 from being automatically removed from the shape
of the output. Default is True. of the output. Default is True.
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) cache (:obj:`dict`, optional): A dictionary of (varname, ndarray)
that can be used to supply pre-extracted NetCDF variables to the that can be used to supply pre-extracted NetCDF variables to the
computational routines. It is primarily used for internal computational routines. It is primarily used for internal
purposes, but can also be used to improve performance by purposes, but can also be used to improve performance by
eliminating the need to repeatedly extract the same variables eliminating the need to repeatedly extract the same variables
used in multiple diagnostics calculations, particularly when using used in multiple diagnostics calculations, particularly when using
large sequences of files. large sequences of files.
Default is None. Default is None.
meta (:obj:`bool`, optional): Set to False to disable metadata and meta (:obj:`bool`, optional): Set to False to disable metadata and
return :class:`numpy.ndarray` instead of return :class:`numpy.ndarray` instead of
:class:`xarray.DataArray`. Default is True. :class:`xarray.DataArray`. Default is True.
_key (:obj:`int`, optional): A caching key. This is used for internal _key (:obj:`int`, optional): A caching key. This is used for internal
purposes only. Default is None. purposes only. Default is None.
units (:obj:`str`): The desired units. Refer to the :meth:`getvar` units (:obj:`str`): The desired units. Refer to the :meth:`getvar`
product table for a list of available units for 'slp'. Default product table for a list of available units for 'slp'. Default
is 'Pa'. is 'Pa'.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The sea level :class:`xarray.DataArray` or :class:`numpy.ndarray`: The sea level
pressure in the specified units. If xarray is pressure in the specified units. If xarray is
enabled and the *meta* parameter is True, then the result will be a enabled and the *meta* parameter is True, then the result will be a
:class:`xarray.DataArray` object. Otherwise, the result will be a :class:`xarray.DataArray` object. Otherwise, the result will be a
:class:`numpy.ndarray` object with no metadata. :class:`numpy.ndarray` object with no metadata.
""" """
varnames=("T", "P", "PB", "QVAPOR", "PH", "PHB") varnames = ("T", "P", "PB", "QVAPOR", "PH", "PHB")
ncvars = extract_vars(wrfin, timeidx, varnames, method, squeeze, cache, ncvars = extract_vars(wrfin, timeidx, varnames, method, squeeze, cache,
meta=False, _key=_key) meta=False, _key=_key)
t = ncvars["T"] t = ncvars["T"]
p = ncvars["P"] p = ncvars["P"]
pb = ncvars["PB"] pb = ncvars["PB"]
# Copy needed for the mmap nonsense of scipy.io.netcdf, which seems to # Copy needed for the mmap nonsense of scipy.io.netcdf, which seems to
# break with every release # break with every release
qvapor = ncvars["QVAPOR"].copy() qvapor = ncvars["QVAPOR"].copy()
ph = ncvars["PH"] ph = ncvars["PH"]
phb = ncvars["PHB"] phb = ncvars["PHB"]
full_t = t + Constants.T_BASE full_t = t + Constants.T_BASE
full_p = p + pb full_p = p + pb
qvapor[qvapor < 0] = 0. qvapor[qvapor < 0] = 0.
full_ph = (ph + phb) / Constants.G full_ph = (ph + phb) / Constants.G
destag_ph = destagger(full_ph, -3) destag_ph = destagger(full_ph, -3)
tk = _tk(full_p, full_t) tk = _tk(full_p, full_t)
slp = _slp(destag_ph, tk, full_p, qvapor) slp = _slp(destag_ph, tk, full_p, qvapor)
return slp
return slp

623
src/wrf/g_temp.py

@ -7,70 +7,70 @@ from .metadecorators import copy_and_set_metadata
from .util import extract_vars from .util import extract_vars
@copy_and_set_metadata(copy_varname="T", name="theta", @copy_and_set_metadata(copy_varname="T", name="theta",
description="potential temperature") description="potential temperature")
@convert_units("temp", "k") @convert_units("temp", "k")
def get_theta(wrfin, timeidx=0, method="cat", squeeze=True, def get_theta(wrfin, timeidx=0, method="cat", squeeze=True,
cache=None, meta=True, _key=None, cache=None, meta=True, _key=None,
units="K"): units="K"):
"""Return the potential temperature. """Return the potential temperature.
This functions extracts the necessary variables from the NetCDF file This functions extracts the necessary variables from the NetCDF file
object in order to perform the calculation. object in order to perform the calculation.
Args: Args:
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \
iterable): WRF-ARW NetCDF iterable): WRF-ARW NetCDF
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile`
or an iterable sequence of the aforementioned types. or an iterable sequence of the aforementioned types.
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The
desired time index. This value can be a positive integer, desired time index. This value can be a positive integer,
negative integer, or negative integer, or
:data:`wrf.ALL_TIMES` (an alias for None) to return :data:`wrf.ALL_TIMES` (an alias for None) to return
all times in the file or sequence. The default is 0. all times in the file or sequence. The default is 0.
method (:obj:`str`, optional): The aggregation method to use for method (:obj:`str`, optional): The aggregation method to use for
sequences. Must be either 'cat' or 'join'. sequences. Must be either 'cat' or 'join'.
'cat' combines the data along the Time dimension. 'cat' combines the data along the Time dimension.
'join' creates a new dimension for the file index. 'join' creates a new dimension for the file index.
The default is 'cat'. The default is 'cat'.
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions squeeze (:obj:`bool`, optional): Set to False to prevent dimensions
with a size of 1 from being automatically removed from the shape with a size of 1 from being automatically removed from the shape
of the output. Default is True. of the output. Default is True.
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) cache (:obj:`dict`, optional): A dictionary of (varname, ndarray)
that can be used to supply pre-extracted NetCDF variables to the that can be used to supply pre-extracted NetCDF variables to the
computational routines. It is primarily used for internal computational routines. It is primarily used for internal
purposes, but can also be used to improve performance by purposes, but can also be used to improve performance by
eliminating the need to repeatedly extract the same variables eliminating the need to repeatedly extract the same variables
used in multiple diagnostics calculations, particularly when using used in multiple diagnostics calculations, particularly when using
large sequences of files. large sequences of files.
Default is None. Default is None.
meta (:obj:`bool`, optional): Set to False to disable metadata and meta (:obj:`bool`, optional): Set to False to disable metadata and
return :class:`numpy.ndarray` instead of return :class:`numpy.ndarray` instead of
:class:`xarray.DataArray`. Default is True. :class:`xarray.DataArray`. Default is True.
_key (:obj:`int`, optional): A caching key. This is used for internal _key (:obj:`int`, optional): A caching key. This is used for internal
purposes only. Default is None. purposes only. Default is None.
units (:obj:`str`): The desired units. Refer to the :meth:`getvar` units (:obj:`str`): The desired units. Refer to the :meth:`getvar`
product table for a list of available units for 'theta'. Default product table for a list of available units for 'theta'. Default
is 'K'. is 'K'.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The :class:`xarray.DataArray` or :class:`numpy.ndarray`: The
potential temperature. potential temperature.
If xarray is enabled and the *meta* parameter is True, then the result If xarray is enabled and the *meta* parameter is True, then the result
will be a :class:`xarray.DataArray` object. Otherwise, the result will will be a :class:`xarray.DataArray` object. Otherwise, the result will
be a :class:`numpy.ndarray` object with no metadata. be a :class:`numpy.ndarray` object with no metadata.
""" """
varnames = ("T",) varnames = ("T", )
ncvars = extract_vars(wrfin, timeidx, varnames, method, squeeze, cache, ncvars = extract_vars(wrfin, timeidx, varnames, method, squeeze, cache,
meta=False, _key=_key) meta=False, _key=_key)
t = ncvars["T"] t = ncvars["T"]
@ -79,438 +79,435 @@ def get_theta(wrfin, timeidx=0, method="cat", squeeze=True,
return full_t return full_t
@copy_and_set_metadata(copy_varname="T", name="temp", @copy_and_set_metadata(copy_varname="T", name="temp",
description="temperature") description="temperature")
@convert_units("temp", "k") @convert_units("temp", "k")
def get_temp(wrfin, timeidx=0, method="cat", squeeze=True, def get_temp(wrfin, timeidx=0, method="cat", squeeze=True,
cache=None, meta=True, _key=None, cache=None, meta=True, _key=None,
units="K"): units="K"):
"""Return the temperature in the specified units. """Return the temperature in the specified units.
This functions extracts the necessary variables from the NetCDF file This functions extracts the necessary variables from the NetCDF file
object in order to perform the calculation. object in order to perform the calculation.
Args: Args:
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \
iterable): WRF-ARW NetCDF iterable): WRF-ARW NetCDF
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile`
or an iterable sequence of the aforementioned types. or an iterable sequence of the aforementioned types.
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The
desired time index. This value can be a positive integer, desired time index. This value can be a positive integer,
negative integer, or negative integer, or
:data:`wrf.ALL_TIMES` (an alias for None) to return :data:`wrf.ALL_TIMES` (an alias for None) to return
all times in the file or sequence. The default is 0. all times in the file or sequence. The default is 0.
method (:obj:`str`, optional): The aggregation method to use for method (:obj:`str`, optional): The aggregation method to use for
sequences. Must be either 'cat' or 'join'. sequences. Must be either 'cat' or 'join'.
'cat' combines the data along the Time dimension. 'cat' combines the data along the Time dimension.
'join' creates a new dimension for the file index. 'join' creates a new dimension for the file index.
The default is 'cat'. The default is 'cat'.
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions squeeze (:obj:`bool`, optional): Set to False to prevent dimensions
with a size of 1 from being automatically removed from the shape with a size of 1 from being automatically removed from the shape
of the output. Default is True. of the output. Default is True.
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) cache (:obj:`dict`, optional): A dictionary of (varname, ndarray)
that can be used to supply pre-extracted NetCDF variables to the that can be used to supply pre-extracted NetCDF variables to the
computational routines. It is primarily used for internal computational routines. It is primarily used for internal
purposes, but can also be used to improve performance by purposes, but can also be used to improve performance by
eliminating the need to repeatedly extract the same variables eliminating the need to repeatedly extract the same variables
used in multiple diagnostics calculations, particularly when using used in multiple diagnostics calculations, particularly when using
large sequences of files. large sequences of files.
Default is None. Default is None.
meta (:obj:`bool`, optional): Set to False to disable metadata and meta (:obj:`bool`, optional): Set to False to disable metadata and
return :class:`numpy.ndarray` instead of return :class:`numpy.ndarray` instead of
:class:`xarray.DataArray`. Default is True. :class:`xarray.DataArray`. Default is True.
_key (:obj:`int`, optional): A caching key. This is used for internal _key (:obj:`int`, optional): A caching key. This is used for internal
purposes only. Default is None. purposes only. Default is None.
units (:obj:`str`): The desired units. Refer to the :meth:`getvar` units (:obj:`str`): The desired units. Refer to the :meth:`getvar`
product table for a list of available units for 'temp'. Default product table for a list of available units for 'temp'. Default
is 'K'. is 'K'.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The :class:`xarray.DataArray` or :class:`numpy.ndarray`: The
temperature in the specified units. temperature in the specified units.
If xarray is enabled and the *meta* parameter is True, then the result If xarray is enabled and the *meta* parameter is True, then the result
will be a :class:`xarray.DataArray` object. Otherwise, the result will will be a :class:`xarray.DataArray` object. Otherwise, the result will
be a :class:`numpy.ndarray` object with no metadata. be a :class:`numpy.ndarray` object with no metadata.
""" """
varnames=("T", "P", "PB") varnames = ("T", "P", "PB")
ncvars = extract_vars(wrfin, timeidx, varnames, method, squeeze, cache, ncvars = extract_vars(wrfin, timeidx, varnames, method, squeeze, cache,
meta=False, _key=_key) meta=False, _key=_key)
t = ncvars["T"] t = ncvars["T"]
p = ncvars["P"] p = ncvars["P"]
pb = ncvars["PB"] pb = ncvars["PB"]
full_t = t + Constants.T_BASE full_t = t + Constants.T_BASE
full_p = p + pb full_p = p + pb
tk = _tk(full_p, full_t) tk = _tk(full_p, full_t)
return tk return tk
@copy_and_set_metadata(copy_varname="T", name="theta_e", @copy_and_set_metadata(copy_varname="T", name="theta_e",
description="equivalent potential temperature") description="equivalent potential temperature")
@convert_units("temp", "K") @convert_units("temp", "K")
def get_eth(wrfin, timeidx=0, method="cat", squeeze=True, def get_eth(wrfin, timeidx=0, method="cat", squeeze=True,
cache=None, meta=True, _key=None, cache=None, meta=True, _key=None,
units="K"): units="K"):
"""Return the equivalent potential temperature. """Return the equivalent potential temperature.
This functions extracts the necessary variables from the NetCDF file This functions extracts the necessary variables from the NetCDF file
object in order to perform the calculation. object in order to perform the calculation.
Args: Args:
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \
iterable): WRF-ARW NetCDF iterable): WRF-ARW NetCDF
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile`
or an iterable sequence of the aforementioned types. or an iterable sequence of the aforementioned types.
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The
desired time index. This value can be a positive integer, desired time index. This value can be a positive integer,
negative integer, or negative integer, or
:data:`wrf.ALL_TIMES` (an alias for None) to return :data:`wrf.ALL_TIMES` (an alias for None) to return
all times in the file or sequence. The default is 0. all times in the file or sequence. The default is 0.
method (:obj:`str`, optional): The aggregation method to use for method (:obj:`str`, optional): The aggregation method to use for
sequences. Must be either 'cat' or 'join'. sequences. Must be either 'cat' or 'join'.
'cat' combines the data along the Time dimension. 'cat' combines the data along the Time dimension.
'join' creates a new dimension for the file index. 'join' creates a new dimension for the file index.
The default is 'cat'. The default is 'cat'.
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions squeeze (:obj:`bool`, optional): Set to False to prevent dimensions
with a size of 1 from being automatically removed from the shape with a size of 1 from being automatically removed from the shape
of the output. Default is True. of the output. Default is True.
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) cache (:obj:`dict`, optional): A dictionary of (varname, ndarray)
that can be used to supply pre-extracted NetCDF variables to the that can be used to supply pre-extracted NetCDF variables to the
computational routines. It is primarily used for internal computational routines. It is primarily used for internal
purposes, but can also be used to improve performance by purposes, but can also be used to improve performance by
eliminating the need to repeatedly extract the same variables eliminating the need to repeatedly extract the same variables
used in multiple diagnostics calculations, particularly when using used in multiple diagnostics calculations, particularly when using
large sequences of files. large sequences of files.
Default is None. Default is None.
meta (:obj:`bool`, optional): Set to False to disable metadata and meta (:obj:`bool`, optional): Set to False to disable metadata and
return :class:`numpy.ndarray` instead of return :class:`numpy.ndarray` instead of
:class:`xarray.DataArray`. Default is True. :class:`xarray.DataArray`. Default is True.
_key (:obj:`int`, optional): A caching key. This is used for internal _key (:obj:`int`, optional): A caching key. This is used for internal
purposes only. Default is None. purposes only. Default is None.
units (:obj:`str`): The desired units. Refer to the :meth:`getvar` units (:obj:`str`): The desired units. Refer to the :meth:`getvar`
product table for a list of available units for 'eth'. Default product table for a list of available units for 'eth'. Default
is 'K'. is 'K'.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The :class:`xarray.DataArray` or :class:`numpy.ndarray`: The
equivalent potential temperature. equivalent potential temperature.
If xarray is enabled and the *meta* parameter is True, then the result If xarray is enabled and the *meta* parameter is True, then the result
will be a :class:`xarray.DataArray` object. Otherwise, the result will will be a :class:`xarray.DataArray` object. Otherwise, the result will
be a :class:`numpy.ndarray` object with no metadata. be a :class:`numpy.ndarray` object with no metadata.
""" """
varnames=("T", "P", "PB", "QVAPOR") varnames = ("T", "P", "PB", "QVAPOR")
ncvars = extract_vars(wrfin, timeidx, varnames, method, squeeze, cache, ncvars = extract_vars(wrfin, timeidx, varnames, method, squeeze, cache,
meta=False, _key=_key) meta=False, _key=_key)
t = ncvars["T"] t = ncvars["T"]
p = ncvars["P"] p = ncvars["P"]
pb = ncvars["PB"] pb = ncvars["PB"]
qv = ncvars["QVAPOR"] qv = ncvars["QVAPOR"]
full_t = t + Constants.T_BASE full_t = t + Constants.T_BASE
full_p = p + pb full_p = p + pb
tk = _tk(full_p, full_t) tk = _tk(full_p, full_t)
eth = _eth(qv, tk, full_p) eth = _eth(qv, tk, full_p)
return eth return eth
@copy_and_set_metadata(copy_varname="T", name="tv", @copy_and_set_metadata(copy_varname="T", name="tv",
description="virtual temperature") description="virtual temperature")
@convert_units("temp", "k") @convert_units("temp", "k")
def get_tv(wrfin, timeidx=0, method="cat", squeeze=True, def get_tv(wrfin, timeidx=0, method="cat", squeeze=True,
cache=None, meta=True, _key=None, cache=None, meta=True, _key=None,
units="K"): units="K"):
"""Return the virtual temperature. """Return the virtual temperature.
This functions extracts the necessary variables from the NetCDF file This functions extracts the necessary variables from the NetCDF file
object in order to perform the calculation. object in order to perform the calculation.
Args: Args:
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \
iterable): WRF-ARW NetCDF iterable): WRF-ARW NetCDF
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile`
or an iterable sequence of the aforementioned types. or an iterable sequence of the aforementioned types.
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The
desired time index. This value can be a positive integer, desired time index. This value can be a positive integer,
negative integer, or negative integer, or
:data:`wrf.ALL_TIMES` (an alias for None) to return :data:`wrf.ALL_TIMES` (an alias for None) to return
all times in the file or sequence. The default is 0. all times in the file or sequence. The default is 0.
method (:obj:`str`, optional): The aggregation method to use for method (:obj:`str`, optional): The aggregation method to use for
sequences. Must be either 'cat' or 'join'. sequences. Must be either 'cat' or 'join'.
'cat' combines the data along the Time dimension. 'cat' combines the data along the Time dimension.
'join' creates a new dimension for the file index. 'join' creates a new dimension for the file index.
The default is 'cat'. The default is 'cat'.
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions squeeze (:obj:`bool`, optional): Set to False to prevent dimensions
with a size of 1 from being automatically removed from the shape with a size of 1 from being automatically removed from the shape
of the output. Default is True. of the output. Default is True.
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) cache (:obj:`dict`, optional): A dictionary of (varname, ndarray)
that can be used to supply pre-extracted NetCDF variables to the that can be used to supply pre-extracted NetCDF variables to the
computational routines. It is primarily used for internal computational routines. It is primarily used for internal
purposes, but can also be used to improve performance by purposes, but can also be used to improve performance by
eliminating the need to repeatedly extract the same variables eliminating the need to repeatedly extract the same variables
used in multiple diagnostics calculations, particularly when using used in multiple diagnostics calculations, particularly when using
large sequences of files. large sequences of files.
Default is None. Default is None.
meta (:obj:`bool`, optional): Set to False to disable metadata and meta (:obj:`bool`, optional): Set to False to disable metadata and
return :class:`numpy.ndarray` instead of return :class:`numpy.ndarray` instead of
:class:`xarray.DataArray`. Default is True. :class:`xarray.DataArray`. Default is True.
_key (:obj:`int`, optional): A caching key. This is used for internal _key (:obj:`int`, optional): A caching key. This is used for internal
purposes only. Default is None. purposes only. Default is None.
units (:obj:`str`): The desired units. Refer to the :meth:`getvar` units (:obj:`str`): The desired units. Refer to the :meth:`getvar`
product table for a list of available units for 'tv'. Default product table for a list of available units for 'tv'. Default
is 'K'. is 'K'.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The :class:`xarray.DataArray` or :class:`numpy.ndarray`: The
virtual temperature. virtual temperature.
If xarray is enabled and the *meta* parameter is True, then the result If xarray is enabled and the *meta* parameter is True, then the result
will be a :class:`xarray.DataArray` object. Otherwise, the result will will be a :class:`xarray.DataArray` object. Otherwise, the result will
be a :class:`numpy.ndarray` object with no metadata. be a :class:`numpy.ndarray` object with no metadata.
""" """
varnames=("T", "P", "PB", "QVAPOR") varnames = ("T", "P", "PB", "QVAPOR")
ncvars = extract_vars(wrfin, timeidx, varnames, method, squeeze, cache, ncvars = extract_vars(wrfin, timeidx, varnames, method, squeeze, cache,
meta=False, _key=_key) meta=False, _key=_key)
t = ncvars["T"] t = ncvars["T"]
p = ncvars["P"] p = ncvars["P"]
pb = ncvars["PB"] pb = ncvars["PB"]
qv = ncvars["QVAPOR"] qv = ncvars["QVAPOR"]
full_t = t + Constants.T_BASE full_t = t + Constants.T_BASE
full_p = p + pb full_p = p + pb
tk = _tk(full_p, full_t) tk = _tk(full_p, full_t)
tv = _tv(tk, qv) tv = _tv(tk, qv)
return tv return tv
@copy_and_set_metadata(copy_varname="T", name="twb", @copy_and_set_metadata(copy_varname="T", name="twb",
description="wetbulb temperature") description="wetbulb temperature")
@convert_units("temp", "k") @convert_units("temp", "k")
def get_tw(wrfin, timeidx=0, method="cat", squeeze=True, def get_tw(wrfin, timeidx=0, method="cat", squeeze=True,
cache=None, meta=True, _key=None, cache=None, meta=True, _key=None,
units="K"): units="K"):
"""Return the wetbulb temperature. """Return the wetbulb temperature.
This functions extracts the necessary variables from the NetCDF file This functions extracts the necessary variables from the NetCDF file
object in order to perform the calculation. object in order to perform the calculation.
Args: Args:
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \
iterable): WRF-ARW NetCDF iterable): WRF-ARW NetCDF
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile`
or an iterable sequence of the aforementioned types. or an iterable sequence of the aforementioned types.
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The
desired time index. This value can be a positive integer, desired time index. This value can be a positive integer,
negative integer, or negative integer, or
:data:`wrf.ALL_TIMES` (an alias for None) to return :data:`wrf.ALL_TIMES` (an alias for None) to return
all times in the file or sequence. The default is 0. all times in the file or sequence. The default is 0.
method (:obj:`str`, optional): The aggregation method to use for method (:obj:`str`, optional): The aggregation method to use for
sequences. Must be either 'cat' or 'join'. sequences. Must be either 'cat' or 'join'.
'cat' combines the data along the Time dimension. 'cat' combines the data along the Time dimension.
'join' creates a new dimension for the file index. 'join' creates a new dimension for the file index.
The default is 'cat'. The default is 'cat'.
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions squeeze (:obj:`bool`, optional): Set to False to prevent dimensions
with a size of 1 from being automatically removed from the shape with a size of 1 from being automatically removed from the shape
of the output. Default is True. of the output. Default is True.
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) cache (:obj:`dict`, optional): A dictionary of (varname, ndarray)
that can be used to supply pre-extracted NetCDF variables to the that can be used to supply pre-extracted NetCDF variables to the
computational routines. It is primarily used for internal computational routines. It is primarily used for internal
purposes, but can also be used to improve performance by purposes, but can also be used to improve performance by
eliminating the need to repeatedly extract the same variables eliminating the need to repeatedly extract the same variables
used in multiple diagnostics calculations, particularly when using used in multiple diagnostics calculations, particularly when using
large sequences of files. large sequences of files.
Default is None. Default is None.
meta (:obj:`bool`, optional): Set to False to disable metadata and meta (:obj:`bool`, optional): Set to False to disable metadata and
return :class:`numpy.ndarray` instead of return :class:`numpy.ndarray` instead of
:class:`xarray.DataArray`. Default is True. :class:`xarray.DataArray`. Default is True.
_key (:obj:`int`, optional): A caching key. This is used for internal _key (:obj:`int`, optional): A caching key. This is used for internal
purposes only. Default is None. purposes only. Default is None.
units (:obj:`str`): The desired units. Refer to the :meth:`getvar` units (:obj:`str`): The desired units. Refer to the :meth:`getvar`
product table for a list of available units for 'twb'. Default product table for a list of available units for 'twb'. Default
is 'K'. is 'K'.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The :class:`xarray.DataArray` or :class:`numpy.ndarray`: The
wetbulb temperature. wetbulb temperature.
If xarray is enabled and the *meta* parameter is True, then the result If xarray is enabled and the *meta* parameter is True, then the result
will be a :class:`xarray.DataArray` object. Otherwise, the result will will be a :class:`xarray.DataArray` object. Otherwise, the result will
be a :class:`numpy.ndarray` object with no metadata. be a :class:`numpy.ndarray` object with no metadata.
""" """
varnames=("T", "P", "PB", "QVAPOR") varnames = ("T", "P", "PB", "QVAPOR")
ncvars = extract_vars(wrfin, timeidx, varnames, method, squeeze, cache, ncvars = extract_vars(wrfin, timeidx, varnames, method, squeeze, cache,
meta=False, _key=_key) meta=False, _key=_key)
t = ncvars["T"] t = ncvars["T"]
p = ncvars["P"] p = ncvars["P"]
pb = ncvars["PB"] pb = ncvars["PB"]
qv = ncvars["QVAPOR"] qv = ncvars["QVAPOR"]
full_t = t + Constants.T_BASE full_t = t + Constants.T_BASE
full_p = p + pb full_p = p + pb
tk = _tk(full_p, full_t) tk = _tk(full_p, full_t)
tw = _wetbulb(full_p, tk, qv) tw = _wetbulb(full_p, tk, qv)
return tw return tw
def get_tk(wrfin, timeidx=0, method="cat", squeeze=True, cache=None, def get_tk(wrfin, timeidx=0, method="cat", squeeze=True, cache=None,
meta=True, _key=None): meta=True, _key=None):
"""Return the temperature in [K]. """Return the temperature in [K].
This functions extracts the necessary variables from the NetCDF file This functions extracts the necessary variables from the NetCDF file
object in order to perform the calculation. object in order to perform the calculation.
Args: Args:
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \
iterable): WRF-ARW NetCDF iterable): WRF-ARW NetCDF
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile`
or an iterable sequence of the aforementioned types. or an iterable sequence of the aforementioned types.
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The
desired time index. This value can be a positive integer, desired time index. This value can be a positive integer,
negative integer, or negative integer, or
:data:`wrf.ALL_TIMES` (an alias for None) to return :data:`wrf.ALL_TIMES` (an alias for None) to return
all times in the file or sequence. The default is 0. all times in the file or sequence. The default is 0.
method (:obj:`str`, optional): The aggregation method to use for method (:obj:`str`, optional): The aggregation method to use for
sequences. Must be either 'cat' or 'join'. sequences. Must be either 'cat' or 'join'.
'cat' combines the data along the Time dimension. 'cat' combines the data along the Time dimension.
'join' creates a new dimension for the file index. 'join' creates a new dimension for the file index.
The default is 'cat'. The default is 'cat'.
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions squeeze (:obj:`bool`, optional): Set to False to prevent dimensions
with a size of 1 from being automatically removed from the shape with a size of 1 from being automatically removed from the shape
of the output. Default is True. of the output. Default is True.
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) cache (:obj:`dict`, optional): A dictionary of (varname, ndarray)
that can be used to supply pre-extracted NetCDF variables to the that can be used to supply pre-extracted NetCDF variables to the
computational routines. It is primarily used for internal computational routines. It is primarily used for internal
purposes, but can also be used to improve performance by purposes, but can also be used to improve performance by
eliminating the need to repeatedly extract the same variables eliminating the need to repeatedly extract the same variables
used in multiple diagnostics calculations, particularly when using used in multiple diagnostics calculations, particularly when using
large sequences of files. large sequences of files.
Default is None. Default is None.
meta (:obj:`bool`, optional): Set to False to disable metadata and meta (:obj:`bool`, optional): Set to False to disable metadata and
return :class:`numpy.ndarray` instead of return :class:`numpy.ndarray` instead of
:class:`xarray.DataArray`. Default is True. :class:`xarray.DataArray`. Default is True.
_key (:obj:`int`, optional): A caching key. This is used for internal _key (:obj:`int`, optional): A caching key. This is used for internal
purposes only. Default is None. purposes only. Default is None.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The :class:`xarray.DataArray` or :class:`numpy.ndarray`: The
temperature in [K]. temperature in [K].
If xarray is enabled and the *meta* parameter is True, then the result If xarray is enabled and the *meta* parameter is True, then the result
will be a :class:`xarray.DataArray` object. Otherwise, the result will will be a :class:`xarray.DataArray` object. Otherwise, the result will
be a :class:`numpy.ndarray` object with no metadata. be a :class:`numpy.ndarray` object with no metadata.
""" """
return get_temp(wrfin, timeidx, method, squeeze, cache, meta, _key, return get_temp(wrfin, timeidx, method, squeeze, cache, meta, _key,
units="K") units="K")
def get_tc(wrfin, timeidx=0, method="cat", squeeze=True, cache=None, def get_tc(wrfin, timeidx=0, method="cat", squeeze=True, cache=None,
meta=True, _key=None): meta=True, _key=None):
"""Return the temperature in [degC]. """Return the temperature in [degC].
This functions extracts the necessary variables from the NetCDF file This functions extracts the necessary variables from the NetCDF file
object in order to perform the calculation. object in order to perform the calculation.
Args: Args:
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \
iterable): WRF-ARW NetCDF iterable): WRF-ARW NetCDF
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile`
or an iterable sequence of the aforementioned types. or an iterable sequence of the aforementioned types.
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The
desired time index. This value can be a positive integer, desired time index. This value can be a positive integer,
negative integer, or negative integer, or
:data:`wrf.ALL_TIMES` (an alias for None) to return :data:`wrf.ALL_TIMES` (an alias for None) to return
all times in the file or sequence. The default is 0. all times in the file or sequence. The default is 0.
method (:obj:`str`, optional): The aggregation method to use for method (:obj:`str`, optional): The aggregation method to use for
sequences. Must be either 'cat' or 'join'. sequences. Must be either 'cat' or 'join'.
'cat' combines the data along the Time dimension. 'cat' combines the data along the Time dimension.
'join' creates a new dimension for the file index. 'join' creates a new dimension for the file index.
The default is 'cat'. The default is 'cat'.
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions squeeze (:obj:`bool`, optional): Set to False to prevent dimensions
with a size of 1 from being automatically removed from the shape with a size of 1 from being automatically removed from the shape
of the output. Default is True. of the output. Default is True.
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) cache (:obj:`dict`, optional): A dictionary of (varname, ndarray)
that can be used to supply pre-extracted NetCDF variables to the that can be used to supply pre-extracted NetCDF variables to the
computational routines. It is primarily used for internal computational routines. It is primarily used for internal
purposes, but can also be used to improve performance by purposes, but can also be used to improve performance by
eliminating the need to repeatedly extract the same variables eliminating the need to repeatedly extract the same variables
used in multiple diagnostics calculations, particularly when using used in multiple diagnostics calculations, particularly when using
large sequences of files. large sequences of files.
Default is None. Default is None.
meta (:obj:`bool`, optional): Set to False to disable metadata and meta (:obj:`bool`, optional): Set to False to disable metadata and
return :class:`numpy.ndarray` instead of return :class:`numpy.ndarray` instead of
:class:`xarray.DataArray`. Default is True. :class:`xarray.DataArray`. Default is True.
_key (:obj:`int`, optional): A caching key. This is used for internal _key (:obj:`int`, optional): A caching key. This is used for internal
purposes only. Default is None. purposes only. Default is None.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The :class:`xarray.DataArray` or :class:`numpy.ndarray`: The
temperature in [degC]. temperature in [degC].
If xarray is enabled and the *meta* parameter is True, then the result If xarray is enabled and the *meta* parameter is True, then the result
will be a :class:`xarray.DataArray` object. Otherwise, the result will will be a :class:`xarray.DataArray` object. Otherwise, the result will
be a :class:`numpy.ndarray` object with no metadata. be a :class:`numpy.ndarray` object with no metadata.
""" """
return get_temp(wrfin, timeidx, method, squeeze, cache, meta, _key, return get_temp(wrfin, timeidx, method, squeeze, cache, meta, _key,
units="degC") units="degC")

97
src/wrf/g_terrain.py

@ -6,73 +6,70 @@ from .util import extract_vars, either
# Need to handle either # Need to handle either
@copy_and_set_metadata(copy_varname=either("HGT", "HGT_M"), name="terrain", @copy_and_set_metadata(copy_varname=either("HGT", "HGT_M"), name="terrain",
description="terrain height") description="terrain height")
@convert_units("height", "m") @convert_units("height", "m")
def get_terrain(wrfin, timeidx=0, method="cat", squeeze=True, def get_terrain(wrfin, timeidx=0, method="cat", squeeze=True,
cache=None, meta=False, _key=None, units="m"): cache=None, meta=False, _key=None, units="m"):
"""Return the terrain height in the specified units. """Return the terrain height in the specified units.
This functions extracts the necessary variables from the NetCDF file This functions extracts the necessary variables from the NetCDF file
object in order to perform the calculation. object in order to perform the calculation.
Args: Args:
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \
iterable): WRF-ARW NetCDF iterable): WRF-ARW NetCDF
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile`
or an iterable sequence of the aforementioned types. or an iterable sequence of the aforementioned types.
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The
desired time index. This value can be a positive integer, desired time index. This value can be a positive integer,
negative integer, or negative integer, or
:data:`wrf.ALL_TIMES` (an alias for None) to return :data:`wrf.ALL_TIMES` (an alias for None) to return
all times in the file or sequence. The default is 0. all times in the file or sequence. The default is 0.
method (:obj:`str`, optional): The aggregation method to use for method (:obj:`str`, optional): The aggregation method to use for
sequences. Must be either 'cat' or 'join'. sequences. Must be either 'cat' or 'join'.
'cat' combines the data along the Time dimension. 'cat' combines the data along the Time dimension.
'join' creates a new dimension for the file index. 'join' creates a new dimension for the file index.
The default is 'cat'. The default is 'cat'.
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions squeeze (:obj:`bool`, optional): Set to False to prevent dimensions
with a size of 1 from being automatically removed from the shape with a size of 1 from being automatically removed from the shape
of the output. Default is True. of the output. Default is True.
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) cache (:obj:`dict`, optional): A dictionary of (varname, ndarray)
that can be used to supply pre-extracted NetCDF variables to the that can be used to supply pre-extracted NetCDF variables to the
computational routines. It is primarily used for internal computational routines. It is primarily used for internal
purposes, but can also be used to improve performance by purposes, but can also be used to improve performance by
eliminating the need to repeatedly extract the same variables eliminating the need to repeatedly extract the same variables
used in multiple diagnostics calculations, particularly when using used in multiple diagnostics calculations, particularly when using
large sequences of files. large sequences of files.
Default is None. Default is None.
meta (:obj:`bool`, optional): Set to False to disable metadata and meta (:obj:`bool`, optional): Set to False to disable metadata and
return :class:`numpy.ndarray` instead of return :class:`numpy.ndarray` instead of
:class:`xarray.DataArray`. Default is True. :class:`xarray.DataArray`. Default is True.
_key (:obj:`int`, optional): A caching key. This is used for internal _key (:obj:`int`, optional): A caching key. This is used for internal
purposes only. Default is None. purposes only. Default is None.
units (:obj:`str`): The desired units. Refer to the :meth:`getvar` units (:obj:`str`): The desired units. Refer to the :meth:`getvar`
product table for a list of available units for 'ter'. Default product table for a list of available units for 'ter'. Default
is 'm'. is 'm'.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The terrain :class:`xarray.DataArray` or :class:`numpy.ndarray`: The terrain
height in the specified units. If xarray is height in the specified units. If xarray is
enabled and the *meta* parameter is True, then the result will be a enabled and the *meta* parameter is True, then the result will be a
:class:`xarray.DataArray` object. Otherwise, the result will be a :class:`xarray.DataArray` object. Otherwise, the result will be a
:class:`numpy.ndarray` object with no metadata. :class:`numpy.ndarray` object with no metadata.
""" """
varname = either("HGT", "HGT_M")(wrfin) varname = either("HGT", "HGT_M")(wrfin)
return extract_vars(wrfin, timeidx, varname, return extract_vars(wrfin, timeidx, varname,
method, squeeze, cache, meta=False, method, squeeze, cache, meta=False,
_key=_key)[varname] _key=_key)[varname]

161
src/wrf/g_times.py

@ -3,119 +3,118 @@ from __future__ import (absolute_import, division, print_function)
from .util import extract_times from .util import extract_times
def get_times(wrfin, timeidx=0, method="cat", squeeze=True, cache=None, def get_times(wrfin, timeidx=0, method="cat", squeeze=True, cache=None,
meta=True, _key=None): meta=True, _key=None):
"""Return a sequence of time objects. """Return a sequence of time objects.
This function reads the 'Times' variable and creates a sequence of This function reads the 'Times' variable and creates a sequence of
:class:`datetime.datetime` objects. :class:`datetime.datetime` objects.
Args: Args:
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \
iterable): WRF-ARW NetCDF iterable): WRF-ARW NetCDF
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile`
or an iterable sequence of the aforementioned types. or an iterable sequence of the aforementioned types.
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`): The timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`): The
desired time index. This value can be a positive integer, desired time index. This value can be a positive integer,
negative integer, or negative integer, or
:data:`wrf.ALL_TIMES` (an alias for None) to return :data:`wrf.ALL_TIMES` (an alias for None) to return
all times in the file or sequence. all times in the file or sequence.
method (:obj:`str`, optional): The aggregation method to use for method (:obj:`str`, optional): The aggregation method to use for
sequences. Must be either 'cat' or 'join'. sequences. Must be either 'cat' or 'join'.
'cat' combines the data along the Time dimension. 'cat' combines the data along the Time dimension.
'join' creates a new dimension for the file index. 'join' creates a new dimension for the file index.
The default is 'cat'. The default is 'cat'.
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions squeeze (:obj:`bool`, optional): Set to False to prevent dimensions
with a size of 1 from being automatically removed from the shape with a size of 1 from being automatically removed from the shape
of the output. Default is True. of the output. Default is True.
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) cache (:obj:`dict`, optional): A dictionary of (varname, ndarray)
that can be used to supply pre-extracted NetCDF variables to the that can be used to supply pre-extracted NetCDF variables to the
computational routines. It is primarily used for internal computational routines. It is primarily used for internal
purposes, but can also be used to improve performance by purposes, but can also be used to improve performance by
eliminating the need to repeatedly extract the same variables eliminating the need to repeatedly extract the same variables
used in multiple diagnostics calculations, particularly when using used in multiple diagnostics calculations, particularly when using
large sequences of files. large sequences of files.
Default is None. Default is None.
meta (:obj:`bool`, optional): Set to False to disable metadata. meta (:obj:`bool`, optional): Set to False to disable metadata.
_key (:obj:`int`, optional): A caching key. This is used for internal _key (:obj:`int`, optional): A caching key. This is used for internal
purposes only. Default is None. purposes only. Default is None.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: A sequence of :class:`xarray.DataArray` or :class:`numpy.ndarray`: A sequence of
:class:`datetime.datetime` objects. If *meta* is True, the sequence :class:`datetime.datetime` objects. If *meta* is True, the sequence
will be of type :class:`xarray.DataArray`, otherwise the sequence is will be of type :class:`xarray.DataArray`, otherwise the sequence is
:class:`numpy.ndarray`. :class:`numpy.ndarray`.
""" """
return extract_times(wrfin, timeidx, method, squeeze, cache, return extract_times(wrfin, timeidx, method, squeeze, cache,
meta=meta, do_xtime=False) meta=meta, do_xtime=False)
def get_xtimes(wrfin, timeidx=0, method="cat", squeeze=True, cache=None, def get_xtimes(wrfin, timeidx=0, method="cat", squeeze=True, cache=None,
meta=True, _key=None): meta=True, _key=None):
"""Return a sequence of time objects. """Return a sequence of time objects.
This function reads the 'XTIME' variable and creates a sequence of This function reads the 'XTIME' variable and creates a sequence of
:obj:`float` objects. :obj:`float` objects.
Args: Args:
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \
iterable): WRF-ARW NetCDF iterable): WRF-ARW NetCDF
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile`
or an iterable sequence of the aforementioned types. or an iterable sequence of the aforementioned types.
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`): The timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`): The
desired time index. This value can be a positive integer, desired time index. This value can be a positive integer,
negative integer, or negative integer, or
:data:`wrf.ALL_TIMES` (an alias for None) to return :data:`wrf.ALL_TIMES` (an alias for None) to return
all times in the file or sequence. all times in the file or sequence.
method (:obj:`str`, optional): The aggregation method to use for method (:obj:`str`, optional): The aggregation method to use for
sequences. Must be either 'cat' or 'join'. sequences. Must be either 'cat' or 'join'.
'cat' combines the data along the Time dimension. 'cat' combines the data along the Time dimension.
'join' creates a new dimension for the file index. 'join' creates a new dimension for the file index.
The default is 'cat'. The default is 'cat'.
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions squeeze (:obj:`bool`, optional): Set to False to prevent dimensions
with a size of 1 from being automatically removed from the shape with a size of 1 from being automatically removed from the shape
of the output. Default is True. of the output. Default is True.
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) cache (:obj:`dict`, optional): A dictionary of (varname, ndarray)
that can be used to supply pre-extracted NetCDF variables to the that can be used to supply pre-extracted NetCDF variables to the
computational routines. It is primarily used for internal computational routines. It is primarily used for internal
purposes, but can also be used to improve performance by purposes, but can also be used to improve performance by
eliminating the need to repeatedly extract the same variables eliminating the need to repeatedly extract the same variables
used in multiple diagnostics calculations, particularly when using used in multiple diagnostics calculations, particularly when using
large sequences of files. large sequences of files.
Default is None. Default is None.
meta (:obj:`bool`, optional): Set to False to disable metadata. meta (:obj:`bool`, optional): Set to False to disable metadata.
_key (:obj:`int`, optional): A caching key. This is used for internal _key (:obj:`int`, optional): A caching key. This is used for internal
purposes only. Default is None. purposes only. Default is None.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: A sequence of :class:`xarray.DataArray` or :class:`numpy.ndarray`: A sequence of
:obj:`float` objects. If *meta* is True, the sequence will be of type :obj:`float` objects. If *meta* is True, the sequence will be of type
:class:`xarray.DataArray`, otherwise the sequence is :class:`xarray.DataArray`, otherwise the sequence is
:class:`numpy.ndarray`. :class:`numpy.ndarray`.
Raises: Raises:
:class:`KeyError`: Raised if the 'XTIME' variable is not present :class:`KeyError`: Raised if the 'XTIME' variable is not present
in the NetCDF file. in the NetCDF file.
""" """
return extract_times(wrfin, timeidx, method, squeeze, cache, return extract_times(wrfin, timeidx, method, squeeze, cache,
meta=meta, do_xtime=True) meta=meta, do_xtime=True)

1007
src/wrf/g_uvmet.py

File diff suppressed because it is too large Load Diff

179
src/wrf/g_vorticity.py

@ -5,69 +5,69 @@ from .util import extract_vars, extract_global_attrs
from .metadecorators import copy_and_set_metadata from .metadecorators import copy_and_set_metadata
@copy_and_set_metadata(copy_varname="T", name="avo", @copy_and_set_metadata(copy_varname="T", name="avo",
description="absolute vorticity", description="absolute vorticity",
units="10-5 s-1") units="10-5 s-1")
def get_avo(wrfin, timeidx=0, method="cat", squeeze=True, cache=None, def get_avo(wrfin, timeidx=0, method="cat", squeeze=True, cache=None,
meta=True, _key=None): meta=True, _key=None):
"""Return the absolute vorticity. """Return the absolute vorticity.
This function extracts the necessary variables from the NetCDF file This function extracts the necessary variables from the NetCDF file
object in order to perform the calculation. object in order to perform the calculation.
Args: Args:
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \
iterable): WRF-ARW NetCDF iterable): WRF-ARW NetCDF
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile`
or an iterable sequence of the aforementioned types. or an iterable sequence of the aforementioned types.
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The
desired time index. This value can be a positive integer, desired time index. This value can be a positive integer,
negative integer, or negative integer, or
:data:`wrf.ALL_TIMES` (an alias for None) to return :data:`wrf.ALL_TIMES` (an alias for None) to return
all times in the file or sequence. The default is 0. all times in the file or sequence. The default is 0.
method (:obj:`str`, optional): The aggregation method to use for method (:obj:`str`, optional): The aggregation method to use for
sequences. Must be either 'cat' or 'join'. sequences. Must be either 'cat' or 'join'.
'cat' combines the data along the Time dimension. 'cat' combines the data along the Time dimension.
'join' creates a new dimension for the file index. 'join' creates a new dimension for the file index.
The default is 'cat'. The default is 'cat'.
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions squeeze (:obj:`bool`, optional): Set to False to prevent dimensions
with a size of 1 from being automatically removed from the shape with a size of 1 from being automatically removed from the shape
of the output. Default is True. of the output. Default is True.
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) cache (:obj:`dict`, optional): A dictionary of (varname, ndarray)
that can be used to supply pre-extracted NetCDF variables to the that can be used to supply pre-extracted NetCDF variables to the
computational routines. It is primarily used for internal computational routines. It is primarily used for internal
purposes, but can also be used to improve performance by purposes, but can also be used to improve performance by
eliminating the need to repeatedly extract the same variables eliminating the need to repeatedly extract the same variables
used in multiple diagnostics calculations, particularly when using used in multiple diagnostics calculations, particularly when using
large sequences of files. large sequences of files.
Default is None. Default is None.
meta (:obj:`bool`, optional): Set to False to disable metadata and meta (:obj:`bool`, optional): Set to False to disable metadata and
return :class:`numpy.ndarray` instead of return :class:`numpy.ndarray` instead of
:class:`xarray.DataArray`. Default is True. :class:`xarray.DataArray`. Default is True.
_key (:obj:`int`, optional): A caching key. This is used for internal _key (:obj:`int`, optional): A caching key. This is used for internal
purposes only. Default is None. purposes only. Default is None.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The absolute :class:`xarray.DataArray` or :class:`numpy.ndarray`: The absolute
vorticity. If xarray is vorticity. If xarray is
enabled and the *meta* parameter is True, then the result will be a enabled and the *meta* parameter is True, then the result will be a
:class:`xarray.DataArray` object. Otherwise, the result will be a :class:`xarray.DataArray` object. Otherwise, the result will be a
:class:`numpy.ndarray` object with no metadata. :class:`numpy.ndarray` object with no metadata.
""" """
ncvars = extract_vars(wrfin, timeidx, ("U", "V", "MAPFAC_U", ncvars = extract_vars(wrfin, timeidx, ("U", "V", "MAPFAC_U",
"MAPFAC_V", "MAPFAC_M", "MAPFAC_V", "MAPFAC_M",
"F"), "F"),
method, squeeze, cache, meta=False, _key=_key) method, squeeze, cache, meta=False, _key=_key)
attrs = extract_global_attrs(wrfin, attrs=("DX", "DY")) attrs = extract_global_attrs(wrfin, attrs=("DX", "DY"))
u = ncvars["U"] u = ncvars["U"]
v = ncvars["V"] v = ncvars["V"]
@ -75,70 +75,70 @@ def get_avo(wrfin, timeidx=0, method="cat", squeeze=True, cache=None,
msfv = ncvars["MAPFAC_V"] msfv = ncvars["MAPFAC_V"]
msfm = ncvars["MAPFAC_M"] msfm = ncvars["MAPFAC_M"]
cor = ncvars["F"] cor = ncvars["F"]
dx = attrs["DX"] dx = attrs["DX"]
dy = attrs["DY"] dy = attrs["DY"]
return _avo(u, v, msfu, msfv, msfm, cor, dx, dy) return _avo(u, v, msfu, msfv, msfm, cor, dx, dy)
@copy_and_set_metadata(copy_varname="T", name="pvo", @copy_and_set_metadata(copy_varname="T", name="pvo",
description="potential vorticity", description="potential vorticity",
units="PVU") units="PVU")
def get_pvo(wrfin, timeidx=0, method="cat", squeeze=True, cache=None, def get_pvo(wrfin, timeidx=0, method="cat", squeeze=True, cache=None,
meta=True, _key=None): meta=True, _key=None):
"""Return the potential vorticity. """Return the potential vorticity.
This function extracts the necessary variables from the NetCDF file This function extracts the necessary variables from the NetCDF file
object in order to perform the calculation. object in order to perform the calculation.
Args: Args:
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \
iterable): WRF-ARW NetCDF iterable): WRF-ARW NetCDF
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile`
or an iterable sequence of the aforementioned types. or an iterable sequence of the aforementioned types.
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The
desired time index. This value can be a positive integer, desired time index. This value can be a positive integer,
negative integer, or negative integer, or
:data:`wrf.ALL_TIMES` (an alias for None) to return :data:`wrf.ALL_TIMES` (an alias for None) to return
all times in the file or sequence. The default is 0. all times in the file or sequence. The default is 0.
method (:obj:`str`, optional): The aggregation method to use for method (:obj:`str`, optional): The aggregation method to use for
sequences. Must be either 'cat' or 'join'. sequences. Must be either 'cat' or 'join'.
'cat' combines the data along the Time dimension. 'cat' combines the data along the Time dimension.
'join' creates a new dimension for the file index. 'join' creates a new dimension for the file index.
The default is 'cat'. The default is 'cat'.
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions squeeze (:obj:`bool`, optional): Set to False to prevent dimensions
with a size of 1 from being automatically removed from the shape with a size of 1 from being automatically removed from the shape
of the output. Default is True. of the output. Default is True.
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) cache (:obj:`dict`, optional): A dictionary of (varname, ndarray)
that can be used to supply pre-extracted NetCDF variables to the that can be used to supply pre-extracted NetCDF variables to the
computational routines. It is primarily used for internal computational routines. It is primarily used for internal
purposes, but can also be used to improve performance by purposes, but can also be used to improve performance by
eliminating the need to repeatedly extract the same variables eliminating the need to repeatedly extract the same variables
used in multiple diagnostics calculations, particularly when using used in multiple diagnostics calculations, particularly when using
large sequences of files. large sequences of files.
Default is None. Default is None.
meta (:obj:`bool`, optional): Set to False to disable metadata and meta (:obj:`bool`, optional): Set to False to disable metadata and
return :class:`numpy.ndarray` instead of return :class:`numpy.ndarray` instead of
:class:`xarray.DataArray`. Default is True. :class:`xarray.DataArray`. Default is True.
_key (:obj:`int`, optional): A caching key. This is used for internal _key (:obj:`int`, optional): A caching key. This is used for internal
purposes only. Default is None. purposes only. Default is None.
Returns: Returns:
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The potential :class:`xarray.DataArray` or :class:`numpy.ndarray`: The potential
vorticity. If xarray is vorticity. If xarray is
enabled and the *meta* parameter is True, then the result will be a enabled and the *meta* parameter is True, then the result will be a
:class:`xarray.DataArray` object. Otherwise, the result will be a :class:`xarray.DataArray` object. Otherwise, the result will be a
:class:`numpy.ndarray` object with no metadata. :class:`numpy.ndarray` object with no metadata.
""" """
ncvars = extract_vars(wrfin, timeidx, ("U", "V", "T", "P", ncvars = extract_vars(wrfin, timeidx, ("U", "V", "T", "P",
"PB", "MAPFAC_U", "PB", "MAPFAC_U",
@ -146,7 +146,7 @@ def get_pvo(wrfin, timeidx=0, method="cat", squeeze=True, cache=None,
"F"), "F"),
method, squeeze, cache, meta=False, _key=_key) method, squeeze, cache, meta=False, _key=_key)
attrs = extract_global_attrs(wrfin, attrs=("DX", "DY")) attrs = extract_global_attrs(wrfin, attrs=("DX", "DY"))
u = ncvars["U"] u = ncvars["U"]
v = ncvars["V"] v = ncvars["V"]
t = ncvars["T"] t = ncvars["T"]
@ -156,12 +156,11 @@ def get_pvo(wrfin, timeidx=0, method="cat", squeeze=True, cache=None,
msfv = ncvars["MAPFAC_V"] msfv = ncvars["MAPFAC_V"]
msfm = ncvars["MAPFAC_M"] msfm = ncvars["MAPFAC_M"]
cor = ncvars["F"] cor = ncvars["F"]
dx = attrs["DX"] dx = attrs["DX"]
dy = attrs["DY"] dy = attrs["DY"]
full_t = t + 300 full_t = t + 300
full_p = p + pb full_p = p + pb
return _pvo(u, v, full_t, full_p, msfu, msfv, msfm, cor, dx, dy) return _pvo(u, v, full_t, full_p, msfu, msfv, msfm, cor, dx, dy)

989
src/wrf/g_wind.py

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save