stream_cgribex.c 57.8 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:     { if ( ISEC2_Reduced )      break; }
40
41
42
43
44
45
46
47
48
49
    case  GRIB1_GTYPE_LATLON_ROT: { gridtype = GRID_LONLAT;   break; }
    case  GRIB1_GTYPE_LCC:        { gridtype = GRID_LCC;      break; }
    case  GRIB1_GTYPE_GAUSSIAN:   { if ( ISEC2_Reduced )
	                              gridtype = GRID_GAUSSIAN_REDUCED;
                         	    else
				      gridtype = GRID_GAUSSIAN;
          	                    break;
                                  }
    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
  bool isRotated = (ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT) ? true : false;
59

Uwe Schulzweida's avatar
Uwe Schulzweida committed
60
  return isRotated;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
61
62
}

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
79
  return lbounds;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
80
81
}

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
107
  return timeunit;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
108
109
}

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
115
  return isFC;
116
117
118
119
120
}

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
142
  return tsteptype;
143
144
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
145
static
146
void cgribexGetGrid(stream_t *streamptr, int *isec2, double *fsec2, int *isec4, grid_t *grid, int iret)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
147
{
148
  bool compyinc = true;
149
  int gridtype = cgribexGetGridType(isec2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
150

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

162
  grid_init(grid);
163
  cdiGridTypeInit(grid, gridtype, 0);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
164
165
166
167
168
169
  switch (gridtype)
    {
    case GRID_LONLAT:
    case GRID_GAUSSIAN:
      {
	if ( ISEC4_NumValues != ISEC2_NumLon*ISEC2_NumLat )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
170
	  Error("numberOfPoints (%d) and gridSize (%d) differ!", ISEC4_NumValues, ISEC2_NumLon*ISEC2_NumLat);
171
172
173
	grid->size  = ISEC4_NumValues;
	grid->xsize = ISEC2_NumLon;
	grid->ysize = ISEC2_NumLat;
174
        if ( gridtype == GRID_GAUSSIAN ) grid->np = ISEC2_NumPar;
175
176
177
	grid->xinc  = 0;
	grid->yinc  = 0;
	grid->xdef  = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
178
179
	/* if ( ISEC2_FirstLon != 0 || ISEC2_LastLon != 0 ) */
	  {
180
	    if ( grid->xsize > 1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
181
	      {
182
                bool recompinc = true;
183

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
186
		if ( ISEC2_ResFlag && ISEC2_LonIncr > 0 )
187
188
189
                  {
                    if ( abs(ISEC2_LastLon - (ISEC2_FirstLon+ISEC2_LonIncr*(grid->xsize-1))) <= 2 )
                      {
190
                        recompinc = false;
191
192
193
                        grid->xinc = ISEC2_LonIncr * 0.001;
                      }
                  }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
194

195
		/* recompute xinc if necessary */
196
                if ( recompinc ) grid->xinc = (ISEC2_LastLon - ISEC2_FirstLon) * 0.001 / (grid->xsize-1);
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->xsize;

		    if ( fabs(grid->xinc-xinc) > 0.0 )
		      {
			grid->xinc = xinc;
			if ( CDI_Debug ) Message("set xinc to %g", grid->xinc);
		      }
		  }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
209
	      }
210
211
	    grid->xfirst = ISEC2_FirstLon * 0.001;
	    grid->xlast  = ISEC2_LastLon  * 0.001;
212
	    grid->xdef   = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
213
	  }
214
	grid->ydef  = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
215
216
	/* if ( ISEC2_FirstLat != 0 || ISEC2_LastLat != 0 ) */
	  {
217
	    if ( grid->ysize > 1 && compyinc )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
218
	      {
219
                bool recompinc = true;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
220
		if ( ISEC2_ResFlag && ISEC2_LatIncr > 0 )
221
222
223
                  {
                    if ( abs(ISEC2_LastLat - (ISEC2_FirstLat+ISEC2_LatIncr*(grid->ysize-1))) <= 2 )
                      {
224
                        recompinc = false;
225
226
227
                        grid->yinc = ISEC2_LatIncr * 0.001;
                      }
                  }
228

229
		/* recompute yinc if necessary */
230
                if ( recompinc ) grid->yinc = (ISEC2_LastLat - ISEC2_FirstLat) * 0.001 / (grid->ysize - 1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
231
	      }
232
233
	    grid->yfirst = ISEC2_FirstLat * 0.001;
	    grid->ylast  = ISEC2_LastLat  * 0.001;
234
	    grid->ydef   = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
235
236
237
238
239
	  }
	break;
      }
    case GRID_GAUSSIAN_REDUCED:
      {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
240
241
242
243
244
245
246
247
        grid->np      = ISEC2_NumPar;
	grid->size    = ISEC4_NumValues;
        grid->rowlon  = ISEC2_RowLonPtr;
	grid->nrowlon = ISEC2_NumLat;
	grid->ysize   = ISEC2_NumLat;
	grid->xinc    = 0;
	grid->yinc    = 0;
	grid->xdef    = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
248
249
	/* if ( ISEC2_FirstLon != 0 || ISEC2_LastLon != 0 ) */
	  {
250
	    if ( grid->xsize > 1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
251
	      {
252
253
                if ( ISEC2_LastLon < ISEC2_FirstLon && ISEC2_LastLon < 0 ) ISEC2_LastLon += 360000;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
254
		if ( ISEC2_ResFlag && ISEC2_LonIncr > 0 )
255
		  grid->xinc = ISEC2_LonIncr * 0.001;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
256
		else
257
		  grid->xinc = (ISEC2_LastLon - ISEC2_FirstLon) * 0.001 / (grid->xsize - 1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
258
	      }
259
260
	    grid->xfirst = ISEC2_FirstLon * 0.001;
	    grid->xlast  = ISEC2_LastLon  * 0.001;
261
	    grid->xdef   = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
262
	  }
263
	grid->ydef  = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
264
265
	/* if ( ISEC2_FirstLat != 0 || ISEC2_LastLat != 0 ) */
	  {
266
	    if ( grid->ysize > 1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
267
268
	      {
		if ( ISEC2_ResFlag && ISEC2_LatIncr > 0 )
269
		  grid->yinc = ISEC2_LatIncr * 0.001;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
270
		else
271
		  grid->yinc = (ISEC2_LastLat - ISEC2_FirstLat) * 0.001 / (grid->ysize - 1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
272
	      }
273
274
	    grid->yfirst = ISEC2_FirstLat * 0.001;
	    grid->ylast  = ISEC2_LastLat  * 0.001;
275
	    grid->ydef   = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
276
277
278
	  }
	break;
      }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
279
    case GRID_LCC:
280
281
      {
	if ( ISEC4_NumValues != ISEC2_NumLon*ISEC2_NumLat )
282
	  Error("numberOfPoints (%d) and gridSize (%d) differ!",
283
		ISEC4_NumValues, ISEC2_NumLon*ISEC2_NumLat);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
284

285
286
287
	grid->size  = ISEC4_NumValues;
	grid->xsize = ISEC2_NumLon;
	grid->ysize = ISEC2_NumLat;
288

289
290
291
292
293
294
295
296
297
	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;
298

299
	grid->xdef   = 0;
300
	grid->ydef   = 0;
301
302
303

	break;
      }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
304
305
    case GRID_SPECTRAL:
      {
306
307
	grid->size  = ISEC4_NumValues;
	grid->trunc = ISEC2_PentaJ;
308
	if ( ISEC2_RepMode == 2 )
309
	  grid->lcomplex = 1;
310
	else
311
	  grid->lcomplex = 0;
312

Uwe Schulzweida's avatar
Uwe Schulzweida committed
313
314
315
316
	break;
      }
    case GRID_GME:
      {
317
	grid->size  = ISEC4_NumValues;
318
319
320
321
	grid->gme.nd    = ISEC2_GME_ND;
	grid->gme.ni    = ISEC2_GME_NI;
	grid->gme.ni2   = ISEC2_GME_NI2;
	grid->gme.ni3   = ISEC2_GME_NI3;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
322
323
324
325
	break;
      }
    case GRID_GENERIC:
      {
326
327
328
	grid->size  = ISEC4_NumValues;
	grid->xsize = 0;
	grid->ysize = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
329
330
331
332
	break;
      }
    default:
      {
333
	Error("Unsupported grid type: %s", gridNamePtr(gridtype));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
334
335
336
337
	break;
      }
    }

338
  grid->isRotated = FALSE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
339
  if ( cgribexGetIsRotated(isec2) )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
340
    {
341
      grid->isRotated = TRUE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
342
343
      grid->ypole     = - ISEC2_LatSP*0.001;
      grid->xpole     =   ISEC2_LonSP*0.001 - 180;
344
      grid->angle     = - FSEC2_RotAngle;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
345
346
    }

347
348
349
350
351
352
  grid->xvals = NULL;
  grid->yvals = NULL;
  grid->type  = gridtype;
}

static
353
void cgribexAddRecord(stream_t * streamptr, int param, int *isec1, int *isec2, double *fsec2, double *fsec3,
354
		      int *isec4, long recsize, off_t position, int datatype, int comptype, int lmv, int iret)
355
{
356
  int varID;
357
358
  int levelID = 0;

359
360
361
  int vlistID = streamptr->vlistID;
  int tsID    = streamptr->curTsID;
  int recID   = recordNewEntry(streamptr, tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
362
  record_t *record = &streamptr->tsteps[tsID].records[recID];
363

364
365
  int tsteptype = cgribexGetTsteptype(ISEC1_TimeRange);
  int numavg    = ISEC1_AvgNum;
366

367
368
  int level1  = ISEC1_Level1;
  int level2  = ISEC1_Level2;
369
370
371

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

372
373
374
375
376
377
  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
378
  record->tsteptype = (short)tsteptype;
379

Uwe Schulzweida's avatar
Uwe Schulzweida committed
380
381
  grid_t *gridptr = (grid_t*) Malloc(sizeof(*gridptr));
  cgribexGetGrid(streamptr, isec2, fsec2, isec4, gridptr, iret);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
382

Uwe Schulzweida's avatar
Uwe Schulzweida committed
383
  struct addIffNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, gridptr, 0);
384
  int gridID = gridAdded.Id;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
385
386
387
388
389
390
391
392
393
394
395
396
  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));
        }
    }
  else
    Free(gridptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
397

398
  int zaxistype = grib1ltypeToZaxisType(ISEC1_LevelType);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
399

400
  if ( zaxistype == ZAXIS_HYBRID || zaxistype == ZAXIS_HYBRID_HALF )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
401
    {
402
      size_t vctsize = (size_t)ISEC2_NumVCP;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
403
404
405
406
407
      double *vctptr = &fsec2[10];

      varDefVCT(vctsize, vctptr);
    }

408
  int lbounds = cgribexGetZaxisHasBounds(ISEC1_LevelType);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
409

410
411
  if ( datatype > 32 ) datatype = DATATYPE_PACK32;
  if ( datatype <  0 ) datatype = DATATYPE_PACK;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
412

413
  varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2, 0, 0,
414
415
	       datatype, &varID, &levelID, tsteptype, numavg, ISEC1_LevelType, -1,
               NULL, NULL, NULL, NULL, NULL, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
416

Thomas Jahns's avatar
Thomas Jahns committed
417
418
  record->varID   = (short)varID;
  record->levelID = (short)levelID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
419

420
  varDefCompType(varID, comptype);
421

422
423
424
425
426
427
428
  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]);
    }
429

430
431
  if ( lmv ) varDefMissval(varID, FSEC3_MissVal);

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
443
  if ( varInqModel(varID) == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
444
445
446
    {
      int modelID;
      modelID = modelInq(varInqInst(varID), ISEC1_ModelID, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
447
      if ( modelID == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
448
449
450
451
	modelID = modelDef(varInqInst(varID), ISEC1_ModelID, NULL);
      varDefModel(varID, modelID);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
452
  if ( varInqTable(varID) == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
453
454
    {
      int tableID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
455

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
458
      if ( tableID == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
459
460
461
462
	tableID = tableDef(varInqModel(varID), ISEC1_CodeTable, NULL);
      varDefTable(varID, tableID);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
463
464
  streamptr->tsteps[tsID].nallrecs++;
  streamptr->nrecs++;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
465
466
}

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

499
500
  memset(isec1, 0, 256*sizeof(int));

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

  *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;
    }
}
515
516

static
517
compvar_t cgribexVarSet(int param, int level1, int level2, int leveltype, int trange)
518
519
{
  compvar_t compVar;
520
  int tsteptype = cgribexGetTsteptype(trange);
521

522
523
524
525
526
  compVar.param     = param;
  compVar.level1    = level1;
  compVar.level2    = level2;
  compVar.ltype     = leveltype;
  compVar.tsteptype = tsteptype;
527

Uwe Schulzweida's avatar
Uwe Schulzweida committed
528
  return compVar;
529
530
}

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

548
549
550
#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)

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

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


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

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

614
615
616
617
618
  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
619

620
621
  int tsID  = tstepsNewEntry(streamptr);
  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
622
623

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

626
  int fileID = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
627

628
629
630
  while ( nskip-- > 0 )
    {
      recsize = gribGetSize(fileID);
631
      if ( recsize == 0 )
632
	Error("Skipping of %d records failed!", cdiSkipRecords);
633

634
      recpos  = fileGetPos(fileID);
635
      fileSetPos(fileID, (off_t)recsize, SEEK_CUR);
636
637
    }

638
  unsigned nrecs = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
639
640
641
642
643
644
645
  while ( TRUE )
    {
      recsize = gribGetSize(fileID);
      recpos  = fileGetPos(fileID);

      if ( recsize == 0 )
	{
646
	  if ( nrecs == 0 )
647
	    Error("No GRIB records found!");
648

Uwe Schulzweida's avatar
Uwe Schulzweida committed
649
	  streamptr->ntsteps = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
650
651
	  break;
	}
652
      if ( (size_t)recsize > buffersize )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
653
	{
654
	  buffersize = (size_t)recsize;
655
	  gribbuffer = Realloc(gribbuffer, buffersize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
656
657
	}

658
      readsize = (size_t)recsize;
659
      rstatus = gribRead(fileID, (unsigned char *)gribbuffer, &readsize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
660
      if ( rstatus ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
661

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

674
      nrecs_scanned++;
675
      cgribexDecodeHeader(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, fsec4,
676
			  (int *) gribbuffer, (int)recsize, &lmv, &iret);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
677

Uwe Schulzweida's avatar
Uwe Schulzweida committed
678
      param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255);
679
680
      cdiParamToString(param, paramstr, sizeof(paramstr));

681
682
      if ( ISEC1_LevelType == 100 ) ISEC1_Level1 *= 100;
      if ( ISEC1_LevelType ==  99 ) ISEC1_LevelType = 100;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
683
684
685
      level1   = ISEC1_Level1;
      level2   = ISEC1_Level2;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
686
687
      gribDateTime(isec1, &vdate, &vtime);

688
      if ( ISEC4_NumBits > 0 && ISEC4_NumBits <= 32 )
689
	datatype = ISEC4_NumBits;
690
      else
691
        datatype = DATATYPE_PACK;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
692
693
694
695
696
697
698

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

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

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

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

      nrecs++;

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

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

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

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

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

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

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

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

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
796
  streamptr->record->buffer     = gribbuffer;
797
  streamptr->record->buffersize = (size_t)buffersize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
798

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
805

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

898
899
      nrecs_scanned++;

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

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

	  datetime0.date = vdate;
	  datetime0.time = vtime;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
928
929
	}