stream_cgribex.c 58.2 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
  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;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
308
309
310
311
      grid->gme.nd  = ISEC2_GME_ND;
      grid->gme.ni  = ISEC2_GME_NI;
      grid->gme.ni2 = ISEC2_GME_NI2;
      grid->gme.ni3 = ISEC2_GME_NI3;
312
313
314
315
316
317
318
319
320
321
322
    }
  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
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
328
329
330
331
332
333
334
335
336
337
static
void cgribexGetLevel(int *isec1, int *leveltype, int *level1, int *level2)
{
  *leveltype = ISEC1_LevelType;
  *level1 = ISEC1_Level1;
  *level2 = ISEC1_Level2;
  if ( *leveltype == GRIB1_LTYPE_ISOBARIC ) *level1 *= 100;
  else if ( *leveltype == GRIB1_LTYPE_99 || *leveltype == GRIB1_LTYPE_ISOBARIC_PA ) *leveltype = GRIB1_LTYPE_ISOBARIC;
}

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

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

350
351
  int tsteptype = cgribexGetTsteptype(ISEC1_TimeRange);
  int numavg    = ISEC1_AvgNum;
352

Uwe Schulzweida's avatar
Uwe Schulzweida committed
353
354
  int leveltype, level1, level2;
  cgribexGetLevel(isec1, &leveltype, &level1, &level2);
355

Uwe Schulzweida's avatar
Uwe Schulzweida committed
356
  /* fprintf(stderr, "param %d %d %d %d\n", param, level1, level2, leveltype); */
357

358
  record->size      = recsize;
359
360
361
362
  record->position  = position;
  record->param     = param;
  record->ilevel    = level1;
  record->ilevel2   = level2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
363
  record->ltype     = leveltype;
Thomas Jahns's avatar
Thomas Jahns committed
364
  record->tsteptype = (short)tsteptype;
365

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
391
  int zaxistype = grib1ltypeToZaxisType(leveltype);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
392

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

      varDefVCT(vctsize, vctptr);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
401
  int lbounds = cgribexGetZaxisHasBounds(leveltype);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
402

403
404
  if ( datatype > 32 ) datatype = CDI_DATATYPE_PACK32;
  if ( datatype <  0 ) datatype = CDI_DATATYPE_PACK;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
405

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

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

413
  varDefCompType(varID, comptype);
414

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

423
424
  if ( lmv ) varDefMissval(varID, FSEC3_MissVal);

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

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

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

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
456
457
  streamptr->tsteps[tsID].nallrecs++;
  streamptr->nrecs++;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
458
459
}

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
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,
487
			 int *isec3, double *fsec3, int *isec4, double *fsec4,
488
			 int *gribbuffer, int recsize, int *lmv, int *iret)
489
{
490
  int ipunp = 0, iword = 0;
491

492
493
  memset(isec1, 0, 256*sizeof(int));

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

  *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;
    }
}
508
509

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

515
516
517
518
519
  compVar.param     = param;
  compVar.level1    = level1;
  compVar.level2    = level2;
  compVar.ltype     = leveltype;
  compVar.tsteptype = tsteptype;
520

Uwe Schulzweida's avatar
Uwe Schulzweida committed
521
  return compVar;
522
523
}

Thomas Jahns's avatar
Thomas Jahns committed
524
525
static inline int
cgribexVarCompare(compvar_t compVar, record_t record, int flag)
526
{
527
528
529
530
  bool vinst = compVar.tsteptype == TSTEP_INSTANT || compVar.tsteptype == TSTEP_INSTANT2 || compVar.tsteptype == TSTEP_INSTANT3;
  bool rinst = record.tsteptype == TSTEP_INSTANT || record.tsteptype == TSTEP_INSTANT2 || record.tsteptype == TSTEP_INSTANT3;
  int tstepDiff = (!((flag == 0) & (vinst && rinst)))
                & (compVar.tsteptype != record.tsteptype);
Thomas Jahns's avatar
Thomas Jahns committed
531
532
533
534
535
  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
536
  return rstatus;
537
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
538
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
539

540
541
542
#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)

543
#if  defined  (HAVE_LIBCGRIBEX)
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;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
568
569
	  for ( int varID = 0; varID < streamptr->nvars; varID++ )
            vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
570
571
572
573
574
	}
    }
}


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

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

604
605
606
607
608
  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
609

610
611
  int tsID  = tstepsNewEntry(streamptr);
  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
612
613

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

616
  int fileID = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
617

618
619
620
  while ( nskip-- > 0 )
    {
      recsize = gribGetSize(fileID);
621
      if ( recsize == 0 )
622
	Error("Skipping of %d records failed!", cdiSkipRecords);
623

624
      recpos  = fileGetPos(fileID);
625
      fileSetPos(fileID, (off_t)recsize, SEEK_CUR);
626
627
    }

628
  unsigned nrecs = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
629
630
631
632
633
634
635
  while ( TRUE )
    {
      recsize = gribGetSize(fileID);
      recpos  = fileGetPos(fileID);

      if ( recsize == 0 )
	{
636
	  if ( nrecs == 0 )
637
	    Error("No GRIB records found!");
638

Uwe Schulzweida's avatar
Uwe Schulzweida committed
639
	  streamptr->ntsteps = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
640
641
	  break;
	}
642
      if ( recsize > buffersize )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
643
	{
644
	  buffersize = recsize;
645
	  gribbuffer = Realloc(gribbuffer, buffersize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
646
647
	}

648
      readsize = recsize;
649
      rstatus = gribRead(fileID, (unsigned char *)gribbuffer, &readsize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
650
      if ( rstatus ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
651

652
      comptype = CDI_COMPRESS_NONE;
653
      if ( gribGetZip(recsize, (unsigned char *)gribbuffer, &unzipsize) > 0 )
654
	{
655
	  comptype = CDI_COMPRESS_SZIP;
656
	  unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
657
	  if ( buffersize < unzipsize )
658
	    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
659
	      buffersize = unzipsize;
660
	      gribbuffer = Realloc(gribbuffer, buffersize);
661
662
663
	    }
	}

664
      nrecs_scanned++;
665
      cgribexDecodeHeader(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, fsec4,
666
			  (int *) gribbuffer, (int)recsize, &lmv, &iret);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
667

Uwe Schulzweida's avatar
Uwe Schulzweida committed
668
      param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255);
669
670
      cdiParamToString(param, paramstr, sizeof(paramstr));

Uwe Schulzweida's avatar
Uwe Schulzweida committed
671
      cgribexGetLevel(isec1, &leveltype, &level1, &level2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
672

Uwe Schulzweida's avatar
Uwe Schulzweida committed
673
674
      gribDateTime(isec1, &vdate, &vtime);

675
      if ( ISEC4_NumBits > 0 && ISEC4_NumBits <= 32 )
676
	datatype = ISEC4_NumBits;
677
      else
678
        datatype = CDI_DATATYPE_PACK;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
679
680
681
682
683
684
685

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

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

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

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

      nrecs++;

      if ( CDI_Debug )
737
	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
738

739
      cgribexAddRecord(streamptr, param, isec1, isec2, fsec2, fsec3,
740
		       isec4, recsize, recpos, datatype, comptype, lmv, iret);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
741
742
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
743
  streamptr->rtsteps = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
744

Uwe Schulzweida's avatar
Uwe Schulzweida committed
745
  if ( nrecs == 0 ) return CDI_EUFSTRUCT;
746

747
  cdi_generate_vars(streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
748
749
750

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

764
765
  taxis->vdate = (int)datetime0.date;
  taxis->vtime = (int)datetime0.time;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
766

Uwe Schulzweida's avatar
Uwe Schulzweida committed
767
  vlistID = streamptr->vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
768
769
  vlistDefTaxis(vlistID, taxisID);

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

778
  streamptr->tsteps[0].recIDs = (int *) Malloc(nrecords*sizeof(int));
779
  streamptr->tsteps[0].nrecs = (int)nrecords;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
780
  for ( recID = 0; recID < nrecords; recID++ )
781
    streamptr->tsteps[0].recIDs[recID] = (int)recID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
782

Uwe Schulzweida's avatar
Uwe Schulzweida committed
783
  streamptr->record->buffer     = gribbuffer;
784
  streamptr->record->buffersize = buffersize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
785

786
787
  cgribexScanTsFixNtsteps(streamptr, recpos);
  cgribexScanTsConstAdjust(streamptr, taxis);
788

Uwe Schulzweida's avatar
Uwe Schulzweida committed
789
  return 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
790
791
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
792

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
811
812
  streamptr->curTsID = 1;

813
814
815
816
817
  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
818

819
820
821
  int fileID  = streamptr->fileID;
  int vlistID = streamptr->vlistID;
  int taxisID = vlistInqTaxis(vlistID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
822

823
824
  void *gribbuffer = streamptr->record->buffer;
  size_t buffersize = streamptr->record->buffersize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
825

826
  int tsID = streamptr->rtsteps;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
827
  if ( tsID != 1 )
Thomas Jahns's avatar
Thomas Jahns committed
828
    Error("Internal problem! unexpected timestep %d", tsID+1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
829

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

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

834
  cdi_create_records(streamptr, tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
835

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
842
843
  for ( recID = 0; recID < nrecords; recID++ )
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
844
      varID = streamptr->tsteps[0].records[recID].varID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
845
846
      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
847
848
    }

849
850
  int nrecs_scanned = nrecords;
  int rindex = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
851
  while ( TRUE )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
852
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
853
854
      if ( rindex > nrecords ) break;

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

868
      readsize = recsize;
869
      rstatus = gribRead(fileID, (unsigned char *)gribbuffer, &readsize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
870
      if ( rstatus ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
871

872
      if ( gribGetZip(recsize, (unsigned char *)gribbuffer, &unzipsize) > 0 )
873
874
	{
	  unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
875
	  if ( buffersize < unzipsize )
876
	    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
877
	      buffersize = unzipsize;
878
	      gribbuffer = Realloc(gribbuffer, buffersize);
879
880
881
	    }
	}

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

885
886
      nrecs_scanned++;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
887
      param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255);
888
889
      cdiParamToString(param, paramstr, sizeof(paramstr));

Uwe Schulzweida's avatar
Uwe Schulzweida committed
890
      cgribexGetLevel(isec1, &leveltype, &level1, &level2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905

      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;
	    }
906
	  taxis->unit  = cgribexGetTimeUnit(isec1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
907
908
	  taxis->vdate = vdate;
	  taxis->vtime = vtime;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
909
910
911

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

914
915
      tsteptype = cgribexGetTsteptype(ISEC1_TimeRange);

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
935
      compvar_t compVar = cgribexVarSet(param, level1, level2, leveltype, ISEC1_TimeRange);
936

Uwe Schulzweida's avatar
Uwe Schulzweida committed
937
938
      for ( recID = 0; recID < nrecords; recID++ )
	{