stream_cgribex.c 61.5 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)
32
33
static bool bit_get(int number, int bit) { return (bool)((number >> bit) & 1); }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
34
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
35
int cgribexGetGridType(int *isec2)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
36
{
37
  int gridtype = GRID_GENERIC;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
38
39
40

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
49
  return gridtype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
50
51
}

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
58
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
59
int cgribexGetZaxisHasBounds(int grb_ltype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
60
61
62
{
  int lbounds = 0;

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
74
  return lbounds;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
75
76
}

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

  switch ( ISEC1_TimeUnit )
    {
85
86
87
88
89
90
91
92
    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
93
94
95
    default:
      if ( lprint )
	{
96
	  Message("GRIB time unit %d unsupported!", ISEC1_TimeUnit);
97
	  lprint = false;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
98
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
99
      break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
100
101
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
102
  return timeunit;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
103
104
}

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
110
  return isFC;
111
112
113
114
115
}

static
int cgribexGetTsteptype(int timerange)
{
116
  static bool lprint = true;
117

118
  int tsteptype = TSTEP_INSTANT;
119
120
121
122
123
124
125
126
127
128
129
130
  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 )
	{
131
	  Message("Time range indicator %d unsupported, set to 0!", timerange);
132
	  lprint = false;
133
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
134
      break;
135
136
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
137
  return tsteptype;
138
139
}

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

147
  if ( streamptr->unreduced && gridtype == GRID_GAUSSIAN_REDUCED && iret != -801 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
148
    {
149
150
151
      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
152
      gridtype = GRID_GAUSSIAN;
153
154
      ISEC2_NumLon = nlon;
      ISEC4_NumValues = nlon*ISEC2_NumLat;
155
      compyinc = false;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
156
157
    }

158
  grid_init(grid);
159
  cdiGridTypeInit(grid, gridtype, 0);
160

161
  if ( gridtype == GRID_LONLAT || gridtype == GRID_GAUSSIAN || projtype == CDI_PROJ_RLL )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
162
    {
163
164
165
      bool ijDirectionIncrementGiven = bit_get(ISEC2_ResFlag, 7);
      bool uvRelativeToGrid = bit_get(ISEC2_ResFlag, 3);
      if ( uvRelativeToGrid ) grid->uvRelativeToGrid = 1;
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
            if ( ISEC2_LastLon < ISEC2_FirstLon && ISEC2_LastLon < 0 ) ISEC2_LastLon += 360000;

183
            if ( ijDirectionIncrementGiven && ISEC2_LonIncr > 0 )
184
185
              {
                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
        if ( grid->y.size > 1 && compyinc )
          {
            bool recompinc = true;
216
            if ( ijDirectionIncrementGiven && ISEC2_LatIncr > 0 )
217
218
219
220
221
222
223
224
225
226
227
228
229
230
              {
                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
    }
  else if ( gridtype == GRID_GAUSSIAN_REDUCED )
    {
235
236
237
      bool ijDirectionIncrementGiven = bit_get(ISEC2_ResFlag, 7);
      bool uvRelativeToGrid = bit_get(ISEC2_ResFlag, 3);
      if ( uvRelativeToGrid ) grid->uvRelativeToGrid = 1;
238
239
240
241
242
243
244
245
246
      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
        if ( grid->x.size > 1 )
          {
            if ( ISEC2_LastLon < ISEC2_FirstLon && ISEC2_LastLon < 0 ) ISEC2_LastLon += 360000;

252
            if ( ijDirectionIncrementGiven && ISEC2_LonIncr > 0 )
253
254
255
256
257
258
259
              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
        if ( grid->y.size > 1 )
          {
266
            if ( ijDirectionIncrementGiven && ISEC2_LatIncr > 0 )
267
268
269
270
271
272
273
              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
  else if ( gridtype == GRID_LCC )
    {
278
279
280
      bool uvRelativeToGrid = bit_get(ISEC2_ResFlag, 3);
      if ( uvRelativeToGrid ) grid->uvRelativeToGrid = 1;

281
282
283
284
      if ( ISEC4_NumValues != ISEC2_NumLon*ISEC2_NumLat )
        Error("numberOfPoints (%d) and gridSize (%d) differ!",
              ISEC4_NumValues, ISEC2_NumLon*ISEC2_NumLat);

285
      grid->size   = ISEC4_NumValues;
286
287
288
289
290
291
292
293
294
295
296
      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;
297
      grid->lcc.scanflag  = (short)ISEC2_ScanFlag;
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313

      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
314
315
316
317
      grid->gme.nd  = ISEC2_GME_ND;
      grid->gme.ni  = ISEC2_GME_NI;
      grid->gme.ni2 = ISEC2_GME_NI2;
      grid->gme.ni3 = ISEC2_GME_NI3;
318
319
320
321
322
323
324
325
326
327
328
    }
  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
329

330
331
  grid->type = gridtype;
  grid->projtype = projtype;
332
333
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
334
335
336
337
338
339
340
341
342
343
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;
}

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

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

356
357
  int tsteptype = cgribexGetTsteptype(ISEC1_TimeRange);
  int numavg    = ISEC1_AvgNum;
358

Uwe Schulzweida's avatar
Uwe Schulzweida committed
359
360
  int leveltype, level1, level2;
  cgribexGetLevel(isec1, &leveltype, &level1, &level2);
361

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

364
  record->size      = recsize;
365
366
367
368
  record->position  = position;
  record->param     = param;
  record->ilevel    = level1;
  record->ilevel2   = level2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
369
  record->ltype     = leveltype;
Thomas Jahns's avatar
Thomas Jahns committed
370
  record->tsteptype = (short)tsteptype;
371

Uwe Schulzweida's avatar
Uwe Schulzweida committed
372
  grid_t *gridptr = (grid_t*) Malloc(sizeof(*gridptr));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
373
  cgribexGetGrid(streamptr, isec2, isec4, gridptr, iret);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
374

Uwe Schulzweida's avatar
Uwe Schulzweida committed
375
  struct addIfNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, gridptr, 0);
376
  int gridID = gridAdded.Id;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
377
378
379
380
381
382
383
384
385
  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));
        }
386
387
388
389
390
      else if ( gridptr->projtype == CDI_PROJ_RLL )
        {
          double xpole =   ISEC2_LonSP*0.001 - 180;
          double ypole = - ISEC2_LatSP*0.001;
          double angle = - FSEC2_RotAngle;
391
          gridDefParamRLL(gridID, xpole, ypole, angle);
392
        }
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
      else if ( gridptr->projtype == CDI_PROJ_LCC )
        {
          double lcc_xinc      = ISEC2_Lambert_dx;
          double lcc_yinc      = ISEC2_Lambert_dy;
          double lcc_originLon = ISEC2_FirstLon * 0.001;
          double lcc_originLat = ISEC2_FirstLat * 0.001;
          double lcc_lonParY   = ISEC2_Lambert_Lov * 0.001;
          double lcc_lat1      = ISEC2_Lambert_LatS1 * 0.001;
          double lcc_lat2      = ISEC2_Lambert_LatS2 * 0.001;
          double lcc_projflag  = ISEC2_Lambert_ProjFlag;
          double lcc_scanflag  = (short)ISEC2_ScanFlag;
          gridDefParamLCC(gridID, lcc_originLon, lcc_originLat, lcc_lonParY,
                          lcc_lat1, lcc_lat2, lcc_xinc, lcc_yinc,
                          lcc_projflag, lcc_scanflag);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
408
409
410
    }
  else
    Free(gridptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
411

Uwe Schulzweida's avatar
Uwe Schulzweida committed
412
  int zaxistype = grib1ltypeToZaxisType(leveltype);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
413

414
  if ( zaxistype == ZAXIS_HYBRID || zaxistype == ZAXIS_HYBRID_HALF )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
415
    {
416
      size_t vctsize = (size_t)ISEC2_NumVCP;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
417
418
419
420
421
      double *vctptr = &fsec2[10];

      varDefVCT(vctsize, vctptr);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
422
  int lbounds = cgribexGetZaxisHasBounds(leveltype);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
423

424
425
  if ( datatype > 32 ) datatype = CDI_DATATYPE_PACK32;
  if ( datatype <  0 ) datatype = CDI_DATATYPE_PACK;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
426

427
  varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2, 0, 0,
Uwe Schulzweida's avatar
Uwe Schulzweida committed
428
	       datatype, &varID, &levelID, tsteptype, numavg, leveltype, -1,
429
               NULL, NULL, NULL, NULL, NULL, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
430

Thomas Jahns's avatar
Thomas Jahns committed
431
432
  record->varID   = (short)varID;
  record->levelID = (short)levelID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
433

434
  varDefCompType(varID, comptype);
435

436
437
438
439
440
441
442
  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]);
    }
443

444
445
  if ( lmv ) varDefMissval(varID, FSEC3_MissVal);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
446
  if ( varInqInst(varID) == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
447
    {
448
449
450
      int center    = ISEC1_CenterID;
      int subcenter = ISEC1_SubCenterID;
      int instID    = institutInq(center, subcenter, NULL, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
451
      if ( instID == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
452
453
454
455
	instID = institutDef(center, subcenter, NULL, NULL);
      varDefInst(varID, instID);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
456
  if ( varInqModel(varID) == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
457
    {
458
      int modelID = modelInq(varInqInst(varID), ISEC1_ModelID, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
459
      if ( modelID == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
460
461
462
463
	modelID = modelDef(varInqInst(varID), ISEC1_ModelID, NULL);
      varDefModel(varID, modelID);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
464
  if ( varInqTable(varID) == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
465
    {
466
      int tableID = tableInq(varInqModel(varID), ISEC1_CodeTable, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
467
      if ( tableID == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
468
469
470
471
	tableID = tableDef(varInqModel(varID), ISEC1_CodeTable, NULL);
      varDefTable(varID, tableID);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
472
473
  streamptr->tsteps[tsID].nallrecs++;
  streamptr->nrecs++;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
474
475
}

476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
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,
503
			 int *isec3, double *fsec3, int *isec4, double *fsec4,
504
			 int *gribbuffer, int recsize, int *lmv, int *iret)
505
{
506
  int ipunp = 0, iword = 0;
507

508
509
  memset(isec1, 0, 256*sizeof(int));

510
  gribExDP(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, fsec4,
511
	   ipunp, (int *) gribbuffer, recsize, &iword, "J", iret);
512
513
514
515
516
517
518
519
520
521
522

  *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;
    }
}
523
524

static
525
compvar_t cgribexVarSet(int param, int level1, int level2, int leveltype, int trange)
526
{
527
  int tsteptype = cgribexGetTsteptype(trange);
528

529
  compvar_t compVar;
530
531
532
533
534
  compVar.param     = param;
  compVar.level1    = level1;
  compVar.level2    = level2;
  compVar.ltype     = leveltype;
  compVar.tsteptype = tsteptype;
535

Uwe Schulzweida's avatar
Uwe Schulzweida committed
536
  return compVar;
537
538
}

Thomas Jahns's avatar
Thomas Jahns committed
539
540
static inline int
cgribexVarCompare(compvar_t compVar, record_t record, int flag)
541
{
542
543
544
545
  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
546
547
548
549
550
  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
551
  return rstatus;
552
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
553
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
554

555
556
557
#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)

558
#if  defined  (HAVE_LIBCGRIBEX)
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582

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
583
584
	  for ( int varID = 0; varID < streamptr->nvars; varID++ )
            vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
585
586
587
588
589
	}
    }
}


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

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

619
620
621
622
623
  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
624

625
626
  int tsID  = tstepsNewEntry(streamptr);
  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
627
628

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

631
  int fileID = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
632

633
634
635
  while ( nskip-- > 0 )
    {
      recsize = gribGetSize(fileID);
636
      if ( recsize == 0 )
637
	Error("Skipping of %d records failed!", cdiSkipRecords);
638

639
      recpos  = fileGetPos(fileID);
640
      fileSetPos(fileID, (off_t)recsize, SEEK_CUR);
641
642
    }

643
  unsigned nrecs = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
644
645
646
647
648
649
650
  while ( TRUE )
    {
      recsize = gribGetSize(fileID);
      recpos  = fileGetPos(fileID);

      if ( recsize == 0 )
	{
651
	  if ( nrecs == 0 )
652
	    Error("No GRIB records found!");
653

Uwe Schulzweida's avatar
Uwe Schulzweida committed
654
	  streamptr->ntsteps = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
655
656
	  break;
	}
657
      if ( recsize > buffersize )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
658
	{
659
	  buffersize = recsize;
660
	  gribbuffer = Realloc(gribbuffer, buffersize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
661
662
	}

663
      readsize = recsize;
664
      rstatus = gribRead(fileID, (unsigned char *)gribbuffer, &readsize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
665
      if ( rstatus ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
666

667
      comptype = CDI_COMPRESS_NONE;
668
      if ( gribGetZip(recsize, (unsigned char *)gribbuffer, &unzipsize) > 0 )
669
	{
670
	  comptype = CDI_COMPRESS_SZIP;
671
	  unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
672
	  if ( buffersize < unzipsize )
673
	    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
674
	      buffersize = unzipsize;
675
	      gribbuffer = Realloc(gribbuffer, buffersize);
676
677
678
	    }
	}

679
      nrecs_scanned++;
680
      cgribexDecodeHeader(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, fsec4,
681
			  (int *) gribbuffer, (int)recsize, &lmv, &iret);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
682

Uwe Schulzweida's avatar
Uwe Schulzweida committed
683
      param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255);
684
685
      cdiParamToString(param, paramstr, sizeof(paramstr));

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
688
689
      gribDateTime(isec1, &vdate, &vtime);

690
      datatype = (ISEC4_NumBits > 0 && ISEC4_NumBits <= 32) ? ISEC4_NumBits : CDI_DATATYPE_PACK;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
691
692
693
694
695
696
697

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

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

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

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

      nrecs++;

      if ( CDI_Debug )
749
	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
750

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
755
  streamptr->rtsteps = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
756

Uwe Schulzweida's avatar
Uwe Schulzweida committed
757
  if ( nrecs == 0 ) return CDI_EUFSTRUCT;
758

759
  cdi_generate_vars(streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
760
761
762

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

776
777
  taxis->vdate = (int)datetime0.date;
  taxis->vtime = (int)datetime0.time;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
778

Uwe Schulzweida's avatar
Uwe Schulzweida committed
779
  vlistID = streamptr->vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
780
781
  vlistDefTaxis(vlistID, taxisID);

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
795
  streamptr->record->buffer     = gribbuffer;
796
  streamptr->record->buffersize = buffersize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
797

798
799
  cgribexScanTsFixNtsteps(streamptr, recpos);
  cgribexScanTsConstAdjust(streamptr, taxis);
800

Uwe Schulzweida's avatar
Uwe Schulzweida committed
801
  return 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
802
803
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
804

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
823
824
  streamptr->curTsID = 1;

825
826
827
828
829
  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
830

831
832
833
  int fileID  = streamptr->fileID;
  int vlistID = streamptr->vlistID;
  int taxisID = vlistInqTaxis(vlistID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
834

835
836
  void *gribbuffer = streamptr->record->buffer;
  size_t buffersize = streamptr->record->buffersize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
837

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

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

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

846
  cdi_create_records(streamptr, tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
847

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

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

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

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

880
      readsize = recsize;
881
      rstatus = gribRead(fileID, (unsigned char *)gribbuffer, &readsize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
882
      if ( rstatus ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
883

884
      if ( gribGetZip(recsize, (unsigned char *)gribbuffer, &unzipsize) > 0 )
885
886
	{
	  unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
887
	  if ( buffersize < unzipsize )
888
	    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
889
	      buffersize = unzipsize;
890
	      gribbuffer = Realloc(gribbuffer, buffersize);
891
892
893
	    }
	}

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

897
898
      nrecs_scanned++;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
899
      param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255);
900
901
      cdiParamToString(param, paramstr, sizeof(paramstr));

Uwe Schulzweida's avatar
Uwe Schulzweida committed
902
      cgribexGetLevel(isec1, &leveltype, &level1, &level2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917

      gribDateTime(isec1, &vdate, &vtime);

      if ( rindex == 0 )
	{
	  if ( taxisInqType(taxisID) == TAXIS_RELATIVE )
	    {
	      taxis->type  = TAXIS_RELATIVE;
	      taxis->rdate = gribRefDate(