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

#include <stdio.h>
6
// #include <float.h>  /* FLT_EPSILON */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
7
8
9

#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"
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
	  lprint = FALSE;
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
108
      break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
109
110
111
112
113
    }

  return (timeunit);
}

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

  return (tsteptype);
}

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
157
  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;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
167
168
    }

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

190
191
                if ( ISEC2_LastLon < ISEC2_FirstLon && ISEC2_LastLon < 0 ) ISEC2_LastLon += 360000;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
192
		if ( ISEC2_ResFlag && ISEC2_LonIncr > 0 )
193
194
195
196
197
198
199
                  {
                    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
200

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

		/* 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
215
	      }
216
217
	    grid->xfirst = ISEC2_FirstLon * 0.001;
	    grid->xlast  = ISEC2_LastLon  * 0.001;
218
	    grid->xdef   = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
219
	  }
220
	grid->ydef  = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
221
222
	/* if ( ISEC2_FirstLat != 0 || ISEC2_LastLat != 0 ) */
	  {
223
	    if ( grid->ysize > 1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
224
	      {
225
                int recompinc = TRUE;
226

Uwe Schulzweida's avatar
Uwe Schulzweida committed
227
		if ( ISEC2_ResFlag && ISEC2_LatIncr > 0 )
228
229
230
231
232
233
234
                  {
                    if ( abs(ISEC2_LastLat - (ISEC2_FirstLat+ISEC2_LatIncr*(grid->ysize-1))) <= 2 )
                      {
                        recompinc = FALSE;
                        grid->yinc = ISEC2_LatIncr * 0.001;
                      }
                  }
235

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

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

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

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

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
319
320
321
322
	break;
      }
    case GRID_GME:
      {
323
324
325
326
327
	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
328
329
330
331
	break;
      }
    case GRID_GENERIC:
      {
332
333
334
	grid->size  = ISEC4_NumValues;
	grid->xsize = 0;
	grid->ysize = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
335
336
337
338
	break;
      }
    default:
      {
339
	Error("Unsupported grid type: %s", gridNamePtr(gridtype));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
340
341
342
343
	break;
      }
    }

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

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

static
359
void cgribexAddRecord(stream_t * streamptr, int param, int *isec1, int *isec2, double *fsec2, double *fsec3,
360
		      int *isec4, long recsize, off_t position, int datatype, int comptype, int lmv, int iret)
361
362
363
364
365
366
367
368
369
370
371
372
373
{
  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;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
374
  vlistID = streamptr->vlistID;
375
  tsID    = streamptr->curTsID;
376
  recID   = recordNewEntry(streamptr, tsID);
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
  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;

394
  cgribexGetGrid(streamptr, isec2, isec4, &grid, iret);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
395
396
397

  gridID = varDefGrid(vlistID, grid, 0);

398
  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
403
404
405
406
407
    {
      int vctsize = ISEC2_NumVCP;
      double *vctptr = &fsec2[10];

      varDefVCT(vctsize, vctptr);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
408
  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
	       datatype, &varID, &levelID, tsteptype, numavg, ISEC1_LevelType, NULL, NULL, NULL, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
415
416
417
418

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

419
  varDefCompType(varID, comptype);
420

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

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

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

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

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

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

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

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

  if ( CDI_Debug )
466
    Message("varID = %d  param = %d  zaxistype = %d  gridID = %d  levelID = %d",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
467
	    varID, param, zaxistype, gridID, levelID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
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
494
495
496
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,
497
			 int *isec3, double *fsec3, int *isec4, double *fsec4,
498
			 int *gribbuffer, int recsize, int *lmv, int *iret)
499
{
500
  int ipunp = 0, iword = 0;
501

502
503
  memset(isec1, 0, 256*sizeof(int));

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

  *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;
    }
}
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546

static
compvar_t cgribexVarSet(int param, int level1, int level2, int leveltype)
{
  compvar_t compVar;

  compVar.param  = param;
  compVar.level1 = level1;
  compVar.level2 = level2;
  compVar.ltype  = leveltype;

  return (compVar);
}

static
int cgribexVarCompare(compvar_t compVar, record_t record)
{
  int rstatus;
  compvar_t compVar0;

  compVar0.param  = record.param;
  compVar0.level1 = record.ilevel;
  compVar0.level2 = record.ilevel2;
  compVar0.ltype  = record.ltype;

  rstatus = memcmp(&compVar0, &compVar, sizeof(compvar_t));

  return (rstatus);
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
547
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
548

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

552
int cgribexScanTimestep1(stream_t * streamptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
553
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
554
#if  defined  (HAVE_LIBCGRIBEX)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
555
556
  int *isec0, *isec1, *isec2, *isec3, *isec4;
  double fsec2[512], fsec3[2], *fsec4 = NULL;
557
  int lmv = 0, iret = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
558
559
560
  off_t recpos = 0;
  unsigned char *gribbuffer = NULL;
  long buffersize = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
561
  int rstatus;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
562
  int fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
563
564
  int param = 0;
  int level1 = 0, level2 = 0, vdate = 0, vtime = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
565
566
567
568
569
  DateTime datetime, datetime0;
  int tsID;
  int varID;
  size_t readsize;
  int nrecords, nrecs, recID;
570
  int nrecs_scanned = 0;
571
  int datatype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
572
  long recsize = 0;
573
  int warn_time = TRUE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
574
575
576
  int warn_numavg = TRUE;
  int taxisID = -1;
  int rdate = 0, rtime = 0, tunit = 0, fcast = 0;
577
  taxis_t *taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
578
  int vlistID;
579
  int comptype;
580
  long unzipsize;
581
  compvar_t compVar;
582
  char paramstr[32];
583
584
  extern int cdiSkipRecords;
  int nskip = cdiSkipRecords;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
585
586

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
588
589
590
591
592
  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
593

594
  tsID  = tstepsNewEntry(streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
595
  taxis = &streamptr->tsteps[tsID].taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
596
597

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
600
  fileID = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
601

602
603
604
  while ( nskip-- > 0 )
    {
      recsize = gribGetSize(fileID);
605
      if ( recsize == 0 )
606
	Error("Skipping of %d records failed!", cdiSkipRecords);
607

608
609
610
611
      recpos  = fileGetPos(fileID);
      fileSetPos(fileID, recsize, SEEK_CUR);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
612
613
614
615
616
617
618
619
  nrecs = 0;
  while ( TRUE )
    {
      recsize = gribGetSize(fileID);
      recpos  = fileGetPos(fileID);

      if ( recsize == 0 )
	{
620
	  if ( nrecs == 0 )
621
	    Error("No GRIB records found!");
622

Uwe Schulzweida's avatar
Uwe Schulzweida committed
623
	  streamptr->ntsteps = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
624
625
626
627
628
629
630
631
632
	  break;
	}
      if ( recsize > buffersize )
	{
	  buffersize = recsize;
	  gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
	}

      readsize = recsize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
633
634
      rstatus = gribRead(fileID, gribbuffer, &readsize);
      if ( rstatus ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
635

636
      comptype = COMPRESS_NONE;
637
638
      if ( gribGetZip(recsize, gribbuffer, &unzipsize) > 0 )
	{
639
	  comptype = COMPRESS_SZIP;
640
641
642
643
644
645
646
647
	  unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
	  if ( (long) buffersize < unzipsize )
	    {
	      buffersize = unzipsize;
	      gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
	    }
	}

648
      nrecs_scanned++;
649
      cgribexDecodeHeader(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, fsec4,
650
			  (int *) gribbuffer, recsize, &lmv, &iret);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
651

Uwe Schulzweida's avatar
Uwe Schulzweida committed
652
      param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255);
653
654
      cdiParamToString(param, paramstr, sizeof(paramstr));

655
656
      if ( ISEC1_LevelType == 100 ) ISEC1_Level1 *= 100;
      if ( ISEC1_LevelType ==  99 ) ISEC1_LevelType = 100;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
657
658
659
      level1   = ISEC1_Level1;
      level2   = ISEC1_Level2;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
660
661
      gribDateTime(isec1, &vdate, &vtime);

662
      if ( ISEC4_NumBits > 0 && ISEC4_NumBits <= 32 )
663
	datatype = ISEC4_NumBits;
664
      else
665
        datatype = DATATYPE_PACK;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
666
667
668
669
670
671
672

      if ( nrecs == 0 )
	{
	  datetime0.date = vdate;
	  datetime0.time = vtime;
	  rdate = gribRefDate(isec1);
	  rtime = gribRefTime(isec1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
673
	  tunit = cgribexGetTimeUnit(isec1);
674
	  fcast = cgribexTimeIsFC(isec1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
675
676
677
678
679
	}
      else
	{
	  datetime.date  = vdate;
	  datetime.time  = vtime;
680
681
682

	  compVar = cgribexVarSet(param, level1, level2, ISEC1_LevelType);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
683
684
	  for ( recID = 0; recID < nrecs; recID++ )
	    {
685
	      if ( cgribexVarCompare(compVar, streamptr->tsteps[0].records[recID]) == 0 ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
686
	    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
687
688
689
690
691
692
693

	  if ( cdiInventoryMode == 1 )
	    {
	      if ( recID < nrecs ) break;
	      if ( warn_time )
		if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 )
		  {
694
                    gribWarning("Inconsistent verification time!", nrecs_scanned, tsID+1, paramstr, level1, level2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
695
696
697
698
699
700
701
702
703
		    warn_time = FALSE;
		  }
	    }
	  else
	    {
	      if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 ) break;

	      if ( recID < nrecs )
		{
704
		  gribWarning("Parameter already exist, skipped!", nrecs_scanned, tsID+1, paramstr, level1, level2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
705
706
707
		  continue;
		}
	    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
708
709
710
711
712
713
	}

      if ( ISEC1_AvgNum )
	{
	  if (  taxis->numavg && warn_numavg && (taxis->numavg != ISEC1_AvgNum) )
	    {
714
	      Warning("Changing numavg from %d to %d not supported!", taxis->numavg, ISEC1_AvgNum);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
715
716
717
718
719
720
721
722
723
724
725
	      warn_numavg = FALSE;
	    }
	  else
	    {
	      taxis->numavg = ISEC1_AvgNum;
	    }
	}

      nrecs++;

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

728
      cgribexAddRecord(streamptr, param, isec1, isec2, fsec2, fsec3,
729
		       isec4, recsize, recpos, datatype, comptype, lmv, iret);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
730
731
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
732
  streamptr->rtsteps = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
733

734
735
  if ( nrecs == 0 ) return (CDI_EUFSTRUCT);

736
  cdi_generate_vars(streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
737
738
739

  if ( fcast )
    {
740
      taxisID = taxisCreate(TAXIS_RELATIVE);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
741
742
743
744
745
746
747
      taxis->type  = TAXIS_RELATIVE;
      taxis->rdate = rdate;
      taxis->rtime = rtime;
      taxis->unit  = tunit;
    }
  else
    {
748
      taxisID = taxisCreate(TAXIS_ABSOLUTE);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
749
      taxis->type  = TAXIS_ABSOLUTE;
750
      taxis->unit  = tunit;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
751
752
753
754
755
    }

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
756
  vlistID = streamptr->vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
757
758
  vlistDefTaxis(vlistID, taxisID);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
759
760
  nrecords = streamptr->tsteps[0].nallrecs;
  if ( nrecords < streamptr->tsteps[0].recordSize )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
761
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
762
763
      streamptr->tsteps[0].recordSize = nrecords;
      streamptr->tsteps[0].records =
Uwe Schulzweida's avatar
Uwe Schulzweida committed
764
      (record_t *) realloc(streamptr->tsteps[0].records, nrecords*sizeof(record_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
765
766
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
767
768
  streamptr->tsteps[0].recIDs = (int *) malloc(nrecords*sizeof(int));
  streamptr->tsteps[0].nrecs = nrecords;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
769
  for ( recID = 0; recID < nrecords; recID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
770
    streamptr->tsteps[0].recIDs[recID] = recID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
771

Uwe Schulzweida's avatar
Uwe Schulzweida committed
772
773
  streamptr->record->buffer     = gribbuffer;
  streamptr->record->buffersize = buffersize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
774

Uwe Schulzweida's avatar
Uwe Schulzweida committed
775
  if ( streamptr->ntsteps == -1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
776
    {
777
      tsID = tstepsNewEntry(streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
778
      if ( tsID != streamptr->rtsteps )
779
	Error("Internal error. tsID = %d", tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
780

Uwe Schulzweida's avatar
Uwe Schulzweida committed
781
782
      streamptr->tsteps[tsID-1].next   = TRUE;
      streamptr->tsteps[tsID].position = recpos;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
783
784
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
785
  if ( streamptr->ntsteps == 1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
786
787
788
    {
      if ( taxis->vdate == 0 && taxis->vtime == 0 )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
789
790
	  streamptr->ntsteps = 0;
	  for ( varID = 0; varID < streamptr->nvars; varID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
791
	    {
792
	      vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
793
794
795
	    }
	}
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
796
797
798
#else
  Error("CGRIBEX support not compiled in!");
#endif
799
800

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
803

804
int cgribexScanTimestep2(stream_t * streamptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
805
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
806
807
  int rstatus = 0;
#if  defined  (HAVE_LIBCGRIBEX)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
808
809
  int *isec0, *isec1, *isec2, *isec3, *isec4;
  double fsec2[512], fsec3[2], *fsec4 = NULL;
810
  int lmv = 0, iret = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
811
812
813
814
  off_t recpos = 0;
  unsigned char *gribbuffer = NULL;
  long buffersize = 0;
  int fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
815
816
  int param = 0;
  int level1 = 0, level2 = 0, vdate = 0, vtime = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
817
  DateTime datetime, datetime0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
818
819
820
821
  int tsID;
  int varID, gridID;
  size_t readsize;
  int nrecords, nrecs, recID, rindex;
822
  int nrecs_scanned = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
823
824
  long recsize = 0;
  int warn_numavg = TRUE;
825
  int tsteptype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
826
  int taxisID = -1;
827
  taxis_t *taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
828
  int vlistID;
829
  long unzipsize;
830
  compvar_t compVar;
831
  char paramstr[32];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
832

Uwe Schulzweida's avatar
Uwe Schulzweida committed
833
834
835
836
837
838
839
  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
840

Uwe Schulzweida's avatar
Uwe Schulzweida committed
841
842
  fileID  = streamptr->fileID;
  vlistID = streamptr->vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
843
844
  taxisID = vlistInqTaxis(vlistID);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
845
846
  gribbuffer = (unsigned char *) streamptr->record->buffer;
  buffersize = streamptr->record->buffersize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
847

Uwe Schulzweida's avatar
Uwe Schulzweida committed
848
  tsID = streamptr->rtsteps;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
849
  if ( tsID != 1 )
850
    Error("Internal problem! unexpeceted timestep %d", tsID+1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
851

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

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

856
  cdi_create_records(streamptr, tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
857

Uwe Schulzweida's avatar
Uwe Schulzweida committed
858
  nrecords = streamptr->tsteps[tsID].nallrecs;
859
  if ( nrecords ) streamptr->tsteps[1].recIDs = (int *) malloc(nrecords*sizeof(int));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
860
  streamptr->tsteps[1].nrecs = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
861
  for ( recID = 0; recID < nrecords; recID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
862
    streamptr->tsteps[1].recIDs[recID] = -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
863

Uwe Schulzweida's avatar
Uwe Schulzweida committed
864
865
  for ( recID = 0; recID < nrecords; recID++ )
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
866
      varID = streamptr->tsteps[0].records[recID].varID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
867
868
      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
869
870
    }

871
  nrecs_scanned = nrecords;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
872
873
  rindex = 0;
  while ( TRUE )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
874
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
875
876
      if ( rindex > nrecords ) break;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
877
878
879
880
      recsize = gribGetSize(fileID);
      recpos  = fileGetPos(fileID);
      if ( recsize == 0 )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
881
	  streamptr->ntsteps = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
882
883
884
885
886
	  break;
	}
      if ( recsize > buffersize )
	{
	  buffersize = recsize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
887
	  gribbuffer = (unsigned char *) realloc(gribbuffer, (size_t)buffersize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
888
889
890
	}

      readsize = recsize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
891
892
      rstatus = gribRead(fileID, gribbuffer, &readsize);
      if ( rstatus ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
893

894
895
896
897
898
899
900
901
902
903
      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);
	    }
	}

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
907
      param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255);
908
909
      cdiParamToString(param, paramstr, sizeof(paramstr));

910
911
      if ( ISEC1_LevelType == 100 ) ISEC1_Level1 *= 100;
      if ( ISEC1_LevelType ==  99 ) ISEC1_LevelType = 100;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
      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;
	    }
929
	  taxis->unit  = cgribexGetTimeUnit(isec1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
930
931
	  taxis->vdate = vdate;
	  taxis->vtime = vtime;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
932
933
934

	  datetime0.date = vdate;
	  datetime0.time = vtime;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
935
936
	}

937
938
      tsteptype = cgribexGetTsteptype(ISEC1_TimeRange);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
939
940
941
      if ( ISEC1_AvgNum )
	{
	  if (  taxis->numavg && warn_numavg &&
942
        	(taxis->numavg != ISEC1_AvgNum) )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
943
944
	    {
	  /*
945
	      Warning("Changing numavg from %d to %d not supported!", taxis->numavg, ISEC1_AvgNum);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
946
947
948
949
950
951
952
953
954
	  */
	      warn_numavg = FALSE;
	    }
	  else
	    {
	      taxis->numavg = ISEC1_AvgNum;
	    }
	}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
955
956
      datetime.date  = vdate;
      datetime.time  = vtime;
957
958
959

      compVar = cgribexVarSet(param, level1, level2, ISEC1_LevelType);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
960
961
      for ( recID = 0; recID < nrecords; recID++ )
	{
962
	  if ( cgribexVarCompare(compVar, streamptr->tsteps[tsID].records[recID]) == 0 ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
963
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
964

Uwe Schulzweida's avatar
Uwe Schulzweida committed
965
966
      if ( recID == nrecords )
	{
967
	  gribWarning("Parameter not defined at timestep 1!", nrecs_scanned, tsID+1, paramstr, level1, level2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
968
969
970
	  return (CDI_EUFSTRUCT);
	}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
971
972
973
974
975
976
977
978
979
980
      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
981
	    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
982
983
984
985
986
987
988
	}
      else
	{
	  if ( streamptr->tsteps[tsID].records[recID].used )
	    {
	      if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 ) break;

989
              gribWarning("Parameter already exist, skipped!", nrecs_scanned, tsID+1, paramstr, level1, level2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
990
991
992
993
994
995
	      continue;
	    }
	  else
	    {
	      streamptr->tsteps[tsID].records[recID].used = TRUE;
	      streamptr->tsteps[tsID].recIDs[rindex] = recID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
996
	    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
997
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
998
999

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

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

1004
      if ( cgribexVarCompare(compVar, streamptr->tsteps[tsID].records[recID]) != 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1005
	{
1006
	  Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1007
		  tsID, recID,
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1008
		  streamptr->tsteps[tsID].records[recID].param, param,
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1009
		  streamptr->tsteps[tsID].records[recID].ilevel, level1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1010
1011
1012
	  return (CDI_EUFSTRUCT);
	}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1013
1014
      streamptr->tsteps[1].records[recID].position = recpos;
      varID = streamptr->tsteps[tsID].records[recID].varID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1015
1016
1017
      gridID = vlistInqVarGrid(vlistID, varID);
      if ( gridInqSize(gridID) == 1 && gridInqType(gridID) == GRID_LONLAT )
	{
1018
1019
	  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
1020
1021
	    gridChangeType(gridID, GRID_TRAJECTORY);
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1022

1023
1024
1025
      if ( tsteptype != vlistInqVarTsteptype(vlistID, varID) )
	vlistDefVarTsteptype(vlistID, varID, tsteptype);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1026
      rindex++;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1027
1028
1029
1030
1031
    }

  nrecs = 0;
  for ( recID = 0; recID < nrecords; recID++ )
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1032
      if ( ! streamptr->tsteps[tsID].records[recID].used )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1033
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1034
	  varID = streamptr->tsteps[tsID].records[recID].varID;
1035
          vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1036
1037
1038
1039
1040
1041
	}
      else
	{
	  nrecs++;
	}
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1042
  streamptr->tsteps[tsID].nrecs = nrecs;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1043

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1044
  streamptr->rtsteps = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1045

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1046
  if ( streamptr->ntsteps == -1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1047
    {