stream_cgribex.c 56.7 KB
Newer Older
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#if defined (HAVE_CONFIG_H)
#  include "config.h"
#endif

#include <stdio.h>
#include <float.h>  /* FLT_EPSILON */

#include "dmemory.h"
#include "cdi.h"
#include "stream_int.h"
#include "file.h"
#include "varscan.h"
#include "datetime.h"
#include "vlist.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
15
#include "stream_grb.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
16

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
21
extern int cdiInventoryMode;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
22
23

typedef struct {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
24
  int param;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
25
26
27
  int level1;
  int level2;
  int ltype;
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
    case ISEC1_TABLE4_MINUTE:  timeunit = TUNIT_MINUTE;  break;
    case ISEC1_TABLE4_QUARTER: timeunit = TUNIT_QUARTER; break;
    case ISEC1_TABLE4_HOUR:    timeunit = TUNIT_HOUR;    break;
98
99
100
    case ISEC1_TABLE4_3HOURS:  timeunit = TUNIT_3HOURS;  break;
    case ISEC1_TABLE4_6HOURS:  timeunit = TUNIT_6HOURS;  break;
    case ISEC1_TABLE4_12HOURS: timeunit = TUNIT_12HOURS; break;
101
    case ISEC1_TABLE4_DAY:     timeunit = TUNIT_DAY;     break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
102
103
104
    default:
      if ( lprint )
	{
105
	  Message("GRIB time unit %d unsupported!", ISEC1_TimeUnit);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
106
107
108
109
110
111
112
	  lprint = FALSE;
	}
    }

  return (timeunit);
}

113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
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)
{
  int tsteptype = 0;
  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 )
	{
142
	  Message("GRIB time range %d unsupported!", timerange);
143
144
145
146
147
148
149
	  lprint = FALSE;
	}
    }

  return (tsteptype);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
150
static
151
void cgribexGetGrid(stream_t *streamptr, int *isec2, int *isec4, grid_t *grid, int iret)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
152
{
153
  int gridtype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
154

Uwe Schulzweida's avatar
Uwe Schulzweida committed
155
  gridtype = cgribexGetGridType(isec2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
156

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
190
		if ( ISEC2_ResFlag && ISEC2_LonIncr > 0 )
191
		  grid->xinc = ISEC2_LonIncr * 0.001;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
192
		else
193
		  grid->xinc = (ISEC2_LastLon - ISEC2_FirstLon) * 0.001 / (grid->xsize - 1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
194
195
196
197

		/* correct xinc if necessary */
		if ( ISEC2_FirstLon == 0 && ISEC2_LastLon > 354000 )
		  {
198
		    double xinc = 360. / grid->xsize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
199

200
		    if ( fabs(grid->xinc-xinc) > 0.0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
201
		      {
202
203
			grid->xinc = xinc;
			if ( CDI_Debug ) Message("set xinc to %g", grid->xinc);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
204
205
206
		      }
		  }
	      }
207
208
	    grid->xfirst = ISEC2_FirstLon * 0.001;
	    grid->xlast  = ISEC2_LastLon  * 0.001;
209
	    grid->xdef   = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
210
	  }
211
	grid->ydef  = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
212
213
	/* if ( ISEC2_FirstLat != 0 || ISEC2_LastLat != 0 ) */
	  {
214
	    if ( grid->ysize > 1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
215
	      {
216
		if ( ISEC2_ResFlag && ISEC2_LatIncr > 0 )
217
		  if ( ISEC2_LatIncr*(grid->ysize-1) > 180000 ) ISEC2_LatIncr = 0;
218

Uwe Schulzweida's avatar
Uwe Schulzweida committed
219
		if ( ISEC2_ResFlag && ISEC2_LatIncr > 0 )
220
		  grid->yinc = ISEC2_LatIncr * 0.001;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
221
		else
222
		  grid->yinc = (ISEC2_LastLat - ISEC2_FirstLat) * 0.001 / (grid->ysize - 1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
223
	      }
224
225
	    grid->yfirst = ISEC2_FirstLat * 0.001;
	    grid->ylast  = ISEC2_LastLat  * 0.001;
226
	    grid->ydef   = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
227
228
229
230
231
	  }
	break;
      }
    case GRID_GAUSSIAN_REDUCED:
      {
232
        grid->np     = ISEC2_NumPar;
233
234
235
	grid->size   = ISEC4_NumValues;
        grid->rowlon = ISEC2_RowLonPtr;
	grid->ysize  = ISEC2_NumLat;
236
237
238
	grid->xinc   = 0;
	grid->yinc   = 0;
	grid->xdef   = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
239
240
	/* if ( ISEC2_FirstLon != 0 || ISEC2_LastLon != 0 ) */
	  {
241
	    if ( grid->xsize > 1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
242
243
	      {
		if ( ISEC2_ResFlag && ISEC2_LonIncr > 0 )
244
		  grid->xinc = ISEC2_LonIncr * 0.001;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
245
		else
246
		  grid->xinc = (ISEC2_LastLon - ISEC2_FirstLon) * 0.001 / (grid->xsize - 1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
247
	      }
248
249
	    grid->xfirst = ISEC2_FirstLon * 0.001;
	    grid->xlast  = ISEC2_LastLon  * 0.001;
250
	    grid->xdef   = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
251
	  }
252
	grid->ydef  = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
253
254
	/* if ( ISEC2_FirstLat != 0 || ISEC2_LastLat != 0 ) */
	  {
255
	    if ( grid->ysize > 1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
256
257
	      {
		if ( ISEC2_ResFlag && ISEC2_LatIncr > 0 )
258
		  grid->yinc = ISEC2_LatIncr * 0.001;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
259
		else
260
		  grid->yinc = (ISEC2_LastLat - ISEC2_FirstLat) * 0.001 / (grid->ysize - 1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
261
	      }
262
263
	    grid->yfirst = ISEC2_FirstLat * 0.001;
	    grid->ylast  = ISEC2_LastLat  * 0.001;
264
	    grid->ydef   = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
265
266
267
	  }
	break;
      }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
268
    case GRID_LCC:
269
270
      {
	if ( ISEC4_NumValues != ISEC2_NumLon*ISEC2_NumLat )
271
	  Error("numberOfPoints (%d) and gridSize (%d) differ!",
272
		ISEC4_NumValues, ISEC2_NumLon*ISEC2_NumLat);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
273

274
275
276
	grid->size  = ISEC4_NumValues;
	grid->xsize = ISEC2_NumLon;
	grid->ysize = ISEC2_NumLat;
277

278
279
280
281
282
283
284
285
286
	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;
287

288
	grid->xdef   = 0;
289
	grid->ydef   = 0;
290
291
292

	break;
      }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
293
294
    case GRID_SPECTRAL:
      {
295
296
	grid->size  = ISEC4_NumValues;
	grid->trunc = ISEC2_PentaJ;
297
	if ( ISEC2_RepMode == 2 )
298
	  grid->lcomplex = 1;
299
	else
300
	  grid->lcomplex = 0;
301

Uwe Schulzweida's avatar
Uwe Schulzweida committed
302
303
304
305
	break;
      }
    case GRID_GME:
      {
306
307
308
309
310
	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
311
312
313
314
	break;
      }
    case GRID_GENERIC:
      {
315
316
317
	grid->size  = ISEC4_NumValues;
	grid->xsize = 0;
	grid->ysize = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
318
319
320
321
	break;
      }
    default:
      {
322
	Error("Unsupported grid type: %s", gridNamePtr(gridtype));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
323
324
325
326
	break;
      }
    }

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

336
337
338
339
340
341
342
  grid->xvals = NULL;
  grid->yvals = NULL;
  grid->type  = gridtype;
}

static
void cgribexAddRecord(int streamID, int param, int *isec1, int *isec2, double *fsec2, double *fsec3,
343
		      int *isec4, long recsize, off_t position, int datatype, int comptype, int lmv, int iret)
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
{
  int zaxistype;
  int gridID = CDI_UNDEFID, varID;
  int levelID = 0;
  int tsID, recID;
  int level1, level2;
  int numavg;
  int tsteptype;
  int lbounds = 0;
  record_t *record;
  grid_t grid;
  int vlistID;
  stream_t *streamptr;

  streamptr = stream_to_pointer(streamID);

  vlistID = streamInqVlist(streamID);
  tsID    = streamptr->curTsID;
  recID   = recordNewEntry(streamID, tsID);
  record  = &streamptr->tsteps[tsID].records[recID];

  tsteptype = cgribexGetTsteptype(ISEC1_TimeRange);
  numavg    = ISEC1_AvgNum;

  level1  = ISEC1_Level1;
  level2  = ISEC1_Level2;

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

  (*record).size     = recsize;
  (*record).position = position;
  (*record).param    = param;
  (*record).ilevel   = level1;
  (*record).ilevel2  = level2;
  (*record).ltype    = ISEC1_LevelType;

380
  cgribexGetGrid(streamptr, isec2, isec4, &grid, iret);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
381
382
383

  gridID = varDefGrid(vlistID, grid, 0);

384
  zaxistype = grib1ltypeToZaxisType(ISEC1_LevelType);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
385

386
  if ( zaxistype == ZAXIS_HYBRID || zaxistype == ZAXIS_HYBRID_HALF )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
387
388
389
390
391
392
393
    {
      int vctsize = ISEC2_NumVCP;
      double *vctptr = &fsec2[10];

      varDefVCT(vctsize, vctptr);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
394
  lbounds = cgribexGetZaxisHasBounds(ISEC1_LevelType);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
395

396
397
  if ( datatype > 32 ) datatype = DATATYPE_PACK32;
  if ( datatype <  0 ) datatype = DATATYPE_PACK;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
398

Uwe Schulzweida's avatar
Uwe Schulzweida committed
399
  varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2,
400
	       datatype, &varID, &levelID, tsteptype, numavg, ISEC1_LevelType, NULL, NULL, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
401
402
403
404

  (*record).varID   = varID;
  (*record).levelID = levelID;

405
  varDefCompType(varID, comptype);
406

407
408
409
  if ( isec1[36] )
    varDefEnsembleInfo(varID, isec1[37], isec1[38], isec1[39]);

410
411
  if ( lmv ) varDefMissval(varID, FSEC3_MissVal);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
412
  if ( varInqInst(varID) == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
413
414
415
416
417
    {
      int center, subcenter, instID;
      center    = ISEC1_CenterID;
      subcenter = ISEC1_SubCenterID;
      instID    = institutInq(center, subcenter, NULL, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
418
      if ( instID == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
419
420
421
422
	instID = institutDef(center, subcenter, NULL, NULL);
      varDefInst(varID, instID);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
423
  if ( varInqModel(varID) == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
424
425
426
    {
      int modelID;
      modelID = modelInq(varInqInst(varID), ISEC1_ModelID, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
427
      if ( modelID == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
428
429
430
431
	modelID = modelDef(varInqInst(varID), ISEC1_ModelID, NULL);
      varDefModel(varID, modelID);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
432
  if ( varInqTable(varID) == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
433
434
    {
      int tableID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
435

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
438
      if ( tableID == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
439
440
441
442
	tableID = tableDef(varInqModel(varID), ISEC1_CodeTable, NULL);
      varDefTable(varID, tableID);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
443
444
  streamptr->tsteps[tsID].nallrecs++;
  streamptr->nrecs++;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
445
446

  if ( CDI_Debug )
447
    Message("varID = %d  param = %d  zaxistype = %d  gridID = %d  levelID = %d",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
448
	    varID, param, zaxistype, gridID, levelID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
449
450
}

451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
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,
			 int *isec3, double *fsec3, int *isec4, double *fsec4, 
479
			 int *gribbuffer, int recsize, int *lmv, int *iret)
480
{
481
  int ipunp = 0, iword = 0;
482

483
484
  memset(isec1, 0, 256*sizeof(int));

485
  gribExDP(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, fsec4,
486
	   ipunp, (int *) gribbuffer, recsize, &iword, "J", iret);
487
488
489
490
491
492
493
494
495
496
497
498

  *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;
    }
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
499
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
500

501
int cgribexScanTimestep1(int streamID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
502
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
503
#if  defined  (HAVE_LIBCGRIBEX)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
504
505
  int *isec0, *isec1, *isec2, *isec3, *isec4;
  double fsec2[512], fsec3[2], *fsec4 = NULL;
506
  int lmv = 0, iret = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
507
508
509
  off_t recpos = 0;
  unsigned char *gribbuffer = NULL;
  long buffersize = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
510
  int rstatus;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
511
  int fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
512
513
  int param = 0;
  int level1 = 0, level2 = 0, vdate = 0, vtime = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
514
515
516
517
518
  DateTime datetime, datetime0;
  int tsID;
  int varID;
  size_t readsize;
  int nrecords, nrecs, recID;
519
  int datatype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
520
  long recsize = 0;
521
  int warn_time = TRUE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
522
523
524
  int warn_numavg = TRUE;
  int taxisID = -1;
  int rdate = 0, rtime = 0, tunit = 0, fcast = 0;
525
  taxis_t *taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
526
  int vlistID;
527
  int comptype;
528
  long unzipsize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
529
530
  compvar_t compVar, compVar0;
  stream_t *streamptr;
531
532
  extern int cdiSkipRecords;
  int nskip = cdiSkipRecords;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
533
534

  streamptr = stream_to_pointer(streamID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
535

536
  stream_check_ptr(__func__, streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
537

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
540
541
542
543
544
  isec0 = streamptr->record->sec0;
  isec1 = streamptr->record->sec1;
  isec2 = streamptr->record->sec2;
  isec3 = streamptr->record->sec3;
  isec4 = streamptr->record->sec4;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
545
546

  tsID  = tstepsNewEntry(streamID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
547
  taxis = &streamptr->tsteps[tsID].taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
548
549

  if ( tsID != 0 )
550
    Error("Internal problem! tstepsNewEntry returns %d", tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
551
552
553

  fileID = streamInqFileID(streamID);

554
555
556
  while ( nskip-- > 0 )
    {
      recsize = gribGetSize(fileID);
557
      if ( recsize == 0 )
558
	Error("Skipping of %d records failed!", cdiSkipRecords);
559

560
561
562
563
      recpos  = fileGetPos(fileID);
      fileSetPos(fileID, recsize, SEEK_CUR);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
564
565
566
567
568
569
570
571
  nrecs = 0;
  while ( TRUE )
    {
      recsize = gribGetSize(fileID);
      recpos  = fileGetPos(fileID);

      if ( recsize == 0 )
	{
572
	  if ( nrecs == 0 )
573
	    Error("No GRIB records found!");
574

Uwe Schulzweida's avatar
Uwe Schulzweida committed
575
	  streamptr->ntsteps = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
576
577
578
579
580
581
582
583
584
	  break;
	}
      if ( recsize > buffersize )
	{
	  buffersize = recsize;
	  gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
	}

      readsize = recsize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
585
586
      rstatus = gribRead(fileID, gribbuffer, &readsize);
      if ( rstatus ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
587

588
      comptype = COMPRESS_NONE;
589
590
      if ( gribGetZip(recsize, gribbuffer, &unzipsize) > 0 )
	{
591
	  comptype = COMPRESS_SZIP;
592
593
594
595
596
597
598
599
	  unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
	  if ( (long) buffersize < unzipsize )
	    {
	      buffersize = unzipsize;
	      gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
	    }
	}

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
603
      param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255);
604
605
      if ( ISEC1_LevelType == 100 ) ISEC1_Level1 *= 100;
      if ( ISEC1_LevelType ==  99 ) ISEC1_LevelType = 100;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
606
607
608
      level1   = ISEC1_Level1;
      level2   = ISEC1_Level2;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
609
610
      gribDateTime(isec1, &vdate, &vtime);

611
      if ( ISEC4_NumBits > 0 && ISEC4_NumBits <= 32 )
612
	datatype = ISEC4_NumBits;
613
      else
614
        datatype = DATATYPE_PACK;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
615
616
617
618
619
620
621

      if ( nrecs == 0 )
	{
	  datetime0.date = vdate;
	  datetime0.time = vtime;
	  rdate = gribRefDate(isec1);
	  rtime = gribRefTime(isec1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
622
	  tunit = cgribexGetTimeUnit(isec1);
623
	  fcast = cgribexTimeIsFC(isec1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
624
625
626
627
628
	}
      else
	{
	  datetime.date  = vdate;
	  datetime.time  = vtime;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
629
	  compVar.param  = param;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
630
631
632
633
634
          compVar.level1 = level1;
          compVar.level2 = level2;
          compVar.ltype  = ISEC1_LevelType;
	  for ( recID = 0; recID < nrecs; recID++ )
	    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
635
	      compVar0.param  = streamptr->tsteps[0].records[recID].param;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
636
637
638
	      compVar0.level1 = streamptr->tsteps[0].records[recID].ilevel;
	      compVar0.level2 = streamptr->tsteps[0].records[recID].ilevel2;
	      compVar0.ltype  = streamptr->tsteps[0].records[recID].ltype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
639

Uwe Schulzweida's avatar
Uwe Schulzweida committed
640
	      if ( memcmp(&compVar0, &compVar, sizeof(compvar_t)) == 0 ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
641
	    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
642
643
644
645
646
647
648

	  if ( cdiInventoryMode == 1 )
	    {
	      if ( recID < nrecs ) break;
	      if ( warn_time )
		if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 )
		  {
649
650
		    char paramstr[32];
		    cdiParamToString(param, paramstr, sizeof(paramstr));
651
		    Warning("Inconsistent verification time (param=%s level=%d)", paramstr, level1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
652
653
654
655
656
657
658
659
660
		    warn_time = FALSE;
		  }
	    }
	  else
	    {
	      if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 ) break;

	      if ( recID < nrecs )
		{
661
662
		  char paramstr[32];
		  cdiParamToString(param, paramstr, sizeof(paramstr));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
663
		  Warning("Param=%s level=%d already exist, skipped!", paramstr, level1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
664
665
666
		  continue;
		}
	    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
667
668
669
670
671
672
	}

      if ( ISEC1_AvgNum )
	{
	  if (  taxis->numavg && warn_numavg && (taxis->numavg != ISEC1_AvgNum) )
	    {
673
	      Warning("Changing numavg from %d to %d not supported!",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
674
675
676
677
678
679
680
681
682
683
684
685
		      taxis->numavg, ISEC1_AvgNum);
	      warn_numavg = FALSE;
	    }
	  else
	    {
	      taxis->numavg = ISEC1_AvgNum;
	    }
	}

      nrecs++;

      if ( CDI_Debug )
686
	Message("%4d %8d %4d  %8d %8d %6d", nrecs, (int)recpos, param, level1, vdate, vtime);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
687

688
      cgribexAddRecord(streamID, param, isec1, isec2, fsec2, fsec3,
689
		       isec4, recsize, recpos, datatype, comptype, lmv, iret);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
690
691
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
692
  streamptr->rtsteps = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
693

694
695
  if ( nrecs == 0 ) return (CDI_EUFSTRUCT);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
696
697
698
699
  cdiGenVars(streamID);

  if ( fcast )
    {
700
      taxisID = taxisCreate(TAXIS_RELATIVE);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
701
702
703
704
705
706
707
      taxis->type  = TAXIS_RELATIVE;
      taxis->rdate = rdate;
      taxis->rtime = rtime;
      taxis->unit  = tunit;
    }
  else
    {
708
      taxisID = taxisCreate(TAXIS_ABSOLUTE);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
709
      taxis->type  = TAXIS_ABSOLUTE;
710
      taxis->unit  = tunit;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
711
712
713
714
715
716
717
718
    }

  taxis->vdate = datetime0.date;
  taxis->vtime = datetime0.time;

  vlistID = streamInqVlist(streamID);
  vlistDefTaxis(vlistID, taxisID);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
719
720
  nrecords = streamptr->tsteps[0].nallrecs;
  if ( nrecords < streamptr->tsteps[0].recordSize )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
721
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
722
723
      streamptr->tsteps[0].recordSize = nrecords;
      streamptr->tsteps[0].records =
Uwe Schulzweida's avatar
Uwe Schulzweida committed
724
      (record_t *) realloc(streamptr->tsteps[0].records, nrecords*sizeof(record_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
725
726
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
727
728
  streamptr->tsteps[0].recIDs = (int *) malloc(nrecords*sizeof(int));
  streamptr->tsteps[0].nrecs = nrecords;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
729
  for ( recID = 0; recID < nrecords; recID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
730
    streamptr->tsteps[0].recIDs[recID] = recID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
731

Uwe Schulzweida's avatar
Uwe Schulzweida committed
732
733
  streamptr->record->buffer     = gribbuffer;
  streamptr->record->buffersize = buffersize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
734

Uwe Schulzweida's avatar
Uwe Schulzweida committed
735
  if ( streamptr->ntsteps == -1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
736
737
    {
      tsID = tstepsNewEntry(streamID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
738
      if ( tsID != streamptr->rtsteps )
739
	Error("Internal error. tsID = %d", tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
740

Uwe Schulzweida's avatar
Uwe Schulzweida committed
741
742
      streamptr->tsteps[tsID-1].next   = TRUE;
      streamptr->tsteps[tsID].position = recpos;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
743
744
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
745
  if ( streamptr->ntsteps == 1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
746
747
748
    {
      if ( taxis->vdate == 0 && taxis->vtime == 0 )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
749
750
	  streamptr->ntsteps = 0;
	  for ( varID = 0; varID < streamptr->nvars; varID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
751
	    {
752
	      vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
753
754
755
	    }
	}
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
756
757
758
#else
  Error("CGRIBEX support not compiled in!");
#endif
759
760

  return (0);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
761
762
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
763
764

int cgribexScanTimestep2(int streamID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
765
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
766
767
  int rstatus = 0;
#if  defined  (HAVE_LIBCGRIBEX)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
768
769
  int *isec0, *isec1, *isec2, *isec3, *isec4;
  double fsec2[512], fsec3[2], *fsec4 = NULL;
770
  int lmv = 0, iret = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
771
772
773
774
  off_t recpos = 0;
  unsigned char *gribbuffer = NULL;
  long buffersize = 0;
  int fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
775
776
  int param = 0;
  int level1 = 0, level2 = 0, vdate = 0, vtime = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
777
  DateTime datetime, datetime0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
778
779
780
781
782
783
  int tsID;
  int varID, gridID;
  size_t readsize;
  int nrecords, nrecs, recID, rindex;
  long recsize = 0;
  int warn_numavg = TRUE;
784
  int tsteptype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
785
  int taxisID = -1;
786
  taxis_t *taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
787
  int vlistID;
788
  long unzipsize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
789
790
  compvar_t compVar, compVar0;
  stream_t *streamptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
791

Uwe Schulzweida's avatar
Uwe Schulzweida committed
792
  streamptr = stream_to_pointer(streamID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
793

794
  stream_check_ptr(__func__, streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
795

Uwe Schulzweida's avatar
Uwe Schulzweida committed
796
797
798
799
800
801
802
  streamptr->curTsID = 1;

  isec0 = streamptr->record->sec0;
  isec1 = streamptr->record->sec1;
  isec2 = streamptr->record->sec2;
  isec3 = streamptr->record->sec3;
  isec4 = streamptr->record->sec4;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
803
804
805
806
807

  fileID  = streamInqFileID(streamID);
  vlistID = streamInqVlist(streamID);
  taxisID = vlistInqTaxis(vlistID);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
808
809
  gribbuffer = (unsigned char *) streamptr->record->buffer;
  buffersize = streamptr->record->buffersize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
810

Uwe Schulzweida's avatar
Uwe Schulzweida committed
811
  tsID = streamptr->rtsteps;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
812
  if ( tsID != 1 )
813
    Error("Internal problem! unexpeceted timestep %d", tsID+1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
814

Uwe Schulzweida's avatar
Uwe Schulzweida committed
815
  taxis = &streamptr->tsteps[tsID].taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
816

Uwe Schulzweida's avatar
Uwe Schulzweida committed
817
  fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
818
819
820

  cdiCreateRecords(streamID, tsID);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
821
822
823
  nrecords = streamptr->tsteps[tsID].nallrecs;
  streamptr->tsteps[1].recIDs = (int *) malloc(nrecords*sizeof(int));
  streamptr->tsteps[1].nrecs = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
824
  for ( recID = 0; recID < nrecords; recID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
825
    streamptr->tsteps[1].recIDs[recID] = -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
826

Uwe Schulzweida's avatar
Uwe Schulzweida committed
827
828
  for ( recID = 0; recID < nrecords; recID++ )
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
829
      varID = streamptr->tsteps[0].records[recID].varID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
830
831
      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
832
833
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
834
835
  rindex = 0;
  while ( TRUE )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
836
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
837
838
      if ( rindex > nrecords ) break;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
839
840
841
842
      recsize = gribGetSize(fileID);
      recpos  = fileGetPos(fileID);
      if ( recsize == 0 )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
843
	  streamptr->ntsteps = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
844
845
846
847
848
	  break;
	}
      if ( recsize > buffersize )
	{
	  buffersize = recsize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
849
	  gribbuffer = (unsigned char *) realloc(gribbuffer, (size_t)buffersize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
850
851
852
	}

      readsize = recsize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
853
854
      rstatus = gribRead(fileID, gribbuffer, &readsize);
      if ( rstatus ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
855

856
857
858
859
860
861
862
863
864
865
      if ( gribGetZip(recsize, gribbuffer, &unzipsize) > 0 )
	{
	  unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
	  if ( (long) buffersize < unzipsize )
	    {
	      buffersize = unzipsize;
	      gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
	    }
	}

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
869
      param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255);
870
871
      if ( ISEC1_LevelType == 100 ) ISEC1_Level1 *= 100;
      if ( ISEC1_LevelType ==  99 ) ISEC1_LevelType = 100;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
      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;
	    }
889
	  taxis->unit  = cgribexGetTimeUnit(isec1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
890
891
	  taxis->vdate = vdate;
	  taxis->vtime = vtime;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
892
893
894

	  datetime0.date = vdate;
	  datetime0.time = vtime;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
895
896
	}

897
898
      tsteptype = cgribexGetTsteptype(ISEC1_TimeRange);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
899
900
901
      if ( ISEC1_AvgNum )
	{
	  if (  taxis->numavg && warn_numavg &&
902
        	(taxis->numavg != ISEC1_AvgNum) )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
903
904
	    {
	  /*
905
	      Warning("Changing numavg from %d to %d not supported!",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
906
907
908
909
910
911
912
913
914
915
		      taxis->numavg, ISEC1_AvgNum);
	  */
	      warn_numavg = FALSE;
	    }
	  else
	    {
	      taxis->numavg = ISEC1_AvgNum;
	    }
	}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
916
917
      datetime.date  = vdate;
      datetime.time  = vtime;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
918
      compVar.param  = param;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
919
920
921
922
923
      compVar.level1 = level1;
      compVar.level2 = level2;
      compVar.ltype  = ISEC1_LevelType;
      for ( recID = 0; recID < nrecords; recID++ )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
924
	  compVar0.param  = streamptr->tsteps[tsID].records[recID].param;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
925
926
927
	  compVar0.level1 = streamptr->tsteps[tsID].records[recID].ilevel;
	  compVar0.level2 = streamptr->tsteps[tsID].records[recID].ilevel2;
	  compVar0.ltype  = streamptr->tsteps[tsID].records[recID].ltype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
928

Uwe Schulzweida's avatar
Uwe Schulzweida committed
929
	  if ( memcmp(&compVar0, &compVar, sizeof(compvar_t)) == 0 ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
930
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
931

Uwe Schulzweida's avatar
Uwe Schulzweida committed
932
933
      if ( recID == nrecords )
	{
934
935
	  char paramstr[32];
	  cdiParamToString(param, paramstr, sizeof(paramstr));
936
	  Warning("Param=%s level=%d not defined at timestep 1!", paramstr, level1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
937
938
939
	  return (CDI_EUFSTRUCT);
	}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
940
941
942
943
944
945
946
947
948
949
      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
950
	    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
951
952
953
954
955
	}
      else
	{
	  if ( streamptr->tsteps[tsID].records[recID].used )
	    {
956
957
958
	      char paramstr[32];
	      cdiParamToString(param, paramstr, sizeof(paramstr));

Uwe Schulzweida's avatar
Uwe Schulzweida committed
959
960
	      if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 ) break;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
961
	      Warning("Param=%s level=%d already exist, skipped!", paramstr, level1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
962
963
964
965
966
967
	      continue;
	    }
	  else
	    {
	      streamptr->tsteps[tsID].records[recID].used = TRUE;
	      streamptr->tsteps[tsID].recIDs[rindex] = recID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
968
	    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
969
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
970
971

      if ( CDI_Debug )
972
	Message("%4d %8d %4d %8d %8d %6d", rindex+1, (int)recpos, param, level1, vdate, vtime);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
973

Uwe Schulzweida's avatar
Uwe Schulzweida committed
974
      streamptr->tsteps[tsID].records[recID].size = recsize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
975

Uwe Schulzweida's avatar
Uwe Schulzweida committed
976
      compVar0.param  = streamptr->tsteps[tsID].records[recID].param;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
977
978
979
      compVar0.level1 = streamptr->tsteps[tsID].records[recID].ilevel;
      compVar0.level2 = streamptr->tsteps[tsID].records[recID].ilevel2;
      compVar0.ltype  = streamptr->tsteps[tsID].records[recID].ltype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
980

Uwe Schulzweida's avatar
Uwe Schulzweida committed
981
      if ( memcmp(&compVar0, &compVar, sizeof(compvar_t)) != 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
982
	{
983
	  Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
984
		  tsID, recID,
Uwe Schulzweida's avatar
Uwe Schulzweida committed
985
		  streamptr->tsteps[tsID].records[recID].param, param,
Uwe Schulzweida's avatar
Uwe Schulzweida committed
986
		  streamptr->tsteps[tsID].records[recID].ilevel, level1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
987
988
989
	  return (CDI_EUFSTRUCT);
	}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
990
991
      streamptr->tsteps[1].records[recID].position = recpos;
      varID = streamptr->tsteps[tsID].records[recID].varID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
992
993
994
      gridID = vlistInqVarGrid(vlistID, varID);
      if ( gridInqSize(gridID) == 1 && gridInqType(gridID) == GRID_LONLAT )
	{
995
996
	  if ( IS_NOT_EQUAL(gridInqXval(gridID, 0),ISEC2_FirstLon*0.001) ||
	       IS_NOT_EQUAL(gridInqYval(gridID, 0),ISEC2_FirstLat*0.001) )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
997
998
	    gridChangeType(gridID, GRID_TRAJECTORY);
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
999

1000
1001
1002
      if ( tsteptype != vlistInqVarTsteptype(vlistID, varID) )
	vlistDefVarTsteptype(vlistID, varID, tsteptype);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1003
      rindex++;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1004
1005
1006
1007
1008
    }

  nrecs = 0;
  for ( recID = 0; recID < nrecords; recID++ )
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1009
      if ( ! streamptr->tsteps[tsID].records[recID].used )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1010
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1011
	  varID = streamptr->tsteps[tsID].records[recID].varID;
1012
          vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1013
1014
1015
1016
1017
1018
	}
      else
	{
	  nrecs++;
	}
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1019
  streamptr->tsteps[tsID].nrecs = nrecs;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1020

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1021
  streamptr->rtsteps = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1022

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1023
  if ( streamptr->ntsteps == -1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1024
1025
    {
      tsID = tstepsNewEntry(streamID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1026
      if ( tsID != streamptr->rtsteps )
1027
	Error("Internal error. tsID = %d"