stream_cdf.c 220 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"
18
#include "cdi_int.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
19
20
21
22
23
#include "stream_cdf.h"
#include "cdf_int.h"
#include "varscan.h"
#include "vlist.h"

24
#include "pio_util.h"
25

Uwe Schulzweida's avatar
Uwe Schulzweida committed
26
27
28
29
#if  defined  (HAVE_LIBNETCDF)
#  include "netcdf.h"
#endif

30
31
//#define PROJECTION_TEST

Uwe Schulzweida's avatar
Uwe Schulzweida committed
32
33
34
35
#undef  UNDEFID
#define UNDEFID  CDI_UNDEFID


36
37
void cdfDefGlobalAtts(stream_t *streamptr);
void cdfDefLocalAtts(stream_t *streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
38
39
40
41
42
43
44


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

45
46
47
#define  POSITIVE_UP    1
#define  POSITIVE_DOWN  2

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

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

120
#ifdef HAVE_LIBNETCDF
121
122
123
124
125
126
127
128
129
130
131
132
static
void strtolower(char *str)
{
  int i, len;

  if ( str )
    {
      len = (int) strlen(str);
      for ( i = 0; i < len; i++ )
        str[i] = tolower((int) str[i]);
    }
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
133

134
135
136
137
static
int get_timeunit(int len, char *ptu)
{
  int timeunit = -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
138

139
140
141
142
143
144
145
146
147
148
  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;
    }
149
150
151
152
  else if ( len == 1 )
    {
      if ( ptu[0] == 's' ) timeunit = TUNIT_SECOND;
    }
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178

  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 )
179
180
        {
          while ( isspace(*ptu) ) ptu++;
Deike Kleberg's avatar
Deike Kleberg committed
181

182
183
184
185
          if ( memcmp(ptu, "as", 2) == 0 )
            timetype = TAXIS_ABSOLUTE;
          else if ( memcmp(ptu, "since", 5) == 0 )
            timetype = TAXIS_RELATIVE;
186

187
188
          if ( timetype != -1 ) status = TRUE;
        }
189
190
191
192
193
194
195
196
    }

  free(tu);

  return (status);
}

static
197
int splitBasetime(const char *timeunits, taxis_t *taxis)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
198
{
199
  int len, i;
200
  char *ptu, *tu;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
201
202
203
204
  int year, month, day;
  int hour = 0, minute = 0, second = 0;
  int timetype = TAXIS_ABSOLUTE;
  int rdate = -1, rtime = -1;
205
  int timeunit;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
206

Uwe Schulzweida's avatar
Uwe Schulzweida committed
207
  len = (int) strlen(timeunits);
208
209
210
  tu = (char *) malloc((len+1)*sizeof(char));
  memcpy(tu, timeunits, (len+1)*sizeof(char));
  ptu = tu;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
211

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

214
215
  timeunit = get_timeunit(len, ptu);
  if ( timeunit == -1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
216
    {
217
      Message("Unsupported TIMEUNIT: %s!", timeunits);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
218
219
220
221
222
223
      return (1);
    }

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

226
      if ( memcmp(ptu, "as", 2) == 0 )
227
        timetype = TAXIS_ABSOLUTE;
228
      else if ( memcmp(ptu, "since", 5) == 0 )
229
        timetype = TAXIS_RELATIVE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
230
231
232

      while ( ! isspace(*ptu) && *ptu != 0 ) ptu++;
      if ( *ptu )
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
        {
          while ( isspace(*ptu) ) ptu++;

          if ( timetype == TAXIS_ABSOLUTE )
            {
              if ( memcmp(ptu, "%y%m%d.%f", 9) != 0 && timeunit == TUNIT_DAY )
                {
                  Message("Unsupported format %s for TIMEUNIT day!", ptu);
                  timeunit = -1;
                }
              else if ( memcmp(ptu, "%y%m.%f", 7) != 0 && timeunit == TUNIT_MONTH )
                {
                  Message("Unsupported format %s for TIMEUNIT month!", ptu);
                  timeunit = -1;
                }
            }
          else if ( timetype == TAXIS_RELATIVE )
            {
251
252
253
              int v1, v2, v3;
              v1 = atoi(ptu);
              if ( v1 < 0 ) ptu++;
254
              while ( isdigit((int) *ptu) ) ptu++;
255
              v2 = atoi(++ptu);
256
              while ( isdigit((int) *ptu) ) ptu++;
257
              v3 = atoi(++ptu);
258
259
              while ( isdigit((int) *ptu) ) ptu++;

260
261
262
263
264
              if ( v3 > 999 && v1 < 32 )
                { year = v3; month = v2; day = v1; }
              else
                { year = v1; month = v2; day = v3; }

265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
              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 )
                            Message("Seconds not supported in time units!");
                          */
                        }
                    }
                }

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

              if ( CDI_Debug )
Deike Kleberg's avatar
Deike Kleberg committed
296
                Message("rdate = %d  rtime = %d", rdate, rtime);
297
298
            }
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
299
300
301
302
303
    }

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

304
305
  free(tu);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
306
  if ( CDI_Debug )
307
    Message("timetype = %d  unit = %d", timetype, timeunit);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
308
309
310
311

  return (0);
}

312
313
static
void cdfGetAttInt(int fileID, int ncvarid, char *attname, int attlen, int *attint)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
314
{
315
  size_t nc_attlen;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
316
317
  int *pintatt;

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

320
321
  if ( (int)nc_attlen > attlen )
    pintatt = (int *) malloc(nc_attlen*sizeof(int));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
322
  else
323
    pintatt = attint;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
324
325
326

  cdf_get_att_int(fileID, ncvarid, attname, pintatt);

327
328
329
330
331
  if ( (int)nc_attlen > attlen )
    {
      memcpy(attint, pintatt, attlen*sizeof(int));
      free(pintatt);
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
332
333
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
334
335
static
void cdfGetAttDouble(int fileID, int ncvarid, char *attname, int attlen, double *attdouble)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
336
{
337
  size_t nc_attlen;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
338
339
  double *pdoubleatt;

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

342
343
  if ( (int)nc_attlen > attlen )
    pdoubleatt = (double *) malloc(nc_attlen*sizeof(double));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
344
  else
345
    pdoubleatt = attdouble;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
346
347
348

  cdf_get_att_double(fileID, ncvarid, attname, pdoubleatt);

349
350
351
352
353
  if ( (int)nc_attlen > attlen )
    {
      memcpy(attdouble, pdoubleatt, attlen*sizeof(double));
      free(pdoubleatt);
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
354
355
}

356
357
static
void cdfGetAttText(int fileID, int ncvarid, char *attname, int attlen, char *atttext)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
358
{
359
  size_t nc_attlen;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
360
361
  char attbuf[65636];

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

364
  if ( nc_attlen < sizeof(attbuf) )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
365
366
367
    {
      cdf_get_att_text(fileID, ncvarid, attname, attbuf);

368
      attbuf[nc_attlen++] = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
369

370
371
      if ( (int) nc_attlen > attlen ) nc_attlen = attlen;
      memcpy(atttext, attbuf, nc_attlen);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
372
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
373
374
375
376
  else
    {
      atttext[0] = 0;
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
377
378
}

379
380
381
382
383
384
385
386
static
int xtypeIsFloat(int xtype)
{
  int isFloat = FALSE;
  if ( xtype == NC_FLOAT || xtype == NC_DOUBLE ) isFloat = TRUE;
  return isFloat;
}

387
static
Deike Kleberg's avatar
Deike Kleberg committed
388
int cdfInqDatatype(int xtype, int lunsigned)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
389
{
390
  int datatype = -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
391

392
#if  defined  (HAVE_NETCDF4)
Deike Kleberg's avatar
Deike Kleberg committed
393
  if ( xtype == NC_BYTE && lunsigned ) xtype = NC_UBYTE;
394
#endif
Deike Kleberg's avatar
Deike Kleberg committed
395

Uwe Schulzweida's avatar
Uwe Schulzweida committed
396
397
398
399
  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;
400
  else if ( xtype == NC_FLOAT  )  datatype = DATATYPE_FLT32;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
401
  else if ( xtype == NC_DOUBLE )  datatype = DATATYPE_FLT64;
Deike Kleberg's avatar
Deike Kleberg committed
402
#if  defined  (HAVE_NETCDF4)
403
  else if ( xtype == NC_UBYTE  )  datatype = DATATYPE_UINT8;
404
405
406
407
408
409
  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
410
411
412
413

  return (datatype);
}

414
static
415
int cdfDefDatatype(int datatype, int filetype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
416
417
418
{
  int xtype;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
419
  if ( datatype == DATATYPE_CPX32 || datatype == DATATYPE_CPX64 )
420
421
422
423
424
425
426
    Error("CDI/netCDF library does not support complex numbers!");

  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;
Deike Kleberg's avatar
Deike Kleberg committed
427
#if  defined  (HAVE_NETCDF4)
428
429
430
431
      else if ( datatype == DATATYPE_UINT8  ) xtype = NC_UBYTE;
      else if ( datatype == DATATYPE_UINT16 ) xtype = NC_USHORT;
      else if ( datatype == DATATYPE_UINT32 ) xtype = NC_UINT;
#else
432
      else if ( datatype == DATATYPE_UINT8  ) xtype = NC_SHORT;
433
434
435
436
437
438
439
440
441
442
443
      else if ( datatype == DATATYPE_UINT16 ) xtype = NC_INT;
      else if ( datatype == DATATYPE_UINT32 ) xtype = NC_INT;
#endif
      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;
444
      else if ( datatype == DATATYPE_UINT8  ) xtype = NC_SHORT;
445
446
447
448
449
      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
450

Uwe Schulzweida's avatar
Uwe Schulzweida committed
451
452
453
  return (xtype);
}

454
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
455
456
457
void defineAttributes(int vlistID, int varID, int fileID, int ncvarID)
{
  int natts, iatt;
458
  int atttype, attlen;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
459
  size_t len;
460
  char attname[1024];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
461
462
463
464
465

  vlistInqNatts(vlistID, varID, &natts);

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

468
469
      if ( attlen == 0 ) continue;

470
      if ( atttype == DATATYPE_TXT )
471
        {
Deike Kleberg's avatar
Deike Kleberg committed
472
473
474
          char *atttxt;
          atttxt = (char *) malloc(attlen*sizeof(char));
          vlistInqAttTxt(vlistID, varID, attname, attlen, atttxt);
475
476
          len = attlen;
          cdf_put_att_text(fileID, ncvarID, attname, len, atttxt);
Deike Kleberg's avatar
Deike Kleberg committed
477
          free(atttxt);
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
        }
      else if ( atttype == DATATYPE_INT16 || atttype == DATATYPE_INT32 )
        {
          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);
        }
      else if ( atttype == DATATYPE_FLT32 || atttype == DATATYPE_FLT64 )
        {
          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
503
504
505
506
    }
}
#endif

507
int cdfCopyRecord(stream_t *streamptr2, stream_t *streamptr1)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
508
509
{
  double *data;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
510
  int datasize;
Thomas Jahns's avatar
Thomas Jahns committed
511
  int tsID1, recID1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
512
513
514
  int ivarID, gridID;
  int nmiss;
  int ierr = 0;
515
  int memtype = MEMTYPE_DOUBLE;
Thomas Jahns's avatar
Thomas Jahns committed
516
  int vlistID1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
517

Uwe Schulzweida's avatar
Uwe Schulzweida committed
518
  vlistID1 = streamptr1->vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
519

Uwe Schulzweida's avatar
Uwe Schulzweida committed
520
  tsID1 = streamptr1->curTsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
521

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
524
525
526
  ivarID = streamptr1->tsteps[tsID1].records[recID1].varID;

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

Deike Kleberg's avatar
Deike Kleberg committed
528
  datasize = gridInqSize(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
529
530
531
532
533
  /* bug fix for constant netCDF fields */
  if ( datasize < 1048576 ) datasize = 1048576;

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

534
535
  cdfReadRecord(streamptr1, data, &nmiss);
  cdf_write_record(streamptr2, memtype, data, nmiss);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
536
537
538
539
540

  free(data);

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
542
/* not used
543
int cdfInqRecord(stream_t *streamptr, int *varID, int *levelID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
544
545
546
{
  int tsID, recID;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
547
548
549
  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
550

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

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

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

  if ( CDI_Debug )
563
    Message("recID = %d  varID = %d  levelID = %d", recID, *varID, *levelID);
564

Uwe Schulzweida's avatar
Uwe Schulzweida committed
565
566
567
  return (recID+1);
}
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
568

Uwe Schulzweida's avatar
Uwe Schulzweida committed
569

570
571
572
int cdfDefRecord(stream_t *streamptr)
{
  int ierr = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
573
574
575
576

  return (ierr);
}

577
#if  defined  (HAVE_LIBNETCDF)
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
578
static
579
void cdfWriteGridTraj(stream_t *streamptr, int gridID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
580
581
582
583
584
585
{
  int tsID, fileID;
  int lonID, latID, gridindex;
  size_t index;
  double xlon, xlat;
  int vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
586

587
588
  vlistID = streamptr->vlistID;
  fileID  = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
589
590

  gridindex = vlistGridIndex(vlistID, gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
591
592
  lonID = streamptr->xdimID[gridindex];
  latID = streamptr->ydimID[gridindex];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
593
594
595

  xlon = gridInqXval(gridID, 0);
  xlat = gridInqYval(gridID, 0);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
596
  tsID = streamptr->curTsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
597
598
599
600
601
602
  index = tsID;

  cdf_put_var1_double(fileID, lonID, &index, &xlon);
  cdf_put_var1_double(fileID, latID, &index, &xlat);
}

Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
603
static
604
void cdfReadGridTraj(stream_t *streamptr, int gridID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
605
606
607
608
609
610
{
  int tsID, fileID;
  int lonID, latID, gridindex;
  size_t index;
  double xlon, xlat;
  int vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
611

612
613
  vlistID = streamptr->vlistID;
  fileID  = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
614
615

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
619
  tsID = streamptr->curTsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
620
621
622
623
624
625
626
627
  index = tsID;

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

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

630
#if  defined  (HAVE_LIBNETCDF)
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
631
static
632
633
void cdfDefVarDeflate(int ncid, int ncvarid, int deflate_level)
{
Deike Kleberg's avatar
Deike Kleberg committed
634
#if  defined  (HAVE_NETCDF4)
635
636
637
638
639
640
641
642
643
  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)))
    {
644
      Error("nc_def_var_deflate failed, status = %d", retval);
645
646
647
648
649
650
651
    }
#else
  static int lwarn = TRUE;

  if ( lwarn )
    {
      lwarn = FALSE;
652
      Warning("Deflate compression failed, netCDF4 not available!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
653
654
655
656
657
    }
#endif
}
#endif

Uwe Schulzweida's avatar
Uwe Schulzweida committed
658
#if  defined(HAVE_LIBNETCDF) && defined(NC_SZIP_NN_OPTION_MASK)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
659
660
661
662
663
static
void cdfDefVarSzip(int ncid, int ncvarid)
{
  int retval;
  /* Set options_mask and bits_per_pixel. */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
664
  int options_mask = NC_SZIP_NN_OPTION_MASK;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
665
666
667
668
669
  int bits_per_pixel = 16;

  if ((retval = nc_def_var_szip(ncid, ncvarid, options_mask, bits_per_pixel)))
    {
      if ( retval == NC_EINVAL )
670
671
672
673
674
675
676
        {
          static int lwarn = TRUE;

          if ( lwarn )
            {
              lwarn = FALSE;
              Warning("netCDF4/Szip compression not compiled in!");
Deike Kleberg's avatar
Deike Kleberg committed
677
            }
678
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
679
      else
680
        Error("nc_def_var_szip failed, status = %d", retval);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
681
    }
682
683
684
}
#endif

685
#if  defined  (HAVE_LIBNETCDF)
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
686
static
687
void cdfDefVarMissval(stream_t *streamptr, int varID, int dtype, int lcheck)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
688
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
689
  if ( streamptr->vars[varID].defmiss == FALSE )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
690
691
692
693
694
695
696
    {
      int fileID;
      int ncvarid;
      double missval;
      int vlistID;
      int xtype;

697
698
      vlistID = streamptr->vlistID;
      fileID  = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
699
      ncvarid = streamptr->vars[varID].ncvarid;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
700
      missval = vlistInqVarMissval(vlistID, varID);
701

702
      if ( lcheck && streamptr->ncmode == 2 ) cdf_redef(fileID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
703

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

706
      if ( xtype == NC_BYTE && missval > 127 && missval < 256 ) xtype = NC_INT;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
707

708
709
      cdf_put_att_double(fileID, ncvarid, "_FillValue", (nc_type) xtype, 1, &missval);
      cdf_put_att_double(fileID, ncvarid, "missing_value", (nc_type) xtype, 1, &missval);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
710

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
713
      streamptr->vars[varID].defmiss = TRUE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
714
715
    }
}
716
#endif
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
717

718
void cdf_write_record(stream_t *streamptr, int memtype, const void *data, int nmiss)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
719
720
721
722
723
{
#if  defined  (HAVE_LIBNETCDF)
  int varID;
  int levelID;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
724
725
  varID   = streamptr->record->varID;
  levelID = streamptr->record->levelID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
726

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

729
  cdf_write_var_slice(streamptr, varID, levelID, memtype, data, nmiss);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
730
731
732
#endif
}

Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
733

734
int cdfReadRecord(stream_t *streamptr, double *data, int *nmiss)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
735
736
737
738
{
  int ierr = 0;
  int levelID, varID, tsID, recID, vrecID;

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
741
742
743
744
745
  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
746

747
  cdfReadVarSliceDP(streamptr, varID, levelID, data, nmiss);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
748
749
750
751

  return (ierr);
}

752
static
753
void cdfDefTimeValue(stream_t *streamptr, int tsID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
754
755
756
757
758
759
{
#if  defined  (HAVE_LIBNETCDF)
  int fileID;
  double timevalue;
  int ncvarid;
  size_t index;
760
  taxis_t *taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
761

762
  fileID = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
763
764

  if ( CDI_Debug )
765
    Message("streamID = %d, fileID = %d", streamptr->self, fileID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
766

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
769
  if ( streamptr->ncmode == 1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
770
771
    {
      cdf_enddef(fileID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
772
      streamptr->ncmode = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
773
774
775
776
    }

  index = tsID;

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
780
  ncvarid = streamptr->basetime.ncvarid;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
781
782
783
784
785
786
  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
787
      ncvarid = streamptr->basetime.ncvarboundsid;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
788

Uwe Schulzweida's avatar
Uwe Schulzweida committed
789
      timevalue = cdiEncodeTimeval(taxis->vdate_lb, taxis->vtime_lb, &streamptr->tsteps[0].taxis);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
790
791
792
      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
793
      timevalue = cdiEncodeTimeval(taxis->vdate_ub, taxis->vtime_ub, &streamptr->tsteps[0].taxis);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
794
795
796
797
798
799
800
801
802
      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
803
static
804
void cdfDefTime(stream_t *streamptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
805
806
807
808
809
810
{
#if  defined  (HAVE_LIBNETCDF)
  int fileID;
  int time_varid;
  int time_bndsid;
  int dims[2];
811
  int year, month, day, hour, minute, second;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
812
813
  char unitstr[80];
  char calstr[80];
814
815
816
  char tmpstr[CDI_MAX_NAME];
  char default_name[] = "time";
  char *taxis_name = default_name;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
817
  size_t len;
818
  taxis_t *taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
819

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

822
  fileID = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
823

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

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

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

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

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

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

837
  streamptr->basetime.ncvarid = time_varid;
Deike Kleberg's avatar
Deike Kleberg committed
838
839
840
841

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

842
843
844
  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
845
846
847
848
  if ( taxis->has_bounds )
    {
      /* fprintf(stderr, "time has bounds\n"); */

849
850
851
      if ( nc_inq_dimid(fileID, "nb2", &dims[1]) != NC_NOERR )
	cdf_def_dim(fileID, "nb2", 2, &dims[1]);

852
853
854
      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
855

Uwe Schulzweida's avatar
Uwe Schulzweida committed
856
      streamptr->basetime.ncvarboundsid = time_bndsid;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
857

858
      cdf_put_att_text(fileID, time_varid, "bounds", strlen(tmpstr), tmpstr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
859
860
861
    }

  unitstr[0] = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
862
  if ( streamptr->tsteps[0].taxis.type == TAXIS_ABSOLUTE )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
863
    {
864
      if ( streamptr->tsteps[0].taxis.unit == TUNIT_YEAR )
865
        sprintf(unitstr, "year as %s", "%Y.%f");
866
      else if ( streamptr->tsteps[0].taxis.unit == TUNIT_MONTH )
867
        sprintf(unitstr, "month as %s", "%Y%m.%f");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
868
      else
869
        sprintf(unitstr, "day as %s", "%Y%m%d.%f");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
870
871
872
873
874
875
876
    }
  else
    {
      int rdate, rtime;
      int timeunit;

      timeunit = taxis->unit;
877
      if ( timeunit == -1 ) timeunit = TUNIT_HOUR;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
878
879
880
      rdate    = taxis->rdate;
      rtime    = taxis->rtime;
      if ( rdate == -1 )
881
882
883
884
        {
          rdate  = taxis->vdate;
          rtime  = taxis->vtime;
        }
885

Uwe Schulzweida's avatar
Uwe Schulzweida committed
886
887
      cdiDecodeDate(rdate, &year, &month, &day);
      cdiDecodeTime(rtime, &hour, &minute, &second);
888

889
      if ( timeunit == TUNIT_QUARTER ) timeunit = TUNIT_MINUTE;
890
891
892
893
      if ( timeunit == TUNIT_3HOURS  ||
	   timeunit == TUNIT_6HOURS  ||
	   timeunit == TUNIT_12HOURS ) timeunit = TUNIT_HOUR;

894
      sprintf(unitstr, "%s since %d-%02d-%02d %02d:%02d:%02d",
895
              tunitNamePtr(timeunit), year, month, day, hour, minute, second);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
896
897
898
899
900
901
902
903
904
905
906
907
908
909
    }

  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;

910
911
912
      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
913
914
915
916
917
918
      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 )
919
920
        {
          cdf_put_att_text(fileID, time_varid, "calendar", len, calstr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
921

922
923
924
          if ( taxis->has_bounds )
            cdf_put_att_text(fileID, time_bndsid, "calendar", len, calstr);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
925
926
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
927
  if ( streamptr->ncmode == 2 ) cdf_enddef(fileID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
928
929
930
931
#endif
}


932
void cdfDefTimestep(stream_t *streamptr, int tsID)
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
933
934
935
{
  int vlistID;

936
  vlistID = streamptr->vlistID;
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
937

938
  if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
939

940
  cdfDefTimeValue(streamptr, tsID);
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
941
942
}

943
#if  defined  (HAVE_LIBNETCDF)
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
944
static
945
void cdfDefComplex(stream_t *streamptr, int gridID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
946
{
947
  char axisname[] = "nc2";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
948
949
950
951
952
953
954
  int index;
  int dimID = UNDEFID;
  int gridID0, gridtype0, gridindex;
  int ngrids;
  int fileID;
  int dimlen;
  int vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
955

956
957
  vlistID = streamptr->vlistID;
  fileID  = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
958
959
960
961
962

  ngrids = vlistNgrids(vlistID);

  for ( index = 0; index < ngrids; index++ )
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
963
      if ( streamptr->xdimID[index] != UNDEFID )
964
965
966
        {
          gridID0 = vlistGrid(vlistID, index);
          gridtype0 = gridInqType(gridID0);
967
          if ( gridtype0 == GRID_SPECTRAL || gridtype0 == GRID_FOURIER )
968
969
970
971
972
            {
              dimID = streamptr->xdimID[index];
              break;
            }
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
973
974
975
976
977
978
    }

  if ( dimID == UNDEFID )
    {
      dimlen = 2;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
979
      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
980
981
982
983

      cdf_def_dim(fileID, axisname, dimlen, &dimID);

      cdf_enddef(fileID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
984
      streamptr->ncmode = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
985
986
987
    }

  gridindex = vlistGridIndex(vlistID, gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
988
  streamptr->xdimID[gridindex] = dimID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
989
}
990
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
991

992
#if  defined  (HAVE_LIBNETCDF)
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
993
static
994
void cdfDefSP(stream_t *streamptr, int gridID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
995
996
997
998
{
  /*
  char longname[] = "Spherical harmonic coefficient";
  */
999
  char axisname[5] = "nspX";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1000
1001
1002
1003
1004
1005
1006
1007
  int index, iz = 0;
  int gridID0, gridtype0, gridindex;
  int dimID = UNDEFID;
  int ngrids;
  int fileID;
  int dimlen, dimlen0;
  int vlistID;

1008
1009
  vlistID = streamptr->vlistID;
  fileID  = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1010
1011
1012
1013
1014
1015
1016

  ngrids = vlistNgrids(vlistID);

  dimlen = gridInqSize(gridID)/2;

  for ( index = 0; index < ngrids; index++ )
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1017
      if ( streamptr->ydimID[index] != UNDEFID )
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
        {
          gridID0 = vlistGrid(vlistID, index);
          gridtype0 = gridInqType(gridID0);
          if ( gridtype0 == GRID_SPECTRAL )
            {
              dimlen0 = gridInqSize(gridID0)/2;
              if ( dimlen == dimlen0 )
                {
                  dimID = streamptr->ydimID[index];
                  break;
                }
              else
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
                iz++;
            }
        }
    }

  if ( dimID == UNDEFID )
    {
      if ( iz == 0 ) axisname[3] = '\0';
      else           sprintf(&axisname[3], "%1d", iz+1);

      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);

      cdf_def_dim(fileID, axisname, dimlen, &dimID);

      cdf_enddef(fileID);
      streamptr->ncmode = 2;
    }

  gridindex = vlistGridIndex(vlistID, gridID);
  streamptr->ydimID[gridindex] = dimID;
}
#endif

#if  defined  (HAVE_LIBNETCDF)
static
1055
void cdfDefFC(stream_t *streamptr, int gridID)
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
{
  char axisname[5] = "nfcX";
  int index, iz = 0;
  int gridID0, gridtype0, gridindex;
  int dimID = UNDEFID;
  int ngrids;
  int fileID;
  int dimlen, dimlen0;
  int vlistID;

1066
1067
  vlistID = streamptr->vlistID;
  fileID  = streamptr->fileID;
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088

  ngrids = vlistNgrids(vlistID);

  dimlen = gridInqSize(gridID)/2;

  for ( index = 0; index < ngrids; index++ )
    {
      if ( streamptr->ydimID[index] != UNDEFID )
        {
          gridID0 = vlistGrid(vlistID, index);
          gridtype0 = gridInqType(gridID0);
          if ( gridtype0 == GRID_FOURIER )
            {
              dimlen0 = gridInqSize(gridID0)/2;
              if ( dimlen == dimlen0 )
                {
                  dimID = streamptr->ydimID[index];
                  break;
                }
              else
                iz++;
1089
1090
            }
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1091
1092
1093
1094
1095
1096
1097
    }

  if ( dimID == UNDEFID )
    {
      if ( iz == 0 ) axisname[3] = '\0';
      else           sprintf(&axisname[3], "%1d", iz+1);