source: trunk/WRF.COMMON/WRFV2/external/io_grib1/MEL_grib1/ld_dec_lookup.c

Last change on this file was 11, checked in by aslmd, 14 years ago

spiga@svn-planeto:ajoute le modele meso-echelle martien

File size: 25.9 KB
Line 
1/*  FILENAME:   ld_dec_lookup.c
2Revision logs:
316Jul97 /atn: clear Decoder section of structs only; chg warnings to Stdout;
4*/
5#include <stdio.h>
6#include <string.h>
7#include <stdlib.h>
8#include "grib_lookup.h"        /* combined lookup structs */
9#include "dprints.h"            /* for dprints */
10#include "gribfuncs.h"          /* prototypes */
11
12/*
13*.....................................................
14*  ld_dec_lookup.c defines the following global vars:
15*.....................................................
16*  PARM_DEFN  db_parm_tbl[NPARM*MAX_PARM_TBLS]   Parameter Conversion info
17*  LVL_DEFN   db_lvl_tbl[NLEV]                  Level Conversion info
18*  MODEL_DEFN db_mdl_tbl[NMODEL]                 Model Conversion info
19*  GEOM_DEFN  db_geom_tbl[NGEOM]                 Geom Conversion info
20*             
21*/
22PARM_DEFN   db_parm_tbl [NPARM*MAX_PARM_TBLS];/* GLOBVAR parm conversion info*/
23LVL_DEFN    db_lvl_tbl [NLEV];    /* GLOBVAR level conversion info */
24MODEL_DEFN  db_mdl_tbl [NMODEL];  /* GLOBVAR model conversion info */
25GEOM_DEFN   db_geom_tbl [NGEOM];  /* GLOBVAR Geom conversion info */
26
27/*
28**********************************************************************
29* A.  FUNCTION:      ld_dec_lookup
30*        This function reads in the information from an external Lookup
31*        table (ie: g1tab_2.1).  This info is used to convert
32*        from the Database's parameter names to the GRIB Code Numbers.
33*
34*    INTERFACE:
35*       int ld_dec_lookup (lookup_fn,  errmsg)
36*
37*    ARGUMENTS (I=input, O=output, I&O=input and output):
38*      (I)  char *lookup_fn
39*           Name of Lookup file to read from (ie:  /abspath/g1tab_128_2.1)
40*      (O)  char *errmsg
41*           empty array, returned filled if error occurred;
42*
43*     RETURN CODE:
44*        0>  successful, the 4 database tables Filled;
45*        1>  file open error or got error/eof while reading;  errmsg filled;
46**********************************************************************
47*
48-    REQUIREMENTS:  *** do not use the TAB character !!! ***
49-     Rules for creating Decoder Lookup file:
50-     a)  lines starting out with  '#' is Comment lines & are skipped;   
51-     b)  the tables within the file are defined in this order:
52-         'GRIB Table 2',
53-         'GRIB Table 2 - Sub A',
54-         'GRIB Table 2 - Sub B',
55-         'GRIB Table 2 - Sub C',
56-         'GRIB Table 2 - Sub D',
57-         'GRIB Table 2 - Sub E',
58-         'GRIB Table 3: Level Definitions',
59-         'GRIB Table - Generating Process Definitions (Octet 6 of PDS)',
60-         'GRIB Table - Pre-defined geometries (Octet 7 of PDS)'
61-     c)  Each Header section MUST start out with "GRIB Table";
62-         All Header Section except that of the LEVEL tbl MUST end with a line
63-         containing atleast 4 consecutives '=';
64-     e)  Header lines are any number of lines before the '===' line which is
65-         considered as a the last line of this section's Header;
66-     f)  the Parameter defn (Table 2 & subTables) must have at least 2 spaces
67-         between the Field Parameter and Unit fields;
68-
69-     While getting entries for current table, the program assumes it has
70-     gotten to the end of current Table if Hdr SEction for next Table
71-     (string "GRIB Table").
72*/
73
74#if PROTOTYPE_NEEDED
75int  ld_dec_lookup ( char *lookup_fn, char *errmsg)
76#else
77int  ld_dec_lookup ( lookup_fn, errmsg)
78                     char *lookup_fn; 
79                     char *errmsg;
80#endif
81{
82  FILE  *infile;
83  char  *func="ld_dec_lookup", line[200], temp[200], dummy;
84  char  *ptr2, *ptr, strGribCode[50], grib_dsc[150], grib_unit_dsc[150]; 
85  char  strScale[50], strOffset[50], strDSF[50];
86  char  lvl_name_1[150], lvl_name_2[150];
87  int   LineRead, indx, sub, stat=1, num, cnt, iOctets;
88  char  strOctets[30]; 
89  int   GribCode;
90  PARM_DEFN *parmptr;   /* ptr to cell w/in Parm array */
91
92  DPRINT1 ("Entering %s\n", func);
93/*
94* A.0       CLEAR out all the lookup arrays's decoder part
95*/
96  for (num=0; num < NPARM ; num++) {
97        db_parm_tbl[num].usParm_id=  num;
98        db_parm_tbl[num].usParm_sub= 0;       /* not used for main tbl */
99        db_parm_tbl[num].grib_dsc[0] ='\0';
100        db_parm_tbl[num].grib_unit_dsc[0] ='\0';
101        }
102  for (num=NPARM; num < NPARM * MAX_PARM_TBLS; num++) {  /* for sub-tbls */
103        db_parm_tbl[num].usParm_id=  249 + num / NPARM;
104        db_parm_tbl[num].usParm_sub= num % NPARM;
105        db_parm_tbl[num].grib_dsc[0] ='\0';
106        db_parm_tbl[num].grib_unit_dsc[0] ='\0';
107        }
108
109  for (num=0; num < NLEV; num++) {
110        db_lvl_tbl[num].usLevel_id =  num;
111        db_lvl_tbl[num].grib_dsc[0] = '\0';
112        db_lvl_tbl[num].lvl_name_1[0] = '\0';
113        db_lvl_tbl[num].lvl_name_2[0] = '\0';
114        db_lvl_tbl[num].num_octets = 0;
115        }
116
117  for (num=0; num < NMODEL; num++) {
118        db_mdl_tbl[num].usModel_id  = num;
119        db_mdl_tbl[num].grib_dsc[0] = '\0';
120        }
121
122  for (num=0; num < NGEOM; num++) {
123        db_geom_tbl[num].usGeom_id  = num;
124        db_geom_tbl[num].grib_dsc[0] = '\0';
125        }
126
127/*
128*
129* A.1       OPEN Lookup file for reading
130*           RETURN 1 if fails;
131*/
132  infile = fopen(lookup_fn, "r");
133  if (infile==NULL) { 
134        DPRINT2 ("%s:  failed to open %s\n", func, lookup_fn);
135        sprintf (errmsg ,"%s:  failed to open %s\n", func, lookup_fn);
136        goto BYE;
137        }
138  DPRINT1 ("Loading Decoder file= '%s'\n", lookup_fn);
139
140/**** PARM SECTION (TABLE 0/A/B/C/D/E) ***
141 To be loaded continuously where Main tbl range is 0-255, B is 256-511, ...
142Sample:
143   GRIB Table 2
144   Code Figure    Field Parameter                                       Unit
145   ===========    ===============                                       ====
146   000            Reserved                                              *
147   001            Pressure                                              Pa
148   002            Pressure reduced to MSL                               Pa
149   003            Pressure tendency                                     Pa/s
150   #####################################################################
151   GRIB Table 2 - Sub A
152   Code Figure    Field Parameter                                       Unit
153   ===========    ===============                                       ====
154   ######################################################################
155   GRIB Table 2 - Sub B
156   Code Figure    Field Parameter                                       Unit
157   ===========    ===============                                       ====
158   ######################################################################
159   GRIB Table 2 - Sub C
160   Code Figure    Field Parameter                                       Unit
161   ===========    ===============                                       ====
162   ######################################################################
163   GRIB Table 2 - Sub D
164   Code Figure    Field Parameter                                       Unit
165   ===========    ===============                                       ====
166   ######################################################################
167
168*
169*           *** Parameter Conversion info ***
170* A.2       FOR (each Parameter Table/subTable to load) DO
171*/
172 LineRead = 0;
173 for (sub=0; sub < 6; sub++)   { /* 6 Parm tables altogether (0/A/B/C/D/E) */
174/*
175* A.2.1       CALCULATE the index offset for this Table within the Parm array
176*/
177     indx = sub * 256; 
178
179/*
180* A.2.2       KEEP reading until end of comment line (line with '====')
181*             RETURN error if fails
182*/
183     /* Read until last of Header line */
184     for (line[0]='\0'; ! strstr(line,"====") ; ) 
185     {
186       fgets(line, sizeof(line), infile);  ++LineRead;
187       if (feof(infile) || ferror(infile)) 
188         { sprintf(errmsg,
189           "%s: got EOF/ERROR before PARM TABLE #%d info (Line %d in %s)\n", 
190            func, sub, LineRead, lookup_fn);
191           goto BYE;
192         }
193      }
194
195/*
196* A.2.3       FOR (successfully read a line from file) DO
197*                LOOP if it's a comment line
198*                BREAK out if already got to next Section (see "GRIB Table")
199*                DROP line if it's a empty line
200*/
201  DPRINT2("*** %s: Start reading Tbl2- sub#%d ***\n", func, sub);
202  for (cnt=0 ; fgets(line, sizeof(line), infile)!=NULL; ) 
203    { 
204        ++LineRead;
205       /* skip additional comments,  Break if already got to next Table Defn,
206        else replace tabs with spaces, newlines with null
207       */
208        for (ptr=line; *ptr==' '; ptr++) ; if (*ptr == '#') continue; 
209        if (strstr(line, "GRIB Table ") != NULL) break;  /* END OF CURR SECT */
210        while (ptr=strchr(line,'\t')) *ptr=' '; 
211        if (ptr=strchr(line,'\n')) *ptr='\0'; 
212/*
213*                EXTRACT line partially  !Parmid, 1st word of Description
214*                DROP line out if extraction fails;
215*                DROP line if parmid is invalid or out or range
216*                >> Note: valid parm id range is 0-255 for main table,
217*                1-255 for sub tables.
218*/
219        /* DO a partial read, get parm_id and 1st word of Description */
220        if ((num=sscanf (line,"%s%s", strGribCode, temp )) !=2) {
221            if (num>0) fprintf(stdout,
222            "Warning: drop incomplete %s Line %d\n" ,lookup_fn, LineRead); 
223             continue;
224          }
225
226       /* Make sure Parmid field has a Number */
227       if (strspn (strGribCode, "0123456789") != strlen(strGribCode)) {
228           fprintf(stdout,"Warning: Invalid Parmid '%s', drop line#%d in %s\n", 
229           strGribCode, LineRead, lookup_fn);
230           continue; }
231
232       GribCode =  atoi(strGribCode);
233       /* check if id is out of range */
234       if (GribCode < 0 || GribCode >= NPARM) {
235           fprintf(stdout, 
236           "Warning: Parm id '%d' out of range, drop %s:Line %d\n",
237           GribCode, lookup_fn, LineRead); continue; }
238
239       /*
240          Can only have Parm code 0 in Main table;
241          Donot load if parm is 0 and this is a Sub table;
242        */
243       if (GribCode == 0 && sub!=0) {
244           fprintf(stdout,
245           "Warning: cannot have Gribcode 0 in Sub-tables, drop %s:Line %d\n",
246           lookup_fn, LineRead); continue; 
247        }
248
249/*
250*                EXTRACT Grib_Dsc & Grib_Unit_Dsc from line (both multi words)
251*                !these 2 fields must be separated by atleast 2 spaces;
252*                DROP line if cannot find Grib_Dsc/Unit;
253*/
254        /*
255          Now, get Grib_Desc and Grib_Unit_Dsc fields, both multi words...
256           TEMP has 1st word of the Grib_Desc;  This field ends when
257           we see 2 consecutive spaces;
258           locate Grib_Desc, move max of 75, then cap it where there are
259           4 consecutive spaces
260        */
261        if (!(ptr= strstr (line, temp)) || !(ptr2= strstr (ptr, "  ")))
262          { fprintf(stdout, 
263            "Warning:  cannot find Grib_Dsc, drop line#%d in %s\n",
264            LineRead, lookup_fn); continue;
265          }
266        strncpy (grib_dsc, ptr, ptr2-ptr); /*sizeof(grib_dsc)-1); */
267        grib_dsc[ptr2 - ptr] = '\0';
268
269        /* Grib_Dsc now contains both "Desc & Unit", find where Unit begins
270           (look for 2 consecutive spaces) then put null terminator to cap
271           off Grib_Dsc
272        if ((ptr= strstr (grib_dsc, "  ")) == NULL)
273        */
274
275        while (*ptr2==' ') ptr2++;
276        if (! *ptr2) 
277          { fprintf(stdout, "Warning: cannot find Unit, drop Line %d in %s\n" , 
278            LineRead, lookup_fn);
279            continue;
280          }
281        else strcpy (grib_unit_dsc, ptr2);
282        for (ptr=grib_unit_dsc + strlen(grib_unit_dsc)-1; *ptr==' '; ptr--)
283                *ptr='\0';   /* remove ending spaces */
284
285/*     
286        *ptr= '\0';     /# cap off GribDsc, where delimitor begins #/
287        for (ptr= grib_unit_dsc+strlen(grib_unit_dsc) -1;
288             *ptr=='\n' || *ptr == ' '; --ptr)
289            *ptr='\0';          /# rm ending spaces in Unit #/
290*/
291       
292     
293/*
294*                DROP defn if this parmid is already defined;
295*/
296      parmptr =  db_parm_tbl + indx + GribCode;
297      if (parmptr->grib_dsc[0] != '\0') { 
298         fprintf(stdout,
299         "Warning: duplic Parm defn #%d (Index=%d), drop line %d in %s\n",
300         GribCode, PARMTBL_INDX (parmptr->usParm_id, parmptr->usParm_sub),
301         LineRead, lookup_fn);
302         continue;
303       }
304/*
305*                STORE info in the array cell whose index is 'parm_id'
306*                !undefined parm ids are all set to zero;
307*/
308      /* depending on which Table Code it is, entry will be stored in
309         its corresponding Parameter Range; 
310         >>> ENTRIES ARE STORED IN ARRAY CELL WHOSE INDEX IS 'PARM_ID'
311         >>> UNDEFINED IDS WILL HAVE CELL WITH EMPTY DEFNS;
312      */
313      /* Store entry just read in Parm Defn Array */
314
315      if (sub == 0) { /* Main Table only */
316              parmptr->usParm_id = (unsigned short)GribCode;
317              parmptr->usParm_sub = 0;
318           }
319      else {    /* for all Sub-Tables (non-zero sub) */
320              parmptr->usParm_id = sub + 249;  /* range 250 to 254 only */
321              parmptr->usParm_sub = (unsigned short)GribCode;
322           }
323      strcpy (parmptr->grib_dsc, grib_dsc);
324      strcpy (parmptr->grib_unit_dsc, grib_unit_dsc);
325
326      DPRINT7(
327        "(+D) T2-%d cd=%d: Parm=%d, ParmSub=%d, INDX=%d, Dscr='%s' Unit='%s'\n"
328        ,sub, GribCode,
329        parmptr->usParm_id, parmptr->usParm_sub, indx+GribCode,
330        parmptr->grib_dsc, parmptr->grib_unit_dsc);
331
332      ++cnt;    /* keep track of #entries loaded */
333/*
334* A.2.3       ENDFOR
335*/
336   }
337   DPRINT2 ("Parameter table#%d has %d entries\n", sub, cnt);
338
339/*
340* A.2       ENDFOR   !load all 6 Parameter tables
341*/
342} /* load all 6 parm tables */
343 
344
345/******** GRIB's LEVEL TABLE *******
346Sample:
347   ######################################################################
348   GRIB Table 3: Level Definitions
349   Line 1: Level ID | Number of Octets | Meaning
350   Line 2: Contents of octet 11 (optional)
351   Line 3: Contents of octet 12 (optional)
352   001  0  Ground or water surface
353   002  0  Cloud base level
354   ...
355   100  2  Isobaric surface
356   Pressure in hPa
357   ...
358   101  1  Layer between two isobaric surfaces
359   Pressure of top in kPa
360   Pressure of bottom in kPa
361   ######################################################################
362
363*
364*           *** Level Conversion info ***
365* A.3       LOOP until last line of comments ("Line3:" or "====");
366*           RETURN error if fails
367*/
368
369  DPRINT1 ("*** %s: Start reading Level Defns  ***\n", func);
370  /* Read until the last line of Comments */
371  for (line[0]='\0'; ! strstr(line,"====") && ! strstr(line,"Line 3:") ; ) 
372  {
373    fgets(line, sizeof(line), infile); 
374    ++LineRead;
375    if (feof(infile) || ferror(infile)) 
376      { sprintf(errmsg,
377        "%s: got EOF/ERROR before loading LEVEL info (Line %d in %s)\n",
378        func, LineRead, lookup_fn);
379        goto BYE;
380      }
381   }
382
383/*
384* A.4       LOOP (successfully read a line from file) DO
385*              SKIP if comment line
386*              BREAK out of loop if see next section "GRIB Table"
387*/
388  for (cnt=0; fgets(line, sizeof(line), infile) != NULL; ) 
389  {
390    ++LineRead;
391    /* skip additional comments,  Break if already got to next Table Defn,
392        else replace tabs with spaces, newlines with null
393    */
394    for (ptr=line; *ptr==' '; ptr++); if (*ptr == '#') continue; 
395    if (strstr(line, "GRIB Table ") != NULL) break; /* end of CURR SECT */
396     while (ptr=strchr(line,'\t')) *ptr=' '; 
397     if (ptr=strchr(line,'\n')) *ptr='\0'; 
398
399/*
400*              EXTRACT next GRIB's Level info into Level Array:
401*              DROP line if extraction fails;
402*              ! line 1 format:  lvl id, #octets and Level_description
403*              DROP line if level_id is invalid or out of range
404*              DROP line if unable to extract level description
405*/
406    /* --- Read Line 1 of Level:  frmt=  (Lvlid #octs  Multiwords Dscr) --*/
407    if ((num= sscanf (line, "%s%s%s", strGribCode, strOctets, temp))!= 3) {
408         if (num>0) fprintf(stdout,
409        "Warning: dropping incomplete Level defn (%s:Line %d)\n",
410        lookup_fn,LineRead); 
411         continue;
412        }
413       
414    /* Make sure Parmid field has a Number, and is within Range  */
415    if (strspn (strGribCode, "0123456789") != strlen(strGribCode)) {
416           fprintf(stdout,"Warning: Invalid Levelid '%s', drop Line=%d in %s\n",
417           strGribCode, LineRead, lookup_fn); 
418           continue; }
419    else GribCode =  atoi(strGribCode);
420
421    if (GribCode < 0 || GribCode >= NLEV) {
422         fprintf(stdout, 
423         "Warning: Level Gribcode '%d' out of range, drop (Line %d in %s)",
424         GribCode, LineRead, lookup_fn); 
425         continue; 
426        }
427
428    /* Make sure #Octets field has a Number, and is within Range */
429    if (strspn (strOctets, "0123456789") != strlen(strOctets)) {
430           fprintf(stdout,
431           "Warning:  Invalid NumOctets '%s' for Lvl %d, drop line#%d in %s\n", 
432           strOctets, GribCode, LineRead, lookup_fn); 
433           continue;
434        }
435    else iOctets = atoi(strOctets);
436    if (iOctets < 0 || iOctets > 2) {
437           fprintf(stdout,
438           "Warning: Octets '%d' out of range (0-2 only), drop Line %d in %s\n",
439           iOctets, LineRead, lookup_fn); 
440           continue; 
441        }
442
443    /* TEMP here has 1st word of Lvl Descr, need to get rest of it */ 
444        if ((ptr= strstr (line, temp)) == NULL)
445          { fprintf(stdout,
446           "Warning:   Cannot find Lvl_Dsc, drop line#%d in %s\n",
447             LineRead, lookup_fn);
448            continue;
449          }
450
451        strncpy (grib_dsc, ptr, sizeof(grib_dsc)-1); 
452        if (ptr=strstr(grib_dsc,"  ")) *ptr='\0'; /* rm trail blanks */
453/*
454*              IF (0 #octets)
455*                 SET lvl_name_1 and _2 to null;
456*              ELSE if (1 #octets)
457*                 READ in 2 more lines   !for lvl_name_1 & lvl_name_2
458*              ELSE  !2 octets
459*                 READ in 1 more line    !for lvl_name_1
460*                 SET lvl_name_2 to null;
461*              ENDIF
462*/
463    /* --- Get Optional Lvl_1 and Lvl_2 lines, depneding on #octs */
464    switch (iOctets) {
465        case 0:  lvl_name_1[0]= '\0'; lvl_name_2[0]= '\0';break;
466        case 1:  if (!fgets(lvl_name_1, sizeof(lvl_name_1), infile) ||
467                     !fgets(lvl_name_2, sizeof(lvl_name_2), infile)) {
468                    fprintf(stdout,
469                    "Warning: failed to get LvlName1/LvlName2; "
470                    "drop Level %d defn (Line#%d in %s)\n",
471                    GribCode, LineRead,  lookup_fn); 
472                    continue;
473                  }
474                 LineRead += 2; break;
475        case 2:  if (!fgets(lvl_name_1, sizeof(lvl_name_1), infile) )
476                  { 
477                    fprintf(stdout,
478                    "Warning: failed to get LvlName1; "
479                    "drop Level %d defn (Line#%d in %s)\n",
480                    GribCode, LineRead,  lookup_fn); 
481                    continue;
482                  }
483                 lvl_name_2[0]='\0'; ++LineRead; break;
484         }
485
486   /* replace tabs w/space, replace Newline with Null terminator,
487      and  rm trail blanks ;
488   */
489   if (lvl_name_1[0]) {
490         while (ptr=strchr(lvl_name_1,'\t')) *ptr=' '; 
491        if (ptr=strchr(lvl_name_1,'\n')) *ptr='\0'; 
492        if (ptr=strstr(lvl_name_1,"  ")) *ptr='\0'; 
493        }
494   if (lvl_name_2[0]) {
495         while (ptr=strchr(lvl_name_2,'\t')) *ptr=' '; 
496        if (ptr=strchr(lvl_name_2,'\n')) *ptr='\0'; 
497        if (ptr=strstr(lvl_name_2,"  ")) *ptr='\0'; 
498        }
499
500/*
501*              DROP defn if this ID has already been defined;
502*/ 
503    if (db_lvl_tbl[GribCode].grib_dsc[0] != '\0') {
504        fprintf(stdout,
505        "Warning: drop duplic Level %d defn, currently at line %d in %s\n",
506        GribCode, LineRead, lookup_fn);
507        continue;
508    }
509
510/*
511*              STORE all this info into Level Array cell whose index
512*              equals the Level_id
513*/
514    db_lvl_tbl[GribCode].usLevel_id  = (unsigned short)GribCode;
515    strncpy (db_lvl_tbl[GribCode].grib_dsc, grib_dsc, 
516            sizeof(db_lvl_tbl[GribCode].grib_dsc)-1);
517    db_lvl_tbl[GribCode].num_octets  = iOctets;
518    strncpy (db_lvl_tbl[GribCode].lvl_name_1, lvl_name_1, 
519            sizeof(db_lvl_tbl[GribCode].lvl_name_1)-1);
520    strncpy (db_lvl_tbl[GribCode].lvl_name_2, lvl_name_2, 
521            sizeof(db_lvl_tbl[GribCode].lvl_name_2)-1);
522
523/*
524*              DEBUG print
525*/
526    switch (iOctets) {
527     case 0:
528        DPRINT3("(+D) Lvl=%d Dsc='%s' %d octs\n",
529        db_lvl_tbl[GribCode].usLevel_id,
530        db_lvl_tbl[GribCode].grib_dsc,
531        db_lvl_tbl[GribCode].num_octets);break;
532     case 1:
533      DPRINT5(
534        "(+D) Lvl=%d Dsc='%s' %d octs\n     Name1='%s'\n     Name2='%s'\n",
535        db_lvl_tbl[GribCode].usLevel_id,
536        db_lvl_tbl[GribCode].grib_dsc,
537        db_lvl_tbl[GribCode].num_octets,
538        db_lvl_tbl[GribCode].lvl_name_1,
539        db_lvl_tbl[GribCode].lvl_name_2);break;
540     case 2:
541        DPRINT4 ("(+D) Lvl=%d Dsc='%s'  %d octs\n     Name1='%s'\n",
542        db_lvl_tbl[GribCode].usLevel_id,
543        db_lvl_tbl[GribCode].grib_dsc,
544        db_lvl_tbl[GribCode].num_octets,
545        db_lvl_tbl[GribCode].lvl_name_1);break;
546     }
547         
548    ++cnt;  /* number loaded */
549/*
550* A.4       ENDFOR !Level defns
551*/
552  }
553  DPRINT1 ("Level table has %d entries\n", cnt);
554
555
556/*** GRIB MODEL TABLE***
557Sample:
558        ######################################################################
559        GRIB Table - Generating Process Definitions (Octet 6 of PDS)
560        Code Figure    Model Name
561        ===========    ==========
562        001            NORAPS
563        002            COAMPS
564        003            NOGAPS
565*
566*           *** Model Conversion info ***
567* A.5       WHILE (line is comment or header line) skip line;
568*           RETURN error if fails
569*/
570  DPRINT1 ("*** %s: Start reading Model Defns  ***\n", func);
571  /* Read until the last line of Comments */
572  for (line[0]='\0'; ! strstr(line,"====") ; ) 
573  {
574    fgets(line, sizeof(line), infile); ++LineRead;
575    if (feof(infile) || ferror(infile)) 
576      { sprintf(errmsg,
577        "%s: got EOF/ERROR before loading MODEL info %s Line %d\n", 
578        func, lookup_fn, LineRead);
579        goto BYE;
580      }
581   }
582
583/*
584*
585* A.6       FOR (successfully read a line from file) DO
586*              DROP line if comment
587*              BREAK out if see next section "GRIB Table"
588*/
589  for (cnt=0; fgets(line, sizeof(line), infile)!=NULL; ) 
590   {
591    ++LineRead;
592    /* skip additional comments,  Break if already got to next Table Defn,
593        else replace tabs with spaces, newlines with null
594    */
595     for (ptr=line; *ptr==' '; ptr++) ; if (*ptr == '#') continue; 
596     if (strstr(line, "GRIB Table ") != NULL) break; /* end of CURR SECT */
597     while (ptr=strchr(line,'\t')) *ptr=' '; 
598     if (ptr=strchr(line,'\n')) *ptr='\0'; 
599/*
600*              EXTRACT from line the GRIB's Model info ;
601*              DROP line if extraction fails;
602*              ! frmat:    model_name model_id;
603*              DROP line if modelid is invalid or out of range
604*/
605     if ((num= sscanf (line, "%s%s", strGribCode, temp))  !=2) {
606         if (num > 0) fprintf(stdout,
607        "Warning: Drop incomplete Model line %d in %s\n", LineRead, lookup_fn); 
608         continue;
609        }
610     if (strspn (strGribCode, "0123456789") != strlen(strGribCode)) {
611           fprintf(stdout,"Warning:  Invalid Level '%s', drop line=%d in %s\n", 
612           strGribCode, LineRead, lookup_fn); 
613           continue; 
614        }
615     else GribCode =  atoi(strGribCode);
616
617     if (GribCode < 0 || GribCode >= NMODEL) {
618         fprintf(stdout,
619         "Warning: Model '%d' out of range, drop %s Line %d\n",
620         GribCode, lookup_fn, LineRead); 
621         continue; 
622        }
623
624/*
625*              DROP line if this model is already defined
626*/
627     if (db_mdl_tbl[GribCode].grib_dsc[0] != '\0') { 
628               fprintf(stdout, 
629                "Warning: duplic Model#%d defn , drop (%s Line %d)\n",
630                 GribCode, lookup_fn, LineRead);
631               continue;
632            }
633/*
634*              STORE model info into model array cell whose index
635*              equals the model_id;
636*/
637     db_mdl_tbl[GribCode].usModel_id = (unsigned short)GribCode;
638     strncpy (db_mdl_tbl[GribCode].grib_dsc, 
639        line+(strstr(line,temp)-line),
640        sizeof(db_mdl_tbl[GribCode].grib_dsc)-1);  /* 1/more words */
641     DPRINT2 ("(+D) Mdl=%d,  Gribdscr=%s\n", 
642     db_mdl_tbl[GribCode].usModel_id, db_mdl_tbl[GribCode].grib_dsc);
643     ++cnt;  /* number loaded */
644/*
645* A.6       ENDFOR
646*/
647   }
648  DPRINT1 ("Model table has %d entries\n", cnt);
649     
650
651/*** GRIB GEOMETRY TABLE***
652Sample:
653        ######################################################################
654        GRIB Table - Pre-defined geometries (Octet 7 of PDS)
655        Code Figure    Geometry Name
656        ===========    =============
657        001            mediterranean_109x82
658        002            persian_gulf_NORAPS_63x63
659        003            global_144x288
660        255            Undefined grid, description in GDS
661*
662*           *** Geometry Conversion info ***
663* A.7       WHILE (line is comment or header line) skip line;
664*           RETURN error if fails
665*/
666
667  DPRINT1 ("*** %s: Start reading Geom Defns  ***\n", func);
668  /* Read until the last line of Comments */
669  for (line[0]='\0'; ! strstr(line,"====") ; ) {
670    fgets(line, sizeof(line), infile); 
671    ++LineRead;
672    if (feof(infile) || ferror(infile)) 
673      { sprintf(errmsg,
674        "%s: got EOF/ERROR before loading GEOM info, %s Line %d\n",
675        func, lookup_fn, LineRead);
676        goto BYE;
677      }
678   }
679
680/*
681* A.8       FOR (successfully read a line from file) DO
682*              DROP line if comment
683*              BREAK out if see next section "GRIB Table"
684*/
685  for (cnt=0; fgets(line, sizeof(line), infile)!=NULL; ) 
686   {
687    ++LineRead;
688    /* skip additional comments,  Break if already got to next Table Defn,
689        else replace tabs with spaces, newlines with null
690    */
691     for (ptr=line; *ptr==' '; ptr++) ; if (*ptr == '#') continue; 
692     if (strstr(line, "GRIB Table ") != NULL) break; /* end of CURR SECT */
693     while (ptr=strchr(line,'\t')) *ptr=' '; 
694     if (ptr=strchr(line,'\n')) *ptr='\0'; 
695
696/*
697*              EXTRACT next GRIB's Geometry info into Geometry Array;
698*              DROP line if extraction fails;
699*              !format:  geom_id geom_descr
700*              DROP line if geom_id is invalid or out of range
701*/
702     if ((num= sscanf (line, "%s%s", strGribCode, temp))  !=2) {
703         if (num > 0) fprintf(stdout,
704        "Warning: drop incomplete Geom line %d in %s\n", LineRead, lookup_fn);
705         continue;
706        }
707
708     if (strspn (strGribCode, "0123456789") != strlen(strGribCode)) {
709           fprintf(stdout,"Warning: Invalid Geom_id '%s', drop %s line=%d\n", 
710           strGribCode, lookup_fn, LineRead); 
711           continue; }
712     else GribCode =  atoi(strGribCode);
713
714     if (GribCode < 0 || GribCode >= NGEOM) {
715         fprintf(stdout, "Warning: Geomid '%d' out of range, drop %s Line %d\n",
716         GribCode, lookup_fn, LineRead); 
717         continue; 
718        }
719
720/*
721*              DROP line if geom_id is already defined
722*/
723     if (db_geom_tbl[GribCode].grib_dsc[0] != '\0') { 
724               fprintf(stdout, "Warning: duplic GeomID=%d, drop %s line %d\n",
725                GribCode,  lookup_fn, LineRead);
726               continue;
727            }
728/*
729*              STORE this geom info into array cell whose index
730*              equals the geom_id;
731*/
732     db_geom_tbl[GribCode].usGeom_id = (unsigned short)GribCode;
733     strncpy (db_geom_tbl[GribCode].grib_dsc, 
734        line+(strstr(line,temp)-line),
735        sizeof(db_geom_tbl[GribCode].grib_dsc)-1);  /* 1/more words */
736
737     ++cnt;  /* number loaded */
738     DPRINT2("(+D) Geom=%d,  Gribdscr=%s\n", 
739     db_geom_tbl[GribCode].usGeom_id, db_geom_tbl[GribCode].grib_dsc);
740/*
741* A.8       ENDFOR
742*/
743   }
744  DPRINT1 ("Geometry table has %d entries\n", cnt);
745
746/*
747*
748* A.9      SET status to 0 !success
749*/
750  stat=0;
751
752/*
753*
754* A.10     CLOSE Lookup file;
755*/
756BYE:
757  if (infile) fclose(infile);
758  DPRINT2 ("Leaving %s, stat=%d\n", func,stat);
759/*
760*
761* A.11     RETURN with status
762*/
763  return (stat);
764/*
765* END OF FUNCTION
766*
767*/
768}
Note: See TracBrowser for help on using the repository browser.