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

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

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

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

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


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

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
55
static
56
bool cgribexGetIsRotated(int *isec2)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
57
{
58
  return (ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
59
60
}

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
77
  return lbounds;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
78
79
}

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
105
  return timeunit;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
106
107
}

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
113
  return isFC;
114
115
116
117
118
}

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
140
  return tsteptype;
141
142
}

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

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

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

182
183
                if ( ISEC2_LastLon < ISEC2_FirstLon && ISEC2_LastLon < 0 ) ISEC2_LastLon += 360000;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
184
		if ( ISEC2_ResFlag && ISEC2_LonIncr > 0 )
185
                  {
186
                    if ( abs(ISEC2_LastLon - (ISEC2_FirstLon+ISEC2_LonIncr*(grid->x.size-1))) <= 2 )
187
                      {
188
                        recompinc = false;
189
                        grid->x.inc = ISEC2_LonIncr * 0.001;
190
191
                      }
                  }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
192

193
		/* recompute xinc if necessary */
194
                if ( recompinc ) grid->x.inc = (ISEC2_LastLon - ISEC2_FirstLon) * 0.001 / (grid->x.size-1);
195
196
197
198

		/* correct xinc if necessary */
		if ( ISEC2_FirstLon == 0 && ISEC2_LastLon > 354000 && ISEC2_LastLon < 360000 )
		  {
199
		    double xinc = 360. / grid->x.size;
200

201
		    if ( fabs(grid->x.inc-xinc) > 0.0 )
202
		      {
203
204
			grid->x.inc = xinc;
			if ( CDI_Debug ) Message("set xinc to %g", grid->x.inc);
205
206
		      }
		  }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
207
	      }
208
209
210
	    grid->x.first = ISEC2_FirstLon * 0.001;
	    grid->x.last  = ISEC2_LastLon  * 0.001;
	    grid->x.flag  = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
211
	  }
212
	grid->y.flag = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
213
214
	/* if ( ISEC2_FirstLat != 0 || ISEC2_LastLat != 0 ) */
	  {
215
	    if ( grid->y.size > 1 && compyinc )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
216
	      {
217
                bool recompinc = true;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
218
		if ( ISEC2_ResFlag && ISEC2_LatIncr > 0 )
219
                  {
220
                    if ( abs(ISEC2_LastLat - (ISEC2_FirstLat+ISEC2_LatIncr*(grid->y.size-1))) <= 2 )
221
                      {
222
                        recompinc = false;
223
                        grid->y.inc = ISEC2_LatIncr * 0.001;
224
225
                      }
                  }
226

227
		/* recompute yinc if necessary */
228
                if ( recompinc ) grid->y.inc = (ISEC2_LastLat - ISEC2_FirstLat) * 0.001 / (grid->y.size - 1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
229
	      }
230
231
232
	    grid->y.first = ISEC2_FirstLat * 0.001;
	    grid->y.last  = ISEC2_LastLat  * 0.001;
	    grid->y.flag  = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
233
234
235
236
237
	  }
	break;
      }
    case GRID_GAUSSIAN_REDUCED:
      {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
238
239
240
241
        grid->np      = ISEC2_NumPar;
	grid->size    = ISEC4_NumValues;
        grid->rowlon  = ISEC2_RowLonPtr;
	grid->nrowlon = ISEC2_NumLat;
242
	grid->y.size   = ISEC2_NumLat;
243
244
245
	grid->x.inc    = 0;
	grid->y.inc    = 0;
	grid->x.flag   = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
246
247
	/* if ( ISEC2_FirstLon != 0 || ISEC2_LastLon != 0 ) */
	  {
248
	    if ( grid->x.size > 1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
249
	      {
250
251
                if ( ISEC2_LastLon < ISEC2_FirstLon && ISEC2_LastLon < 0 ) ISEC2_LastLon += 360000;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
252
		if ( ISEC2_ResFlag && ISEC2_LonIncr > 0 )
253
		  grid->x.inc = ISEC2_LonIncr * 0.001;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
254
		else
255
		  grid->x.inc = (ISEC2_LastLon - ISEC2_FirstLon) * 0.001 / (grid->x.size - 1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
256
	      }
257
258
259
	    grid->x.first = ISEC2_FirstLon * 0.001;
	    grid->x.last  = ISEC2_LastLon  * 0.001;
	    grid->x.flag  = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
260
	  }
261
	grid->y.flag = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
262
263
	/* if ( ISEC2_FirstLat != 0 || ISEC2_LastLat != 0 ) */
	  {
264
	    if ( grid->y.size > 1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
265
266
	      {
		if ( ISEC2_ResFlag && ISEC2_LatIncr > 0 )
267
		  grid->y.inc = ISEC2_LatIncr * 0.001;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
268
		else
269
		  grid->y.inc = (ISEC2_LastLat - ISEC2_FirstLat) * 0.001 / (grid->y.size - 1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
270
	      }
271
272
273
	    grid->y.first = ISEC2_FirstLat * 0.001;
	    grid->y.last  = ISEC2_LastLat  * 0.001;
	    grid->y.flag  = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
274
275
276
	  }
	break;
      }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
277
    case GRID_LCC:
278
279
      {
	if ( ISEC4_NumValues != ISEC2_NumLon*ISEC2_NumLat )
280
	  Error("numberOfPoints (%d) and gridSize (%d) differ!",
281
		ISEC4_NumValues, ISEC2_NumLon*ISEC2_NumLat);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
282

283
	grid->size  = ISEC4_NumValues;
284
285
	grid->x.size = ISEC2_NumLon;
	grid->y.size = ISEC2_NumLat;
286

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

297
298
	grid->x.flag = 0;
	grid->y.flag = 0;
299
300
301

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

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

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

345
346
347
348
  grid->type  = gridtype;
}

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

355
356
357
  int vlistID = streamptr->vlistID;
  int tsID    = streamptr->curTsID;
  int recID   = recordNewEntry(streamptr, tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
358
  record_t *record = &streamptr->tsteps[tsID].records[recID];
359

360
361
  int tsteptype = cgribexGetTsteptype(ISEC1_TimeRange);
  int numavg    = ISEC1_AvgNum;
362

363
364
  int level1  = ISEC1_Level1;
  int level2  = ISEC1_Level2;
365
366
367

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

368
369
370
371
372
373
  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
374
  record->tsteptype = (short)tsteptype;
375

Uwe Schulzweida's avatar
Uwe Schulzweida committed
376
377
  grid_t *gridptr = (grid_t*) Malloc(sizeof(*gridptr));
  cgribexGetGrid(streamptr, isec2, fsec2, isec4, gridptr, iret);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
378

Uwe Schulzweida's avatar
Uwe Schulzweida committed
379
  struct addIfNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, gridptr, 0);
380
  int gridID = gridAdded.Id;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
381
382
383
384
385
386
387
388
389
390
391
392
  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
393

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

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

      varDefVCT(vctsize, vctptr);
    }

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

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

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

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

416
  varDefCompType(varID, comptype);
417

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

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

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

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

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

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

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

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

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

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

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

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

  *lmv = 0;

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

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

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
524
  return compVar;
525
526
}

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

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

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

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

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

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


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

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

610
611
612
613
614
  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
615

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

      nrecs++;

      if ( CDI_Debug )
746
	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
747

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
754
  if ( nrecs == 0 ) return CDI_EUFSTRUCT;
755

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

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

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

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

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

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

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

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
801

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

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

822
823
824
825
826
  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
827

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

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

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

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

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

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

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

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

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

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

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

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

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

894
895
      nrecs_scanned++;

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

899
900
      if ( ISEC1_LevelType == 100 ) ISEC1_Level1 *= 100;
      if ( ISEC1_LevelType ==  99 ) ISEC1_LevelType = 100;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
901
902
903
904
905
906
907
908
909
910
911