stream_cgribex.c 59 KB
Newer Older
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1
2
3
4
#if defined (HAVE_CONFIG_H)
#  include "config.h"
#endif

5
#include <limits.h>
Uwe Schulzweida's avatar
Uwe Schulzweida committed
6
7
8
9
#include <stdio.h>

#include "dmemory.h"
#include "cdi.h"
10
#include "cdi_int.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
11
12
13
14
#include "file.h"
#include "varscan.h"
#include "datetime.h"
#include "vlist.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
15
#include "stream_grb.h"
16
#include "stream_cgribex.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
17

Uwe Schulzweida's avatar
Uwe Schulzweida committed
18
19
20
#if  defined  (HAVE_LIBCGRIBEX)
#  include "cgribex.h"
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
21
22

typedef struct {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
23
  int param;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
24
25
26
  int level1;
  int level2;
  int ltype;
27
  int tsteptype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
28
} compvar_t;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
29
30


Uwe Schulzweida's avatar
Uwe Schulzweida committed
31
#if  defined  (HAVE_LIBCGRIBEX)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
32
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
33
int cgribexGetGridType(int *isec2)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
34
{
35
  int gridtype = GRID_GENERIC;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
36
37
38

  switch (ISEC2_GridType)
    {
39
    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
52
53
54
    }

  return (gridtype);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
55
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
56
int cgribexGetIsRotated(int *isec2)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
57
58
59
{
  int isRotated = 0;

60
  if ( ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
61
62
63
    {
      isRotated = 1;
    }
64

Uwe Schulzweida's avatar
Uwe Schulzweida committed
65
66
67
  return (isRotated);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
68
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
69
int cgribexGetZaxisHasBounds(int grb_ltype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
70
71
72
{
  int lbounds = 0;

73
  switch (grb_ltype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
74
    {
75
    case GRIB1_LTYPE_SIGMA_LAYER:
Uwe Schulzweida's avatar
Uwe Schulzweida committed
76
77
    case GRIB1_LTYPE_HYBRID_LAYER:
    case GRIB1_LTYPE_LANDDEPTH_LAYER:
Uwe Schulzweida's avatar
Uwe Schulzweida committed
78
79
80
81
82
83
84
85
86
      {
	lbounds = 1;
	break;
      }
    }

  return (lbounds);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
87
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
88
int cgribexGetTimeUnit(int *isec1)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
89
{
90
  int timeunit = TUNIT_HOUR;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
91
92
93
94
  static int lprint = TRUE;

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

  return (timeunit);
}

115
116
117
118
119
120
121
122
123
124
125
126
127
128
static
int cgribexTimeIsFC(int *isec1)
{
  int isFC = TRUE;

  if ( ISEC1_TimeRange == 10 && ISEC1_TimePeriod1 == 0 && ISEC1_TimePeriod2 == 0 )
    isFC = FALSE;

  return (isFC);
}

static
int cgribexGetTsteptype(int timerange)
{
129
  int tsteptype = TSTEP_INSTANT;
130
131
132
133
134
135
136
137
138
139
140
141
142
143
  static int lprint = TRUE;

  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 )
	{
144
	  Message("Time range indicator %d unsupported, set to 0!", timerange);
145
146
	  lprint = FALSE;
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
147
      break;
148
149
150
151
152
    }

  return (tsteptype);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
153
static
154
void cgribexGetGrid(stream_t *streamptr, int *isec2, double *fsec2, int *isec4, grid_t *grid, int iret)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
155
{
156
157
  int compyinc = TRUE;
  int gridtype = cgribexGetGridType(isec2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
158

159
  if ( streamptr->unreduced && gridtype == GRID_GAUSSIAN_REDUCED && iret != -801 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
160
    {
161
162
163
      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
164
      gridtype = GRID_GAUSSIAN;
165
166
      ISEC2_NumLon = nlon;
      ISEC4_NumValues = nlon*ISEC2_NumLat;
167
      compyinc = FALSE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
168
169
    }

170
  grid_init(grid);
171
  cdiGridTypeInit(grid, gridtype, 0);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
172
173
174
175
176
177
  switch (gridtype)
    {
    case GRID_LONLAT:
    case GRID_GAUSSIAN:
      {
	if ( ISEC4_NumValues != ISEC2_NumLon*ISEC2_NumLat )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
178
	  Error("numberOfPoints (%d) and gridSize (%d) differ!", ISEC4_NumValues, ISEC2_NumLon*ISEC2_NumLat);
179
180
181
	grid->size  = ISEC4_NumValues;
	grid->xsize = ISEC2_NumLon;
	grid->ysize = ISEC2_NumLat;
182
        if ( gridtype == GRID_GAUSSIAN ) grid->np = ISEC2_NumPar;
183
184
185
	grid->xinc  = 0;
	grid->yinc  = 0;
	grid->xdef  = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
186
187
	/* if ( ISEC2_FirstLon != 0 || ISEC2_LastLon != 0 ) */
	  {
188
	    if ( grid->xsize > 1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
189
	      {
190
                int recompinc = TRUE;
191

192
193
                if ( ISEC2_LastLon < ISEC2_FirstLon && ISEC2_LastLon < 0 ) ISEC2_LastLon += 360000;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
194
		if ( ISEC2_ResFlag && ISEC2_LonIncr > 0 )
195
196
197
198
199
200
201
                  {
                    if ( abs(ISEC2_LastLon - (ISEC2_FirstLon+ISEC2_LonIncr*(grid->xsize-1))) <= 2 )
                      {
                        recompinc = FALSE;
                        grid->xinc = ISEC2_LonIncr * 0.001;
                      }
                  }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
202

203
		/* recompute xinc if necessary */
204
                if ( recompinc ) grid->xinc = (ISEC2_LastLon - ISEC2_FirstLon) * 0.001 / (grid->xsize-1);
205
206
207
208
209
210
211
212
213
214
215
216

		/* 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
217
	      }
218
219
	    grid->xfirst = ISEC2_FirstLon * 0.001;
	    grid->xlast  = ISEC2_LastLon  * 0.001;
220
	    grid->xdef   = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
221
	  }
222
	grid->ydef  = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
223
224
	/* if ( ISEC2_FirstLat != 0 || ISEC2_LastLat != 0 ) */
	  {
225
	    if ( grid->ysize > 1 && compyinc )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
226
	      {
227
                int recompinc = TRUE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
228
		if ( ISEC2_ResFlag && ISEC2_LatIncr > 0 )
229
230
231
232
233
234
235
                  {
                    if ( abs(ISEC2_LastLat - (ISEC2_FirstLat+ISEC2_LatIncr*(grid->ysize-1))) <= 2 )
                      {
                        recompinc = FALSE;
                        grid->yinc = ISEC2_LatIncr * 0.001;
                      }
                  }
236

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

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

292
293
294
	grid->size  = ISEC4_NumValues;
	grid->xsize = ISEC2_NumLon;
	grid->ysize = ISEC2_NumLat;
295

296
297
298
299
300
301
302
303
304
	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;
305

306
	grid->xdef   = 0;
307
	grid->ydef   = 0;
308
309
310

	break;
      }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
311
312
    case GRID_SPECTRAL:
      {
313
314
	grid->size  = ISEC4_NumValues;
	grid->trunc = ISEC2_PentaJ;
315
	if ( ISEC2_RepMode == 2 )
316
	  grid->lcomplex = 1;
317
	else
318
	  grid->lcomplex = 0;
319

Uwe Schulzweida's avatar
Uwe Schulzweida committed
320
321
322
323
	break;
      }
    case GRID_GME:
      {
324
325
326
327
328
	grid->size  = ISEC4_NumValues;
	grid->nd    = ISEC2_GME_ND;
	grid->ni    = ISEC2_GME_NI;
	grid->ni2   = ISEC2_GME_NI2;
	grid->ni3   = ISEC2_GME_NI3;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
329
330
331
332
	break;
      }
    case GRID_GENERIC:
      {
333
334
335
	grid->size  = ISEC4_NumValues;
	grid->xsize = 0;
	grid->ysize = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
336
337
338
339
	break;
      }
    default:
      {
340
	Error("Unsupported grid type: %s", gridNamePtr(gridtype));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
341
342
343
344
	break;
      }
    }

345
  grid->isRotated = FALSE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
346
  if ( cgribexGetIsRotated(isec2) )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
347
    {
348
      grid->isRotated = TRUE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
349
350
      grid->ypole     = - ISEC2_LatSP*0.001;
      grid->xpole     =   ISEC2_LonSP*0.001 - 180;
351
      grid->angle     = - FSEC2_RotAngle;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
352
353
    }

354
355
356
357
358
359
  grid->xvals = NULL;
  grid->yvals = NULL;
  grid->type  = gridtype;
}

static
360
void cgribexAddRecord(stream_t * streamptr, int param, int *isec1, int *isec2, double *fsec2, double *fsec3,
361
		      int *isec4, long recsize, off_t position, int datatype, int comptype, int lmv, int iret)
362
{
363
  int varID;
364
  int levelID = 0;
365
  grid_t *grid = (grid_t *)Malloc(sizeof (*grid));
366

367
368
369
370
  int vlistID = streamptr->vlistID;
  int tsID    = streamptr->curTsID;
  int recID   = recordNewEntry(streamptr, tsID);
  record_t *record  = &streamptr->tsteps[tsID].records[recID];
371

372
373
  int tsteptype = cgribexGetTsteptype(ISEC1_TimeRange);
  int numavg    = ISEC1_AvgNum;
374

375
376
  int level1  = ISEC1_Level1;
  int level2  = ISEC1_Level2;
377
378
379

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

380
381
382
383
384
385
386
  record->size      = (size_t)recsize;
  record->position  = position;
  record->param     = param;
  record->ilevel    = level1;
  record->ilevel2   = level2;
  record->ltype     = ISEC1_LevelType;
  record->tsteptype = tsteptype;
387

388
  cgribexGetGrid(streamptr, isec2, fsec2, isec4, grid, iret);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
389

390
391
392
  struct addIffNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, grid, 0);
  int gridID = gridAdded.Id;
  if (!gridAdded.isNew) Free(grid);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
393

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

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

      varDefVCT(vctsize, vctptr);
    }

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

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

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

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

416
  varDefCompType(varID, comptype);
417

418
419
420
421
422
423
424
  if ( ISEC1_LocalFLag )
    {
      if      ( ISEC1_CenterID == 78  && isec1[36] == 253 ) // DWD local extension
        varDefEnsembleInfo(varID, isec1[54], isec1[53], isec1[52]);
      else if ( ISEC1_CenterID == 252 && isec1[36] ==   1 ) // MPIM local extension
        varDefEnsembleInfo(varID, isec1[38], isec1[39], isec1[37]);
    }
425

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

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

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

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

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

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

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

463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
static
void MCH_get_undef(int *isec1, double *undef_pds, double *undef_eps)
{
  /* 2010-01-13: Oliver Fuhrer */
  if ( ISEC1_CenterID == 215 ) {
    if (isec1[34] != 0 && isec1[34] != 255) {
      if (isec1[34] & 2) {
        if (isec1[34] & 1) {
          *undef_pds = -0.99*pow(10.0,-isec1[35]);
        } else {
          *undef_pds = +0.99*pow(10.0,-isec1[35]);
        }
        *undef_eps = pow(10.0,-isec1[35]-1);
      } else {
        if (isec1[34] & 1) {
          *undef_pds = -0.99*pow(10.0,+isec1[35]);
        } else {
          *undef_pds = +0.99*pow(10.0,+isec1[35]);
        }
        *undef_eps = pow(10.0,isec1[35]-1);
      }
    }
  }
}

static
void cgribexDecodeHeader(int *isec0, int *isec1, int *isec2, double *fsec2,
490
			 int *isec3, double *fsec3, int *isec4, double *fsec4,
491
			 int *gribbuffer, int recsize, int *lmv, int *iret)
492
{
493
  int ipunp = 0, iword = 0;
494

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

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

  *lmv = 0;

  if ( ISEC1_CenterID == 215 && (isec1[34] != 0 && isec1[34] != 255) )
    {
      double undef_pds, undef_eps;

      MCH_get_undef(isec1, &undef_pds, &undef_eps);
      FSEC3_MissVal = undef_pds;
      *lmv = 1;
    }
}
511
512

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

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

  return (compVar);
}

Thomas Jahns's avatar
Thomas Jahns committed
527
528
static inline int
cgribexVarCompare(compvar_t compVar, record_t record, int flag)
529
{
Thomas Jahns's avatar
Thomas Jahns committed
530
531
532
533
  int tstepDiff = (!((flag == 0) & (((compVar.tsteptype == TSTEP_INSTANT)
                                     & (record.tsteptype == TSTEP_INSTANT3))
                                    |((compVar.tsteptype == TSTEP_INSTANT3)
                                      & (record.tsteptype == TSTEP_INSTANT)))))
Thomas Jahns's avatar
Thomas Jahns committed
534
535
536
537
538
539
    & (compVar.tsteptype != record.tsteptype);
  int rstatus = (compVar.param != record.param)
    |           (compVar.level1 != record.ilevel)
    |           (compVar.level2 != record.ilevel2)
    |           (compVar.ltype != record.ltype)
    |           tstepDiff;
540
541
  return (rstatus);
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
542
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
543

544
545
546
#define gribWarning(text, nrecs, timestep, paramstr, level1, level2) \
            Warning("Record %2d (id=%s lev1=%d lev2=%d) timestep %d: %s", nrecs, paramstr, level1, level2, timestep, text)

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

static inline void
cgribexScanTsFixNtsteps(stream_t *streamptr, off_t recpos)
{
  if ( streamptr->ntsteps == -1 )
    {
      int tsID = tstepsNewEntry(streamptr);
      if ( tsID != streamptr->rtsteps )
	Error("Internal error. tsID = %d", tsID);

      streamptr->tsteps[tsID-1].next   = TRUE;
      streamptr->tsteps[tsID].position = recpos;
    }
}

static inline void
cgribexScanTsConstAdjust(stream_t *streamptr, taxis_t *taxis)
{
  int vlistID = streamptr->vlistID;
  if ( streamptr->ntsteps == 1 )
    {
      if ( taxis->vdate == 0 && taxis->vtime == 0 )
	{
	  streamptr->ntsteps = 0;
	  for (int varID = 0; varID < streamptr->nvars; varID++ )
	    {
	      vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
	    }
	}
    }
}


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

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

609
610
611
612
613
  int *isec0 = streamptr->record->sec0;
  int *isec1 = streamptr->record->sec1;
  int *isec2 = streamptr->record->sec2;
  int *isec3 = streamptr->record->sec3;
  int *isec4 = streamptr->record->sec4;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
614

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

      nrecs++;

      if ( CDI_Debug )
745
	Message("Read record %2d (id=%s lev1=%d lev2=%d) %8d %6d", nrecs_scanned, paramstr, level1, level2, vdate, vtime);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
746

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

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

753
754
  if ( nrecs == 0 ) return (CDI_EUFSTRUCT);

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

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

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

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

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

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

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

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
800

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

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

821
822
823
824
825
  int *isec0 = streamptr->record->sec0;
  int *isec1 = streamptr->record->sec1;
  int *isec2 = streamptr->record->sec2;
  int *isec3 = streamptr->record->sec3;
  int *isec4 = streamptr->record->sec4;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
826

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

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

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

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

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

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

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

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

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

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

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

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

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

893
894
      nrecs_scanned++;

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

898
899
      if ( ISEC1_LevelType == 100 ) ISEC1_Level1 *= 100;
      if ( ISEC1_LevelType ==  99 ) ISEC1_LevelType = 100;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
      level1    = ISEC1_Level1;
      level2    = ISEC1_Level2;

      gribDateTime(isec1, &vdate, &vtime);

      if ( rindex == 0 )
	{
	  if ( taxisInqType(taxisID) == TAXIS_RELATIVE )
	    {
	      taxis->type  = TAXIS_RELATIVE;
	      taxis->rdate = gribRefDate(isec1);
	      taxis->rtime = gribRefTime(isec1);
	    }
	  else
	    {
	      taxis->type  = TAXIS_ABSOLUTE;
	    }
917
	  taxis->unit  = cgribexGetTimeUnit(isec1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
918
919
	  taxis->vdate = vdate;
	  taxis->vtime = vtime;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
920
921
922

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

925
926
      tsteptype = cgribexGetTsteptype(ISEC1_TimeRange);

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

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

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

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
959
960
961
962
963
964
965
966
967
968
      if ( cdiInventoryMode == 1 )
	{
	  if ( streamptr->tsteps[tsID].records[recID].used )
	    {
	      break;
	    }
	  else
	    {
	      streamptr->tsteps[tsID].records[recID].used = TRUE;
	      streamptr->tsteps[tsID].recIDs[rindex] = recID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
969
	    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
970
971
972
973
974
	}
      else
	{
	  if ( streamptr->tsteps[tsID].records[recID].used )
	    {
975
	      if ( datetimeCmp(datetime, datetime0) != 0 ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
976

977
              gribWarning("Parameter already exist, skipped!", nrecs_scanned, tsID+1, paramstr, level1, level2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
978
979
980
981
982
983
	      continue;
	    }
	  else
	    {
	      streamptr->