Browse Source

Updated documentation. Fixed bugs found while creating examples, mostly related to xarray and compiled extensions.

main
Bill Ladwig 9 years ago
parent
commit
1c7baf0a4e
  1. BIN
      doc/source/_static/images/cartopy_slp.png
  2. BIN
      doc/source/_static/images/matthew.png
  3. 2
      doc/source/api.rst
  4. 1176
      doc/source/basic_usage.rst
  5. 7
      doc/source/diagnostics.rst
  6. 26
      doc/source/index.rst
  7. 54
      doc/source/installation.rst
  8. 2
      doc/source/internal_api/index.rst
  9. 10
      doc/source/new.rst
  10. 91
      doc/source/plot.rst
  11. 2
      doc/source/user_api/index.rst
  12. 2
      src/wrf/api.py
  13. 34
      src/wrf/interputils.py
  14. 16
      src/wrf/latlonutils.py
  15. 2
      src/wrf/metadecorators.py
  16. 5
      src/wrf/projection.py
  17. 6
      src/wrf/util.py
  18. 6
      src/wrf/uvmet.py
  19. 415
      test/ipynb/Doc_Examples.ipynb
  20. 29
      test/ipynb/WRF_Workshop_Demo.ipynb
  21. 275
      test/ipynb/WRF_python_demo.ipynb
  22. 14
      test/utests.py

BIN
doc/source/_static/images/cartopy_slp.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

BIN
doc/source/_static/images/matthew.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

2
doc/source/api.rst

@ -3,7 +3,7 @@ API Reference
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 2
user_api/index.rst user_api/index.rst
internal_api/index.rst internal_api/index.rst

1176
doc/source/basic_usage.rst

File diff suppressed because it is too large Load Diff

7
doc/source/diagnostics.rst

@ -0,0 +1,7 @@
.. _diagnostic-table:
Table of Available Diagnostics
=================================
.. include:: _templates/product_table.txt

26
doc/source/index.rst

@ -3,14 +3,32 @@
You can adapt this file completely to your liking, but it should at least You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive. contain the root `toctree` directive.
User Guide for wrf-python
==========================
Contents: wrf-python
===========
wrf-python is a package to help users working with the Weather
Research and Forecasting Model (WRF-ARW) output. wrf-python includes over
thirty diagnostics calculations along with various interpolation routines. When
coupled with either matplotlib or PyNGL, users can create plots like this:
.. image:: _static/images/matthew.png
:scale: 100%
:align: center
Documentation
==================
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 2
./new
./installation
./diagnostics
./basic_usage
./plot
./api ./api

54
doc/source/installation.rst

@ -0,0 +1,54 @@
Installation
============
Required Dependencies
----------------------
- Python 2.7, 3.4, or 3.5
- numpy (1.9 or later)
- wrapt (1.10 or later)
Highly Recommended Packages
----------------------------
- xarray (0.7.0 or later)
- PyNIO (1.4.3 or later)
- netCDF4-python (1.2.0 or later)
Plotting Packages
-------------------------
- PyNGL (1.4.3 or later)
- matplotlib (1.4.3 or later)
- cartopy (0.13 or later)
- basemap (1.0.8 or later)
Installing via Conda
---------------------
The easiest way to install wrf-python is using
`Conda <http://conda.pydata.org/docs/>`_::
$ conda install -c bladwig wrf-python
Installing via Source Code
--------------------------
Installation via source code will require a Fortran and C compiler in order
to run f2py. You can get them
`here <https://gcc.gnu.org/wiki/GFortranBinaries>`_.
The source code is available via github:
https://github.com/NCAR/wrf-python
To install, change to the wrf-python directory and run::
$ pip install .

2
doc/source/internal_api/index.rst

@ -1,8 +1,6 @@
Internal API Internal API
============= =============
-------------
Routines Routines
------------- -------------

10
doc/source/new.rst

@ -0,0 +1,10 @@
What's New
===========
v1.0a3
-----------
- Alpha release 3
- Added docstrings
- Now uses CoordPair for cross sections so that lat/lon can be used
- Renamed some functions and or arguments

91
doc/source/plot.rst

@ -0,0 +1,91 @@
Plotting Examples
=================
The examples below show how wrf-python can be used to make plots with
matplotlib (with basemap and cartopy) and PyNGL. None of these examples
make use of xarray's builtin plotting functions, since additional work is most
likely needed to extend xarray in order to work correctly. This is planned
for a future release.
Matplotlib With Cartopy
-------------------------
Cartopy is becoming the main tool for base mapping with matplotlib, but you should
be aware of a few shortcomings when working with WRF data.
- The builtin tranformations of coordinates when calling the contouring functions
do not work correctly with the rotated pole projection. The
transform_points method needs to be called manually on the latitude and
longitude arrays.
- The rotated pole projection requires the x and y limits to be set manually
using set_xlim and set_ylim.
- You can't place latitude and longitude labels on the axes when using
any projection other than Mercator or LatLon.
Plotting a Two-dimensional Field
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. image:: _static/images/cartopy_slp.png
:scale: 100%
:align: center
.. code-block:: python
from __future__ import (absolute_import, division, print_function, unicode_literals)
from netCDF4 import Dataset
import matplotlib.pyplot as plt
from matplotlib.cm import get_cmap
import cartopy.crs as crs
from cartopy.feature import NaturalEarthFeature
from wrf import npvalues, getvar, smooth2d
ncfile = Dataset("wrfout_d01_2016-10-07_00_00_00")
# Get the sea level pressure
slp = getvar(ncfile, "slp")
# Smooth the sea level pressure since it tends to be noisy near the mountains
smooth_slp = smooth2d(slp, 3)
# Get the numpy array from the XLAT and XLONG coordinates
lats = npvalues(slp.coords["XLAT"])
lons = npvalues(slp.coords["XLONG"])
# Get the wrf.WrfProj object
wrf_proj = slp.attrs["projection"]
# The WrfProj.cartopy() method returns a cartopy.crs projection object
cart_proj = wrf_proj.cartopy()
# Create a figure that's 10x10
fig = plt.figure(figsize=(10,10))
# Get the GeoAxes set to the projection used by WRF
ax = plt.axes(projection=cart_proj)
# Download and add the states and coastlines
states = NaturalEarthFeature(category='cultural', scale='50m', facecolor='none',
name='admin_1_states_provinces_shp')
ax.add_feature(states, linewidth=.5)
ax.coastlines('50m', linewidth=0.8)
# Make the contour outlines and filled contours for the smoothed sea level pressure.
# The transform keyword indicates that the lats and lons arrays are lat/lon coordinates and tells
# cartopy to transform the points in to the WRF projection set for the GeoAxes.
plt.contour(lons, lats, npvalues(smooth_slp), 10, colors="black", transform=crs.PlateCarree())
plt.contourf(lons, lats, npvalues(smooth_slp), 10, transform=crs.PlateCarree())
# Add a color bar
plt.colorbar(ax=ax, shrink=.47)
# Set the map limits
ax.set_xlim(wrf_proj.cartopy_xlim())
ax.set_ylim(wrf_proj.cartopy_ylim())
# Add the gridlines
ax.gridlines()

2
doc/source/user_api/index.rst

@ -1,8 +1,6 @@
User API User API
============= =============
-----------------
Routines Routines
------------------ ------------------

2
src/wrf/api.py

@ -29,6 +29,7 @@ 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 cache import cache_item, get_cached_item from cache import cache_item, get_cached_item
from .version import __version__ from .version import __version__
@ -63,6 +64,7 @@ __all__ += ["npvalues", "extract_global_attrs", "is_standard_wrf_var",
__all__ += ["WrfProj", "NullProjection", "LambertConformal", "Mercator", __all__ += ["WrfProj", "NullProjection", "LambertConformal", "Mercator",
"PolarStereographic", "LatLon", "RotatedLatLon", "getproj"] "PolarStereographic", "LatLon", "RotatedLatLon", "getproj"]
__all__ += ["CoordPair"] __all__ += ["CoordPair"]
__all__ += ["to_xy_coords"]
__all__ += ["cache_item", "get_cached_item"] __all__ += ["cache_item", "get_cached_item"]
__all__ += ["__version__"] __all__ += ["__version__"]

34
src/wrf/interputils.py

@ -408,23 +408,25 @@ def to_xy_coords(pairs, wrfin=None, timeidx=0, stagger=None, projection=None):
latinc = 0.0 latinc = 0.0
loninc = 0.0 loninc = 0.0
xy_vals = _ll_to_xy(lat, lon, meta=False, squeeze=True, xy_vals = _ll_to_xy(lat, lon, meta=False, squeeze=True,
as_int=True, as_int=True,
map_proj=projection.map_proj, map_proj=projection.map_proj,
truelat1=projection.truelat1, truelat1=projection.truelat1,
truelat2=projection.truelat2, truelat2=projection.truelat2,
stand_lon=projection.stand_lon, stand_lon=projection.stand_lon,
ref_lat=projection.ll_lat, ref_lat=projection.ll_lat,
ref_lon=projection.ll_lon, ref_lon=projection.ll_lon,
pole_lat=pole_lat, pole_lat=pole_lat,
pole_lon=pole_lon, pole_lon=pole_lon,
known_x=0, known_x=0,
known_y=0, known_y=0,
dx=projection.dx, dx=projection.dx,
dy=projection.dy, dy=projection.dy,
latinc=latinc, latinc=latinc,
loninc=loninc) loninc=loninc)
xy_vals = xy_vals.squeeze()
if xy_vals.ndim == 1: if xy_vals.ndim == 1:
return CoordPair(x=xy_vals[0], y=xy_vals[1]) return CoordPair(x=xy_vals[0], y=xy_vals[1])

16
src/wrf/latlonutils.py

@ -9,7 +9,8 @@ from .constants import Constants, ProjectionTypes
from .extension import _lltoxy, _xytoll from .extension import _lltoxy, _xytoll
from .util import (extract_vars, extract_global_attrs, from .util import (extract_vars, extract_global_attrs,
either, is_moving_domain, is_multi_time_req, either, is_moving_domain, is_multi_time_req,
iter_left_indexes, is_mapping, is_multi_file) iter_left_indexes, is_mapping, is_multi_file,
npvalues)
from .py3compat import viewkeys, viewitems from .py3compat import viewkeys, viewitems
from .projutils import dict_keys_to_upper from .projutils import dict_keys_to_upper
@ -372,11 +373,10 @@ def _ll_to_xy(latitude, longitude, wrfin=None, timeidx=0,
lats = np.asarray(latitude) lats = np.asarray(latitude)
lons = np.asarray(longitude) lons = np.asarray(longitude)
if lats.ndim > 1: # Note: For scalars, this will make a single element array
lats = lats.ravel() lats = lats.ravel()
if lons.ndim > 1: lons = lons.ravel()
lons = lons.ravel()
if (lats.size != lons.size): if (lats.size != lons.size):
raise ValueError("'latitude' and 'longitude' " raise ValueError("'latitude' and 'longitude' "
@ -541,11 +541,9 @@ def _xy_to_ll(x, y, wrfin=None, timeidx=0, stagger=None,
x_arr = x_arr + 1 x_arr = x_arr + 1
y_arr = y_arr + 1 y_arr = y_arr + 1
if x_arr.ndim > 1: x_arr = x_arr.ravel()
x_arr = x_arr.ravel()
if y_arr.ndim > 1: y_arr = y_arr.ravel()
y_arr = y_arr.ravel()
if (x_arr.size != y_arr.size): if (x_arr.size != y_arr.size):
raise ValueError("'x' and 'y' must be the same length") raise ValueError("'x' and 'y' must be the same length")

2
src/wrf/metadecorators.py

@ -783,7 +783,7 @@ def _set_horiz_meta(wrapped, instance, args, kwargs):
outname = "field3d_{0}".format(name_levelstr) outname = "field3d_{0}".format(name_levelstr)
outattrs = OrderedDict() outattrs = OrderedDict()
outattrs["PlotLevelID"] = levelstr outattrs["level"] = levelstr
outattrs["missing_value"] = missingval outattrs["missing_value"] = missingval
outattrs["_FillValue"] = missingval outattrs["_FillValue"] = missingval

5
src/wrf/projection.py

@ -47,7 +47,7 @@ if cartopy_enabled():
extent of the projection. Default is -80.0. extent of the projection. Default is -80.0.
max_latitude (:obj:`float`, optional): The maximum northerly max_latitude (:obj:`float`, optional): The maximum northerly
extent of the projection. Default is 84.0.. extent of the projection. Default is 84.0.
globe (:class:`cartopy.crs.Globe`, optional): A globe object. globe (:class:`cartopy.crs.Globe`, optional): A globe object.
If omitted, a default globe is created. If omitted, a default globe is created.
@ -280,10 +280,13 @@ class WrfProj(object):
def __repr__(self): def __repr__(self):
args = ("bottom_left={}, top_right={}, " args = ("bottom_left={}, top_right={}, "
"stand_lon={}, moad_cen_lat={}, " "stand_lon={}, moad_cen_lat={}, "
"truelat1={}, truelat2={}, "
"pole_lat={}, pole_lon={}".format((self.ll_lat, self.ll_lon), "pole_lat={}, pole_lon={}".format((self.ll_lat, self.ll_lon),
(self.ur_lat, self.ur_lon), (self.ur_lat, self.ur_lon),
self.stand_lon, self.stand_lon,
self.moad_cen_lat, self.moad_cen_lat,
self.truelat1,
self.truelat2,
self.pole_lat, self.pole_lat,
self.pole_lon)) self.pole_lon))
return "{}({})".format(self.__class__.__name__, args) return "{}({})".format(self.__class__.__name__, args)

6
src/wrf/util.py

@ -920,14 +920,11 @@ def _combine_dict(wrfdict, varname, timeidx, method, meta, _key):
is_moving = is_moving_domain(wrfdict, varname, _key=_key) is_moving = is_moving_domain(wrfdict, varname, _key=_key)
# Not quite sure how to handle coord caching with dictionaries, so
# disabling it for now by setting _key to None.
first_array = _extract_var(wrfdict[first_key], varname, first_array = _extract_var(wrfdict[first_key], varname,
timeidx, is_moving=is_moving, method=method, timeidx, is_moving=is_moving, method=method,
squeeze=False, cache=None, meta=meta, squeeze=False, cache=None, meta=meta,
_key=_key[first_key]) _key=_key[first_key])
# Create the output data numpy array based on the first array # Create the output data numpy array based on the first array
outdims = [numkeys] outdims = [numkeys]
outdims += first_array.shape outdims += first_array.shape
@ -1587,7 +1584,6 @@ def _cat_files(wrfseq, varname, timeidx, is_moving, squeeze, meta, _key):
outdata[startidx:endidx, :] = vardata[:] outdata[startidx:endidx, :] = vardata[:]
if xarray_enabled() and meta: if xarray_enabled() and meta:
# XTIME new in 3.7
if timename is not None and not timecached: if timename is not None and not timecached:
xtimedata = wrfnc.variables[timename][:] xtimedata = wrfnc.variables[timename][:]
outxtimes[startidx:endidx] = xtimedata[:] outxtimes[startidx:endidx] = xtimedata[:]
@ -2414,7 +2410,7 @@ def extract_times(wrfin, timeidx, method="cat", squeeze=True, cache=None,
dims=outdimnames, attrs=outattrs) dims=outdimnames, attrs=outattrs)
else: else:
outarr = np.asarray(time_list) outarr = np.asarray(time_list, dtype="datetime64[ns]")
if not multitime: if not multitime:
return outarr[timeidx] return outarr[timeidx]

6
src/wrf/uvmet.py

@ -18,7 +18,7 @@ from .util import extract_vars, extract_global_attrs, either
@convert_units("wind", "m s-1") @convert_units("wind", "m s-1")
def _get_uvmet(wrfin, timeidx=0, method="cat", squeeze=True, def _get_uvmet(wrfin, timeidx=0, method="cat", squeeze=True,
cache=None, meta=True, _key=None, cache=None, meta=True, _key=None,
ten_m=False, units ="m s-1"): ten_m=False, units="m s-1"):
"""Return the u,v wind components rotated to earth coordinates. """Return the u,v wind components rotated to earth coordinates.
The leftmost dimension of the returned array represents two different The leftmost dimension of the returned array represents two different
@ -426,7 +426,7 @@ def get_uvmet_wspd_wdir(wrfin, timeidx=0, method="cat", squeeze=True,
""" """
uvmet = _get_uvmet(wrfin, timeidx, method, squeeze, uvmet = _get_uvmet(wrfin, timeidx, method, squeeze,
cache, meta, _key, False, units) cache, meta, _key, False, units="m s-1")
return _calc_wspd_wdir(uvmet[0,...,:,:,:], uvmet[1,...,:,:,:], return _calc_wspd_wdir(uvmet[0,...,:,:,:], uvmet[1,...,:,:,:],
False, units) False, units)
@ -509,7 +509,7 @@ def get_uvmet10_wspd_wdir(wrfin, timeidx=0, method="cat", squeeze=True,
""" """
uvmet10 = _get_uvmet(wrfin, timeidx, method, squeeze, cache, meta, _key, uvmet10 = _get_uvmet(wrfin, timeidx, method, squeeze, cache, meta, _key,
True, units) True, units="m s-1")
return _calc_wspd_wdir(uvmet10[0,...,:,:], uvmet10[1,...,:,:], True, units) return _calc_wspd_wdir(uvmet10[0,...,:,:], uvmet10[1,...,:,:], True, units)

415
test/ipynb/Doc_Examples.ipynb

@ -0,0 +1,415 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"%matplotlib inline"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"from __future__ import (absolute_import, division, print_function, unicode_literals)\n",
"\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"from matplotlib.cm import get_cmap\n",
"import cartopy.crs as crs\n",
"import cartopy.feature as cfeature\n",
"from netCDF4 import Dataset as nc\n",
"\n",
"from wrf import npvalues, getvar, smooth2d\n",
"\n",
"# Open the output NetCDF with netcdf-python\n",
"filename = \"/Users/ladwig/Documents/wrf_files/wrfout_d01_2016-10-07_00_00_00\"\n",
"ncfile = nc(filename)\n",
"\n",
"# Get sea level pressure and cloud top temperature\n",
"slp = getvar(ncfile, \"slp\")\n",
"ctt = getvar(ncfile, \"ctt\")\n",
"\n",
"# Smooth the SLP\n",
"smooth_slp = smooth2d(slp, 3)\n",
"\n",
"# Extract the latitude and longitude coordinate arrays as regular numpy array instead of xarray.DataArray\n",
"lons = npvalues(slp.coords[\"XLONG\"])\n",
"lats = npvalues(slp.coords[\"XLAT\"])\n",
"\n",
"# Get the cartopy projection class\n",
"wrf_proj = slp.attrs[\"projection\"]\n",
"cart_proj = wrf_proj.cartopy()\n",
"\n",
"# Create the figure\n",
"fig = plt.figure(figsize=(4,4))\n",
"ax = plt.axes([0.1,0.1,0.8,0.8], projection=cart_proj)\n",
"\n",
"# Download and create the states, land, and oceans using cartopy features\n",
"states = cfeature.NaturalEarthFeature(category='cultural', scale='50m', facecolor='none',\n",
" name='admin_1_states_provinces_shp')\n",
"land = cfeature.NaturalEarthFeature(category='physical', name='land', scale='50m', \n",
" facecolor=cfeature.COLORS['land'])\n",
"ocean = cfeature.NaturalEarthFeature(category='physical', name='ocean', scale='50m', \n",
" facecolor=cfeature.COLORS['water'])\n",
"\n",
"# Make the pressure contours.\n",
"contour_levels = [960, 965, 970, 975, 980, 990]\n",
"c1 = plt.contour(lons, lats, npvalues(smooth_slp), levels=contour_levels, colors=\"white\", \n",
" transform=crs.PlateCarree(), zorder=3, linewidths=1.0)\n",
"\n",
"# Add pressure contour labels\n",
"#plt.clabel(c1, contour_levels, inline=True, fmt='%.0f', fontsize=7)\n",
"\n",
"# Create the filled cloud top temperature contours\n",
"contour_levels = [-80, -70, -60, -50, -40, -30, -20, -10, 0, 10]\n",
"plt.contourf(lons, lats, npvalues(ctt), contour_levels, cmap=get_cmap(\"Greys\"),\n",
" transform=crs.PlateCarree(), zorder=2)\n",
"\n",
"plt.plot([-80,-77.8], [26.75,26.75], color=\"yellow\", marker=\"o\", transform=crs.PlateCarree(), zorder=3)\n",
"\n",
"# Create the label bar for cloud top temperature\n",
"#cb2 = plt.colorbar(ax=ax, fraction=0.046, pad=0.04)\n",
"cb2 = plt.colorbar(ax=ax)\n",
"\n",
"# Draw the oceans, land, and states\n",
"ax.add_feature(ocean)\n",
"ax.add_feature(land)\n",
"ax.add_feature(states, linewidth=.5, edgecolor=\"black\")\n",
"\n",
"# Crop the domain to the region around the hurricane\n",
"ax.set_extent([-85., -75.0, np.amin(lats), 30.0], crs=crs.PlateCarree())\n",
"ax.gridlines(crs=crs.PlateCarree(), draw_labels=False)\n",
"\n",
"# Add the title and show the image\n",
"#plt.title(\"Hurricane Matthew Cloud Top Temperature (degC) \")\n",
"plt.savefig(\"/Users/ladwig/Documents/workspace/wrf_python/doc/source/_static/images/matthew.png\",\n",
" transparent=True, bbox_inches=\"tight\")\n",
"plt.show()\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"%matplotlib inline\n",
"\n",
"from __future__ import (absolute_import, division, print_function, unicode_literals)\n",
"\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"from matplotlib.cm import get_cmap\n",
"import cartopy.crs as crs\n",
"from cartopy.feature import NaturalEarthFeature\n",
"from Nio import open_file\n",
"\n",
"from wrf import npvalues, getvar, smooth2d, ll_to_xy, CoordPair, vertcross, getproj, get_proj_params, to_xy_coords\n",
"\n",
"# Open the output NetCDF file with PyNIO\n",
"filename = \"/Users/ladwig/Documents/wrf_files/wrfout_d01_2016-10-07_00_00_00\"\n",
"pynio_filename = filename + \".nc\"\n",
"ncfile = open_file(pynio_filename)\n",
"\n",
"# Extract pressure and model height\n",
"z = getvar(ncfile, \"z\", timeidx=0)\n",
"dbz = getvar(ncfile, \"dbz\", timeidx=0)\n",
"\n",
"wspd = getvar(ncfile, \"uvmet_wspd_wdir\", units=\"kt\")[0,:]\n",
"Z = 10**(dbz/10.)\n",
"\n",
"start_point = CoordPair(lat=26.75, lon=-80.0)\n",
"end_point = CoordPair(lat=26.75, lon=-77.8)\n",
"\n",
"# Compute the vertical cross-section interpolation. Also, include the lat/lon points along the cross-section.\n",
"z_cross = vertcross(Z, z, wrfin=ncfile, start_point=start_point, end_point=end_point, latlon=True, meta=True)\n",
"wspd_cross = vertcross(wspd, z, wrfin=ncfile, start_point=start_point, end_point=end_point, latlon=True, meta=True)\n",
"dbz_cross = 10.0 * np.log10(z_cross)\n",
"\n",
"# Create the figure\n",
"fig, axes = plt.subplots(nrows=2, ncols=1, figsize=(4,4))\n",
"#ax = plt.axes([0.1,0.1,0.8,0.8])\n",
"\n",
"# Define the contour levels [0, 50, 100, 150, ....]\n",
"levels = [5 + 5*n for n in range(15)]\n",
"\n",
"# Make the contour plot\n",
"a = axes[0].contourf(npvalues(wspd_cross))\n",
"# Add the color bar\n",
"fig.colorbar(a, ax=axes[0])\n",
"\n",
"b = axes[1].contourf(npvalues(dbz_cross), levels=levels)\n",
"fig.colorbar(b, ax=axes[1])\n",
"\n",
"# Set the x-ticks to use latitude and longitude labels.\n",
"coord_pairs = npvalues(dbz_cross.coords[\"xy_loc\"])\n",
"x_ticks = np.arange(coord_pairs.shape[0])\n",
"x_labels = [pair.latlon_str() for pair in npvalues(coord_pairs)]\n",
"axes[0].set_xticks(x_ticks[::20])\n",
"axes[0].set_xticklabels([], rotation=45)\n",
"axes[1].set_xticks(x_ticks[::20])\n",
"axes[1].set_xticklabels(x_labels[::20], rotation=45, fontsize=6) \n",
"\n",
"\n",
"# Set the y-ticks to be height.\n",
"vert_vals = npvalues(dbz_cross.coords[\"vertical\"])\n",
"v_ticks = np.arange(vert_vals.shape[0])\n",
"axes[0].set_yticks(v_ticks[::20])\n",
"axes[0].set_yticklabels(vert_vals[::20], fontsize=6) \n",
"axes[1].set_yticks(v_ticks[::20])\n",
"axes[1].set_yticklabels(vert_vals[::20], fontsize=6) \n",
"\n",
"# Set the x-axis and y-axis labels\n",
"axes[1].set_xlabel(\"Latitude, Longitude\", fontsize=7)\n",
"axes[0].set_ylabel(\"Height (m)\", fontsize=7)\n",
"axes[1].set_ylabel(\"Height (m)\", fontsize=7)\n",
"\n",
"# Add a title\n",
"axes[0].set_title(\"Cross-Section of Wind Speed (kt)\", {\"fontsize\" : 10})\n",
"axes[1].set_title(\"Cross-Section of Reflectivity (dBZ)\", {\"fontsize\" : 10})\n",
"\n",
"plt.savefig(\"/Users/ladwig/Documents/workspace/wrf_python/doc/source/_static/images/matthew_cross.png\",\n",
" transparent=True, bbox_inches=\"tight\")\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"%matplotlib inline\n",
"\n",
"from __future__ import (absolute_import, division, print_function, unicode_literals)\n",
"\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"from matplotlib.cm import get_cmap\n",
"import cartopy.crs as crs\n",
"import cartopy.feature as cfeature\n",
"from Nio import open_file\n",
"\n",
"from wrf import getvar, npvalues, vertcross, smooth2d, CoordPair\n",
"\n",
"# Open the output NetCDF file with PyNIO\n",
"filename = \"/Users/ladwig/Documents/wrf_files/wrfout_d01_2016-10-07_00_00_00\"\n",
"pynio_filename = filename + \".nc\"\n",
"ncfile = open_file(pynio_filename)\n",
"\n",
"# Get the WRF variables\n",
"slp = getvar(ncfile, \"slp\")\n",
"smooth_slp = smooth2d(slp, 3)\n",
"ctt = getvar(ncfile, \"ctt\")\n",
"z = getvar(ncfile, \"z\", timeidx=0)\n",
"dbz = getvar(ncfile, \"dbz\", timeidx=0)\n",
"Z = 10**(dbz/10.)\n",
"wspd = getvar(ncfile, \"uvmet_wspd_wdir\", units=\"kt\")[0,:]\n",
"\n",
"# Set the start point and end point for the cross section\n",
"start_point = CoordPair(lat=26.75, lon=-80.0)\n",
"end_point = CoordPair(lat=26.75, lon=-77.8)\n",
"\n",
"# Compute the vertical cross-section interpolation. Also, include the lat/lon points along the cross-section.\n",
"z_cross = vertcross(Z, z, wrfin=ncfile, start_point=start_point, end_point=end_point, latlon=True, meta=True)\n",
"wspd_cross = vertcross(wspd, z, wrfin=ncfile, start_point=start_point, end_point=end_point, latlon=True, meta=True)\n",
"dbz_cross = 10.0 * np.log10(z_cross)\n",
"\n",
"# Extract the latitude and longitude coordinate arrays as regular numpy array instead of xarray.DataArray\n",
"lons = npvalues(slp.coords[\"XLONG\"])\n",
"lats = npvalues(slp.coords[\"XLAT\"])\n",
"\n",
"# Get the cartopy projection class\n",
"wrf_proj = slp.attrs[\"projection\"]\n",
"cart_proj = wrf_proj.cartopy()\n",
"\n",
"# Create the figure which will have 3 subplots\n",
"fig = plt.figure(figsize=(7,5))\n",
"ax_ctt = fig.add_subplot(1,2,1,projection=cart_proj)\n",
"ax_wspd = fig.add_subplot(2,2,2)\n",
"ax_dbz = fig.add_subplot(2,2,4)\n",
"\n",
"## Plot the cloud top temperature\n",
"\n",
"# Download and create the states, land, and oceans using cartopy features\n",
"states = cfeature.NaturalEarthFeature(category='cultural', scale='50m', facecolor='none',\n",
" name='admin_1_states_provinces_shp')\n",
"land = cfeature.NaturalEarthFeature(category='physical', name='land', scale='50m', \n",
" facecolor=cfeature.COLORS['land'])\n",
"ocean = cfeature.NaturalEarthFeature(category='physical', name='ocean', scale='50m', \n",
" facecolor=cfeature.COLORS['water'])\n",
"\n",
"# Make the pressure contours.\n",
"contour_levels = [960, 965, 970, 975, 980, 990]\n",
"c1 = ax_ctt.contour(lons, lats, npvalues(smooth_slp), levels=contour_levels, colors=\"white\", \n",
" transform=crs.PlateCarree(), zorder=3, linewidths=1.0)\n",
"\n",
"# Create the filled cloud top temperature contours\n",
"contour_levels = [-80.0, -70.0, -60, -50, -40, -30, -20, -10, 0, 10]\n",
"ctt_contours = ax_ctt.contourf(lons, lats, npvalues(ctt), contour_levels, cmap=get_cmap(\"Greys\"),\n",
" transform=crs.PlateCarree(), zorder=2)\n",
"\n",
"ax_ctt.plot([start_point.lon, end_point.lon], [start_point.lat, end_point.lat], color=\"yellow\", \n",
" marker=\"o\", transform=crs.PlateCarree(), zorder=3)\n",
"\n",
"# Create the label bar for cloud top temperature\n",
"cb_ctt = fig.colorbar(ctt_contours, ax=ax_ctt, shrink=.5)\n",
"cb_ctt.ax.tick_params(labelsize=5)\n",
"\n",
"# Draw the oceans, land, and states\n",
"ax_ctt.add_feature(ocean)\n",
"ax_ctt.add_feature(land)\n",
"ax_ctt.add_feature(states, linewidth=.5, edgecolor=\"black\")\n",
"\n",
"# Crop the domain to the region around the hurricane\n",
"ax_ctt.set_extent([-85., -75.0, np.amin(lats), 30.0], crs=crs.PlateCarree())\n",
"ax_ctt.gridlines(crs=crs.PlateCarree(), draw_labels=False)\n",
"\n",
"## Plot the cross sections\n",
"\n",
"# Make the contour plot for wspd\n",
"wspd_contours = ax_wspd.contourf(npvalues(wspd_cross))\n",
"# Add the color bar\n",
"cb_wspd = fig.colorbar(wspd_contours, ax=ax_wspd)\n",
"cb_wspd.ax.tick_params(labelsize=5)\n",
"\n",
"# Make the contour plot for dbz\n",
"levels = [5 + 5*n for n in range(15)]\n",
"dbz_contours = ax_dbz.contourf(npvalues(dbz_cross), levels=levels)\n",
"cb_dbz = fig.colorbar(dbz_contours, ax=ax_dbz)\n",
"cb_dbz.ax.tick_params(labelsize=5)\n",
"\n",
"# Set the x-ticks to use latitude and longitude labels.\n",
"coord_pairs = npvalues(dbz_cross.coords[\"xy_loc\"])\n",
"x_ticks = np.arange(coord_pairs.shape[0])\n",
"x_labels = [pair.latlon_str() for pair in npvalues(coord_pairs)]\n",
"ax_wspd.set_xticks(x_ticks[::20])\n",
"ax_wspd.set_xticklabels([], rotation=45)\n",
"ax_dbz.set_xticks(x_ticks[::20])\n",
"ax_dbz.set_xticklabels(x_labels[::20], rotation=45, fontsize=4) \n",
"\n",
"\n",
"# Set the y-ticks to be height.\n",
"vert_vals = npvalues(dbz_cross.coords[\"vertical\"])\n",
"v_ticks = np.arange(vert_vals.shape[0])\n",
"ax_wspd.set_yticks(v_ticks[::20])\n",
"ax_wspd.set_yticklabels(vert_vals[::20], fontsize=4) \n",
"ax_dbz.set_yticks(v_ticks[::20])\n",
"ax_dbz.set_yticklabels(vert_vals[::20], fontsize=4) \n",
"\n",
"# Set the x-axis and y-axis labels\n",
"ax_dbz.set_xlabel(\"Latitude, Longitude\", fontsize=5)\n",
"ax_wspd.set_ylabel(\"Height (m)\", fontsize=5)\n",
"ax_dbz.set_ylabel(\"Height (m)\", fontsize=5)\n",
"\n",
"# Add a title\n",
"ax_ctt.set_title(\"Cloud Top Temperature (degC)\", {\"fontsize\" : 7})\n",
"ax_wspd.set_title(\"Cross-Section of Wind Speed (kt)\", {\"fontsize\" : 7})\n",
"ax_dbz.set_title(\"Cross-Section of Reflectivity (dBZ)\", {\"fontsize\" : 7})\n",
"\n",
"plt.savefig(\"/Users/ladwig/Documents/workspace/wrf_python/doc/source/_static/images/matthew.png\",\n",
" transparent=True, bbox_inches=\"tight\")\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# SLP\n",
"from __future__ import (absolute_import, division, print_function, unicode_literals)\n",
" \n",
"from netCDF4 import Dataset \n",
"import matplotlib.pyplot as plt\n",
"from matplotlib.cm import get_cmap\n",
"import cartopy.crs as crs\n",
"from cartopy.feature import NaturalEarthFeature\n",
"\n",
"from wrf import npvalues, getvar, smooth2d\n",
"\n",
"ncfile = Dataset(\"/Users/ladwig/Documents/wrf_files/wrfout_d01_2016-10-07_00_00_00\")\n",
"\n",
"# Get the sea level pressure\n",
"slp = getvar(ncfile, \"slp\")\n",
"\n",
"# Smooth the sea level pressure since it tends to be noisey near the mountains\n",
"smooth_slp = smooth2d(slp, 3)\n",
"\n",
"# Get the numpy array from the XLAT and XLONG coordinates\n",
"lats = npvalues(slp.coords[\"XLAT\"])\n",
"lons = npvalues(slp.coords[\"XLONG\"])\n",
"\n",
"# Get the wrf.WrfProj object\n",
"wrf_proj = slp.attrs[\"projection\"]\n",
"\n",
"# The cartopy() method returns a cartopy.crs projection object\n",
"cart_proj = wrf_proj.cartopy()\n",
"\n",
"# Create a figure that's 10x10\n",
"fig = plt.figure(figsize=(10,10))\n",
"# Get the GeoAxes set to the projection used by WRF\n",
"ax = plt.axes(projection=cart_proj)\n",
"\n",
"# Download and add the states and coastlines\n",
"states = NaturalEarthFeature(category='cultural', scale='50m', facecolor='none',\n",
" name='admin_1_states_provinces_shp')\n",
"ax.add_feature(states, linewidth=.5)\n",
"ax.coastlines('50m', linewidth=0.8)\n",
"\n",
"# Make the contour outlines and filled contours for the smoothed sea level pressure.\n",
"# The transform keyword indicates that the lats and lons arrays are lat/lon coordinates and tells \n",
"# cartopy to transform the points in to grid space.\n",
"plt.contour(lons, lats, npvalues(smooth_slp), 10, colors=\"black\", transform=crs.PlateCarree())\n",
"plt.contourf(lons, lats, npvalues(smooth_slp), 10, transform=crs.PlateCarree())\n",
"\n",
"# Add a color bar\n",
"plt.colorbar(ax=ax, shrink=.47)\n",
"\n",
"# Set the map limits\n",
"ax.set_xlim(wrf_proj.cartopy_xlim())\n",
"ax.set_ylim(wrf_proj.cartopy_ylim())\n",
"\n",
"# Add the gridlines\n",
"ax.gridlines()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.12"
}
},
"nbformat": 4,
"nbformat_minor": 1
}

29
test/ipynb/WRF_Workshop_Demo.ipynb

@ -69,7 +69,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 1,
"metadata": { "metadata": {
"collapsed": true "collapsed": true
}, },
@ -81,11 +81,24 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 2,
"metadata": { "metadata": {
"collapsed": false "collapsed": false
}, },
"outputs": [], "outputs": [
{
"ename": "NIOError",
"evalue": "Unable to open file",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mNIOError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-2-9e6cb63ecf8c>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 7\u001b[0m \u001b[0mfilename\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m\"wrfout_d01_2010-06-13_21-00-00\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0mpynio_filename\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfilename\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m\".nc\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 9\u001b[0;31m \u001b[0mncfile\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mopen_file\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpynio_filename\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 10\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 11\u001b[0m \u001b[0;31m# Alternative using netCDF4-python (for reference)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/Users/ladwig/miniconda2/lib/python2.7/site-packages/PyNIO/Nio.pyc\u001b[0m in \u001b[0;36mopen_file\u001b[0;34m(filename, mode, options, history, format)\u001b[0m\n\u001b[1;32m 733\u001b[0m \u001b[0mmask_above_value\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_get_option_value\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0moptions\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0m_Nio\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0moption_defaults\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m'MaskAboveValue'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 734\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 735\u001b[0;31m \u001b[0mfile\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_Nio\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mopen_file\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfilename\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mmode\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0moptions\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mhistory\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 736\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 737\u001b[0m \u001b[0mfile_proxy\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_proxy\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfile\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'str'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0m__del__\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0m__del__\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mcreate_variable\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mcreate_variable\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mcreate_group\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mcreate_group\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mclose\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mclose\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mNIOError\u001b[0m: Unable to open file"
]
}
],
"source": [ "source": [
"import numpy as np\n", "import numpy as np\n",
"import matplotlib.pyplot as plt\n", "import matplotlib.pyplot as plt\n",
@ -424,21 +437,21 @@
], ],
"metadata": { "metadata": {
"kernelspec": { "kernelspec": {
"display_name": "Python 3", "display_name": "Python 2",
"language": "python", "language": "python",
"name": "python3" "name": "python2"
}, },
"language_info": { "language_info": {
"codemirror_mode": { "codemirror_mode": {
"name": "ipython", "name": "ipython",
"version": 3 "version": 2
}, },
"file_extension": ".py", "file_extension": ".py",
"mimetype": "text/x-python", "mimetype": "text/x-python",
"name": "python", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython2",
"version": "3.5.2" "version": "2.7.12"
} }
}, },
"nbformat": 4, "nbformat": 4,

275
test/ipynb/WRF_python_demo.ipynb

@ -19,14 +19,16 @@
"\n", "\n",
"from wrf import getvar\n", "from wrf import getvar\n",
"from netCDF4 import Dataset as nc\n", "from netCDF4 import Dataset as nc\n",
"ncfile = nc(\"/Users/ladwig/Documents/wrf_files/wrfout_d01_2016-02-25_18_00_00\")\n" "#ncfile = nc(\"/Users/ladwig/Documents/wrf_files/wrfout_d01_2016-02-25_18_00_00\")\n",
"ncfile = nc(\"/Users/ladwig/Documents/wrf_files/wrfout_d01_2016-10-07_00_00_00\")\n"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": { "metadata": {
"collapsed": false "collapsed": false,
"scrolled": false
}, },
"outputs": [], "outputs": [],
"source": [ "source": [
@ -148,8 +150,9 @@
}, },
"outputs": [], "outputs": [],
"source": [ "source": [
"from wrf import ALL_TIMES\n",
"wrflist = [ncfile, ncfile, ncfile]\n", "wrflist = [ncfile, ncfile, ncfile]\n",
"p_cat = getvar(wrflist, \"P\", method=\"cat\")\n", "p_cat = getvar(wrflist, \"P\", timeidx=ALL_TIMES, method=\"cat\")\n",
"print(p_cat)\n", "print(p_cat)\n",
"del p_cat" "del p_cat"
] ]
@ -169,7 +172,7 @@
}, },
"outputs": [], "outputs": [],
"source": [ "source": [
"p_join = getvar(wrflist, \"P\", method=\"join\")\n", "p_join = getvar(wrflist, \"P\", timeidx=ALL_TIMES, method=\"join\")\n",
"print(p_join)" "print(p_join)"
] ]
}, },
@ -191,7 +194,8 @@
}, },
"outputs": [], "outputs": [],
"source": [ "source": [
"p_join = getvar(wrflist, \"P\", timeidx=0, method=\"join\", squeeze=False)\n", "from wrf import ALL_TIMES\n",
"p_join = getvar(wrflist, \"P\", timeidx=ALL_TIMES, method=\"join\", squeeze=False)\n",
"print(p_join)\n", "print(p_join)\n",
"del p_join" "del p_join"
] ]
@ -213,7 +217,7 @@
"source": [ "source": [
"wrf_dict = {\"label1\" : [ncfile, ncfile],\n", "wrf_dict = {\"label1\" : [ncfile, ncfile],\n",
" \"label2\" : [ncfile, ncfile]}\n", " \"label2\" : [ncfile, ncfile]}\n",
"p_dict = getvar(wrf_dict, \"P\")\n", "p_dict = getvar(wrf_dict, \"P\", timeidx=ALL_TIMES)\n",
"print(p_dict)\n", "print(p_dict)\n",
"del p_dict" "del p_dict"
] ]
@ -308,8 +312,9 @@
" \"pvo\", \"pw\", \"rh2\", \"rh\", \"slp\", \"ter\", \"td2\", \"td\", \"tc\",\n", " \"pvo\", \"pw\", \"rh2\", \"rh\", \"slp\", \"ter\", \"td2\", \"td\", \"tc\",\n",
" \"theta\", \"tk\", \"tv\", \"twb\", \"updraft_helicity\", \"ua\", \"va\", \n", " \"theta\", \"tk\", \"tv\", \"twb\", \"updraft_helicity\", \"ua\", \"va\", \n",
" \"wa\", \"uvmet10\", \"uvmet\", \"z\", \"ctt\"]\n", " \"wa\", \"uvmet10\", \"uvmet\", \"z\", \"ctt\"]\n",
"wrf_vars = [\"slp\"]\n",
"\n", "\n",
"vard = {varname: getvar(ncfile, varname, method=\"join\", squeeze=False) for varname in wrf_vars}\n", "vard = {varname: getvar(ncfile, varname, method=\"cat\", squeeze=True) for varname in wrf_vars}\n",
"for varname in wrf_vars:\n", "for varname in wrf_vars:\n",
" print(vard[varname])\n", " print(vard[varname])\n",
" print (\"\\n\")\n" " print (\"\\n\")\n"
@ -331,8 +336,8 @@
"outputs": [], "outputs": [],
"source": [ "source": [
"from wrf import npvalues\n", "from wrf import npvalues\n",
"masked_ndarray = npvalues(vard[\"cape_2d\"])\n", "masked_ndarray = npvalues(vard[\"slp\"])\n",
"print(masked_ndarray)\n", "print(type(masked_ndarray))\n",
"del masked_ndarray" "del masked_ndarray"
] ]
}, },
@ -398,11 +403,11 @@
"outputs": [], "outputs": [],
"source": [ "source": [
"# Pressure using pivot and angle\n", "# Pressure using pivot and angle\n",
"from wrf import getvar, vertcross\n", "from wrf import getvar, vertcross, CoordPair\n",
"\n", "\n",
"z = getvar(ncfile, \"z\")\n", "z = getvar(ncfile, \"z\")\n",
"p = getvar(ncfile, \"pressure\")\n", "p = getvar(ncfile, \"pressure\")\n",
"pivot_point = (z.shape[-1] / 2, z.shape[-2] / 2) \n", "pivot_point = CoordPair((z.shape[-1]-1) // 2, (z.shape[-2] - 1) // 2) \n",
"angle = 90.0\n", "angle = 90.0\n",
"\n", "\n",
"p_vert = vertcross(p, z, pivot_point=pivot_point, angle=angle, latlon=True)\n", "p_vert = vertcross(p, z, pivot_point=pivot_point, angle=angle, latlon=True)\n",
@ -411,14 +416,122 @@
"del p_vert\n", "del p_vert\n",
"\n", "\n",
"# Pressure using start_point and end_point\n", "# Pressure using start_point and end_point\n",
"start_point = (0, z.shape[-2]/2)\n", "start_point = CoordPair(0, (z.shape[-2]-1) // 2)\n",
"end_point = (-1, z.shape[-2]/2)\n", "end_point = CoordPair(-1, (z.shape[-2]-1) // 2)\n",
"\n", "\n",
"p_vert = vertcross(p, z, start_point=start_point, end_point=end_point, latlon=True)\n", "p_vert = vertcross(p, z, start_point=start_point, end_point=end_point, latlon=True)\n",
"print(p_vert)\n", "print(p_vert)\n",
"del p_vert, p, z" "del p_vert, p, z"
] ]
}, },
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# Pressure using pivot and angle\n",
"from wrf import getvar, vertcross, CoordPair, xy_to_ll\n",
"\n",
"z = getvar(ncfile, \"z\")\n",
"p = getvar(ncfile, \"pressure\")\n",
"lats = getvar(ncfile, \"lat\")\n",
"lons = getvar(ncfile, \"lon\")\n",
"\n",
"#print ((lats.shape[-2]-1) / 2)\n",
"#print ((lats.shape[-1]-1) / 2)\n",
"\n",
"#print (npvalues(lats[529, 899]))\n",
"#print (npvalues(lons[529, 899]))\n",
"\n",
"#print (npvalues(lats[529, 0]))\n",
"#print (npvalues(lons[529, 0]))\n",
"\n",
"#print (npvalues(lats[529, -1]))\n",
"#print (npvalues(lons[529, -1]))\n",
"\n",
"pivot_point = CoordPair(lat=38.5, lon=-97.5) \n",
"angle = 90.0\n",
"\n",
"p_vert = vertcross(p, z, wrfin=ncfile, pivot_point=pivot_point, angle=angle, latlon=True)\n",
"print (p_vert)\n",
"print (\"\\n\")\n",
"\n",
"start_lat = lats[(lats.shape[-2]-1)//2, 0]\n",
"end_lat = lats[(lats.shape[-2]-1)//2, -1]\n",
"start_lon = lons[(lats.shape[-2]-1)//2, 0]\n",
"end_lon = lons[(lats.shape[-2]-1)//2, -1]\n",
"\n",
"print (start_lat)\n",
"print (end_lat)\n",
"print (start_lon)\n",
"print (end_lon)\n",
"\n",
"# Pressure using start_point and end_point\n",
"start_point = CoordPair(lat=start_lat, lon=start_lon)\n",
"end_point = CoordPair(lat=end_lat, lon=end_lon)\n",
"\n",
"p_vert = vertcross(p, z, wrfin=ncfile, start_point=start_point, end_point=end_point, latlon=True)\n",
"print(p_vert)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# Pressure using pivot and angle\n",
"from wrf import getvar, vertcross, CoordPair, xy_to_ll\n",
"\n",
"z = getvar(ncfile, \"z\")\n",
"p = getvar(ncfile, \"pressure\")\n",
"lats = getvar(ncfile, \"lat\")\n",
"lons = getvar(ncfile, \"lon\")\n",
"\n",
"#print ((lats.shape[-2]-1) / 2)\n",
"#print ((lats.shape[-1]-1) / 2)\n",
"\n",
"#print (npvalues(lats[529, 899]))\n",
"#print (npvalues(lons[529, 899]))\n",
"\n",
"#print (npvalues(lats[529, 0]))\n",
"#print (npvalues(lons[529, 0]))\n",
"\n",
"#print (npvalues(lats[529, -1]))\n",
"#print (npvalues(lons[529, -1]))\n",
"\n",
"pivot_point = CoordPair(lat=38.5, lon=-97.5) \n",
"angle = 90.0\n",
"\n",
"p_vert = vertcross(p, z, wrfin=ncfile, pivot_point=pivot_point, angle=angle, latlon=True)\n",
"print (p_vert)\n",
"print (\"\\n\")\n",
"\n",
"start_lat = lats[(lats.shape[-2]-1)//2, 0]\n",
"end_lat = lats[(lats.shape[-2]-1)//2, -1]\n",
"start_lon = lons[(lats.shape[-2]-1)//2, 0]\n",
"end_lon = lons[(lats.shape[-2]-1)//2, -1]\n",
"\n",
"print (start_lat)\n",
"print (end_lat)\n",
"print (start_lon)\n",
"print (end_lon)\n",
"\n",
"# Pressure using start_point and end_point\n",
"start_point = CoordPair(lat=start_lat, lon=start_lon)\n",
"end_point = CoordPair(lat=end_lat, lon=end_lon)\n",
"\n",
"levels = [1000., 2000., 3000.]\n",
"\n",
"p_vert = vertcross(p, z, wrfin=ncfile, levels=levels, start_point=start_point, end_point=end_point, latlon=True)\n",
"print(p_vert)"
]
},
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
@ -435,11 +548,11 @@
"outputs": [], "outputs": [],
"source": [ "source": [
"# T2 using pivot and angle\n", "# T2 using pivot and angle\n",
"from wrf import interpline, getvar\n", "from wrf import interpline, getvar, CoordPair\n",
"\n", "\n",
"t2 = getvar(ncfile, \"T2\")\n", "t2 = getvar(ncfile, \"T2\")\n",
"pivot_point = (t2.shape[-2] / 2, t2.shape[-1] / 2) \n", "pivot_point = CoordPair((t2.shape[-1]-1)//2, (t2.shape[-2]-1)//2) \n",
"angle = 90.0\n", "angle = 0.0\n",
"\n", "\n",
"t2_line = interpline(t2, pivot_point=pivot_point, angle=angle, latlon=True)\n", "t2_line = interpline(t2, pivot_point=pivot_point, angle=angle, latlon=True)\n",
"print(t2_line, \"\\n\")\n", "print(t2_line, \"\\n\")\n",
@ -447,13 +560,30 @@
"del t2_line\n", "del t2_line\n",
"\n", "\n",
"# T2 using start_point and end_point\n", "# T2 using start_point and end_point\n",
"start_point = (t2.shape[-2]/2, 0)\n", "start_point = CoordPair((t2.shape[-1]-1)//2, 0)\n",
"end_point = (t2.shape[-2]/2, -1)\n", "end_point = CoordPair((t2.shape[-1]-1)//2, -1)\n",
"\n", "\n",
"t2_line = interpline(t2, start_point=start_point, end_point=end_point, latlon=True)\n", "t2_line = interpline(t2, start_point=start_point, end_point=end_point, latlon=True)\n",
"print(t2_line, \"\\n\")\n", "print(t2_line, \"\\n\")\n",
"\n", "\n",
"del t2_line, t2" "del t2_line\n",
"\n",
"t2 = getvar(ncfile, \"T2\")\n",
"lats = getvar(ncfile, \"lat\")\n",
"lons = getvar(ncfile, \"lon\")\n",
"\n",
"start_lat = lats[0, (lats.shape[-1]-1)//2]\n",
"end_lat = lats[-1, (lats.shape[-1]-1)//2]\n",
"start_lon = lons[0, (lons.shape[-1]-1)//2]\n",
"end_lon = lons[-1, (lons.shape[-1]-1)//2]\n",
"\n",
"start_point = CoordPair(lat=start_lat, lon=start_lon)\n",
"end_point = CoordPair(lat=end_lat, lon=end_lon)\n",
"\n",
"t2_line = interpline(t2, wrfin=ncfile, start_point=start_point, end_point=end_point, latlon=True)\n",
"print (t2_line)\n",
"\n",
"del t2_line, t2\n"
] ]
}, },
{ {
@ -566,7 +696,16 @@
"from wrf.latlon import xy_to_ll, ll_to_xy \n", "from wrf.latlon import xy_to_ll, ll_to_xy \n",
"\n", "\n",
"a = xy_to_ll(ncfile, 400, 200)\n", "a = xy_to_ll(ncfile, 400, 200)\n",
"a1 = ll_to_xy(ncfile, a[0], a[1])\n",
"\n",
"#print(a)\n",
"#print(\"\\n\")\n",
"#print(a1)\n",
"#print(\"\\n\")\n",
"\n",
"a = xy_to_ll(ncfile, [400,105], [200,205])\n", "a = xy_to_ll(ncfile, [400,105], [200,205])\n",
"a1 = ll_to_xy(ncfile, a[0,:], a[1,:])\n",
"\n",
"b = ll_to_xy(ncfile, 45.5, -110.8, as_int=True)\n", "b = ll_to_xy(ncfile, 45.5, -110.8, as_int=True)\n",
"\n", "\n",
"# Note: Lists/Dictionaries of files will add a new dimension ('domain') only if the domain is moving\n", "# Note: Lists/Dictionaries of files will add a new dimension ('domain') only if the domain is moving\n",
@ -577,6 +716,8 @@
"\n", "\n",
"print(a)\n", "print(a)\n",
"print(\"\\n\")\n", "print(\"\\n\")\n",
"print(a1)\n",
"print(\"\\n\")\n",
"print(b)\n", "print(b)\n",
"print(\"\\n\")\n", "print(\"\\n\")\n",
"print(c)\n", "print(c)\n",
@ -618,17 +759,18 @@
"import cartopy.crs as crs\n", "import cartopy.crs as crs\n",
"from cartopy.feature import NaturalEarthFeature\n", "from cartopy.feature import NaturalEarthFeature\n",
"\n", "\n",
"from wrf import npvalues, getvar\n", "from wrf import npvalues, getvar, smooth2d\n",
"\n", "\n",
"slp = getvar(ncfile, \"slp\")\n", "slp = getvar(ncfile, \"slp\")\n",
"smooth_slp = smooth2d(slp, 3)\n",
"lons = npvalues(slp.coords[\"XLONG\"])\n", "lons = npvalues(slp.coords[\"XLONG\"])\n",
"lats = npvalues(slp.coords[\"XLAT\"])\n", "lats = npvalues(slp.coords[\"XLAT\"])\n",
"\n", "\n",
"wrf_proj = slp.attrs[\"projection\"]\n", "wrf_proj = slp.attrs[\"projection\"]\n",
"cart_proj = wrf_proj.cartopy()\n", "cart_proj = wrf_proj.cartopy()\n",
"\n", "\n",
"fig = plt.figure(figsize=(20,20))\n", "fig = plt.figure(figsize=(10,10))\n",
"ax = plt.axes([0.1,0.1,0.8,0.8], projection=cart_proj)\n", "ax = plt.axes(projection=cart_proj)\n",
"\n", "\n",
"states = NaturalEarthFeature(category='cultural', scale='50m', facecolor='none',\n", "states = NaturalEarthFeature(category='cultural', scale='50m', facecolor='none',\n",
" name='admin_1_states_provinces_shp')\n", " name='admin_1_states_provinces_shp')\n",
@ -640,14 +782,80 @@
"x = xform_coords[:,:,0]\n", "x = xform_coords[:,:,0]\n",
"y = xform_coords[:,:,1]\n", "y = xform_coords[:,:,1]\n",
"\n", "\n",
"plt.contour(x, y, npvalues(slp), 20, cmap=get_cmap(\"gist_ncar\"))\n", "plt.contour(x, y, npvalues(smooth_slp), 10, colors=\"black\")\n",
"plt.colorbar(ax=ax, shrink=.7)\n", "plt.contourf(x, y, npvalues(smooth_slp), 10)\n",
"plt.colorbar(ax=ax, shrink=.47)\n",
"\n", "\n",
"ax.set_xlim(wrf_proj.cartopy_xlim())\n", "ax.set_xlim(wrf_proj.cartopy_xlim())\n",
"ax.set_ylim(wrf_proj.cartopy_ylim())\n", "ax.set_ylim(wrf_proj.cartopy_ylim())\n",
"ax.gridlines()\n" "ax.gridlines()\n"
] ]
}, },
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# SLP\n",
"from __future__ import (absolute_import, division, print_function, unicode_literals)\n",
" \n",
"from netCDF4 import Dataset \n",
"import matplotlib.pyplot as plt\n",
"from matplotlib.cm import get_cmap\n",
"import cartopy.crs as crs\n",
"from cartopy.feature import NaturalEarthFeature\n",
"\n",
"from wrf import npvalues, getvar, smooth2d\n",
"\n",
"ncfile = Dataset(\"/Users/ladwig/Documents/wrf_files/wrfout_d01_2016-10-07_00_00_00\")\n",
"\n",
"# Get the sea level pressure\n",
"slp = getvar(ncfile, \"slp\")\n",
"\n",
"# Smooth the sea level pressure since it tends to be noisey near the mountains\n",
"smooth_slp = smooth2d(slp, 3)\n",
"\n",
"# Get the numpy array from the XLAT and XLONG coordinates\n",
"lats = npvalues(slp.coords[\"XLAT\"])\n",
"lons = npvalues(slp.coords[\"XLONG\"])\n",
"\n",
"# Get the wrf.WrfProj object\n",
"wrf_proj = slp.attrs[\"projection\"]\n",
"\n",
"# The cartopy() method returns a cartopy.crs projection object\n",
"cart_proj = wrf_proj.cartopy()\n",
"\n",
"# Create a figure that's 10x10\n",
"fig = plt.figure(figsize=(10,10))\n",
"# Get the GeoAxes set to the projection used by WRF\n",
"ax = plt.axes(projection=cart_proj)\n",
"\n",
"# Download and add the states and coastlines\n",
"states = NaturalEarthFeature(category='cultural', scale='50m', facecolor='none',\n",
" name='admin_1_states_provinces_shp')\n",
"ax.add_feature(states, linewidth=.5)\n",
"ax.coastlines('50m', linewidth=0.8)\n",
"\n",
"# Make the contour outlines and filled contours for the smoothed sea level pressure.\n",
"# The transform keyword indicates that the lats and lons arrays are lat/lon coordinates and tells \n",
"# cartopy to transform the points in to grid space.\n",
"plt.contour(lons, lats, npvalues(smooth_slp), 10, colors=\"black\", transform=crs.PlateCarree())\n",
"plt.contourf(lons, lats, npvalues(smooth_slp), 10, transform=crs.PlateCarree())\n",
"\n",
"# Add a color bar\n",
"plt.colorbar(ax=ax, shrink=.47)\n",
"\n",
"# Set the map limits\n",
"ax.set_xlim(wrf_proj.cartopy_xlim())\n",
"ax.set_ylim(wrf_proj.cartopy_ylim())\n",
"\n",
"# Add the gridlines\n",
"ax.gridlines()"
]
},
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
@ -708,7 +916,8 @@
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": { "metadata": {
"collapsed": false "collapsed": false,
"scrolled": false
}, },
"outputs": [], "outputs": [],
"source": [ "source": [
@ -717,15 +926,15 @@
"import matplotlib.pyplot as plt\n", "import matplotlib.pyplot as plt\n",
"from matplotlib.cm import get_cmap\n", "from matplotlib.cm import get_cmap\n",
"\n", "\n",
"from wrf import getvar, vertcross, npvalues\n", "from wrf import getvar, vertcross, npvalues, CoordPair\n",
"\n", "\n",
"p = getvar(ncfile, \"pressure\")\n", "p = getvar(ncfile, \"pressure\")\n",
"z = getvar(ncfile, \"z\", units=\"dm\")\n", "z = getvar(ncfile, \"z\", units=\"dm\")\n",
"\n", "\n",
"pivot_point = (z.shape[-1] / 2, z.shape[-2] / 2) \n", "pivot_point = CoordPair(z.shape[-1] / 2, z.shape[-2] / 2) \n",
"angle = 90.0\n", "angle = 90.0\n",
"\n", "\n",
"p_vert = vertcross(p, z, pivot_point=pivot_point, angle=angle)\n", "p_vert = vertcross(p, z, pivot_point=pivot_point, angle=angle, levels=[1000,850,500])\n",
"\n", "\n",
"fig = plt.figure(figsize=(20,8))\n", "fig = plt.figure(figsize=(20,8))\n",
"ax = plt.axes([0.1,0.1,0.8,0.8])\n", "ax = plt.axes([0.1,0.1,0.8,0.8])\n",
@ -1038,21 +1247,21 @@
], ],
"metadata": { "metadata": {
"kernelspec": { "kernelspec": {
"display_name": "Python 3", "display_name": "Python 2",
"language": "python", "language": "python",
"name": "python3" "name": "python2"
}, },
"language_info": { "language_info": {
"codemirror_mode": { "codemirror_mode": {
"name": "ipython", "name": "ipython",
"version": 3 "version": 2
}, },
"file_extension": ".py", "file_extension": ".py",
"mimetype": "text/x-python", "mimetype": "text/x-python",
"name": "python", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython2",
"version": "3.5.2" "version": "2.7.12"
} }
}, },
"nbformat": 4, "nbformat": 4,

14
test/utests.py

@ -8,7 +8,7 @@ import subprocess
from wrf import (getvar, interplevel, interpline, vertcross, vinterp, from wrf import (getvar, interplevel, interpline, vertcross, vinterp,
disable_xarray, xarray_enabled, npvalues, disable_xarray, xarray_enabled, npvalues,
xy_to_ll, ll_to_xy, xy_to_ll_proj, ll_to_xy_proj, xy_to_ll, ll_to_xy, xy_to_ll_proj, ll_to_xy_proj,
extract_global_attrs, viewitems) extract_global_attrs, viewitems, CoordPair)
from wrf.util import is_multi_file from wrf.util import is_multi_file
NCL_EXE = "/Users/ladwig/nclbuild/6.3.0/bin/ncl" NCL_EXE = "/Users/ladwig/nclbuild/6.3.0/bin/ncl"
@ -258,7 +258,7 @@ def make_interp_test(varname, wrf_in, referent, multi=False,
hts = getvar(in_wrfnc, "z", timeidx=timeidx) hts = getvar(in_wrfnc, "z", timeidx=timeidx)
p = getvar(in_wrfnc, "pressure", timeidx=timeidx) p = getvar(in_wrfnc, "pressure", timeidx=timeidx)
pivot_point = (hts.shape[-1] / 2, hts.shape[-2] / 2) pivot_point = CoordPair(hts.shape[-1] / 2, hts.shape[-2] / 2)
ht_cross = vertcross(hts, p, pivot_point=pivot_point, angle=90.) ht_cross = vertcross(hts, p, pivot_point=pivot_point, angle=90.)
nt.assert_allclose(npvalues(ht_cross), ref_ht_cross, rtol=.01) nt.assert_allclose(npvalues(ht_cross), ref_ht_cross, rtol=.01)
@ -270,8 +270,8 @@ def make_interp_test(varname, wrf_in, referent, multi=False,
ref_p_cross, ref_p_cross,
rtol=.01) rtol=.01)
# Test point to point # Test point to point
start_point = (0,hts.shape[-2]/2) start_point = CoordPair(0, hts.shape[-2]/2)
end_point = (-1,hts.shape[-2]/2) end_point = CoordPair(-1,hts.shape[-2]/2)
p_cross2 = vertcross(p,hts,start_point=start_point, p_cross2 = vertcross(p,hts,start_point=start_point,
end_point=end_point) end_point=end_point)
@ -284,15 +284,15 @@ def make_interp_test(varname, wrf_in, referent, multi=False,
ref_t2_line = _get_refvals(referent, "t2_line", repeat, multi) ref_t2_line = _get_refvals(referent, "t2_line", repeat, multi)
t2 = getvar(in_wrfnc, "T2", timeidx=timeidx) t2 = getvar(in_wrfnc, "T2", timeidx=timeidx)
pivot_point = (t2.shape[-1] / 2, t2.shape[-2] / 2) pivot_point = CoordPair(t2.shape[-1] / 2, t2.shape[-2] / 2)
t2_line1 = interpline(t2, pivot_point=pivot_point, angle=90.0) t2_line1 = interpline(t2, pivot_point=pivot_point, angle=90.0)
nt.assert_allclose(npvalues(t2_line1), ref_t2_line) nt.assert_allclose(npvalues(t2_line1), ref_t2_line)
# Test point to point # Test point to point
start_point = (0, t2.shape[-2]/2) start_point = CoordPair(0, t2.shape[-2]/2)
end_point = (-1, t2.shape[-2]/2) end_point = CoordPair(-1, t2.shape[-2]/2)
t2_line2 = interpline(t2, start_point=start_point, t2_line2 = interpline(t2, start_point=start_point,
end_point=end_point) end_point=end_point)

Loading…
Cancel
Save