stream_cgribex.c 58.9 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
40
41
42
43
44
45
    case  GRIB1_GTYPE_LATLON:     { if ( ISEC2_Reduced )        break; }
#ifdef TEST_PROJECTION
    case  GRIB1_GTYPE_LATLON_ROT: { gridtype = GRID_PROJECTION; break; }
#else
    case  GRIB1_GTYPE_LATLON_ROT: { gridtype = GRID_LONLAT;     break; }
#endif
    case  GRIB1_GTYPE_LCC:        { gridtype = GRID_LCC;        break; }
46
47
48
49
50
51
    case  GRIB1_GTYPE_GAUSSIAN:   { if ( ISEC2_Reduced )
	                              gridtype = GRID_GAUSSIAN_REDUCED;
                         	    else
				      gridtype = GRID_GAUSSIAN;
          	                    break;
                                  }
52
53
    case  GRIB1_GTYPE_SPECTRAL:   { gridtype = GRID_SPECTRAL;   break; }
    case  GRIB1_GTYPE_GME:        { gridtype = GRID_GME;        break; }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
54
55
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
56
  return gridtype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
57
58
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
59
static
60
bool cgribexGetIsRotated(int *isec2)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
61
{
62
  return (ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
63
64
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
65
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
66
int cgribexGetZaxisHasBounds(int grb_ltype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
67
68
69
{
  int lbounds = 0;

70
  switch (grb_ltype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
71
    {
72
    case GRIB1_LTYPE_SIGMA_LAYER:
Uwe Schulzweida's avatar
Uwe Schulzweida committed
73
74
    case GRIB1_LTYPE_HYBRID_LAYER:
    case GRIB1_LTYPE_LANDDEPTH_LAYER:
Uwe Schulzweida's avatar
Uwe Schulzweida committed
75
76
77
78
79
80
      {
	lbounds = 1;
	break;
      }
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
81
  return lbounds;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
82
83
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
84
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
85
int cgribexGetTimeUnit(int *isec1)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
86
{
87
  int timeunit = TUNIT_HOUR;
88
  static bool lprint = true;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
89
90
91

  switch ( ISEC1_TimeUnit )
    {
92
93
94
95
96
97
98
99
    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
100
101
102
    default:
      if ( lprint )
	{
103
	  Message("GRIB time unit %d unsupported!", ISEC1_TimeUnit);
104
	  lprint = false;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
105
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
106
      break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
107
108
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
109
  return timeunit;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
110
111
}

112
static
113
bool cgribexTimeIsFC(int *isec1)
114
{
115
  bool isFC = (ISEC1_TimeRange == 10 && ISEC1_TimePeriod1 == 0 && ISEC1_TimePeriod2 == 0) ? false : true;
116

Uwe Schulzweida's avatar
Uwe Schulzweida committed
117
  return isFC;
118
119
120
121
122
}

static
int cgribexGetTsteptype(int timerange)
{
123
  int tsteptype = TSTEP_INSTANT;
124
  static bool lprint = true;
125
126
127
128
129
130
131
132
133
134
135
136
137

  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 )
	{
138
	  Message("Time range indicator %d unsupported, set to 0!", timerange);
139
	  lprint = false;
140
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
141
      break;
142
143
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
144
  return tsteptype;
145
146
}

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

154
  if ( streamptr->unreduced && gridtype == GRID_GAUSSIAN_REDUCED && iret != -801 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
155
    {
156
157
158
      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
159
      gridtype = GRID_GAUSSIAN;
160
161
      ISEC2_NumLon = nlon;
      ISEC4_NumValues = nlon*ISEC2_NumLat;
162
      compyinc = false;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
163
164
    }

165
  grid_init(grid);
166
  cdiGridTypeInit(grid, gridtype, 0);
167

168
  if ( gridtype == GRID_LONLAT || gridtype == GRID_GAUSSIAN || projtype == CDI_PROJ_RLL )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
169
    {
170
171
172
173
174
175
176
177
178
179
      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
180
      {
181
182
183
        if ( grid->x.size > 1 )
          {
            bool recompinc = true;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
184

185
186
187
188
189
            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 )
190
                  {
191
192
                    recompinc = false;
                    grid->x.inc = ISEC2_LonIncr * 0.001;
193
                  }
194
              }
195

196
197
            /* recompute xinc if necessary */
            if ( recompinc ) grid->x.inc = (ISEC2_LastLon - ISEC2_FirstLon) * 0.001 / (grid->x.size-1);
198

199
200
201
202
203
204
205
206
207
208
209
210
211
212
            /* 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
213
      }
214
215
      grid->y.flag = 0;
      /* if ( ISEC2_FirstLat != 0 || ISEC2_LastLat != 0 ) */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
216
      {
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
        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
235
      }
236
237
238
239
240
241
242
243
244
245
246
247
    }
  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
248
      {
249
250
251
252
253
254
255
256
257
258
259
260
        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
261
      }
262
263
      grid->y.flag = 0;
      /* if ( ISEC2_FirstLat != 0 || ISEC2_LastLat != 0 ) */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
264
      {
265
266
267
268
269
270
271
272
273
274
        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
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
323
324
325
326
  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
327

328
  grid->isRotated = FALSE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
329
  if ( cgribexGetIsRotated(isec2) )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
330
    {
331
      grid->isRotated = TRUE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
332
      grid->rll.xpole =   ISEC2_LonSP*0.001 - 180;
333
      grid->rll.ypole = - ISEC2_LatSP*0.001;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
334
      grid->rll.angle = - FSEC2_RotAngle;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
335
336
    }

337
338
  grid->type = gridtype;
  grid->projtype = projtype;
339
340
341
}

static
342
void cgribexAddRecord(stream_t * streamptr, int param, int *isec1, int *isec2, double *fsec2, double *fsec3,
343
		      int *isec4, long recsize, off_t position, int datatype, int comptype, int lmv, int iret)
344
{
345
  int varID;
346
347
  int levelID = 0;

348
349
350
  int vlistID = streamptr->vlistID;
  int tsID    = streamptr->curTsID;
  int recID   = recordNewEntry(streamptr, tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
351
  record_t *record = &streamptr->tsteps[tsID].records[recID];
352

353
354
  int tsteptype = cgribexGetTsteptype(ISEC1_TimeRange);
  int numavg    = ISEC1_AvgNum;
355

356
357
  int level1  = ISEC1_Level1;
  int level2  = ISEC1_Level2;
358
359
360

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

361
362
363
364
365
366
  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
367
  record->tsteptype = (short)tsteptype;
368

Uwe Schulzweida's avatar
Uwe Schulzweida committed
369
370
  grid_t *gridptr = (grid_t*) Malloc(sizeof(*gridptr));
  cgribexGetGrid(streamptr, isec2, fsec2, isec4, gridptr, iret);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
371

Uwe Schulzweida's avatar
Uwe Schulzweida committed
372
  struct addIfNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, gridptr, 0);
373
  int gridID = gridAdded.Id;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
374
375
376
377
378
379
380
381
382
  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));
        }
383
384
385
386
387
388
389
      else if ( gridptr->projtype == CDI_PROJ_RLL )
        {
          double xpole =   ISEC2_LonSP*0.001 - 180;
          double ypole = - ISEC2_LatSP*0.001;
          double angle = - FSEC2_RotAngle;
          gridDefProjParamRLL(gridID, xpole, ypole, angle);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
390
391
392
    }
  else
    Free(gridptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
393

394
  int zaxistype = grib1ltypeToZaxisType(ISEC1_LevelType);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
395

396
  if ( zaxistype == ZAXIS_HYBRID || zaxistype == ZAXIS_HYBRID_HALF )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
397
    {
398
      size_t vctsize = (size_t)ISEC2_NumVCP;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
399
400
401
402
403
      double *vctptr = &fsec2[10];

      varDefVCT(vctsize, vctptr);
    }

404
  int lbounds = cgribexGetZaxisHasBounds(ISEC1_LevelType);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
405

406
407
  if ( datatype > 32 ) datatype = DATATYPE_PACK32;
  if ( datatype <  0 ) datatype = DATATYPE_PACK;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
408

409
  varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2, 0, 0,
410
411
	       datatype, &varID, &levelID, tsteptype, numavg, ISEC1_LevelType, -1,
               NULL, NULL, NULL, NULL, NULL, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
412

Thomas Jahns's avatar
Thomas Jahns committed
413
414
  record->varID   = (short)varID;
  record->levelID = (short)levelID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
415

416
  varDefCompType(varID, comptype);
417

418
419
420
421
422
423
424
  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]);
    }
425

426
427
  if ( lmv ) varDefMissval(varID, FSEC3_MissVal);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
428
  if ( varInqInst(varID) == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
429
430
431
432
433
    {
      int center, subcenter, instID;
      center    = ISEC1_CenterID;
      subcenter = ISEC1_SubCenterID;
      instID    = institutInq(center, subcenter, NULL, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
434
      if ( instID == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
435
436
437
438
	instID = institutDef(center, subcenter, NULL, NULL);
      varDefInst(varID, instID);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
439
  if ( varInqModel(varID) == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
440
441
442
    {
      int modelID;
      modelID = modelInq(varInqInst(varID), ISEC1_ModelID, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
443
      if ( modelID == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
444
445
446
447
	modelID = modelDef(varInqInst(varID), ISEC1_ModelID, NULL);
      varDefModel(varID, modelID);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
448
  if ( varInqTable(varID) == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
449
450
    {
      int tableID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
451

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
454
      if ( tableID == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
455
456
457
458
	tableID = tableDef(varInqModel(varID), ISEC1_CodeTable, NULL);
      varDefTable(varID, tableID);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
459
460
  streamptr->tsteps[tsID].nallrecs++;
  streamptr->nrecs++;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
461
462
}

463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
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,
490
			 int *isec3, double *fsec3, int *isec4, double *fsec4,
491
			 int *gribbuffer, int recsize, int *lmv, int *iret)
492
{
493
  int ipunp = 0, iword = 0;
494

495
496
  memset(isec1, 0, 256*sizeof(int));

497
  gribExDP(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, fsec4,
498
	   ipunp, (int *) gribbuffer, recsize, &iword, "J", iret);
499
500
501
502
503
504
505
506
507
508
509
510

  *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;
    }
}
511
512

static
513
compvar_t cgribexVarSet(int param, int level1, int level2, int leveltype, int trange)
514
515
{
  compvar_t compVar;
516
  int tsteptype = cgribexGetTsteptype(trange);
517

518
519
520
521
522
  compVar.param     = param;
  compVar.level1    = level1;
  compVar.level2    = level2;
  compVar.ltype     = leveltype;
  compVar.tsteptype = tsteptype;
523

Uwe Schulzweida's avatar
Uwe Schulzweida committed
524
  return compVar;
525
526
}

Thomas Jahns's avatar
Thomas Jahns committed
527
528
static inline int
cgribexVarCompare(compvar_t compVar, record_t record, int flag)
529
{
Thomas Jahns's avatar
Thomas Jahns committed
530
531
532
533
  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
534
535
536
537
538
539
    & (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
540
  return rstatus;
541
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
542
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
543

544
545
546
#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)

547
#if  defined  (HAVE_LIBCGRIBEX)
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580

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);
	    }
	}
    }
}


581
int cgribexScanTimestep1(stream_t * streamptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
582
583
{
  double fsec2[512], fsec3[2], *fsec4 = NULL;
584
  int lmv = 0, iret = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
585
  off_t recpos = 0;
586
  void *gribbuffer = NULL;
587
  size_t buffersize = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
588
  int rstatus;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
589
590
  int param = 0;
  int level1 = 0, level2 = 0, vdate = 0, vtime = 0;
591
  DateTime datetime, datetime0 = { LONG_MIN, LONG_MIN };
Uwe Schulzweida's avatar
Uwe Schulzweida committed
592
  size_t readsize;
593
  unsigned nrecords, recID;
594
  int nrecs_scanned = 0;
595
  int datatype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
596
  long recsize = 0;
597
598
  bool warn_time = true;
  bool warn_numavg = true;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
599
  int taxisID = -1;
600
601
  int rdate = 0, rtime = 0, tunit = 0;
  bool fcast = false;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
602
  int vlistID;
603
  int comptype;
604
  long unzipsize;
605
  char paramstr[32];
606
  int nskip = cdiSkipRecords;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
607
608

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

610
611
612
613
614
  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
615

616
617
  int tsID  = tstepsNewEntry(streamptr);
  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
618
619

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

622
  int fileID = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
623

624
625
626
  while ( nskip-- > 0 )
    {
      recsize = gribGetSize(fileID);
627
      if ( recsize == 0 )
628
	Error("Skipping of %d records failed!", cdiSkipRecords);
629

630
      recpos  = fileGetPos(fileID);
631
      fileSetPos(fileID, (off_t)recsize, SEEK_CUR);
632
633
    }

634
  unsigned nrecs = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
635
636
637
638
639
640
641
  while ( TRUE )
    {
      recsize = gribGetSize(fileID);
      recpos  = fileGetPos(fileID);

      if ( recsize == 0 )
	{
642
	  if ( nrecs == 0 )
643
	    Error("No GRIB records found!");
644

Uwe Schulzweida's avatar
Uwe Schulzweida committed
645
	  streamptr->ntsteps = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
646
647
	  break;
	}
648
      if ( (size_t)recsize > buffersize )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
649
	{
650
	  buffersize = (size_t)recsize;
651
	  gribbuffer = Realloc(gribbuffer, buffersize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
652
653
	}

654
      readsize = (size_t)recsize;
655
      rstatus = gribRead(fileID, (unsigned char *)gribbuffer, &readsize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
656
      if ( rstatus ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
657

658
      comptype = COMPRESS_NONE;
659
      if ( gribGetZip(recsize, (unsigned char *)gribbuffer, &unzipsize) > 0 )
660
	{
661
	  comptype = COMPRESS_SZIP;
662
	  unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
663
	  if ( buffersize < (size_t)unzipsize )
664
	    {
665
	      buffersize = (size_t)unzipsize;
666
	      gribbuffer = Realloc(gribbuffer, buffersize);
667
668
669
	    }
	}

670
      nrecs_scanned++;
671
      cgribexDecodeHeader(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, fsec4,
672
			  (int *) gribbuffer, (int)recsize, &lmv, &iret);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
673

Uwe Schulzweida's avatar
Uwe Schulzweida committed
674
      param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255);
675
676
      cdiParamToString(param, paramstr, sizeof(paramstr));

677
678
      if ( ISEC1_LevelType == 100 ) ISEC1_Level1 *= 100;
      if ( ISEC1_LevelType ==  99 ) ISEC1_LevelType = 100;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
679
680
681
      level1   = ISEC1_Level1;
      level2   = ISEC1_Level2;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
682
683
      gribDateTime(isec1, &vdate, &vtime);

684
      if ( ISEC4_NumBits > 0 && ISEC4_NumBits <= 32 )
685
	datatype = ISEC4_NumBits;
686
      else
687
        datatype = DATATYPE_PACK;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
688
689
690
691
692
693
694

      if ( nrecs == 0 )
	{
	  datetime0.date = vdate;
	  datetime0.time = vtime;
	  rdate = gribRefDate(isec1);
	  rtime = gribRefTime(isec1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
695
	  tunit = cgribexGetTimeUnit(isec1);
696
	  fcast = cgribexTimeIsFC(isec1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
697
698
699
700
701
	}
      else
	{
	  datetime.date  = vdate;
	  datetime.time  = vtime;
702
	  compvar_t compVar = cgribexVarSet(param, level1, level2, ISEC1_LevelType, ISEC1_TimeRange);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
703
704
	  for ( recID = 0; recID < nrecs; recID++ )
	    {
705
	      if ( cgribexVarCompare(compVar, streamptr->tsteps[0].records[recID], 0) == 0 ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
706
	    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
707
708
709
710
711

	  if ( cdiInventoryMode == 1 )
	    {
	      if ( recID < nrecs ) break;
	      if ( warn_time )
712
		if ( datetimeCmp(datetime, datetime0) != 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
713
		  {
714
                    gribWarning("Inconsistent verification time!", nrecs_scanned, tsID+1, paramstr, level1, level2);
715
		    warn_time = false;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
716
717
718
719
		  }
	    }
	  else
	    {
720
	      if ( datetimeCmp(datetime, datetime0) != 0 ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
721
722
723

	      if ( recID < nrecs )
		{
724
		  gribWarning("Parameter already exist, skipped!", nrecs_scanned, tsID+1, paramstr, level1, level2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
725
726
727
		  continue;
		}
	    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
728
729
730
731
732
733
	}

      if ( ISEC1_AvgNum )
	{
	  if (  taxis->numavg && warn_numavg && (taxis->numavg != ISEC1_AvgNum) )
	    {
734
	      Warning("Changing numavg from %d to %d not supported!", taxis->numavg, ISEC1_AvgNum);
735
	      warn_numavg = false;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
736
737
738
739
740
741
742
743
744
745
	    }
	  else
	    {
	      taxis->numavg = ISEC1_AvgNum;
	    }
	}

      nrecs++;

      if ( CDI_Debug )
746
	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
747

748
      cgribexAddRecord(streamptr, param, isec1, isec2, fsec2, fsec3,
749
		       isec4, recsize, recpos, datatype, comptype, lmv, iret);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
750
751
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
752
  streamptr->rtsteps = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
753

Uwe Schulzweida's avatar
Uwe Schulzweida committed
754
  if ( nrecs == 0 ) return CDI_EUFSTRUCT;
755

756
  cdi_generate_vars(streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
757
758
759

  if ( fcast )
    {
760
      taxisID = taxisCreate(TAXIS_RELATIVE);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
761
762
763
764
765
766
767
      taxis->type  = TAXIS_RELATIVE;
      taxis->rdate = rdate;
      taxis->rtime = rtime;
      taxis->unit  = tunit;
    }
  else
    {
768
      taxisID = taxisCreate(TAXIS_ABSOLUTE);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
769
      taxis->type  = TAXIS_ABSOLUTE;
770
      taxis->unit  = tunit;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
771
772
    }

773
774
  taxis->vdate = (int)datetime0.date;
  taxis->vtime = (int)datetime0.time;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
775

Uwe Schulzweida's avatar
Uwe Schulzweida committed
776
  vlistID = streamptr->vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
777
778
  vlistDefTaxis(vlistID, taxisID);

779
780
  nrecords = (unsigned)streamptr->tsteps[0].nallrecs;
  if ( nrecords < (unsigned)streamptr->tsteps[0].recordSize )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
781
    {
782
      streamptr->tsteps[0].recordSize = (int)nrecords;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
783
      streamptr->tsteps[0].records =
784
      (record_t *) Realloc(streamptr->tsteps[0].records, nrecords*sizeof(record_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
785
786
    }

787
  streamptr->tsteps[0].recIDs = (int *) Malloc(nrecords*sizeof(int));
788
  streamptr->tsteps[0].nrecs = (int)nrecords;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
789
  for ( recID = 0; recID < nrecords; recID++ )
790
    streamptr->tsteps[0].recIDs[recID] = (int)recID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
791

Uwe Schulzweida's avatar
Uwe Schulzweida committed
792
  streamptr->record->buffer     = gribbuffer;
793
  streamptr->record->buffersize = (size_t)buffersize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
794

795
796
  cgribexScanTsFixNtsteps(streamptr, recpos);
  cgribexScanTsConstAdjust(streamptr, taxis);
797

Uwe Schulzweida's avatar
Uwe Schulzweida committed
798
  return 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
799
800
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
801

802
int cgribexScanTimestep2(stream_t * streamptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
803
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
804
  int rstatus = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
805
  double fsec2[512], fsec3[2], *fsec4 = NULL;
806
  int lmv = 0, iret = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
807
  off_t recpos = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
808
809
  int param = 0;
  int level1 = 0, level2 = 0, vdate = 0, vtime = 0;
810
  DateTime datetime, datetime0 = { LONG_MIN, LONG_MIN };
Uwe Schulzweida's avatar
Uwe Schulzweida committed
811
812
  int varID, gridID;
  size_t readsize;
813
  int nrecs, recID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
814
  long recsize = 0;
815
  bool warn_numavg = true;
816
  int tsteptype;
817
  long unzipsize;
818
  char paramstr[32];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
819

Uwe Schulzweida's avatar
Uwe Schulzweida committed
820
821
  streamptr->curTsID = 1;

822
823
824
825
826
  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
827

828
829
830
  int fileID  = streamptr->fileID;
  int vlistID = streamptr->vlistID;
  int taxisID = vlistInqTaxis(vlistID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
831

832
833
  void *gribbuffer = streamptr->record->buffer;
  size_t buffersize = streamptr->record->buffersize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
834

835
  int tsID = streamptr->rtsteps;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
836
  if ( tsID != 1 )
Thomas Jahns's avatar
Thomas Jahns committed
837
    Error("Internal problem! unexpected timestep %d", tsID+1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
838

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

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

843
  cdi_create_records(streamptr, tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
844

845
  int nrecords = streamptr->tsteps[tsID].nallrecs;
846
  if ( nrecords ) streamptr->tsteps[1].recIDs = (int *) Malloc((size_t)nrecords * sizeof(int));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
847
  streamptr->tsteps[1].nrecs = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
848
  for ( recID = 0; recID < nrecords; recID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
849
    streamptr->tsteps[1].recIDs[recID] = -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
850

Uwe Schulzweida's avatar
Uwe Schulzweida committed
851
852
  for ( recID = 0; recID < nrecords; recID++ )
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
853
      varID = streamptr->tsteps[0].records[recID].varID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
854
855
      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
856
857
    }

858
859
  int nrecs_scanned = nrecords;
  int rindex = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
860
  while ( TRUE )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
861
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
862
863
      if ( rindex > nrecords ) break;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
864
865
866
867
      recsize = gribGetSize(fileID);
      recpos  = fileGetPos(fileID);
      if ( recsize == 0 )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
868
	  streamptr->ntsteps = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
869
870
	  break;
	}
871
      if ( (size_t)recsize > buffersize )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
872
	{
873
	  buffersize = (size_t)recsize;
874
	  gribbuffer = Realloc(gribbuffer, buffersize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
875
876
	}

877
      readsize = (size_t)recsize;
878
      rstatus = gribRead(fileID, (unsigned char *)gribbuffer, &readsize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
879
      if ( rstatus ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
880

881
      if ( gribGetZip(recsize, (unsigned char *)gribbuffer, &unzipsize) > 0 )
882
883
	{
	  unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
884
	  if ( buffersize < (size_t)unzipsize )
885
	    {
886
	      buffersize = (size_t)unzipsize;
887
	      gribbuffer = Realloc(gribbuffer, buffersize);
888
889
890
	    }
	}

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

894
895
      nrecs_scanned++;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
896
      param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255);
897
898
      cdiParamToString(param, paramstr, sizeof(paramstr));

899
900
      if ( ISEC1_LevelType == 100 ) ISEC1_Level1 *= 100;
      if ( ISEC1_LevelType ==  99 ) ISEC1_LevelType = 100;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
      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;
	    }
918
	  taxis->unit  = cgribexGetTimeUnit(isec1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
919
920
	  taxis->vdate = vdate;
	  taxis->vtime = vtime;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
921
922
923

	  datetime0.date = vdate;
	  datetime0.time = vtime;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
924
925
	}

926
927
      tsteptype = cgribexGetTsteptype(ISEC1_TimeRange);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
928
929
930
      if ( ISEC1_AvgNum )
	{
	  if (  taxis->numavg && warn_numavg &&
931
        	(taxis->numavg != ISEC1_AvgNum) )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
932
933
	    {
	  /*
934
	      Warning("Changing numavg from %d to %d not supported!", taxis->numavg, ISEC1_AvgNum);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
935
	  */
936
	      warn_numavg = false;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
937
938
939
940
941
942
943
	    }
	  else
	    {
	      taxis->numavg = ISEC1_AvgNum;
	    }
	}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
944
945
      datetime.date  = vdate;
      datetime.time  = vtime;
946

947
      compvar_t compVar = cgribexVarSet(param, level1, level2, ISEC1_LevelType, ISEC1_TimeRange);
948

Uwe Schulzweida's avatar
Uwe Schulzweida committed
949
950
      for ( recID = 0; recID < nrecords; recID++ )
	{
951
	  if ( cgribexVarCompare(compVar, streamptr->tsteps[tsID].records[recID], 0) == 0 ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
952
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
953

Uwe Schulzweida's avatar
Uwe Schulzweida committed
954
955
      if ( recID == nrecords )
	{
956
	  gribWarning("Parameter not defined at timestep 1!", nrecs_scanned, tsID+1, paramstr, level1, level2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
957
	  return CDI_EUFSTRUCT;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
958
959
	}