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

#include "dmemory.h"
#include "cdi.h"
#include "stream_int.h"
#include "vlist.h"
#include "varscan.h"
10
#include "namespace.h"
11
#include "pio_util.h"
12
#include "resource_handle.h"
Thomas Jahns's avatar
Thomas Jahns committed
13
#include "vlist_var.h"
14
#include "vlist_att.h"
15
#include "pio_rpc.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
16

17
static int VLIST_Debug = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
18
19
20
21
22
23

static void vlist_initialize(void);

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

24
static pthread_once_t  _vlist_init_thread = PTHREAD_ONCE_INIT;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
25

26
#  define VLIST_INIT()        \
27
  pthread_once(&_vlist_init_thread, vlist_initialize)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
28
29
30

#else

31
static int vlistIsInitialized = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
32

33
34
35
#  define VLIST_INIT()               \
  if ( _vlist_init == FALSE ) vlist_initialize()
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
36
37


38
39
40
/* FIXME: implementation incomplete, fix once leaf nodes are complete */
static int
vlist_compare(vlist_t *a, vlist_t *b)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
41
{
42
43
44
45
46
47
  int diff;
  diff = (a->nvars != b->nvars) || (a->ngrids != b->ngrids)
    || (a->nzaxis != b->nzaxis) || (a->instID != b->instID)
    || (a->modelID != b->modelID) || (a->tableID != b->tableID)
    || (a->ntsteps != b->ntsteps);
  return diff;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
48
49
}

50
static void
51
vlistPrintKernel(vlist_t *vlistptr, FILE * fp );
52
#ifdef USE_MPI
53
static int  vlistGetSizeP ( void * vlistptr, MPI_Comm comm );
54
55
static void vlistPackP    ( void * vlistptr, void * buff, int size,
                            int *position, MPI_Comm comm );
56
static int  vlistTxCode   ( void );
57
#endif
58

59
60
resOps vlist_ops = {
  (valCompareFunc)vlist_compare,
61
  free,
62
63
64
  (valPrintFunc)vlistPrintKernel
#ifdef USE_MPI
  , vlistGetSizeP,
65
66
  vlistPackP,
  vlistTxCode
67
#endif
68
};
Uwe Schulzweida's avatar
Uwe Schulzweida committed
69
70


71
vlist_t *vlist_to_pointer(int code)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
72
{
73
  VLIST_INIT();
74
  return reshGetVal(code, &vlist_ops );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
75
76
}

77
78
static
void vlist_init_entry(vlist_t *vlistptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
79
{
80
  vlistptr->self           = reshPut(vlistptr, &vlist_ops);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
81
82
83
84
85

  vlistptr->nvars          = 0;
  vlistptr->vars           = NULL;
  vlistptr->ngrids         = 0;
  vlistptr->nzaxis         = 0;
86
  vlistptr->taxisID        = CDI_UNDEFID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
87
88
89
90
91
  vlistptr->instID         = cdiDefaultInstID;
  vlistptr->modelID        = cdiDefaultModelID;
  vlistptr->tableID        = cdiDefaultTableID;
  vlistptr->varsAllocated  = 0;
  vlistptr->ntsteps        = CDI_UNDEFID;
92
  vlistptr->atts.nalloc    = MAX_ATTRIBUTES;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
93
  vlistptr->atts.nelems    = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
94
95
}

96
97
static
vlist_t *vlist_new_entry(void)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
98
{
99
  vlist_t *vlistptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
100

101
  vlistptr = (vlist_t *)xmalloc(sizeof(vlist_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
102

103
  vlist_init_entry(vlistptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
104
105
106
107

  return (vlistptr);
}

108
109
static
void vlist_delete_entry(vlist_t *vlistptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
110
{
Thomas Jahns's avatar
Thomas Jahns committed
111
  int idx;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
112
113
114

  idx = vlistptr->self;

115
  reshRemove(idx, &vlist_ops );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
116
117
118
119

  free(vlistptr);

  if ( VLIST_Debug )
120
    Message("Removed idx %d from vlist list", idx);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
121
122
}

123
124
static
void vlist_initialize(void)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
125
126
127
128
129
130
131
{
  char *env;

  env = getenv("VLIST_DEBUG");
  if ( env ) VLIST_Debug = atoi(env);
}

132
133
static
void vlist_copy(vlist_t *vlistptr2, vlist_t *vlistptr1)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
134
135
136
137
{
  int vlistID2;

  vlistID2 = vlistptr2->self;
138
  memcpy(vlistptr2, vlistptr1, sizeof(vlist_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
139
  vlistptr2->atts.nelems = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
140
141
142
  vlistptr2->self = vlistID2;
}

143
144
static
void vlist_check_ptr(const char *caller, vlist_t *vlistptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
145
146
{
  if ( vlistptr == NULL )
147
    Errorc("vlist undefined!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
148
149
150
}

/*
151
@Function  vlistCreate
Uwe Schulzweida's avatar
Uwe Schulzweida committed
152
153
@Title     Create a variable list

154
@Prototype int vlistCreate(void)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
155

Uwe Schulzweida's avatar
Uwe Schulzweida committed
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
@Example
Here is an example using @func{vlistCreate} to create a variable list
and add a variable with @func{vlistDefVar}.

@Source
#include "cdi.h"
   ...
int vlistID, varID;
   ...
vlistID = vlistCreate();
varID = vlistDefVar(vlistID, gridID, zaxisID, TIME_VARIABLE);
   ...
streamDefVlist(streamID, vlistID);
   ...
vlistDestroy(vlistID);
   ...
@EndSource
Uwe Schulzweida's avatar
Uwe Schulzweida committed
173
174
@EndFunction
*/
175
int vlistCreate(void)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
176
177
{
  int vlistID = 0;
178
  vlist_t *vlistptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
179

180
  VLIST_INIT();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
181
182
183
184
185
186
187
188
189

  vlistptr = vlist_new_entry();

  vlistID = vlistptr->self;

  return (vlistID);
}

/*
190
@Function  vlistDestroy
191
@Title     Destroy a variable list
Uwe Schulzweida's avatar
Uwe Schulzweida committed
192

193
@Prototype void vlistDestroy(int vlistID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
194
@Parameter
195
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
196
197
198

@EndFunction
*/
199
void vlistDestroy(int vlistID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
200
{
201
  vlist_t *vlistptr;
Deike Kleberg's avatar
Deike Kleberg committed
202
203
  int nvars;
  int varID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
204
205
206

  vlistptr = vlist_to_pointer(vlistID);

207
  vlist_check_ptr(__func__, vlistptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
208

Deike Kleberg's avatar
Deike Kleberg committed
209
  vlistDelAtts(vlistID, CDI_GLOBAL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
210

Deike Kleberg's avatar
Deike Kleberg committed
211
  nvars = vlistptr->nvars;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
212

Deike Kleberg's avatar
Deike Kleberg committed
213
214
215
216
217
218
219
220
221
  for ( varID = 0; varID < nvars; varID++ )
    {
      if ( vlistptr->vars[varID].levinfo )  free(vlistptr->vars[varID].levinfo);
      if ( vlistptr->vars[varID].name )     free(vlistptr->vars[varID].name);
      if ( vlistptr->vars[varID].longname ) free(vlistptr->vars[varID].longname);
      if ( vlistptr->vars[varID].stdname )  free(vlistptr->vars[varID].stdname);
      if ( vlistptr->vars[varID].units )    free(vlistptr->vars[varID].units);
      
      vlistDelAtts(vlistID, varID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
222
    }
Deike Kleberg's avatar
Deike Kleberg committed
223
224
  
  if ( vlistptr->vars ) free(vlistptr->vars);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
225

Deike Kleberg's avatar
Deike Kleberg committed
226
  vlist_delete_entry(vlistptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
227
228
229
230
231
232
233
234
}

/*
@Function  vlistCopy
@Title     Copy a variable list

@Prototype void vlistCopy(int vlistID2, int vlistID1)
@Parameter
235
236
    @Item  vlistID2  Target variable list ID
    @Item  vlistID1  Source variable list ID
Uwe Schulzweida's avatar
Uwe Schulzweida committed
237
238

@Description
239
The function @func{vlistCopy} copies all entries from vlistID1 to vlistID2.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
240
241
242
243
244

@EndFunction
*/
void vlistCopy(int vlistID2, int vlistID1)
{
245
  vlist_t *vlistptr1, *vlistptr2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
246
247
248
249

  vlistptr1 = vlist_to_pointer(vlistID1);
  vlistptr2 = vlist_to_pointer(vlistID2);

250
251
  vlist_check_ptr(__func__, vlistptr1);
  vlist_check_ptr(__func__, vlistptr2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
252
253
254

  vlist_copy(vlistptr2, vlistptr1);

255
  vlistCopyVarAtts(vlistID1, CDI_GLOBAL, vlistID2, CDI_GLOBAL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
256

Uwe Schulzweida's avatar
Uwe Schulzweida committed
257
258
259
260
261
  if ( vlistptr1->vars )
    {
      int nvars = vlistptr1->nvars;
      int nlevs, varID;

262
263
264
      //vlistptr2->varsAllocated = nvars;
      vlistptr2->vars = (var_t *) malloc(vlistptr2->varsAllocated*sizeof(var_t));
      memcpy(vlistptr2->vars, vlistptr1->vars, vlistptr2->varsAllocated*sizeof(var_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
265
266

      for ( varID = 0; varID < nvars; varID++ )
Thomas Jahns's avatar
Thomas Jahns committed
267
268
269
        {
          if ( vlistptr1->vars[varID].name )
            vlistptr2->vars[varID].name = strdupx(vlistptr1->vars[varID].name);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
270

Thomas Jahns's avatar
Thomas Jahns committed
271
272
          if ( vlistptr1->vars[varID].longname )
            vlistptr2->vars[varID].longname = strdupx(vlistptr1->vars[varID].longname);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
273

Thomas Jahns's avatar
Thomas Jahns committed
274
275
          if ( vlistptr1->vars[varID].stdname )
            vlistptr2->vars[varID].stdname = strdupx(vlistptr1->vars[varID].stdname);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
276

Thomas Jahns's avatar
Thomas Jahns committed
277
278
          if ( vlistptr1->vars[varID].units )
            vlistptr2->vars[varID].units = strdupx(vlistptr1->vars[varID].units);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
279

Thomas Jahns's avatar
Thomas Jahns committed
280
281
282
283
          nlevs = vlistptr1->vars[varID].nlevs;
          vlistptr2->vars[varID].levinfo = (levinfo_t *) malloc(nlevs*sizeof(levinfo_t));
          memcpy(vlistptr2->vars[varID].levinfo,
                 vlistptr1->vars[varID].levinfo, nlevs*sizeof(levinfo_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
284

Thomas Jahns's avatar
Thomas Jahns committed
285
286
287
          vlistptr2->vars[varID].atts.nelems = 0;
          vlistCopyVarAtts(vlistID1, varID, vlistID2, varID);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
288
289
290
291
292
293
294
295
296
    }
}

/*
@Function  vlistDuplicate
@Title     Duplicate a variable list

@Prototype int vlistDuplicate(int vlistID)
@Parameter
297
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
298
299

@Description
300
The function @func{vlistDuplicate} duplicates the variable list from vlistID1.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
301
302

@Result
303
@func{vlistDuplicate} returns an identifier to the duplicated variable list.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
304
305
306
307
308
309

@EndFunction
*/
int vlistDuplicate(int vlistID)
{
  int vlistIDnew;
310
  vlist_t *vlistptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
311
312
313

  vlistptr = vlist_to_pointer(vlistID);

314
  vlist_check_ptr(__func__, vlistptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
315

316
  vlistIDnew = vlistCreate();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
317
318
319

  vlistCopy(vlistIDnew, vlistID);

320
321
322
  if ( ! namespaceHasLocalFile ( namespaceGetActive ()))
    reshSetStatus ( vlistIDnew, &vlist_ops, SUSPENDED );

Uwe Schulzweida's avatar
Uwe Schulzweida committed
323
324
325
326
327
328
329
  return (vlistIDnew);
}


void vlistClearFlag(int vlistID)
{
  int varID, levID;
330
  vlist_t *vlistptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
331
332
333
334
335
336
337

  vlistptr = vlist_to_pointer(vlistID);

  for ( varID = 0; varID < vlistptr->nvars; varID++ )
    {
      vlistptr->vars[varID].flag = FALSE;
      for ( levID = 0; levID < vlistptr->vars[varID].nlevs; levID++ )
Thomas Jahns's avatar
Thomas Jahns committed
338
339
340
        {
          vlistptr->vars[varID].levinfo[levID].flag = FALSE;
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
341
342
343
344
    }
}


345
int vlistInqZaxis(int vlistID, int zaxistype, int nlevels, double *levels, int lbounds, double *levels2,
Thomas Jahns's avatar
Thomas Jahns committed
346
                  int vctsize, const double *vct)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
347
348
349
350
351
352
{
  int zaxisdefined;
  int nzaxis;
  int zaxisID = CDI_UNDEFID;
  int index;
  int zaxisglobdefined = 0;
353
  vlist_t *vlistptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
354
355
356

  vlistptr = vlist_to_pointer(vlistID);

357
  vlist_check_ptr(__func__, vlistptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
358
359
360
361
362
363
364
365

  zaxisdefined = 0;
  nzaxis = vlistptr->nzaxis;

  for ( index = 0; index < nzaxis; index++ )
    {
      zaxisID = vlistptr->zaxisIDs[index];

366
      if ( zaxisCompare(zaxisID, zaxistype, nlevels, lbounds, levels, NULL, NULL, 0) == 0 )
Thomas Jahns's avatar
Thomas Jahns committed
367
368
369
370
        {
          zaxisdefined = 1;
          break;
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
371
372
373
374
375
376
    }

  if ( ! zaxisdefined )
    {
      nzaxis = zaxisSize();
      for ( zaxisID = 0; zaxisID < nzaxis; zaxisID++ )
Thomas Jahns's avatar
Thomas Jahns committed
377
378
379
380
381
        if ( zaxisCompare(zaxisID, zaxistype, nlevels, lbounds, levels, NULL, NULL, 0) == 0 )
          {
            zaxisglobdefined = 1;
            break;
          }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
382
383
384
385
386
    }

  if ( ! zaxisdefined )
    {
      if ( ! zaxisglobdefined )
Thomas Jahns's avatar
Thomas Jahns committed
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
        {
          zaxisID = zaxisCreate(zaxistype, nlevels);
          zaxisDefLevels(zaxisID, levels);
          if ( lbounds )
            {
              zaxisDefLbounds(zaxisID, levels);
              zaxisDefUbounds(zaxisID, levels2);
            }

          if ( zaxistype == ZAXIS_HYBRID )
            {
              if ( vctsize > 0 )
                zaxisDefVct(zaxisID, vctsize, vct);
              else
                Warning("VCT missing");
            }
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418

      nzaxis = vlistptr->nzaxis;
      vlistptr->zaxisIDs[nzaxis] = zaxisID;
      vlistptr->nzaxis++;
    }

  return (zaxisID);
}

/*
@Function  vlistCopyFlag
@Title     Copy some entries of a variable list

@Prototype void vlistCopyFlag(int vlistID2, int vlistID1)
@Parameter
419
420
    @Item  vlistID2  Target variable list ID
    @Item  vlistID1  Source variable list ID
Uwe Schulzweida's avatar
Uwe Schulzweida committed
421
422

@Description
423
The function @func{vlistCopyFlag} copies all entries with a flag from vlistID1 to vlistID2.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
424
425
426
427
428

@EndFunction
*/
void vlistCopyFlag(int vlistID2, int vlistID1)
{
429
  vlist_t *vlistptr1, *vlistptr2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
430
431
432
433

  vlistptr1 = vlist_to_pointer(vlistID1);
  vlistptr2 = vlist_to_pointer(vlistID2);

434
435
  vlist_check_ptr(__func__, vlistptr1);
  vlist_check_ptr(__func__, vlistptr2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
436
437

  vlist_copy(vlistptr2, vlistptr1);
Thomas Jahns's avatar
Thomas Jahns committed
438

439
  vlistCopyVarAtts(vlistID1, CDI_GLOBAL, vlistID2, CDI_GLOBAL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
440

Uwe Schulzweida's avatar
Uwe Schulzweida committed
441
442
443
444
445
446
447
448
449
450
451
452
  if ( vlistptr1->vars )
    {
      int nvars = vlistptr1->nvars;
      int nvars2 = 0, levID2;
      int nlevs, nlevs2, levID, varID, varID2;
      int gridID, zaxisID;
      int index;

      vlistptr2->ngrids = 0;
      vlistptr2->nzaxis = 0;

      for ( varID = 0; varID < nvars; varID++ )
Thomas Jahns's avatar
Thomas Jahns committed
453
        if ( vlistptr1->vars[varID].flag ) nvars2++;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
454
455

      vlistptr2->nvars = nvars2;
456
      vlistptr2->varsAllocated = nvars2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
457
      if ( nvars2 > 0 )
Thomas Jahns's avatar
Thomas Jahns committed
458
        vlistptr2->vars  = (var_t *) malloc(nvars2*sizeof(var_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
459
      else
Thomas Jahns's avatar
Thomas Jahns committed
460
        vlistptr2->vars  = NULL;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
461
462
463

      varID2 = 0;
      for ( varID = 0; varID < nvars; varID++ )
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
	if ( vlistptr1->vars[varID].flag )
	  {
	    vlistptr2->vars[varID2].flag = FALSE;
	    zaxisID = vlistptr1->vars[varID].zaxisID;
	    gridID  = vlistptr1->vars[varID].gridID;

	    memcpy(&vlistptr2->vars[varID2], &vlistptr1->vars[varID], sizeof(var_t));

	    vlistptr1->vars[varID].fvarID = varID2;
	    vlistptr2->vars[varID2].fvarID = varID;

	    vlistptr2->vars[varID2].mvarID = varID2;

	    if ( vlistptr1->vars[varID].name )
	      vlistptr2->vars[varID2].name = strdupx(vlistptr1->vars[varID].name);

	    if ( vlistptr1->vars[varID].longname )
	      vlistptr2->vars[varID2].longname = strdupx(vlistptr1->vars[varID].longname);

	    if ( vlistptr1->vars[varID].stdname )
	      vlistptr2->vars[varID2].stdname = strdupx(vlistptr1->vars[varID].stdname);

	    if ( vlistptr1->vars[varID].units )
	      vlistptr2->vars[varID2].units = strdupx(vlistptr1->vars[varID].units);

	    nlevs  = vlistptr1->vars[varID].nlevs;
	    nlevs2 = 0;
	    for ( levID = 0; levID < nlevs; levID++ )
	      if ( vlistptr1->vars[varID].levinfo[levID].flag ) nlevs2++;

	    vlistptr2->vars[varID2].levinfo = (levinfo_t *) malloc(nlevs2*sizeof(levinfo_t));

	    vlistptr2->vars[varID2].atts.nelems = 0;
	    vlistCopyVarAtts(vlistID1, varID, vlistID2, varID2);

	    if ( nlevs != nlevs2 )
	      {
		int zaxisType;
		int zaxisID2;
		int nvct = 0;
		int lbounds;
		double *levels;
		double *levels2;
		const double *vct = NULL;

		zaxisID = vlistptr1->vars[varID].zaxisID;
		levels = (double *) malloc(nlevs2*sizeof(double));
		levID2 = 0;
		for ( levID = 0; levID < nlevs; levID++ )
		  if ( vlistptr1->vars[varID].levinfo[levID].flag )
		    {
		      vlistptr1->vars[varID].levinfo[levID].flevelID = levID2;
		      vlistptr1->vars[varID].levinfo[levID].mlevelID = levID2;
		      levels[levID2++] = zaxisInqLevel(zaxisID, levID);
		    }

		zaxisType = zaxisInqType(zaxisID);

		if ( zaxisType == ZAXIS_HYBRID )
		  {
		    nvct = zaxisInqVctSize(zaxisID);
		    vct  = zaxisInqVctPtr(zaxisID);
		  }
		lbounds  = 0;     /* <------------ have to defined */
		levels2  = NULL;  /* <------------ have to defined */
		zaxisID2 = vlistInqZaxis(vlistID2, zaxisType, nlevs2, levels, lbounds, levels2, nvct, vct);
		free(levels);

		{
		  char ctemp[256];
		  zaxisInqName(zaxisID, ctemp);
		  zaxisDefName(zaxisID2, ctemp);
		  zaxisInqLongname(zaxisID, ctemp);
		  zaxisDefLongname(zaxisID2, ctemp);
		  zaxisInqUnits(zaxisID, ctemp);
		  zaxisDefUnits(zaxisID2, ctemp);
		}

		zaxisID = zaxisID2;
		vlistptr2->vars[varID2].zaxisID = zaxisID2;
		vlistptr2->vars[varID2].nlevs   = nlevs2;
	      }

	    for ( levID = 0; levID < nlevs2; levID++ )
	      {
		vlistptr2->vars[varID2].levinfo[levID].flag  = FALSE;
		vlistptr2->vars[varID2].levinfo[levID].index = -1;
	      }

	    levID2 = 0;
	    for ( levID = 0; levID < nlevs; levID++ )
	      if ( vlistptr1->vars[varID].levinfo[levID].flag )
		{
		  vlistptr2->vars[varID2].levinfo[levID2].flevelID = levID;
		  vlistptr2->vars[varID2].levinfo[levID2].mlevelID = levID;
		  levID2++;
		}

	    for ( index = 0; index <vlistptr2->ngrids; index++ )
	      if (vlistptr2->gridIDs[index] == gridID ) break;

	    if ( index == vlistptr2->ngrids )
	      {
		vlistptr2->gridIDs[vlistptr2->ngrids++] = gridID;
		if (vlistptr2->ngrids >= MAX_GRIDS_PS )
		  Error("Internal Problem! More than %d grids.", MAX_GRIDS_PS);
	      }

	    for ( index = 0; index < vlistptr2->nzaxis; index++ )
	      if ( vlistptr2->zaxisIDs[index] == zaxisID ) break;

	    if ( index == vlistptr2->nzaxis )
	      {
		vlistptr2->zaxisIDs[vlistptr2->nzaxis++] = zaxisID;
		if (vlistptr2->nzaxis >= MAX_ZAXES_PS )
		  Error("Internal Problem! More than %d zaxis.", MAX_ZAXES_PS);
	      }

	    varID2++;
	  }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
584
585
586
587
588
589
590
591
592
    }
}

/*
@Function  vlistCat
@Title     Concatenate two variable lists

@Prototype void vlistCat(int vlistID2, int vlistID1)
@Parameter
593
594
    @Item  vlistID2  Target variable list ID
    @Item  vlistID1  Source variable list ID
Uwe Schulzweida's avatar
Uwe Schulzweida committed
595
596
597
598
599
600
601
602
603
604
605

@Description
Concatenate the variable list vlistID1 at the end of vlistID2.

@EndFunction
*/
void vlistCat(int vlistID2, int vlistID1)
{
  int nvars, nvars1, nvars2;
  int varID, varID2, nlevs;
  int index, gridID, zaxisID;
606
  vlist_t *vlistptr1, *vlistptr2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
607
608
609
610

  vlistptr1 = vlist_to_pointer(vlistID1);
  vlistptr2 = vlist_to_pointer(vlistID2);

611
612
  vlist_check_ptr(__func__, vlistptr1);
  vlist_check_ptr(__func__, vlistptr2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
613
614
615
616
617
618

  nvars1 = vlistptr1->nvars;
  nvars2 = vlistptr2->nvars;
  nvars = nvars1 + nvars2;
  vlistptr2->nvars = nvars;

619
620
621
622
623
  if ( nvars > vlistptr2->varsAllocated )
    {
      vlistptr2->varsAllocated = nvars;
      vlistptr2->vars = (var_t *) realloc(vlistptr2->vars, nvars*sizeof(var_t));
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
624
  memcpy(vlistptr2->vars+nvars2, vlistptr1->vars, nvars1*sizeof(var_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
625
626
627
628
629
630
631

  for ( varID = 0; varID < nvars1; varID++ )
    {
      varID2 = varID + nvars2;
      vlistptr1->vars[varID].fvarID = varID2;
      vlistptr2->vars[varID2].fvarID = varID;

632
633
634
      vlistptr1->vars[varID].mvarID = varID2;
      vlistptr2->vars[varID2].mvarID = varID;

635
      if ( vlistptr1->vars[varID].param < 0 )
Thomas Jahns's avatar
Thomas Jahns committed
636
637
638
639
640
641
        {
          int pnum, pcat, pdis;
          cdiDecodeParam(vlistptr1->vars[varID].param, &pnum, &pcat, &pdis);
          pnum=-(varID2+1);
          vlistptr2->vars[varID2].param = cdiEncodeParam(pnum, pcat, pdis);
        }
642

Uwe Schulzweida's avatar
Uwe Schulzweida committed
643
      if ( vlistptr1->vars[varID].name )
Thomas Jahns's avatar
Thomas Jahns committed
644
        vlistptr2->vars[varID2].name = strdupx(vlistptr1->vars[varID].name);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
645
646

      if ( vlistptr1->vars[varID].longname )
Thomas Jahns's avatar
Thomas Jahns committed
647
        vlistptr2->vars[varID2].longname = strdupx(vlistptr1->vars[varID].longname);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
648
649

      if ( vlistptr1->vars[varID].stdname )
Thomas Jahns's avatar
Thomas Jahns committed
650
        vlistptr2->vars[varID2].stdname = strdupx(vlistptr1->vars[varID].stdname);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
651
652

      if ( vlistptr1->vars[varID].units )
Thomas Jahns's avatar
Thomas Jahns committed
653
        vlistptr2->vars[varID2].units = strdupx(vlistptr1->vars[varID].units);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
654
655

      nlevs = vlistptr1->vars[varID].nlevs;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
656
657
      vlistptr2->vars[varID2].levinfo = (levinfo_t *) malloc(nlevs*sizeof(levinfo_t));
      memcpy(vlistptr2->vars[varID2].levinfo, vlistptr1->vars[varID].levinfo, nlevs*sizeof(levinfo_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
658

659
660
661
      vlistptr2->vars[varID2].atts.nelems = 0;
      vlistCopyVarAtts(vlistID1, varID, vlistID2, varID2);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
662
663
      gridID = vlistptr1->vars[varID].gridID;
      for ( index = 0; index < vlistptr2->ngrids; index++ )
Thomas Jahns's avatar
Thomas Jahns committed
664
        if ( gridID == vlistptr2->gridIDs[index] ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
665
666

      if ( index == vlistptr2->ngrids )
Thomas Jahns's avatar
Thomas Jahns committed
667
668
669
670
671
        {
          vlistptr2->gridIDs[vlistptr2->ngrids++] = gridID;
          if ( vlistptr2->ngrids >= MAX_GRIDS_PS )
            Error("Internal Problem! More than %d grids.", MAX_GRIDS_PS);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
672
673
674

      zaxisID = vlistptr1->vars[varID].zaxisID;
      for ( index = 0; index < vlistptr2->nzaxis; index++ )
Thomas Jahns's avatar
Thomas Jahns committed
675
        if ( zaxisID == vlistptr2->zaxisIDs[index] ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
676
677

      if ( index == vlistptr2->nzaxis )
Thomas Jahns's avatar
Thomas Jahns committed
678
679
680
681
682
        {
          vlistptr2->zaxisIDs[vlistptr2->nzaxis++] = zaxisID;
          if ( vlistptr2->nzaxis >= MAX_ZAXES_PS )
            Error("Internal Problem! More than %d zaxis.", MAX_ZAXES_PS);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
683
684
685
686
687
688
689
690
691
    }
}

/*
@Function  vlistMerge
@Title     Merge two variable lists

@Prototype void vlistMerge(int vlistID2, int vlistID1)
@Parameter
692
693
    @Item  vlistID2  Target variable list ID
    @Item  vlistID1  Source variable list ID
Uwe Schulzweida's avatar
Uwe Schulzweida committed
694
695

@Description
Uwe Schulzweida's avatar
Uwe Schulzweida committed
696
Merge the variable list vlistID1 to the variable list vlistID2.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
697
698
699
700
701
702
703
704
705
706
707

@EndFunction
*/
void vlistMerge(int vlistID2, int vlistID1)
{
  int nvars1, nvars2;
  int varID = 0, varID2, levID, nlevs, nlevs1, nlevs2;
  int index, zaxisID;
  int zaxisID1, zaxisID2;
  int *lvar;
  double *levels;
708
  vlist_t *vlistptr1, *vlistptr2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
709
710
711
712

  vlistptr1 = vlist_to_pointer(vlistID1);
  vlistptr2 = vlist_to_pointer(vlistID2);

713
714
  vlist_check_ptr(__func__, vlistptr1);
  vlist_check_ptr(__func__, vlistptr2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
715
716
717
718
719
720
721

  nvars1 = vlistptr1->nvars;
  nvars2 = vlistptr2->nvars;

  if ( nvars1 == nvars2 )
    {
      for ( varID = 0; varID < nvars2; varID++ )
Thomas Jahns's avatar
Thomas Jahns committed
722
723
724
725
726
727
728
729
730
731
732
733
        {
          if ( vlistptr1->vars[varID].name && vlistptr2->vars[varID].name )
            {
              if ( strcmp(vlistptr1->vars[varID].name,
                          vlistptr2->vars[varID].name) != 0 ) break;
            }
          else
            {
              if ( vlistptr1->vars[varID].param != vlistptr2->vars[varID].param )
                break;
            }
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
734
735
736
737
738
    }

  if ( varID == nvars2 ) /* same variables in vlistID1 and vlistID2 */
    {
      for ( varID = 0; varID < nvars2; varID++ )
Thomas Jahns's avatar
Thomas Jahns committed
739
740
741
        {
          vlistptr1->vars[varID].fvarID = varID;
          vlistptr2->vars[varID].fvarID = varID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
742

Thomas Jahns's avatar
Thomas Jahns committed
743
744
          vlistptr1->vars[varID].mvarID = varID;
          vlistptr2->vars[varID].mvarID = varID;
745

Thomas Jahns's avatar
Thomas Jahns committed
746
747
          nlevs1 = vlistptr1->vars[varID].nlevs;
          nlevs2 = vlistptr2->vars[varID].nlevs;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
748

Thomas Jahns's avatar
Thomas Jahns committed
749
          nlevs = nlevs1 + nlevs2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
750

Thomas Jahns's avatar
Thomas Jahns committed
751
752
753
754
755
756
          vlistptr2->vars[varID].nlevs = nlevs;
          /*
          fprintf(stderr, "var %d %d %d %d %d\n", varID, nlevs1, nlevs2, nlevs, sizeof(levinfo_t));
          */
          vlistptr2->vars[varID].levinfo =
            (levinfo_t *) realloc(vlistptr2->vars[varID].levinfo, nlevs*sizeof(levinfo_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
757

Thomas Jahns's avatar
Thomas Jahns committed
758
759
          memcpy(vlistptr2->vars[varID].levinfo+nlevs2,
                 vlistptr1->vars[varID].levinfo, nlevs1*sizeof(levinfo_t));
760

Thomas Jahns's avatar
Thomas Jahns committed
761
762
763
764
765
          for ( levID = 0; levID < nlevs1; levID++ )
            {
              vlistptr1->vars[varID].levinfo[levID].mlevelID = nlevs2 + levID;
            }
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
766
767
768
769
770

      lvar = (int *) malloc(nvars2*sizeof(int));
      for ( varID = 0; varID < nvars2; varID++ ) lvar[varID] = FALSE;

      for ( varID = 0; varID < nvars2; varID++ )
Thomas Jahns's avatar
Thomas Jahns committed
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
        {
          if ( lvar[varID] == TRUE ) continue;

          zaxisID1 = vlistptr1->vars[varID].zaxisID;
          zaxisID2 = vlistptr2->vars[varID].zaxisID;
          /*
          nlevs1 = vlistptr1->vars[varID].nlevs;
          nlevs2 = vlistptr2->vars[varID].nlevs;
          */
          nlevs1 = zaxisInqSize(zaxisID1);
          nlevs2 = zaxisInqSize(zaxisID2);
          /*
          fprintf(stderr, "zaxis %d %d %d %d\n", zaxisID1, zaxisID2, nlevs1, nlevs2);
          */
          nlevs = nlevs1 + nlevs2;

          zaxisID = zaxisDuplicate(zaxisID2);

          zaxisResize(zaxisID, nlevs);

          levels = (double *) malloc(nlevs1*sizeof(double));

          zaxisInqLevels(zaxisID1, levels);
          /*
          for ( levID = 0; levID < nlevs1; levID++ )
            fprintf(stderr, "%d %d %d %d %d %g\n", varID, levID, nlevs1, nlevs2, vlistptr2->vars[varID].nlevs, levels[levID]);
          */
          for ( levID = 0; levID < nlevs1; levID++ )
            zaxisDefLevel(zaxisID, nlevs2+levID, levels[levID]);

          free(levels);

          for ( index = 0; index < vlistptr2->nzaxis; index++ )
            if ( vlistptr2->zaxisIDs[index] == zaxisID2 )
              vlistptr2->zaxisIDs[index] = zaxisID;

          for ( varID2 = 0; varID2 < nvars2; varID2++ )
            if ( lvar[varID2] == FALSE && vlistptr2->vars[varID2].zaxisID == zaxisID2 )
              {
                vlistptr2->vars[varID2].zaxisID = zaxisID;
                lvar[varID2] = TRUE;
              }
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828

      free(lvar);
    }
  else
    {
      vlistCat(vlistID2, vlistID1);
    }
}

/*
@Function  vlistNvars
@Title     Number of variables in a variable list

@Prototype int vlistNvars(int vlistID)
@Parameter
829
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
830
831

@Description
832
The function @func{vlistNvars} returns the number of variables in the variable list vlistID.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
833
834

@Result
835
@func{vlistNvars} returns the number of variables in a variable list.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
836
837
838
839
840

@EndFunction
*/
int vlistNvars(int vlistID)
{
841
  vlist_t *vlistptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
842
843
844

  vlistptr = vlist_to_pointer(vlistID);

845
  vlist_check_ptr(__func__, vlistptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
846
847
848
849

  return (vlistptr->nvars);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
850

Uwe Schulzweida's avatar
Uwe Schulzweida committed
851
852
853
int vlistNrecs(int vlistID)
{
  int varID, nrecs = 0;
854
  vlist_t *vlistptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
855
856
857

  vlistptr = vlist_to_pointer(vlistID);

858
  vlist_check_ptr(__func__, vlistptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
859
860
861
862
863
864
865
866

  for ( varID = 0; varID < vlistptr->nvars; varID++ )
    nrecs +=  vlistptr->vars[varID].nlevs;

  return (nrecs);
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
867
868
int vlistNumber(int vlistID)
{
869
  int varID, number, number2, datatype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
870
871
872
873
  vlist_t *vlistptr;

  vlistptr = vlist_to_pointer(vlistID);

874
  vlist_check_ptr(__func__, vlistptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
875

876
877
878
879
880
881
  datatype = vlistptr->vars[0].datatype;
  if (  datatype== DATATYPE_CPX32 || datatype == DATATYPE_CPX64 )
    number = CDI_COMP;
  else
    number = CDI_REAL;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
882
  for ( varID = 1; varID < vlistptr->nvars; varID++ )
883
884
885
    {
      datatype = vlistptr->vars[varID].datatype;
      if ( datatype == DATATYPE_CPX32 || datatype == DATATYPE_CPX64 )
Thomas Jahns's avatar
Thomas Jahns committed
886
        number2 = CDI_COMP;
887
      else
Thomas Jahns's avatar
Thomas Jahns committed
888
        number2 = CDI_REAL;
889
890

      if ( number2 != number )
Thomas Jahns's avatar
Thomas Jahns committed
891
892
893
894
        {
          number = CDI_BOTH;
          break;
        }
895
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
896
897
898
899

  return (number);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
900
901
902
903
904
905
/*
@Function  vlistNgrids
@Title     Number of grids in a variable list

@Prototype int vlistNgrids(int vlistID)
@Parameter
906
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
907
908

@Description
909
The function @func{vlistNgrids} returns the number of grids in the variable list vlistID.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
910
911

@Result
912
@func{vlistNgrids} returns the number of grids in a variable list.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
913
914
915
916
917

@EndFunction
*/
int vlistNgrids(int vlistID)
{
918
  vlist_t *vlistptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
919
920
921

  vlistptr = vlist_to_pointer(vlistID);

922
  vlist_check_ptr(__func__, vlistptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
923
924
925
926
927
928
929
930
931
932

  return (vlistptr->ngrids);
}

/*
@Function  vlistNzaxis
@Title     Number of zaxis in a variable list

@Prototype int vlistNzaxis(int vlistID)
@Parameter
933
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
934
935

@Description
936
The function @func{vlistNzaxis} returns the number of zaxis in the variable list vlistID.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
937
938

@Result
939
@func{vlistNzaxis} returns the number of zaxis in a variable list.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
940
941
942
943
944

@EndFunction
*/
int vlistNzaxis(int vlistID)
{
945
  vlist_t *vlistptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
946
947
948

  vlistptr = vlist_to_pointer(vlistID);

949
  vlist_check_ptr(__func__, vlistptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
950
951
952
953
954
955
956

  return (vlistptr->nzaxis);
}


void vlistDefNtsteps(int vlistID, int nts)
{
957
  vlist_t *vlistptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
958
959
960

  vlistptr = vlist_to_pointer(vlistID);

961
  vlist_check_ptr(__func__, vlistptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
962

963
964
  if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
    {
965
      xwarning("%s", "Operation not executed." );
966
967
968
      return;
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
969
970
971
972
973
974
  vlistptr->ntsteps = nts;
}


int vlistNtsteps(int vlistID)
{
975
  vlist_t *vlistptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
976
977
978

  vlistptr = vlist_to_pointer(vlistID);

979
  vlist_check_ptr(__func__, vlistptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
980
981
982
983

  return (vlistptr->ntsteps);
}

984
static void
985
vlistPrintKernel(vlist_t *vlistptr, FILE * fp )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
986
{
987
  int nvars, flag, index;
988
  int varID, fvarID, mvarID, flevID, mlevID, levID;
989
  int param, gridID, zaxisID, timeID, nlevs;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
990
  int dtype;
991
992
993

  int i, iorank, decoSize, size, rank, offset, chunk;

994
  char paramstr[32];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
995
996
997
  char *name, *longname, *units;
  double level;

998
  vlist_check_ptr(__func__, vlistptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
999

1000
  fprintf ( fp, "#\n# vlistID %d\n#\n", vlistptr->self);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1001
1002
1003

  nvars = vlistptr->nvars;

1004
1005
1006
1007
1008
1009
1010
  fprintf ( fp, "nvars   %d\n", nvars);
  fprintf ( fp, "ngrids  %d\n", vlistptr->ngrids);
  fprintf ( fp, "nzaxis  %d\n", vlistptr->nzaxis);
  fprintf ( fp, "taxisID %d\n", vlistptr->taxisID);
  fprintf ( fp, "instID  %d\n", vlistptr->instID);
  fprintf ( fp, "modelID %d\n", vlistptr->modelID);
  fprintf ( fp, "tableID %d\n", vlistptr->tableID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1011
1012
1013

  if ( nvars > 0 )
    {
1014
      fprintf ( fp, " varID param gridID zaxisID timeID nlevel flag "
1015
		" name longname iorank decosize\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1016
      for ( varID = 0; varID < nvars; varID++ )
Thomas Jahns's avatar
Thomas Jahns committed
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
        {
          param    = vlistptr->vars[varID].param;
          gridID   = vlistptr->vars[varID].gridID;
          zaxisID  = vlistptr->vars[varID].zaxisID;
          timeID   = vlistptr->vars[varID].timeID;
          nlevs    = vlistptr->vars[varID].nlevs;
          name     = vlistptr->vars[varID].name;
          longname = vlistptr->vars[varID].longname;
          units    = vlistptr->vars[varID].units;
          flag     = vlistptr->vars[varID].flag;
1027
          iorank   = vlistptr->vars[varID].iorank;
1028
          decoSize = vlistptr->vars[varID].decoSize;
Thomas Jahns's avatar
Thomas Jahns committed
1029
1030

          cdiParamToString(param, paramstr, sizeof(paramstr));
1031
1032
1033
1034
1035
1036
1037
          fprintf ( fp, "%6d   %s %6d %6d %6d %6d %6d %s"
                    " %s %6d %6d",
                    varID, paramstr, gridID, zaxisID, timeID, nlevs, flag,
                    name ? name : "    ", 
                    longname ? longname : "        ",
                    iorank, decoSize );

1038
1039
          if ( units ) fprintf ( fp, "   [%s]", units);
          fprintf ( fp, "\n");
Thomas Jahns's avatar
Thomas Jahns committed
1040
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1041

1042
1043
      fprintf ( fp, "\n");
      fprintf ( fp, " varID  levID fvarID flevID mvarID mlevID  index  dtype  flag  level\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1044
      for ( varID = 0; varID < nvars; varID++ )
Thomas Jahns's avatar
Thomas Jahns committed
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
        {
          nlevs    = vlistptr->vars[varID].nlevs;
          zaxisID  = vlistptr->vars[varID].zaxisID;
          fvarID   = vlistptr->vars[varID].fvarID;
          mvarID   = vlistptr->vars[varID].mvarID;
          dtype    = vlistptr->vars[varID].datatype;
          for ( levID = 0; levID < nlevs; levID++ )
            {
              flevID = vlistptr->vars[varID].levinfo[levID].flevelID;
              mlevID = vlistptr->vars[varID].levinfo[levID].mlevelID;
              index  = vlistptr->vars[varID].levinfo[levID].index;
              flag   = vlistptr->vars[varID].levinfo[levID].flag;
              level  = zaxisInqLevel(zaxisID, levID);
1058
1059
1060
              fprintf ( fp, "%6d %6d %6d %6d %6d %6d %6d %6d %5d  %.9g\n",
			varID, levID, fvarID, flevID, mvarID, mlevID, index, 
			dtype, flag, level);
Thomas Jahns's avatar
Thomas Jahns committed
1061
1062
            }
        }
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082

      fprintf ( fp, "\n");
      fprintf ( fp, " varID  size iorank decosize corank offset  chunk\n");
      for ( varID = 0; varID < nvars; varID++ )
        {
          iorank    = vlistptr->vars[varID].iorank;
          decoSize  = vlistptr->vars[varID].decoSize;
          size      = vlistptr->vars[varID].nlevs *
            gridInqSize ( vlistptr->vars[varID].gridID );
          
          for ( i = 0; i < decoSize; i++ )
            {
              rank   = vlistptr->vars[varID].deco[i].rank;
              offset = vlistptr->vars[varID].deco[i].offset;
              offset = vlistptr->vars[varID].deco[i].offset;
              chunk  = vlistptr->vars[varID].deco[i].chunk;
              fprintf ( fp, "%3d %8d %6d %6d %6d %8d %6d\n",
                        varID, size, iorank, decoSize, rank, offset, chunk );
            }
        }      
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1083
1084
1085
    }
}

1086
1087
1088
1089
1090
1091
1092
1093
1094

void vlistPrint(int vlistID)
{
  vlist_t *vlistptr;

  if ( vlistID == CDI_UNDEFID ) return;

  vlistptr = vlist_to_pointer(vlistID);
  vlist_check_ptr(__func__, vlistptr);
1095
  vlistPrintKernel(vlistptr, stdout);
1096
1097
}

1098
1099
1100
1101
1102
1103
1104
/*
@Function  vlistDefTaxis
@Title     Define the time axis

@Prototype void vlistDefTaxis(int vlistID, int taxisID)
@Parameter
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1105
    @Item  taxisID  Time axis ID, from a previous call to @fref{taxisCreate}
1106
1107
1108
1109
1110
1111

@Description
The function @func{vlistDefTaxis} defines the time axis of a variable list.

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1112
1113
void vlistDefTaxis(int vlistID, int taxisID)
{
1114
  vlist_t *vlistptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1115
1116
1117

  vlistptr = vlist_to_pointer(vlistID);

1118
  vlist_check_ptr(__func__, vlistptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1119

1120
1121
  if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
    {
1122
      xwarning("%s", "Operation not executed." );
1123
1124
1125
      return;
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1126
1127
1128
  vlistptr->taxisID = taxisID;
}

1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
/*
@Function  vlistInqTaxis
@Title     Get the time axis

@Prototype int vlistInqTaxis(int vlistID)
@Parameter
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}

@Description
The function @func{vlistInqTaxis} returns the time axis of a variable list.

@Result
@func{vlistInqTaxis} returns an identifier to the time axis.

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1145
1146
int vlistInqTaxis(int vlistID)
{
1147
  vlist_t *vlistptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1148
1149
1150

  vlistptr = vlist_to_pointer(vlistID);

1151
  vlist_check_ptr(__func__, vlistptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1152
1153
1154
1155

  return (vlistptr->taxisID);
}

1156

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1157
1158
void  vlistDefTable(int vlistID, int tableID)
{
1159
  vlist_t *vlistptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1160
1161
1162

  vlistptr = vlist_to_pointer(vlistID);

1163
  vlist_check_ptr(__func__, vlistptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1164

1165
1166
  if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
    {
1167
      xwarning("%s", "Operation not executed." );
1168
1169
1170
      return;
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1171
1172
1173
  vlistptr->tableID = tableID;
}

1174

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1175
1176
int vlistInqTable(int vlistID)
{
1177
  vlist_t *vlistptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1178
1179
1180

  vlistptr = vlist_to_pointer(vlistID);

1181
  vlist_check_ptr(__func__, vlistptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1182
1183
1184
1185

  return (vlistptr->tableID);
}

1186

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1187
1188
void vlistDefInstitut(int vlistID, int instID)
{
1189
  vlist_t *vlistptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1190
1191
1192

  vlistptr = vlist_to_pointer(vlistID);

1193
  vlist_check_ptr(__func__, vlistptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1194

1195
1196
  if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
    {
1197
      xwarning("%s", "Operation not executed." );
Deike Kleberg's avatar
Deike Kleberg committed
1198

1199
      xdebug("%s", "");
1200
1201
1202
      return;
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1203
1204
1205
  vlistptr->instID = instID;
}

1206

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1207
1208
1209
int vlistInqInstitut(int vlistID)
{
  int varID, instID;
1210
  vlist_t *vlistptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1211
1212
1213

  vlistptr = vlist_to_pointer(vlistID);

1214
  vlist_check_ptr(__func__, vlistptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1215
1216
1217
1218
1219
1220
1221
1222

  instID = vlistptr->instID;

  if ( instID == CDI_UNDEFID )
    {
      instID  = vlistInqVarInstitut(vlistID, 0);

      for ( varID = 1; varID < vlistptr->nvars; varID++ )
Thomas Jahns's avatar
Thomas Jahns committed
1223
1224
1225
1226
        if ( instID != vlistInqVarInstitut(vlistID, varID) )
          {
            instID = CDI_UNDEFID;
            break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1227
1228
1229
1230
1231
1232
1233
      }
      vlistDefInstitut(vlistID, instID);
    }

  return (instID);
}

1234

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1235
1236
void vlistDefModel(int vlistID, int modelID)
{
1237
  vlist_t *vlistptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1238
1239
1240

  vlistptr = vlist_to_pointer(vlistID);

1241
  vlist_check_ptr(__func__, vlistptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1242

1243
1244
  if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
    {
1245
      xwarning("%s", "Operation not executed." );
1246
1247
1248
      return;
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1249
1250
1251
  vlistptr->modelID = modelID;
}

1252

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1253
1254
1255
int vlistInqModel(int vlistID)
{
  int varID, modelID;
1256
  vlist_t *vlistptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1257
1258
1259

  vlistptr = vlist_to_pointer(vlistID);

1260
  vlist_check_ptr(__func__, vlistptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1261
1262
1263
1264
1265
1266
1267
1268

  modelID = vlistptr->modelID;

  if ( modelID == CDI_UNDEFID )
    {
      modelID = vlistInqVarModel(vlistID, 0);

      for ( varID = 1; varID < vlistptr->nvars; varID++ )
Thomas Jahns's avatar
Thomas Jahns committed
1269
1270
1271
1272
1273
        if ( modelID != vlistInqVarModel(vlistID, varID) )
          {
            modelID = CDI_UNDEFID;
            break;
          }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1274
1275
1276
1277
1278
1279
1280

      vlistDefModel(vlistID, modelID);
    }

  return (modelID);
}

1281

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1282
1283
1284
1285
int vlistGridsizeMax(int vlistID)
{
  int gridsize, gridsizemax = 0;
  int gridID, index;
1286
  vlist_t *vlistptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1287
1288
1289

  vlistptr = vlist_to_pointer(vlistID);

1290
  vlist_check_ptr(__func__, vlistptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1291
1292
1293
1294
1295
1296
1297

  for ( index = 0 ; index < vlistptr->ngrids ; index++ )
    {
      gridID = vlistptr->gridIDs[index];
      gridsize<