stream_cdf.c 213 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
24
25
26
27
28
#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
#undef  UNDEFID
#define UNDEFID  CDI_UNDEFID


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


#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
  int      cellarea;
  int      calendar;
  int      tableID;
  int      truncation;
83
84
  int      defmissval;
  int      deffillval;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
85
86
87
88
89
90
  int      xtype;
  int      ndims;
  int      gmapid;
  int      positive;
  int      dimids[8];
  int      dimtype[8];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
91
92
93
  int      chunks[8];
  int      chunked;
  int      chunktype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
94
95
  int      natts;
  int     *atts;
96
  int      deflate;
97
98
  int      lunsigned;
  int      lvalidrange;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
99
100
101
  size_t   vlen;
  double  *vdata;
  double   missval;
102
  double   fillval;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
103
104
  double   addoffset;
  double   scalefactor;
105
  double   validrange[2];
106
107
108
109
  char     name[CDI_MAX_NAME];
  char     longname[CDI_MAX_NAME];
  char     stdname[CDI_MAX_NAME];
  char     units[CDI_MAX_NAME];
110
  char     extra[CDI_MAX_NAME];
111
  ensinfo_t   *ensdata;    /* Ensemble information */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
112
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
113
ncvar_t;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
114

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

  if ( str )
    {
      len = (int) strlen(str);
      for ( i = 0; i < len; i++ )
125
        str[i] = tolower((int) str[i]);
126
127
128
    }
}

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

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

  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 )
174
175
        {
          while ( isspace(*ptu) ) ptu++;
176

177
178
179
180
181
182
183
          if ( memcmp(ptu, "as", 2) == 0 )
            timetype = TAXIS_ABSOLUTE;
          else if ( memcmp(ptu, "since", 5) == 0 )
            timetype = TAXIS_RELATIVE;

          if ( timetype != -1 ) status = TRUE;
        }
184
185
186
187
188
189
190
191
    }

  free(tu);

  return (status);
}

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

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

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

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

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

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

      while ( ! isspace(*ptu) && *ptu != 0 ) ptu++;
      if ( *ptu )
228
229
230
231
232
233
234
        {
          while ( isspace(*ptu) ) ptu++;

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

255
256
257
258
259
              if ( v3 > 999 && v1 < 32 )
                { year = v3; month = v2; day = v1; }
              else
                { year = v1; month = v2; day = v3; }

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

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

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

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

299
300
  free(tu);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
301
  if ( CDI_Debug )
302
    Message("timetype = %d  unit = %d", timetype, timeunit);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
303
304
305
306

  return (0);
}

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

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

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

  cdf_get_att_int(fileID, ncvarid, attname, pintatt);

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

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

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

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

  cdf_get_att_double(fileID, ncvarid, attname, pdoubleatt);

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

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

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

359
  if ( nc_attlen < sizeof(attbuf) )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
360
361
362
    {
      cdf_get_att_text(fileID, ncvarid, attname, attbuf);

363
      attbuf[nc_attlen++] = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
364

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

374
static
375
int cdfInqDatatype(int xtype, int lunsigned)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
376
{
377
  int datatype = -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
378

379
#if  defined  (HAVE_NETCDF4)
380
  if ( xtype == NC_BYTE && lunsigned ) xtype = NC_UBYTE;
381
#endif
382

Uwe Schulzweida's avatar
Uwe Schulzweida committed
383
384
385
386
  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;
387
  else if ( xtype == NC_FLOAT  )  datatype = DATATYPE_FLT32;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
388
  else if ( xtype == NC_DOUBLE )  datatype = DATATYPE_FLT64;
389
#if  defined  (HAVE_NETCDF4)
390
  else if ( xtype == NC_UBYTE  )  datatype = DATATYPE_UINT8;
391
392
393
394
395
396
  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
397
398
399
400

  return (datatype);
}

401
static
402
int cdfDefDatatype(int datatype, int filetype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
403
404
405
{
  int xtype;

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

409
410
411
412
413
  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;
414
#if  defined  (HAVE_NETCDF4)
415
416
417
      else if ( datatype == DATATYPE_UINT8  ) xtype = NC_UBYTE;
      else if ( datatype == DATATYPE_UINT16 ) xtype = NC_USHORT;
      else if ( datatype == DATATYPE_UINT32 ) xtype = NC_UINT;
418
#else
419
      else if ( datatype == DATATYPE_UINT8  ) xtype = NC_SHORT;
420
421
      else if ( datatype == DATATYPE_UINT16 ) xtype = NC_INT;
      else if ( datatype == DATATYPE_UINT32 ) xtype = NC_INT;
422
#endif
423
424
425
426
427
428
429
430
      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;
431
      else if ( datatype == DATATYPE_UINT8  ) xtype = NC_SHORT;
432
433
434
435
436
437
      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
438
439
440
  return (xtype);
}

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

  vlistInqNatts(vlistID, varID, &natts);

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

455
456
      if ( attlen == 0 ) continue;

457
      if ( atttype == DATATYPE_TXT )
458
        {
459
460
461
          char *atttxt;
          atttxt = (char *) malloc(attlen*sizeof(char));
          vlistInqAttTxt(vlistID, varID, attname, attlen, atttxt);
462
463
          len = attlen;
          cdf_put_att_text(fileID, ncvarID, attname, len, atttxt);
464
          free(atttxt);
465
        }
466
      else if ( atttype == DATATYPE_INT16 || atttype == DATATYPE_INT32 )
467
468
469
470
471
472
473
474
475
476
477
        {
          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);
        }
478
      else if ( atttype == DATATYPE_FLT32 || atttype == DATATYPE_FLT64 )
479
480
481
482
483
484
485
486
487
488
489
        {
          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
490
491
492
493
    }
}
#endif

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
505
  vlistID1 = streamptr1->vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
506

Uwe Schulzweida's avatar
Uwe Schulzweida committed
507
  tsID1 = streamptr1->curTsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
508

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
511
512
513
  ivarID = streamptr1->tsteps[tsID1].records[recID1].varID;

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

515
  datasize = gridInqSize(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
516
517
518
519
520
  /* bug fix for constant netCDF fields */
  if ( datasize < 1048576 ) datasize = 1048576;

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

521
522
  cdfReadRecord(streamptr1, data, &nmiss);
  cdf_write_record(streamptr2, memtype, data, nmiss);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
523
524
525
526
527

  free(data);

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
529
/* not used
530
int cdfInqRecord(stream_t *streamptr, int *varID, int *levelID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
531
532
533
{
  int tsID, recID;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
534
535
536
  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
537

538
  if ( streamptr->tsteps[0].curRecID >= streamptr->tsteps[0].nrecs )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
539
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
540
      streamptr->tsteps[0].curRecID = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
541
542
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
543
544
  *varID   = streamptr->tsteps[0].records[recID].varID;
  *levelID = streamptr->tsteps[0].records[recID].levelID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
545

Uwe Schulzweida's avatar
Uwe Schulzweida committed
546
547
  streamptr->record->varID   = *varID;
  streamptr->record->levelID = *levelID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
548
549

  if ( CDI_Debug )
550
    Message("recID = %d  varID = %d  levelID = %d", recID, *varID, *levelID);
551

Uwe Schulzweida's avatar
Uwe Schulzweida committed
552
553
554
  return (recID+1);
}
*/
555
556


557
int cdfDefRecord(stream_t *streamptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
558
559
560
561
562
563
{
  int ierr = 0;

  return (ierr);
}

564
#if  defined  (HAVE_LIBNETCDF)
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
565
static
566
void cdfWriteGridTraj(stream_t *streamptr, int gridID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
567
568
569
570
571
572
573
{
  int tsID, fileID;
  int lonID, latID, gridindex;
  size_t index;
  double xlon, xlat;
  int vlistID;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
574
575
  vlistID = streamptr->vlistID;
  fileID  = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
576
577

  gridindex = vlistGridIndex(vlistID, gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
578
579
  lonID = streamptr->xdimID[gridindex];
  latID = streamptr->ydimID[gridindex];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
580
581
582

  xlon = gridInqXval(gridID, 0);
  xlat = gridInqYval(gridID, 0);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
583
  tsID = streamptr->curTsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
584
585
586
587
588
589
  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
590
static
591
void cdfReadGridTraj(stream_t *streamptr, int gridID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
592
593
594
595
596
597
598
{
  int tsID, fileID;
  int lonID, latID, gridindex;
  size_t index;
  double xlon, xlat;
  int vlistID;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
599
600
  vlistID = streamptr->vlistID;
  fileID  = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
601
602

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
606
  tsID = streamptr->curTsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
607
608
609
610
611
612
613
614
  index = tsID;

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

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

617
#if  defined  (HAVE_LIBNETCDF)
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
618
static
619
620
void cdfDefVarDeflate(int ncid, int ncvarid, int deflate_level)
{
621
#if  defined  (HAVE_NETCDF4)
622
623
624
625
626
627
628
629
630
  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)))
    {
631
      Error("nc_def_var_deflate failed, status = %d", retval);
632
633
634
635
636
637
638
    }
#else
  static int lwarn = TRUE;

  if ( lwarn )
    {
      lwarn = FALSE;
639
      Warning("Deflate compression failed, netCDF4 not available!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
640
641
642
643
644
    }
#endif
}
#endif

645
#if  defined(HAVE_LIBNETCDF) && defined(NC_SZIP_NN_OPTION_MASK)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
646
647
648
649
650
static
void cdfDefVarSzip(int ncid, int ncvarid)
{
  int retval;
  /* Set options_mask and bits_per_pixel. */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
651
  int options_mask = NC_SZIP_NN_OPTION_MASK;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
652
653
654
655
656
  int bits_per_pixel = 16;

  if ((retval = nc_def_var_szip(ncid, ncvarid, options_mask, bits_per_pixel)))
    {
      if ( retval == NC_EINVAL )
657
658
659
660
661
662
        {
          static int lwarn = TRUE;

          if ( lwarn )
            {
              lwarn = FALSE;
663
              Warning("netCDF4/Szip compression not compiled in!");
664
            }
665
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
666
      else
667
        Error("nc_def_var_szip failed, status = %d", retval);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
668
    }
669
670
671
}
#endif

672
#if  defined  (HAVE_LIBNETCDF)
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
673
static
674
void cdfDefVarMissval(stream_t *streamptr, int varID, int dtype, int lcheck)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
675
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
676
  if ( streamptr->vars[varID].defmiss == FALSE )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
677
678
679
680
681
682
683
    {
      int fileID;
      int ncvarid;
      double missval;
      int vlistID;
      int xtype;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
684
685
      vlistID = streamptr->vlistID;
      fileID  = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
686
      ncvarid = streamptr->vars[varID].ncvarid;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
687
      missval = vlistInqVarMissval(vlistID, varID);
688

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

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

693
      cdf_put_att_double(fileID, ncvarid, "_FillValue", (nc_type) xtype, 1, &missval);
694
      cdf_put_att_double(fileID, ncvarid, "missing_value", (nc_type) xtype, 1, &missval);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
695

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
698
      streamptr->vars[varID].defmiss = TRUE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
699
700
    }
}
701
#endif
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
702

703
void cdf_write_record(stream_t *streamptr, int memtype, const void *data, int nmiss)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
704
705
706
707
708
{
#if  defined  (HAVE_LIBNETCDF)
  int varID;
  int levelID;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
709
710
  varID   = streamptr->record->varID;
  levelID = streamptr->record->levelID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
711

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

714
  cdf_write_var_slice(streamptr, varID, levelID, memtype, data, nmiss);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
715
716
717
#endif
}

Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
718

719
int cdfReadRecord(stream_t *streamptr, double *data, int *nmiss)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
720
721
722
723
{
  int ierr = 0;
  int levelID, varID, tsID, recID, vrecID;

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
726
727
728
729
730
  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
731

732
  cdfReadVarSliceDP(streamptr, varID, levelID, data, nmiss);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
733
734
735
736

  return (ierr);
}

737
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
738
void cdfDefTimeValue(stream_t *streamptr, int tsID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
739
740
741
742
743
744
{
#if  defined  (HAVE_LIBNETCDF)
  int fileID;
  double timevalue;
  int ncvarid;
  size_t index;
745
  taxis_t *taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
746

Uwe Schulzweida's avatar
Uwe Schulzweida committed
747
  fileID = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
748
749

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
754
  if ( streamptr->ncmode == 1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
755
756
    {
      cdf_enddef(fileID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
757
      streamptr->ncmode = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
758
759
760
761
    }

  index = tsID;

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
765
  ncvarid = streamptr->basetime.ncvarid;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
766
767
768
769
770
771
  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
772
      ncvarid = streamptr->basetime.ncvarboundsid;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
773

Uwe Schulzweida's avatar
Uwe Schulzweida committed
774
      timevalue = cdiEncodeTimeval(taxis->vdate_lb, taxis->vtime_lb, &streamptr->tsteps[0].taxis);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
775
776
777
      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
778
      timevalue = cdiEncodeTimeval(taxis->vdate_ub, taxis->vtime_ub, &streamptr->tsteps[0].taxis);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
779
780
781
782
783
784
785
786
787
      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
788
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
789
void cdfDefTime(stream_t *streamptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
790
791
792
793
794
795
{
#if  defined  (HAVE_LIBNETCDF)
  int fileID;
  int time_varid;
  int time_bndsid;
  int dims[2];
796
  int year, month, day, hour, minute, second;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
797
798
  char unitstr[80];
  char calstr[80];
799
  char tmpstr[CDI_MAX_NAME];
800
801
  char default_name[] = "time";
  char *taxis_name = default_name;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
802
  size_t len;
803
  taxis_t *taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
804

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
807
  fileID = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
808

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

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

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

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

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

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

822
  streamptr->basetime.ncvarid = time_varid;
823
824
825
826

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

827
828
829
  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
830
831
832
833
  if ( taxis->has_bounds )
    {
      /* fprintf(stderr, "time has bounds\n"); */

834
835
836
      if ( nc_inq_dimid(fileID, "nb2", &dims[1]) != NC_NOERR )
	cdf_def_dim(fileID, "nb2", 2, &dims[1]);

837
838
839
      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
840

Uwe Schulzweida's avatar
Uwe Schulzweida committed
841
      streamptr->basetime.ncvarboundsid = time_bndsid;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
842

843
      cdf_put_att_text(fileID, time_varid, "bounds", strlen(tmpstr), tmpstr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
844
845
846
    }

  unitstr[0] = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
847
  if ( streamptr->tsteps[0].taxis.type == TAXIS_ABSOLUTE )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
848
    {
849
      if ( streamptr->tsteps[0].taxis.unit == TUNIT_YEAR )
850
        sprintf(unitstr, "year as %s", "%Y.%f");
851
      else if ( streamptr->tsteps[0].taxis.unit == TUNIT_MONTH )
852
        sprintf(unitstr, "month as %s", "%Y%m.%f");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
853
      else
854
        sprintf(unitstr, "day as %s", "%Y%m%d.%f");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
855
856
857
858
859
860
861
    }
  else
    {
      int rdate, rtime;
      int timeunit;

      timeunit = taxis->unit;
862
      if ( timeunit == -1 ) timeunit = TUNIT_HOUR;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
863
864
865
      rdate    = taxis->rdate;
      rtime    = taxis->rtime;
      if ( rdate == -1 )
866
867
868
869
        {
          rdate  = taxis->vdate;
          rtime  = taxis->vtime;
        }
870

Uwe Schulzweida's avatar
Uwe Schulzweida committed
871
872
      cdiDecodeDate(rdate, &year, &month, &day);
      cdiDecodeTime(rtime, &hour, &minute, &second);
873

874
      if ( timeunit == TUNIT_QUARTER ) timeunit = TUNIT_MINUTE;
875
876
877
878
      if ( timeunit == TUNIT_3HOURS  ||
	   timeunit == TUNIT_6HOURS  ||
	   timeunit == TUNIT_12HOURS ) timeunit = TUNIT_HOUR;

879
      sprintf(unitstr, "%s since %d-%02d-%02d %02d:%02d:%02d",
880
              tunitNamePtr(timeunit), year, month, day, hour, minute, second);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
881
882
883
884
885
886
887
888
889
890
891
892
893
894
    }

  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;

895
896
897
      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
898
899
900
901
902
903
      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 )
904
905
        {
          cdf_put_att_text(fileID, time_varid, "calendar", len, calstr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
906

907
908
909
          if ( taxis->has_bounds )
            cdf_put_att_text(fileID, time_bndsid, "calendar", len, calstr);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
910
911
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
912
  if ( streamptr->ncmode == 2 ) cdf_enddef(fileID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
913
914
915
916
#endif
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
917
void cdfDefTimestep(stream_t *streamptr, int tsID)
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
918
919
920
{
  int vlistID;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
921
  vlistID = streamptr->vlistID;
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
922

Uwe Schulzweida's avatar
Uwe Schulzweida committed
923
  if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
924

Uwe Schulzweida's avatar
Uwe Schulzweida committed
925
  cdfDefTimeValue(streamptr, tsID);
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
926
927
}

928
#if  defined  (HAVE_LIBNETCDF)
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
929
static
930
void cdfDefComplex(stream_t *streamptr, int gridID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
931
{
932
  char axisname[] = "nc2";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
933
934
935
936
937
938
939
940
  int index;
  int dimID = UNDEFID;
  int gridID0, gridtype0, gridindex;
  int ngrids;
  int fileID;
  int dimlen;
  int vlistID;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
941
942
  vlistID = streamptr->vlistID;
  fileID  = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
943
944
945
946
947

  ngrids = vlistNgrids(vlistID);

  for ( index = 0; index < ngrids; index++ )
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
948
      if ( streamptr->xdimID[index] != UNDEFID )
949
950
951
        {
          gridID0 = vlistGrid(vlistID, index);
          gridtype0 = gridInqType(gridID0);
952
          if ( gridtype0 == GRID_SPECTRAL || gridtype0 == GRID_FOURIER )
953
954
955
956
957
            {
              dimID = streamptr->xdimID[index];
              break;
            }
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
958
959
960
961
962
963
    }

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
964
      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
965
966
967
968

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

      cdf_enddef(fileID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
969
      streamptr->ncmode = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
970
971
972
    }

  gridindex = vlistGridIndex(vlistID, gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
973
  streamptr->xdimID[gridindex] = dimID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
974
}
975
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
976

977
#if  defined  (HAVE_LIBNETCDF)
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
978
static
979
void cdfDefSP(stream_t *streamptr, int gridID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
980
981
982
983
{
  /*
  char longname[] = "Spherical harmonic coefficient";
  */
984
  char axisname[5] = "nspX";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
985
986
987
988
989
990
991
992
  int index, iz = 0;
  int gridID0, gridtype0, gridindex;
  int dimID = UNDEFID;
  int ngrids;
  int fileID;
  int dimlen, dimlen0;
  int vlistID;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
993
994
  vlistID = streamptr->vlistID;
  fileID  = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
995
996
997
998
999
1000

  ngrids = vlistNgrids(vlistID);

  dimlen = gridInqSize(gridID)/2;

  for ( index = 0; index < ngrids; index++ )
For faster browsing, not all history is shown. View entire blame