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

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

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

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

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

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


Uwe Schulzweida's avatar
Uwe Schulzweida committed
31
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
32
int cgribexGetGridType(int *isec2)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
33
34
35
36
37
{
  int gridtype = 0;

  switch (ISEC2_GridType)
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
38
39
    case  GTYPE_LATLON:
    case  GTYPE_LATLON_ROT:
Uwe Schulzweida's avatar
Uwe Schulzweida committed
40
41
42
43
      {
	gridtype = GRID_LONLAT;
	break;
      }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
44
    case  GTYPE_LCC:
45
      {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
46
	gridtype = GRID_LCC;
47
48
	break;
      }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
49
    case  GTYPE_GAUSSIAN:
Uwe Schulzweida's avatar
Uwe Schulzweida committed
50
51
52
53
54
55
56
      {
	if ( ISEC2_Reduced )
	  gridtype = GRID_GAUSSIAN_REDUCED;
	else
	  gridtype = GRID_GAUSSIAN;
	break;
      }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
57
    case  GTYPE_SPECTRAL:
Uwe Schulzweida's avatar
Uwe Schulzweida committed
58
59
60
61
      {
	gridtype = GRID_SPECTRAL;
	break;
      }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
62
    case  GTYPE_GME:
Uwe Schulzweida's avatar
Uwe Schulzweida committed
63
64
65
66
67
68
69
70
71
72
73
74
75
76
      {
	gridtype = GRID_GME;
	break;
      }
    default:
      {
	gridtype = GRID_GENERIC;
	break;
      }
    }

  return (gridtype);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
77
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
78
int cgribexGetIsRotated(int *isec2)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
79
80
81
82
83
84
85
86
87
88
89
{
  int isRotated = 0;

  if ( ISEC2_GridType == 10 )
    {
      isRotated = 1;
    }

  return (isRotated);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
90
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
91
int cgribexGetZaxisType(int grb_ltype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
92
{
93
  int zaxistype = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
94

95
  switch ( grb_ltype )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
96
97
98
    {
    case LTYPE_SURFACE:
      {
99
	zaxistype = ZAXIS_SURFACE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
100
101
	break;
      }
102
103
104
105
106
    case LTYPE_MEANSEA:
      {
	zaxistype = ZAXIS_MEANSEA;
	break;
      }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
107
108
109
    case LTYPE_99:
    case LTYPE_ISOBARIC:
      {
110
	zaxistype = ZAXIS_PRESSURE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
111
112
113
114
	break;
      }
    case LTYPE_HEIGHT:
      {
115
	zaxistype = ZAXIS_HEIGHT;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
116
117
118
119
	break;
      }
    case LTYPE_ALTITUDE:
      {
120
	zaxistype = ZAXIS_ALTITUDE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
121
122
	break;
      }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
123
124
    case LTYPE_SIGMA:
      {
125
	zaxistype = ZAXIS_SIGMA;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
126
127
	break;
      }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
128
129
130
    case LTYPE_HYBRID:
    case LTYPE_HYBRID_LAYER:
      {
131
	zaxistype = ZAXIS_HYBRID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
132
133
134
135
136
	break;
      }
    case LTYPE_LANDDEPTH:
    case LTYPE_LANDDEPTH_LAYER:
      {
137
	zaxistype = ZAXIS_DEPTH_BELOW_LAND;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
138
139
	break;
      }
140
141
    case LTYPE_ISENTROPIC:
      {
142
	zaxistype = ZAXIS_ISENTROPIC;
143
144
	break;
      }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
145
146
    case LTYPE_SEADEPTH:
      {
147
	zaxistype = ZAXIS_DEPTH_BELOW_SEA;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
148
149
150
151
	break;
      }
    default:
      {
152
	zaxistype = ZAXIS_GENERIC;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
153
154
155
156
	break;
      }
    }

157
  return (zaxistype);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
158
159
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
160
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
161
int cgribexGetZaxisHasBounds(int grb_ltype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
162
163
164
{
  int lbounds = 0;

165
  switch (grb_ltype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
166
167
168
169
170
171
172
173
174
175
176
177
    {
    case LTYPE_HYBRID_LAYER:
    case LTYPE_LANDDEPTH_LAYER:
      {
	lbounds = 1;
	break;
      }
    }

  return (lbounds);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
178
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
179
int cgribexGetTimeUnit(int *isec1)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
180
181
182
183
184
185
{
  int timeunit = -1;
  static int lprint = TRUE;

  switch ( ISEC1_TimeUnit )
    {
186
187
188
    case ISEC1_TABLE4_MINUTE:  timeunit = TUNIT_MINUTE;  break;
    case ISEC1_TABLE4_QUARTER: timeunit = TUNIT_QUARTER; break;
    case ISEC1_TABLE4_HOUR:    timeunit = TUNIT_HOUR;    break;
189
190
191
    case ISEC1_TABLE4_3HOURS:  timeunit = TUNIT_3HOURS;  break;
    case ISEC1_TABLE4_6HOURS:  timeunit = TUNIT_6HOURS;  break;
    case ISEC1_TABLE4_12HOURS: timeunit = TUNIT_12HOURS; break;
192
    case ISEC1_TABLE4_DAY:     timeunit = TUNIT_DAY;     break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
193
194
195
    default:
      if ( lprint )
	{
196
	  Message("Time unit %d unsupported", ISEC1_TimeUnit);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
197
198
199
200
201
202
203
	  lprint = FALSE;
	}
    }

  return (timeunit);
}

204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
static
int cgribexTimeIsFC(int *isec1)
{
  int isFC = TRUE;

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

  return (isFC);
}

static
int cgribexGetTsteptype(int timerange)
{
  int tsteptype = 0;
  static int lprint = TRUE;

  switch ( timerange )
    {
    case  0:  tsteptype = TSTEP_INSTANT;  break;
    case  1:  tsteptype = TSTEP_INSTANT2; break;
    case  2:  tsteptype = TSTEP_RANGE;    break;
    case  3:  tsteptype = TSTEP_AVG;      break;
    case  4:  tsteptype = TSTEP_ACCUM;    break;
    case  5:  tsteptype = TSTEP_DIFF;     break;
    case 10:  tsteptype = TSTEP_INSTANT3; break;
    default:
      if ( lprint )
	{
233
	  Message("Time range %d unsupported", timerange);
234
235
236
237
238
239
240
	  lprint = FALSE;
	}
    }

  return (tsteptype);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
241

Uwe Schulzweida's avatar
Uwe Schulzweida committed
242
static
243
244
void cgribexAddRecord(int streamID, int param, int *isec1, int *isec2, double *fsec2, double *fsec3,
		      int *isec4, long recsize, off_t position, int prec, int ztype, int lmv)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
245
246
{
  int gridtype;
247
  int zaxistype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
248
  int gridID = CDI_UNDEFID, varID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
249
250
251
252
  int levelID = 0;
  int tsID, recID;
  int level1, level2;
  int numavg;
253
  int tsteptype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
254
  int lbounds = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
255
  record_t *record;
256
  grid_t grid;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
257
  int vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
258
  stream_t *streamptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
259
260

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

  vlistID = streamInqVlist(streamID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
263
  tsID    = streamptr->curTsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
264
  recID   = recordNewEntry(streamID, tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
265
  record  = &streamptr->tsteps[tsID].records[recID];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
266

267
268
  tsteptype = cgribexGetTsteptype(ISEC1_TimeRange);
  numavg    = ISEC1_AvgNum;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
269
270
271
272

  level1  = ISEC1_Level1;
  level2  = ISEC1_Level2;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
273
  /* fprintf(stderr, "param %d %d %d %d\n", param, level1, level2, ISEC1_LevelType); */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
274
275
276

  (*record).size     = recsize;
  (*record).position = position;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
277
  (*record).param    = param;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
278
279
280
281
  (*record).ilevel   = level1;
  (*record).ilevel2  = level2;
  (*record).ltype    = ISEC1_LevelType;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
282
  gridtype = cgribexGetGridType(isec2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
283

Uwe Schulzweida's avatar
Uwe Schulzweida committed
284
  if ( streamptr->unreduced && gridtype == GRID_GAUSSIAN_REDUCED )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
285
286
287
288
289
290
    {
      gridtype = GRID_GAUSSIAN;
      ISEC2_NumLon = 2*ISEC2_NumLat;
      ISEC4_NumValues = ISEC2_NumLon*ISEC2_NumLat;
    }

291
  memset(&grid, 0, sizeof(grid_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
292
293
294
295
296
297
  switch (gridtype)
    {
    case GRID_LONLAT:
    case GRID_GAUSSIAN:
      {
	if ( ISEC4_NumValues != ISEC2_NumLon*ISEC2_NumLat )
298
	  Error("numberOfPoints (%d) and gridSize (%d) differ!",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
299
300
301
302
303
304
305
306
307
308
309
		ISEC4_NumValues, ISEC2_NumLon*ISEC2_NumLat);
	grid.size  = ISEC4_NumValues;
	grid.xsize = ISEC2_NumLon;
	grid.ysize = ISEC2_NumLat;
	grid.xinc  = 0;
	grid.yinc  = 0;
	grid.xdef  = 0;
	/* if ( ISEC2_FirstLon != 0 || ISEC2_LastLon != 0 ) */
	  {
	    if ( grid.xsize > 1 )
	      {
310
311
312
		if ( ISEC2_ResFlag && ISEC2_LonIncr > 0 )
		  if ( ISEC2_LonIncr*(grid.xsize-1) > 360000 ) ISEC2_LonIncr = 0;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
313
314
315
316
317
318
319
320
321
322
323
324
325
		if ( ISEC2_ResFlag && ISEC2_LonIncr > 0 )
		  grid.xinc = ISEC2_LonIncr * 0.001;
		else
		  grid.xinc = (ISEC2_LastLon - ISEC2_FirstLon) * 0.001 / (grid.xsize - 1);

		/* correct xinc if necessary */
		if ( ISEC2_FirstLon == 0 && ISEC2_LastLon > 354000 )
		  {
		    double xinc = 360. / grid.xsize;

		    if ( fabs(grid.xinc-xinc) > 0.0 )
		      {
			grid.xinc = xinc;
326
			if ( CDI_Debug ) Message("set xinc to %g", grid.xinc);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
327
328
329
330
331
332
333
334
335
336
337
338
		      }
		  }
	      }
	    grid.xfirst = ISEC2_FirstLon * 0.001;
	    grid.xlast  = ISEC2_LastLon  * 0.001;
	    grid.xdef   = 2;	    
	  }
	grid.ydef  = 0;
	/* if ( ISEC2_FirstLat != 0 || ISEC2_LastLat != 0 ) */
	  {
	    if ( grid.ysize > 1 )
	      {
339
340
341
		if ( ISEC2_ResFlag && ISEC2_LatIncr > 0 )
		  if ( ISEC2_LatIncr*(grid.ysize-1) > 180000 ) ISEC2_LatIncr = 0;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
		if ( ISEC2_ResFlag && ISEC2_LatIncr > 0 )
		  grid.yinc = ISEC2_LatIncr * 0.001;
		else
		  grid.yinc = (ISEC2_LastLat - ISEC2_FirstLat) * 0.001 / (grid.ysize - 1);
	      }
	    grid.yfirst = ISEC2_FirstLat * 0.001;
	    grid.ylast  = ISEC2_LastLat  * 0.001;
	    grid.ydef   = 2;	    
	  }
	break;
      }
    case GRID_GAUSSIAN_REDUCED:
      {
	grid.size   = ISEC4_NumValues;
        grid.rowlon = ISEC2_RowLonPtr;
	grid.ysize  = ISEC2_NumLat;
	grid.xinc  = 0;
	grid.yinc  = 0;
	grid.xdef  = 0;
	/* if ( ISEC2_FirstLon != 0 || ISEC2_LastLon != 0 ) */
	  {
	    if ( grid.xsize > 1 )
	      {
		if ( ISEC2_ResFlag && ISEC2_LonIncr > 0 )
		  grid.xinc = ISEC2_LonIncr * 0.001;
		else
		  grid.xinc = (ISEC2_LastLon - ISEC2_FirstLon) * 0.001 / (grid.xsize - 1);
	      }
	    grid.xfirst = ISEC2_FirstLon * 0.001;
	    grid.xlast  = ISEC2_LastLon  * 0.001;
	    grid.xdef   = 2;	    
	  }
	grid.ydef  = 0;
	/* if ( ISEC2_FirstLat != 0 || ISEC2_LastLat != 0 ) */
	  {
	    if ( grid.ysize > 1 )
	      {
		if ( ISEC2_ResFlag && ISEC2_LatIncr > 0 )
		  grid.yinc = ISEC2_LatIncr * 0.001;
		else
		  grid.yinc = (ISEC2_LastLat - ISEC2_FirstLat) * 0.001 / (grid.ysize - 1);
	      }
	    grid.yfirst = ISEC2_FirstLat * 0.001;
	    grid.ylast  = ISEC2_LastLat  * 0.001;
	    grid.ydef   = 2;	    
	  }
	break;
      }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
390
    case GRID_LCC:
391
392
      {
	if ( ISEC4_NumValues != ISEC2_NumLon*ISEC2_NumLat )
393
	  Error("numberOfPoints (%d) and gridSize (%d) differ!",
394
		ISEC4_NumValues, ISEC2_NumLon*ISEC2_NumLat);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
395

396
397
398
399
	grid.size  = ISEC4_NumValues;
	grid.xsize = ISEC2_NumLon;
	grid.ysize = ISEC2_NumLat;

400
401
	grid.lcc_xinc      = ISEC2_Lambert_dx;
	grid.lcc_yinc      = ISEC2_Lambert_dy;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
402
403
	grid.lcc_originLon = ISEC2_FirstLon * 0.001;
	grid.lcc_originLat = ISEC2_FirstLat * 0.001;
404
405
406
407
408
	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;
409

410
	grid.xdef   = 0;	    
411
412
413
414
	grid.ydef   = 0;

	break;
      }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
415
416
417
418
    case GRID_SPECTRAL:
      {
	grid.size  = ISEC4_NumValues;
	grid.trunc = ISEC2_PentaJ;
419
420
421
422
423
	if ( ISEC2_RepMode == 2 )
	  grid.lcomplex = 1;
	else
	  grid.lcomplex = 0;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
	break;
      }
    case GRID_GME:
      {
	grid.size  = ISEC4_NumValues;
	grid.nd    = ISEC2_GME_ND;
	grid.ni    = ISEC2_GME_NI;
	grid.ni2   = ISEC2_GME_NI2;
	grid.ni3   = ISEC2_GME_NI3;
	break;
      }
    case GRID_GENERIC:
      {
	grid.size  = ISEC4_NumValues;
	grid.xsize = 0;
	grid.ysize = 0;
	break;
      }
    default:
      {
444
	Error("Unsupported grid type: %s", gridNamePtr(gridtype));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
445
446
447
448
449
	break;
      }
    }

  grid.isRotated = FALSE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
450
  if ( cgribexGetIsRotated(isec2) )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
451
452
453
454
455
456
457
458
459
460
461
462
463
    {
      grid.isRotated = TRUE;
      grid.ypole     = - ISEC2_LatSP * 0.001;
      grid.xpole     =   ISEC2_LonSP * 0.001 - 180;
      grid.angle     = 0;
    }

  grid.xvals = NULL;
  grid.yvals = NULL;
  grid.type  = gridtype;

  gridID = varDefGrid(vlistID, grid, 0);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
464
  zaxistype = cgribexGetZaxisType(ISEC1_LevelType);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
465

466
  if ( zaxistype == ZAXIS_HYBRID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
467
468
469
470
471
472
473
    {
      int vctsize = ISEC2_NumVCP;
      double *vctptr = &fsec2[10];

      varDefVCT(vctsize, vctptr);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
474
  lbounds = cgribexGetZaxisHasBounds(ISEC1_LevelType);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
475

476
477
  if ( prec > 32 ) prec = DATATYPE_PACK32;
  if ( prec <  0 ) prec = DATATYPE_PACK;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
478

Uwe Schulzweida's avatar
Uwe Schulzweida committed
479
  varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2,
480
	       prec, &varID, &levelID, tsteptype, numavg, ISEC1_LevelType, NULL, NULL, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
481
482
483
484

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

485
  varDefZtype(varID, ztype);
486

487
488
  if ( lmv ) varDefMissval(varID, FSEC3_MissVal);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
489
  if ( varInqInst(varID) == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
490
491
492
493
494
    {
      int center, subcenter, instID;
      center    = ISEC1_CenterID;
      subcenter = ISEC1_SubCenterID;
      instID    = institutInq(center, subcenter, NULL, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
495
      if ( instID == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
496
497
498
499
	instID = institutDef(center, subcenter, NULL, NULL);
      varDefInst(varID, instID);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
500
  if ( varInqModel(varID) == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
501
502
503
    {
      int modelID;
      modelID = modelInq(varInqInst(varID), ISEC1_ModelID, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
504
      if ( modelID == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
505
506
507
508
	modelID = modelDef(varInqInst(varID), ISEC1_ModelID, NULL);
      varDefModel(varID, modelID);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
509
  if ( varInqTable(varID) == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
510
511
    {
      int tableID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
512

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
515
      if ( tableID == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
516
517
518
519
	tableID = tableDef(varInqModel(varID), ISEC1_CodeTable, NULL);
      varDefTable(varID, tableID);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
520
521
  streamptr->tsteps[tsID].nallrecs++;
  streamptr->nrecs++;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
522
523

  if ( CDI_Debug )
524
    Message("varID = %d  param = %d  zaxistype = %d  gridID = %d  levelID = %d",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
525
	    varID, param, zaxistype, gridID, levelID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
526
527
}

528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
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
static
void MCH_get_undef(int *isec1, double *undef_pds, double *undef_eps)
{
  /* 2010-01-13: Oliver Fuhrer */
  if ( ISEC1_CenterID == 215 ) {
    if (isec1[34] != 0 && isec1[34] != 255) {
      if (isec1[34] & 2) {
        if (isec1[34] & 1) {
          *undef_pds = -0.99*pow(10.0,-isec1[35]);
        } else {
          *undef_pds = +0.99*pow(10.0,-isec1[35]);
        }
        *undef_eps = pow(10.0,-isec1[35]-1);
      } else {
        if (isec1[34] & 1) {
          *undef_pds = -0.99*pow(10.0,+isec1[35]);
        } else {
          *undef_pds = +0.99*pow(10.0,+isec1[35]);
        }
        *undef_eps = pow(10.0,isec1[35]-1);
      }
    }
  }
}

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

  gribExDP(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, fsec4,
	   ipunp, (int *) gribbuffer, recsize, &iword, "J", &iret);

  *lmv = 0;

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
575

576
int cgribexScanTimestep1(int streamID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
577
578
579
{
  int *isec0, *isec1, *isec2, *isec3, *isec4;
  double fsec2[512], fsec3[2], *fsec4 = NULL;
580
  int lmv = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
581
582
583
584
585
  off_t recpos = 0;
  unsigned char *gribbuffer = NULL;
  long buffersize = 0;
  int status;
  int fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
586
587
  int param = 0;
  int level1 = 0, level2 = 0, vdate = 0, vtime = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
588
589
590
591
592
593
594
  DateTime datetime, datetime0;
  int tsID;
  int varID;
  size_t readsize;
  int nrecords, nrecs, recID;
  int prec;
  long recsize = 0;
595
  int warn_time = TRUE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
596
597
598
  int warn_numavg = TRUE;
  int taxisID = -1;
  int rdate = 0, rtime = 0, tunit = 0, fcast = 0;
599
  taxis_t *taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
600
  int vlistID;
601
  int ztype;
602
  long unzipsize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
603
604
  compvar_t compVar, compVar0;
  stream_t *streamptr;
605
606
  extern int cdiSkipRecords;
  int nskip = cdiSkipRecords;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
607
608

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

610
  stream_check_ptr(__func__, streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
611

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
614
615
616
617
618
  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
619
620

  tsID  = tstepsNewEntry(streamID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
621
  taxis = &streamptr->tsteps[tsID].taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
622
623

  if ( tsID != 0 )
624
    Error("Internal problem! tstepsNewEntry returns %d", tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
625
626
627

  fileID = streamInqFileID(streamID);

628
629
630
  while ( nskip-- > 0 )
    {
      recsize = gribGetSize(fileID);
631
      if ( recsize == 0 )
632
	Error("Skipping of %d records failed!", cdiSkipRecords);
633

634
635
636
637
      recpos  = fileGetPos(fileID);
      fileSetPos(fileID, recsize, SEEK_CUR);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
638
639
640
641
642
643
644
645
  nrecs = 0;
  while ( TRUE )
    {
      recsize = gribGetSize(fileID);
      recpos  = fileGetPos(fileID);

      if ( recsize == 0 )
	{
646
	  if ( nrecs == 0 )
647
	    Error("No GRIB records found!");
648

Uwe Schulzweida's avatar
Uwe Schulzweida committed
649
	  streamptr->ntsteps = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
650
651
652
653
654
655
656
657
658
659
660
661
	  break;
	}
      if ( recsize > buffersize )
	{
	  buffersize = recsize;
	  gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
	}

      readsize = recsize;
      status = gribRead(fileID, gribbuffer, &readsize);
      if ( status ) break;

662
      ztype = COMPRESS_NONE;
663
664
      if ( gribGetZip(recsize, gribbuffer, &unzipsize) > 0 )
	{
665
	  ztype = COMPRESS_SZIP;
666
667
668
669
670
671
672
673
	  unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
	  if ( (long) buffersize < unzipsize )
	    {
	      buffersize = unzipsize;
	      gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
	    }
	}

674
675
      cgribexDecodeHeader(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, fsec4,
			  (int *) gribbuffer, recsize, &lmv);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
676

Uwe Schulzweida's avatar
Uwe Schulzweida committed
677
      param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255);
678
679
      if ( ISEC1_LevelType == 100 ) ISEC1_Level1 *= 100;
      if ( ISEC1_LevelType ==  99 ) ISEC1_LevelType = 100;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
680
681
682
      level1   = ISEC1_Level1;
      level2   = ISEC1_Level2;

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

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
714
	      if ( memcmp(&compVar0, &compVar, sizeof(compvar_t)) == 0 ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
715
	    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
716
717
718
719
720
721
722

	  if ( cdiInventoryMode == 1 )
	    {
	      if ( recID < nrecs ) break;
	      if ( warn_time )
		if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 )
		  {
723
724
		    char paramstr[32];
		    cdiParamToString(param, paramstr, sizeof(paramstr));
725
		    Warning("Inconsistent verification time (param=%s level=%d)", paramstr, level1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
726
727
728
729
730
731
732
733
734
		    warn_time = FALSE;
		  }
	    }
	  else
	    {
	      if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 ) break;

	      if ( recID < nrecs )
		{
735
736
		  char paramstr[32];
		  cdiParamToString(param, paramstr, sizeof(paramstr));
737
		  Warning("Param=%s level=%d already exist, skipped!", paramstr, level1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
738
739
740
		  continue;
		}
	    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
741
742
743
744
745
746
	}

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

      nrecs++;

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

762
763
      cgribexAddRecord(streamID, param, isec1, isec2, fsec2, fsec3,
		       isec4, recsize, recpos, prec, ztype, lmv);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
764
765
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
766
  streamptr->rtsteps = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
767

768
769
  if ( nrecs == 0 ) return (CDI_EUFSTRUCT);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
770
771
772
773
  cdiGenVars(streamID);

  if ( fcast )
    {
774
      taxisID = taxisCreate(TAXIS_RELATIVE);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
775
776
777
778
779
780
781
      taxis->type  = TAXIS_RELATIVE;
      taxis->rdate = rdate;
      taxis->rtime = rtime;
      taxis->unit  = tunit;
    }
  else
    {
782
      taxisID = taxisCreate(TAXIS_ABSOLUTE);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
783
      taxis->type  = TAXIS_ABSOLUTE;
784
      taxis->unit  = tunit;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
785
786
787
788
789
790
791
792
    }

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
793
794
  nrecords = streamptr->tsteps[0].nallrecs;
  if ( nrecords < streamptr->tsteps[0].recordSize )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
795
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
796
797
      streamptr->tsteps[0].recordSize = nrecords;
      streamptr->tsteps[0].records =
Uwe Schulzweida's avatar
Uwe Schulzweida committed
798
      (record_t *) realloc(streamptr->tsteps[0].records, nrecords*sizeof(record_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
799
800
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
801
802
  streamptr->tsteps[0].recIDs = (int *) malloc(nrecords*sizeof(int));
  streamptr->tsteps[0].nrecs = nrecords;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
803
  for ( recID = 0; recID < nrecords; recID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
804
    streamptr->tsteps[0].recIDs[recID] = recID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
805

Uwe Schulzweida's avatar
Uwe Schulzweida committed
806
807
  streamptr->record->buffer     = gribbuffer;
  streamptr->record->buffersize = buffersize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
808

Uwe Schulzweida's avatar
Uwe Schulzweida committed
809
  if ( streamptr->ntsteps == -1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
810
811
    {
      tsID = tstepsNewEntry(streamID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
812
      if ( tsID != streamptr->rtsteps )
813
	Error("Internal error. tsID = %d", tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
814

Uwe Schulzweida's avatar
Uwe Schulzweida committed
815
816
      streamptr->tsteps[tsID-1].next   = TRUE;
      streamptr->tsteps[tsID].position = recpos;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
817
818
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
819
  if ( streamptr->ntsteps == 1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
820
821
822
    {
      if ( taxis->vdate == 0 && taxis->vtime == 0 )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
823
824
	  streamptr->ntsteps = 0;
	  for ( varID = 0; varID < streamptr->nvars; varID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
825
826
827
828
829
	    {
	      vlistDefVarTime(vlistID, varID, TIME_CONSTANT);
	    }
	}
    }
830
831

  return (0);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
832
833
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
834
835

int cgribexScanTimestep2(int streamID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
836
837
838
{
  int *isec0, *isec1, *isec2, *isec3, *isec4;
  double fsec2[512], fsec3[2], *fsec4 = NULL;
839
  int lmv = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
840
841
842
843
844
  off_t recpos = 0;
  unsigned char *gribbuffer = NULL;
  long buffersize = 0;
  int status;
  int fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
845
846
  int param = 0;
  int level1 = 0, level2 = 0, vdate = 0, vtime = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
847
  DateTime datetime, datetime0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
848
849
850
851
852
853
  int tsID;
  int varID, gridID;
  size_t readsize;
  int nrecords, nrecs, recID, rindex;
  long recsize = 0;
  int warn_numavg = TRUE;
854
  int tsteptype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
855
  int taxisID = -1;
856
  taxis_t *taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
857
  int vlistID;
858
  long unzipsize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
859
860
  compvar_t compVar, compVar0;
  stream_t *streamptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
861

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

864
  stream_check_ptr(__func__, streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
865

Uwe Schulzweida's avatar
Uwe Schulzweida committed
866
867
868
869
870
871
872
  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
873
874
875
876
877

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
878
879
  gribbuffer = (unsigned char *) streamptr->record->buffer;
  buffersize = streamptr->record->buffersize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
880
                                          
Uwe Schulzweida's avatar
Uwe Schulzweida committed
881
  tsID = streamptr->rtsteps;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
882
  if ( tsID != 1 )
883
    Error("Internal problem! unexpeceted timestep %d", tsID+1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
884

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
887
  fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
888
889
890

  cdiCreateRecords(streamID, tsID);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
891
892
893
  nrecords = streamptr->tsteps[tsID].nallrecs;
  streamptr->tsteps[1].recIDs = (int *) malloc(nrecords*sizeof(int));
  streamptr->tsteps[1].nrecs = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
894
  for ( recID = 0; recID < nrecords; recID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
895
    streamptr->tsteps[1].recIDs[recID] = -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
896
897
898
      
  for ( recID = 0; recID < nrecords; recID++ )
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
899
900
901
902
903
      varID = streamptr->tsteps[0].records[recID].varID;
      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
904
905
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
906
907
  rindex = 0;
  while ( TRUE )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
908
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
909
910
      if ( rindex > nrecords ) break;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
911
912
913
914
      recsize = gribGetSize(fileID);
      recpos  = fileGetPos(fileID);
      if ( recsize == 0 )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
915
	  streamptr->ntsteps = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
916
917
918
919
920
	  break;
	}
      if ( recsize > buffersize )
	{
	  buffersize = recsize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
921
	  gribbuffer = (unsigned char *) realloc(gribbuffer, (size_t)buffersize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
922
923
924
925
926
927
	}

      readsize = recsize;
      status = gribRead(fileID, gribbuffer, &readsize);
      if ( status ) break;

928
929
930
931
932
933
934
935
936
937
      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);
	    }
	}

938
939
      cgribexDecodeHeader(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, fsec4,
			  (int *) gribbuffer, recsize, &lmv);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
940

Uwe Schulzweida's avatar
Uwe Schulzweida committed
941
      param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255);
942
943
      if ( ISEC1_LevelType == 100 ) ISEC1_Level1 *= 100;
      if ( ISEC1_LevelType ==  99 ) ISEC1_LevelType = 100;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
      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;
	    }
961
	  taxis->unit  = cgribexGetTimeUnit(isec1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
962
963
	  taxis->vdate = vdate;
	  taxis->vtime = vtime;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
964
965
966

	  datetime0.date = vdate;
	  datetime0.time = vtime;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
967
968
	}

969
970
      tsteptype = cgribexGetTsteptype(ISEC1_TimeRange);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
971
972
973
974
975
976
      if ( ISEC1_AvgNum )
	{
	  if (  taxis->numavg && warn_numavg &&
		(taxis->numavg != ISEC1_AvgNum) )
	    {
	  /*
977
	      Warning("Changing numavg from %d to %d not supported!",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
978
979
980
981
982
983
984
985
986
987
		      taxis->numavg, ISEC1_AvgNum);
	  */
	      warn_numavg = FALSE;
	    }
	  else
	    {
	      taxis->numavg = ISEC1_AvgNum;
	    }
	}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
988
989
      datetime.date  = vdate;
      datetime.time  = vtime;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
990
      compVar.param  = param;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
991
992
993
994
995
      compVar.level1 = level1;
      compVar.level2 = level2;
      compVar.ltype  = ISEC1_LevelType;
      for ( recID = 0; recID < nrecords; recID++ )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
996
	  compVar0.param  = streamptr->tsteps[tsID].records[recID].param;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
997
998
999
	  compVar0.level1 = streamptr->tsteps[tsID].records[recID].ilevel;
	  compVar0.level2 = streamptr->tsteps[tsID].records[recID].ilevel2;
	  compVar0.ltype  = streamptr->tsteps[tsID].records[recID].ltype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1000

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1001
	  if ( memcmp(&compVar0, &compVar, sizeof(compvar_t)) == 0 ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1002
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1003

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1004
1005
      if ( recID == nrecords )
	{
1006
1007
	  char paramstr[32];
	  cdiParamToString(param, paramstr, sizeof(paramstr));
1008
	  Warning("Param=%s level=%d not defined at timestep 1!", paramstr, level1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1009
1010
1011
	  return (CDI_EUFSTRUCT);
	}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
      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;
	    }    
	}
      else
	{
	  if ( streamptr->tsteps[tsID].records[recID].used )
	    {
1028
1029
1030
	      char paramstr[32];
	      cdiParamToString(param, paramstr, sizeof(paramstr));

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

1033
	      Warning("Param=%s level=%d already exist, skipped!", paramstr, level1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1034
1035
1036
1037
1038
1039
1040
1041
	      continue;
	    }
	  else
	    {
	      streamptr->tsteps[tsID].records[recID].used = TRUE;
	      streamptr->tsteps[tsID].recIDs[rindex] = recID;
	    }    
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1042
1043

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1048
      compVar0.param  = streamptr->tsteps[tsID].records[recID].param;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1049
1050
1051
      compVar0.level1 = streamptr->tsteps[tsID].records[recID].ilevel;
      compVar0.level2 = streamptr->tsteps[tsID].records[recID].ilevel2;
      compVar0.ltype  = streamptr->tsteps[tsID].records[recID].ltype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1052

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1053
      if ( memcmp(&compVar0, &compVar, sizeof(compvar_t)) != 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1054
	{
1055
	  Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1056
		  tsID, recID,
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1057
		  streamptr->tsteps[tsID].records[recID].param, param,
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1058
		  streamptr->tsteps[tsID].records[recID].ilevel, level1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1059
1060
1061
	  return (CDI_EUFSTRUCT);
	}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1062
1063
      streamptr->tsteps[1].records[recID].position = recpos;
      varID = streamptr->tsteps[tsID].records[recID].varID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1064
1065
1066
      gridID = vlistInqVarGrid(vlistID, varID);
      if ( gridInqSize(gridID) == 1 && gridInqType(gridID) == GRID_LONLAT )
	{
1067
1068
	  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
1069
1070
	    gridChangeType(gridID, GRID_TRAJECTORY);
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1071

1072
1073
1074
      if ( tsteptype != vlistInqVarTsteptype(vlistID, varID) )
	vlistDefVarTsteptype(vlistID, varID, tsteptype);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1075
      rindex++;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1076
1077
1078
1079
1080
    }

  nrecs = 0;
  for ( recID = 0; recID < nrecords; recID++ )
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1081
      if ( ! streamptr->tsteps[tsID].records[recID].used )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1082
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1083
	  varID = streamptr->tsteps[tsID].records[recID].varID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1084
1085
1086
1087
1088
1089
1090
	  vlistDefVarTime(vlistID, varID, TIME_CONSTANT);
	}
      else
	{
	  nrecs++;
	}
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1091
  streamptr->tsteps[tsID].nrecs = nrecs;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1092

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1093
  streamptr->rtsteps = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1094

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1095
  if ( streamptr->ntsteps == -1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1096
1097
    {
      tsID = tstepsNewEntry(streamID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1098
      if ( tsID != streamptr->rtsteps )
1099
	Error("Internal error. tsID = %d", tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1100

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1101
1102
      streamptr->tsteps[tsID-1].next   = TRUE;
      streamptr->tsteps[tsID].position = recpos;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1103
1104
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1105
1106
  streamptr->record->buffer     = gribbuffer;
  streamptr->record->buffersize = buffersize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1107
1108
1109
1110
1111

  return (0);
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
1112
int cgribexScanTimestep(int streamID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1113
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1114
1115
  int *isec0, *isec1, *isec2, *isec3, *isec4;
  double fsec2[512], fsec3[2], *fsec4 = NULL;
1116
  int lmv = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1117
1118
1119
1120
1121
  long recsize = 0;
  off_t recpos = 0;
  unsigned char *gribbuffer;
  long buffersize = 0;
  int status;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1122
  int fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1123
1124
  int param = 0;
  int level1 = 0, level2 = 0, vdate = 0, vtime = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1125
1126
1127
1128
1129
1130
  DateTime datetime, datetime0;
  int tsID;
  int vrecID, recID;
  int warn_numavg = TRUE;
  size_t readsize;
  int taxisID = -1;
1131
  taxis_t *taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1132
1133
1134
1135
  int vlistID;
  int rindex, nrecs = 0;
  long unzipsize;
  compvar_t compVar, compVar0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1136
  stream_t *streamptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1137
1138

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

1140
  stream_check_ptr(__func__, streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1141

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1142
  vlistID = streamInqVlist(streamID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1143

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1144
1145
  if ( CDI_Debug )
    {
1146
1147
1148
1149
      Message("streamID = %d", streamID);
      Message("cts = %d", streamptr->curTsID);
      Message("rts = %d", streamptr->rtsteps);
      Message("nts = %d", streamptr->ntsteps);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1150
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1151

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1152
1153
1154
1155
1156
  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
1157

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1158
1159
  tsID  = streamptr->rtsteps;
  taxis = &streamptr->tsteps[tsID].taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1160

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1161
1162
1163
1164
  if ( streamptr->tsteps[tsID].recordSize == 0 )
    {
      gribbuffer = (unsigned char *) streamptr->record->buffer;
      buffersize = streamptr->record->buffersize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1165

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1166
      cdiCreateRecords(streamID, tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1167

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1168
      nrecs = streamptr->tsteps[1].nrecs;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1169

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1170
1171
1172
1173
      streamptr->tsteps[tsID].nrecs = nrecs;
      streamptr->tsteps[tsID].recIDs = (int *) malloc(nrecs*sizeof(int));
      for ( recID = 0; recID < nrecs; recID++ )
	streamptr->tsteps[tsID].recIDs[recID] = streamptr->tsteps[1].recIDs[recID];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1174

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1175
      fileID = streamInqFileID(streamID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1176

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1179
1180
      rindex = 0;
      while ( TRUE )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1181
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1182
	  if ( rindex > nrecs ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1183

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
	  recsize = gribGetSize(fileID);
	  recpos  = fileGetPos(fileID);
	  if ( recsize == 0 )
	    {
	      streamptr->ntsteps = streamptr->rtsteps + 1;
	      break;
	    }
	  if ( recsize > buffersize )
	    {
	      buffersize = recsize;
	      gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
	    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1196

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1197
1198
1199
1200
	  readsize = recsize;
	  status = gribRead(fileID, gribbuffer, &readsize);
	  if ( status )
	    {
1201
	      Error("Inconsistent timestep %d (GRIB record %d/%d)!\n", tsID+1, rindex+1,
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212