stream_cdf.c 214 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
#include "stream_int.h"
#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
45
46
47
48


#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;
49
  char    name[CDI_MAX_NAME];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
50
}
51
ncdim_t;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
52
53

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

113
#ifdef HAVE_LIBNETCDF
114
115
116
117
118
119
120
121
122
123
124
125
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
126

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

132
133
134
135
136
137
138
139
140
141
  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;
    }
142
143
144
145
  else if ( len == 1 )
    {
      if ( ptu[0] == 's' ) timeunit = TUNIT_SECOND;
    }
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
171

  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 )
172
173
        {
          while ( isspace(*ptu) ) ptu++;
Deike Kleberg's avatar
Deike Kleberg committed
174

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

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

  free(tu);

  return (status);
}

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

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

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

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

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

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

      while ( ! isspace(*ptu) && *ptu != 0 ) ptu++;
      if ( *ptu )
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
        {
          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 )
            {
244
245
246
              int v1, v2, v3;
              v1 = atoi(ptu);
              if ( v1 < 0 ) ptu++;
247
              while ( isdigit((int) *ptu) ) ptu++;
248
              v2 = atoi(++ptu);
249
              while ( isdigit((int) *ptu) ) ptu++;
250
              v3 = atoi(++ptu);
251
252
              while ( isdigit((int) *ptu) ) ptu++;

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

258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
              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
289
                Message("rdate = %d  rtime = %d", rdate, rtime);
290
291
            }
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
292
293
294
295
296
    }

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

297
298
  free(tu);

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

  return (0);
}

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

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

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

  cdf_get_att_int(fileID, ncvarid, attname, pintatt);

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

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

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

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

  cdf_get_att_double(fileID, ncvarid, attname, pdoubleatt);

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

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

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

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

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

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

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

377
#if  defined  (HAVE_NETCDF4)
Deike Kleberg's avatar
Deike Kleberg committed
378
  if ( xtype == NC_BYTE && lunsigned ) xtype = NC_UBYTE;
379
#endif
Deike Kleberg's avatar
Deike Kleberg committed
380

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

  return (datatype);
}

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
404
  if ( datatype == DATATYPE_CPX32 || datatype == DATATYPE_CPX64 )
405
406
407
408
409
410
411
    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
412
#if  defined  (HAVE_NETCDF4)
413
414
415
416
      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
417
      else if ( datatype == DATATYPE_UINT8  ) xtype = NC_SHORT;
418
419
420
421
422
423
424
425
426
427
428
      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;
429
      else if ( datatype == DATATYPE_UINT8  ) xtype = NC_SHORT;
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

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

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

  vlistInqNatts(vlistID, varID, &natts);

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

453
454
      if ( attlen == 0 ) continue;

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

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

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

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

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

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

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

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

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

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

  free(data);

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

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

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

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

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

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

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
554

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

  return (ierr);
}

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

572
573
  vlistID = streamptr->vlistID;
  fileID  = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
574
575

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

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

597
598
  vlistID = streamptr->vlistID;
  fileID  = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
599
600

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

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

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

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

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

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

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

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

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

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

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

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

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

Deike Kleberg's avatar
Deike Kleberg committed
691
      cdf_put_att_double(fileID, ncvarid, "_FillValue", (nc_type) xtype, 1, &missval);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
692
693

      if ( cdiNcMissingValue == 1 )
Deike Kleberg's avatar
Deike Kleberg committed
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
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

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
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
800
801
  char tmpstr[CDI_MAX_NAME];
  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

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;
Deike Kleberg's avatar
Deike Kleberg committed
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
}


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

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

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

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
  int index;
  int dimID = UNDEFID;
  int gridID0, gridtype0, gridindex;
  int ngrids;
  int fileID;
  int dimlen;
  int vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
940

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;

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