zaxis.c 53.1 KB
Newer Older
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1
2
3
4
5
6
7
8
9
10
11
#if defined (HAVE_CONFIG_H)
#  include "config.h"
#endif

#include <string.h>
#include <math.h>
#include <float.h>

#include "dmemory.h"

#include "cdi.h"
12
#include "cdi_cksum.h"
13
#include "cdi_int.h"
14
#include "cdi_uuid.h"
15
#include "resource_handle.h"
16
#include "resource_unpack.h"
17
#include "varscan.h"
Deike Kleberg's avatar
Deike Kleberg committed
18
#include "namespace.h"
19
#include "serialize.h"
20
#include "zaxis.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
21

Deike Kleberg's avatar
Deike Kleberg committed
22
23
24
25
#define  LevelUp    1
#define  LevelDown  2


Thomas Jahns's avatar
Thomas Jahns committed
26
static const struct {
27
  unsigned char positive;   // 1: up;  2: down
Oliver Heidmann's avatar
Oliver Heidmann committed
28
29
30
31
  const char *name;
  const char *longname;
  const char *stdname;
  const char *units;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
32
}
33
ZaxistypeEntry[] = {
34
  { /*  0 */ 0, "sfc",               "surface",                "",               ""},
35
  { /*  1 */ 0, "lev",               "generic",                "",               ""},
36
37
  { /*  2 */ 2, "lev",               "hybrid",                 "",               "level"},
  { /*  3 */ 2, "lev",               "hybrid_half",            "",               "level"},
38
  { /*  4 */ 2, "plev",              "pressure",               "air_pressure",   "Pa"},
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
  { /*  5 */ 1, "height",            "height",                 "height",         "m"},
  { /*  6 */ 2, "depth",             "depth_below_sea",        "depth",          "m"},
  { /*  7 */ 2, "depth",             "depth_below_land",       "",               "cm"},
  { /*  8 */ 0, "lev",               "isentropic",             "",               "K"},
  { /*  9 */ 0, "lev",               "trajectory",             "",               ""},
  { /* 10 */ 1, "alt",               "altitude",               "",               "m"},
  { /* 11 */ 0, "lev",               "sigma",                  "",               "level"},
  { /* 12 */ 0, "lev",               "meansea",                "",               "level"},
  { /* 13 */ 0, "toa",               "top_of_atmosphere",      "",               ""},
  { /* 14 */ 0, "seabottom",         "sea_bottom",             "",               ""},
  { /* 15 */ 0, "atmosphere",        "atmosphere",             "",               ""},
  { /* 16 */ 0, "cloudbase",         "cloud_base",             "",               ""},
  { /* 17 */ 0, "cloudtop",          "cloud_top",              "",               ""},
  { /* 18 */ 0, "isotherm0",         "isotherm_zero",          "",               ""},
  { /* 19 */ 0, "snow",              "snow",                   "",               ""},
  { /* 20 */ 0, "lakebottom",        "lake_bottom",            "",               ""},
  { /* 21 */ 0, "sedimentbottom",    "sediment_bottom",        "",               ""},
  { /* 22 */ 0, "sedimentbottomta",  "sediment_bottom_ta",     "",               ""},
  { /* 23 */ 0, "sedimentbottomtw",  "sediment_bottom_tw",     "",               ""},
  { /* 24 */ 0, "mixlayer",          "mix_layer",              "",               ""},
59
  { /* 25 */ 0, "height",            "generalized_height",     "height",         ""},
Uwe Schulzweida's avatar
Uwe Schulzweida committed
60
  { /* 26 */ 0, "character",         "area_type",              "",               ""},
Uwe Schulzweida's avatar
Uwe Schulzweida committed
61
62
};

63
enum {
64
  CDI_NumZaxistype = sizeof(ZaxistypeEntry) / sizeof(ZaxistypeEntry[0]),
65
};
66

Uwe Schulzweida's avatar
Uwe Schulzweida committed
67

68
static int    zaxisCompareP    (zaxis_t *z1, zaxis_t *z2);
Deike Kleberg's avatar
Deike Kleberg committed
69
70
static void   zaxisDestroyP    ( void * zaxisptr );
static void   zaxisPrintP      ( void * zaxisptr, FILE * fp );
71
72
static int    zaxisGetPackSize ( void * zaxisptr, void *context);
static void   zaxisPack        ( void * zaxisptr, void * buffer, int size, int *pos, void *context);
Deike Kleberg's avatar
Deike Kleberg committed
73
static int    zaxisTxCode      ( void );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
74

Thomas Jahns's avatar
Thomas Jahns committed
75
static const resOps zaxisOps = {
76
  (int (*)(void *, void *))zaxisCompareP,
77
78
79
80
81
  zaxisDestroyP,
  zaxisPrintP,
  zaxisGetPackSize,
  zaxisPack,
  zaxisTxCode
82
};
Uwe Schulzweida's avatar
Uwe Schulzweida committed
83

84
const resOps *getZaxisOps(void)
85
86
87
88
{
  return &zaxisOps;
}

89
static int  ZAXIS_Debug = 0;   /* If set to 1, debugging */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
90

91
void zaxisGetTypeDescription(int zaxisType, int *outPositive, const char **outName, const char **outLongName, const char **outStdName, const char **outUnit)
92
{
93
  if ( zaxisType < 0 || zaxisType >= CDI_NumZaxistype )
94
    {
95
96
97
98
99
      if (outPositive) *outPositive = 0;
      if (outName) *outName = NULL;
      if (outLongName) *outLongName = NULL;
      if (outStdName) *outStdName = NULL;
      if (outUnit) *outUnit = NULL;
100
101
102
    }
  else
    {
103
104
105
106
107
      if (outPositive) *outPositive = ZaxistypeEntry[zaxisType].positive;
      if (outName) *outName = ZaxistypeEntry[zaxisType].name;
      if (outLongName) *outLongName = ZaxistypeEntry[zaxisType].longname;
      if (outStdName) *outStdName = ZaxistypeEntry[zaxisType].stdname;
      if (outUnit) *outUnit = ZaxistypeEntry[zaxisType].units;
108
109
110
    }
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
111
112
113
114
115
116

zaxis_t *zaxis_to_pointer(int id)
{
  return (zaxis_t *)reshGetVal(id, &zaxisOps);
}

117
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
118
void zaxis_init(zaxis_t *zaxisptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
119
{
120
121
122
123
124
125
126
127
  zaxisptr->self          = CDI_UNDEFID;
  zaxisptr->name[0]       = 0;
  zaxisptr->longname[0]   = 0;
  zaxisptr->stdname[0]    = 0;
  zaxisptr->dimname[0]    = 0;
  zaxisptr->vdimname[0]   = 0;
  zaxisptr->units[0]      = 0;
  zaxisptr->psname[0]     = 0;
128
129
  zaxisptr->p0name[0]     = 0;
  zaxisptr->p0value.defined = false;
130
  zaxisptr->vals          = NULL;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
131
  zaxisptr->cvals         = NULL;
132
  zaxisptr->clength       = 0;
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
  zaxisptr->ubounds       = NULL;
  zaxisptr->lbounds       = NULL;
  zaxisptr->weights       = NULL;
  zaxisptr->type          = CDI_UNDEFID;
  zaxisptr->ltype         = 0;
  zaxisptr->ltype2        = -1;
  zaxisptr->positive      = 0;
  zaxisptr->scalar        = 0;
  zaxisptr->direction     = 0;
  zaxisptr->prec          = 0;
  zaxisptr->size          = 0;
  zaxisptr->vctsize       = 0;
  zaxisptr->vct           = NULL;
  zaxisptr->number        = 0;
  zaxisptr->nhlev         = 0;
Thomas Jahns's avatar
Thomas Jahns committed
148
  memset(zaxisptr->uuid, 0, CDI_UUID_SIZE);
149
150
  zaxisptr->atts.nalloc   = MAX_ATTRIBUTES;
  zaxisptr->atts.nelems   = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
151
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
152

153
static
154
zaxis_t *zaxisNewEntry(int id)
155
{
156
  zaxis_t *zaxisptr = (zaxis_t *) Malloc(sizeof(zaxis_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
157
  zaxis_init(zaxisptr);
158

159
  if ( id == CDI_UNDEFID )
160
161
162
163
164
165
    zaxisptr->self = reshPut(zaxisptr, &zaxisOps);
  else
    {
      zaxisptr->self = id;
      reshReplace(id, zaxisptr, &zaxisOps);
    }
166

167
  return zaxisptr;
168
169
}

170
static
171
void zaxisInit(void)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
172
{
173
  static bool zaxisInitialized = false;
174
  if ( zaxisInitialized ) return;
175
  zaxisInitialized = true;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
176

177
  const char *env = getenv("ZAXIS_DEBUG");
178
  if ( env ) ZAXIS_Debug = atoi(env);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
179
180
}

181
182
static
void zaxis_copy(zaxis_t *zaxisptr2, zaxis_t *zaxisptr1)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
183
{
184
  int zaxisID2 = zaxisptr2->self;
185
  memcpy(zaxisptr2, zaxisptr1, sizeof(zaxis_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
186
187
188
  zaxisptr2->self = zaxisID2;
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
189

190
unsigned cdiZaxisCount(void)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
191
{
192
  return reshCountType(&zaxisOps);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
193
194
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
195
196
static
int zaxisCreate_(int zaxistype, int size, int id)
197
198
199
{
  zaxis_t *zaxisptr = zaxisNewEntry(id);

200
  xassert(size >= 0);
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
  zaxisptr->type = zaxistype;
  zaxisptr->size = size;

  if ( zaxistype >= CDI_NumZaxistype || zaxistype < 0 )
    Error("Internal problem! zaxistype > CDI_MaxZaxistype");

  int zaxisID = zaxisptr->self;
  zaxisDefName(zaxisID, ZaxistypeEntry[zaxistype].name);
  zaxisDefLongname(zaxisID, ZaxistypeEntry[zaxistype].longname);
  zaxisDefUnits(zaxisID, ZaxistypeEntry[zaxistype].units);

  if ( *ZaxistypeEntry[zaxistype].stdname )
    strcpy(zaxisptr->stdname, ZaxistypeEntry[zaxistype].stdname);

  zaxisptr->positive = ZaxistypeEntry[zaxistype].positive;

  return zaxisID;
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
220
/*
221
@Function  zaxisCreate
222
@Title     Create a vertical Z-axis
Uwe Schulzweida's avatar
Uwe Schulzweida committed
223

224
@Prototype int zaxisCreate(int zaxistype, int size)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
225
226
@Parameter
    @Item  zaxistype  The type of the Z-axis, one of the set of predefined CDI Z-axis types.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
227
                      The valid CDI Z-axis types are @func{ZAXIS_GENERIC}, @func{ZAXIS_SURFACE},
Uwe Schulzweida's avatar
Uwe Schulzweida committed
228
                      @func{ZAXIS_HYBRID}, @func{ZAXIS_SIGMA}, @func{ZAXIS_PRESSURE}, @func{ZAXIS_HEIGHT},
229
230
                      @func{ZAXIS_ISENTROPIC}, @func{ZAXIS_ALTITUDE}, @func{ZAXIS_MEANSEA}, @func{ZAXIS_TOA},
                      @func{ZAXIS_SEA_BOTTOM}, @func{ZAXIS_ATMOSPHERE}, @func{ZAXIS_CLOUD_BASE},
231
                      @func{ZAXIS_CLOUD_TOP}, @func{ZAXIS_ISOTHERM_ZERO}, @func{ZAXIS_SNOW},
232
233
                      @func{ZAXIS_LAKE_BOTTOM}, @func{ZAXIS_SEDIMENT_BOTTOM}, @func{ZAXIS_SEDIMENT_BOTTOM_TA},
                      @func{ZAXIS_SEDIMENT_BOTTOM_TW}, @func{ZAXIS_MIX_LAYER},
234
                      @func{ZAXIS_DEPTH_BELOW_SEA} and @func{ZAXIS_DEPTH_BELOW_LAND}.
Deike Kleberg's avatar
Deike Kleberg committed
235
    @Item  size       Number of levels.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
236
237

@Description
238
The function @func{zaxisCreate} creates a vertical Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
239
240

@Result
241
@func{zaxisCreate} returns an identifier to the Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
242

Uwe Schulzweida's avatar
Uwe Schulzweida committed
243
@Example
244
Here is an example using @func{zaxisCreate} to create a pressure level Z-axis:
Uwe Schulzweida's avatar
Uwe Schulzweida committed
245
246
247
248

@Source
#include "cdi.h"
   ...
249
#define  nlev    5
Uwe Schulzweida's avatar
Uwe Schulzweida committed
250
   ...
251
double levs[nlev] = {101300, 92500, 85000, 50000, 20000};
Uwe Schulzweida's avatar
Uwe Schulzweida committed
252
253
int zaxisID;
   ...
254
zaxisID = zaxisCreate(ZAXIS_PRESSURE, nlev);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
255
256
257
zaxisDefLevels(zaxisID, levs);
   ...
@EndSource
Uwe Schulzweida's avatar
Uwe Schulzweida committed
258
259
@EndFunction
*/
260
int zaxisCreate(int zaxistype, int size)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
261
{
262
  if ( CDI_Debug ) Message("zaxistype: %d size: %d ", zaxistype, size);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
263

Uwe Schulzweida's avatar
Uwe Schulzweida committed
264
265
  zaxisInit();

266
  return zaxisCreate_(zaxistype, size, CDI_UNDEFID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
267
268
}

269
270
static
void zaxisDestroyKernel( zaxis_t * zaxisptr )
271
{
Deike Kleberg's avatar
Deike Kleberg committed
272
  xassert ( zaxisptr );
273

274
  int id = zaxisptr->self;
275

Uwe Schulzweida's avatar
Uwe Schulzweida committed
276
  if ( zaxisptr->vals )    Free( zaxisptr->vals );
277
278
279
280
281
282
  if ( zaxisptr->cvals )
    {
      for ( int i=0; i<zaxisptr->size; i++)
        Free(zaxisptr->cvals[i]);
      Free( zaxisptr->cvals );
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
283
284
285
286
  if ( zaxisptr->lbounds ) Free( zaxisptr->lbounds );
  if ( zaxisptr->ubounds ) Free( zaxisptr->ubounds );
  if ( zaxisptr->weights ) Free( zaxisptr->weights );
  if ( zaxisptr->vct )     Free( zaxisptr->vct );
287

Uwe Schulzweida's avatar
Uwe Schulzweida committed
288
  Free( zaxisptr );
289

290
  reshRemove ( id, &zaxisOps );
291
292
}

293
294
295
296
297
298
/*
@Function  zaxisDestroy
@Title     Destroy a vertical Z-axis

@Prototype void zaxisDestroy(int zaxisID)
@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
299
    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
300
301
302
303
304

@EndFunction
*/
void zaxisDestroy(int zaxisID)
{
305
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
306
  zaxisDestroyKernel(zaxisptr);
307
308
309
}


310
static
311
void zaxisDestroyP(void *zaxisptr)
312
{
313
  zaxisDestroyKernel((zaxis_t *) zaxisptr);
314
315
316
}


Oliver Heidmann's avatar
Oliver Heidmann committed
317
const char *zaxisNamePtr(int zaxistype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
318
{
Oliver Heidmann's avatar
Oliver Heidmann committed
319
  const char *name = (zaxistype >= 0 && zaxistype < CDI_NumZaxistype)
320
321
    ? ZaxistypeEntry[zaxistype].longname
    : ZaxistypeEntry[ZAXIS_GENERIC].longname;
322
  return name;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
323
324
325
326
327
328
329
330
}


void zaxisName(int zaxistype, char *zaxisname)
{
  strcpy(zaxisname, zaxisNamePtr(zaxistype));
}

331
332
333
static inline
void zaxisSetString(char *zaxisstrname, const char *name, size_t len)
{
334
  if ( len > CDI_MAX_NAME ) len = CDI_MAX_NAME;
335
  strncpy(zaxisstrname, name, len);
336
  zaxisstrname[len-1] = 0;
337
338
339
340
341
}

static inline
void zaxisGetString(char *name, const char *zaxisstrname, size_t len)
{
342
343
344
345
346
  size_t slen = strlen(zaxisstrname)+1;
  if ( slen > len ) slen = len;
  if ( slen > CDI_MAX_NAME ) slen = CDI_MAX_NAME;
  strncpy(name, zaxisstrname, slen);
  name[slen-1] = 0;
347
348
349
}

static
350
void *zaxis_key_to_ptr(zaxis_t *zaxisptr, int key)
351
{
352
  void *keyptr = NULL;
353
354
355

  switch (key)
    {
356
357
358
359
360
    case CDI_KEY_NAME:      keyptr = (void*)zaxisptr->name; break;
    case CDI_KEY_LONGNAME:  keyptr = (void*)zaxisptr->longname; break;
    case CDI_KEY_UNITS:     keyptr = (void*)zaxisptr->units; break;
    case CDI_KEY_DIMNAME:   keyptr = (void*)zaxisptr->dimname; break;
    case CDI_KEY_VDIMNAME:  keyptr = (void*)zaxisptr->vdimname; break;
361
    case CDI_KEY_PSNAME:    keyptr = (void*)zaxisptr->psname; break;
362
363
    case CDI_KEY_P0NAME:    keyptr = (void*)zaxisptr->p0name; break;
    case CDI_KEY_P0VALUE:   keyptr = (void*)&zaxisptr->p0value; break;
364
365
    }

366
  return keyptr;
367
368
369
}

/*
370
@Function  cdiZaxisDefKeyStr
371
372
@Title     Define a CDI Z-axis string value from a key

373
@Prototype int cdiZaxisDefKeyStr(int zaxisID, int key, int size, const char *mesg)
374
375
376
377
378
379
380
@Parameter
    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
    @Item  key      The key to be searched
    @Item  size     The allocated length of the string on input
    @Item  mesg     The address of a string where the data will be read

@Description
381
The function @func{cdiZaxisDefKeyStr} defines a CDI Z-axis string value from a key.
382
383

@Result
384
@func{cdiZaxisDefKeyStr} returns 0 if OK and integer value on error.
385
386
387

@EndFunction
*/
388
int cdiZaxisDefKeyStr(int zaxisID, int key, int size, const char *mesg)
389
{
390
  if ( size < 1 || mesg == NULL || *mesg == 0 ) return -1;
391

392
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
393

394
  char *keyptr = (char*)zaxis_key_to_ptr(zaxisptr, key);
395
  if ( keyptr == NULL)
396
397
398
399
400
    {
      Warning("CDI zaxis string key %d not supported!", key);
      return -1;
    }

401
  zaxisSetString(keyptr, mesg, (size_t)size);
402
403
404
405
406
407
  reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);

  return 0;
}

/*
408
@Function  cdiZaxisInqKeyStr
409
410
@Title     Get a CDI Z-axis string value from a key

411
@Prototype int cdiZaxisInqKeyStr(int zaxisID, int key, int size, char *mesg)
412
413
414
415
416
417
418
419
420
421
@Parameter
    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
    @Item  key      The key to be searched.
    @Item  size     The allocated length of the string on input.
    @Item  mesg     The address of a string where the data will be retrieved.
                    The caller must allocate space for the returned string.
                    The maximum possible length, in characters, of the string
                    is given by the predefined constant @func{CDI_MAX_NAME}.

@Description
422
The function @func{cdiZaxisInqKeyStr} return a CDI Z-axis string value from a key.
423
424

@Result
425
@func{cdiZaxisInqKeyStr} returns 0 if OK and integer value on error.
426
427
428

@EndFunction
*/
429
int cdiZaxisInqKeyStr(int zaxisID, int key, int size, char *mesg)
430
{
431
  if ( size < 1 || mesg == NULL ) return -1;
432

433
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
434
  const char *keyptr = (const char*)zaxis_key_to_ptr(zaxisptr, key);
435
  if ( keyptr == NULL)
436
437
438
439
440
    {
      Warning("CDI zaxis string key %d not supported!", key);
      return -1;
    }

441
  zaxisGetString(mesg, keyptr, (size_t)size);
442
443
444
445

  return 0;
}

446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
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
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518

/*
@Function  cdiZaxisDefKeyFlt
@Title     Define a CDI Z-axis floating point value from a key

@Prototype int cdiZaxisDefKeyFlt(int zaxisID, int key, double value)
@Parameter
    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
    @Item  key      The key to be searched
    @Item  value    A double where the data will be read

@Description
The function @func{cdiZaxisDefKeyFlt} defines a CDI Z-axis double value from a key.

@Result
@func{cdiZaxisDefKeyFlt} returns 0 if OK and integer value on error.

@EndFunction
*/
int cdiZaxisDefKeyFlt(int zaxisID, int key, double value)
{
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);

  zkey_double_t *keyptr = (zkey_double_t*)zaxis_key_to_ptr(zaxisptr, key);
  if ( keyptr == NULL)
    {
      Warning("CDI zaxis double key %d not supported!", key);
      return -1;
    }

  keyptr->value = value;
  keyptr->defined = true;

  reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);

  return 0;
}

/*
@Function  cdiZaxisInqKeyFlt
@Title     Get a CDI Z-axis floating point value from a key

@Prototype int cdiZaxisInqKeyFlt(int zaxisID, int key, double *value)
@Parameter
    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
    @Item  key      The key to be searched.
    @Item value     The address of a double where the data will be retrieved.

@Description
The function @func{cdiZaxisInqKeyFlt} return a CDI Z-axis double value from a key.

@Result
@func{cdiZaxisInqKeyFlt} returns 0 if OK and integer value on error.

@EndFunction
*/
int cdiZaxisInqKeyFlt(int zaxisID, int key, double *value)
{
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
  zkey_double_t *keyptr = (zkey_double_t*)zaxis_key_to_ptr(zaxisptr, key);
  if ( keyptr == NULL)
    {
      Warning("CDI zaxis double key %d not supported!", key);
      return -1;
    }

  if ( !keyptr->defined ) return 1;

  *value = keyptr->value;

  return 0;
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
519
520
521
522
523
524
/*
@Function  zaxisDefName
@Title     Define the name of a Z-axis

@Prototype void zaxisDefName(int zaxisID, const char *name)
@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
525
526
    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
    @Item  name     Name of the Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
527
528

@Description
529
The function @func{zaxisDefName} defines the name of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
530
531
532
533
534

@EndFunction
*/
void zaxisDefName(int zaxisID, const char *name)
{
535
  (void)cdiZaxisDefKeyStr(zaxisID, CDI_KEY_NAME, CDI_MAX_NAME, name);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
536
537
538
539
540
541
542
543
}

/*
@Function  zaxisDefLongname
@Title     Define the longname of a Z-axis

@Prototype void zaxisDefLongname(int zaxisID, const char *longname)
@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
544
545
    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
    @Item  longname Longname of the Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
546
547

@Description
548
The function @func{zaxisDefLongname} defines the longname of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
549
550
551
552
553

@EndFunction
*/
void zaxisDefLongname(int zaxisID, const char *longname)
{
554
  (void)cdiZaxisDefKeyStr(zaxisID, CDI_KEY_LONGNAME, CDI_MAX_NAME, longname);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
555
556
557
558
559
560
561
562
}

/*
@Function  zaxisDefUnits
@Title     Define the units of a Z-axis

@Prototype void zaxisDefUnits(int zaxisID, const char *units)
@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
563
564
    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
    @Item  units    Units of the Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
565
566

@Description
567
The function @func{zaxisDefUnits} defines the units of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
568
569
570
571
572

@EndFunction
*/
void zaxisDefUnits(int zaxisID, const char *units)
{
573
  (void)cdiZaxisDefKeyStr(zaxisID, CDI_KEY_UNITS, CDI_MAX_NAME, units);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
574
575
576
577
578
579
580
581
}

/*
@Function  zaxisInqName
@Title     Get the name of a Z-axis

@Prototype void zaxisInqName(int zaxisID, char *name)
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
582
    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
Deike Kleberg's avatar
Deike Kleberg committed
583
    @Item  name     Name of the Z-axis. The caller must allocate space for the
Deike Kleberg's avatar
Deike Kleberg committed
584
                    returned string. The maximum possible length, in characters, of
585
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
586
587

@Description
588
The function @func{zaxisInqName} returns the name of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
589
590

@Result
591
@func{zaxisInqName} returns the name of the Z-axis to the parameter name.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
592
593
594
595
596

@EndFunction
*/
void zaxisInqName(int zaxisID, char *name)
{
597
  (void)cdiZaxisInqKeyStr(zaxisID, CDI_KEY_NAME, CDI_MAX_NAME, name);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
598
599
}

600
601
const char *zaxisInqNamePtr(int zaxisID)
{
602
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
603
604
605
  return zaxisptr->name;
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
606
607
608
609
610
611
/*
@Function  zaxisInqLongname
@Title     Get the longname of a Z-axis

@Prototype void zaxisInqLongname(int zaxisID, char *longname)
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
612
    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
Deike Kleberg's avatar
Deike Kleberg committed
613
    @Item  longname Longname of the Z-axis. The caller must allocate space for the
Deike Kleberg's avatar
Deike Kleberg committed
614
                    returned string. The maximum possible length, in characters, of
615
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
616
617

@Description
618
The function @func{zaxisInqLongname} returns the longname of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
619
620

@Result
621
@func{zaxisInqLongname} returns the longname of the Z-axis to the parameter longname.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
622
623
624
625
626

@EndFunction
*/
void zaxisInqLongname(int zaxisID, char *longname)
{
627
  (void)cdiZaxisInqKeyStr(zaxisID, CDI_KEY_LONGNAME, CDI_MAX_NAME, longname);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
628
629
630
631
632
633
634
635
}

/*
@Function  zaxisInqUnits
@Title     Get the units of a Z-axis

@Prototype void zaxisInqUnits(int zaxisID, char *units)
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
636
    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
Deike Kleberg's avatar
Deike Kleberg committed
637
    @Item  units    Units of the Z-axis. The caller must allocate space for the
Deike Kleberg's avatar
Deike Kleberg committed
638
                    returned string. The maximum possible length, in characters, of
639
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
640
641

@Description
642
The function @func{zaxisInqUnits} returns the units of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
643
644

@Result
645
@func{zaxisInqUnits} returns the units of the Z-axis to the parameter units.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
646
647
648
649
650

@EndFunction
*/
void zaxisInqUnits(int zaxisID, char *units)
{
651
  (void)cdiZaxisInqKeyStr(zaxisID, CDI_KEY_UNITS, CDI_MAX_NAME, units);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
652
653
654
}


Deike Kleberg's avatar
Deike Kleberg committed
655
656
void zaxisInqStdname(int zaxisID, char *stdname)
{
657
658
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
  strcpy(stdname, zaxisptr->stdname);
Deike Kleberg's avatar
Deike Kleberg committed
659
660
661
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
662
663
void zaxisDefPrec(int zaxisID, int prec)
{
664
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
665

Uwe Schulzweida's avatar
Uwe Schulzweida committed
666
  if ( zaxisptr->prec != prec )
667
668
669
670
    {
      zaxisptr->prec = prec;
      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
671
672
673
674
675
}


int zaxisInqPrec(int zaxisID)
{
676
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
677
  return zaxisptr->prec;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
678
679
680
}


681
682
void zaxisDefPositive(int zaxisID, int positive)
{
683
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
684

Uwe Schulzweida's avatar
Uwe Schulzweida committed
685
  if ( zaxisptr->positive != (unsigned)positive )
686
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
687
      zaxisptr->positive = (unsigned)positive;
688
689
      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
    }
690
691
692
}


Deike Kleberg's avatar
Deike Kleberg committed
693
694
int zaxisInqPositive(int zaxisID)
{
695
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
Thomas Jahns's avatar
Thomas Jahns committed
696
  return (int)zaxisptr->positive;
Deike Kleberg's avatar
Deike Kleberg committed
697
698
699
}


700
701
void zaxisDefScalar(int zaxisID)
{
702
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
703
704
705
706
707
708
709

  zaxisptr->scalar = 1;
  reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
}

int zaxisInqScalar(int zaxisID)
{
710
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
711
712
713
714
  return zaxisptr->scalar;
}


715
716
void zaxisDefLtype(int zaxisID, int ltype)
{
717
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
718

719
720
721
722
723
  if (zaxisptr->ltype != ltype)
    {
      zaxisptr->ltype = ltype;
      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
    }
724
725
726
727
728
}


int zaxisInqLtype(int zaxisID)
{
729
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
730
  return zaxisptr->ltype;
731
732
}

733
734
735

void zaxisDefLtype2(int zaxisID, int ltype2)
{
736
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
737

Uwe Schulzweida's avatar
Uwe Schulzweida committed
738
  if ( zaxisptr->ltype2 != ltype2 )
739
740
741
742
743
744
745
746
747
    {
      zaxisptr->ltype2 = ltype2;
      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
    }
}


int zaxisInqLtype2(int zaxisID)
{
748
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
749
  return zaxisptr->ltype2;
750
751
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
752
753
754
755
/*
@Function  zaxisDefLevels
@Title     Define the levels of a Z-axis

Uwe Schulzweida's avatar
Uwe Schulzweida committed
756
@Prototype void zaxisDefLevels(int zaxisID, const double *levels)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
757
@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
758
759
    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
    @Item  levels   All levels of the Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
760
761

@Description
762
The function @func{zaxisDefLevels} defines the levels of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
763
764
765

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
766
void zaxisDefLevels(int zaxisID, const double *levels)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
767
{
768
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
769
770
  size_t size = (size_t)zaxisptr->size;

771
772
773
774
  if ( levels )
    {
      if ( zaxisptr->vals == NULL )
        zaxisptr->vals = (double*) Malloc(size*sizeof(double));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
775

776
      double *vals = zaxisptr->vals;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
777

778
779
      for ( size_t ilev = 0; ilev < size; ++ilev )
        vals[ilev] = levels[ilev];
780

781
782
      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
783
784
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
785

786
void zaxisDefCvals(int zaxisID, const char **cvals, int clen)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
787
788
{
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
789
  int size = zaxisptr->size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
790

791
  if ( cvals && clen )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
792
    {
793
      zaxisptr->clength = clen;
794
      zaxisptr->cvals = (char**) Malloc((size_t)size*sizeof(char *));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
795

796
      for ( int ilev = 0; ilev < size; ++ilev )
797
        {
798
799
          zaxisptr->cvals[ilev] = Malloc((size_t)clen*sizeof(char));
          memcpy(zaxisptr->cvals[ilev],cvals[ilev], (size_t)clen*sizeof(char));
800
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
801
802
803
804
      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
    }
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
805
806
807
808
809
810
/*
@Function  zaxisDefLevel
@Title     Define one level of a Z-axis

@Prototype void zaxisDefLevel(int zaxisID, int levelID, double level)
@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
811
812
813
    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
    @Item  levelID  Level identifier.
    @Item  level    Level.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
814
815

@Description
816
The function @func{zaxisDefLevel} defines one level of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
817
818
819
820
821

@EndFunction
*/
void zaxisDefLevel(int zaxisID, int levelID, double level)
{
822
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
823
824
825
826
827
828
  int size = zaxisptr->size;

  if ( zaxisptr->vals == NULL )
    zaxisptr->vals = (double*) Malloc((size_t)size*sizeof(double));

  if ( levelID >= 0 && levelID < size )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
829
    zaxisptr->vals[levelID] = level;
830

831
  reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
832
833
}

834
835
836

void zaxisDefNlevRef(int zaxisID, const int nhlev)
{
837
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
838
839
840
841
842
  if (zaxisptr->nhlev != nhlev)
    {
      zaxisptr->nhlev = nhlev;
      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
    }
843
844
845
846
847
}


int zaxisInqNlevRef(int zaxisID)
{
848
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
849
  return zaxisptr->nhlev;
850
851
}

852
/*
853
854
@Function  zaxisDefNumber
@Title     Define the reference number for a generalized Z-axis
855

856
@Prototype void zaxisDefNumber(int zaxisID, const int number)
857
858
@Parameter
    @Item  zaxisID     Z-axis ID, from a previous call to @fref{zaxisCreate}.
859
    @Item  number      Reference number for a generalized Z-axis.
860
861

@Description
862
The function @func{zaxisDefNumber} defines the reference number for a generalized Z-axis.
863
864
865

@EndFunction
*/
866
void zaxisDefNumber(int zaxisID, const int number)
867
{
868
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
869
870
871
872
873
  if (zaxisptr->number != number)
    {
      zaxisptr->number = number;
      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
    }
874
875
}

876
877
878
879
880
881
/*
@Function  zaxisInqNumber
@Title     Get the reference number to a generalized Z-axis

@Prototype int zaxisInqNumber(int zaxisID)
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
882
    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
883
884
885
886
887
888
889
890
891
892

@Description
The function @func{zaxisInqNumber} returns the reference number to a generalized Z-axis.

@Result
@func{zaxisInqNumber} returns the reference number to a generalized Z-axis.
@EndFunction
*/
int zaxisInqNumber(int zaxisID)
{
893
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
894
  return zaxisptr->number;
895
896
}

897
898
899
900
901
902
903
904
905
906
907
908
909
910
/*
@Function  zaxisDefUUID
@Title     Define the UUID for a genralized Z-axis

@Prototype void zaxisDefUUID(int zaxisID, const char *uuid)
@Parameter
    @Item  zaxisID     Z-axis ID, from a previous call to @fref{zaxisCreate}.
    @Item  uuid        UUID for a generalized Z-axis.

@Description
The function @func{zaxisDefUUID} defines the UUID for a generalized  Z-axis.

@EndFunction
*/
911
void zaxisDefUUID(int zaxisID, const unsigned char uuid[CDI_UUID_SIZE])
912
{
913
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
914
  memcpy(zaxisptr->uuid, uuid, CDI_UUID_SIZE);
915
  reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
916
917
918
919
}

/*
@Function  zaxisInqUUID
920
@Title     Get the uuid to a generalized Z-axis
921

922
@Prototype void zaxisInqUUID(int zaxisID, char *uuid)
923
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
924
    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
925
    @Item uuid A user supplied buffer of at least 16 bytes.
926
927
928
929
930

@Description
The function @func{zaxisInqUUID} returns the UUID to a generalized Z-axis.

@Result
931
@func{zaxisInqUUID} returns the UUID to a generalized Z-axis to the parameter uuid.
932
933
@EndFunction
*/
934
void zaxisInqUUID(int zaxisID, unsigned char uuid[CDI_UUID_SIZE])
935
{
936
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
937
  memcpy(uuid, zaxisptr->uuid, CDI_UUID_SIZE);
938
939
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
940
941
942
943
944
945
/*
@Function  zaxisInqLevel
@Title     Get one level of a Z-axis

@Prototype double zaxisInqLevel(int zaxisID, int levelID)
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
946
    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
Deike Kleberg's avatar
Deike Kleberg committed
947
    @Item  levelID  Level index (range: 0 to nlevel-1).
Uwe Schulzweida's avatar
Uwe Schulzweida committed
948
949

@Description
950
The function @func{zaxisInqLevel} returns one level of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
951
952

@Result
953
@func{zaxisInqLevel} returns the level of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
954
955
956
957
@EndFunction
*/
double zaxisInqLevel(int zaxisID, int levelID)
{
958
  double level = 0;
959
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
960

961
  if ( zaxisptr->vals && levelID >= 0 && levelID < zaxisptr->size )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
962
    level = zaxisptr->vals[levelID];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
963

964
  return level;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
965
966
}

967

968
double zaxisInqLbound(int zaxisID, int levelID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
969
{
970
  double level = 0;
971
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
972

973
974
  if ( zaxisptr->lbounds && levelID >= 0 && levelID < zaxisptr->size )
    level = zaxisptr->lbounds[levelID];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
975

976
  return level;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
977
978
979
}


980
double zaxisInqUbound(int zaxisID, int levelID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
981
{
982
  double level = 0;
983
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
984

985
986
987
  if ( zaxisptr->ubounds && levelID >= 0 && levelID < zaxisptr->size )
    level = zaxisptr->ubounds[levelID];

988
  return level;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
989
990
991
992
993
}


const double *zaxisInqLevelsPtr(int zaxisID)
{
994
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
995
  return zaxisptr->vals;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
996
997
}

998

999
char **zaxisInqCValsPtr(int zaxisID)
1000
{
For faster browsing, not all history is shown. View entire blame