stream_ieg.c 32.5 KB
Newer Older
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1
2
#ifdef HAVE_CONFIG_H
#include "config.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
3
4
5
6
7
8
9
10
11
#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_scan.h"
17
#include "stream_ieg.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
18
#include "exse.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
19
20


Uwe Schulzweida's avatar
Uwe Schulzweida committed
21
#ifdef HAVE_LIBIEG
Uwe Schulzweida's avatar
Uwe Schulzweida committed
22

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
void iegReadRecord(stream_t *streamptr, double *data, size_t *nmiss)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
48
{
49
50
51
52
53
54
55
  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
56
57
58

  fileSetPos(fileID, recpos, SEEK_SET);

59
  void *iegp = streamptr->record->exsep;
60
  int status = iegRead(fileID, iegp);
61
  if ( status != 0 ) Error("Could not read IEG record!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
62
63
64

  iegInqDataDP(iegp, data);

65
66
  double missval = vlistInqVarMissval(vlistID, varID);
  int gridID  = vlistInqVarGrid(vlistID, varID);
67
  size_t size = gridInqSize(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
68

Uwe Schulzweida's avatar
Uwe Schulzweida committed
69
  streamptr->numvals += size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
70
71

  *nmiss = 0;
72
  for ( size_t i = 0; i < size; i++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
73
74
75
76
77
78
79
    if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
      {
	data[i] = missval;
	(*nmiss)++;
      }
}

80
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
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;
      }
    }

132
  return leveltype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
133
134
135
}


136
static void iegDefTime(int *pdb, int64_t date, int time, int taxisID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
137
{
138
  int timetype = (taxisID != -1) ? taxisInqType(taxisID) : -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
139
140
  if ( timetype == TAXIS_ABSOLUTE || timetype == TAXIS_RELATIVE )
    {
141
      int year, month, day, hour, minute, second;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
142
143
      cdiDecodeDate(date, &year, &month, &day);
      cdiDecodeTime(time, &hour, &minute, &second);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160

      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
161
162
163
164
165
/* 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)
166
{
Thomas Jahns's avatar
Thomas Jahns committed
167
168
169
170
171
172
173
174
175
176
  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 )
177
    {
Thomas Jahns's avatar
Thomas Jahns committed
178
179
180
      double scaleBy = scaleFactors[j];
      bool fractionalScale = false;
      for (size_t i = 0; i < nMultTests; ++i )
181
        {
182
          fractionalScale = fractionalScale || fabs(vals[i]*scaleBy - round(vals[i]*scaleBy)) > FLT_EPSILON;
183
        }
Thomas Jahns's avatar
Thomas Jahns committed
184
      if ( !fractionalScale )
185
        {
Thomas Jahns's avatar
Thomas Jahns committed
186
          resfac = scaleBy;
187
188
189
190
          break;
        }
    }

191
  return resfac;
192
193
}

194
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
195
196
void iegDefGrid(int *gdb, int gridID)
{
197
198
199
  int projID = gridInqProj(gridID);
  if ( projID != CDI_UNDEFID && gridInqProjType(projID) == CDI_PROJ_RLL ) gridID = projID;

200
  int gridtype = gridInqType(gridID);
201
202
203
  int projtype = CDI_UNDEFID;
  if ( gridtype == GRID_PROJECTION && gridInqProjType(gridID) == CDI_PROJ_RLL ) projtype = CDI_PROJ_RLL;

204
205
206
  size_t xsize = gridInqXsize(gridID);
  size_t ysize = gridInqYsize(gridID);

207
  cdi_check_gridsize_int_limit("IEG", xsize*ysize);
208

Uwe Schulzweida's avatar
Uwe Schulzweida committed
209
210
  if ( gridtype == GRID_GENERIC )
    {
211
      if ( (ysize == 32  || ysize == 48 || ysize == 64 || ysize == 96  || ysize == 160) &&
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
	   (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
227
228
229
230
231
232
    }
  else if ( gridtype == GRID_CURVILINEAR )
    {
      gridtype = GRID_LONLAT;
    }

233
  bool lrotated = (projtype == CDI_PROJ_RLL);
234
235

  if ( gridtype == GRID_LONLAT || gridtype == GRID_GAUSSIAN || projtype == CDI_PROJ_RLL )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
236
    {
237
238
      double xfirst = 0, xlast = 0, xinc = 0;
      double yfirst = 0, ylast = 0, yinc = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
239

240
      if ( xsize == 0 ) xsize = 1;
241
242
      else
	{
243
244
	  xfirst = gridInqXval(gridID,       0);
	  xlast  = gridInqXval(gridID, xsize-1);
245
246
247
	  xinc   = gridInqXinc(gridID);
	}

248
      if ( ysize == 0 ) ysize = 1;
249
250
      else
	{
251
252
	  yfirst = gridInqYval(gridID,       0);
	  ylast  = gridInqYval(gridID, ysize-1);
253
254
255
	  yinc   = gridInqYinc(gridID);
	}

256
257
      if ( gridtype == GRID_GAUSSIAN )
	IEG_G_GridType(gdb) = 4;
258
      else if ( lrotated )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
259
260
261
262
	IEG_G_GridType(gdb) = 10;
      else
	IEG_G_GridType(gdb) = 0;

Thomas Jahns's avatar
Thomas Jahns committed
263
264
      double resfac = calc_resfac(xfirst, xlast, xinc, yfirst, ylast, yinc);
      int iresfac = (int)resfac;
265
266
267
268
      if ( iresfac == 1000 ) iresfac = 0;

      IEG_G_ResFac(gdb)   = iresfac;

269
270
      IEG_G_NumLon(gdb)   = (int)xsize;
      IEG_G_NumLat(gdb)   = (int)ysize;
271
272
273
274
275
      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);
276
      if ( fabs(xinc*resfac - IEG_G_LonIncr(gdb)) > FLT_EPSILON )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
277
278
	IEG_G_LonIncr(gdb) = 0;

279
      if ( gridtype == GRID_GAUSSIAN )
280
	IEG_G_LatIncr(gdb) = (int)ysize/2;
281
282
      else
	{
283
	  IEG_G_LatIncr(gdb) = (int)lround(yinc*resfac);
284
	  if ( fabs(yinc*resfac - IEG_G_LatIncr(gdb)) > FLT_EPSILON )
285
	    IEG_G_LatIncr(gdb) = 0;
286
287

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

290
      if ( IEG_G_NumLon(gdb) > 1 && IEG_G_NumLat(gdb) == 1 )
291
292
	if ( IEG_G_LonIncr(gdb) != 0 && IEG_G_LatIncr(gdb) == 0 ) IEG_G_LatIncr(gdb) = IEG_G_LonIncr(gdb);

293
      if ( IEG_G_NumLon(gdb) == 1 && IEG_G_NumLat(gdb) > 1 )
294
295
	if ( IEG_G_LonIncr(gdb) == 0 && IEG_G_LatIncr(gdb) != 0 ) IEG_G_LonIncr(gdb) = IEG_G_LatIncr(gdb);

296
      IEG_G_ResFlag(gdb) = (IEG_G_LatIncr(gdb) == 0 || IEG_G_LonIncr(gdb) == 0) ? 0 : 128;
297

298
      if ( lrotated )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
299
	{
300
          double xpole = 0, ypole = 0, angle = 0;
301
          gridInqParamRLL(gridID, &xpole, &ypole, &angle);
302
303
304

	  IEG_G_LatSP(gdb) = - (int)lround(ypole * resfac);
	  IEG_G_LonSP(gdb) =   (int)lround((xpole + 180) * resfac);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
305
306
307
308
309
310
311
312
313
	  IEG_G_Size(gdb)  = 42;
	}
      else
	{
	  IEG_G_Size(gdb)  = 32;
	}
    }
  else
    {
314
      Error("Unsupported grid type: %s", gridNamePtr(gridtype));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
315
316
317
318
319
    }

  IEG_G_ScanFlag(gdb) = 64;
}

320
321
322
323
324
325
326
327
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;
}

328
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
329
330
331
void iegDefLevel(int *pdb, int *gdb, double *vct, int zaxisID, int levelID)
{
  double level;
332
  int ilevel;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
333

334
  int leveltype = zaxisInqType(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
335
336
  if ( leveltype == ZAXIS_GENERIC )
    {
337
      Message("Changed zaxis type from %s to %s",
338
	      zaxisNamePtr(leveltype), zaxisNamePtr(ZAXIS_PRESSURE));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
339
340
      leveltype = ZAXIS_PRESSURE;
      zaxisChangeType(zaxisID, leveltype);
341
      zaxisDefUnits(zaxisID, "Pa");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
342
343
344
345
346
347
348
349
    }

  /*  IEG_G_NumVCP(gdb) = 0; */

  switch (leveltype)
    {
    case ZAXIS_SURFACE:
      {
350
        pdbDefLevel(pdb, IEG_LTYPE_SURFACE, 0, (int)(zaxisInqLevel(zaxisID, levelID)));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
351
352
353
354
355
	break;
      }
    case ZAXIS_HYBRID:
      {
	if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
356
357
          pdbDefLevel(pdb, IEG_LTYPE_HYBRID_LAYER, (int)(zaxisInqLbound(zaxisID, levelID)),
                      (int)(zaxisInqUbound(zaxisID, levelID)));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
358
	else
359
          pdbDefLevel(pdb, IEG_LTYPE_HYBRID, 0, (int)(zaxisInqLevel(zaxisID, levelID)));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
360

361
	int vctsize = zaxisInqVctSize(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
362
363
	if ( vctsize > 100 )
	  {
364
            static bool vct_warning = true;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
365
366
367
	    /*	    IEG_G_NumVCP(gdb) = 0; */
	    if ( vct_warning )
	      {
368
		Warning("VCT size of %d is too large (maximum is 100). Set to 0!", vctsize);
369
		vct_warning = false;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
370
371
372
373
374
	      }
	  }
	else
	  {
	    IEG_G_Size(gdb) += (vctsize*4);
375
376
	    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
377
378
379
380
381
382
	  }
	break;
      }
    case ZAXIS_PRESSURE:
      {
	double dum;
383
	char units[CDI_MAX_NAME];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
384
385

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

	zaxisInqUnits(zaxisID, units);
389
	if ( memcmp(units, "hPa", 3) == 0 || memcmp(units, "mb",2 ) == 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
390
391
392
393
	  level = level*100;

	ilevel = (int) level;
	if ( level < 32768 && (level < 100 || modf(level/100, &dum) > 0) )
394
          pdbDefLevel(pdb, IEG_LTYPE_99, 0, ilevel);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
395
	else
396
397
398
          pdbDefLevel(pdb, IEG_LTYPE_ISOBARIC, 0, ilevel/100);

        break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
399
400
401
402
      }
    case ZAXIS_HEIGHT:
      {
	level = zaxisInqLevel(zaxisID, levelID);
403
        pdbDefLevel(pdb, IEG_LTYPE_HEIGHT, 0, (int)level);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
404
405
406
407
408
	break;
      }
    case ZAXIS_ALTITUDE:
      {
	level = zaxisInqLevel(zaxisID, levelID);
409
        pdbDefLevel(pdb, IEG_LTYPE_ALTITUDE, 0, (int)level);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
410
411
412
413
414
	break;
      }
    case ZAXIS_DEPTH_BELOW_LAND:
      {
	if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
415
          pdbDefLevel(pdb, IEG_LTYPE_LANDDEPTH_LAYER, (int)(zaxisInqLbound(zaxisID, levelID)), (int)(zaxisInqUbound(zaxisID, levelID)));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
416
	else
417
          pdbDefLevel(pdb, IEG_LTYPE_LANDDEPTH, 0, (int)(zaxisInqLevel(zaxisID, levelID)));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
418
419
420
421
422
423

	break;
      }
    case ZAXIS_DEPTH_BELOW_SEA:
      {
	level = zaxisInqLevel(zaxisID, levelID);
424
        pdbDefLevel(pdb, IEG_LTYPE_SEADEPTH, 0, (int)level);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
425
426
427
428
429
	break;
      }
    case ZAXIS_ISENTROPIC:
      {
	level = zaxisInqLevel(zaxisID, levelID);
430
        pdbDefLevel(pdb, 113, 0, (int)level);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
431
432
433
434
	break;
      }
    default:
      {
435
	Error("Unsupported zaxis type: %s", zaxisNamePtr(leveltype));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
436
437
438
439
440
441
	break;
      }
    }
}


442
void iegCopyRecord(stream_t *streamptr2, stream_t *streamptr1)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
443
{
444
  streamFCopyRecord(streamptr2, streamptr1, "IEG");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
445
446
447
}


448
void iegDefRecord(stream_t *streamptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
449
{
450
  Record *record = streamptr->record;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
451

452
453
  int vlistID = streamptr->vlistID;
  int byteorder = streamptr->byteorder;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
454

455
456
  int varID   = record->varID;
  int levelID = record->levelID;
457
  int tsID    = streamptr->curTsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
458

459
460
  int gridID  = vlistInqVarGrid(vlistID, varID);
  int zaxisID = vlistInqVarZaxis(vlistID, varID);
461

462
  iegrec_t *iegp = (iegrec_t*) record->exsep;
463
  iegInitMem(iegp);
464
  for ( int i = 0; i < 37; i++ ) iegp->ipdb[i] = -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
465
466
467

  iegp->byteswap = getByteswap(byteorder);

468
  int param = vlistInqVarParam(vlistID, varID);
469
  int pdis, pcat, pnum;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
470
  cdiDecodeParam(param, &pnum, &pcat, &pdis);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
471
472
  IEG_P_Parameter(iegp->ipdb) = pnum;
  if ( pdis == 255 ) IEG_P_CodeTable(iegp->ipdb) = pcat;
473

474
  int64_t date = streamptr->tsteps[tsID].taxis.vdate;
475
  int time = streamptr->tsteps[tsID].taxis.vtime;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
476
477
478
479
  iegDefTime(iegp->ipdb, date, time, vlistInqTaxis(vlistID));
  iegDefGrid(iegp->igdb, gridID);
  iegDefLevel(iegp->ipdb, iegp->igdb, iegp->vct, zaxisID, levelID);

480
  iegp->dprec = iegDefDatatype(record->prec);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
481
482
483
}


484
void iegWriteRecord(stream_t *streamptr, const double *data)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
485
{
486
487
  Record *record = streamptr->record;
  iegrec_t *iegp = (iegrec_t*) record->exsep;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
488

489
  int fileID = streamptr->fileID;
490
  size_t gridsize = gridInqSize(record->gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
491

492
  double refval = data[0];
493
  for ( size_t i = 1; i < gridsize; i++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
494
495
496
497
498
499
500
501
    if ( data[i] < refval ) refval = data[i];

  iegp->refval = refval;

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

502
static
503
void iegAddRecord(stream_t *streamptr, int param, int *pdb, int *gdb, double *vct,
504
		  size_t recsize, off_t position, int prec)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
505
{
506
507
508
509
  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
510

511
  int level1, level2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
512
513
514
515
516
517
518
519
520
  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;
521
      if ( IEG_P_LevelType(pdb) == 100 ) level1 *= 100;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
522
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
523

524
525
526
527
528
529
  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
530

531
532
533
  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
534

535
536
  grid_t *grid = (grid_t *)Malloc(sizeof (*grid));
  grid_init(grid);
537
  cdiGridTypeInit(grid, gridtype, IEG_G_NumLon(gdb)*IEG_G_NumLat(gdb));
538
539
  size_t xsize = (size_t)IEG_G_NumLon(gdb);
  size_t ysize = (size_t)IEG_G_NumLat(gdb);
540
541
  grid->x.size = xsize;
  grid->y.size = ysize;
542
543
544
  grid->x.inc  = 0;
  grid->y.inc  = 0;
  grid->x.flag = 0;
545
546
547
548
549

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

550
551
  /* if ( IEG_G_FirstLon != 0 || IEG_G_LastLon != 0 ) */
  {
552
    if ( xsize > 1 )
553
554
      {
	if ( IEG_G_ResFlag(gdb) && IEG_G_LonIncr(gdb) > 0 )
555
	  grid->x.inc = IEG_G_LonIncr(gdb) * resfac;
556
	else
557
	  grid->x.inc = (IEG_G_LastLon(gdb) - IEG_G_FirstLon(gdb)) * resfac / (xsize - 1);
558
559
560
561

	/* correct xinc if necessary */
	if ( IEG_G_FirstLon(gdb) == 0 && IEG_G_LastLon(gdb) > 354000 )
	  {
562
	    double xinc = 360. / xsize;
563
564
            /* FIXME: why not use grid->x.inc != xinc as condition? */
	    if ( fabs(grid->x.inc-xinc) > 0.0 )
565
	      {
566
567
		grid->x.inc = xinc;
		if ( CDI_Debug ) Message("set xinc to %g", grid->x.inc);
568
569
570
	      }
	  }
      }
571
572
573
    grid->x.first = IEG_G_FirstLon(gdb) * resfac;
    grid->x.last  = IEG_G_LastLon(gdb)  * resfac;
    grid->x.flag  = 2;
574
  }
575
  grid->y.flag = 0;
576
577
  /* if ( IEG_G_FirstLat != 0 || IEG_G_LastLat != 0 ) */
  {
578
    if ( ysize > 1 )
579
580
      {
	if ( IEG_G_ResFlag(gdb) && IEG_G_LatIncr(gdb) > 0 )
581
	  grid->y.inc = IEG_G_LatIncr(gdb) * resfac;
582
	else
583
	  grid->y.inc = (IEG_G_LastLat(gdb) - IEG_G_FirstLat(gdb)) * resfac / (ysize - 1);
584
      }
585
586
587
    grid->y.first = IEG_G_FirstLat(gdb) * resfac;
    grid->y.last  = IEG_G_LastLat(gdb)  * resfac;
    grid->y.flag  = 2;
588
  }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
589

590
  double xpole = 0, ypole = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
591
592
  if ( IEG_G_GridType(gdb) == 10 )
    {
593
594
      xpole =   IEG_G_LonSP(gdb) * resfac - 180;
      ypole = - IEG_G_LatSP(gdb) * resfac;
595
      grid->projtype = CDI_PROJ_RLL;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
596
597
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
598
  struct addIfNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, grid, 0);
599
  int gridID = gridAdded.Id;
600
  if ( !gridAdded.isNew ) Free(grid);
601
  else if ( gridtype == GRID_PROJECTION ) gridDefParamRLL(gridID, xpole, ypole, 0);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
602

603
  int leveltype = iegGetZaxisType(IEG_P_LevelType(pdb));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
604
605
606
  if ( leveltype == ZAXIS_HYBRID )
    {
      double tmpvct[100];
607
      size_t vctsize = (size_t)IEG_G_NumVCP(gdb);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
608

609
      for ( size_t i = 0; i < vctsize/2; i++ ) tmpvct[i] = vct[i];
610
      for ( size_t i = 0; i < vctsize/2; i++ ) tmpvct[i+vctsize/2] = vct[i+50];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
611
612
613
614

      varDefVCT(vctsize, tmpvct);
    }

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

617
  int datatype = iegInqDatatype(prec);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
618

619
  int varID, levelID = 0;
620
  varAddRecord(recID, param, gridID, leveltype, lbounds, level1, level2, 0, 0,
621
	       datatype, &varID, &levelID, TSTEP_INSTANT, 0, 0, -1,
622
               NULL, NULL, NULL, NULL, NULL, NULL, 0);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
623

624
625
  record->varID   = (short)varID;
  record->levelID = (short)levelID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
626

Uwe Schulzweida's avatar
Uwe Schulzweida committed
627
628
  streamptr->tsteps[tsID].nallrecs++;
  streamptr->nrecs++;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
629
630

  if ( CDI_Debug )
631
    Message("varID = %d gridID = %d levelID = %d", varID, gridID, levelID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
632
633
}

Thomas Jahns's avatar
Thomas Jahns committed
634
#if 0
635
static
636
void iegCmpRecord(stream_t *streamptr, int tsID, int recID, off_t position, int param,
637
		  int level, size_t xsize, size_t ysize)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
638
639
640
{
  int varID = 0;
  int levelID = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
641

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
644
  if ( param != (*record).param || level != (*record).ilevel )
645
    Error("inconsistent timestep");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
646
647
648
649
650
651

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
654
655
  streamptr->tsteps[tsID].nallrecs++;
  streamptr->nrecs++;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
656
657
  */
  if ( CDI_Debug )
658
    Message("varID = %d levelID = %d", varID, levelID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
659
}
Thomas Jahns's avatar
Thomas Jahns committed
660
#endif
661

662
static
663
void iegDateTime(int *pdb, int64_t *date, int *time)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
664
{
665
666
667
  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
668

669
670
  int rhour   = IEG_P_Hour(pdb);
  int rminute = IEG_P_Minute(pdb);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
671
672
673

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
674
675
  *date = cdiEncodeDate(ryear, rmonth, rday);
  *time = cdiEncodeTime(rhour, rminute, 0);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
676
677
}

678
static
679
680
void iegScanTimestep1(stream_t *streamptr)
{
681
  DateTime datetime0 = { LONG_MIN, LONG_MIN };
Uwe Schulzweida's avatar
Uwe Schulzweida committed
682
  off_t recpos;
683
  iegcompvar_t compVar, compVar0;
684
  iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
685

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

688
  int tsID = tstepsNewEntry(streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
689
  if ( tsID != 0 )
690
    Error("Internal problem! tstepsNewEntry returns %d", tsID);
691
  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
692

693
  int fileID = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
694

695
  int nrecs = 0;
696
  while ( true )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
697
698
    {
      recpos = fileGetPos(fileID);
699
      int status = iegRead(fileID, iegp);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
700
701
      if ( status != 0 )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
702
	  streamptr->ntsteps = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
703
704
	  break;
	}
705
      size_t recsize = (size_t)(fileGetPos(fileID) - recpos);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
706

707
708
709
710
      int prec   = iegp->dprec;
      int rcode  = IEG_P_Parameter(iegp->ipdb);
      int tabnum = IEG_P_CodeTable(iegp->ipdb);
      int param  = cdiEncodeParam(rcode, tabnum, 255);
711
      int rlevel = (IEG_P_LevelType(iegp->ipdb) == IEG_LTYPE_HYBRID_LAYER) ? IEG_P_Level1(iegp->ipdb) : IEG_P_Level2(iegp->ipdb);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
712

713
714
      if ( IEG_P_LevelType(iegp->ipdb) == 100 ) rlevel *= 100;

715
716
      int64_t vdate = 0;
      int vtime = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
717
718
719
720
721
722
723
724
725
      iegDateTime(iegp->ipdb, &vdate, &vtime);

      if ( nrecs == 0 )
	{
	  datetime0.date = vdate;
	  datetime0.time = vtime;
	}
      else
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
726
	  compVar.param = param;
727
          compVar.level = rlevel;
728
          int recID = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
729
730
	  for ( recID = 0; recID < nrecs; recID++ )
	    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
731
	      compVar0.param = streamptr->tsteps[0].records[recID].param;
732
733
	      compVar0.level = streamptr->tsteps[0].records[recID].ilevel;

734
	      if ( memcmp(&compVar0, &compVar, sizeof(iegcompvar_t)) == 0 ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
735
736
	    }
	  if ( recID < nrecs ) break;
737
738
	  DateTime datetime = { .date = vdate, .time = vtime};
	  if ( datetimeCmp(datetime, datetime0) )
739
	    Warning("Inconsistent verification time for param %d level %d", param, rlevel);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
740
741
742
743
744
	}

      nrecs++;

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

747
      iegAddRecord(streamptr, param, iegp->ipdb, iegp->igdb, iegp->vct, recsize, recpos, prec);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
748
749
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
750
  streamptr->rtsteps = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
751

752
  cdi_generate_vars(streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
753

754
  int taxisID = taxisCreate(TAXIS_ABSOLUTE);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
755
  taxis->type  = TAXIS_ABSOLUTE;
756
  taxis->vdate = datetime0.date;
757
  taxis->vtime = (int)datetime0.time;
758
759
  taxis->rdate = taxis->vdate;
  taxis->rtime = taxis->vtime;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
760

761
  int vlistID = streamptr->vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
762
763
  vlistDefTaxis(vlistID, taxisID);

764
  vlist_check_contents(vlistID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
765

766
  int nrecords = streamptr->tsteps[0].nallrecs;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
767
  if ( nrecords < streamptr->tsteps[0].recordSize )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
768
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
769
770
      streamptr->tsteps[0].recordSize = nrecords;
      streamptr->tsteps[0].records =
771
	(record_t *) Realloc(streamptr->tsteps[0].records,
772
                             (size_t)nrecords * sizeof (record_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
773
774
    }

775
  streamptr->tsteps[0].recIDs = (int *) Malloc((size_t)nrecords * sizeof (int));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
776
  streamptr->tsteps[0].nrecs = nrecords;
777
  for ( int recID = 0; recID < nrecords; recID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
778
    streamptr->tsteps[0].recIDs[recID] = recID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
779

Uwe Schulzweida's avatar
Uwe Schulzweida committed
780
  if ( streamptr->ntsteps == -1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
781
    {
782
      int tsID = tstepsNewEntry(streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
783
      if ( tsID != streamptr->rtsteps )
784
	Error("Internal error. tsID = %d", tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
785

786
      streamptr->tsteps[tsID-1].next   = true;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
787
      streamptr->tsteps[tsID].position = recpos;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
788
789
    }

790
  streamScanTimeConstAdjust(streamptr, taxis);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
791
792
}

793
static
794
int iegScanTimestep2(stream_t *streamptr)
795
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
796
  off_t recpos = 0;
797
  iegcompvar_t compVar, compVar0;
798
  iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
799
800

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

802
803
  int vlistID = streamptr->vlistID;
  int fileID  = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
804

805
  int tsID = streamptr->rtsteps;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
806
  if ( tsID != 1 )
807
    Error("Internal problem! unexpected timestep %d", tsID+1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
808

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

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

813
  cdi_create_records(streamptr, tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
814

815
  int nrecords = streamptr->tsteps[0].nallrecs;
816
  streamptr->tsteps[1].recIDs = (int *) Malloc((size_t)nrecords * sizeof(int));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
817
  streamptr->tsteps[1].nrecs = 0;
818
  for ( int recID = 0; recID < nrecords; recID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
819
    streamptr->tsteps[1].recIDs[recID] = -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
820

821
  for ( int recID = 0; recID < nrecords; recID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
822
    {
823
      streamptr->tsteps[tsID].records[recID].position =
Uwe Schulzweida's avatar
Uwe Schulzweida committed
824
	streamptr->tsteps[0].records[recID].position;
825
      streamptr->tsteps[tsID].records[recID].size     =
Uwe Schulzweida's avatar
Uwe Schulzweida committed
826
	streamptr->tsteps[0].records[recID].size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
827
828
    }

829
  for ( int rindex = 0; rindex <= nrecords; rindex++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
830
831
    {
      recpos = fileGetPos(fileID);
832
      int status = iegRead(fileID, iegp);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
833
834
      if ( status != 0 )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
835
	  streamptr->ntsteps = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
836
837
	  break;
	}
838
      size_t recsize = (size_t)(fileGetPos(fileID) - recpos);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
839

840
841
842
      int rcode  = IEG_P_Parameter(iegp->ipdb);
      int tabnum = IEG_P_CodeTable(iegp->ipdb);
      int param  = cdiEncodeParam(rcode, tabnum, 255);
843
      int rlevel = (IEG_P_LevelType(iegp->ipdb) == IEG_LTYPE_HYBRID_LAYER) ? IEG_P_Level1(iegp->ipdb) : IEG_P_Level2(iegp->ipdb);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
844

845
846
      if ( IEG_P_LevelType(iegp->ipdb) == 100 ) rlevel *= 100;

847
848
      int64_t vdate = 0;
      int vtime = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
849
850
851
852
853
854
855
856
857
      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
858
      compVar.param = param;
859
      compVar.level = rlevel;
860
861
      bool nextstep = false;
      int recID = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
862
863
      for ( recID = 0; recID < nrecords; recID++ )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
864
	  compVar0.param = streamptr->tsteps[tsID].records[recID].param;
865
866
	  compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;

867
	  if ( memcmp(&compVar0, &compVar, sizeof(iegcompvar_t)) == 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
868
	    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
869
	      if ( streamptr->tsteps[tsID].records[recID].used )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
870
		{
871
		  nextstep = true;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
872
873
874
		}
	      else
		{
875
		  streamptr->tsteps[tsID].records[recID].used = true;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
876
		  streamptr->tsteps[tsID].recIDs[rindex] = recID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
877
878
879
880
881
882
		}
	      break;
	    }
	}
      if ( recID == nrecords )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
883
884
	  char paramstr[32];
	  cdiParamToString(param, paramstr, sizeof(paramstr));
885
	  Warning("param %s level %d not defined at timestep 1", paramstr, rlevel);
886
	  return CDI_EUFSTRUCT;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
887
888
889
890
891
	}

      if ( nextstep ) break;

      if ( CDI_Debug )
892
	Message("%4d%8d%4d%8d%8ld%6d", rindex+1, (int)recpos, param, rlevel, (long)vdate, vtime);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
893

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
896
      compVar0.param = streamptr->tsteps[tsID].records[recID].param;
897
      compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
898

899
      if ( memcmp(