Browse Source

Improved documentation for the vintrp routine.

Closes #79.
lon0
Bill Ladwig 7 years ago
parent
commit
7cd61c756f
  1. 135
      src/wrf/interp.py

135
src/wrf/interp.py

@ -7,7 +7,8 @@ from .extension import (_interpz3d, _vertcross, _interpline, _smooth2d,
_monotonic, _vintrp, _interpz3d_lev2d) _monotonic, _vintrp, _interpz3d_lev2d)
from .metadecorators import set_interp_metadata from .metadecorators import set_interp_metadata
from .util import extract_vars, is_staggered, get_id, to_np, get_iterable from .util import (extract_vars, is_staggered, get_id, to_np, get_iterable,
is_moving_domain, is_latlon_pair)
from .py3compat import py3range from .py3compat import py3range
from .interputils import get_xy, get_xy_z_params, to_xy_coords from .interputils import get_xy, get_xy_z_params, to_xy_coords
from .constants import Constants, default_fill, ConversionFactors from .constants import Constants, default_fill, ConversionFactors
@ -105,6 +106,52 @@ def interplevel(field3d, vert, desiredlev, missing=default_fill(np.float64),
return masked return masked
def _vertcross_nest_alltimes(field3d, vert, levels=None,
missing=default_fill(np.float64),
wrfin=None, timeidx=0, stagger=None, projection=None,
ll_point=None,
pivot_point=None, angle=None,
start_point=None, end_point=None,
latlon=False, autolevels=100, cache=None, meta=True):
# Some fields like uvmet have an extra left dimension for the product
# type, we'll handle that iteration here.
multi = True if field3d.ndim - vert.ndim == 1 else False
# Check if we have a wrfin file, or this is a no go.
if wrfin is None:
raise ValueError("'wrfin' is required when using all times "
"from a moving nest with lat/lon coords")
if multi:
if field3d.ndim == 4:
raise ValueError("all times requested for a moving nest, "
"but no time dimension found for "
'field3d')
else:
if field3d.ndim < 4:
raise ValueError("all times requested for a moving nest, "
"but no time dimension found for "
'field3d')
numtimes = field3d.shape[-4]
for t in py3range(numtimes):
#_meta = True if t == 0 else False
_meta = True
v = vertcross(field3d, vert, levels, missing, wrfin, t, stagger,
projection, ll_point, pivot_point, angle, start_point,
end_point, latlon, autolevels, cache, _meta)
print(v.attrs)
@set_interp_metadata("cross") @set_interp_metadata("cross")
def vertcross(field3d, vert, levels=None, missing=default_fill(np.float64), def vertcross(field3d, vert, levels=None, missing=default_fill(np.float64),
wrfin=None, timeidx=0, stagger=None, projection=None, wrfin=None, timeidx=0, stagger=None, projection=None,
@ -257,14 +304,37 @@ def vertcross(field3d, vert, levels=None, missing=default_fill(np.float64),
:class:`numpy.ndarray` object with no metadata. :class:`numpy.ndarray` object with no metadata.
""" """
if timeidx is None:
raise ValueError("'timeidx' must be a positive or negative integer")
# Some fields like uvmet have an extra left dimension for the product # Some fields like uvmet have an extra left dimension for the product
# type, we'll handle that iteration here. # type, we'll handle that iteration here.
multi = True if field3d.ndim - vert.ndim == 1 else False multi = True if field3d.ndim - vert.ndim == 1 else False
if timeidx is None:
if (latlon is True or is_latlon_pair(start_point) or
is_latlon_pair(pivot_point)):
if wrfin is not None:
# Moving nests aren't supported with ALL_TIMES because the
# domain could move outside of the cross section, which causes
# crashes or different line lengths.
if is_moving_domain(wrfin):
raise ValueError("Requesting all times with a moving nest "
"is not supported when using lat/lon "
"cross sections because the domain could "
"move outside of the cross section. "
"You must request each time "
"individually.")
else:
_timeidx = 0
# If using grid coordinates, then don't care about lat/lon
# coordinates. Just use 0.
else:
_timeidx = 0
else:
_timeidx = timeidx
try: try:
xy = cache["xy"] xy = cache["xy"]
var2dz = cache["var2dz"] var2dz = cache["var2dz"]
@ -277,7 +347,7 @@ def vertcross(field3d, vert, levels=None, missing=default_fill(np.float64),
if pivot_point is not None: if pivot_point is not None:
if pivot_point.lat is not None and pivot_point.lon is not None: if pivot_point.lat is not None and pivot_point.lon is not None:
xy_coords = to_xy_coords(pivot_point, wrfin, timeidx, xy_coords = to_xy_coords(pivot_point, wrfin, _timeidx,
stagger, projection, ll_point) stagger, projection, ll_point)
pivot_point_xy = (xy_coords.x, xy_coords.y) pivot_point_xy = (xy_coords.x, xy_coords.y)
else: else:
@ -285,14 +355,14 @@ def vertcross(field3d, vert, levels=None, missing=default_fill(np.float64),
if start_point is not None and end_point is not None: if start_point is not None and end_point is not None:
if start_point.lat is not None and start_point.lon is not None: if start_point.lat is not None and start_point.lon is not None:
xy_coords = to_xy_coords(start_point, wrfin, timeidx, xy_coords = to_xy_coords(start_point, wrfin, _timeidx,
stagger, projection, ll_point) stagger, projection, ll_point)
start_point_xy = (xy_coords.x, xy_coords.y) start_point_xy = (xy_coords.x, xy_coords.y)
else: else:
start_point_xy = (start_point.x, start_point.y) start_point_xy = (start_point.x, start_point.y)
if end_point.lat is not None and end_point.lon is not None: if end_point.lat is not None and end_point.lon is not None:
xy_coords = to_xy_coords(end_point, wrfin, timeidx, xy_coords = to_xy_coords(end_point, wrfin, _timeidx,
stagger, projection, ll_point) stagger, projection, ll_point)
end_point_xy = (xy_coords.x, xy_coords.y) end_point_xy = (xy_coords.x, xy_coords.y)
else: else:
@ -443,7 +513,29 @@ def interpline(field2d, pivot_point=None,
""" """
if timeidx is None: if timeidx is None:
raise ValueError("'timeidx' must be a positive or negative integer") if (latlon is True or is_latlon_pair(start_point) or
is_latlon_pair(pivot_point)):
if wrfin is not None:
# Moving nests aren't supported with ALL_TIMES because the
# domain could move outside of the line, which causes
# crashes or different line lengths.
if is_moving_domain(wrfin):
raise ValueError("Requesting all times with a moving nest "
"is not supported when using a lat/lon "
"line because the domain could "
"move outside of line. "
"You must request each time "
"individually.")
else:
_timeidx = 0
# If using grid coordinates, then don't care about lat/lon
# coordinates. Just use 0.
else:
_timeidx = 0
else:
_timeidx = timeidx
try: try:
xy = cache["xy"] xy = cache["xy"]
@ -454,7 +546,7 @@ def interpline(field2d, pivot_point=None,
if pivot_point is not None: if pivot_point is not None:
if pivot_point.lat is not None and pivot_point.lon is not None: if pivot_point.lat is not None and pivot_point.lon is not None:
xy_coords = to_xy_coords(pivot_point, wrfin, timeidx, xy_coords = to_xy_coords(pivot_point, wrfin, _timeidx,
stagger, projection, ll_point) stagger, projection, ll_point)
pivot_point_xy = (xy_coords.x, xy_coords.y) pivot_point_xy = (xy_coords.x, xy_coords.y)
else: else:
@ -462,14 +554,14 @@ def interpline(field2d, pivot_point=None,
if start_point is not None and end_point is not None: if start_point is not None and end_point is not None:
if start_point.lat is not None and start_point.lon is not None: if start_point.lat is not None and start_point.lon is not None:
xy_coords = to_xy_coords(start_point, wrfin, timeidx, xy_coords = to_xy_coords(start_point, wrfin, _timeidx,
stagger, projection, ll_point) stagger, projection, ll_point)
start_point_xy = (xy_coords.x, xy_coords.y) start_point_xy = (xy_coords.x, xy_coords.y)
else: else:
start_point_xy = (start_point.x, start_point.y) start_point_xy = (start_point.x, start_point.y)
if end_point.lat is not None and end_point.lon is not None: if end_point.lat is not None and end_point.lon is not None:
xy_coords = to_xy_coords(end_point, wrfin, timeidx, xy_coords = to_xy_coords(end_point, wrfin, _timeidx,
stagger, projection, ll_point) stagger, projection, ll_point)
end_point_xy = (xy_coords.x, xy_coords.y) end_point_xy = (xy_coords.x, xy_coords.y)
else: else:
@ -514,10 +606,14 @@ def vinterp(wrfin, field, vert_coord, interp_levels, extrapolate=False,
above for the *vert_coord* parameter. above for the *vert_coord* parameter.
extrapolate (:obj:`bool`, optional): Set to True to extrapolate extrapolate (:obj:`bool`, optional): Set to True to extrapolate
values below ground. This is only performed when the values below ground. This is only performed when *vert_coord* is
vertical coordinate type is pressure or height. For temperature a pressure or height type, and the *field_type* is a pressure type
vertical coordinate types, setting this to True will set (with height vertical coordinate), a height type (with pressure as
values below ground to the lowest model level. Default is False. the vertical coordinate), or a temperature type (with either height
or pressure as the vertical coordinate). If those conditions are
not met, or *field_type* is None, then the lowest model level
will be used. Extrapolation is performed using standard atmosphere.
Default is False.
field_type (:obj:`str`, optional): field_type (:obj:`str`, optional):
The type of field. Default is None. The type of field. Default is None.
@ -533,8 +629,11 @@ def vinterp(wrfin, field, vert_coord, interp_levels, extrapolate=False,
* 'theta', 'th': potential temperature [K] * 'theta', 'th': potential temperature [K]
* 'theta-e', 'thetae', 'eth': equivalent potential temperature * 'theta-e', 'thetae', 'eth': equivalent potential temperature
log_p (:obj:`bool`, optional): Use the log of the pressure for log_p (:obj:`bool`, optional): Set to True to use the log of the
interpolation instead of pressure. Default is False. vertical coordinate for interpolation. This is mainly intended
for pressure vertical coordinate types, but note that the log
will still be taken for any vertical coordinate type when
this is set to True. Default is False.
timeidx (:obj:`int`, optional): timeidx (:obj:`int`, optional):
The time index to use when extracting auxiallary variables used in The time index to use when extracting auxiallary variables used in

Loading…
Cancel
Save