xWRF
overview¶
xWRF
is a package designed to make the post-processing of WRF
output data more pythonic. It’s aim is to smooth the rough edges around the unique, non CF-compliant WRF
output data format and make the data accessible to utilities like dask
and the wider Pangeo universe.
It is built as an Accessor on top of xarray
, providing a very simple user interface.
Examining the data¶
When opening up a normal WRF
output file with the simple xarray
netcdf backend, one can see that it does not provide a lot of useful information.
import xwrf
ds_old = xwrf.tutorial.open_dataset("wrfout")
ds_old
<xarray.Dataset> Size: 89MB Dimensions: (Time: 1, south_north: 340, west_east: 270, bottom_top: 39, west_east_stag: 271, south_north_stag: 341) Coordinates: XLAT (Time, south_north, west_east) float32 367kB ... XLONG (Time, south_north, west_east) float32 367kB ... XTIME (Time) datetime64[ns] 8B ... XLAT_U (Time, south_north, west_east_stag) float32 369kB ... XLONG_U (Time, south_north, west_east_stag) float32 369kB ... XLAT_V (Time, south_north_stag, west_east) float32 368kB ... XLONG_V (Time, south_north_stag, west_east) float32 368kB ... Dimensions without coordinates: Time, south_north, west_east, bottom_top, west_east_stag, south_north_stag Data variables: ZNU (Time, bottom_top) float32 156B ... Times (Time) |S19 19B ... U (Time, bottom_top, south_north, west_east_stag) float32 14MB ... V (Time, bottom_top, south_north_stag, west_east) float32 14MB ... SINALPHA (Time, south_north, west_east) float32 367kB ... COSALPHA (Time, south_north, west_east) float32 367kB ... T (Time, bottom_top, south_north, west_east) float32 14MB ... QVAPOR (Time, bottom_top, south_north, west_east) float32 14MB ... P (Time, bottom_top, south_north, west_east) float32 14MB ... PB (Time, bottom_top, south_north, west_east) float32 14MB ... PSN (Time, south_north, west_east) float32 367kB ... Attributes: (12/149) TITLE: OUTPUT FROM WRF V4.1.3 MODEL START_DATE: 2099-08-01_00:00:00 SIMULATION_START_DATE: 2099-08-01_00:00:00 WEST-EAST_GRID_DIMENSION: 271 SOUTH-NORTH_GRID_DIMENSION: 341 BOTTOM-TOP_GRID_DIMENSION: 40 ... ... ISLAKE: 21 ISICE: 15 ISURBAN: 13 ISOILWATER: 14 HYBRID_OPT: 0 ETAC: 0.0
While all variables are present, e.g. the information about the projection is still in the metadata and also for some fields, there are non-metpy
compliant units attributes.
So let’s try to use the standard xWRF.postprocess()
function in order to make this information useable.
ds_new = xwrf.tutorial.open_dataset("wrfout").xwrf.postprocess()
ds_new
<xarray.Dataset> Size: 104MB Dimensions: (y: 340, x: 270, Time: 1, z: 39, x_stag: 271, y_stag: 341) Coordinates: (12/13) XLAT (y, x) float32 367kB 22.27 22.31 ... 57.54 57.58 XLONG (y, x) float32 367kB -116.7 -116.6 ... -110.9 XTIME (Time) datetime64[ns] 8B ... XLAT_U (y, x_stag) float32 369kB 22.25 22.29 ... 57.6 XLONG_U (y, x_stag) float32 369kB -116.7 ... -110.8 XLAT_V (y_stag, x) float32 368kB 22.23 22.28 ... 57.62 ... ... * z (z) float32 156B 0.9969 0.9899 ... 0.002948 * Time (Time) datetime64[ns] 8B 2099-10-01 * x_stag (x_stag) float64 2kB -4.733e+06 ... -2.303e+06 * y_stag (y_stag) float64 3kB -3.386e+05 ... 2.721e+06 * y (y) float64 3kB -3.341e+05 ... 2.717e+06 * x (x) float64 2kB -4.728e+06 ... -2.307e+06 Data variables: Times (Time) |S19 19B b'2099-10-01_00:00:00' U (Time, z, y, x_stag) float32 14MB ... V (Time, z, y_stag, x) float32 14MB ... SINALPHA (Time, y, x) float32 367kB 0.5507 ... 0.489 COSALPHA (Time, y, x) float32 367kB 0.8347 ... 0.8723 QVAPOR (Time, z, y, x) float32 14MB ... PSN (Time, y, x) float32 367kB ... air_potential_temperature (Time, z, y, x) float32 14MB 302.2 ... 501.3 air_pressure (Time, z, y, x) float32 14MB 1.009e+05 ... 5.2... wind_east (Time, z, y, x) float32 14MB -0.8541 ... 12.5 wind_north (Time, z, y, x) float32 14MB -4.625 ... -0.8308 wrf_projection object 8B +proj=lcc +x_0=0 +y_0=0 +a=6370000 +... Attributes: (12/149) TITLE: OUTPUT FROM WRF V4.1.3 MODEL START_DATE: 2099-08-01_00:00:00 SIMULATION_START_DATE: 2099-08-01_00:00:00 WEST-EAST_GRID_DIMENSION: 271 SOUTH-NORTH_GRID_DIMENSION: 341 BOTTOM-TOP_GRID_DIMENSION: 40 ... ... ISLAKE: 21 ISICE: 15 ISURBAN: 13 ISOILWATER: 14 HYBRID_OPT: 0 ETAC: 0.0
As you see, xWRF
added some coordinate data, reassigned some dimensions and generally increased the amount of information available in the dataset.
Projection treatment¶
xWRF
has determined the correct projection from the netCDF metadata and has added a wrf_projection
variable to the dataset storing the pyproj
projection object.
ds_new['wrf_projection'].item()
<Projected CRS: +proj=lcc +x_0=0 +y_0=0 +a=6370000 +b=6370000 +lat ...>
Name: unknown
Axis Info [cartesian]:
- E[east]: Easting (metre)
- N[north]: Northing (metre)
Area of Use:
- undefined
Coordinate Operation:
- name: unknown
- method: Lambert Conic Conformal (2SP)
Datum: unknown
- Ellipsoid: unknown
- Prime Meridian: Greenwich
Using this projection xWRF
has also calculated the regular model grid, which the WRF simulation is performed on and which can be used for e.g. bilinear interpolation.
ds_new[['x', 'y']]
<xarray.Dataset> Size: 739kB Dimensions: (x: 270, y: 340) Coordinates: * x (x) float64 2kB -4.728e+06 -4.719e+06 ... -2.316e+06 -2.307e+06 * y (y) float64 3kB -3.341e+05 -3.251e+05 ... 2.708e+06 2.717e+06 XLAT (y, x) float32 367kB 22.27 22.31 22.35 22.4 ... 57.5 57.54 57.58 XLONG (y, x) float32 367kB -116.7 -116.6 -116.6 ... -111.2 -111.0 -110.9 Data variables: *empty* Attributes: (12/149) TITLE: OUTPUT FROM WRF V4.1.3 MODEL START_DATE: 2099-08-01_00:00:00 SIMULATION_START_DATE: 2099-08-01_00:00:00 WEST-EAST_GRID_DIMENSION: 271 SOUTH-NORTH_GRID_DIMENSION: 341 BOTTOM-TOP_GRID_DIMENSION: 40 ... ... ISLAKE: 21 ISICE: 15 ISURBAN: 13 ISOILWATER: 14 HYBRID_OPT: 0 ETAC: 0.0
Attribute changes¶
xWRF
adds additional attributes to variables in order to make them CF- and COMODO-compliant. It also amends unit
attributes to work with metpy
units, enabling a seamless integration with the Pangeo software stack.
Here, for example the x-wind component gets the correct CF standard_name
and a COMODO grid_mapping
attribute indicating the respective projection.
ds_old['U'].attrs, ds_new['U'].attrs
({'FieldType': np.int32(104),
'MemoryOrder': 'XYZ',
'description': 'x-wind component',
'units': 'm s-1',
'stagger': 'X'},
{'FieldType': np.int32(104),
'MemoryOrder': 'XYZ',
'description': 'x-wind component',
'units': 'm s-1',
'stagger': 'X',
'standard_name': 'x_wind',
'grid_mapping': 'wrf_projection'})
Also, the units
attribute of the PSN
variable was cleaned up to conform to metpy
unit conventions.
Note
As of now, unit translations are implemented on a manual basis, so please raise an issue with us if you encounter any problems in this regard. In the future, this will be implemented in a more structured manner.
ds_old['PSN'].attrs['units'], ds_new['PSN'].attrs['units']
('umol co2/m2/s', 'umol m-2 s-1')
import metpy
try:
ds_old['PSN'].metpy.quantify()
except metpy.units.UndefinedUnitError as e:
print(e)
ds_new['PSN'].metpy.quantify()
'co' is not defined in the unit registry
<xarray.DataArray 'PSN' (Time: 1, y: 340, x: 270)> Size: 367kB <Quantity([[[0. 0. 0. ... 0. 0. 0. ] [0. 0. 0. ... 0. 0. 0. ] [0. 0. 0. ... 0. 0. 0. ] ... [0. 0. 0. ... 2.0479841 2.014872 2.0163262] [0. 0. 0. ... 2.122164 2.3794565 2.0393817] [0. 0. 0. ... 2.0216792 1.9838098 1.9889725]]], 'micromole / meter ** 2 / second')> Coordinates: XLAT (y, x) float32 367kB 22.27 22.31 22.35 22.4 ... 57.5 57.54 57.58 XLONG (y, x) float32 367kB -116.7 -116.6 -116.6 ... -111.2 -111.0 -110.9 XTIME (Time) datetime64[ns] 8B ... * Time (Time) datetime64[ns] 8B 2099-10-01 * y (y) float64 3kB -3.341e+05 -3.251e+05 ... 2.708e+06 2.717e+06 * x (x) float64 2kB -4.728e+06 -4.719e+06 ... -2.316e+06 -2.307e+06 Attributes: FieldType: 104 MemoryOrder: XY description: total photosynthesis stagger: grid_mapping: wrf_projection
Diagnostic variables¶
Because some WRF
output fields are quite raw, essential diagnostic variables like air_pressure
or air_potential_temperature
are missing. Also wind fields are natively in grid-space and not oriented in west-east, north-south direction, so the wind_east
and wind_north
fields are added. These useful variables get added by xWRF
by default. Users can choose to keep the fields after the computation of diagnostics is done by using .xwrf.postprocess(drop_diagnostic_variable_components=False)
, however grid-relative winds are always retained.
ds_new['air_pressure']
<xarray.DataArray 'air_pressure' (Time: 1, z: 39, y: 340, x: 270)> Size: 14MB array([[[[100893.734 , 100889.61 , 100888.09 , ..., 99661.97 , 99665.875 , 99651.086 ], [100893.55 , 100891.305 , 100887.91 , ..., 99460.77 , 99437.125 , 99507.88 ], [100896.195 , 100891.875 , 100890.65 , ..., 99259.664 , 99260.1 , 99446.16 ], ..., [101696.73 , 101671.125 , 101662.305 , ..., 95169.67 , 95047.93 , 94998.36 ], [101684.664 , 101665.67 , 101655.04 , ..., 95912.805 , 95763.6 , 95652.57 ], [101672.53 , 101665.94 , 101659.2 , ..., 96404.76 , 96312.66 , 96160.69 ]], [[100203.97 , 100202.63 , 100201.086 , ..., 98989.78 , 98996.55 , 98979. ], [100206.67 , 100205.6 , 100202.766 , ..., 98787.086 , 98764.5 , 98832.36 ], [100209.414 , 100205.04 , 100203.88 , ..., 98584.98 , 98589.43 , 98770.89 ], ... [ 5886.9263, 5886.67 , 5886.6123, ..., 5827.5776, 5825.9956, 5821.3135], [ 5886.796 , 5886.5864, 5886.468 , ..., 5833.852 , 5831.8096, 5818.641 ], [ 5886.6597, 5886.6133, 5886.5464, ..., 5813.8115, 5815.558 , 5817.2427]], [[ 5281.6 , 5281.608 , 5281.594 , ..., 5275.668 , 5275.5195, 5275.705 ], [ 5281.6064, 5281.692 , 5281.7773, ..., 5277.55 , 5277.2354, 5277.1577], [ 5281.6157, 5281.8145, 5281.881 , ..., 5276.886 , 5276.828 , 5277.4326], ..., [ 5284.9956, 5284.882 , 5284.917 , ..., 5266.0586, 5265.268 , 5260.8257], [ 5284.9634, 5284.8643, 5284.846 , ..., 5267.7246, 5266.5693, 5254.022 ], [ 5284.9243, 5284.8877, 5284.871 , ..., 5244.3447, 5246.701 , 5249.4062]]]], dtype=float32) Coordinates: XLAT (y, x) float32 367kB 22.27 22.31 22.35 22.4 ... 57.5 57.54 57.58 XLONG (y, x) float32 367kB -116.7 -116.6 -116.6 ... -111.2 -111.0 -110.9 XTIME (Time) datetime64[ns] 8B ... * z (z) float32 156B 0.9969 0.9899 0.981 ... 0.0161 0.009174 0.002948 * Time (Time) datetime64[ns] 8B 2099-10-01 * y (y) float64 3kB -3.341e+05 -3.251e+05 ... 2.708e+06 2.717e+06 * x (x) float64 2kB -4.728e+06 -4.719e+06 ... -2.316e+06 -2.307e+06 Attributes: units: Pa standard_name: air_pressure grid_mapping: wrf_projection
ds_new['wind_east']
<xarray.DataArray 'wind_east' (Time: 1, z: 39, y: 340, x: 270)> Size: 14MB array([[[[-0.8540844 , -0.738251 , -0.545264 , ..., 1.4950651 , 1.7660816 , 1.9395261 ], [-0.8818562 , -0.74259746, -0.5333221 , ..., 1.348903 , 1.5153437 , 1.7764862 ], [-0.9169271 , -0.7991271 , -0.6141951 , ..., 1.3527424 , 1.460252 , 1.6192899 ], ..., [ 9.255407 , 9.28659 , 9.1721 , ..., 4.580781 , 4.4629016 , 3.488285 ], [ 9.394391 , 9.397248 , 9.32838 , ..., 5.3224483 , 4.4839735 , 3.1068704 ], [ 9.494457 , 9.411124 , 9.363975 , ..., 5.2005925 , 4.8733425 , 3.7735646 ]], [[-0.87797356, -0.7614403 , -0.59394455, ..., 1.882653 , 2.3743167 , 2.5777702 ], [-0.90974176, -0.77123356, -0.5847976 , ..., 1.7839468 , 2.272645 , 2.497768 ], [-0.9420047 , -0.8337804 , -0.67352176, ..., 1.8757367 , 2.2196953 , 2.3774064 ], ... [14.407449 , 14.719514 , 14.945457 , ..., 11.257124 , 11.583581 , 14.111986 ], [14.562296 , 14.829544 , 15.028374 , ..., 11.101351 , 11.73059 , 14.226654 ], [14.707831 , 14.862129 , 15.002537 , ..., 12.704432 , 12.850094 , 14.030186 ]], [[-1.1588178 , -1.0782948 , -1.0017282 , ..., 1.8423607 , 1.7980661 , 1.6273091 ], [-1.1129029 , -1.0681975 , -0.9338307 , ..., 3.0397072 , 2.6984587 , 1.9549323 ], [-1.0991675 , -1.181081 , -1.0825561 , ..., 3.7225795 , 3.3059304 , 2.319018 ], ..., [12.773672 , 13.064896 , 13.278723 , ..., 9.394521 , 9.826231 , 12.684486 ], [12.933495 , 13.184 , 13.374461 , ..., 9.11593 , 9.9368305 , 12.795868 ], [13.088163 , 13.237101 , 13.3752 , ..., 10.920462 , 11.129587 , 12.496285 ]]]], dtype=float32) Coordinates: XLAT (y, x) float32 367kB 22.27 22.31 22.35 22.4 ... 57.5 57.54 57.58 XLONG (y, x) float32 367kB -116.7 -116.6 -116.6 ... -111.2 -111.0 -110.9 XTIME (Time) datetime64[ns] 8B ... * z (z) float32 156B 0.9969 0.9899 0.981 ... 0.0161 0.009174 0.002948 * Time (Time) datetime64[ns] 8B 2099-10-01 * y (y) float64 3kB -3.341e+05 -3.251e+05 ... 2.708e+06 2.717e+06 * x (x) float64 2kB -4.728e+06 -4.719e+06 ... -2.316e+06 -2.307e+06 Attributes: description: earth-relative x-wind component standard_name: eastward_wind units: m s-1 grid_mapping: wrf_projection