stream_cgribex.c 58.3 KB
Newer Older
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1
2
3
4
#if defined (HAVE_CONFIG_H)
#  include "config.h"
#endif

5
#include <limits.h>
Uwe Schulzweida's avatar
Uwe Schulzweida committed
6
7
8
9
#include <stdio.h>

#include "dmemory.h"
#include "cdi.h"
10
#include "cdi_int.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
11
12
13
14
#include "file.h"
#include "varscan.h"
#include "datetime.h"
#include "vlist.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
15
#include "stream_grb.h"
16
#include "stream_cgribex.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
17

Uwe Schulzweida's avatar
Uwe Schulzweida committed
18
19
20
#if  defined  (HAVE_LIBCGRIBEX)
#  include "cgribex.h"
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
21
22

typedef struct {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
23
  int param;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
24
25
26
  int level1;
  int level2;
  int ltype;
27
  int tsteptype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
28
} compvar_t;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
29
30


Uwe Schulzweida's avatar
Uwe Schulzweida committed
31
#if  defined  (HAVE_LIBCGRIBEX)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
32
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
33
int cgribexGetGridType(int *isec2)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
34
{
35
  int gridtype = GRID_GENERIC;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
36
37
38

  switch (ISEC2_GridType)
    {
39
    case  GRIB1_GTYPE_LATLON:     { gridtype = GRID_LONLAT;     break; }
40
41
    case  GRIB1_GTYPE_LATLON_ROT: { gridtype = GRID_PROJECTION; break; }
    case  GRIB1_GTYPE_LCC:        { gridtype = GRID_LCC;        break; }
42
43
44
45
46
47
    case  GRIB1_GTYPE_GAUSSIAN:   { if ( ISEC2_Reduced )
	                              gridtype = GRID_GAUSSIAN_REDUCED;
                         	    else
				      gridtype = GRID_GAUSSIAN;
          	                    break;
                                  }
48
49
    case  GRIB1_GTYPE_SPECTRAL:   { gridtype = GRID_SPECTRAL;   break; }
    case  GRIB1_GTYPE_GME:        { gridtype = GRID_GME;        break; }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
50
51
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
52
  return gridtype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
53
54
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
55
static
56
bool cgribexGetIsRotated(int *isec2)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
57
{
58
  return (ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
59
60
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
61
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
62
int cgribexGetZaxisHasBounds(int grb_ltype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
63
64
65
{
  int lbounds = 0;

66
  switch (grb_ltype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
67
    {
68
    case GRIB1_LTYPE_SIGMA_LAYER:
Uwe Schulzweida's avatar
Uwe Schulzweida committed
69
70
    case GRIB1_LTYPE_HYBRID_LAYER:
    case GRIB1_LTYPE_LANDDEPTH_LAYER:
Uwe Schulzweida's avatar
Uwe Schulzweida committed
71
72
73
74
75
76
      {
	lbounds = 1;
	break;
      }
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
77
  return lbounds;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
78
79
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
80
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
81
int cgribexGetTimeUnit(int *isec1)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
82
{
83
  int timeunit = TUNIT_HOUR;
84
  static bool lprint = true;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
85
86
87

  switch ( ISEC1_TimeUnit )
    {
88
89
90
91
92
93
94
95
    case ISEC1_TABLE4_MINUTE:    timeunit = TUNIT_MINUTE;    break;
    case ISEC1_TABLE4_QUARTER:   timeunit = TUNIT_QUARTER;   break;
    case ISEC1_TABLE4_30MINUTES: timeunit = TUNIT_30MINUTES; break;
    case ISEC1_TABLE4_HOUR:      timeunit = TUNIT_HOUR;      break;
    case ISEC1_TABLE4_3HOURS:    timeunit = TUNIT_3HOURS;    break;
    case ISEC1_TABLE4_6HOURS:    timeunit = TUNIT_6HOURS;    break;
    case ISEC1_TABLE4_12HOURS:   timeunit = TUNIT_12HOURS;   break;
    case ISEC1_TABLE4_DAY:       timeunit = TUNIT_DAY;       break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
96
97
98
    default:
      if ( lprint )
	{
99
	  Message("GRIB time unit %d unsupported!", ISEC1_TimeUnit);
100
	  lprint = false;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
101
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
102
      break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
103
104
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
105
  return timeunit;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
106
107
}

108
static
109
bool cgribexTimeIsFC(int *isec1)
110
{
111
  bool isFC = (ISEC1_TimeRange == 10 && ISEC1_TimePeriod1 == 0 && ISEC1_TimePeriod2 == 0) ? false : true;
112

Uwe Schulzweida's avatar
Uwe Schulzweida committed
113
  return isFC;
114
115
116
117
118
}

static
int cgribexGetTsteptype(int timerange)
{
119
  int tsteptype = TSTEP_INSTANT;
120
  static bool lprint = true;
121
122
123
124
125
126
127
128
129
130
131
132
133

  switch ( timerange )
    {
    case  0:  tsteptype = TSTEP_INSTANT;  break;
    case  1:  tsteptype = TSTEP_INSTANT2; break;
    case  2:  tsteptype = TSTEP_RANGE;    break;
    case  3:  tsteptype = TSTEP_AVG;      break;
    case  4:  tsteptype = TSTEP_ACCUM;    break;
    case  5:  tsteptype = TSTEP_DIFF;     break;
    case 10:  tsteptype = TSTEP_INSTANT3; break;
    default:
      if ( lprint )
	{
134
	  Message("Time range indicator %d unsupported, set to 0!", timerange);
135
	  lprint = false;
136
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
137
      break;
138
139
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
140
  return tsteptype;
141
142
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
143
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
144
void cgribexGetGrid(stream_t *streamptr, int *isec2, int *isec4, grid_t *grid, int iret)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
145
{
146
  bool compyinc = true;
147
  int gridtype = cgribexGetGridType(isec2);
148
  int projtype = (gridtype == GRID_PROJECTION && cgribexGetIsRotated(isec2)) ? CDI_PROJ_RLL : CDI_UNDEFID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
149

150
  if ( streamptr->unreduced && gridtype == GRID_GAUSSIAN_REDUCED && iret != -801 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
151
    {
152
153
154
      int ilat, nlon = 0;
      for ( ilat = 0; ilat < ISEC2_NumLat; ++ilat )
        if ( ISEC2_RowLon(ilat) > nlon ) nlon = ISEC2_RowLon(ilat);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
155
      gridtype = GRID_GAUSSIAN;
156
157
      ISEC2_NumLon = nlon;
      ISEC4_NumValues = nlon*ISEC2_NumLat;
158
      compyinc = false;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
159
160
    }

161
  grid_init(grid);
162
  cdiGridTypeInit(grid, gridtype, 0);
163

164
  if ( gridtype == GRID_LONLAT || gridtype == GRID_GAUSSIAN || projtype == CDI_PROJ_RLL )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
165
    {
166
167
168
169
170
171
172
173
174
175
      if ( ISEC4_NumValues != ISEC2_NumLon*ISEC2_NumLat )
        Error("numberOfPoints (%d) and gridSize (%d) differ!", ISEC4_NumValues, ISEC2_NumLon*ISEC2_NumLat);
      grid->size  = ISEC4_NumValues;
      grid->x.size = ISEC2_NumLon;
      grid->y.size = ISEC2_NumLat;
      if ( gridtype == GRID_GAUSSIAN ) grid->np = ISEC2_NumPar;
      grid->x.inc  = 0;
      grid->y.inc  = 0;
      grid->x.flag = 0;
      /* if ( ISEC2_FirstLon != 0 || ISEC2_LastLon != 0 ) */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
176
      {
177
178
179
        if ( grid->x.size > 1 )
          {
            bool recompinc = true;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
180

181
182
183
184
185
            if ( ISEC2_LastLon < ISEC2_FirstLon && ISEC2_LastLon < 0 ) ISEC2_LastLon += 360000;

            if ( ISEC2_ResFlag && ISEC2_LonIncr > 0 )
              {
                if ( abs(ISEC2_LastLon - (ISEC2_FirstLon+ISEC2_LonIncr*(grid->x.size-1))) <= 2 )
186
                  {
187
188
                    recompinc = false;
                    grid->x.inc = ISEC2_LonIncr * 0.001;
189
                  }
190
              }
191

192
193
            /* recompute xinc if necessary */
            if ( recompinc ) grid->x.inc = (ISEC2_LastLon - ISEC2_FirstLon) * 0.001 / (grid->x.size-1);
194

195
196
197
198
199
200
201
202
203
204
205
206
207
208
            /* correct xinc if necessary */
            if ( ISEC2_FirstLon == 0 && ISEC2_LastLon > 354000 && ISEC2_LastLon < 360000 )
              {
                double xinc = 360. / grid->x.size;
                if ( fabs(grid->x.inc-xinc) > 0.0 )
                  {
                    grid->x.inc = xinc;
                    if ( CDI_Debug ) Message("set xinc to %g", grid->x.inc);
                  }
              }
          }
        grid->x.first = ISEC2_FirstLon * 0.001;
        grid->x.last  = ISEC2_LastLon  * 0.001;
        grid->x.flag  = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
209
      }
210
211
      grid->y.flag = 0;
      /* if ( ISEC2_FirstLat != 0 || ISEC2_LastLat != 0 ) */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
212
      {
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
        if ( grid->y.size > 1 && compyinc )
          {
            bool recompinc = true;
            if ( ISEC2_ResFlag && ISEC2_LatIncr > 0 )
              {
                if ( abs(ISEC2_LastLat - (ISEC2_FirstLat+ISEC2_LatIncr*(grid->y.size-1))) <= 2 )
                  {
                    recompinc = false;
                    grid->y.inc = ISEC2_LatIncr * 0.001;
                  }
              }

            /* recompute yinc if necessary */
            if ( recompinc ) grid->y.inc = (ISEC2_LastLat - ISEC2_FirstLat) * 0.001 / (grid->y.size - 1);
          }
        grid->y.first = ISEC2_FirstLat * 0.001;
        grid->y.last  = ISEC2_LastLat  * 0.001;
        grid->y.flag  = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
231
      }
232
233
234
235
236
237
238
239
240
241
242
243
    }
  else if ( gridtype == GRID_GAUSSIAN_REDUCED )
    {
      grid->np      = ISEC2_NumPar;
      grid->size    = ISEC4_NumValues;
      grid->rowlon  = ISEC2_RowLonPtr;
      grid->nrowlon = ISEC2_NumLat;
      grid->y.size  = ISEC2_NumLat;
      grid->x.inc   = 0;
      grid->y.inc   = 0;
      grid->x.flag  = 0;
      /* if ( ISEC2_FirstLon != 0 || ISEC2_LastLon != 0 ) */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
244
      {
245
246
247
248
249
250
251
252
253
254
255
256
        if ( grid->x.size > 1 )
          {
            if ( ISEC2_LastLon < ISEC2_FirstLon && ISEC2_LastLon < 0 ) ISEC2_LastLon += 360000;

            if ( ISEC2_ResFlag && ISEC2_LonIncr > 0 )
              grid->x.inc = ISEC2_LonIncr * 0.001;
            else
              grid->x.inc = (ISEC2_LastLon - ISEC2_FirstLon) * 0.001 / (grid->x.size - 1);
          }
        grid->x.first = ISEC2_FirstLon * 0.001;
        grid->x.last  = ISEC2_LastLon  * 0.001;
        grid->x.flag  = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
257
      }
258
259
      grid->y.flag = 0;
      /* if ( ISEC2_FirstLat != 0 || ISEC2_LastLat != 0 ) */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
260
      {
261
262
263
264
265
266
267
268
269
270
        if ( grid->y.size > 1 )
          {
            if ( ISEC2_ResFlag && ISEC2_LatIncr > 0 )
              grid->y.inc = ISEC2_LatIncr * 0.001;
            else
              grid->y.inc = (ISEC2_LastLat - ISEC2_FirstLat) * 0.001 / (grid->y.size - 1);
          }
        grid->y.first = ISEC2_FirstLat * 0.001;
        grid->y.last  = ISEC2_LastLat  * 0.001;
        grid->y.flag  = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
271
272
      }
    }
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
  else if ( gridtype == GRID_LCC )
    {
      if ( ISEC4_NumValues != ISEC2_NumLon*ISEC2_NumLat )
        Error("numberOfPoints (%d) and gridSize (%d) differ!",
              ISEC4_NumValues, ISEC2_NumLon*ISEC2_NumLat);

      grid->size  = ISEC4_NumValues;
      grid->x.size = ISEC2_NumLon;
      grid->y.size = ISEC2_NumLat;

      grid->lcc.xinc      = ISEC2_Lambert_dx;
      grid->lcc.yinc      = ISEC2_Lambert_dy;
      grid->lcc.originLon = ISEC2_FirstLon * 0.001;
      grid->lcc.originLat = ISEC2_FirstLat * 0.001;
      grid->lcc.lonParY   = ISEC2_Lambert_Lov * 0.001;
      grid->lcc.lat1      = ISEC2_Lambert_LatS1 * 0.001;
      grid->lcc.lat2      = ISEC2_Lambert_LatS2 * 0.001;
      grid->lcc.projflag  = ISEC2_Lambert_ProjFlag;
      grid->lcc.scanflag  = ISEC2_ScanFlag;

      grid->x.flag = 0;
      grid->y.flag = 0;
    }
  else if ( gridtype == GRID_SPECTRAL )
    {
      grid->size  = ISEC4_NumValues;
      grid->trunc = ISEC2_PentaJ;
      if ( ISEC2_RepMode == 2 )
        grid->lcomplex = 1;
      else
        grid->lcomplex = 0;
    }
  else if ( gridtype == GRID_GME )
    {
      grid->size  = ISEC4_NumValues;
      grid->gme.nd    = ISEC2_GME_ND;
      grid->gme.ni    = ISEC2_GME_NI;
      grid->gme.ni2   = ISEC2_GME_NI2;
      grid->gme.ni3   = ISEC2_GME_NI3;
    }
  else if ( gridtype == GRID_GENERIC )
    {
      grid->size  = ISEC4_NumValues;
      grid->x.size = 0;
      grid->y.size = 0;
    }
  else
    {
      Error("Unsupported grid type: %s", gridNamePtr(gridtype));
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
323

324
325
  grid->type = gridtype;
  grid->projtype = projtype;
326
327
328
}

static
329
void cgribexAddRecord(stream_t * streamptr, int param, int *isec1, int *isec2, double *fsec2, double *fsec3,
330
		      int *isec4, long recsize, off_t position, int datatype, int comptype, int lmv, int iret)
331
{
332
  int varID;
333
334
  int levelID = 0;

335
336
337
  int vlistID = streamptr->vlistID;
  int tsID    = streamptr->curTsID;
  int recID   = recordNewEntry(streamptr, tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
338
  record_t *record = &streamptr->tsteps[tsID].records[recID];
339

340
341
  int tsteptype = cgribexGetTsteptype(ISEC1_TimeRange);
  int numavg    = ISEC1_AvgNum;
342

343
344
  int level1  = ISEC1_Level1;
  int level2  = ISEC1_Level2;
345
346
347

  /* fprintf(stderr, "param %d %d %d %d\n", param, level1, level2, ISEC1_LevelType); */

348
349
350
351
352
353
  record->size      = (size_t)recsize;
  record->position  = position;
  record->param     = param;
  record->ilevel    = level1;
  record->ilevel2   = level2;
  record->ltype     = ISEC1_LevelType;
Thomas Jahns's avatar
Thomas Jahns committed
354
  record->tsteptype = (short)tsteptype;
355

Uwe Schulzweida's avatar
Uwe Schulzweida committed
356
  grid_t *gridptr = (grid_t*) Malloc(sizeof(*gridptr));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
357
  cgribexGetGrid(streamptr, isec2, isec4, gridptr, iret);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
358

Uwe Schulzweida's avatar
Uwe Schulzweida committed
359
  struct addIfNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, gridptr, 0);
360
  int gridID = gridAdded.Id;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
361
362
363
364
365
366
367
368
369
  if ( gridAdded.isNew )
    {
      if ( gridptr->nrowlon )
        {
          size_t nrowlon = (size_t) gridptr->nrowlon;
          int *rowlon = gridptr->rowlon;
          gridptr->rowlon = (int*) Malloc(nrowlon * sizeof(int));
          memcpy(gridptr->rowlon, rowlon, nrowlon * sizeof(int));
        }
370
371
372
373
374
      else if ( gridptr->projtype == CDI_PROJ_RLL )
        {
          double xpole =   ISEC2_LonSP*0.001 - 180;
          double ypole = - ISEC2_LatSP*0.001;
          double angle = - FSEC2_RotAngle;
375
          gridDefParamRLL(gridID, xpole, ypole, angle);
376
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
377
378
379
    }
  else
    Free(gridptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
380

381
  int zaxistype = grib1ltypeToZaxisType(ISEC1_LevelType);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
382

383
  if ( zaxistype == ZAXIS_HYBRID || zaxistype == ZAXIS_HYBRID_HALF )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
384
    {
385
      size_t vctsize = (size_t)ISEC2_NumVCP;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
386
387
388
389
390
      double *vctptr = &fsec2[10];

      varDefVCT(vctsize, vctptr);
    }

391
  int lbounds = cgribexGetZaxisHasBounds(ISEC1_LevelType);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
392

393
394
  if ( datatype > 32 ) datatype = DATATYPE_PACK32;
  if ( datatype <  0 ) datatype = DATATYPE_PACK;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
395

396
  varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2, 0, 0,
397
398
	       datatype, &varID, &levelID, tsteptype, numavg, ISEC1_LevelType, -1,
               NULL, NULL, NULL, NULL, NULL, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
399

Thomas Jahns's avatar
Thomas Jahns committed
400
401
  record->varID   = (short)varID;
  record->levelID = (short)levelID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
402

403
  varDefCompType(varID, comptype);
404

405
406
407
408
409
410
411
  if ( ISEC1_LocalFLag )
    {
      if      ( ISEC1_CenterID == 78  && isec1[36] == 253 ) // DWD local extension
        varDefEnsembleInfo(varID, isec1[54], isec1[53], isec1[52]);
      else if ( ISEC1_CenterID == 252 && isec1[36] ==   1 ) // MPIM local extension
        varDefEnsembleInfo(varID, isec1[38], isec1[39], isec1[37]);
    }
412

413
414
  if ( lmv ) varDefMissval(varID, FSEC3_MissVal);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
415
  if ( varInqInst(varID) == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
416
417
418
419
420
    {
      int center, subcenter, instID;
      center    = ISEC1_CenterID;
      subcenter = ISEC1_SubCenterID;
      instID    = institutInq(center, subcenter, NULL, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
421
      if ( instID == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
422
423
424
425
	instID = institutDef(center, subcenter, NULL, NULL);
      varDefInst(varID, instID);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
426
  if ( varInqModel(varID) == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
427
428
429
    {
      int modelID;
      modelID = modelInq(varInqInst(varID), ISEC1_ModelID, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
430
      if ( modelID == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
431
432
433
434
	modelID = modelDef(varInqInst(varID), ISEC1_ModelID, NULL);
      varDefModel(varID, modelID);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
435
  if ( varInqTable(varID) == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
436
437
    {
      int tableID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
438

Uwe Schulzweida's avatar
Uwe Schulzweida committed
439
      tableID = tableInq(varInqModel(varID), ISEC1_CodeTable, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
440

Uwe Schulzweida's avatar
Uwe Schulzweida committed
441
      if ( tableID == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
442
443
444
445
	tableID = tableDef(varInqModel(varID), ISEC1_CodeTable, NULL);
      varDefTable(varID, tableID);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
446
447
  streamptr->tsteps[tsID].nallrecs++;
  streamptr->nrecs++;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
448
449
}

450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
static
void MCH_get_undef(int *isec1, double *undef_pds, double *undef_eps)
{
  /* 2010-01-13: Oliver Fuhrer */
  if ( ISEC1_CenterID == 215 ) {
    if (isec1[34] != 0 && isec1[34] != 255) {
      if (isec1[34] & 2) {
        if (isec1[34] & 1) {
          *undef_pds = -0.99*pow(10.0,-isec1[35]);
        } else {
          *undef_pds = +0.99*pow(10.0,-isec1[35]);
        }
        *undef_eps = pow(10.0,-isec1[35]-1);
      } else {
        if (isec1[34] & 1) {
          *undef_pds = -0.99*pow(10.0,+isec1[35]);
        } else {
          *undef_pds = +0.99*pow(10.0,+isec1[35]);
        }
        *undef_eps = pow(10.0,isec1[35]-1);
      }
    }
  }
}

static
void cgribexDecodeHeader(int *isec0, int *isec1, int *isec2, double *fsec2,
477
			 int *isec3, double *fsec3, int *isec4, double *fsec4,
478
			 int *gribbuffer, int recsize, int *lmv, int *iret)
479
{
480
  int ipunp = 0, iword = 0;
481

482
483
  memset(isec1, 0, 256*sizeof(int));

484
  gribExDP(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, fsec4,
485
	   ipunp, (int *) gribbuffer, recsize, &iword, "J", iret);
486
487
488
489
490
491
492
493
494
495
496
497

  *lmv = 0;

  if ( ISEC1_CenterID == 215 && (isec1[34] != 0 && isec1[34] != 255) )
    {
      double undef_pds, undef_eps;

      MCH_get_undef(isec1, &undef_pds, &undef_eps);
      FSEC3_MissVal = undef_pds;
      *lmv = 1;
    }
}
498
499

static
500
compvar_t cgribexVarSet(int param, int level1, int level2, int leveltype, int trange)
501
502
{
  compvar_t compVar;
503
  int tsteptype = cgribexGetTsteptype(trange);
504

505
506
507
508
509
  compVar.param     = param;
  compVar.level1    = level1;
  compVar.level2    = level2;
  compVar.ltype     = leveltype;
  compVar.tsteptype = tsteptype;
510

Uwe Schulzweida's avatar
Uwe Schulzweida committed
511
  return compVar;
512
513
}

Thomas Jahns's avatar
Thomas Jahns committed
514
515
static inline int
cgribexVarCompare(compvar_t compVar, record_t record, int flag)
516
{
Thomas Jahns's avatar
Thomas Jahns committed
517
518
519
520
  int tstepDiff = (!((flag == 0) & (((compVar.tsteptype == TSTEP_INSTANT)
                                     & (record.tsteptype == TSTEP_INSTANT3))
                                    |((compVar.tsteptype == TSTEP_INSTANT3)
                                      & (record.tsteptype == TSTEP_INSTANT)))))
Thomas Jahns's avatar
Thomas Jahns committed
521
522
523
524
525
526
    & (compVar.tsteptype != record.tsteptype);
  int rstatus = (compVar.param != record.param)
    |           (compVar.level1 != record.ilevel)
    |           (compVar.level2 != record.ilevel2)
    |           (compVar.ltype != record.ltype)
    |           tstepDiff;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
527
  return rstatus;
528
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
529
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
530

531
532
533
#define gribWarning(text, nrecs, timestep, paramstr, level1, level2) \
            Warning("Record %2d (id=%s lev1=%d lev2=%d) timestep %d: %s", nrecs, paramstr, level1, level2, timestep, text)

534
#if  defined  (HAVE_LIBCGRIBEX)
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567

static inline void
cgribexScanTsFixNtsteps(stream_t *streamptr, off_t recpos)
{
  if ( streamptr->ntsteps == -1 )
    {
      int tsID = tstepsNewEntry(streamptr);
      if ( tsID != streamptr->rtsteps )
	Error("Internal error. tsID = %d", tsID);

      streamptr->tsteps[tsID-1].next   = TRUE;
      streamptr->tsteps[tsID].position = recpos;
    }
}

static inline void
cgribexScanTsConstAdjust(stream_t *streamptr, taxis_t *taxis)
{
  int vlistID = streamptr->vlistID;
  if ( streamptr->ntsteps == 1 )
    {
      if ( taxis->vdate == 0 && taxis->vtime == 0 )
	{
	  streamptr->ntsteps = 0;
	  for (int varID = 0; varID < streamptr->nvars; varID++ )
	    {
	      vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
	    }
	}
    }
}


568
int cgribexScanTimestep1(stream_t * streamptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
569
570
{
  double fsec2[512], fsec3[2], *fsec4 = NULL;
571
  int lmv = 0, iret = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
572
  off_t recpos = 0;
573
  void *gribbuffer = NULL;
574
  size_t buffersize = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
575
  int rstatus;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
576
577
  int param = 0;
  int level1 = 0, level2 = 0, vdate = 0, vtime = 0;
578
  DateTime datetime, datetime0 = { LONG_MIN, LONG_MIN };
Uwe Schulzweida's avatar
Uwe Schulzweida committed
579
  size_t readsize;
580
  unsigned nrecords, recID;
581
  int nrecs_scanned = 0;
582
  int datatype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
583
  long recsize = 0;
584
585
  bool warn_time = true;
  bool warn_numavg = true;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
586
  int taxisID = -1;
587
588
  int rdate = 0, rtime = 0, tunit = 0;
  bool fcast = false;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
589
  int vlistID;
590
  int comptype;
591
  long unzipsize;
592
  char paramstr[32];
593
  int nskip = cdiSkipRecords;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
594
595

  streamptr->curTsID = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
596

597
598
599
600
601
  int *isec0 = streamptr->record->sec0;
  int *isec1 = streamptr->record->sec1;
  int *isec2 = streamptr->record->sec2;
  int *isec3 = streamptr->record->sec3;
  int *isec4 = streamptr->record->sec4;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
602

603
604
  int tsID  = tstepsNewEntry(streamptr);
  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
605
606

  if ( tsID != 0 )
607
    Error("Internal problem! tstepsNewEntry returns %d", tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
608

609
  int fileID = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
610

611
612
613
  while ( nskip-- > 0 )
    {
      recsize = gribGetSize(fileID);
614
      if ( recsize == 0 )
615
	Error("Skipping of %d records failed!", cdiSkipRecords);
616

617
      recpos  = fileGetPos(fileID);
618
      fileSetPos(fileID, (off_t)recsize, SEEK_CUR);
619
620
    }

621
  unsigned nrecs = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
622
623
624
625
626
627
628
  while ( TRUE )
    {
      recsize = gribGetSize(fileID);
      recpos  = fileGetPos(fileID);

      if ( recsize == 0 )
	{
629
	  if ( nrecs == 0 )
630
	    Error("No GRIB records found!");
631

Uwe Schulzweida's avatar
Uwe Schulzweida committed
632
	  streamptr->ntsteps = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
633
634
	  break;
	}
635
      if ( (size_t)recsize > buffersize )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
636
	{
637
	  buffersize = (size_t)recsize;
638
	  gribbuffer = Realloc(gribbuffer, buffersize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
639
640
	}

641
      readsize = (size_t)recsize;
642
      rstatus = gribRead(fileID, (unsigned char *)gribbuffer, &readsize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
643
      if ( rstatus ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
644

645
      comptype = CDI_COMPRESS_NONE;
646
      if ( gribGetZip(recsize, (unsigned char *)gribbuffer, &unzipsize) > 0 )
647
	{
648
	  comptype = CDI_COMPRESS_SZIP;
649
	  unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
650
	  if ( buffersize < (size_t)unzipsize )
651
	    {
652
	      buffersize = (size_t)unzipsize;
653
	      gribbuffer = Realloc(gribbuffer, buffersize);
654
655
656
	    }
	}

657
      nrecs_scanned++;
658
      cgribexDecodeHeader(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, fsec4,
659
			  (int *) gribbuffer, (int)recsize, &lmv, &iret);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
660

Uwe Schulzweida's avatar
Uwe Schulzweida committed
661
      param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255);
662
663
      cdiParamToString(param, paramstr, sizeof(paramstr));

664
665
      if ( ISEC1_LevelType == 100 ) ISEC1_Level1 *= 100;
      if ( ISEC1_LevelType ==  99 ) ISEC1_LevelType = 100;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
666
667
668
      level1   = ISEC1_Level1;
      level2   = ISEC1_Level2;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
669
670
      gribDateTime(isec1, &vdate, &vtime);

671
      if ( ISEC4_NumBits > 0 && ISEC4_NumBits <= 32 )
672
	datatype = ISEC4_NumBits;
673
      else
674
        datatype = DATATYPE_PACK;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
675
676
677
678
679
680
681

      if ( nrecs == 0 )
	{
	  datetime0.date = vdate;
	  datetime0.time = vtime;
	  rdate = gribRefDate(isec1);
	  rtime = gribRefTime(isec1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
682
	  tunit = cgribexGetTimeUnit(isec1);
683
	  fcast = cgribexTimeIsFC(isec1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
684
685
686
687
688
	}
      else
	{
	  datetime.date  = vdate;
	  datetime.time  = vtime;
689
	  compvar_t compVar = cgribexVarSet(param, level1, level2, ISEC1_LevelType, ISEC1_TimeRange);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
690
691
	  for ( recID = 0; recID < nrecs; recID++ )
	    {
692
	      if ( cgribexVarCompare(compVar, streamptr->tsteps[0].records[recID], 0) == 0 ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
693
	    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
694
695
696
697
698

	  if ( cdiInventoryMode == 1 )
	    {
	      if ( recID < nrecs ) break;
	      if ( warn_time )
699
		if ( datetimeCmp(datetime, datetime0) != 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
700
		  {
701
                    gribWarning("Inconsistent verification time!", nrecs_scanned, tsID+1, paramstr, level1, level2);
702
		    warn_time = false;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
703
704
705
706
		  }
	    }
	  else
	    {
707
	      if ( datetimeCmp(datetime, datetime0) != 0 ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
708
709
710

	      if ( recID < nrecs )
		{
711
		  gribWarning("Parameter already exist, skipped!", nrecs_scanned, tsID+1, paramstr, level1, level2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
712
713
714
		  continue;
		}
	    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
715
716
717
718
719
720
	}

      if ( ISEC1_AvgNum )
	{
	  if (  taxis->numavg && warn_numavg && (taxis->numavg != ISEC1_AvgNum) )
	    {
721
	      Warning("Changing numavg from %d to %d not supported!", taxis->numavg, ISEC1_AvgNum);
722
	      warn_numavg = false;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
723
724
725
726
727
728
729
730
731
732
	    }
	  else
	    {
	      taxis->numavg = ISEC1_AvgNum;
	    }
	}

      nrecs++;

      if ( CDI_Debug )
733
	Message("Read record %2d (id=%s lev1=%d lev2=%d) %8d %6d", nrecs_scanned, paramstr, level1, level2, vdate, vtime);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
734

735
      cgribexAddRecord(streamptr, param, isec1, isec2, fsec2, fsec3,
736
		       isec4, recsize, recpos, datatype, comptype, lmv, iret);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
737
738
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
739
  streamptr->rtsteps = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
740

Uwe Schulzweida's avatar
Uwe Schulzweida committed
741
  if ( nrecs == 0 ) return CDI_EUFSTRUCT;
742

743
  cdi_generate_vars(streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
744
745
746

  if ( fcast )
    {
747
      taxisID = taxisCreate(TAXIS_RELATIVE);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
748
749
750
751
752
753
754
      taxis->type  = TAXIS_RELATIVE;
      taxis->rdate = rdate;
      taxis->rtime = rtime;
      taxis->unit  = tunit;
    }
  else
    {
755
      taxisID = taxisCreate(TAXIS_ABSOLUTE);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
756
      taxis->type  = TAXIS_ABSOLUTE;
757
      taxis->unit  = tunit;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
758
759
    }

760
761
  taxis->vdate = (int)datetime0.date;
  taxis->vtime = (int)datetime0.time;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
762

Uwe Schulzweida's avatar
Uwe Schulzweida committed
763
  vlistID = streamptr->vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
764
765
  vlistDefTaxis(vlistID, taxisID);

766
767
  nrecords = (unsigned)streamptr->tsteps[0].nallrecs;
  if ( nrecords < (unsigned)streamptr->tsteps[0].recordSize )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
768
    {
769
      streamptr->tsteps[0].recordSize = (int)nrecords;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
770
      streamptr->tsteps[0].records =
771
      (record_t *) Realloc(streamptr->tsteps[0].records, nrecords*sizeof(record_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
772
773
    }

774
  streamptr->tsteps[0].recIDs = (int *) Malloc(nrecords*sizeof(int));
775
  streamptr->tsteps[0].nrecs = (int)nrecords;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
776
  for ( recID = 0; recID < nrecords; recID++ )
777
    streamptr->tsteps[0].recIDs[recID] = (int)recID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
778

Uwe Schulzweida's avatar
Uwe Schulzweida committed
779
  streamptr->record->buffer     = gribbuffer;
780
  streamptr->record->buffersize = (size_t)buffersize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
781

782
783
  cgribexScanTsFixNtsteps(streamptr, recpos);
  cgribexScanTsConstAdjust(streamptr, taxis);
784

Uwe Schulzweida's avatar
Uwe Schulzweida committed
785
  return 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
786
787
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
788

789
int cgribexScanTimestep2(stream_t * streamptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
790
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
791
  int rstatus = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
792
  double fsec2[512], fsec3[2], *fsec4 = NULL;
793
  int lmv = 0, iret = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
794
  off_t recpos = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
795
796
  int param = 0;
  int level1 = 0, level2 = 0, vdate = 0, vtime = 0;
797
  DateTime datetime, datetime0 = { LONG_MIN, LONG_MIN };
Uwe Schulzweida's avatar
Uwe Schulzweida committed
798
799
  int varID, gridID;
  size_t readsize;
800
  int nrecs, recID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
801
  long recsize = 0;
802
  bool warn_numavg = true;
803
  int tsteptype;
804
  long unzipsize;
805
  char paramstr[32];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
806

Uwe Schulzweida's avatar
Uwe Schulzweida committed
807
808
  streamptr->curTsID = 1;

809
810
811
812
813
  int *isec0 = streamptr->record->sec0;
  int *isec1 = streamptr->record->sec1;
  int *isec2 = streamptr->record->sec2;
  int *isec3 = streamptr->record->sec3;
  int *isec4 = streamptr->record->sec4;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
814

815
816
817
  int fileID  = streamptr->fileID;
  int vlistID = streamptr->vlistID;
  int taxisID = vlistInqTaxis(vlistID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
818

819
820
  void *gribbuffer = streamptr->record->buffer;
  size_t buffersize = streamptr->record->buffersize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
821

822
  int tsID = streamptr->rtsteps;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
823
  if ( tsID != 1 )
Thomas Jahns's avatar
Thomas Jahns committed
824
    Error("Internal problem! unexpected timestep %d", tsID+1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
825

826
  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
827

Uwe Schulzweida's avatar
Uwe Schulzweida committed
828
  fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
829

830
  cdi_create_records(streamptr, tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
831

832
  int nrecords = streamptr->tsteps[tsID].nallrecs;
833
  if ( nrecords ) streamptr->tsteps[1].recIDs = (int *) Malloc((size_t)nrecords * sizeof(int));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
834
  streamptr->tsteps[1].nrecs = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
835
  for ( recID = 0; recID < nrecords; recID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
836
    streamptr->tsteps[1].recIDs[recID] = -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
837

Uwe Schulzweida's avatar
Uwe Schulzweida committed
838
839
  for ( recID = 0; recID < nrecords; recID++ )
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
840
      varID = streamptr->tsteps[0].records[recID].varID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
841
842
      streamptr->tsteps[tsID].records[recID].position =	streamptr->tsteps[0].records[recID].position;
      streamptr->tsteps[tsID].records[recID].size     =	streamptr->tsteps[0].records[recID].size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
843
844
    }

845
846
  int nrecs_scanned = nrecords;
  int rindex = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
847
  while ( TRUE )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
848
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
849
850
      if ( rindex > nrecords ) break;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
851
852
853
854
      recsize = gribGetSize(fileID);
      recpos  = fileGetPos(fileID);
      if ( recsize == 0 )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
855
	  streamptr->ntsteps = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
856
857
	  break;
	}
858
      if ( (size_t)recsize > buffersize )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
859
	{
860
	  buffersize = (size_t)recsize;
861
	  gribbuffer = Realloc(gribbuffer, buffersize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
862
863
	}

864
      readsize = (size_t)recsize;
865
      rstatus = gribRead(fileID, (unsigned char *)gribbuffer, &readsize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
866
      if ( rstatus ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
867

868
      if ( gribGetZip(recsize, (unsigned char *)gribbuffer, &unzipsize) > 0 )
869
870
	{
	  unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
871
	  if ( buffersize < (size_t)unzipsize )
872
	    {
873
	      buffersize = (size_t)unzipsize;
874
	      gribbuffer = Realloc(gribbuffer, buffersize);
875
876
877
	    }
	}

878
      cgribexDecodeHeader(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, fsec4,
879
			  (int *) gribbuffer, (int)recsize, &lmv, &iret);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
880

881
882
      nrecs_scanned++;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
883
      param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255);
884
885
      cdiParamToString(param, paramstr, sizeof(paramstr));

886
887
      if ( ISEC1_LevelType == 100 ) ISEC1_Level1 *= 100;
      if ( ISEC1_LevelType ==  99 ) ISEC1_LevelType = 100;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
      level1    = ISEC1_Level1;
      level2    = ISEC1_Level2;

      gribDateTime(isec1, &vdate, &vtime);

      if ( rindex == 0 )
	{
	  if ( taxisInqType(taxisID) == TAXIS_RELATIVE )
	    {
	      taxis->type  = TAXIS_RELATIVE;
	      taxis->rdate = gribRefDate(isec1);
	      taxis->rtime = gribRefTime(isec1);
	    }
	  else
	    {
	      taxis->type  = TAXIS_ABSOLUTE;
	    }
905
	  taxis->unit  = cgribexGetTimeUnit(isec1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
906
907
	  taxis->vdate = vdate;
	  taxis->vtime = vtime;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
908
909
910

	  datetime0.date = vdate;
	  datetime0.time = vtime;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
911
912
	}

913
914
      tsteptype = cgribexGetTsteptype(ISEC1_TimeRange);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
915
916
917
      if ( ISEC1_AvgNum )
	{
	  if (  taxis->numavg && warn_numavg &&
918
        	(taxis->numavg != ISEC1_AvgNum) )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
919
920
	    {
	  /*
921
	      Warning("Changing numavg from %d to %d not supported!", taxis->numavg, ISEC1_AvgNum);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
922
	  */
923
	      warn_numavg = false;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
924
925
926
927
928
929
930
	    }
	  else
	    {
	      taxis->numavg = ISEC1_AvgNum;
	    }
	}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
931
932
      datetime.date  = vdate;
      datetime.time  = vtime;
933

934
      compvar_t compVar = cgribexVarSet(param, level1, level2, ISEC1_LevelType, ISEC1_TimeRange);
935

Uwe Schulzweida's avatar
Uwe Schulzweida committed
936
937
      for ( recID = 0; recID < nrecords; recID++ )
	{
938
	  if ( cgribexVarCompare(compVar, streamptr->tsteps[tsID].records[recID], 0) == 0 ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
939
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
940

Uwe Schulzweida's avatar
Uwe Schulzweida committed
941
942
      if ( recID == nrecords )
	{
943
	  gribWarning("Parameter not defined at timestep 1!", nrecs_scanned, tsID+1, paramstr, level1, level2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
944
	  return CDI_EUFSTRUCT;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
945
946
	}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
947
948
949
950
951
952
953
954
955
956
      if ( cdiInventoryMode == 1 )
	{
	  if ( streamptr->tsteps[tsID].records[recID].used )
	    {
	      break;
	    }
	  else
	    {
	      streamptr->tsteps[tsID].records[recID].used = TRUE;
	      streamptr->tsteps[tsID].recIDs[rindex] = recID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
957
	    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
958
959
960
961
962
	}
      else
	{
	  if ( streamptr->tsteps[tsID].records[recID].used )
	    {