1 : /*****************************************************************************
2 : * metaname.c
3 : *
4 : * DESCRIPTION
5 : * This file contains the code necessary to parse the GRIB2 product
6 : * definition information into human readable text. In addition to the
7 : * tables in the GRIB2 specs, it also attempts to handle local table
8 : * definitions that NCEP and NDFD have developed.
9 : *
10 : * HISTORY
11 : * 1/2004 Arthur Taylor (MDL / RSIS): Created.
12 : *
13 : * NOTES
14 : *****************************************************************************
15 : */
16 : #include <string.h>
17 : #include <stdlib.h>
18 : #include "meta.h"
19 : #include "metaname.h"
20 : #include "myerror.h"
21 : #include "myassert.h"
22 : #include "myutil.h"
23 :
24 0 : const char *centerLookup (unsigned short int center)
25 : {
26 : /* see:
27 : * http://www.wmo.ch/web/www/WMOCodes/Operational/CommonTables/BUFRCommon-2005feb.pdf
28 : * http://www.wmo.int/web/www/WMOCodes/Operational/CommonTables/BUFRCommon-2005nov.pdf
29 : * also see:
30 : * http://www.nco.ncep.noaa.gov/pmb/docs/on388/table0.html
31 : * I typed this in on 11/2/2006 */
32 : /* *INDENT-OFF* */
33 : static struct {
34 : unsigned short int num;
35 : const char *name;
36 : } Center[] = {
37 : {0, "WMO Secretariat"},
38 : {1, "Melbourne"},
39 : {2, "Melbourne"},
40 : {3, ") Melbourne"},
41 : {4, "Moscow"},
42 : {5, "Moscow"},
43 : {6, ") Moscow"},
44 : {7, "US-NCEP"},
45 : {8, "US-NWSTG"},
46 : {9, "US-Other"},
47 : {10, "Cairo"},
48 : {11, ") Cairo"},
49 : {12, "Dakar"},
50 : {13, ") Dakar"},
51 : {14, "Nairobi"},
52 : {15, ") Nairobi"},
53 : {16, "Casablanca"},
54 : {17, "Tunis"},
55 : {18, "Tunis Casablanca"},
56 : {19, ") Tunis Casablanca"},
57 : {20, "Las Palmas"},
58 : {21, "Algiers"},
59 : {22, "ACMAD"},
60 : {23, "Mozambique"},
61 : {24, "Pretoria"},
62 : {25, "La Réunion"},
63 : {26, "Khabarovsk"},
64 : {27, ") Khabarovsk"},
65 : {28, "New Delhi"},
66 : {29, ") New Delhi"},
67 : {30, "Novosibirsk"},
68 : {31, ") Novosibirsk"},
69 : {32, "Tashkent"},
70 : {33, "Jeddah"},
71 : {34, "Tokyo"},
72 : {35, ") Tokyo"},
73 : {36, "Bangkok"},
74 : {37, "Ulan Bator"},
75 : {38, "Beijing"},
76 : {39, ") Beijing"},
77 : {40, "Seoul"},
78 : {41, "Buenos Aires"},
79 : {42, ") Buenos Aires"},
80 : {43, "Brasilia"},
81 : {44, ") Brasilia"},
82 : {45, "Santiago"},
83 : {46, "Brazilian Space Agency"},
84 : {47, "Colombia"},
85 : {48, "Ecuador"},
86 : {49, "Peru"},
87 : {50, "Venezuela"},
88 : {51, "Miami"},
89 : {52, "Miami-NHC"},
90 : {53, "Montreal"},
91 : {54, ") Montreal"},
92 : {55, "San Francisco"},
93 : {56, "ARINC Centre"},
94 : {57, "US-Air Force Weather"},
95 : {58, "US-Fleet Meteorology and Oceanography"},
96 : {59, "US-FSL"},
97 : {60, "US-NCAR"},
98 : {61, "US-Service ARGOS"},
99 : {62, "US-Naval Oceanographic Office"},
100 : /* {63, "Reserved for another centre in Region IV"},*/
101 : {64, "Honolulu"},
102 : {65, "Darwin"},
103 : {66, ") Darwin"},
104 : {67, "Melbourne"},
105 : /* {68, "Reserved"},*/
106 : {69, "Wellington"},
107 : {70, ") Wellington"},
108 : {71, "Nadi"},
109 : {72, "Singapore"},
110 : {73, "Malaysia"},
111 : {74, "UK-Met-Exeter"},
112 : {75, ") UK-Met-Exeter"},
113 : {76, "Moscow"},
114 : /* {77, "Reserved"},*/
115 : {78, "Offenbach"},
116 : {79, ") Offenbach"},
117 : {80, "Rome"},
118 : {81, ") Rome"},
119 : {82, "Norrköping"},
120 : {83, ") Norrköping"},
121 : {84, "Toulouse"},
122 : {85, "Toulouse"},
123 : {86, "Helsinki"},
124 : {87, "Belgrade"},
125 : {88, "Oslo"},
126 : {89, "Prague"},
127 : {90, "Episkopi"},
128 : {91, "Ankara"},
129 : {92, "Frankfurt/Main"},
130 : {93, "London"},
131 : {94, "Copenhagen"},
132 : {95, "Rota"},
133 : {96, "Athens"},
134 : {97, "ESA-European Space Agency"},
135 : {98, "ECMWF"},
136 : {99, "DeBilt"},
137 : {100, "Brazzaville"},
138 : {101, "Abidjan"},
139 : {102, "Libyan Arab Jamahiriya"},
140 : {103, "Madagascar"},
141 : {104, "Mauritius"},
142 : {105, "Niger"},
143 : {106, "Seychelles"},
144 : {107, "Uganda"},
145 : {108, "Tanzania"},
146 : {109, "Zimbabwe"},
147 : {110, "Hong-Kong, China"},
148 : {111, "Afghanistan"},
149 : {112, "Bahrain"},
150 : {113, "Bangladesh"},
151 : {114, "Bhutan"},
152 : {115, "Cambodia"},
153 : {116, "Democratic People's Republic of Korea"},
154 : {117, "Islamic Republic of Iran"},
155 : {118, "Iraq"},
156 : {119, "Kazakhstan"},
157 : {120, "Kuwait"},
158 : {121, "Kyrgyz Republic"},
159 : {122, "Lao People's Democratic Republic"},
160 : {123, "Macao, China"},
161 : {124, "Maldives"},
162 : {125, "Myanmar"},
163 : {126, "Nepal"},
164 : {127, "Oman"},
165 : {128, "Pakistan"},
166 : {129, "Qatar"},
167 : {130, "Republic of Yemen"},
168 : {131, "Sri Lanka"},
169 : {132, "Tajikistan"},
170 : {133, "Turkmenistan"},
171 : {134, "United Arab Emirates"},
172 : {135, "Uzbekistan"},
173 : {136, "Socialist Republic of Viet Nam"},
174 : /* {137, "Reserved"},*/
175 : /* {138, "Reserved"},*/
176 : /* {139, "Reserved"},*/
177 : {140, "Bolivia"},
178 : {141, "Guyana"},
179 : {142, "Paraguay"},
180 : {143, "Suriname"},
181 : {144, "Uruguay"},
182 : {145, "French Guyana"},
183 : {146, "Brazilian Navy Hydrographic Centre"},
184 : /* {147, "Reserved"},*/
185 : /* {148, "Reserved"},*/
186 : /* {149, "Reserved"},*/
187 : {150, "Antigua and Barbuda"},
188 : {151, "Bahamas"},
189 : {152, "Barbados"},
190 : {153, "Belize"},
191 : {154, "British Caribbean Territories"},
192 : {155, "San Jose"},
193 : {156, "Cuba"},
194 : {157, "Dominica"},
195 : {158, "Dominican Republic"},
196 : {159, "El Salvador"},
197 : {160, "US-NESDIS"},
198 : {161, "US-OAR"},
199 : {162, "Guatemala"},
200 : {163, "Haiti"},
201 : {164, "Honduras"},
202 : {165, "Jamaica"},
203 : {166, "Mexico"},
204 : {167, "Netherlands Antilles and Aruba"},
205 : {168, "Nicaragua"},
206 : {169, "Panama"},
207 : {170, "Saint Lucia NMC"},
208 : {171, "Trinidad and Tobago"},
209 : {172, "French Departments"},
210 : /* {173, "Reserved"},*/
211 : /* {174, "Reserved"},*/
212 : /* {175, "Reserved"},*/
213 : /* {176, "Reserved"},*/
214 : /* {177, "Reserved"},*/
215 : /* {178, "Reserved"},*/
216 : /* {179, "Reserved"},*/
217 : /* {180, "Reserved"},*/
218 : /* {181, "Reserved"},*/
219 : /* {182, "Reserved"},*/
220 : /* {183, "Reserved"},*/
221 : /* {184, "Reserved"},*/
222 : /* {185, "Reserved"},*/
223 : /* {186, "Reserved"},*/
224 : /* {187, "Reserved"},*/
225 : /* {188, "Reserved"},*/
226 : /* {189, "Reserved"},*/
227 : {190, "Cook Islands"},
228 : {191, "French Polynesia"},
229 : {192, "Tonga"},
230 : {193, "Vanuatu"},
231 : {194, "Brunei"},
232 : {195, "Indonesia"},
233 : {196, "Kiribati"},
234 : {197, "Federated States of Micronesia"},
235 : {198, "New Caledonia"},
236 : {199, "Niue"},
237 : {200, "Papua New Guinea"},
238 : {201, "Philippines"},
239 : {202, "Samoa"},
240 : {203, "Solomon Islands"},
241 : /* {204, "Reserved"},*/
242 : /* {205, "Reserved"},*/
243 : /* {206, "Reserved"},*/
244 : /* {207, "Reserved"},*/
245 : /* {208, "Reserved"},*/
246 : /* {209, "Reserved"},*/
247 : {210, "Frascati (ESA/ESRIN)"},
248 : {211, "Lanion"},
249 : {212, "Lisboa"},
250 : {213, "Reykiavik"},
251 : {214, "Madrid"},
252 : {215, "Zürich"},
253 : {216, "Service ARGOS Toulouse"},
254 : {217, "Bratislava"},
255 : {218, "Budapest"},
256 : {219, "Ljubljana"},
257 : {220, "Warsaw"},
258 : {221, "Zagreb"},
259 : {222, "Albania"},
260 : {223, "Armenia"},
261 : {224, "Austria"},
262 : {225, "Azerbaijan"},
263 : {226, "Belarus"},
264 : {227, "Belgium"},
265 : {228, "Bosnia and Herzegovina"},
266 : {229, "Bulgaria"},
267 : {230, "Cyprus"},
268 : {231, "Estonia"},
269 : {232, "Georgia"},
270 : {233, "Dublin"},
271 : {234, "Israel"},
272 : {235, "Jordan"},
273 : {236, "Latvia"},
274 : {237, "Lebanon"},
275 : {238, "Lithuania"},
276 : {239, "Luxembourg"},
277 : {240, "Malta"},
278 : {241, "Monaco"},
279 : {242, "Romania"},
280 : {243, "Syrian Arab Republic"},
281 : {244, "The former Yugoslav Republic of Macedonia"},
282 : {245, "Ukraine"},
283 : {246, "Republic of Moldova"},
284 : /* {247, "Reserved"},*/
285 : /* {248, "Reserved"},*/
286 : /* {249, "Reserved"},*/
287 : /* {250, "Reserved"},*/
288 : /* {251, "Reserved"},*/
289 : /* {252, "Reserved"},*/
290 : /* {253, "Reserved"},*/
291 : {254, "EUMETSAT Operation Centre"},
292 : /* {255, "Reserved"},*/
293 : {256, "Angola"},
294 : {257, "Benin"},
295 : {258, "Botswana"},
296 : {259, "Burkina Faso"},
297 : {260, "Burundi"},
298 : {261, "Cameroon"},
299 : {262, "Cape Verde"},
300 : {263, "Central African republic"},
301 : {264, "Chad"},
302 : {265, "Comoros"},
303 : {266, "Democratic Republic of the Congo"},
304 : {267, "Djibouti"},
305 : {268, "Eritrea"},
306 : {269, "Ethiopia"},
307 : {270, "Gabon"},
308 : {271, "Gambia"},
309 : {272, "Ghana"},
310 : {273, "Guinea"},
311 : {274, "Guinea Bissau"},
312 : {275, "Lesotho"},
313 : {276, "Liberia"},
314 : {277, "Malawi"},
315 : {278, "Mali"},
316 : {279, "Mauritania"},
317 : {280, "Namibia"},
318 : {281, "Nigeria"},
319 : {282, "Rwanda"},
320 : {283, "Sao Tome and Principe"},
321 : {284, "Sierra Leone"},
322 : {285, "Somalia"},
323 : {286, "Sudan"},
324 : {287, "Swaziland"},
325 : {288, "Togo"},
326 : {289, "Zambia"}
327 : };
328 : /* *INDENT-ON* */
329 0 : int numCenter = sizeof (Center) / sizeof (Center[0]);
330 : int i;
331 :
332 0 : for (i = 0; i < numCenter; i++) {
333 0 : if (Center[i].num == center) {
334 0 : return Center[i].name;
335 : }
336 : }
337 0 : return NULL;
338 : }
339 :
340 0 : const char *subCenterLookup(unsigned short int center,
341 : unsigned short int subcenter)
342 : {
343 : /* *INDENT-OFF* */
344 : /* see:
345 : * http://www.wmo.ch/web/www/WMOCodes/Operational/CommonTables/
346 : * BUFRCommon-2005feb.pdf as of 10/12/2005
347 : * http://www.nco.ncep.noaa.gov/pmb/docs/on388/tablec.html as of 11/9/2005
348 : * http://www.ecmwf.int/publications/manuals/libraries/gribex/
349 : * localGRIBUsage.html as of 4/5/2006
350 : */
351 : static struct {
352 : unsigned short int center, subcenter;
353 : const char *name;
354 : } SubCenter[] = {
355 : {7, 1, "NCEP Re-Analysis Project"}, {7, 2, "NCEP Ensemble Products"},
356 : {7, 3, "NCEP Central Operations"},
357 : {7, 4, "Environmental Modeling Center"},
358 : {7, 5, "Hydrometeorological Prediction Center"},
359 : {7, 6, "Ocean Prediction Center"}, {7, 7, "Climate Prediction Center"},
360 : {7, 8, "Aviation Weather Center"}, {7, 9, "Storm Prediction Center"},
361 : {7, 10, "Tropical Prediction Center"},
362 : {7, 11, "Techniques Development Laboratory"},
363 : {7, 12, "NESDIS Office of Research and Applications"},
364 : {7, 13, "FAA"},
365 : {7, 14, "Meteorological Development Laboratory (MDL)"},
366 : {7, 15, "North American Regional Reanalysis (NARR) Project"},
367 : {7, 16, "Space Environment Center"},
368 : {8, 0, "National Digital Forecast Database"},
369 : /* {8, GRIB2MISSING_2, "National Digital Forecast Database"},*/
370 : {161, 1, "Great Lakes Environmental Research Laboratory"},
371 : {161, 2, "Forecast Systems Laboratory"},
372 : {74, 1, "Shanwick Oceanic Area Control Centre"},
373 : {74, 2, "Fucino"}, {74, 3, "Gatineau"}, {74, 4, "Maspalomas"},
374 : {74, 5, "ESA ERS Central Facility"}, {74, 6, "Prince Albert"},
375 : {74, 7, "West Freugh"}, {74, 13, "Tromso"},
376 : {74, 21, "Agenzia Spaziale Italiana (Italy)"},
377 : {74, 22, "Centre National de la Recherche Scientifique (France)"},
378 : {74, 23, "GeoForschungsZentrum (Germany)"},
379 : {74, 24, "Geodetic Observatory Pecny (Czech Republic)"},
380 : {74, 25, "Institut d'Estudis Espacials de Catalunya (Spain)"},
381 : {74, 26, "Swiss Federal Office of Topography"},
382 : {74, 27, "Nordic Commission of Geodesy (Norway)"},
383 : {74, 28, "Nordic Commission of Geodesy (Sweden)"},
384 : {74, 29, "Institute de Geodesie National (France)"},
385 : {74, 30, "Bundesamt für Kartographie und Geodäsie (Germany)"},
386 : {74, 31, "Institute of Engineering Satellite Surveying and Geodesy (U.K.)"},
387 : {254, 10, "Tromso (Norway)"}, {254, 10, "Maspalomas (Spain)"},
388 : {254, 30, "Kangerlussuaq (Greenland)"}, {254, 40, "Edmonton (Canada)"},
389 : {254, 50, "Bedford (Canada)"}, {254, 60, "Gander (Canada)"},
390 : {254, 70, "Monterey (USA)"}, {254, 80, "Wallops Island (USA)"},
391 : {254, 90, "Gilmor Creek (USA)"}, {254, 100, "Athens (Greece)"},
392 : {98, 231, "CNRM, Meteo France Climate Centre (HIRETYCS)"},
393 : {98, 232, "MPI, Max Planck Institute Climate Centre (HIRETYCS)"},
394 : {98, 233, "UKMO Climate Centre (HIRETYCS)"},
395 : {98, 234, "ECMWF (DEMETER)"},
396 : {98, 235, "INGV-CNR (Bologna, Italy)(DEMETER)"},
397 : {98, 236, "LODYC (Paris, France)(DEMETER)"},
398 : {98, 237, "DMI (Copenhagen, Denmark)(DEMETER)"},
399 : {98, 238, "INM (Madrid, Spain)(DEMETER)"},
400 : {98, 239, "CERFACS (Toulouse, France)(DEMETER)"},
401 : {98, 240, "ECMWF (PROVOST)"},
402 : {98, 241, "Meteo France (PROVOST)"},
403 : {98, 242, "EDF (PROVOST)"},
404 : {98, 243, "UKMO (PROVOST)"},
405 : {98, 244, "Biometeorology group, University of Veterinary Medicine, Vienna (ELDAS)"},
406 : };
407 : /* *INDENT-ON* */
408 0 : int numSubCenter = sizeof (SubCenter) / sizeof (SubCenter[0]);
409 : int i;
410 :
411 0 : for (i = 0; i < numSubCenter; i++) {
412 0 : if ((SubCenter[i].center == center) &&
413 : (SubCenter[i].subcenter == subcenter)) {
414 0 : return SubCenter[i].name;
415 : }
416 : }
417 0 : return NULL;
418 : }
419 :
420 0 : const char *processLookup (unsigned short int center, unsigned char process)
421 : {
422 : /* see: http://www.nco.ncep.noaa.gov/pmb/docs/on388/tablea.html I typed
423 : * this in on 10/12/2005 */
424 : /* *INDENT-OFF* */
425 : static struct {
426 : unsigned short int center;
427 : unsigned char process;
428 : const char *name;
429 : } Process[] = {
430 : {7, 2, "Ultra Violet Index Model"},
431 : {7, 3, "NCEP/ARL Transport and Dispersion Model"},
432 : {7, 4, "NCEP/ARL Smoke Model"},
433 : {7, 5, "Satellite Derived Precipitation and temperatures, from IR"},
434 : {7, 10, "Global Wind-Wave Forecast Model"},
435 : {7, 19, "Limited-area Fine Mesh (LFM) analysis"},
436 : {7, 25, "Snow Cover Analysis"},
437 : {7, 30, "Forecaster generated field"},
438 : {7, 31, "Value added post processed field"},
439 : {7, 39, "Nested Grid forecast Model (NGM)"},
440 : {7, 42, "Global Optimum Interpolation Analysis (GOI) from GFS model"},
441 : {7, 43, "Global Optimum Interpolation Analysis (GOI) from 'Final' run"},
442 : {7, 44, "Sea Surface Temperature Analysis"},
443 : {7, 45, "Coastal Ocean Circulation Model"},
444 : {7, 46, "HYCOM - Global"},
445 : {7, 47, "HYCOM - North Pacific basin"},
446 : {7, 48, "HYCOM - North Atlantic basin"},
447 : {7, 49, "Ozone Analysis from TIROS Observations"},
448 : {7, 52, "Ozone Analysis from Nimbus 7 Observations"},
449 : {7, 53, "LFM-Fourth Order Forecast Model"},
450 : {7, 64, "Regional Optimum Interpolation Analysis (ROI)"},
451 : {7, 68, "80 wave triangular, 18-layer Spectral model from GFS model"},
452 : {7, 69, "80 wave triangular, 18 layer Spectral model from 'Medium Range Forecast' run"},
453 : {7, 70, "Quasi-Lagrangian Hurricane Model (QLM)"},
454 : {7, 73, "Fog Forecast model - Ocean Prod. Center"},
455 : {7, 74, "Gulf of Mexico Wind/Wave"},
456 : {7, 75, "Gulf of Alaska Wind/Wave"},
457 : {7, 76, "Bias corrected Medium Range Forecast"},
458 : {7, 77, "126 wave triangular, 28 layer Spectral model from GFS model"},
459 : {7, 78, "126 wave triangular, 28 layer Spectral model from 'Medium Range Forecast' run"},
460 : {7, 79, "Backup from the previous run"},
461 : {7, 80, "62 wave triangular, 28 layer Spectral model from 'Medium Range Forecast' run"},
462 : {7, 81, "Spectral Statistical Interpolation (SSI) analysis from GFS model"},
463 : {7, 82, "Spectral Statistical Interpolation (SSI) analysis from 'Final' run."},
464 : {7, 84, "MESO ETA Model (currently 12 km)"},
465 : {7, 86, "RUC Model from FSL (isentropic; scale: 60km at 40N)"},
466 : {7, 87, "CAC Ensemble Forecasts from Spectral (ENSMB)"},
467 : {7, 88, "NOAA Wave Watch III (NWW3) Ocean Wave Model"},
468 : {7, 89, "Non-hydrostatic Meso Model (NMM) Currently 8 km)"},
469 : {7, 90, "62 wave triangular, 28 layer spectral model extension of the 'Medium Range Forecast' run"},
470 : {7, 91, "62 wave triangular, 28 layer spectral model extension of the GFS model"},
471 : {7, 92, "62 wave triangular, 28 layer spectral model run from the 'Medium Range Forecast' final analysis"},
472 : {7, 93, "62 wave triangular, 28 layer spectral model run from the T62 GDAS analysis of the 'Medium Range Forecast' run"},
473 : {7, 94, "T170/L42 Global Spectral Model from MRF run"},
474 : {7, 95, "T126/L42 Global Spectral Model from MRF run"},
475 : {7, 96, "Global Forecast System Model"},
476 : {7, 98, "Climate Forecast System Model"},
477 : {7, 100, "RUC Surface Analysis (scale: 60km at 40N)"},
478 : {7, 101, "RUC Surface Analysis (scale: 40km at 40N)"},
479 : {7, 105, "RUC Model from FSL (isentropic; scale: 20km at 40N)"},
480 : {7, 110, "ETA Model - 15km version"},
481 : {7, 111, "Eta model, generic resolution"},
482 : {7, 112, "WRF-NMM (Nondydrostatic Mesoscale Model) model, generic resolution"},
483 : {7, 113, "Products from NCEP SREF processing"},
484 : {7, 115, "Downscaled GFS from Eta eXtension"},
485 : {7, 116, "WRF-EM (Eulerian Mass-core) model, generic resolution "},
486 : {7, 120, "Ice Concentration Analysis"},
487 : {7, 121, "Western North Atlantic Regional Wave Model"},
488 : {7, 122, "Alaska Waters Regional Wave Model"},
489 : {7, 123, "North Atlantic Hurricane Wave Model"},
490 : {7, 124, "Eastern North Pacific Regional Wave Model"},
491 : {7, 125, "North Pacific Hurricane Wave Model"},
492 : {7, 126, "Sea Ice Forecast Model"},
493 : {7, 127, "Lake Ice Forecast Model"},
494 : {7, 128, "Global Ocean Forecast Model"},
495 : {7, 129, "Global Ocean Data Analysis System (GODAS)"},
496 : {7, 130, "Merge of fields from the RUC, Eta, and Spectral Model"},
497 : {7, 131, "Great Lakes Wave Model"},
498 : {7, 140, "North American Regional Reanalysis (NARR)"},
499 : {7, 141, "Land Data Assimilation and Forecast System"},
500 : {7, 150, "NWS River Forecast System (NWSRFS)"},
501 : {7, 151, "NWS Flash Flood Guidance System (NWSFFGS)"},
502 : {7, 152, "WSR-88D Stage II Precipitation Analysis"},
503 : {7, 153, "WSR-88D Stage III Precipitation Analysis"},
504 : {7, 180, "Quantitative Precipitation Forecast"},
505 : {7, 181, "River Forecast Center Quantitative Precipitation Forecast mosaic"},
506 : {7, 182, "River Forecast Center Quantitative Precipitation estimate mosaic"},
507 : {7, 183, "NDFD product generated by NCEP/HPC"},
508 : {7, 190, "National Convective Weather Diagnostic"},
509 : {7, 191, "Current Icing Potential automated product"},
510 : {7, 192, "Analysis product from NCEP/AWC"},
511 : {7, 193, "Forecast product from NCEP/AWC"},
512 : {7, 195, "Climate Data Assimilation System 2 (CDAS2)"},
513 : {7, 196, "Climate Data Assimilation System 2 (CDAS2)"},
514 : {7, 197, "Climate Data Assimilation System (CDAS)"},
515 : {7, 198, "Climate Data Assimilation System (CDAS)"},
516 : {7, 200, "CPC Manual Forecast Product"},
517 : {7, 201, "CPC Automated Product"},
518 : {7, 210, "EPA Air Quality Forecast"},
519 : {7, 211, "EPA Air Quality Forecast"},
520 : {7, 220, "NCEP/OPC automated product"}
521 : };
522 : /* *INDENT-ON* */
523 0 : int numProcess = sizeof (Process) / sizeof (Process[0]);
524 : int i;
525 :
526 0 : for (i = 0; i < numProcess; i++) {
527 0 : if ((Process[i].center == center) && (Process[i].process == process)) {
528 0 : return Process[i].name;
529 : }
530 : }
531 0 : return NULL;
532 : }
533 :
534 : typedef struct {
535 : const char *name, *comment, *unit;
536 : unit_convert convert;
537 : } GRIB2ParmTable;
538 :
539 : typedef struct {
540 : int prodType, cat, subcat;
541 : const char *name, *comment, *unit;
542 : unit_convert convert;
543 : } GRIB2LocalTable;
544 :
545 : typedef struct {
546 : const char *GRIB2name, *NDFDname;
547 : } NDFD_AbrevOverideTable;
548 :
549 : /* *INDENT-OFF* */
550 : /* Updated based on:
551 : * http://www.wmo.ch/web/www/WMOCodes/Operational/GRIB2/FM92-GRIB2-2005nov.pdf
552 : * 1/3/2006
553 : */
554 : /* GRIB2 Code table 4.2 : 0.0 */
555 : GRIB2ParmTable MeteoTemp[] = {
556 : /* 0 */ {"TMP", "Temperature", "K", UC_K2F}, /* Need NDFD override. T */
557 : /* 1 */ {"VTMP", "Virtual temperature", "K", UC_K2F},
558 : /* 2 */ {"POT", "Potential temperature", "K", UC_K2F},
559 : /* 3 */ {"EPOT", "Pseudo-adiabatic potential temperature", "K", UC_K2F},
560 : /* 4 */ {"TMAX", "Maximum Temperature", "K", UC_K2F}, /* Need NDFD override MaxT */
561 : /* 5 */ {"TMIN", "Minimum Temperature", "K", UC_K2F}, /* Need NDFD override MinT */
562 : /* 6 */ {"DPT", "Dew point temperature", "K", UC_K2F}, /* Need NDFD override Td */
563 : /* 7 */ {"DEPR", "Dew point depression", "K", UC_K2F},
564 : /* 8 */ {"LAPR", "Lapse rate", "K/m", UC_NONE},
565 : /* 9 */ {"TMPA", "Temperature anomaly", "K", UC_K2F},
566 : /* 10 */ {"LHTFL", "Latent heat net flux", "W/(m^2)", UC_NONE},
567 : /* 11 */ {"SHTFL", "Sensible heat net flux", "W/(m^2)", UC_NONE},
568 : /* NDFD */
569 : /* 12 */ {"HeatIndex", "Heat index", "K", UC_K2F},
570 : /* NDFD */
571 : /* 13 */ {"WCI", "Wind chill factor", "K", UC_K2F},
572 : /* 14 */ {"", "Minimum dew point depression", "K", UC_K2F},
573 : /* 15 */ {"VPTMP", "Virtual potential temperature", "K", UC_K2F},
574 : /* 16 */ {"SNOHF", "Snow phase change heat flux", "W/m^2", UC_NONE},
575 : };
576 :
577 : /* GRIB2 Code table 4.2 : 0.1 */
578 : /* NCEP added "Water" to items 22, 24, 25 */
579 : GRIB2ParmTable MeteoMoist[] = {
580 : /* 0 */ {"SPFH", "Specific humidity", "kg/kg", UC_NONE},
581 : /* 1 */ {"RH", "Relative Humidity", "%", UC_NONE},
582 : /* 2 */ {"MIXR", "Humidity mixing ratio", "kg/kg", UC_NONE},
583 : /* 3 */ {"PWAT", "Precipitable water", "kg/(m^2)", UC_NONE},
584 : /* 4 */ {"VAPP", "Vapor Pressure", "Pa", UC_NONE},
585 : /* 5 */ {"SATD", "Saturation deficit", "Pa", UC_NONE},
586 : /* 6 */ {"EVP", "Evaporation", "kg/(m^2)", UC_NONE},
587 : /* 7 */ {"PRATE", "Precipitation rate", "kg/(m^2 s)", UC_NONE},
588 : /* 8 */ {"APCP", "Total precipitation", "kg/(m^2)", UC_InchWater}, /* Need NDFD override QPF */
589 : /* 9 */ {"NCPCP", "Large scale precipitation", "kg/(m^2)", UC_NONE},
590 : /* 10 */ {"ACPCP", "Convective precipitation", "kg/(m^2)", UC_NONE},
591 : /* 11 */ {"SNOD", "Snow depth", "m", UC_M2Inch}, /* Need NDFD override SnowDepth ? */
592 : /* 12 */ {"SRWEQ", "Snowfall rate water equivalent", "kg/(m^2 s)", UC_NONE},
593 : /* 13 */ {"WEASD", "Water equivalent of accumulated snow depth",
594 : "kg/(m^2)", UC_NONE},
595 : /* 14 */ {"SNOC", "Convective snow", "kg/(m^2)", UC_NONE},
596 : /* 15 */ {"SNOL", "Large scale snow", "kg/(m^2)", UC_NONE},
597 : /* 16 */ {"SNOM", "Snow melt", "kg/(m^2)", UC_NONE},
598 : /* 17 */ {"SNOAG", "Snow age", "day", UC_NONE},
599 : /* 18 */ {"", "Absolute humidity", "kg/(m^3)", UC_NONE},
600 : /* 19 */ {"", "Precipitation type", "(1 Rain, 2 Thunderstorm, "
601 : "3 Freezing Rain, 4 Mixed/ice, 5 snow, 255 missing)", UC_NONE},
602 : /* 20 */ {"", "Integrated liquid water", "kg/(m^2)", UC_NONE},
603 : /* 21 */ {"TCOND", "Condensate", "kg/kg", UC_NONE},
604 : /* CLWMR Did not make it to tables yet should be "-" */
605 : /* 22 */ {"CLWMR", "Cloud Water Mixing Ratio", "kg/kg", UC_NONE},
606 : /* 23 */ {"ICMR", "Ice water mixing ratio", "kg/kg", UC_NONE}, /* ICMR? */
607 : /* 24 */ {"RWMR", "Rain Water Mixing Ratio", "kg/kg", UC_NONE},
608 : /* 25 */ {"SNMR", "Snow Water Mixing Ratio", "kg/kg", UC_NONE},
609 : /* 26 */ {"MCONV", "Horizontal moisture convergence", "kg/(kg s)", UC_NONE},
610 : /* 27 */ {"", "Maximum relative humidity", "%", UC_NONE},
611 : /* 28 */ {"", "Maximum absolute humidity", "kg/(m^3)", UC_NONE},
612 : /* NDFD */
613 : /* 29 */ {"ASNOW", "Total snowfall", "m", UC_M2Inch},
614 : /* 30 */ {"", "Precipitable water category", "(undefined)", UC_NONE},
615 : /* 31 */ {"", "Hail", "m", UC_NONE},
616 : /* 32 */ {"", "Graupel (snow pellets)", "kg/kg", UC_NONE},
617 : /* 33 */ {"CRAIN", "Categorical rain", "0=no, 1=yes", UC_NONE},
618 : /* 34 */ {"CFRZR", "Categorical freezing rain", "0=no, 1=yes", UC_NONE},
619 : /* 35 */ {"CICEP", "Categorical ice pellets", "0=no, 1=yes", UC_NONE},
620 : /* 36 */ {"CSNOW", "Categorical snow", "0=no, 1=yes", UC_NONE},
621 : /* 37 */ {"CPRAT", "Convective precipitation rate", "kg/(m^2*s)", UC_NONE},
622 : /* 38 */ {"MCONV", "Horizontal moisture divergence", "kg/(kg*s)", UC_NONE},
623 : /* 39 */ {"CPOFP", "Percent frozen precipitation", "%", UC_NONE},
624 : /* 40 */ {"PEVAP", "Potential evaporation", "kg/m^2", UC_NONE},
625 : /* 41 */ {"PEVPR", "Potential evaporation rate", "W/m^2", UC_NONE},
626 : /* 42 */ {"SNOWC", "Snow Cover", "%", UC_NONE},
627 : /* 43 */ {"FRAIN", "Rain fraction of total cloud water", "-", UC_NONE},
628 : /* 44 */ {"RIME", "Rime factor", "-", UC_NONE},
629 : /* 45 */ {"TCOLR", "Total column integrated rain", "kg/m^2", UC_NONE},
630 : /* 46 */ {"TCOLS", "Total column integrated snow", "kg/m^2", UC_NONE},
631 : };
632 :
633 : /* GRIB2 Code table 4.2 : 0.2 */
634 : GRIB2ParmTable MeteoMoment[] = {
635 : /* 0 */ {"WDIR", "Wind direction (from which blowing)", "deg true",
636 : UC_NONE}, /* Need NDFD override WindDir */
637 : /* 1 */ {"WIND", "Wind speed", "m/s", UC_MS2Knots}, /* Need NDFD override WindSpd */
638 : /* 2 */ {"UGRD", "u-component of wind", "m/s", UC_NONE},
639 : /* 3 */ {"VGRD", "v-component of wind", "m/s", UC_NONE},
640 : /* 4 */ {"STRM", "Stream function", "(m^2)/s", UC_NONE},
641 : /* 5 */ {"VPOT", "Velocity potential", "(m^2)/s", UC_NONE},
642 : /* 6 */ {"MNTSF", "Montgomery stream function", "(m^2)/(s^2)", UC_NONE},
643 : /* 7 */ {"SGCVV", "Sigma coordinate vertical velocity", "1/s", UC_NONE},
644 : /* 8 */ {"VVEL", "Vertical velocity (pressure)", "Pa/s", UC_NONE}, /* NCEP override WEL? */
645 : /* 9 */ {"DZDT", "Verical velocity (geometric)", "m/s", UC_NONE},
646 : /* 10 */ {"ABSV", "Absolute vorticity", "1/s", UC_NONE},
647 : /* 11 */ {"ABSD", "Absolute divergence", "1/s", UC_NONE},
648 : /* 12 */ {"RELV", "Relative vorticity", "1/s", UC_NONE},
649 : /* 13 */ {"RELD", "Relative divergence", "1/s", UC_NONE},
650 : /* 14 */ {"PV", "Potential vorticity", "K(m^2)/(kg s)", UC_NONE},
651 : /* 15 */ {"VUCSH", "Vertical u-component shear", "1/s", UC_NONE},
652 : /* 16 */ {"VVCSH", "Vertical v-component shear", "1/s", UC_NONE},
653 : /* 17 */ {"UFLX", "Momentum flux; u component", "N/(m^2)", UC_NONE},
654 : /* 18 */ {"VFLX", "Momentum flux; v component", "N/(m^2)", UC_NONE},
655 : /* 19 */ {"WMIXE", "Wind mixing energy", "J", UC_NONE},
656 : /* 20 */ {"BLYDP", "Boundary layer dissipation", "W/(m^2)", UC_NONE},
657 : /* 21 */ {"", "Maximum wind speed", "m/s", UC_NONE},
658 : /* 22 */ {"GUST", "Wind speed (gust)", "m/s", UC_MS2Knots}, /* GUST? */
659 : /* 23 */ {"", "u-component of wind (gust)", "m/s", UC_NONE},
660 : /* 24 */ {"", "v-component of wind (gust)", "m/s", UC_NONE},
661 : /* 25 */ {"VWSH", "Vertical speed shear", "1/s", UC_NONE},
662 : /* 26 */ {"MFLX", "Horizontal momentum flux", "N/(m^2)", UC_NONE},
663 : /* 27 */ {"USTM", "U-component storm motion", "m/s", UC_NONE},
664 : /* 28 */ {"VSTM", "V-component storm motion", "m/s", UC_NONE},
665 : /* 29 */ {"CD", "Drag coefficient", "-", UC_NONE},
666 : /* 30 */ {"FRICV", "Frictional velocity", "m/s", UC_NONE},
667 : };
668 :
669 : /* GRIB2 Code table 4.2 : 0.3 */
670 : GRIB2ParmTable MeteoMass[] = {
671 : /* 0 */ {"PRES", "Pressure", "Pa", UC_NONE},
672 : /* 1 */ {"PRMSL", "Pressure reduced to MSL", "Pa", UC_NONE},
673 : /* 2 */ {"PTEND", "Pressure tendency", "Pa/s", UC_NONE},
674 : /* 3 */ {"ICAHT", "ICAO Standard Atmosphere Reference Height", "m", UC_NONE},
675 : /* 4 */ {"GP", "Geopotential", "(m^2)/(s^2)", UC_NONE},
676 : /* 5 */ {"HGT", "Geopotential height", "gpm", UC_NONE},
677 : /* 6 */ {"DIST", "Geometric Height", "m", UC_NONE},
678 : /* 7 */ {"HSTDV", "Standard deviation of height", "m", UC_NONE},
679 : /* 8 */ {"PRESA", "Pressure anomaly", "Pa", UC_NONE},
680 : /* 9 */ {"GPA", "Geopotential height anomally", "gpm", UC_NONE},
681 : /* 10 */ {"DEN", "Density", "kg/(m^3)", UC_NONE},
682 : /* 11 */ {"", "Altimeter setting", "Pa", UC_NONE},
683 : /* 12 */ {"", "Thickness", "m", UC_NONE},
684 : /* 13 */ {"", "Pressure altitude", "m", UC_NONE},
685 : /* 14 */ {"", "Density altitude", "m", UC_NONE},
686 : /* 15 */ {"5WAVH", "5-wave geopotential height", "gpm", UC_NONE},
687 : /* 16 */ {"U-GWD", "Zonal flux of gravity wave stress", "N/(m^2)", UC_NONE},
688 : /* 17 */ {"V-GWD", "Meridional flux of gravity wave stress", "N/(m^2)", UC_NONE},
689 : /* 18 */ {"HPBL", "Planetary boundary layer height", "m", UC_NONE},
690 : /* 19 */ {"5WAVA", "5-Wave geopotential height anomaly", "gpm", UC_NONE},
691 : };
692 :
693 : /* GRIB2 Code table 4.2 : 0.4 */
694 : GRIB2ParmTable MeteoShortRadiate[] = {
695 : /* 0 */ {"NSWRS", "Net short-wave radiation flux (surface)", "W/(m^2)", UC_NONE},
696 : /* 1 */ {"NSWRT", "Net short-wave radiation flux (top of atmosphere)",
697 : "W/(m^2)", UC_NONE},
698 : /* 2 */ {"SWAVR", "Short wave radiation flux", "W/(m^2)", UC_NONE},
699 : /* 3 */ {"GRAD", "Global radiation flux", "W/(m^2)", UC_NONE},
700 : /* 4 */ {"BRTMP", "Brightness temperature", "K", UC_NONE},
701 : /* 5 */ {"LWRAD", "Radiance (with respect to wave number)", "W/(m sr)", UC_NONE},
702 : /* 6 */ {"SWRAD", "Radiance (with respect to wave length)", "W/(m^3 sr)", UC_NONE},
703 : /* 7 */ {"DSWRF", "Downward short-wave radiation flux", "W/(m^2)", UC_NONE},
704 : /* 8 */ {"USWRF", "Upward short-wave radiation flux", "W/(m^2)", UC_NONE},
705 : };
706 :
707 : /* GRIB2 Code table 4.2 : 0.5 */
708 : GRIB2ParmTable MeteoLongRadiate[] = {
709 : /* 0 */ {"NLWRS", "Net long wave radiation flux (surface)", "W/(m^2)", UC_NONE},
710 : /* 1 */ {"NLWRT", "Net long wave radiation flux (top of atmosphere)",
711 : "W/(m^2)", UC_NONE},
712 : /* 2 */ {"LWAVR", "Long wave radiation flux", "W/(m^2)", UC_NONE},
713 : /* 3 */ {"DLWRF", "Downward Long-Wave Rad. Flux", "W/(m^2)", UC_NONE},
714 : /* 4 */ {"ULWRF", "Upward Long-Wave Rad. Flux", "W/(m^2)", UC_NONE},
715 : };
716 :
717 : /* GRIB2 Code table 4.2 : 0.6 */
718 : GRIB2ParmTable MeteoCloud[] = {
719 : /* 0 */ {"CICE", "Cloud Ice", "kg/(m^2)", UC_NONE},
720 : /* 1 */ {"TCDC", "Total cloud cover", "%", UC_NONE}, /* Need NDFD override Sky */
721 : /* 2 */ {"CDCON", "Convective cloud cover", "%", UC_NONE},
722 : /* 3 */ {"LCDC", "Low cloud cover", "%", UC_NONE},
723 : /* 4 */ {"MCDC", "Medium cloud cover", "%", UC_NONE},
724 : /* 5 */ {"HCDC", "High cloud cover", "%", UC_NONE},
725 : /* 6 */ {"CWAT", "Cloud water", "kg/(m^2)", UC_NONE},
726 : /* 7 */ {"", "Cloud amount", "%", UC_NONE},
727 : /* 8 */ {"", "Cloud type", "(0 clear, 1 Cumulonimbus, 2 Stratus, "
728 : "3 Stratocumulus, 4 Cumulus, 5 Altostratus, 6 Nimbostratus, "
729 : "7 Altocumulus, 8 Cirrostratus, 9 Cirrocumulus, 10 Cirrus, "
730 : "11 Cumulonimbus (fog), 12 Stratus (fog), 13 Stratocumulus (fog),"
731 : " 14 Cumulus (fog), 15 Altostratus (fog), 16 Nimbostratus (fog), "
732 : "17 Altocumulus (fog), 18 Cirrostratus (fog), "
733 : "19 Cirrocumulus (fog), 20 Cirrus (fog), 191 unknown, "
734 : "255 missing)", UC_NONE},
735 : /* 9 */ {"", "Thunderstorm maximum tops", "m", UC_NONE},
736 : /* 10 */ {"", "Thunderstorm coverage", "(0 none, 1 isolated (1%-2%), "
737 : "2 few (3%-15%), 3 scattered (16%-45%), 4 numerous (> 45%), "
738 : "255 missing)", UC_NONE},
739 : /* 11 */ {"", "Cloud base", "m", UC_NONE},
740 : /* 12 */ {"", "Cloud top", "m", UC_NONE},
741 : /* 13 */ {"", "Ceiling", "m", UC_NONE},
742 : /* 14 */ {"CDLYR", "Non-convective cloud cover", "%", UC_NONE},
743 : /* 15 */ {"CWORK", "Cloud work function", "J/kg", UC_NONE},
744 : /* 16 */ {"CUEFI", "Convective cloud efficiency", "-", UC_NONE},
745 : /* 17 */ {"TCOND", "Total condensate", "kg/kg", UC_NONE},
746 : /* 18 */ {"TCOLW", "Total column-integrated cloud water", "kg/(m^2)", UC_NONE},
747 : /* 19 */ {"TCOLI", "Total column-integrated cloud ice", "kg/(m^2)", UC_NONE},
748 : /* 20 */ {"TCOLC", "Total column-integrated condensate", "kg/(m^2)", UC_NONE},
749 : /* 21 */ {"FICE", "Ice fraction of total condensate", "-", UC_NONE},
750 : };
751 :
752 : /* GRIB2 Code table 4.2 : 0.7 */
753 : /* NCEP capitalized items 6, 7, 8 */
754 : GRIB2ParmTable MeteoStability[] = {
755 : /* 0 */ {"PLI", "Parcel lifted index (to 500 hPa)", "K", UC_NONE},
756 : /* 1 */ {"BLI", "Best lifted index (to 500 hPa)", "K", UC_NONE},
757 : /* 2 */ {"KX", "K index", "K", UC_NONE},
758 : /* 3 */ {"", "KO index", "K", UC_NONE},
759 : /* 4 */ {"", "Total totals index", "K", UC_NONE},
760 : /* 5 */ {"SX", "Sweat index", "numeric", UC_NONE},
761 : /* 6 */ {"CAPE", "Convective available potential energy", "J/kg", UC_NONE},
762 : /* 7 */ {"CIN", "Convective inhibition", "J/kg", UC_NONE},
763 : /* 8 */ {"HLCY", "Storm relative helicity", "J/kg", UC_NONE},
764 : /* 9 */ {"", "Energy helicity index", "numeric", UC_NONE},
765 : /* 10 */ {"LFTX", "Surface fifted index", "K", UC_NONE},
766 : /* 11 */ {"4LFTX", "Best (4-layer) lifted index", "K", UC_NONE},
767 : /* 12 */ {"RI", "Richardson number", "-", UC_NONE},
768 : };
769 :
770 : /* GRIB2 Code table 4.2 : 0.13 */
771 : GRIB2ParmTable MeteoAerosols[] = {
772 : /* 0 */ {"", "Aerosol type", "(0 Aerosol not present, 1 Aerosol present, "
773 : "255 missing)", UC_NONE},
774 : };
775 :
776 : /* GRIB2 Code table 4.2 : 0.14 */
777 : GRIB2ParmTable MeteoGases[] = {
778 : /* 0 */ {"TOZNE", "Total ozone", "Dobson", UC_NONE},
779 : /* 1 */ {"O3MR", "Ozone Mixing Ratio", "kg/kg", UC_NONE},
780 : };
781 :
782 : /* GRIB2 Code table 4.2 : 0.15 */
783 : GRIB2ParmTable MeteoRadar[] = {
784 : /* 0 */ {"", "Base spectrum width", "m/s", UC_NONE},
785 : /* 1 */ {"", "Base reflectivity", "dB", UC_NONE},
786 : /* 2 */ {"", "Base radial velocity", "m/s", UC_NONE},
787 : /* 3 */ {"", "Vertically-integrated liquid", "kg/m", UC_NONE},
788 : /* 4 */ {"", "Layer-maximum base reflectivity", "dB", UC_NONE},
789 : /* 5 */ {"", "Precipitation", "kg/(m^2)", UC_NONE},
790 : /* 6 */ {"RDSP1", "Radar spectra (1)", "-", UC_NONE},
791 : /* 7 */ {"RDSP2", "Radar spectra (2)", "-", UC_NONE},
792 : /* 8 */ {"RDSP3", "Radar spectra (3)", "-", UC_NONE},
793 : };
794 :
795 : /* GRIB2 Code table 4.2 : 0.18 */
796 : GRIB2ParmTable MeteoNuclear[] = {
797 : /* 0 */ {"", "Air concentration of Caesium 137", "Bq/(m^3)", UC_NONE},
798 : /* 1 */ {"", "Air concentration of Iodine 131", "Bq/(m^3)", UC_NONE},
799 : /* 2 */ {"", "Air concentration of radioactive pollutant", "Bq/(m^3)", UC_NONE},
800 : /* 3 */ {"", "Ground deposition of Caesium 137", "Bq/(m^2)", UC_NONE},
801 : /* 4 */ {"", "Ground deposition of Iodine 131", "Bq/(m^2)", UC_NONE},
802 : /* 5 */ {"", "Ground deposition of radioactive pollutant", "Bq/(m^2)", UC_NONE},
803 : /* 6 */ {"", "Time-integrated air concentration of caesium pollutant",
804 : "(Bq s)/(m^3)", UC_NONE},
805 : /* 7 */ {"", "Time-integrated air concentration of iodine pollutant",
806 : "(Bq s)/(m^3)", UC_NONE},
807 : /* 8 */ {"", "Time-integrated air concentration of radioactive pollutant",
808 : "(Bq s)/(m^3)", UC_NONE},
809 : };
810 :
811 : /* GRIB2 Code table 4.2 : 0.19 */
812 : /* NCEP capitalized items 11 */
813 : GRIB2ParmTable MeteoAtmos[] = {
814 : /* 0 */ {"VIS", "Visibility", "m", UC_NONE},
815 : /* 1 */ {"ALBDO", "Albedo", "%", UC_NONE},
816 : /* 2 */ {"TSTM", "Thunderstorm probability", "%", UC_NONE},
817 : /* 3 */ {"MIXHT", "mixed layer depth", "m", UC_NONE},
818 : /* 4 */ {"", "Volcanic ash", "(0 not present, 1 present, 255 missing)", UC_NONE},
819 : /* 5 */ {"", "Icing top", "m", UC_NONE},
820 : /* 6 */ {"", "Icing base", "m", UC_NONE},
821 : /* 7 */ {"", "Icing", "(0 None, 1 Light, 2 Moderate, 3 Severe, "
822 : "255 missing)", UC_NONE},
823 : /* 8 */ {"", "Turbulance top", "m", UC_NONE},
824 : /* 9 */ {"", "Turbulence base", "m", UC_NONE},
825 : /* 10 */ {"", "Turbulance", "(0 None(smooth), 1 Light, 2 Moderate, "
826 : "3 Severe, 4 Extreme, 255 missing)", UC_NONE},
827 : /* 11 */ {"TKE", "Turbulent Kinetic Energy", "J/kg", UC_NONE},
828 : /* 12 */ {"", "Planetary boundary layer regime", "(0 Reserved, 1 Stable, "
829 : "2 Mechanically driven turbulence, 3 Forced convection, "
830 : "4 Free convection, 255 missing)", UC_NONE},
831 : /* 13 */ {"", "Contrail intensity", "(0 Contrail not present, "
832 : "1 Contrail present, 255 missing)", UC_NONE},
833 : /* 14 */ {"", "Contrail engine type", "(0 Low bypass, 1 High bypass, "
834 : "2 Non bypass, 255 missing)", UC_NONE},
835 : /* 15 */ {"", "Contrail top", "m", UC_NONE},
836 : /* 16 */ {"", "Contrail base", "m", UC_NONE},
837 : /* 17 */ {"MXSALB", "Maximum snow albedo", "%", UC_NONE},
838 : /* 18 */ {"SNFALB", "Snow free albedo", "%", UC_NONE},
839 : };
840 :
841 : /* GRIB2 Code table 4.2 : 0.253 or 0.190 (Document is inconsistant.) */
842 : GRIB2ParmTable MeteoText[] = {
843 : /* 0 */ {"", "Arbitrary text string", "CCITTIA5", UC_NONE},
844 : };
845 :
846 : GRIB2ParmTable MeteoMisc[] = {
847 : /* 0 */ {"TSEC", "Seconds prior to initial reference time (defined in Section"
848 : " 1)", "s", UC_NONE},
849 : };
850 :
851 : /* GRIB2 Code table 4.2 : 1.0 */
852 : GRIB2ParmTable HydroBasic[] = {
853 : /* 0 */ {"", "Flash flood guidance", "kg/(m^2)", UC_NONE},
854 : /* 1 */ {"", "Flash flood runoff", "kg/(m^2)", UC_NONE},
855 : /* 2 */ {"", "Remotely sensed snow cover", "(50 no-snow/no-cloud, "
856 : "100 Clouds, 250 Snow, 255 missing)", UC_NONE},
857 : /* 3 */ {"", "Elevation of snow covered terrain", "(0-90 elevation in "
858 : "increments of 100m, 254 clouds, 255 missing)", UC_NONE},
859 : /* 4 */ {"", "Snow water equivalent percent of normal", "%", UC_NONE},
860 : /* 5 */ {"BGRUN", "Baseflow-groundwater runoff", "kg/(m^2)", UC_NONE},
861 : /* 6 */ {"SSRUN", "Storm surface runoff", "kg/(m^2)", UC_NONE},
862 : };
863 :
864 : /* GRIB2 Code table 4.2 : 1.1 */
865 : GRIB2ParmTable HydroProb[] = {
866 : /* 0 */ {"", "Conditional percent precipitation amount fractile for an "
867 : "overall period", "kg/(m^2)", UC_NONE},
868 : /* 1 */ {"", "Percent precipitation in a sub-period of an overall period",
869 : "%", UC_NONE},
870 : /* 2 */ {"PoP", "Probability of 0.01 inch of precipitation", "%", UC_NONE},
871 : };
872 :
873 : /* GRIB2 Code table 4.2 : 2.0 */
874 : GRIB2ParmTable LandVeg[] = {
875 : /* 0 */ {"LAND", "Land cover (1=land; 2=sea)", "Proportion", UC_NONE},
876 : /* 1 */ {"SFCR", "Surface roughness", "m", UC_NONE}, /*NCEP override SFRC? */
877 : /* 2 */ {"TSOIL", "Soil temperature", "K", UC_NONE},
878 : /* 3 */ {"SOILM", "Soil moisture content", "kg/(m^2)", UC_NONE},
879 : /* 4 */ {"VEG", "Vegetation", "%", UC_NONE},
880 : /* 5 */ {"WATR", "Water runoff", "kg/(m^2)", UC_NONE},
881 : /* 6 */ {"", "Evapotranspiration", "1/(kg^2 s)", UC_NONE},
882 : /* 7 */ {"", "Model terrain height", "m", UC_NONE},
883 : /* 8 */ {"", "Land use", "(1 Urban land, 2 agriculture, 3 Range Land, "
884 : "4 Deciduous forest, 5 Coniferous forest, 6 Forest/wetland, "
885 : "7 Water, 8 Wetlands, 9 Desert, 10 Tundra, 11 Ice, "
886 : "12 Tropical forest, 13 Savannah)", UC_NONE},
887 : /* 9 */ {"SOILW", "Volumetric soil moisture content", "fraction", UC_NONE},
888 : /* 10 */ {"GFLUX", "Ground heat flux", "W/(m^2)", UC_NONE},
889 : /* 11 */ {"MSTAV", "Moisture availability", "%", UC_NONE},
890 : /* 12 */ {"SFEXC", "Exchange coefficient", "(kg/(m^3))(m/s)", UC_NONE},
891 : /* 13 */ {"CNWAT", "Plant canopy surface water", "kg/(m^2)", UC_NONE},
892 : /* 14 */ {"BMIXL", "Blackadar's mixing length scale", "m", UC_NONE},
893 : /* 15 */ {"CCOND", "Canopy conductance", "m/s", UC_NONE},
894 : /* 16 */ {"RSMIN", "Minimal stomatal resistance", "s/m", UC_NONE},
895 : /* 17 */ {"WILT", "Wilting point", "fraction", UC_NONE},
896 : /* 18 */ {"RCS", "Solar parameter in canopy conductance", "fraction", UC_NONE},
897 : /* 19 */ {"RCT", "Temperature parameter in canopy conductance", "fraction", UC_NONE},
898 : /* 20 */ {"RCSOL", "Soil moisture parameter in canopy conductance", "fraction", UC_NONE},
899 : /* 21 */ {"RCQ", "Humidity parameter in canopy conductance", "fraction", UC_NONE},
900 : };
901 :
902 : /* GRIB2 Code table 4.2 : 2.3 */
903 : /* NCEP changed 0 to be "Soil type (as in Zobler)" I ignored them */
904 : GRIB2ParmTable LandSoil[] = {
905 : /* 0 */ {"SOTYP", "Soil type", "(1 Sand, 2 Loamy sand, 3 Sandy loam, "
906 : "4 Silt loam, 5 Organic (redefined), 6 Sandy clay loam, "
907 : "7 Silt clay loam, 8 Clay loam, 9 Sandy clay, 10 Silty clay, "
908 : "11 Clay)", UC_NONE},
909 : /* 1 */ {"", "Upper layer soil temperature", "K", UC_NONE},
910 : /* 2 */ {"", "Upper layer soil moisture", "kg/(m^3)", UC_NONE},
911 : /* 3 */ {"", "Lower layer soil moisture", "kg/(m^3)", UC_NONE},
912 : /* 4 */ {"", "Bottom layer soil temperature", "K", UC_NONE},
913 : /* 5 */ {"SOILL", "Liquid volumetric soil moisture (non-frozen)", "fraction", UC_NONE},
914 : /* 6 */ {"RLYRS", "Number of soil layers in root zone", "-", UC_NONE},
915 : /* 7 */ {"SMREF", "Transpiration stress-onset (soil moisture)", "fraction", UC_NONE},
916 : /* 8 */ {"SMDRY", "Direct evaporation cease (soil moisture)", "fraction", UC_NONE},
917 : /* 9 */ {"POROS", "Soil porosity", "fraction", UC_NONE},
918 : };
919 :
920 : /* GRIB2 Code table 4.2 : 3.0 */
921 : GRIB2ParmTable SpaceImage[] = {
922 : /* 0 */ {"", "Scaled radiance", "numeric", UC_NONE},
923 : /* 1 */ {"", "Scaled albedo", "numeric", UC_NONE},
924 : /* 2 */ {"", "Scaled brightness temperature", "numeric", UC_NONE},
925 : /* 3 */ {"", "Scaled precipitable water", "numeric", UC_NONE},
926 : /* 4 */ {"", "Scaled lifted index", "numeric", UC_NONE},
927 : /* 5 */ {"", "Scaled cloud top pressure", "numeric", UC_NONE},
928 : /* 6 */ {"", "Scaled skin temperature", "numeric", UC_NONE},
929 : /* 7 */ {"", "Cloud mask", "(0 clear over water, 1 clear over land, "
930 : "2 cloud)", UC_NONE},
931 : /* 8 */ {"", "Pixel scene type", "(0 No scene, 1 needle, 2 broad-leafed, "
932 : "3 Deciduous needle, 4 Deciduous broad-leafed, 5 Deciduous mixed, "
933 : "6 Closed shrub, 7 Open shrub, 8 Woody savannah, 9 Savannah, "
934 : "10 Grassland, 11 wetland, 12 Cropland, 13 Urban, 14 crops, "
935 : "15 snow, 16 Desert, 17 Water, 18 Tundra, 97 Snow on land, "
936 : "98 Snow on water, 99 Sun-glint, 100 General cloud, "
937 : "101 (fog, Stratus), 102 Stratocumulus, 103 Low cloud, "
938 : "104 Nimbotratus, 105 Altostratus, 106 Medium cloud, 107 Cumulus, "
939 : "108 Cirrus, 109 High cloud, 110 Unknown cloud)", UC_NONE},
940 : };
941 :
942 : /* GRIB2 Code table 4.2 : 3.1 */
943 : GRIB2ParmTable SpaceQuantitative[] = {
944 : /* 0 */ {"", "Estimated precipitation", "kg/(m^2)", UC_NONE},
945 : /* 1 */ {"", "Instantaneous rain rate", "kg/(m^2*s)", UC_NONE},
946 : /* 2 */ {"", "Cloud top height", "kg/(m^2*s)", UC_NONE},
947 : /* 3 */ {"", "Cloud top height quality indicator", "(0 Nominal cloud top "
948 : "height quality, 1 Fog in segment, 2 Poor quality height estimation "
949 : "3 Fog in segment and poor quality height estimation)", UC_NONE},
950 : /* 4 */ {"", "Estimated u component of wind", "m/s", UC_NONE},
951 : /* 5 */ {"", "Estimated v component of wind", "m/s", UC_NONE},
952 : };
953 :
954 : /* GRIB2 Code table 4.2 : 10.0 */
955 : GRIB2ParmTable OceanWaves[] = {
956 : /* 0 */ {"WVSP1", "Wave spectra (1)", "-", UC_NONE},
957 : /* 1 */ {"WVSP2", "Wave spectra (2)", "-", UC_NONE},
958 : /* 2 */ {"WVSP3", "Wave spectra (3)", "-", UC_NONE},
959 : /* 3 */ {"HTSGW", "Significant height of combined wind waves and swell", "m", UC_NONE},
960 : /* 4 */ {"WVDIR", "Direction of wind waves", "Degree true", UC_NONE},
961 : /* 5 */ {"WVHGT", "Significant height of wind waves", "m", UC_M2Feet}, /* NDFD override needed WaveHeight */
962 : /* 6 */ {"WVPER", "Mean period of wind waves", "s", UC_NONE},
963 : /* 7 */ {"SWDIR", "Direction of swell waves", "Degree true", UC_NONE},
964 : /* 8 */ {"SWELL", "Significant height of swell waves", "m", UC_NONE},
965 : /* 9 */ {"SWPER", "Mean period of swell waves", "s", UC_NONE},
966 : /* 10 */ {"DIRPW", "Primary wave direction", "Degree true", UC_NONE},
967 : /* 11 */ {"PERPW", "Primary wave mean period", "s", UC_NONE},
968 : /* 12 */ {"DIRSW", "Secondary wave direction", "Degree true", UC_NONE},
969 : /* 13 */ {"PERSW", "Secondary wave mean period", "s", UC_NONE},
970 : };
971 :
972 : /* GRIB2 Code table 4.2 : 10.1 */
973 : GRIB2ParmTable OceanCurrents[] = {
974 : /* 0 */ {"DIRC", "Current direction", "Degree true", UC_NONE},
975 : /* 1 */ {"SPC", "Current speed", "m/s", UC_NONE},
976 : /* 2 */ {"UOGRD", "u-component of current", "m/s", UC_NONE},
977 : /* 3 */ {"VOGRD", "v-component of current", "m/s", UC_NONE},
978 : };
979 :
980 : /* GRIB2 Code table 4.2 : 10.2 */
981 : GRIB2ParmTable OceanIce[] = {
982 : /* 0 */ {"ICEC", "Ice cover", "Proportion", UC_NONE},
983 : /* 1 */ {"ICETK", "Ice thinkness", "m", UC_NONE},
984 : /* 2 */ {"DICED", "Direction of ice drift", "Degree true", UC_NONE},
985 : /* 3 */ {"SICED", "Speed of ice drift", "m/s", UC_NONE},
986 : /* 4 */ {"UICE", "u-component of ice drift", "m/s", UC_NONE},
987 : /* 5 */ {"VICE", "v-component of ice drift", "m/s", UC_NONE},
988 : /* 6 */ {"ICEG", "Ice growth rate", "m/s", UC_NONE},
989 : /* 7 */ {"ICED", "Ice divergence", "1/s", UC_NONE},
990 : };
991 :
992 : /* GRIB2 Code table 4.2 : 10.3 */
993 : GRIB2ParmTable OceanSurface[] = {
994 : /* 0 */ {"WTMP", "Water temperature", "K", UC_NONE},
995 : /* 1 */ {"DSLM", "Deviation of sea level from mean", "m", UC_NONE},
996 : };
997 :
998 : /* GRIB2 Code table 4.2 : 10.4 */
999 : GRIB2ParmTable OceanSubSurface[] = {
1000 : /* 0 */ {"MTHD", "Main thermocline depth", "m", UC_NONE},
1001 : /* 1 */ {"MTHA", "Main thermocline anomaly", "m", UC_NONE},
1002 : /* 2 */ {"TTHDP", "Transient thermocline depth", "m", UC_NONE},
1003 : /* 3 */ {"SALTY", "Salinity", "kg/kg", UC_NONE},
1004 : };
1005 :
1006 : /* *INDENT-ON* */
1007 :
1008 : /*****************************************************************************
1009 : * Choose_GRIB2ParmTable() --
1010 : *
1011 : * Arthur Taylor / MDL
1012 : *
1013 : * PURPOSE
1014 : * Chooses the correct Parameter table depending on what is in the GRIB2
1015 : * message's "Product Definition Section".
1016 : *
1017 : * ARGUMENTS
1018 : * prodType = The product type (meteo, hydro, land, space, ocean, etc) (In)
1019 : * cat = The category inside the product (Input)
1020 : * tableLen = The length of the returned table (Output)
1021 : *
1022 : * FILES/DATABASES: None
1023 : *
1024 : * RETURNS: ParmTable (appropriate parameter table.)
1025 : *
1026 : * HISTORY
1027 : * 1/2004 Arthur Taylor (MDL/RSIS): Created
1028 : *
1029 : * NOTES
1030 : *****************************************************************************
1031 : */
1032 4 : static GRIB2ParmTable *Choose_GRIB2ParmTable (int prodType, int cat,
1033 : size_t *tableLen)
1034 : {
1035 : enum { METEO_TEMP = 0, METEO_MOIST = 1, METEO_MOMENT = 2, METEO_MASS = 3,
1036 : METEO_SW_RAD = 4, METEO_LW_RAD = 5, METEO_CLOUD = 6,
1037 : METEO_THERMO_INDEX = 7, METEO_KINEMATIC_INDEX = 8, METEO_TEMP_PROB = 9,
1038 : METEO_MOISTURE_PROB = 10, METEO_MOMENT_PROB = 11, METEO_MASS_PROB = 12,
1039 : METEO_AEROSOL = 13, METEO_GAS = 14, METEO_RADAR = 15,
1040 : METEO_RADAR_IMAGERY = 16, METEO_ELECTRO = 17, METEO_NUCLEAR = 18,
1041 : METEO_ATMOS = 19, METEO_CCITT = 190, METEO_MISC = 191,
1042 : METEO_CCITT2 = 253
1043 : };
1044 : enum { HYDRO_BASIC = 0, HYDRO_PROB = 1 };
1045 : enum { LAND_VEG = 0, LAND_SOIL = 3 };
1046 : enum { SPACE_IMAGE = 0, SPACE_QUANTIT = 1 };
1047 : enum { OCEAN_WAVES = 0, OCEAN_CURRENTS = 1, OCEAN_ICE = 2, OCEAN_SURF = 3,
1048 : OCEAN_SUBSURF = 4
1049 : };
1050 :
1051 4 : switch (prodType) {
1052 : case 0: /* Meteo type. */
1053 4 : switch (cat) {
1054 : case METEO_TEMP:
1055 4 : *tableLen = sizeof (MeteoTemp) / sizeof (GRIB2ParmTable);
1056 4 : return &MeteoTemp[0];
1057 : case METEO_MOIST:
1058 0 : *tableLen = sizeof (MeteoMoist) / sizeof (GRIB2ParmTable);
1059 0 : return &MeteoMoist[0];
1060 : case METEO_MOMENT:
1061 0 : *tableLen = sizeof (MeteoMoment) / sizeof (GRIB2ParmTable);
1062 0 : return &MeteoMoment[0];
1063 : case METEO_MASS:
1064 0 : *tableLen = sizeof (MeteoMass) / sizeof (GRIB2ParmTable);
1065 0 : return &MeteoMass[0];
1066 : case METEO_SW_RAD:
1067 : *tableLen = (sizeof (MeteoShortRadiate) /
1068 0 : sizeof (GRIB2ParmTable));
1069 0 : return &MeteoShortRadiate[0];
1070 : case METEO_LW_RAD:
1071 : *tableLen = (sizeof (MeteoLongRadiate) /
1072 0 : sizeof (GRIB2ParmTable));
1073 0 : return &MeteoLongRadiate[0];
1074 : case METEO_CLOUD:
1075 0 : *tableLen = sizeof (MeteoCloud) / sizeof (GRIB2ParmTable);
1076 0 : return &MeteoCloud[0];
1077 : case METEO_THERMO_INDEX:
1078 0 : *tableLen = sizeof (MeteoStability) / sizeof (GRIB2ParmTable);
1079 0 : return &MeteoStability[0];
1080 : case METEO_KINEMATIC_INDEX:
1081 : case METEO_TEMP_PROB:
1082 : case METEO_MOISTURE_PROB:
1083 : case METEO_MOMENT_PROB:
1084 : case METEO_MASS_PROB:
1085 0 : *tableLen = 0;
1086 0 : return NULL;
1087 : case METEO_AEROSOL:
1088 0 : *tableLen = sizeof (MeteoAerosols) / sizeof (GRIB2ParmTable);
1089 0 : return &MeteoAerosols[0];
1090 : case METEO_GAS:
1091 0 : *tableLen = sizeof (MeteoGases) / sizeof (GRIB2ParmTable);
1092 0 : return &MeteoGases[0];
1093 : case METEO_RADAR:
1094 0 : *tableLen = sizeof (MeteoRadar) / sizeof (GRIB2ParmTable);
1095 0 : return &MeteoRadar[0];
1096 : case METEO_RADAR_IMAGERY:
1097 : case METEO_ELECTRO:
1098 0 : *tableLen = 0;
1099 0 : return NULL;
1100 : case METEO_NUCLEAR:
1101 0 : *tableLen = sizeof (MeteoNuclear) / sizeof (GRIB2ParmTable);
1102 0 : return &MeteoNuclear[0];
1103 : case METEO_ATMOS:
1104 0 : *tableLen = sizeof (MeteoAtmos) / sizeof (GRIB2ParmTable);
1105 0 : return &MeteoAtmos[0];
1106 : case METEO_CCITT:
1107 : case METEO_CCITT2:
1108 0 : *tableLen = sizeof (MeteoText) / sizeof (GRIB2ParmTable);
1109 0 : return &MeteoText[0];
1110 : case METEO_MISC:
1111 0 : *tableLen = sizeof (MeteoMisc) / sizeof (GRIB2ParmTable);
1112 0 : return &MeteoMisc[0];
1113 : default:
1114 0 : *tableLen = 0;
1115 0 : return NULL;
1116 : }
1117 : case 1: /* Hydro type. */
1118 0 : switch (cat) {
1119 : case HYDRO_BASIC:
1120 0 : *tableLen = sizeof (HydroBasic) / sizeof (GRIB2ParmTable);
1121 0 : return &HydroBasic[0];
1122 : case HYDRO_PROB:
1123 0 : *tableLen = sizeof (HydroProb) / sizeof (GRIB2ParmTable);
1124 0 : return &HydroProb[0];
1125 : default:
1126 0 : *tableLen = 0;
1127 0 : return NULL;
1128 : }
1129 : case 2: /* Land type. */
1130 0 : switch (cat) {
1131 : case LAND_VEG:
1132 0 : *tableLen = sizeof (LandVeg) / sizeof (GRIB2ParmTable);
1133 0 : return &LandVeg[0];
1134 : case LAND_SOIL:
1135 0 : *tableLen = sizeof (LandSoil) / sizeof (GRIB2ParmTable);
1136 0 : return &LandSoil[0];
1137 : default:
1138 0 : *tableLen = 0;
1139 0 : return NULL;
1140 : }
1141 : case 3: /* Space type. */
1142 0 : switch (cat) {
1143 : case SPACE_IMAGE:
1144 0 : *tableLen = sizeof (SpaceImage) / sizeof (GRIB2ParmTable);
1145 0 : return &SpaceImage[0];
1146 : case SPACE_QUANTIT:
1147 : *tableLen = (sizeof (SpaceQuantitative) /
1148 0 : sizeof (GRIB2ParmTable));
1149 0 : return &SpaceQuantitative[0];
1150 : default:
1151 0 : *tableLen = 0;
1152 0 : return NULL;
1153 : }
1154 : case 10: /* ocean type. */
1155 0 : switch (cat) {
1156 : case OCEAN_WAVES:
1157 0 : *tableLen = sizeof (OceanWaves) / sizeof (GRIB2ParmTable);
1158 0 : return &OceanWaves[0];
1159 : case OCEAN_CURRENTS:
1160 0 : *tableLen = sizeof (OceanCurrents) / sizeof (GRIB2ParmTable);
1161 0 : return &OceanCurrents[0];
1162 : case OCEAN_ICE:
1163 0 : *tableLen = sizeof (OceanIce) / sizeof (GRIB2ParmTable);
1164 0 : return &OceanIce[0];
1165 : case OCEAN_SURF:
1166 0 : *tableLen = sizeof (OceanSurface) / sizeof (GRIB2ParmTable);
1167 0 : return &OceanSurface[0];
1168 : default:
1169 0 : *tableLen = 0;
1170 0 : return NULL;
1171 : }
1172 : default:
1173 0 : *tableLen = 0;
1174 0 : return NULL;
1175 : }
1176 : }
1177 :
1178 : /* *INDENT-OFF* */
1179 : NDFD_AbrevOverideTable NDFD_Overide[] = {
1180 : /* 0 */ {"TMP", "T"},
1181 : /* 1 */ {"TMAX", "MaxT"},
1182 : /* 2 */ {"TMIN", "MinT"},
1183 : /* 3 */ {"DPT", "Td"},
1184 : /* 4 */ {"APCP", "QPF"},
1185 : /* Don't need SNOD for now. */
1186 : /* 5 */ /* {"SNOD", "SnowDepth"}, */
1187 : /* 6 */ {"WDIR", "WindDir"},
1188 : /* 7 */ {"WIND", "WindSpd"},
1189 : /* 8 */ {"TCDC", "Sky"},
1190 : /* 9 */ {"WVHGT", "WaveHeight"},
1191 : /* 10 */ {"ASNOW", "SnowAmt"},
1192 : /* 11 */ {"GUST", "WindGust"},
1193 : };
1194 :
1195 : GRIB2LocalTable NDFD_LclTable[] = {
1196 : /* 0 */ {0, 1, 192, "Wx", "Weather string", "-", UC_NONE},
1197 : /* 1 */ {0, 0, 193, "ApparentT", "Apparent Temperature", "K", UC_K2F},
1198 : /* 2 */ {0, 14, 192, "O3MR", "Ozone Mixing Ratio", "kg/kg", UC_NONE},
1199 : /* 3 */ {0, 14, 193, "OZCON", "Ozone Concentration", "PPB", UC_NONE},
1200 : /* grandfather'ed in a NDFD choice for POP. */
1201 : /* 4 */ {0, 10, 8, "PoP12", "Prob of 0.01 In. of Precip", "%", UC_NONE},
1202 : {0, 13, 194, "smokes", "Surface level smoke from fires",
1203 : "log10(µg/m^3)", UC_LOG10},
1204 : {0, 13, 195, "smokec", "Average vertical column smoke from fires",
1205 : "log10(µg/m^3)", UC_LOG10},
1206 : /* Arthur Added this to both NDFD and NCEP local tables. (5/1/2006) */
1207 : {10, 3, 192, "Surge", "Hurricane Storm Surge", "m", UC_M2Feet},
1208 : {10, 3, 193, "ETSurge", "Extra Tropical Storm Surge", "m", UC_M2Feet},
1209 : };
1210 :
1211 : GRIB2LocalTable HPC_LclTable[] = {
1212 : /* 0 */ {0, 1, 192, "HPC-Wx", "HPC Code", "-", UC_NONE},
1213 : };
1214 :
1215 : /*
1216 : Updated this table last on 12/29/2005
1217 : Based on:
1218 : http://www.nco.ncep.noaa.gov/pmb/docs/grib2/GRIB2_parmeter_conversion_table.html
1219 : Better source is:
1220 : http://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_table4-1.shtml
1221 : For abreviations see:
1222 : http://www.nco.ncep.noaa.gov/pmb/docs/on388/table2.html
1223 :
1224 : Updated again on 2/14/2006
1225 : Updated again on 3/15/2006
1226 : */
1227 : GRIB2LocalTable NCEP_LclTable[] = {
1228 : /* 0 */ {0, 0, 192, "SNOHF", "Snow Phase Change Heat Flux", "W/(m^2)", UC_NONE},
1229 : {0, 0, 193, "TTRAD", "Temperature tendency by all radiation", "K/s", UC_NONE},
1230 :
1231 : /* 1 */ {0, 1, 192, "CRAIN", "Categorical Rain", "(0 no; 1 yes)", UC_NONE},
1232 : /* 2 */ {0, 1, 193, "CFRZR", "Categorical Freezing Rain", "(0 no; 1 yes)", UC_NONE},
1233 : /* 3 */ {0, 1, 194, "CICEP", "Categorical Ice Pellets", "(0 no; 1 yes)", UC_NONE},
1234 : /* 4 */ {0, 1, 195, "CSNOW", "Categorical Snow", "(0 no; 1 yes)", UC_NONE},
1235 : /* 5 */ {0, 1, 196, "CPRAT", "Convective Precipitation Rate", "kg/(m^2*s)", UC_NONE},
1236 : /* 6 */ {0, 1, 197, "MCONV", "Horizontal Moisture Divergence", "kg/(kg*s)", UC_NONE},
1237 : /* Following was grandfathered in... Should use: 1, 1, 193 */
1238 : /* 7 */ {0, 1, 198, "CPOFP", "Percent Frozen Precipitation", "%", UC_NONE},
1239 : /* 8 */ {0, 1, 199, "PEVAP", "Potential Evaporation", "kg/(m^2)", UC_NONE},
1240 : /* 9 */ {0, 1, 200, "PEVPR", "Potential Evaporation Rate", "W/(m^2)", UC_NONE},
1241 : /* 10 */ {0, 1, 201, "SNOWC", "Snow Cover", "%", UC_NONE},
1242 : /* 11 */ {0, 1, 202, "FRAIN", "Rain Fraction of Total Liquid Water", "-", UC_NONE},
1243 : /* FRIME -> RIME 12/29/2005 */
1244 : /* 12 */ {0, 1, 203, "RIME", "Rime Factor", "-", UC_NONE},
1245 : /* 13 */ {0, 1, 204, "TCOLR", "Total Column Integrated Rain", "kg/(m^2)", UC_NONE},
1246 : /* 14 */ {0, 1, 205, "TCOLS", "Total Column Integrated Snow", "kg/(m^2)", UC_NONE},
1247 : {0, 1, 206, "TIPD", "Total Icing Potential Diagnostic", "-", UC_NONE},
1248 : {0, 1, 207, "NCIP", "Number concentration for ice particles", "-", UC_NONE},
1249 : {0, 1, 208, "SNOT", "Snow temperature", "K", UC_NONE},
1250 :
1251 : /* 15 */ {0, 2, 192, "VWSH", "Vertical speed sheer", "1/s", UC_NONE},
1252 : /* 16 */ {0, 2, 193, "MFLX", "Horizontal Momentum Flux", "N/(m^2)", UC_NONE},
1253 : /* 17 */ {0, 2, 194, "USTM", "U-Component Storm Motion", "m/s", UC_NONE},
1254 : /* 18 */ {0, 2, 195, "VSTM", "V-Component Storm Motion", "m/s", UC_NONE},
1255 : /* 19 */ {0, 2, 196, "CD", "Drag Coefficient", "-", UC_NONE},
1256 : /* 20 */ {0, 2, 197, "FRICV", "Frictional Velocity", "m/s", UC_NONE},
1257 :
1258 : /* 21 */ {0, 3, 192, "MSLET", "Mean Sea Level Pressure (Eta Reduction)", "Pa", UC_NONE},
1259 : /* 22 */ {0, 3, 193, "5WAVH", "5-Wave Geopotential Height", "gpm", UC_NONE},
1260 : /* 23 */ {0, 3, 194, "U-GWD", "Zonal Flux of Gravity Wave Stress", "N/(m^2)", UC_NONE},
1261 : /* 24 */ {0, 3, 195, "V-GWD", "Meridional Flux of Gravity Wave Stress", "N/(m^2)", UC_NONE},
1262 : /* 25 */ {0, 3, 196, "HPBL", "Planetary Boundary Layer Height", "m", UC_NONE},
1263 : /* 26 */ {0, 3, 197, "5WAVA", "5-Wave Geopotential Height Anomaly", "gpm", UC_NONE},
1264 : {0, 3, 198, "MSLMA", "Mean Sea Level Pressure (MAPS System Reduction)", "Pa", UC_NONE},
1265 : {0, 3, 199, "TSLSA", "3-hr pressure tendency (Std. Atmos. Reduction)", "Pa/s", UC_NONE},
1266 : {0, 3, 200, "PLPL", "Pressure of level from which parcel was lifted", "Pa", UC_NONE},
1267 :
1268 : /* 27 */ {0, 4, 192, "DSWRF", "Downward Short-Wave Rad. Flux", "W/(m^2)", UC_NONE},
1269 : /* 28 */ {0, 4, 193, "USWRF", "Upward Short-Wave Rad. Flux", "W/(m^2)", UC_NONE},
1270 : {0, 4, 194, "DUVB", "UV-B downward solar flux", "W/(m^2)", UC_NONE},
1271 : {0, 4, 195, "CDUVB", "Clear sky UV-B downward solar flux", "W/(m^2)", UC_NONE},
1272 :
1273 : /* 29 */ {0, 5, 192, "DLWRF", "Downward Long-Wave Rad. Flux", "W/(m^2)", UC_NONE},
1274 : /* 30 */ {0, 5, 193, "ULWRF", "Upward Long-Wave Rad. Flux", "W/(m^2)", UC_NONE},
1275 :
1276 : /* 31 */ {0, 6, 192, "CDLYR", "Non-Convective Cloud Cover", "%", UC_NONE},
1277 : /* 32 */ {0, 6, 193, "CWORK", "Cloud Work Function", "J/kg", UC_NONE},
1278 : /* 33 */ {0, 6, 194, "CUEFI", "Convective Cloud Efficiency", "-", UC_NONE},
1279 : /* 34 */ {0, 6, 195, "TCOND", "Total Condensate", "kg/kg", UC_NONE},
1280 : /* 35 */ {0, 6, 196, "TCOLW", "Total Column-Integrated Cloud Water", "kg/(m^2)", UC_NONE},
1281 : /* 36 */ {0, 6, 197, "TCOLI", "Total Column-Integrated Cloud Ice", "kg/(m^2)", UC_NONE},
1282 : /* 37 */ {0, 6, 198, "TCOLC", "Total Column-Integrated Condensate", "kg/(m^2)", UC_NONE},
1283 : /* 38 */ {0, 6, 199, "FICE", "Ice fraction of total condensate", "-", UC_NONE},
1284 :
1285 : /* 39 */ {0, 7, 192, "LFTX", "Surface Lifted Index", "K", UC_NONE},
1286 : /* 40 */ {0, 7, 193, "4LFTX", "Best (4 layer) Lifted Index", "K", UC_NONE},
1287 : /* 41 */ {0, 7, 194, "RI", "Richardson Number", "-", UC_NONE},
1288 :
1289 : {0, 13, 192, "PMTC", "Particulate matter (coarse)", "µg/m^3", UC_NONE},
1290 : {0, 13, 193, "PMTF", "Particulate matter (fine)", "µg/m^3", UC_NONE},
1291 : {0, 13, 194, "LPMTF", "Particulate matter (fine)",
1292 : "log10(µg/m^3)", UC_LOG10},
1293 : {0, 13, 195, "LIPMF", "Integrated column particulate matter "
1294 : "(fine)", "log10(µg/m^3)", UC_LOG10},
1295 :
1296 : /* 42 */ {0, 14, 192, "O3MR", "Ozone Mixing Ratio", "kg/kg", UC_NONE},
1297 : /* 43 */ {0, 14, 193, "OZCON", "Ozone Concentration", "PPB", UC_NONE},
1298 : /* 44 */ {0, 14, 194, "OZCAT", "Categorical Ozone Concentration", "-", UC_NONE},
1299 :
1300 : {0, 16, 192, "REFZR", "Derived radar reflectivity backscatter from rain", "mm^6/m^3", UC_NONE},
1301 : {0, 16, 193, "REFZI", "Derived radar reflectivity backscatter from ice", "mm^6/m^3", UC_NONE},
1302 : {0, 16, 194, "REFZC", "Derived radar reflectivity backscatter from parameterized convection", "mm^6/m^3", UC_NONE},
1303 : {0, 16, 195, "REFD", "Derived radar reflectivity", "dB", UC_NONE},
1304 : {0, 16, 196, "REFC", "Maximum / Composite radar reflectivity", "dB", UC_NONE},
1305 :
1306 : {0, 17, 192, "LTNG", "Lightning", "-", UC_NONE},
1307 :
1308 : /* 45 */ {0, 19, 192, "MXSALB", "Maximum Snow Albedo", "%", UC_NONE},
1309 : /* 46 */ {0, 19, 193, "SNFALB", "Snow-Free Albedo", "%", UC_NONE},
1310 : {0, 19, 194, "", "Slight risk convective outlook", "categorical", UC_NONE},
1311 : {0, 19, 195, "", "Moderate risk convective outlook", "categorical", UC_NONE},
1312 : {0, 19, 196, "", "High risk convective outlook", "categorical", UC_NONE},
1313 : {0, 19, 197, "", "Tornado probability", "%", UC_NONE},
1314 : {0, 19, 198, "", "Hail probability", "%", UC_NONE},
1315 : {0, 19, 199, "", "Wind probability", "%", UC_NONE},
1316 : {0, 19, 200, "", "Significant Tornado probability", "%", UC_NONE},
1317 : {0, 19, 201, "", "Significant Hail probability", "%", UC_NONE},
1318 : {0, 19, 202, "", "Significant Wind probability", "%", UC_NONE},
1319 : {0, 19, 203, "TSTMC", "Categorical Thunderstorm", "0=no, 1=yes", UC_NONE},
1320 : {0, 19, 204, "MIXLY", "Number of mixed layers next to surface", "integer", UC_NONE},
1321 :
1322 : /* 47 */ {0, 191, 192, "NLAT", "Latitude (-90 to 90)", "deg", UC_NONE},
1323 : /* 48 */ {0, 191, 193, "ELON", "East Longitude (0 to 360)", "deg", UC_NONE},
1324 : /* 49 */ {0, 191, 194, "TSEC", "Seconds prior to initial reference time", "s", UC_NONE},
1325 :
1326 : /* 50 */ {1, 0, 192, "BGRUN", "Baseflow-Groundwater Runoff", "kg/(m^2)", UC_NONE},
1327 : /* 51 */ {1, 0, 193, "SSRUN", "Storm Surface Runoff", "kg/(m^2)", UC_NONE},
1328 :
1329 : {1, 1, 192, "CPOZP", "Probability of Freezing Precipitation", "%", UC_NONE},
1330 : {1, 1, 193, "CPOFP", "Probability of Frozen Precipitation", "%", UC_NONE},
1331 : {1, 1, 194, "PPFFG", "Probability of precipitation exceeding flash flood guidance values", "%", UC_NONE},
1332 :
1333 : /* 52 */ {2, 0, 192, "SOILW", "Volumetric Soil Moisture Content", "Fraction", UC_NONE},
1334 : /* 53 */ {2, 0, 193, "GFLUX", "Ground Heat Flux", "W/(m^2)", UC_NONE},
1335 : /* 54 */ {2, 0, 194, "MSTAV", "Moisture Availability", "%", UC_NONE},
1336 : /* 55 */ {2, 0, 195, "SFEXC", "Exchange Coefficient", "(kg/(m^3))(m/s)", UC_NONE},
1337 : /* 56 */ {2, 0, 196, "CNWAT", "Plant Canopy Surface Water", "kg/(m^2)", UC_NONE},
1338 : /* 57 */ {2, 0, 197, "BMIXL", "Blackadar's Mixing Length Scale", "m", UC_NONE},
1339 : /* 58 */ {2, 0, 198, "VGTYP", "Vegetation Type", "0..13", UC_NONE},
1340 : /* 59 */ {2, 0, 199, "CCOND", "Canopy Conductance", "m/s", UC_NONE},
1341 : /* 60 */ {2, 0, 200, "RSMIN", "Minimal Stomatal Resistance", "s/m", UC_NONE},
1342 : /* 61 */ {2, 0, 201, "WILT", "Wilting Point", "Fraction", UC_NONE},
1343 : /* 62 */ {2, 0, 202, "RCS", "Solar parameter in canopy conductance", "Fraction", UC_NONE},
1344 : /* 63 */ {2, 0, 203, "RCT", "Temperature parameter in canopy conductance", "Fraction", UC_NONE},
1345 : /* 64 */ {2, 0, 204, "RCQ", "Humidity parameter in canopy conductance", "Fraction", UC_NONE},
1346 : /* 65 */ {2, 0, 205, "RCSOL", "Soil moisture parameter in canopy conductance", "Fraction", UC_NONE},
1347 : {2, 0, 206, "RDRIP", "Rate of water dropping from canopy to ground", "unknown", UC_NONE},
1348 : {2, 0, 207, "ICWAT", "Ice-free water surface", "%", UC_NONE},
1349 :
1350 : /* 66 */ {2, 3, 192, "SOILL", "Liquid Volumetric Soil Moisture (non Frozen)", "Proportion", UC_NONE},
1351 : /* 67 */ {2, 3, 193, "RLYRS", "Number of Soil Layers in Root Zone", "-", UC_NONE},
1352 : /* 68 */ {2, 3, 194, "SLTYP", "Surface Slope Type", "Index", UC_NONE},
1353 : /* 69 */ {2, 3, 195, "SMREF", "Transpiration Stress-onset (soil moisture)", "Proportion", UC_NONE},
1354 : /* 70 */ {2, 3, 196, "SMDRY", "Direct Evaporation Cease (soil moisture)", "Proportion", UC_NONE},
1355 : /* 71 */ {2, 3, 197, "POROS", "Soil Porosity", "Proportion", UC_NONE},
1356 :
1357 : /* ScatEstUWind -> USCT, ScatEstVWind -> VSCT as of 7/5/2006 (pre 1.80) */
1358 : /* 72 */ {3, 1, 192, "USCT", "Scatterometer Estimated U Wind", "m/s", UC_NONE},
1359 : /* 73 */ {3, 1, 193, "VSCT", "Scatterometer Estimated V Wind", "m/s", UC_NONE},
1360 :
1361 : /* Arthur Added this to both NDFD and NCEP local tables. (5/1/2006) */
1362 : {10, 3, 192, "SURGE", "Hurricane Storm Surge", "m", UC_M2Feet},
1363 : {10, 3, 193, "ETSRG", "Extra Tropical Storm Surge", "m", UC_M2Feet},
1364 : };
1365 : /* *INDENT-ON* */
1366 :
1367 4 : int IsData_NDFD (unsigned short int center, unsigned short int subcenter)
1368 : {
1369 : return ((center == 8) &&
1370 4 : ((subcenter == GRIB2MISSING_u2) || (subcenter == 0)));
1371 : }
1372 :
1373 0 : int IsData_MOS (unsigned short int center, unsigned short int subcenter)
1374 : {
1375 0 : return ((center == 7) && (subcenter == 14));
1376 : }
1377 :
1378 : /*****************************************************************************
1379 : * Choose_LocalParmTable() --
1380 : *
1381 : * Arthur Taylor / MDL
1382 : *
1383 : * PURPOSE
1384 : * Chooses the local parameter table for a given center/subcenter.
1385 : * Typically this is called after the default Choose_ParmTable was tried,
1386 : * since it consists of all the local specs, and one has to linearly walk
1387 : * through the table.
1388 : *
1389 : * ARGUMENTS
1390 : * center = The center that created the data. (Input)
1391 : * subcenter = The subcenter that created the data. (Input)
1392 : * tableLen = The length of the returned table (Output)
1393 : *
1394 : * FILES/DATABASES: None
1395 : *
1396 : * RETURNS: LocalParmTable (appropriate parameter table.)
1397 : *
1398 : * HISTORY
1399 : * 1/2004 Arthur Taylor (MDL/RSIS): Created
1400 : *
1401 : * NOTES
1402 : *****************************************************************************
1403 : */
1404 0 : static GRIB2LocalTable *Choose_LocalParmTable (unsigned short int center,
1405 : unsigned short int subcenter,
1406 : size_t *tableLen)
1407 : {
1408 0 : switch (center) {
1409 : case 7: /* NWS NCEP */
1410 : /* Check if all subcenters of NCEP use the same local table. */
1411 : /*
1412 : *tableLen = sizeof (NCEP_LclTable) / sizeof (GRIB2LocalTable);
1413 : return &NCEP_LclTable[0];
1414 : */
1415 0 : switch (subcenter) {
1416 : case 5: /* Have HPC use NDFD table. */
1417 0 : *tableLen = sizeof (HPC_LclTable) / sizeof (GRIB2LocalTable);
1418 0 : return &HPC_LclTable[0];
1419 : default:
1420 0 : *tableLen = sizeof (NCEP_LclTable) / sizeof (GRIB2LocalTable);
1421 0 : return &NCEP_LclTable[0];
1422 : /*
1423 : *tableLen = 0;
1424 : return NULL;
1425 : */
1426 : }
1427 : case 8: /* NWS Telecomunications gateway */
1428 0 : switch (subcenter) {
1429 : case GRIB2MISSING_u2: /* NDFD */
1430 : case 0: /* NDFD */
1431 0 : *tableLen = sizeof (NDFD_LclTable) / sizeof (GRIB2LocalTable);
1432 0 : return &NDFD_LclTable[0];
1433 : default:
1434 0 : *tableLen = 0;
1435 0 : return NULL;
1436 : }
1437 : default:
1438 0 : *tableLen = 0;
1439 0 : return NULL;
1440 : }
1441 : }
1442 :
1443 : /*****************************************************************************
1444 : * ParseElemName() --
1445 : *
1446 : * Arthur Taylor / MDL
1447 : *
1448 : * PURPOSE
1449 : * Converts a prodType, template, category and subcategory quadruple to the
1450 : * ASCII string abreviation of that variable.
1451 : * For example: 0, 0, 0, 0, = "T" for temperature.
1452 : *
1453 : * ARGUMENTS
1454 : * center = The center that created the data. (Input)
1455 : * subcenter = The subcenter that created the data. (Input)
1456 : * prodType = The GRIB2, section 0 product type. (Input)
1457 : * templat = The GRIB2 section 4 template number. (Input)
1458 : * cat = The GRIB2 section 4 "General category of Product." (Input)
1459 : * subcat = The GRIB2 section 4 "Specific subcategory of Product". (Input)
1460 : * lenTime = The length of time over which statistics are done
1461 : * (see template 4.8). (Input)
1462 : * genID = The Generating process ID (used for GFS MOS) (Input)
1463 : * probType = For Probability templates (Input)
1464 : * lowerProb = Lower Limit for probability templates. (Input)
1465 : * upperProb = Upper Limit for probability templates. (Input)
1466 : * name = Short name for the data set (T, MaxT, etc) (Output)
1467 : * comment = Long form of the name (Temperature, etc) (Output)
1468 : * unit = What unit this variable is originally in (Output)
1469 : *
1470 : * FILES/DATABASES: None
1471 : *
1472 : * RETURNS: void
1473 : *
1474 : * HISTORY
1475 : * 1/2004 Arthur Taylor (MDL/RSIS): Re-Created.
1476 : * 6/2004 AAT: Added deltTime (because of Ozone issues).
1477 : * 8/2004 AAT: Adjusted so template 9 gets units of % and no convert.
1478 : * 3/2005 AAT: ReWrote to handle template 5, 9 and MOS.
1479 : * 9/2005 AAT: Added code to handle MOS PoP06 vs MOS PoP12.
1480 : *
1481 : * NOTES
1482 : *****************************************************************************
1483 : */
1484 : /* Deal with probability templates 2/16/2006 */
1485 0 : static void ElemNameProb (uShort2 center, uShort2 subcenter, int prodType,
1486 : int templat, uChar cat, uChar subcat, sInt4 lenTime,
1487 : uChar timeIncrType, uChar genID, uChar probType,
1488 : double lowerProb, double upperProb, char **name,
1489 : char **comment, char **unit, int *convert)
1490 : {
1491 : GRIB2ParmTable *table;
1492 : GRIB2LocalTable *local;
1493 : size_t tableLen;
1494 : size_t i;
1495 0 : char f_isNdfd = IsData_NDFD (center, subcenter);
1496 0 : char f_isMos = IsData_MOS (center, subcenter);
1497 :
1498 0 : *unit = (char *) malloc (strlen ("[%]") + 1);
1499 0 : strcpy (*unit, "[%]");
1500 :
1501 0 : if (f_isNdfd || f_isMos) {
1502 : /* Deal with NDFD/MOS handling of Prob Precip_Tot -> PoP12 */
1503 0 : if ((prodType == 0) && (cat == 1) && (subcat == 8)) {
1504 0 : myAssert (probType == 1);
1505 0 : if (lenTime > 0) {
1506 0 : mallocSprintf (name, "PoP%02d", lenTime);
1507 : mallocSprintf (comment, "%02d hr Prob of Precip > 0.01 "
1508 0 : "In. [%%]", lenTime);
1509 : } else {
1510 0 : *name = (char *) malloc (strlen ("PoP") + 1);
1511 0 : strcpy (*name, "PoP");
1512 : *comment =
1513 : (char *) malloc (strlen ("Prob of Precip > 0.01 In. [%]") +
1514 0 : 1);
1515 0 : strcpy (*comment, "Prob of Precip > 0.01 In. [%]");
1516 : }
1517 0 : *convert = UC_NONE;
1518 0 : return;
1519 : }
1520 : /*
1521 : * Deal with NDFD handling of Prob. Wind speeds.
1522 : * There are different solutions for naming the Prob. Wind fields
1523 : * AAT(Mine): ProbSurge5c
1524 : */
1525 0 : if ((prodType == 10) && (cat == 3) && (subcat == 192)) {
1526 0 : myAssert (probType == 1);
1527 0 : myAssert (lenTime > 0);
1528 0 : if (timeIncrType == 2) {
1529 : /* Incremental */
1530 : mallocSprintf (name, "ProbSurge%02di",
1531 0 : (int) ((upperProb / 0.3048) + .5));
1532 : } else {
1533 : /* Cumulative */
1534 0 : myAssert (timeIncrType == 192);
1535 : mallocSprintf (name, "ProbSurge%02dc",
1536 0 : (int) ((upperProb / 0.3048) + .5));
1537 : }
1538 : mallocSprintf (comment, "%02d hr Prob of Hurricane Storm Surge > %g "
1539 0 : "m [%%]", lenTime, upperProb);
1540 0 : *convert = UC_NONE;
1541 0 : return;
1542 : }
1543 : }
1544 0 : if (f_isNdfd) {
1545 : /*
1546 : * Deal with NDFD handling of Prob. Wind speeds.
1547 : * There are different solutions for naming the Prob. Wind fields
1548 : * Tim Boyer: TCWindSpdIncr34 TCWindSpdIncr50 TCWindSpdIncr64
1549 : * TCWindSpdCumu34 TCWindSpdCumu50 TCWindSpdCumu64
1550 : * Dave Ruth: tcwspdabv34i tcwspdabv50i tcwspdabv64i
1551 : * tcwspdabv34c tcwspdabv50c tcwspdabv64c
1552 : * AAT(Mine): ProbWindSpd34c ProbWindSpd50c ProbWindSpd64c
1553 : * ProbWindSpd34i ProbWindSpd50i ProbWindSpd64i
1554 : */
1555 0 : if ((prodType == 0) && (cat == 2) && (subcat == 1)) {
1556 0 : myAssert (probType == 1);
1557 0 : myAssert (lenTime > 0);
1558 0 : if (timeIncrType == 2) {
1559 : /* Incremental */
1560 : mallocSprintf (name, "ProbWindSpd%02di",
1561 0 : (int) ((upperProb * 3600. / 1852.) + .5));
1562 : } else {
1563 : /* Cumulative */
1564 0 : myAssert (timeIncrType == 192);
1565 : mallocSprintf (name, "ProbWindSpd%02dc",
1566 0 : (int) ((upperProb * 3600. / 1852.) + .5));
1567 : }
1568 : mallocSprintf (comment, "%02d hr Prob of Wind speed > %g m/s [%%]",
1569 0 : lenTime, upperProb);
1570 0 : *convert = UC_NONE;
1571 0 : return;
1572 : }
1573 : }
1574 :
1575 : /* Generic tables. */
1576 0 : table = Choose_GRIB2ParmTable (prodType, cat, &tableLen);
1577 0 : if (table != NULL) {
1578 0 : if (subcat < tableLen) {
1579 : /* Check for NDFD over-rides. */
1580 : /* The NDFD over-rides for probability templates have already been
1581 : * handled. */
1582 0 : if (lenTime > 0) {
1583 0 : mallocSprintf (name, "Prob%s%02d", table[subcat].name, lenTime);
1584 : mallocSprintf (comment, "%02d hr Prob of %s ", lenTime,
1585 0 : table[subcat].comment);
1586 : } else {
1587 0 : mallocSprintf (name, "Prob%s", table[subcat].name);
1588 0 : mallocSprintf (comment, "Prob of %s ", table[subcat].comment);
1589 : }
1590 0 : if (probType == 0) {
1591 : reallocSprintf (comment, "< %g %s [%%]", lowerProb,
1592 0 : table[subcat].unit);
1593 0 : } else if (probType == 1) {
1594 : reallocSprintf (comment, "> %g %s [%%]", upperProb,
1595 0 : table[subcat].unit);
1596 0 : } else if (probType == 2) {
1597 : reallocSprintf (comment, ">= %g, < %g %s [%%]", lowerProb,
1598 0 : upperProb, table[subcat].unit);
1599 0 : } else if (probType == 3) {
1600 : reallocSprintf (comment, "> %g %s [%%]", lowerProb,
1601 0 : table[subcat].unit);
1602 0 : } else if (probType == 4) {
1603 : reallocSprintf (comment, "< %g %s [%%]", upperProb,
1604 0 : table[subcat].unit);
1605 : } else {
1606 0 : reallocSprintf (comment, "%s [%%]", table[subcat].unit);
1607 : }
1608 0 : *convert = UC_NONE;
1609 0 : return;
1610 : }
1611 : }
1612 :
1613 : /* Local use tables. */
1614 0 : local = Choose_LocalParmTable (center, subcenter, &tableLen);
1615 0 : if (local != NULL) {
1616 0 : for (i = 0; i < tableLen; i++) {
1617 0 : if ((prodType == local[i].prodType) && (cat == local[i].cat) &&
1618 0 : (subcat == local[i].subcat)) {
1619 0 : if (lenTime > 0) {
1620 0 : mallocSprintf (name, "Prob%s%02d", local[i].name, lenTime);
1621 : mallocSprintf (comment, "%02d hr Prob of %s ", lenTime,
1622 0 : local[i].comment);
1623 : } else {
1624 0 : mallocSprintf (name, "Prob%s", local[i].name);
1625 0 : mallocSprintf (comment, "Prob of %s ", local[i].comment);
1626 : }
1627 0 : if (probType == 0) {
1628 : reallocSprintf (comment, "< %g %s [%%]", lowerProb,
1629 0 : local[i].unit);
1630 0 : } else if (probType == 1) {
1631 : reallocSprintf (comment, "> %g %s [%%]", upperProb,
1632 0 : local[i].unit);
1633 0 : } else if (probType == 2) {
1634 : reallocSprintf (comment, ">= %g, < %g %s [%%]", lowerProb,
1635 0 : upperProb, local[i].unit);
1636 0 : } else if (probType == 3) {
1637 : reallocSprintf (comment, "> %g %s [%%]", lowerProb,
1638 0 : local[i].unit);
1639 0 : } else if (probType == 4) {
1640 : reallocSprintf (comment, "< %g %s [%%]", upperProb,
1641 0 : local[i].unit);
1642 : } else {
1643 0 : reallocSprintf (comment, "%s [%%]", local[i].unit);
1644 : }
1645 0 : *convert = UC_NONE;
1646 0 : return;
1647 : }
1648 : }
1649 : }
1650 :
1651 0 : *name = (char *) malloc (strlen ("ProbUnknown") + 1);
1652 0 : strcpy (*name, "ProbUnknown");
1653 : mallocSprintf (comment, "Prob of (prodType %d, cat %d, subcat %d) [-]",
1654 0 : prodType, cat, subcat);
1655 0 : *convert = UC_NONE;
1656 0 : return;
1657 : }
1658 :
1659 : /* Deal with percentile templates 5/1/2006 */
1660 0 : static void ElemNamePerc (uShort2 center, uShort2 subcenter, int prodType,
1661 : int templat, uChar cat, uChar subcat, sInt4 lenTime,
1662 : sChar percentile, char **name, char **comment,
1663 : char **unit, int *convert)
1664 : {
1665 : GRIB2ParmTable *table;
1666 : GRIB2LocalTable *local;
1667 : size_t tableLen;
1668 : size_t i;
1669 :
1670 : /* Generic tables. */
1671 0 : table = Choose_GRIB2ParmTable (prodType, cat, &tableLen);
1672 0 : if (table != NULL) {
1673 0 : if (subcat < tableLen) {
1674 : /* Check for NDFD over-rides. */
1675 0 : if (IsData_NDFD (center, subcenter) ||
1676 : IsData_MOS (center, subcenter)) {
1677 0 : for (i = 0; i < (sizeof (NDFD_Overide) /
1678 : sizeof (NDFD_AbrevOverideTable)); i++) {
1679 0 : if (strcmp (NDFD_Overide[i].GRIB2name, table[subcat].name) ==
1680 : 0) {
1681 : mallocSprintf (name, "%s%02d", NDFD_Overide[i].NDFDname,
1682 0 : percentile);
1683 0 : if (lenTime > 0) {
1684 : mallocSprintf (comment, "%02d hr %s Percentile(%d) [%s]",
1685 0 : lenTime, table[subcat].comment,
1686 0 : percentile, table[subcat].unit);
1687 : } else {
1688 : mallocSprintf (comment, "%s Percentile(%d) [%s]",
1689 0 : table[subcat].comment, percentile,
1690 0 : table[subcat].unit);
1691 : }
1692 0 : mallocSprintf (unit, "[%s]", table[subcat].unit);
1693 0 : *convert = table[subcat].convert;
1694 0 : return;
1695 : }
1696 : }
1697 : }
1698 0 : mallocSprintf (name, "%s%02d", table[subcat].name, percentile);
1699 0 : if (lenTime > 0) {
1700 : mallocSprintf (comment, "%02d hr %s Percentile(%d) [%s]",
1701 0 : lenTime, table[subcat].comment, percentile,
1702 0 : table[subcat].unit);
1703 : } else {
1704 : mallocSprintf (comment, "%s Percentile(%d) [%s]",
1705 0 : table[subcat].comment, percentile,
1706 0 : table[subcat].unit);
1707 : }
1708 0 : mallocSprintf (unit, "[%s]", table[subcat].unit);
1709 0 : *convert = table[subcat].convert;
1710 0 : return;
1711 : }
1712 : }
1713 :
1714 : /* Local use tables. */
1715 0 : local = Choose_LocalParmTable (center, subcenter, &tableLen);
1716 0 : if (local != NULL) {
1717 0 : for (i = 0; i < tableLen; i++) {
1718 0 : if ((prodType == local[i].prodType) && (cat == local[i].cat) &&
1719 0 : (subcat == local[i].subcat)) {
1720 0 : mallocSprintf (name, "%s%02d", local[i].name, percentile);
1721 0 : if (lenTime > 0) {
1722 : mallocSprintf (comment, "%02d hr %s Percentile(%d) [%s]",
1723 0 : lenTime, local[i].comment, percentile,
1724 0 : local[i].unit);
1725 : } else {
1726 : mallocSprintf (comment, "%s Percentile(%d) [%s]",
1727 0 : local[i].comment, percentile, local[i].unit);
1728 : }
1729 0 : mallocSprintf (unit, "[%s]", local[i].unit);
1730 0 : *convert = local[i].convert;
1731 0 : return;
1732 : }
1733 : }
1734 : }
1735 :
1736 0 : *name = (char *) malloc (strlen ("unknown") + 1);
1737 0 : strcpy (*name, "unknown");
1738 : mallocSprintf (comment, "(prodType %d, cat %d, subcat %d) [-]", prodType,
1739 0 : cat, subcat);
1740 0 : *unit = (char *) malloc (strlen ("[-]") + 1);
1741 0 : strcpy (*unit, "[-]");
1742 0 : *convert = UC_NONE;
1743 0 : return;
1744 : }
1745 :
1746 : /* Deal with non-prob templates 2/16/2006 */
1747 4 : static void ElemNameNorm (uShort2 center, uShort2 subcenter, int prodType,
1748 : int templat, uChar cat, uChar subcat, sInt4 lenTime,
1749 : uChar timeIncrType, uChar genID, uChar probType,
1750 : double lowerProb, double upperProb, char **name,
1751 : char **comment, char **unit, int *convert)
1752 : {
1753 : GRIB2ParmTable *table;
1754 : GRIB2LocalTable *local;
1755 : size_t tableLen;
1756 : size_t i;
1757 : sChar f_accum;
1758 :
1759 : /* Check for over-ride case for ozone. Originally just for NDFD, but I
1760 : * think it is useful for ozone data that originated elsewhere. */
1761 4 : if ((prodType == 0) && (templat == 8) && (cat == 14) && (subcat == 193)) {
1762 0 : if (lenTime > 0) {
1763 0 : mallocSprintf (name, "Ozone%02d", lenTime);
1764 : mallocSprintf (comment, "%d hr Average Ozone Concentration "
1765 0 : "[PPB]", lenTime);
1766 : } else {
1767 0 : *name = (char *) malloc (strlen ("AVGOZCON") + 1);
1768 0 : strcpy (*name, "AVGOZCON");
1769 : *comment =
1770 : (char *) malloc (strlen ("Average Ozone Concentration [PPB]") +
1771 0 : 1);
1772 0 : strcpy (*comment, "Average Ozone Concentration [PPB]");
1773 : }
1774 0 : *unit = (char *) malloc (strlen ("[PPB]") + 1);
1775 0 : strcpy (*unit, "[PPB]");
1776 0 : *convert = UC_NONE;
1777 0 : return;
1778 : }
1779 :
1780 : /* Generic tables. */
1781 4 : table = Choose_GRIB2ParmTable (prodType, cat, &tableLen);
1782 4 : if (table != NULL) {
1783 4 : if (subcat < tableLen) {
1784 : /* Check for NDFD over-rides. */
1785 4 : if (IsData_NDFD (center, subcenter) ||
1786 : IsData_MOS (center, subcenter)) {
1787 12 : for (i = 0; i < (sizeof (NDFD_Overide) /
1788 : sizeof (NDFD_AbrevOverideTable)); i++) {
1789 12 : if (strcmp (NDFD_Overide[i].GRIB2name, table[subcat].name) ==
1790 : 0) {
1791 : *name =
1792 : (char *) malloc (strlen (NDFD_Overide[i].NDFDname) +
1793 4 : 1);
1794 4 : strcpy (*name, NDFD_Overide[i].NDFDname);
1795 4 : mallocSprintf (comment, "%s [%s]", table[subcat].comment,
1796 8 : table[subcat].unit);
1797 4 : mallocSprintf (unit, "[%s]", table[subcat].unit);
1798 4 : *convert = table[subcat].convert;
1799 4 : return;
1800 : }
1801 : }
1802 : }
1803 : /* Allow hydrologic PoP, thunderstorm probability (TSTM), or APCP to
1804 : * have lenTime labels. */
1805 : f_accum = (((prodType == 1) && (cat == 1) && (subcat == 2)) ||
1806 : ((prodType == 0) && (cat == 19) && (subcat == 2)) ||
1807 : ((prodType == 0) && (cat == 1) && (subcat == 8)) ||
1808 0 : ((prodType == 0) && (cat == 19) && (subcat == 203)));
1809 0 : if (f_accum && (lenTime > 0)) {
1810 0 : mallocSprintf (name, "%s%02d", table[subcat].name, lenTime);
1811 : mallocSprintf (comment, "%02d hr %s [%s]", lenTime,
1812 0 : table[subcat].comment, table[subcat].unit);
1813 : } else {
1814 0 : *name = (char *) malloc (strlen (table[subcat].name) + 1);
1815 0 : strcpy (*name, table[subcat].name);
1816 0 : mallocSprintf (comment, "%s [%s]", table[subcat].comment,
1817 0 : table[subcat].unit);
1818 : }
1819 0 : mallocSprintf (unit, "[%s]", table[subcat].unit);
1820 0 : *convert = table[subcat].convert;
1821 0 : return;
1822 : }
1823 : }
1824 :
1825 : /* Local use tables. */
1826 0 : local = Choose_LocalParmTable (center, subcenter, &tableLen);
1827 0 : if (local != NULL) {
1828 0 : for (i = 0; i < tableLen; i++) {
1829 0 : if ((prodType == local[i].prodType) && (cat == local[i].cat) &&
1830 0 : (subcat == local[i].subcat)) {
1831 : /* Allow specific products with non-zero lenTime to reflect that.
1832 : */
1833 0 : f_accum = 0;
1834 0 : if (f_accum && (lenTime > 0)) {
1835 0 : mallocSprintf (name, "%s%02d", local[i].name, lenTime);
1836 : mallocSprintf (comment, "%02d hr %s [%s]", lenTime,
1837 0 : local[i].comment, local[i].unit);
1838 : } else {
1839 0 : *name = (char *) malloc (strlen (local[i].name) + 1);
1840 0 : strcpy (*name, local[i].name);
1841 0 : mallocSprintf (comment, "%s [%s]", local[i].comment,
1842 0 : local[i].unit);
1843 : }
1844 0 : mallocSprintf (unit, "[%s]", local[i].unit);
1845 0 : *convert = local[i].convert;
1846 0 : return;
1847 : }
1848 : }
1849 : }
1850 :
1851 0 : *name = (char *) malloc (strlen ("unknown") + 1);
1852 0 : strcpy (*name, "unknown");
1853 : mallocSprintf (comment, "(prodType %d, cat %d, subcat %d) [-]", prodType,
1854 0 : cat, subcat);
1855 0 : *unit = (char *) malloc (strlen ("[-]") + 1);
1856 0 : strcpy (*unit, "[-]");
1857 0 : *convert = UC_NONE;
1858 0 : return;
1859 : }
1860 :
1861 4 : void ParseElemName (uShort2 center, uShort2 subcenter, int prodType,
1862 : int templat, int cat, int subcat, sInt4 lenTime,
1863 : uChar timeIncrType, uChar genID, uChar probType,
1864 : double lowerProb, double upperProb, char **name,
1865 : char **comment, char **unit, int *convert,
1866 : sChar percentile)
1867 : {
1868 4 : myAssert (*name == NULL);
1869 4 : myAssert (*comment == NULL);
1870 4 : myAssert (*unit == NULL);
1871 :
1872 : /* Check if this is Probability data */
1873 4 : if ((templat == GS4_PROBABIL_TIME) || (templat == GS4_PROBABIL_PNT)) {
1874 : ElemNameProb (center, subcenter, prodType, templat, cat, subcat,
1875 : lenTime, timeIncrType, genID, probType, lowerProb,
1876 0 : upperProb, name, comment, unit, convert);
1877 4 : } else if (templat == GS4_PERCENTILE) {
1878 : ElemNamePerc (center, subcenter, prodType, templat, cat, subcat,
1879 0 : lenTime, percentile, name, comment, unit, convert);
1880 : } else {
1881 : ElemNameNorm (center, subcenter, prodType, templat, cat, subcat,
1882 : lenTime, timeIncrType, genID, probType, lowerProb,
1883 4 : upperProb, name, comment, unit, convert);
1884 : }
1885 4 : }
1886 :
1887 : /*****************************************************************************
1888 : * ParseElemName2() -- Review 12/2002
1889 : *
1890 : * Arthur Taylor / MDL
1891 : *
1892 : * PURPOSE
1893 : * Converts a prodType, template, category and subcategory quadruple to the
1894 : * ASCII string abreviation of that variable.
1895 : * For example: 0, 0, 0, 0, = "T" for temperature.
1896 : *
1897 : * ARGUMENTS
1898 : * prodType = The GRIB2, section 0 product type. (Input)
1899 : * templat = The GRIB2 section 4 template number. (Input)
1900 : * cat = The GRIB2 section 4 "General category of Product." (Input)
1901 : * subcat = The GRIB2 section 4 "Specific subcategory of Product". (Input)
1902 : * name = Where to store the result (assumed already allocated to at
1903 : * least 15 bytes) (Output)
1904 : * comment = Extra info about variable (assumed already allocated to at
1905 : * least 100 bytes) (Output)
1906 : * unit = What unit this variable is in. (assumed already allocated to at
1907 : * least 20 bytes) (Output)
1908 : *
1909 : * FILES/DATABASES: None
1910 : *
1911 : * RETURNS: char *
1912 : * Same as 'strcpy', ie it returns name.
1913 : *
1914 : * HISTORY
1915 : * 9/2002 Arthur Taylor (MDL/RSIS): Created.
1916 : * 11/2002 AAT: Added MOIST_TOT_SNOW (and switched MOIST_SNOWAMT to
1917 : * SnowDepth)
1918 : * 12/2002 (TK,AC,TB,&MS): Code Review.
1919 : * 2/2003 AAT: moved from degrib.c to metaparse.c
1920 : * (Reason: primarily for Sect2 Parsing)
1921 : * (renamed from ElementName to ParseElemName)
1922 : * 4/2003 AAT: Added the comment as a return element.(see GRIB2 discipline)
1923 : * 6/2003 AAT: Added the unit as a return element.
1924 : * 6/2003 AAT: Added Wave Height.
1925 : *
1926 : * NOTES
1927 : * Similar to GRIB1_Table2LookUp... May want to take this and the unit
1928 : * stuff and combine them into a module.
1929 : *****************************************************************************
1930 : */
1931 : /*
1932 : static void ParseElemName2 (int prodType, int templat, int cat, int subcat,
1933 : char *name, char *comment, char *unit)
1934 : {
1935 : if (prodType == 0) {
1936 : if (cat == CAT_TEMP) { * 0 *
1937 : switch (subcat) {
1938 : case TEMP_TEMP: * 0 *
1939 : strcpy (comment, "Temperature [K]");
1940 : strcpy (name, "T");
1941 : strcpy (unit, "[K]");
1942 : return;
1943 : case TEMP_MAXT: * 4 *
1944 : strcpy (comment, "Maximum temperature [K]");
1945 : strcpy (name, "MaxT");
1946 : strcpy (unit, "[K]");
1947 : return;
1948 : case TEMP_MINT: * 5 *
1949 : strcpy (comment, "Minimum temperature [K]");
1950 : strcpy (name, "MinT");
1951 : strcpy (unit, "[K]");
1952 : return;
1953 : case TEMP_DEW_TEMP: * 6 *
1954 : strcpy (comment, "Dew point temperature [K]");
1955 : strcpy (name, "Td");
1956 : strcpy (unit, "[K]");
1957 : return;
1958 : case TEMP_WINDCHILL: * 13 *
1959 : strcpy (comment, "Wind chill factor [K]");
1960 : strcpy (name, "WCI");
1961 : strcpy (unit, "[K]");
1962 : return;
1963 : case TEMP_HEAT: * 12 *
1964 : strcpy (comment, "Heat index [K]");
1965 : strcpy (name, "HeatIndex");
1966 : strcpy (unit, "[K]");
1967 : return;
1968 : }
1969 : } else if (cat == CAT_MOIST) { * 1 *
1970 : switch (subcat) {
1971 : case MOIST_REL_HUMID: * 1 *
1972 : strcpy (comment, "Relative Humidity [%]");
1973 : strcpy (name, "RH");
1974 : strcpy (unit, "[%]");
1975 : return;
1976 : case MOIST_PRECIP_TOT: * 8 *
1977 : if (templat == GS4_PROBABIL_TIME) { * template number 9 implies prob. *
1978 : strcpy (comment, "Prob of 0.01 In. of Precip [%]");
1979 : strcpy (name, "PoP12");
1980 : strcpy (unit, "[%]");
1981 : return;
1982 : } else {
1983 : strcpy (comment, "Total precipitation [kg/(m^2)]");
1984 : strcpy (name, "QPF");
1985 : strcpy (unit, "[kg/(m^2)]");
1986 : return;
1987 : }
1988 : case MOIST_SNOWAMT: * 11 *
1989 : strcpy (comment, "Snow Depth [m]");
1990 : strcpy (name, "SnowDepth");
1991 : strcpy (unit, "[m]");
1992 : return;
1993 : case MOIST_TOT_SNOW: * 29 *
1994 : strcpy (comment, "Total snowfall [m]");
1995 : strcpy (name, "SnowAmt");
1996 : strcpy (unit, "[m]");
1997 : return;
1998 : case 192: * local use moisture. *
1999 : strcpy (comment, "Weather (local use moisture) [-]");
2000 : strcpy (name, "Wx");
2001 : strcpy (unit, "[-]");
2002 : return;
2003 : }
2004 : } else if (cat == CAT_MOMENT) { * 2 *
2005 : switch (subcat) {
2006 : case MOMENT_WINDDIR: * 0 *
2007 : strcpy (comment, "Wind direction (from which blowing) "
2008 : "[deg true]");
2009 : strcpy (name, "WindDir");
2010 : strcpy (unit, "[deg true]");
2011 : return;
2012 : case MOMENT_WINDSPD: * 1 *
2013 : strcpy (comment, "Wind speed [m/s]");
2014 : strcpy (name, "WindSpd");
2015 : strcpy (unit, "[m/s]");
2016 : return;
2017 : }
2018 : } else if (cat == CAT_CLOUD) { * 6 *
2019 : switch (subcat) {
2020 : case CLOUD_COVER: * 1 *
2021 : strcpy (comment, "Total cloud cover [%]");
2022 : strcpy (name, "Sky");
2023 : strcpy (unit, "[%]");
2024 : return;
2025 : }
2026 : } else if (cat == CAT_MOISTURE_PROB) { * 10 *
2027 : if (subcat == 8) { * grandfather'ed in. *
2028 : strcpy (comment, "Prob of 0.01 In. of Precip [%]");
2029 : strcpy (name, "PoP12");
2030 : strcpy (unit, "[%]");
2031 : return;
2032 : }
2033 : }
2034 : } else if (prodType == 10) {
2035 : if (cat == OCEAN_CAT_WAVES) { * 0 *
2036 : if (subcat == OCEAN_WAVE_SIG_HT_WV) { * 5 *
2037 : strcpy (comment, "Significant height of wind waves [m]");
2038 : strcpy (name, "WaveHeight");
2039 : strcpy (unit, "[m]");
2040 : return;
2041 : }
2042 : }
2043 : }
2044 : strcpy (name, "");
2045 : strcpy (comment, "unknown");
2046 : strcpy (unit, "[-]");
2047 : return;
2048 : }
2049 : */
2050 :
2051 : /*****************************************************************************
2052 : * ComputeUnit() --
2053 : *
2054 : * Arthur Taylor / MDL
2055 : *
2056 : * PURPOSE
2057 : * Sets m, and b for equation y = mx + b, where x is in the unit
2058 : * specified by GRIB2, and y is the one specified by f_unit. The default
2059 : * is m = 1, b = 0.
2060 : *
2061 : * Currently:
2062 : * For f_unit = 1 (english) we return Fahrenheit, knots, and inches for
2063 : * temperature, wind speed, and amount of snow or rain. The original units
2064 : * are Kelvin, m/s, kg/m**2.
2065 : * For f_unit = 2 (metric) we return Celsius instead of Kelvin.
2066 : *
2067 : * ARGUMENTS
2068 : * convert = The enumerated type describing the type of conversion. (Input)
2069 : * origName = Original unit name (needed for log10 option) (Input)
2070 : * f_unit = What type of unit to return (see above) (Input).
2071 : * unitM = M in equation y = m x + b (Output)
2072 : * unitB = B in equation y = m x + b (Output)
2073 : * name = Where to store the result (assumed already allocated to at
2074 : * least 15 bytes) (Output)
2075 : *
2076 : * FILES/DATABASES: None
2077 : *
2078 : * RETURNS: int
2079 : * 0 if we set M and B, 1 if we used defaults.
2080 : *
2081 : * HISTORY
2082 : * 1/2004 Arthur Taylor (MDL/RSIS): Re-Created.
2083 : *
2084 : * NOTES
2085 : *****************************************************************************
2086 : */
2087 6 : int ComputeUnit (int convert, char *origName, sChar f_unit, double *unitM,
2088 : double *unitB, char *name)
2089 : {
2090 6 : switch (convert) {
2091 : case UC_NONE:
2092 4 : break;
2093 : case UC_K2F: /* Convert from Kelvin to F or C. */
2094 2 : if (f_unit == 1) {
2095 0 : strcpy (name, "[F]");
2096 0 : *unitM = 9. / 5.;
2097 : /* 32 - (9/5 * 273.15) = 32 - 491.67 = -459.67. */
2098 0 : *unitB = -459.67;
2099 0 : return 0;
2100 2 : } else if (f_unit == 2) {
2101 2 : strcpy (name, "[C]");
2102 2 : *unitM = 1;
2103 2 : *unitB = -273.15;
2104 2 : return 0;
2105 : }
2106 0 : break;
2107 : case UC_InchWater: /* Convert from kg/(m^2) to inches water. */
2108 0 : if (f_unit == 1) {
2109 0 : strcpy (name, "[inch]");
2110 : /*
2111 : * kg/m**2 / density of water (1000 kg/m**3)
2112 : * 1/1000 m * 1/2.54 in/cm * 100 cm/m = 1/25.4 inches
2113 : */
2114 0 : *unitM = 1. / 25.4;
2115 0 : *unitB = 0;
2116 0 : return 0;
2117 : }
2118 0 : break;
2119 : case UC_M2Feet: /* Convert from meters to feet. */
2120 0 : if (f_unit == 1) {
2121 : /* 1 (m) * (100cm/m) * (inch/2.54cm) * (ft/12inch) = X (ft) */
2122 0 : strcpy (name, "[feet]");
2123 0 : *unitM = 100. / 30.48;
2124 0 : *unitB = 0;
2125 0 : return 0;
2126 : }
2127 0 : break;
2128 : case UC_M2Inch: /* Convert from meters to inches. */
2129 0 : if (f_unit == 1) {
2130 0 : strcpy (name, "[inch]");
2131 0 : *unitM = 100. / 2.54; /* inch / m */
2132 0 : *unitB = 0;
2133 0 : return 0;
2134 : }
2135 0 : break;
2136 : /* NCEP goes with a convention of 1 nm = 1853.248 m.
2137 : * http://www.sizes.com/units/mile_USnautical.htm Shows that on
2138 : * 7/1/1954 US Department of Commerce switched to 1 nm = 1852 m
2139 : * (International standard.) */
2140 : case UC_MS2Knots: /* Convert from m/s to knots. */
2141 0 : if (f_unit == 1) {
2142 0 : strcpy (name, "[knots]");
2143 0 : *unitM = 3600. / 1852.; /* knot / m s**-1 */
2144 0 : *unitB = 0;
2145 0 : return 0;
2146 : }
2147 0 : break;
2148 : case UC_LOG10: /* convert from log10 (x) to x */
2149 0 : if ((f_unit == 1) || (f_unit == 2)) {
2150 0 : origName[strlen (origName) - 2] = '\0';
2151 0 : if (strlen (origName) > 21)
2152 0 : origName[21] = '\0';
2153 0 : sprintf (name, "[%s]", origName + 7);
2154 0 : *unitM = -10; /* M = -10 => take 10^(x) */
2155 0 : *unitB = 0;
2156 0 : return 0;
2157 : }
2158 : break;
2159 : }
2160 : /* Default case is for the unit in the GRIB2 document. */
2161 4 : strcpy (name, "[GRIB2 unit]");
2162 4 : *unitM = 1;
2163 4 : *unitB = 0;
2164 4 : return 1;
2165 : }
2166 :
2167 : /*****************************************************************************
2168 : * ComputeUnit2() --
2169 : *
2170 : * Arthur Taylor / MDL
2171 : *
2172 : * PURPOSE
2173 : * Sets m, and b for equation y = mx + b, where x is in the unit
2174 : * specified by GRIB2, and y is the one specified by f_unit. The default
2175 : * is m = 1, b = 0.
2176 : *
2177 : * Currently:
2178 : * For f_unit = 1 (english) we return Fahrenheit, knots, and inches for
2179 : * temperature, wind speed, and amount of snow or rain. The original units
2180 : * are Kelvin, m/s, kg/m**2.
2181 : * For f_unit = 2 (metric) we return Celsius instead of Kelvin.
2182 : *
2183 : * ARGUMENTS
2184 : * prodType = The GRIB2, section 0 product type. (Input)
2185 : * templat = The GRIB2 section 4 template number. (Input)
2186 : * cat = The GRIB2 section 4 "General category of Product." (Input)
2187 : * subcat = The GRIB2 section 4 "Specific subcategory of Product". (Input)
2188 : * f_unit = What type of unit to return (see above) (Input).
2189 : * unitM = M in equation y = m x + b (Output)
2190 : * unitB = B in equation y = m x + b (Output)
2191 : * name = Where to store the result (assumed already allocated to at
2192 : * least 15 bytes) (Output)
2193 : *
2194 : * FILES/DATABASES: None
2195 : *
2196 : * RETURNS: int
2197 : * 0 if we set M and B, 1 if we used defaults.
2198 : *
2199 : * HISTORY
2200 : * 11/2002 Arthur Taylor (MDL/RSIS): Created.
2201 : *
2202 : * NOTES
2203 : *****************************************************************************
2204 : */
2205 : /*
2206 : static int ComputeUnit2 (int prodType, int templat, int cat, int subcat,
2207 : sChar f_unit, double *unitM, double *unitB,
2208 : char *name)
2209 : {
2210 : if (prodType == 0) {
2211 : switch (cat) {
2212 : case CAT_TEMP:
2213 : * subcat 8 is K/m, 10, 11 is W/m**2 *
2214 : if ((subcat < 16) && (subcat != 8) &&
2215 : (subcat != 10) && (subcat != 11)) {
2216 : if (f_unit == 1) {
2217 : strcpy (name, "[F]");
2218 : *unitM = 9. / 5.;
2219 : * 32 - (9/5 * 273.15) = 32 - 491.67 = -459.67. *
2220 : *unitB = -459.67;
2221 : return 0;
2222 : } else if (f_unit == 2) {
2223 : strcpy (name, "[C]");
2224 : *unitM = 1;
2225 : *unitB = -273.15;
2226 : return 0;
2227 : }
2228 : }
2229 : break;
2230 : case CAT_MOIST:
2231 : if (subcat == MOIST_PRECIP_TOT) {
2232 : if (templat != 9) { * template number != 9 implies QPF. *
2233 : if (f_unit == 1) {
2234 : strcpy (name, "[inch]");
2235 : *
2236 : * kg/m**2 / density of water (1000 kg/m**3)
2237 : * 1/1000 m * 1/2.54 in/cm * 100 cm/m = 1/25.4 inches
2238 : *
2239 : *unitM = 1. / 25.4;
2240 : *unitB = 0;
2241 : return 0;
2242 : }
2243 : }
2244 : }
2245 : if ((subcat == MOIST_SNOWAMT) || (subcat == MOIST_TOT_SNOW)) {
2246 : if (f_unit == 1) {
2247 : strcpy (name, "[inch]");
2248 : *unitM = 100. / 2.54; * inch / m *
2249 : *unitB = 0;
2250 : return 0;
2251 : }
2252 : }
2253 : break;
2254 : case CAT_MOMENT:
2255 : if (subcat == MOMENT_WINDSPD) {
2256 : if (f_unit == 1) {
2257 : strcpy (name, "[knots]");
2258 : *unitM = 3600. / 1852.; * knot / m s**-1 *
2259 : *unitB = 0;
2260 : return 0;
2261 : }
2262 : }
2263 : break;
2264 : }
2265 : } else if (prodType == 10) {
2266 : if (cat == OCEAN_CAT_WAVES) { * 0 *
2267 : if (subcat == OCEAN_WAVE_SIG_HT_WV) { * 5 *
2268 : if (f_unit == 1) {
2269 : * 1 (m) * (100cm/m) * (inch/2.54cm) * (ft/12inch) = X (ft) *
2270 : strcpy (name, "[feet]");
2271 : *unitM = 100. / 30.48;
2272 : *unitB = 0;
2273 : return 0;
2274 : }
2275 : }
2276 : }
2277 : }
2278 : * Default case is for the unit in the GRIB2 document. *
2279 : strcpy (name, "[GRIB2 unit]");
2280 : *unitM = 1;
2281 : *unitB = 0;
2282 : return 1;
2283 : }
2284 : */
2285 :
2286 : /* GRIB2 Code Table 4.5 */
2287 : /* *INDENT-OFF* */
2288 : GRIB2SurfTable Surface[] = {
2289 : /* 0 */ {"RESERVED", "Reserved", "-"},
2290 : /* 1 */ {"SFC", "Ground or water surface", "-"},
2291 : /* 2 */ {"CBL", "Cloud base level", "-"},
2292 : /* 3 */ {"CTL", "Level of cloud tops", "-"},
2293 : /* 4 */ {"0DEG", "Level of 0 degree C isotherm", "-"},
2294 : /* 5 */ {"ADCL", "Level of adiabatic condensation lifted from the surface", "-"},
2295 : /* 6 */ {"MWSL", "Maximum wind level", "-"},
2296 : /* 7 */ {"TRO", "Tropopause", "-"},
2297 : /* 8 */ {"NTAT", "Nominal top of atmosphere", "-"},
2298 : /* 9 */ {"SEAB", "Sea bottom", "-"},
2299 : /* 10: 10-19 */ {"RESERVED", "Reserved", "-"},
2300 : /* 11: 20 */ {"TMPL", "Isothermal level", "K"},
2301 : /* 12: 21-99 */ {"RESERVED", "Reserved", "-"},
2302 : /* 13: 100 */ {"ISBL", "Isobaric surface", "Pa"},
2303 : /* 14: 101 */ {"MSL", "Mean sea level", "-"},
2304 : /* 15: 102 */ {"GPML", "Specific altitude above mean sea level", "m"},
2305 : /* 16: 103 */ {"HTGL", "Specified height level above ground", "m"},
2306 : /* 17: 104 */ {"SIGL", "Sigma level", "'sigma' value"},
2307 : /* 18: 105 */ {"HYBL", "Hybrid level", "-"},
2308 : /* 19: 106 */ {"DBLL", "Depth below land surface", "m"},
2309 : /* 20: 107 */ {"THEL", "Isentropic (theta) level", "K"},
2310 : /* 21: 108 */ {"SPDL", "Level at specified pressure difference from ground to level", "Pa"},
2311 : /* 22: 109 */ {"PVL", "Potential vorticity surface", "(K m^2)/(kg s)"},
2312 : /* 23: 110 */ {"RESERVED", "Reserved", "-"},
2313 : /* 24: 111 */ {"EtaL", "Eta* level", "-"},
2314 : /* 25: 112-116 */ {"RESERVED", "Reserved", "-"},
2315 : /* 26: 117 */ {"unknown", "Mixed layer depth", "m"}, /* unknown abbrev */
2316 : /* 27: 118-159 */ {"RESERVED", "Reserved", "-"},
2317 : /* 28: 160 */ {"DBSL", "Depth below sea level", "m"},
2318 : /* 29: 161-191 */ {"RESERVED", "Reserved", "-"},
2319 : /* 30: 192-254 */ {"RESERVED", "Reserved Local use", "-"},
2320 : /* 31: 255 */ {"MISSING", "Missing", "-"},
2321 : };
2322 :
2323 : typedef struct {
2324 : int index;
2325 : GRIB2SurfTable surface;
2326 : } GRIB2LocalSurface;
2327 :
2328 : /* based on http://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_table4-5.shtml
2329 : * updated last on 3/14/2006 */
2330 : GRIB2LocalSurface NCEP_Surface[] = {
2331 : {200, {"EATM", "Entire atmosphere (considerd as a single layer)", "-"}},
2332 : {201, {"EOCN", "Entire ocean (considered as a single layer)", "-"}},
2333 : {204, {"HTFL", "Highest tropospheric freezing level", "-"}},
2334 : {206, {"GCBL", "Grid scale cloud bottom level", "-"}},
2335 : {207, {"GCTL", "Grid scale cloud top level", "-"}},
2336 : {209, {"BCBL", "Boundary layer cloud bottom level", "-"}},
2337 : {210, {"BCTL", "Boundary layer cloud top level", "-"}},
2338 : {211, {"BCY", "Boundary layer cloud level", "-"}},
2339 : {212, {"LCBL", "Low cloud bottom level", "-"}},
2340 : {213, {"LCTL", "Low cloud top level", "-"}},
2341 : {214, {"LCY", "Low cloud level", "-"}},
2342 : {215, {"CEIL", "Cloud ceiling", "-"}},
2343 : {222, {"MCBL", "Middle cloud bottom level", "-"}},
2344 : {223, {"MCTL", "Middle cloud top level", "-"}},
2345 : {224, {"MCY", "Middle cloud level", "-"}},
2346 : {232, {"HCBL", "High cloud bottom level", "-"}},
2347 : {233, {"HCTL", "High cloud top level", "-"}},
2348 : {234, {"HCY", "High cloud level", "-"}},
2349 : {235, {"OITL", "Ocean Isotherm Level (1/10 deg C)", "-"}},
2350 : {236, {"OLYR", "Layer between two depths below ocean surface", "-"}},
2351 : {237, {"OBML", "Bottom of Ocean Mixed Layer (m)", "-"}},
2352 : {238, {"OBIL", "Bottom of Ocean Isothermal Layer (m)", "-"}},
2353 : {242, {"CCBL", "Convective cloud bottom level", "-"}},
2354 : {243, {"CCTL", "Convective cloud top level", "-"}},
2355 : {244, {"CCY", "Convective cloud level", "-"}},
2356 : {245, {"LLTW", "Lowest level of the wet bulb zero", "-"}},
2357 : {246, {"MTHE", "Maximum equivalent potential temperature level", "-"}},
2358 : {247, {"EHLT", "Equilibrium level", "-"}},
2359 : {248, {"SCBL", "Shallow convective cloud bottom level", "-"}},
2360 : {249, {"SCTL", "Shallow convective cloud top level", "-"}},
2361 : {251, {"DCBL", "Deep convective cloud bottom level", "-"}},
2362 : {252, {"DCTL", "Deep convective cloud top level", "-"}},
2363 : {253, {"LBLSW", "Lowest bottom level of supercooled liquid water layer", "-"}},
2364 : {254, {"HTLSW", "Highest top level of supercooled liquid water layer", "-"}},
2365 : };
2366 : /* *INDENT-ON* */
2367 :
2368 : /*****************************************************************************
2369 : * Table45Index() --
2370 : *
2371 : * Arthur Taylor / MDL
2372 : *
2373 : * PURPOSE
2374 : * To figure out the entry in the "Surface" table (used for Code Table 4.5)
2375 : *
2376 : * ARGUMENTS
2377 : * i = The original index to look up. (Input)
2378 : * f_reserved = If the index is a "reserved" index (Output)
2379 : *
2380 : * FILES/DATABASES: None
2381 : *
2382 : * RETURNS: GRIB2SurfTable
2383 : *
2384 : * HISTORY
2385 : * 9/2002 Arthur Taylor (MDL/RSIS): Created.
2386 : * 12/2004 Arthur Taylor (RSIS): Modified to return SurfaceTable.
2387 : *
2388 : * NOTES
2389 : *****************************************************************************
2390 : */
2391 4 : GRIB2SurfTable Table45Index (int i, int *f_reserved, uShort2 center,
2392 : uShort2 subcenter)
2393 : {
2394 : size_t j;
2395 :
2396 4 : *f_reserved = 1;
2397 4 : if ((i > 255) || (i < 0)) {
2398 : #ifdef DEBUG
2399 0 : printf ("Surface index is out of 0..255 range?\n");
2400 : #endif
2401 0 : return Surface[0];
2402 : }
2403 4 : if (i == 255)
2404 0 : return Surface[31];
2405 4 : if (i > 191) {
2406 0 : if (center == 7) {
2407 0 : for (j = 0; j < sizeof (NCEP_Surface) / sizeof (NCEP_Surface[0]);
2408 : j++) {
2409 0 : if (i == NCEP_Surface[j].index) {
2410 0 : *f_reserved = 0;
2411 0 : return (NCEP_Surface[j].surface);
2412 : }
2413 : }
2414 : }
2415 0 : return Surface[30];
2416 : }
2417 4 : if (i > 160)
2418 0 : return Surface[29];
2419 4 : if (i == 160) {
2420 0 : *f_reserved = 0;
2421 0 : return Surface[28];
2422 : }
2423 4 : if (i > 117)
2424 0 : return Surface[27];
2425 4 : if (i == 117) {
2426 0 : *f_reserved = 0;
2427 0 : return Surface[26];
2428 : }
2429 4 : if (i > 111)
2430 0 : return Surface[25];
2431 4 : if (i == 111) {
2432 0 : *f_reserved = 0;
2433 0 : return Surface[i - 87];
2434 : }
2435 4 : if (i == 110)
2436 0 : return Surface[i - 87];
2437 4 : if (i > 99) {
2438 0 : *f_reserved = 0;
2439 0 : return Surface[i - 87];
2440 : }
2441 4 : if (i > 20)
2442 0 : return Surface[12];
2443 4 : if (i == 20) {
2444 0 : *f_reserved = 0;
2445 0 : return Surface[11];
2446 : }
2447 4 : if (i > 9)
2448 0 : return Surface[10];
2449 4 : if (i > 0) {
2450 4 : *f_reserved = 0;
2451 4 : return Surface[i];
2452 : }
2453 0 : return Surface[0];
2454 : }
2455 :
2456 4 : void ParseLevelName (unsigned short int center, unsigned short int subcenter,
2457 : uChar surfType, double value, sChar f_sndValue,
2458 : double sndValue, char **shortLevelName,
2459 : char **longLevelName)
2460 : {
2461 : int f_reserved;
2462 : char valBuff[512];
2463 : char sndBuff[512];
2464 : GRIB2SurfTable surf = Table45Index (surfType, &f_reserved, center,
2465 4 : subcenter);
2466 :
2467 : /* Check if index is defined... 191 is undefined. */
2468 4 : free (*shortLevelName);
2469 4 : *shortLevelName = NULL;
2470 4 : free (*longLevelName);
2471 4 : *longLevelName = NULL;
2472 4 : sprintf (valBuff, "%f", value);
2473 4 : strTrimRight (valBuff, '0');
2474 4 : if (valBuff[strlen (valBuff) - 1] == '.') {
2475 4 : valBuff[strlen (valBuff) - 1] = '\0';
2476 : }
2477 4 : if (f_sndValue) {
2478 0 : sprintf (sndBuff, "%f", sndValue);
2479 0 : strTrimRight (sndBuff, '0');
2480 0 : if (sndBuff[strlen (sndBuff) - 1] == '.') {
2481 0 : sndBuff[strlen (sndBuff) - 1] = '\0';
2482 : }
2483 0 : if (f_reserved) {
2484 : reallocSprintf (shortLevelName, "%s-%s-%s(%d)", valBuff, sndBuff,
2485 0 : surf.name, surfType);
2486 : reallocSprintf (longLevelName, "%s-%s[%s] %s(%d) (%s)", valBuff,
2487 : sndBuff, surf.unit, surf.name, surfType,
2488 0 : surf.comment);
2489 : } else {
2490 : reallocSprintf (shortLevelName, "%s-%s-%s", valBuff, sndBuff,
2491 0 : surf.name);
2492 : reallocSprintf (longLevelName, "%s-%s[%s] %s=\"%s\"", valBuff,
2493 0 : sndBuff, surf.unit, surf.name, surf.comment);
2494 : }
2495 : } else {
2496 4 : if (f_reserved) {
2497 : reallocSprintf (shortLevelName, "%s-%s(%d)", valBuff, surf.name,
2498 0 : surfType);
2499 : reallocSprintf (longLevelName, "%s[%s] %s(%d) (%s)", valBuff,
2500 0 : surf.unit, surf.name, surfType, surf.comment);
2501 : } else {
2502 4 : reallocSprintf (shortLevelName, "%s-%s", valBuff, surf.name);
2503 : reallocSprintf (longLevelName, "%s[%s] %s=\"%s\"", valBuff,
2504 4 : surf.unit, surf.name, surf.comment);
2505 : }
2506 : }
2507 4 : }
|