source: lmdz_wrf/trunk/tools/read_grib.py @ 2318

Last change on this file since 2318 was 2240, checked in by lfita, 6 years ago

Removing wrong quit

File size: 9.4 KB
Line 
1# Python script to read a GRIB file and transform it to a NetCDF using full python
2#   libraries (pupygrib)
3# L. Fita. CIMA, November 2018
4# More information at: http://www.xn--llusfb-5va.cat/python/PyNCplot
5#
6# pyNCplot and its component nc_var.py comes with ABSOLUTELY NO WARRANTY.
7# This work is licendes under a Creative Commons
8#   Attribution-ShareAlike 4.0 International License (http://creativecommons.org/licenses/by-sa/4.0)
9#
10## e.g. # python read_grib.py -g ERAI_pl200503_130.grib -o ERAI_pl200503_T.nc -t 'minutes!since!1949-12-01!00:00:00'
11
12# FROM: https://pypi.org/project/pupygrib/
13from optparse import OptionParser
14import numpy as np
15import pupygrib
16import os
17from netCDF4 import Dataset as NetCDFFile
18import generic_tools as gen
19import nc_var_tools as ncvar
20
21errormsg = 'ERROR -- error -- ERROR -- error'
22
23def grib128_ncname(varid):
24    """ Function to provide CF name from a ECMWF GRIB table 128 variable ID
25    >>> grib128_ncname(130)
26    ['T', 'Temperature', 'K', 'air_temperature', 'air temperature']
27    """
28    fname = 'grib128_ncname'
29
30    folder = os.path.dirname(os.path.realpath(__file__))
31
32    infile = folder + '/transform_128ECMWF.html'
33
34    if not os.path.isfile(infile):
35        print errormsg
36        print '  ' + fname + ": File '" + infile + "' does not exist !!"
37        quit(-1)
38
39    of = open(infile, 'r')
40
41    idS = str(varid).zfill(3)
42
43    for line in of:
44        if len(line) > 28:
45            #print line[0:27], ':', idS, line[0:27] == '<td align="center">' + idS + '</td>'
46            if line[0:27] == '<td align="center">' + idS + '</td>':
47                linevals = line.replace('\n','').split('</td>')
48                varn = linevals[1].replace('<td align="center">','')
49                Lvarn = linevals[2].replace('<td align="left">','')
50                units = linevals[3].replace('<td align="left">','')
51                units = units.replace('<sup>','').replace('</sup>','')
52                units = units.replace('<sub>','').replace('</sub>','')
53                units = units.replace('<nobr>','').replace('</nobr>','')
54
55                #print varn, Lvarn, units
56
57                cfvalues = gen.variables_values(varn)
58
59                break
60
61    return [varn,Lvarn,units,cfvalues[0], cfvalues[1], cfvalues[4].replace('|', ' ')]
62
63parser = OptionParser()
64parser.add_option("-g", "--grib_file", dest="gribfile", help="GRIB file to use", 
65  metavar="FILE")
66parser.add_option("-o", "--output_file", dest="ncfile", help="name of NC file to generate", 
67  metavar="FILE")
68parser.add_option("-t", "--timeunits", dest="timeunits", 
69  help="CF reference of time values [Tunits] since [DateRef] ('!', for spaces minutes!since!1949-12-01!00:00:00 as default)", 
70  metavar="STRING")
71
72(opts, args) = parser.parse_args()
73
74#######    #######
75## MAIN
76    #######
77
78if opts.gribfile is None:
79    print errormsg
80    print "  no grib input file name provided !!"
81    print "     you should provide one file name as -g [FileName]"
82    quit(-1)
83
84if not os.path.isfile(opts.gribfile):
85    print errormsg
86    print "  no grib file '" + opts.gribfile + "' found !!"
87    quit(-1)
88else:
89    ifile = opts.gribfile
90
91if opts.ncfile is None:
92    print errormsg
93    print "  no netcdf output file name provided !!"
94    print "     you should provide one file name as -o [FileName]"
95    quit(-1)
96else:
97    ofile = opts.ncfile
98
99if opts.timeunits is None:
100    print errormsg
101    print "  no time units provided !!"
102    print "     using the default ones as 'minutes since 1949-12-01 00:00:00'"
103else:
104  timeu = opts.timeunits.replace('!', ' ')
105
106with open(ifile, 'rb') as stream:
107    for i, msg in enumerate(pupygrib.read(stream), 1):
108        if i == 1:
109            lons, lats = msg.get_coordinates()
110            onewnc = NetCDFFile(ofile, 'w')
111
112            # Create dimension
113            dimx = lons.shape[1]
114            dimy = lons.shape[0]
115
116            newdim = onewnc.createDimension('lon',dimx)
117            newdim = onewnc.createDimension('lat',dimy)
118            newdim = onewnc.createDimension('time',None)
119            newdim = onewnc.createDimension('Lstring',64)
120           
121            dlon = msg[2].longitudeOfLastGridPoint - msg[2].longitudeOfFirstGridPoint
122            dlat = msg[2].latitudeOfLastGridPoint - msg[2].latitudeOfFirstGridPoint
123            print dlon, dlat
124
125            if dlat < 0.:
126                lons[:,:] = lons[::-1,:]
127                lats[:,:] = lats[::-1,:]
128
129            # Create dimension-varibale
130            newvar = onewnc.createVariable('lon', 'f8', ('lat', 'lon'))
131            newvar[:] = lons[:]
132            ncvar.basicvardef(newvar, 'lon', 'Longitude', 'degrees_east')
133            newvar.setncattr('axis', 'X')
134            newvar.setncattr('_CoordinateAxisType', 'Lon')
135
136            newvar = onewnc.createVariable('lat', 'f8', ('lat', 'lon'))
137            newvar[:] = lats[:]
138            ncvar.basicvardef(newvar, 'lat', 'Latitude', 'degrees_north')
139            newvar.setncattr('axis', 'Y')
140            newvar.setncattr('_CoordinateAxisType', 'Lat')
141           
142            newvartime = onewnc.createVariable('time', 'f8', ('time'))
143            ncvar.basicvardef(newvartime, 'time', 'time', timeu)
144            newvar.setncattr('axis', 'T')
145            newvar.setncattr('_CoordinateAxisType', 'Time')
146           
147            newvartimeS = onewnc.createVariable('timeS', 'c', ('time', 'Lstring'))
148            ncvar.basicvardef(newvartimeS, 'time', 'time', 'YmdHMS')
149            newvar.setncattr('axis', 'T')
150            newvar.setncattr('_CoordinateAxisType', 'Time')
151
152        values = msg.get_values()
153        century = msg[1].centuryOfReferenceTimeOfData
154        year = msg[1].yearOfCentury
155        month = msg[1].month
156        day = msg[1].day
157        hour = msg[1].hour
158        minute = msg[1].minute
159        levtype = msg[1].indicatorOfTypeOfLevel
160        level = msg[1].level
161        varid = msg[1].indicatorOfParameter
162        offset = msg[1].offset
163        scalefactor = msg[1].decimalScaleFactor
164        timerange = msg[1].timeRangeIndicator
165
166        if levtype == 100:
167            if not onewnc.variables.has_key('press'):
168                print '  we got a variable with a pressure value !!'
169                pressv = []
170                newdim = onewnc.createDimension('press', None)
171                newvarpress = onewnc.createVariable('press', 'f8', ('press'))
172                newvarpress[0] = level*100.
173                ncvar.basicvardef(newvarpress, 'air_pressure', 'air pressure', 'Pa')
174                newvarpress.setncattr('axis', 'Z')
175                newvarpress.setncattr('_CoordinateAxisType', 'Press')
176            if not gen.searchInlist(pressv, level*100.): 
177                pressv.append(level*100.)
178                iz = gen.index_vec(pressv, level*100.)
179                newvarpress[iz] = level*100.
180            else: 
181                iz = gen.index_vec(pressv, level*100.)
182        elif levtype == 1:
183            if not onewnc.variables.has_key('height'):
184                print '  we got a variable with a height value !!'
185                heightv = []
186                newdim = onewnc.createDimension('height', None)
187                newvarheight = onewnc.createVariable('height', 'f8', ('height'))
188                newvarheight[0] = level
189                ncvar.basicvardef(newvarheight, 'height', 'height', 'm')
190                newvarheight.setncattr('axis', 'Z')
191                newvarheight.setncattr('_CoordinateAxisType', 'Height')
192            if not gen.searchInlist(heightv, level): 
193                heightv.append(level)
194                iz = gen.index_vec(heightv, level)
195                newvarheight[iz] = level
196            else:
197                iz = gen.index_vec(heightv, level)
198
199        #print "Message :", i, values.mean(), values.shape, ':', msg[1].centuryOfReferenceTimeOfData, \
200        #  msg[1].yearOfCentury, msg[1].month, msg[1].day, msg[1].hour, msg[1].minute, \
201        #  msg[1].indicatorOfTypeOfLevel, msg[1].level, msg[1].localDefinitionNumber, msg[1].indicatorOfParameter, \
202        #  msg[1].offset, msg[1].decimalScaleFactor, msg[1].timeRangeIndicator
203        #print 'msg:', dir(msg)
204        #for i in range(6):
205        #    print 'msg ' + str(i) + ':', dir(msg[i])
206
207        varparams = grib128_ncname(varid)
208        if i==1: print varparams
209
210        timeS=str((century-1)*100 + year) + str(month).zfill(2) + str(day).zfill(2)+\
211          str(hour).zfill(2) + str(minute).zfill(2) + '00'
212
213        if i == 1: timevs = [timeS]
214
215        if not gen.searchInlist(timevs, timeS): timevs.append(timeS)
216        it = gen.index_vec(timevs, timeS)
217        #print 'timeS:', timeS, 'it:', it, 'lev:', level, 'iz:', iz
218        cftime = gen.datetimeStr_conversion(timeS,'YmdHMS','cfTime,'+timeu)
219
220        newvartimeS[it,0:14] = timeS
221        newvartime[it] = cftime
222
223        if not onewnc.variables.has_key(varparams[3]):
224            if levtype == 1:
225                dimns = ['time', 'height', 'lat', 'lon']
226            elif levtype == 100:
227                dimns = ['time', 'press', 'lat', 'lon']
228            else:
229                dimns = ['time', 'lat', 'lon']
230
231            newvar = onewnc.createVariable(varparams[3], 'f', tuple(dimns))
232            ncvar.basicvardef(newvar, varparams[4], varparams[5], varparams[2])
233        else:
234            newvar = onewnc.variables[varparams[3]]
235
236        if dlat < 0.: 
237            values[:] = values[::-1,:]
238
239        if levtype == 1 or levtype == 100:
240            newvar[it,iz,:,:] = values[:]
241        else:
242            newvar[it,:,:] = values[:]
243
244        onewnc.sync()
245
246# Global values
247ncvar.add_global_PyNCplot(onewnc, 'red_grib.py', ' ', '0.1') 
248
249onewnc.close()
250print "Successfull writting of '" + ofile + "' !!"
Note: See TracBrowser for help on using the repository browser.