Skip to content

Instantly share code, notes, and snippets.

@jthielen
Created May 3, 2019 18:44
Show Gist options
  • Save jthielen/8881d32d08d625c75c906a7e8ad7583f to your computer and use it in GitHub Desktop.
Save jthielen/8881d32d08d625c75c906a7e8ad7583f to your computer and use it in GitHub Desktop.
Use wrf-python, xarray, and pyproj to post-process WRF output
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')
@fipoucat
Copy link

fipoucat commented Jul 6, 2020

is it possible to extract all time steps in the same command

@jthielen
Copy link
Author

jthielen commented Jul 6, 2020

@fipoucat Yes, you should be able to alter the getvar call on line 8 to use ALL_TIMES (when imported from wrf-python with from 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).

@fipoucat
Copy link

fipoucat commented Jul 6, 2020

Ok, thank you.

@kenichi0225703
Copy link

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