1 | """ |
---|
2 | This function accepts the fields needed by WRF and more specifically: |
---|
3 | |
---|
4 | based on the GFS Vtable. |
---|
5 | Assumptions: |
---|
6 | - all the 3D fields need to be on isobaric levels when they are passed to the |
---|
7 | encoding function |
---|
8 | - every 3D field must be supplied with a corresponding surface field |
---|
9 | - the COARDS ordering of dimensions is assumed i.e. time, level, lat, lon |
---|
10 | |
---|
11 | Usage: |
---|
12 | |
---|
13 | """ |
---|
14 | |
---|
15 | ############################################################################# |
---|
16 | # TODO |
---|
17 | # - change the 'data' structure to a dictionary creating appropriate labels |
---|
18 | # from the dates |
---|
19 | ############################################################################# |
---|
20 | import os |
---|
21 | import sys |
---|
22 | |
---|
23 | # the syntax to import nio depends on its version. We try all options from the |
---|
24 | # newest to the oldest |
---|
25 | try: |
---|
26 | import Nio as nio |
---|
27 | except: |
---|
28 | try: |
---|
29 | import PyNGL.Nio as nio |
---|
30 | except: |
---|
31 | import PyNGL_numpy.Nio as nio |
---|
32 | |
---|
33 | # The following is only needed for hn3.its.monash.edu.au |
---|
34 | # Unfortunately we must get rid of spurious entries in the sys.path that can |
---|
35 | # lead to the loading of conflicting packages |
---|
36 | for dir_idx in range(len(sys.path)-1,-1,-1): |
---|
37 | if 'python2.4' in sys.path[dir_idx]: |
---|
38 | sys.path.pop(dir_idx) |
---|
39 | |
---|
40 | import numpy as n |
---|
41 | import pylab as p |
---|
42 | from matplotlib.numerix import ma |
---|
43 | import grib2 |
---|
44 | from string import zfill |
---|
45 | import pywrf.viz.utils as vu |
---|
46 | from pywrf.misc.met_utils import * |
---|
47 | #data_directory = '/Users/val/data/laps_nc_files/press/first_try/' |
---|
48 | #sfc_data_directory = '/Users/val/data/laps_surface_data/' |
---|
49 | #data_directory = '/mnt/mac/Users/val/data/laps_nc_files/press/first_try/' |
---|
50 | #sfc_data_directory = '/mnt/mac/Users/val/data/laps_surface_data/' |
---|
51 | #data_directory = '/media/DATA/wrf/canberra_nc_files/press/' |
---|
52 | #sfc_data_directory = '/media/DATA/wrf/canberra_nc_files/sfc/' |
---|
53 | #data_directory = '/media/DATA/wrf/canberra/press/' |
---|
54 | #sfc_data_directory = '/media/DATA/wrf/canberra/sfc/' |
---|
55 | #data_directory = '/Volumes/COMMON/wrf/canberra/press/' |
---|
56 | #sfc_data_directory = '/Volumes/COMMON/wrf/canberra/sfc/' |
---|
57 | #data_directory = '/Volumes/DATA/wrf/canberra/press/' |
---|
58 | #sfc_data_directory = '/Volumes/DATA/wrf/canberra/sfc/' |
---|
59 | #data_directory = '/Users/val/Desktop/workspace/plotting/canberra/press/' |
---|
60 | #sfc_data_directory = '/Users/val/Desktop/workspace/plotting/canberra/sfc/' |
---|
61 | #data_directory = \ |
---|
62 | # '/nfs/1/home/vbisign/wrf/wps_data/pygrib2_test/canberra/press/analyses/' |
---|
63 | #sfc_data_directory = \ |
---|
64 | # '/nfs/1/home/vbisign/wrf/wps_data/pygrib2_test/canberra/sfc/' |
---|
65 | data_directory = \ |
---|
66 | '/nfs/1/home/vbisign/wrf/wps_data/run_003/press/' |
---|
67 | sfc_data_directory = \ |
---|
68 | #sfc_data_directory = '/Users/val/Desktop/workspace/plotting/canberra/sfc/' |
---|
69 | # It is assumed that most people will use a single nc file as the source |
---|
70 | # of their fields. Neverthless, the field nc_file_name is available for those |
---|
71 | # that need to use multiple data sources. |
---|
72 | |
---|
73 | # the code is split in two parts... the first part gathers all the |
---|
74 | # information that is specific to your data source... stuff like the location |
---|
75 | # of the netcdf files, the name of the variables of interest in your files, |
---|
76 | # and any special treatment of the fields like changing units, scaling the |
---|
77 | # data or anything that is needed to get the data in the form required by the |
---|
78 | # encoding function. |
---|
79 | # This translates to simply having to generate a fairly pedantic dictionary |
---|
80 | # that spells out what needs to be done with the fields during the grib |
---|
81 | # encoding |
---|
82 | # the second part is the encoding function itself in which it is assumed the |
---|
83 | # data is passed in a dictionary containing the data as numpy arrays in the |
---|
84 | # right units |
---|
85 | |
---|
86 | # Unfortunately it proves hard to both generalize the data structure and |
---|
87 | # maintain flexibility... hence at the price of making the code longer I am |
---|
88 | # going to process one field at the time so that it is clear to anyone what |
---|
89 | # the steps that are (may be) involved are... |
---|
90 | # I still believe it is a good idea to collect all the information needed in |
---|
91 | # one big dictionary for ease of retrieval |
---|
92 | |
---|
93 | |
---|
94 | ############################################################################# |
---|
95 | # Preliminaries |
---|
96 | # This is the data structure that I will pass to the encoder |
---|
97 | data = [] |
---|
98 | |
---|
99 | # to generate a grib2 file using Jeffrey Whitaker's grib2 class, it is necessary |
---|
100 | # to provide the constructor with two pieces of information: |
---|
101 | # - the discipline of the data to be encoded |
---|
102 | # - the identification section |
---|
103 | # this means the class will need to be reconstructed every time the discipline |
---|
104 | # changes |
---|
105 | |
---|
106 | |
---|
107 | def missing(octects): |
---|
108 | # To say that something is not available in a grib field they use a |
---|
109 | # sequence of 1s as long as the space allocated (number of octects). |
---|
110 | # When this sequence is read as an integer, it corresponds to the maximum |
---|
111 | # representable number given the octects*8 bits of memory, hence: |
---|
112 | # PS: refer to the grib documentation to know how many octects are |
---|
113 | # allocated to any particular field |
---|
114 | return 2**(8*octects) - 1 |
---|
115 | |
---|
116 | def prepare_sfc_data(f, fv): |
---|
117 | # work out which file to pick based on the base date of the first file |
---|
118 | # this is based on the (fragile) assumption that nobody changed the file |
---|
119 | # names from the standard laps... |
---|
120 | # this was needed for the first batch of data... |
---|
121 | valid_date = fv['valid_date'].get_value()[0] |
---|
122 | valid_time = fv['valid_time'].get_value()[0] |
---|
123 | # the following is old stuff |
---|
124 | if 0: |
---|
125 | # the data in each file 'starts' at 12:00pm (UTC) |
---|
126 | if valid_time < 1200: |
---|
127 | valid_date -= 1 |
---|
128 | #sfc_file = 'laps' + str(valid_date)[4:] + '_surface.nc' |
---|
129 | print sfc_data_directory + sfc_file |
---|
130 | # this is new and (hopefully) better |
---|
131 | if 1: |
---|
132 | # there is one sfc data file for each of the analysis containing the |
---|
133 | # full 73 hours of diagnostic fields |
---|
134 | # in the simplified case that we do not span analysis -> we start again |
---|
135 | # with a different file at every analysis: |
---|
136 | base_date = fv['base_date'].get_value() |
---|
137 | base_time = fv['base_time'].get_value() |
---|
138 | sfc_file = 'regprog.laps_pt375.' \ |
---|
139 | + str(base_date)[4:] + '.' + str(base_time).zfill(4)[:2] \ |
---|
140 | + '.slvfld.n3.nc' |
---|
141 | # if we use data from a single forecast we just name the appropriate file |
---|
142 | # sfc_file = 'laps0117_surface.nc' |
---|
143 | sfc_f = nio.open_file(sfc_data_directory + sfc_file) |
---|
144 | sfc_fv = sfc_f.variables |
---|
145 | # I need this to work out which time to pick in the file... |
---|
146 | sfc_valid_time = sfc_fv['valid_time'].get_value() |
---|
147 | time_idx = sfc_valid_time.tolist().index(valid_time) |
---|
148 | return sfc_file, sfc_f, sfc_fv, time_idx |
---|
149 | |
---|
150 | ############################################################################# |
---|
151 | |
---|
152 | ############################################################################# |
---|
153 | # this variables remain unchanged across the different times |
---|
154 | # BTW these (with the exception of the significance_ref_time) should not |
---|
155 | # affect WRF |
---|
156 | |
---|
157 | # Id of originating centre (Common Code Table C-1) -> 1 for Melbourne |
---|
158 | # Id of originating centre (Common Code Table C-1) -> 7 for NCEP |
---|
159 | centre = 7 |
---|
160 | # Id of orginating sub-centre (local table) -> 0 for no subcentre |
---|
161 | # Id of orginating sub-centre (local table) -> 3 for NCEP Central Operations |
---|
162 | subcentre = 0 |
---|
163 | # GRIB Master Tables Version Number (Code Table 1.0) |
---|
164 | master_table = 1 |
---|
165 | # GRIB Local Tables Version Number (Code Table 1.1) -> 0 for not used |
---|
166 | # GRIB Local Tables Version Number (Code Table 1.1) -> 1 for let's see what happens |
---|
167 | local_table = 1 |
---|
168 | # Significance of Reference Time (Code Table 1.2) -> 1 for start of forecast |
---|
169 | significance_ref_time = 1 |
---|
170 | # Production status of data (Code Table 1.3) -> 2 for research product |
---|
171 | production_status = 2 |
---|
172 | # idsect[12]=Type of processed data (Code Table 1.4) -> 1 -> forecast product |
---|
173 | type_processed_data = 1 |
---|
174 | |
---|
175 | ############################################################################# |
---|
176 | |
---|
177 | # the first dimension of data will be the times to be processed |
---|
178 | # you will have to modify this to suit your data |
---|
179 | # this could mean just having a time index to get different times from the |
---|
180 | # same file or just pick different files for different times. |
---|
181 | files = os.listdir(data_directory) |
---|
182 | #for file in files[:2]: |
---|
183 | for file in files: |
---|
184 | f = nio.open_file(data_directory + file) |
---|
185 | fv = f.variables |
---|
186 | base_date = str(fv['base_date'].get_value()) |
---|
187 | year = int(base_date[0:4]) |
---|
188 | month = int(base_date[4:6]) |
---|
189 | day = int(base_date[6:8]) |
---|
190 | # padding needed to use a string method on an integer |
---|
191 | base_time = zfill(str(fv['base_time'].get_value()),4) |
---|
192 | hour = int(base_time[0:2]) |
---|
193 | minute = int(base_time[2:]) |
---|
194 | second = 0 |
---|
195 | # I did not generate this in the preamble above because I needed to wait |
---|
196 | # for the base date and time info from the netcdf files... |
---|
197 | # NB the order of the variables in the list MATTERS! |
---|
198 | idsect = [ |
---|
199 | centre, |
---|
200 | subcentre, |
---|
201 | master_table, |
---|
202 | local_table, |
---|
203 | significance_ref_time, |
---|
204 | year, |
---|
205 | month, |
---|
206 | day, |
---|
207 | hour, |
---|
208 | minute, |
---|
209 | second, |
---|
210 | production_status, |
---|
211 | type_processed_data |
---|
212 | ] |
---|
213 | |
---|
214 | print file |
---|
215 | # gdsinfo - Sequence containing information needed for the grid definition |
---|
216 | # section. |
---|
217 | gdsinfo = n.zeros((5,), dtype=int) |
---|
218 | # gdsinfo[0] = Source of grid definition (see Code Table 3.0) -> 0 -> will be |
---|
219 | # specified in octects 13-14 |
---|
220 | gdsinfo[0] = 0 |
---|
221 | # gdsinfo[1] = Number of grid points in the defined grid. |
---|
222 | # TODO make it more general |
---|
223 | #lat = fv['lat'].get_value() |
---|
224 | # the idx was chosen to stop the data at 55S and avoid the rubbish far south |
---|
225 | lat_cheat_idx = 30 |
---|
226 | # 1 for the full range |
---|
227 | lon_cheat_idx = 1 |
---|
228 | lat = fv['lat'].get_value()[lat_cheat_idx:] |
---|
229 | lon = fv['lon'].get_value()[:-lon_cheat_idx] |
---|
230 | gdsinfo[1] = len(lat)*len(lon) |
---|
231 | # gdsinfo[2] = Number of octets needed for each additional grid points defn. |
---|
232 | # Used to define number of points in each row for non-reg grids |
---|
233 | # (=0 for regular grid). |
---|
234 | gdsinfo[2] = 0 |
---|
235 | # gdsinfo[3] = Interp. of list for optional points defn (Code Table 3.11) |
---|
236 | # 0 -> There is no appended list |
---|
237 | gdsinfo[3] = 0 |
---|
238 | # gdsinfo[4] = Grid Definition Template Number (Code Table 3.1) |
---|
239 | # 0 -> Latitude/Longitude (or equidistant cylindrical, or Plate Carree) |
---|
240 | gdsinfo[4] = 0 |
---|
241 | |
---|
242 | # gdtmpl - Contains the data values for the specified Grid Definition |
---|
243 | # Template ( NN=gds[4] ). Each element of this integer array contains |
---|
244 | # an entry (in the order specified) of Grid Definition Template 3.NN |
---|
245 | gdtmpl = n.zeros((19,), dtype=n.int64) |
---|
246 | # In the following we refer to the lat/lon template (grid template 3.0) |
---|
247 | # Oct: 15 Shape of the Earth (See Table 3.2) |
---|
248 | # 0 -> spherical with radius = 6,367,470.0 m |
---|
249 | # TODO double check the radius they used in Tan's code |
---|
250 | gdtmpl[0] = 0 |
---|
251 | # Oct: 16 Scale Factor of radius of spherical Earth |
---|
252 | # TODO hopefully (given the last option) the next 5 are ignored... |
---|
253 | # if 1 octet is the basic unit then a value of 255 should be equivalent |
---|
254 | # to all bits set to 1 -> this could be broken if more than one octect |
---|
255 | # is assigned -> maybe I should use the maximum represantable number |
---|
256 | # tailored to the number of octects? |
---|
257 | # are there any rules that make the encoder ignore automatically certain |
---|
258 | # options e.g. the oblate spheroid one when a spherical shape is assumed |
---|
259 | gdtmpl[1] = missing(1) |
---|
260 | # Oct: 17-20 Scale value of radius of spherical Earth |
---|
261 | # NB they (grib2 std) interprets all bits set to 1 as a missing value |
---|
262 | # hence the value is base*(word_width*words_assigned) - 1 |
---|
263 | # base is 2 since we are working in binary |
---|
264 | # word_width is 8 since they use octects |
---|
265 | # words_assigned is the number of words reserved to represent the value |
---|
266 | # -1 gives us the greatest representable number since we start from 0 |
---|
267 | gdtmpl[2] = missing(1) |
---|
268 | # Oct: 21 Scale factor of major axis of oblate spheroid Earth |
---|
269 | gdtmpl[3] = missing(1) |
---|
270 | # Oct: 22-25 Scaled value of major axis of oblate spheroid Earth |
---|
271 | gdtmpl[4] = missing(4) |
---|
272 | # Oct: 26 Scale factor of minor axis of oblate spheroid Earth |
---|
273 | gdtmpl[5] = missing(1) |
---|
274 | # Oct: 27-30 Scaled value of minor axis of oblate spheroid Earth |
---|
275 | gdtmpl[6] = missing(4) |
---|
276 | # Oct: 31-34 Number of points along a parallel |
---|
277 | gdtmpl[7] = len(lon) |
---|
278 | # Oct: 35-38 Number of points along a meridian |
---|
279 | gdtmpl[8] = len(lat) |
---|
280 | # Oct: 39-42 Basic angle of the initial production domain (see Note 1) |
---|
281 | gdtmpl[9] = missing(4) |
---|
282 | # Oct: 43-46 Subdivisions of basic angle used to define extreme longitudes |
---|
283 | # and latitudes, and direction increments (see Note 1) |
---|
284 | gdtmpl[10] = missing(4) |
---|
285 | # Oct: 47-50 La1 - Latitude of first grid point (see Note 1) |
---|
286 | #gdtmpl.append(in_vars['lat'].get_value()[-1]*1e6) |
---|
287 | gdtmpl[11] = lat[-1]*1e6 |
---|
288 | #gdtmpl[11] = lat[0]*1e6 |
---|
289 | # Oct: 51-54 Lo1 - Longitude of first grid point (see Note 1) |
---|
290 | #gdtmpl.append(in_vars['lon'].get_value()[0]*1e6) |
---|
291 | gdtmpl[12] = lon[0]*1e6 |
---|
292 | # Oct: 55 Resolution and component flags (see Table 3.3) |
---|
293 | # This should set all the bits to 0 meaning |
---|
294 | # bit value meaning |
---|
295 | # 1-2 ? Reserved |
---|
296 | # 3 0 i direction increments not given |
---|
297 | # 4 0 j direction increments not given |
---|
298 | # 5 0 Resolved u and v components of vector quantities |
---|
299 | # relative to easterly and northerly directions |
---|
300 | # 6-8 0 Reserved - set to zero |
---|
301 | #gdtmpl[13] = 0 |
---|
302 | #gdtmpl[13] = 12 |
---|
303 | gdtmpl[13] = 48 |
---|
304 | # Oct: 56-59 La2 - Latitude of last grid point (see Note1) |
---|
305 | #gdtmpl.append(in_vars['lat'].get_value()[0]*1e6) |
---|
306 | gdtmpl[14] = lat[0]*1e6 |
---|
307 | #gdtmpl[14] = lat[-1]*1e6 |
---|
308 | # Oct: 60-63 Lo2 - Longitude of last grid point (see Note 1) |
---|
309 | #gdtmpl.append(in_vars['lon'].get_value()[-1]*1e6) |
---|
310 | gdtmpl[15] = lon[-1]*1e6 |
---|
311 | # Oct: 64-67 i (west-east) Direction increment (see Note1) |
---|
312 | #gdtmpl[16] = missing(4) |
---|
313 | gdtmpl[16] = 0.375*1e6 |
---|
314 | # Oct: 68-71 j (south-north) Direction increment (see Note1) |
---|
315 | #gdtmpl[17] = missing(4) |
---|
316 | gdtmpl[17] = 0.375*1e6 |
---|
317 | #gdtmpl[17] = -0.375*1e6 |
---|
318 | #gdtmpl[17] = 33143 |
---|
319 | # Oct: 72 Scanning mode (flags see Table 3.4) |
---|
320 | # TODO double check if this is legit considering the flags |
---|
321 | # This should set all the bits to 0 meaning |
---|
322 | # bit value meaning |
---|
323 | # 1 0 Points in the first row or column scan in +i (+x) |
---|
324 | # direction |
---|
325 | # 2 0 Points in the first row or column scan in -i (-x) |
---|
326 | # direction |
---|
327 | # 3 0 Adjacent pints in i(x) direction are consecutive |
---|
328 | # 4 0 All rows scan in the same direction |
---|
329 | # 5-8 0 Reserved (set to zero) |
---|
330 | # NB I suspect the 3 bit might be important for the 'majoring' of the array? |
---|
331 | # # 2^7 2^6 2^5 2^4 2^3 2^2 2^1 2^0 |
---|
332 | # # 1 2 3 4 5 6 7 8 |
---|
333 | gdtmpl[18] = 0 # 0 0 0 0 0 0 0 0 |
---|
334 | #gdtmpl[18] = 16 # 0 0 0 1 0 0 0 0 |
---|
335 | #gdtmpl[18] = 32 # 0 0 1 0 0 0 0 0 |
---|
336 | #gdtmpl[18] = 64 # 0 1 0 0 0 0 0 0 |
---|
337 | #gdtmpl[18] = 128 # 1 0 0 0 0 0 0 0 |
---|
338 | |
---|
339 | #gdtmpl[18] = 192 # 1 1 0 0 0 0 0 0 |
---|
340 | #gdtmpl[18] = 160 # 1 0 1 0 0 0 0 0 |
---|
341 | #gdtmpl[18] = 144 # 1 0 0 1 0 0 0 0 |
---|
342 | #gdtmpl[18] = 96 # 0 1 1 0 0 0 0 0 |
---|
343 | #gdtmpl[18] = 80 # 0 1 0 1 0 0 0 0 |
---|
344 | #gdtmpl[18] = 48 # 0 0 1 1 0 0 0 0 |
---|
345 | |
---|
346 | #gdtmpl[18] = 224 # 1 1 1 0 0 0 0 0 |
---|
347 | #gdtmpl[18] = 208 # 1 1 0 1 0 0 0 0 |
---|
348 | #gdtmpl[18] = 176 # 1 0 1 1 0 0 0 0 |
---|
349 | #gdtmpl[18] = 112 # 0 1 1 1 0 0 0 0 |
---|
350 | |
---|
351 | #gdtmpl[18] = 240 # 1 1 1 1 0 0 0 0 |
---|
352 | |
---|
353 | data.append( |
---|
354 | { |
---|
355 | 'idsect' : idsect, |
---|
356 | 'gdsinfo' : gdsinfo, |
---|
357 | 'gdtmpl' : gdtmpl, |
---|
358 | 'discipline': |
---|
359 | { |
---|
360 | # the first number in the list is the code for the discipline |
---|
361 | 'atmos': |
---|
362 | { |
---|
363 | 'code':0, |
---|
364 | 'fields':{'2d':{}, '3d':{}} |
---|
365 | }, |
---|
366 | 'ocean': |
---|
367 | { |
---|
368 | 'code':10, |
---|
369 | 'fields':{'2d':{}, '3d':{}} |
---|
370 | }, |
---|
371 | 'land': |
---|
372 | { |
---|
373 | 'code':2, |
---|
374 | 'fields':{'2d':{}, '3d':{}} |
---|
375 | } |
---|
376 | } |
---|
377 | } |
---|
378 | ) |
---|
379 | # this is the part where we extract the data from the nc files and put |
---|
380 | # into the structure we will pass later to the encoder |
---|
381 | # let's start with the atmospheric products specifically the surface |
---|
382 | # fields |
---|
383 | # each variables comes with all the metadata necessary to do its grib |
---|
384 | # encoding using the addfield method of the encoder class i.e. pdtnum, |
---|
385 | # pdtmpl, drtnum, drtmpl, field |
---|
386 | |
---|
387 | # -1 stands for the last one (time) added |
---|
388 | dummy = data[-1]['discipline']['atmos']['fields']['2d'] |
---|
389 | |
---|
390 | # Let's prepare the surface pressure data and metadata |
---|
391 | # Product Definition Template Number (see Code Table 4.0) |
---|
392 | # 0 -> Analysis or forecast at a horizontal level or in a |
---|
393 | # horizontal layer at a point in time. (see Template 4.0) |
---|
394 | pdtnum = 0 |
---|
395 | # array of zeros (int) of size 15 |
---|
396 | pdtmpl = n.zeros((15,),dtype=int) |
---|
397 | # Follows the definition of template 4.0 |
---|
398 | # Oct 10: Parameter category (see Code table 4.1). 3 -> mass |
---|
399 | pdtmpl[0] = 3 |
---|
400 | # Oct 11: Parameter number (see Code table 4.2). 0 -> pressure |
---|
401 | pdtmpl[1] = 0 |
---|
402 | # Oct 12: Type of generating process (see Code table 4.3). 2 -> forecast |
---|
403 | pdtmpl[2] = 2 |
---|
404 | # Oct 13: Background generating process identifier |
---|
405 | # (defined by originating centre) |
---|
406 | pdtmpl[3] = missing(1) |
---|
407 | # Oct 14: Analysis or forecast generating process identified |
---|
408 | # (defined by originating centre) |
---|
409 | pdtmpl[4] = missing(1) |
---|
410 | # Oct 15-16: Hours of observational data cutoff after reference time |
---|
411 | pdtmpl[5] = missing(2) |
---|
412 | # Oct 17: Minutes of observational data cutoff after reference time |
---|
413 | pdtmpl[6] = missing(1) |
---|
414 | # Oct 18: Indicator of unit of time range (see Code table 4.4) |
---|
415 | # 1 -> hours |
---|
416 | # NB WPS expects this to be hours! |
---|
417 | pdtmpl[7] = 1 |
---|
418 | # Oct 19-22: Forecast time in units defined by octet 18 |
---|
419 | pdtmpl[8] = fv['forc_hrs'].get_value()[0] |
---|
420 | # Oct 23: Type of first fixed surface (see Code table 4.5) |
---|
421 | # 1 -> ground or water surface |
---|
422 | pdtmpl[9] = 1 |
---|
423 | # Oct 24: Scale factor of first fixed surface |
---|
424 | pdtmpl[10] = 0 |
---|
425 | # Oct 25-28: Scaled value of first fixed surface |
---|
426 | pdtmpl[11] = 0 |
---|
427 | # Oct 29: Type of second fixed surface (see Code table 4.5) |
---|
428 | pdtmpl[12] = missing(1) |
---|
429 | # Oct 30: Scale factor of second fixed surface |
---|
430 | pdtmpl[13] = missing(1) |
---|
431 | # Oct 31-34: Scaled value of second fixed surfaces |
---|
432 | pdtmpl[14] = missing(3) |
---|
433 | |
---|
434 | # drtnum - Data Representation Template Number (see Code Table 5.0). |
---|
435 | # 0 -> grid point data - simple packing |
---|
436 | drtnum = 0 |
---|
437 | # drtmpl - Sequence with the data values for the specified Data Representation |
---|
438 | # Template (N=drtnum). Each element of this integer array contains an |
---|
439 | # entry (in the order specified) of Data Representation Template 5.N Note |
---|
440 | # that some values in this template (eg. reference values, number of |
---|
441 | # bits, etc...) may be changed by the data packing algorithms. Use this to |
---|
442 | # specify scaling factors and order of spatial differencing, if desired. |
---|
443 | drtmpl = n.zeros((5,),dtype=int) |
---|
444 | # NB to make sense of the following remember (from the wmo std): |
---|
445 | # The original data value Y (in the units of code table 4.2) can be recovered |
---|
446 | # with the formula: |
---|
447 | # Y * 10^D= R + (X1+X2) * 2^E |
---|
448 | # For simple packing and all spectral data |
---|
449 | # E = Binary scale factor, |
---|
450 | # D = Decimal scale factor |
---|
451 | # R = Reference value of the whole field, |
---|
452 | # X1 = 0, |
---|
453 | # X2 = Scaled (encoded) value. |
---|
454 | |
---|
455 | # Oct: 12-15. Reference value (R) (IEEE 32-bit floating-point value) |
---|
456 | drtmpl[0] = 0 |
---|
457 | # Oct: 16-17. Binary scale factor (E) |
---|
458 | drtmpl[1] = 0 |
---|
459 | # Oct: 18-19. Decimal scale factor (D) |
---|
460 | drtmpl[2] = 0 |
---|
461 | # Oct: 20. Number of bits used for each packed value for simple packing, or |
---|
462 | drtmpl[3] = 24 |
---|
463 | # for each group reference value for complex packing or spatial differencing |
---|
464 | # Oct: 21. Type of original field values (see Code Table 5.1) |
---|
465 | # 0 -> floating point |
---|
466 | drtmpl[4] = 0 |
---|
467 | |
---|
468 | cheat = fv['sfc_pres'].get_value()[0,lat_cheat_idx:,:-lon_cheat_idx] |
---|
469 | field = n.zeros(cheat.shape) |
---|
470 | for lat_idx in range(cheat.shape[0]): |
---|
471 | field[-(lat_idx+1)] = cheat[lat_idx] |
---|
472 | |
---|
473 | if 0: |
---|
474 | dummy['sfc_pres'] = { |
---|
475 | 'long_name' : 'surface pressure', |
---|
476 | 'pdtnum' : pdtnum, |
---|
477 | 'pdtmpl' : pdtmpl, |
---|
478 | 'drtnum' : drtnum, |
---|
479 | 'drtmpl' : drtmpl, |
---|
480 | #'field' : fv['sfc_pres'].get_value()[0] |
---|
481 | #'field' : fv['sfc_pres'].get_value()[0,lat_cheat_idx:,:-lon_cheat_idx] |
---|
482 | 'field' : field |
---|
483 | } |
---|
484 | |
---|
485 | # Let's prepare the mean sea level pressure data and metadata |
---|
486 | # Product Definition Template Number (see Code Table 4.0) |
---|
487 | # 0 -> Analysis or forecast at a horizontal level or in a |
---|
488 | # horizontal layer at a point in time. (see Template 4.0) |
---|
489 | pdtnum = 0 |
---|
490 | # array of zeros (int) of size 15 |
---|
491 | pdtmpl = n.zeros((15,),dtype=int) |
---|
492 | # Follows the definition of template 4.0 |
---|
493 | # Oct 10: Parameter category (see Code table 4.1). 3 -> mass |
---|
494 | pdtmpl[0] = 3 |
---|
495 | # Oct 11: Parameter number (see Code table 4.2). 1 -> MSLP |
---|
496 | pdtmpl[1] = 1 |
---|
497 | # Oct 12: Type of generating process (see Code table 4.3). 2 -> forecast |
---|
498 | pdtmpl[2] = 2 |
---|
499 | # Oct 13: Background generating process identifier |
---|
500 | # (defined by originating centre) |
---|
501 | pdtmpl[3] = missing(1) |
---|
502 | # Oct 14: Analysis or forecast generating process identified |
---|
503 | # (defined by originating centre) |
---|
504 | pdtmpl[4] = missing(1) |
---|
505 | # Oct 15-16: Hours of observational data cutoff after reference time |
---|
506 | pdtmpl[5] = missing(2) |
---|
507 | # Oct 17: Minutes of observational data cutoff after reference time |
---|
508 | pdtmpl[6] = missing(1) |
---|
509 | # Oct 18: Indicator of unit of time range (see Code table 4.4) |
---|
510 | # 1 -> hours |
---|
511 | # NB WPS expects this to be hours! |
---|
512 | pdtmpl[7] = 1 |
---|
513 | # Oct 19-22: Forecast time in units defined by octet 18 |
---|
514 | pdtmpl[8] = fv['forc_hrs'].get_value()[0] |
---|
515 | # Oct 23: Type of first fixed surface (see Code table 4.5) |
---|
516 | # 101 -> sea level |
---|
517 | pdtmpl[9] = 101 |
---|
518 | # Oct 24: Scale factor of first fixed surface |
---|
519 | pdtmpl[10] = 0 |
---|
520 | # Oct 25-28: Scaled value of first fixed surface |
---|
521 | pdtmpl[11] = 0 |
---|
522 | # Oct 29: Type of second fixed surface (see Code table 4.5) |
---|
523 | pdtmpl[12] = missing(1) |
---|
524 | # Oct 30: Scale factor of second fixed surface |
---|
525 | pdtmpl[13] = missing(1) |
---|
526 | # Oct 31-34: Scaled value of second fixed surfaces |
---|
527 | pdtmpl[14] = missing(3) |
---|
528 | |
---|
529 | # NB I am using the same drtnum and drtmpl for all data so I want |
---|
530 | # replicate it in the following fields if you need to change this on a |
---|
531 | # per-variable basis this is the place to redefine it. If you choose to do |
---|
532 | # so then make sure you define one for each variable that follows or be |
---|
533 | # aware that the last one defined will apply to all that follows. |
---|
534 | |
---|
535 | cheat = fv['mslp'].get_value()[0,lat_cheat_idx:,:-lon_cheat_idx] |
---|
536 | # to go from mb to Pa |
---|
537 | #cheat *= 100. |
---|
538 | cheat = cheat * 100. |
---|
539 | field = n.zeros(cheat.shape) |
---|
540 | for lat_idx in range(cheat.shape[0]): |
---|
541 | field[-(lat_idx+1)] = cheat[lat_idx] |
---|
542 | |
---|
543 | dummy['mslp'] = { |
---|
544 | 'long_name' : 'mean sea level pressure', |
---|
545 | # in my data it comes in mb and I want in Pascals |
---|
546 | 'pdtnum' : pdtnum, |
---|
547 | 'pdtmpl' : pdtmpl, |
---|
548 | 'drtnum' : drtnum, |
---|
549 | 'drtmpl' : drtmpl, |
---|
550 | #'field' : fv['mslp'].get_value()[0]*100. |
---|
551 | #'field' : fv['mslp'].get_value()[0,lat_cheat_idx:,:-lon_cheat_idx]*100. |
---|
552 | 'field' : field |
---|
553 | } |
---|
554 | |
---|
555 | # Let's prepare the 2m temperature data and metadata |
---|
556 | # Product Definition Template Number (see Code Table 4.0) |
---|
557 | # 0 -> Analysis or forecast at a horizontal level or in a |
---|
558 | # horizontal layer at a point in time. (see Template 4.0) |
---|
559 | pdtnum = 0 |
---|
560 | # array of zeros (int) of size 15 |
---|
561 | pdtmpl = n.zeros((15,),dtype=int) |
---|
562 | # Follows the definition of template 4.0 |
---|
563 | # Oct 10: Parameter category (see Code table 4.1). 0 -> temperature |
---|
564 | pdtmpl[0] = 0 |
---|
565 | # Oct 11: Parameter number (see Code table 4.2). 0 -> temperature |
---|
566 | pdtmpl[1] = 0 |
---|
567 | # Oct 12: Type of generating process (see Code table 4.3). 2 -> forecast |
---|
568 | pdtmpl[2] = 2 |
---|
569 | # Oct 13: Background generating process identifier |
---|
570 | # (defined by originating centre) |
---|
571 | pdtmpl[3] = missing(1) |
---|
572 | # Oct 14: Analysis or forecast generating process identified |
---|
573 | # (defined by originating centre) |
---|
574 | pdtmpl[4] = missing(1) |
---|
575 | # Oct 15-16: Hours of observational data cutoff after reference time |
---|
576 | pdtmpl[5] = missing(2) |
---|
577 | # Oct 17: Minutes of observational data cutoff after reference time |
---|
578 | pdtmpl[6] = missing(1) |
---|
579 | # Oct 18: Indicator of unit of time range (see Code table 4.4) |
---|
580 | # 1 -> hours |
---|
581 | # NB WPS expects this to be hours! |
---|
582 | pdtmpl[7] = 1 |
---|
583 | # Oct 19-22: Forecast time in units defined by octet 18 |
---|
584 | pdtmpl[8] = fv['forc_hrs'].get_value()[0] |
---|
585 | # Oct 23: Type of first fixed surface (see Code table 4.5) |
---|
586 | # 1 -> ground or water surface |
---|
587 | pdtmpl[9] = 103 |
---|
588 | # Oct 24: Scale factor of first fixed surface |
---|
589 | pdtmpl[10] = 0 |
---|
590 | # Oct 25-28: Scaled value of first fixed surface |
---|
591 | # -> 2m above ground |
---|
592 | pdtmpl[11] = 2 |
---|
593 | # Oct 29: Type of second fixed surface (see Code table 4.5) |
---|
594 | pdtmpl[12] = missing(1) |
---|
595 | # Oct 30: Scale factor of second fixed surface |
---|
596 | pdtmpl[13] = missing(1) |
---|
597 | # Oct 31-34: Scaled value of second fixed surfaces |
---|
598 | pdtmpl[14] = missing(3) |
---|
599 | |
---|
600 | # NB I am using the same drtnum and drtmpl for all data so I want |
---|
601 | # replicate it in the following fields if you need to change this on a |
---|
602 | # per-variable basis this is the place to redefine it. If you choose to do |
---|
603 | # so then make sure you define one for each variable that follows or be |
---|
604 | # aware that the last one defined will apply to all that follows. |
---|
605 | |
---|
606 | cheat = fv['sfc_temp'].get_value()[0,lat_cheat_idx:,:-lon_cheat_idx] |
---|
607 | field = n.zeros(cheat.shape) |
---|
608 | for lat_idx in range(cheat.shape[0]): |
---|
609 | field[-(lat_idx+1)] = cheat[lat_idx] |
---|
610 | |
---|
611 | dummy['sfc_temp'] = { |
---|
612 | 'long_name' : 'surface temperature', |
---|
613 | 'pdtnum' : pdtnum, |
---|
614 | 'pdtmpl' : pdtmpl, |
---|
615 | 'drtnum' : drtnum, |
---|
616 | 'drtmpl' : drtmpl, |
---|
617 | #'field' : fv['sfc_temp'].get_value()[0] |
---|
618 | #'field' : fv['sfc_temp'].get_value()[0,lat_cheat_idx:,:-lon_cheat_idx] |
---|
619 | 'field' : field |
---|
620 | } |
---|
621 | |
---|
622 | # Let's prepare the 2m temperature data and metadata |
---|
623 | # Product Definition Template Number (see Code Table 4.0) |
---|
624 | # 0 -> Analysis or forecast at a horizontal level or in a |
---|
625 | # horizontal layer at a point in time. (see Template 4.0) |
---|
626 | pdtnum = 0 |
---|
627 | # array of zeros (int) of size 15 |
---|
628 | pdtmpl = n.zeros((15,),dtype=int) |
---|
629 | # Follows the definition of template 4.0 |
---|
630 | # Oct 10: Parameter category (see Code table 4.1). 0 -> temperature |
---|
631 | pdtmpl[0] = 0 |
---|
632 | # Oct 11: Parameter number (see Code table 4.2). 0 -> temperature |
---|
633 | pdtmpl[1] = 0 |
---|
634 | # Oct 12: Type of generating process (see Code table 4.3). 2 -> forecast |
---|
635 | pdtmpl[2] = 2 |
---|
636 | # Oct 13: Background generating process identifier |
---|
637 | # (defined by originating centre) |
---|
638 | pdtmpl[3] = missing(1) |
---|
639 | # Oct 14: Analysis or forecast generating process identified |
---|
640 | # (defined by originating centre) |
---|
641 | pdtmpl[4] = missing(1) |
---|
642 | # Oct 15-16: Hours of observational data cutoff after reference time |
---|
643 | pdtmpl[5] = missing(2) |
---|
644 | # Oct 17: Minutes of observational data cutoff after reference time |
---|
645 | pdtmpl[6] = missing(1) |
---|
646 | # Oct 18: Indicator of unit of time range (see Code table 4.4) |
---|
647 | # 1 -> hours |
---|
648 | # NB WPS expects this to be hours! |
---|
649 | pdtmpl[7] = 1 |
---|
650 | # Oct 19-22: Forecast time in units defined by octet 18 |
---|
651 | pdtmpl[8] = fv['forc_hrs'].get_value()[0] |
---|
652 | # Oct 23: Type of first fixed surface (see Code table 4.5) |
---|
653 | # 1 -> surface |
---|
654 | pdtmpl[9] = 1 |
---|
655 | # Oct 24: Scale factor of first fixed surface |
---|
656 | pdtmpl[10] = 0 |
---|
657 | # Oct 25-28: Scaled value of first fixed surface |
---|
658 | # -> 2m above ground |
---|
659 | pdtmpl[11] = 0 |
---|
660 | # Oct 29: Type of second fixed surface (see Code table 4.5) |
---|
661 | pdtmpl[12] = missing(1) |
---|
662 | # Oct 30: Scale factor of second fixed surface |
---|
663 | pdtmpl[13] = missing(1) |
---|
664 | # Oct 31-34: Scaled value of second fixed surfaces |
---|
665 | pdtmpl[14] = missing(3) |
---|
666 | |
---|
667 | # NB I am using the same drtnum and drtmpl for all data so I want |
---|
668 | # replicate it in the following fields if you need to change this on a |
---|
669 | # per-variable basis this is the place to redefine it. If you choose to do |
---|
670 | # so then make sure you define one for each variable that follows or be |
---|
671 | # aware that the last one defined will apply to all that follows. |
---|
672 | |
---|
673 | cheat = fv['skin_temp'].get_value()[0,lat_cheat_idx:,:-lon_cheat_idx] |
---|
674 | field = n.zeros(cheat.shape) |
---|
675 | for lat_idx in range(cheat.shape[0]): |
---|
676 | field[-(lat_idx+1)] = cheat[lat_idx] |
---|
677 | |
---|
678 | dummy['skin_temp'] = { |
---|
679 | 'long_name' : 'skin temperature', |
---|
680 | 'pdtnum' : pdtnum, |
---|
681 | 'pdtmpl' : pdtmpl, |
---|
682 | 'drtnum' : drtnum, |
---|
683 | 'drtmpl' : drtmpl, |
---|
684 | #'field' : fv['skin_temp'].get_value()[0] |
---|
685 | #'field' : fv['skin_temp'].get_value()[0,lat_cheat_idx:,:-lon_cheat_idx] |
---|
686 | 'field' : field |
---|
687 | } |
---|
688 | |
---|
689 | # the next fields will come from a different file... |
---|
690 | sfc_file, sfc_f, sfc_fv, time_idx = prepare_sfc_data(f,fv) |
---|
691 | # DEBUG |
---|
692 | #p.figure() |
---|
693 | #p.contour(dummy['skin_temp']['field']) |
---|
694 | #p.figure() |
---|
695 | #p.contour(sfc_fv['skin_temp'].get_value()[time_idx]) |
---|
696 | |
---|
697 | # Let's prepare the 2m RH data and metadata |
---|
698 | # Product Definition Template Number (see Code Table 4.0) |
---|
699 | # 0 -> Analysis or forecast at a horizontal level or in a |
---|
700 | # horizontal layer at a point in time. (see Template 4.0) |
---|
701 | pdtnum = 0 |
---|
702 | # array of zeros (int) of size 15 |
---|
703 | pdtmpl = n.zeros((15,),dtype=int) |
---|
704 | # Follows the definition of template 4.0 |
---|
705 | # Oct 10: Parameter category (see Code table 4.1). 1 -> moisture |
---|
706 | pdtmpl[0] = 1 |
---|
707 | # Oct 11: Parameter number (see Code table 4.2). 1 -> RH |
---|
708 | pdtmpl[1] = 1 |
---|
709 | # Oct 12: Type of generating process (see Code table 4.3). 2 -> forecast |
---|
710 | pdtmpl[2] = 2 |
---|
711 | # Oct 13: Background generating process identifier |
---|
712 | # (defined by originating centre) |
---|
713 | pdtmpl[3] = missing(1) |
---|
714 | # Oct 14: Analysis or forecast generating process identified |
---|
715 | # (defined by originating centre) |
---|
716 | pdtmpl[4] = missing(1) |
---|
717 | # Oct 15-16: Hours of observational data cutoff after reference time |
---|
718 | pdtmpl[5] = missing(2) |
---|
719 | # Oct 17: Minutes of observational data cutoff after reference time |
---|
720 | pdtmpl[6] = missing(1) |
---|
721 | # Oct 18: Indicator of unit of time range (see Code table 4.4) |
---|
722 | # 1 -> hours |
---|
723 | # NB WPS expects this to be hours! |
---|
724 | pdtmpl[7] = 1 |
---|
725 | # Oct 19-22: Forecast time in units defined by octet 18 |
---|
726 | pdtmpl[8] = fv['forc_hrs'].get_value()[0] |
---|
727 | # Oct 23: Type of first fixed surface (see Code table 4.5) |
---|
728 | # 103 -> fixed height above ground |
---|
729 | pdtmpl[9] = 103 |
---|
730 | # Oct 24: Scale factor of first fixed surface |
---|
731 | pdtmpl[10] = 0 |
---|
732 | # Oct 25-28: Scaled value of first fixed surface |
---|
733 | # -> 2m above ground |
---|
734 | pdtmpl[11] = 2 |
---|
735 | # Oct 29: Type of second fixed surface (see Code table 4.5) |
---|
736 | pdtmpl[12] = missing(1) |
---|
737 | # Oct 30: Scale factor of second fixed surface |
---|
738 | pdtmpl[13] = missing(1) |
---|
739 | # Oct 31-34: Scaled value of second fixed surfaces |
---|
740 | pdtmpl[14] = missing(3) |
---|
741 | |
---|
742 | # NB I am using the same drtnum and drtmpl for all data so I want |
---|
743 | # replicate it in the following fields if you need to change this on a |
---|
744 | # per-variable basis this is the place to redefine it. If you choose to do |
---|
745 | # so then make sure you define one for each variable that follows or be |
---|
746 | # aware that the last one defined will apply to all that follows. |
---|
747 | |
---|
748 | # The surface files do not come with mixing ratio, but we can calculate |
---|
749 | # that from the dew point temperature... |
---|
750 | #dew_point = sfc_fv['scrn_dewpt'].get_value()[time_idx] |
---|
751 | dew_point = sfc_fv['scrn_dewpt'].get_value()[time_idx,lat_cheat_idx:,:-lon_cheat_idx] |
---|
752 | vapour_pressure = goff_gratch(dew_point) |
---|
753 | #sfc_temp = sfc_fv['scrn_temp'].get_value()[time_idx] |
---|
754 | sfc_temp = sfc_fv['scrn_temp'].get_value()[time_idx,lat_cheat_idx:,:-lon_cheat_idx] |
---|
755 | sat_vapour_pressure = goff_gratch(sfc_temp) |
---|
756 | #sat_vapour_pressure = ma.masked_where(sat_vapour_pressure == 0., |
---|
757 | # sat_vapour_pressure) |
---|
758 | sfc_rh = vapour_pressure / sat_vapour_pressure * 100 |
---|
759 | del sfc_temp, vapour_pressure, dew_point, sat_vapour_pressure |
---|
760 | |
---|
761 | cheat = sfc_rh |
---|
762 | field = n.zeros(cheat.shape) |
---|
763 | for lat_idx in range(cheat.shape[0]): |
---|
764 | field[-(lat_idx+1)] = cheat[lat_idx] |
---|
765 | |
---|
766 | dummy['sfc_rh'] = { |
---|
767 | 'long_name' : '2m relative humidity', |
---|
768 | 'pdtnum' : pdtnum, |
---|
769 | 'pdtmpl' : pdtmpl, |
---|
770 | 'drtnum' : drtnum, |
---|
771 | 'drtmpl' : drtmpl, |
---|
772 | #'field' : sfc_rh.filled(fill_value=0.) |
---|
773 | #'field' : sfc_rh |
---|
774 | 'field' : field |
---|
775 | } |
---|
776 | |
---|
777 | # Let's prepare the zonal 10m wind data and metadata |
---|
778 | # Product Definition Template Number (see Code Table 4.0) |
---|
779 | # 0 -> Analysis or forecast at a horizontal level or in a |
---|
780 | # horizontal layer at a point in time. (see Template 4.0) |
---|
781 | pdtnum = 0 |
---|
782 | # array of zeros (int) of size 15 |
---|
783 | pdtmpl = n.zeros((15,),dtype=int) |
---|
784 | # Follows the definition of template 4.0 |
---|
785 | # Oct 10: Parameter category (see Code table 4.1). 2 -> momentum |
---|
786 | pdtmpl[0] = 2 |
---|
787 | # Oct 11: Parameter number (see Code table 4.2). 2 -> u-component of wind |
---|
788 | pdtmpl[1] = 2 |
---|
789 | # Oct 12: Type of generating process (see Code table 4.3). 2 -> forecast |
---|
790 | pdtmpl[2] = 2 |
---|
791 | # Oct 13: Background generating process identifier |
---|
792 | # (defined by originating centre) |
---|
793 | pdtmpl[3] = missing(1) |
---|
794 | # Oct 14: Analysis or forecast generating process identified |
---|
795 | # (defined by originating centre) |
---|
796 | pdtmpl[4] = missing(1) |
---|
797 | # Oct 15-16: Hours of observational data cutoff after reference time |
---|
798 | pdtmpl[5] = missing(2) |
---|
799 | # Oct 17: Minutes of observational data cutoff after reference time |
---|
800 | pdtmpl[6] = missing(1) |
---|
801 | # Oct 18: Indicator of unit of time range (see Code table 4.4) |
---|
802 | # 1 -> hours |
---|
803 | # NB WPS expects this to be hours! |
---|
804 | pdtmpl[7] = 1 |
---|
805 | # Oct 19-22: Forecast time in units defined by octet 18 |
---|
806 | pdtmpl[8] = fv['forc_hrs'].get_value()[0] |
---|
807 | # Oct 23: Type of first fixed surface (see Code table 4.5) |
---|
808 | # 103 -> fixed height above ground |
---|
809 | pdtmpl[9] = 103 |
---|
810 | # Oct 24: Scale factor of first fixed surface |
---|
811 | pdtmpl[10] = 0 |
---|
812 | # Oct 25-28: Scaled value of first fixed surface |
---|
813 | # -> 10m above ground |
---|
814 | pdtmpl[11] = 10 |
---|
815 | # Oct 29: Type of second fixed surface (see Code table 4.5) |
---|
816 | pdtmpl[12] = missing(1) |
---|
817 | # Oct 30: Scale factor of second fixed surface |
---|
818 | pdtmpl[13] = missing(1) |
---|
819 | # Oct 31-34: Scaled value of second fixed surfaces |
---|
820 | pdtmpl[14] = missing(3) |
---|
821 | |
---|
822 | # NB I am using the same drtnum and drtmpl for all data so I want |
---|
823 | # replicate it in the following fields if you need to change this on a |
---|
824 | # per-variable basis this is the place to redefine it. If you choose to do |
---|
825 | # so then make sure you define one for each variable that follows or be |
---|
826 | # aware that the last one defined will apply to all that follows. |
---|
827 | |
---|
828 | cheat = sfc_fv['q10m_zonal_wnd'].get_value()[time_idx,lat_cheat_idx:,:-lon_cheat_idx] |
---|
829 | field = n.zeros(cheat.shape) |
---|
830 | for lat_idx in range(cheat.shape[0]): |
---|
831 | field[-(lat_idx+1)] = cheat[lat_idx] |
---|
832 | |
---|
833 | dummy['sfc_zonal_wnd'] = { |
---|
834 | 'long_name' : '10m zonal wind', |
---|
835 | 'pdtnum' : pdtnum, |
---|
836 | 'pdtmpl' : pdtmpl, |
---|
837 | 'drtnum' : drtnum, |
---|
838 | 'drtmpl' : drtmpl, |
---|
839 | #'field' : sfc_fv['q10m_zonal_wnd'].get_value()[time_idx] |
---|
840 | #'field' : sfc_fv['q10m_zonal_wnd'].get_value()[time_idx,lat_cheat_idx:,:-lon_cheat_idx] |
---|
841 | 'field' : field |
---|
842 | } |
---|
843 | |
---|
844 | # Let's prepare the meridional 10m wind data and metadata |
---|
845 | # Product Definition Template Number (see Code Table 4.0) |
---|
846 | # 0 -> Analysis or forecast at a horizontal level or in a |
---|
847 | # horizontal layer at a point in time. (see Template 4.0) |
---|
848 | pdtnum = 0 |
---|
849 | # array of zeros (int) of size 15 |
---|
850 | pdtmpl = n.zeros((15,),dtype=int) |
---|
851 | # Follows the definition of template 4.0 |
---|
852 | # Oct 10: Parameter category (see Code table 4.1). 2 -> momentum |
---|
853 | pdtmpl[0] = 2 |
---|
854 | # Oct 11: Parameter number (see Code table 4.2). 3 -> v-component of wind |
---|
855 | pdtmpl[1] = 3 |
---|
856 | # Oct 12: Type of generating process (see Code table 4.3). 2 -> forecast |
---|
857 | pdtmpl[2] = 2 |
---|
858 | # Oct 13: Background generating process identifier |
---|
859 | # (defined by originating centre) |
---|
860 | pdtmpl[3] = missing(1) |
---|
861 | # Oct 14: Analysis or forecast generating process identified |
---|
862 | # (defined by originating centre) |
---|
863 | pdtmpl[4] = missing(1) |
---|
864 | # Oct 15-16: Hours of observational data cutoff after reference time |
---|
865 | pdtmpl[5] = missing(2) |
---|
866 | # Oct 17: Minutes of observational data cutoff after reference time |
---|
867 | pdtmpl[6] = missing(1) |
---|
868 | # Oct 18: Indicator of unit of time range (see Code table 4.4) |
---|
869 | # 1 -> hours |
---|
870 | # NB WPS expects this to be hours! |
---|
871 | pdtmpl[7] = 1 |
---|
872 | # Oct 19-22: Forecast time in units defined by octet 18 |
---|
873 | pdtmpl[8] = fv['forc_hrs'].get_value()[0] |
---|
874 | # Oct 23: Type of first fixed surface (see Code table 4.5) |
---|
875 | # 103 -> fixed height above ground |
---|
876 | pdtmpl[9] = 103 |
---|
877 | # Oct 24: Scale factor of first fixed surface |
---|
878 | pdtmpl[10] = 0 |
---|
879 | # Oct 25-28: Scaled value of first fixed surface |
---|
880 | # -> 10m above ground |
---|
881 | pdtmpl[11] = 10 |
---|
882 | # Oct 29: Type of second fixed surface (see Code table 4.5) |
---|
883 | pdtmpl[12] = missing(1) |
---|
884 | # Oct 30: Scale factor of second fixed surface |
---|
885 | pdtmpl[13] = missing(1) |
---|
886 | # Oct 31-34: Scaled value of second fixed surfaces |
---|
887 | pdtmpl[14] = missing(3) |
---|
888 | |
---|
889 | # NB I am using the same drtnum and drtmpl for all data so I want |
---|
890 | # replicate it in the following fields if you need to change this on a |
---|
891 | # per-variable basis this is the place to redefine it. If you choose to do |
---|
892 | # so then make sure you define one for each variable that follows or be |
---|
893 | # aware that the last one defined will apply to all that follows. |
---|
894 | |
---|
895 | cheat = sfc_fv['q10m_merid_wnd'].get_value()[time_idx,lat_cheat_idx:,:-lon_cheat_idx] |
---|
896 | field = n.zeros(cheat.shape) |
---|
897 | for lat_idx in range(cheat.shape[0]): |
---|
898 | field[-(lat_idx+1)] = cheat[lat_idx] |
---|
899 | |
---|
900 | dummy['sfc_merid_wnd'] = { |
---|
901 | 'long_name' : '10m meridional wind', |
---|
902 | 'pdtnum' : pdtnum, |
---|
903 | 'pdtmpl' : pdtmpl, |
---|
904 | 'drtnum' : drtnum, |
---|
905 | 'drtmpl' : drtmpl, |
---|
906 | #'field' : sfc_fv['q10m_merid_wnd'].get_value()[time_idx] |
---|
907 | #'field' : sfc_fv['q10m_merid_wnd'].get_value()[time_idx,lat_cheat_idx:,:-lon_cheat_idx] |
---|
908 | 'field' : field |
---|
909 | } |
---|
910 | |
---|
911 | if 1: |
---|
912 | # Let's prepare the topography data and metadata |
---|
913 | # Product Definition Template Number (see Code Table 4.0) |
---|
914 | # 0 -> Analysis or forecast at a horizontal level or in a |
---|
915 | # horizontal layer at a point in time. (see Template 4.0) |
---|
916 | pdtnum = 0 |
---|
917 | # array of zeros (int) of size 15 |
---|
918 | pdtmpl = n.zeros((15,),dtype=int) |
---|
919 | # Follows the definition of template 4.0 |
---|
920 | # Oct 10: Parameter category (see Code table 4.1). 3 -> mass |
---|
921 | pdtmpl[0] = 3 |
---|
922 | # Oct 11: Parameter number (see Code table 4.2). 5 -> geopotential height |
---|
923 | pdtmpl[1] = 5 |
---|
924 | # Oct 12: Type of generating process (see Code table 4.3). 2 -> forecast |
---|
925 | pdtmpl[2] = 2 |
---|
926 | # Oct 13: Background generating process identifier |
---|
927 | # (defined by originating centre) |
---|
928 | pdtmpl[3] = missing(1) |
---|
929 | # Oct 14: Analysis or forecast generating process identified |
---|
930 | # (defined by originating centre) |
---|
931 | pdtmpl[4] = missing(1) |
---|
932 | # Oct 15-16: Hours of observational data cutoff after reference time |
---|
933 | pdtmpl[5] = missing(2) |
---|
934 | # Oct 17: Minutes of observational data cutoff after reference time |
---|
935 | pdtmpl[6] = missing(1) |
---|
936 | # Oct 18: Indicator of unit of time range (see Code table 4.4) |
---|
937 | # 1 -> hours |
---|
938 | # NB WPS expects this to be hours! |
---|
939 | pdtmpl[7] = 1 |
---|
940 | # Oct 19-22: Forecast time in units defined by octet 18 |
---|
941 | pdtmpl[8] = fv['forc_hrs'].get_value()[0] |
---|
942 | # Oct 23: Type of first fixed surface (see Code table 4.5) |
---|
943 | # 1 -> surface |
---|
944 | pdtmpl[9] = 1 |
---|
945 | # Oct 24: Scale factor of first fixed surface |
---|
946 | pdtmpl[10] = 0 |
---|
947 | # Oct 25-28: Scaled value of first fixed surface |
---|
948 | pdtmpl[11] = 0 |
---|
949 | # Oct 29: Type of second fixed surface (see Code table 4.5) |
---|
950 | pdtmpl[12] = missing(1) |
---|
951 | # Oct 30: Scale factor of second fixed surface |
---|
952 | pdtmpl[13] = missing(1) |
---|
953 | # Oct 31-34: Scaled value of second fixed surfaces |
---|
954 | pdtmpl[14] = missing(3) |
---|
955 | |
---|
956 | # NB I am using the same drtnum and drtmpl for all data so I want |
---|
957 | # replicate it in the following fields if you need to change this on a |
---|
958 | # per-variable basis this is the place to redefine it. If you choose to do |
---|
959 | # so then make sure you define one for each variable that follows or be |
---|
960 | # aware that the last one defined will apply to all that follows. |
---|
961 | |
---|
962 | cheat = fv['topog'].get_value()[lat_cheat_idx:,:-lon_cheat_idx] |
---|
963 | field = n.zeros(cheat.shape) |
---|
964 | for lat_idx in range(cheat.shape[0]): |
---|
965 | field[-(lat_idx+1)] = cheat[lat_idx] |
---|
966 | |
---|
967 | dummy['topog'] = { |
---|
968 | 'long_name' : 'topography', |
---|
969 | 'pdtnum' : pdtnum, |
---|
970 | 'pdtmpl' : pdtmpl, |
---|
971 | 'drtnum' : drtnum, |
---|
972 | 'drtmpl' : drtmpl, |
---|
973 | #'field' : fv['topog'].get_value() |
---|
974 | #'field' : fv['topog'].get_value()[lat_cheat_idx:,:-lon_cheat_idx] |
---|
975 | 'field' : field |
---|
976 | } |
---|
977 | |
---|
978 | if 1: |
---|
979 | # Let's prepare the water equivalent accumulated snow depth |
---|
980 | # data and metadata |
---|
981 | # Product Definition Template Number (see Code Table 4.0) |
---|
982 | # 0 -> Analysis or forecast at a horizontal level or in a |
---|
983 | # horizontal layer at a point in time. (see Template 4.0) |
---|
984 | pdtnum = 0 |
---|
985 | # array of zeros (int) of size 15 |
---|
986 | pdtmpl = n.zeros((15,),dtype=int) |
---|
987 | # Follows the definition of template 4.0 |
---|
988 | # Oct 10: Parameter category (see Code table 4.1). 1 -> moisture |
---|
989 | pdtmpl[0] = 1 |
---|
990 | # Oct 11: Parameter number (see Code table 4.2). 13 -> |
---|
991 | # water equivalent of accumulated snow depth |
---|
992 | pdtmpl[1] = 13 |
---|
993 | # Oct 12: Type of generating process (see Code table 4.3). 2 -> forecast |
---|
994 | pdtmpl[2] = 2 |
---|
995 | # Oct 13: Background generating process identifier |
---|
996 | # (defined by originating centre) |
---|
997 | pdtmpl[3] = missing(1) |
---|
998 | # Oct 14: Analysis or forecast generating process identified |
---|
999 | # (defined by originating centre) |
---|
1000 | pdtmpl[4] = missing(1) |
---|
1001 | # Oct 15-16: Hours of observational data cutoff after reference time |
---|
1002 | pdtmpl[5] = missing(2) |
---|
1003 | # Oct 17: Minutes of observational data cutoff after reference time |
---|
1004 | pdtmpl[6] = missing(1) |
---|
1005 | # Oct 18: Indicator of unit of time range (see Code table 4.4) |
---|
1006 | # 1 -> hours |
---|
1007 | # NB WPS expects this to be hours! |
---|
1008 | pdtmpl[7] = 1 |
---|
1009 | # Oct 19-22: Forecast time in units defined by octet 18 |
---|
1010 | pdtmpl[8] = fv['forc_hrs'].get_value()[0] |
---|
1011 | # Oct 23: Type of first fixed surface (see Code table 4.5) |
---|
1012 | # 1 -> surface |
---|
1013 | pdtmpl[9] = 1 |
---|
1014 | # Oct 24: Scale factor of first fixed surface |
---|
1015 | pdtmpl[10] = 0 |
---|
1016 | # Oct 25-28: Scaled value of first fixed surface |
---|
1017 | pdtmpl[11] = 0 |
---|
1018 | # Oct 29: Type of second fixed surface (see Code table 4.5) |
---|
1019 | pdtmpl[12] = missing(1) |
---|
1020 | # Oct 30: Scale factor of second fixed surface |
---|
1021 | pdtmpl[13] = missing(1) |
---|
1022 | # Oct 31-34: Scaled value of second fixed surfaces |
---|
1023 | pdtmpl[14] = missing(3) |
---|
1024 | |
---|
1025 | # NB I am using the same drtnum and drtmpl for all data so I want |
---|
1026 | # replicate it in the following fields if you need to change this on a |
---|
1027 | # per-variable basis this is the place to redefine it. If you choose to do |
---|
1028 | # so then make sure you define one for each variable that follows or be |
---|
1029 | # aware that the last one defined will apply to all that follows. |
---|
1030 | |
---|
1031 | #dummy_field = n.zeros((len(lon),len(lat)),dtype=float) |
---|
1032 | dummy_field = n.zeros((len(lat),len(lon)),dtype=float) |
---|
1033 | dummy['weasd'] = { |
---|
1034 | 'long_name' : 'water equivalent of accumulated snow depth', |
---|
1035 | 'pdtnum' : pdtnum, |
---|
1036 | 'pdtmpl' : pdtmpl, |
---|
1037 | 'drtnum' : drtnum, |
---|
1038 | 'drtmpl' : drtmpl, |
---|
1039 | 'field' : dummy_field |
---|
1040 | } |
---|
1041 | |
---|
1042 | ####################################################################### |
---|
1043 | # Finished with the 2d fields |
---|
1044 | # Let's move on to the 3d ones |
---|
1045 | ####################################################################### |
---|
1046 | |
---|
1047 | dummy = data[-1]['discipline']['atmos']['fields']['3d'] |
---|
1048 | |
---|
1049 | # Let's prepare the air temperature data and metadata |
---|
1050 | # Product Definition Template Number (see Code Table 4.0) |
---|
1051 | # 0 -> Analysis or forecast at a horizontal level or in a |
---|
1052 | # horizontal layer at a point in time. (see Template 4.0) |
---|
1053 | pdtnum = 0 |
---|
1054 | # array of zeros (int) of size 15 |
---|
1055 | pdtmpl = n.zeros((15,),dtype=int) |
---|
1056 | # Follows the definition of template 4.0 |
---|
1057 | # Oct 10: Parameter category (see Code table 4.1). 0 -> temperature |
---|
1058 | pdtmpl[0] = 0 |
---|
1059 | # Oct 11: Parameter number (see Code table 4.2). 0 -> temperature |
---|
1060 | pdtmpl[1] = 0 |
---|
1061 | # Oct 12: Type of generating process (see Code table 4.3). 2 -> forecast |
---|
1062 | pdtmpl[2] = 2 |
---|
1063 | # Oct 13: Background generating process identifier |
---|
1064 | # (defined by originating centre) |
---|
1065 | pdtmpl[3] = missing(1) |
---|
1066 | # Oct 14: Analysis or forecast generating process identified |
---|
1067 | # (defined by originating centre) |
---|
1068 | pdtmpl[4] = missing(1) |
---|
1069 | # Oct 15-16: Hours of observational data cutoff after reference time |
---|
1070 | pdtmpl[5] = missing(2) |
---|
1071 | # Oct 17: Minutes of observational data cutoff after reference time |
---|
1072 | pdtmpl[6] = missing(1) |
---|
1073 | # Oct 18: Indicator of unit of time range (see Code table 4.4) |
---|
1074 | # 1 -> hours |
---|
1075 | # NB WPS expects this to be hours! |
---|
1076 | pdtmpl[7] = 1 |
---|
1077 | # Oct 19-22: Forecast time in units defined by octet 18 |
---|
1078 | pdtmpl[8] = fv['forc_hrs'].get_value()[0] |
---|
1079 | # Oct 23: Type of first fixed surface (see Code table 4.5) |
---|
1080 | # 1 -> isobaric level |
---|
1081 | pdtmpl[9] = 100 |
---|
1082 | # Oct 24: Scale factor of first fixed surface |
---|
1083 | pdtmpl[10] = 0 |
---|
1084 | # Oct 25-28: Scaled value of first fixed surface |
---|
1085 | # -> missing as there is will be defined later when the data is sliced in |
---|
1086 | # horizontal slabs for its encoding |
---|
1087 | pdtmpl[11] = missing(3) |
---|
1088 | # Oct 29: Type of second fixed surface (see Code table 4.5) |
---|
1089 | pdtmpl[12] = missing(1) |
---|
1090 | # Oct 30: Scale factor of second fixed surface |
---|
1091 | pdtmpl[13] = missing(1) |
---|
1092 | # Oct 31-34: Scaled value of second fixed surfaces |
---|
1093 | pdtmpl[14] = missing(3) |
---|
1094 | |
---|
1095 | # NB I am using the same drtnum and drtmpl for all data so I want |
---|
1096 | # replicate it in the following fields if you need to change this on a |
---|
1097 | # per-variable basis this is the place to redefine it. If you choose to do |
---|
1098 | # so then make sure you define one for each variable that follows or be |
---|
1099 | # aware that the last one defined will apply to all that follows. |
---|
1100 | |
---|
1101 | cheat = fv['air_temp'].get_value()[0,:,lat_cheat_idx:,:-lon_cheat_idx] |
---|
1102 | field = n.zeros(cheat.shape) |
---|
1103 | for lvl_idx in range(cheat.shape[0]): |
---|
1104 | for lat_idx in range(cheat.shape[1]): |
---|
1105 | field[lvl_idx,-(lat_idx+1)] = cheat[lvl_idx,lat_idx] |
---|
1106 | |
---|
1107 | dummy['air_temp'] = { |
---|
1108 | 'long_name' : '3D air temperature', |
---|
1109 | 'pdtnum' : pdtnum, |
---|
1110 | 'pdtmpl' : pdtmpl, |
---|
1111 | 'drtnum' : drtnum, |
---|
1112 | 'drtmpl' : drtmpl, |
---|
1113 | #'field' : fv['air_temp'].get_value()[0], |
---|
1114 | #'field' : fv['air_temp'].get_value()[0,:,lat_cheat_idx:,:-lon_cheat_idx], |
---|
1115 | 'field' : field, |
---|
1116 | #'field' : '', |
---|
1117 | 'lvl' : fv['lvl'].get_value() |
---|
1118 | } |
---|
1119 | |
---|
1120 | # Let's prepare the 3d relative humidity data and metadata |
---|
1121 | # Product Definition Template Number (see Code Table 4.0) |
---|
1122 | # 0 -> Analysis or forecast at a horizontal level or in a |
---|
1123 | # horizontal layer at a point in time. (see Template 4.0) |
---|
1124 | pdtnum = 0 |
---|
1125 | # array of zeros (int) of size 15 |
---|
1126 | pdtmpl = n.zeros((15,),dtype=int) |
---|
1127 | # Follows the definition of template 4.0 |
---|
1128 | # Oct 10: Parameter category (see Code table 4.1). 1 -> moisture |
---|
1129 | pdtmpl[0] = 1 |
---|
1130 | # Oct 11: Parameter number (see Code table 4.2). 1 -> RH |
---|
1131 | pdtmpl[1] = 1 |
---|
1132 | # Oct 12: Type of generating process (see Code table 4.3). 2 -> forecast |
---|
1133 | pdtmpl[2] = 2 |
---|
1134 | # Oct 13: Background generating process identifier |
---|
1135 | # (defined by originating centre) |
---|
1136 | pdtmpl[3] = missing(1) |
---|
1137 | # Oct 14: Analysis or forecast generating process identified |
---|
1138 | # (defined by originating centre) |
---|
1139 | pdtmpl[4] = missing(1) |
---|
1140 | # Oct 15-16: Hours of observational data cutoff after reference time |
---|
1141 | pdtmpl[5] = missing(2) |
---|
1142 | # Oct 17: Minutes of observational data cutoff after reference time |
---|
1143 | pdtmpl[6] = missing(1) |
---|
1144 | # Oct 18: Indicator of unit of time range (see Code table 4.4) |
---|
1145 | # 1 -> hours |
---|
1146 | # NB WPS expects this to be hours! |
---|
1147 | pdtmpl[7] = 1 |
---|
1148 | # Oct 19-22: Forecast time in units defined by octet 18 |
---|
1149 | pdtmpl[8] = fv['forc_hrs'].get_value()[0] |
---|
1150 | # Oct 23: Type of first fixed surface (see Code table 4.5) |
---|
1151 | # 1 -> isobaric level |
---|
1152 | pdtmpl[9] = 100 |
---|
1153 | # Oct 24: Scale factor of first fixed surface |
---|
1154 | pdtmpl[10] = 0 |
---|
1155 | # Oct 25-28: Scaled value of first fixed surface |
---|
1156 | # -> missing as there is will be defined later when the data is sliced in |
---|
1157 | # horizontal slabs for its encoding |
---|
1158 | pdtmpl[11] = missing(3) |
---|
1159 | # Oct 29: Type of second fixed surface (see Code table 4.5) |
---|
1160 | pdtmpl[12] = missing(1) |
---|
1161 | # Oct 30: Scale factor of second fixed surface |
---|
1162 | pdtmpl[13] = missing(1) |
---|
1163 | # Oct 31-34: Scaled value of second fixed surfaces |
---|
1164 | pdtmpl[14] = missing(3) |
---|
1165 | |
---|
1166 | # NB I am using the same drtnum and drtmpl for all data so I want |
---|
1167 | # replicate it in the following fields if you need to change this on a |
---|
1168 | # per-variable basis this is the place to redefine it. If you choose to do |
---|
1169 | # so then make sure you define one for each variable that follows or be |
---|
1170 | # aware that the last one defined will apply to all that follows. |
---|
1171 | |
---|
1172 | #mix_rto = fv['mix_rto'].get_value()[0] |
---|
1173 | mix_rto = fv['mix_rto'].get_value()[0,:,lat_cheat_idx:,:-lon_cheat_idx] |
---|
1174 | spec_hum = n.zeros(mix_rto.shape,dtype=float) |
---|
1175 | spec_hum = mix_rto / (mix_rto + 1) |
---|
1176 | #temp = fv['air_temp'].get_value()[0] |
---|
1177 | temp = fv['air_temp'].get_value()[0,:,lat_cheat_idx:,:-lon_cheat_idx] |
---|
1178 | #print temp.min(), temp.max() |
---|
1179 | #print temp.min()-273.16, temp.max()-273.16 |
---|
1180 | sat_vapour_pres = goff_gratch(temp) |
---|
1181 | #print sat_vapour_pres.min(), sat_vapour_pres.max() |
---|
1182 | pres = fv['lvl'].get_value() |
---|
1183 | sat_spec_hum = n.zeros(mix_rto.shape,dtype=float) |
---|
1184 | for lvl_idx in range(len(pres)): |
---|
1185 | sat_spec_hum[lvl_idx] = 0.622 * sat_vapour_pres[lvl_idx] \ |
---|
1186 | / pres[lvl_idx] |
---|
1187 | #sat_spec_hum = ma.masked_where(sat_spec_hum <= 1.e-9, |
---|
1188 | #sat_spec_hum = ma.masked_where(sat_spec_hum <= 1.e-6, |
---|
1189 | #sat_spec_hum) |
---|
1190 | rh = n.zeros(mix_rto.shape,dtype=float) |
---|
1191 | rh = spec_hum / sat_spec_hum * 100 |
---|
1192 | #sys.exit() |
---|
1193 | del mix_rto, spec_hum, temp, sat_vapour_pres, pres, sat_spec_hum |
---|
1194 | |
---|
1195 | #cheat = rh |
---|
1196 | #field = n.zeros(cheat.shape) |
---|
1197 | #for lat_idx in range(cheat.shape[0]): |
---|
1198 | # field[-(lat_idx+1)] = cheat[lat_idx] |
---|
1199 | |
---|
1200 | cheat = rh |
---|
1201 | field = n.zeros(cheat.shape) |
---|
1202 | for lvl_idx in range(cheat.shape[0]): |
---|
1203 | for lat_idx in range(cheat.shape[1]): |
---|
1204 | field[lvl_idx,-(lat_idx+1)] = cheat[lvl_idx,lat_idx] |
---|
1205 | |
---|
1206 | dummy['rh'] = { |
---|
1207 | 'long_name' : '3D relative humidity', |
---|
1208 | 'pdtnum' : pdtnum, |
---|
1209 | 'pdtmpl' : pdtmpl, |
---|
1210 | 'drtnum' : drtnum, |
---|
1211 | 'drtmpl' : drtmpl, |
---|
1212 | #'field' : rh.filled(fill_value=0.), |
---|
1213 | #'field' : rh, |
---|
1214 | 'field' : field, |
---|
1215 | 'lvl' : fv['lvl'].get_value() |
---|
1216 | } |
---|
1217 | #sys.exit() |
---|
1218 | |
---|
1219 | # Let's prepare the 3d zonal wind data and metadata |
---|
1220 | # Product Definition Template Number (see Code Table 4.0) |
---|
1221 | # 0 -> Analysis or forecast at a horizontal level or in a |
---|
1222 | # horizontal layer at a point in time. (see Template 4.0) |
---|
1223 | pdtnum = 0 |
---|
1224 | # array of zeros (int) of size 15 |
---|
1225 | pdtmpl = n.zeros((15,),dtype=int) |
---|
1226 | # Follows the definition of template 4.0 |
---|
1227 | # Oct 10: Parameter category (see Code table 4.1). 2 -> momentum |
---|
1228 | pdtmpl[0] = 2 |
---|
1229 | # Oct 11: Parameter number (see Code table 4.2). 2 -> u-component of the |
---|
1230 | # wind |
---|
1231 | pdtmpl[1] = 2 |
---|
1232 | # Oct 12: Type of generating process (see Code table 4.3). 2 -> forecast |
---|
1233 | pdtmpl[2] = 2 |
---|
1234 | # Oct 13: Background generating process identifier |
---|
1235 | # (defined by originating centre) |
---|
1236 | pdtmpl[3] = missing(1) |
---|
1237 | # Oct 14: Analysis or forecast generating process identified |
---|
1238 | # (defined by originating centre) |
---|
1239 | pdtmpl[4] = missing(1) |
---|
1240 | # Oct 15-16: Hours of observational data cutoff after reference time |
---|
1241 | pdtmpl[5] = missing(2) |
---|
1242 | # Oct 17: Minutes of observational data cutoff after reference time |
---|
1243 | pdtmpl[6] = missing(1) |
---|
1244 | # Oct 18: Indicator of unit of time range (see Code table 4.4) |
---|
1245 | # 1 -> hours |
---|
1246 | # NB WPS expects this to be hours! |
---|
1247 | pdtmpl[7] = 1 |
---|
1248 | # Oct 19-22: Forecast time in units defined by octet 18 |
---|
1249 | pdtmpl[8] = fv['forc_hrs'].get_value()[0] |
---|
1250 | # Oct 23: Type of first fixed surface (see Code table 4.5) |
---|
1251 | # 1 -> isobaric level |
---|
1252 | pdtmpl[9] = 100 |
---|
1253 | # Oct 24: Scale factor of first fixed surface |
---|
1254 | pdtmpl[10] = 0 |
---|
1255 | # Oct 25-28: Scaled value of first fixed surface |
---|
1256 | # -> missing as there is will be defined later when the data is sliced in |
---|
1257 | # horizontal slabs for its encoding |
---|
1258 | pdtmpl[11] = missing(3) |
---|
1259 | # Oct 29: Type of second fixed surface (see Code table 4.5) |
---|
1260 | pdtmpl[12] = missing(1) |
---|
1261 | # Oct 30: Scale factor of second fixed surface |
---|
1262 | pdtmpl[13] = missing(1) |
---|
1263 | # Oct 31-34: Scaled value of second fixed surfaces |
---|
1264 | pdtmpl[14] = missing(3) |
---|
1265 | |
---|
1266 | # NB I am using the same drtnum and drtmpl for all data so I want |
---|
1267 | # replicate it in the following fields if you need to change this on a |
---|
1268 | # per-variable basis this is the place to redefine it. If you choose to do |
---|
1269 | # so then make sure you define one for each variable that follows or be |
---|
1270 | # aware that the last one defined will apply to all that follows. |
---|
1271 | |
---|
1272 | cheat = fv['zonal_wnd'].get_value()[0,:,lat_cheat_idx:,:-lon_cheat_idx] |
---|
1273 | field = n.zeros(cheat.shape) |
---|
1274 | for lvl_idx in range(cheat.shape[0]): |
---|
1275 | for lat_idx in range(cheat.shape[1]): |
---|
1276 | field[lvl_idx,-(lat_idx+1)] = cheat[lvl_idx,lat_idx] |
---|
1277 | |
---|
1278 | dummy['zonal_wnd'] = { |
---|
1279 | 'long_name' : '3D zonal wind', |
---|
1280 | 'pdtnum' : pdtnum, |
---|
1281 | 'pdtmpl' : pdtmpl, |
---|
1282 | 'drtnum' : drtnum, |
---|
1283 | 'drtmpl' : drtmpl, |
---|
1284 | #'field' : fv['zonal_wnd'].get_value()[0], |
---|
1285 | #'field' : fv['zonal_wnd'].get_value()[0,:,lat_cheat_idx:,:-lon_cheat_idx], |
---|
1286 | 'field' : field, |
---|
1287 | #'field' : '', |
---|
1288 | 'lvl' : fv['lvl'].get_value() |
---|
1289 | } |
---|
1290 | |
---|
1291 | # Let's prepare the 3d zonal wind data and metadata |
---|
1292 | # Product Definition Template Number (see Code Table 4.0) |
---|
1293 | # 0 -> Analysis or forecast at a horizontal level or in a |
---|
1294 | # horizontal layer at a point in time. (see Template 4.0) |
---|
1295 | pdtnum = 0 |
---|
1296 | # array of zeros (int) of size 15 |
---|
1297 | pdtmpl = n.zeros((15,),dtype=int) |
---|
1298 | # Follows the definition of template 4.0 |
---|
1299 | # Oct 10: Parameter category (see Code table 4.1). 2 -> momentum |
---|
1300 | pdtmpl[0] = 2 |
---|
1301 | # Oct 11: Parameter number (see Code table 4.2). 2 -> v-component of the |
---|
1302 | # wind |
---|
1303 | pdtmpl[1] = 3 |
---|
1304 | # Oct 12: Type of generating process (see Code table 4.3). 2 -> forecast |
---|
1305 | pdtmpl[2] = 2 |
---|
1306 | # Oct 13: Background generating process identifier |
---|
1307 | # (defined by originating centre) |
---|
1308 | pdtmpl[3] = missing(1) |
---|
1309 | # Oct 14: Analysis or forecast generating process identified |
---|
1310 | # (defined by originating centre) |
---|
1311 | pdtmpl[4] = missing(1) |
---|
1312 | # Oct 15-16: Hours of observational data cutoff after reference time |
---|
1313 | pdtmpl[5] = missing(2) |
---|
1314 | # Oct 17: Minutes of observational data cutoff after reference time |
---|
1315 | pdtmpl[6] = missing(1) |
---|
1316 | # Oct 18: Indicator of unit of time range (see Code table 4.4) |
---|
1317 | # 1 -> hours |
---|
1318 | # NB WPS expects this to be hours! |
---|
1319 | pdtmpl[7] = 1 |
---|
1320 | # Oct 19-22: Forecast time in units defined by octet 18 |
---|
1321 | pdtmpl[8] = fv['forc_hrs'].get_value()[0] |
---|
1322 | # Oct 23: Type of first fixed surface (see Code table 4.5) |
---|
1323 | # 1 -> isobaric level |
---|
1324 | pdtmpl[9] = 100 |
---|
1325 | # Oct 24: Scale factor of first fixed surface |
---|
1326 | pdtmpl[10] = 0 |
---|
1327 | # Oct 25-28: Scaled value of first fixed surface |
---|
1328 | # -> missing as there is will be defined later when the data is sliced in |
---|
1329 | # horizontal slabs for its encoding |
---|
1330 | pdtmpl[11] = missing(3) |
---|
1331 | # Oct 29: Type of second fixed surface (see Code table 4.5) |
---|
1332 | pdtmpl[12] = missing(1) |
---|
1333 | # Oct 30: Scale factor of second fixed surface |
---|
1334 | pdtmpl[13] = missing(1) |
---|
1335 | # Oct 31-34: Scaled value of second fixed surfaces |
---|
1336 | pdtmpl[14] = missing(3) |
---|
1337 | |
---|
1338 | # NB I am using the same drtnum and drtmpl for all data so I want |
---|
1339 | # replicate it in the following fields if you need to change this on a |
---|
1340 | # per-variable basis this is the place to redefine it. If you choose to do |
---|
1341 | # so then make sure you define one for each variable that follows or be |
---|
1342 | # aware that the last one defined will apply to all that follows. |
---|
1343 | |
---|
1344 | cheat =fv['merid_wnd'].get_value()[0,:,lat_cheat_idx:,:-lon_cheat_idx] |
---|
1345 | field = n.zeros(cheat.shape) |
---|
1346 | for lvl_idx in range(cheat.shape[0]): |
---|
1347 | for lat_idx in range(cheat.shape[1]): |
---|
1348 | field[lvl_idx,-(lat_idx+1)] = cheat[lvl_idx,lat_idx] |
---|
1349 | |
---|
1350 | dummy['merid_wnd'] = { |
---|
1351 | 'long_name' : '3D meridional wind', |
---|
1352 | 'pdtnum' : pdtnum, |
---|
1353 | 'pdtmpl' : pdtmpl, |
---|
1354 | 'drtnum' : drtnum, |
---|
1355 | 'drtmpl' : drtmpl, |
---|
1356 | #'field' : fv['merid_wnd'].get_value()[0], |
---|
1357 | #'field' : fv['merid_wnd'].get_value()[0,:,lat_cheat_idx:,:-lon_cheat_idx], |
---|
1358 | 'field' : field, |
---|
1359 | #'field' : '', |
---|
1360 | 'lvl' : fv['lvl'].get_value() |
---|
1361 | } |
---|
1362 | |
---|
1363 | # Let's prepare the 3d geopotential height data and metadata |
---|
1364 | # Product Definition Template Number (see Code Table 4.0) |
---|
1365 | # 0 -> Analysis or forecast at a horizontal level or in a |
---|
1366 | # horizontal layer at a point in time. (see Template 4.0) |
---|
1367 | pdtnum = 0 |
---|
1368 | # array of zeros (int) of size 15 |
---|
1369 | pdtmpl = n.zeros((15,),dtype=int) |
---|
1370 | # Follows the definition of template 4.0 |
---|
1371 | # Oct 10: Parameter category (see Code table 4.1). 3 -> mass |
---|
1372 | pdtmpl[0] = 3 |
---|
1373 | # Oct 11: Parameter number (see Code table 4.2). 5 -> geopotential height |
---|
1374 | pdtmpl[1] = 5 |
---|
1375 | # Oct 12: Type of generating process (see Code table 4.3). 2 -> forecast |
---|
1376 | pdtmpl[2] = 2 |
---|
1377 | # Oct 13: Background generating process identifier |
---|
1378 | # (defined by originating centre) |
---|
1379 | pdtmpl[3] = missing(1) |
---|
1380 | # Oct 14: Analysis or forecast generating process identified |
---|
1381 | # (defined by originating centre) |
---|
1382 | pdtmpl[4] = missing(1) |
---|
1383 | # Oct 15-16: Hours of observational data cutoff after reference time |
---|
1384 | pdtmpl[5] = missing(2) |
---|
1385 | # Oct 17: Minutes of observational data cutoff after reference time |
---|
1386 | pdtmpl[6] = missing(1) |
---|
1387 | # Oct 18: Indicator of unit of time range (see Code table 4.4) |
---|
1388 | # 1 -> hours |
---|
1389 | # NB WPS expects this to be hours! |
---|
1390 | pdtmpl[7] = 1 |
---|
1391 | # Oct 19-22: Forecast time in units defined by octet 18 |
---|
1392 | pdtmpl[8] = fv['forc_hrs'].get_value()[0] |
---|
1393 | # Oct 23: Type of first fixed surface (see Code table 4.5) |
---|
1394 | # 1 -> isobaric level |
---|
1395 | pdtmpl[9] = 100 |
---|
1396 | # Oct 24: Scale factor of first fixed surface |
---|
1397 | pdtmpl[10] = 0 |
---|
1398 | # Oct 25-28: Scaled value of first fixed surface |
---|
1399 | # -> missing as there is will be defined later when the data is sliced in |
---|
1400 | # horizontal slabs for its encoding |
---|
1401 | pdtmpl[11] = missing(3) |
---|
1402 | # Oct 29: Type of second fixed surface (see Code table 4.5) |
---|
1403 | pdtmpl[12] = missing(1) |
---|
1404 | # Oct 30: Scale factor of second fixed surface |
---|
1405 | pdtmpl[13] = missing(1) |
---|
1406 | # Oct 31-34: Scaled value of second fixed surfaces |
---|
1407 | pdtmpl[14] = missing(3) |
---|
1408 | |
---|
1409 | # NB I am using the same drtnum and drtmpl for all data so I want |
---|
1410 | # replicate it in the following fields if you need to change this on a |
---|
1411 | # per-variable basis this is the place to redefine it. If you choose to do |
---|
1412 | # so then make sure you define one for each variable that follows or be |
---|
1413 | # aware that the last one defined will apply to all that follows. |
---|
1414 | |
---|
1415 | cheat = fv['geop_ht'].get_value()[0,:,lat_cheat_idx:,:-lon_cheat_idx] |
---|
1416 | field = n.zeros(cheat.shape) |
---|
1417 | for lvl_idx in range(cheat.shape[0]): |
---|
1418 | for lat_idx in range(cheat.shape[1]): |
---|
1419 | field[lvl_idx,-(lat_idx+1)] = cheat[lvl_idx,lat_idx] |
---|
1420 | |
---|
1421 | dummy['geop_ht'] = { |
---|
1422 | 'long_name' : 'geopotential height', |
---|
1423 | 'pdtnum' : pdtnum, |
---|
1424 | 'pdtmpl' : pdtmpl, |
---|
1425 | 'drtnum' : drtnum, |
---|
1426 | 'drtmpl' : drtmpl, |
---|
1427 | #'field' : fv['geop_ht'].get_value()[0], |
---|
1428 | #'field' : fv['geop_ht'].get_value()[0,:,lat_cheat_idx:,:-lon_cheat_idx], |
---|
1429 | 'field' : field, |
---|
1430 | #'field' : '', |
---|
1431 | 'lvl' : fv['lvl'].get_value() |
---|
1432 | } |
---|
1433 | |
---|
1434 | ####################################################################### |
---|
1435 | # Finished with the atmospheric discipline |
---|
1436 | # Let's move on to the oceanographic one |
---|
1437 | ####################################################################### |
---|
1438 | |
---|
1439 | if 0: |
---|
1440 | # Preliminaries: we need to unpack the land_sea_ice mask from the laps |
---|
1441 | # files. |
---|
1442 | #sea_lnd_ice_mask = fv['sea_lnd_ice_mask'].get_value()[0] |
---|
1443 | sea_lnd_ice_mask = fv['sea_lnd_ice_mask'].get_value()[0,lat_cheat_idx:,:-lon_cheat_idx] |
---|
1444 | shape = sea_lnd_ice_mask.shape |
---|
1445 | land_cover = n.zeros(shape, 'i') |
---|
1446 | ice_cover = n.zeros(shape, 'i') |
---|
1447 | # I assume (know) that the mask has 3 dimensions of which the first is time |
---|
1448 | # which I am going to ignore for now |
---|
1449 | # I am sure this could be done more elegantly with a numpy in-built |
---|
1450 | # function, but I am not sure about which one would it be |
---|
1451 | for i in range(shape[0]): |
---|
1452 | for j in range(shape[1]): |
---|
1453 | if sea_lnd_ice_mask[i,j] == 0: |
---|
1454 | land_cover[i,j] = 0 |
---|
1455 | ice_cover[i,j] = 0 |
---|
1456 | elif sea_lnd_ice_mask[i,j] == 1: |
---|
1457 | land_cover[i,j] = 1 |
---|
1458 | ice_cover[i,j] = 0 |
---|
1459 | elif sea_lnd_ice_mask[i,j] == 2: |
---|
1460 | # the BoM only considers ice over water |
---|
1461 | land_cover[i,j] = 0 |
---|
1462 | ice_cover[i,j] = 1 |
---|
1463 | else: |
---|
1464 | print 'Illegal value in the sea_land_ice mask!' |
---|
1465 | sys.exit() |
---|
1466 | |
---|
1467 | dummy = data[-1]['discipline']['ocean']['fields']['2d'] |
---|
1468 | |
---|
1469 | # Let's prepare the ice cover data and metadata |
---|
1470 | # Product Definition Template Number (see Code Table 4.0) |
---|
1471 | # 0 -> Analysis or forecast at a horizontal level or in a |
---|
1472 | # horizontal layer at a point in time. (see Template 4.0) |
---|
1473 | pdtnum = 0 |
---|
1474 | # array of zeros (int) of size 15 |
---|
1475 | pdtmpl = n.zeros((15,),dtype=int) |
---|
1476 | # Follows the definition of template 4.0 |
---|
1477 | # Oct 10: Parameter category (see Code table 4.1). 2 -> ice |
---|
1478 | pdtmpl[0] = 2 |
---|
1479 | # Oct 11: Parameter number (see Code table 4.2). 0 -> ice-cover |
---|
1480 | # 1=ice, 0=no-ice (over water) |
---|
1481 | pdtmpl[1] = 0 |
---|
1482 | # Oct 12: Type of generating process (see Code table 4.3). 2 -> forecast |
---|
1483 | pdtmpl[2] = 2 |
---|
1484 | # Oct 13: Background generating process identifier |
---|
1485 | # (defined by originating centre) |
---|
1486 | pdtmpl[3] = missing(1) |
---|
1487 | # Oct 14: Analysis or forecast generating process identified |
---|
1488 | # (defined by originating centre) |
---|
1489 | pdtmpl[4] = missing(1) |
---|
1490 | # Oct 15-16: Hours of observational data cutoff after reference time |
---|
1491 | pdtmpl[5] = missing(2) |
---|
1492 | # Oct 17: Minutes of observational data cutoff after reference time |
---|
1493 | pdtmpl[6] = missing(1) |
---|
1494 | # Oct 18: Indicator of unit of time range (see Code table 4.4) |
---|
1495 | # 1 -> hours |
---|
1496 | # NB WPS expects this to be hours! |
---|
1497 | pdtmpl[7] = 1 |
---|
1498 | # Oct 19-22: Forecast time in units defined by octet 18 |
---|
1499 | pdtmpl[8] = fv['forc_hrs'].get_value()[0] |
---|
1500 | # Oct 23: Type of first fixed surface (see Code table 4.5) |
---|
1501 | # 1 -> surface |
---|
1502 | pdtmpl[9] = 1 |
---|
1503 | # Oct 24: Scale factor of first fixed surface |
---|
1504 | pdtmpl[10] = 0 |
---|
1505 | # Oct 25-28: Scaled value of first fixed surface |
---|
1506 | pdtmpl[11] = 0 |
---|
1507 | # Oct 29: Type of second fixed surface (see Code table 4.5) |
---|
1508 | pdtmpl[12] = missing(1) |
---|
1509 | # Oct 30: Scale factor of second fixed surface |
---|
1510 | pdtmpl[13] = missing(1) |
---|
1511 | # Oct 31-34: Scaled value of second fixed surfaces |
---|
1512 | pdtmpl[14] = missing(3) |
---|
1513 | |
---|
1514 | # NB I am using the same drtnum and drtmpl for all data so I want |
---|
1515 | # replicate it in the following fields if you need to change this on a |
---|
1516 | # per-variable basis this is the place to redefine it. If you choose to do |
---|
1517 | # so then make sure you define one for each variable that follows or be |
---|
1518 | # aware that the last one defined will apply to all that follows. |
---|
1519 | |
---|
1520 | cheat = ice_cover |
---|
1521 | field = n.zeros(cheat.shape) |
---|
1522 | for lat_idx in range(cheat.shape[0]): |
---|
1523 | field[-(lat_idx+1)] = cheat[lat_idx] |
---|
1524 | |
---|
1525 | dummy['ice_cover'] = { |
---|
1526 | 'long_name' : 'ice cover', |
---|
1527 | 'pdtnum' : pdtnum, |
---|
1528 | 'pdtmpl' : pdtmpl, |
---|
1529 | 'drtnum' : drtnum, |
---|
1530 | 'drtmpl' : drtmpl, |
---|
1531 | #'field' : ice_cover |
---|
1532 | 'field' : field |
---|
1533 | } |
---|
1534 | |
---|
1535 | ####################################################################### |
---|
1536 | # Finished with the oceanographic discipline |
---|
1537 | # Let's move on to the land one |
---|
1538 | ####################################################################### |
---|
1539 | |
---|
1540 | dummy = data[-1]['discipline']['land']['fields']['2d'] |
---|
1541 | |
---|
1542 | if 0: |
---|
1543 | # Let's prepare the land cover data and metadata |
---|
1544 | # Product Definition Template Number (see Code Table 4.0) |
---|
1545 | # 0 -> Analysis or forecast at a horizontal level or in a |
---|
1546 | # horizontal layer at a point in time. (see Template 4.0) |
---|
1547 | pdtnum = 0 |
---|
1548 | # array of zeros (int) of size 15 |
---|
1549 | pdtmpl = n.zeros((15,),dtype=int) |
---|
1550 | # Follows the definition of template 4.0 |
---|
1551 | # Oct 10: Parameter category (see Code table 4.1). 0 -> vegetation/biomass |
---|
1552 | pdtmpl[0] = 0 |
---|
1553 | # Oct 11: Parameter number (see Code table 4.2). 0 -> land-cover |
---|
1554 | # (1=land, 0=ocean) |
---|
1555 | pdtmpl[1] = 0 |
---|
1556 | # Oct 12: Type of generating process (see Code table 4.3). 2 -> forecast |
---|
1557 | pdtmpl[2] = 2 |
---|
1558 | # Oct 13: Background generating process identifier |
---|
1559 | # (defined by originating centre) |
---|
1560 | pdtmpl[3] = missing(1) |
---|
1561 | # Oct 14: Analysis or forecast generating process identified |
---|
1562 | # (defined by originating centre) |
---|
1563 | pdtmpl[4] = missing(1) |
---|
1564 | # Oct 15-16: Hours of observational data cutoff after reference time |
---|
1565 | pdtmpl[5] = missing(2) |
---|
1566 | # Oct 17: Minutes of observational data cutoff after reference time |
---|
1567 | pdtmpl[6] = missing(1) |
---|
1568 | # Oct 18: Indicator of unit of time range (see Code table 4.4) |
---|
1569 | # 1 -> hours |
---|
1570 | # NB WPS expects this to be hours! |
---|
1571 | pdtmpl[7] = 1 |
---|
1572 | # Oct 19-22: Forecast time in units defined by octet 18 |
---|
1573 | pdtmpl[8] = fv['forc_hrs'].get_value()[0] |
---|
1574 | # Oct 23: Type of first fixed surface (see Code table 4.5) |
---|
1575 | # 1 -> surface |
---|
1576 | pdtmpl[9] = 1 |
---|
1577 | # Oct 24: Scale factor of first fixed surface |
---|
1578 | pdtmpl[10] = 0 |
---|
1579 | # Oct 25-28: Scaled value of first fixed surface |
---|
1580 | pdtmpl[11] = 0 |
---|
1581 | # Oct 29: Type of second fixed surface (see Code table 4.5) |
---|
1582 | pdtmpl[12] = missing(1) |
---|
1583 | # Oct 30: Scale factor of second fixed surface |
---|
1584 | pdtmpl[13] = missing(1) |
---|
1585 | # Oct 31-34: Scaled value of second fixed surfaces |
---|
1586 | pdtmpl[14] = missing(3) |
---|
1587 | |
---|
1588 | # NB I am using the same drtnum and drtmpl for all data so I want |
---|
1589 | # replicate it in the following fields if you need to change this on a |
---|
1590 | # per-variable basis this is the place to redefine it. If you choose to do |
---|
1591 | # so then make sure you define one for each variable that follows or be |
---|
1592 | # aware that the last one defined will apply to all that follows. |
---|
1593 | |
---|
1594 | # I seem to remember there was a problem with the land cover that I could |
---|
1595 | # fix using the decimal scale factor... let's try |
---|
1596 | land_cover_decimal_factor = 1 |
---|
1597 | # Oct: 18-19. Decimal scale factor (D) |
---|
1598 | #drtmpl[2] = land_cover_decimal_factor |
---|
1599 | #print 'land_cover drtmpl', drtmpl |
---|
1600 | |
---|
1601 | cheat = land_cover * 10**land_cover_decimal_factor |
---|
1602 | field = n.zeros(cheat.shape) |
---|
1603 | for lat_idx in range(cheat.shape[0]): |
---|
1604 | field[-(lat_idx+1)] = cheat[lat_idx] |
---|
1605 | |
---|
1606 | dummy['land_cover'] = { |
---|
1607 | 'long_name' : 'land cover', |
---|
1608 | 'pdtnum' : pdtnum, |
---|
1609 | 'pdtmpl' : pdtmpl, |
---|
1610 | 'drtnum' : drtnum, |
---|
1611 | 'drtmpl' : n.array([0,0,land_cover_decimal_factor,24,0]), |
---|
1612 | #'drtmpl' : drtmpl, |
---|
1613 | #'field' : land_cover * 10**land_cover_decimal_factor |
---|
1614 | 'field' : field |
---|
1615 | } |
---|
1616 | |
---|
1617 | # Now put it back to what it was |
---|
1618 | # Oct: 18-19. Decimal scale factor (D) |
---|
1619 | #drtmpl[2] = 0 |
---|
1620 | |
---|
1621 | if 1: |
---|
1622 | # Let's prepare the topography data and metadata |
---|
1623 | # Product Definition Template Number (see Code Table 4.0) |
---|
1624 | # 0 -> Analysis or forecast at a horizontal level or in a |
---|
1625 | # horizontal layer at a point in time. (see Template 4.0) |
---|
1626 | pdtnum = 0 |
---|
1627 | # array of zeros (int) of size 15 |
---|
1628 | pdtmpl = n.zeros((15,),dtype=int) |
---|
1629 | # Follows the definition of template 4.0 |
---|
1630 | # Oct 10: Parameter category (see Code table 4.1). 0 -> vegetation/biomass |
---|
1631 | pdtmpl[0] = 0 |
---|
1632 | # Oct 11: Parameter number (see Code table 4.2). 7 -> model terrain height |
---|
1633 | pdtmpl[1] = 7 |
---|
1634 | # Oct 12: Type of generating process (see Code table 4.3). 2 -> forecast |
---|
1635 | pdtmpl[2] = 2 |
---|
1636 | # Oct 13: Background generating process identifier |
---|
1637 | # (defined by originating centre) |
---|
1638 | pdtmpl[3] = missing(1) |
---|
1639 | # Oct 14: Analysis or forecast generating process identified |
---|
1640 | # (defined by originating centre) |
---|
1641 | pdtmpl[4] = missing(1) |
---|
1642 | # Oct 15-16: Hours of observational data cutoff after reference time |
---|
1643 | pdtmpl[5] = missing(2) |
---|
1644 | # Oct 17: Minutes of observational data cutoff after reference time |
---|
1645 | pdtmpl[6] = missing(1) |
---|
1646 | # Oct 18: Indicator of unit of time range (see Code table 4.4) |
---|
1647 | # 1 -> hours |
---|
1648 | # NB WPS expects this to be hours! |
---|
1649 | pdtmpl[7] = 1 |
---|
1650 | # Oct 19-22: Forecast time in units defined by octet 18 |
---|
1651 | pdtmpl[8] = fv['forc_hrs'].get_value()[0] |
---|
1652 | # Oct 23: Type of first fixed surface (see Code table 4.5) |
---|
1653 | # 1 -> surface |
---|
1654 | pdtmpl[9] = 1 |
---|
1655 | # Oct 24: Scale factor of first fixed surface |
---|
1656 | pdtmpl[10] = 0 |
---|
1657 | # Oct 25-28: Scaled value of first fixed surface |
---|
1658 | pdtmpl[11] = 0 |
---|
1659 | # Oct 29: Type of second fixed surface (see Code table 4.5) |
---|
1660 | pdtmpl[12] = missing(1) |
---|
1661 | # Oct 30: Scale factor of second fixed surface |
---|
1662 | pdtmpl[13] = missing(1) |
---|
1663 | # Oct 31-34: Scaled value of second fixed surfaces |
---|
1664 | pdtmpl[14] = missing(3) |
---|
1665 | |
---|
1666 | # NB I am using the same drtnum and drtmpl for all data so I want |
---|
1667 | # replicate it in the following fields if you need to change this on a |
---|
1668 | # per-variable basis this is the place to redefine it. If you choose to do |
---|
1669 | # so then make sure you define one for each variable that follows or be |
---|
1670 | # aware that the last one defined will apply to all that follows. |
---|
1671 | cheat = fv['topog'].get_value()[lat_cheat_idx:,:-lon_cheat_idx] |
---|
1672 | field = n.zeros(cheat.shape) |
---|
1673 | for lat_idx in range(cheat.shape[0]): |
---|
1674 | field[-(lat_idx+1)] = cheat[lat_idx] |
---|
1675 | |
---|
1676 | dummy['topog'] = { |
---|
1677 | 'long_name' : 'topography', |
---|
1678 | 'pdtnum' : pdtnum, |
---|
1679 | 'pdtmpl' : pdtmpl, |
---|
1680 | 'drtnum' : drtnum, |
---|
1681 | 'drtmpl' : drtmpl, |
---|
1682 | #'field' : fv['topog'].get_value() |
---|
1683 | #'field' : fv['topog'].get_value()[lat_cheat_idx:,:-lon_cheat_idx] |
---|
1684 | 'field' : field |
---|
1685 | } |
---|
1686 | |
---|
1687 | dummy = data[-1]['discipline']['land']['fields']['3d'] |
---|
1688 | |
---|
1689 | if 1: |
---|
1690 | # Let's prepare the 3d soil temperature data and metadata |
---|
1691 | # Product Definition Template Number (see Code Table 4.0) |
---|
1692 | # 0 -> Analysis or forecast at a horizontal level or in a |
---|
1693 | # horizontal layer at a point in time. (see Template 4.0) |
---|
1694 | pdtnum = 0 |
---|
1695 | # array of zeros (int) of size 15 |
---|
1696 | pdtmpl = n.zeros((15,),dtype=int) |
---|
1697 | # Follows the definition of template 4.0 |
---|
1698 | # Oct 10: Parameter category (see Code table 4.1). 0 -> vegetation/biomass |
---|
1699 | pdtmpl[0] = 0 |
---|
1700 | # Oct 11: Parameter number (see Code table 4.2). 2 -> soil temperature |
---|
1701 | pdtmpl[1] = 2 |
---|
1702 | # Oct 12: Type of generating process (see Code table 4.3). 2 -> forecast |
---|
1703 | pdtmpl[2] = 2 |
---|
1704 | # Oct 13: Background generating process identifier |
---|
1705 | # (defined by originating centre) |
---|
1706 | pdtmpl[3] = missing(1) |
---|
1707 | # Oct 14: Analysis or forecast generating process identified |
---|
1708 | # (defined by originating centre) |
---|
1709 | pdtmpl[4] = missing(1) |
---|
1710 | # Oct 15-16: Hours of observational data cutoff after reference time |
---|
1711 | pdtmpl[5] = missing(2) |
---|
1712 | # Oct 17: Minutes of observational data cutoff after reference time |
---|
1713 | pdtmpl[6] = missing(1) |
---|
1714 | # Oct 18: Indicator of unit of time range (see Code table 4.4) |
---|
1715 | # 1 -> hours |
---|
1716 | # NB WPS expects this to be hours! |
---|
1717 | pdtmpl[7] = 1 |
---|
1718 | # Oct 19-22: Forecast time in units defined by octet 18 |
---|
1719 | pdtmpl[8] = fv['forc_hrs'].get_value()[0] |
---|
1720 | # Oct 23: Type of first fixed surface (see Code table 4.5) |
---|
1721 | # 106 -> depth below land surface |
---|
1722 | pdtmpl[9] = 106 |
---|
1723 | # Oct 24: Scale factor of first fixed surface |
---|
1724 | # 3 -> preserve mm accuracy |
---|
1725 | # 2 -> preserve cm accuracy |
---|
1726 | soil_lvl_scaling = 2 |
---|
1727 | pdtmpl[10] = soil_lvl_scaling |
---|
1728 | # Oct 25-28: Scaled value of first fixed surface |
---|
1729 | # -> missing as there is will be defined later when the data is sliced in |
---|
1730 | # horizontal slabs for its encoding |
---|
1731 | pdtmpl[11] = missing(3) |
---|
1732 | # Oct 29: Type of second fixed surface (see Code table 4.5) |
---|
1733 | # 106 -> depth below land surface |
---|
1734 | pdtmpl[12] = 106 |
---|
1735 | # Oct 30: Scale factor of second fixed surface |
---|
1736 | # 3 -> preserve mm accuracy |
---|
1737 | pdtmpl[13] = soil_lvl_scaling |
---|
1738 | # Oct 31-34: Scaled value of second fixed surfaces |
---|
1739 | pdtmpl[14] = missing(3) |
---|
1740 | # -> missing as there is will be defined later when the data is sliced in |
---|
1741 | # horizontal slabs for its encoding |
---|
1742 | |
---|
1743 | # NB I am using the same drtnum and drtmpl for all data so I want |
---|
1744 | # replicate it in the following fields if you need to change this on a |
---|
1745 | # per-variable basis this is the place to redefine it. If you choose to do |
---|
1746 | # so then make sure you define one for each variable that follows or be |
---|
1747 | # aware that the last one defined will apply to all that follows. |
---|
1748 | |
---|
1749 | # Let's interpolate linearly to the Noah levels |
---|
1750 | # NB for the deepest level we actually have an extrapolation |
---|
1751 | laps_soil_lvl = fv['soil_lvl'].get_value() |
---|
1752 | noah_soil_lvl = [0.10, 0.40, 1.0, 2.0] |
---|
1753 | #laps_soil_temp = fv['soil_temp'].get_value()[0] |
---|
1754 | laps_soil_temp = fv['soil_temp'].get_value()[0,:,lat_cheat_idx:,:-lon_cheat_idx] |
---|
1755 | shape = laps_soil_temp.shape |
---|
1756 | noah_soil_temp = n.zeros(shape, dtype=float) |
---|
1757 | max_soil_lvl = 4 |
---|
1758 | for soil_idx in range(max_soil_lvl): |
---|
1759 | if soil_idx < max_soil_lvl - 1: |
---|
1760 | x_a = n.ones((shape[1],shape[2])) * laps_soil_lvl[soil_idx] |
---|
1761 | x_b = n.ones((shape[1],shape[2])) * laps_soil_lvl[soil_idx + 1] |
---|
1762 | y_a = laps_soil_temp[soil_idx] |
---|
1763 | y_b = laps_soil_temp[soil_idx + 1] |
---|
1764 | else: |
---|
1765 | # this accomplishes the extrapolation |
---|
1766 | x_a = n.ones((shape[1],shape[2])) * laps_soil_lvl[soil_idx - 1] |
---|
1767 | x_b = n.ones((shape[1],shape[2])) * laps_soil_lvl[soil_idx] |
---|
1768 | y_a = laps_soil_temp[soil_idx - 1] |
---|
1769 | y_b = laps_soil_temp[soil_idx] |
---|
1770 | #print x_a, '\n\n', x_b, '\n\n', y_a, '\n\n', y_b, '\n\n' |
---|
1771 | #print soil_idx, x_a.shape, x_b.shape, y_a.shape, y_b.shape |
---|
1772 | x = n.ones((shape[1],shape[2])) * noah_soil_lvl[soil_idx] |
---|
1773 | noah_soil_temp[soil_idx] = vu.lin_interp(x_a, x_b, y_a, y_b, x) |
---|
1774 | |
---|
1775 | |
---|
1776 | cheat = noah_soil_temp |
---|
1777 | field = n.zeros(cheat.shape) |
---|
1778 | for lvl_idx in range(cheat.shape[0]): |
---|
1779 | for lat_idx in range(cheat.shape[1]): |
---|
1780 | field[lvl_idx,-(lat_idx+1)] = cheat[lvl_idx,lat_idx] |
---|
1781 | |
---|
1782 | dummy['soil_temp'] = { |
---|
1783 | 'long_name' : '3D volumetric soil temperature', |
---|
1784 | 'pdtnum' : pdtnum, |
---|
1785 | 'pdtmpl' : pdtmpl, |
---|
1786 | 'drtnum' : drtnum, |
---|
1787 | 'drtmpl' : drtmpl, |
---|
1788 | #TODO: make sure the scaling is right |
---|
1789 | #'field' : noah_soil_temp, |
---|
1790 | 'field' : field, |
---|
1791 | 'lvl' : noah_soil_lvl |
---|
1792 | } |
---|
1793 | |
---|
1794 | |
---|
1795 | if 1: |
---|
1796 | # Let's prepare the 3d volumetric soil moisture |
---|
1797 | # Product Definition Template Number (see Code Table 4.0) |
---|
1798 | # 0 -> Analysis or forecast at a horizontal level or in a |
---|
1799 | # horizontal layer at a point in time. (see Template 4.0) |
---|
1800 | pdtnum = 0 |
---|
1801 | # array of zeros (int) of size 15 |
---|
1802 | pdtmpl = n.zeros((15,),dtype=int) |
---|
1803 | # Follows the definition of template 4.0 |
---|
1804 | # Oct 10: Parameter category (see Code table 4.1). 0 -> vegetation/biomass |
---|
1805 | pdtmpl[0] = 0 |
---|
1806 | # Oct 11: Parameter number (see Code table 4.2). 9 -> volumetric soil |
---|
1807 | # moisture |
---|
1808 | # pdtmpl[1] = 9 |
---|
1809 | # I don't like this choice but maybe it is going to work more easily with |
---|
1810 | # WRF and other NCAR utilities like cnvgrib |
---|
1811 | pdtmpl[1] = 192 |
---|
1812 | # Oct 12: Type of generating process (see Code table 4.3). 2 -> forecast |
---|
1813 | pdtmpl[2] = 2 |
---|
1814 | # Oct 13: Background generating process identifier |
---|
1815 | # (defined by originating centre) |
---|
1816 | pdtmpl[3] = missing(1) |
---|
1817 | # Oct 14: Analysis or forecast generating process identified |
---|
1818 | # (defined by originating centre) |
---|
1819 | pdtmpl[4] = missing(1) |
---|
1820 | # Oct 15-16: Hours of observational data cutoff after reference time |
---|
1821 | pdtmpl[5] = missing(2) |
---|
1822 | # Oct 17: Minutes of observational data cutoff after reference time |
---|
1823 | pdtmpl[6] = missing(1) |
---|
1824 | # Oct 18: Indicator of unit of time range (see Code table 4.4) |
---|
1825 | # 1 -> hours |
---|
1826 | # NB WPS expects this to be hours! |
---|
1827 | pdtmpl[7] = 1 |
---|
1828 | # Oct 19-22: Forecast time in units defined by octet 18 |
---|
1829 | pdtmpl[8] = fv['forc_hrs'].get_value()[0] |
---|
1830 | # Oct 23: Type of first fixed surface (see Code table 4.5) |
---|
1831 | # 106 -> depth below land surface |
---|
1832 | pdtmpl[9] = 106 |
---|
1833 | # Oct 24: Scale factor of first fixed surface |
---|
1834 | # 2 -> preserve cm accuracy |
---|
1835 | pdtmpl[10] = 2 |
---|
1836 | # Oct 25-28: Scaled value of first fixed surface |
---|
1837 | # -> missing as there is will be defined later when the data is sliced in |
---|
1838 | # horizontal slabs for its encoding |
---|
1839 | pdtmpl[11] = missing(3) |
---|
1840 | # Oct 29: Type of second fixed surface (see Code table 4.5) |
---|
1841 | # 106 -> depth below land surface |
---|
1842 | pdtmpl[12] = 106 |
---|
1843 | # Oct 30: Scale factor of second fixed surface |
---|
1844 | # 2 -> preserve cm accuracy |
---|
1845 | pdtmpl[13] = 2 |
---|
1846 | # Oct 31-34: Scaled value of second fixed surfaces |
---|
1847 | pdtmpl[14] = missing(3) |
---|
1848 | # -> missing as there is will be defined later when the data is sliced in |
---|
1849 | # horizontal slabs for its encoding |
---|
1850 | |
---|
1851 | # NB I am using the same drtnum and drtmpl for all data so I want |
---|
1852 | # replicate it in the following fields if you need to change this on a |
---|
1853 | # per-variable basis this is the place to redefine it. If you choose to do |
---|
1854 | # so then make sure you define one for each variable that follows or be |
---|
1855 | # aware that the last one defined will apply to all that follows. |
---|
1856 | |
---|
1857 | # in the ECMWF soil scheme the data is saved scaled by the depth of the |
---|
1858 | # soil layer (or so I understand...) |
---|
1859 | |
---|
1860 | # TODO work out this 'not writable' rubbish |
---|
1861 | #print laps_soil_mois.flags['WRITEABLE'] |
---|
1862 | #laps_soil_mois.flags['WRITEABLE'] = True |
---|
1863 | #laps_soil_mois = fv['soil_mois'].get_value()[0] |
---|
1864 | #laps_soil_mois = fv['soil_mois'].get_value()[0,:,lat_cheat_idx:,:-lon_cheat_idx] |
---|
1865 | tmp = fv['soil_mois'].get_value()[0,:,lat_cheat_idx:,:-lon_cheat_idx] |
---|
1866 | shape = tmp.shape |
---|
1867 | laps_soil_mois = n.zeros(shape) |
---|
1868 | laps_soil_lvl = fv['soil_lvl'].get_value() |
---|
1869 | for soil_idx in range(len(laps_soil_lvl)): |
---|
1870 | #laps_soil_mois[soil_idx] /= laps_soil_lvl[soil_idx] |
---|
1871 | laps_soil_mois[soil_idx] = tmp[soil_idx] / laps_soil_lvl[soil_idx] |
---|
1872 | |
---|
1873 | # Let's interpolate linearly to the Noah levels |
---|
1874 | # NB for the deepest level we actually have an extrapolation |
---|
1875 | noah_soil_lvl = [0.10, 0.40, 1.0, 2.0] |
---|
1876 | noah_soil_mois = n.zeros(laps_soil_mois.shape, dtype=float) |
---|
1877 | max_soil_lvl = 4 |
---|
1878 | for soil_idx in range(max_soil_lvl): |
---|
1879 | if soil_idx < max_soil_lvl - 1: |
---|
1880 | x_a = n.ones((shape[1],shape[2])) * laps_soil_lvl[soil_idx] |
---|
1881 | x_b = n.ones((shape[1],shape[2])) * laps_soil_lvl[soil_idx + 1] |
---|
1882 | y_a = laps_soil_mois[soil_idx] |
---|
1883 | y_b = laps_soil_mois[soil_idx + 1] |
---|
1884 | else: |
---|
1885 | # this accomplishes the extrapolation |
---|
1886 | x_a = n.ones((shape[1],shape[2])) * laps_soil_lvl[soil_idx - 1] |
---|
1887 | x_b = n.ones((shape[1],shape[2])) * laps_soil_lvl[soil_idx] |
---|
1888 | y_a = laps_soil_mois[soil_idx - 1] |
---|
1889 | y_b = laps_soil_mois[soil_idx] |
---|
1890 | x = n.ones((shape[1],shape[2])) * noah_soil_lvl[soil_idx] |
---|
1891 | noah_soil_mois[soil_idx] = vu.lin_interp(x_a, x_b, y_a, y_b, x) |
---|
1892 | |
---|
1893 | |
---|
1894 | cheat = noah_soil_mois |
---|
1895 | field = n.zeros(cheat.shape) |
---|
1896 | for lvl_idx in range(cheat.shape[0]): |
---|
1897 | for lat_idx in range(cheat.shape[1]): |
---|
1898 | field[lvl_idx,-(lat_idx+1)] = cheat[lvl_idx,lat_idx] |
---|
1899 | |
---|
1900 | dummy['soil_mois'] = { |
---|
1901 | 'long_name' : '3D volumetric soil moisture', |
---|
1902 | 'pdtnum' : pdtnum, |
---|
1903 | 'pdtmpl' : pdtmpl, |
---|
1904 | 'drtnum' : drtnum, |
---|
1905 | 'drtmpl' : drtmpl, |
---|
1906 | #TODO: make sure the scaling is right |
---|
1907 | #'field' : noah_soil_mois, |
---|
1908 | 'field' : field, |
---|
1909 | 'lvl' : noah_soil_lvl |
---|
1910 | } |
---|
1911 | |
---|
1912 | f.close() |
---|
1913 | sfc_f.close() |
---|
1914 | |
---|
1915 | #sys.exit() |
---|
1916 | #p.show() |
---|
1917 | |
---|
1918 | |
---|
1919 | |
---|
1920 | # Multiple times can be included in a grib files as sequential messages so the |
---|
1921 | # outermost 'dimension' of the data structure should be time |
---|
1922 | # As I am going to use the GFS grib files from ncep as a template for my own |
---|
1923 | # files, I will include only one time in each of the files. |
---|
1924 | # It should be easy to wrap to modify the following code to concatenate |
---|
1925 | # multiple times |
---|
1926 | |
---|
1927 | def do_the_encoding(data): |
---|
1928 | dummy_idx = 0 |
---|
1929 | for time_slice in data: |
---|
1930 | g2e = grib2.grib2.Grib2Encode( |
---|
1931 | time_slice['discipline']['atmos']['code'], |
---|
1932 | time_slice['idsect']) |
---|
1933 | g2e.addgrid(time_slice['gdsinfo'],time_slice['gdtmpl']) |
---|
1934 | dummy = time_slice['discipline']['atmos']['fields']['2d'] |
---|
1935 | for var_key in dummy.keys(): |
---|
1936 | print 'Processing ' + dummy[var_key]['long_name'] |
---|
1937 | g2e.addfield( |
---|
1938 | dummy[var_key]['pdtnum'], |
---|
1939 | dummy[var_key]['pdtmpl'], |
---|
1940 | dummy[var_key]['drtnum'], |
---|
1941 | dummy[var_key]['drtmpl'], |
---|
1942 | dummy[var_key]['field'] |
---|
1943 | ) |
---|
1944 | dummy = time_slice['discipline']['atmos']['fields']['3d'] |
---|
1945 | for var_key in dummy.keys(): |
---|
1946 | print 'Processing ' + dummy[var_key]['long_name'] |
---|
1947 | for lvl_idx in range(len(dummy[var_key]['lvl'])): |
---|
1948 | print '\tlevel ' + str(lvl_idx) |
---|
1949 | # '*100' because it must be in Pa |
---|
1950 | dummy[var_key]['pdtmpl'][11] = \ |
---|
1951 | dummy[var_key]['lvl'][lvl_idx]*100 |
---|
1952 | g2e.addfield( |
---|
1953 | dummy[var_key]['pdtnum'], |
---|
1954 | dummy[var_key]['pdtmpl'], |
---|
1955 | dummy[var_key]['drtnum'], |
---|
1956 | dummy[var_key]['drtmpl'], |
---|
1957 | dummy[var_key]['field'][lvl_idx] |
---|
1958 | ) |
---|
1959 | g2e.end() |
---|
1960 | file_name = 'laps_' + str(time_slice['idsect'][5]) + '_' \ |
---|
1961 | + str(zfill(time_slice['idsect'][6],2)) + '_' \ |
---|
1962 | + str(zfill(time_slice['idsect'][7],2)) + '_' \ |
---|
1963 | + str(zfill(time_slice['idsect'][8],2)) + 'Z_' \ |
---|
1964 | + str(zfill(dummy[var_key]['pdtmpl'][8],2)) + '_hrs_fcst.grb2' |
---|
1965 | #f = open('dummy' + str(dummy_idx) + '.grb2', 'w') |
---|
1966 | f = open(file_name, 'w') |
---|
1967 | f.write(g2e.msg) |
---|
1968 | f.close() |
---|
1969 | |
---|
1970 | g2e = grib2.grib2.Grib2Encode( |
---|
1971 | time_slice['discipline']['ocean']['code'], |
---|
1972 | time_slice['idsect']) |
---|
1973 | g2e.addgrid(time_slice['gdsinfo'],time_slice['gdtmpl']) |
---|
1974 | dummy = time_slice['discipline']['ocean']['fields']['2d'] |
---|
1975 | for var_key in dummy.keys(): |
---|
1976 | print 'Processing ' + dummy[var_key]['long_name'] |
---|
1977 | g2e.addfield( |
---|
1978 | dummy[var_key]['pdtnum'], |
---|
1979 | dummy[var_key]['pdtmpl'], |
---|
1980 | dummy[var_key]['drtnum'], |
---|
1981 | dummy[var_key]['drtmpl'], |
---|
1982 | dummy[var_key]['field'] |
---|
1983 | ) |
---|
1984 | if 0: |
---|
1985 | dummy = time_slice['discipline']['ocean']['fields']['3d'] |
---|
1986 | for var_key in dummy.keys(): |
---|
1987 | print 'Processing ' + dummy[var_key]['long_name'] |
---|
1988 | for lvl_idx in range(len(dummy[var_key]['lvl'])): |
---|
1989 | print '\tlevel ' + str(lvl_idx) |
---|
1990 | # '*100' because it must be in Pa |
---|
1991 | dummy[var_key]['pdtmpl'][11] = \ |
---|
1992 | dummy[var_key]['lvl'][lvl_idx]*100 |
---|
1993 | g2e.addfield( |
---|
1994 | dummy[var_key]['pdtnum'], |
---|
1995 | dummy[var_key]['pdtmpl'], |
---|
1996 | dummy[var_key]['drtnum'], |
---|
1997 | dummy[var_key]['drtmpl'], |
---|
1998 | dummy[var_key]['field'][lvl_idx] |
---|
1999 | ) |
---|
2000 | g2e.end() |
---|
2001 | #f = open('dummy' + str(dummy_idx) + '.grb2', 'a') |
---|
2002 | f = open(file_name, 'a') |
---|
2003 | f.write(g2e.msg) |
---|
2004 | f.close() |
---|
2005 | |
---|
2006 | g2e = grib2.grib2.Grib2Encode( |
---|
2007 | time_slice['discipline']['land']['code'], |
---|
2008 | time_slice['idsect']) |
---|
2009 | g2e.addgrid(time_slice['gdsinfo'],time_slice['gdtmpl']) |
---|
2010 | dummy = time_slice['discipline']['land']['fields']['2d'] |
---|
2011 | for var_key in dummy.keys(): |
---|
2012 | print 'Processing ' + dummy[var_key]['long_name'] |
---|
2013 | g2e.addfield( |
---|
2014 | dummy[var_key]['pdtnum'], |
---|
2015 | dummy[var_key]['pdtmpl'], |
---|
2016 | dummy[var_key]['drtnum'], |
---|
2017 | dummy[var_key]['drtmpl'], |
---|
2018 | dummy[var_key]['field'] |
---|
2019 | ) |
---|
2020 | dummy = time_slice['discipline']['land']['fields']['3d'] |
---|
2021 | for var_key in dummy.keys(): |
---|
2022 | print 'Processing ' + dummy[var_key]['long_name'] |
---|
2023 | for lvl_idx in range(len(dummy[var_key]['lvl'])): |
---|
2024 | print '\tlevel ' + str(lvl_idx) |
---|
2025 | if lvl_idx == 0: |
---|
2026 | dummy[var_key]['pdtmpl'][11] = 0 |
---|
2027 | else: |
---|
2028 | dummy[var_key]['pdtmpl'][11] = \ |
---|
2029 | round(dummy[var_key]['lvl'][lvl_idx-1]* 10**soil_lvl_scaling) |
---|
2030 | dummy[var_key]['pdtmpl'][14] = \ |
---|
2031 | round(dummy[var_key]['lvl'][lvl_idx]* 10**soil_lvl_scaling) |
---|
2032 | g2e.addfield( |
---|
2033 | dummy[var_key]['pdtnum'], |
---|
2034 | dummy[var_key]['pdtmpl'], |
---|
2035 | dummy[var_key]['drtnum'], |
---|
2036 | dummy[var_key]['drtmpl'], |
---|
2037 | dummy[var_key]['field'][lvl_idx] |
---|
2038 | ) |
---|
2039 | g2e.end() |
---|
2040 | #f = open('dummy' + str(dummy_idx) + '.grb2', 'a') |
---|
2041 | f = open(file_name, 'a') |
---|
2042 | f.write(g2e.msg) |
---|
2043 | f.close() |
---|
2044 | |
---|
2045 | #os.system('cnvgrib -g21 ' + file_name + ' ' + file_name[:-4] + 'grb') |
---|
2046 | #os.system('/Users/val/src/cnvgrib-1.1.3/cnvgrib -g21 ' + file_name + ' ' + file_name[:-4] + 'grb') |
---|
2047 | os.system('cnvgrib -g21 ' + file_name + ' ' + file_name[:-4] + 'grb') |
---|
2048 | os.system('rm ' + file_name) |
---|
2049 | |
---|
2050 | dummy_idx += 1 |
---|
2051 | |
---|