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

#include <float.h>

#include "dmemory.h"

#include "error.h"
#include "file.h"
#include "cdi.h"
12
#include "cdi_int.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
13
14
15
#include "varscan.h"
#include "datetime.h"
#include "ieg.h"
16
#include "stream_ieg.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
17
#include "vlist.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
18
#include "exse.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
19
20
21
22


#if defined (HAVE_LIBIEG)

23
typedef struct {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
24
  int param;
25
  int level;
26
} iegcompvar_t;
27
28


29
30
static
int iegInqDatatype(int prec)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
31
{
32
  return (prec == EXSE_DOUBLE_PRECISION) ? CDI_DATATYPE_FLT64 : CDI_DATATYPE_FLT32;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
33
34
}

35
36
static
int iegDefDatatype(int datatype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
37
{
38
  if ( datatype == CDI_DATATYPE_CPX32 || datatype == CDI_DATATYPE_CPX64 )
39
    Error("CDI/IEG library does not support complex numbers!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
40

41
42
  if ( datatype != CDI_DATATYPE_FLT32 && datatype != CDI_DATATYPE_FLT64 )
    datatype = CDI_DATATYPE_FLT32;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
43

44
  return (datatype == CDI_DATATYPE_FLT64) ? EXSE_DOUBLE_PRECISION : EXSE_SINGLE_PRECISION;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
45
46
}

47
/* not used
48
int iegInqRecord(stream_t *streamptr, int *varID, int *levelID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
49
50
51
{
  int status;
  int fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
52
  int icode, ilevel;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
53
54
  int zaxisID = -1;
  int vlistID;
55
  iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
56

Uwe Schulzweida's avatar
Uwe Schulzweida committed
57
58
  vlistID = streamptr->vlistID;
  fileID  = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
59
60
61
62
63

  *varID   = -1;
  *levelID = -1;

  status = iegRead(fileID, iegp);
64
  if ( status != 0 ) return 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
65

Uwe Schulzweida's avatar
Uwe Schulzweida committed
66
  icode  = IEG_P_Parameter(iegp->ipdb);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
67
68
69
70
71
  if ( IEG_P_LevelType(iegp->ipdb) == IEG_LTYPE_HYBRID_LAYER )
    ilevel = IEG_P_Level1(iegp->ipdb);
  else
    ilevel = IEG_P_Level2(iegp->ipdb);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
72
  *varID = vlistInqVarID(vlistID, icode);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
73

74
  if ( *varID == CDI_UNDEFID ) Error("Code %d undefined", icode);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
75
76
77
78

  zaxisID = vlistInqVarZaxis(vlistID, *varID);

  *levelID = zaxisInqLevelID(zaxisID, (double) ilevel);
79

80
  return 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
81
}
82
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
83

84
void iegReadRecord(stream_t *streamptr, double *data, int *nmiss)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
85
{
86
87
88
89
90
91
92
  int vlistID = streamptr->vlistID;
  int fileID  = streamptr->fileID;
  int tsID    = streamptr->curTsID;
  int vrecID  = streamptr->tsteps[tsID].curRecID;
  int recID   = streamptr->tsteps[tsID].recIDs[vrecID];
  int varID   = streamptr->tsteps[tsID].records[recID].varID;
  off_t recpos = streamptr->tsteps[tsID].records[recID].position;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
93
94
95

  fileSetPos(fileID, recpos, SEEK_SET);

96
  void *iegp = streamptr->record->exsep;
97
  int status = iegRead(fileID, iegp);
98
99
  if ( status != 0 )
    Error("Could not read IEG record!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
100
101
102

  iegInqDataDP(iegp, data);

103
104
  double missval = vlistInqVarMissval(vlistID, varID);
  int gridID  = vlistInqVarGrid(vlistID, varID);
105
  size_t size = gridInqSize(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
106

Uwe Schulzweida's avatar
Uwe Schulzweida committed
107
  streamptr->numvals += size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
108
109

  *nmiss = 0;
110
  for ( size_t i = 0; i < size; i++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
111
112
113
114
115
116
117
    if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
      {
	data[i] = missval;
	(*nmiss)++;
      }
}

118
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
int iegGetZaxisType(int iegleveltype)
{
  int leveltype = 0;

  switch ( iegleveltype )
    {
    case IEG_LTYPE_SURFACE:
      {
	leveltype = ZAXIS_SURFACE;
	break;
      }
    case IEG_LTYPE_99:
    case IEG_LTYPE_ISOBARIC:
      {
	leveltype = ZAXIS_PRESSURE;
	break;
      }
    case IEG_LTYPE_HEIGHT:
      {
	leveltype = ZAXIS_HEIGHT;
	break;
      }
    case IEG_LTYPE_ALTITUDE:
      {
	leveltype = ZAXIS_ALTITUDE;
	break;
      }
    case IEG_LTYPE_HYBRID:
    case IEG_LTYPE_HYBRID_LAYER:
      {
	leveltype = ZAXIS_HYBRID;
	break;
      }
    case IEG_LTYPE_LANDDEPTH:
    case IEG_LTYPE_LANDDEPTH_LAYER:
      {
	leveltype = ZAXIS_DEPTH_BELOW_LAND;
	break;
      }
    case IEG_LTYPE_SEADEPTH:
      {
	leveltype = ZAXIS_DEPTH_BELOW_SEA;
	break;
      }
    default:
      {
	leveltype = ZAXIS_GENERIC;
	break;
      }
    }

170
  return leveltype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
171
172
173
}


Thomas Jahns's avatar
Thomas Jahns committed
174
static void iegDefTime(int *pdb, int date, int time, int taxisID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
175
176
{
  int timetype = -1;
177
  if ( taxisID != -1 ) timetype = taxisInqType(taxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
178
179
180

  if ( timetype == TAXIS_ABSOLUTE || timetype == TAXIS_RELATIVE )
    {
181
      int year, month, day, hour, minute, second;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
182
183
      cdiDecodeDate(date, &year, &month, &day);
      cdiDecodeTime(time, &hour, &minute, &second);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200

      IEG_P_Year(pdb)     = year;
      IEG_P_Month(pdb)    = month;
      IEG_P_Day(pdb)      = day;
      IEG_P_Hour(pdb)     = hour;
      IEG_P_Minute(pdb)   = minute;

      pdb[15] = 1;
      pdb[16] = 0;
      pdb[17] = 0;
      pdb[18] = 10;
      pdb[36] = 1;
    }

  pdb[5] = 128;
}

Thomas Jahns's avatar
Thomas Jahns committed
201
202
203
204
205
/* find smallest power of 10 in [1000,10000000] that upon
 * multiplication results in fractional part close to zero for all
 * arguments */
static double
calc_resfac(double xfirst, double xlast, double xinc, double yfirst, double ylast, double yinc)
206
{
Thomas Jahns's avatar
Thomas Jahns committed
207
208
209
210
211
212
213
214
215
216
  double resfac = 1000.0;
  enum {
    nPwrOf10 = 5,
    nMultTests = 6,
  };
  static const double scaleFactors[nPwrOf10]
    = { 1000, 10000, 100000, 1000000, 10000000 };
  double vals[nMultTests] = { xfirst, xlast, xinc, yfirst, ylast, yinc };

  for (size_t j = 0; j < nPwrOf10; ++j )
217
    {
Thomas Jahns's avatar
Thomas Jahns committed
218
219
220
      double scaleBy = scaleFactors[j];
      bool fractionalScale = false;
      for (size_t i = 0; i < nMultTests; ++i )
221
        {
Thomas Jahns's avatar
Thomas Jahns committed
222
223
          fractionalScale = fractionalScale
            || fabs(vals[i]*scaleBy - round(vals[i]*scaleBy)) > FLT_EPSILON;
224
        }
Thomas Jahns's avatar
Thomas Jahns committed
225
      if ( !fractionalScale )
226
        {
Thomas Jahns's avatar
Thomas Jahns committed
227
          resfac = scaleBy;
228
229
230
231
          break;
        }
    }

232
  return resfac;
233
234
}

235
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
236
237
void iegDefGrid(int *gdb, int gridID)
{
238
239
240
  int projID = gridInqProj(gridID);
  if ( projID != CDI_UNDEFID && gridInqProjType(projID) == CDI_PROJ_RLL ) gridID = projID;

241
  int gridtype = gridInqType(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
242

243
244
245
  int projtype = CDI_UNDEFID;
  if ( gridtype == GRID_PROJECTION && gridInqProjType(gridID) == CDI_PROJ_RLL ) projtype = CDI_PROJ_RLL;

246
247
248
  size_t xsize = gridInqXsize(gridID);
  size_t ysize = gridInqYsize(gridID);

249
  cdi_check_gridsize_int_limit("IEG", xsize*ysize);
250

Uwe Schulzweida's avatar
Uwe Schulzweida committed
251
252
  if ( gridtype == GRID_GENERIC )
    {
253
      if ( (ysize == 32  || ysize == 48 || ysize == 64 ||
254
	    ysize == 96  || ysize == 160) &&
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
	   (xsize == 2*ysize || xsize == 1) )
	{
	  gridtype = GRID_GAUSSIAN;
	  gridChangeType(gridID, gridtype);
	}
      else if ( (xsize == 1 && ysize == 1) || (xsize == 0 && ysize == 0) )
	{
	  gridtype = GRID_LONLAT;
	  gridChangeType(gridID, gridtype);
	}
      else if ( gridInqXvals(gridID, NULL) && gridInqYvals(gridID, NULL) )
	{
	  gridtype = GRID_LONLAT;
	  gridChangeType(gridID, gridtype);
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
270
271
272
273
274
275
    }
  else if ( gridtype == GRID_CURVILINEAR )
    {
      gridtype = GRID_LONLAT;
    }

276
  bool lrotated = (projtype == CDI_PROJ_RLL);
277
278

  if ( gridtype == GRID_LONLAT || gridtype == GRID_GAUSSIAN || projtype == CDI_PROJ_RLL )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
279
    {
280
281
      double xfirst = 0, xlast = 0, xinc = 0;
      double yfirst = 0, ylast = 0, yinc = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
282

283
      if ( xsize == 0 ) xsize = 1;
284
285
      else
	{
286
287
	  xfirst = gridInqXval(gridID,       0);
	  xlast  = gridInqXval(gridID, xsize-1);
288
289
290
	  xinc   = gridInqXinc(gridID);
	}

291
      if ( ysize == 0 ) ysize = 1;
292
293
      else
	{
294
295
	  yfirst = gridInqYval(gridID,       0);
	  ylast  = gridInqYval(gridID, ysize-1);
296
297
298
	  yinc   = gridInqYinc(gridID);
	}

299
300
      if ( gridtype == GRID_GAUSSIAN )
	IEG_G_GridType(gdb) = 4;
301
      else if ( lrotated )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
302
303
304
305
	IEG_G_GridType(gdb) = 10;
      else
	IEG_G_GridType(gdb) = 0;

Thomas Jahns's avatar
Thomas Jahns committed
306
307
      double resfac = calc_resfac(xfirst, xlast, xinc, yfirst, ylast, yinc);
      int iresfac = (int)resfac;
308
309
310
311
      if ( iresfac == 1000 ) iresfac = 0;

      IEG_G_ResFac(gdb)   = iresfac;

312
313
      IEG_G_NumLon(gdb)   = (int)xsize;
      IEG_G_NumLat(gdb)   = (int)ysize;
314
315
316
317
318
      IEG_G_FirstLat(gdb) = (int)lround(yfirst*resfac);
      IEG_G_LastLat(gdb)  = (int)lround(ylast*resfac);
      IEG_G_FirstLon(gdb) = (int)lround(xfirst*resfac);
      IEG_G_LastLon(gdb)  = (int)lround(xlast*resfac);
      IEG_G_LonIncr(gdb)  = (int)lround(xinc*resfac);
319
      if ( fabs(xinc*resfac - IEG_G_LonIncr(gdb)) > FLT_EPSILON )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
320
321
	IEG_G_LonIncr(gdb) = 0;

322
      if ( gridtype == GRID_GAUSSIAN )
323
	IEG_G_LatIncr(gdb) = (int)ysize/2;
324
325
      else
	{
326
	  IEG_G_LatIncr(gdb) = (int)lround(yinc*resfac);
327
	  if ( fabs(yinc*resfac - IEG_G_LatIncr(gdb)) > FLT_EPSILON )
328
	    IEG_G_LatIncr(gdb) = 0;
329
330

	  if ( IEG_G_LatIncr(gdb) < 0 ) IEG_G_LatIncr(gdb) = -IEG_G_LatIncr(gdb);
331
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
332

333
      if ( IEG_G_NumLon(gdb) > 1 && IEG_G_NumLat(gdb) == 1 )
334
335
	if ( IEG_G_LonIncr(gdb) != 0 && IEG_G_LatIncr(gdb) == 0 ) IEG_G_LatIncr(gdb) = IEG_G_LonIncr(gdb);

336
      if ( IEG_G_NumLon(gdb) == 1 && IEG_G_NumLat(gdb) > 1 )
337
338
	if ( IEG_G_LonIncr(gdb) == 0 && IEG_G_LatIncr(gdb) != 0 ) IEG_G_LonIncr(gdb) = IEG_G_LatIncr(gdb);

339
      IEG_G_ResFlag(gdb) = (IEG_G_LatIncr(gdb) == 0 || IEG_G_LonIncr(gdb) == 0) ? 0 : 128;
340

341
      if ( lrotated )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
342
	{
343
          double xpole = 0, ypole = 0, angle = 0;
344
          gridInqParamRLL(gridID, &xpole, &ypole, &angle);
345
346
347

	  IEG_G_LatSP(gdb) = - (int)lround(ypole * resfac);
	  IEG_G_LonSP(gdb) =   (int)lround((xpole + 180) * resfac);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
348
349
350
351
352
353
354
355
356
	  IEG_G_Size(gdb)  = 42;
	}
      else
	{
	  IEG_G_Size(gdb)  = 32;
	}
    }
  else
    {
357
      Error("Unsupported grid type: %s", gridNamePtr(gridtype));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
358
359
360
361
362
    }

  IEG_G_ScanFlag(gdb) = 64;
}

363
364
365
366
367
368
369
370
static
void pdbDefLevel(int *pdb, int leveltype, int level1, int level2)
{
  IEG_P_LevelType(pdb) = leveltype;
  IEG_P_Level1(pdb)    = level1;
  IEG_P_Level2(pdb)    = level2;
}

371
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
372
373
374
void iegDefLevel(int *pdb, int *gdb, double *vct, int zaxisID, int levelID)
{
  double level;
375
  int ilevel;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
376

377
  int leveltype = zaxisInqType(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
378
379
380

  if ( leveltype == ZAXIS_GENERIC )
    {
381
      Message("Changed zaxis type from %s to %s",
382
	      zaxisNamePtr(leveltype), zaxisNamePtr(ZAXIS_PRESSURE));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
383
384
      leveltype = ZAXIS_PRESSURE;
      zaxisChangeType(zaxisID, leveltype);
385
      zaxisDefUnits(zaxisID, "Pa");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
386
387
388
389
390
391
392
393
    }

  /*  IEG_G_NumVCP(gdb) = 0; */

  switch (leveltype)
    {
    case ZAXIS_SURFACE:
      {
394
        pdbDefLevel(pdb, IEG_LTYPE_SURFACE, 0, (int)(zaxisInqLevel(zaxisID, levelID)));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
395
396
397
398
399
	break;
      }
    case ZAXIS_HYBRID:
      {
	if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
400
401
          pdbDefLevel(pdb, IEG_LTYPE_HYBRID_LAYER, (int)(zaxisInqLbound(zaxisID, levelID)),
                      (int)(zaxisInqUbound(zaxisID, levelID)));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
402
	else
403
          pdbDefLevel(pdb, IEG_LTYPE_HYBRID, 0, (int)(zaxisInqLevel(zaxisID, levelID)));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
404

405
	int vctsize = zaxisInqVctSize(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
406
407
	if ( vctsize > 100 )
	  {
408
            static bool vct_warning = true;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
409
410
411
	    /*	    IEG_G_NumVCP(gdb) = 0; */
	    if ( vct_warning )
	      {
412
		Warning("VCT size of %d is too large (maximum is 100). Set to 0!", vctsize);
413
		vct_warning = false;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
414
415
416
417
418
	      }
	  }
	else
	  {
	    IEG_G_Size(gdb) += (vctsize*4);
419
420
	    memcpy(vct, zaxisInqVctPtr(zaxisID), (size_t)vctsize/2*sizeof(double));
	    memcpy(vct+50, zaxisInqVctPtr(zaxisID)+vctsize/2, (size_t)vctsize/2*sizeof(double));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
421
422
423
424
425
426
	  }
	break;
      }
    case ZAXIS_PRESSURE:
      {
	double dum;
427
	char units[CDI_MAX_NAME];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
428
429

	level = zaxisInqLevel(zaxisID, levelID);
430
	if ( level < 0 ) Warning("pressure level of %f Pa is below 0.", level);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
431
432

	zaxisInqUnits(zaxisID, units);
433
	if ( memcmp(units, "hPa", 3) == 0 || memcmp(units, "mb",2 ) == 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
434
435
436
437
	  level = level*100;

	ilevel = (int) level;
	if ( level < 32768 && (level < 100 || modf(level/100, &dum) > 0) )
438
          pdbDefLevel(pdb, IEG_LTYPE_99, 0, ilevel);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
439
	else
440
441
442
          pdbDefLevel(pdb, IEG_LTYPE_ISOBARIC, 0, ilevel/100);

        break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
443
444
445
446
      }
    case ZAXIS_HEIGHT:
      {
	level = zaxisInqLevel(zaxisID, levelID);
447
        pdbDefLevel(pdb, IEG_LTYPE_HEIGHT, 0, (int)level);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
448
449
450
451
452
	break;
      }
    case ZAXIS_ALTITUDE:
      {
	level = zaxisInqLevel(zaxisID, levelID);
453
        pdbDefLevel(pdb, IEG_LTYPE_ALTITUDE, 0, (int)level);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
454
455
456
457
458
	break;
      }
    case ZAXIS_DEPTH_BELOW_LAND:
      {
	if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
459
          pdbDefLevel(pdb, IEG_LTYPE_LANDDEPTH_LAYER, (int)(zaxisInqLbound(zaxisID, levelID)), (int)(zaxisInqUbound(zaxisID, levelID)));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
460
	else
461
          pdbDefLevel(pdb, IEG_LTYPE_LANDDEPTH, 0, (int)(zaxisInqLevel(zaxisID, levelID)));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
462
463
464
465
466
467

	break;
      }
    case ZAXIS_DEPTH_BELOW_SEA:
      {
	level = zaxisInqLevel(zaxisID, levelID);
468
        pdbDefLevel(pdb, IEG_LTYPE_SEADEPTH, 0, (int)level);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
469
470
471
472
473
	break;
      }
    case ZAXIS_ISENTROPIC:
      {
	level = zaxisInqLevel(zaxisID, levelID);
474
        pdbDefLevel(pdb, 113, 0, (int)level);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
475
476
477
478
	break;
      }
    default:
      {
479
	Error("Unsupported zaxis type: %s", zaxisNamePtr(leveltype));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
480
481
482
483
484
485
	break;
      }
    }
}


486
void iegCopyRecord(stream_t *streamptr2, stream_t *streamptr1)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
487
{
488
  streamFCopyRecord(streamptr2, streamptr1, "IEG");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
489
490
491
}


492
void iegDefRecord(stream_t *streamptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
493
{
494
495
  Record *record = streamptr->record;
  iegrec_t *iegp = (iegrec_t*) record->exsep;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
496

497
498
  int vlistID = streamptr->vlistID;
  int byteorder = streamptr->byteorder;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
499

500
501
  int varID   = record->varID;
  int levelID = record->levelID;
502
  int tsID    = streamptr->curTsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
503

504
505
  int gridID  = vlistInqVarGrid(vlistID, varID);
  int zaxisID = vlistInqVarZaxis(vlistID, varID);
506

507
  iegInitMem(iegp);
508
  for ( int i = 0; i < 37; i++ ) iegp->ipdb[i] = -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
509
510
511

  iegp->byteswap = getByteswap(byteorder);

512
  int param = vlistInqVarParam(vlistID, varID);
513
  int pdis, pcat, pnum;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
514
  cdiDecodeParam(param, &pnum, &pcat, &pdis);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
515
516
  IEG_P_Parameter(iegp->ipdb) = pnum;
  if ( pdis == 255 ) IEG_P_CodeTable(iegp->ipdb) = pcat;
517

518
519
  int date = streamptr->tsteps[tsID].taxis.vdate;
  int time = streamptr->tsteps[tsID].taxis.vtime;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
520
521
522
523
  iegDefTime(iegp->ipdb, date, time, vlistInqTaxis(vlistID));
  iegDefGrid(iegp->igdb, gridID);
  iegDefLevel(iegp->ipdb, iegp->igdb, iegp->vct, zaxisID, levelID);

524
  iegp->dprec = iegDefDatatype(record->prec);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
525
526
527
}


528
void iegWriteRecord(stream_t *streamptr, const double *data)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
529
{
530
531
  Record *record = streamptr->record;
  iegrec_t *iegp = (iegrec_t*) record->exsep;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
532

533
  int fileID = streamptr->fileID;
534
  size_t gridsize = gridInqSize(record->gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
535

536
  double refval = data[0];
537
  for ( size_t i = 1; i < gridsize; i++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
538
539
540
541
542
543
544
545
    if ( data[i] < refval ) refval = data[i];

  iegp->refval = refval;

  iegDefDataDP(iegp, data);
  iegWrite(fileID, iegp);
}

546
static
547
void iegAddRecord(stream_t *streamptr, int param, int *pdb, int *gdb, double *vct,
548
		  size_t recsize, off_t position, int prec)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
549
{
550
551
552
553
  int vlistID = streamptr->vlistID;
  int tsID    = streamptr->curTsID;
  int recID   = recordNewEntry(streamptr, tsID);
  record_t *record = &streamptr->tsteps[tsID].records[recID];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
554

555
  int level1, level2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
556
557
558
559
560
561
562
563
564
  if ( IEG_P_LevelType(pdb) == IEG_LTYPE_HYBRID_LAYER )
    {
      level1 = IEG_P_Level1(pdb);
      level2 = IEG_P_Level2(pdb);
    }
  else
    {
      level1 = IEG_P_Level2(pdb);
      level2 = 0;
565
      if ( IEG_P_LevelType(pdb) == 100 ) level1 *= 100;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
566
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
567

568
569
570
571
572
573
  record->size     = recsize;
  record->position = position;
  record->param    = param;
  record->ilevel   = level1;
  record->ilevel2  = level2;
  record->ltype    = IEG_P_LevelType(pdb);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
574

575
576
577
  int gridtype = (IEG_G_GridType(gdb) == 0) ? GRID_LONLAT :
                 (IEG_G_GridType(gdb) == 10) ? GRID_PROJECTION :
                 (IEG_G_GridType(gdb) == 4) ? GRID_GAUSSIAN : GRID_GENERIC;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
578

579
580
  grid_t *grid = (grid_t *)Malloc(sizeof (*grid));
  grid_init(grid);
581
  cdiGridTypeInit(grid, gridtype, IEG_G_NumLon(gdb)*IEG_G_NumLat(gdb));
582
583
  size_t xsize = (size_t)IEG_G_NumLon(gdb);
  size_t ysize = (size_t)IEG_G_NumLat(gdb);
584
585
  grid->x.size = xsize;
  grid->y.size = ysize;
586
587
588
  grid->x.inc  = 0;
  grid->y.inc  = 0;
  grid->x.flag = 0;
589
590
591
592
593

  int iresfac = IEG_G_ResFac(gdb);
  if ( iresfac == 0 ) iresfac = 1000;
  double resfac = 1./(double) iresfac;

594
595
  /* if ( IEG_G_FirstLon != 0 || IEG_G_LastLon != 0 ) */
  {
596
    if ( xsize > 1 )
597
598
      {
	if ( IEG_G_ResFlag(gdb) && IEG_G_LonIncr(gdb) > 0 )
599
	  grid->x.inc = IEG_G_LonIncr(gdb) * resfac;
600
	else
601
	  grid->x.inc = (IEG_G_LastLon(gdb) - IEG_G_FirstLon(gdb)) * resfac / (xsize - 1);
602
603
604
605

	/* correct xinc if necessary */
	if ( IEG_G_FirstLon(gdb) == 0 && IEG_G_LastLon(gdb) > 354000 )
	  {
606
	    double xinc = 360. / xsize;
607
608
            /* FIXME: why not use grid->x.inc != xinc as condition? */
	    if ( fabs(grid->x.inc-xinc) > 0.0 )
609
	      {
610
611
		grid->x.inc = xinc;
		if ( CDI_Debug ) Message("set xinc to %g", grid->x.inc);
612
613
614
	      }
	  }
      }
615
616
617
    grid->x.first = IEG_G_FirstLon(gdb) * resfac;
    grid->x.last  = IEG_G_LastLon(gdb)  * resfac;
    grid->x.flag  = 2;
618
  }
619
  grid->y.flag = 0;
620
621
  /* if ( IEG_G_FirstLat != 0 || IEG_G_LastLat != 0 ) */
  {
622
    if ( ysize > 1 )
623
624
      {
	if ( IEG_G_ResFlag(gdb) && IEG_G_LatIncr(gdb) > 0 )
625
	  grid->y.inc = IEG_G_LatIncr(gdb) * resfac;
626
	else
627
	  grid->y.inc = (IEG_G_LastLat(gdb) - IEG_G_FirstLat(gdb)) * resfac / (ysize - 1);
628
      }
629
630
631
    grid->y.first = IEG_G_FirstLat(gdb) * resfac;
    grid->y.last  = IEG_G_LastLat(gdb)  * resfac;
    grid->y.flag  = 2;
632
  }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
633

634
  double xpole = 0, ypole = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
635
636
  if ( IEG_G_GridType(gdb) == 10 )
    {
637
638
      xpole =   IEG_G_LonSP(gdb) * resfac - 180;
      ypole = - IEG_G_LatSP(gdb) * resfac;
639
      grid->projtype = CDI_PROJ_RLL;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
640
641
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
642
  struct addIfNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, grid, 0);
643
  int gridID = gridAdded.Id;
644
  if ( !gridAdded.isNew ) Free(grid);
645
  else if ( gridtype == GRID_PROJECTION ) gridDefParamRLL(gridID, xpole, ypole, 0);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
646

647
  int leveltype = iegGetZaxisType(IEG_P_LevelType(pdb));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
648
649
650
  if ( leveltype == ZAXIS_HYBRID )
    {
      double tmpvct[100];
651
      size_t vctsize = (size_t)IEG_G_NumVCP(gdb);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
652

653
      for ( size_t i = 0; i < vctsize/2; i++ ) tmpvct[i] = vct[i];
654
      for ( size_t i = 0; i < vctsize/2; i++ ) tmpvct[i+vctsize/2] = vct[i+50];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
655
656
657
658

      varDefVCT(vctsize, tmpvct);
    }

659
  int lbounds = IEG_P_LevelType(pdb) == IEG_LTYPE_HYBRID_LAYER ? 1 : 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
660

661
  int datatype = iegInqDatatype(prec);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
662

663
  int varID;
664
  int levelID = 0;
665
  varAddRecord(recID, param, gridID, leveltype, lbounds, level1, level2, 0, 0,
666
667
	       datatype, &varID, &levelID, TSTEP_INSTANT, 0, 0, -1,
               NULL, NULL, NULL, NULL, NULL, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
668

669
670
  record->varID   = (short)varID;
  record->levelID = (short)levelID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
671

Uwe Schulzweida's avatar
Uwe Schulzweida committed
672
673
  streamptr->tsteps[tsID].nallrecs++;
  streamptr->nrecs++;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
674
675

  if ( CDI_Debug )
676
    Message("varID = %d gridID = %d levelID = %d", varID, gridID, levelID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
677
678
}

Thomas Jahns's avatar
Thomas Jahns committed
679
#if 0
680
static
681
void iegCmpRecord(stream_t *streamptr, int tsID, int recID, off_t position, int param,
682
		  int level, size_t xsize, size_t ysize)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
683
684
685
{
  int varID = 0;
  int levelID = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
686

687
  record_t *record  = &streamptr->tsteps[tsID].records[recID];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
688

Uwe Schulzweida's avatar
Uwe Schulzweida committed
689
  if ( param != (*record).param || level != (*record).ilevel )
690
    Error("inconsistent timestep");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
691
692
693
694
695
696

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
697
  streamptr->vars[varID].level[levelID] = recID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
698

Uwe Schulzweida's avatar
Uwe Schulzweida committed
699
700
  streamptr->tsteps[tsID].nallrecs++;
  streamptr->nrecs++;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
701
702
  */
  if ( CDI_Debug )
703
    Message("varID = %d levelID = %d", varID, levelID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
704
}
Thomas Jahns's avatar
Thomas Jahns committed
705
#endif
706

707
708
static
void iegDateTime(int *pdb, int *date, int *time)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
709
{
710
711
712
  int ryear   = IEG_P_Year(pdb);
  int rmonth  = IEG_P_Month(pdb);
  int rday    = IEG_P_Day(pdb);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
713

714
715
  int rhour   = IEG_P_Hour(pdb);
  int rminute = IEG_P_Minute(pdb);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
716
717
718

  if ( rminute == -1 ) rminute = 0;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
719
720
  *date = cdiEncodeDate(ryear, rmonth, rday);
  *time = cdiEncodeTime(rhour, rminute, 0);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
721
722
}

723
static
724
725
void iegScanTimestep1(stream_t *streamptr)
{
726
  DateTime datetime0 = { LONG_MIN, LONG_MIN };
Uwe Schulzweida's avatar
Uwe Schulzweida committed
727
  off_t recpos;
728
  iegcompvar_t compVar, compVar0;
729
  iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
730

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

733
  int tsID = tstepsNewEntry(streamptr);
734
  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
735
736

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

739
  int fileID = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
740

741
  int nrecs = 0;
742
  while ( true )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
743
744
    {
      recpos = fileGetPos(fileID);
745
      int status = iegRead(fileID, iegp);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
746
747
      if ( status != 0 )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
748
	  streamptr->ntsteps = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
749
750
	  break;
	}
751
      size_t recsize = (size_t)(fileGetPos(fileID) - recpos);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
752

753
754
755
756
      int prec   = iegp->dprec;
      int rcode  = IEG_P_Parameter(iegp->ipdb);
      int tabnum = IEG_P_CodeTable(iegp->ipdb);
      int param  = cdiEncodeParam(rcode, tabnum, 255);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
757

758
      int rlevel = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
759
760
761
762
763
      if ( IEG_P_LevelType(iegp->ipdb) == IEG_LTYPE_HYBRID_LAYER )
	rlevel = IEG_P_Level1(iegp->ipdb);
      else
	rlevel = IEG_P_Level2(iegp->ipdb);

764
765
      if ( IEG_P_LevelType(iegp->ipdb) == 100 ) rlevel *= 100;

766
      int vdate = 0, vtime = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
767
768
769
770
771
772
773
774
775
      iegDateTime(iegp->ipdb, &vdate, &vtime);

      if ( nrecs == 0 )
	{
	  datetime0.date = vdate;
	  datetime0.time = vtime;
	}
      else
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
776
	  compVar.param = param;
777
          compVar.level = rlevel;
778
          int recID = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
779
780
	  for ( recID = 0; recID < nrecs; recID++ )
	    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
781
	      compVar0.param = streamptr->tsteps[0].records[recID].param;
782
783
	      compVar0.level = streamptr->tsteps[0].records[recID].ilevel;

784
	      if ( memcmp(&compVar0, &compVar, sizeof(iegcompvar_t)) == 0 ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
785
786
	    }
	  if ( recID < nrecs ) break;
787
788
	  DateTime datetime = { .date = vdate, .time = vtime};
	  if ( datetimeCmp(datetime, datetime0) )
789
	    Warning("Inconsistent verification time for param %d level %d", param, rlevel);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
790
791
792
793
794
	}

      nrecs++;

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

797
      iegAddRecord(streamptr, param, iegp->ipdb, iegp->igdb, iegp->vct, recsize, recpos, prec);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
798
799
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
800
  streamptr->rtsteps = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
801

802
  cdi_generate_vars(streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
803

804
  int taxisID = taxisCreate(TAXIS_ABSOLUTE);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
805
  taxis->type  = TAXIS_ABSOLUTE;
806
807
  taxis->vdate = (int)datetime0.date;
  taxis->vtime = (int)datetime0.time;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
808

809
  int vlistID = streamptr->vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
810
811
  vlistDefTaxis(vlistID, taxisID);

812
  vlist_check_contents(vlistID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
813

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

823
  streamptr->tsteps[0].recIDs = (int *) Malloc((size_t)nrecords * sizeof (int));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
824
  streamptr->tsteps[0].nrecs = nrecords;
825
  for ( int recID = 0; recID < nrecords; recID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
826
    streamptr->tsteps[0].recIDs[recID] = recID;
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(streamptr);
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

834
      streamptr->tsteps[tsID-1].next   = true;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
835
      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
	  streamptr->ntsteps = 0;
843
	  for ( int varID = 0; varID < streamptr->nvars; varID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
844
	    {
845
	      vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
846
847
848
849
850
	    }
	}
    }
}

851
static
852
int iegScanTimestep2(stream_t *streamptr)
853
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
854
  off_t recpos = 0;
855
  iegcompvar_t compVar, compVar0;
856
  iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
857
858

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

860
861
  int vlistID = streamptr->vlistID;
  int fileID  = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
862

863
  int tsID = streamptr->rtsteps;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
864
  if ( tsID != 1 )
865
    Error("Internal problem! unexpected timestep %d", tsID+1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
866

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

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

871
  cdi_create_records(streamptr, tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
872

873
  int nrecords = streamptr->tsteps[0].nallrecs;
874
  streamptr->tsteps[1].recIDs = (int *) Malloc((size_t)nrecords * sizeof(int));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
875
  streamptr->tsteps[1].nrecs = 0;
876
  for ( int recID = 0; recID < nrecords; recID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
877
    streamptr->tsteps[1].recIDs[recID] = -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
878

879
  for ( int recID = 0; recID < nrecords; recID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
880
    {
881
      streamptr->tsteps[tsID].records[recID].position =
Uwe Schulzweida's avatar
Uwe Schulzweida committed
882
	streamptr->tsteps[0].records[recID].position;
883
      streamptr->tsteps[tsID].records[recID].size     =
Uwe Schulzweida's avatar
Uwe Schulzweida committed
884
	streamptr->tsteps[0].records[recID].size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
885
886
    }

887
  for ( int rindex = 0; rindex <= nrecords; rindex++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
888
889
    {
      recpos = fileGetPos(fileID);
890
      int status = iegRead(fileID, iegp);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
891
892
      if ( status != 0 )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
893
	  streamptr->ntsteps = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
894
895
	  break;
	}
896
      size_t recsize = (size_t)(fileGetPos(fileID) - recpos);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
897

898
899
900
      int rcode  = IEG_P_Parameter(iegp->ipdb);
      int tabnum = IEG_P_CodeTable(iegp->ipdb);
      int param  = cdiEncodeParam(rcode, tabnum, 255);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
901

902
      int rlevel = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
903
904
905
906
907
      if ( IEG_P_LevelType(iegp->ipdb) == IEG_LTYPE_HYBRID_LAYER )
	rlevel = IEG_P_Level1(iegp->ipdb);
      else
	rlevel = IEG_P_Level2(iegp->ipdb);

908
909
      if ( IEG_P_LevelType(iegp->ipdb) == 100 ) rlevel *= 100;

910
      int vdate = 0, vtime = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
911
912
913
914
915
916
917
918
919
      iegDateTime(iegp->ipdb, &vdate, &vtime);

      if ( rindex == 0 )
	{
	  taxis->type  = TAXIS_ABSOLUTE;
	  taxis->vdate = vdate;
	  taxis->vtime = vtime;
	}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
920
      compVar.param = param;
921
      compVar.level = rlevel;
922
923