zaxis.c 26.7 KB
Newer Older
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#if defined (HAVE_CONFIG_H)
#  include "config.h"
#endif

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

#include "dmemory.h"

#include "cdi.h"
#include "stream_int.h"


static struct {
  char *name;
  char *longname;
  char *units;
}
20
ZaxistypeEntry[] = {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
21
22
23
24
25
26
  {"sfc",     "surface",                  ""},
  {"lev",     "generic",                  "level"},
  {"lev",     "hybrid",                   "level"},
  {"lev",     "hybrid_half",              "level"},
  {"lev",     "pressure",                 "Pa"},
  {"height",  "height",                   "m"},
27
28
  {"depth",   "depth_below_sea",          "m"},
  {"depth",   "depth_below_land",         "cm"},
Uwe Schulzweida's avatar
Uwe Schulzweida committed
29
30
31
  {"lev",     "isentropic",               "K"},
  {"lev",     "trajectory",               ""},
  {"alt",     "altitude",                 "m"},
Uwe Schulzweida's avatar
Uwe Schulzweida committed
32
  {"lev",     "sigma",                    "level"},
Uwe Schulzweida's avatar
Uwe Schulzweida committed
33
34
};

35
static int CDI_MaxZaxistype = sizeof(ZaxistypeEntry) / sizeof(ZaxistypeEntry[0]);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
36
37
38
39
40
41
42
43
44
45
46
47
48


#define  LevelDown  0
#define  LevelUp    1

typedef struct {
  char     name[256];
  char     longname[256];
  char     units[256];
  double  *vals;
  double  *lbounds;
  double  *ubounds;
  double  *weights;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
49
  int      self;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
50
51
  int      prec;
  int      type;
52
  int      ltype;    /* GRIB level type */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
53
54
55
56
57
58
59
  int      size;
  int      direction;
  int      vctsize;
  double  *vct;
}
ZAXIS;

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

62
static int _zaxis_max = MAX_ZAXIS;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
63

Uwe Schulzweida's avatar
Uwe Schulzweida committed
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
static void zaxis_initialize(void);

static int _zaxis_init = FALSE;

#if  defined  (HAVE_LIBPTHREAD)
#  include <pthread.h>

static pthread_once_t _zaxis_init_thread = PTHREAD_ONCE_INIT;
static pthread_mutex_t _zaxis_mutex;

#  define ZAXIS_LOCK           pthread_mutex_lock(&_zaxis_mutex);
#  define ZAXIS_UNLOCK         pthread_mutex_unlock(&_zaxis_mutex);
#  define ZAXIS_INIT                               \
   if ( _zaxis_init == FALSE ) pthread_once(&_zaxis_init_thread, zaxis_initialize);

#else

#  define ZAXIS_LOCK
#  define ZAXIS_UNLOCK
#  define ZAXIS_INIT                               \
   if ( _zaxis_init == FALSE ) zaxis_initialize();

#endif


typedef struct _zaxisPtrToIdx {
  int idx;
  ZAXIS *ptr;
  struct _zaxisPtrToIdx *next;
} zaxisPtrToIdx;


Uwe Schulzweida's avatar
Uwe Schulzweida committed
96
97
static zaxisPtrToIdx *_zaxisList  = NULL;
static zaxisPtrToIdx *_zaxisAvail = NULL;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
98
99
100


static void zaxis_list_new(void)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
101
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
102
103
  static char func[] = "zaxis_list_new";

Uwe Schulzweida's avatar
Uwe Schulzweida committed
104
105
  assert(_zaxisList == NULL);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
106
  _zaxisList = (zaxisPtrToIdx *) malloc(_zaxis_max*sizeof(zaxisPtrToIdx));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
107
108
109
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
110
static void zaxis_list_delete(void)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
111
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
112
113
114
115
116
  static char func[] = "zaxis_list_delete";

  if ( _zaxisList ) free(_zaxisList);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
117

Uwe Schulzweida's avatar
Uwe Schulzweida committed
118
119
120
121
122
static void zaxis_init_pointer(void)
{
  int  i;
  
  for ( i = 0; i < _zaxis_max; i++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
123
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
124
125
126
127
      _zaxisList[i].next = _zaxisList + i + 1;
      _zaxisList[i].idx  = i;
      _zaxisList[i].ptr  = 0;
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
128

Uwe Schulzweida's avatar
Uwe Schulzweida committed
129
  _zaxisList[_zaxis_max-1].next = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
130

Uwe Schulzweida's avatar
Uwe Schulzweida committed
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
  _zaxisAvail = _zaxisList;
}


ZAXIS *zaxis_to_pointer(int idx)
{
  static char func[] = "zaxis_to_pointer";
  ZAXIS *zaxisptr = NULL;

  ZAXIS_INIT

  if ( idx >= 0 && idx < _zaxis_max )
    {
      ZAXIS_LOCK

      zaxisptr = _zaxisList[idx].ptr;

      ZAXIS_UNLOCK
Uwe Schulzweida's avatar
Uwe Schulzweida committed
149
150
    }
  else
Uwe Schulzweida's avatar
Uwe Schulzweida committed
151
152
153
154
155
156
157
158
159
160
161
162
163
164
    Error(func, "zaxis index %d undefined!", idx);

  return (zaxisptr);
}


/* Create an index from a pointer */
static int zaxis_from_pointer(ZAXIS *ptr)
{
  static char func[] = "zaxis_from_pointer";
  int      idx = -1;
  zaxisPtrToIdx *newptr;

  if ( ptr )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
165
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
166
167
168
      ZAXIS_LOCK

      if ( _zaxisAvail )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
169
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
170
171
172
173
174
175
176
177
	  newptr       = _zaxisAvail;
	  _zaxisAvail  = _zaxisAvail->next;
	  newptr->next = 0;
	  idx	       = newptr->idx;
	  newptr->ptr  = ptr;
      
	  if ( ZAXIS_Debug )
	    Message(func, "Pointer %p has idx %d from zaxis list", ptr, idx);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
178
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
179
      else
Uwe Schulzweida's avatar
Uwe Schulzweida committed
180
	Warning(func, "Too many open zaxis (limit is %d)!", _zaxis_max);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
181
182

      ZAXIS_UNLOCK
Uwe Schulzweida's avatar
Uwe Schulzweida committed
183
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
184
185
  else
    Error(func, "Internal problem (pointer %p undefined)", ptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
186

Uwe Schulzweida's avatar
Uwe Schulzweida committed
187
188
  return (idx);
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
189
190


Uwe Schulzweida's avatar
Uwe Schulzweida committed
191
192
193
194
195
196
197
198
199
200
201
202
static void zaxis_init_entry(ZAXIS *zaxisptr)
{
  zaxisptr->self        = zaxis_from_pointer(zaxisptr);

  zaxisptr->name[0]     = 0;
  zaxisptr->longname[0] = 0;
  zaxisptr->units[0]    = 0;
  zaxisptr->vals        = NULL;
  zaxisptr->ubounds     = NULL;
  zaxisptr->lbounds     = NULL;
  zaxisptr->weights     = NULL;
  zaxisptr->type        = CDI_UNDEFID;
203
  zaxisptr->ltype       = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
204
205
206
207
208
209
  zaxisptr->direction   = CDI_UNDEFID;
  zaxisptr->prec        = 0;
  zaxisptr->size        = 0;
  zaxisptr->vctsize     = 0;
  zaxisptr->vct         = NULL;
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
210
211


Uwe Schulzweida's avatar
Uwe Schulzweida committed
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
static ZAXIS *zaxis_new_entry(void)
{
  static char func[] = "zaxis_new_entry";
  ZAXIS *zaxisptr;

  zaxisptr = (ZAXIS *) malloc(sizeof(ZAXIS));

  if ( zaxisptr ) zaxis_init_entry(zaxisptr);

  return (zaxisptr);
}


static void zaxis_delete_entry(ZAXIS *zaxisptr)
{
  static char func[] = "zaxis_delete_entry";
  int idx;

  idx = zaxisptr->self;

  ZAXIS_LOCK

  free(zaxisptr);

  _zaxisList[idx].next = _zaxisAvail;
  _zaxisList[idx].ptr  = 0;
  _zaxisAvail          = &_zaxisList[idx];

  ZAXIS_UNLOCK

  if ( ZAXIS_Debug )
    Message(func, "Removed idx %d from zaxis list", idx);
}


static void zaxis_initialize(void)
{
  char *env;

#if  defined  (HAVE_LIBPTHREAD)
  /* initialize global API mutex lock */
  pthread_mutex_init(&_zaxis_mutex, NULL);
#endif

  env = getenv("ZAXIS_DEBUG");
  if ( env ) ZAXIS_Debug = atoi(env);

  zaxis_list_new();
  atexit(zaxis_list_delete);

262
263
  ZAXIS_LOCK

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

266
267
  ZAXIS_UNLOCK

Uwe Schulzweida's avatar
Uwe Schulzweida committed
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
  _zaxis_init = TRUE;
}


static void zaxis_copy(ZAXIS *zaxisptr2, ZAXIS *zaxisptr1)
{
  int zaxisID2;

  zaxisID2 = zaxisptr2->self;
  memcpy(zaxisptr2, zaxisptr1, sizeof(ZAXIS));
  zaxisptr2->self = zaxisID2;
}


static void zaxis_check_ptr(const char *func, ZAXIS *zaxisptr)
{
  if ( zaxisptr == NULL )
    Error(func, "zaxis undefined!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
286
287
288
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
289
int zaxisSize(void)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
290
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
291
292
293
294
295
296
297
298
299
300
301
  int zaxissize = 0;
  int i;
  
  ZAXIS_INIT

  ZAXIS_LOCK

  for ( i = 0; i < _zaxis_max; i++ )
    if ( _zaxisList[i].ptr ) zaxissize++;

  ZAXIS_UNLOCK
Uwe Schulzweida's avatar
Uwe Schulzweida committed
302

Uwe Schulzweida's avatar
Uwe Schulzweida committed
303
  return (zaxissize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
304
305
306
307
}


/*
308
@Function  zaxisCreate
309
@Title     Create a vertical Z-axis
Uwe Schulzweida's avatar
Uwe Schulzweida committed
310

311
@Prototype int zaxisCreate(int zaxistype, int size)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
312
313
@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
314
                      The valid CDI Z-axis types are @func{ZAXIS_GENERIC}, @func{ZAXIS_SURFACE},
Uwe Schulzweida's avatar
Uwe Schulzweida committed
315
                      @func{ZAXIS_HYBRID}, @func{ZAXIS_SIGMA}, @func{ZAXIS_PRESSURE}, @func{ZAXIS_HEIGHT},
316
                      @func{ZAXIS_DEPTH_BELOW_SEA} and @func{ZAXIS_DEPTH_BELOW_LAND}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
317
318
319
    @Item  size       Number of levels

@Description
320
The function @func{zaxisCreate} creates a vertical Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
321
322

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
325
@Example
326
Here is an example using @func{zaxisCreate} to create a pressure level Z-axis:
Uwe Schulzweida's avatar
Uwe Schulzweida committed
327
328
329
330
331
332
333
334
335
336
337
338
339

@Source
#include "cdi.h"
   ...
#define  NLEV    5
   ...
double levs[NLEV] = {101300, 92500, 85000, 50000, 20000};
int zaxisID;
   ...
zaxisID = zaxisCreate(ZAXIS_PRESSURE, NLEV);
zaxisDefLevels(zaxisID, levs);
   ...
@EndSource
Uwe Schulzweida's avatar
Uwe Schulzweida committed
340
341
@EndFunction
*/
342
int zaxisCreate(int zaxistype, int size)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
343
{
344
  static char func[] = "zaxisCreate";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
345
346
347
  int ilev;
  int zaxisID;
  double *vals;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
348
  ZAXIS *zaxisptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
349
350
351
352

  if ( CDI_Debug )
    Message(func, "zaxistype: %d size: %d ", zaxistype, size);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
353
  ZAXIS_INIT
Uwe Schulzweida's avatar
Uwe Schulzweida committed
354

Uwe Schulzweida's avatar
Uwe Schulzweida committed
355
356
357
358
359
  zaxisptr = zaxis_new_entry();
  if ( ! zaxisptr ) Error(func, "No memory");

  zaxisID = zaxisptr->self;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
360
  zaxisptr->type = zaxistype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
361
  zaxisptr->size = size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
362

363
364
  if ( zaxistype > CDI_MaxZaxistype )
    Error(func, "Internal problem! zaxistype > CDI_MaxZaxistype");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
365

366
367
368
  zaxisDefName(zaxisID, ZaxistypeEntry[zaxistype].name);
  zaxisDefLongname(zaxisID, ZaxistypeEntry[zaxistype].longname);
  zaxisDefUnits(zaxisID, ZaxistypeEntry[zaxistype].units);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
369
370
371
372
373
374

  vals = (double *) malloc(size*sizeof(double));

  for ( ilev = 0; ilev < size; ilev++ )
    vals[ilev] = 0.0;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
375
  zaxisptr->vals = vals;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
376
377
378
379
380

  return (zaxisID);
}


381
382
383
384
385
386
/*
@Function  zaxisDestroy
@Title     Destroy a vertical Z-axis

@Prototype void zaxisDestroy(int zaxisID)
@Parameter
387
    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}
388
389
390
391
392

@EndFunction
*/
void zaxisDestroy(int zaxisID)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
393
394
395
  ZAXIS *zaxisptr;

  zaxisptr = zaxis_to_pointer(zaxisID);
396
397
398
}


399
char *zaxisNamePtr(int zaxistype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
400
401
402
{
  char *name;

403
404
  if ( zaxistype >= 0 && zaxistype < CDI_MaxZaxistype )
    name = ZaxistypeEntry[zaxistype].longname;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
405
  else
406
    name = ZaxistypeEntry[ZAXIS_GENERIC].longname;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423

  return (name);
}


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
424
425
    @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
426
427

@Description
428
The function @func{zaxisDefName} defines the name of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
429
430
431
432
433

@EndFunction
*/
void zaxisDefName(int zaxisID, const char *name)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
434
435
436
437
  ZAXIS *zaxisptr;

  zaxisptr = zaxis_to_pointer(zaxisID);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
438
  if ( name )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
439
    strcpy(zaxisptr->name, name);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
440
441
442
443
444
445
446
447
448
}


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

@Prototype void zaxisDefLongname(int zaxisID, const char *longname)
@Parameter
449
450
    @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
451
452

@Description
453
The function @func{zaxisDefLongname} defines the longname of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
454
455
456
457
458

@EndFunction
*/
void zaxisDefLongname(int zaxisID, const char *longname)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
459
460
461
462
  ZAXIS *zaxisptr;

  zaxisptr = zaxis_to_pointer(zaxisID);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
463
  if ( longname )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
464
    strcpy(zaxisptr->longname, longname);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
465
466
467
468
469
470
471
472
473
}


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

@Prototype void zaxisDefUnits(int zaxisID, const char *units)
@Parameter
474
475
    @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
476
477

@Description
478
The function @func{zaxisDefUnits} defines the units of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
479
480
481
482
483

@EndFunction
*/
void zaxisDefUnits(int zaxisID, const char *units)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
484
485
486
487
  ZAXIS *zaxisptr;

  zaxisptr = zaxis_to_pointer(zaxisID);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
488
  if ( units )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
489
    strcpy(zaxisptr->units, units);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
490
491
492
493
494
495
496
497
498
}


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

@Prototype void zaxisInqName(int zaxisID, char *name)
@Parameter
499
500
    @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
501
502

@Description
503
The function @func{zaxisInqName} returns the name of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
504
505

@Result
506
@func{zaxisInqName} returns the name of the Z-axis to the parameter name.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
507
508
509
510
511

@EndFunction
*/
void zaxisInqName(int zaxisID, char *name)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
512
513
514
515
516
  ZAXIS *zaxisptr;

  zaxisptr = zaxis_to_pointer(zaxisID);

  strcpy(name, zaxisptr->name);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
517
518
519
520
521
522
523
524
525
}


/*
@Function  zaxisInqLongname
@Title     Get the longname of a Z-axis

@Prototype void zaxisInqLongname(int zaxisID, char *longname)
@Parameter
526
527
    @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
528
529

@Description
530
The function @func{zaxisInqLongname} returns the longname of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
531
532

@Result
533
@func{zaxisInqLongname} returns the longname of the Z-axis to the parameter longname.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
534
535
536
537
538

@EndFunction
*/
void zaxisInqLongname(int zaxisID, char *longname)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
539
540
541
542
543
  ZAXIS *zaxisptr;

  zaxisptr = zaxis_to_pointer(zaxisID);

  strcpy(longname, zaxisptr->longname);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
544
545
546
547
548
549
550
551
552
}


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

@Prototype void zaxisInqUnits(int zaxisID, char *units)
@Parameter
553
554
    @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
555
556

@Description
557
The function @func{zaxisInqUnits} returns the units of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
558
559

@Result
560
@func{zaxisInqUnits} returns the units of the Z-axis to the parameter units.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
561
562
563
564
565

@EndFunction
*/
void zaxisInqUnits(int zaxisID, char *units)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
566
567
568
569
570
  ZAXIS *zaxisptr;

  zaxisptr = zaxis_to_pointer(zaxisID);

  strcpy(units, zaxisptr->units);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
571
572
573
574
575
576
}


void zaxisDefPrec(int zaxisID, int prec)
{
  static char func[] = "zaxisDefPrec";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
577
  ZAXIS *zaxisptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
578

Uwe Schulzweida's avatar
Uwe Schulzweida committed
579
  zaxisptr = zaxis_to_pointer(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
580

Uwe Schulzweida's avatar
Uwe Schulzweida committed
581
582
583
  zaxis_check_ptr(func, zaxisptr);

  zaxisptr->prec = prec;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
584
585
586
587
588
589
}


int zaxisInqPrec(int zaxisID)
{
  static char func[] = "zaxisInqPrec";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
590
591
592
  ZAXIS *zaxisptr;

  zaxisptr = zaxis_to_pointer(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
593

Uwe Schulzweida's avatar
Uwe Schulzweida committed
594
  zaxis_check_ptr(func, zaxisptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
595

Uwe Schulzweida's avatar
Uwe Schulzweida committed
596
  return (zaxisptr->prec);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
597
598
599
}


600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
void zaxisDefLtype(int zaxisID, int ltype)
{
  static char func[] = "zaxisDefLtype";
  ZAXIS *zaxisptr;

  zaxisptr = zaxis_to_pointer(zaxisID);

  zaxis_check_ptr(func, zaxisptr);

  zaxisptr->ltype = ltype;
}


int zaxisInqLtype(int zaxisID)
{
  static char func[] = "zaxisInqLtype";
  ZAXIS *zaxisptr;

  zaxisptr = zaxis_to_pointer(zaxisID);

  zaxis_check_ptr(func, zaxisptr);

  return (zaxisptr->ltype);
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
626
627
628
629
630
631
/*
@Function  zaxisDefLevels
@Title     Define the levels of a Z-axis

@Prototype void zaxisDefLevels(int zaxisID, double *levels)
@Parameter
632
633
    @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
634
635

@Description
636
The function @func{zaxisDefLevels} defines the levels of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
637
638
639
640
641
642
643
644
645

@EndFunction
*/
void zaxisDefLevels(int zaxisID, double *levels)
{
  static char func[] = "zaxisDefLevels";
  int ilev;
  int size;
  double *vals;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
646
  ZAXIS *zaxisptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
647

Uwe Schulzweida's avatar
Uwe Schulzweida committed
648
  zaxisptr = zaxis_to_pointer(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
649

Uwe Schulzweida's avatar
Uwe Schulzweida committed
650
  zaxis_check_ptr(func, zaxisptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
651

Uwe Schulzweida's avatar
Uwe Schulzweida committed
652
653
654
  size = zaxisptr->size;

  vals = zaxisptr->vals;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
655
656
657
658
659
660
661
662
663
664
665
666

  for ( ilev = 0; ilev < size; ilev++ )
    vals[ilev] = levels[ilev];
}


/*
@Function  zaxisDefLevel
@Title     Define one level of a Z-axis

@Prototype void zaxisDefLevel(int zaxisID, int levelID, double level)
@Parameter
667
668
669
    @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
670
671

@Description
672
The function @func{zaxisDefLevel} defines one level of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
673
674
675
676
677
678

@EndFunction
*/
void zaxisDefLevel(int zaxisID, int levelID, double level)
{
  static char func[] = "zaxisDefLevel";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
679
680
681
  ZAXIS *zaxisptr;

  zaxisptr = zaxis_to_pointer(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
682

Uwe Schulzweida's avatar
Uwe Schulzweida committed
683
  zaxis_check_ptr(func, zaxisptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
684

Uwe Schulzweida's avatar
Uwe Schulzweida committed
685
686
  if ( levelID >= 0 && levelID < zaxisptr->size )
    zaxisptr->vals[levelID] = level;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
687
688
689
690
691
692
693
694
695
}


/*
@Function  zaxisInqLevel
@Title     Get one level of a Z-axis

@Prototype double zaxisInqLevel(int zaxisID, int levelID)
@Parameter
696
697
    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}
    @Item  levelID  Level index (range: 0 to nlevel-1)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
698
699

@Description
700
The function @func{zaxisInqLevel} returns one level of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
701
702

@Result
703
@func{zaxisInqLevel} returns the level of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
704
705
706
707
708
709
@EndFunction
*/
double zaxisInqLevel(int zaxisID, int levelID)
{
  static char func[] = "zaxisInqLevel";
  double level = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
710
711
712
  ZAXIS *zaxisptr;

  zaxisptr = zaxis_to_pointer(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
713

Uwe Schulzweida's avatar
Uwe Schulzweida committed
714
  zaxis_check_ptr(func, zaxisptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
715

Uwe Schulzweida's avatar
Uwe Schulzweida committed
716
717
  if ( levelID >= 0 && levelID < zaxisptr->size )
    level = zaxisptr->vals[levelID];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
718
719
720
721
722
723
724
725
726

  return (level);
}


double zaxisInqLbound(int zaxisID, int index)
{
  static char func[] = "zaxisInqLbound";
  double level = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
727
  ZAXIS *zaxisptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
728

Uwe Schulzweida's avatar
Uwe Schulzweida committed
729
  zaxisptr = zaxis_to_pointer(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
730

Uwe Schulzweida's avatar
Uwe Schulzweida committed
731
732
  zaxis_check_ptr(func, zaxisptr);

733
734
735
  if ( zaxisptr->lbounds )
    if ( index >= 0 && index < zaxisptr->size )
      level = zaxisptr->lbounds[index];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
736
737
738
739
740
741
742
743
744

  return (level);
}


double zaxisInqUbound(int zaxisID, int index)
{
  static char func[] = "zaxisInqUbound";
  double level = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
745
746
747
  ZAXIS *zaxisptr;

  zaxisptr = zaxis_to_pointer(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
748

Uwe Schulzweida's avatar
Uwe Schulzweida committed
749
  zaxis_check_ptr(func, zaxisptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
750

751
752
753
  if ( zaxisptr->ubounds )
    if ( index >= 0 && index < zaxisptr->size )
      level = zaxisptr->ubounds[index];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
754
755
756
757
758
759
760

  return (level);
}


const double *zaxisInqLevelsPtr(int zaxisID)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
761
762
763
764
765
  ZAXIS *zaxisptr;

  zaxisptr = zaxis_to_pointer(zaxisID);

  return ( zaxisptr->vals );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
766
767
768
769
770
771
772
773
774
}


/*
@Function  zaxisInqLevels
@Title     Get all levels of a Z-axis

@Prototype void zaxisInqLevels(int zaxisID, double *levels)
@Parameter
775
776
    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}
    @Item  levels   Levels of the Z-axis
Uwe Schulzweida's avatar
Uwe Schulzweida committed
777
778
    
@Description
779
The function @func{zaxisInqLevels} returns all levels of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
780
781

@Result
782
@func{zaxisInqLevels} saves all levels to the parameter @func{levels}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
783
784
785
786
787
788
789
@EndFunction
*/
void zaxisInqLevels(int zaxisID, double *levels)
{
  static char func[] = "zaxisInqLevels";
  int size;
  int i;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
790
  ZAXIS *zaxisptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
791

Uwe Schulzweida's avatar
Uwe Schulzweida committed
792
  zaxisptr = zaxis_to_pointer(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
793

Uwe Schulzweida's avatar
Uwe Schulzweida committed
794
795
796
  zaxis_check_ptr(func, zaxisptr);

  size = zaxisptr->size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
797
  for ( i = 0; i < size; i++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
798
    levels[i] =  zaxisptr->vals[i];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
799
800
801
802
803
804
805
806
}


int zaxisInqLbounds(int zaxisID, double *lbounds)
{
  static char func[] = "zaxisInqLbounds";
  int size = 0;
  int i;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
807
808
809
  ZAXIS *zaxisptr;

  zaxisptr = zaxis_to_pointer(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
810

Uwe Schulzweida's avatar
Uwe Schulzweida committed
811
  zaxis_check_ptr(func, zaxisptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
812

Uwe Schulzweida's avatar
Uwe Schulzweida committed
813
  if ( zaxisptr->lbounds )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
814
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
815
      size = zaxisptr->size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
816
817
818

      if ( lbounds )
	for ( i = 0; i < size; i++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
819
	  lbounds[i] =  zaxisptr->lbounds[i];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
820
821
822
823
824
825
826
827
828
829
830
    }

  return (size);
}


int zaxisInqUbounds(int zaxisID, double *ubounds)
{
  static char func[] = "zaxisInqUbounds";
  int size = 0;
  int i;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
831
  ZAXIS *zaxisptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
832

Uwe Schulzweida's avatar
Uwe Schulzweida committed
833
  zaxisptr = zaxis_to_pointer(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
834

Uwe Schulzweida's avatar
Uwe Schulzweida committed
835
836
837
  zaxis_check_ptr(func, zaxisptr);

  if ( zaxisptr->ubounds )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
838
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
839
      size = zaxisptr->size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
840
841
842

      if ( ubounds )
	for ( i = 0; i < size; i++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
843
	  ubounds[i] =  zaxisptr->ubounds[i];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
844
845
846
847
848
849
850
851
852
853
854
    }

  return (size);
}


int zaxisInqWeights(int zaxisID, double *weights)
{
  static char func[] = "zaxisInqWeights";
  int size = 0;
  int i;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
855
856
857
  ZAXIS *zaxisptr;

  zaxisptr = zaxis_to_pointer(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
858

Uwe Schulzweida's avatar
Uwe Schulzweida committed
859
  zaxis_check_ptr(func, zaxisptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
860

Uwe Schulzweida's avatar
Uwe Schulzweida committed
861
  if ( zaxisptr->weights )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
862
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
863
      size = zaxisptr->size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
864
865
866

      if ( weights )
	for ( i = 0; i < size; i++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
867
	  weights[i] =  zaxisptr->weights[i];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
868
869
870
871
872
873
874
875
876
877
878
879
    }

  return (size);
}


int zaxisInqLevelID(int zaxisID, double level)
{
  static char func[] = "zaxisInqLevelID";
  int size;
  int levelID = CDI_UNDEFID;
  int i;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
880
881
882
  ZAXIS *zaxisptr;

  zaxisptr = zaxis_to_pointer(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
883

Uwe Schulzweida's avatar
Uwe Schulzweida committed
884
  zaxis_check_ptr(func, zaxisptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
885

Uwe Schulzweida's avatar
Uwe Schulzweida committed
886
  size = zaxisptr->size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
887
  for ( i = 0; i < size; i++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
888
    if ( fabs(level-zaxisptr->vals[i]) < DBL_EPSILON ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
889
890
891
892
893
894
895
896
897
898
899
900
901

  if ( i < size ) levelID = i;

  return (levelID);
}


/*
@Function  zaxisInqType
@Title     Get the type of a Z-axis

@Prototype int zaxisInqType(int zaxisID)
@Parameter
902
    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
903
904

@Description
905
The function @func{zaxisInqType} returns the type of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
906
907

@Result
908
@func{zaxisInqType} returns the type of the Z-axis,
Uwe Schulzweida's avatar
Uwe Schulzweida committed
909
one of the set of predefined CDI Z-axis types.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
910
The valid CDI Z-axis types are @func{ZAXIS_GENERIC}, @func{ZAXIS_SURFACE},
Uwe Schulzweida's avatar
Uwe Schulzweida committed
911
@func{ZAXIS_HYBRID}, @func{ZAXIS_SIGMA}, @func{ZAXIS_PRESSURE}, @func{ZAXIS_HEIGHT},
912
@func{ZAXIS_DEPTH_BELOW_SEA} and @func{ZAXIS_DEPTH_BELOW_LAND}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
913
914
915
916
917
918

@EndFunction
*/
int zaxisInqType(int zaxisID)
{
  static char func[] = "zaxisInqType";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
919
  ZAXIS *zaxisptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
920

Uwe Schulzweida's avatar
Uwe Schulzweida committed
921
  zaxisptr = zaxis_to_pointer(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
922

Uwe Schulzweida's avatar
Uwe Schulzweida committed
923
924
925
  zaxis_check_ptr(func, zaxisptr);

  return (zaxisptr->type);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
926
927
928
929
930
931
932
933
934
}


/*
@Function  zaxisInqSize
@Title     Get the size of a Z-axis

@Prototype int zaxisInqSize(int zaxisID)
@Parameter
935
    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
936
937

@Description
938
The function @func{zaxisInqSize} returns the size of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
939
940

@Result
941
@func{zaxisInqSize} returns the number of levels of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
942
943
944
945
946
947
948

@EndFunction
*/
int zaxisInqSize(int zaxisID)
{
  static char func[] = "zaxisInqSize";
  int size = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
949
950
951
  ZAXIS *zaxisptr;

  zaxisptr = zaxis_to_pointer(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
952

Uwe Schulzweida's avatar
Uwe Schulzweida committed
953
  zaxis_check_ptr(func, zaxisptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
954

Uwe Schulzweida's avatar
Uwe Schulzweida committed
955
  size = zaxisptr->size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
956
957
958
959
960
961
962
963
964

  return (size);
}


void cdiCheckZaxis(int zaxisID)
{
  static char func[] = "cdiCheckZaxis";
  int size, i, found;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
965
966
967
  ZAXIS *zaxisptr;

  zaxisptr = zaxis_to_pointer(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
968
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
969
  zaxis_check_ptr(func, zaxisptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
970
971
972

  if ( zaxisInqType(zaxisID) == ZAXIS_GENERIC )
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
973
      size = zaxisptr->size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
974
975
976
      if ( size > 1 )
	{
	  /* check direction */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
977
	  if ( zaxisptr->direction == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
978
979
980
	    {
	      found = 0;
	      for ( i = 1; i < size; i++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
981
		if ( zaxisptr->vals[i] > zaxisptr->vals[i-1] )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
982
983
984
		  found++;
	      if ( found == size-1 )
		{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
985
		  zaxisptr->direction = LevelUp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
986
987
988
989
990
		}
	      else
		{
		  found = 0;
		  for ( i = 1; i < size; i++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
991
		    if ( zaxisptr->vals[i] < zaxisptr->vals[i-1] )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
992
993
994
		      found++;
		  if ( found == size-1 )
		    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
995
		      zaxisptr->direction = LevelDown;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
996
997
998
999
		    }
		}
	    }
	  /* check consistent */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1000
	  if ( zaxisptr->direction == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
	    {
	      Warning(func, "direction undefined for zaxisID %d", zaxisID);
	    }
	}
    }
}


void zaxisDefVct(int zaxisID, int size, const double *vct)
{
  static char func[] = "zaxisDefVct";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1012
  ZAXIS *zaxisptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1013

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1014
  zaxisptr = zaxis_to_pointer(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1015

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1016
1017
1018
  zaxis_check_ptr(func, zaxisptr);

  if ( zaxisptr->vct == 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1019
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1020
1021
1022
      zaxisptr->vctsize = size;
      zaxisptr->vct = (double *) malloc(size*sizeof(double));
      memcpy(zaxisptr->vct, vct, size*sizeof(double));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1023
1024
    }
  else
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1025
    if ( zaxisptr->vctsize != size )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1026
      Warning(func, "VCT was already defined");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1027
1028
1029
1030
1031
1032
}


int zaxisInqVctSize(int zaxisID)
{
  static char func[] = "zaxisInqVctSize";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1033
1034
1035
  ZAXIS *zaxisptr;

  zaxisptr = zaxis_to_pointer(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1036

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1037
  zaxis_check_ptr(func, zaxisptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1038

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1039
  return (zaxisptr->vctsize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1040
1041
1042
1043
1044
1045
}


const double *zaxisInqVctPtr(int zaxisID)
{
  static char func[] = "zaxisInqVctPtr";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1046
  ZAXIS *zaxisptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1047

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1048
  zaxisptr = zaxis_to_pointer(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1049

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1050
1051
1052
  zaxis_check_ptr(func, zaxisptr);

  return (zaxisptr->vct);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1053
1054
1055
1056
1057
1058
1059
}


void zaxisDefLbounds(int zaxisID, double *lbounds)
{
  static char func[] = "zaxisDefLbounds";
  size_t size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1060
1061
1062
  ZAXIS *zaxisptr;

  zaxisptr = zaxis_to_pointer(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1063

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1064
  zaxis_check_ptr(func, zaxisptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1065

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1066
  size = zaxisptr->size;
1067
1068
1069
1070
  
  if ( CDI_Debug )
    if ( zaxisptr->lbounds != NULL )
      Warning(func, "Lower bounds already defined for zaxisID = %d", zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1071

1072
1073
  if ( zaxisptr->lbounds == NULL )
    zaxisptr->lbounds = (double *) malloc(size*sizeof(double));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1074

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1075
  memcpy(zaxisptr->lbounds, lbounds, size*sizeof(double));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1076
1077
1078
1079
1080
1081
1082
}


void zaxisDefUbounds(int zaxisID, double *ubounds)
{
  static char func[] = "zaxisDefUbounds";
  size_t size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1083
  ZAXIS *zaxisptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1084

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1085
  zaxisptr = zaxis_to_pointer(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1086

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1087
  zaxis_check_ptr(func, zaxisptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1088

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1089
1090
  size = zaxisptr->size;

1091
1092
1093
1094
1095
1096
  if ( CDI_Debug )
    if ( zaxisptr->ubounds != NULL )
      Warning(func, "Upper bounds already defined for zaxisID = %d", zaxisID);

  if ( zaxisptr->ubounds == NULL )
    zaxisptr->ubounds = (double *) malloc(size*sizeof(double));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1097

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1098
  memcpy(zaxisptr->ubounds, ubounds, size*sizeof(double));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1099
1100
1101
1102
1103
1104
1105
}


void zaxisDefWeights(int zaxisID, double *weights)
{
  static char func[] = "zaxisDefWeights";
  size_t size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1106
1107
1108
  ZAXIS *zaxisptr;

  zaxisptr = zaxis_to_pointer(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1109

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1110
  zaxis_check_ptr(func, zaxisptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1111

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1112
  size = zaxisptr->size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1113

1114
1115
1116
1117
1118
1119
  if ( CDI_Debug )
    if ( zaxisptr->weights != NULL )
      Warning(func, "Weights already defined for zaxisID = %d", zaxisID);

  if ( zaxisptr->weights == NULL )
    zaxisptr->weights = (double *) malloc(size*sizeof(double));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1120

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1121
  memcpy(zaxisptr->weights, weights, size*sizeof(double));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1122
1123
1124
}


1125
void zaxisChangeType(int zaxisID, int zaxistype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1126
1127
{
  static char func[] = "zaxisChangeType";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1128
  ZAXIS *zaxisptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1129

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1130
1131
1132
  zaxisptr = zaxis_to_pointer(zaxisID);

  zaxis_check_ptr(func, zaxisptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1133
1134

  Message(func, "Change zaxis type from %s to %s\n",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1135
	  zaxisNamePtr(zaxisptr->type),
1136
	  zaxisNamePtr(zaxistype));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1137
  
1138
  zaxisptr->type = zaxistype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1139
1140
1141
1142
1143
1144
}


void zaxisResize(int zaxisID, int size)
{
  static char func[] = "zaxisResize";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1145
1146
1147
  ZAXIS *zaxisptr;

  zaxisptr = zaxis_to_pointer(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1148

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1149
  zaxis_check_ptr(func, zaxisptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1150

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1151
  zaxisptr->size = size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1152

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1153
  if ( zaxisptr->vals )
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
1154
    zaxisptr->vals = (double *) realloc(zaxisptr->vals, size*sizeof(double));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1155
1156
1157
1158
1159
1160
1161
1162
1163
}


int zaxisDuplicate(int zaxisID)
{
  static char func[] = "zaxisDuplicate";
  int zaxisIDnew;
  int zaxistype, zaxissize;
  int size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1164
1165
1166
  ZAXIS *zaxisptr, *zaxisptrnew;

  zaxisptr = zaxis_to_pointer(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1167
1168
1169
1170

  zaxistype = zaxisInqType(zaxisID);
  zaxissize = zaxisInqSize(zaxisID);

1171
  zaxisIDnew = zaxisCreate(zaxistype, zaxissize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1172
  zaxisptrnew = zaxis_to_pointer(zaxisIDnew);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1173

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1174
  zaxis_copy(zaxisptrnew, zaxisptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1175

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1176
1177
1178
  strcpy(zaxisptrnew->name, zaxisptr->name);
  strcpy(zaxisptrnew->longname, zaxisptr->longname);
  strcpy(zaxisptrnew->units, zaxisptr->units);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1179

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1180
  if ( zaxisptr->vals != NULL )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1181
1182
1183
    {
      size = zaxissize;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1184
1185
      zaxisptrnew->vals = (double *) malloc(size*sizeof(double));
      memcpy(zaxisptrnew->vals, zaxisptr->vals, size*sizeof(double));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1186
1187
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1188
  if ( zaxisptr->lbounds )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1189
1190
1191
    {
      size = zaxissize;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1192
1193
      zaxisptrnew->lbounds = (double *) malloc(size*sizeof(double));
      memcpy(zaxisptrnew->lbounds, zaxisptr->lbounds, size*sizeof(double));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1194
1195
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1196
  if ( zaxisptr->ubounds )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1197
1198
1199
    {
      size = zaxissize;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1200
1201
      zaxisptrnew->ubounds = (double *) malloc(size*sizeof(double));
      memcpy(zaxisptrnew->ubounds, zaxisptr->ubounds, size*sizeof(double));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1202
1203
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1204
  if ( zaxisptr->vct != NULL )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1205
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1206
      size = zaxisptr->vctsize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1207
1208
1209

      if ( size )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1210
1211
1212
	  zaxisptrnew->vctsize = size;
	  zaxisptrnew->vct = (double *) malloc(size*sizeof(double));
	  memcpy(zaxisptrnew->vct, zaxisptr->vct, size*sizeof(double));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
	}
    }

  return (zaxisIDnew);
}


void zaxisPrint(int zaxisID)
{
  FILE *fp = stdout;
  int type;
  int nlevels, levelID;
  int nbyte0, nbyte;
  double level;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1227
1228
1229
  ZAXIS *zaxisptr;

  zaxisptr = zaxis_to_pointer(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239

  type    = zaxisInqType(zaxisID);
  nlevels = zaxisInqSize(zaxisID);

  nbyte0 = 0;
  fprintf(fp, "#\n");
  fprintf(fp, "# zaxisID %d\n", zaxisID);
  fprintf(fp, "#\n");
  fprintf(fp, "zaxistype : %s\n", zaxisNamePtr(type));
  fprintf(fp, "size      : %d\n", nlevels);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1240
1241
1242
  if ( zaxisptr->name[0]     ) fprintf(fp, "name      : %s\n", zaxisptr->name);
  if ( zaxisptr->longname[0] ) fprintf(fp, "longname  : %s\n", zaxisptr->longname);
  if ( zaxisptr->units[0]    ) fprintf(fp, "units     : %s\n", zaxisptr->units);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258

  nbyte0 = fprintf(fp, "levels    : ");
  nbyte = nbyte0;
  for ( levelID = 0; levelID < nlevels; levelID++ )
    {
      if ( nbyte > 80 )
	{
	  fprintf(stdout, "\n");
	  fprintf(stdout, "%*s", nbyte0, "");
	  nbyte = nbyte0;
	}
      level = zaxisInqLevel(zaxisID, levelID);
      nbyte += fprintf(stdout, "%.9g ", level);
    }
  fprintf(stdout, "\n");

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1259
  if ( zaxisptr->lbounds && zaxisptr->ubounds )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
    {
      double level1, level2;
      nbyte = nbyte0;
      nbyte0 = fprintf(stdout, "%32s : ", "bounds");
      for ( levelID = 0; levelID < nlevels; levelID++ )
	{
	  if ( nbyte > 80 )
	    {
	      fprintf(stdout, "\n");
	      fprintf(stdout, "%*s", nbyte0, "");
	      nbyte = nbyte0;
	    }
	  level1 = zaxisInqLbound(zaxisID, levelID);
	  level2 = zaxisInqUbound(zaxisID, levelID);
	  nbyte += fprintf(stdout, "%.9g-%.9g ", level1, level2);
	}
      fprintf(stdout, "\n");
    }

1279
  if ( type == ZAXIS_HYBRID || type == ZAXIS_HYBRID_HALF )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
    {
      int i;
      int vctsize;
      const double *vct;

      vctsize = zaxisInqVctSize(zaxisID);
      vct     = zaxisInqVctPtr(zaxisID);
      fprintf(stdout, "vctsize   : %d\n", vctsize);
      if ( vctsize )
	{
	  nbyte0 = fprintf(stdout, "vct       : ");
	  nbyte = nbyte0;
	  for ( i = 0; i < vctsize; i++ )
	    {
	      if ( nbyte > 70 )
		{
		  fprintf(stdout, "\n%*s", nbyte0, "");
		  nbyte = nbyte0;
		}
	      nbyte += fprintf(stdout, "%.9g ", vct[i]);
	    }
	  fprintf(stdout, "\n");
	  /*
	  nbyte0 = fprintf(stdout, "vct_b     : ");
	  nbyte  = nbyte0;
	  for ( i = 0; i < vctsize/2; i++ )
	    {
	      if ( nbyte > 70 )
		{
		  fprintf(stdout, "\n%*s", nbyte0, "");
		  nbyte = nbyte0;
		}
	      nbyte += fprintf(stdout, "%.9g ", vct[vctsize/2+i]);
	    }
	  fprintf(stdout, "\n");
	  */
	}
    }
}