stream_cgribex.c 54.7 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
#if  defined  (HAVE_LIBCGRIBEX)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
32
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
33
int cgribexGetGridType(int *isec2)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
34
35
36
37
38
{
  int gridtype = 0;

  switch (ISEC2_GridType)
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
39
40
    case  GTYPE_LATLON:
    case  GTYPE_LATLON_ROT:
Uwe Schulzweida's avatar
Uwe Schulzweida committed
41
42
43
44
      {
	gridtype = GRID_LONLAT;
	break;
      }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
45
    case  GTYPE_LCC:
46
      {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
47
	gridtype = GRID_LCC;
48
49
	break;
      }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
50
    case  GTYPE_GAUSSIAN:
Uwe Schulzweida's avatar
Uwe Schulzweida committed
51
52
53
54
55
56
57
      {
	if ( ISEC2_Reduced )
	  gridtype = GRID_GAUSSIAN_REDUCED;
	else
	  gridtype = GRID_GAUSSIAN;
	break;
      }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
58
    case  GTYPE_SPECTRAL:
Uwe Schulzweida's avatar
Uwe Schulzweida committed
59
60
61
62
      {
	gridtype = GRID_SPECTRAL;
	break;
      }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
63
    case  GTYPE_GME:
Uwe Schulzweida's avatar
Uwe Schulzweida committed
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
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
78

Uwe Schulzweida's avatar
Uwe Schulzweida committed
79
#if  defined  (HAVE_LIBCGRIBEX)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
80
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
81
int cgribexGetIsRotated(int *isec2)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
82
83
84
85
86
87
88
89
90
91
{
  int isRotated = 0;

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

  return (isRotated);
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
92
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
93

Uwe Schulzweida's avatar
Uwe Schulzweida committed
94
#if  defined  (HAVE_LIBCGRIBEX)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
95
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
96
int cgribexGetZaxisType(int grb_ltype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
97
{
98
  int zaxistype = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
99

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

162
  return (zaxistype);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
163
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
164
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
165

Uwe Schulzweida's avatar
Uwe Schulzweida committed
166
#if  defined  (HAVE_LIBCGRIBEX)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
167
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
168
int cgribexGetZaxisHasBounds(int grb_ltype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
169
170
171
{
  int lbounds = 0;

172
  switch (grb_ltype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
173
174
175
176
177
178
179
180
181
182
183
    {
    case LTYPE_HYBRID_LAYER:
    case LTYPE_LANDDEPTH_LAYER:
      {
	lbounds = 1;
	break;
      }
    }

  return (lbounds);
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
184
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
185

Uwe Schulzweida's avatar
Uwe Schulzweida committed
186
#if  defined  (HAVE_LIBCGRIBEX)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
187
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
188
int cgribexGetTimeUnit(int *isec1)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
189
190
191
192
193
194
{
  int timeunit = -1;
  static int lprint = TRUE;

  switch ( ISEC1_TimeUnit )
    {
195
196
197
    case ISEC1_TABLE4_MINUTE:  timeunit = TUNIT_MINUTE;  break;
    case ISEC1_TABLE4_QUARTER: timeunit = TUNIT_QUARTER; break;
    case ISEC1_TABLE4_HOUR:    timeunit = TUNIT_HOUR;    break;
198
199
200
    case ISEC1_TABLE4_3HOURS:  timeunit = TUNIT_3HOURS;  break;
    case ISEC1_TABLE4_6HOURS:  timeunit = TUNIT_6HOURS;  break;
    case ISEC1_TABLE4_12HOURS: timeunit = TUNIT_12HOURS; break;
201
    case ISEC1_TABLE4_DAY:     timeunit = TUNIT_DAY;     break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
202
203
204
    default:
      if ( lprint )
	{
205
	  Message("Time unit %d unsupported", ISEC1_TimeUnit);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
206
207
208
209
210
211
	  lprint = FALSE;
	}
    }

  return (timeunit);
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
212
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
213

Uwe Schulzweida's avatar
Uwe Schulzweida committed
214
#if  defined  (HAVE_LIBCGRIBEX)
215
216
217
218
219
220
221
222
223
224
static
int cgribexTimeIsFC(int *isec1)
{
  int isFC = TRUE;

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

  return (isFC);
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
225
#endif
226

Uwe Schulzweida's avatar
Uwe Schulzweida committed
227
#if  defined  (HAVE_LIBCGRIBEX)
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
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 )
	{
246
	  Message("Time range %d unsupported", timerange);
247
248
249
250
251
252
	  lprint = FALSE;
	}
    }

  return (tsteptype);
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
253
#endif
254

Uwe Schulzweida's avatar
Uwe Schulzweida committed
255
#if  defined  (HAVE_LIBCGRIBEX)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
256
static
257
258
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
259
260
{
  int gridtype;
261
  int zaxistype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
262
  int gridID = CDI_UNDEFID, varID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
263
264
265
266
  int levelID = 0;
  int tsID, recID;
  int level1, level2;
  int numavg;
267
  int tsteptype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
268
  int lbounds = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
269
  record_t *record;
270
  grid_t grid;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
271
  int vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
272
  stream_t *streamptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
273
274

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

  vlistID = streamInqVlist(streamID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
277
  tsID    = streamptr->curTsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
278
  recID   = recordNewEntry(streamID, tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
279
  record  = &streamptr->tsteps[tsID].records[recID];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
280

281
282
  tsteptype = cgribexGetTsteptype(ISEC1_TimeRange);
  numavg    = ISEC1_AvgNum;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
283
284
285
286

  level1  = ISEC1_Level1;
  level2  = ISEC1_Level2;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
287
  /* fprintf(stderr, "param %d %d %d %d\n", param, level1, level2, ISEC1_LevelType); */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
288
289
290

  (*record).size     = recsize;
  (*record).position = position;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
291
  (*record).param    = param;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
292
293
294
295
  (*record).ilevel   = level1;
  (*record).ilevel2  = level2;
  (*record).ltype    = ISEC1_LevelType;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
296
  gridtype = cgribexGetGridType(isec2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
297

Uwe Schulzweida's avatar
Uwe Schulzweida committed
298
  if ( streamptr->unreduced && gridtype == GRID_GAUSSIAN_REDUCED )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
299
300
301
302
303
304
    {
      gridtype = GRID_GAUSSIAN;
      ISEC2_NumLon = 2*ISEC2_NumLat;
      ISEC4_NumValues = ISEC2_NumLon*ISEC2_NumLat;
    }

305
  memset(&grid, 0, sizeof(grid_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
306
307
308
309
310
311
  switch (gridtype)
    {
    case GRID_LONLAT:
    case GRID_GAUSSIAN:
      {
	if ( ISEC4_NumValues != ISEC2_NumLon*ISEC2_NumLat )
312
	  Error("numberOfPoints (%d) and gridSize (%d) differ!",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
313
314
315
316
317
318
319
320
321
322
323
		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 )
	      {
324
325
326
		if ( ISEC2_ResFlag && ISEC2_LonIncr > 0 )
		  if ( ISEC2_LonIncr*(grid.xsize-1) > 360000 ) ISEC2_LonIncr = 0;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
327
328
329
330
331
332
333
334
335
336
337
338
339
		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;
340
			if ( CDI_Debug ) Message("set xinc to %g", grid.xinc);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
341
342
343
344
345
346
347
348
349
350
351
352
		      }
		  }
	      }
	    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 )
	      {
353
354
355
		if ( ISEC2_ResFlag && ISEC2_LatIncr > 0 )
		  if ( ISEC2_LatIncr*(grid.ysize-1) > 180000 ) ISEC2_LatIncr = 0;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
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
390
391
392
393
394
395
396
397
398
399
400
401
402
403
		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
404
    case GRID_LCC:
405
406
      {
	if ( ISEC4_NumValues != ISEC2_NumLon*ISEC2_NumLat )
407
	  Error("numberOfPoints (%d) and gridSize (%d) differ!",
408
		ISEC4_NumValues, ISEC2_NumLon*ISEC2_NumLat);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
409

410
411
412
413
	grid.size  = ISEC4_NumValues;
	grid.xsize = ISEC2_NumLon;
	grid.ysize = ISEC2_NumLat;

414
415
	grid.lcc_xinc      = ISEC2_Lambert_dx;
	grid.lcc_yinc      = ISEC2_Lambert_dy;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
416
417
	grid.lcc_originLon = ISEC2_FirstLon * 0.001;
	grid.lcc_originLat = ISEC2_FirstLat * 0.001;
418
419
420
421
422
	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;
423

424
	grid.xdef   = 0;	    
425
426
427
428
	grid.ydef   = 0;

	break;
      }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
429
430
431
432
    case GRID_SPECTRAL:
      {
	grid.size  = ISEC4_NumValues;
	grid.trunc = ISEC2_PentaJ;
433
434
435
436
437
	if ( ISEC2_RepMode == 2 )
	  grid.lcomplex = 1;
	else
	  grid.lcomplex = 0;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
	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:
      {
458
	Error("Unsupported grid type: %s", gridNamePtr(gridtype));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
459
460
461
462
463
	break;
      }
    }

  grid.isRotated = FALSE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
464
  if ( cgribexGetIsRotated(isec2) )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
465
466
467
468
469
470
471
472
473
474
475
476
477
    {
      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
478
  zaxistype = cgribexGetZaxisType(ISEC1_LevelType);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
479

480
  if ( zaxistype == ZAXIS_HYBRID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
481
482
483
484
485
486
487
    {
      int vctsize = ISEC2_NumVCP;
      double *vctptr = &fsec2[10];

      varDefVCT(vctsize, vctptr);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
488
  lbounds = cgribexGetZaxisHasBounds(ISEC1_LevelType);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
489

490
491
  if ( prec > 32 ) prec = DATATYPE_PACK32;
  if ( prec <  0 ) prec = DATATYPE_PACK;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
492

Uwe Schulzweida's avatar
Uwe Schulzweida committed
493
  varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2,
494
	       prec, &varID, &levelID, tsteptype, numavg, ISEC1_LevelType, NULL, NULL, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
495
496
497
498

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

499
  varDefZtype(varID, ztype);
500

501
502
  if ( lmv ) varDefMissval(varID, FSEC3_MissVal);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
503
  if ( varInqInst(varID) == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
504
505
506
507
508
    {
      int center, subcenter, instID;
      center    = ISEC1_CenterID;
      subcenter = ISEC1_SubCenterID;
      instID    = institutInq(center, subcenter, NULL, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
509
      if ( instID == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
510
511
512
513
	instID = institutDef(center, subcenter, NULL, NULL);
      varDefInst(varID, instID);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
514
  if ( varInqModel(varID) == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
515
516
517
    {
      int modelID;
      modelID = modelInq(varInqInst(varID), ISEC1_ModelID, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
518
      if ( modelID == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
519
520
521
522
	modelID = modelDef(varInqInst(varID), ISEC1_ModelID, NULL);
      varDefModel(varID, modelID);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
523
  if ( varInqTable(varID) == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
524
525
    {
      int tableID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
526

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
529
      if ( tableID == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
530
531
532
533
	tableID = tableDef(varInqModel(varID), ISEC1_CodeTable, NULL);
      varDefTable(varID, tableID);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
534
535
  streamptr->tsteps[tsID].nallrecs++;
  streamptr->nrecs++;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
536
537

  if ( CDI_Debug )
538
    Message("varID = %d  param = %d  zaxistype = %d  gridID = %d  levelID = %d",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
539
	    varID, param, zaxistype, gridID, levelID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
540
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
541
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
542

Uwe Schulzweida's avatar
Uwe Schulzweida committed
543
#if  defined  (HAVE_LIBCGRIBEX)
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
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);
      }
    }
  }
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
568
#endif
569

Uwe Schulzweida's avatar
Uwe Schulzweida committed
570
#if  defined  (HAVE_LIBCGRIBEX)
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
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
592
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
593

594
int cgribexScanTimestep1(int streamID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
595
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
596
#if  defined  (HAVE_LIBCGRIBEX)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
597
598
  int *isec0, *isec1, *isec2, *isec3, *isec4;
  double fsec2[512], fsec3[2], *fsec4 = NULL;
599
  int lmv = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
600
601
602
  off_t recpos = 0;
  unsigned char *gribbuffer = NULL;
  long buffersize = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
603
  int rstatus;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
604
  int fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
605
606
  int param = 0;
  int level1 = 0, level2 = 0, vdate = 0, vtime = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
607
608
609
610
611
612
613
  DateTime datetime, datetime0;
  int tsID;
  int varID;
  size_t readsize;
  int nrecords, nrecs, recID;
  int prec;
  long recsize = 0;
614
  int warn_time = TRUE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
615
616
617
  int warn_numavg = TRUE;
  int taxisID = -1;
  int rdate = 0, rtime = 0, tunit = 0, fcast = 0;
618
  taxis_t *taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
619
  int vlistID;
620
  int ztype;
621
  long unzipsize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
622
623
  compvar_t compVar, compVar0;
  stream_t *streamptr;
624
625
  extern int cdiSkipRecords;
  int nskip = cdiSkipRecords;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
626
627

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

629
  stream_check_ptr(__func__, streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
630

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
633
634
635
636
637
  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
638
639

  tsID  = tstepsNewEntry(streamID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
640
  taxis = &streamptr->tsteps[tsID].taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
641
642

  if ( tsID != 0 )
643
    Error("Internal problem! tstepsNewEntry returns %d", tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
644
645
646

  fileID = streamInqFileID(streamID);

647
648
649
  while ( nskip-- > 0 )
    {
      recsize = gribGetSize(fileID);
650
      if ( recsize == 0 )
651
	Error("Skipping of %d records failed!", cdiSkipRecords);
652

653
654
655
656
      recpos  = fileGetPos(fileID);
      fileSetPos(fileID, recsize, SEEK_CUR);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
657
658
659
660
661
662
663
664
  nrecs = 0;
  while ( TRUE )
    {
      recsize = gribGetSize(fileID);
      recpos  = fileGetPos(fileID);

      if ( recsize == 0 )
	{
665
	  if ( nrecs == 0 )
666
	    Error("No GRIB records found!");
667

Uwe Schulzweida's avatar
Uwe Schulzweida committed
668
	  streamptr->ntsteps = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
669
670
671
672
673
674
675
676
677
	  break;
	}
      if ( recsize > buffersize )
	{
	  buffersize = recsize;
	  gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
	}

      readsize = recsize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
678
679
      rstatus = gribRead(fileID, gribbuffer, &readsize);
      if ( rstatus ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
680

681
      ztype = COMPRESS_NONE;
682
683
      if ( gribGetZip(recsize, gribbuffer, &unzipsize) > 0 )
	{
684
	  ztype = COMPRESS_SZIP;
685
686
687
688
689
690
691
692
	  unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
	  if ( (long) buffersize < unzipsize )
	    {
	      buffersize = unzipsize;
	      gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
	    }
	}

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
696
      param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255);
697
698
      if ( ISEC1_LevelType == 100 ) ISEC1_Level1 *= 100;
      if ( ISEC1_LevelType ==  99 ) ISEC1_LevelType = 100;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
699
700
701
      level1   = ISEC1_Level1;
      level2   = ISEC1_Level2;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
702
703
      gribDateTime(isec1, &vdate, &vtime);

704
705
706
707
      if ( ISEC4_NumBits > 0 && ISEC4_NumBits <= 32 )
	prec = ISEC4_NumBits;
      else
        prec = DATATYPE_PACK;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
708
709
710
711
712
713
714

      if ( nrecs == 0 )
	{
	  datetime0.date = vdate;
	  datetime0.time = vtime;
	  rdate = gribRefDate(isec1);
	  rtime = gribRefTime(isec1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
715
	  tunit = cgribexGetTimeUnit(isec1);
716
	  fcast = cgribexTimeIsFC(isec1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
717
718
719
720
721
	}
      else
	{
	  datetime.date  = vdate;
	  datetime.time  = vtime;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
722
	  compVar.param  = param;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
723
724
725
726
727
          compVar.level1 = level1;
          compVar.level2 = level2;
          compVar.ltype  = ISEC1_LevelType;
	  for ( recID = 0; recID < nrecs; recID++ )
	    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
728
	      compVar0.param  = streamptr->tsteps[0].records[recID].param;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
729
730
731
	      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
732

Uwe Schulzweida's avatar
Uwe Schulzweida committed
733
	      if ( memcmp(&compVar0, &compVar, sizeof(compvar_t)) == 0 ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
734
	    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
735
736
737
738
739
740
741

	  if ( cdiInventoryMode == 1 )
	    {
	      if ( recID < nrecs ) break;
	      if ( warn_time )
		if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 )
		  {
742
743
		    char paramstr[32];
		    cdiParamToString(param, paramstr, sizeof(paramstr));
744
		    Warning("Inconsistent verification time (param=%s level=%d)", paramstr, level1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
745
746
747
748
749
750
751
752
753
		    warn_time = FALSE;
		  }
	    }
	  else
	    {
	      if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 ) break;

	      if ( recID < nrecs )
		{
754
755
		  char paramstr[32];
		  cdiParamToString(param, paramstr, sizeof(paramstr));
756
		  Warning("Param=%s level=%d already exist, skipped!", paramstr, level1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
757
758
759
		  continue;
		}
	    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
760
761
762
763
764
765
	}

      if ( ISEC1_AvgNum )
	{
	  if (  taxis->numavg && warn_numavg && (taxis->numavg != ISEC1_AvgNum) )
	    {
766
	      Warning("Changing numavg from %d to %d not supported!",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
767
768
769
770
771
772
773
774
775
776
777
778
		      taxis->numavg, ISEC1_AvgNum);
	      warn_numavg = FALSE;
	    }
	  else
	    {
	      taxis->numavg = ISEC1_AvgNum;
	    }
	}

      nrecs++;

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

781
782
      cgribexAddRecord(streamID, param, isec1, isec2, fsec2, fsec3,
		       isec4, recsize, recpos, prec, ztype, lmv);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
783
784
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
785
  streamptr->rtsteps = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
786

787
788
  if ( nrecs == 0 ) return (CDI_EUFSTRUCT);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
789
790
791
792
  cdiGenVars(streamID);

  if ( fcast )
    {
793
      taxisID = taxisCreate(TAXIS_RELATIVE);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
794
795
796
797
798
799
800
      taxis->type  = TAXIS_RELATIVE;
      taxis->rdate = rdate;
      taxis->rtime = rtime;
      taxis->unit  = tunit;
    }
  else
    {
801
      taxisID = taxisCreate(TAXIS_ABSOLUTE);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
802
      taxis->type  = TAXIS_ABSOLUTE;
803
      taxis->unit  = tunit;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
804
805
806
807
808
809
810
811
    }

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
812
813
  nrecords = streamptr->tsteps[0].nallrecs;
  if ( nrecords < streamptr->tsteps[0].recordSize )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
814
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
815
816
      streamptr->tsteps[0].recordSize = nrecords;
      streamptr->tsteps[0].records =
Uwe Schulzweida's avatar
Uwe Schulzweida committed
817
      (record_t *) realloc(streamptr->tsteps[0].records, nrecords*sizeof(record_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
818
819
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
820
821
  streamptr->tsteps[0].recIDs = (int *) malloc(nrecords*sizeof(int));
  streamptr->tsteps[0].nrecs = nrecords;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
822
  for ( recID = 0; recID < nrecords; recID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
823
    streamptr->tsteps[0].recIDs[recID] = recID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
824

Uwe Schulzweida's avatar
Uwe Schulzweida committed
825
826
  streamptr->record->buffer     = gribbuffer;
  streamptr->record->buffersize = buffersize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
827

Uwe Schulzweida's avatar
Uwe Schulzweida committed
828
  if ( streamptr->ntsteps == -1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
829
830
    {
      tsID = tstepsNewEntry(streamID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
831
      if ( tsID != streamptr->rtsteps )
832
	Error("Internal error. tsID = %d", tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
833

Uwe Schulzweida's avatar
Uwe Schulzweida committed
834
835
      streamptr->tsteps[tsID-1].next   = TRUE;
      streamptr->tsteps[tsID].position = recpos;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
836
837
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
838
  if ( streamptr->ntsteps == 1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
839
840
841
    {
      if ( taxis->vdate == 0 && taxis->vtime == 0 )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
842
843
	  streamptr->ntsteps = 0;
	  for ( varID = 0; varID < streamptr->nvars; varID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
844
845
846
847
848
	    {
	      vlistDefVarTime(vlistID, varID, TIME_CONSTANT);
	    }
	}
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
849
850
851
#else
  Error("CGRIBEX support not compiled in!");
#endif
852
853

  return (0);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
854
855
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
856
857

int cgribexScanTimestep2(int streamID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
858
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
859
860
  int rstatus = 0;
#if  defined  (HAVE_LIBCGRIBEX)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
861
862
  int *isec0, *isec1, *isec2, *isec3, *isec4;
  double fsec2[512], fsec3[2], *fsec4 = NULL;
863
  int lmv = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
864
865
866
867
  off_t recpos = 0;
  unsigned char *gribbuffer = NULL;
  long buffersize = 0;
  int fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
868
869
  int param = 0;
  int level1 = 0, level2 = 0, vdate = 0, vtime = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
870
  DateTime datetime, datetime0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
871
872
873
874
875
876
  int tsID;
  int varID, gridID;
  size_t readsize;
  int nrecords, nrecs, recID, rindex;
  long recsize = 0;
  int warn_numavg = TRUE;
877
  int tsteptype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
878
  int taxisID = -1;
879
  taxis_t *taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
880
  int vlistID;
881
  long unzipsize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
882
883
  compvar_t compVar, compVar0;
  stream_t *streamptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
884

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

887
  stream_check_ptr(__func__, streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
888

Uwe Schulzweida's avatar
Uwe Schulzweida committed
889
890
891
892
893
894
895
  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
896
897
898
899
900

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
901
902
  gribbuffer = (unsigned char *) streamptr->record->buffer;
  buffersize = streamptr->record->buffersize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
903
                                          
Uwe Schulzweida's avatar
Uwe Schulzweida committed
904
  tsID = streamptr->rtsteps;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
905
  if ( tsID != 1 )
906
    Error("Internal problem! unexpeceted timestep %d", tsID+1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
907

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
910
  fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
911
912
913

  cdiCreateRecords(streamID, tsID);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
914
915
916
  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
917
  for ( recID = 0; recID < nrecords; recID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
918
    streamptr->tsteps[1].recIDs[recID] = -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
919
920
921
      
  for ( recID = 0; recID < nrecords; recID++ )
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
922
923
924
925
926
      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
927
928
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
929
930
  rindex = 0;
  while ( TRUE )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
931
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
932
933
      if ( rindex > nrecords ) break;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
934
935
936
937
      recsize = gribGetSize(fileID);
      recpos  = fileGetPos(fileID);
      if ( recsize == 0 )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
938
	  streamptr->ntsteps = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
939
940
941
942
943
	  break;
	}
      if ( recsize > buffersize )
	{
	  buffersize = recsize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
944
	  gribbuffer = (unsigned char *) realloc(gribbuffer, (size_t)buffersize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
945
946
947
	}

      readsize = recsize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
948
949
      rstatus = gribRead(fileID, gribbuffer, &readsize);
      if ( rstatus ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
950

951
952
953
954
955
956
957
958
959
960
      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);
	    }
	}

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
964
      param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255);
965
966
      if ( ISEC1_LevelType == 100 ) ISEC1_Level1 *= 100;
      if ( ISEC1_LevelType ==  99 ) ISEC1_LevelType = 100;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
      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;
	    }
984
	  taxis->unit  = cgribexGetTimeUnit(isec1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
985
986
	  taxis->vdate = vdate;
	  taxis->vtime = vtime;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
987
988
989

	  datetime0.date = vdate;
	  datetime0.time = vtime;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
990
991
	}

992
993
      tsteptype = cgribexGetTsteptype(ISEC1_TimeRange);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
994
995
996
997
998
999
      if ( ISEC1_AvgNum )
	{
	  if (  taxis->numavg && warn_numavg &&
		(taxis->numavg != ISEC1_AvgNum) )
	    {
	  /*
1000
	      Warning("Changing numavg from %d to %d not supported!",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
		      taxis->numavg, ISEC1_AvgNum);
	  */
	      warn_numavg = FALSE;
	    }
	  else
	    {
	      taxis->numavg = ISEC1_AvgNum;
	    }
	}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1011
1012
      datetime.date  = vdate;
      datetime.time  = vtime;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1013
      compVar.param  = param;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1014
1015
1016
1017
1018
      compVar.level1 = level1;
      compVar.level2 = level2;
      compVar.ltype  = ISEC1_LevelType;
      for ( recID = 0; recID < nrecords; recID++ )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1019
	  compVar0.param  = streamptr->tsteps[tsID].records[recID].param;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1020
1021
1022
	  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
1023

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1024
	  if ( memcmp(&compVar0, &compVar, sizeof(compvar_t)) == 0 ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1025
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1026

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1027
1028
      if ( recID == nrecords )
	{
1029
1030
	  char paramstr[32];
	  cdiParamToString(param, paramstr, sizeof(paramstr));
1031
	  Warning("Param=%s level=%d not defined at timestep 1!", paramstr, level1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1032
1033
1034
	  return (CDI_EUFSTRUCT);
	}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
      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 )
	    {
1051
1052
1053
	      char paramstr[32];
	      cdiParamToString(param, paramstr, sizeof(paramstr));

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

1056
	      Warning("Param=%s level=%d already exist, skipped!", paramstr, level1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1057
1058
1059
1060
1061
1062
1063
1064
	      continue;
	    }
	  else
	    {
	      streamptr->tsteps[tsID].records[recID].used = TRUE;
	      streamptr->tsteps[tsID].recIDs[rindex] = recID;
	    }    
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1065
1066

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1071
      compVar0.param  = streamptr->tsteps[tsID].records[recID].param;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1072
1073
1074
      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
1075

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1076
      if ( memcmp(&compVar0, &compVar, sizeof(compvar_t)) != 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1077
	{
1078
	  Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1079
		  tsID, recID,
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1080
		  streamptr->tsteps[tsID].records[recID].param, param,
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1081
		  streamptr->tsteps[tsID].records[recID].ilevel, level1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1082
1083
1084
	  return (CDI_EUFSTRUCT);
	}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1085
1086
      streamptr->tsteps[1].records[recID].position = recpos;
      varID = streamptr->tsteps[tsID].records[recID].varID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1087
1088
1089
      gridID = vlistInqVarGrid(vlistID, varID);
      if ( gridInqSize(gridID) == 1 && gridInqType(gridID) == GRID_LONLAT )
	{
1090
1091
	  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
1092
1093
	    gridChangeType(gridID, GRID_TRAJECTORY);
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1094

1095
1096
1097
      if ( tsteptype != vlistInqVarTsteptype(vlistID, varID) )
	vlistDefVarTsteptype(vlistID, varID, tsteptype);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1098
      rindex++;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1099
1100
1101
1102
1103
    }

  nrecs = 0;
  for ( recID = 0; recID < nrecords; recID++ )
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1104
      if ( ! streamptr->tsteps[tsID].records[recID].used )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1105
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1106
	  varID = streamptr->tsteps[tsID].records[recID].varID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1107
1108
1109
1110
1111
1112
1113
	  vlistDefVarTime(vlistID, varID, TIME_CONSTANT);
	}
      else
	{
	  nrecs++;
	}
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1114
  streamptr->tsteps[tsID].nrecs = nrecs;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1115

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1116
  streamptr->rtsteps = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1117

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1118
  if ( streamptr->ntsteps == -1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1119
1120
    {
      tsID = tstepsNewEntry(streamID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1121
      if ( tsID != streamptr->rtsteps )
1122
	Error("Internal error. tsID = %d", tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1123

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1124
1125
      streamptr->tsteps[tsID-1].next   = TRUE;
      streamptr->tsteps[tsID].position = recpos;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1126
1127
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1128
1129
  streamptr->record->buffer     = gribbuffer;
  streamptr->record->buffersize = buffersize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1130
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1131

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1132
  return (rstatus);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1133
1134
1135
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
1136
int cgribexScanTimestep(int streamID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1137
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1138
1139
  int rstatus = 0;
#if  defined  (HAVE_LIBCGRIBEX)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1140
1141
  int *isec0, *isec1, *isec2, *isec3, *isec4;
  double fsec2[512], fsec3[2], *fsec4 = NULL;
1142
  int lmv = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1143
1144
1145
1146
  long recsize = 0;
  off_t recpos = 0;
  unsigned char *gribbuffer;
  long buffersize = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1147
  int fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1148
1149
  int param = 0;
  int level1 = 0, level2 = 0, vdate = 0, vtime = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1150
1151
1152
1153
1154
1155
  DateTime datetime, datetime0;
  int tsID;
  int vrecID, recID;
  int warn_numavg = TRUE;
  size_t readsize;
  int taxisID = -1;
1156
  taxis_t *taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1157
1158
1159
1160
  int vlistID;
  int rindex, nrecs = 0;
  long unzipsize;
  compvar_t compVar, compVar0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1161
  stream_t *streamptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1162
1163

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