stream_cdf.c 207 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

491
int cdfCopyRecord(stream_t *streamptr2, stream_t *streamptr1)
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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
502
  vlistID1 = streamptr1->vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
503

Uwe Schulzweida's avatar
Uwe Schulzweida committed
504
  tsID1 = streamptr1->curTsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
505

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
508
509
510
  ivarID = streamptr1->tsteps[tsID1].records[recID1].varID;

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

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

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

518
519
  cdfReadRecord(streamptr1, data, &nmiss);
  cdf_write_record(streamptr2, memtype, data, nmiss);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
520
521
522
523
524

  free(data);

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
531
532
533
  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
534

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
540
541
  *varID   = streamptr->tsteps[0].records[recID].varID;
  *levelID = streamptr->tsteps[0].records[recID].levelID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
542

Uwe Schulzweida's avatar
Uwe Schulzweida committed
543
544
  streamptr->record->varID   = *varID;
  streamptr->record->levelID = *levelID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
545
546

  if ( CDI_Debug )
547
    Message("recID = %d  varID = %d  levelID = %d", recID, *varID, *levelID);
548

Uwe Schulzweida's avatar
Uwe Schulzweida committed
549
550
551
  return (recID+1);
}
*/
552
553


Uwe Schulzweida's avatar
Uwe Schulzweida committed
554
555
556
int cdfDefRecord(int streamID)
{
  int ierr = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
557
  stream_t *streamptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
558
559

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

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

564
  stream_check_ptr(__func__, streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
565
566
567
568

  return (ierr);
}

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
579
580
  vlistID = streamptr->vlistID;
  fileID  = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
581
582

  gridindex = vlistGridIndex(vlistID, gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
583
584
  lonID = streamptr->xdimID[gridindex];
  latID = streamptr->ydimID[gridindex];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
585
586
587

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
604
605
  vlistID = streamptr->vlistID;
  fileID  = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
606
607

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
611
  tsID = streamptr->curTsID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
612
613
614
615
616
617
618
619
  index = tsID;

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

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

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

  if ( lwarn )
    {
      lwarn = FALSE;
644
      Warning("Deflate compression failed, netCDF4 not available!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
645
646
647
648
649
    }
#endif
}
#endif

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

  if ((retval = nc_def_var_szip(ncid, ncvarid, options_mask, bits_per_pixel)))
    {
      if ( retval == NC_EINVAL )
662
663
664
665
666
667
        {
          static int lwarn = TRUE;

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
689
690
      vlistID = streamptr->vlistID;
      fileID  = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
691
      ncvarid = streamptr->vars[varID].ncvarid;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
692
      missval = vlistInqVarMissval(vlistID, varID);
693
      if ( lcheck && streamptr->ncmode == 2 ) cdf_redef(fileID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
694

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

697
      cdf_put_att_double(fileID, ncvarid, "_FillValue", (nc_type) xtype, 1, &missval);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
698
699

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
704
      streamptr->vars[varID].defmiss = TRUE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
705
706
    }
}
707
#endif
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
708

709
void cdf_write_record(stream_t *streamptr, int memtype, const void *data, int nmiss)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
710
711
712
713
714
{
#if  defined  (HAVE_LIBNETCDF)
  int varID;
  int levelID;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
715
716
  varID   = streamptr->record->varID;
  levelID = streamptr->record->levelID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
717

718
  if ( CDI_Debug ) Message("streamptr = %p  varID = %d", streamptr, varID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
719

720
  cdf_write_var_slice(streamptr, varID, levelID, memtype, data, nmiss);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
721
722
723
#endif
}

Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
724

725
int cdfReadRecord(stream_t *streamptr, double *data, int *nmiss)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
726
727
728
729
{
  int ierr = 0;
  int levelID, varID, tsID, recID, vrecID;

730
  if ( CDI_Debug ) Message("streamptr = %p", streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
731

Uwe Schulzweida's avatar
Uwe Schulzweida committed
732
733
734
735
736
  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
737

738
  cdfReadVarSliceDP(streamptr, varID, levelID, data, nmiss);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
739
740
741
742

  return (ierr);
}

743
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
744
void cdfDefTimeValue(stream_t *streamptr, int tsID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
745
746
747
748
749
750
{
#if  defined  (HAVE_LIBNETCDF)
  int fileID;
  double timevalue;
  int ncvarid;
  size_t index;
751
  taxis_t *taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
752

Uwe Schulzweida's avatar
Uwe Schulzweida committed
753
  fileID = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
754
755

  if ( CDI_Debug )
756
    Message("streamptr = %p, fileID = %d", streamptr, fileID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
757

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
760
  if ( streamptr->ncmode == 1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
761
762
    {
      cdf_enddef(fileID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
763
      streamptr->ncmode = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
764
765
766
767
    }

  index = tsID;

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
771
  ncvarid = streamptr->basetime.ncvarid;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
772
773
774
775
776
777
  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
778
      ncvarid = streamptr->basetime.ncvarboundsid;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
779

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
813
  fileID = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
814

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

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

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

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

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

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

828
  streamptr->basetime.ncvarid = time_varid;
829
830
831
832

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

833
834
835
  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
836
837
838
839
  if ( taxis->has_bounds )
    {
      /* fprintf(stderr, "time has bounds\n"); */

840
841
842
      if ( nc_inq_dimid(fileID, "nb2", &dims[1]) != NC_NOERR )
	cdf_def_dim(fileID, "nb2", 2, &dims[1]);

843
844
845
      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
846

Uwe Schulzweida's avatar
Uwe Schulzweida committed
847
      streamptr->basetime.ncvarboundsid = time_bndsid;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
848

849
      cdf_put_att_text(fileID, time_varid, "bounds", strlen(tmpstr), tmpstr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
850
851
852
    }

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

      timeunit = taxis->unit;
868
      if ( timeunit == -1 ) timeunit = TUNIT_HOUR;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
869
870
871
      rdate    = taxis->rdate;
      rtime    = taxis->rtime;
      if ( rdate == -1 )
872
873
874
875
        {
          rdate  = taxis->vdate;
          rtime  = taxis->vtime;
        }
876

Uwe Schulzweida's avatar
Uwe Schulzweida committed
877
878
      cdiDecodeDate(rdate, &year, &month, &day);
      cdiDecodeTime(rtime, &hour, &minute, &second);
879

880
      if ( timeunit == TUNIT_QUARTER ) timeunit = TUNIT_MINUTE;
881
882
883
884
      if ( timeunit == TUNIT_3HOURS  ||
	   timeunit == TUNIT_6HOURS  ||
	   timeunit == TUNIT_12HOURS ) timeunit = TUNIT_HOUR;

885
      sprintf(unitstr, "%s since %d-%02d-%02d %02d:%02d:%02d",
886
              tunitNamePtr(timeunit), year, month, day, hour, minute, second);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
887
888
889
890
891
892
893
894
895
896
897
898
899
900
    }

  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;

901
902
903
      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
904
905
906
907
908
909
      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 )
910
911
        {
          cdf_put_att_text(fileID, time_varid, "calendar", len, calstr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
912

913
914
915
          if ( taxis->has_bounds )
            cdf_put_att_text(fileID, time_bndsid, "calendar", len, calstr);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
916
917
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
918
  if ( streamptr->ncmode == 2 ) cdf_enddef(fileID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
919
920
921
922
#endif
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
923
void cdfDefTimestep(stream_t *streamptr, int tsID)
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
924
925
926
{
  int vlistID;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
927
  vlistID = streamptr->vlistID;
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
928

Uwe Schulzweida's avatar
Uwe Schulzweida committed
929
  if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
930

Uwe Schulzweida's avatar
Uwe Schulzweida committed
931
  cdfDefTimeValue(streamptr, tsID);
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
932
933
}

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
947
948
  vlistID = streamptr->vlistID;
  fileID  = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
949
950
951
952
953

  ngrids = vlistNgrids(vlistID);

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
970
      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
971
972
973
974

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

      cdf_enddef(fileID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
975
      streamptr->ncmode = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
976
977
978
    }

  gridindex = vlistGridIndex(vlistID, gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
979
  streamptr->xdimID[gridindex] = dimID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
980
}
981
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
982

983
#if  defined  (HAVE_LIBNETCDF)
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
984
static
985
void cdfDefSP(stream_t *streamptr, int gridID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
986
987
988
989
{
  /*
  char longname[] = "Spherical harmonic coefficient";
  */
990
  char axisname[5] = "nspX";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
991
992
993
994
995
996
997
998
  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
999
1000
  vlistID = streamptr->vlistID;
  fileID  = streamptr->fileID;
For faster browsing, not all history is shown. View entire blame