pywinter¶
Python WRF-WPS Intermediate Files
Pywinter is a Python3 library designed for handling files in WRF-WPS intermediate file format. Usually you don’t need to deal with the intermediate files by your own because that is the function of ungrib.exe, but sometimes you don’t have your meteorological data in GRIB format. Pywinter allows to read and create intermediate files by a simple way.
Dependencies¶
pywinter requires:
Pywinter has been tested in linux distributions.
Fortran compiler (gfortran)
Python (>= 3.6)
Numpy
Read intermediate files (rinter)¶
For reading the intermediate files information you must utilize the function rinter. Once you have read the information you can manipulate the data easily. The results will be a dictionary that contains the variables in the intermediate file, also every key includes general information, geo information, levels, and the data array.
Example¶
import numpy as np
import pywinter.winter as pyw
infile = '/home/allyson/Documents/files/FILE:1994-05-18_06'
interfile = pyw.rinter(infile)
print(interfile.keys())
>> dict_keys(['LANDSEA', 'ST', 'SST', 'SOILHGT', 'PSFC', 'GTH', 'SKINTEMP', 'TT',
'PMSL', 'VV', 'SM', 'UU', 'RH', 'TT2M', 'RH2M', 'UU10M', 'VV10M'])
print(interfile['TT'].general)
>> {'VERSION': 5, 'HDATE': '2015-07-27_12:00:00', 'XFCST': 0.0, 'MAP_SOURCE': 'ECMWF',
'FIELD': 'TT', 'UNITS': 'K', 'DESC': 'Temperature', 'XLVL': '1000', 'NX': 329, 'NY': 441,
'EARTH_RADIUS': 6367.47021484375, 'IS_WIND_EARTH_REL': False}
print(interfile['TT'].geoinfo)
>> {'IPROJ': 0, 'PROJ': 'Cylindrical Equidistant (0)', 'STARTLOC': 'SWCORNER',
'STARTLAT': 38.0, 'STARTLON': -130.0, 'DELTALAT': -0.25, 'DELTALON': 0.25}
print(interfile['TT'].level)
>> [100000. 97500. 95000. 92500. 90000. 87500. 85000. 82500. 80000.
77500. 75000. 70000. 65000. 60000. 55000. 50000. 45000. 40000.
35000. 30000. 25000. 20000. 17500. 15000. 12500. 10000. 7000.
5000. 3000. 2000. 1000.]
print(interfile['TT'].val)
>> [[[289.86547852 289.89868164 289.85571289 ... 294.19750977 294.20141602
294.19360352]
...
[278.23071289 277.93383789 277.69360352 ... 280.58032227 280.63500977
280.70727539]]
...
[[234.77418518 234.80836487 234.85231018 ... 232.22828674 232.20973206
232.20582581]
...
[213.70191956 213.95289612 214.19410706 ... 211.46461487 211.38844299
211.31422424]]]
print(interfile['TT'].val.shape)
>> (31, 329, 441)
Creating Intermediate files¶
Before create intermediate files (cinter function), you must use the Geo-information(Geo0,Geo1,Geo3,Geo4,Geo5) and the type of variable you are using (V2d,V3d,V3dp,Vsl)
Geo-Information (Geo)¶
This funtions ares utilized to locate the information in the space. There are several kind of geo-info, it depends on projection of the original data:
- 0: Cylindrical Equidistant (Lat/lon)
- 1: Mercator projection
- 3: Lambert conformal conic
- 4: Gaussian [global only] (Transverse mercator)
- 5: Polar-stereographic projection
Geo0¶
Cylindrical Equidistant (Lat/lon)
Geo0(stlat,stlon,dlat,dlon): | |
---|---|
- stlat: SOUTH-WEST corner latitude of data (degrees north)
- stlon: SOUTH-WEST corner longitude of data (degrees east)
- dlat: latitude increment (degrees)
- dlon: longitude increment (degrees)
Geo1¶
Mercator
Geo1(stlat,stlon,dx,dy,tlat1): | |
---|---|
- stlat: SOUTH-WEST corner latitude of data (degrees north)
- stlon: SOUTH-WEST corner longitude of data (degrees east)
- dx: Grid spacing in x (Km)
- dy: Grid spacing in y (Km)
- tlat1: True latitude 1 of projection (degrees north)
Geo3¶
Lambert conformal conic
Geo3(stlat,stlon,dx,dy,xloc,tlat1,tlat2,iswin): | |
---|---|
- stlat: SOUTH-WEST corner latitude of data (degrees north)
- stlon: SOUTH-WEST corner longitude of data (degrees east)
- dx: Grid spacing in x (Km)
- dy: Grid spacing in y (Km)
- xloc: Center longitude of projection
- tlat1: True latitude 1 of projection (degrees north)
- tlat2: True latitude 2 of projection (degrees north)
- iswin: Earth[False] or source grid[True] rotated winds
Geo4¶
Gaussian [global only] (Transverse mercator)
Geo4(stlat,stlon,nlats,dlon,iswin): | |
---|---|
- stlat: SOUTH-WEST corner latitude of data (degrees north)
- stlon: SOUTH-WEST corner longitude of data (degrees east)
- nlats: Number of latitudes north of equator
- dlon: longitude increment (degrees)
- iswin: Earth[False] or source grid[True] rotated winds
Geo5¶
Polar-stereographic
Geo5(stlat,stlon,dx,dy,xloc,tlat1,iswin): | |
---|---|
- stlat: SOUTH-WEST corner latitude of data (degrees north)
- stlon: SOUTH-WEST corner longitude of data (degrees east)
- dx: Grid spacing in x (Km)
- dy: Grid spacing in y (Km)
- xloc: Center longitude of projection
- tlat1: True latitude 1 of projection (degrees north)
- iswin: Earth[False] or source grid[True] rotated winds
Example¶
import numpy as np
import pywinter.winter as pyw
import data_example as data
# Read Geo-data (Latitudes and longitudes)
lat = data.variables['Latitude'][:] # degrees north
lon = data.variables['Longitude'][:] # degrees east
dlat = np.abs(lat[1] - lat[0])
dlon = np.abs(lon[1] - lon[0])
# create winter Geo-information for cylindrical equidistant projection
winter_geo = pwy.Geo0(lat[0],lon[0],dlat,dlon)
2D Field (V2d)¶
Surface variables
V2d(name,field): | |
---|---|
- name: WPS field name (see table)
- field: 2D array [lat,lon]
2D avalaible name fields¶
Field name | Units | Description | Notes |
---|---|---|---|
PSFC | Pa | Surface pressure | |
PMSL | Pa | Mean sea-level pressure | |
SKINTEMP | K | Skin temperature | |
SOILHGT | m | Soil height | |
TT | K | 2m air temperature | |
RH | % | 2m relative humidity | Not needed if SPECHUMD is avalaible |
SPECHUMD | kg/kg | 2m specific humidity | Not needed if RH is avalaible |
UU | m/s | 10m wind u component | |
VV | m/s | 10m wind v component | |
LANDSEA | fraction | Land-sea mask | 0=water, 1=land |
SST | K | Sea surface temperature | |
SEAICE | fraction | Sea-ice fraction | |
SNOW | kg/m^2 | Water equivalent snow depth | |
TAVGSFC | K | Daily mean of surface air |
Some 2D fields are masked fields, so you must make sure to convert the missing values to numpy nan before create the pywinter 2d field.
Example¶
import numpy as np
import pywinter.winter as pyw
import data_example as data
# Read 2D data (2m temperature, 10m U wind, 10m V wind)
tp2m = data.variables['T2'][:,:]
u10m = data.variables['U10'][:,:]
v10m = data.variables['V10'][:,:]
# Create winter 2D fields
winter_t2m = pyw.V2d('TT',tp2m)
winter_u10 = pyw.V2d('UU',u10m)
winter_v10 = pyw.V2d('VV',u10m)
2D not avalaible name fields (create new 2d fields)¶
The 2D fields listed in the Table are the most important, however exists more 2D fields that are less common but can be useful for some WRF applications, for this reason it is also possible to add your own variables to pywinter. For doing this, it is necessary give to the function additional information about the field description, units and pressure level:
import numpy as np
import pywinter.winter as pyw
import data_example as data
# Read 2D data
pmaxw = data.variables['pmax'][:,:]
# Create new winter 2D fields
winter_new = pyw.V2d('PMAXW',pmaxw,'Pressure at max wind level','Pa','200100')
You must use 200100 for surface data and 201300 for sea level pressure data. Also it is very important to remember that all the fields you add must be in accordance with the information processed by metgrid.exe, you can get more information about this in the METGRID.TBL file or in the VTABLE files.
3D non-isobaric Field (V3d)¶
Vertical non-isobaric atmospehere variables
V3d(name,field): | |
---|---|
- name: WPS field name (see table)
- field: 3D array [lev,lat,lon]
3D non-isobaric avalaible name fields¶
Field name | Units | Description | Notes |
---|---|---|---|
TT | K | 3D air temperature | |
RH | % | 3D relative humidity | Not needed if SPECHUMD is avalaible |
SPECHUMD | kg/kg | 3D specific humidity | Not needed if RH is avalaible |
UU | m/s | 3D wind u component | |
VV | m/s | 3D wind v component | |
GHT | m | 3D geopotential height | |
PRESSURE | Pa | 3D pressure | Only needed for non-isobaric datasets |
Example¶
import numpy as np
import pywinter.winter as pyw
import data_example as data
# Read 3D non-isobaric data (Pressure, U wind, V wind)
press = data.variables['P'][:,:,:]
uwind = data.variables['U'][:,:,:]
vwind = data.variables['V'][:,:,:]
# Create winter 3D non-isobaric fields
winter_p = pyw.V3d('PRESSURE',press)
winter_u = pyw.V3d('UU',u10m)
winter_v = pyw.V3d('VV',u10m)
3D isobaric Field (V3dp)¶
Vertical isobaric atmospehere variables
V3dp(name,field,plevs): | |
---|---|
- name: WPS field name (see table)
- field: 3D array [plev,lat,lon]
- plevs: 1D array of pressure levels (Pa)
3D isobaric avalaible name fields¶
Field name | Units | Description | Notes |
---|---|---|---|
TT | K | 3D air temperature | |
RH | % | 3D relative humidity | Not needed if SPECHUMD is avalaible |
SPECHUMD | kg/kg | 3D specific humidity | Not needed if RH is avalaible |
UU | m/s | 3D wind u component | |
VV | m/s | 3D wind v component | |
GHT | m | 3D geopotential height |
Example¶
import numpy as np
import pywinter.winter as pyw
import data_example as data
# Read 3D isobaric data (temperature, U wind, V wind)
temp = data.variables['T'][:,:,:]
uwind = data.variables['U'][:,:,:]
vwind = data.variables['V'][:,:,:]
# Read 3D pressure levels (hPa)
plevs = data.variables['PLEV'][:]
# Create winter 3D isobaric fields
winter_t = pyw.V3dp('TT',tp2m,plevs)
winter_u = pyw.V3dp('UU',u10m,plevs)
winter_v = pyw.V3dp('VV',u10m,plevs)
Soil Field (Vsl)¶
Soil level variables
Vsl(name,field,levs): | |
---|---|
- name: WPS field name (see table)
- field: 3D array [lev,lat,lon]
- levs: 1D list of string soil levels in cm
3D soil avalaible name fields¶
Field name | Units | Description | Notes |
---|---|---|---|
SM | m^3/m^3 | Soil moisture | ‘ttt’ is layer top, ‘bbb’ is layer bottom |
ST | K | Soil temperature | ‘ttt’ is layer top, ‘bbb’ is layer bottom |
SOILM | kg^3/m^3 | Soil moisture | ‘mmm’ is tthe level depth |
SOILT | K | Soil temperature | ‘mmm’ is tthe level depth |
Is important to know that if you have ST or SM, you must indicate the layer as [bbbttt] (top layer - bottom layer in cm) and if you have SOILT or SOILM, you must indicate the level as [mmm] (level depth in cm).
Aditionally if you have ST then SOILT is needed. if you have SM then SOILM is needed.
Soil fields are used to be masked fields, so you must make sure to convert the missing values to numpy nan before create the pywinter soil field.
Example¶
import numpy as np
import pywinter.winter as pyw
import data_example as data
# Read 3D soil data (temperature and moisture)
soilt_lay = data.variables['SLTY'][:,:,:]
soilm_lev = data.variables['SLTL'][:,:,:]
# 3D soil layers and levels
slt_layer = ['000010','010040','040100','100200']
slm_level = ['010','040','100','200']
# Create winter 3D soil fields
winter_soilt_layer = pyw.Vsl('ST',soilt_lay,slt_layer)
winter_soitm_level = pyw.Vsl('SOILM',soilt_lev,slm_level)
Create intermediate files (cinter)¶
When you have all the pywinter meteorological variables, now is time to create the intermediate files, you must use cinter function and it is very easy.
cinter(filen,date,geoinfo,varias,rout): | |
---|---|
- filen: File name or prefix.
- date: Datetime of the file
- geoinfo: pywinter Geo object.
- varias: List of pywinter fields.
- rout: Path where files will be created. ([optional] if not rout, files will be created in current folder)
Actually you can write just one file per time step. For creating several files you can use a loop, just remember that parameters filen, geoinfo, and rout will be static.
Example¶
import numpy as np
import pywinter.winter as pyw
import data_example as data
## Read data
############################################################
# Read Geo-data
lat = data.variables['Latitude'][:]
lon = data.variables['Longitude'][:]
dlat = np.abs(lat[1]-lat[0])
dlon = np.abs(lon[1]-lon[0])
# Read 2D data
tp2m = data.variables['T2'][:,:]
# Read 3D data
temp = data.variables['T'][:,:,:]
plevs = data.variables['PLEV'][:]
# Read 3D soil data
soilt = data.variables['SLTY'][:,:,:]
sl_layer = ['000010','010040','040100','100200']
## Pywinter
############################################################
# Create winter fields
winter_geo = pyw.Geo0(lat[0],lon[0],dlat,dlon)
winter_t2m = pyw.V2d('TT',tp2m)
winter_t = pyw.V3dp('TT',temp,plevs)
winter_soilt_layer = pyw.Vsl('ST',soilt,sl_layer)
# Listing fields
total_fields = [winter_t2m,
winter_t,
winter_soilt_layer]
# Out path
path_out = '/home/Documents/intermediate_files/'
# Write intermediate file
pyw.cinter('FILE','1994-05-18_06',winter_geo,total_fields,path_out)
IMPORTANT WARNING¶
Note
You can choose any prefix for the intermediate files though usually are called FILE, however the datetime must be chosen carefully, the files will be created with success but metgrid.exe sometimes can’t read them:
- If your original data has an exact hourly time resolution, for example: [ 05:00:00, 06:00:00 ], your intermediate files will be [ FILE:YYYY-MM-DD_05, FILE:YYYY-MM-DD_06} ]. Minutes and seconds are not needed, if you put them, it is probably metgrid.exe can’t find the intermediate files.
- If your original data has less than one hour time resolution, for example: [ 05:00:00, 05:30:00 ], your intermediate files will be [ FILE:YYYY-MM-DD_05:00 , FILE:YYYY-MM-DD_05:30 ]. Seconds are not needed, if you put them, it is probably metgrid.exe can’t find the intermediate files.
- If your original data has a not-exact hourly time resolution, for example: [ 05:30:00, 06:30:00, 07:30:00 ], metgrid.exe won’t find the intermediate files. You can trick the program if you set the interval_seconds namelist parameter as 3601 and your intermediate files in this case will be [ FILE:YYYY-MM-DD_05:30:00 , FILE:YYYY-MM-DD_06:30:01, FILE:YYYY-MM-DD_07:30:02 ]. This just works for short runs, because you must remember that in 60 hours the delay will be 1 minute with respect to your original data. This could be a bug or a simple restriction from metgrid.exe.
Final notes¶
Actually pywinter can’t check if you write the file with all the necessary fields to run WRF, neither cannot check if your information is consistent, therefore is important you make sure the data is well before you create the files, you can get more information of how to create good files in the WRF User guide and WRF web tutorial, also you can check the intermediate files with WPS util programs:
- …/WRF/WPS/util/rd_intermediate.exe: It reads fields into intermediate files and show them
- …/WRF/WPS/util/int2nc.exe: it converts intermediate files to netCDF format.