Created
May 3, 2019 18:44
-
-
Save jthielen/8881d32d08d625c75c906a7e8ad7583f to your computer and use it in GitHub Desktop.
Use wrf-python, xarray, and pyproj to post-process WRF output
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from wrf import getvar | |
from netCDF4 import Dataset | |
import xarray as xr | |
import pyproj | |
# Extract the variables of interest at time index 17 | |
ds = Dataset('../wrfout_d02_2015-07-12_1200.nc') | |
variables = [getvar(ds, var, 17) for var in ('z', 'dbz', 'pressure', 'ter', 'ua', | |
'va', 'wa', 'temp', 'rh')] | |
data = xr.merge(variables) | |
# Define the WRF projection (see https://fabienmaussion.info/2018/01/06/wrf-projection/) | |
wrf_proj = pyproj.Proj(proj='lcc', | |
lat_1=ds.TRUELAT1, lat_2=ds.TRUELAT2, | |
lat_0=ds.MOAD_CEN_LAT, lon_0=ds.STAND_LON, | |
a=6370000, b=6370000) | |
# Easting and Northing of the domain center point | |
wgs_proj = pyproj.Proj(proj='latlong', datum='WGS84') | |
e, n = pyproj.transform(wgs_proj, wrf_proj, ds.CEN_LON, ds.CEN_LAT) | |
# Grid parameters | |
dx, dy = ds.DX, ds.DY | |
nx, ny = ds.dimensions['west_east'].size, ds.dimensions['south_north'].size | |
# Lower left corner of the domain | |
x0 = -(nx-1) / 2. * dx + e | |
y0 = -(ny-1) / 2. * dy + n | |
# Get grid values | |
x, y = np.arange(nx) * dx + x0, np.arange(ny) * dy + y0 | |
# Add in dimension coordinates | |
eta_attrs = {attr: ds['ZNU'].getncattr(attr) for attr in ds['ZNU'].ncattrs()} | |
eta_attrs['axis'] = 'Z' | |
data['bottom_top'] = xr.DataArray(ds['ZNU'][17], dims='bottom_top', attrs=eta_attrs) | |
data['south_north'] = xr.DataArray(y, dims='south_north', attrs={'axis': 'Y', 'units': 'm'}) | |
data['west_east'] = xr.DataArray(x, dims='west_east', attrs={'axis': 'X', 'units': 'm'}) | |
# Define the grid_mapping | |
data['LambertConformal'] = xr.DataArray(np.array(0), attrs={ | |
'grid_mapping_name': 'lambert_conformal_conic', | |
'earth_radius': 6370000, | |
'standard_parallel': (ds.TRUELAT1, ds.TRUELAT2), | |
'longitude_of_central_meridian': ds.STAND_LON, | |
'latitude_of_projection_origin': ds.MOAD_CEN_LAT | |
}) | |
for var in data.data_vars: | |
data[var].attrs['grid_mapping'] = 'LambertConformal' | |
if 'projection' in data[var].attrs: | |
del data[var].attrs['projection'] | |
if 'coordinates' in data[var].attrs: | |
del data[var].attrs['coordinates'] | |
# Save result | |
data.to_netcdf('wrfout_d02_2015-07-12_1200_processed.nc') |
Ok, thank you.
I just tried to do your python script. There was the next error.
TypeError: Invalid value for attr 'projection': LambertConformal(stand_lon=137.0, moad_cen_lat=38.0000114440918, truelat1=30.0, truelat2=60.0, pole_lat=90.0, pole_lon=0.0). For serialization to netCDF files, its value must be of one of the following types: str, Number, ndarray, number, list, tuple
It seems that 'coordinates' and 'projection' in global attributes has not been deleted.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@fipoucat Yes, you should be able to alter the
getvar
call on line 8 to useALL_TIMES
(when imported from wrf-python withfrom wrf import ALL_TIMES
). Just note that wrf-python tends to load all data into memory (at least when I've last used it), so this could easily become slow or even fill your available RAM (giving a MemoryError).