source: trunk/WRF.COMMON/WRFV2/external/io_grib1/MEL_grib1/ld_enc_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: 16.8 KB
Line 
1/* Revision logs:
216Jul97 /atn:  only clr Encoder section of db tables; chg warning to stdout;
3*/
4
5#include <stdio.h>
6#include <stdlib.h>
7#include <string.h>
8#include <math.h>
9#include <stdlib.h>
10#include "grib_lookup.h"        /* combined lookup structs */
11#include "dprints.h"            /* for dprints */
12#include "gribfuncs.h"          /* prototypes */
13
14extern PARM_DEFN   db_parm_tbl[];  /* parm conversion info */
15extern LVL_DEFN    db_lvl_tbl[];   /* level conversion info */
16extern MODEL_DEFN  db_mdl_tbl[];   /* model conversion info */
17extern GEOM_DEFN   db_geom_tbl[];  /* Geom conversion info */
18/*
19****************************************************************************
20* A. FUNCTION: ld_enc_lookup
21*      This function reads in the information from an external Lookup
22*      table used by the GRIB Encoder (ie: neons2grib.tab).  This info
23*      is used to convert Databse codes to the GRIB Code Numbers.
24*
25*    INTERFACE:
26*      int ld_enc_lookup (lookup_fn, errmsg)
27*
28*    ARGUMENTS (I=input, O=output, I&O=input and output):
29*      (I)  char *lookup_fn;   Name of Lookup file to read from;
30*      (O)  char *errmsg       REturned filled if error occurred;
31*
32*     RETURN CODE:
33*       0>  successful, the following pre-defined arrays required for
34*           encoding GRIB messages are filled=
35*           PARM_DEFN  db_parm_tbl[NPARM * MAX_PARM_TBLS]; (parameter info)
36*           LVL_DEFN db_lvl_tbl[NLEV];      (level info)
37*           MODEL_DEFN db_mdl_tbl[NMODEL];  (model info)
38*           GEOM_DEFN db_geom_tbl[NGEOM];   (geometry info)
39*       1>  file open error or got error/eof while reading;  errmsg filled;
40****************************************************************************
41- only break out of curr Loop if sees next section's header string;
42
43*/
44#if PROTOTYPE_NEEDED
45int ld_enc_lookup ( char *lookup_fn, char *errmsg)
46
47#else
48int ld_enc_lookup ( lookup_fn, errmsg)
49                char *lookup_fn; char *errmsg;
50#endif
51{
52  FILE  *infile;
53  char  *func="ld_enc_lookup";     /* name of function */
54  char  *ptr, temp[200], TableCode, dummy[100]; 
55  int   stat=1, num, LineRead, cnt, code=0, indx0= 0;
56  int   Indx, indxA=0, indxB=0, indxC=0, indxD=0, indxE= 0;
57  int   *indxptr;
58  char  *px;
59  char             achDBsField[30];  /* DBs Field Name                  */
60  char             strDSF[50],strGribCode[50], strScale[50], strOffset[50];
61  char             subtbl[20];    /* (0:maintbl) or (a/b/c/d/e:subtabl)*/
62  int   GribCode;         /* GRIB Code Number                  */
63  float            fScale;             /* Scale                             */
64  float            fOffset;            /* Offset                            */
65  short            sDSF;               /* DSF                               */
66  PARM_DEFN        *parmptr;           /* ptr to desired cell w/in Parm arr*/
67
68  DPRINT2 ("Entering %s\nlookup %s\n", func, lookup_fn);
69/*
70*
71* A.0       CLEAR out all lookup arrays  ! Encoder section only
72*/
73 for (num=0; num < NPARM ; num++) {
74        db_parm_tbl[num].usParm_id=  num;
75        db_parm_tbl[num].usParm_sub= 0;       /* not used for main tbl */
76        db_parm_tbl[num].db_name[0] = '\0';
77        db_parm_tbl[num].fScale     = 1.;
78        db_parm_tbl[num].fOffset    = 0.;
79        db_parm_tbl[num].sDSF       = 0;
80        }
81  for (num=NPARM; num < NPARM * MAX_PARM_TBLS; num++) {  /* for sub-tbls */
82        db_parm_tbl[num].usParm_id=  250 + num / NPARM;
83        db_parm_tbl[num].usParm_sub= num % NPARM;
84        db_parm_tbl[num].db_name[0] = '\0';
85        db_parm_tbl[num].fScale     = 1.;
86        db_parm_tbl[num].fOffset    = 0.;
87        db_parm_tbl[num].sDSF       = 0;
88        }
89
90  for (num=0; num < NLEV; num++) {
91        db_lvl_tbl[num].usLevel_id =  num;
92        db_lvl_tbl[num].db_name[0] = '\0';
93        db_lvl_tbl[num].fScale     =  1.;
94        db_lvl_tbl[num].fOffset    =  0.;
95        }
96
97  for (num=0; num < NMODEL; num++) {
98        db_mdl_tbl[num].usModel_id  = num;
99        db_mdl_tbl[num].db_name[0] = '\0';
100        }
101
102  for (num=0; num < NGEOM; num++) {
103        db_geom_tbl[num].usGeom_id  = num;
104        db_geom_tbl[num].db_name[0] = '\0';
105        }
106/*
107*
108* A.1       OPEN Lookup file for reading
109*           RETURN 1 if fails;
110*/
111  infile = fopen(lookup_fn, "r");
112  if (infile==NULL) { 
113        DPRINT2 ("%s:  failed to open %s\n", func, lookup_fn);
114        sprintf (errmsg ,"%s:  failed to open %s\n", func, lookup_fn);
115        goto BYE;
116        }
117
118/****Database's PARM TABLE -- (0/A/B/C/D/E) ***
119Sample:
120NEONS to GRIB Parameter Table
121NEONS FIELD             TABLE CODE    GRIB CODE     SCALE     OFFSET     DSF
122===========             ==========    =========     =====     ======     ===
123pres                        0           001           1.0        0.0      1
124pres                        0           002           1.0        0.0      1
125*
126*           *** Database's Parameter Defn conversion info ***
127* A.2       KEEP reading until last of Header/Comment line (see '===')
128*           RETURN error if fails
129*/
130  LineRead = 0;
131
132  while (strstr (temp, "===") == NULL) {
133        fgets(temp, sizeof(temp), infile); /* skip Comment/Header lines */
134        LineRead++; 
135        if (feof(infile) || ferror(infile)) {
136           DPRINT1 ("%s: got EOF/ERROR before loading DBs PARM info\n", func);
137           sprintf(errmsg,
138           "%s: got EOF/ERROR before loading DBs PARM info (%s:line %d)\n",
139            func , lookup_fn, LineRead);
140           goto BYE;
141          }
142        }
143/*
144*
145* A.3       FOR (successfully read a line from file) DO
146*              BREAK out of loop if sees Header of next Table
147*              EXTRACT next DBs's Parameter info from line read
148*              IF (fails) SKIP rest of Parm defn ;
149*              !parm_name, tblcode, parmid, scalefctr, offset, Decsclfctr;
150*              DROP line if Parm id is out of range
151*              DROP line if Table Code is not (0/A/B/C/D/E)
152*              DROP defn if Code has already been defined;
153*              STORE in Parm Array cell whose index equals Parmid
154*           ENDFOR
155*/
156  for (cnt=0; fgets(temp, sizeof(temp), infile)!=NULL; ) {
157     
158        LineRead++; 
159        for (ptr=temp; *ptr==' '; ptr++) ; if (*ptr == '#') continue; 
160        if (strstr(temp, "to GRIB Level Table") != NULL) 
161                break;  /* END OF CURR SECT */
162
163        if ((num= sscanf (temp,"%s%s%s%s%s%s%s", achDBsField, subtbl, 
164            strGribCode, strScale, strOffset, strDSF, dummy)) != 6) 
165          {
166            if (num>0)
167            fprintf(stdout,"Warning: unmatched Parm args, drop line %d in %s\n", 
168                LineRead, lookup_fn);
169            continue;
170          }
171
172       for (px=strGribCode; *px; px++) 
173          if (!isdigit(*px)) {
174                fprintf(stdout,
175                "Warning: invalid GRIB code, drop line %d in %s\n",
176                LineRead, lookup_fn);
177                continue;
178                }
179
180       GribCode =  atoi(strGribCode);
181       fScale     = (float) atof(strScale);
182       fOffset    = (float) atof(strOffset);
183       sDSF       = (short) atoi(strDSF);
184
185       if (GribCode < 0 || GribCode >= NPARM) {
186           fprintf(stdout,
187           "Warning:  ParmId '%d' out of range, drop line %d in %s\n",
188           GribCode,  LineRead, lookup_fn); continue; }
189
190        if (strlen(subtbl) > 1) { fprintf(stdout,
191           "Warning:  Invalid bad TableCode '%s', drop line %d in %s;\n",
192           subtbl, LineRead, lookup_fn); continue; }
193
194      /* depending on which Table Code it is, entry will be stored in
195         its corresponding Parameter Table; 
196         >>> if Tablecode is '0', store at array index PARM_ID;
197         >>> if Tablecode is 'A/B/C/D/E',
198         >>> then store at array index [NPARM*(PARM_ID-249) + PARM_SUB];
199         >>> UNDEFINED IDS WILL HAVE EMPTY CELLS;
200      */
201      TableCode = (isalpha(*subtbl) ? tolower(*subtbl) : *subtbl);
202
203      if   (TableCode=='0')  {
204                Indx = 0;
205                parmptr             = db_parm_tbl + GribCode;
206                parmptr->usParm_id  = (unsigned short) GribCode;
207                parmptr->usParm_sub = 0; 
208        }
209      else if (TableCode>= 'a' && TableCode <= 'e')  {
210              if (GribCode==0) {
211                fprintf(stdout,
212                "Warning: Cannot use Parmid 0 for sub-tbl, drop line %d in %s\n"
213                ,  LineRead, lookup_fn);
214                continue;
215                }
216                Indx = 256 * (TableCode-'a'+1);   /* 'a':256-.. 'b':512-.. */ 
217                parmptr = db_parm_tbl + Indx + GribCode; /* actual Index */
218                parmptr->usParm_id  = 250 + (TableCode-'a');
219                parmptr->usParm_sub = (unsigned short) GribCode;
220        }
221      else {  fprintf(stdout,
222              "Warning:  Invalid Table '%s' (0,A-E only), drop line %d in %s\n",
223              subtbl,  LineRead, lookup_fn);
224              continue;
225        }
226       
227      if (parmptr->db_name[0] != '\0')
228            { /* drop line if Duplicate */
229               fprintf(stdout,
230           "Warning: duplic Parm %d in Tbl %c (Index=%d), drop line %d in %s\n",
231                parmptr->usParm_id, TableCode,
232                PARMTBL_INDX(parmptr->usParm_id, parmptr->usParm_sub),
233                LineRead, lookup_fn);
234              continue;
235            }
236
237      strcpy (parmptr->db_name, achDBsField);
238      parmptr->fScale = fScale;
239      parmptr->fOffset = fOffset;
240      parmptr->sDSF = sDSF;
241      ++cnt;    /* keep track of #entries loaded */
242
243      DPRINT9(
244 "(+)T2-%c cd=%d:  Parm=%d sub=%d, INDX=%d, dbnm=%s Scl=%.2f Ofs=%.2f D=%d\n"
245        , TableCode, GribCode,
246        parmptr->usParm_id, parmptr->usParm_sub,Indx+GribCode, 
247        parmptr->db_name, parmptr->fScale, parmptr->fOffset, parmptr->sDSF);
248   }
249 
250/*
251*          DEBUG print
252*/
253 DPRINT1("Parameter table has %d entries\n", cnt);
254
255
256/******** Database's LEVEL TABLE *******
257Sample:
258NEONS to GRIB Level Table (FNMOC VERSION)
259NEONS Level Type        GRIB CODE     SCALE     OFFSET
260================        =========     =====     ======
261surface                   001           1.0        0.0
262isth_lvl                  004           0.0      273.16
263trpp_lvl                  007           1.0        0.0
264*
265*           *** DBs's Level Defn conversion info ***
266* A.4       KEEP reading until last of Header/Comment line (see '===')
267*           RETURN error if fails
268*/
269  while (strstr (temp, "====") == NULL) {
270        fgets(temp, sizeof(temp), infile); /* skip Comment/Header lines */
271        LineRead++; 
272        if (feof(infile) || ferror(infile)) {
273          DPRINT1 ("%s: got EOF/ERROR before loading DBs LEVEL info\n",func);
274          sprintf(errmsg,
275          "%s: got EOF/ERROR before loading LEVEL info (line %d in %s)\n",
276          func , LineRead, lookup_fn);
277          goto BYE;
278        }
279   }
280
281/*
282* A.5       FOR (successfully read a line from file) DO
283*              BREAK out of loop if sees Header of next Table
284*              EXTRACT next DBs's Level info into Level Array:
285*              !format= level_type, level_id, scale, offset
286*              DROP line if not enough arguments
287*              DROP line if Duplicate Parm defn
288*              STORE in Level  Array cell whose index equals Level id
289*           ENDFOR
290*/
291  for (cnt=0; fgets(temp, sizeof(temp), infile) != NULL; ) 
292  {
293    LineRead++;
294    if (strstr(temp, "to GRIB Model Table") != NULL) 
295        break;  /* Assume end of section */
296    for (ptr=temp; *ptr==' '; ptr++) ; if (*ptr == '#') continue; 
297    if ((num= sscanf (temp, "%s%s%s%s%s", 
298              achDBsField, strGribCode, strScale, strOffset, dummy)) != 4) 
299        {
300          if (num>0)
301            fprintf(stdout,"Warning: unmatched Level args, drop line %d in %s\n",
302            LineRead, lookup_fn);
303          continue;
304        }
305
306    GribCode =  atoi(strGribCode);
307    fScale     = (float) atof(strScale);
308    fOffset    = (float) atof(strOffset);
309
310    if (GribCode < 0 || GribCode >= NLEV) {
311         fprintf(stdout,
312        "Warning: Level_id '%d' out of range, drop line %d in %s\n"
313        ,GribCode, LineRead, lookup_fn); 
314         continue; 
315        }
316
317    if (db_lvl_tbl[GribCode].db_name[0] != '\0') {
318        fprintf(stdout,
319        "Warning: duplic Level %d, drop defn ending on line %d in %s\n",
320        GribCode, LineRead, lookup_fn);
321        continue;
322        }
323
324    db_lvl_tbl[GribCode].usLevel_id  = (unsigned short) GribCode;
325    strncpy (db_lvl_tbl[GribCode].db_name, achDBsField, 
326            sizeof(db_lvl_tbl[GribCode].db_name)-1);
327    db_lvl_tbl[GribCode].fScale  = fScale;
328    db_lvl_tbl[GribCode].fOffset = fOffset;
329    ++cnt;  /* number loaded */
330
331    DPRINT4("(+)  Level=%d,  db_name=%s,  Scl=%f, Offs=%f\n", 
332        db_lvl_tbl[GribCode].usLevel_id, db_lvl_tbl[GribCode].db_name,
333        db_lvl_tbl[GribCode].fScale, db_lvl_tbl[GribCode].fOffset);
334  }
335 
336/*
337*          DEBUG print
338*/
339  DPRINT1("Level table has %d entries\n", cnt);
340
341
342/*** Database's MODEL TABLE***
343Sample:
344NEONS to GRIB Model ID Table (FNMOC VERSION)
345NEONS Model Name        GRIB CODE
346================        =========
347NORAPS                    001
348COAMPS                    002
349*
350*           *** Database 's Model Defn conversion info ***
351* A.6       KEEP reading until last of Header/Comment line (see '===')
352*           RETURN error if fails
353*/
354  while (strstr (temp, "====") == NULL) {
355        fgets(temp, sizeof(temp), infile); /* skip Comment/Header lines */
356        LineRead++;
357        if (feof(infile) || ferror(infile)) {
358          DPRINT1 ("%s: got EOF/ERROR before loading MODEL info\n",func);
359          sprintf(errmsg,
360          "%s: got EOF/ERROR before loading MODEL info (line %d in %s)\n",
361          func , LineRead, lookup_fn);
362          goto BYE;
363        }
364    }
365/*
366* A.7       FOR (successfully read a line from file) DO
367*              BREAK out of loop if sees Header of next Table
368*              EXTRACT next DBs's Model info into Model Array;
369*              DROP line if not enough arguments
370*              DROP line if Duplicate model defn
371*              ! format= model_name, model_id;
372*              STORE in Model  Array cell whose index equals Model id
373*           ENDFOR
374*/
375  for (cnt=0; fgets(temp, sizeof(temp), infile)!=NULL; ) 
376   {
377     LineRead++;
378     for (ptr=temp; *ptr==' '; ptr++) ; if (*ptr == '#') continue; 
379     if (strstr(temp, "to GRIB Geometry Table") != NULL) 
380        break; /*  Assume end of section */
381     if ((num= sscanf (temp, "%s%s%s", achDBsField, strGribCode,dummy))  !=2) {
382          if (num>0)
383            fprintf(stdout,"Warning: unmatched Model args, drop line %d in %s\n",
384            LineRead, lookup_fn);
385          continue;
386        }
387   
388     GribCode =  atoi(strGribCode);
389     if (GribCode < 0 || GribCode >= NMODEL) {
390         fprintf(stdout,
391           "Warning:  Model_id '%d' out of range, drop line %d in %s",
392           GribCode, LineRead, lookup_fn); continue; }
393
394    if (db_mdl_tbl[GribCode].db_name[0] != '\0') {
395        fprintf(stdout,
396        "Warning: duplic Model %d, drop defn ending on line %d in %s\n",
397        GribCode, LineRead, lookup_fn);
398        continue;
399        }
400
401     db_mdl_tbl[GribCode].usModel_id = (unsigned short) GribCode;
402     strcpy (db_mdl_tbl[GribCode].db_name, achDBsField);
403     ++cnt;  /* number loaded */
404     DPRINT2("(+)  Model=%d,  db_name=%s\n", 
405        db_mdl_tbl[GribCode].usModel_id, db_mdl_tbl[GribCode].db_name);
406   }
407   
408/*
409*          DEBUG print
410*/
411  DPRINT1("Model table has %d entries\n", cnt);
412     
413
414/*** Database's GEOMETRY TABLE***
415Sample:
416NEONS to GRIB Geometry Table
417NEONS Geometry Name     GRIB CODE
418===================     =========
419mediterranean_109x82       001
420persian_gulf_NORAPS_63x63  002
421global_144x288             003
422*
423*           *** Database's Geometry Defn conversion info ***
424* A.8       KEEP reading until last of Header/Comment line (see '===')
425*           RETURN error if fails
426*/
427  while (strstr (temp, "====") == NULL) {
428     fgets(temp, sizeof(temp), infile); /* skip Comment/Header lines */
429     LineRead++; 
430     if (feof(infile) || ferror(infile)) {
431          DPRINT1 ("%s: got EOF/ERROR before loading DBs GEOM info\n",func);
432          sprintf(errmsg,
433          "%s: got EOF/ERROR before loading GEOM info (line %d in %s)\n",
434          func , LineRead, lookup_fn);
435          goto BYE;
436        }
437    }
438/*
439* A.9       FOR (successfully read a line from file) DO
440*              EXTRACT next DBs's Geometry info into Geometry Array;
441*              IF (fails) SKIP rest of Geometry defn ;
442*              !format= parm_name, parm_id, scalefctr, offset, dec scale factor;
443*              STORE in Geom  Array cell whose index equals Geom id
444*           ENDFOR
445*/
446  for (cnt=0; fgets(temp, sizeof(temp), infile)!=NULL; ) {
447    LineRead++;
448    for (ptr=temp; *ptr==' '; ptr++) ; if (*ptr == '#') continue; 
449    if ((num= sscanf (temp, "%s%s%s", achDBsField, strGribCode, dummy))  !=2) {
450          if (num>0)
451            fprintf(stdout,"Warning: unmatched Geom args, drop line %d in %s\n",
452            LineRead, lookup_fn);
453          continue; 
454        }
455
456    GribCode =  atoi(strGribCode);
457    if (GribCode < 0 || GribCode >= NGEOM) {
458         fprintf(stdout,
459           "Warning:  Geom_id '%d' out of range, drop line %d in %s\n",
460           GribCode, LineRead, lookup_fn); continue; }
461
462    if (db_geom_tbl[GribCode].db_name[0] != '\0') {
463        fprintf(stdout,
464        "Warning: duplic Geom %d, drop defn ending on line %d in %s\n",
465        GribCode, LineRead, lookup_fn);
466        continue;
467        }
468
469    db_geom_tbl[GribCode].usGeom_id= (unsigned short) GribCode; 
470    strcpy (db_geom_tbl[GribCode].db_name, achDBsField);
471    ++cnt;
472    DPRINT2("(+) geom=%d,  db_name=%s\n", 
473        db_geom_tbl[GribCode].usGeom_id, db_geom_tbl[GribCode].db_name);
474   }
475   
476/*
477*          DEBUG print
478*/
479  DPRINT1("Geometry table has %d entries\n", cnt);
480
481/*
482*
483* A.10     SET status to 0 !success
484*/
485  stat=0;
486
487/*
488*
489* A.11     CLOSE Lookup file;
490*/
491BYE:
492  if (infile) fclose(infile);
493  DPRINT2 ("Leaving %s(), stat=%d\n", func,stat);
494/*
495*
496* A.12     RETURN with status
497*/
498  return (stat);
499/*
500* END OF FUNCTION
501*
502*/
503}
Note: See TracBrowser for help on using the repository browser.