cdi.c 29.3 KB
Newer Older
1
2
3
4
#if defined (HAVE_CONFIG_H)
#  include "../src/config.h"
#endif

5
#include <inttypes.h>
Uwe Schulzweida's avatar
Uwe Schulzweida committed
6
7
8
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
Uwe Schulzweida's avatar
Uwe Schulzweida committed
9
#include <stdbool.h>
Uwe Schulzweida's avatar
Uwe Schulzweida committed
10
11
12
#include <string.h>
#include <ctype.h>
#include <unistd.h>
Uwe Schulzweida's avatar
Uwe Schulzweida committed
13
#include <math.h>
Uwe Schulzweida's avatar
Uwe Schulzweida committed
14

15
#include <cdi.h>
16
17
#include <cdi_uuid.h>

Uwe Schulzweida's avatar
Uwe Schulzweida committed
18
int      vlistInqVarMissvalUsed(int vlistID, int varID);
19
#ifndef DBL_IS_NAN
20
#if  defined  (HAVE_DECL_ISNAN)
21
#  define DBL_IS_NAN(x)     (isnan(x))
22
#elif  defined  (FP_NAN)
23
#  define DBL_IS_NAN(x)     (fpclassify(x) == FP_NAN)
24
#else
25
#  define DBL_IS_NAN(x)     ((x) != (x))
Uwe Schulzweida's avatar
Uwe Schulzweida committed
26
#endif
27
28
#endif

29
30
31
32
33
#ifndef DBL_IS_EQUAL
/*#define DBL_IS_EQUAL(x,y) (!(x < y || y < x)) */
#  define DBL_IS_EQUAL(x,y) (DBL_IS_NAN(x)||DBL_IS_NAN(y)?(DBL_IS_NAN(x)&&DBL_IS_NAN(y)?1:0):!(x < y || y < x))
#endif

Thomas Jahns's avatar
Thomas Jahns committed
34
#ifndef IS_NOT_EQUAL
35
36
37
#  define IS_NOT_EQUAL(x,y) (x < y || y < x)
#endif

38
39
40
41
42
43
44
45
#ifndef HOST_ENDIANNESS
#ifdef __cplusplus
static const uint32_t HOST_ENDIANNESS_temp[1] = { UINT32_C(0x00030201) };
#define HOST_ENDIANNESS (((const unsigned char *)HOST_ENDIANNESS_temp)[0])
#else
#define HOST_ENDIANNESS (((const unsigned char *)&(const uint32_t[1]){UINT32_C(0x00030201)})[0])
#endif
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
46

Uwe Schulzweida's avatar
Uwe Schulzweida committed
47
48
#include "printinfo.h"

49
50
51
#ifdef __cplusplus
extern "C" {
#endif
52
void cdiDefTableID(int tableID);
53
54
55
#if defined (__cplusplus)
}
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
56

Uwe Schulzweida's avatar
Uwe Schulzweida committed
57
58
59
60
61
62
int getopt(int argc, char *const argv[], const char *optstring);

extern char *optarg;
extern int optind, opterr, optopt;


63
static char *Progname;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
64

65
66
67
static int DefaultFileType  = CDI_UNDEFID;
static int DefaultDataType  = CDI_UNDEFID;
static int DefaultByteorder = CDI_UNDEFID;
68

69
static int comptype  = CDI_COMPRESS_NONE;  // Compression type
70
static int complevel = 0;              // Compression level
Uwe Schulzweida's avatar
Uwe Schulzweida committed
71

Uwe Schulzweida's avatar
Uwe Schulzweida committed
72
73
enum datamode {SP_MODE, DP_MODE};
static int datamode = DP_MODE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
74

Uwe Schulzweida's avatar
Uwe Schulzweida committed
75
76
static
void version(void)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
77
{
78
  int   filetypes[] = {CDI_FILETYPE_SRV, CDI_FILETYPE_EXT, CDI_FILETYPE_IEG, CDI_FILETYPE_GRB, CDI_FILETYPE_GRB2, CDI_FILETYPE_NC, CDI_FILETYPE_NC2, CDI_FILETYPE_NC4, CDI_FILETYPE_NC4C};
79
   const char *typenames[] = {        "srv",        "ext",        "ieg",        "grb",        "grb2",        "nc",        "nc2",        "nc4",        "nc4c"};
80

81
  fprintf(stderr, "CDI version 1.8\n");
82
83
84
85
86
87
#if defined (COMPILER)
  fprintf(stderr, "Compiler: %s\n", COMPILER);
#endif
#if defined (COMP_VERSION)
  fprintf(stderr, " version: %s\n", COMP_VERSION);
#endif
88
89
90
91
92
93
94
95
96
97
#if defined (USER_NAME) && defined(HOST_NAME) && defined(SYSTEM_TYPE)
  fprintf(stderr, "Compiled: by %s on %s (%s) %s %s\n",
	  USER_NAME, HOST_NAME, SYSTEM_TYPE, __DATE__, __TIME__);
#endif

  fprintf(stderr, "filetype: ");
  for ( size_t i = 0; i < sizeof(filetypes)/sizeof(int); ++i )
    if ( cdiHaveFiletype(filetypes[i]) ) fprintf(stderr, "%s ", typenames[i]);
  fprintf(stderr, "\n");

98
99
100
101
102
103
104
  fprintf(stderr, "    with:");
#if defined (HAVE_LIBPTHREAD)
  fprintf(stderr, " PTHREADS");
#endif
#if defined (_OPENMP)
  fprintf(stderr, " OpenMP");
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
105
#if  defined(HAVE_NETCDF4)
106
  fprintf(stderr, " NC4");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
107
108
109
110
111
112
#if  defined(HAVE_NC4HDF5)
  fprintf(stderr, "/HDF5");
#if  defined(HAVE_NC4HDF5_THREADSAFE)
  fprintf(stderr, "/threadsafe");
#endif
#endif
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#endif
#if  defined  (HAVE_LIBNC_DAP)
  fprintf(stderr, " OPeNDAP");
#endif
#if defined (HAVE_LIBSZ)
  fprintf(stderr, " SZ");
#endif
#if defined (HAVE_LIBJASPER)
  fprintf(stderr, " JASPER");
#endif
#if defined (HAVE_LIBPROJ)
  fprintf(stderr, " PROJ.4");
#endif
#if defined (HAVE_LIBDRMAA)
  fprintf(stderr, " DRMAA");
#endif
#if defined (HAVE_LIBCURL)
  fprintf(stderr, " CURL");
#endif
  fprintf(stderr, "\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
133
134
135
136
137
138
139
140
141
142
143
144
  cdiPrintVersion();
  fprintf(stderr, "\n");
/*
  1.0.0   6 Feb 2001 : initial version
  1.1.0  30 Jul 2003 : missing values implemented
  1.2.0   8 Aug 2003 : changes for CDI library version 0.7.0
  1.3.0  10 Feb 2004 : changes for CDI library version 0.7.9
  1.4.0   5 May 2004 : changes for CDI library version 0.8.1 (error handling)
  1.4.1  18 Sep 2004 : netCDF 2 support
  1.4.2  22 Mar 2005 : change level from int to double
  1.4.3  11 Apr 2005 : change date and time format to ISO
  1.5.0  22 Nov 2005 : IEG support
145
146
  1.5.1  21 Feb 2006 : added option -s for short info
  1.6.0   1 Aug 2006 : added option -z szip for SZIP compression of GRIB records
147
  1.6.1  27 Feb 2007 : short info with ltype for GENERIC zaxis
148
  1.6.2   3 Jan 2008 : changes for CDI library version 1.1.0 (compress)
149
  1.6.3  26 Mar 2008 : call streamDefTimestep also if ntsteps = 0 (buf fix)
150
151
152
  1.7.0  11 Apr 2008 : added option -z zip for deflate compression of netCDF4 variables
  1.7.1   1 Nov 2009 : added option -z jpeg for JPEG compression of GRIB2 records
  1.7.2  14 Nov 2012 : added optional compression level -z zip[_1-9]
Uwe Schulzweida's avatar
Uwe Schulzweida committed
153
154
155
*/
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
156
157
static
void usage(void)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
158
{
159
  const char *name;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
160
161
162
163
164
165
  int id;

  fprintf(stderr, "usage : %s  [Option]  [ifile]  [ofile]\n", Progname);

  fprintf(stderr, "\n");
  fprintf(stderr, "  Options:\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
166
  fprintf(stderr, "    -d             Print debugging information\n");
167
  fprintf(stderr, "    -f <format>    Format of the output file. (grb, grb2, nc, nc2, nc4, nc4c, src, ext or ieg)\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
168
169
  fprintf(stderr, "    -s             give short information if ofile is missing\n");
  fprintf(stderr, "    -t <table>     Parameter table name/file\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
170
171
172
173
174
175
176
  fprintf(stderr, "                   Predefined tables: ");
  for ( id = 0; id < tableInqNumber(); id++ )
    if ( (name = tableInqNamePtr(id)) )
      fprintf(stderr, " %s", name);
  fprintf(stderr, "\n");

  fprintf(stderr, "    -V             Print version number\n");
177
178
  fprintf(stderr, "    -z szip        SZIP compression of GRIB1 records\n");
  fprintf(stderr, "       jpeg        JPEG compression of GRIB2 records\n");
179
  fprintf(stderr, "        zip[_1-9]  Deflate compression of netCDF4 variables\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
180
  fprintf(stderr, "\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
181
  fprintf(stderr, "  Report bugs to <http://code.zmaw.de/projects/cdi>\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
182
183
184
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
185
static
186
void printInfo(int vdate, int vtime, char *varname, double level,
187
	       int datasize, int number, int nmiss, double missval, const double *data, int vardis)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
188
189
190
191
{
  static int rec = 0;
  int i, ivals = 0, imiss = 0;
  double arrmean, arrmin, arrmax;
192
  char vdatestr[32], vtimestr[32];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
193

Uwe Schulzweida's avatar
Uwe Schulzweida committed
194
195
  if ( ! rec )
  {
196
    if ( vardis )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
197
198
      fprintf(stdout,
    "   Rec :       Date     Time   Level Gridsize    Miss :     Minimum        Mean     Maximum : Parameter name\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
199
/*   ----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+ */
200
    else
Uwe Schulzweida's avatar
Uwe Schulzweida committed
201
202
      fprintf(stdout,
    "   Rec :       Date     Time   Level Gridsize    Miss :     Minimum        Mean     Maximum : Parameter ID\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
203
/*   ----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+ */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
204
205
  }

206
207
  date2str(vdate, vdatestr, sizeof(vdatestr));
  time2str(vtime, vtimestr, sizeof(vtimestr));
208

Uwe Schulzweida's avatar
Uwe Schulzweida committed
209
  fprintf(stdout, "%6d :%s %s %7g ", ++rec, vdatestr, vtimestr, level);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
210

Uwe Schulzweida's avatar
Uwe Schulzweida committed
211
  fprintf(stdout, "%8d ", datasize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
212
213

  fprintf(stdout, "%7d :", nmiss);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
214
215

  if ( number == CDI_REAL )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
216
217
218
219
    {
      if ( nmiss > 0 )
	{
	  arrmean = 0;
220
221
	  arrmin  =  1.e300;
	  arrmax  = -1.e300;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
222
223
	  for ( i = 0; i < datasize; i++ )
	    {
224
	      if ( !DBL_IS_EQUAL(data[i], missval) )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
		{
		  if ( data[i] < arrmin ) arrmin = data[i];
		  if ( data[i] > arrmax ) arrmax = data[i];
		  arrmean += data[i];
		  ivals++;
		}
	    }
	  imiss = datasize - ivals;
	  datasize = ivals;
	}
      else
	{
	  arrmean = data[0];
	  arrmin  = data[0];
	  arrmax  = data[0];
	  for ( i = 1; i < datasize; i++ )
	    {
	      if ( data[i] < arrmin ) arrmin = data[i];
	      if ( data[i] > arrmax ) arrmax = data[i];
	      arrmean += data[i];
	    }
	}

      if ( datasize > 0 ) arrmean /= datasize;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
250
      fprintf(stdout, "%#12.5g%#12.5g%#12.5g", arrmin, arrmean, arrmax);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
251
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
252
253
254
  else
    {
      int nvals_r = 0, nvals_i = 0;
255
      double arrsum_r = 0, arrsum_i = 0, arrmean_r = 0, arrmean_i = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270

      for ( i = 0; i < datasize; i++ )
	{
	  if ( !DBL_IS_EQUAL(data[i*2], missval) )
	    {
	      arrsum_r += data[i*2];
	      nvals_r++;
	    }
	  if ( !DBL_IS_EQUAL(data[i*2+1], missval) )
	    {
	      arrsum_i += data[i*2+1];
	      nvals_i++;
	    }
	}

271
272
      imiss = datasize - nvals_r;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
273
274
      if ( nvals_r > 0 ) arrmean_r = arrsum_r / nvals_r;
      if ( nvals_i > 0 ) arrmean_i = arrsum_i / nvals_i;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
275
      fprintf(stdout, "  -  (%#12.5g,%#12.5g)  -", arrmean_r, arrmean_i);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
276
    }
277

278
  fprintf(stdout, " : %-14s\n", varname);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
279

280
281
  if ( imiss != nmiss && nmiss > 0 )
    fprintf(stdout, "Found %d of %d missing values!\n", imiss, nmiss);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
282
283
}

284
static const char *tunit2str(int tunits)
285
{
286
287
288
289
290
291
292
293
294
295
296
297
  if      ( tunits == TUNIT_YEAR )       return ("years");
  else if ( tunits == TUNIT_MONTH )      return ("months");
  else if ( tunits == TUNIT_DAY )        return ("days");
  else if ( tunits == TUNIT_12HOURS )    return ("12hours");
  else if ( tunits == TUNIT_6HOURS )     return ("6hours");
  else if ( tunits == TUNIT_3HOURS )     return ("3hours");
  else if ( tunits == TUNIT_HOUR )       return ("hours");
  else if ( tunits == TUNIT_30MINUTES )  return ("30minutes");
  else if ( tunits == TUNIT_QUARTER )    return ("15minutes");
  else if ( tunits == TUNIT_MINUTE )     return ("minutes");
  else if ( tunits == TUNIT_SECOND )     return ("seconds");
  else                                   return ("unknown");
298
299
300
}


301
static const char *calendar2str(int calendar)
302
303
304
305
306
307
308
309
310
{
  if      ( calendar == CALENDAR_STANDARD )  return ("standard");
  else if ( calendar == CALENDAR_PROLEPTIC ) return ("proleptic_gregorian");
  else if ( calendar == CALENDAR_360DAYS )   return ("360_day");
  else if ( calendar == CALENDAR_365DAYS )   return ("365_day");
  else if ( calendar == CALENDAR_366DAYS )   return ("366_day");
  else                                       return ("unknown");
}

311
static
312
void limit_string_length(char* string, size_t maxlen)
313
{
314
  string[maxlen-1] = 0;
315
316
317
318
319
  size_t len = strlen(string);

  if ( len > 10 )
    {
      for ( size_t i = 3; i < len; ++i )
320
	if ( string[i] == ' ' || string[i] == ',' || (i>10 && string[i] == '.') )
321
322
323
324
325
326
327
	  {
	    string[i] = 0;
	    break;
	  }
    }
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
328
329
static
void printShortinfo(int streamID, int vlistID, int vardis)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
330
331
{
  int varID;
332
  char tmpname[CDI_MAX_NAME];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
333
  char varname[CDI_MAX_NAME];
334
  int year, month, day, hour, minute, second;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
335
  char pstr[4];
336
  char paramstr[32];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
337

338
339
      fprintf(stdout, "   File format");
      fprintf(stdout, " : ");
340
      printFiletype(streamID, vlistID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
341

342
343
344
345
346
347
      //vlistPrint(vlistID);
      int nvars = vlistNvars(vlistID);
      int nsubtypes = vlistNsubtypes(vlistID);

      if ( nsubtypes > 0 )
        fprintf(stdout, "   Var : Institut Source   Ttype    Subtypes Num  Levels Num  Gridsize Num Dtype : ");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
348
      else
349
        fprintf(stdout, "   Var : Institut Source   Ttype    Levels Num  Gridsize Num Dtype : ");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
350

351
352
353
354
      if ( vardis )
	fprintf(stdout, "Parameter name\n");
      else
	fprintf(stdout, "Parameter ID\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
355
356
357

      for ( varID = 0; varID < nvars; varID++ )
	{
358
359
360
	  int param   = vlistInqVarParam(vlistID, varID);
	  int gridID  = vlistInqVarGrid(vlistID, varID);
	  int zaxisID = vlistInqVarZaxis(vlistID, varID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
361
362
363

	  fprintf(stdout, "%6d : ", varID + 1);

364
	  /* institute info */
365
	  const char *instptr = institutInqNamePtr(vlistInqVarInstitut(vlistID, varID));
366
	  strcpy(tmpname, "unknown");
367
368
	  if ( instptr ) strncpy(tmpname, instptr, CDI_MAX_NAME);
	  limit_string_length(tmpname, CDI_MAX_NAME);
369
	  fprintf(stdout, "%-8s ", tmpname);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
370

371
	  /* source info */
372
	  const char *modelptr = modelInqNamePtr(vlistInqVarModel(vlistID, varID));
373
	  strcpy(tmpname, "unknown");
374
375
	  if ( modelptr ) strncpy(tmpname, modelptr, CDI_MAX_NAME);
	  limit_string_length(tmpname, CDI_MAX_NAME);
376
	  fprintf(stdout, "%-8s ", tmpname);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
377

378
	  /* tsteptype */
379
	  int tsteptype = vlistInqVarTsteptype(vlistID, varID);
380
381
	  if      ( tsteptype == TSTEP_CONSTANT ) fprintf(stdout, "%-8s ", "constant");
	  else if ( tsteptype == TSTEP_INSTANT  ) fprintf(stdout, "%-8s ", "instant");
382
383
	  else if ( tsteptype == TSTEP_INSTANT2 ) fprintf(stdout, "%-8s ", "instant");
	  else if ( tsteptype == TSTEP_INSTANT3 ) fprintf(stdout, "%-8s ", "instant");
384
385
	  else if ( tsteptype == TSTEP_MIN      ) fprintf(stdout, "%-8s ", "min");
	  else if ( tsteptype == TSTEP_MAX      ) fprintf(stdout, "%-8s ", "max");
386
	  else if ( tsteptype == TSTEP_AVG      ) fprintf(stdout, "%-8s ", "avg");
387
	  else if ( tsteptype == TSTEP_ACCUM    ) fprintf(stdout, "%-8s ", "accum");
388
389
	  else if ( tsteptype == TSTEP_RANGE    ) fprintf(stdout, "%-8s ", "range");
	  else if ( tsteptype == TSTEP_DIFF     ) fprintf(stdout, "%-8s ", "diff");
390
391
	  else                                    fprintf(stdout, "%-8s ", "unknown");

392
393
394
395
396
397
398
399
          if ( nsubtypes > 0 )
            {
              int subtypeID = vlistInqVarSubtype(vlistID, varID);
              int subtypesize = subtypeInqSize(subtypeID);
              fprintf(stdout, " %6d  ", subtypesize);
              fprintf(stdout, "%3d ", vlistSubtypeIndex(vlistID, subtypeID) + 1);
            }

400
	  /* layer info */
401
          int levelsize = zaxisInqSize(zaxisID);
402
403
	  fprintf(stdout, "%6d ", levelsize);
	  fprintf(stdout, "%3d ", vlistZaxisIndex(vlistID, zaxisID) + 1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
404

405
	  /* grid info */
406
	  int gridsize = gridInqSize(gridID);
407
408
	  fprintf(stdout, "%9d ", gridsize);
	  fprintf(stdout, "%3d ", vlistGridIndex(vlistID, gridID) + 1);
409

410
	  /* datatype */
411
          int datatype = vlistInqVarDatatype(vlistID, varID);
412
	  if      ( datatype == CDI_DATATYPE_PACK   ) strcpy(pstr, "P0");
413
	  else if ( datatype > 0 && datatype <= 32  ) sprintf(pstr, "P%d", datatype);
414
415
416
417
418
419
420
421
422
423
	  else if ( datatype == CDI_DATATYPE_CPX32  ) strcpy(pstr, "C32");
	  else if ( datatype == CDI_DATATYPE_CPX64  ) strcpy(pstr, "C64");
	  else if ( datatype == CDI_DATATYPE_FLT32  ) strcpy(pstr, "F32");
	  else if ( datatype == CDI_DATATYPE_FLT64  ) strcpy(pstr, "F64");
	  else if ( datatype == CDI_DATATYPE_INT8   ) strcpy(pstr, "I8");
	  else if ( datatype == CDI_DATATYPE_INT16  ) strcpy(pstr, "I16");
	  else if ( datatype == CDI_DATATYPE_INT32  ) strcpy(pstr, "I32");
	  else if ( datatype == CDI_DATATYPE_UINT8  ) strcpy(pstr, "U8");
	  else if ( datatype == CDI_DATATYPE_UINT16 ) strcpy(pstr, "U16");
	  else if ( datatype == CDI_DATATYPE_UINT32 ) strcpy(pstr, "U32");
424
	  else                                    strcpy(pstr, "-1");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
425
426
427

	  fprintf(stdout, " %-3s", pstr);

428
	  if ( vlistInqVarCompType(vlistID, varID) == CDI_COMPRESS_NONE )
429
	    fprintf(stdout, "  ");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
430
	  else
431
	    fprintf(stdout, "z ");
432

433
434
	  /* parameter info */
	  fprintf(stdout, ": ");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
435

436
	  cdiParamToString(param, paramstr, sizeof(paramstr));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
437

438
	  if ( vardis )
439
440
            {
              vlistInqVarName(vlistID, varID, varname);
441
              fprintf(stdout, "%-14s", varname);
442
            }
443
	  else
444
	    fprintf(stdout, "%-14s", paramstr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
445
446
447
448

	  fprintf(stdout, "\n");
	}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
449
450
451
      fprintf(stdout, "   Grid coordinates");
      fprintf(stdout, " :\n");

452
      printGridInfo(vlistID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
453

Uwe Schulzweida's avatar
Uwe Schulzweida committed
454
455
      fprintf(stdout, "   Vertical coordinates");
      fprintf(stdout, " :\n");
456

Uwe Schulzweida's avatar
Uwe Schulzweida committed
457
      printZaxisInfo(vlistID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
458

459
460
461
462
463
464
465
466
      if ( nsubtypes > 0 )
        {
          fprintf(stdout, "   Subtypes");
          fprintf(stdout, " :\n");

          printSubtypeInfo(vlistID);
        }

467
468
      int taxisID = vlistInqTaxis(vlistID);
      int ntsteps = vlistNtsteps(vlistID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
469
470
471
472

      if ( ntsteps != 0 )
	{
	  if ( ntsteps == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
473
	    fprintf(stdout, "   Time coordinate :  unlimited steps\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
474
	  else
Uwe Schulzweida's avatar
Uwe Schulzweida committed
475
	    fprintf(stdout, "   Time coordinate :  %d step%s\n", ntsteps, ntsteps == 1 ? "" : "s");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
476
477
478
479
480

	  if ( taxisID != CDI_UNDEFID )
	    {
	      if ( taxisInqType(taxisID) == TAXIS_RELATIVE )
		{
481
482
		  int vdate = taxisInqRdate(taxisID);
		  int vtime = taxisInqRtime(taxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
483

Uwe Schulzweida's avatar
Uwe Schulzweida committed
484
485
		  cdiDecodeDate(vdate, &year, &month, &day);
		  cdiDecodeTime(vtime, &hour, &minute, &second);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
486

487
488
		  fprintf(stdout, "     RefTime = %4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d",
			  year, month, day, hour, minute, second);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
489

490
		  int tunits = taxisInqTunit(taxisID);
491
		  if ( tunits != CDI_UNDEFID )  fprintf(stdout, "  Units = %s", tunit2str(tunits));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
492

493
		  int calendar = taxisInqCalendar(taxisID);
494
		  if ( calendar != CDI_UNDEFID )  fprintf(stdout, "  Calendar = %s", calendar2str(calendar));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
495

Uwe Schulzweida's avatar
Uwe Schulzweida committed
496
497
498
		  if ( taxisHasBounds(taxisID) )
		    fprintf(stdout, "  Bounds = true");

Uwe Schulzweida's avatar
Uwe Schulzweida committed
499
500
501
502
		  fprintf(stdout, "\n");
		}
	    }

503
	  fprintf(stdout, "  YYYY-MM-DD hh:mm:ss  YYYY-MM-DD hh:mm:ss  YYYY-MM-DD hh:mm:ss  YYYY-MM-DD hh:mm:ss\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
504

505
	  printTimesteps(streamID, taxisID, 0);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
506
507
508
509
510
511

	  fprintf(stdout, "\n");
	}
}


512

Uwe Schulzweida's avatar
Uwe Schulzweida committed
513
514
static
void setDefaultDataType(char *datatypestr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
515
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
516
  int nbits = -1;
517
  enum {D_UINT, D_INT, D_FLT, D_CPX};
Uwe Schulzweida's avatar
Uwe Schulzweida committed
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
  int dtype = -1;

  if      ( *datatypestr == 'i' || *datatypestr == 'I' )
    {
      dtype = D_INT;
      datatypestr++;
    }
  else if ( *datatypestr == 'u' || *datatypestr == 'U' )
    {
      dtype = D_UINT;
      datatypestr++;
    }
  else if ( *datatypestr == 'f' || *datatypestr == 'F' )
    {
      dtype = D_FLT;
      datatypestr++;
    }
535
536
537
538
539
  else if ( *datatypestr == 'c' || *datatypestr == 'C' )
    {
      dtype = D_CPX;
      datatypestr++;
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
540
541
542

  if ( isdigit((int) *datatypestr) )
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
543
544
      nbits = atoi(datatypestr);
      if ( nbits < 10 )
545
546
547
	datatypestr += 1;
      else
	datatypestr += 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
548

Uwe Schulzweida's avatar
Uwe Schulzweida committed
549
      if ( dtype == -1 )
550
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
551
552
553
	  if      ( nbits > 0 && nbits < 32 ) DefaultDataType = nbits;
	  else if ( nbits == 32 )
	    {
554
	      if ( DefaultFileType == CDI_FILETYPE_GRB )
555
		DefaultDataType = CDI_DATATYPE_PACK32;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
556
	      else
557
		DefaultDataType = CDI_DATATYPE_FLT32;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
558
	    }
559
	  else if ( nbits == 64 ) DefaultDataType = CDI_DATATYPE_FLT64;
560
	  else
Uwe Schulzweida's avatar
Uwe Schulzweida committed
561
562
	    {
	      fprintf(stderr, "Unsupported number of bits %d!\n", nbits);
563
	      fprintf(stderr, "Use I8/I16/I32/F32/F64 for nc/nc2/nc4/nc4c; F32/F64 for grb2/srv/ext/ieg; P1 - P24 for grb/grb2.\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
564
565
	      exit(EXIT_FAILURE);
	    }
566
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
567
568
      else
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
569
570
	  if ( dtype == D_INT )
	    {
571
572
573
	      if      ( nbits ==  8 ) DefaultDataType = CDI_DATATYPE_INT8;
	      else if ( nbits == 16 ) DefaultDataType = CDI_DATATYPE_INT16;
	      else if ( nbits == 32 ) DefaultDataType = CDI_DATATYPE_INT32;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
574
575
576
577
578
579
580
581
582
	      else
		{
		  fprintf(stderr, "Unsupported number of bits = %d for datatype INT!\n", nbits);
		  exit(EXIT_FAILURE);
		}
	    }
	  /*
	  else if ( dtype == D_UINT )
	    {
583
	      if      ( nbits ==  8 ) DefaultDataType = CDI_DATATYPE_UINT8;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
584
585
586
587
588
589
590
591
592
	      else
		{
		  fprintf(stderr, "Unsupported number of bits = %d for datatype UINT!\n", nbits);
		  exit(EXIT_FAILURE);
		}
	    }
	  */
	  else if ( dtype == D_FLT )
	    {
593
594
	      if      ( nbits == 32 ) DefaultDataType = CDI_DATATYPE_FLT32;
	      else if ( nbits == 64 ) DefaultDataType = CDI_DATATYPE_FLT64;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
595
596
597
598
599
600
	      else
		{
		  fprintf(stderr, "Unsupported number of bits = %d for datatype FLT!\n", nbits);
		  exit(EXIT_FAILURE);
		}
	    }
601
602
	  else if ( dtype == D_CPX )
	    {
603
604
	      if      ( nbits == 32 ) DefaultDataType = CDI_DATATYPE_CPX32;
	      else if ( nbits == 64 ) DefaultDataType = CDI_DATATYPE_CPX64;
605
606
607
608
609
610
	      else
		{
		  fprintf(stderr, "Unsupported number of bits = %d for datatype CPX!\n", nbits);
		  exit(EXIT_FAILURE);
		}
	    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
611
612
613
	}
    }

614
  if ( *datatypestr != 0 )
615
    {
616
617
      if ( *datatypestr == 'l' || *datatypestr == 'L' )
	{
618
	  if ( HOST_ENDIANNESS == CDI_BIGENDIAN ) DefaultByteorder = CDI_LITTLEENDIAN;
619
620
621
622
	  datatypestr++;
	}
      else if ( *datatypestr == 'b' || *datatypestr == 'B' )
	{
623
	  if ( HOST_ENDIANNESS == CDI_LITTLEENDIAN ) DefaultByteorder = CDI_BIGENDIAN;
624
625
626
627
628
629
630
	  datatypestr++;
	}
      else
	{
	  fprintf(stderr, "Unsupported character in number of bytes: >%s< !\n", datatypestr);
	  exit(EXIT_FAILURE);
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
631
632
633
    }
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
634
635
static
void setDefaultFileType(char *filetypestr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
636
637
638
{
  if ( filetypestr )
    {
639
640
      char *ftstr = filetypestr;

641
642
643
644
645
646
647
648
649
650
651
      if      ( memcmp(filetypestr, "grb2", 4)  == 0 ) { ftstr += 4; DefaultFileType = CDI_FILETYPE_GRB2;}
      else if ( memcmp(filetypestr, "grb1", 4)  == 0 ) { ftstr += 4; DefaultFileType = CDI_FILETYPE_GRB; }
      else if ( memcmp(filetypestr, "grb",  3)  == 0 ) { ftstr += 3; DefaultFileType = CDI_FILETYPE_GRB; }
      else if ( memcmp(filetypestr, "nc2",  3)  == 0 ) { ftstr += 3; DefaultFileType = CDI_FILETYPE_NC2; }
      else if ( memcmp(filetypestr, "nc4c", 4)  == 0 ) { ftstr += 4; DefaultFileType = CDI_FILETYPE_NC4C;}
      else if ( memcmp(filetypestr, "nc4",  3)  == 0 ) { ftstr += 3; DefaultFileType = CDI_FILETYPE_NC4; }
      else if ( memcmp(filetypestr, "nc1",  3)  == 0 ) { ftstr += 3; DefaultFileType = CDI_FILETYPE_NC;  }
      else if ( memcmp(filetypestr, "nc",   2)  == 0 ) { ftstr += 2; DefaultFileType = CDI_FILETYPE_NC2; }
      else if ( memcmp(filetypestr, "srv",  3)  == 0 ) { ftstr += 3; DefaultFileType = CDI_FILETYPE_SRV; }
      else if ( memcmp(filetypestr, "ext",  3)  == 0 ) { ftstr += 3; DefaultFileType = CDI_FILETYPE_EXT; }
      else if ( memcmp(filetypestr, "ieg",  3)  == 0 ) { ftstr += 3; DefaultFileType = CDI_FILETYPE_IEG; }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
652
653
654
      else
	{
	  fprintf(stderr, "Unsupported filetype %s!\n", filetypestr);
655
	  fprintf(stderr, "Available filetypes: grb, grb2, nc, nc2, nc4, nc4c, srv, ext and ieg\n");
656
	  exit(EXIT_FAILURE);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
657
658
	}

659
      if ( DefaultFileType != CDI_UNDEFID && *ftstr != 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
660
	{
661
	  if ( *ftstr == '_' )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
662
	    {
663
	      ftstr++;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
664

665
666
667
668
669
670
	      setDefaultDataType(ftstr);
	    }
	  else
	    {
	      fprintf(stderr, "Unexpected character >%c< in file type >%s<!\n", *ftstr, filetypestr);
	      fprintf(stderr, "Use format[_nbits] with:\n");
671
	      fprintf(stderr, "    format = grb, grb2, nc, nc2, nc4, nc4c, srv, ext or ieg\n");
672
	      fprintf(stderr, "    nbits  = 32/64 for grb2/nc/nc2/nc4/nc4c/srv/ext/ieg; 1 - 24 for grb/grb2\n");
673
	      exit(EXIT_FAILURE);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
674
675
676
677
678
	    }
	}
    }
}

679
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
680
681
682
int handle_error(int cdiErrno, const char *fmt, ...)
{
  va_list args;
683

Uwe Schulzweida's avatar
Uwe Schulzweida committed
684
685
686
687
688
689
690
691
692
693
  va_start(args, fmt);

  printf("\n");
  vfprintf(stderr, fmt, args);
   fprintf(stderr, "\n");

  va_end(args);

  fprintf(stderr, "%s\n", cdiStringError(cdiErrno));

694
  return cdiErrno;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
695
696
}

697
static
698
699
700
701
702
void defineCompress(const char *arg)
{
  size_t len = strlen(arg);

  if      ( strncmp(arg, "szip", len) == 0 )
703
    {
704
      comptype = CDI_COMPRESS_SZIP;
705
    }
706
707
  else if ( strncmp(arg, "jpeg", len) == 0 )
    {
708
      comptype = CDI_COMPRESS_JPEG;
709
    }
710
  else if ( strncmp(arg, "gzip", len) == 0 )
711
    {
712
      comptype = CDI_COMPRESS_GZIP;
713
      complevel = 6;
714
    }
715
  else if ( strncmp(arg, "zip", 3) == 0 )
716
    {
717
      comptype = CDI_COMPRESS_ZIP;
718
719
720
721
      if ( len == 5 && arg[3] == '_' && isdigit(arg[4]) )
	complevel = atoi(&arg[4]);
      else
        complevel = 1;
722
    }
723
  else
724
    fprintf(stderr, "%s compression unsupported!\n", arg);
725
726
727
728
}



Uwe Schulzweida's avatar
Uwe Schulzweida committed
729
730
731
732
733
734
735
736
737
738
int main(int argc, char *argv[])
{
  int c;
  char *fname1 = NULL;
  char *fname2 = NULL;
  char *rTable = NULL;
  char *wTable = NULL;
  int Move = 0;
  int Record = 0;
  int Debug = 0;
Thomas Jahns's avatar
Thomas Jahns committed
739
  /* int Quiet  = 0; */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
740
  int Vardis = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
741
742
  int Version = 0;
  int Longinfo = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
743
  int Shortinfo = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
744
745
  int varID;
  int itableID = CDI_UNDEFID, otableID = CDI_UNDEFID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
746
  int Info = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
747
  char varname[CDI_MAX_NAME];
748
  char paramstr[32];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
749
750
751
752
753

  Progname = strrchr(argv[0], '/');
  if (Progname == 0) Progname = argv[0];
  else               Progname++;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
754
  while ( (c = getopt(argc, argv, "b:f:t:w:z:cdhlMmqRrsvVxZ")) != EOF )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
755
756
757
    {
      switch (c)
	{
758
759
760
	case 'b':
	  setDefaultDataType(optarg);
	  break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
761
762
763
764
765
766
	case 'd':
	  Debug = 1;
	  break;
	case 'f':
	  setDefaultFileType(optarg);
	  break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
767
768
769
	case 'h':
	  usage();
	  exit (0);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
770
771
772
	case 'l':
	  Longinfo = 1;
	  break;
773
774
775
	case 'M':
	  cdiDefGlobal("HAVE_MISSVAL", 1);
	  break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
776
777
778
779
	case 'm':
	  Move = 1;
	  break;
	case 'q':
Thomas Jahns's avatar
Thomas Jahns committed
780
	  /* Quiet = 1; */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
781
	  break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
782
783
784
785
786
787
	case 'R':
	  cdiDefGlobal("REGULARGRID", 1);
	  break;
	case 'r':
	  Record = 1;
	  break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
788
789
790
	case 's':
	  Shortinfo = 1;
	  break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
791
792
793
	case 't':
	  rTable = optarg;
	  break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
794
795
796
797
798
799
	case 'v':
	  Vardis = 1;
	  break;
	case 'V':
	  Version = 1;
	  break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
800
801
802
	case 'w':
	  wTable = optarg;
	  break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
803
804
805
	case 'x':
	  datamode = SP_MODE;
	  break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
806
	case 'z':
807
	  defineCompress(optarg);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
808
809
810
811
812
813
	  break;
	}
    }

  if ( optind < argc ) fname1 = argv[optind++];
  if ( optind < argc ) fname2 = argv[optind++];
814
  if ( optind < argc ) fprintf(stderr, "optind: %d argc: %d\n", optind, argc);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
815
816
817
818
819
820
821
822

  if ( Debug || Version ) version();

  if ( Debug ) cdiDebug(Debug);

  if ( rTable )
    {
      itableID = tableInq(-1, 0, rTable);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
823
      if ( itableID != CDI_UNDEFID ) cdiDefTableID(itableID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
824
825
826
827
828
829
830
831
832
833
834
835
      otableID = itableID;
    }

  if ( fname1 == NULL && ! (Debug || Version) )
    {
      usage();
      exit (0);
    }

  if ( fname1 )
    {
      int nmiss;
836
      int number;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
837
838
839
      int datasize = 0;
      int streamID2 = CDI_UNDEFID;
      int filetype;
840
      int gridID, zaxisID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
841
      int param;
842
      int nrecs;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
843
844
      int levelID, levelsize;
      int nts = 0;
845
      int gridsize = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
846
      int recID;
847
848
      int taxisID2 = CDI_UNDEFID;
      int vlistID2 = CDI_UNDEFID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
849

850
851
      int streamID1 = streamOpenRead(fname1);
      if ( streamID1 < 0 ) return handle_error(streamID1, "Open failed on %s", fname1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
852

853
      int vlistID1 = streamInqVlist(streamID1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
854

855
      if ( Longinfo ) vlistPrint(vlistID1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
856

857
858
859
      int nvars = vlistNvars(vlistID1);
      int taxisID1 = vlistInqTaxis(vlistID1);
      int ntsteps = vlistNtsteps(vlistID1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
860

861
862
      if ( Debug )
        fprintf(stderr, "nvars   = %d\nntsteps = %d\n", nvars, ntsteps);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
863

864
865
866
867
868
869
      if ( fname2 )
        {
          vlistID2 = vlistDuplicate(vlistID1);
          taxisID2 = taxisDuplicate(taxisID1);
          vlistDefTaxis(vlistID2, taxisID2);
        }
870

Uwe Schulzweida's avatar
Uwe Schulzweida committed
871
872
873
874
875
876
877
878
879
880
881
882
883
884
      for ( varID = 0; varID < nvars; varID++)
	{
	  gridID   = vlistInqVarGrid(vlistID1, varID);
	  gridsize = gridInqSize(gridID);
	  if ( gridsize > datasize ) datasize = gridsize;
	  if ( fname2 )
	    {
	      if ( DefaultDataType != CDI_UNDEFID )
		vlistDefVarDatatype(vlistID2, varID, DefaultDataType);
	    }
	}

      if ( fname2 )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
885
	  Info = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
886
887
888
889
890
891
892
	  filetype = streamInqFiletype(streamID1);

	  if ( DefaultFileType != CDI_UNDEFID )
	    filetype = DefaultFileType;

	  streamID2 = streamOpenWrite(fname2, filetype);
	  if ( streamID2 < 0 )
893
	    return handle_error(streamID2, "Open failed on %s", fname2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
894

895
896
897
	  if ( DefaultByteorder != CDI_UNDEFID )
	    streamDefByteorder(streamID2, DefaultByteorder);

898
	  if ( comptype != CDI_COMPRESS_NONE )
899
	    {
900
	      streamDefCompType(streamID2, comptype);
901
	      streamDefCompLevel(streamID2, complevel);
902
903
	    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
904
905
906
907
	  streamDefVlist(streamID2, vlistID2);

	  if ( otableID == CDI_UNDEFID ) otableID = itableID;
	}
908

Uwe Schulzweida's avatar
Uwe Schulzweida committed
909
      if ( vlistNumber(vlistID1) != CDI_REAL ) datasize *= 2;
910
      double *data = (double *) malloc((size_t)datasize * sizeof (double));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
911
912
913
914

      /*
	nts = cdiInqTimeSize(streamID1);
      */
915
916
      if ( Debug )
	printf("nts = %d streamID1 = %d, streamID2 = %d\n", nts, streamID1, streamID2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
917

Uwe Schulzweida's avatar
Uwe Schulzweida committed
918
919
920
921
922
923
      if ( Shortinfo )
	{
	  Info = 0;
	  printShortinfo(streamID1, vlistID1, Vardis);
	}

924
      int tsID = 0;
925
      if ( Info || fname2 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
926
927
      while ( (nrecs = streamInqTimestep(streamID1, tsID)) > 0 )
	{
928
	  if ( fname2 /* && ntsteps != 0*/ )
929
930
931
932
            {
              taxisCopyTimestep(taxisID2, taxisID1);
              streamDefTimestep(streamID2, tsID);
            }
933
934
	  int vdate = taxisInqVdate(taxisID1);
	  int vtime = taxisInqVtime(taxisID1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
935
936
937
938
939
940
941
942
943
944
945

	  if ( Debug )
	    fprintf(stdout, "tsID = %d nrecs = %d date = %d time = %d\n", tsID, nrecs, vdate, vtime);

	  if ( Record )
	    {
	      for ( recID = 0; recID < nrecs; recID++ )
		{
		  streamInqRecord(streamID1, &varID, &levelID);
		  streamReadRecord(streamID1, data, &nmiss);

946
		  number   = vlistInqVarNumber(vlistID1, varID);
947
948
949
		  gridID   = vlistInqVarGrid(vlistID1, varID);
		  zaxisID  = vlistInqVarZaxis(vlistID1, varID);
		  param    = vlistInqVarParam(vlistID1, varID);
950

951
		  cdiParamToString(param, paramstr, sizeof(paramstr));
952
953
954

		  if ( Vardis ) vlistInqVarName(vlistID1, varID, varname);
		  else          strcpy(varname, paramstr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
955
		  /*
956
957
		  printf("varID=%d, param=%d, gridID=%d, zaxisID=%d levelID=%d\n",
			 varID, param, gridID, zaxisID, levelID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
958
959
		  */
		  gridsize = gridInqSize(gridID);
960
961
		  double level   = zaxisInqLevels(zaxisID, NULL) ? zaxisInqLevel(zaxisID, levelID) : levelID+1;
                  double missval = vlistInqVarMissval(vlistID1, varID);
962

Uwe Schulzweida's avatar
Uwe Schulzweida committed
963
		  if ( Info )
964
		    printInfo(vdate, vtime, varname, level, gridsize, number, nmiss, missval, data, Vardis);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
965
966
967
968
969
970
971

		  if ( fname2 )
		    {
		      streamDefRecord(streamID2, varID, levelID);
		      if ( Move )
			streamCopyRecord(streamID2, streamID1);
		      else
972
			streamWriteRecord(streamID2, data, nmiss);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
973
974
975
976
977
978
979
		    }
	      	}
	    }
	  else
	    {
	      for ( varID = 0; varID < nvars; varID++ )
		{
980
		  if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT && tsID > 0 ) continue;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
981

982
		  number   = vlistInqVarNumber(vlistID1, varID);
983
984
985
		  gridID   = vlistInqVarGrid(vlistID1, varID);
		  zaxisID  = vlistInqVarZaxis(vlistID1, varID);
		  param    = vlistInqVarParam(vlistID1, varID);
986

987
		  cdiParamToString(param, paramstr, sizeof(paramstr));
988
989
990
991

		  if ( Vardis ) vlistInqVarName(vlistID1, varID, varname);
		  else          strcpy(varname, paramstr);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
992
		  if ( Debug )
993
994
		    fprintf(stdout, "varID = %d param = %d gridID = %d zaxisID = %d\n",
			    varID, param, gridID, zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
995
996

		  gridsize = gridInqSize(gridID);
997
		  double missval = vlistInqVarMissval(vlistID1, varID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
998
999
1000
1001

		  levelsize = zaxisInqSize(zaxisID);
		  for ( levelID = 0; levelID < levelsize; levelID++ )
		    {
1002
                      double level = zaxisInqLevels(zaxisID, NULL) ? zaxisInqLevel(zaxisID, levelID) : levelID+1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1003
1004
		      streamReadVarSlice(streamID1, varID, levelID, data, &nmiss);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1005
		      if ( Info )
1006
			printInfo(vdate, vtime, varname, level, gridsize, number, nmiss, missval, data, Vardis);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1007
1008
1009
1010
1011
1012

		      if ( fname2 )
			streamWriteVarSlice(streamID2, varID, levelID, data, nmiss);
		    }
		}
	    }
1013

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1014
1015
1016
1017
1018
	  tsID++;
        }

      free(data);

1019
      /* fprintf(stderr, "%ld\n", (long) streamNvals(streamID1)); */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1020

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1021
1022
1023
1024
      if ( fname2 )
	{
	  streamClose(streamID2);
	  vlistDestroy(vlistID2);
1025
	  taxisDestroy(taxisID2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1026
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1027
1028
1029
1030
1031
1032
      streamClose(streamID1);
    }

  if ( wTable )
    tableWrite(wTable, itableID);

1033
  return 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1034
}