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

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

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

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

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


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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
52
  return gridtype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
53
54
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
55
static
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
  return isRotated;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
66
67
}

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
      {
	lbounds = 1;
	break;
      }
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
84
  return lbounds;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
85
86
}

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
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
112
  return timeunit;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
113
114
}

115
116
117
118
119
120
121
122
static
int cgribexTimeIsFC(int *isec1)
{
  int isFC = TRUE;

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
123
  return isFC;
124
125
126
127
128
}

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
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
150
  return tsteptype;
151
152
}

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:
      {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
248
249
250
251
252
253
254
255
        grid->np      = ISEC2_NumPar;
	grid->size    = ISEC4_NumValues;
        grid->rowlon  = ISEC2_RowLonPtr;
	grid->nrowlon = ISEC2_NumLat;
	grid->ysize   = ISEC2_NumLat;
	grid->xinc    = 0;
	grid->yinc    = 0;
	grid->xdef    = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
256
257
	/* if ( ISEC2_FirstLon != 0 || ISEC2_LastLon != 0 ) */
	  {
258
	    if ( grid->xsize > 1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
259
	      {
260
261
                if ( ISEC2_LastLon < ISEC2_FirstLon && ISEC2_LastLon < 0 ) ISEC2_LastLon += 360000;

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

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

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

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

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

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

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

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

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

367
368
369
  int vlistID = streamptr->vlistID;
  int tsID    = streamptr->curTsID;
  int recID   = recordNewEntry(streamptr, tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
370
  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
  record->size      = (size_t)recsize;
  record->position  = position;
  record->param     = param;
  record->ilevel    = level1;
  record->ilevel2   = level2;
  record->ltype     = ISEC1_LevelType;
Thomas Jahns's avatar
Thomas Jahns committed
386
  record->tsteptype = (short)tsteptype;
387

Uwe Schulzweida's avatar
Uwe Schulzweida committed
388
389
  grid_t *gridptr = (grid_t*) Malloc(sizeof(*gridptr));
  cgribexGetGrid(streamptr, isec2, fsec2, isec4, gridptr, iret);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
390

Uwe Schulzweida's avatar
Uwe Schulzweida committed
391
  struct addIffNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, gridptr, 0);
392
  int gridID = gridAdded.Id;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
393
394
395
396
397
398
399
400
401
402
403
404
  if ( gridAdded.isNew )
    {
      if ( gridptr->nrowlon )
        {
          size_t nrowlon = (size_t) gridptr->nrowlon;
          int *rowlon = gridptr->rowlon;
          gridptr->rowlon = (int*) Malloc(nrowlon * sizeof(int));
          memcpy(gridptr->rowlon, rowlon, nrowlon * sizeof(int));
        }
    }
  else
    Free(gridptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
405

406
  int zaxistype = grib1ltypeToZaxisType(ISEC1_LevelType);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
407

408
  if ( zaxistype == ZAXIS_HYBRID || zaxistype == ZAXIS_HYBRID_HALF )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
409
    {
410
      size_t vctsize = (size_t)ISEC2_NumVCP;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
411
412
413
414
415
      double *vctptr = &fsec2[10];

      varDefVCT(vctsize, vctptr);
    }

416
  int lbounds = cgribexGetZaxisHasBounds(ISEC1_LevelType);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
417

418
419
  if ( datatype > 32 ) datatype = DATATYPE_PACK32;
  if ( datatype <  0 ) datatype = DATATYPE_PACK;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
420

421
  varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2, 0, 0,
422
423
	       datatype, &varID, &levelID, tsteptype, numavg, ISEC1_LevelType, -1,
               NULL, NULL, NULL, NULL, NULL, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
424

Thomas Jahns's avatar
Thomas Jahns committed
425
426
  record->varID   = (short)varID;
  record->levelID = (short)levelID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
427

428
  varDefCompType(varID, comptype);
429

430
431
432
433
434
435
436
  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]);
    }
437

438
439
  if ( lmv ) varDefMissval(varID, FSEC3_MissVal);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
440
  if ( varInqInst(varID) == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
441
442
443
444
445
    {
      int center, subcenter, instID;
      center    = ISEC1_CenterID;
      subcenter = ISEC1_SubCenterID;
      instID    = institutInq(center, subcenter, NULL, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
446
      if ( instID == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
447
448
449
450
	instID = institutDef(center, subcenter, NULL, NULL);
      varDefInst(varID, instID);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
451
  if ( varInqModel(varID) == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
452
453
454
    {
      int modelID;
      modelID = modelInq(varInqInst(varID), ISEC1_ModelID, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
455
      if ( modelID == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
456
457
458
459
	modelID = modelDef(varInqInst(varID), ISEC1_ModelID, NULL);
      varDefModel(varID, modelID);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
460
  if ( varInqTable(varID) == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
461
462
    {
      int tableID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
463

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
466
      if ( tableID == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
467
468
469
470
	tableID = tableDef(varInqModel(varID), ISEC1_CodeTable, NULL);
      varDefTable(varID, tableID);
    }

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

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

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

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

  *lmv = 0;

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

      MCH_get_undef(isec1, &undef_pds, &undef_eps);
      FSEC3_MissVal = undef_pds;
      *lmv = 1;
    }
}
523
524

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

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

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

Thomas Jahns's avatar
Thomas Jahns committed
539
540
static inline int
cgribexVarCompare(compvar_t compVar, record_t record, int flag)
541
{
Thomas Jahns's avatar
Thomas Jahns committed
542
543
544
545
  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
546
547
548
549
550
551
    & (compVar.tsteptype != record.tsteptype);
  int rstatus = (compVar.param != record.param)
    |           (compVar.level1 != record.ilevel)
    |           (compVar.level2 != record.ilevel2)
    |           (compVar.ltype != record.ltype)
    |           tstepDiff;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
552
  return rstatus;
553
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
554
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
555

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

559
#if  defined  (HAVE_LIBCGRIBEX)
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592

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


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

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

621
622
623
624
625
  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
626

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

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

633
  int fileID = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
634

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

641
      recpos  = fileGetPos(fileID);
642
      fileSetPos(fileID, (off_t)recsize, SEEK_CUR);
643
644
    }

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

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

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

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

669
      comptype = COMPRESS_NONE;
670
      if ( gribGetZip(recsize, (unsigned char *)gribbuffer, &unzipsize) > 0 )
671
	{
672
	  comptype = COMPRESS_SZIP;
673
	  unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
674
	  if ( buffersize < (size_t)unzipsize )
675
	    {
676
	      buffersize = (size_t)unzipsize;
677
	      gribbuffer = Realloc(gribbuffer, buffersize);
678
679
680
	    }
	}

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

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

688
689
      if ( ISEC1_LevelType == 100 ) ISEC1_Level1 *= 100;
      if ( ISEC1_LevelType ==  99 ) ISEC1_LevelType = 100;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
690
691
692
      level1   = ISEC1_Level1;
      level2   = ISEC1_Level2;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
693
694
      gribDateTime(isec1, &vdate, &vtime);

695
      if ( ISEC4_NumBits > 0 && ISEC4_NumBits <= 32 )
696
	datatype = ISEC4_NumBits;
697
      else
698
        datatype = DATATYPE_PACK;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
699
700
701
702
703
704
705

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

	  if ( cdiInventoryMode == 1 )
	    {
	      if ( recID < nrecs ) break;
	      if ( warn_time )
723
		if ( datetimeCmp(datetime, datetime0) != 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
724
		  {
725
                    gribWarning("Inconsistent verification time!", nrecs_scanned, tsID+1, paramstr, level1, level2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
726
727
728
729
730
		    warn_time = FALSE;
		  }
	    }
	  else
	    {
731
	      if ( datetimeCmp(datetime, datetime0) != 0 ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
732
733
734

	      if ( recID < nrecs )
		{
735
		  gribWarning("Parameter already exist, skipped!", nrecs_scanned, tsID+1, paramstr, level1, level2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
736
737
738
		  continue;
		}
	    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
739
740
741
742
743
744
	}

      if ( ISEC1_AvgNum )
	{
	  if (  taxis->numavg && warn_numavg && (taxis->numavg != ISEC1_AvgNum) )
	    {
745
	      Warning("Changing numavg from %d to %d not supported!", taxis->numavg, ISEC1_AvgNum);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
746
747
748
749
750
751
752
753
754
755
756
	      warn_numavg = FALSE;
	    }
	  else
	    {
	      taxis->numavg = ISEC1_AvgNum;
	    }
	}

      nrecs++;

      if ( CDI_Debug )
757
	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
758

759
      cgribexAddRecord(streamptr, param, isec1, isec2, fsec2, fsec3,
760
		       isec4, recsize, recpos, datatype, comptype, lmv, iret);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
761
762
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
763
  streamptr->rtsteps = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
764

Uwe Schulzweida's avatar
Uwe Schulzweida committed
765
  if ( nrecs == 0 ) return CDI_EUFSTRUCT;
766

767
  cdi_generate_vars(streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
768
769
770

  if ( fcast )
    {
771
      taxisID = taxisCreate(TAXIS_RELATIVE);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
772
773
774
775
776
777
778
      taxis->type  = TAXIS_RELATIVE;
      taxis->rdate = rdate;
      taxis->rtime = rtime;
      taxis->unit  = tunit;
    }
  else
    {
779
      taxisID = taxisCreate(TAXIS_ABSOLUTE);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
780
      taxis->type  = TAXIS_ABSOLUTE;
781
      taxis->unit  = tunit;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
782
783
    }

784
785
  taxis->vdate = (int)datetime0.date;
  taxis->vtime = (int)datetime0.time;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
786

Uwe Schulzweida's avatar
Uwe Schulzweida committed
787
  vlistID = streamptr->vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
788
789
  vlistDefTaxis(vlistID, taxisID);

790
791
  nrecords = (unsigned)streamptr->tsteps[0].nallrecs;
  if ( nrecords < (unsigned)streamptr->tsteps[0].recordSize )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
792
    {
793
      streamptr->tsteps[0].recordSize = (int)nrecords;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
794
      streamptr->tsteps[0].records =
795
      (record_t *) Realloc(streamptr->tsteps[0].records, nrecords*sizeof(record_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
796
797
    }

798
  streamptr->tsteps[0].recIDs = (int *) Malloc(nrecords*sizeof(int));
799
  streamptr->tsteps[0].nrecs = (int)nrecords;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
800
  for ( recID = 0; recID < nrecords; recID++ )
801
    streamptr->tsteps[0].recIDs[recID] = (int)recID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
802

Uwe Schulzweida's avatar
Uwe Schulzweida committed
803
  streamptr->record->buffer     = gribbuffer;
804
  streamptr->record->buffersize = (size_t)buffersize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
805

806
807
  cgribexScanTsFixNtsteps(streamptr, recpos);
  cgribexScanTsConstAdjust(streamptr, taxis);
808

Uwe Schulzweida's avatar
Uwe Schulzweida committed
809
  return 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
810
811
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
812

813
int cgribexScanTimestep2(stream_t * streamptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
814
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
815
  int rstatus = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
816
  double fsec2[512], fsec3[2], *fsec4 = NULL;
817
  int lmv = 0, iret = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
818
  off_t recpos = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
819
820
  int param = 0;
  int level1 = 0, level2 = 0, vdate = 0, vtime = 0;
821
  DateTime datetime, datetime0 = { LONG_MIN, LONG_MIN };
Uwe Schulzweida's avatar
Uwe Schulzweida committed
822
823
  int varID, gridID;
  size_t readsize;
824
  int nrecs, recID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
825
826
  long recsize = 0;
  int warn_numavg = TRUE;
827
  int tsteptype;
828
  long unzipsize;
829
  char paramstr[32];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
830

Uwe Schulzweida's avatar
Uwe Schulzweida committed
831
832
  streamptr->curTsID = 1;

833
834
835
836
837
  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
838

839
840
841
  int fileID  = streamptr->fileID;
  int vlistID = streamptr->vlistID;
  int taxisID = vlistInqTaxis(vlistID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
842

843
844
  void *gribbuffer = streamptr->record->buffer;
  size_t buffersize = streamptr->record->buffersize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
845

846
  int tsID = streamptr->rtsteps;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
847
  if ( tsID != 1 )
Thomas Jahns's avatar
Thomas Jahns committed
848
    Error("Internal problem! unexpected timestep %d", tsID+1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
849

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

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

854
  cdi_create_records(streamptr, tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
855

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

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

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

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

888
      readsize = (size_t)recsize;
889
      rstatus = gribRead(fileID, (unsigned char *)gribbuffer, &readsize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
890
      if ( rstatus ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
891

892
      if ( gribGetZip(recsize, (unsigned char *)gribbuffer, &unzipsize) > 0 )
893
894
	{
	  unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
895
	  if ( buffersize < (size_t)unzipsize )
896
	    {
897
	      buffersize = (size_t)unzipsize;
898
	      gribbuffer = Realloc(gribbuffer, buffersize);
899
900
901
	    }
	}

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

905
906
      nrecs_scanned++;

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
      compvar_t compVar = cgribexVarSet(param, level1, level2, ISEC1_LevelType, ISEC1_TimeRange);
959

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) == 0 ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed