stream_srv.c 22.9 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
#include <stdio.h>
7
#include <stdlib.h>
Uwe Schulzweida's avatar
Uwe Schulzweida committed
8
9
10
11
12
13
14
#include <string.h>

#include "dmemory.h"

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


#undef  UNDEFID
#define UNDEFID  CDI_UNDEFID

#define SINGLE_PRECISION  4
#define DOUBLE_PRECISION  8

#if defined (HAVE_LIBSERVICE)

32
33

typedef struct {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
34
  int param;
35
  int level;
36
} SRVCOMPVAR;
37
38


Uwe Schulzweida's avatar
Uwe Schulzweida committed
39
40
41
42
int srvInqDatatype(int prec)
{
  int datatype;

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

  return (datatype);
}


int srvDefDatatype(int datatype)
{
  int prec;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
54
  if ( datatype == DATATYPE_CPX32 || datatype == DATATYPE_CPX64 )
55
    Error("CDI/SERVICE library does not support complex numbers!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
56

57
58
  if ( datatype != DATATYPE_FLT32 && datatype != DATATYPE_FLT64 )
    datatype = DATATYPE_FLT32;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
59

60
  if ( datatype == DATATYPE_FLT64 ) prec = DOUBLE_PRECISION;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
61
62
63
64
65
  else                              prec = SINGLE_PRECISION;

  return (prec);
}

66
/* not used
67
int srvInqRecord(stream_t *streamptr, int *varID, int *levelID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
68
69
70
{
  int status;
  int fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
71
  int icode, ilevel;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
72
73
74
  int zaxisID = -1;
  int header[8];
  int vlistID;
75
  srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
76

77
78
  vlistID = streamptr->vlistID;
  fileID  = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
79
80
81
82
83
84
85
86
87

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

  status = srvRead(fileID, srvp);
  if ( status != 0 ) return (0);

  srvInqHeader(srvp, header);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
88
  icode  = header[0];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
89
90
  ilevel = header[1];

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

93
  if ( *varID == UNDEFID ) Error("Code %d undefined", icode);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
94
95
96
97

  zaxisID = vlistInqVarZaxis(vlistID, *varID);

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
99
100
  return (1);
}
101
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
102

103
void srvReadRecord(stream_t *streamptr, double *data, int *nmiss)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
104
105
106
107
108
109
110
111
112
{
  int vlistID, fileID;
  int status;
  int recID, vrecID, tsID;
  off_t recpos;
  int header[8];
  int varID, gridID;
  int i, size;
  double missval;
113
  srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
114

115
116
  vlistID = streamptr->vlistID;
  fileID  = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
117
118
119
120
121
  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
122
123
124
125

  fileSetPos(fileID, recpos, SEEK_SET);

  status = srvRead(fileID, srvp);
126
127
  if ( status != 0 )
    Error("Failed to read record from SRV file");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
128
129
130
131

  srvInqHeader(srvp, header);
  srvInqDataDP(srvp, data);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
132
  missval = vlistInqVarMissval(vlistID, varID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
133
134
  gridID  = vlistInqVarGrid(vlistID, varID);
  size    = gridInqSize(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
135

Uwe Schulzweida's avatar
Uwe Schulzweida committed
136
  streamptr->numvals += size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
137
138
139
140
141
142
143
144
145
146
147

  *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)++;
      }
}


148
void srvCopyRecord(stream_t *streamptr2, stream_t *streamptr1)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
149
{
150
  streamFCopyRecord(streamptr2, streamptr1, "SRV");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
151
152
153
}


154
void srvDefRecord(stream_t *streamptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
155
156
157
158
159
{
  int gridID;
  int header[8];
  int xsize, ysize;
  int datatype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
160
  int pdis, pcat, pnum;
161
  srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
162

Uwe Schulzweida's avatar
Uwe Schulzweida committed
163
  gridID = streamptr->record->gridID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
164

Uwe Schulzweida's avatar
Uwe Schulzweida committed
165
  cdiDecodeParam(streamptr->record->param, &pnum, &pcat, &pdis);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
166
  header[0] = pnum;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
167
168
169
  header[1] = streamptr->record->level;
  header[2] = streamptr->record->date;
  header[3] = streamptr->record->time;
170

Uwe Schulzweida's avatar
Uwe Schulzweida committed
171
172
173
174
175
176
177
  xsize = gridInqXsize(gridID);
  ysize = gridInqYsize(gridID);
  if ( xsize == 0 || ysize == 0 )
    {
      xsize = gridInqSize(gridID);
      ysize = 1;
    }
178
  if ( gridInqType(gridID) == GRID_UNSTRUCTURED ) ysize = 1;
179
  if ( gridInqSize(gridID) != xsize*ysize )
180
    Error("Internal problem with gridsize!");
181

Uwe Schulzweida's avatar
Uwe Schulzweida committed
182
183
184
185
186
  header[4] = xsize;
  header[5] = ysize;
  header[6] = 0;
  header[7] = 0;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
187
  datatype = streamptr->record->prec;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
188
189
190
191
192
193
194

  srvp->dprec = srvDefDatatype(datatype);

  srvDefHeader(srvp, header);
}


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

  srvDefDataDP(srvp, data);

  srvWrite(fileID, srvp);
}

205
206
static
void srv_add_record(stream_t *streamptr, int param, int level, int xsize, int ysize,
207
                    size_t recsize, off_t position, int prec)
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
  grid_t grid;
220
  memset(&grid, 0, sizeof(grid_t));
221
  grid.type  = GRID_GENERIC;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
222
223
224
225
226
  grid.size  = xsize*ysize;
  grid.xsize = xsize;
  grid.ysize = ysize;
  grid.xvals = NULL;
  grid.yvals = NULL;
227
  int gridID = varDefGrid(vlistID, &grid, 0);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
228
229
230
231
  /*
  if ( level == 0 ) leveltype = ZAXIS_SURFACE;
  else              leveltype = ZAXIS_GENERIC;
  */
232
  int leveltype = ZAXIS_GENERIC;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
233

234
  int datatype = srvInqDatatype(prec);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
235

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

242
  xassert(varID <= SHRT_MAX && levelID <= SHRT_MAX);
243
244
  record->varID   = (short)varID;
  record->levelID = (short)levelID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
245

Uwe Schulzweida's avatar
Uwe Schulzweida committed
246
247
  streamptr->tsteps[tsID].nallrecs++;
  streamptr->nrecs++;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
248
249

  if ( CDI_Debug )
250
    Message("varID = %d gridID = %d levelID = %d",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
251
252
253
	    varID, gridID, levelID);
}

254
static
255
256
void srvScanTimestep1(stream_t *streamptr)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
257
258
259
260
261
  int header[8];
  int prec = 0;
  int status;
  int fileID;
  int rxsize = 0, rysize = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
262
263
  int param = 0;
  int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
264
265
266
267
268
269
  DateTime datetime, datetime0;
  int tsID;
  int varID;
  off_t recpos;
  int nrecords, nrecs, recID;
  int taxisID = -1;
270
  taxis_t *taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
271
  int vlistID;
272
  SRVCOMPVAR compVar, compVar0;
273
  srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
274

Uwe Schulzweida's avatar
Uwe Schulzweida committed
275
  streamptr->curTsID = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
276

277
  tsID  = tstepsNewEntry(streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
278
  taxis = &streamptr->tsteps[tsID].taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
279
280

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

283
  fileID = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
284
285
286
287
288
289
290
291

  nrecs = 0;
  while ( TRUE )
    {
      recpos = fileGetPos(fileID);
      status = srvRead(fileID, srvp);
      if ( status != 0 )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
292
	  streamptr->ntsteps = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
293
294
	  break;
	}
295
      size_t recsize = (size_t)(fileGetPos(fileID) - recpos);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
296
297
298
299

      srvInqHeader(srvp, header);

      prec   = srvp->dprec;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
300
      rcode  = header[0];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
301
302
303
304
305
306
      rlevel = header[1];
      vdate  = header[2];
      vtime  = header[3];
      rxsize = header[4];
      rysize = header[5];

Uwe Schulzweida's avatar
Uwe Schulzweida committed
307
      param = cdiEncodeParam(rcode, 255, 255);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
308

Uwe Schulzweida's avatar
Uwe Schulzweida committed
309
310
311
312
313
314
315
316
317
      if ( nrecs == 0 )
	{
	  datetime0.date = vdate;
	  datetime0.time = vtime;
	}
      else
	{
	  datetime.date = vdate;
	  datetime.time = vtime;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
318
	  compVar.param = param;
319
          compVar.level = rlevel;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
320
321
	  for ( recID = 0; recID < nrecs; recID++ )
	    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
322
	      compVar0.param = streamptr->tsteps[0].records[recID].param;
323
324
325
	      compVar0.level = streamptr->tsteps[0].records[recID].ilevel;

	      if ( memcmp(&compVar0, &compVar, sizeof(SRVCOMPVAR)) == 0 ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
326
327
328
	    }
	  if ( recID < nrecs ) break;
	  if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) )
329
	    Warning("Inconsistent verification time for code %d level %d", rcode, rlevel);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
330
331
332
333
334
	}

      nrecs++;

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

337
      srv_add_record(streamptr, param, rlevel, rxsize, rysize, recsize, recpos, prec);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
338
339
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
340
  streamptr->rtsteps = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
341

342
  cdi_generate_vars(streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
343

344
  taxisID = taxisCreate(TAXIS_ABSOLUTE);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
345
  taxis->type  = TAXIS_ABSOLUTE;
346
347
  taxis->vdate = (int)datetime0.date;
  taxis->vtime = (int)datetime0.time;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
348

349
  vlistID = streamptr->vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
350
351
  vlistDefTaxis(vlistID, taxisID);

352
  vlist_check_contents(vlistID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
353

Uwe Schulzweida's avatar
Uwe Schulzweida committed
354
355
  nrecords = streamptr->tsteps[0].nallrecs;
  if ( nrecords < streamptr->tsteps[0].recordSize )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
356
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
357
358
      streamptr->tsteps[0].recordSize = nrecords;
      streamptr->tsteps[0].records =
359
360
	(record_t *)xrealloc(streamptr->tsteps[0].records,
                             (size_t)nrecords * sizeof(record_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
361
362
    }

363
  streamptr->tsteps[0].recIDs = (int *)xmalloc((size_t)nrecords * sizeof (int));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
364
  streamptr->tsteps[0].nrecs = nrecords;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
365
  for ( recID = 0; recID < nrecords; recID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
366
    streamptr->tsteps[0].recIDs[recID] = recID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
367

Uwe Schulzweida's avatar
Uwe Schulzweida committed
368
  if ( streamptr->ntsteps == -1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
369
    {
370
      tsID = tstepsNewEntry(streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
371
      if ( tsID != streamptr->rtsteps )
372
	Error("Internal error. tsID = %d", tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
373

Uwe Schulzweida's avatar
Uwe Schulzweida committed
374
375
      streamptr->tsteps[tsID-1].next   = TRUE;
      streamptr->tsteps[tsID].position = recpos;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
376
377
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
378
  if ( streamptr->ntsteps == 1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
379
380
381
    {
      if ( taxis->vdate == 0 && taxis->vtime == 0 )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
382
383
	  streamptr->ntsteps = 0;
	  for ( varID = 0; varID < streamptr->nvars; varID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
384
	    {
385
	      vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
386
387
388
389
390
	    }
	}
    }
}

391
static
392
393
int srvScanTimestep2(stream_t *streamptr)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
394
395
396
  int header[8];
  int status;
  int fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
397
398
  int param = 0;
  int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
399
400
401
402
403
  int tsID;
  int varID;
  off_t recpos = 0;
  int nrecords, nrecs, recID, rindex;
  int nextstep;
404
  taxis_t *taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
405
  int vlistID;
406
  SRVCOMPVAR compVar, compVar0;
407
  srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
408
409

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

411
412
  vlistID = streamptr->vlistID;
  fileID  = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
413

Uwe Schulzweida's avatar
Uwe Schulzweida committed
414
  tsID = streamptr->rtsteps;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
415
  if ( tsID != 1 )
416
    Error("Internal problem! unexpected timestep %d", tsID+1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
417

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

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

422
  cdi_create_records(streamptr, tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
423

Uwe Schulzweida's avatar
Uwe Schulzweida committed
424
  nrecords = streamptr->tsteps[0].nallrecs;
425
  streamptr->tsteps[1].recIDs = (int *)xmalloc((size_t)nrecords * sizeof (int));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
426
  streamptr->tsteps[1].nrecs = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
427
  for ( recID = 0; recID < nrecords; recID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
428
    streamptr->tsteps[1].recIDs[recID] = -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
429
430
431

  for ( recID = 0; recID < nrecords; recID++ )
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
432
      varID = streamptr->tsteps[0].records[recID].varID;
433
      streamptr->tsteps[tsID].records[recID].position =
Uwe Schulzweida's avatar
Uwe Schulzweida committed
434
	streamptr->tsteps[0].records[recID].position;
435
      streamptr->tsteps[tsID].records[recID].size     =
Uwe Schulzweida's avatar
Uwe Schulzweida committed
436
	streamptr->tsteps[0].records[recID].size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
437
438
439
440
441
442
443
444
    }

  for ( rindex = 0; rindex <= nrecords; rindex++ )
    {
      recpos = fileGetPos(fileID);
      status = srvRead(fileID, srvp);
      if ( status != 0 )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
445
	  streamptr->ntsteps = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
446
447
	  break;
	}
448
      size_t recsize = (size_t)(fileGetPos(fileID) - recpos);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
449
450
451

      srvInqHeader(srvp, header);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
452
      rcode  = header[0];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
453
454
455
456
      rlevel = header[1];
      vdate  = header[2];
      vtime  = header[3];

Uwe Schulzweida's avatar
Uwe Schulzweida committed
457
      param = cdiEncodeParam(rcode, 255, 255);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
458

Uwe Schulzweida's avatar
Uwe Schulzweida committed
459
460
461
462
463
464
465
      if ( rindex == 0 )
	{
	  taxis->type  = TAXIS_ABSOLUTE;
	  taxis->vdate = vdate;
	  taxis->vtime = vtime;
	}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
466
      compVar.param = param;
467
      compVar.level = rlevel;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
468
469
470
      nextstep = FALSE;
      for ( recID = 0; recID < nrecords; recID++ )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
471
	  compVar0.param  = streamptr->tsteps[tsID].records[recID].param;
472
473
474
	  compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;

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

      if ( nextstep ) break;

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
501
      compVar0.param  = streamptr->tsteps[tsID].records[recID].param;
502
      compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
503

504
      if ( memcmp(&compVar0, &compVar, sizeof(SRVCOMPVAR)) != 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
505
	{
506
	  Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
507
		  tsID, recID,
Uwe Schulzweida's avatar
Uwe Schulzweida committed
508
		  streamptr->tsteps[tsID].records[recID].param, param,
Uwe Schulzweida's avatar
Uwe Schulzweida committed
509
		  streamptr->tsteps[tsID].records[recID].ilevel, rlevel);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
510
511
512
	  return (CDI_EUFSTRUCT);
	}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
513
      streamptr->tsteps[1].records[recID].position = recpos;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
514
515
516
517
518
    }

  nrecs = 0;
  for ( recID = 0; recID < nrecords; recID++ )
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
519
      if ( ! streamptr->tsteps[tsID].records[recID].used )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
520
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
521
	  varID = streamptr->tsteps[tsID].records[recID].varID;
522
          vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
523
524
525
526
527
528
	}
      else
	{
	  nrecs++;
	}
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
529
  streamptr->tsteps[tsID].nrecs = nrecs;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
530

Uwe Schulzweida's avatar
Uwe Schulzweida committed
531
  streamptr->rtsteps = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
532

Uwe Schulzweida's avatar
Uwe Schulzweida committed
533
  if ( streamptr->ntsteps == -1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
534
    {
535
      tsID = tstepsNewEntry(streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
536
      if ( tsID != streamptr->rtsteps )
537
	Error("Internal error. tsID = %d", tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
538

Uwe Schulzweida's avatar
Uwe Schulzweida committed
539
540
      streamptr->tsteps[tsID-1].next   = TRUE;
      streamptr->tsteps[tsID].position = recpos;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
541
542
543
544
545
546
    }

  return (0);
}


547
int srvInqContents(stream_t *streamptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
548
549
550
{
  int fileID;
  int status = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
551

552
  fileID = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
553

Uwe Schulzweida's avatar
Uwe Schulzweida committed
554
  streamptr->curTsID = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
555

556
557
558
  srvScanTimestep1(streamptr);

  if ( streamptr->ntsteps == -1 ) status = srvScanTimestep2(streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
559
560
561
562
563
564

  fileSetPos(fileID, 0, SEEK_SET);

  return (status);
}

565
static
566
long srvScanTimestep(stream_t *streamptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
567
568
569
570
{
  int header[8];
  int status;
  int fileID;
Thomas Jahns's avatar
Thomas Jahns committed
571
  /* int rxsize = 0, rysize = 0; */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
572
573
  int param = 0;
  int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
574
575
576
  off_t recpos = 0;
  int recID;
  int rindex, nrecs = 0;
577
  SRVCOMPVAR compVar, compVar0;
578
  srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
579
  /*
Uwe Schulzweida's avatar
Uwe Schulzweida committed
580
581
  if ( CDI_Debug )
    {
582
      Message("streamID = %d", streamptr->self);
583
584
585
      Message("cts = %d", streamptr->curTsID);
      Message("rts = %d", streamptr->rtsteps);
      Message("nts = %d", streamptr->ntsteps);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
586
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
587
  */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
588

Uwe Schulzweida's avatar
Uwe Schulzweida committed
589
590
  int tsID  = streamptr->rtsteps;
  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
591

Uwe Schulzweida's avatar
Uwe Schulzweida committed
592
  if ( streamptr->tsteps[tsID].recordSize == 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
593
    {
594
      cdi_create_records(streamptr, tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
595

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
598
      streamptr->tsteps[tsID].nrecs = nrecs;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
599
      streamptr->tsteps[tsID].recIDs = (int *)xmalloc((size_t)nrecs * sizeof (int));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
600
      for ( recID = 0; recID < nrecs; recID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
601
	streamptr->tsteps[tsID].recIDs[recID] = streamptr->tsteps[1].recIDs[recID];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
602

603
      fileID = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
604

Uwe Schulzweida's avatar
Uwe Schulzweida committed
605
      fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
606
607
608
609
610
611
612

      for ( rindex = 0; rindex <= nrecs; rindex++ )
	{
	  recpos = fileGetPos(fileID);
	  status = srvRead(fileID, srvp);
	  if ( status != 0 )
	    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
613
	      streamptr->ntsteps = streamptr->rtsteps + 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
614
615
	      break;
	    }
616
	  size_t recsize = (size_t)(fileGetPos(fileID) - recpos);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
617
618
619

	  srvInqHeader(srvp, header);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
620
	  rcode  = header[0];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
621
622
623
	  rlevel = header[1];
	  vdate  = header[2];
	  vtime  = header[3];
624
625
          /* rxsize = header[4]; */
          /* rysize = header[5]; */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
626

Uwe Schulzweida's avatar
Uwe Schulzweida committed
627
	  param = cdiEncodeParam(rcode, 255, 255);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
628

629
630
	  // if ( rindex == nrecs ) break; gcc-4.5 internal compiler error
	  if ( rindex == nrecs ) continue;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
631
	  recID = streamptr->tsteps[tsID].recIDs[rindex];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
632
633
634
635
636
637
638

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
640
641
642
	  compVar.param  = param;
          compVar.level  = rlevel;
	  compVar0.param = streamptr->tsteps[tsID].records[recID].param;
643
	  compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
644

645
	  if ( memcmp(&compVar0, &compVar, sizeof(SRVCOMPVAR)) != 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
646
	    {
647
	      Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
648
		      tsID, recID,
Uwe Schulzweida's avatar
Uwe Schulzweida committed
649
		      streamptr->tsteps[tsID].records[recID].param, param,
Uwe Schulzweida's avatar
Uwe Schulzweida committed
650
		      streamptr->tsteps[tsID].records[recID].ilevel, rlevel);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
651
	      Error("Invalid, unsupported or inconsistent record structure!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
652
653
	    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
654
655
	  streamptr->tsteps[tsID].records[recID].position = recpos;
	  streamptr->tsteps[tsID].records[recID].size = recsize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
656
657

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
661
      streamptr->rtsteps++;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
662

Uwe Schulzweida's avatar
Uwe Schulzweida committed
663
      if ( streamptr->ntsteps != streamptr->rtsteps )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
664
	{
665
	  tsID = tstepsNewEntry(streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
666
	  if ( tsID != streamptr->rtsteps )
667
	    Error("Internal error. tsID = %d", tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
668

Uwe Schulzweida's avatar
Uwe Schulzweida committed
669
670
	  streamptr->tsteps[tsID-1].next   = 1;
	  streamptr->tsteps[tsID].position = recpos;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
671
672
	}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
673
674
      fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
      streamptr->tsteps[tsID].position = recpos;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
675
676
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
677
  if ( nrecs > 0 && nrecs < streamptr->tsteps[tsID].nrecs )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
678
    {
679
      Warning("Incomplete timestep. Stop scanning at timestep %d.", tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
680
      streamptr->ntsteps = tsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
681
682
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
683
  return (streamptr->ntsteps);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
684
685
686
}


687
int srvInqTimestep(stream_t *streamptr, int tsID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
688
{
689
690
  long ntsteps;
  int nrecs;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
691

Uwe Schulzweida's avatar
Uwe Schulzweida committed
692
  if ( tsID == 0 && streamptr->rtsteps == 0 )
693
    Error("Call to cdiInqContents missing!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
694
695

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
698
  ntsteps = UNDEFID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
699
  while ( ( tsID + 1 ) > streamptr->rtsteps && ntsteps == UNDEFID )
700
    ntsteps = srvScanTimestep(streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
701

702
  if ( tsID >= streamptr->ntsteps && streamptr->ntsteps != UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
703
704
705
706
707
    {
      nrecs = 0;
    }
  else
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
708
709
      streamptr->curTsID = tsID;
      nrecs = streamptr->tsteps[tsID].nrecs;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
710
711
712
713
714
715
    }

  return (nrecs);
}


716
void srvReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
717
718
719
720
721
722
723
724
725
{
  int vlistID, fileID;
  int levID, nlevs, gridID, gridsize;
  off_t recpos, currentfilepos;
  int header[8];
  int tsid;
  int recID;
  int i;
  double missval;
726
  srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
727

728
729
  vlistID  = streamptr->vlistID;
  fileID   = streamptr->fileID;
730
731
  /* NOTE: tiles are not supported here! */
  nlevs    = streamptr->vars[varID].recordTable[0].nlevs;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
732
733
734
  missval  = vlistInqVarMissval(vlistID, varID);
  gridID   = vlistInqVarGrid(vlistID, varID);
  gridsize = gridInqSize(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
735
  tsid     = streamptr->curTsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
736
737

  if ( CDI_Debug )
738
    Message("nlevs = %d gridID = %d gridsize = %d", nlevs, gridID, gridsize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
739
740
741
742
743

  currentfilepos = fileGetPos(fileID);

  for (levID = 0; levID < nlevs; levID++)
    {
744
745
      /* NOTE: tiles are not supported here! */
      recID = streamptr->vars[varID].recordTable[0].recordID[levID];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
746
      recpos = streamptr->tsteps[tsid].records[recID].position;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
747
      fileSetPos(fileID, recpos, SEEK_SET);
Thomas Jahns's avatar
Thomas Jahns committed
748
749
      if (srvRead(fileID, srvp) < 0)
        abort();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
      srvInqHeader(srvp, header);
      srvInqDataDP(srvp, &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)++;
      }
}


765
void srvReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data, int *nmiss)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
766
767
768
769
770
771
772
773
774
{
  int vlistID, fileID;
  int nlevs, gridID, gridsize;
  off_t recpos, currentfilepos;
  int header[8];
  int tsid;
  int recID;
  int i;
  double missval;
775
  srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
776

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

  if ( CDI_Debug )
787
    Message("nlevs = %d gridID = %d gridsize = %d",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
788
789
790
791
	     nlevs, gridID, gridsize);

  currentfilepos = fileGetPos(fileID);

792
793
  /* NOTE: tiles are not supported here! */
  recID = streamptr->vars[varID].recordTable[0].recordID[levID];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
794
  recpos = streamptr->tsteps[tsid].records[recID].position;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
795
  fileSetPos(fileID, recpos, SEEK_SET);
Thomas Jahns's avatar
Thomas Jahns committed
796
797
  if (srvRead(fileID, srvp) < 0)
    abort();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
  srvInqHeader(srvp, header);
  srvInqDataDP(srvp, 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)++;
      }
}


813
void srvWriteVarDP(stream_t *streamptr, int varID, const double *data)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
814
815
816
817
818
819
{
  int fileID;
  int levID, nlevs, gridID, gridsize;
  int zaxisID;
  double level;
  int header[8];
820
  int xsize, ysize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
821
822
823
  int datatype;
  int tsID;
  int vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
824
  int pdis, pcat, pnum;
825
  srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
826
827

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

830
831
  vlistID  = streamptr->vlistID;
  fileID   = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
832
  tsID     = streamptr->curTsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
833
834
835
836
837
838
  gridID   = vlistInqVarGrid(vlistID, varID);
  gridsize = gridInqSize(gridID);
  zaxisID  = vlistInqVarZaxis(vlistID, varID);
  nlevs    = zaxisInqSize(zaxisID);

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
841
  cdiDecodeParam(vlistInqVarParam(vlistID, varID), &pnum, &pcat, &pdis);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
842
843

  header[0] = pnum;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
844
845
  header[2] = streamptr->tsteps[tsID].taxis.vdate;
  header[3] = streamptr->tsteps[tsID].taxis.vtime;
846
847
848
849

  xsize = gridInqXsize(gridID);
  ysize = gridInqYsize(gridID);
  if ( xsize == 0 || ysize == 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
850
    {
851
852
      xsize = gridInqSize(gridID);
      ysize = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
853
    }
854
  if ( gridInqType(gridID) == GRID_UNSTRUCTURED ) ysize = 1;
855
  if ( gridInqSize(gridID) != xsize*ysize )
856
    Error("Internal problem with gridsize!");
857
858
859

  header[4] = xsize;
  header[5] = ysize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
860
861
862
863
864
865
866
  header[6] = 0;
  header[7] = 0;

  datatype = vlistInqVarDatatype(vlistID, varID);

  srvp->dprec = srvDefDatatype(datatype);

867
  for ( levID = 0; levID < nlevs; levID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
868
869
870
871
872
873
874
875
876
877
878
    {
      level = zaxisInqLevel(zaxisID, levID);

      header[1] = (int) level;
      srvDefHeader(srvp, header);
      srvDefDataDP(srvp, &data[levID*gridsize]);
      srvWrite(fileID, srvp);
    }
}


879
void srvWriteVarSliceDP(stream_t *streamptr, int varID, int levID, const double *data)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
880
881
882
883
884
885
{
  int fileID;
  int gridID;
  int zaxisID;
  double level;
  int header[8];
886
  int xsize, ysize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
887
888
889
  int datatype;
  int tsID;
  int vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
890
  int pdis, pcat, pnum;
891
  srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
892

893
894
  vlistID  = streamptr->vlistID;
  fileID   = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
895
  tsID     = streamptr->curTsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
896
897
898
899
900
  gridID   = vlistInqVarGrid(vlistID, varID);
  zaxisID  = vlistInqVarZaxis(vlistID, varID);
  level    = zaxisInqLevel(zaxisID, levID);

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
903
  cdiDecodeParam(vlistInqVarParam(vlistID, varID), &pnum, &pcat, &pdis);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
904
905

  header[0] = pnum;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
906
  header[1] = (int) level;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
907
908
  header[2] = streamptr->tsteps[tsID].taxis.vdate;
  header[3] = streamptr->tsteps[tsID].taxis.vtime;
909
910
911
912

  xsize = gridInqXsize(gridID);
  ysize = gridInqYsize(gridID);
  if ( xsize == 0 || ysize == 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
913
    {
914
915
      xsize = gridInqSize(gridID);
      ysize = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
916
    }
917
  if ( gridInqType(gridID) == GRID_UNSTRUCTURED ) ysize = 1;
918
  if ( gridInqSize(gridID) != xsize*ysize )
919
    Error("Internal problem with gridsize!");
920
921
922

  header[4] = xsize;
  header[5] = ysize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
923
924
925
926
927
928
929
930
931
932
933
934
935
  header[6] = 0;
  header[7] = 0;

  datatype = vlistInqVarDatatype(vlistID, varID);

  srvp->dprec = srvDefDatatype(datatype);

  srvDefHeader(srvp, header);
  srvDefDataDP(srvp, data);
  srvWrite(fileID, srvp);
}

#endif /* HAVE_LIBSERVICE */
936
937
938
939
940
941
942
943
944
/*
 * Local Variables:
 * c-file-style: "Java"
 * c-basic-offset: 2
 * indent-tabs-mode: nil
 * show-trailing-whitespace: t
 * require-trailing-newline: t
 * End:
 */