1 #include <string.h>
2 #include <math.h>
3 #include <float.h>
4
5 #include "dmemory.h"
6
7 #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"
13 #include "namespace.h"
14 #include "serialize.h"
15 #include "zaxis.h"
16
17 #define LevelUp 1
18 #define LevelDown 2
19
20
21 static const struct {
22 unsigned char positive; // 1: up; 2: down
23 const char *name;
24 const char *longname;
25 const char *stdname;
26 const char *units;
27 }
28 ZaxistypeEntry[] = {
29 { /* 0 */ 0, "sfc", "surface", "", ""},
30 { /* 1 */ 0, "lev", "generic", "", ""},
31 { /* 2 */ 2, "lev", "hybrid", "", "level"},
32 { /* 3 */ 2, "lev", "hybrid_half", "", "level"},
33 { /* 4 */ 2, "plev", "pressure", "air_pressure", "Pa"},
34 { /* 5 */ 1, "height", "height", "height", "m"},
35 { /* 6 */ 2, "depth", "depth_below_sea", "depth", "m"},
36 { /* 7 */ 2, "depth", "depth_below_land", "", "cm"},
37 { /* 8 */ 0, "lev", "isentropic", "", "K"},
38 { /* 9 */ 0, "lev", "trajectory", "", ""},
39 { /* 10 */ 1, "alt", "altitude", "", "m"},
40 { /* 11 */ 0, "lev", "sigma", "", "level"},
41 { /* 12 */ 0, "lev", "meansea", "", "level"},
42 { /* 13 */ 0, "toa", "top_of_atmosphere", "", ""},
43 { /* 14 */ 0, "seabottom", "sea_bottom", "", ""},
44 { /* 15 */ 0, "atmosphere", "atmosphere", "", ""},
45 { /* 16 */ 0, "cloudbase", "cloud_base", "", ""},
46 { /* 17 */ 0, "cloudtop", "cloud_top", "", ""},
47 { /* 18 */ 0, "isotherm0", "isotherm_zero", "", ""},
48 { /* 19 */ 0, "snow", "snow", "", ""},
49 { /* 20 */ 0, "lakebottom", "lake_bottom", "", ""},
50 { /* 21 */ 0, "sedimentbottom", "sediment_bottom", "", ""},
51 { /* 22 */ 0, "sedimentbottomta", "sediment_bottom_ta", "", ""},
52 { /* 23 */ 0, "sedimentbottomtw", "sediment_bottom_tw", "", ""},
53 { /* 24 */ 0, "mixlayer", "mix_layer", "", ""},
54 { /* 25 */ 0, "height", "generalized_height", "height", ""},
55 { /* 26 */ 0, "character", "area_type", "", ""},
56 { /* 27 */ 0, "tropopause", "tropopause", "", ""},
57 };
58
59 enum {
60 CDI_NumZaxistype = sizeof(ZaxistypeEntry) / sizeof(ZaxistypeEntry[0]),
61 };
62
63
64 static int zaxisCompareP (zaxis_t *z1, zaxis_t *z2);
65 static void zaxisDestroyP (void *zaxisptr);
66 static void zaxisPrintP (void *zaxisptr, FILE *fp);
67 static int zaxisGetPackSize (void *zaxisptr, void *context);
68 static void zaxisPack (void *zaxisptr, void *buffer, int size, int *pos, void *context);
69 static int zaxisTxCode (void);
70
71 static const resOps zaxisOps = {
72 (int (*)(void *, void *))zaxisCompareP,
73 zaxisDestroyP,
74 zaxisPrintP,
75 zaxisGetPackSize,
76 zaxisPack,
77 zaxisTxCode
78 };
79
getZaxisOps(void)80 const resOps *getZaxisOps(void)
81 {
82 return &zaxisOps;
83 }
84
85 static int ZAXIS_Debug = 0; /* If set to 1, debugging */
86
zaxisGetTypeDescription(int zaxisType,int * outPositive,const char ** outName,const char ** outLongName,const char ** outStdName,const char ** outUnit)87 void zaxisGetTypeDescription(int zaxisType, int *outPositive, const char **outName, const char **outLongName, const char **outStdName, const char **outUnit)
88 {
89 if ( zaxisType < 0 || zaxisType >= CDI_NumZaxistype )
90 {
91 if (outPositive) *outPositive = 0;
92 if (outName) *outName = NULL;
93 if (outLongName) *outLongName = NULL;
94 if (outStdName) *outStdName = NULL;
95 if (outUnit) *outUnit = NULL;
96 }
97 else
98 {
99 if (outPositive) *outPositive = ZaxistypeEntry[zaxisType].positive;
100 if (outName) *outName = ZaxistypeEntry[zaxisType].name;
101 if (outLongName && zaxisType != ZAXIS_GENERIC) *outLongName = ZaxistypeEntry[zaxisType].longname;
102 if (outStdName) *outStdName = ZaxistypeEntry[zaxisType].stdname;
103 if (outUnit) *outUnit = ZaxistypeEntry[zaxisType].units;
104 }
105 }
106
107
zaxis_to_pointer(int id)108 zaxis_t *zaxis_to_pointer(int id)
109 {
110 return (zaxis_t *)reshGetVal(id, &zaxisOps);
111 }
112
113 static
zaxis_init(zaxis_t * zaxisptr)114 void zaxis_init(zaxis_t *zaxisptr)
115 {
116 zaxisptr->self = CDI_UNDEFID;
117 zaxisptr->vals = NULL;
118 #ifndef USE_MPI
119 zaxisptr->cvals = NULL;
120 zaxisptr->clength = 0;
121 #endif
122 zaxisptr->ubounds = NULL;
123 zaxisptr->lbounds = NULL;
124 zaxisptr->weights = NULL;
125 zaxisptr->type = CDI_UNDEFID;
126 zaxisptr->positive = 0;
127 zaxisptr->scalar = 0;
128 zaxisptr->direction = 0;
129 zaxisptr->size = 0;
130 zaxisptr->vctsize = 0;
131 zaxisptr->vct = NULL;
132
133 cdiInitKeys(&zaxisptr->keys);
134 zaxisptr->atts.nalloc = MAX_ATTRIBUTES;
135 zaxisptr->atts.nelems = 0;
136
137 cdiDefVarKeyInt(&zaxisptr->keys, CDI_KEY_DATATYPE, CDI_DATATYPE_FLT64);
138 }
139
140 static
zaxisNewEntry(int id)141 zaxis_t *zaxisNewEntry(int id)
142 {
143 zaxis_t *zaxisptr = (zaxis_t *) Malloc(sizeof(zaxis_t));
144 zaxis_init(zaxisptr);
145
146 if ( id == CDI_UNDEFID )
147 zaxisptr->self = reshPut(zaxisptr, &zaxisOps);
148 else
149 {
150 zaxisptr->self = id;
151 reshReplace(id, zaxisptr, &zaxisOps);
152 }
153
154 return zaxisptr;
155 }
156
157 static
zaxisInit(void)158 void zaxisInit(void)
159 {
160 static bool zaxisInitialized = false;
161 if ( zaxisInitialized ) return;
162 zaxisInitialized = true;
163
164 const char *env = getenv("ZAXIS_DEBUG");
165 if ( env ) ZAXIS_Debug = atoi(env);
166 }
167
168 static
zaxis_copy(zaxis_t * zaxisptr2,zaxis_t * zaxisptr1)169 void zaxis_copy(zaxis_t *zaxisptr2, zaxis_t *zaxisptr1)
170 {
171 const int zaxisID2 = zaxisptr2->self;
172 memcpy(zaxisptr2, zaxisptr1, sizeof(zaxis_t));
173 zaxisptr2->self = zaxisID2;
174 cdiInitKeys(&zaxisptr2->keys);
175 cdiCopyVarKeys(&zaxisptr1->keys, &zaxisptr2->keys);
176 }
177
178
cdiZaxisCount(void)179 unsigned cdiZaxisCount(void)
180 {
181 return reshCountType(&zaxisOps);
182 }
183
184 static
zaxisCreate_(int zaxistype,int size,int id)185 int zaxisCreate_(int zaxistype, int size, int id)
186 {
187 zaxis_t *zaxisptr = zaxisNewEntry(id);
188
189 xassert(size >= 0);
190 zaxisptr->type = zaxistype;
191 zaxisptr->size = size;
192
193 if ( zaxistype >= CDI_NumZaxistype || zaxistype < 0 )
194 Error("Internal problem! zaxistype=%d out of range (min=0/max=%d)!", zaxistype, CDI_NumZaxistype-1);
195
196 const int zaxisID = zaxisptr->self;
197 cdiDefKeyString(zaxisID, CDI_GLOBAL, CDI_KEY_NAME, ZaxistypeEntry[zaxistype].name);
198 if ( zaxistype != ZAXIS_GENERIC ) zaxisDefLongname(zaxisID, ZaxistypeEntry[zaxistype].longname);
199 cdiDefKeyString(zaxisID, CDI_GLOBAL, CDI_KEY_UNITS, ZaxistypeEntry[zaxistype].units);
200
201 const char *stdname = ZaxistypeEntry[zaxistype].stdname;
202 if ( *stdname )
203 cdiDefVarKeyBytes(&zaxisptr->keys, CDI_KEY_STDNAME, (const unsigned char*)stdname, (int)strlen(stdname)+1);
204
205 zaxisptr->positive = ZaxistypeEntry[zaxistype].positive;
206
207 return zaxisID;
208 }
209
210 /*
211 @Function zaxisCreate
212 @Title Create a vertical Z-axis
213
214 @Prototype int zaxisCreate(int zaxistype, int size)
215 @Parameter
216 @Item zaxistype The type of the Z-axis, one of the set of predefined CDI Z-axis types.
217 The valid CDI Z-axis types are @func{ZAXIS_GENERIC}, @func{ZAXIS_SURFACE},
218 @func{ZAXIS_HYBRID}, @func{ZAXIS_SIGMA}, @func{ZAXIS_PRESSURE}, @func{ZAXIS_HEIGHT},
219 @func{ZAXIS_ISENTROPIC}, @func{ZAXIS_ALTITUDE}, @func{ZAXIS_MEANSEA}, @func{ZAXIS_TOA},
220 @func{ZAXIS_SEA_BOTTOM}, @func{ZAXIS_ATMOSPHERE}, @func{ZAXIS_CLOUD_BASE},
221 @func{ZAXIS_CLOUD_TOP}, @func{ZAXIS_ISOTHERM_ZERO}, @func{ZAXIS_SNOW},
222 @func{ZAXIS_LAKE_BOTTOM}, @func{ZAXIS_SEDIMENT_BOTTOM}, @func{ZAXIS_SEDIMENT_BOTTOM_TA},
223 @func{ZAXIS_SEDIMENT_BOTTOM_TW}, @func{ZAXIS_MIX_LAYER},
224 @func{ZAXIS_DEPTH_BELOW_SEA} and @func{ZAXIS_DEPTH_BELOW_LAND}.
225 @Item size Number of levels.
226
227 @Description
228 The function @func{zaxisCreate} creates a vertical Z-axis.
229
230 @Result
231 @func{zaxisCreate} returns an identifier to the Z-axis.
232
233 @Example
234 Here is an example using @func{zaxisCreate} to create a pressure level Z-axis:
235
236 @Source
237 #include "cdi.h"
238 ...
239 #define nlev 5
240 ...
241 double levs[nlev] = {101300, 92500, 85000, 50000, 20000};
242 int zaxisID;
243 ...
244 zaxisID = zaxisCreate(ZAXIS_PRESSURE, nlev);
245 zaxisDefLevels(zaxisID, levs);
246 ...
247 @EndSource
248 @EndFunction
249 */
zaxisCreate(int zaxistype,int size)250 int zaxisCreate(int zaxistype, int size)
251 {
252 if ( CDI_Debug ) Message("zaxistype: %d size: %d ", zaxistype, size);
253
254 xassert(size);
255 zaxisInit();
256
257 return zaxisCreate_(zaxistype, size, CDI_UNDEFID);
258 }
259
260 static
zaxisDestroyKernel(zaxis_t * zaxisptr)261 void zaxisDestroyKernel( zaxis_t * zaxisptr )
262 {
263 xassert ( zaxisptr );
264
265 const int id = zaxisptr->self;
266
267 if ( zaxisptr->vals ) Free( zaxisptr->vals );
268 #ifndef USE_MPI
269 if ( zaxisptr->cvals )
270 {
271 for ( int i=0; i<zaxisptr->size; i++)
272 Free(zaxisptr->cvals[i]);
273 Free( zaxisptr->cvals );
274 }
275 #endif
276 if ( zaxisptr->lbounds ) Free( zaxisptr->lbounds );
277 if ( zaxisptr->ubounds ) Free( zaxisptr->ubounds );
278 if ( zaxisptr->weights ) Free( zaxisptr->weights );
279 if ( zaxisptr->vct ) Free( zaxisptr->vct );
280
281 cdiDeleteKeys(id, CDI_GLOBAL);
282 cdiDeleteAtts(id, CDI_GLOBAL);
283
284 Free(zaxisptr);
285
286 reshRemove(id, &zaxisOps);
287 }
288
289 /*
290 @Function zaxisDestroy
291 @Title Destroy a vertical Z-axis
292
293 @Prototype void zaxisDestroy(int zaxisID)
294 @Parameter
295 @Item zaxisID Z-axis ID, from a previous call to @fref{zaxisCreate}.
296
297 @EndFunction
298 */
zaxisDestroy(int zaxisID)299 void zaxisDestroy(int zaxisID)
300 {
301 zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
302 zaxisDestroyKernel(zaxisptr);
303 }
304
305
306 static
zaxisDestroyP(void * zaxisptr)307 void zaxisDestroyP(void *zaxisptr)
308 {
309 zaxisDestroyKernel((zaxis_t *) zaxisptr);
310 }
311
312
zaxisNamePtr(int zaxistype)313 const char *zaxisNamePtr(int zaxistype)
314 {
315 const char *name = (zaxistype >= 0 && zaxistype < CDI_NumZaxistype)
316 ? ZaxistypeEntry[zaxistype].longname
317 : ZaxistypeEntry[ZAXIS_GENERIC].longname;
318 return name;
319 }
320
321
zaxisName(int zaxistype,char * zaxisname)322 void zaxisName(int zaxistype, char *zaxisname)
323 {
324 strcpy(zaxisname, zaxisNamePtr(zaxistype));
325 }
326
327 /*
328 @Function zaxisDefName
329 @Title Define the name of a Z-axis
330
331 @Prototype void zaxisDefName(int zaxisID, const char *name)
332 @Parameter
333 @Item zaxisID Z-axis ID, from a previous call to @fref{zaxisCreate}.
334 @Item name Name of the Z-axis.
335
336 @Description
337 The function @func{zaxisDefName} defines the name of a Z-axis.
338
339 @EndFunction
340 */
zaxisDefName(int zaxisID,const char * name)341 void zaxisDefName(int zaxisID, const char *name)
342 {
343 (void)cdiDefKeyString(zaxisID, CDI_GLOBAL, CDI_KEY_NAME, name);
344 }
345
346 /*
347 @Function zaxisDefLongname
348 @Title Define the longname of a Z-axis
349
350 @Prototype void zaxisDefLongname(int zaxisID, const char *longname)
351 @Parameter
352 @Item zaxisID Z-axis ID, from a previous call to @fref{zaxisCreate}.
353 @Item longname Longname of the Z-axis.
354
355 @Description
356 The function @func{zaxisDefLongname} defines the longname of a Z-axis.
357
358 @EndFunction
359 */
zaxisDefLongname(int zaxisID,const char * longname)360 void zaxisDefLongname(int zaxisID, const char *longname)
361 {
362 (void)cdiDefKeyString(zaxisID, CDI_GLOBAL, CDI_KEY_LONGNAME, longname);
363 }
364
365 /*
366 @Function zaxisDefUnits
367 @Title Define the units of a Z-axis
368
369 @Prototype void zaxisDefUnits(int zaxisID, const char *units)
370 @Parameter
371 @Item zaxisID Z-axis ID, from a previous call to @fref{zaxisCreate}.
372 @Item units Units of the Z-axis.
373
374 @Description
375 The function @func{zaxisDefUnits} defines the units of a Z-axis.
376
377 @EndFunction
378 */
zaxisDefUnits(int zaxisID,const char * units)379 void zaxisDefUnits(int zaxisID, const char *units)
380 {
381 (void)cdiDefKeyString(zaxisID, CDI_GLOBAL, CDI_KEY_UNITS, units);
382 }
383
384 /*
385 @Function zaxisInqName
386 @Title Get the name of a Z-axis
387
388 @Prototype void zaxisInqName(int zaxisID, char *name)
389 @Parameter
390 @Item zaxisID Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
391 @Item name Name of the Z-axis. The caller must allocate space for the
392 returned string. The maximum possible length, in characters, of
393 the string is given by the predefined constant @func{CDI_MAX_NAME}.
394
395 @Description
396 The function @func{zaxisInqName} returns the name of a Z-axis.
397
398 @Result
399 @func{zaxisInqName} returns the name of the Z-axis to the parameter name.
400
401 @EndFunction
402 */
zaxisInqName(int zaxisID,char * name)403 void zaxisInqName(int zaxisID, char *name)
404 {
405 int length = CDI_MAX_NAME;
406 (void)cdiInqKeyString(zaxisID, CDI_GLOBAL, CDI_KEY_NAME, name, &length);
407 }
408
zaxisInqNamePtr(int zaxisID)409 const char *zaxisInqNamePtr(int zaxisID)
410 {
411 zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
412 return cdiInqVarKeyString(&zaxisptr->keys, CDI_KEY_NAME);
413 }
414
415 /*
416 @Function zaxisInqLongname
417 @Title Get the longname of a Z-axis
418
419 @Prototype void zaxisInqLongname(int zaxisID, char *longname)
420 @Parameter
421 @Item zaxisID Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
422 @Item longname Longname of the Z-axis. The caller must allocate space for the
423 returned string. The maximum possible length, in characters, of
424 the string is given by the predefined constant @func{CDI_MAX_NAME}.
425
426 @Description
427 The function @func{zaxisInqLongname} returns the longname of a Z-axis.
428
429 @Result
430 @func{zaxisInqLongname} returns the longname of the Z-axis to the parameter longname.
431
432 @EndFunction
433 */
zaxisInqLongname(int zaxisID,char * longname)434 void zaxisInqLongname(int zaxisID, char *longname)
435 {
436 int length = CDI_MAX_NAME;
437 (void)cdiInqKeyString(zaxisID, CDI_GLOBAL, CDI_KEY_LONGNAME, longname, &length);
438 }
439
440 /*
441 @Function zaxisInqUnits
442 @Title Get the units of a Z-axis
443
444 @Prototype void zaxisInqUnits(int zaxisID, char *units)
445 @Parameter
446 @Item zaxisID Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
447 @Item units Units of the Z-axis. The caller must allocate space for the
448 returned string. The maximum possible length, in characters, of
449 the string is given by the predefined constant @func{CDI_MAX_NAME}.
450
451 @Description
452 The function @func{zaxisInqUnits} returns the units of a Z-axis.
453
454 @Result
455 @func{zaxisInqUnits} returns the units of the Z-axis to the parameter units.
456
457 @EndFunction
458 */
zaxisInqUnits(int zaxisID,char * units)459 void zaxisInqUnits(int zaxisID, char *units)
460 {
461 int length = CDI_MAX_NAME;
462 (void)cdiInqKeyString(zaxisID, CDI_GLOBAL, CDI_KEY_UNITS, units, &length);
463 }
464
465
zaxisInqStdname(int zaxisID,char * stdname)466 void zaxisInqStdname(int zaxisID, char *stdname)
467 {
468 int length = CDI_MAX_NAME;
469 (void)cdiInqKeyString(zaxisID, CDI_GLOBAL, CDI_KEY_STDNAME, stdname, &length);
470 }
471
472
zaxisDefDatatype(int zaxisID,int datatype)473 void zaxisDefDatatype(int zaxisID, int datatype)
474 {
475 cdiDefKeyInt(zaxisID, CDI_GLOBAL, CDI_KEY_DATATYPE, datatype);
476 }
477
478
zaxisInqDatatype(int zaxisID)479 int zaxisInqDatatype(int zaxisID)
480 {
481 int datatype = 0;
482 cdiInqKeyInt(zaxisID, CDI_GLOBAL, CDI_KEY_DATATYPE, &datatype);
483 return datatype;
484 }
485
486
zaxisDefPositive(int zaxisID,int positive)487 void zaxisDefPositive(int zaxisID, int positive)
488 {
489 zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
490
491 if ( zaxisptr->positive != (unsigned)positive )
492 {
493 zaxisptr->positive = (unsigned)positive;
494 reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
495 }
496 }
497
498
zaxisInqPositive(int zaxisID)499 int zaxisInqPositive(int zaxisID)
500 {
501 zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
502 return (int)zaxisptr->positive;
503 }
504
505
zaxisDefScalar(int zaxisID)506 void zaxisDefScalar(int zaxisID)
507 {
508 zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
509
510 zaxisptr->scalar = 1;
511 reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
512 }
513
zaxisInqScalar(int zaxisID)514 int zaxisInqScalar(int zaxisID)
515 {
516 zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
517 return zaxisptr->scalar;
518 }
519
520 /*
521 @Function zaxisDefLevels
522 @Title Define the levels of a Z-axis
523
524 @Prototype void zaxisDefLevels(int zaxisID, const double *levels)
525 @Parameter
526 @Item zaxisID Z-axis ID, from a previous call to @fref{zaxisCreate}.
527 @Item levels All levels of the Z-axis.
528
529 @Description
530 The function @func{zaxisDefLevels} defines the levels of a Z-axis.
531
532 @EndFunction
533 */
zaxisDefLevels(int zaxisID,const double * levels)534 void zaxisDefLevels(int zaxisID, const double *levels)
535 {
536 if ( levels )
537 {
538 zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
539 const size_t size = (size_t)zaxisptr->size;
540 xassert(size);
541
542 if (zaxisptr->vals == NULL && size)
543 zaxisptr->vals = (double*) Malloc(size*sizeof(double));
544
545 double *vals = zaxisptr->vals;
546
547 for ( size_t ilev = 0; ilev < size; ++ilev )
548 vals[ilev] = levels[ilev];
549
550 reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
551 }
552 }
553
554
zaxisDefCvals(int zaxisID,const char ** cvals,int clen)555 void zaxisDefCvals(int zaxisID, const char **cvals, int clen)
556 {
557 #ifndef USE_MPI
558 if ( cvals && clen )
559 {
560 zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
561 const size_t size = zaxisptr->size;
562 xassert(size);
563
564 zaxisptr->clength = clen;
565 if (size) zaxisptr->cvals = (char**) Malloc(size*sizeof(char *));
566
567 for ( size_t ilev = 0; ilev < size; ++ilev )
568 {
569 zaxisptr->cvals[ilev] = (char*) Malloc(clen*sizeof(char));
570 memcpy(zaxisptr->cvals[ilev], cvals[ilev], clen*sizeof(char));
571 }
572 reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
573 }
574 #else
575 Error("This function was disabled!");
576 #endif
577 }
578
579 /*
580 @Function zaxisDefLevel
581 @Title Define one level of a Z-axis
582
583 @Prototype void zaxisDefLevel(int zaxisID, int levelID, double level)
584 @Parameter
585 @Item zaxisID Z-axis ID, from a previous call to @fref{zaxisCreate}.
586 @Item levelID Level identifier.
587 @Item level Level.
588
589 @Description
590 The function @func{zaxisDefLevel} defines one level of a Z-axis.
591
592 @EndFunction
593 */
zaxisDefLevel(int zaxisID,int levelID,double level)594 void zaxisDefLevel(int zaxisID, int levelID, double level)
595 {
596 zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
597 const int size = zaxisptr->size;
598 xassert(size);
599 xassert(levelID >= 0 && levelID < size);
600
601 if (zaxisptr->vals == NULL && size)
602 zaxisptr->vals = (double*) Malloc((size_t)size*sizeof(double));
603
604 if ( levelID >= 0 && levelID < size )
605 zaxisptr->vals[levelID] = level;
606
607 reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
608 }
609
610
zaxisDefNlevRef(int zaxisID,int nlev)611 void zaxisDefNlevRef(int zaxisID, int nlev)
612 {
613 cdiDefKeyInt(zaxisID, CDI_GLOBAL, CDI_KEY_NLEV, nlev);
614 }
615
616
zaxisInqNlevRef(int zaxisID)617 int zaxisInqNlevRef(int zaxisID)
618 {
619 int nlev = 0;
620 cdiInqKeyInt(zaxisID, CDI_GLOBAL, CDI_KEY_NLEV, &nlev);
621 return nlev;
622 }
623
624 /*
625 @Function zaxisDefNumber
626 @Title Define the reference number for a generalized Z-axis
627
628 @Prototype void zaxisDefNumber(int zaxisID, int number)
629 @Parameter
630 @Item zaxisID Z-axis ID, from a previous call to @fref{zaxisCreate}.
631 @Item number Reference number for a generalized Z-axis.
632
633 @Description
634 The function @func{zaxisDefNumber} defines the reference number for a generalized Z-axis.
635
636 @EndFunction
637 */
zaxisDefNumber(int zaxisID,int number)638 void zaxisDefNumber(int zaxisID, int number)
639 {
640 cdiDefKeyInt(zaxisID, CDI_GLOBAL, CDI_KEY_NUMBEROFVGRIDUSED, number);
641 }
642
643 /*
644 @Function zaxisInqNumber
645 @Title Get the reference number to a generalized Z-axis
646
647 @Prototype int zaxisInqNumber(int zaxisID)
648 @Parameter
649 @Item zaxisID Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
650
651 @Description
652 The function @func{zaxisInqNumber} returns the reference number to a generalized Z-axis.
653
654 @Result
655 @func{zaxisInqNumber} returns the reference number to a generalized Z-axis.
656 @EndFunction
657 */
zaxisInqNumber(int zaxisID)658 int zaxisInqNumber(int zaxisID)
659 {
660 int referenceNumber = 0;
661 cdiInqKeyInt(zaxisID, CDI_GLOBAL, CDI_KEY_NUMBEROFVGRIDUSED, &referenceNumber);
662 return referenceNumber;
663 }
664
665 /*
666 @Function zaxisDefUUID
667 @Title Define the UUID for a genralized Z-axis
668
669 @Prototype void zaxisDefUUID(int zaxisID, const char *uuid)
670 @Parameter
671 @Item zaxisID Z-axis ID, from a previous call to @fref{zaxisCreate}.
672 @Item uuid UUID for a generalized Z-axis.
673
674 @Description
675 The function @func{zaxisDefUUID} defines the UUID for a generalized Z-axis.
676
677 @EndFunction
678 */
zaxisDefUUID(int zaxisID,const unsigned char uuid[CDI_UUID_SIZE])679 void zaxisDefUUID(int zaxisID, const unsigned char uuid[CDI_UUID_SIZE])
680 {
681 cdiDefKeyBytes(zaxisID, CDI_GLOBAL, CDI_KEY_UUID, uuid, CDI_UUID_SIZE);
682
683 reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
684 }
685
686 /*
687 @Function zaxisInqUUID
688 @Title Get the uuid to a generalized Z-axis
689
690 @Prototype void zaxisInqUUID(int zaxisID, char *uuid)
691 @Parameter
692 @Item zaxisID Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
693 @Item uuid A user supplied buffer of at least 16 bytes.
694
695 @Description
696 The function @func{zaxisInqUUID} returns the UUID to a generalized Z-axis.
697
698 @Result
699 @func{zaxisInqUUID} returns the UUID to a generalized Z-axis to the parameter uuid.
700 @EndFunction
701 */
zaxisInqUUID(int zaxisID,unsigned char uuid[CDI_UUID_SIZE])702 void zaxisInqUUID(int zaxisID, unsigned char uuid[CDI_UUID_SIZE])
703 {
704 memset(uuid, 0, CDI_UUID_SIZE);
705 int length = CDI_UUID_SIZE;
706 cdiInqKeyBytes(zaxisID, CDI_GLOBAL, CDI_KEY_UUID, uuid, &length);
707 }
708
709 /*
710 @Function zaxisInqLevel
711 @Title Get one level of a Z-axis
712
713 @Prototype double zaxisInqLevel(int zaxisID, int levelID)
714 @Parameter
715 @Item zaxisID Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
716 @Item levelID Level index (range: 0 to nlevel-1).
717
718 @Description
719 The function @func{zaxisInqLevel} returns one level of a Z-axis.
720
721 @Result
722 @func{zaxisInqLevel} returns the level of a Z-axis.
723 @EndFunction
724 */
zaxisInqLevel(int zaxisID,int levelID)725 double zaxisInqLevel(int zaxisID, int levelID)
726 {
727 double level = 0;
728 zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
729 if ( zaxisptr->vals && levelID >= 0 && levelID < zaxisptr->size )
730 level = zaxisptr->vals[levelID];
731
732 return level;
733 }
734
735
zaxisInqLbound(int zaxisID,int levelID)736 double zaxisInqLbound(int zaxisID, int levelID)
737 {
738 double level = 0;
739 zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
740 if ( zaxisptr->lbounds && levelID >= 0 && levelID < zaxisptr->size )
741 level = zaxisptr->lbounds[levelID];
742
743 return level;
744 }
745
746
zaxisInqUbound(int zaxisID,int levelID)747 double zaxisInqUbound(int zaxisID, int levelID)
748 {
749 double level = 0;
750 zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
751 if ( zaxisptr->ubounds && levelID >= 0 && levelID < zaxisptr->size )
752 level = zaxisptr->ubounds[levelID];
753
754 return level;
755 }
756
757
zaxisInqLevelsPtr(int zaxisID)758 const double *zaxisInqLevelsPtr(int zaxisID)
759 {
760 zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
761 return zaxisptr->vals;
762 }
763
764
765 #ifndef USE_MPI
zaxisInqCValsPtr(int zaxisID)766 char **zaxisInqCValsPtr(int zaxisID)
767 {
768 zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
769 return zaxisptr->cvals;
770 }
771 #endif
772
773 /*
774 @Function zaxisInqLevels
775 @Title Get all levels of a Z-axis
776
777 @Prototype void zaxisInqLevels(int zaxisID, double *levels)
778 @Parameter
779 @Item zaxisID Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
780 @Item levels Pointer to the location into which the levels are read.
781 The caller must allocate space for the returned values.
782
783 @Description
784 The function @func{zaxisInqLevels} returns all levels of a Z-axis.
785
786 @Result
787 @func{zaxisInqLevels} saves all levels to the parameter @func{levels}.
788 @EndFunction
789 */
zaxisInqLevels(int zaxisID,double * levels)790 int zaxisInqLevels(int zaxisID, double *levels)
791 {
792 zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
793
794 int size = 0;
795 if ( zaxisptr->vals )
796 {
797 size = zaxisptr->size;
798
799 if ( levels )
800 for ( int i = 0; i < size; i++ )
801 levels[i] = zaxisptr->vals[i];
802 }
803
804 return size;
805 }
806
807
zaxisInqCLen(int zaxisID)808 int zaxisInqCLen(int zaxisID)
809 {
810 int clen = 0;
811 #ifndef USE_MPI
812 zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
813 if ( zaxisptr->cvals && zaxisptr->clength)
814 clen = zaxisptr->clength;
815 #endif
816
817 return clen;
818 }
819
820
zaxisInqCVals(int zaxisID,char *** clevels)821 int zaxisInqCVals(int zaxisID, char ***clevels)
822 {
823 int size = 0;
824 #ifndef USE_MPI
825 zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
826 if ( zaxisptr->cvals )
827 {
828 size = zaxisptr->size;
829 const size_t clen = zaxisptr->clength;
830 if ( size && clen )
831 {
832 (*clevels) = (char**) Malloc(size*sizeof(char*));
833 for ( int i = 0; i < size; i++ )
834 {
835 (*clevels)[i] = (char*) Malloc(clen*sizeof(char));
836 memcpy((*clevels)[i], zaxisptr->cvals[i], clen*sizeof(char));
837 }
838 }
839 }
840 #endif
841
842 return size;
843 }
844
845
zaxisInqLbounds(int zaxisID,double * lbounds)846 int zaxisInqLbounds(int zaxisID, double *lbounds)
847 {
848 int size = 0;
849 zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
850 if ( zaxisptr->lbounds )
851 {
852 size = zaxisptr->size;
853
854 if ( lbounds )
855 for ( int i = 0; i < size; i++ )
856 lbounds[i] = zaxisptr->lbounds[i];
857 }
858
859 return size;
860 }
861
862
zaxisInqUbounds(int zaxisID,double * ubounds)863 int zaxisInqUbounds(int zaxisID, double *ubounds)
864 {
865 int size = 0;
866 zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
867 if ( zaxisptr->ubounds )
868 {
869 size = zaxisptr->size;
870
871 if ( ubounds )
872 for ( int i = 0; i < size; i++ )
873 ubounds[i] = zaxisptr->ubounds[i];
874 }
875
876 return size;
877 }
878
879
zaxisInqWeights(int zaxisID,double * weights)880 int zaxisInqWeights(int zaxisID, double *weights)
881 {
882 int size = 0;
883 zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
884 if ( zaxisptr->weights )
885 {
886 size = zaxisptr->size;
887
888 if ( weights )
889 for ( int i = 0; i < size; i++ )
890 weights[i] = zaxisptr->weights[i];
891 }
892
893 return size;
894 }
895
896
zaxisInqLevelID(int zaxisID,double level)897 int zaxisInqLevelID(int zaxisID, double level)
898 {
899 int levelID = CDI_UNDEFID;
900 zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
901 if ( zaxisptr->vals )
902 {
903 const int size = zaxisptr->size;
904 for ( int i = 0; i < size; i++ )
905 if ( fabs(level-zaxisptr->vals[i]) < DBL_EPSILON )
906 {
907 levelID = i;
908 break;
909 }
910 }
911
912 return levelID;
913 }
914
915 /*
916 @Function zaxisInqType
917 @Title Get the type of a Z-axis
918
919 @Prototype int zaxisInqType(int zaxisID)
920 @Parameter
921 @Item zaxisID Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
922
923 @Description
924 The function @func{zaxisInqType} returns the type of a Z-axis.
925
926 @Result
927 @func{zaxisInqType} returns the type of the Z-axis,
928 one of the set of predefined CDI Z-axis types.
929 The valid CDI Z-axis types are @func{ZAXIS_GENERIC}, @func{ZAXIS_SURFACE},
930 @func{ZAXIS_HYBRID}, @func{ZAXIS_SIGMA}, @func{ZAXIS_PRESSURE}, @func{ZAXIS_HEIGHT},
931 @func{ZAXIS_ISENTROPIC}, @func{ZAXIS_ALTITUDE}, @func{ZAXIS_MEANSEA}, @func{ZAXIS_TOA},
932 @func{ZAXIS_SEA_BOTTOM}, @func{ZAXIS_ATMOSPHERE}, @func{ZAXIS_CLOUD_BASE},
933 @func{ZAXIS_CLOUD_TOP}, @func{ZAXIS_ISOTHERM_ZERO}, @func{ZAXIS_SNOW},
934 @func{ZAXIS_LAKE_BOTTOM}, @func{ZAXIS_SEDIMENT_BOTTOM}, @func{ZAXIS_SEDIMENT_BOTTOM_TA},
935 @func{ZAXIS_SEDIMENT_BOTTOM_TW}, @func{ZAXIS_MIX_LAYER},
936 @func{ZAXIS_DEPTH_BELOW_SEA} and @func{ZAXIS_DEPTH_BELOW_LAND}.
937
938 @EndFunction
939 */
zaxisInqType(int zaxisID)940 int zaxisInqType(int zaxisID)
941 {
942 zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
943 return zaxisptr->type;
944 }
945
946 /*
947 @Function zaxisInqSize
948 @Title Get the size of a Z-axis
949
950 @Prototype int zaxisInqSize(int zaxisID)
951 @Parameter
952 @Item zaxisID Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
953
954 @Description
955 The function @func{zaxisInqSize} returns the size of a Z-axis.
956
957 @Result
958 @func{zaxisInqSize} returns the number of levels of a Z-axis.
959
960 @EndFunction
961 */
zaxisInqSize(int zaxisID)962 int zaxisInqSize(int zaxisID)
963 {
964 zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
965 return zaxisptr->size;
966 }
967
968
cdiCheckZaxis(int zaxisID)969 void cdiCheckZaxis(int zaxisID)
970 {
971 zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
972
973 if ( zaxisInqType(zaxisID) == ZAXIS_GENERIC && zaxisptr->vals )
974 {
975 const int size = zaxisptr->size;
976 if ( size > 1 )
977 {
978 /* check direction */
979 if ( ! zaxisptr->direction )
980 {
981 int ups = 0, downs = 0;
982 for ( int i = 1; i < size; i++ )
983 {
984 ups += (zaxisptr->vals[i] > zaxisptr->vals[i-1]);
985 downs += (zaxisptr->vals[i] < zaxisptr->vals[i-1]);
986 }
987 if ( ups == size-1 )
988 {
989 zaxisptr->direction = LevelUp;
990 }
991 else if ( downs == size-1 )
992 {
993 zaxisptr->direction = LevelDown;
994 }
995 else /* !zaxisptr->direction */
996 {
997 Warning("Direction undefined for zaxisID %d", zaxisID);
998 }
999 }
1000 }
1001 }
1002 }
1003
1004
zaxisDefVct(int zaxisID,int size,const double * vct)1005 void zaxisDefVct(int zaxisID, int size, const double *vct)
1006 {
1007 zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
1008
1009 if ( zaxisptr->vct == 0 || zaxisptr->vctsize != size )
1010 {
1011 zaxisptr->vctsize = size;
1012 zaxisptr->vct = (double *) Realloc(zaxisptr->vct, (size_t)size*sizeof(double));
1013 }
1014
1015 if (vct) memcpy(zaxisptr->vct, vct, (size_t)size*sizeof(double));
1016 reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
1017 }
1018
1019
zaxisInqVct(int zaxisID,double * vct)1020 void zaxisInqVct(int zaxisID, double *vct)
1021 {
1022 zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
1023 memcpy(vct, zaxisptr->vct, (size_t)zaxisptr->vctsize * sizeof (double));
1024 }
1025
1026
zaxisInqVctSize(int zaxisID)1027 int zaxisInqVctSize(int zaxisID)
1028 {
1029 zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
1030 return zaxisptr->vctsize;
1031 }
1032
1033
zaxisInqVctPtr(int zaxisID)1034 const double *zaxisInqVctPtr(int zaxisID)
1035 {
1036 zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
1037 return zaxisptr->vct;
1038 }
1039
1040
zaxisDefLbounds(int zaxisID,const double * lbounds)1041 void zaxisDefLbounds(int zaxisID, const double *lbounds)
1042 {
1043 zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
1044
1045 const size_t size = (size_t)zaxisptr->size;
1046
1047 if ( CDI_Debug )
1048 if ( zaxisptr->lbounds )
1049 Warning("Lower bounds already defined for zaxisID = %d", zaxisID);
1050
1051 if ( zaxisptr->lbounds == NULL )
1052 zaxisptr->lbounds = (double *) Malloc(size*sizeof(double));
1053
1054 if (lbounds) memcpy(zaxisptr->lbounds, lbounds, size*sizeof(double));
1055 reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
1056 }
1057
1058
zaxisDefUbounds(int zaxisID,const double * ubounds)1059 void zaxisDefUbounds(int zaxisID, const double *ubounds)
1060 {
1061 zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
1062
1063 const size_t size = (size_t)zaxisptr->size;
1064
1065 if ( CDI_Debug )
1066 if ( zaxisptr->ubounds )
1067 Warning("Upper bounds already defined for zaxisID = %d", zaxisID);
1068
1069 if ( zaxisptr->ubounds == NULL )
1070 zaxisptr->ubounds = (double *) Malloc(size*sizeof(double));
1071
1072 if (ubounds) memcpy(zaxisptr->ubounds, ubounds, size*sizeof(double));
1073 reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
1074 }
1075
1076
zaxisDefWeights(int zaxisID,const double * weights)1077 void zaxisDefWeights(int zaxisID, const double *weights)
1078 {
1079 zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
1080
1081 const size_t size = (size_t)zaxisptr->size;
1082
1083 if ( CDI_Debug )
1084 if ( zaxisptr->weights != NULL )
1085 Warning("Weights already defined for zaxisID = %d", zaxisID);
1086
1087 if ( zaxisptr->weights == NULL )
1088 zaxisptr->weights = (double *) Malloc(size*sizeof(double));
1089
1090 memcpy(zaxisptr->weights, weights, size*sizeof(double));
1091 reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
1092 }
1093
1094
zaxisChangeType(int zaxisID,int zaxistype)1095 void zaxisChangeType(int zaxisID, int zaxistype)
1096 {
1097 zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
1098 zaxisptr->type = zaxistype;
1099 }
1100
1101
zaxisResize(int zaxisID,int size)1102 void zaxisResize(int zaxisID, int size)
1103 {
1104 zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
1105
1106 xassert(size >= 0);
1107
1108 zaxisptr->size = size;
1109
1110 if ( zaxisptr->vals )
1111 zaxisptr->vals = (double *) Realloc(zaxisptr->vals, (size_t)size*sizeof(double));
1112 }
1113
1114 static inline
zaxisCopyKeyStr(zaxis_t * zaxisptr1,zaxis_t * zaxisptr2,int key)1115 void zaxisCopyKeyStr(zaxis_t *zaxisptr1, zaxis_t *zaxisptr2, int key)
1116 {
1117 cdi_key_t *keyp = find_key(&zaxisptr1->keys, key);
1118 if (keyp && keyp->type == KEY_BYTES)
1119 cdiDefVarKeyBytes(&zaxisptr2->keys, key, (const unsigned char*)keyp->v.s, (int)keyp->length);
1120 }
1121
1122
zaxisDuplicate(int zaxisID)1123 int zaxisDuplicate(int zaxisID)
1124 {
1125 zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
1126
1127 const int zaxistype = zaxisInqType(zaxisID);
1128 const int zaxissize = zaxisInqSize(zaxisID);
1129
1130 const int zaxisIDnew = zaxisCreate(zaxistype, zaxissize);
1131 zaxis_t *zaxisptrnew = zaxis_to_pointer(zaxisIDnew);
1132
1133 zaxis_copy(zaxisptrnew, zaxisptr);
1134
1135 zaxisCopyKeyStr(zaxisptr, zaxisptrnew, CDI_KEY_NAME);
1136 zaxisCopyKeyStr(zaxisptr, zaxisptrnew, CDI_KEY_LONGNAME);
1137 zaxisCopyKeyStr(zaxisptr, zaxisptrnew, CDI_KEY_UNITS);
1138
1139 if ( zaxisptr->vals )
1140 {
1141 const size_t size = (size_t)zaxissize;
1142 zaxisptrnew->vals = (double *) Malloc(size * sizeof (double));
1143 memcpy(zaxisptrnew->vals, zaxisptr->vals, size * sizeof (double));
1144 }
1145
1146 if ( zaxisptr->lbounds )
1147 {
1148 const size_t size = (size_t)zaxissize;
1149 zaxisptrnew->lbounds = (double *) Malloc(size * sizeof (double));
1150 memcpy(zaxisptrnew->lbounds, zaxisptr->lbounds, size * sizeof(double));
1151 }
1152
1153 if ( zaxisptr->ubounds )
1154 {
1155 const size_t size = (size_t)zaxissize;
1156 zaxisptrnew->ubounds = (double *) Malloc(size * sizeof (double));
1157 memcpy(zaxisptrnew->ubounds, zaxisptr->ubounds, size * sizeof (double));
1158 }
1159
1160 if ( zaxisptr->vct )
1161 {
1162 const size_t size = (size_t)zaxisptr->vctsize;
1163 if ( size )
1164 {
1165 zaxisptrnew->vctsize = (int)size;
1166 zaxisptrnew->vct = (double *) Malloc(size * sizeof (double));
1167 memcpy(zaxisptrnew->vct, zaxisptr->vct, size * sizeof (double));
1168 }
1169 }
1170
1171 zaxisptrnew->atts.nelems = 0;
1172 cdiCopyAtts(zaxisID, CDI_GLOBAL, zaxisIDnew, CDI_GLOBAL);
1173
1174 return zaxisIDnew;
1175 }
1176
1177 static
zaxisPrintKernel(zaxis_t * zaxisptr,FILE * fp)1178 void zaxisPrintKernel(zaxis_t *zaxisptr, FILE *fp)
1179 {
1180 xassert(zaxisptr);
1181
1182 int zaxisID = zaxisptr->self;
1183 int datatype = CDI_UNDEFID;
1184 cdiInqKeyInt(zaxisID, CDI_GLOBAL, CDI_KEY_DATATYPE, &datatype);
1185
1186 const int type = zaxisptr->type;
1187 const int nlevels = zaxisptr->size;
1188
1189 const int dig = (datatype == CDI_DATATYPE_FLT64) ? 15 : 7;
1190
1191 fprintf(fp, "zaxistype = %s\n", zaxisNamePtr(type));
1192 fprintf(fp, "size = %d\n", nlevels);
1193 if ( nlevels == 1 )
1194 {
1195 const bool zscalar = (bool)zaxisptr->scalar;
1196 if ( zscalar ) fprintf(fp, "scalar = true\n");
1197 }
1198
1199 const char *string = cdiInqVarKeyString(&zaxisptr->keys, CDI_KEY_NAME);
1200 if ( string[0] ) fprintf(fp, "name = %s\n", string);
1201 string = cdiInqVarKeyString(&zaxisptr->keys, CDI_KEY_LONGNAME);
1202 if ( string[0] ) fprintf(fp, "longname = %s\n", string);
1203 string = cdiInqVarKeyString(&zaxisptr->keys, CDI_KEY_UNITS);
1204 if ( string[0] ) fprintf(fp, "units = %s\n", string);
1205
1206 if ( zaxisptr->vals )
1207 {
1208 int nbyte0 = fprintf(fp, "levels = ");
1209 int nbyte = nbyte0;
1210 for ( int levelID = 0; levelID < nlevels; levelID++ )
1211 {
1212 if ( nbyte > 80 )
1213 {
1214 fprintf(fp, "\n");
1215 fprintf(fp, "%*s", nbyte0, "");
1216 nbyte = nbyte0;
1217 }
1218 nbyte += fprintf(fp, "%.*g ", dig, zaxisptr->vals[levelID]);
1219 }
1220 fprintf(fp, "\n");
1221 }
1222
1223 if ( zaxisptr->lbounds && zaxisptr->ubounds )
1224 {
1225 int nbyte0 = fprintf(fp, "lbounds = ");
1226 int nbyte = nbyte0;
1227 for ( int levelID = 0; levelID < nlevels; levelID++ )
1228 {
1229 if ( nbyte > 80 )
1230 {
1231 fprintf(fp, "\n");
1232 fprintf(fp, "%*s", nbyte0, "");
1233 nbyte = nbyte0;
1234 }
1235 nbyte += fprintf(fp, "%.*g ", dig, zaxisptr->lbounds[levelID]);
1236 }
1237 fprintf(fp, "\n");
1238
1239 nbyte0 = fprintf(fp, "ubounds = ");
1240 nbyte = nbyte0;
1241 for ( int levelID = 0; levelID < nlevels; levelID++ )
1242 {
1243 if ( nbyte > 80 )
1244 {
1245 fprintf(fp, "\n");
1246 fprintf(fp, "%*s", nbyte0, "");
1247 nbyte = nbyte0;
1248 }
1249 nbyte += fprintf(fp, "%.*g ", dig, zaxisptr->ubounds[levelID]);
1250 }
1251 fprintf(fp, "\n");
1252 }
1253
1254 if ( type == ZAXIS_HYBRID || type == ZAXIS_HYBRID_HALF )
1255 {
1256 const int vctsize = zaxisptr->vctsize;
1257 const double *vct = zaxisptr->vct;
1258 fprintf(fp, "vctsize = %d\n", vctsize);
1259 if ( vctsize )
1260 {
1261 int nbyte0 = fprintf(fp, "vct = ");
1262 int nbyte = nbyte0;
1263 for ( int i = 0; i < vctsize; i++ )
1264 {
1265 if ( nbyte > 70 || i == vctsize/2 )
1266 {
1267 fprintf(fp, "\n%*s", nbyte0, "");
1268 nbyte = nbyte0;
1269 }
1270 nbyte += fprintf(fp, "%.15g ", vct[i]);
1271 }
1272 fprintf(fp, "\n");
1273 }
1274 }
1275 }
1276
1277
1278 static
zaxisPrintP(void * voidptr,FILE * fp)1279 void zaxisPrintP(void *voidptr, FILE *fp)
1280 {
1281 zaxis_t *zaxisptr = (zaxis_t *) voidptr;
1282
1283 xassert(zaxisptr);
1284
1285 zaxisPrintKernel(zaxisptr, fp);
1286 }
1287
1288
1289 static
zaxisCompareP(zaxis_t * z1,zaxis_t * z2)1290 int zaxisCompareP(zaxis_t *z1, zaxis_t *z2)
1291 {
1292 enum { differ = 1 };
1293 int diff = 0;
1294 xassert(z1 && z2);
1295
1296 diff |= (z1->type != z2->type)
1297 | (cdiInqVarKeyInt(&z1->keys, CDI_KEY_TYPEOFFIRSTFIXEDSURFACE) != cdiInqVarKeyInt(&z2->keys, CDI_KEY_TYPEOFFIRSTFIXEDSURFACE))
1298 | (cdiInqVarKeyInt(&z1->keys, CDI_KEY_DATATYPE) != cdiInqVarKeyInt(&z2->keys, CDI_KEY_DATATYPE))
1299 | (z1->direction != z2->direction)
1300 | (z1->size != z2->size)
1301 | (z1->vctsize != z2->vctsize)
1302 | (z1->positive != z2->positive);
1303
1304 if ( diff ) return differ;
1305
1306 int size = z1->size;
1307 int anyPresent = 0;
1308 int present = (z1->vals != NULL);
1309 diff |= (present ^ (z2->vals != NULL));
1310 anyPresent |= present;
1311 if (!diff && present)
1312 {
1313 const double *p = z1->vals, *q = z2->vals;
1314 for ( int i = 0; i < size; i++ )
1315 diff |= IS_NOT_EQUAL(p[i], q[i]);
1316 }
1317
1318 present = (z1->lbounds != NULL);
1319 diff |= (present ^ (z2->lbounds != NULL));
1320 anyPresent |= present;
1321 if (!diff && present)
1322 {
1323 const double *p = z1->lbounds, *q = z2->lbounds;
1324 for ( int i = 0; i < size; i++ )
1325 diff |= IS_NOT_EQUAL(p[i], q[i]);
1326 }
1327
1328 present = (z1->ubounds != NULL);
1329 diff |= (present ^ (z2->ubounds != NULL));
1330 anyPresent |= present;
1331 if (!diff && present)
1332 {
1333 const double *p = z1->ubounds, *q = z2->ubounds;
1334 for ( int i = 0; i < size; ++i )
1335 diff |= IS_NOT_EQUAL(p[i], q[i]);
1336 }
1337
1338 present = (z1->weights != NULL);
1339 diff |= (present ^ (z2->weights != NULL));
1340 anyPresent |= present;
1341 if (!diff && present)
1342 {
1343 const double *p = z1->weights, *q = z2->weights;
1344 for ( int i = 0; i < size; ++i )
1345 diff |= IS_NOT_EQUAL(p[i], q[i]);
1346 }
1347
1348 present = (z1->vct != NULL);
1349 diff |= (present ^ (z2->vct != NULL));
1350 if (!diff && present)
1351 {
1352 int vctsize = z1->vctsize;
1353 xassert(vctsize);
1354 const double *p = z1->vct, *q = z2->vct;
1355 for ( int i = 0; i < vctsize; ++i )
1356 diff |= IS_NOT_EQUAL(p[i], q[i]);
1357 }
1358
1359 if (anyPresent)
1360 xassert(size);
1361
1362 diff |= strcmp(cdiInqVarKeyString(&z1->keys, CDI_KEY_NAME), cdiInqVarKeyString(&z2->keys, CDI_KEY_NAME))
1363 | strcmp(cdiInqVarKeyString(&z1->keys, CDI_KEY_LONGNAME), cdiInqVarKeyString(&z2->keys, CDI_KEY_LONGNAME))
1364 | strcmp(cdiInqVarKeyString(&z1->keys, CDI_KEY_STDNAME), cdiInqVarKeyString(&z2->keys, CDI_KEY_STDNAME))
1365 | strcmp(cdiInqVarKeyString(&z1->keys, CDI_KEY_UNITS), cdiInqVarKeyString(&z2->keys, CDI_KEY_UNITS));
1366
1367 return diff != 0;
1368 }
1369
1370
1371 static
zaxisTxCode(void)1372 int zaxisTxCode(void)
1373 {
1374 return ZAXIS;
1375 }
1376
1377 enum { zaxisNint = 6,
1378 vals = 1 << 0,
1379 lbounds = 1 << 1,
1380 ubounds = 1 << 2,
1381 weights = 1 << 3,
1382 vct = 1 << 4,
1383 };
1384
1385 static
zaxisGetMemberMask(zaxis_t * zaxisP)1386 int zaxisGetMemberMask( zaxis_t * zaxisP )
1387 {
1388 int memberMask = 0;
1389
1390 if ( zaxisP->vals ) memberMask |= vals;
1391 if ( zaxisP->lbounds ) memberMask |= lbounds;
1392 if ( zaxisP->ubounds ) memberMask |= ubounds;
1393 if ( zaxisP->weights ) memberMask |= weights;
1394 if ( zaxisP->vct ) memberMask |= vct;
1395
1396 return memberMask;
1397 }
1398
1399 static int
zaxisGetPackSize(void * voidP,void * context)1400 zaxisGetPackSize(void * voidP, void *context)
1401 {
1402 zaxis_t * zaxisP = ( zaxis_t * ) voidP;
1403 int packBufferSize = serializeGetSize(zaxisNint, CDI_DATATYPE_INT, context)
1404 + serializeGetSize(1, CDI_DATATYPE_UINT32, context);
1405
1406 if (zaxisP->vals || zaxisP->lbounds || zaxisP->ubounds || zaxisP->weights)
1407 xassert(zaxisP->size);
1408
1409 if ( zaxisP->vals )
1410 packBufferSize += serializeGetSize(zaxisP->size, CDI_DATATYPE_FLT64, context)
1411 + serializeGetSize(1, CDI_DATATYPE_UINT32, context);
1412
1413 if ( zaxisP->lbounds )
1414 packBufferSize += serializeGetSize(zaxisP->size, CDI_DATATYPE_FLT64, context)
1415 + serializeGetSize(1, CDI_DATATYPE_UINT32, context);
1416
1417 if ( zaxisP->ubounds )
1418 packBufferSize += serializeGetSize(zaxisP->size, CDI_DATATYPE_FLT64, context)
1419 + serializeGetSize(1, CDI_DATATYPE_UINT32, context);
1420
1421 if ( zaxisP->weights )
1422 packBufferSize += serializeGetSize(zaxisP->size, CDI_DATATYPE_FLT64, context)
1423 + serializeGetSize(1, CDI_DATATYPE_UINT32, context);
1424
1425 if ( zaxisP->vct )
1426 {
1427 xassert ( zaxisP->vctsize );
1428 packBufferSize += serializeGetSize(zaxisP->vctsize, CDI_DATATYPE_FLT64, context)
1429 + serializeGetSize(1, CDI_DATATYPE_UINT32, context);
1430 }
1431
1432 packBufferSize += serializeKeysGetPackSize(&zaxisP->keys, context);
1433
1434 packBufferSize += serializeGetSize(1, CDI_DATATYPE_UCHAR, context);
1435
1436 return packBufferSize;
1437 }
1438
1439
1440 void
zaxisUnpack(char * unpackBuffer,int unpackBufferSize,int * unpackBufferPos,int originNamespace,void * context,int force_id)1441 zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
1442 int * unpackBufferPos, int originNamespace, void *context,
1443 int force_id)
1444 {
1445 int intBuffer[zaxisNint], memberMask;
1446 uint32_t d;
1447
1448 serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
1449 intBuffer, zaxisNint, CDI_DATATYPE_INT, context);
1450 serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
1451 &d, 1, CDI_DATATYPE_UINT32, context);
1452
1453 xassert(cdiCheckSum(CDI_DATATYPE_INT, zaxisNint, intBuffer) == d);
1454
1455 zaxisInit();
1456
1457 zaxis_t *zaxisP
1458 = zaxisNewEntry(force_id ? namespaceAdaptKey(intBuffer[0], originNamespace)
1459 : CDI_UNDEFID);
1460
1461 zaxisP->type = intBuffer[1];
1462 zaxisP->size = intBuffer[2];
1463 zaxisP->direction = intBuffer[3];
1464 zaxisP->vctsize = intBuffer[4];
1465 memberMask = intBuffer[5];
1466
1467 if (memberMask & vals)
1468 {
1469 int size = zaxisP->size;
1470 xassert(size >= 0);
1471
1472 zaxisP->vals = (double *) Malloc((size_t)size * sizeof (double));
1473 serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
1474 zaxisP->vals, size, CDI_DATATYPE_FLT64, context);
1475 serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
1476 &d, 1, CDI_DATATYPE_UINT32, context);
1477 xassert(cdiCheckSum(CDI_DATATYPE_FLT, size, zaxisP->vals) == d);
1478 }
1479
1480 if (memberMask & lbounds)
1481 {
1482 int size = zaxisP->size;
1483 xassert(size >= 0);
1484
1485 zaxisP->lbounds = (double *) Malloc((size_t)size * sizeof (double));
1486 serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
1487 zaxisP->lbounds, size, CDI_DATATYPE_FLT64, context);
1488 serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
1489 &d, 1, CDI_DATATYPE_UINT32, context);
1490 xassert(cdiCheckSum(CDI_DATATYPE_FLT, size, zaxisP->lbounds) == d);
1491 }
1492
1493 if (memberMask & ubounds)
1494 {
1495 int size = zaxisP->size;
1496 xassert(size >= 0);
1497
1498 zaxisP->ubounds = (double *) Malloc((size_t)size * sizeof (double));
1499 serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
1500 zaxisP->ubounds, size, CDI_DATATYPE_FLT64, context);
1501 serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
1502 &d, 1, CDI_DATATYPE_UINT32, context);
1503 xassert(cdiCheckSum(CDI_DATATYPE_FLT, size, zaxisP->ubounds) == d);
1504 }
1505
1506 if (memberMask & weights)
1507 {
1508 int size = zaxisP->size;
1509 xassert(size >= 0);
1510
1511 zaxisP->weights = (double *) Malloc((size_t)size * sizeof (double));
1512 serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
1513 zaxisP->weights, size, CDI_DATATYPE_FLT64, context);
1514 serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
1515 &d, 1, CDI_DATATYPE_UINT32, context);
1516 xassert(cdiCheckSum(CDI_DATATYPE_FLT, size, zaxisP->weights) == d);
1517 }
1518
1519 if (memberMask & vct)
1520 {
1521 int size = zaxisP->vctsize;
1522 xassert(size >= 0);
1523
1524 zaxisP->vct = (double *) Malloc((size_t)size * sizeof (double));
1525 serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
1526 zaxisP->vct, size, CDI_DATATYPE_FLT64, context);
1527 serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
1528 &d, 1, CDI_DATATYPE_UINT32, context);
1529 xassert(cdiCheckSum(CDI_DATATYPE_FLT64, size, zaxisP->vct) == d);
1530 }
1531
1532 serializeKeysUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos, &zaxisP->keys, context);
1533
1534 serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
1535 &zaxisP->positive, 1, CDI_DATATYPE_UINT, context);
1536
1537 reshSetStatus(zaxisP->self, &zaxisOps,
1538 reshGetStatus(zaxisP->self, &zaxisOps) & ~RESH_SYNC_BIT);
1539 }
1540
1541 static void
zaxisPack(void * voidP,void * packBuffer,int packBufferSize,int * packBufferPos,void * context)1542 zaxisPack(void * voidP, void * packBuffer, int packBufferSize,
1543 int * packBufferPos, void *context)
1544 {
1545 zaxis_t * zaxisP = ( zaxis_t * ) voidP;
1546 int intBuffer[zaxisNint];
1547 int memberMask;
1548 uint32_t d;
1549
1550 intBuffer[0] = zaxisP->self;
1551 intBuffer[1] = zaxisP->type;
1552 intBuffer[2] = zaxisP->size;
1553 intBuffer[3] = zaxisP->direction;
1554 intBuffer[4] = zaxisP->vctsize;
1555 intBuffer[5] = memberMask = zaxisGetMemberMask ( zaxisP );
1556
1557 serializePack(intBuffer, zaxisNint, CDI_DATATYPE_INT,
1558 packBuffer, packBufferSize, packBufferPos, context);
1559 d = cdiCheckSum(CDI_DATATYPE_INT, zaxisNint, intBuffer);
1560 serializePack(&d, 1, CDI_DATATYPE_UINT32,
1561 packBuffer, packBufferSize, packBufferPos, context);
1562
1563
1564 if ( memberMask & vals )
1565 {
1566 xassert(zaxisP->size);
1567 serializePack(zaxisP->vals, zaxisP->size, CDI_DATATYPE_FLT64,
1568 packBuffer, packBufferSize, packBufferPos, context);
1569 d = cdiCheckSum(CDI_DATATYPE_FLT, zaxisP->size, zaxisP->vals );
1570 serializePack(&d, 1, CDI_DATATYPE_UINT32,
1571 packBuffer, packBufferSize, packBufferPos, context);
1572 }
1573
1574 if (memberMask & lbounds)
1575 {
1576 xassert(zaxisP->size);
1577 serializePack(zaxisP->lbounds, zaxisP->size, CDI_DATATYPE_FLT64,
1578 packBuffer, packBufferSize, packBufferPos, context);
1579 d = cdiCheckSum(CDI_DATATYPE_FLT, zaxisP->size, zaxisP->lbounds);
1580 serializePack(&d, 1, CDI_DATATYPE_UINT32,
1581 packBuffer, packBufferSize, packBufferPos, context);
1582 }
1583
1584 if (memberMask & ubounds)
1585 {
1586 xassert(zaxisP->size);
1587
1588 serializePack(zaxisP->ubounds, zaxisP->size, CDI_DATATYPE_FLT64,
1589 packBuffer, packBufferSize, packBufferPos, context);
1590 d = cdiCheckSum(CDI_DATATYPE_FLT, zaxisP->size, zaxisP->ubounds);
1591 serializePack(&d, 1, CDI_DATATYPE_UINT32,
1592 packBuffer, packBufferSize, packBufferPos, context);
1593 }
1594
1595 if (memberMask & weights)
1596 {
1597 xassert(zaxisP->size);
1598
1599 serializePack(zaxisP->weights, zaxisP->size, CDI_DATATYPE_FLT64,
1600 packBuffer, packBufferSize, packBufferPos, context);
1601 d = cdiCheckSum(CDI_DATATYPE_FLT, zaxisP->size, zaxisP->weights);
1602 serializePack(&d, 1, CDI_DATATYPE_UINT32,
1603 packBuffer, packBufferSize, packBufferPos, context);
1604 }
1605
1606 if (memberMask & vct)
1607 {
1608 xassert(zaxisP->vctsize);
1609
1610 serializePack(zaxisP->vct, zaxisP->vctsize, CDI_DATATYPE_FLT64,
1611 packBuffer, packBufferSize, packBufferPos, context);
1612 d = cdiCheckSum(CDI_DATATYPE_FLT64, zaxisP->vctsize, zaxisP->vct);
1613 serializePack(&d, 1, CDI_DATATYPE_UINT32,
1614 packBuffer, packBufferSize, packBufferPos, context);
1615 }
1616
1617 serializeKeysPack(&zaxisP->keys, packBuffer, packBufferSize, packBufferPos, context);
1618
1619 serializePack(&zaxisP->positive, 1, CDI_DATATYPE_UINT,
1620 packBuffer, packBufferSize, packBufferPos, context);
1621 }
1622
1623
cdiZaxisGetIndexList(unsigned nzaxis,int * zaxisResHs)1624 void cdiZaxisGetIndexList(unsigned nzaxis, int *zaxisResHs)
1625 {
1626 reshGetResHListOfType(nzaxis, zaxisResHs, &zaxisOps);
1627 }
1628
1629 /*
1630 * Local Variables:
1631 * c-file-style: "Java"
1632 * c-basic-offset: 2
1633 * indent-tabs-mode: nil
1634 * show-trailing-whitespace: t
1635 * require-trailing-newline: t
1636 * End:
1637 */
1638