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

5
//#define TEST_GROUPS 1
Uwe Schulzweida's avatar
Uwe Schulzweida committed
6

Uwe Schulzweida's avatar
Uwe Schulzweida committed
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include <float.h>

#include "dmemory.h"

#include "cdi.h"
#include "basetime.h"
17
#include "gaussgrid.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
18
19
20
21
22
23
24
25
26
27
28
#include "stream_int.h"
#include "stream_cdf.h"
#include "cdf_int.h"
#include "varscan.h"
#include "vlist.h"


#if  defined  (HAVE_LIBNETCDF)
#  include "netcdf.h"
#endif

29
30
//#define PROJECTION_TEST

Uwe Schulzweida's avatar
Uwe Schulzweida committed
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#undef  UNDEFID
#define UNDEFID  CDI_UNDEFID


void cdfDefGlobalAtts(int streamID);
void cdfDefLocalAtts(int streamID);


#define  X_AXIS  1
#define  Y_AXIS  2
#define  Z_AXIS  3
#define  T_AXIS  4

typedef struct {
  int     ncvarid;
  int     dimtype;
  size_t  len;
48
  char    name[CDI_MAX_NAME];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
49
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
50
ncdim_t;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
51
52

typedef struct {
53
  int      ncid;
54
  int      ignore;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
55
56
57
58
  int      isvar;
  int      islon;
  int      islat;
  int      islev;
59
  int      istime;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
60
  int      warn;
61
  int      tsteptype;
62
  int      param;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
63
  int      code;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
64
  int      tabnum;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
65
66
67
68
69
70
71
72
73
74
75
76
  int      bounds;
  int      gridID;
  int      zaxisID;
  int      gridtype;
  int      zaxistype;
  int      xdim;
  int      ydim;
  int      zdim;
  int      xvarid;
  int      yvarid;
  int      zvarid;
  int      tvarid;
77
78
  int      ncoordvars;
  int      coordvarids[4];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
79
80
81
82
83
84
85
86
87
88
89
  int      cellarea;
  int      calendar;
  int      tableID;
  int      truncation;
  int      defmiss;
  int      xtype;
  int      ndims;
  int      gmapid;
  int      positive;
  int      dimids[8];
  int      dimtype[8];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
90
91
92
  int      chunks[8];
  int      chunked;
  int      chunktype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
93
94
  int      natts;
  int     *atts;
95
  int      deflate;
96
97
  int      lunsigned;
  int      lvalidrange;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
98
99
100
101
102
  size_t   vlen;
  double  *vdata;
  double   missval;
  double   addoffset;
  double   scalefactor;
103
  double   validrange[2];
104
105
106
107
  char     name[CDI_MAX_NAME];
  char     longname[CDI_MAX_NAME];
  char     stdname[CDI_MAX_NAME];
  char     units[CDI_MAX_NAME];
108
  ensinfo_t   *ensdata;    /* Ensemble information */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
109
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
110
ncvar_t;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
111

112
#ifdef HAVE_LIBNETCDF
113
114
115
116
117
118
119
120
121
static
void strtolower(char *str)
{
  int i, len;

  if ( str )
    {
      len = (int) strlen(str);
      for ( i = 0; i < len; i++ )
122
        str[i] = tolower((int) str[i]);
123
124
125
    }
}

126
127
128
129
static
int get_timeunit(int len, char *ptu)
{
  int timeunit = -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
130

131
132
133
134
135
136
137
138
139
140
  if ( len > 2 )
    {
      if      ( memcmp(ptu, "sec",    3) == 0 )          timeunit = TUNIT_SECOND;
      else if ( memcmp(ptu, "minute", 6) == 0 )          timeunit = TUNIT_MINUTE;
      else if ( memcmp(ptu, "hour",   4) == 0 )          timeunit = TUNIT_HOUR;
      else if ( memcmp(ptu, "day",    3) == 0 )          timeunit = TUNIT_DAY;
      else if ( memcmp(ptu, "month",  5) == 0 )          timeunit = TUNIT_MONTH;
      else if ( memcmp(ptu, "calendar_month", 14) == 0 ) timeunit = TUNIT_MONTH;
      else if ( memcmp(ptu, "year",   4) == 0 )          timeunit = TUNIT_YEAR;
    }
141
142
143
144
  else if ( len == 1 )
    {
      if ( ptu[0] == 's' ) timeunit = TUNIT_SECOND;
    }
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170

  return (timeunit);
}

static
int isTimeUnits(const char *timeunits)
{
  int len, i;
  char *ptu, *tu;
  int timetype = -1;
  int timeunit;
  int status = FALSE;

  len = (int) strlen(timeunits);
  tu = (char *) malloc((len+1)*sizeof(char));
  memcpy(tu, timeunits, (len+1)*sizeof(char));
  ptu = tu;

  for ( i = 0; i < len; i++ ) ptu[i] = tolower((int) ptu[i]);

  timeunit = get_timeunit(len, ptu);
  if ( timeunit != -1 )
    {

      while ( ! isspace(*ptu) && *ptu != 0 ) ptu++;
      if ( *ptu )
171
172
        {
          while ( isspace(*ptu) ) ptu++;
173

174
175
176
177
178
179
180
          if ( memcmp(ptu, "as", 2) == 0 )
            timetype = TAXIS_ABSOLUTE;
          else if ( memcmp(ptu, "since", 5) == 0 )
            timetype = TAXIS_RELATIVE;

          if ( timetype != -1 ) status = TRUE;
        }
181
182
183
184
185
186
187
188
    }

  free(tu);

  return (status);
}

static
189
int splitBasetime(const char *timeunits, taxis_t *taxis)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
190
{
191
  int len, i;
192
  char *ptu, *tu;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
193
194
195
196
  int year, month, day;
  int hour = 0, minute = 0, second = 0;
  int timetype = TAXIS_ABSOLUTE;
  int rdate = -1, rtime = -1;
197
  int timeunit;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
198

Uwe Schulzweida's avatar
Uwe Schulzweida committed
199
  len = (int) strlen(timeunits);
200
201
202
  tu = (char *) malloc((len+1)*sizeof(char));
  memcpy(tu, timeunits, (len+1)*sizeof(char));
  ptu = tu;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
203

204
205
  for ( i = 0; i < len; i++ ) ptu[i] = tolower((int) ptu[i]);

206
207
  timeunit = get_timeunit(len, ptu);
  if ( timeunit == -1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
208
    {
209
      Message("Unsupported TIMEUNIT: %s!", timeunits);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
210
211
212
213
214
215
      return (1);
    }

  while ( ! isspace(*ptu) && *ptu != 0 ) ptu++;
  if ( *ptu )
    {
216
      while ( isspace(*ptu) ) ptu++;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
217

218
      if ( memcmp(ptu, "as", 2) == 0 )
219
        timetype = TAXIS_ABSOLUTE;
220
      else if ( memcmp(ptu, "since", 5) == 0 )
221
        timetype = TAXIS_RELATIVE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
222
223
224

      while ( ! isspace(*ptu) && *ptu != 0 ) ptu++;
      if ( *ptu )
225
226
227
228
229
230
231
        {
          while ( isspace(*ptu) ) ptu++;

          if ( timetype == TAXIS_ABSOLUTE )
            {
              if ( memcmp(ptu, "%y%m%d.%f", 9) != 0 && timeunit == TUNIT_DAY )
                {
232
                  Message("Unsupported format %s for TIMEUNIT day!", ptu);
233
234
235
236
                  timeunit = -1;
                }
              else if ( memcmp(ptu, "%y%m.%f", 7) != 0 && timeunit == TUNIT_MONTH )
                {
237
                  Message("Unsupported format %s for TIMEUNIT month!", ptu);
238
239
240
241
242
                  timeunit = -1;
                }
            }
          else if ( timetype == TAXIS_RELATIVE )
            {
243
244
245
              int v1, v2, v3;
              v1 = atoi(ptu);
              if ( v1 < 0 ) ptu++;
246
              while ( isdigit((int) *ptu) ) ptu++;
247
              v2 = atoi(++ptu);
248
              while ( isdigit((int) *ptu) ) ptu++;
249
              v3 = atoi(++ptu);
250
251
              while ( isdigit((int) *ptu) ) ptu++;

252
253
254
255
256
              if ( v3 > 999 && v1 < 32 )
                { year = v3; month = v2; day = v1; }
              else
                { year = v1; month = v2; day = v3; }

257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
              while ( isspace((int) *ptu) ) ptu++;

              if ( *ptu )
                {
                  while ( ! isdigit((int) *ptu) ) ptu++;

                  hour = atoi(ptu);
                  while ( isdigit((int) *ptu) ) ptu++;
                  if ( *ptu == ':' )
                    {
                      ptu++;
                      minute = atoi(ptu);
                      while ( isdigit((int) *ptu) ) ptu++;
                      if ( *ptu == ':' )
                        {
                          ptu++;
                          second = atoi(ptu);
                          /*
                          if ( second != 0 )
276
                            Message("Seconds not supported in time units!");
277
278
279
280
281
282
283
284
285
286
287
                          */
                        }
                    }
                }

              rdate = cdiEncodeDate(year, month, day);
              rtime = cdiEncodeTime(hour, minute, second);
              (*taxis).rdate = rdate;
              (*taxis).rtime = rtime;

              if ( CDI_Debug )
288
                Message("rdate = %d  rtime = %d", rdate, rtime);
289
290
            }
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
291
292
293
294
295
    }

  (*taxis).type = timetype;
  (*taxis).unit = timeunit;

296
297
  free(tu);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
298
  if ( CDI_Debug )
299
    Message("timetype = %d  unit = %d", timetype, timeunit);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
300
301
302
303

  return (0);
}

304
305
static
void cdfGetAttInt(int fileID, int ncvarid, char *attname, int attlen, int *attint)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
306
{
307
  size_t nc_attlen;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
308
309
  int *pintatt;

310
  cdf_inq_attlen(fileID, ncvarid, attname, &nc_attlen);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
311

312
313
  if ( (int)nc_attlen > attlen )
    pintatt = (int *) malloc(nc_attlen*sizeof(int));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
314
  else
315
    pintatt = attint;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
316
317
318

  cdf_get_att_int(fileID, ncvarid, attname, pintatt);

319
320
321
322
323
  if ( (int)nc_attlen > attlen )
    {
      memcpy(attint, pintatt, attlen*sizeof(int));
      free(pintatt);
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
324
325
}

326
327
static
void cdfGetAttDouble(int fileID, int ncvarid, char *attname, int attlen, double *attdouble)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
328
{
329
  size_t nc_attlen;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
330
331
  double *pdoubleatt;

332
  cdf_inq_attlen(fileID, ncvarid, attname, &nc_attlen);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
333

334
335
  if ( (int)nc_attlen > attlen )
    pdoubleatt = (double *) malloc(nc_attlen*sizeof(double));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
336
  else
337
    pdoubleatt = attdouble;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
338
339
340

  cdf_get_att_double(fileID, ncvarid, attname, pdoubleatt);

341
342
343
344
345
  if ( (int)nc_attlen > attlen )
    {
      memcpy(attdouble, pdoubleatt, attlen*sizeof(double));
      free(pdoubleatt);
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
346
347
}

348
349
static
void cdfGetAttText(int fileID, int ncvarid, char *attname, int attlen, char *atttext)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
350
{
351
  size_t nc_attlen;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
352
353
  char attbuf[65636];

354
  cdf_inq_attlen(fileID, ncvarid, attname, &nc_attlen);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
355

356
  if ( nc_attlen < sizeof(attbuf) )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
357
358
359
    {
      cdf_get_att_text(fileID, ncvarid, attname, attbuf);

360
      attbuf[nc_attlen++] = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
361

362
363
      if ( (int) nc_attlen > attlen ) nc_attlen = attlen;
      memcpy(atttext, attbuf, nc_attlen);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
364
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
365
366
367
368
  else
    {
      atttext[0] = 0;
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
369
370
}

371
static
372
int cdfInqDatatype(int xtype, int lunsigned)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
373
{
374
  int datatype = -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
375

376
#if  defined  (HAVE_NETCDF4)
377
  if ( xtype == NC_BYTE && lunsigned ) xtype = NC_UBYTE;
378
#endif
379

Uwe Schulzweida's avatar
Uwe Schulzweida committed
380
381
382
383
  if      ( xtype == NC_BYTE   )  datatype = DATATYPE_INT8;
  /* else if ( xtype == NC_CHAR   )  datatype = DATATYPE_UINT8; */
  else if ( xtype == NC_SHORT  )  datatype = DATATYPE_INT16;
  else if ( xtype == NC_INT    )  datatype = DATATYPE_INT32;
384
  else if ( xtype == NC_FLOAT  )  datatype = DATATYPE_FLT32;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
385
  else if ( xtype == NC_DOUBLE )  datatype = DATATYPE_FLT64;
386
#if  defined  (HAVE_NETCDF4)
387
  else if ( xtype == NC_UBYTE  )  datatype = DATATYPE_UINT8;
388
389
390
391
392
393
  else if ( xtype == NC_LONG   )  datatype = DATATYPE_INT32;
  else if ( xtype == NC_USHORT )  datatype = DATATYPE_UINT16;
  else if ( xtype == NC_UINT   )  datatype = DATATYPE_UINT32;
  else if ( xtype == NC_INT64  )  datatype = DATATYPE_FLT64;
  else if ( xtype == NC_UINT64 )  datatype = DATATYPE_FLT64;
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
394
395
396
397

  return (datatype);
}

398
static
399
int cdfDefDatatype(int datatype, int filetype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
400
401
402
{
  int xtype;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
403
  if ( datatype == DATATYPE_CPX32 || datatype == DATATYPE_CPX64 )
404
    Error("CDI/netCDF library does not support complex numbers!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
405

406
407
408
409
410
  if ( filetype == FILETYPE_NC4 )
    {
      if      ( datatype == DATATYPE_INT8   ) xtype = NC_BYTE;
      else if ( datatype == DATATYPE_INT16  ) xtype = NC_SHORT;
      else if ( datatype == DATATYPE_INT32  ) xtype = NC_INT;
411
#if  defined  (HAVE_NETCDF4)
412
413
414
      else if ( datatype == DATATYPE_UINT8  ) xtype = NC_UBYTE;
      else if ( datatype == DATATYPE_UINT16 ) xtype = NC_USHORT;
      else if ( datatype == DATATYPE_UINT32 ) xtype = NC_UINT;
415
#else
416
      else if ( datatype == DATATYPE_UINT8  ) xtype = NC_SHORT;
417
418
      else if ( datatype == DATATYPE_UINT16 ) xtype = NC_INT;
      else if ( datatype == DATATYPE_UINT32 ) xtype = NC_INT;
419
#endif
420
421
422
423
424
425
426
427
      else if ( datatype == DATATYPE_FLT64  ) xtype = NC_DOUBLE;
      else                                    xtype = NC_FLOAT;
    }
  else
    {
      if      ( datatype == DATATYPE_INT8   ) xtype = NC_BYTE;
      else if ( datatype == DATATYPE_INT16  ) xtype = NC_SHORT;
      else if ( datatype == DATATYPE_INT32  ) xtype = NC_INT;
428
      else if ( datatype == DATATYPE_UINT8  ) xtype = NC_SHORT;
429
430
431
432
433
434
      else if ( datatype == DATATYPE_UINT16 ) xtype = NC_INT;
      else if ( datatype == DATATYPE_UINT32 ) xtype = NC_INT;
      else if ( datatype == DATATYPE_FLT64  ) xtype = NC_DOUBLE;
      else                                    xtype = NC_FLOAT;
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
435
436
437
  return (xtype);
}

438
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
439
440
441
void defineAttributes(int vlistID, int varID, int fileID, int ncvarID)
{
  int natts, iatt;
442
  int atttype, attlen;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
443
  size_t len;
444
  char attname[1024];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
445
446
447
448
449

  vlistInqNatts(vlistID, varID, &natts);

  for ( iatt = 0; iatt < natts; iatt++ )
    {
450
      vlistInqAtt(vlistID, varID, iatt, attname, &atttype, &attlen);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
451

452
453
      if ( attlen == 0 ) continue;

454
      if ( atttype == DATATYPE_TXT )
455
        {
456
457
458
          char *atttxt;
          atttxt = (char *) malloc(attlen*sizeof(char));
          vlistInqAttTxt(vlistID, varID, attname, attlen, atttxt);
459
460
          len = attlen;
          cdf_put_att_text(fileID, ncvarID, attname, len, atttxt);
461
          free(atttxt);
462
        }
463
      else if ( atttype == DATATYPE_INT16 || atttype == DATATYPE_INT32 )
464
465
466
467
468
469
470
471
472
473
474
        {
          int *attint;
          attint = (int *) malloc(attlen*sizeof(int));
          vlistInqAttInt(vlistID, varID, attname, attlen, &attint[0]);
          len = attlen;
          if ( atttype == DATATYPE_INT16 )
            cdf_put_att_int(fileID, ncvarID, attname, NC_SHORT, len, attint);
          else
            cdf_put_att_int(fileID, ncvarID, attname, NC_INT, len, attint);
          free(attint);
        }
475
      else if ( atttype == DATATYPE_FLT32 || atttype == DATATYPE_FLT64 )
476
477
478
479
480
481
482
483
484
485
486
        {
          double *attflt;
          attflt = (double *) malloc(attlen*sizeof(double));
          vlistInqAttFlt(vlistID, varID, attname, attlen, attflt);
          len = attlen;
          if ( atttype == DATATYPE_FLT32 )
            cdf_put_att_double(fileID, ncvarID, attname, NC_FLOAT, len, attflt);
          else
            cdf_put_att_double(fileID, ncvarID, attname, NC_DOUBLE, len, attflt);
          free(attflt);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
487
488
489
490
    }
}
#endif

Uwe Schulzweida's avatar
Uwe Schulzweida committed
491
int cdfCopyRecord(int streamID2, int streamID1)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
492
493
{
  double *data;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
494
  int datasize;
495
  int tsID1, recID1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
496
497
498
  int ivarID, gridID;
  int nmiss;
  int ierr = 0;
499
  int memtype = MEMTYPE_DOUBLE;
500
  int vlistID1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
501
502
  stream_t *streamptr1;
  stream_t *streamptr2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
503

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

507
508
  stream_check_ptr(__func__, streamptr1);
  stream_check_ptr(__func__, streamptr2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
509

Uwe Schulzweida's avatar
Uwe Schulzweida committed
510
  vlistID1 = streamptr1->vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
511

Uwe Schulzweida's avatar
Uwe Schulzweida committed
512
  tsID1 = streamptr1->curTsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
513

Uwe Schulzweida's avatar
Uwe Schulzweida committed
514
  recID1 = streamptr1->tsteps[tsID1].curRecID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
515

Uwe Schulzweida's avatar
Uwe Schulzweida committed
516
517
518
  ivarID = streamptr1->tsteps[tsID1].records[recID1].varID;

  gridID = vlistInqVarGrid(vlistID1, ivarID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
519

520
  datasize = gridInqSize(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
521
522
523
524
525
  /* bug fix for constant netCDF fields */
  if ( datasize < 1048576 ) datasize = 1048576;

  data = (double *) malloc(datasize*sizeof(double));

Uwe Schulzweida's avatar
Uwe Schulzweida committed
526
  streamReadRecord(streamID1, data, &nmiss);
527
  stream_write_record(streamID2, memtype, data, nmiss);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
528
529
530
531
532

  free(data);

  return (ierr);
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
533

Uwe Schulzweida's avatar
Uwe Schulzweida committed
534
535
536
537
/* not used
int cdfInqRecord(int streamID, int *varID, int *levelID)
{
  int tsID, recID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
538
  stream_t *streamptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
539
540

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

542
  stream_check_ptr(__func__, streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
543

Uwe Schulzweida's avatar
Uwe Schulzweida committed
544
545
546
  recID = streamptr->tsteps[0].curRecID++;
  printf("cdfInqRecord recID %d %d\n", recID, streamptr->tsteps[0].curRecID);
  printf("cdfInqRecord tsID %d\n", streamptr->curTsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
547

Uwe Schulzweida's avatar
Uwe Schulzweida committed
548
549
  if ( streamptr->tsteps[0].curRecID >= 
       streamptr->tsteps[0].nrecs )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
550
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
551
      streamptr->tsteps[0].curRecID = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
552
553
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
554
555
  *varID   = streamptr->tsteps[0].records[recID].varID;
  *levelID = streamptr->tsteps[0].records[recID].levelID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
556

Uwe Schulzweida's avatar
Uwe Schulzweida committed
557
558
  streamptr->record->varID   = *varID;
  streamptr->record->levelID = *levelID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
559
560

  if ( CDI_Debug )
561
    Message("recID = %d  varID = %d  levelID = %d", recID, *varID, *levelID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
562
563
564
565
566
567
568
  
  return (recID+1);
}
*/
int cdfDefRecord(int streamID)
{
  int ierr = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
569
  stream_t *streamptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
570
571

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

  if ( CDI_Debug )
574
    Message("streamID = %d", streamID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
575

576
  stream_check_ptr(__func__, streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
577
578
579
580

  return (ierr);
}

581
#if  defined  (HAVE_LIBNETCDF)
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
582
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
583
584
585
586
587
588
589
void cdfWriteGridTraj(int streamID, int gridID)
{
  int tsID, fileID;
  int lonID, latID, gridindex;
  size_t index;
  double xlon, xlat;
  int vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
590
  stream_t *streamptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
591
592

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
594
595
  vlistID = streamptr->vlistID;
  fileID  = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
596
597

  gridindex = vlistGridIndex(vlistID, gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
598
599
  lonID = streamptr->xdimID[gridindex];
  latID = streamptr->ydimID[gridindex];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
600
601
602

  xlon = gridInqXval(gridID, 0);
  xlat = gridInqYval(gridID, 0);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
603
  tsID = streamptr->curTsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
604
605
606
607
608
  index = tsID;

  cdf_put_var1_double(fileID, lonID, &index, &xlon);
  cdf_put_var1_double(fileID, latID, &index, &xlat);
}
609
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
610

611
#if  defined  (HAVE_LIBNETCDF)
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
612
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
613
614
615
616
617
618
619
void cdfReadGridTraj(int streamID, int gridID)
{
  int tsID, fileID;
  int lonID, latID, gridindex;
  size_t index;
  double xlon, xlat;
  int vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
620
  stream_t *streamptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
621
622

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
624
625
  vlistID = streamptr->vlistID;
  fileID  = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
626
627

  gridindex = vlistGridIndex(vlistID, gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
628
629
  lonID = streamptr->xdimID[gridindex];
  latID = streamptr->ydimID[gridindex];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
630

Uwe Schulzweida's avatar
Uwe Schulzweida committed
631
  tsID = streamptr->curTsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
632
633
634
635
636
637
638
639
  index = tsID;

  cdf_get_var1_double(fileID, lonID, &index, &xlon);
  cdf_get_var1_double(fileID, latID, &index, &xlat);

  gridDefXvals(gridID, &xlon);
  gridDefYvals(gridID, &xlat);
}
640
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
641

642
#if  defined  (HAVE_LIBNETCDF)
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
643
static
644
645
void cdfDefVarDeflate(int ncid, int ncvarid, int deflate_level)
{
646
#if  defined  (HAVE_NETCDF4)
647
648
649
650
651
652
653
654
655
  int retval;
  /* Set chunking, shuffle, and deflate. */
  int shuffle = 1;
  int deflate = 1;

  if ( deflate_level < 1 || deflate_level > 9 ) deflate_level = 1;

  if ((retval = nc_def_var_deflate(ncid, ncvarid, shuffle, deflate, deflate_level)))
    {
656
      Error("nc_def_var_deflate failed, status = %d", retval);
657
658
659
660
661
662
663
    }
#else
  static int lwarn = TRUE;

  if ( lwarn )
    {
      lwarn = FALSE;
664
      Warning("Deflate compression failed, netCDF4 not available!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
665
666
667
668
669
    }
#endif
}
#endif

670
#if  defined(HAVE_LIBNETCDF) && defined(NC_SZIP_NN_OPTION_MASK)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
671
672
673
674
675
static
void cdfDefVarSzip(int ncid, int ncvarid)
{
  int retval;
  /* Set options_mask and bits_per_pixel. */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
676
  int options_mask = NC_SZIP_NN_OPTION_MASK;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
677
678
679
680
681
  int bits_per_pixel = 16;

  if ((retval = nc_def_var_szip(ncid, ncvarid, options_mask, bits_per_pixel)))
    {
      if ( retval == NC_EINVAL )
682
683
684
685
686
687
        {
          static int lwarn = TRUE;

          if ( lwarn )
            {
              lwarn = FALSE;
688
              Warning("netCDF4/Szip compression not compiled in!");
689
            }
690
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
691
      else
692
        Error("nc_def_var_szip failed, status = %d", retval);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
693
    }
694
695
696
}
#endif

697
#if  defined  (HAVE_LIBNETCDF)
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
698
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
699
void cdfDefVarMissval(int streamID, int varID, int dtype, int lcheck)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
700
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
701
  stream_t *streamptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
702
703
704
705

  streamptr = stream_to_pointer(streamID);

  if ( streamptr->vars[varID].defmiss == FALSE )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
706
707
708
709
710
711
712
    {
      int fileID;
      int ncvarid;
      double missval;
      int vlistID;
      int xtype;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
713
714
      vlistID = streamptr->vlistID;
      fileID  = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
715
      ncvarid = streamptr->vars[varID].ncvarid;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
716
      missval = vlistInqVarMissval(vlistID, varID);
717
      if ( lcheck && streamptr->ncmode == 2 ) cdf_redef(fileID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
718

719
      xtype = cdfDefDatatype(dtype, streamptr->filetype);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
720

721
      cdf_put_att_double(fileID, ncvarid, "_FillValue", (nc_type) xtype, 1, &missval);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
722
723

      if ( cdiNcMissingValue == 1 )
724
        cdf_put_att_double(fileID, ncvarid, "missing_value", (nc_type) xtype, 1, &missval);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
725

726
      if ( lcheck && streamptr->ncmode == 2 ) cdf_enddef(fileID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
727

Uwe Schulzweida's avatar
Uwe Schulzweida committed
728
      streamptr->vars[varID].defmiss = TRUE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
729
730
    }
}
731
#endif
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
732

733
void cdf_write_record(int streamID, int memtype, const void *data, int nmiss)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
734
735
736
737
{
#if  defined  (HAVE_LIBNETCDF)
  int varID;
  int levelID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
738
  stream_t *streamptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
739
740

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
742
743
  varID   = streamptr->record->varID;
  levelID = streamptr->record->levelID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
744
745

  if ( CDI_Debug )
746
    Message("streamID = %d  varID = %d", streamID, varID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
747

748
  cdf_write_var_slice(streamID, varID, levelID, memtype, data, nmiss);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
749
750
751
#endif
}

Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
752

Uwe Schulzweida's avatar
Uwe Schulzweida committed
753
754
755
756
int cdfReadRecord(int streamID, double *data, int *nmiss)
{
  int ierr = 0;
  int levelID, varID, tsID, recID, vrecID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
757
  stream_t *streamptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
758
759

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

761
  if ( CDI_Debug ) Message("streamID = %d", streamID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
762

Uwe Schulzweida's avatar
Uwe Schulzweida committed
763
764
765
766
767
  tsID    = streamptr->curTsID;
  vrecID  = streamptr->tsteps[tsID].curRecID;
  recID   = streamptr->tsteps[tsID].recIDs[vrecID];
  varID   = streamptr->tsteps[tsID].records[recID].varID;
  levelID = streamptr->tsteps[tsID].records[recID].levelID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
768
769
770
771
772
773

  cdfReadVarSliceDP(streamID, varID, levelID, data, nmiss);

  return (ierr);
}

774
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
775
void cdfDefTimeValue(stream_t *streamptr, int tsID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
776
777
778
779
780
781
{
#if  defined  (HAVE_LIBNETCDF)
  int fileID;
  double timevalue;
  int ncvarid;
  size_t index;
782
  taxis_t *taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
783

Uwe Schulzweida's avatar
Uwe Schulzweida committed
784
  fileID = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
785
786

  if ( CDI_Debug )
787
    Message("streamID = %d, fileID = %d", streamID, fileID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
788

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
791
  if ( streamptr->ncmode == 1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
792
793
    {
      cdf_enddef(fileID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
794
      streamptr->ncmode = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
795
796
797
798
    }

  index = tsID;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
799
  timevalue = cdiEncodeTimeval(taxis->vdate, taxis->vtime, &streamptr->tsteps[0].taxis);
800
  if ( CDI_Debug ) Message("tsID = %d  timevalue = %f", tsID, timevalue);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
801

Uwe Schulzweida's avatar
Uwe Schulzweida committed
802
  ncvarid = streamptr->basetime.ncvarid;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
803
804
805
806
807
808
  cdf_put_var1_double(fileID, ncvarid, &index, &timevalue);

  if ( taxis->has_bounds )
    {
      size_t start[2], count[2];

Uwe Schulzweida's avatar
Uwe Schulzweida committed
809
      ncvarid = streamptr->basetime.ncvarboundsid;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
810

Uwe Schulzweida's avatar
Uwe Schulzweida committed
811
      timevalue = cdiEncodeTimeval(taxis->vdate_lb, taxis->vtime_lb, &streamptr->tsteps[0].taxis);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
812
813
814
      start[0] = tsID; count[0] = 1; start[1] = 0; count[1] = 1;
      cdf_put_vara_double(fileID, ncvarid, start, count, &timevalue);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
815
      timevalue = cdiEncodeTimeval(taxis->vdate_ub, taxis->vtime_ub, &streamptr->tsteps[0].taxis);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
816
817
818
819
820
821
822
823
824
      start[0] = tsID; count[0] = 1; start[1] = 1; count[1] = 1;
      cdf_put_vara_double(fileID, ncvarid, start, count, &timevalue);
    }
  /*
printf("fileID = %d %d %d %f\n", fileID, time_varid, index, timevalue);
  */
#endif
}

Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
825
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
826
void cdfDefTime(stream_t *streamptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
827
828
829
830
831
832
{
#if  defined  (HAVE_LIBNETCDF)
  int fileID;
  int time_varid;
  int time_bndsid;
  int dims[2];
833
  int year, month, day, hour, minute, second;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
834
835
  char unitstr[80];
  char calstr[80];
836
  char tmpstr[CDI_MAX_NAME];
837
838
  char default_name[] = "time";
  char *taxis_name = default_name;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
839
  size_t len;
840
  taxis_t *taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
841

Uwe Schulzweida's avatar
Uwe Schulzweida committed
842
  if ( streamptr->basetime.ncvarid != UNDEFID ) return;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
843

Uwe Schulzweida's avatar
Uwe Schulzweida committed
844
  fileID = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
845

Uwe Schulzweida's avatar
Uwe Schulzweida committed
846
  if ( streamptr->ncmode == 0 ) streamptr->ncmode = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
847

Uwe Schulzweida's avatar
Uwe Schulzweida committed
848
  if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
849

850
  taxis = &streamptr->tsteps[0].taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
851

852
  if ( taxis->name && taxis->name[0] ) taxis_name = taxis->name;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
853

854
  cdf_def_dim(fileID, taxis_name, NC_UNLIMITED, &streamptr->basetime.ncdimid);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
855

856
857
  dims[0] = streamptr->basetime.ncdimid;
  cdf_def_var(fileID, taxis_name, NC_DOUBLE, 1, dims, &time_varid);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
858

859
  streamptr->basetime.ncvarid = time_varid;
860
861
862
863

  strcpy(tmpstr, "time");
  cdf_put_att_text(fileID, time_varid, "standard_name", strlen(tmpstr), tmpstr);

864
865
866
  if ( taxis->longname && taxis->longname[0] )
    cdf_put_att_text(fileID, time_varid, "long_name", strlen(taxis->longname), taxis->longname);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
867
868
869
870
  if ( taxis->has_bounds )
    {
      /* fprintf(stderr, "time has bounds\n"); */

871
872
873
      if ( nc_inq_dimid(fileID, "nb2", &dims[1]) != NC_NOERR )
	cdf_def_dim(fileID, "nb2", 2, &dims[1]);

874
875
876
      strcpy(tmpstr, taxis_name);
      strcat(tmpstr, "_bnds");
      cdf_def_var(fileID, tmpstr, NC_DOUBLE, 2, dims, &time_bndsid);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
877

Uwe Schulzweida's avatar
Uwe Schulzweida committed
878
      streamptr->basetime.ncvarboundsid = time_bndsid;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
879

880
      cdf_put_att_text(fileID, time_varid, "bounds", strlen(tmpstr), tmpstr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
881
882
883
    }

  unitstr[0] = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
884
  if ( streamptr->tsteps[0].taxis.type == TAXIS_ABSOLUTE )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
885
    {
886
      if ( streamptr->tsteps[0].taxis.unit == TUNIT_YEAR )
887
        sprintf(unitstr, "year as %s", "%Y.%f");
888
      else if ( streamptr->tsteps[0].taxis.unit == TUNIT_MONTH )
889
        sprintf(unitstr, "month as %s", "%Y%m.%f");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
890
      else
891
        sprintf(unitstr, "day as %s", "%Y%m%d.%f");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
892
893
894
895
896
897
898
    }
  else
    {
      int rdate, rtime;
      int timeunit;

      timeunit = taxis->unit;
899
      if ( timeunit == -1 ) timeunit = TUNIT_HOUR;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
900
901
902
      rdate    = taxis->rdate;
      rtime    = taxis->rtime;
      if ( rdate == -1 )
903
904
905
906
        {
          rdate  = taxis->vdate;
          rtime  = taxis->vtime;
        }
907

Uwe Schulzweida's avatar
Uwe Schulzweida committed
908
909
      cdiDecodeDate(rdate, &year, &month, &day);
      cdiDecodeTime(rtime, &hour, &minute, &second);
910

911
      if ( timeunit == TUNIT_QUARTER ) timeunit = TUNIT_MINUTE;
912
913
914
915
      if ( timeunit == TUNIT_3HOURS  ||
	   timeunit == TUNIT_6HOURS  ||
	   timeunit == TUNIT_12HOURS ) timeunit = TUNIT_HOUR;

916
      sprintf(unitstr, "%s since %d-%02d-%02d %02d:%02d:%02d",
917
              tunitNamePtr(timeunit), year, month, day, hour, minute, second);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
918
919
920
921
922
923
924
925
926
927
928
929
930
931
    }

  len = strlen(unitstr);
  if ( len )
    cdf_put_att_text(fileID, time_varid, "units", len, unitstr);

  if ( taxis->has_bounds )
    if ( len )
      cdf_put_att_text(fileID, time_bndsid, "units", len, unitstr);

  if ( taxis->calendar != -1 )
    {
      calstr[0] = 0;

932
933
934
      if      ( taxis->calendar == CALENDAR_STANDARD )  strcpy(calstr, "standard");
      else if ( taxis->calendar == CALENDAR_PROLEPTIC ) strcpy(calstr, "proleptic_gregorian");
      else if ( taxis->calendar == CALENDAR_NONE )      strcpy(calstr, "none");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
935
936
937
938
939
940
      else if ( taxis->calendar == CALENDAR_360DAYS )   strcpy(calstr, "360_day");
      else if ( taxis->calendar == CALENDAR_365DAYS )   strcpy(calstr, "365_day");
      else if ( taxis->calendar == CALENDAR_366DAYS )   strcpy(calstr, "366_day");

      len = strlen(calstr);
      if ( len )
941
942
        {
          cdf_put_att_text(fileID, time_varid, "calendar", len, calstr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
943

944
945
946
          if ( taxis->has_bounds )
            cdf_put_att_text(fileID, time_bndsid, "calendar", len, calstr);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
947
948
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
949
  if ( streamptr->ncmode == 2 ) cdf_enddef(fileID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
950
951
952
953
#endif
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
954
void cdfDefTimestep(stream_t *streamptr, int tsID)
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
955
956
957
{
  int vlistID;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
958
  vlistID = streamptr->vlistID;
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
959

Uwe Schulzweida's avatar
Uwe Schulzweida committed
960
  if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
961

Uwe Schulzweida's avatar
Uwe Schulzweida committed
962
  cdfDefTimeValue(streamptr, tsID);
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
963
964
}

965
#if  defined  (HAVE_LIBNETCDF)
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
966
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
967
968
void cdfDefComplex(int streamID, int gridID)
{
969
  char axisname[] = "nc2";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
970
971
972
973
974
975
976
  int index;
  int dimID = UNDEFID;
  int gridID0, gridtype0, gridindex;
  int ngrids;
  int fileID;
  int dimlen;
  int vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
977
  stream_t *streamptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
978
979

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
981
982
  vlistID = streamptr->vlistID;
  fileID  = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
983
984
985
986
987

  ngrids = vlistNgrids(vlistID);

  for ( index = 0; index < ngrids; index++ )
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
988
      if ( streamptr->xdimID[index] != UNDEFID )
989
990
991
        {
          gridID0 = vlistGrid(vlistID, index);
          gridtype0 = gridInqType(gridID0);
992
          if ( gridtype0 == GRID_SPECTRAL || gridtype0 == GRID_FOURIER )
993
994
995
996
997
            {
              dimID = streamptr->xdimID[index];
              break;
            }
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
998
999
1000
    }

  if ( dimID == UNDEFID )
For faster browsing, not all history is shown. View entire blame