zaxis.c 26.5 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
27
28
29
30
31
  {"sfc",     "surface",                  ""},
  {"lev",     "generic",                  "level"},
  {"lev",     "hybrid",                   "level"},
  {"lev",     "hybrid_half",              "level"},
  {"lev",     "pressure",                 "Pa"},
  {"height",  "height",                   "m"},
  {"depth",   "depth below sea",          "m"},
  {"depth",   "depth below land",         "cm"},
  {"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
733
734
  zaxis_check_ptr(func, zaxisptr);

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

  return (level);
}


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

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

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

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

  return (level);
}


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

  zaxisptr = zaxis_to_pointer(zaxisID);

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


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

@Prototype void zaxisInqLevels(int zaxisID, double *levels)
@Parameter
773
774
    @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
775
776
    
@Description
777
The function @func{zaxisInqLevels} returns all levels of a Z-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
778
779

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
792
793
794
  zaxis_check_ptr(func, zaxisptr);

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


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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
809
  zaxis_check_ptr(func, zaxisptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
810

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

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

  return (size);
}


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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
833
834
835
  zaxis_check_ptr(func, zaxisptr);

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

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

  return (size);
}


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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
857
  zaxis_check_ptr(func, zaxisptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
858

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

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

  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
878
879
880
  ZAXIS *zaxisptr;

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
882
  zaxis_check_ptr(func, zaxisptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
883

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

  if ( i < size ) levelID = i;

  return (levelID);
}


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

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

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

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

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
921
922
923
  zaxis_check_ptr(func, zaxisptr);

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


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

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

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

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

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
951
  zaxis_check_ptr(func, zaxisptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
952

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

  return (size);
}


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

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

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1014
1015
1016
  zaxis_check_ptr(func, zaxisptr);

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


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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1035
  zaxis_check_ptr(func, zaxisptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1036

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


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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1048
1049
1050
  zaxis_check_ptr(func, zaxisptr);

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


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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1062
  zaxis_check_ptr(func, zaxisptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1063

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1064
  size = zaxisptr->size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1065

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1066
  if ( zaxisptr->lbounds != NULL )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1067
1068
    Warning(func, "Lbounds allready defined for zaxisID = %d", zaxisID);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1069
1070
  zaxisptr->lbounds = (double *) malloc(size*sizeof(double));
  memcpy(zaxisptr->lbounds, lbounds, size*sizeof(double));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1071
1072
1073
1074
1075
1076
1077
}


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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1082
  zaxis_check_ptr(func, zaxisptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1083

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1084
1085
1086
  size = zaxisptr->size;

  if ( zaxisptr->ubounds != NULL )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1087
1088
    Warning(func, "Ubounds allready defined for zaxisID = %d", zaxisID);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1089
1090
  zaxisptr->ubounds = (double *) malloc(size*sizeof(double));
  memcpy(zaxisptr->ubounds, ubounds, size*sizeof(double));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1091
1092
1093
1094
1095
1096
1097
}


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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1102
  zaxis_check_ptr(func, zaxisptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1103

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1104
  size = zaxisptr->size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1105

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1106
  if ( zaxisptr->weights != NULL )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1107
1108
    Warning(func, "Weights allready defined for zaxisID = %d", zaxisID);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1109
1110
  zaxisptr->weights = (double *) malloc(size*sizeof(double));
  memcpy(zaxisptr->weights, weights, size*sizeof(double));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1111
1112
1113
}


1114
void zaxisChangeType(int zaxisID, int zaxistype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1115
1116
{
  static char func[] = "zaxisChangeType";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1117
  ZAXIS *zaxisptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1118

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1119
1120
1121
  zaxisptr = zaxis_to_pointer(zaxisID);

  zaxis_check_ptr(func, zaxisptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1122
1123

  Message(func, "Change zaxis type from %s to %s\n",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1124
	  zaxisNamePtr(zaxisptr->type),
1125
	  zaxisNamePtr(zaxistype));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1126
  
1127
  zaxisptr->type = zaxistype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1128
1129
1130
1131
1132
1133
}


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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1138
  zaxis_check_ptr(func, zaxisptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1139

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1140
  zaxisptr->size = size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1141

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1142
  if ( zaxisptr->vals )
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
1143
    zaxisptr->vals = (double *) realloc(zaxisptr->vals, size*sizeof(double));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1144
1145
1146
1147
1148
1149
1150
1151
1152
}


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

  zaxisptr = zaxis_to_pointer(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1156
1157
1158
1159

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

1160
  zaxisIDnew = zaxisCreate(zaxistype, zaxissize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1161
  zaxisptrnew = zaxis_to_pointer(zaxisIDnew);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1162

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1163
  zaxis_copy(zaxisptrnew, zaxisptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1164

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1165
1166
1167
  strcpy(zaxisptrnew->name, zaxisptr->name);
  strcpy(zaxisptrnew->longname, zaxisptr->longname);
  strcpy(zaxisptrnew->units, zaxisptr->units);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1168

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1169
  if ( zaxisptr->vals != NULL )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1170
1171
1172
    {
      size = zaxissize;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1173
1174
      zaxisptrnew->vals = (double *) malloc(size*sizeof(double));
      memcpy(zaxisptrnew->vals, zaxisptr->vals, size*sizeof(double));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1175
1176
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1177
  if ( zaxisptr->lbounds )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1178
1179
1180
    {
      size = zaxissize;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1181
1182
      zaxisptrnew->lbounds = (double *) malloc(size*sizeof(double));
      memcpy(zaxisptrnew->lbounds, zaxisptr->lbounds, size*sizeof(double));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1183
1184
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1185
  if ( zaxisptr->ubounds )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1186
1187
1188
    {
      size = zaxissize;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1189
1190
      zaxisptrnew->ubounds = (double *) malloc(size*sizeof(double));
      memcpy(zaxisptrnew->ubounds, zaxisptr->ubounds, size*sizeof(double));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1191
1192
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1193
  if ( zaxisptr->vct != NULL )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1194
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1195
      size = zaxisptr->vctsize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1196
1197
1198

      if ( size )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1199
1200
1201
	  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
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
	}
    }

  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
1216
1217
1218
  ZAXIS *zaxisptr;

  zaxisptr = zaxis_to_pointer(zaxisID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228

  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
1229
1230
1231
  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
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247

  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
1248
  if ( zaxisptr->lbounds && zaxisptr->ubounds )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
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
    {
      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");
    }

  if ( type == ZAXIS_HYBRID )
    {
      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");
	  */
	}
    }
}