stream_srv.c 23.8 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
#if defined (HAVE_CONFIG_H)
#  include "config.h"
#endif

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

#include "dmemory.h"

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


#undef  UNDEFID
#define UNDEFID  CDI_UNDEFID

#define SINGLE_PRECISION  4
#define DOUBLE_PRECISION  8

#if defined (HAVE_LIBSERVICE)

28
29

typedef struct {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
30
  int param;
31
  int level;
32
} SRVCOMPVAR;
33
34


Uwe Schulzweida's avatar
Uwe Schulzweida committed
35
36
37
38
int srvInqDatatype(int prec)
{
  int datatype;

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

  return (datatype);
}


int srvDefDatatype(int datatype)
{
  int prec;

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

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

56
  if ( datatype == DATATYPE_FLT64 ) prec = DOUBLE_PRECISION;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
57
58
59
60
61
  else                              prec = SINGLE_PRECISION;

  return (prec);
}

62
/* not used
63
int srvInqRecord(stream_t *streamptr, int *varID, int *levelID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
64
65
66
{
  int status;
  int fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
67
  int icode, ilevel;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
68
69
70
  int zaxisID = -1;
  int header[8];
  int vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
71
  srvrec_t *srvp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
72

73
74
  vlistID = streamptr->vlistID;
  fileID  = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
75
  srvp    = streamptr->record->srvp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
76
77
78
79
80
81
82
83
84

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

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

  srvInqHeader(srvp, header);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
85
  icode  = header[0];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
86
87
  ilevel = header[1];

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

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

  zaxisID = vlistInqVarZaxis(vlistID, *varID);

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
96
97
  return (1);
}
98
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
99

100
int srvReadRecord(stream_t *streamptr, double *data, int *nmiss)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
101
102
103
104
105
106
107
108
109
{
  int vlistID, fileID;
  int status;
  int recID, vrecID, tsID;
  off_t recpos;
  int header[8];
  int varID, gridID;
  int i, size;
  double missval;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
110
  srvrec_t *srvp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
111

112
113
  vlistID = streamptr->vlistID;
  fileID  = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
114
115
116
117
118
119
  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;
  srvp    = streamptr->record->srvp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
120
121
122
123
124
125
126
127
128

  fileSetPos(fileID, recpos, SEEK_SET);

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
129
  missval = vlistInqVarMissval(vlistID, varID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
130
131
  gridID  = vlistInqVarGrid(vlistID, varID);
  size    = gridInqSize(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
132

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

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


147
int srvCopyRecord(stream_t *streamptr2, stream_t *streamptr1)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
148
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
149
  int fileID1, fileID2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
150
151
152
153
154
155
  int tsID, recID, vrecID;
  long recsize;
  off_t recpos;
  int status = 0;
  char *buffer;

156
157
  fileID1 = streamptr1->fileID;
  fileID2 = streamptr2->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
158

Uwe Schulzweida's avatar
Uwe Schulzweida committed
159
160
161
162
163
164
165
  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
166
167
168

  buffer = (char *) malloc(recsize);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
169
  fileRead(fileID1, buffer, recsize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
170

Uwe Schulzweida's avatar
Uwe Schulzweida committed
171
  fileWrite(fileID2, buffer, recsize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
172
173
174
175
176
177
178

  free(buffer);

  return (status);
}


179
int srvDefRecord(stream_t *streamptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
180
181
182
183
184
185
{
  int gridID;
  int header[8];
  int status = 0;
  int xsize, ysize;
  int datatype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
186
  int pdis, pcat, pnum;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
187
  srvrec_t *srvp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
188

Uwe Schulzweida's avatar
Uwe Schulzweida committed
189
190
  gridID = streamptr->record->gridID;
  srvp   = streamptr->record->srvp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
191

Uwe Schulzweida's avatar
Uwe Schulzweida committed
192
  cdiDecodeParam(streamptr->record->param, &pnum, &pcat, &pdis);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
193
  header[0] = pnum;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
194
195
196
  header[1] = streamptr->record->level;
  header[2] = streamptr->record->date;
  header[3] = streamptr->record->time;
197

Uwe Schulzweida's avatar
Uwe Schulzweida committed
198
199
200
201
202
203
204
  xsize = gridInqXsize(gridID);
  ysize = gridInqYsize(gridID);
  if ( xsize == 0 || ysize == 0 )
    {
      xsize = gridInqSize(gridID);
      ysize = 1;
    }
205
  if ( gridInqType(gridID) == GRID_UNSTRUCTURED ) ysize = 1;
206
  if ( gridInqSize(gridID) != xsize*ysize )
207
    Error("Internal problem with gridsize!");
208

Uwe Schulzweida's avatar
Uwe Schulzweida committed
209
210
211
212
213
  header[4] = xsize;
  header[5] = ysize;
  header[6] = 0;
  header[7] = 0;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
214
  datatype = streamptr->record->prec;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
215
216
217
218
219
220
221
222
223

  srvp->dprec = srvDefDatatype(datatype);

  srvDefHeader(srvp, header);

  return (status);
}


224
int srvWriteRecord(stream_t *streamptr, const double *data)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
225
226
227
{
  int fileID;
  int status = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
228
  srvrec_t *srvp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
229

230
  fileID = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
231
  srvp   = streamptr->record->srvp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
232
233
234
235
236
237
238
239

  srvDefDataDP(srvp, data);

  srvWrite(fileID, srvp);

  return (status);
}

240
241
242
static
void srv_add_record(stream_t *streamptr, int param, int level, int xsize, int ysize,
                    long recsize, off_t position, int prec)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
243
244
245
246
247
248
{
  int leveltype;
  int gridID = UNDEFID;
  int levelID = 0;
  int tsID, recID, varID;
  int datatype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
249
  record_t *record;
250
  grid_t grid;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
251
252
  int vlistID;

253
  vlistID = streamptr->vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
254
  tsID    = streamptr->curTsID;
255
  recID   = recordNewEntry(streamptr, tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
256
  record  = &streamptr->tsteps[tsID].records[recID];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
257
258
259

  (*record).size     = recsize;
  (*record).position = position;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
260
  (*record).param    = param;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
261
262
  (*record).ilevel   = level;

263
  memset(&grid, 0, sizeof(grid_t));
264
  grid.type  = GRID_GENERIC;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
265
266
267
268
269
270
271
272
273
274
275
276
277
278
  grid.size  = xsize*ysize;
  grid.xsize = xsize;
  grid.ysize = ysize;
  grid.xvals = NULL;
  grid.yvals = NULL;
  gridID = varDefGrid(vlistID, grid, 0);
  /*
  if ( level == 0 ) leveltype = ZAXIS_SURFACE;
  else              leveltype = ZAXIS_GENERIC;
  */
  leveltype = ZAXIS_GENERIC;

  datatype = srvInqDatatype(prec);

279
  varAddRecord(recID, param, gridID, leveltype, 0, level, 0, 0,
280
	       datatype, &varID, &levelID, UNDEFID, 0, 0, NULL, NULL, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
281
282
283
284

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
285
286
  streamptr->tsteps[tsID].nallrecs++;
  streamptr->nrecs++;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
287
288

  if ( CDI_Debug )
289
    Message("varID = %d gridID = %d levelID = %d",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
290
291
292
293
	    varID, gridID, levelID);
}


294
void srvCmpRecord(stream_t *streamptr, int tsID, int recID, off_t position, int param,
Uwe Schulzweida's avatar
Uwe Schulzweida committed
295
296
297
298
		  int level, int xsize, int ysize)
{
  int varID = 0;
  int levelID = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
299
  record_t *record;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
300
301

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
303
  if ( param != (*record).param || level != (*record).ilevel )
304
    Error("inconsistent timestep");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
305
306
307
308
309
310

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
313
314
  streamptr->tsteps[tsID].nallrecs++;
  streamptr->nrecs++;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
315
316
  */
  if ( CDI_Debug )
317
    Message("varID = %d levelID = %d", varID, levelID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
318
319
}

320
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
321
void srvScanTimestep1(stream_t *streamptr)
322
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
323
324
325
326
327
  int header[8];
  int prec = 0;
  int status;
  int fileID;
  int rxsize = 0, rysize = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
328
329
  int param = 0;
  int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
330
331
332
333
334
335
336
  DateTime datetime, datetime0;
  int tsID;
  int varID;
  long recsize;
  off_t recpos;
  int nrecords, nrecs, recID;
  int taxisID = -1;
337
  taxis_t *taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
338
  int vlistID;
339
  SRVCOMPVAR compVar, compVar0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
340
  srvrec_t *srvp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
341

Uwe Schulzweida's avatar
Uwe Schulzweida committed
342
  streamptr->curTsID = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
343

Uwe Schulzweida's avatar
Uwe Schulzweida committed
344
  srvp  = streamptr->record->srvp;
345
  tsID  = tstepsNewEntry(streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
346
  taxis = &streamptr->tsteps[tsID].taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
347
348

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

351
  fileID = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
352
353
354
355
356
357
358
359

  nrecs = 0;
  while ( TRUE )
    {
      recpos = fileGetPos(fileID);
      status = srvRead(fileID, srvp);
      if ( status != 0 )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
360
	  streamptr->ntsteps = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
361
362
363
364
365
366
367
	  break;
	}
      recsize = fileGetPos(fileID) - recpos;

      srvInqHeader(srvp, header);

      prec   = srvp->dprec;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
368
      rcode  = header[0];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
369
370
371
372
373
374
      rlevel = header[1];
      vdate  = header[2];
      vtime  = header[3];
      rxsize = header[4];
      rysize = header[5];

Uwe Schulzweida's avatar
Uwe Schulzweida committed
375
      param = cdiEncodeParam(rcode, 255, 255);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
376

Uwe Schulzweida's avatar
Uwe Schulzweida committed
377
378
379
380
381
382
383
384
385
      if ( nrecs == 0 )
	{
	  datetime0.date = vdate;
	  datetime0.time = vtime;
	}
      else
	{
	  datetime.date = vdate;
	  datetime.time = vtime;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
386
	  compVar.param = param;
387
          compVar.level = rlevel;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
388
389
	  for ( recID = 0; recID < nrecs; recID++ )
	    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
390
	      compVar0.param = streamptr->tsteps[0].records[recID].param;
391
392
393
	      compVar0.level = streamptr->tsteps[0].records[recID].ilevel;

	      if ( memcmp(&compVar0, &compVar, sizeof(SRVCOMPVAR)) == 0 ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
394
395
396
	    }
	  if ( recID < nrecs ) break;
	  if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) )
397
	    Warning("Inconsistent verification time for code %d level %d", rcode, rlevel);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
398
399
400
401
402
	}

      nrecs++;

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

405
      srv_add_record(streamptr, param, rlevel, rxsize, rysize, recsize, recpos, prec);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
406
407
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
408
  streamptr->rtsteps = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
409

410
  cdi_generate_vars(streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
411

412
  taxisID = taxisCreate(TAXIS_ABSOLUTE);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
413
414
415
416
  taxis->type  = TAXIS_ABSOLUTE;
  taxis->vdate = datetime0.date;
  taxis->vtime = datetime0.time;

417
  vlistID = streamptr->vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
418
419
  vlistDefTaxis(vlistID, taxisID);

420
  vlist_check_contents(vlistID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
421

Uwe Schulzweida's avatar
Uwe Schulzweida committed
422
423
  nrecords = streamptr->tsteps[0].nallrecs;
  if ( nrecords < streamptr->tsteps[0].recordSize )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
424
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
425
426
      streamptr->tsteps[0].recordSize = nrecords;
      streamptr->tsteps[0].records =
Uwe Schulzweida's avatar
Uwe Schulzweida committed
427
	(record_t *) realloc(streamptr->tsteps[0].records, nrecords*sizeof(record_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
428
429
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
430
431
  streamptr->tsteps[0].recIDs = (int *) malloc(nrecords*sizeof(int));
  streamptr->tsteps[0].nrecs = nrecords;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
432
  for ( recID = 0; recID < nrecords; recID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
433
    streamptr->tsteps[0].recIDs[recID] = recID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
434

Uwe Schulzweida's avatar
Uwe Schulzweida committed
435
  if ( streamptr->ntsteps == -1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
436
    {
437
      tsID = tstepsNewEntry(streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
438
      if ( tsID != streamptr->rtsteps )
439
	Error("Internal error. tsID = %d", tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
440

Uwe Schulzweida's avatar
Uwe Schulzweida committed
441
442
      streamptr->tsteps[tsID-1].next   = TRUE;
      streamptr->tsteps[tsID].position = recpos;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
443
444
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
445
  if ( streamptr->ntsteps == 1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
446
447
448
    {
      if ( taxis->vdate == 0 && taxis->vtime == 0 )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
449
450
	  streamptr->ntsteps = 0;
	  for ( varID = 0; varID < streamptr->nvars; varID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
451
	    {
452
	      vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
453
454
455
456
457
	    }
	}
    }
}

458
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
459
int srvScanTimestep2(stream_t *streamptr)
460
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
461
462
463
  int header[8];
  int status;
  int fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
464
465
  int param = 0;
  int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
466
467
468
469
470
471
  int tsID;
  int varID;
  long recsize;
  off_t recpos = 0;
  int nrecords, nrecs, recID, rindex;
  int nextstep;
472
  taxis_t *taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
473
  int vlistID;
474
  SRVCOMPVAR compVar, compVar0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
475
  srvrec_t *srvp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
476
477

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

479
480
  vlistID = streamptr->vlistID;
  fileID  = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
481
  srvp    = streamptr->record->srvp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
482

Uwe Schulzweida's avatar
Uwe Schulzweida committed
483
  tsID = streamptr->rtsteps;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
484
  if ( tsID != 1 )
485
    Error("Internal problem! unexpeceted timestep %d", tsID+1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
486

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

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

491
  cdi_create_records(streamptr, tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
492

Uwe Schulzweida's avatar
Uwe Schulzweida committed
493
494
495
  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
496
  for ( recID = 0; recID < nrecords; recID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
497
    streamptr->tsteps[1].recIDs[recID] = -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
498
499
500

  for ( recID = 0; recID < nrecords; recID++ )
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
501
      varID = streamptr->tsteps[0].records[recID].varID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
502
      streamptr->tsteps[tsID].records[recID].position =
Uwe Schulzweida's avatar
Uwe Schulzweida committed
503
	streamptr->tsteps[0].records[recID].position;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
504
      streamptr->tsteps[tsID].records[recID].size     =
Uwe Schulzweida's avatar
Uwe Schulzweida committed
505
	streamptr->tsteps[0].records[recID].size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
506
507
508
509
510
511
512
513
    }

  for ( rindex = 0; rindex <= nrecords; rindex++ )
    {
      recpos = fileGetPos(fileID);
      status = srvRead(fileID, srvp);
      if ( status != 0 )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
514
	  streamptr->ntsteps = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
515
516
517
518
519
520
	  break;
	}
      recsize = fileGetPos(fileID) - recpos;

      srvInqHeader(srvp, header);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
521
      rcode  = header[0];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
522
523
524
525
      rlevel = header[1];
      vdate  = header[2];
      vtime  = header[3];

Uwe Schulzweida's avatar
Uwe Schulzweida committed
526
      param = cdiEncodeParam(rcode, 255, 255);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
527

Uwe Schulzweida's avatar
Uwe Schulzweida committed
528
529
530
531
532
533
534
      if ( rindex == 0 )
	{
	  taxis->type  = TAXIS_ABSOLUTE;
	  taxis->vdate = vdate;
	  taxis->vtime = vtime;
	}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
535
      compVar.param = param;
536
      compVar.level = rlevel;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
537
538
539
      nextstep = FALSE;
      for ( recID = 0; recID < nrecords; recID++ )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
540
	  compVar0.param  = streamptr->tsteps[tsID].records[recID].param;
541
542
543
	  compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;

	  if ( memcmp(&compVar0, &compVar, sizeof(SRVCOMPVAR)) == 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
544
	    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
545
	      if ( streamptr->tsteps[tsID].records[recID].used )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
546
547
548
549
550
		{
		  nextstep = TRUE;
		}
	      else
		{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
551
552
		  streamptr->tsteps[tsID].records[recID].used = TRUE;
		  streamptr->tsteps[tsID].recIDs[rindex] = recID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
553
554
555
556
557
558
		}
	      break;
	    }
	}
      if ( recID == nrecords )
	{
559
	  Warning("Code %d level %d not found at timestep %d", rcode, rlevel, tsID+1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
560
561
562
563
564
565
	  return (CDI_EUFSTRUCT);
	}

      if ( nextstep ) break;

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
570
      compVar0.param  = streamptr->tsteps[tsID].records[recID].param;
571
      compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
572

573
      if ( memcmp(&compVar0, &compVar, sizeof(SRVCOMPVAR)) != 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
574
	{
575
	  Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
576
		  tsID, recID,
Uwe Schulzweida's avatar
Uwe Schulzweida committed
577
		  streamptr->tsteps[tsID].records[recID].param, param,
Uwe Schulzweida's avatar
Uwe Schulzweida committed
578
		  streamptr->tsteps[tsID].records[recID].ilevel, rlevel);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
579
580
581
	  return (CDI_EUFSTRUCT);
	}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
582
      streamptr->tsteps[1].records[recID].position = recpos;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
583
584
585
586
587
    }

  nrecs = 0;
  for ( recID = 0; recID < nrecords; recID++ )
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
588
      if ( ! streamptr->tsteps[tsID].records[recID].used )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
589
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
590
	  varID = streamptr->tsteps[tsID].records[recID].varID;
591
          vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
592
593
594
595
596
597
	}
      else
	{
	  nrecs++;
	}
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
598
  streamptr->tsteps[tsID].nrecs = nrecs;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
599

Uwe Schulzweida's avatar
Uwe Schulzweida committed
600
  streamptr->rtsteps = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
601

Uwe Schulzweida's avatar
Uwe Schulzweida committed
602
  if ( streamptr->ntsteps == -1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
603
    {
604
      tsID = tstepsNewEntry(streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
605
      if ( tsID != streamptr->rtsteps )
606
	Error("Internal error. tsID = %d", tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
607

Uwe Schulzweida's avatar
Uwe Schulzweida committed
608
609
      streamptr->tsteps[tsID-1].next   = TRUE;
      streamptr->tsteps[tsID].position = recpos;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
610
611
612
613
614
615
    }

  return (0);
}


616
int srvInqContents(stream_t *streamptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
617
618
619
620
{
  int fileID;
  int status = 0;

621
  fileID = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
622

Uwe Schulzweida's avatar
Uwe Schulzweida committed
623
  streamptr->curTsID = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
624

Uwe Schulzweida's avatar
Uwe Schulzweida committed
625
  srvScanTimestep1(streamptr);
626

Uwe Schulzweida's avatar
Uwe Schulzweida committed
627
  if ( streamptr->ntsteps == -1 ) status = srvScanTimestep2(streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
628
629
630
631
632
633

  fileSetPos(fileID, 0, SEEK_SET);

  return (status);
}

634
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
635
int srvScanTimestep(stream_t *streamptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
636
637
638
639
640
{
  int header[8];
  int status;
  int fileID;
  int tsID;
641
  /* int rxsize = 0, rysize = 0; */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
642
643
  int param = 0;
  int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
644
645
646
  long recsize = 0;
  off_t recpos = 0;
  int recID;
647
  taxis_t *taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
648
  int rindex, nrecs = 0;
649
  SRVCOMPVAR compVar, compVar0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
650
  srvrec_t *srvp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
651
652
653

  if ( CDI_Debug )
    {
654
      Message("streamID = %d", streamptr->self);
655
656
657
      Message("cts = %d", streamptr->curTsID);
      Message("rts = %d", streamptr->rtsteps);
      Message("nts = %d", streamptr->ntsteps);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
658
659
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
660
  if ( streamptr->rtsteps == 0 )
661
    Error("Internal problem! Missing contents.");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
662

Uwe Schulzweida's avatar
Uwe Schulzweida committed
663
664
665
  srvp  = streamptr->record->srvp;
  tsID  = streamptr->rtsteps;
  taxis = &streamptr->tsteps[tsID].taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
666

Uwe Schulzweida's avatar
Uwe Schulzweida committed
667
  if ( streamptr->tsteps[tsID].recordSize == 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
668
    {
669
      cdi_create_records(streamptr, tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
670

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
673
674
      streamptr->tsteps[tsID].nrecs = nrecs;
      streamptr->tsteps[tsID].recIDs = (int *) malloc(nrecs*sizeof(int));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
675
      for ( recID = 0; recID < nrecs; recID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
676
	streamptr->tsteps[tsID].recIDs[recID] = streamptr->tsteps[1].recIDs[recID];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
677

678
      fileID = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
679

Uwe Schulzweida's avatar
Uwe Schulzweida committed
680
      fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
681
682
683
684
685
686
687

      for ( rindex = 0; rindex <= nrecs; rindex++ )
	{
	  recpos = fileGetPos(fileID);
	  status = srvRead(fileID, srvp);
	  if ( status != 0 )
	    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
688
	      streamptr->ntsteps = streamptr->rtsteps + 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
689
690
691
692
693
694
	      break;
	    }
	  recsize = fileGetPos(fileID) - recpos;

	  srvInqHeader(srvp, header);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
695
	  rcode  = header[0];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
696
697
698
	  rlevel = header[1];
	  vdate  = header[2];
	  vtime  = header[3];
699
700
          /* rxsize = header[4]; */
          /* rysize = header[5]; */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
701

Uwe Schulzweida's avatar
Uwe Schulzweida committed
702
	  param = cdiEncodeParam(rcode, 255, 255);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
703

Uwe Schulzweida's avatar
Uwe Schulzweida committed
704
	  // if ( rindex == nrecs ) break; gcc-4.5 internal compiler error
705
	  if ( rindex == nrecs ) continue;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
706
	  recID = streamptr->tsteps[tsID].recIDs[rindex];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
707
708
709
710
711
712
713
714

	  if ( rindex == 0 )
	    {
	      taxis->type  = TAXIS_ABSOLUTE;
	      taxis->vdate = vdate;
	      taxis->vtime = vtime;
	    }
	  /*
715
	  srvCmpRecord(streamptr, tsID, nrecs, recpos, param, rlevel, rxsize, rysize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
716
	  */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
717
718
719
	  compVar.param  = param;
          compVar.level  = rlevel;
	  compVar0.param = streamptr->tsteps[tsID].records[recID].param;
720
	  compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
721

722
	  if ( memcmp(&compVar0, &compVar, sizeof(SRVCOMPVAR)) != 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
723
	    {
724
	      Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
725
		      tsID, recID,
Uwe Schulzweida's avatar
Uwe Schulzweida committed
726
		      streamptr->tsteps[tsID].records[recID].param, param,
Uwe Schulzweida's avatar
Uwe Schulzweida committed
727
		      streamptr->tsteps[tsID].records[recID].ilevel, rlevel);
728
	      Error("Invalid, unsupported or inconsistent record structure");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
729
730
	    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
731
732
	  streamptr->tsteps[tsID].records[recID].position = recpos;
	  streamptr->tsteps[tsID].records[recID].size = recsize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
733
734

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
738
      streamptr->rtsteps++;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
739

Uwe Schulzweida's avatar
Uwe Schulzweida committed
740
      if ( streamptr->ntsteps != streamptr->rtsteps )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
741
	{
742
	  tsID = tstepsNewEntry(streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
743
	  if ( tsID != streamptr->rtsteps )
744
	    Error("Internal error. tsID = %d", tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
745

Uwe Schulzweida's avatar
Uwe Schulzweida committed
746
747
	  streamptr->tsteps[tsID-1].next   = 1;
	  streamptr->tsteps[tsID].position = recpos;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
748
749
	}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
750
751
      fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
      streamptr->tsteps[tsID].position = recpos;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
752
753
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
754
  if ( nrecs > 0 && nrecs < streamptr->tsteps[tsID].nrecs )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
755
    {
756
      Warning("Incomplete timestep. Stop scanning at timestep %d.", tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
757
      streamptr->ntsteps = tsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
758
759
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
760
  return (streamptr->ntsteps);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
761
762
763
}


764
int srvInqTimestep(stream_t *streamptr, int tsID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
765
766
767
{
  int ntsteps, nrecs;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
768
  if ( tsID == 0 && streamptr->rtsteps == 0 )
769
    Error("Call to cdiInqContents missing!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
770
771

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
774
  ntsteps = UNDEFID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
775
  while ( ( tsID + 1 ) > streamptr->rtsteps && ntsteps == UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
776
    ntsteps = srvScanTimestep(streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
777

Uwe Schulzweida's avatar
Uwe Schulzweida committed
778
  if ( tsID >= streamptr->ntsteps && streamptr->ntsteps != CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
779
780
781
782
783
    {
      nrecs = 0;
    }
  else
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
784
785
      streamptr->curTsID = tsID;
      nrecs = streamptr->tsteps[tsID].nrecs;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
786
787
788
789
790
791
    }

  return (nrecs);
}


792
void srvReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
793
794
795
796
797
798
799
800
801
{
  int vlistID, fileID;
  int levID, nlevs, gridID, gridsize;
  off_t recpos, currentfilepos;
  int header[8];
  int tsid;
  int recID;
  int i;
  double missval;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
802
  srvrec_t *srvp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
803
804

  srvp     = streamptr->record->srvp;
805
806
  vlistID  = streamptr->vlistID;
  fileID   = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
807
  nlevs    = streamptr->vars[varID].nlevs;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
808
809
810
  missval  = vlistInqVarMissval(vlistID, varID);
  gridID   = vlistInqVarGrid(vlistID, varID);
  gridsize = gridInqSize(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
811
  tsid     = streamptr->curTsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
812
813

  if ( CDI_Debug )
814
    Message("nlevs = %d gridID = %d gridsize = %d", nlevs, gridID, gridsize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
815
816
817
818
819

  currentfilepos = fileGetPos(fileID);

  for (levID = 0; levID < nlevs; levID++)
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
820
821
      recID = streamptr->vars[varID].level[levID];
      recpos = streamptr->tsteps[tsid].records[recID].position;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
822
      fileSetPos(fileID, recpos, SEEK_SET);
823
      srvRead(fileID, srvp);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
      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)++;
      }
}


839
void srvReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data, int *nmiss)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
840
841
842
843
844
845
846
847
848
{
  int vlistID, fileID;
  int nlevs, gridID, gridsize;
  off_t recpos, currentfilepos;
  int header[8];
  int tsid;
  int recID;
  int i;
  double missval;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
849
  srvrec_t *srvp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
850

Uwe Schulzweida's avatar
Uwe Schulzweida committed
851
  srvp     = streamptr->record->srvp;
852
853
  vlistID  = streamptr->vlistID;
  fileID   = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
854
  nlevs    = streamptr->vars[varID].nlevs;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
855
856
857
  missval  = vlistInqVarMissval(vlistID, varID);
  gridID   = vlistInqVarGrid(vlistID, varID);
  gridsize = gridInqSize(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
858
  tsid     = streamptr->curTsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
859
860

  if ( CDI_Debug )
861
    Message("nlevs = %d gridID = %d gridsize = %d",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
862
863
864
865
	     nlevs, gridID, gridsize);

  currentfilepos = fileGetPos(fileID);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
866
867
  recID = streamptr->vars[varID].level[levID];
  recpos = streamptr->tsteps[tsid].records[recID].position;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
868
  fileSetPos(fileID, recpos, SEEK_SET);
869
  srvRead(fileID, srvp);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
  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)++;
      }
}


885
void srvWriteVarDP(stream_t *streamptr, int varID, const double *data)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
886
887
888
889
890
891
{
  int fileID;
  int levID, nlevs, gridID, gridsize;
  int zaxisID;
  double level;
  int header[8];
892
  int xsize, ysize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
893
894
895
  int datatype;
  int tsID;
  int vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
896
  int pdis, pcat, pnum;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
897
  srvrec_t *srvp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
898
899

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
902
  srvp     = streamptr->record->srvp;
903
904
  vlistID  = streamptr->vlistID;
  fileID   = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
905
  tsID     = streamptr->curTsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
906
907
908
909
910
911
  gridID   = vlistInqVarGrid(vlistID, varID);
  gridsize = gridInqSize(gridID);
  zaxisID  = vlistInqVarZaxis(vlistID, varID);
  nlevs    = zaxisInqSize(zaxisID);

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
914
  cdiDecodeParam(vlistInqVarParam(vlistID, varID), &pnum, &pcat, &pdis);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
915
916

  header[0] = pnum;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
917
918
  header[2] = streamptr->tsteps[tsID].taxis.vdate;
  header[3] = streamptr->tsteps[tsID].taxis.vtime;
919
920
921
922

  xsize = gridInqXsize(gridID);
  ysize = gridInqYsize(gridID);
  if ( xsize == 0 || ysize == 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
923
    {
924
925
      xsize = gridInqSize(gridID);
      ysize = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
926
    }
927
  if ( gridInqType(gridID) == GRID_UNSTRUCTURED ) ysize = 1;
928
  if ( gridInqSize(gridID) != xsize*ysize )
929
    Error("Internal problem with gridsize!");
930
931
932

  header[4] = xsize;
  header[5] = ysize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
933
934
935
936
937
938
939
  header[6] = 0;
  header[7] = 0;

  datatype = vlistInqVarDatatype(vlistID, varID);

  srvp->dprec = srvDefDatatype(datatype);

940
  for ( levID = 0; levID < nlevs; levID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
941
942
943
944
945
946
947
948
949
950
951
    {
      level = zaxisInqLevel(zaxisID, levID);

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


952
void srvWriteVarSliceDP(stream_t *streamptr, int varID, int levID, const double *data)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
953
954
955
956
957
958
{
  int fileID;
  int gridID;
  int zaxisID;
  double level;
  int header[8];
959
  int xsize, ysize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
960
961
962
  int datatype;
  int tsID;
  int vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
963
  int pdis, pcat, pnum;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
964
  srvrec_t *srvp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
965

Uwe Schulzweida's avatar
Uwe Schulzweida committed
966
  srvp     = streamptr->record->srvp;
967
968
  vlistID  = streamptr->vlistID;
  fileID   = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
969
  tsID     = streamptr->curTsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
970
971
972
973
974
  gridID   = vlistInqVarGrid(vlistID, varID);
  zaxisID  = vlistInqVarZaxis(vlistID, varID);
  level    = zaxisInqLevel(zaxisID, levID);

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
977
  cdiDecodeParam(vlistInqVarParam(vlistID, varID), &pnum, &pcat, &pdis);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
978
979

  header[0] = pnum;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
980
  header[1] = (int) level;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
981
982
  header[2] = streamptr->tsteps[tsID].taxis.vdate;
  header[3] = streamptr->tsteps[tsID].taxis.vtime;
983
984
985
986

  xsize = gridInqXsize(gridID);
  ysize = gridInqYsize(gridID);
  if ( xsize == 0 || ysize == 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
987
    {
988
989
      xsize = gridInqSize(gridID);
      ysize = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
990
    }
991
  if ( gridInqType(gridID) == GRID_UNSTRUCTURED ) ysize = 1;
992
  if ( gridInqSize(gridID) != xsize*ysize )
993
    Error("Internal problem with gridsize!");
994
995
996

  header[4] = xsize;
  header[5] = ysize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
  header[6] = 0;
  header[7] = 0;

  datatype = vlistInqVarDatatype(vlistID, varID);