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

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

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

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

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

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

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

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

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

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

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

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
371
  struct addIfNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, gridptr, 0);
372
  int gridID = gridAdded.Id;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
373
374
375
376
377
378
379
380
381
  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));
        }
382
383
384
385
386
387
388
      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
389
390
391
    }
  else
    Free(gridptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
392

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

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

      varDefVCT(vctsize, vctptr);
    }

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

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

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

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

415
  varDefCompType(varID, comptype);
416

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

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

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

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

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

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
458
459
  streamptr->tsteps[tsID].nallrecs++;
  streamptr->nrecs++;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
460
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
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,
489
			 int *isec3, double *fsec3, int *isec4, double *fsec4,
490
			 int *gribbuffer, int recsize, int *lmv, int *iret)
491
{
492
  int ipunp = 0, iword = 0;
493

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

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

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

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

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

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

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

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

546
#if  defined  (HAVE_LIBCGRIBEX)
547
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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

      nrecs++;

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

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

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

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

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

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

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

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

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

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

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

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
800

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

893
894
      nrecs_scanned++;

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

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

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

925
926
      tsteptype = cgribexGetTsteptype(ISEC1_TimeRange);

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

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

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

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
959
960
961
962