cdi_int.c 13.2 KB
Newer Older
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1
2
3
4
5
6
7
#if defined (HAVE_CONFIG_H)
#  include "config.h"
#endif

#include <stdarg.h>
#include <ctype.h>

Thomas Jahns's avatar
Thomas Jahns committed
8
#include "binary.h"
9
#include "cdf.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
10
#include "cdi.h"
11
#include "cdi_int.h"
12
13
#include "dmemory.h"
#include "file.h"
14
15
16
17
#include "gribapi.h"
#ifdef HAVE_LIBNETCDF
#include "stream_cdf.h"
#endif
18
#include "namespace.h"
19
#include "resource_handle.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
20

21
22
23
#if  defined  (HAVE_LIBCGRIBEX)
#include "cgribex.h"
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
24

Uwe Schulzweida's avatar
Uwe Schulzweida committed
25
26
27
28
29
int cdiDefaultCalendar = CALENDAR_PROLEPTIC;

int cdiDefaultInstID   = CDI_UNDEFID;
int cdiDefaultModelID  = CDI_UNDEFID;
int cdiDefaultTableID  = CDI_UNDEFID;
30
//int cdiNcMissingValue  = CDI_UNDEFID;
31
int cdiNcChunksizehint = CDI_UNDEFID;
32
int cdiChunkType       = CDI_CHUNK_GRID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
33
int cdiSplitLtype105   = CDI_UNDEFID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
34

35
int cdiIgnoreAttCoordinates = FALSE;
36
int cdiCoordinatesLonLat    = FALSE;
37
int cdiIgnoreValidRange     = FALSE;
38
int cdiSkipRecords          = 0;
39
int cdiConvention           = CDI_CONVENTION_ECHAM;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
40
int cdiInventoryMode        = 1;
41
int CDI_Version_Info        = 1;
42
int CDI_cmor_mode           = 0;
43
size_t CDI_netcdf_hdr_pad   = 0UL;
44
bool CDI_netcdf_lazy_grid_load = false;
45

Uwe Schulzweida's avatar
Uwe Schulzweida committed
46
47
48
char *cdiPartabPath   = NULL;
int   cdiPartabIntern = 1;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
49
50
double cdiDefaultMissval = -9.E33;

Thomas Jahns's avatar
Thomas Jahns committed
51
static const char Filetypes[][9] = {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
52
53
54
  "UNKNOWN",
  "GRIB",
  "GRIB2",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
55
56
57
58
  "NetCDF",
  "NetCDF2",
  "NetCDF4",
  "NetCDF4c",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
59
60
61
  "SERVICE",
  "EXTRA",
  "IEG",
62
  "HDF5",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
63
64
};

65
int CDI_Debug   = 0;    /* If set to 1, debugging           */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
66
int CDI_Recopt = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
67

68
int cdiGribApiDebug     = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
69
int cdiDefaultLeveltype = -1;
70
71
int cdiDataUnreduced = 0;
int cdiSortName = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
72
int cdiSortParam = 0;
73
int cdiHaveMissval = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
74
75


Oliver Heidmann's avatar
Oliver Heidmann committed
76
static long cdiGetenvInt(const char *envName)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
{
  char *envString;
  long envValue = -1;
  long fact = 1;

  envString = getenv(envName);

  if ( envString )
    {
      int loop, len;

      len = (int) strlen(envString);
      for ( loop = 0; loop < len; loop++ )
	{
	  if ( ! isdigit((int) envString[loop]) )
	    {
	      switch ( tolower((int) envString[loop]) )
		{
		case 'k':  fact = 1024;        break;
		case 'm':  fact = 1048576;     break;
		case 'g':  fact = 1073741824;  break;
		default:
		  fact = 0;
100
101
		  Message("Invalid number string in %s: %s", envName, envString);
		  Warning("%s must comprise only digits [0-9].",envName);
102
		  break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
103
104
105
106
107
108
109
		}
	      break;
	    }
	}

      if ( fact ) envValue = fact*atol(envString);

110
      if ( CDI_Debug ) Message("set %s to %ld", envName, envValue);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
111
112
113
114
115
    }

  return (envValue);
}

116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
static void
cdiPrintDefaults(void)
{
  fprintf(stderr, "default instID     :  %d\n"
          "default modelID    :  %d\n"
          "default tableID    :  %d\n"
          "default missval    :  %g\n", cdiDefaultInstID,
          cdiDefaultModelID, cdiDefaultTableID, cdiDefaultMissval);
}

void cdiPrintVersion(void)
{
  fprintf(stderr, "     CDI library version : %s\n", cdiLibraryVersion());
#if  defined  (HAVE_LIBCGRIBEX)
  fprintf(stderr, " CGRIBEX library version : %s\n", cgribexLibraryVersion());
#endif
#if  defined  (HAVE_LIBGRIB_API)
133
  fprintf(stderr, "GRIB_API library version : %s\n", gribapiLibraryVersionString());
134
135
#endif
#if  defined  (HAVE_LIBNETCDF)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
136
  fprintf(stderr, "  NetCDF library version : %s\n", cdfLibraryVersion());
137
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
138
#if  defined  (HAVE_NC4HDF5)
139
140
141
142
143
144
145
146
147
148
149
150
151
152
  fprintf(stderr, "    HDF5 library version : %s\n", hdfLibraryVersion());
#endif
#if  defined  (HAVE_LIBSERVICE)
  fprintf(stderr, " SERVICE library version : %s\n", srvLibraryVersion());
#endif
#if  defined  (HAVE_LIBEXTRA)
  fprintf(stderr, "   EXTRA library version : %s\n", extLibraryVersion());
#endif
#if  defined  (HAVE_LIBIEG)
  fprintf(stderr, "     IEG library version : %s\n", iegLibraryVersion());
#endif
  fprintf(stderr, "    FILE library version : %s\n", fileLibraryVersion());
}

Thomas Jahns's avatar
Thomas Jahns committed
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
static void cdiPrintDatatypes(void)
{
#define XSTRING(x)	#x
#define STRING(x)	XSTRING(x)
  fprintf (stderr, "+-------------+-------+\n"
           "| types       | bytes |\n"
           "+-------------+-------+\n"
           "| void *      |   %3d |\n"
           "+-------------+-------+\n"
           "| char        |   %3d |\n"
           "+-------------+-------+\n"
           "| bool        |   %3d |\n"
           "| short       |   %3d |\n"
           "| int         |   %3d |\n"
           "| long        |   %3d |\n"
           "| long long   |   %3d |\n"
           "| size_t      |   %3d |\n"
           "| off_t       |   %3d |\n"
           "+-------------+-------+\n"
           "| float       |   %3d |\n"
           "| double      |   %3d |\n"
           "| long double |   %3d |\n"
           "+-------------+-------+\n\n"
           "+-------------+-----------+\n"
           "| INT32       | %-9s |\n"
           "| INT64       | %-9s |\n"
           "| FLT32       | %-9s |\n"
           "| FLT64       | %-9s |\n"
           "+-------------+-----------+\n"
           "\n  byte ordering is %s\n\n",
           (int) sizeof(void *), (int) sizeof(char), (int) sizeof(bool),
           (int) sizeof(short), (int) sizeof(int), (int) sizeof(long), (int) sizeof(long long),
           (int) sizeof(size_t), (int) sizeof(off_t),
           (int) sizeof(float), (int) sizeof(double), (int) sizeof(long double),
           STRING(INT32), STRING(INT64), STRING(FLT32), STRING(FLT64),
           ((HOST_ENDIANNESS == CDI_BIGENDIAN) ? "BIGENDIAN"
            : ((HOST_ENDIANNESS == CDI_LITTLEENDIAN) ? "LITTLEENDIAN"
               : "Unhandled endianness!")));
#undef STRING
#undef XSTRING
}

195
196
197
198
199
200
201
202
203
204
205
206
void cdiDebug(int level)
{
  if ( level == 1 || (level &  2) ) CDI_Debug = 1;

  if ( CDI_Debug ) Message("debug level %d", level);

  if ( level == 1 || (level &  4) ) memDebug(1);

  if ( level == 1 || (level &  8) ) fileDebug(1);

  if ( level == 1 || (level & 16) )
    {
207
#if  defined  (HAVE_LIBCGRIBEX)
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
      gribSetDebug(1);
#endif
#if  defined  (HAVE_LIBNETCDF)
      cdfDebug(1);
#endif
#if  defined  (HAVE_LIBSERVICE)
      srvDebug(1);
#endif
#if  defined  (HAVE_LIBEXTRA)
      extDebug(1);
#endif
#if  defined  (HAVE_LIBIEG)
      iegDebug(1);
#endif
    }

  if ( CDI_Debug )
    {
      cdiPrintDefaults();
      cdiPrintDatatypes();
    }
}


int cdiHaveFiletype(int filetype)
{
  int status = 0;

  switch (filetype)
    {
#if  defined  (HAVE_LIBSERVICE)
239
    case CDI_FILETYPE_SRV:  { status = 1; break; }
240
241
#endif
#if  defined  (HAVE_LIBEXTRA)
242
    case CDI_FILETYPE_EXT:  { status = 1; break; }
243
244
#endif
#if  defined  (HAVE_LIBIEG)
245
    case CDI_FILETYPE_IEG:  { status = 1; break; }
246
247
248
#endif
#if  defined  (HAVE_LIBGRIB)
#if  defined  (HAVE_LIBGRIB_API) || defined  (HAVE_LIBCGRIBEX)
249
    case CDI_FILETYPE_GRB:  { status = 1; break; }
250
251
#endif
#if  defined  (HAVE_LIBGRIB_API)
252
    case CDI_FILETYPE_GRB2: { status = 1; break; }
253
254
255
#endif
#endif
#if  defined  (HAVE_LIBNETCDF)
256
    case CDI_FILETYPE_NC:   { status = 1; break; }
257
#if  defined  (HAVE_NETCDF2)
258
    case CDI_FILETYPE_NC2:  { status = 1; break; }
259
260
#endif
#if  defined  (HAVE_NETCDF4)
261
262
    case CDI_FILETYPE_NC4:  { status = 1; break; }
    case CDI_FILETYPE_NC4C: { status = 1; break; }
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
#endif
#endif
    default: { status = 0; break; }
    }

  return (status);
}

void cdiDefTableID(int tableID)
{
  cdiDefaultTableID = tableID;
  int modelID = cdiDefaultModelID = tableInqModel(tableID);
  cdiDefaultInstID = modelInqInstitut(modelID);
}

278
279
280
281
282
283
284
static
void cdiSetChunk(const char *chunkAlgo)
{
  //char *pch;
  //size_t len = strlen(chunkAlgo);
  int algo = -1;

285
286
287
  if      ( strcmp("auto",  chunkAlgo)   == 0 ) algo = CDI_CHUNK_AUTO;
  else if ( strcmp("grid",  chunkAlgo)   == 0 ) algo = CDI_CHUNK_GRID;
  else if ( strcmp("lines", chunkAlgo)   == 0 ) algo = CDI_CHUNK_LINES;
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
  /*
  else if ( (pch = strstr(chunkAlgo,"x")) != 0 )
    {
      int ix, iy;
      ix = atoi(chunkAlgo);
      iy = atoi(pch+1);
      if ( ix > 0 && iy > 0 )
        {
          cdiChunkX = ix;
          cdiChunkY = iy;
          algo = CHUNK_USER;
        }
      else
        Warning("Invalid environment variable CDI_CHUNK_ALGO: %s", chunkAlgo);
    }
  */
  else
    Warning("Invalid environment variable CDI_CHUNK_ALGO: %s", chunkAlgo);

  if ( algo != -1 )
    {
      cdiChunkType = algo;
      if ( CDI_Debug ) Message("set ChunkAlgo to %s", chunkAlgo);
    }
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
314
315
316
317

void cdiInitialize(void)
{
  static int Init_CDI = FALSE;
318
  char *envstr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
319
320
321
322
323
324
  long value;

  if ( ! Init_CDI )
    {
      Init_CDI = TRUE;

325
326
327
328
329
#if  defined  (HAVE_LIBCGRIBEX)
      gribFixZSE(1);   // 1: Fix ZeroShiftError of simple packed spherical harmonics
      gribSetConst(1); // 1: Don't pack constant fields on regular grids
#endif

330
331
332
      value = cdiGetenvInt("CDI_DEBUG");
      if ( value >= 0 ) CDI_Debug = (int) value;

333
334
335
      value = cdiGetenvInt("CDI_GRIBAPI_DEBUG");
      if ( value >= 0 ) cdiGribApiDebug = (int) value;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
336
337
338
      value = cdiGetenvInt("CDI_RECOPT");
      if ( value >= 0 ) CDI_Recopt = (int) value;

339
340
341
342
343
344
      value = cdiGetenvInt("CDI_REGULARGRID");
      if ( value >= 0 ) cdiDataUnreduced = (int) value;

      value = cdiGetenvInt("CDI_SORTNAME");
      if ( value >= 0 ) cdiSortName = (int) value;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
345
346
347
      value = cdiGetenvInt("CDI_SORTPARAM");
      if ( value >= 0 ) cdiSortParam = (int) value;

348
349
350
      value = cdiGetenvInt("CDI_HAVE_MISSVAL");
      if ( value >= 0 ) cdiHaveMissval = (int) value;

351
352
353
      value = cdiGetenvInt("CDI_LEVELTYPE");
      if ( value >= 0 ) cdiDefaultLeveltype = (int) value;

354
355
356
      value = cdiGetenvInt("CDI_NETCDF_HDR_PAD");
      if ( value >= 0 ) CDI_netcdf_hdr_pad = (size_t) value;

357
358
      envstr = getenv("CDI_MISSVAL");
      if ( envstr ) cdiDefaultMissval = atof(envstr);
359
      /*
360
361
      envstr = getenv("NC_MISSING_VALUE");
      if ( envstr ) cdiNcMissingValue = atoi(envstr);
362
      */
363
364
      envstr = getenv("NC_CHUNKSIZEHINT");
      if ( envstr ) cdiNcChunksizehint = atoi(envstr);
365

366
367
      envstr = getenv("CDI_CHUNK_ALGO");
      if ( envstr ) cdiSetChunk(envstr);
368

369
370
      envstr = getenv("SPLIT_LTYPE_105");
      if ( envstr ) cdiSplitLtype105 = atoi(envstr);
371

372
373
      envstr = getenv("IGNORE_ATT_COORDINATES");
      if ( envstr ) cdiIgnoreAttCoordinates = atoi(envstr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
374

375
376
377
      envstr = getenv("CDI_COORDINATES_LONLAT");
      if ( envstr ) cdiCoordinatesLonLat = atoi(envstr);

378
379
      envstr = getenv("IGNORE_VALID_RANGE");
      if ( envstr ) cdiIgnoreValidRange = atoi(envstr);
380

381
382
      envstr = getenv("CDI_SKIP_RECORDS");
      if ( envstr )
383
	{
384
	  cdiSkipRecords = atoi(envstr);
385
386
387
	  cdiSkipRecords = cdiSkipRecords > 0 ? cdiSkipRecords : 0;
	}

388
389
      envstr = getenv("CDI_CONVENTION");
      if ( envstr )
390
	{
391
	  if ( strcmp(envstr, "CF") == 0 || strcmp(envstr, "cf") == 0 )
392
393
394
395
396
397
398
	    {
	      cdiConvention = CDI_CONVENTION_CF;
	      if ( CDI_Debug )
		Message("CDI convention was set to CF!");
	    }
	}

399
400
      envstr = getenv("CDI_INVENTORY_MODE");
      if ( envstr )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
401
	{
402
	  if ( strncmp(envstr, "time", 4) == 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
403
404
405
	    {
	      cdiInventoryMode = 2;
	      if ( CDI_Debug )
406
		Message("Inventory mode was set to timestep!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
407
408
409
	    }
	}

410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
      envstr = getenv("CDI_VERSION_INFO");
      if ( envstr )
        {
          int ival = atoi(envstr);
          if ( ival == 0 || ival == 1 )
            {
              CDI_Version_Info = ival;
              if ( CDI_Debug )
                Message("CDI_Version_Info = %s", envstr);
            }
        }


      envstr = getenv("CDI_CALENDAR");
      if ( envstr )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
425
	{
426
	  if      ( strncmp(envstr, "standard", 8) == 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
427
	    cdiDefaultCalendar = CALENDAR_STANDARD;
428
	  else if ( strncmp(envstr, "proleptic", 9) == 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
429
	    cdiDefaultCalendar = CALENDAR_PROLEPTIC;
430
	  else if ( strncmp(envstr, "360days", 7) == 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
431
	    cdiDefaultCalendar = CALENDAR_360DAYS;
432
	  else if ( strncmp(envstr, "365days", 7) == 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
433
	    cdiDefaultCalendar = CALENDAR_365DAYS;
434
	  else if ( strncmp(envstr, "366days", 7) == 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
435
	    cdiDefaultCalendar = CALENDAR_366DAYS;
436
	  else if ( strncmp(envstr, "none", 4) == 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
437
438
439
	    cdiDefaultCalendar = CALENDAR_NONE;

	  if ( CDI_Debug )
440
	    Message("Default calendar set to %s!", envstr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
441
	}
442
#if  defined  (HAVE_LIBCGRIBEX)
443
      gribSetCalendar(cdiDefaultCalendar);
444
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
445

446
447
      envstr = getenv("PARTAB_INTERN");
      if ( envstr ) cdiPartabIntern = atoi(envstr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
448

449
450
      envstr = getenv("PARTAB_PATH");
      if ( envstr ) cdiPartabPath = strdup(envstr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
451
452
453
454
    }
}


455
const char *strfiletype(int filetype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
456
{
457
  const char *name;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
458
  int size = (int) (sizeof(Filetypes)/sizeof(char *));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
459

Uwe Schulzweida's avatar
Uwe Schulzweida committed
460
461
462
  if ( filetype > 0 && filetype < size )
    name = Filetypes[filetype];
  else
463
    name = Filetypes[0];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
464

Uwe Schulzweida's avatar
Uwe Schulzweida committed
465
  return (name);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
466
467
468
}


469
void cdiDefGlobal(const char *string, int val)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
470
{
471
472
473
  if      ( strcmp(string, "REGULARGRID")      == 0 ) cdiDataUnreduced = val;
  else if ( strcmp(string, "GRIBAPI_DEBUG")    == 0 ) cdiGribApiDebug = val;
  else if ( strcmp(string, "SORTNAME")         == 0 ) cdiSortName = val;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
474
  else if ( strcmp(string, "SORTPARAM")        == 0 ) cdiSortParam = val;
475
476
  else if ( strcmp(string, "HAVE_MISSVAL")     == 0 ) cdiHaveMissval = val;
  else if ( strcmp(string, "NC_CHUNKSIZEHINT") == 0 ) cdiNcChunksizehint = val;
477
  else if ( strcmp(string, "CMOR_MODE")        == 0 ) CDI_cmor_mode = val;
478
  else if ( strcmp(string, "NETCDF_HDR_PAD")   == 0 ) CDI_netcdf_hdr_pad = (size_t) val;
479
480
  else if ( strcmp(string, "NETCDF_LAZY_GRID_LOAD") == 0)
    CDI_netcdf_lazy_grid_load = (bool)val;
481
  else Warning("Unsupported global key: %s", string);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
482
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
483
484


Uwe Schulzweida's avatar
Uwe Schulzweida committed
485
486
487
488
489
490
491
492
493
494
495
496
void cdiDefMissval(double missval)
{
  cdiInitialize();

  cdiDefaultMissval = missval;
}


double cdiInqMissval(void)
{
  cdiInitialize();

497
  return (cdiDefaultMissval);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
498
499
}

500
501
502
503
504
505
506
507
508
/*
 * Local Variables:
 * c-file-style: "Java"
 * c-basic-offset: 2
 * indent-tabs-mode: nil
 * show-trailing-whitespace: t
 * require-trailing-newline: t
 * End:
 */
509