stream_ext.c 22.4 KB
Newer Older
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1
2
3
4
#if defined (HAVE_CONFIG_H)
#  include "config.h"
#endif

5
#include <limits.h>
Uwe Schulzweida's avatar
Uwe Schulzweida committed
6
7
8
9
10
11
12
13
#include <stdio.h>
#include <string.h>

#include "dmemory.h"

#include "error.h"
#include "file.h"
#include "cdi.h"
14
#include "cdi_int.h"
15
#include "stream_ext.h"
16
#include "stream_fcommon.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include "varscan.h"
#include "datetime.h"
#include "extra.h"
#include "vlist.h"


#undef  UNDEFID
#define UNDEFID  CDI_UNDEFID

#define SINGLE_PRECISION  4
#define DOUBLE_PRECISION  8

#if defined (HAVE_LIBEXTRA)

31
32

typedef struct {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
33
  int param;
34
  int level;
35
} extcompvar_t;
36

Uwe Schulzweida's avatar
Uwe Schulzweida committed
37
static
38
int extInqDatatype(int prec, int number)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
39
40
41
{
  int datatype;

42
43
44
45
46
47
48
49
50
51
  if ( number == 2 )
    {
      if ( prec == DOUBLE_PRECISION ) datatype = DATATYPE_CPX64;
      else                            datatype = DATATYPE_CPX32;
    }
  else
    {
      if ( prec == DOUBLE_PRECISION ) datatype = DATATYPE_FLT64;
      else                            datatype = DATATYPE_FLT32;
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
52
53
54
55

  return (datatype);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
56
static
57
void extDefDatatype(int datatype, int *prec, int *number)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
58
59
{

60
61
  if ( datatype != DATATYPE_FLT32 && datatype != DATATYPE_FLT64 &&
       datatype != DATATYPE_CPX32 && datatype != DATATYPE_CPX64 )
62
    datatype = DATATYPE_FLT32;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
63

64
65
66
67
  if ( datatype == DATATYPE_CPX32 || datatype == DATATYPE_CPX64 )
    *number = 2;
  else
    *number = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
68

69
70
71
72
  if ( datatype == DATATYPE_FLT64 || datatype == DATATYPE_CPX64 )
    *prec = DOUBLE_PRECISION;
  else 
    *prec = SINGLE_PRECISION;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
73
74
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
75
/* not used
76
int extInqRecord(stream_t *streamptr, int *varID, int *levelID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
77
78
79
{
  int status;
  int fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
80
  int icode, ilevel;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
81
82
83
  int zaxisID = -1;
  int header[4];
  int vlistID;
84
  void *extp = streamptr->record->exsep;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
85

86
87
  vlistID = streamptr->vlistID;
  fileID  = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
88
89
90
91
92
93
94
95
96

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

  status = extRead(fileID, extp);
  if ( status != 0 ) return (0);

  extInqHeader(extp, header);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
97
  icode  = header[1];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
98
99
  ilevel = header[2];

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

102
  if ( *varID == UNDEFID ) Error("Code %d undefined", icode);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
103
104
105
106

  zaxisID = vlistInqVarZaxis(vlistID, *varID);

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
108
109
  return (1);
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
110
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
111

112
void extReadRecord(stream_t *streamptr, double *data, int *nmiss)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
113
114
115
116
117
118
119
120
121
{
  int vlistID, fileID;
  int status;
  int recID, vrecID, tsID;
  off_t recpos;
  int header[4];
  int varID, gridID;
  int i, size;
  double missval;
122
  void *extp = streamptr->record->exsep;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
123

124
125
  vlistID = streamptr->vlistID;
  fileID  = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
126
127
128
129
130
  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;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
131
132
133
134

  fileSetPos(fileID, recpos, SEEK_SET);

  status = extRead(fileID, extp);
135
136
  if ( status != 0 )
    Error("Failed to read EXTRA record");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
137
138
139
140

  extInqHeader(extp, header);
  extInqDataDP(extp, data);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
141
  missval = vlistInqVarMissval(vlistID, varID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
142
143
  gridID  = vlistInqVarGrid(vlistID, varID);
  size    = gridInqSize(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
144

Uwe Schulzweida's avatar
Uwe Schulzweida committed
145
  streamptr->numvals += size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
146
147

  *nmiss = 0;
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
  if ( vlistInqVarNumber(vlistID, varID) == CDI_REAL )
    {
      for ( i = 0; i < size; i++ )
	if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
	  {
	    data[i] = missval;
	    (*nmiss)++;
	  }
    }
  else
    {
      for ( i = 0; i < 2*size; i+=2 )
	if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
	  {
	    data[i] = missval;
	    (*nmiss)++;
	  }
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
166
167
168
}


169
void extCopyRecord(stream_t *streamptr2, stream_t *streamptr1)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
170
{
171
  streamFCopyRecord(streamptr2, streamptr1, "EXTRA");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
172
173
174
}


175
void extDefRecord(stream_t *streamptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
176
177
178
{
  int gridID;
  int header[4];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
179
  int pdis, pcat, pnum;
180
  extrec_t *extp = (extrec_t*) streamptr->record->exsep;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
181

182
  gridID   = streamptr->record->gridID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
183

Uwe Schulzweida's avatar
Uwe Schulzweida committed
184
  cdiDecodeParam(streamptr->record->param, &pnum, &pcat, &pdis);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
185
  header[0] = streamptr->record->date;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
186
  header[1] = pnum;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
187
  header[2] = streamptr->record->level;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
188
189
  header[3] = gridInqSize(gridID);

190
  extDefDatatype(streamptr->record->prec, &extp->prec, &extp->number);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
191
192
193
194
195

  extDefHeader(extp, header);
}


196
void extWriteRecord(stream_t *streamptr, const double *data)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
197
{
198
  int fileID = streamptr->fileID;
199
  void *extp = streamptr->record->exsep;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
200
201
202
203
204

  extDefDataDP(extp, data);
  extWrite(fileID, extp);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
205
static
206
void extAddRecord(stream_t *streamptr, int param, int level, int xysize,
207
		  size_t recsize, off_t position, int prec, int number)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
208
{
209
210
211
212
  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
213

214
215
216
217
  record->size     = recsize;
  record->position = position;
  record->param    = param;
  record->ilevel   = level;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
218

219
220
  grid_t *grid = (grid_t *)Malloc(sizeof (*grid));
  grid_init(grid);
221
  cdiGridTypeInit(grid, GRID_GENERIC, xysize);
222
223
224
225
  grid->xsize = xysize;
  grid->ysize = 0;
  grid->xvals = NULL;
  grid->yvals = NULL;
226
227
228
  struct addIffNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, grid, 0);
  int gridID = gridAdded.Id;
  if (!gridAdded.isNew) Free(grid);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
229
230
231
232
  /*
  if ( level == 0 ) leveltype = ZAXIS_SURFACE;
  else              leveltype = ZAXIS_GENERIC;
  */
233
  int leveltype = ZAXIS_GENERIC;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
234

235
  int varID, levelID = 0;
236
  varAddRecord(recID, param, gridID, leveltype, 0, level, 0, 0, 0,
237
               extInqDatatype(prec, number), &varID, &levelID, TSTEP_INSTANT, 0, 0, -1,
238
               NULL, NULL, NULL, NULL, NULL, NULL);
239
240
  record->varID   = (short)varID;
  record->levelID = (short)levelID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
241

Uwe Schulzweida's avatar
Uwe Schulzweida committed
242
243
  streamptr->tsteps[tsID].nallrecs++;
  streamptr->nrecs++;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
244
245

  if ( CDI_Debug )
246
    Message("varID = %d gridID = %d levelID = %d",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
247
248
249
	    varID, gridID, levelID);
}

250
static
251
252
void extScanTimestep1(stream_t *streamptr)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
253
254
255
256
  int header[4];
  int status;
  int fileID;
  int rxysize = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
257
258
  int param = 0;
  int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
259
  DateTime datetime0 = { LONG_MIN, LONG_MIN };
Uwe Schulzweida's avatar
Uwe Schulzweida committed
260
261
262
263
264
265
  int tsID;
  int varID;
  long recsize;
  off_t recpos;
  int nrecords, nrecs, recID;
  int taxisID = -1;
266
  taxis_t *taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
267
  int vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
268
  extcompvar_t compVar, compVar0;
269
  extrec_t *extp = (extrec_t*) streamptr->record->exsep;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
270

Uwe Schulzweida's avatar
Uwe Schulzweida committed
271
  streamptr->curTsID = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
272

273
  tsID  = tstepsNewEntry(streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
274
  taxis = &streamptr->tsteps[tsID].taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
275
276

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

279
  fileID = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
280
281
282
283
284
285
286
287

  nrecs = 0;
  while ( TRUE )
    {
      recpos = fileGetPos(fileID);
      status = extRead(fileID, extp);
      if ( status != 0 )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
288
	  streamptr->ntsteps = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
289
290
291
292
293
294
	  break;
	}
      recsize = fileGetPos(fileID) - recpos;

      extInqHeader(extp, header);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
295
296
297
298
      vdate   = header[0];
      vtime   = 0;
      rcode   = header[1];
      rlevel  = header[2];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
299
300
      rxysize = header[3];

Uwe Schulzweida's avatar
Uwe Schulzweida committed
301
      param = cdiEncodeParam(rcode, 255, 255);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
302

Uwe Schulzweida's avatar
Uwe Schulzweida committed
303
304
305
306
307
308
309
      if ( nrecs == 0 )
	{
	  datetime0.date = vdate;
	  datetime0.time = vtime;
	}
      else
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
310
	  compVar.param = param;
311
          compVar.level = rlevel;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
312
313
	  for ( recID = 0; recID < nrecs; recID++ )
	    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
314
	      compVar0.param  = streamptr->tsteps[0].records[recID].param;
315
316
	      compVar0.level = streamptr->tsteps[0].records[recID].ilevel;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
317
	      if ( memcmp(&compVar0, &compVar, sizeof(extcompvar_t)) == 0 ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
318
319
	    }
	  if ( recID < nrecs ) break;
320
321
	  DateTime datetime = { .date = vdate, .time = vtime};
	  if ( datetimeCmp(datetime, datetime0) )
322
	    Warning("Inconsistent verification time for code %d level %d", rcode, rlevel);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
323
324
325
326
327
	}

      nrecs++;

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

330
      extAddRecord(streamptr, param, rlevel, rxysize, (size_t)recsize, recpos, extp->prec, extp->number);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
331
332
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
333
  streamptr->rtsteps = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
334

335
  cdi_generate_vars(streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
336

337
  taxisID = taxisCreate(TAXIS_ABSOLUTE);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
338
  taxis->type  = TAXIS_ABSOLUTE;
339
340
  taxis->vdate = (int)datetime0.date;
  taxis->vtime = (int)datetime0.time;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
341

342
  vlistID = streamptr->vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
343
344
  vlistDefTaxis(vlistID, taxisID);

345
  vlist_check_contents(vlistID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
346

Uwe Schulzweida's avatar
Uwe Schulzweida committed
347
348
  nrecords = streamptr->tsteps[0].nallrecs;
  if ( nrecords < streamptr->tsteps[0].recordSize )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
349
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
350
351
      streamptr->tsteps[0].recordSize = nrecords;
      streamptr->tsteps[0].records =
352
        (record_t *) Realloc(streamptr->tsteps[0].records, (size_t)nrecords * sizeof (record_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
353
354
    }

355
  streamptr->tsteps[0].recIDs = (int *) Malloc((size_t)nrecords * sizeof (int));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
356
  streamptr->tsteps[0].nrecs = nrecords;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
357
  for ( recID = 0; recID < nrecords; recID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
358
    streamptr->tsteps[0].recIDs[recID] = recID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
359

Uwe Schulzweida's avatar
Uwe Schulzweida committed
360
  if ( streamptr->ntsteps == -1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
361
    {
362
      tsID = tstepsNewEntry(streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
363
      if ( tsID != streamptr->rtsteps )
364
	Error("Internal error. tsID = %d", tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
365

Uwe Schulzweida's avatar
Uwe Schulzweida committed
366
367
      streamptr->tsteps[tsID-1].next   = TRUE;
      streamptr->tsteps[tsID].position = recpos;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
368
369
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
370
  if ( streamptr->ntsteps == 1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
371
372
373
    {
      if ( taxis->vdate == 0 && taxis->vtime == 0 )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
374
375
	  streamptr->ntsteps = 0;
	  for ( varID = 0; varID < streamptr->nvars; varID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
376
	    {
377
	      vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
378
379
380
381
382
	    }
	}
    }
}

383
static
384
385
int extScanTimestep2(stream_t *streamptr)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
386
387
388
  int header[4];
  int status;
  int fileID;
389
  // int rxysize = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
390
391
  int param = 0;
  int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
392
393
394
395
396
  int tsID;
  int varID;
  off_t recpos = 0;
  int nrecords, nrecs, recID, rindex;
  int nextstep;
397
  taxis_t *taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
398
  int vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
399
  extcompvar_t compVar, compVar0;
400
  void *extp = streamptr->record->exsep;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
401
402

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

404
405
  fileID  = streamptr->fileID;
  vlistID = streamptr->vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
406

Uwe Schulzweida's avatar
Uwe Schulzweida committed
407
  tsID = streamptr->rtsteps;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
408
  if ( tsID != 1 )
409
    Error("Internal problem! unexpected timestep %d", tsID+1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
410

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

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

415
  cdi_create_records(streamptr, tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
416

Uwe Schulzweida's avatar
Uwe Schulzweida committed
417
  nrecords = streamptr->tsteps[0].nallrecs;
418
  streamptr->tsteps[1].recIDs = (int *) Malloc((size_t)nrecords * sizeof (int));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
419
  streamptr->tsteps[1].nrecs = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
420
  for ( recID = 0; recID < nrecords; recID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
421
    streamptr->tsteps[1].recIDs[recID] = -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
422
423
424

  for ( recID = 0; recID < nrecords; recID++ )
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
425
      varID = streamptr->tsteps[0].records[recID].varID;
426
      streamptr->tsteps[tsID].records[recID].position =
Uwe Schulzweida's avatar
Uwe Schulzweida committed
427
	streamptr->tsteps[0].records[recID].position;
428
      streamptr->tsteps[tsID].records[recID].size     =
Uwe Schulzweida's avatar
Uwe Schulzweida committed
429
	streamptr->tsteps[0].records[recID].size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
430
431
432
433
434
435
436
437
    }

  for ( rindex = 0; rindex <= nrecords; rindex++ )
    {
      recpos = fileGetPos(fileID);
      status = extRead(fileID, extp);
      if ( status != 0 )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
438
	  streamptr->ntsteps = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
439
440
	  break;
	}
441
      size_t recsize = (size_t)(fileGetPos(fileID) - recpos);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
442
443
444
445
446

      extInqHeader(extp, header);

      vdate  = header[0];
      vtime  = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
447
      rcode  = header[1];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
448
      rlevel = header[2];
449
      // rxysize = header[3];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
450

Uwe Schulzweida's avatar
Uwe Schulzweida committed
451
      param = cdiEncodeParam(rcode, 255, 255);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
452

Uwe Schulzweida's avatar
Uwe Schulzweida committed
453
454
455
456
457
458
459
      if ( rindex == 0 )
	{
	  taxis->type  = TAXIS_ABSOLUTE;
	  taxis->vdate = vdate;
	  taxis->vtime = vtime;
	}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
460
      compVar.param = param;
461
      compVar.level = rlevel;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
462
463
464
      nextstep = FALSE;
      for ( recID = 0; recID < nrecords; recID++ )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
465
	  compVar0.param = streamptr->tsteps[tsID].records[recID].param;
466
467
	  compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
468
	  if ( memcmp(&compVar0, &compVar, sizeof(extcompvar_t)) == 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
469
	    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
470
	      if ( streamptr->tsteps[tsID].records[recID].used )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
471
472
473
474
475
		{
		  nextstep = TRUE;
		}
	      else
		{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
476
477
		  streamptr->tsteps[tsID].records[recID].used = TRUE;
		  streamptr->tsteps[tsID].recIDs[rindex] = recID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
478
479
480
481
482
483
		}
	      break;
	    }
	}
      if ( recID == nrecords )
	{
484
	  Warning("Code %d level %d not found at timestep %d", rcode, rlevel, tsID+1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
485
486
487
488
489
490
	  return (CDI_EUFSTRUCT);
	}

      if ( nextstep ) break;

      if ( CDI_Debug )
491
	Message("%4d%8d%4d%8d%8d%6d", rindex+1, (int)recpos, rcode, rlevel, vdate, vtime);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
492

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
495
      compVar0.param  = streamptr->tsteps[tsID].records[recID].param;
496
      compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
497

Uwe Schulzweida's avatar
Uwe Schulzweida committed
498
      if ( memcmp(&compVar0, &compVar, sizeof(extcompvar_t)) != 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
499
	{
500
	  Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
501
		  tsID, recID,
Uwe Schulzweida's avatar
Uwe Schulzweida committed
502
		  streamptr->tsteps[tsID].records[recID].param, param,
Uwe Schulzweida's avatar
Uwe Schulzweida committed
503
		  streamptr->tsteps[tsID].records[recID].ilevel, rlevel);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
504
505
506
	  return (CDI_EUFSTRUCT);
	}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
507
      streamptr->tsteps[1].records[recID].position = recpos;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
508
509
510
511
512
    }

  nrecs = 0;
  for ( recID = 0; recID < nrecords; recID++ )
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
513
      if ( ! streamptr->tsteps[tsID].records[recID].used )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
514
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
515
	  varID = streamptr->tsteps[tsID].records[recID].varID;
516
          vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
517
518
519
520
521
522
	}
      else
	{
	  nrecs++;
	}
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
523
  streamptr->tsteps[tsID].nrecs = nrecs;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
524

Uwe Schulzweida's avatar
Uwe Schulzweida committed
525
  streamptr->rtsteps = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
526

Uwe Schulzweida's avatar
Uwe Schulzweida committed
527
  if ( streamptr->ntsteps == -1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
528
    {
529
      tsID = tstepsNewEntry(streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
530
      if ( tsID != streamptr->rtsteps )
531
	Error("Internal error. tsID = %d", tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
532

Uwe Schulzweida's avatar
Uwe Schulzweida committed
533
534
      streamptr->tsteps[tsID-1].next   = TRUE;
      streamptr->tsteps[tsID].position = recpos;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
535
536
537
538
539
540
    }

  return (0);
}


541
int extInqContents(stream_t *streamptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
542
543
544
545
{
  int fileID;
  int status = 0;

546
  fileID = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
547

Uwe Schulzweida's avatar
Uwe Schulzweida committed
548
  streamptr->curTsID = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
549

550
551
552
  extScanTimestep1(streamptr);

  if ( streamptr->ntsteps == -1 ) status = extScanTimestep2(streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
553
554
555
556
557
558

  fileSetPos(fileID, 0, SEEK_SET);

  return (status);
}

559
static
560
long extScanTimestep(stream_t *streamptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
561
562
563
564
{
  int header[4];
  int status;
  int fileID;
565
  // int rxysize = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
566
567
  int param = 0;
  int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
568
569
570
  off_t recpos = 0;
  int recID;
  int rindex, nrecs = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
571
  extcompvar_t compVar, compVar0;
572
  void *extp = streamptr->record->exsep;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
573
  /*
Uwe Schulzweida's avatar
Uwe Schulzweida committed
574
575
  if ( CDI_Debug )
    {
576
      Message("streamID = %d", streamptr->self);
577
578
579
      Message("cts = %d", streamptr->curTsID);
      Message("rts = %d", streamptr->rtsteps);
      Message("nts = %d", streamptr->ntsteps);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
580
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
581
  */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
582

Uwe Schulzweida's avatar
Uwe Schulzweida committed
583
584
  int tsID  = streamptr->rtsteps;
  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
585

Uwe Schulzweida's avatar
Uwe Schulzweida committed
586
  if ( streamptr->tsteps[tsID].recordSize == 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
587
    {
588
      cdi_create_records(streamptr, tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
589

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
592
      streamptr->tsteps[tsID].nrecs = nrecs;
593
      streamptr->tsteps[tsID].recIDs = (int *) Malloc((size_t)nrecs * sizeof (int));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
594
      for ( recID = 0; recID < nrecs; recID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
595
	streamptr->tsteps[tsID].recIDs[recID] = streamptr->tsteps[1].recIDs[recID];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
596

597
      fileID = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
598

Uwe Schulzweida's avatar
Uwe Schulzweida committed
599
      fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
600
601
602
603
604
605
606

      for ( rindex = 0; rindex <= nrecs; rindex++ )
	{
	  recpos = fileGetPos(fileID);
	  status = extRead(fileID, extp);
	  if ( status != 0 )
	    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
607
	      streamptr->ntsteps = streamptr->rtsteps + 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
608
609
	      break;
	    }
610
	  size_t recsize = (size_t)(fileGetPos(fileID) - recpos);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
611
612
613
614
615

	  extInqHeader(extp, header);

	  vdate  = header[0];
	  vtime  = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
616
	  rcode  = header[1];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
617
	  rlevel = header[2];
618
	  // rxysize = header[3];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
619

Uwe Schulzweida's avatar
Uwe Schulzweida committed
620
	  param = cdiEncodeParam(rcode, 255, 255);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
621

622
623
	  // if ( rindex == nrecs ) break; gcc-4.5 internal compiler error
	  if ( rindex == nrecs ) continue;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
624
	  recID = streamptr->tsteps[tsID].recIDs[rindex];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
625
626
627
628
629
630
631

	  if ( rindex == 0 )
	    {
	      taxis->type  = TAXIS_ABSOLUTE;
	      taxis->vdate = vdate;
	      taxis->vtime = vtime;
	    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
632

Uwe Schulzweida's avatar
Uwe Schulzweida committed
633
634
635
	  compVar.param  = param;
          compVar.level  = rlevel;
	  compVar0.param = streamptr->tsteps[tsID].records[recID].param;
636
	  compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
637

Uwe Schulzweida's avatar
Uwe Schulzweida committed
638
	  if ( memcmp(&compVar0, &compVar, sizeof(extcompvar_t)) != 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
639
	    {
640
	      Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
641
		      tsID, recID,
Uwe Schulzweida's avatar
Uwe Schulzweida committed
642
		      streamptr->tsteps[tsID].records[recID].param, param,
Uwe Schulzweida's avatar
Uwe Schulzweida committed
643
		      streamptr->tsteps[tsID].records[recID].ilevel, rlevel);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
644
	      Error("Invalid, unsupported or inconsistent record structure!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
645
646
	    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
647
648
	  streamptr->tsteps[tsID].records[recID].position = recpos;
	  streamptr->tsteps[tsID].records[recID].size = recsize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
649
650

	  if ( CDI_Debug )
651
	    Message("%4d%8d%4d%8d%8d%6d", rindex, (int)recpos, rcode, rlevel, vdate, vtime);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
652
653
	}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
654
      streamptr->rtsteps++;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
655

Uwe Schulzweida's avatar
Uwe Schulzweida committed
656
      if ( streamptr->ntsteps != streamptr->rtsteps )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
657
	{
658
	  tsID = tstepsNewEntry(streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
659
	  if ( tsID != streamptr->rtsteps )
660
	    Error("Internal error. tsID = %d", tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
661

Uwe Schulzweida's avatar
Uwe Schulzweida committed
662
663
	  streamptr->tsteps[tsID-1].next   = 1;
	  streamptr->tsteps[tsID].position = recpos;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
664
665
	}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
666
667
      fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
      streamptr->tsteps[tsID].position = recpos;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
668
669
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
670
  if ( nrecs > 0 && nrecs < streamptr->tsteps[tsID].nrecs )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
671
    {
672
      Warning("Incomplete timestep. Stop scanning at timestep %d.", tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
673
      streamptr->ntsteps = tsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
674
675
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
676
  return (streamptr->ntsteps);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
677
678
679
}


680
int extInqTimestep(stream_t *streamptr, int tsID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
681
{
682
683
  int nrecs;
  long ntsteps;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
684

Uwe Schulzweida's avatar
Uwe Schulzweida committed
685
  if ( tsID == 0 && streamptr->rtsteps == 0 )
686
    Error("Call to cdiInqContents missing!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
687
688

  if ( CDI_Debug )
689
    Message("tsID = %d rtsteps = %d", tsID, streamptr->rtsteps);
690

Uwe Schulzweida's avatar
Uwe Schulzweida committed
691
  ntsteps = UNDEFID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
692
  while ( ( tsID + 1 ) > streamptr->rtsteps && ntsteps == UNDEFID )
693
    ntsteps = extScanTimestep(streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
694

Uwe Schulzweida's avatar
Uwe Schulzweida committed
695
  if ( tsID >= streamptr->ntsteps && streamptr->ntsteps != CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
696
697
698
699
700
    {
      nrecs = 0;
    }
  else
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
701
702
      streamptr->curTsID = tsID;
      nrecs = streamptr->tsteps[tsID].nrecs;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
703
704
705
706
707
708
    }

  return (nrecs);
}


709
void extReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
710
711
712
713
714
715
716
717
718
{
  int vlistID, fileID;
  int levID, nlevs, gridID, gridsize;
  off_t recpos, currentfilepos;
  int header[4];
  int tsid;
  int recID;
  int i;
  double missval;
719
  void *extp = streamptr->record->exsep;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
720

721
722
  vlistID  = streamptr->vlistID;
  fileID   = streamptr->fileID;
723
724
  /* NOTE: tiles are not supported here! */
  nlevs    = streamptr->vars[varID].recordTable[0].nlevs;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
725
726
727
  missval  = vlistInqVarMissval(vlistID, varID);
  gridID   = vlistInqVarGrid(vlistID, varID);
  gridsize = gridInqSize(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
728
  tsid     = streamptr->curTsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
729
730

  if ( CDI_Debug )
731
    Message("nlevs = %d gridID = %d gridsize = %d", nlevs, gridID, gridsize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
732
733
734
735
736

  currentfilepos = fileGetPos(fileID);

  for (levID = 0; levID < nlevs; levID++)
    {
737
738
      /* NOTE: tiles are not supported here! */
      recID = streamptr->vars[varID].recordTable[0].recordID[levID];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
739
      recpos = streamptr->tsteps[tsid].records[recID].position;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
740
      fileSetPos(fileID, recpos, SEEK_SET);
741
      extRead(fileID, extp);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
742
743
744
745
746
747
      extInqHeader(extp, header);
      extInqDataDP(extp, &data[levID*gridsize]);
    }
  fileSetPos(fileID, currentfilepos, SEEK_SET);

  *nmiss = 0;
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
  if ( vlistInqVarNumber(vlistID, varID) == CDI_REAL )
    {
      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)++;
	  }
    }
  else
    {
      for ( i = 0; i < 2*nlevs*gridsize; i+=2 )
	if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
	  {
	    data[i] = missval;
	    (*nmiss)++;
	  }
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
766
767
768
}


769
void extReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data, int *nmiss)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
770
771
772
773
774
775
776
777
778
{
  int vlistID, fileID;
  int nlevs, gridID, gridsize;
  off_t recpos, currentfilepos;
  int header[4];
  int tsid;
  int recID;
  int i;
  double missval;
779
  void *extp = streamptr->record->exsep;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
780

781
782
  vlistID  = streamptr->vlistID;
  fileID   = streamptr->fileID;
783
784
  /* NOTE: tiles are not supported here! */
  nlevs    = streamptr->vars[varID].recordTable[0].nlevs;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
785
786
787
  missval  = vlistInqVarMissval(vlistID, varID);
  gridID   = vlistInqVarGrid(vlistID, varID);
  gridsize = gridInqSize(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
788
  tsid     = streamptr->curTsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
789
790

  if ( CDI_Debug )
791
    Message("nlevs = %d gridID = %d gridsize = %d",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
792
793
794
795
	     nlevs, gridID, gridsize);

  currentfilepos = fileGetPos(fileID);

796
797
  /* NOTE: tiles are not supported here! */
  recID = streamptr->vars[varID].recordTable[0].recordID[levID];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
798
  recpos = streamptr->tsteps[tsid].records[recID].position;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
799
  fileSetPos(fileID, recpos, SEEK_SET);
800
  extRead(fileID, extp);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
801
802
  extInqHeader(extp, header);
  extInqDataDP(extp, data);
Thomas Jahns's avatar
Thomas Jahns committed
803

Uwe Schulzweida's avatar
Uwe Schulzweida committed
804
805
806
  fileSetPos(fileID, currentfilepos, SEEK_SET);

  *nmiss = 0;
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
  if ( vlistInqVarNumber(vlistID, varID) == CDI_REAL )
    {
      for ( i = 0; i < gridsize; i++ )
	if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
	  {
	    data[i] = missval;
	    (*nmiss)++;
	  }
    }
  else
    {
      for ( i = 0; i < 2*gridsize; i+=2 )
	if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
	  {
	    data[i] = missval;
	    (*nmiss)++;
	  }
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
825
826
827
}


828
void extWriteVarDP(stream_t *streamptr, int varID, const double *data)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
829
830
831
832
833
834
835
836
{
  int fileID;
  int levID, nlevs, gridID, gridsize;
  int zaxisID;
  double level;
  int header[4];
  int tsID;
  int vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
837
  int pdis, pcat, pnum;
838
  extrec_t *extp = (extrec_t*) streamptr->record->exsep;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
839

840
  if ( CDI_Debug ) Message("streamID = %d  varID = %d", streamptr->self, varID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
841

842
843
  vlistID  = streamptr->vlistID;
  fileID   = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
844
  tsID     = streamptr->curTsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
845
846
847
848
849
850
  gridID   = vlistInqVarGrid(vlistID, varID);
  gridsize = gridInqSize(gridID);
  zaxisID  = vlistInqVarZaxis(vlistID, varID);
  nlevs    = zaxisInqSize(zaxisID);

  if ( CDI_Debug )
851
    Message("nlevs = %d gridID = %d gridsize = %d", nlevs, gridID, gridsize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
852

Uwe Schulzweida's avatar
Uwe Schulzweida committed
853
  cdiDecodeParam(vlistInqVarParam(vlistID, varID), &pnum, &pcat, &pdis);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
854

Uwe Schulzweida's avatar
Uwe Schulzweida committed
855
  header[0] = streamptr->tsteps[tsID].taxis.vdate;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
856
  header[1] = pnum;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
857
858
  header[3] = gridInqSize(gridID);

859
  extDefDatatype(vlistInqVarDatatype(vlistID, varID), &extp->prec, &extp->number);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
860
861
862
863
864
865
866
867
868
869
870
871
872

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

      header[2] = (int) level;
      extDefHeader(extp, header);
      extDefDataDP(extp, &data[levID*gridsize]);
      extWrite(fileID, extp);
    }
}


873
void extWriteVarSliceDP(stream_t *streamptr, int varID, int levID, const double *data)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
874
875
876
877
878
879
880
881
{
  int fileID;
  int gridID;
  int zaxisID;
  double level;
  int header[4];
  int tsID;
  int vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
882
  int pdis, pcat, pnum;
883
  extrec_t *extp = (extrec_t*) streamptr->record->exsep;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
884

885
886
  vlistID  = streamptr->vlistID;
  fileID   = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
887
  tsID     = streamptr->curTsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
888
889
890
891
892
  gridID   = vlistInqVarGrid(vlistID, varID);
  zaxisID  = vlistInqVarZaxis(vlistID, varID);
  level    = zaxisInqLevel(zaxisID, levID);

  if ( CDI_Debug )
893
    Message("gridID = %d zaxisID = %d", gridID, zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
894

Uwe Schulzweida's avatar
Uwe Schulzweida committed
895
  cdiDecodeParam(vlistInqVarParam(vlistID, varID), &pnum, &pcat, &pdis);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
896

Uwe Schulzweida's avatar
Uwe Schulzweida committed
897
  header[0] = streamptr->tsteps[tsID].taxis.vdate;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
898
  header[1] = pnum;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
899
900
901
  header[2] = (int) level;
  header[3] = gridInqSize(gridID);

902
  extDefDatatype(vlistInqVarDatatype(vlistID, varID), &extp->prec, &extp->number);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
903
904
905
906
907
908
909

  extDefHeader(extp, header);
  extDefDataDP(extp, data);
  extWrite(fileID, extp);
}

#endif /* HAVE_LIBEXTRA */
910
911
912
913
914
915
916
917
918
/*
 * Local Variables:
 * c-file-style: "Java"
 * c-basic-offset: 2
 * indent-tabs-mode: nil
 * show-trailing-whitespace: t
 * require-trailing-newline: t
 * End:
 */