varscan.c 29.6 KB
Newer Older
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1
2
3
4
5
6
7
8
#if defined (HAVE_CONFIG_H)
#  include "config.h"
#endif

#include <string.h>
#include <math.h>

#include "cdi.h"
9
#include "cdi_int.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
10
11
12
#include "dmemory.h"
#include "varscan.h"
#include "vlist.h"
13
#include "grid.h"
14
#include "zaxis.h"
15
16
17
18


extern void zaxisGetIndexList ( int, int * );

Uwe Schulzweida's avatar
Uwe Schulzweida committed
19
20
21
22
23
24
25

#undef  UNDEFID
#define UNDEFID -1

static size_t Vctsize = 0;
static double *Vct = NULL;

26
27
28
29
static int numberOfVerticalLevels = 0;
static int numberOfVerticalGrid = 0;
static char uuidVGrid[17];

Uwe Schulzweida's avatar
Uwe Schulzweida committed
30
31
32
33
34
35
36
typedef struct
{
  int      level1;
  int      level2;
  int      recID;
  int      lindex;
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
37
leveltable_t;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
38
39
40

typedef struct
{
41
42
43
44
45
46
47
48
49
50
51
52
53
54
  int           param;
  int           prec;
  int           tsteptype;
  int           timave;
  int           timaccu;
  int           gridID;
  int           zaxistype;
  int           ltype;     /* GRIB level type */
  int           lbounds;
  int           level_sf;
  int           level_unit;
  int           zaxisID;
  int           nlevels;
  int           levelTableSize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
55
  leveltable_t *levelTable;
56
57
58
59
60
61
62
63
  int           instID;
  int           modelID;
  int           tableID;
  int           comptype;       // compression type
  int           complevel;      // compression level
  int           lmissval;
  double        missval;
  char         *name;
64
  char         *stdname;
65
66
67
68
  char         *longname;
  char         *units;
  ensinfo_t    *ensdata;
  int           typeOfGeneratingProcess;
69
  int           productDefinitionTemplate;
70
#if  defined  (HAVE_LIBGRIB_API)
71
  /* (Optional) list of keyword/double value pairs */
72
73
74
  int           opt_grib_dbl_nentries;
  char         *opt_grib_dbl_keyword[MAX_OPT_GRIB_ENTRIES];
  double        opt_grib_dbl_val[MAX_OPT_GRIB_ENTRIES];
75
  /* (Optional) list of keyword/integer value pairs */
76
77
78
  int           opt_grib_int_nentries;
  char         *opt_grib_int_keyword[MAX_OPT_GRIB_ENTRIES];
  int           opt_grib_int_val[MAX_OPT_GRIB_ENTRIES];
79
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
80
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
81
vartable_t;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
82

83

Uwe Schulzweida's avatar
Uwe Schulzweida committed
84
int vartableInit = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
85
vartable_t *vartable;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
86
87
88
static int varTablesize = 0;
int nvars = 0;

89

Uwe Schulzweida's avatar
Uwe Schulzweida committed
90
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
91
void paramInitEntry(int varID, int param)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
92
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
93
  vartable[varID].param          = param;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
94
  vartable[varID].prec           = 0;
95
  vartable[varID].tsteptype      = TSTEP_INSTANT;
96
97
  vartable[varID].timave         = 0;
  vartable[varID].timaccu        = 0;
98
99
100
  vartable[varID].gridID         = UNDEFID;
  vartable[varID].zaxistype      = 0;
  vartable[varID].ltype          = 0;
101
102
  vartable[varID].lbounds        = 0;
  vartable[varID].level_sf       = 0;
103
  vartable[varID].level_unit     = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
104
105
106
107
108
109
  vartable[varID].levelTable     = NULL;
  vartable[varID].levelTableSize = 0;
  vartable[varID].nlevels        = 0;
  vartable[varID].instID         = UNDEFID;
  vartable[varID].modelID        = UNDEFID;
  vartable[varID].tableID        = UNDEFID;
110
111
  vartable[varID].typeOfGeneratingProcess   = UNDEFID;
  vartable[varID].productDefinitionTemplate = UNDEFID;
112
  vartable[varID].comptype       = COMPRESS_NONE;
113
  vartable[varID].complevel      = 1;
114
115
  vartable[varID].lmissval       = 0;
  vartable[varID].missval        = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
116
  vartable[varID].name           = NULL;
117
  vartable[varID].stdname        = NULL;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
118
119
  vartable[varID].longname       = NULL;
  vartable[varID].units          = NULL;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
120
  vartable[varID].ensdata        = NULL;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
121
122
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
123
static
124
int varGetEntry(int param, int zaxistype, int ltype, const char *name)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
125
126
127
128
129
{
  int varID;

  for ( varID = 0; varID < varTablesize; varID++ )
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
130
      if ( vartable[varID].param     == param     &&
131
	   vartable[varID].zaxistype == zaxistype &&
Uwe Schulzweida's avatar
Uwe Schulzweida committed
132
	   vartable[varID].ltype     == ltype )
133
134
135
136
137
138
139
140
141
142
        {
          if ( name && name[0] && vartable[varID].name && vartable[varID].name[0] )
            {
              if ( strcmp(name, vartable[varID].name) == 0 ) return (varID);
            }
          else
            {
              return (varID);
            }
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
143
144
145
146
147
    }

  return (UNDEFID);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
148
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
149
150
151
152
153
154
155
156
void varFree(void)
{
  int varID;

  for ( varID = 0; varID < nvars; varID++ )
    {
      if ( vartable[varID].levelTable )
	free(vartable[varID].levelTable);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
157
158

      if ( vartable[varID].name )     free(vartable[varID].name);
159
      if ( vartable[varID].stdname )  free(vartable[varID].stdname);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
160
161
      if ( vartable[varID].longname ) free(vartable[varID].longname);
      if ( vartable[varID].units )    free(vartable[varID].units);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
162
      if ( vartable[varID].ensdata )  free(vartable[varID].ensdata);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
    }

  if ( vartable )
    free(vartable);

  vartable = NULL;
  varTablesize = 0;
  nvars = 0;

  if ( Vct )
    free(Vct);

  Vct = NULL;
  Vctsize = 0;
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
179
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
180
181
182
183
int levelNewEntry(int varID, int level1, int level2)
{
  int levelID = 0;
  int levelTableSize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
184
  leveltable_t *levelTable;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
185
186
187
188
189
190
191
192
193
194
195
196
197

  levelTableSize = vartable[varID].levelTableSize;
  levelTable     = vartable[varID].levelTable;

  /*
    Look for a free slot in levelTable.
    (Create the table the first time through).
  */
  if ( ! levelTableSize )
    {
      int i;

      levelTableSize = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
198
      levelTable = (leveltable_t *) malloc(levelTableSize*sizeof(leveltable_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
199
200
      if( levelTable == NULL )
	{
201
202
          Message("levelTableSize = %d", levelTableSize);
	  SysError("Allocation of leveltable failed!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
	}

      for( i = 0; i < levelTableSize; i++ )
	levelTable[i].recID = UNDEFID;
    }
  else
    {
      while( levelID < levelTableSize )
	{
	  if ( levelTable[levelID].recID == UNDEFID ) break;
	  levelID++;
	}
    }
  /*
    If the table overflows, double its size.
  */
  if( levelID == levelTableSize )
    {
      int i;

      levelTableSize = 2*levelTableSize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
224
      levelTable = (leveltable_t *) realloc(levelTable, levelTableSize*sizeof(leveltable_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
225
226
      if( levelTable == NULL )
	{
227
228
          Message("levelTableSize = %d", levelTableSize);
	  SysError("Reallocation of leveltable failed");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
229
230
231
232
233
234
235
	}
      levelID = levelTableSize/2;

      for( i = levelID; i < levelTableSize; i++ )
	levelTable[i].recID = UNDEFID;
    }

236
237
238
  levelTable[levelID].level1   = level1;
  levelTable[levelID].level2   = level2;
  levelTable[levelID].lindex   = levelID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
239
240
241
242
243
244
245
246

  vartable[varID].nlevels = levelID+1;
  vartable[varID].levelTableSize = levelTableSize;
  vartable[varID].levelTable = levelTable;

  return (levelID);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
247
#define  UNDEF_PARAM  -4711
Uwe Schulzweida's avatar
Uwe Schulzweida committed
248

Uwe Schulzweida's avatar
Uwe Schulzweida committed
249
250
static
int paramNewEntry(int param)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
251
252
253
254
255
256
257
258
259
260
261
262
{
  int varID = 0;

  /*
    Look for a free slot in vartable.
    (Create the table the first time through).
  */
  if ( ! varTablesize )
    {
      int i;

      varTablesize = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
263
      vartable = (vartable_t *) malloc(varTablesize*sizeof(vartable_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
264
265
      if( vartable == NULL )
	{
266
267
          Message("varTablesize = %d", varTablesize);
	  SysError("Allocation of vartable failed");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
268
269
270
	}

      for( i = 0; i < varTablesize; i++ )
271
272
	{
	  vartable[i].param = UNDEF_PARAM;
273
#if  defined  (HAVE_LIBGRIB_API)
274
275
	  vartable[i].opt_grib_int_nentries = 0;
	  vartable[i].opt_grib_dbl_nentries = 0;
276
#endif
277
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
278
279
280
281
282
    }
  else
    {
      while( varID < varTablesize )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
283
	  if ( vartable[varID].param == UNDEF_PARAM ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
284
285
286
287
288
289
	  varID++;
	}
    }
  /*
    If the table overflows, double its size.
  */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
290
  if ( varID == varTablesize )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
291
292
293
294
    {
      int i;

      varTablesize = 2*varTablesize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
295
      vartable = (vartable_t *) realloc(vartable, varTablesize*sizeof(vartable_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
296
297
      if( vartable == NULL )
	{
298
299
          Message("varTablesize = %d", varTablesize);
	  SysError("Reallocation of vartable failed!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
300
301
302
303
	}
      varID = varTablesize/2;

      for( i = varID; i < varTablesize; i++ )
304
305
	{
	  vartable[i].param = UNDEF_PARAM;
306
#if  defined  (HAVE_LIBGRIB_API)
307
308
	  vartable[i].opt_grib_int_nentries = 0;
	  vartable[i].opt_grib_dbl_nentries = 0;
309
#endif
310
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
311
312
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
313
  paramInitEntry(varID, param);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
314
315
316
317
318

  return (varID);
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
319
void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
320
		  int level1, int level2, int level_sf, int level_unit, int prec,
321
		  int *pvarID, int *plevelID, int tsteptype, int numavg, int ltype,
322
		  const char *name, const char *stdname, const char *longname, const char *units)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
323
{
324
  int varID = UNDEFID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
325
326
  int levelID = -1;

327
  if ( ! (cdiSplitLtype105 == 1 && zaxistype == ZAXIS_HEIGHT) )
328
    varID = varGetEntry(param, zaxistype, ltype, name);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
329
330
331
332

  if ( varID == UNDEFID )
    {
      nvars++;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
333
      varID = paramNewEntry(param);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
334
      vartable[varID].gridID    = gridID;
335
336
      vartable[varID].zaxistype = zaxistype;
      vartable[varID].ltype     = ltype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
337
      vartable[varID].lbounds   = lbounds;
338
      vartable[varID].level_sf  = level_sf;
339
      vartable[varID].level_unit = level_unit;
340
      if ( tsteptype != UNDEFID ) vartable[varID].tsteptype = tsteptype;
341
      if ( numavg ) vartable[varID].timave = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
342
343

      if ( name )     if ( name[0] )     vartable[varID].name     = strdup(name);
344
      if ( stdname )  if ( stdname[0] )  vartable[varID].stdname  = strdup(stdname);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
345
346
      if ( longname ) if ( longname[0] ) vartable[varID].longname = strdup(longname);
      if ( units )    if ( units[0] )    vartable[varID].units    = strdup(units);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
347
348
349
    }
  else
    {
350
351
352
      char paramstr[32];
      cdiParamToString(param, paramstr, sizeof(paramstr));

Uwe Schulzweida's avatar
Uwe Schulzweida committed
353
354
      if ( vartable[varID].gridID != gridID )
	{
355
356
	  Message("param = %s gridID = %d", paramstr, gridID);
	  Error("horizontal grid must not change for same param!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
357
	}
358
      if ( vartable[varID].zaxistype != zaxistype )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
359
	{
360
361
	  Message("param = %s zaxistype = %d", paramstr, zaxistype);
	  Error("zaxistype must not change for same param!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
362
363
364
	}
    }

365
366
  if ( prec > vartable[varID].prec ) vartable[varID].prec = prec;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
367
368
369
370
371
372
  levelID = levelNewEntry(varID, level1, level2);
  vartable[varID].levelTable[levelID].recID = recID;

  *pvarID   = varID;
  *plevelID = levelID;
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
373
/*
Uwe Schulzweida's avatar
Uwe Schulzweida committed
374
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
375
376
377
378
379
380
381
382
383
int dblcmp(const void *s1, const void *s2)
{
  int cmp = 0;

  if      ( *((double *) s1) < *((double *) s2) ) cmp = -1;
  else if ( *((double *) s1) > *((double *) s2) ) cmp =  1;

  return (cmp);
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
384
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
385
static
386
int cmpLevelTable(const void* s1, const void* s2)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
387
388
{
  int cmp = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
389
390
  const leveltable_t* x = (const leveltable_t*) s1;
  const leveltable_t* y = (const leveltable_t*) s2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
391
392
393
394
395
396
397
398
399
  /*
  printf("%g %g  %d %d\n", x->leve11, y->level1, x, y);
  */
  if      ( x->level1 < y->level1 ) cmp = -1;
  else if ( x->level1 > y->level1 ) cmp =  1;

  return (cmp);
}

400
401
402
403
static
int cmpLevelTableInv(const void* s1, const void* s2)
{
  int cmp = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
404
405
  const leveltable_t* x = (const leveltable_t*) s1;
  const leveltable_t* y = (const leveltable_t*) s2;
406
407
408
409
410
411
412
413
414
  /*
  printf("%g %g  %d %d\n", x->leve11, y->level1, x, y);
  */
  if      ( x->level1 < y->level1 ) cmp =  1;
  else if ( x->level1 > y->level1 ) cmp = -1;

  return (cmp);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
415

416
417
418
419
typedef struct
{
  int      varid;
  int      param;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
420
  int      ltype;
421
422
423
424
425
}
param_t;


static
426
int cmpparam(const void* s1, const void* s2)
427
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
428
429
  const param_t* x = (const param_t*) s1;
  const param_t* y = (const param_t*) s2;
430

431
432
  int cmp = (( x->param > y->param ) - ( x->param < y->param )) * 2
           + ( x->ltype > y->ltype ) - ( x->ltype < y->ltype );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
433
434
435
436

  return (cmp);
}

437

438
void cdi_generate_vars(stream_t *streamptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
439
440
441
{
  int varID, gridID, zaxisID, levelID;
  int instID, modelID, tableID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
442
  int param, nlevels, zaxistype, lindex, ltype;
443
  int prec;
444
  int tsteptype;
445
  int timave, timaccu;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
446
  int lbounds;
447
  int comptype;
448
  char name[CDI_MAX_NAME], longname[CDI_MAX_NAME], units[CDI_MAX_NAME];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
449
450
451
452
  double *dlevels = NULL;
  double *dlevels1 = NULL;
  double *dlevels2 = NULL;
  int vlistID;
453
  int *varids, index, varid;
454
  double level_sf = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
455

456
  vlistID =  streamptr->vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
457

458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
  varids = (int *) malloc(nvars*sizeof(int));
  for ( varID = 0; varID < nvars; varID++ ) varids[varID] = varID;

  if ( streamptr->sortname )
    {
      int index;
      param_t **varInfo;
      varInfo    = (param_t **) malloc(nvars*sizeof(param_t *));
      varInfo[0] = (param_t *)  malloc(nvars*sizeof(param_t));

      for ( index = 1; index < nvars; index++ )
	varInfo[index] = varInfo[0] + index;

      for ( varid = 0; varid < nvars; varid++ )
	{
	  varInfo[varid]->varid = varids[varid];
	  varInfo[varid]->param = vartable[varid].param;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
475
	  varInfo[varid]->ltype = vartable[varid].ltype;
476
477
478
479
480
481
482
483
484
485
486
	}
      qsort(varInfo[0], nvars, sizeof(param_t), cmpparam);
      for ( varid = 0; varid < nvars; varid++ )
	{
	  varids[varid] = varInfo[varid]->varid;
	}
      free(varInfo[0]);
      free(varInfo);
    }

  for ( index = 0; index < nvars; index++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
487
    {
488
489
490
491
492
493
494
      varid     = varids[index];

      gridID    = vartable[varid].gridID;
      param     = vartable[varid].param;
      nlevels   = vartable[varid].nlevels;
      ltype     = vartable[varid].ltype;
      zaxistype = vartable[varid].zaxistype;
495
496
      if ( ltype == 0 && zaxistype == ZAXIS_GENERIC && cdiDefaultLeveltype != -1 )
	zaxistype = cdiDefaultLeveltype;
497
498
499
500
501
      lbounds   = vartable[varid].lbounds;
      prec      = vartable[varid].prec;
      instID    = vartable[varid].instID;
      modelID   = vartable[varid].modelID;
      tableID   = vartable[varid].tableID;
502
      tsteptype = vartable[varid].tsteptype;
503
504
      timave    = vartable[varid].timave;
      timaccu   = vartable[varid].timaccu;
505
      comptype  = vartable[varid].comptype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
506

507
      level_sf  = 1;
508
      if ( vartable[varid].level_sf != 0 ) level_sf = 1./vartable[varid].level_sf;
509

Uwe Schulzweida's avatar
Uwe Schulzweida committed
510
511
      zaxisID = UNDEFID;

512
513
      if ( ltype == 0 && zaxistype == ZAXIS_GENERIC && nlevels == 1 &&
	   ! (fabs(vartable[varid].levelTable[0].level1)>0) )
514
	zaxistype = ZAXIS_SURFACE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
515
516
517

      dlevels = (double *) malloc(nlevels*sizeof(double));

518
      if ( lbounds && zaxistype != ZAXIS_HYBRID && zaxistype != ZAXIS_HYBRID_HALF )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
519
	for ( levelID = 0; levelID < nlevels; levelID++ )
520
521
	  dlevels[levelID] = (level_sf*vartable[varid].levelTable[levelID].level1 +
	                      level_sf*vartable[varid].levelTable[levelID].level2)/2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
522
523
      else
	for ( levelID = 0; levelID < nlevels; levelID++ )
524
	  dlevels[levelID] = level_sf*vartable[varid].levelTable[levelID].level1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
525
526
527

      if ( nlevels > 1 )
	{
528
          bool linc = true, ldec = true, lsort = false;
529
          for ( levelID = 1; levelID < nlevels; levelID++ )
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
            {
              /* check increasing of levels */
              linc &= (dlevels[levelID] > dlevels[levelID-1]);
              /* check decreasing of levels */
              ldec &= (dlevels[levelID] < dlevels[levelID-1]);
            }
          /*
           * always sort pressure z-axis to ensure
           * vartable[varid].levelTable[levelID1].level1 < vartable[varid].levelTable[levelID2].level1 <=> levelID1 > levelID2
           * unless already sorted in decreasing order
           */
          if ( !ldec && zaxistype == ZAXIS_PRESSURE )
            {
              qsort(vartable[varid].levelTable, (size_t)nlevels, sizeof(leveltable_t), cmpLevelTableInv);
              lsort = true;
            }
          /*
           * always sort hybrid and depth-below-land z-axis to ensure
           * vartable[varid].levelTable[levelID1].level1 < vartable[varid].levelTable[levelID2].level1 <=> levelID1 < levelID2
           * unless already sorted in increasing order
           */
          else if ( (!linc && !ldec) ||
                    zaxistype == ZAXIS_HYBRID ||
                    zaxistype == ZAXIS_DEPTH_BELOW_LAND )
            {
              qsort(vartable[varid].levelTable, (size_t)nlevels, sizeof(leveltable_t), cmpLevelTable);
              lsort = true;
            }
558
559
560
561
562
563
564
565
566
567
568

          if ( lsort )
            {
              if ( lbounds && zaxistype != ZAXIS_HYBRID && zaxistype != ZAXIS_HYBRID_HALF )
                for ( levelID = 0; levelID < nlevels; levelID++ )
                  dlevels[levelID] = (level_sf*vartable[varid].levelTable[levelID].level1 +
                                      level_sf*vartable[varid].levelTable[levelID].level2)/2.;
              else
                for ( levelID = 0; levelID < nlevels; levelID++ )
                  dlevels[levelID] = level_sf*vartable[varid].levelTable[levelID].level1;
            }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
569
570
571
572
573
574
	}

      if ( lbounds )
	{
	  dlevels1 = (double *) malloc(nlevels*sizeof(double));
	  for ( levelID = 0; levelID < nlevels; levelID++ )
575
	    dlevels1[levelID] = level_sf*vartable[varid].levelTable[levelID].level1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
576
577
	  dlevels2 = (double *) malloc(nlevels*sizeof(double));
	  for ( levelID = 0; levelID < nlevels; levelID++ )
578
	    dlevels2[levelID] = level_sf*vartable[varid].levelTable[levelID].level2;
579
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
580

581
582
583
      char *unitptr = cdiUnitNamePtr(vartable[varid].level_unit);
      zaxisID = varDefZaxis(vlistID, zaxistype, nlevels, dlevels, lbounds, dlevels1, dlevels2,
                            Vctsize, Vct, NULL, NULL, unitptr, 0, 0, ltype);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
584

585
586
      if ( zaxisInqType(zaxisID) == ZAXIS_REFERENCE )
        {
587
          if ( numberOfVerticalLevels > 0 ) zaxisDefNlevRef(zaxisID, numberOfVerticalLevels);
588
589
590
591
          if ( numberOfVerticalGrid > 0 ) zaxisDefNumber(zaxisID, numberOfVerticalGrid);
          if ( uuidVGrid[0] != 0 ) zaxisDefUUID(zaxisID, uuidVGrid);
        }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
592
593
594
595
      if ( lbounds ) free(dlevels1);
      if ( lbounds ) free(dlevels2);
      free(dlevels);

596
      varID = stream_new_var(streamptr, gridID, zaxisID);
597
      varID = vlistDefVar(vlistID, gridID, zaxisID, tsteptype);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
598

Uwe Schulzweida's avatar
Uwe Schulzweida committed
599
      vlistDefVarParam(vlistID, varID, param);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
600
      vlistDefVarDatatype(vlistID, varID, prec);
601
602
      vlistDefVarTimave(vlistID, varID, timave);
      vlistDefVarTimaccu(vlistID, varID, timaccu);
603
      vlistDefVarCompType(vlistID, varID, comptype);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
604

605
606
607
      if ( vartable[varid].typeOfGeneratingProcess != UNDEFID )
        vlistDefVarTypeOfGeneratingProcess(vlistID, varID, vartable[varid].typeOfGeneratingProcess);

608
609
610
      if ( vartable[varid].productDefinitionTemplate != UNDEFID )
        vlistDefVarProductDefinitionTemplate(vlistID, varID, vartable[varid].productDefinitionTemplate);

611
612
      if ( vartable[varid].lmissval ) vlistDefVarMissval(vlistID, varID, vartable[varid].missval);

613
      if ( vartable[varid].name )     vlistDefVarName(vlistID, varID, vartable[varid].name);
614
      if ( vartable[varid].stdname )  vlistDefVarStdname(vlistID, varID, vartable[varid].stdname);
615
616
      if ( vartable[varid].longname ) vlistDefVarLongname(vlistID, varID, vartable[varid].longname);
      if ( vartable[varid].units )    vlistDefVarUnits(vlistID, varID, vartable[varid].units);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
617

Uwe Schulzweida's avatar
Uwe Schulzweida committed
618
619
620
621
      if ( vartable[varid].ensdata )  vlistDefVarEnsemble(vlistID, varID, vartable[varid].ensdata->ens_index,
	                                                  vartable[varid].ensdata->ens_count,
							  vartable[varid].ensdata->forecast_init_type);

622
#if  defined  (HAVE_LIBGRIB_API)
623
624
625
626
627
628
629
630
631
632
633
634
      /* ---------------------------------- */
      /* Local change: 2013-04-23, FP (DWD) */
      /* ---------------------------------- */

      int    i;
      vlist_t *vlistptr;
      vlistptr = vlist_to_pointer(vlistID);
      for (i=0; i<vartable[varid].opt_grib_int_nentries; i++)
        {
          int idx = vlistptr->vars[varID].opt_grib_int_nentries;
          vlistptr->vars[varID].opt_grib_int_nentries++;
          if ( idx >= MAX_OPT_GRIB_ENTRIES ) Error("Too many optional keyword/integer value pairs!");
635
          vlistptr->vars[varID].opt_grib_int_update[idx] = TRUE;
636
637
638
639
640
641
642
643
          vlistptr->vars[varID].opt_grib_int_val[idx] = vartable[varid].opt_grib_int_val[idx];
          vlistptr->vars[varID].opt_grib_int_keyword[idx] = strdupx(vartable[varid].opt_grib_int_keyword[idx]);
        }
      for (i=0; i<vartable[varid].opt_grib_dbl_nentries; i++)
        {
          int idx = vlistptr->vars[varID].opt_grib_dbl_nentries;
          vlistptr->vars[varID].opt_grib_dbl_nentries++;
          if ( idx >= MAX_OPT_GRIB_ENTRIES ) Error("Too many optional keyword/double value pairs!");
644
          vlistptr->vars[varID].opt_grib_dbl_update[idx] = TRUE;
645
646
647
648
          vlistptr->vars[varID].opt_grib_dbl_val[idx] = vartable[varid].opt_grib_dbl_val[idx];
          vlistptr->vars[varID].opt_grib_dbl_keyword[idx] = strdupx(vartable[varid].opt_grib_dbl_keyword[idx]);
        }
      /* note: if the key is not defined, we do not throw an error! */
649
#endif
650

Uwe Schulzweida's avatar
Uwe Schulzweida committed
651
652
      if ( cdiDefaultTableID != UNDEFID )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
653
	  int pdis, pcat, pnum;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
654
	  cdiDecodeParam(param, &pnum, &pcat, &pdis);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
655
	  if ( tableInqParNamePtr(cdiDefaultTableID, pnum) )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
656
657
658
	    {
	      if ( tableID != UNDEFID )
		{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
659
		  strcpy(name, tableInqParNamePtr(cdiDefaultTableID, pnum));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
660
		  vlistDefVarName(vlistID, varID, name);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
661
		  if ( tableInqParLongnamePtr(cdiDefaultTableID, pnum) )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
662
		    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
663
		      strcpy(longname, tableInqParLongnamePtr(cdiDefaultTableID, pnum));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
664
665
		      vlistDefVarLongname(vlistID, varID, longname);
		    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
666
		  if ( tableInqParUnitsPtr(cdiDefaultTableID, pnum) )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
667
		    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
668
		      strcpy(units, tableInqParUnitsPtr(cdiDefaultTableID, pnum));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
		      vlistDefVarUnits(vlistID, varID, units);
		    }
		}
	      else
		tableID = cdiDefaultTableID;
	    }
	  if ( cdiDefaultModelID != UNDEFID ) modelID = cdiDefaultModelID;
	  if ( cdiDefaultInstID  != UNDEFID )  instID = cdiDefaultInstID;
	}

      if ( instID  != UNDEFID ) vlistDefVarInstitut(vlistID, varID, instID);
      if ( modelID != UNDEFID ) vlistDefVarModel(vlistID, varID, modelID);
      if ( tableID != UNDEFID ) vlistDefVarTable(vlistID, varID, tableID);
    }

684
  for ( index = 0; index < nvars; index++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
685
    {
686
687
688
689
      varID     = index;
      varid     = varids[index];

      nlevels   = vartable[varid].nlevels;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
690
691
692
      /*
      for ( levelID = 0; levelID < nlevels; levelID++ )
	{
693
	  lindex = vartable[varid].levelTable[levelID].lindex;
694
	  printf("%d %d %d %d %d\n", varID, levelID,
695
696
697
		 vartable[varid].levelTable[levelID].lindex,
		 vartable[varid].levelTable[levelID].recID,
		 vartable[varid].levelTable[levelID].level1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
698
699
700
701
	}
      */
      for ( levelID = 0; levelID < nlevels; levelID++ )
	{
702
	  streamptr->vars[varID].level[levelID] = vartable[varid].levelTable[levelID].recID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
703
	  for ( lindex = 0; lindex < nlevels; lindex++ )
704
	    if ( levelID == vartable[varid].levelTable[lindex].lindex ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
705
706

	  if ( lindex == nlevels )
707
	    Error("Internal problem! lindex not found.");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
708

Uwe Schulzweida's avatar
Uwe Schulzweida committed
709
	  streamptr->vars[varID].lindex[levelID] = lindex;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
710
711
712
	}
    }

713
714
  free(varids);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
715
716
717
718
719
720
721
722
723
724
  varFree();
}


void varDefVCT(size_t vctsize, double *vctptr)
{
  if ( Vct == NULL && vctptr != NULL && vctsize > 0 )
    {
      Vctsize = vctsize;
      Vct = (double *) malloc(vctsize*sizeof(double));
725
      memcpy(Vct, vctptr, vctsize*sizeof(double));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
726
727
728
    }
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
729

730
void varDefZAxisReference(int nhlev, int nvgrid, char *uuid)
731
{
732
  numberOfVerticalLevels = nhlev;
733
  numberOfVerticalGrid = nvgrid;
734
  memcpy(uuidVGrid, uuid, 16);
735
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
736

Uwe Schulzweida's avatar
Uwe Schulzweida committed
737

738
int varDefGrid(int vlistID, grid_t grid, int mode)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
739
740
741
742
743
{
  /*
    mode: 0 search in vlist and grid table
          1 search in grid table
   */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
744
  int gridglobdefined = FALSE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
745
746
747
748
  int griddefined;
  int ngrids;
  int gridID = UNDEFID;
  int index;
749
  vlist_t *vlistptr;
750
  int * gridIndexList, i;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
751
752
753

  vlistptr = vlist_to_pointer(vlistID);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
754
  griddefined = FALSE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
755
756
757
758
759
760
761
  ngrids = vlistptr->ngrids;

  if ( mode == 0 )
    for ( index = 0; index < ngrids; index++ )
      {
	gridID = vlistptr->gridIDs[index];
	if ( gridID == UNDEFID )
762
	  Error("Internal problem: undefined gridID %d!", gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
763
764
765

	if ( gridCompare(gridID, grid) == 0 )
	  {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
766
	    griddefined = TRUE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
767
768
769
770
771
772
773
	    break;
	  }
      }

  if ( ! griddefined )
    {
      ngrids = gridSize();
774
775
      if ( ngrids > 0 )
        {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
776
          gridIndexList = (int*) malloc(ngrids*sizeof(int));
777
778
779
780
781
782
783
784
785
786
787
788
          gridGetIndexList ( ngrids, gridIndexList );
          for ( i = 0; i < ngrids; i++ )
            {
              gridID = gridIndexList[i];
              if ( gridCompare(gridID, grid) == 0 )
                {
                  gridglobdefined = TRUE;
                  break;
                }
            }
          if ( gridIndexList ) free ( gridIndexList );
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811

      ngrids = vlistptr->ngrids;
      if ( mode == 1 )
	for ( index = 0; index < ngrids; index++ )
	  if ( vlistptr->gridIDs[index] == gridID )
	    {
	      gridglobdefined = FALSE;
	      break;
	    }
    }

  if ( ! griddefined )
    {
      if ( ! gridglobdefined ) gridID = gridGenerate(grid);
      ngrids = vlistptr->ngrids;
      vlistptr->gridIDs[ngrids] = gridID;
      vlistptr->ngrids++;
    }

  return (gridID);
}


812
int zaxisCompare(int zaxisID, int zaxistype, int nlevels, int lbounds, double *levels, char *longname, char *units, int ltype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
813
814
815
816
{
  int differ = 1;
  int levelID;
  int zlbounds = 0;
817
  int ltype_is_equal = FALSE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
818

819
820
821
  if ( ltype == zaxisInqLtype(zaxisID) ) ltype_is_equal = TRUE;

  if ( ltype_is_equal && (zaxistype == zaxisInqType(zaxisID) || zaxistype == ZAXIS_GENERIC) )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
822
823
824
825
826
    {
      if ( zaxisInqLbounds(zaxisID, NULL) > 0 ) zlbounds = 1;
      if ( nlevels == zaxisInqSize(zaxisID) && zlbounds == lbounds )
	{
	  const double *dlevels;
827
828
	  char zlongname[CDI_MAX_NAME];
	  char zunits[CDI_MAX_NAME];
829

Uwe Schulzweida's avatar
Uwe Schulzweida committed
830
831
832
	  dlevels = zaxisInqLevelsPtr(zaxisID);
	  for ( levelID = 0; levelID < nlevels; levelID++ )
	    {
833
	      if ( fabs(dlevels[levelID] - levels[levelID]) > 1.e-9 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
		break;
	    }

	  if ( levelID == nlevels ) differ = 0;

	  if ( ! differ )
	    {
	      zaxisInqLongname(zaxisID, zlongname);
	      zaxisInqUnits(zaxisID, zunits);
	      if ( longname && zlongname[0] )
		{
		  if ( strcmp(longname, zlongname) != 0 ) differ = 1;
		}
	      if ( units && zunits[0] )
		{
		  if ( strcmp(units, zunits) != 0 ) differ = 1;
		}
	    }
	}
    }

  return (differ);
}


859
860
int varDefZaxis(int vlistID, int zaxistype, int nlevels, double *levels, int lbounds,
		double *levels1, double *levels2, int vctsize, double *vct, char *name,
861
		char *longname, char *units, int prec, int mode, int ltype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
862
863
864
865
866
867
868
869
870
871
{
  /*
    mode: 0 search in vlist and zaxis table
          1 search in zaxis table
   */
  int zaxisdefined;
  int nzaxis;
  int zaxisID = UNDEFID;
  int index;
  int zaxisglobdefined = 0;
872
  vlist_t *vlistptr;
873
  int i;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
874
875
876
877
878
879
880
881
882
883
884

  vlistptr = vlist_to_pointer(vlistID);

  zaxisdefined = 0;
  nzaxis = vlistptr->nzaxis;

  if ( mode == 0 )
    for ( index = 0; index < nzaxis; index++ )
      {
	zaxisID = vlistptr->zaxisIDs[index];

885
	if ( zaxisCompare(zaxisID, zaxistype, nlevels, lbounds, levels, longname, units, ltype) == 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
886
887
888
889
890
891
892
893
894
	  {
	    zaxisdefined = 1;
	    break;
	  }
      }

  if ( ! zaxisdefined )
    {
      nzaxis = zaxisSize();
895
896
      if ( nzaxis > 0 )
        {
897
898
          int *zaxisIndexList;
          zaxisIndexList = (int *) malloc ( nzaxis * sizeof ( int ));
899
900
901
902
903
904
905
906
907
908
909
910
          zaxisGetIndexList ( nzaxis, zaxisIndexList );
          for ( i = 0; i < nzaxis; i++ )
            {
              zaxisID = zaxisIndexList[i];
              if ( zaxisCompare(zaxisID, zaxistype, nlevels, lbounds, levels, longname, units, ltype) == 0 )
                {
                  zaxisglobdefined = 1;
                  break;
                }
            }
          if ( zaxisIndexList ) free ( zaxisIndexList );
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925

      nzaxis = vlistptr->nzaxis;
      if ( mode == 1 )
	for ( index = 0; index < nzaxis; index++ )
	  if ( vlistptr->zaxisIDs[index] == zaxisID )
	    {
	      zaxisglobdefined = FALSE;
	      break;
	    }
    }

  if ( ! zaxisdefined )
    {
      if ( ! zaxisglobdefined )
	{
926
	  zaxisID = zaxisCreate(zaxistype, nlevels);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
927
928
929
930
931
932
933
	  zaxisDefLevels(zaxisID, levels);
	  if ( lbounds )
	    {
	      zaxisDefLbounds(zaxisID, levels1);
	      zaxisDefUbounds(zaxisID, levels2);
	    }

934
	  if ( zaxistype == ZAXIS_HYBRID || zaxistype == ZAXIS_HYBRID_HALF )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
935
936
	    {
	      /* if ( vctsize > 0 && vctsize >= 2*(nlevels+1)) */
937
938
	      /* if ( vctsize > 0 && vctsize >= 2*(nlevels)) */
	      if ( vctsize > 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
939
940
		zaxisDefVct(zaxisID, vctsize, vct);
	      else
941
		Warning("VCT missing");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
942
943
944
945
946
947
	    }

	  zaxisDefName(zaxisID, name);
	  zaxisDefLongname(zaxisID, longname);
	  zaxisDefUnits(zaxisID, units);
	  zaxisDefPrec(zaxisID, prec);
948
	  zaxisDefLtype(zaxisID, ltype);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
949
950
951
952
953
954
955
956
957
958
959
	}

      nzaxis = vlistptr->nzaxis;
      vlistptr->zaxisIDs[nzaxis] = zaxisID;
      vlistptr->nzaxis++;
    }

  return (zaxisID);
}


960
961
962
963
964
965
966
void varDefMissval(int varID, double missval)
{
  vartable[varID].lmissval = 1;
  vartable[varID].missval = missval;
}


967
void varDefCompType(int varID, int comptype)
968
{
969
970
  if ( vartable[varID].comptype == COMPRESS_NONE )
    vartable[varID].comptype = comptype;
971
972
973
}


974
void varDefCompLevel(int varID, int complevel)
975
{
976
  vartable[varID].complevel = complevel;
977
978
979
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
int varInqInst(int varID)
{
  return (vartable[varID].instID);
}


void varDefInst(int varID, int instID)
{
  vartable[varID].instID = instID;
}


int varInqModel(int varID)
{
  return (vartable[varID].modelID);
}


void varDefModel(int varID, int modelID)
{
  vartable[varID].modelID = modelID;
}


int varInqTable(int varID)
{
  return (vartable[varID].tableID);
}


void varDefTable(int varID, int tableID)
{
  vartable[varID].tableID = tableID;
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025


void varDefEnsembleInfo(int varID, int ens_idx, int ens_count, int forecast_type)
{
  if ( vartable[varID].ensdata == NULL )
      vartable[varID].ensdata = (ensinfo_t *) malloc( sizeof( ensinfo_t ) );

  vartable[varID].ensdata->ens_index = ens_idx;
  vartable[varID].ensdata->ens_count = ens_count;
  vartable[varID].ensdata->forecast_init_type = forecast_type;
}

1026

1027
1028
1029
1030
1031
1032
void varDefTypeOfGeneratingProcess(int varID, int typeOfGeneratingProcess)
{
  vartable[varID].typeOfGeneratingProcess = typeOfGeneratingProcess;
}


1033
1034
1035
1036
1037
1038
void varDefProductDefinitionTemplate(int varID, int productDefinitionTemplate)
{
  vartable[varID].productDefinitionTemplate = productDefinitionTemplate;
}


1039
1040
void varDefOptGribInt(int varID, long lval, const char *keyword)
{
1041
#if  defined  (HAVE_LIBGRIB_API)
1042
1043
1044
1045
1046
  int idx = vartable[varID].opt_grib_int_nentries;
  vartable[varID].opt_grib_int_nentries++;
  if ( idx >= MAX_OPT_GRIB_ENTRIES ) Error("Too many optional keyword/integer value pairs!");
  vartable[varID].opt_grib_int_val[idx] = (int) lval;
  vartable[varID].opt_grib_int_keyword[idx] = strdupx(keyword);
1047
#endif
1048
1049
1050
1051
1052
}


void varDefOptGribDbl(int varID, double dval, const char *keyword)
{
1053
#if  defined  (HAVE_LIBGRIB_API)
1054
1055
1056
  int idx = vartable[varID].opt_grib_dbl_nentries;
  vartable[varID].opt_grib_dbl_nentries++;
  if ( idx >= MAX_OPT_GRIB_ENTRIES ) Error("Too many optional keyword/double value pairs!");
1057
1058
  vartable[varID].opt_grib_dbl_val[idx] = dval;
  vartable[varID].opt_grib_dbl_keyword[idx] = strdupx(keyword);
1059
#endif
1060
1061
1062
1063
1064
1065
}


int varOptGribNentries(int varID)
{
  int nentries = 0;
1066
#if  defined  (HAVE_LIBGRIB_API)
1067
  nentries = vartable[varID].opt_grib_int_nentries + vartable[varID].opt_grib_dbl_nentries;
1068
#endif
1069
1070
1071
  return (nentries);
}

1072
1073
1074
1075
1076
1077
1078
1079
1080
/*
 * Local Variables:
 * c-file-style: "Java"
 * c-basic-offset: 2
 * indent-tabs-mode: nil
 * show-trailing-whitespace: t
 * require-trailing-newline: t
 * End:
 */