stream_cgribex.c 58.4 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;
28
  int tsteptype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
29
} compvar_t;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
30
31


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

  switch (ISEC2_GridType)
    {
40
    case  GRIB1_GTYPE_LATLON:     { if ( ISEC2_Reduced )      break; }
41
42
43
44
45
46
47
48
49
50
    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
51
52
53
54
55
    }

  return (gridtype);
}

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

61
  if ( ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
62
63
64
    {
      isRotated = 1;
    }
65
 
Uwe Schulzweida's avatar
Uwe Schulzweida committed
66
67
68
  return (isRotated);
}

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

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

  return (lbounds);
}

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

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

  return (timeunit);
}

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

  return (tsteptype);
}

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
159
  gridtype = cgribexGetGridType(isec2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
160

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

171
  memset(grid, 0, sizeof(grid_t));
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 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
226
	      {
227
                int recompinc = TRUE;
228

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

238
		/* recompute yinc if necessary */
239
                if ( recompinc ) grid->yinc = (ISEC2_LastLat - ISEC2_FirstLat) * 0.001 / (grid->ysize - 1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
240
	      }
241
242
	    grid->yfirst = ISEC2_FirstLat * 0.001;
	    grid->ylast  = ISEC2_LastLat  * 0.001;
243
	    grid->ydef   = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
244
245
246
247
248
	  }
	break;
      }
    case GRID_GAUSSIAN_REDUCED:
      {
249
        grid->np     = ISEC2_NumPar;
250
251
252
	grid->size   = ISEC4_NumValues;
        grid->rowlon = ISEC2_RowLonPtr;
	grid->ysize  = ISEC2_NumLat;
253
254
255
	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     = 0;
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
365
366
367
368
369
370
371
372
373
374
375
{
  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
376
  vlistID = streamptr->vlistID;
377
  tsID    = streamptr->curTsID;
378
  recID   = recordNewEntry(streamptr, tsID);
379
380
381
382
383
384
385
386
387
388
  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); */

389
390
391
392
393
394
395
  (*record).size      = recsize;
  (*record).position  = position;
  (*record).param     = param;
  (*record).ilevel    = level1;
  (*record).ilevel2   = level2;
  (*record).ltype     = ISEC1_LevelType;
  (*record).tsteptype = tsteptype;
396

397
  cgribexGetGrid(streamptr, isec2, isec4, &grid, iret);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
398
399
400

  gridID = varDefGrid(vlistID, grid, 0);

401
  zaxistype = grib1ltypeToZaxisType(ISEC1_LevelType);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
402

403
  if ( zaxistype == ZAXIS_HYBRID || zaxistype == ZAXIS_HYBRID_HALF )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
404
405
406
407
408
409
410
    {
      int vctsize = ISEC2_NumVCP;
      double *vctptr = &fsec2[10];

      varDefVCT(vctsize, vctptr);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
411
  lbounds = cgribexGetZaxisHasBounds(ISEC1_LevelType);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
412

413
414
  if ( datatype > 32 ) datatype = DATATYPE_PACK32;
  if ( datatype <  0 ) datatype = DATATYPE_PACK;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
415

416
  varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2, 0, 0,
417
	       datatype, &varID, &levelID, tsteptype, numavg, ISEC1_LevelType, NULL, NULL, NULL, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
418
419
420
421

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

422
  varDefCompType(varID, comptype);
423

424
425
426
427
428
429
430
  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]);
    }
431

432
433
  if ( lmv ) varDefMissval(varID, FSEC3_MissVal);

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
454
  if ( varInqTable(varID) == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
455
456
    {
      int tableID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
457

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
460
      if ( tableID == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
461
462
463
464
	tableID = tableDef(varInqModel(varID), ISEC1_CodeTable, NULL);
      varDefTable(varID, tableID);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
465
466
  streamptr->tsteps[tsID].nallrecs++;
  streamptr->nrecs++;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
467
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
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,
496
			 int *isec3, double *fsec3, int *isec4, double *fsec4,
497
			 int *gribbuffer, int recsize, int *lmv, int *iret)
498
{
499
  int ipunp = 0, iword = 0;
500

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

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

  *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;
    }
}
517
518

static
519
compvar_t cgribexVarSet(int param, int level1, int level2, int leveltype, int trange)
520
521
{
  compvar_t compVar;
522
  int tsteptype = cgribexGetTsteptype(trange);
523

524
525
526
527
528
  compVar.param     = param;
  compVar.level1    = level1;
  compVar.level2    = level2;
  compVar.ltype     = leveltype;
  compVar.tsteptype = tsteptype;
529
530
531
532
533
534
535
536
537

  return (compVar);
}

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

538
539
540
541
  compVar0.param     = record.param;
  compVar0.level1    = record.ilevel;
  compVar0.level2    = record.ilevel2;
  compVar0.ltype     = record.ltype;
542
  compVar0.tsteptype = record.tsteptype;
543

544
  int rstatus = memcmp(&compVar0, &compVar, sizeof(compvar_t));
545
546
547

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

682
	  compVar = cgribexVarSet(param, level1, level2, ISEC1_LevelType, ISEC1_TimeRange);
683

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

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

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

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

      nrecs++;

      if ( CDI_Debug )
727
	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
728

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
804

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

908
909
      nrecs_scanned++;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
910
      param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255);
911
912
      cdiParamToString(param, paramstr, sizeof(paramstr));

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

	  datetime0.date = vdate;
	  datetime0.time = vtime;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
938
939
	}

940
941
      tsteptype = cgribexGetTsteptype(ISEC1_TimeRange);

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

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

961
      compVar = cgribexVarSet(param, level1, level2, ISEC1_LevelType, ISEC1_TimeRange);
962

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

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

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

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

      if ( CDI_Debug )
1003
	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
1004

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

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

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

1026
1027
1028
      if ( tsteptype != vlistInqVarTsteptype(vlistID, varID) )
	vlistDefVarTsteptype(vlistID, varID, tsteptype);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1029
      rindex++;