zaxis.c 45.7 KB
Newer Older
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1
2
3
4
5
6
7
#include <string.h>
#include <math.h>
#include <float.h>

#include "dmemory.h"

#include "cdi.h"
8
#include "cdi_cksum.h"
9
#include "cdi_int.h"
10
#include "cdi_uuid.h"
11
#include "resource_handle.h"
12
#include "resource_unpack.h"
Deike Kleberg's avatar
Deike Kleberg committed
13
#include "namespace.h"
14
#include "serialize.h"
15
#include "zaxis.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
16

Deike Kleberg's avatar
Deike Kleberg committed
17
18
19
20
#define  LevelUp    1
#define  LevelDown  2


Thomas Jahns's avatar
Thomas Jahns committed
21
static const struct {
22
  unsigned char positive;   // 1: up;  2: down
Oliver Heidmann's avatar
Oliver Heidmann committed
23
24
25
26
  const char *name;
  const char *longname;
  const char *stdname;
  const char *units;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
27
}
28
ZaxistypeEntry[] = {
29
  { /*  0 */ 0, "sfc",               "surface",                "",               ""},
30
  { /*  1 */ 0, "lev",               "generic",                "",               ""},
31
32
  { /*  2 */ 2, "lev",               "hybrid",                 "",               "level"},
  { /*  3 */ 2, "lev",               "hybrid_half",            "",               "level"},
33
  { /*  4 */ 2, "plev",              "pressure",               "air_pressure",   "Pa"},
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
  { /*  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",              "",               ""},
54
  { /* 25 */ 0, "height",            "generalized_height",     "height",         ""},
Uwe Schulzweida's avatar
Uwe Schulzweida committed
55
  { /* 26 */ 0, "character",         "area_type",              "",               ""},
Uwe Schulzweida's avatar
Uwe Schulzweida committed
56
57
};

58
enum {
59
  CDI_NumZaxistype = sizeof(ZaxistypeEntry) / sizeof(ZaxistypeEntry[0]),
60
};
61

Uwe Schulzweida's avatar
Uwe Schulzweida committed
62

63
static int    zaxisCompareP    (zaxis_t *z1, zaxis_t *z2);
Deike Kleberg's avatar
Deike Kleberg committed
64
65
static void   zaxisDestroyP    ( void * zaxisptr );
static void   zaxisPrintP      ( void * zaxisptr, FILE * fp );
66
67
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
68
static int    zaxisTxCode      ( void );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
69

Thomas Jahns's avatar
Thomas Jahns committed
70
static const resOps zaxisOps = {
71
  (int (*)(void *, void *))zaxisCompareP,
72
73
74
75
76
  zaxisDestroyP,
  zaxisPrintP,
  zaxisGetPackSize,
  zaxisPack,
  zaxisTxCode
77
};
Uwe Schulzweida's avatar
Uwe Schulzweida committed
78

79
const resOps *getZaxisOps(void)
80
81
82
83
{
  return &zaxisOps;
}

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

86
void zaxisGetTypeDescription(int zaxisType, int *outPositive, const char **outName, const char **outLongName, const char **outStdName, const char **outUnit)
87
{
88
  if ( zaxisType < 0 || zaxisType >= CDI_NumZaxistype )
89
    {
90
91
92
93
94
      if (outPositive) *outPositive = 0;
      if (outName) *outName = NULL;
      if (outLongName) *outLongName = NULL;
      if (outStdName) *outStdName = NULL;
      if (outUnit) *outUnit = NULL;
95
96
97
    }
  else
    {
98
99
      if (outPositive) *outPositive = ZaxistypeEntry[zaxisType].positive;
      if (outName) *outName = ZaxistypeEntry[zaxisType].name;
100
      if (outLongName && zaxisType != ZAXIS_GENERIC) *outLongName = ZaxistypeEntry[zaxisType].longname;
101
102
      if (outStdName) *outStdName = ZaxistypeEntry[zaxisType].stdname;
      if (outUnit) *outUnit = ZaxistypeEntry[zaxisType].units;
103
104
105
    }
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
106
107
108
109
110
111

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

112
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
113
void zaxis_init(zaxis_t *zaxisptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
114
{
115
116
  zaxisptr->self          = CDI_UNDEFID;
  zaxisptr->vals          = NULL;
117
#ifndef USE_MPI
Uwe Schulzweida's avatar
Uwe Schulzweida committed
118
  zaxisptr->cvals         = NULL;
119
  zaxisptr->clength       = 0;
120
#endif
121
122
123
124
125
126
127
  zaxisptr->ubounds       = NULL;
  zaxisptr->lbounds       = NULL;
  zaxisptr->weights       = NULL;
  zaxisptr->type          = CDI_UNDEFID;
  zaxisptr->positive      = 0;
  zaxisptr->scalar        = 0;
  zaxisptr->direction     = 0;
128
  zaxisptr->datatype      = CDI_DATATYPE_FLT64;
129
130
131
  zaxisptr->size          = 0;
  zaxisptr->vctsize       = 0;
  zaxisptr->vct           = NULL;
132

Uwe Schulzweida's avatar
Uwe Schulzweida committed
133
  cdiInitKeys(&zaxisptr->keys);
134
135
  zaxisptr->atts.nalloc    = MAX_ATTRIBUTES;
  zaxisptr->atts.nelems    = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
136
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
137

138
static
139
zaxis_t *zaxisNewEntry(int id)
140
{
141
  zaxis_t *zaxisptr = (zaxis_t *) Malloc(sizeof(zaxis_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
142
  zaxis_init(zaxisptr);
143

144
  if ( id == CDI_UNDEFID )
145
146
147
148
149
150
    zaxisptr->self = reshPut(zaxisptr, &zaxisOps);
  else
    {
      zaxisptr->self = id;
      reshReplace(id, zaxisptr, &zaxisOps);
    }
151

152
  return zaxisptr;
153
154
}

155
static
156
void zaxisInit(void)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
157
{
158
  static bool zaxisInitialized = false;
159
  if ( zaxisInitialized ) return;
160
  zaxisInitialized = true;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
161

162
  const char *env = getenv("ZAXIS_DEBUG");
163
  if ( env ) ZAXIS_Debug = atoi(env);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
164
165
}

166
167
static
void zaxis_copy(zaxis_t *zaxisptr2, zaxis_t *zaxisptr1)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
168
{
169
  const int zaxisID2 = zaxisptr2->self;
170
  memcpy(zaxisptr2, zaxisptr1, sizeof(zaxis_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
171
  zaxisptr2->self = zaxisID2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
172
  cdiInitKeys(&zaxisptr2->keys);
173
  cdiCopyVarKeys(&zaxisptr1->keys, &zaxisptr2->keys);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
174
175
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
176

177
unsigned cdiZaxisCount(void)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
178
{
179
  return reshCountType(&zaxisOps);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
180
181
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
182
183
static
int zaxisCreate_(int zaxistype, int size, int id)
184
185
186
{
  zaxis_t *zaxisptr = zaxisNewEntry(id);

187
  xassert(size >= 0);
188
189
190
191
192
193
  zaxisptr->type = zaxistype;
  zaxisptr->size = size;

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

194
  const int zaxisID = zaxisptr->self;
195
  cdiDefKeyString(zaxisID, CDI_GLOBAL, CDI_KEY_NAME, ZaxistypeEntry[zaxistype].name);
196
  if ( zaxistype != ZAXIS_GENERIC ) zaxisDefLongname(zaxisID, ZaxistypeEntry[zaxistype].longname);
197
198
  zaxisDefUnits(zaxisID, ZaxistypeEntry[zaxistype].units);

199
200
  const char *stdname = ZaxistypeEntry[zaxistype].stdname;
  if ( *stdname )
201
    cdiDefVarKeyBytes(&zaxisptr->keys, CDI_KEY_STDNAME, (const unsigned char*)stdname, (int)strlen(stdname)+1);
202
203
204
205
206
207

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

  return zaxisID;
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
208
/*
209
@Function  zaxisCreate
210
@Title     Create a vertical Z-axis
Uwe Schulzweida's avatar
Uwe Schulzweida committed
211

212
@Prototype int zaxisCreate(int zaxistype, int size)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
213
214
@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
215
                      The valid CDI Z-axis types are @func{ZAXIS_GENERIC}, @func{ZAXIS_SURFACE},
Uwe Schulzweida's avatar
Uwe Schulzweida committed
216
                      @func{ZAXIS_HYBRID}, @func{ZAXIS_SIGMA}, @func{ZAXIS_PRESSURE}, @func{ZAXIS_HEIGHT},
217
218
                      @func{ZAXIS_ISENTROPIC}, @func{ZAXIS_ALTITUDE}, @func{ZAXIS_MEANSEA}, @func{ZAXIS_TOA},
                      @func{ZAXIS_SEA_BOTTOM}, @func{ZAXIS_ATMOSPHERE}, @func{ZAXIS_CLOUD_BASE},
219
                      @func{ZAXIS_CLOUD_TOP}, @func{ZAXIS_ISOTHERM_ZERO}, @func{ZAXIS_SNOW},
220
221
                      @func{ZAXIS_LAKE_BOTTOM}, @func{ZAXIS_SEDIMENT_BOTTOM}, @func{ZAXIS_SEDIMENT_BOTTOM_TA},
                      @func{ZAXIS_SEDIMENT_BOTTOM_TW}, @func{ZAXIS_MIX_LAYER},
222
                      @func{ZAXIS_DEPTH_BELOW_SEA} and @func{ZAXIS_DEPTH_BELOW_LAND}.
Deike Kleberg's avatar
Deike Kleberg committed
223
    @Item  size       Number of levels.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
224
225

@Description
226
The function @func{zaxisCreate} creates a vertical Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
227
228

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
231
@Example
232
Here is an example using @func{zaxisCreate} to create a pressure level Z-axis:
Uwe Schulzweida's avatar
Uwe Schulzweida committed
233
234
235
236

@Source
#include "cdi.h"
   ...
237
#define  nlev    5
Uwe Schulzweida's avatar
Uwe Schulzweida committed
238
   ...
239
double levs[nlev] = {101300, 92500, 85000, 50000, 20000};
Uwe Schulzweida's avatar
Uwe Schulzweida committed
240
241
int zaxisID;
   ...
242
zaxisID = zaxisCreate(ZAXIS_PRESSURE, nlev);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
243
244
245
zaxisDefLevels(zaxisID, levs);
   ...
@EndSource
Uwe Schulzweida's avatar
Uwe Schulzweida committed
246
247
@EndFunction
*/
248
int zaxisCreate(int zaxistype, int size)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
249
{
250
  if ( CDI_Debug ) Message("zaxistype: %d size: %d ", zaxistype, size);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
251

252
  xassert(size);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
253
254
  zaxisInit();

255
  return zaxisCreate_(zaxistype, size, CDI_UNDEFID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
256
257
}

258
259
static
void zaxisDestroyKernel( zaxis_t * zaxisptr )
260
{
Deike Kleberg's avatar
Deike Kleberg committed
261
  xassert ( zaxisptr );
262

263
  const int id = zaxisptr->self;
264

265
266
  if ( zaxisptr->vals ) Free( zaxisptr->vals );
#ifndef USE_MPI
267
268
269
270
271
272
  if ( zaxisptr->cvals )
    {
      for ( int i=0; i<zaxisptr->size; i++)
        Free(zaxisptr->cvals[i]);
      Free( zaxisptr->cvals );
    }
273
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
274
275
276
277
  if ( zaxisptr->lbounds ) Free( zaxisptr->lbounds );
  if ( zaxisptr->ubounds ) Free( zaxisptr->ubounds );
  if ( zaxisptr->weights ) Free( zaxisptr->weights );
  if ( zaxisptr->vct )     Free( zaxisptr->vct );
278

279
280
  cdiDeleteKeys(id, CDI_GLOBAL);
  cdiDeleteAtts(id, CDI_GLOBAL);
281

282
283
284
  Free(zaxisptr);

  reshRemove(id, &zaxisOps);
285
286
}

287
288
289
290
291
292
/*
@Function  zaxisDestroy
@Title     Destroy a vertical Z-axis

@Prototype void zaxisDestroy(int zaxisID)
@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
293
    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
294
295
296
297
298

@EndFunction
*/
void zaxisDestroy(int zaxisID)
{
299
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
300
  zaxisDestroyKernel(zaxisptr);
301
302
303
}


304
static
305
void zaxisDestroyP(void *zaxisptr)
306
{
307
  zaxisDestroyKernel((zaxis_t *) zaxisptr);
308
309
310
}


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


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

/*
@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
331
332
    @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
333
334

@Description
335
The function @func{zaxisDefName} defines the name of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
336
337
338
339
340

@EndFunction
*/
void zaxisDefName(int zaxisID, const char *name)
{
341
  (void)cdiDefKeyString(zaxisID, CDI_GLOBAL, CDI_KEY_NAME, name);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
342
343
344
345
346
347
348
349
}

/*
@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
350
351
    @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
352
353

@Description
354
The function @func{zaxisDefLongname} defines the longname of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
355
356
357
358
359

@EndFunction
*/
void zaxisDefLongname(int zaxisID, const char *longname)
{
360
  (void)cdiDefKeyString(zaxisID, CDI_GLOBAL, CDI_KEY_LONGNAME, longname);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
361
362
363
364
365
366
367
368
}

/*
@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
369
370
    @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
371
372

@Description
373
The function @func{zaxisDefUnits} defines the units of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
374
375
376
377
378

@EndFunction
*/
void zaxisDefUnits(int zaxisID, const char *units)
{
379
  (void)cdiDefKeyString(zaxisID, CDI_GLOBAL, CDI_KEY_UNITS, units);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
380
381
382
383
384
385
386
387
}

/*
@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
388
    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
Deike Kleberg's avatar
Deike Kleberg committed
389
    @Item  name     Name of the Z-axis. The caller must allocate space for the
Deike Kleberg's avatar
Deike Kleberg committed
390
                    returned string. The maximum possible length, in characters, of
391
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
392
393

@Description
394
The function @func{zaxisInqName} returns the name of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
395
396

@Result
397
@func{zaxisInqName} returns the name of the Z-axis to the parameter name.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
398
399
400
401
402

@EndFunction
*/
void zaxisInqName(int zaxisID, char *name)
{
403
404
  int length = CDI_MAX_NAME;
  (void)cdiInqKeyString(zaxisID, CDI_GLOBAL, CDI_KEY_NAME, name, &length);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
405
406
}

407
408
const char *zaxisInqNamePtr(int zaxisID)
{
409
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
410
  return cdiInqVarKeyString(&zaxisptr->keys, CDI_KEY_NAME);
411
412
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
413
414
415
416
417
418
/*
@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
419
    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
Deike Kleberg's avatar
Deike Kleberg committed
420
    @Item  longname Longname of the Z-axis. The caller must allocate space for the
Deike Kleberg's avatar
Deike Kleberg committed
421
                    returned string. The maximum possible length, in characters, of
422
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
423
424

@Description
425
The function @func{zaxisInqLongname} returns the longname of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
426
427

@Result
428
@func{zaxisInqLongname} returns the longname of the Z-axis to the parameter longname.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
429
430
431
432
433

@EndFunction
*/
void zaxisInqLongname(int zaxisID, char *longname)
{
434
435
  int length = CDI_MAX_NAME;
  (void)cdiInqKeyString(zaxisID, CDI_GLOBAL, CDI_KEY_LONGNAME, longname, &length);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
436
437
438
439
440
441
442
443
}

/*
@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
444
    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
Deike Kleberg's avatar
Deike Kleberg committed
445
    @Item  units    Units of the Z-axis. The caller must allocate space for the
Deike Kleberg's avatar
Deike Kleberg committed
446
                    returned string. The maximum possible length, in characters, of
447
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
448
449

@Description
450
The function @func{zaxisInqUnits} returns the units of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
451
452

@Result
453
@func{zaxisInqUnits} returns the units of the Z-axis to the parameter units.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
454
455
456
457
458

@EndFunction
*/
void zaxisInqUnits(int zaxisID, char *units)
{
459
460
  int length = CDI_MAX_NAME;
  (void)cdiInqKeyString(zaxisID, CDI_GLOBAL, CDI_KEY_UNITS, units, &length);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
461
462
463
}


Deike Kleberg's avatar
Deike Kleberg committed
464
465
void zaxisInqStdname(int zaxisID, char *stdname)
{
466
467
  int length = CDI_MAX_NAME;
  (void)cdiInqKeyString(zaxisID, CDI_GLOBAL, CDI_KEY_STDNAME, stdname, &length);
Deike Kleberg's avatar
Deike Kleberg committed
468
469
470
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
471
void zaxisDefDatatype(int zaxisID, int datatype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
472
{
473
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
474

Uwe Schulzweida's avatar
Uwe Schulzweida committed
475
  if ( zaxisptr->datatype != datatype )
476
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
477
      zaxisptr->datatype = datatype;
478
479
      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
480
481
482
}


483
int zaxisInqDatatype(int zaxisID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
484
{
485
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
486
  return zaxisptr->datatype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
487
488
489
}


490
491
void zaxisDefPositive(int zaxisID, int positive)
{
492
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
493

Uwe Schulzweida's avatar
Uwe Schulzweida committed
494
  if ( zaxisptr->positive != (unsigned)positive )
495
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
496
      zaxisptr->positive = (unsigned)positive;
497
498
      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
    }
499
500
501
}


Deike Kleberg's avatar
Deike Kleberg committed
502
503
int zaxisInqPositive(int zaxisID)
{
504
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
Thomas Jahns's avatar
Thomas Jahns committed
505
  return (int)zaxisptr->positive;
Deike Kleberg's avatar
Deike Kleberg committed
506
507
508
}


509
510
void zaxisDefScalar(int zaxisID)
{
511
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
512
513
514
515
516
517
518

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

int zaxisInqScalar(int zaxisID)
{
519
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
520
521
522
  return zaxisptr->scalar;
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
523
524
525
526
/*
@Function  zaxisDefLevels
@Title     Define the levels of a Z-axis

Uwe Schulzweida's avatar
Uwe Schulzweida committed
527
@Prototype void zaxisDefLevels(int zaxisID, const double *levels)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
528
@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
529
530
    @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
531
532

@Description
533
The function @func{zaxisDefLevels} defines the levels of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
534
535
536

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
537
void zaxisDefLevels(int zaxisID, const double *levels)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
538
{
539
540
  if ( levels )
    {
541
542
543
544
545
      zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
      const size_t size = (size_t)zaxisptr->size;
      xassert(size);

      if (zaxisptr->vals == NULL && size)
546
        zaxisptr->vals = (double*) Malloc(size*sizeof(double));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
547

548
      double *vals = zaxisptr->vals;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
549

550
551
      for ( size_t ilev = 0; ilev < size; ++ilev )
        vals[ilev] = levels[ilev];
552

553
554
      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
555
556
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
557

558
void zaxisDefCvals(int zaxisID, const char **cvals, int clen)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
559
{
560
#ifndef USE_MPI
561
  if ( cvals && clen )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
562
    {
563
564
565
566
      zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
      const size_t size = zaxisptr->size;
      xassert(size);

567
      zaxisptr->clength = clen;
568
      if (size) zaxisptr->cvals = (char**) Malloc(size*sizeof(char *));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
569

570
      for ( size_t ilev = 0; ilev < size; ++ilev )
571
        {
572
573
          zaxisptr->cvals[ilev] = (char*) Malloc(clen*sizeof(char));
          memcpy(zaxisptr->cvals[ilev], cvals[ilev], clen*sizeof(char));
574
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
575
576
      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
    }
577
578
579
#else
  Error("This function was disabled!");
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
580
581
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
582
583
584
585
586
587
/*
@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
588
589
590
    @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
591
592

@Description
593
The function @func{zaxisDefLevel} defines one level of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
594
595
596
597
598

@EndFunction
*/
void zaxisDefLevel(int zaxisID, int levelID, double level)
{
599
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
600
601
602
  const int size = zaxisptr->size;
  xassert(size);
  xassert(levelID >= 0 && levelID < size);
603

604
  if (zaxisptr->vals == NULL && size)
605
606
607
    zaxisptr->vals = (double*) Malloc((size_t)size*sizeof(double));

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

610
  reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
611
612
}

613

614
void zaxisDefNlevRef(int zaxisID, int nlev)
615
{
616
  cdiDefKeyInt(zaxisID, CDI_GLOBAL, CDI_KEY_NLEV, nlev);
617
618
619
620
621
}


int zaxisInqNlevRef(int zaxisID)
{
622
623
624
  int nlev = 0;
  cdiInqKeyInt(zaxisID, CDI_GLOBAL, CDI_KEY_NLEV, &nlev);
  return nlev;
625
626
}

627
/*
628
629
@Function  zaxisDefNumber
@Title     Define the reference number for a generalized Z-axis
630

631
@Prototype void zaxisDefNumber(int zaxisID, int number)
632
633
@Parameter
    @Item  zaxisID     Z-axis ID, from a previous call to @fref{zaxisCreate}.
634
    @Item  number      Reference number for a generalized Z-axis.
635
636

@Description
637
The function @func{zaxisDefNumber} defines the reference number for a generalized Z-axis.
638
639
640

@EndFunction
*/
641
void zaxisDefNumber(int zaxisID, int number)
642
{
643
  cdiDefKeyInt(zaxisID, CDI_GLOBAL, CDI_KEY_NUMBEROFVGRIDUSED, number);
644
645
}

646
647
648
649
650
651
/*
@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
652
    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
653
654
655
656
657
658
659
660
661
662

@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)
{
663
664
665
  int referenceNumber = 0;
  cdiInqKeyInt(zaxisID, CDI_GLOBAL, CDI_KEY_NUMBEROFVGRIDUSED, &referenceNumber);
  return referenceNumber;
666
667
}

668
669
670
671
672
673
674
675
676
677
678
679
680
681
/*
@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
*/
682
void zaxisDefUUID(int zaxisID, const unsigned char uuid[CDI_UUID_SIZE])
683
{
684
685
  cdiDefKeyBytes(zaxisID, CDI_GLOBAL, CDI_KEY_UUID, uuid, CDI_UUID_SIZE);

686
  reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
687
688
689
690
}

/*
@Function  zaxisInqUUID
691
@Title     Get the uuid to a generalized Z-axis
692

693
@Prototype void zaxisInqUUID(int zaxisID, char *uuid)
694
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
695
    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
696
    @Item uuid A user supplied buffer of at least 16 bytes.
697
698
699
700
701

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

@Result
702
@func{zaxisInqUUID} returns the UUID to a generalized Z-axis to the parameter uuid.
703
704
@EndFunction
*/
705
void zaxisInqUUID(int zaxisID, unsigned char uuid[CDI_UUID_SIZE])
706
{
707
708
709
  memset(uuid, 0, CDI_UUID_SIZE);
  int length = CDI_UUID_SIZE;
  cdiInqKeyBytes(zaxisID, CDI_GLOBAL, CDI_KEY_UUID, uuid, &length);
710
711
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
712
713
714
715
716
717
/*
@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
718
    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
Deike Kleberg's avatar
Deike Kleberg committed
719
    @Item  levelID  Level index (range: 0 to nlevel-1).
Uwe Schulzweida's avatar
Uwe Schulzweida committed
720
721

@Description
722
The function @func{zaxisInqLevel} returns one level of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
723
724

@Result
725
@func{zaxisInqLevel} returns the level of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
726
727
728
729
@EndFunction
*/
double zaxisInqLevel(int zaxisID, int levelID)
{
730
  double level = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
731
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
732
  if ( zaxisptr->vals && levelID >= 0 && levelID < zaxisptr->size )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
733
    level = zaxisptr->vals[levelID];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
734

735
  return level;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
736
737
}

738

739
double zaxisInqLbound(int zaxisID, int levelID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
740
{
741
  double level = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
742
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
743
744
  if ( zaxisptr->lbounds && levelID >= 0 && levelID < zaxisptr->size )
    level = zaxisptr->lbounds[levelID];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
745

746
  return level;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
747
748
749
}


750
double zaxisInqUbound(int zaxisID, int levelID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
751
{
752
  double level = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
753
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
754
755
756
  if ( zaxisptr->ubounds && levelID >= 0 && levelID < zaxisptr->size )
    level = zaxisptr->ubounds[levelID];

757
  return level;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
758
759
760
761
762
}


const double *zaxisInqLevelsPtr(int zaxisID)
{
763
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
764
  return zaxisptr->vals;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
765
766
}

767

768
#ifndef USE_MPI
769
char **zaxisInqCValsPtr(int zaxisID)
770
771
{
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
772
  return zaxisptr->cvals;
773
}
774
#endif
775

Uwe Schulzweida's avatar
Uwe Schulzweida committed
776
777
778
779
780
781
/*
@Function  zaxisInqLevels
@Title     Get all levels of a Z-axis

@Prototype void zaxisInqLevels(int zaxisID, double *levels)
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
782
    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
Deike Kleberg's avatar
Deike Kleberg committed
783
784
    @Item  levels   Pointer to the location into which the levels are read.
                    The caller must allocate space for the returned values.
Deike Kleberg's avatar
Deike Kleberg committed
785

Uwe Schulzweida's avatar
Uwe Schulzweida committed
786
@Description
787
The function @func{zaxisInqLevels} returns all levels of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
788
789

@Result
790
@func{zaxisInqLevels} saves all levels to the parameter @func{levels}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
791
792
@EndFunction
*/
793
int zaxisInqLevels(int zaxisID, double *levels)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
794
{
795
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
796

797
  int size = 0;
798
799
800
801
802
803
804
805
806
807
  if ( zaxisptr->vals )
    {
      size = zaxisptr->size;

      if ( levels )
        for ( int i = 0; i < size; i++ )
          levels[i] = zaxisptr->vals[i];
    }

  return size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
808
809
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
810

811
812
int zaxisInqCLen(int zaxisID)
{
813
  int clen = 0;
814
#ifndef USE_MPI
Uwe Schulzweida's avatar
Uwe Schulzweida committed
815
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
816
  if ( zaxisptr->cvals && zaxisptr->clength)
817
    clen = zaxisptr->clength;
818
#endif
819
820

  return clen;
821
822
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
823

824
int zaxisInqCVals(int zaxisID, char ***clevels)
825
{
826
  int size = 0;
827
#ifndef USE_MPI
Uwe Schulzweida's avatar
Uwe Schulzweida committed
828
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
829
830
831
  if ( zaxisptr->cvals )
    {
      size = zaxisptr->size;
832
      const size_t clen = zaxisptr->clength;
833
      if ( size && clen )
834
        {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
835
          (*clevels) = (char**) Malloc(size*sizeof(char*));
836
837
          for ( int i = 0; i < size; i++ )
            {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
838
              (*clevels)[i] = (char*) Malloc(clen*sizeof(char));
839
              memcpy((*clevels)[i], zaxisptr->cvals[i], clen*sizeof(char));
840
841
842
            }
          }
    }
843
#endif
844
845
846
847

  return size;
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
848
849
850

int zaxisInqLbounds(int zaxisID, double *lbounds)
{
851
  int size = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
852
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
853
  if ( zaxisptr->lbounds )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
854
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
855
      size = zaxisptr->size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
856
857

      if ( lbounds )
858
859
        for ( int i = 0; i < size; i++ )
          lbounds[i] = zaxisptr->lbounds[i];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
860
861
    }

862
  return size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
863
864
865
866
867
}


int zaxisInqUbounds(int zaxisID, double *ubounds)
{
868
  int size = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
869
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
870
  if ( zaxisptr->ubounds )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
871
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
872
      size = zaxisptr->size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
873
874

      if ( ubounds )
875
876
        for ( int i = 0; i < size; i++ )
          ubounds[i] = zaxisptr->ubounds[i];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
877
878
    }

879
  return size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
880
881
882
883
884
}


int zaxisInqWeights(int zaxisID, double *weights)
{
885
  int size = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
886
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
887
  if ( zaxisptr->weights )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
888
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
889
      size = zaxisptr->size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
890
891

      if ( weights )
Thomas Jahns's avatar
Thomas Jahns committed
892
        for ( int i = 0; i < size; i++ )
893
          weights[i] = zaxisptr->weights[i];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
894
895
    }

896
  return size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
897
898
899
900
901
}


int zaxisInqLevelID(int zaxisID, double level)
{
902
  int levelID = CDI_UNDEFID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
903
  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
904
905
  if ( zaxisptr->vals )
    {
906
      const int size = zaxisptr->size;
907
908
909
910
911
912
913
      for ( int i = 0; i < size; i++ )
        if ( fabs(level-zaxisptr->vals[i]) < DBL_EPSILON )
          {
            levelID = i;
            break;
          }