stream_ieg.c 35.9 KB
Newer Older
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#if defined (HAVE_CONFIG_H)
#  include "config.h"
#endif

#include <stdio.h>
#include <string.h>
#include <float.h>
#include <math.h>

#include "dmemory.h"

#include "error.h"
#include "file.h"
#include "cdi.h"
#include "stream_int.h"
#include "varscan.h"
#include "datetime.h"
#include "ieg.h"
#include "vlist.h"


#undef  UNDEFID
#define UNDEFID  CDI_UNDEFID

#define SINGLE_PRECISION  4
#define DOUBLE_PRECISION  8

#if defined (HAVE_LIBIEG)

30
31
32
33
34
35
36

typedef struct {
  int code;
  int level;
} IEGCOMPVAR; 


Uwe Schulzweida's avatar
Uwe Schulzweida committed
37
38
39
40
int iegInqDatatype(int prec)
{
  int datatype;

41
42
  if ( prec == DOUBLE_PRECISION ) datatype = DATATYPE_FLT64;
  else                            datatype = DATATYPE_FLT32;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
43
44
45
46
47
48
49
50
51

  return (datatype);
}


int iegDefDatatype(int datatype)
{
  int prec;

52
53
  if ( datatype != DATATYPE_FLT32 && datatype != DATATYPE_FLT64 )
    datatype = DATATYPE_FLT32;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
54

55
  if ( datatype == DATATYPE_FLT64 ) prec = DOUBLE_PRECISION;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
  else                              prec = SINGLE_PRECISION;

  return (prec);
}


int iegInqRecord(int streamID, int *varID, int *levelID)
{
  static char func[] = "iegInqRecord";
  int status;
  int fileID;
  int icode, ilevel;
  int zaxisID = -1;
  int vlistID;
  IEGREC *iegp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
71
  STREAM *streamptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
72

Uwe Schulzweida's avatar
Uwe Schulzweida committed
73
74
75
  streamptr = stream_to_pointer(streamID);

  stream_check_ptr(func, streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
76
77
78

  vlistID = streamInqVlist(streamID);
  fileID  = streamInqFileID(streamID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
79
  iegp    = streamptr->record->iegp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
80
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

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

  status = iegRead(fileID, iegp);
  if ( status != 0 ) return (0);

  icode  = IEG_P_Parameter(iegp->ipdb);
  if ( IEG_P_LevelType(iegp->ipdb) == IEG_LTYPE_HYBRID_LAYER )
    ilevel = IEG_P_Level1(iegp->ipdb);
  else
    ilevel = IEG_P_Level2(iegp->ipdb);

  *varID = vlistInqVarID(vlistID, icode);

  if ( *varID == UNDEFID ) Error(func, "code %d undefined", icode);

  zaxisID = vlistInqVarZaxis(vlistID, *varID);

  *levelID = zaxisInqLevelID(zaxisID, (double) ilevel);
  
  return (1);
}


int iegReadRecord(int streamID, double *data, int *nmiss)
{
  static char func[] = "iegReadRecord";
  int vlistID, fileID;
  int status;
  int recID, vrecID, tsID;
  off_t recpos;
  int varID, gridID;
  int i, size;
  double missval;
  IEGREC *iegp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
116
117
118
  STREAM *streamptr;

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
120
  stream_check_ptr(func, streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
121
122
123

  vlistID = streamInqVlist(streamID);
  fileID  = streamInqFileID(streamID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
124
125
126
127
128
129
  tsID    = streamptr->curTsID;
  vrecID  = streamptr->tsteps[tsID].curRecID;
  recID   = streamptr->tsteps[tsID].recIDs[vrecID];
  recpos  = streamptr->tsteps[tsID].records[recID].position;
  varID   = streamptr->tsteps[tsID].records[recID].varID;
  iegp    = streamptr->record->iegp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
130
131
132
133
134
135
136
137

  fileSetPos(fileID, recpos, SEEK_SET);

  status = iegRead(fileID, iegp);
  if ( status != 0 ) return (0);

  iegInqDataDP(iegp, data);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
138
  missval = vlistInqVarMissval(vlistID, varID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
139
140
  gridID  = vlistInqVarGrid(vlistID, varID);
  size    = gridInqSize(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
141

Uwe Schulzweida's avatar
Uwe Schulzweida committed
142
  streamptr->numvals += size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212

  *nmiss = 0;
  for ( i = 0; i < size; i++ )
    if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
      {
	data[i] = missval;
	(*nmiss)++;
      }

  return (1);
}


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;
      }
    }

  return (leveltype);
}


void iegDefTime(int *pdb, int date, int time, int timeID)
{
213
  int year, month, day, hour, minute, second;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
214
215
216
217
218
219
  int timetype = -1;

  if ( timeID != -1 ) timetype = taxisInqType(timeID);

  if ( timetype == TAXIS_ABSOLUTE || timetype == TAXIS_RELATIVE )
    {
220
      decode_date(date, &year, &month, &day);
221
      decode_time(time, &hour, &minute, &second);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256

      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;
}


void iegDefGrid(int *gdb, int gridID)
{
  static char func[] = "iegDefGrid";
  int gridtype;

  gridtype = gridInqType(gridID);

  if ( gridtype == GRID_GENERIC )
    {
      gridtype = GRID_LONLAT;
      gridChangeType(gridID, gridtype);
    }
  else if ( gridtype == GRID_CURVILINEAR )
    {
      gridtype = GRID_LONLAT;
    }

257
  if ( gridtype == GRID_LONLAT || gridtype == GRID_GAUSSIAN )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
258
259
260
261
262
263
264
    {
      int nlon, nlat;

      nlon = (int) gridInqXsize(gridID);

      nlat = (int) gridInqYsize(gridID);

265
266
267
      if ( gridtype == GRID_GAUSSIAN )
	IEG_G_GridType(gdb) = 4;
      else if ( gridtype == GRID_LONLAT && gridIsRotated(gridID) )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
268
269
270
271
272
273
274
275
276
277
278
279
280
281
	IEG_G_GridType(gdb) = 10;
      else
	IEG_G_GridType(gdb) = 0;

      IEG_G_NumLon(gdb)   = nlon;
      IEG_G_NumLat(gdb)   = nlat;
      IEG_G_FirstLat(gdb) = NINT(gridInqYval(gridID,      0)*1000);
      IEG_G_LastLat(gdb)  = NINT(gridInqYval(gridID, nlat-1)*1000);
      IEG_G_FirstLon(gdb) = NINT(gridInqXval(gridID,      0)*1000);
      IEG_G_LastLon(gdb)  = NINT(gridInqXval(gridID, nlon-1)*1000);
      IEG_G_LonIncr(gdb)  = NINT(gridInqXinc(gridID)*1000);
      if ( fabs(gridInqXinc(gridID)*1000 - IEG_G_LonIncr(gdb)) > FLT_EPSILON )
	IEG_G_LonIncr(gdb) = 0;

282
283
284
285
286
287
288
      if ( gridtype == GRID_GAUSSIAN )
	IEG_G_LatIncr(gdb) = nlat/2;
      else
	{
	  IEG_G_LatIncr(gdb) = NINT(gridInqYinc(gridID)*1000);
	  if ( fabs(gridInqYinc(gridID)*1000 - IEG_G_LatIncr(gdb)) > FLT_EPSILON )
	    IEG_G_LatIncr(gdb) = 0;
289
290

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

293
294
295
296
297
298
299
300
301
302
303
      if ( IEG_G_NumLon(gdb) > 1 && IEG_G_NumLat(gdb) == 1 ) 
	if ( IEG_G_LonIncr(gdb) != 0 && IEG_G_LatIncr(gdb) == 0 ) IEG_G_LatIncr(gdb) = IEG_G_LonIncr(gdb);

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

      if ( IEG_G_LatIncr(gdb) == 0 || IEG_G_LonIncr(gdb) == 0 )
	IEG_G_ResFlag(gdb) = 0;
      else
	IEG_G_ResFlag(gdb) = 128;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
      if ( gridIsRotated(gridID) )
	{
	  IEG_G_LatSP(gdb) = - NINT(gridInqYpole(gridID) * 1000);
	  IEG_G_LonSP(gdb) =   NINT((gridInqXpole(gridID) + 180) * 1000);
	  IEG_G_Size(gdb)  = 42;
	}
      else
	{
	  IEG_G_Size(gdb)  = 32;
	}
    }
  else
    {
      Error(func, "%s grid unsupported!", gridNamePtr(gridtype));
    }

  IEG_G_ScanFlag(gdb) = 64;
}


void iegDefLevel(int *pdb, int *gdb, double *vct, int zaxisID, int levelID)
{
  static char func[] = "iegDefLevel";
  double level;
  int ilevel, leveltype;
  static int warning = 1;
  static int vct_warning = 1;

  leveltype = zaxisInqType(zaxisID);

  if ( leveltype == ZAXIS_GENERIC )
    {
      leveltype = ZAXIS_PRESSURE;
      zaxisChangeType(zaxisID, leveltype);
    }

  /*  IEG_G_NumVCP(gdb) = 0; */

  switch (leveltype)
    {
    case ZAXIS_SURFACE:
      {
	IEG_P_LevelType(pdb) = IEG_LTYPE_SURFACE;
	IEG_P_Level1(pdb)    = 0;
	IEG_P_Level2(pdb)    = (int) zaxisInqLevel(zaxisID, levelID);
	break;
      }
    case ZAXIS_HYBRID:
      {
	int vctsize;

	if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
	  {
	    IEG_P_LevelType(pdb) = IEG_LTYPE_HYBRID_LAYER;
	    IEG_P_Level1(pdb)    = (int) zaxisInqLbound(zaxisID, levelID);
	    IEG_P_Level2(pdb)    = (int) zaxisInqUbound(zaxisID, levelID);
	  }
	else
	  {
	    IEG_P_LevelType(pdb) = IEG_LTYPE_HYBRID;
	    IEG_P_Level1(pdb)    = 0;
	    IEG_P_Level2(pdb)    = (int) zaxisInqLevel(zaxisID, levelID);
	  }

	vctsize = zaxisInqVctSize(zaxisID);
	if ( vctsize == 0 && warning )
	  {
	    Warning(func, "VCT missing. ( code = %d, zaxisID = %d )",
		    IEG_P_Parameter(pdb), zaxisID);
	    warning = 0;
	  }
	if ( vctsize > 100 )
	  {
	    /*	    IEG_G_NumVCP(gdb) = 0; */
	    if ( vct_warning )
	      {
		Warning(func, "VCT size of %d is to large (maximum is 100). Set to 0!", vctsize);
		vct_warning = 0;
	      }
	  }
	else
	  {
	    IEG_G_Size(gdb) += (vctsize*4);
	    memcpy(vct, zaxisInqVctPtr(zaxisID), vctsize/2*sizeof(double));
	    memcpy(vct+50, zaxisInqVctPtr(zaxisID)+vctsize/2, vctsize/2*sizeof(double));
	  }
	break;
      }
    case ZAXIS_PRESSURE:
      {
	double dum;
	char units[128];

	level = zaxisInqLevel(zaxisID, levelID);
	if ( level < 0 )
	  Warning(func, "pressure level of %f Pa is below 0.", level);

	zaxisInqUnits(zaxisID, units);
402
	if ( memcmp(units, "hPa", 3) == 0 || memcmp(units, "mb",2 ) == 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
	  level = level*100;

	ilevel = (int) level;
	if ( level < 32768 && (level < 100 || modf(level/100, &dum) > 0) )
	  {
	    IEG_P_LevelType(pdb) = IEG_LTYPE_99;
	    IEG_P_Level1(pdb)    = 0;
	    IEG_P_Level2(pdb)    = ilevel;
	  }
	else
	  {
	    IEG_P_LevelType(pdb) = IEG_LTYPE_ISOBARIC;
	    IEG_P_Level1(pdb)    = 0;
	    IEG_P_Level2(pdb)    = ilevel/100;
	  }
	break;
      }
    case ZAXIS_HEIGHT:
      {
	level = zaxisInqLevel(zaxisID, levelID);

	ilevel = (int) level;
	IEG_P_LevelType(pdb) = IEG_LTYPE_HEIGHT;
	IEG_P_Level1(pdb)    = 0;
	IEG_P_Level2(pdb)    = ilevel;

	break;
      }
    case ZAXIS_ALTITUDE:
      {
	level = zaxisInqLevel(zaxisID, levelID);

	ilevel = (int) level;
	IEG_P_LevelType(pdb) = IEG_LTYPE_ALTITUDE;
	IEG_P_Level1(pdb)    = 0;
	IEG_P_Level2(pdb)    = ilevel;

	break;
      }
    case ZAXIS_DEPTH_BELOW_LAND:
      {
	if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
	  {
	    IEG_P_LevelType(pdb) = IEG_LTYPE_LANDDEPTH_LAYER;
	    IEG_P_Level1(pdb)    = (int) zaxisInqLbound(zaxisID, levelID);
	    IEG_P_Level2(pdb)    = (int) zaxisInqUbound(zaxisID, levelID);
	  }
	else
	  {
	    level = zaxisInqLevel(zaxisID, levelID);

	    ilevel = (int) level;
	    IEG_P_LevelType(pdb) = IEG_LTYPE_LANDDEPTH;
	    IEG_P_Level1(pdb)    = 0;
	    IEG_P_Level2(pdb)    = ilevel;
	  }

	break;
      }
    case ZAXIS_DEPTH_BELOW_SEA:
      {
	level = zaxisInqLevel(zaxisID, levelID);

	ilevel = (int) level;
	IEG_P_LevelType(pdb) = IEG_LTYPE_SEADEPTH;
	IEG_P_Level1(pdb)    = 0;
	IEG_P_Level2(pdb)    = ilevel;

	break;
      }
    case ZAXIS_ISENTROPIC:
      {
	level = zaxisInqLevel(zaxisID, levelID);

	ilevel = (int) level;
	IEG_P_LevelType(pdb) = 113;
	IEG_P_Level1(pdb)    = 0;
	IEG_P_Level2(pdb)    = ilevel;

	break;
      }
    default:
      {
	Error(func, "leveltype >%s< unsupported", zaxisNamePtr(leveltype));
	break;
      }
    }
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
493
int iegCopyRecord(int streamID2, int streamID1)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
494
495
{
  static char func[] = "iegCopyRecord";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
496
  int fileID1, fileID2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
497
498
499
500
501
  int tsID, recID, vrecID;
  long recsize;
  off_t recpos;
  int status = 0;
  char *buffer;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
502
503
  STREAM *streamptr1;
  STREAM *streamptr2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
504

Uwe Schulzweida's avatar
Uwe Schulzweida committed
505
506
  streamptr1 = stream_to_pointer(streamID1);
  streamptr2 = stream_to_pointer(streamID2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
507

Uwe Schulzweida's avatar
Uwe Schulzweida committed
508
509
  stream_check_ptr(func, streamptr1);
  stream_check_ptr(func, streamptr2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
510

Uwe Schulzweida's avatar
Uwe Schulzweida committed
511
512
  fileID1 = streamInqFileID(streamID1);
  fileID2 = streamInqFileID(streamID2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
513

Uwe Schulzweida's avatar
Uwe Schulzweida committed
514
515
516
517
518
519
520
  tsID    = streamptr1->curTsID;
  vrecID  = streamptr1->tsteps[tsID].curRecID;
  recID   = streamptr1->tsteps[tsID].recIDs[vrecID];
  recpos  = streamptr1->tsteps[tsID].records[recID].position;
  recsize = streamptr1->tsteps[tsID].records[recID].size;

  fileSetPos(fileID1, recpos, SEEK_SET);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
521
522
523

  buffer = (char *) malloc(recsize);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
524
  fileRead(fileID1, buffer, recsize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
525

Uwe Schulzweida's avatar
Uwe Schulzweida committed
526
  fileWrite(fileID2, buffer, recsize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545

  free(buffer);

  return (status);
}


int iegDefRecord(int streamID)
{
  static char func[] = "iegDefRecord";
  int status = 0;
  int fileID, vlistID;
  int gridID;
  int date, time;
  int datatype;
  int i;
  int varID, levelID, tsID, zaxisID;
  int byteorder;
  IEGREC *iegp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
546
547
548
  STREAM *streamptr;

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
550
  stream_check_ptr(func, streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
551
552
553

  fileID  = streamInqFileID(streamID);
  vlistID = streamInqVlist(streamID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
554
555
  iegp    = streamptr->record->iegp;
  byteorder = streamptr->byteorder;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
556

Uwe Schulzweida's avatar
Uwe Schulzweida committed
557
558
559
  varID   = streamptr->record->varID;
  levelID = streamptr->record->levelID;
  tsID    = streamptr->curTsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
560
561
562
563

  gridID  = vlistInqVarGrid(vlistID, varID);
  zaxisID = vlistInqVarZaxis(vlistID, varID);
  
564
  iegInitMem(iegp);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
565
566
567
568
569
  for ( i = 0; i < 37; i++ ) iegp->ipdb[i] = -1;

  iegp->byteswap = getByteswap(byteorder);

  IEG_P_Parameter(iegp->ipdb) = vlistInqVarCode(vlistID, varID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
570
571
  date     = streamptr->tsteps[tsID].taxis.vdate;
  time     = streamptr->tsteps[tsID].taxis.vtime;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
572
573
574
575
576

  iegDefTime(iegp->ipdb, date, time, vlistInqTaxis(vlistID));
  iegDefGrid(iegp->igdb, gridID);
  iegDefLevel(iegp->ipdb, iegp->igdb, iegp->vct, zaxisID, levelID);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
577
  datatype = streamptr->record->prec;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592

  iegp->dprec = iegDefDatatype(datatype);

  return (status);
}


int iegWriteRecord(int streamID, const double *data)
{
  static char func[] = "iegWriteRecord";
  int fileID;
  int status = 0;
  int i, gridsize, gridID;
  double refval;
  IEGREC *iegp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
593
  STREAM *streamptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
594

Uwe Schulzweida's avatar
Uwe Schulzweida committed
595
596
597
  streamptr = stream_to_pointer(streamID);

  stream_check_ptr(func, streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
598
599

  fileID = streamInqFileID(streamID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
600
601
  iegp   = streamptr->record->iegp;
  gridID = streamptr->record->gridID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
  
  gridsize = gridInqSize(gridID);

  refval = data[0];
  for ( i = 1; i < gridsize; i++ )
    if ( data[i] < refval ) refval = data[i];

  iegp->refval = refval;

  iegDefDataDP(iegp, data);

  iegWrite(fileID, iegp);

  return (status);
}


void iegAddRecord(int streamID, int code, int *pdb, int *gdb, double *vct,
		  long recsize, off_t position, int prec)
{
  static char func[] = "iegAddRecord";
  int leveltype;
  int gridID = UNDEFID;
  int levelID = 0;
  int tsID, recID, varID;
  int datatype;
  int level1, level2;
  int gridtype;
  int lbounds = 0;
  RECORD *record;
632
  grid_t grid;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
633
  int vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
634
635
636
  STREAM *streamptr;

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

  vlistID = streamInqVlist(streamID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
639
  tsID    = streamptr->curTsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
640
  recID   = recordNewEntry(streamID, tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
641
  record  = &streamptr->tsteps[tsID].records[recID];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
642
643
644
645
646
647
648
649
650
651

  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;
652
      if ( IEG_P_LevelType(pdb) == 100 ) level1 *= 100;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
653
654
655
656
657
658
659
660
661
662
663
664
665
666
    }
  /*
  fprintf(stderr, "%d %d %d %d\n", code, IEG_P_LevelType(pdb), IEG_P_Level1(pdb), IEG_P_Level2(pdb));
  */
  (*record).size     = recsize;
  (*record).position = position;
  (*record).code     = code;
  (*record).table    = IEG_P_CodeTable(pdb);
  (*record).ilevel   = level1;
  (*record).ilevel2  = level2;
  (*record).ltype    = IEG_P_LevelType(pdb);

  if ( IEG_G_GridType(gdb) == 0 || IEG_G_GridType(gdb) == 10 )
    gridtype = GRID_LONLAT;
667
668
  if ( IEG_G_GridType(gdb) == 4 )
    gridtype = GRID_GAUSSIAN;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
669
670
671
  else
    gridtype = GRID_GENERIC;

672
  memset(&grid, 0, sizeof(grid_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
673
674
675
676
  grid.type  = gridtype; 
  grid.size  = IEG_G_NumLon(gdb)*IEG_G_NumLat(gdb);
  grid.xsize = IEG_G_NumLon(gdb);
  grid.ysize = IEG_G_NumLat(gdb);
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
  grid.xinc  = 0;
  grid.yinc  = 0;
  grid.xdef  = 0;
  /* if ( IEG_G_FirstLon != 0 || IEG_G_LastLon != 0 ) */
  {
    if ( grid.xsize > 1 )
      {
	if ( IEG_G_ResFlag(gdb) && IEG_G_LonIncr(gdb) > 0 )
	  grid.xinc = IEG_G_LonIncr(gdb) * 0.001;
	else
	  grid.xinc = (IEG_G_LastLon(gdb) - IEG_G_FirstLon(gdb)) * 0.001 / (grid.xsize - 1);

	/* correct xinc if necessary */
	if ( IEG_G_FirstLon(gdb) == 0 && IEG_G_LastLon(gdb) > 354000 )
	  {
	    double xinc = 360. / grid.xsize;
	    
	    if ( fabs(grid.xinc-xinc) > 0.0 )
	      {
		grid.xinc = xinc;
		if ( CDI_Debug ) Message(func, "set xinc to %g", grid.xinc);
	      }
	  }
      }
    grid.xfirst = IEG_G_FirstLon(gdb) * 0.001;
    grid.xlast  = IEG_G_LastLon(gdb)  * 0.001;
    grid.xdef   = 2;	    
  }
  grid.ydef  = 0;
  /* if ( IEG_G_FirstLat != 0 || IEG_G_LastLat != 0 ) */
  {
    if ( grid.ysize > 1 )
      {
	if ( IEG_G_ResFlag(gdb) && IEG_G_LatIncr(gdb) > 0 )
	  grid.yinc = IEG_G_LatIncr(gdb) * 0.001;
	else
	  grid.yinc = (IEG_G_LastLat(gdb) - IEG_G_FirstLat(gdb)) * 0.001 / (grid.ysize - 1);
      }
    grid.yfirst = IEG_G_FirstLat(gdb) * 0.001;
    grid.ylast  = IEG_G_LastLat(gdb)  * 0.001;
    grid.ydef   = 2;	    
  }
  /*
Uwe Schulzweida's avatar
Uwe Schulzweida committed
720
721
722
723
724
725
726
  grid.xfirst= IEG_G_FirstLon(gdb) * 0.001;
  grid.xlast = IEG_G_LastLon(gdb) * 0.001;
  grid.xinc  = IEG_G_LonIncr(gdb) * 0.001;
  grid.xdef  = 2;	    
  grid.yfirst= IEG_G_FirstLat(gdb) * 0.001;
  grid.ylast = IEG_G_LastLat(gdb) * 0.001;
  grid.yinc  = IEG_G_LatIncr(gdb) * 0.001;
727
728
  grid.ydef  = 2;
  */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
  grid.xvals = NULL;
  grid.yvals = NULL;

  grid.isRotated = FALSE;
  if ( IEG_G_GridType(gdb) == 10 )
    {
      grid.isRotated = TRUE;
      grid.ypole     = - IEG_G_LatSP(gdb) * 0.001;
      grid.xpole     =   IEG_G_LonSP(gdb) * 0.001 - 180;
      grid.angle     = 0;
    }

  gridID = varDefGrid(vlistID, grid, 0);

  leveltype = iegGetZaxisType(IEG_P_LevelType(pdb));
  
  if ( leveltype == ZAXIS_HYBRID )
    {
      int i;
      double tmpvct[100];
      int vctsize = IEG_G_NumVCP(gdb);

      for ( i = 0; i < vctsize/2; i++ ) tmpvct[i] = vct[i];
      for ( i = 0; i < vctsize/2; i++ ) tmpvct[i+vctsize/2] = vct[i+50];

      varDefVCT(vctsize, tmpvct);
    }

  if ( IEG_P_LevelType(pdb) == IEG_LTYPE_HYBRID_LAYER ) lbounds = 1;

  datatype = iegInqDatatype(prec);

  varAddRecord(recID, code, gridID, leveltype, lbounds, level1, level2,
762
	       datatype, &varID, &levelID, 0, 0, 0);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
763
764
765
766

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
767
768
  streamptr->tsteps[tsID].nallrecs++;
  streamptr->nrecs++;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
769
770
771
772
773
774
775
776
777
778
779
780
781
782

  if ( CDI_Debug )
    Message(func, "varID = %d gridID = %d levelID = %d",
	    varID, gridID, levelID);
}


void iegCmpRecord(int streamID, int tsID, int recID, off_t position, int code,
		  int level, int xsize, int ysize)
{
  static char func[] = "iegCmpRecord";
  int varID = 0;
  int levelID = 0;
  RECORD *record;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
783
  STREAM *streamptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
784

Uwe Schulzweida's avatar
Uwe Schulzweida committed
785
786
787
  streamptr = stream_to_pointer(streamID);

  record  = &streamptr->tsteps[tsID].records[recID];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
788
789
790
791
792
793
794
795
796

  if ( code != (*record).code || level != (*record).ilevel )
    Error(func, "inconsistent timestep");

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
799
800
  streamptr->tsteps[tsID].nallrecs++;
  streamptr->nrecs++;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
  */
  if ( CDI_Debug )
    Message(func, "varID = %d levelID = %d", varID, levelID);
}


void iegDateTime(int *pdb, int *date, int *time)
{
  int ryear, rmonth, rday, rhour, rminute;

  ryear   = IEG_P_Year(pdb);

  rmonth  = IEG_P_Month(pdb);
  rday    = IEG_P_Day(pdb);

  rhour   = IEG_P_Hour(pdb);
  rminute = IEG_P_Minute(pdb);

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

821
  *date = encode_date(ryear, rmonth, rday);
822
  *time = encode_time(rhour, rminute, 0);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
}


void iegScanTimestep1(int streamID)
{  
  static char func[] = "iegScanTimestep1";
  int prec = 0;
  int status;
  int fileID;
  int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
  DateTime datetime, datetime0;
  int tsID;
  int varID;
  long recsize;
  off_t recpos;
  int nrecords, nrecs, recID;
  int taxisID = -1;
  TAXIS *taxis;
  int vlistID;
842
  IEGCOMPVAR compVar, compVar0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
843
  IEGREC *iegp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
844
845
846
  STREAM *streamptr;

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
848
  stream_check_ptr(func, streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
849

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
852
  iegp  = streamptr->record->iegp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
853
  tsID  = tstepsNewEntry(streamID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
854
  taxis = &streamptr->tsteps[tsID].taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
855
856
857
858
859
860
861
862
863
864
865
866
867

  if ( tsID != 0 )
    Error(func, "Internal problem! tstepsNewEntry returns %d", tsID);

  fileID = streamInqFileID(streamID);

  nrecs = 0;
  while ( TRUE )
    {
      recpos = fileGetPos(fileID);
      status = iegRead(fileID, iegp);
      if ( status != 0 )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
868
	  streamptr->ntsteps = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
869
870
871
872
873
874
875
876
877
878
879
	  break;
	}
      recsize = fileGetPos(fileID) - recpos;

      prec   = iegp->dprec;
      rcode  = IEG_P_Parameter(iegp->ipdb);
      if ( IEG_P_LevelType(iegp->ipdb) == IEG_LTYPE_HYBRID_LAYER )
	rlevel = IEG_P_Level1(iegp->ipdb);
      else
	rlevel = IEG_P_Level2(iegp->ipdb);

880
881
      if ( IEG_P_LevelType(iegp->ipdb) == 100 ) rlevel *= 100;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
882
883
884
885
886
887
888
889
890
891
892
      iegDateTime(iegp->ipdb, &vdate, &vtime);

      if ( nrecs == 0 )
	{
	  datetime0.date = vdate;
	  datetime0.time = vtime;
	}
      else
	{
	  datetime.date = vdate;
	  datetime.time = vtime;
893
894
	  compVar.code  = rcode;
          compVar.level = rlevel;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
895
896
	  for ( recID = 0; recID < nrecs; recID++ )
	    {
897
898
899
900
	      compVar0.code  = streamptr->tsteps[0].records[recID].code;
	      compVar0.level = streamptr->tsteps[0].records[recID].ilevel;

	      if ( memcmp(&compVar0, &compVar, sizeof(IEGCOMPVAR)) == 0 ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
901
902
903
904
905
906
907
908
909
910
911
912
913
914
	    }
	  if ( recID < nrecs ) break;
	  if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) )
	    Warning(func, "Inconsistent verification time for code %d level %d", rcode, rlevel);
	}

      nrecs++;

      if ( CDI_Debug )
	Message(func, "%4d%8d%4d%8d%8d%6d", nrecs, (int)recpos, rcode, rlevel, vdate, vtime);

      iegAddRecord(streamID, rcode, iegp->ipdb, iegp->igdb, iegp->vct, recsize, recpos, prec);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
915
  streamptr->rtsteps = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
916
917
918

  cdiGenVars(streamID);

919
  taxisID = taxisCreate(TAXIS_ABSOLUTE);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
920
921
922
923
924
925
926
927
928
  taxis->type  = TAXIS_ABSOLUTE;
  taxis->vdate = datetime0.date;
  taxis->vtime = datetime0.time;

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

  cdiCheckContents(streamID);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
929
930
  nrecords = streamptr->tsteps[0].nallrecs;
  if ( nrecords < streamptr->tsteps[0].recordSize )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
931
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
932
933
934
      streamptr->tsteps[0].recordSize = nrecords;
      streamptr->tsteps[0].records =
	(RECORD *) realloc(streamptr->tsteps[0].records, nrecords*sizeof(RECORD));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
935
936
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
937
938
  streamptr->tsteps[0].recIDs = (int *) malloc(nrecords*sizeof(int));
  streamptr->tsteps[0].nrecs = nrecords;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
939
  for ( recID = 0; recID < nrecords; recID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
940
    streamptr->tsteps[0].recIDs[recID] = recID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
941

Uwe Schulzweida's avatar
Uwe Schulzweida committed
942
  if ( streamptr->ntsteps == -1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
943
944
    {
      tsID = tstepsNewEntry(streamID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
945
      if ( tsID != streamptr->rtsteps )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
946
947
	Error(func, "Internal error. tsID = %d", tsID);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
948
949
      streamptr->tsteps[tsID-1].next   = TRUE;
      streamptr->tsteps[tsID].position = recpos;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
950
951
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
952
  if ( streamptr->ntsteps == 1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
953
954
955
    {
      if ( taxis->vdate == 0 && taxis->vtime == 0 )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
956
957
	  streamptr->ntsteps = 0;
	  for ( varID = 0; varID < streamptr->nvars; varID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
	    {
	      vlistDefVarTime(vlistID, varID, TIME_CONSTANT);
	    }
	}
    }
}


int iegScanTimestep2(int streamID)
{  
  static char func[] = "iegScanTimestep2";
  int status;
  int fileID;
  int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
  int tsID;
  int varID;
  long recsize;
  off_t recpos = 0;
  int nrecords, nrecs, recID, rindex;
  int nextstep;
  TAXIS *taxis;
  int vlistID;
980
  IEGCOMPVAR compVar, compVar0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
981
  IEGREC *iegp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
982
  STREAM *streamptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
983

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
986
987
988
  stream_check_ptr(func, streamptr);

  streamptr->curTsID = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
989
990
991

  vlistID = streamInqVlist(streamID);
  fileID  = streamInqFileID(streamID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
992
  iegp    = streamptr->record->iegp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
993

Uwe Schulzweida's avatar
Uwe Schulzweida committed
994
  tsID = streamptr->rtsteps;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
995
996
997
  if ( tsID != 1 )
    Error(func, "Internal problem! unexpeceted timestep %d", tsID+1);

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1000
  fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1001
1002
1003

  cdiCreateRecords(streamID, tsID);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1004
1005
1006
  nrecords = streamptr->tsteps[0].nallrecs;
  streamptr->tsteps[1].recIDs = (int *) malloc(nrecords*sizeof(int));
  streamptr->tsteps[1].nrecs = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1007
  for ( recID = 0; recID < nrecords; recID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1008
    streamptr->tsteps[1].recIDs[recID] = -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1009
1010
1011

  for ( recID = 0; recID < nrecords; recID++ )
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1012
1013
1014
1015
1016
      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
1017
1018
1019
1020
1021
1022
1023
1024
    }

  for ( rindex = 0; rindex <= nrecords; rindex++ )
    {
      recpos = fileGetPos(fileID);
      status = iegRead(fileID, iegp);
      if ( status != 0 )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1025
	  streamptr->ntsteps = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
	  break;
	}
      recsize = fileGetPos(fileID) - recpos;

      rcode  = IEG_P_Parameter(iegp->ipdb);
      if ( IEG_P_LevelType(iegp->ipdb) == IEG_LTYPE_HYBRID_LAYER )
	rlevel = IEG_P_Level1(iegp->ipdb);
      else
	rlevel = IEG_P_Level2(iegp->ipdb);

1036
1037
      if ( IEG_P_LevelType(iegp->ipdb) == 100 ) rlevel *= 100;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1038
1039
1040
1041
1042
1043
1044
1045
1046
      iegDateTime(iegp->ipdb, &vdate, &vtime);

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

1047
1048
      compVar.code  = rcode;
      compVar.level = rlevel;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1049
1050
1051
      nextstep = FALSE;
      for ( recID = 0; recID < nrecords; recID++ )
	{
1052
1053
1054
1055
	  compVar0.code  = streamptr->tsteps[tsID].records[recID].code;
	  compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;

	  if ( memcmp(&compVar0, &compVar, sizeof(IEGCOMPVAR)) == 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1056
	    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1057
	      if ( streamptr->tsteps[tsID].records[recID].used )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1058
1059
1060
1061
1062
		{
		  nextstep = TRUE;
		}
	      else
		{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1063
1064
		  streamptr->tsteps[tsID].records[recID].used = TRUE;
		  streamptr->tsteps[tsID].recIDs[rindex] = recID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
		}
	      break;
	    }
	}
      if ( recID == nrecords )
	{
	  Warning(func, "code %d level %d not found at timestep %d", rcode, rlevel, tsID+1);
	  return (CDI_EUFSTRUCT);
	}

      if ( nextstep ) break;

      if ( CDI_Debug )
	Message(func, "%4d%8d%4d%8d%8d%6d", rindex+1, (int)recpos, rcode, rlevel, vdate, vtime);

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

1082
1083
      compVar0.code  = streamptr->tsteps[tsID].records[recID].code;
      compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1084

1085
      if ( memcmp(&compVar0, &compVar, sizeof(IEGCOMPVAR)) != 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1086
1087
1088
	{
	  Message(func, "tsID = %d recID = %d code = %3d new %3d  level = %3d new %3d",
		  tsID, recID,
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1089
1090
		  streamptr->tsteps[tsID].records[recID].code, rcode,
		  streamptr->tsteps[tsID].records[recID].ilevel, rlevel);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1091
1092
1093
	  return (CDI_EUFSTRUCT);
	}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1094
      streamptr->tsteps[1].records[recID].position = recpos;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1095
1096
1097
1098
1099
    }

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1112
  streamptr->rtsteps = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1113

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1114
  if ( streamptr->ntsteps == -1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1115
1116
    {
      tsID = tstepsNewEntry(streamID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1117
      if ( tsID != streamptr->rtsteps )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1118
1119
	Error(func, "Internal error. tsID = %d", tsID);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1120
1121
      streamptr->tsteps[tsID-1].next   = TRUE;
      streamptr->tsteps[tsID].position = recpos;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
    }

  return (0);
}


int iegInqContents(int streamID)
{
  static char func[] = "iegInqContents";
  int fileID;
  int status = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1133
1134
1135
  STREAM *streamptr;

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1137
  stream_check_ptr(func, streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1138
1139
1140

  fileID = streamInqFileID(streamID);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1141
  streamptr->curTsID = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1142
1143
1144

  iegScanTimestep1(streamID);
 
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1145
  if ( streamptr->ntsteps == -1 ) status = iegScanTimestep2(streamID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164

  fileSetPos(fileID, 0, SEEK_SET);

  return (status);
}


int iegScanTimestep(int streamID)
{
  static char func[] = "iegScanTimestep";
  int status;
  int fileID;
  int tsID;
  int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
  long recsize = 0;
  off_t recpos = 0;
  int recID;
  TAXIS *taxis;
  int rindex, nrecs = 0;
1165
  IEGCOMPVAR compVar, compVar0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1166
  IEGREC *iegp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1167
  STREAM *streamptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1168

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1169
1170
1171
  streamptr = stream_to_pointer(streamID);

  stream_check_ptr(func, streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1172
1173
1174
1175

  if ( CDI_Debug )
    {
      Message(func, "streamID = %d", streamID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1176
1177
1178
      Message(func, "cts = %d", streamptr->curTsID);
      Message(func, "rts = %d", streamptr->rtsteps);
      Message(func, "nts = %d", streamptr->ntsteps);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1179
1180
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1181
  if ( streamptr->rtsteps == 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1182
1183
    Error(func, "Internal problem! Missing contents.");

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1184
1185
1186
  iegp  = streamptr->record->iegp;
  tsID  = streamptr->rtsteps;
  taxis = &streamptr->tsteps[tsID].taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1187

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1188
  if ( streamptr->tsteps[tsID].recordSize == 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1189
1190
1191
    {
      cdiCreateRecords(streamID, tsID);

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1194
1195
      streamptr->tsteps[tsID].nrecs = nrecs;
      streamptr->tsteps[tsID].recIDs = (int *) malloc(nrecs*sizeof(int));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1196
      for ( recID = 0; recID < nrecs; recID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1197
	streamptr->tsteps[tsID].recIDs[recID] = streamptr->tsteps[1].recIDs[recID];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1198
1199
1200

      fileID = streamInqFileID(streamID);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1201
      fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1202
1203
1204
1205
1206
1207
1208

      for ( rindex = 0; rindex <= nrecs; rindex++ )
	{
	  recpos = fileGetPos(fileID);
	  status = iegRead(fileID, iegp);
	  if ( status != 0 )
	    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1209
	      streamptr->ntsteps = streamptr->rtsteps + 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
	      break;
	    }
	  recsize = fileGetPos(fileID) - recpos;

	  rcode  = IEG_P_Parameter(iegp->ipdb);
	  if ( IEG_P_LevelType(iegp->ipdb) == IEG_LTYPE_HYBRID_LAYER )
	    rlevel = IEG_P_Level1(iegp->ipdb);
	  else
	    rlevel = IEG_P_Level2(iegp->ipdb);

1220
1221
	  if ( IEG_P_LevelType(iegp->ipdb) == 100 ) rlevel *= 100;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1222
1223
1224
	  iegDateTime(iegp->ipdb, &vdate, &vtime);

	  if ( rindex == nrecs ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1225
	  recID = streamptr->tsteps[tsID].recIDs[rindex];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1226
1227
1228
1229
1230
1231
1232
1233

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

1234
1235
1236
1237
	  compVar.code  = rcode;
          compVar.level = rlevel;
	  compVar0.code  = streamptr->tsteps[tsID].records[recID].code;
	  compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1238

1239
	  if ( memcmp(&compVar0, &compVar, sizeof(IEGCOMPVAR)) != 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1240
1241
1242
	    {
	      Message(func, "tsID = %d recID = %d code = %3d new %3d  level = %3d new %3d",
		      tsID, recID,
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1243
1244
		      streamptr->tsteps[tsID].records[recID].code, rcode,
		      streamptr->tsteps[tsID].records[recID].ilevel, rlevel);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1245
1246
1247
	      Error(func, "Invalid, unsupported or inconsistent record structure");
	    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1248
1249
	  streamptr->tsteps[tsID].records[recID].position = recpos;
	  streamptr->tsteps[tsID].records[recID].size = recsize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1250
1251
1252
1253
1254

	  if ( CDI_Debug )
	    Message(func, "%4d%8d%4d%8d%8d%6d", rindex, (int)recpos, rcode, rlevel, vdate, vtime);
	}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1255
      streamptr->rtsteps++;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1256

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1257
      if ( streamptr->ntsteps != streamptr->rtsteps )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1258
1259
	{
	  tsID = tstepsNewEntry(streamID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1260
	  if ( tsID != streamptr->rtsteps )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1261
1262
	    Error(func, "Internal error. tsID = %d", tsID);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1263
1264
	  streamptr->tsteps[tsID-1].next   = 1;
	  streamptr->tsteps[tsID].position = recpos;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1265
1266
	}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1267
1268
      fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
      streamptr->tsteps[tsID].position = recpos;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1269
1270
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1271
  if ( nrecs > 0 && nrecs < streamptr->tsteps[tsID].nrecs )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1272
1273
    {
      Warning(func, "Incomplete timestep. Stop scanning at timestep %d.\n", tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1274
      streamptr->ntsteps = tsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1275
1276
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1277
  return (streamptr->ntsteps);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1278
1279
1280
1281
1282
1283
1284
}


int iegInqTimestep(int streamID, int tsID)
{
  static char func[] = "iegInqTimestep";
  int ntsteps, nrecs;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1285
1286
1287
  STREAM *streamptr;

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1289
  stream_check_ptr(func, streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1290

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1291
  if ( tsID == 0 && streamptr->rtsteps == 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1292
1293
1294
    Error(func, "Call to cdiInqContents missing!");

  if ( CDI_Debug )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1295
    Message(func, "tsID = %d rtsteps = %d", tsID, streamptr->rtsteps);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1296
1297
  
  ntsteps = UNDEFID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1298
  while ( ( tsID + 1 ) > streamptr->rtsteps && ntsteps == UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1299
1300
    ntsteps = iegScanTimestep(streamID);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1301
  if ( tsID >= streamptr->ntsteps && streamptr->ntsteps != CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1302
1303
1304
1305
1306
    {
      nrecs = 0;
    }
  else
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1307
1308
      streamptr->curTsID = tsID;
      nrecs = streamptr->tsteps[tsID].nrecs;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
    }

  return (nrecs);
}


void iegReadVarDP(int streamID, int varID, double *data, int *nmiss)
{
  static char func[] = "iegReadVarDP";
  int vlistID, fileID;
  int levID, nlevs, gridID, gridsize;
  off_t recpos, currentfilepos;
  int tsid;
  int recID;
  int i;
  int status;
  double missval;
  IEGREC *iegp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1327
  STREAM *streamptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1328

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1329
1330
1331
  streamptr = stream_to_pointer(streamID);

  iegp     = streamptr->record->iegp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1332
1333
  vlistID  = streamInqVlist(streamID);
  fileID   = streamInqFileID(streamID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1334
  nlevs    = streamptr->vars[varID].nlevs;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1335
1336
1337
  missval  = vlistInqVarMissval(vlistID, varID);
  gridID   = vlistInqVarGrid(vlistID, varID);
  gridsize = gridInqSize(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1338
  tsid     = streamptr->curTsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1339
1340
1341
1342
1343
1344
1345
1346

  if ( CDI_Debug )
    Message(func, "nlevs = %d gridID = %d gridsize = %d", nlevs, gridID, gridsize);

  currentfilepos = fileGetPos(fileID);

  for (levID = 0; levID < nlevs; levID++)
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1347
1348
      recID = streamptr->vars[varID].level[levID];
      recpos = streamptr->tsteps[tsid].records[recID].position;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
      fileSetPos(fileID, recpos, SEEK_SET);
      status = iegRead(fileID, iegp);
      iegInqDataDP(iegp, &data[levID*gridsize]);
    }
  fileSetPos(fileID, currentfilepos, SEEK_SET);

  *nmiss = 0;
  for ( i = 0; i < nlevs*gridsize; i++ )
    if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
      {
	data[i] = missval;
	(*nmiss)++;
      }
}


void iegReadVarSliceDP(int streamID, int varID, int levID, double *data, int *nmiss)
{
  static char func[] = "iegReadVarSliceDP";
  int vlistID, fileID;
  int nlevs, gridID, gridsize;
  off_t recpos, currentfilepos;
  int tsid;
  int recID;
  int i;
  int status;
  double missval;
  IEGREC *iegp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1377
1378
1379
  STREAM *streamptr;

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1381
  iegp     = streamptr->record->iegp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1382
1383
  vlistID  = streamInqVlist(streamID);
  fileID   = streamInqFileID(streamID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1384
  nlevs    = streamptr->vars[varID].nlevs;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1385
1386
1387
  missval  = vlistInqVarMissval(vlistID, varID);
  gridID   = vlistInqVarGrid(vlistID, varID);
  gridsize = gridInqSize(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1388
  tsid     = streamptr->curTsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1389
1390
1391
1392
1393
1394
1395

  if ( CDI_Debug )
    Message(func, "nlevs = %d gridID = %d gridsize = %d",
	     nlevs, gridID, gridsize);

  currentfilepos = fileGetPos(fileID);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1396
1397
  recID = streamptr->vars[varID].level[levID];
  recpos = streamptr->tsteps[tsid].records[recID].position;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
  fileSetPos(fileID, recpos, SEEK_SET);
  status = iegRead(fileID, iegp);
  iegInqDataDP(iegp, data);

  fileSetPos(fileID, currentfilepos, SEEK_SET);

  *nmiss = 0;
  for ( i = 0; i < gridsize; i++ )
    if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
      {
	data[i] = missval;
	(*nmiss)++;
      }
}


void iegWriteVarDP(int streamID, int varID, const double *data)
{
  static char func[] = "iegWriteVarDP";
  int fileID;
  int levID, nlevs, gridID, gridsize;
  int zaxisID;
  double level;
  int datatype;
  int tsID;
  int vlistID;
  int i;
  int code, date, time, datasize;
  IEGREC *iegp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1427
1428
1429
  STREAM *streamptr;

  streamptr = stream_to_pointer(streamID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1430
1431
1432
1433

  if ( CDI_Debug )
    Message(func, "streamID = %d  varID = %d", streamID, varID);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1434
  iegp     = streamptr->record->iegp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1435

1436
  iegInitMem(iegp);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1437
1438
1439
1440
  for ( i = 0; i < 37; i++ ) iegp->ipdb[i] = -1;

  vlistID  = streamInqVlist(streamID);
  fileID   = streamInqFileID(streamID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1441
  tsID     = streamptr->curTsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1442
1443
1444
1445
1446
1447
1448
1449
1450
  gridID   = vlistInqVarGrid(vlistID, varID);
  gridsize = gridInqSize(gridID);
  zaxisID  = vlistInqVarZaxis(vlistID, varID);
  nlevs    = zaxisInqSize(zaxisID);

  if ( CDI_Debug )
    Message(func, "nlevs = %d gridID = %d gridsize = %d", nlevs, gridID, gridsize);

  code     = vlistInqVarCode(vlistID, varID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1451
1452
  date     = streamptr->tsteps[tsID].taxis.vdate;
  time     = streamptr->tsteps[tsID].taxis.vtime;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
  datasize = gridInqSize(gridID);

  datatype = vlistInqVarDatatype(vlistID, varID);

  iegp->dprec = iegDefDatatype(datatype);

  for ( levID = 0;  levID < nlevs; levID++ )
    {
      level = zaxisInqLevel(zaxisID, levID);

      /*  header[1] = (int) level; */
      iegDefDataDP(iegp, &data[levID*gridsize]);
      iegWrite(fileID, iegp);
    }
}


void iegWriteVarSliceDP(int streamID, int varID, int levID, const double *data)
{
  static char func[] = "iegWriteVarSliceDP";
  int fileID;
  int gridID;
  int zaxisID;
  double level;
  int datatype;
  int tsID;
  int vlistID;
  int code, date, time, datasize;
  IEGREC *iegp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1482
1483
1484
  STREAM *streamptr;

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1486
  iegp     = streamptr->record->iegp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1487
1488
  vlistID  = streamInqVlist(streamID);
  fileID   = streamInqFileID(streamID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1489
  tsID     = streamptr->curTsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1490
1491
1492
1493
1494
1495
1496
1497
  gridID   = vlistInqVarGrid(vlistID, varID);
  zaxisID  = vlistInqVarZaxis(vlistID, varID);
  level    = zaxisInqLevel(zaxisID, levID);

  if ( CDI_Debug )
    Message(func, "gridID = %d zaxisID = %d", gridID, zaxisID);

  code = vlistInqVarCode(vlistID, varID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1498
1499
  date = streamptr->tsteps[tsID].taxis.vdate;
  time = streamptr->tsteps[tsID].taxis.vtime;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
  datasize = gridInqSize(gridID);

  datatype = vlistInqVarDatatype(vlistID, varID);

  iegp->dprec = iegDefDatatype(datatype);

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

#endif /* HAVE_LIBIEG */