vlist_var.c 45.5 KB
Newer Older
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1 2
#include "dmemory.h"
#include "cdi.h"
3
#include "cdi_int.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
4
#include "vlist.h"
Deike Kleberg's avatar
Deike Kleberg committed
5
#include "vlist_var.h"
6
#include "resource_handle.h"
7
#include "tablepar.h"
Deike Kleberg's avatar
Deike Kleberg committed
8
#include "namespace.h"
9
#include "serialize.h"
10
#include "error.h"
11 12


13 14
static
void vlistvarInitEntry(int vlistID, int varID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
15
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
16
  vlist_t *vlistptr = vlist_to_pointer(vlistID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
17

Deike Kleberg's avatar
Deike Kleberg committed
18 19 20 21 22
  vlistptr->vars[varID].fvarID        = varID;
  vlistptr->vars[varID].mvarID        = varID;
  vlistptr->vars[varID].flag          = 0;
  vlistptr->vars[varID].param         = 0;
  vlistptr->vars[varID].datatype      = CDI_UNDEFID;
23
  vlistptr->vars[varID].timetype      = CDI_UNDEFID;
Deike Kleberg's avatar
Deike Kleberg committed
24 25
  vlistptr->vars[varID].tsteptype     = TSTEP_INSTANT;
  vlistptr->vars[varID].timave        = 0;
26
  vlistptr->vars[varID].chunktype     = cdiChunkType;
27
  vlistptr->vars[varID].xyz           = 321;
Deike Kleberg's avatar
Deike Kleberg committed
28 29
  vlistptr->vars[varID].gridID        = CDI_UNDEFID;
  vlistptr->vars[varID].zaxisID       = CDI_UNDEFID;
30
  vlistptr->vars[varID].subtypeID     = CDI_UNDEFID;
Deike Kleberg's avatar
Deike Kleberg committed
31 32 33
  vlistptr->vars[varID].instID        = CDI_UNDEFID;
  vlistptr->vars[varID].modelID       = CDI_UNDEFID;
  vlistptr->vars[varID].tableID       = CDI_UNDEFID;
34
  vlistptr->vars[varID].missvalused   = false;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
35
  vlistptr->vars[varID].missval       = CDI_default_missval;
Deike Kleberg's avatar
Deike Kleberg committed
36 37 38 39
  vlistptr->vars[varID].addoffset     = 0.0;
  vlistptr->vars[varID].scalefactor   = 1.0;
  vlistptr->vars[varID].stdname       = NULL;
  vlistptr->vars[varID].units         = NULL;
40
  vlistptr->vars[varID].extra         = NULL;
Deike Kleberg's avatar
Deike Kleberg committed
41
  vlistptr->vars[varID].levinfo       = NULL;
42
  vlistptr->vars[varID].comptype      = CDI_COMPRESS_NONE;
Deike Kleberg's avatar
Deike Kleberg committed
43
  vlistptr->vars[varID].complevel     = 1;
44 45
  vlistptr->vars[varID].keys.nalloc   = MAX_KEYS;
  vlistptr->vars[varID].keys.nelems   = 0;
46 47
  for ( int i = 0; i < MAX_KEYS; ++i )
    vlistptr->vars[varID].keys.value[i].length = 0;
Deike Kleberg's avatar
Deike Kleberg committed
48 49
  vlistptr->vars[varID].atts.nalloc   = MAX_ATTRIBUTES;
  vlistptr->vars[varID].atts.nelems   = 0;
50
  vlistptr->vars[varID].lvalidrange   = false;
Deike Kleberg's avatar
Deike Kleberg committed
51 52
  vlistptr->vars[varID].validrange[0] = VALIDMISS;
  vlistptr->vars[varID].validrange[1] = VALIDMISS;
53
  vlistptr->vars[varID].iorank        = CDI_UNDEFID;
54
  vlistptr->vars[varID].opt_grib_kvpair_size = 0;
55
  vlistptr->vars[varID].opt_grib_kvpair      = NULL;
56
  vlistptr->vars[varID].opt_grib_nentries    = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
57 58
}

59 60
static
int vlistvarNewEntry(int vlistID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
61 62
{
  int varID = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
63
  vlist_t *vlistptr = vlist_to_pointer(vlistID);
64 65
  int vlistvarSize = vlistptr->varsAllocated;
  var_t *vlistvar = vlistptr->vars;
66
  // Look for a free slot in vlistvar. (Create the table the first time through).
Uwe Schulzweida's avatar
Uwe Schulzweida committed
67 68 69
  if ( ! vlistvarSize )
    {
      vlistvarSize = 2;
70
      vlistvar = (var_t *) Malloc((size_t)vlistvarSize * sizeof (var_t));
71
      for ( int i = 0; i < vlistvarSize; i++ ) vlistvar[i].isUsed = false;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
72 73 74
    }
  else
    {
Thomas Jahns's avatar
Thomas Jahns committed
75 76
      while (varID < vlistvarSize && vlistvar[varID].isUsed)
        ++varID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
77
    }
78
  // If the table overflows, double its size.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
79 80
  if ( varID == vlistvarSize )
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
81
      vlistvar = (var_t *) Realloc(vlistvar, (size_t)(vlistvarSize *= 2) * sizeof(var_t));
82
      for ( int i = varID; i < vlistvarSize; i++ ) vlistvar[i].isUsed = false;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
83 84 85 86 87 88 89
    }

  vlistptr->varsAllocated = vlistvarSize;
  vlistptr->vars          = vlistvar;

  vlistvarInitEntry(vlistID, varID);

90
  vlistptr->vars[varID].isUsed = true;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
91

Uwe Schulzweida's avatar
Uwe Schulzweida committed
92
  return varID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
93 94
}

95
void vlistCheckVarID(const char *caller, int vlistID, int varID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
96
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
97
  vlist_t *vlistptr = vlist_to_pointer(vlistID);
98
  if ( vlistptr == NULL ) Errorc("vlist undefined!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
99

100
  if ( varID < 0 || varID >= vlistptr->nvars ) Errorc("varID %d undefined!", varID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
101

102
  if ( ! vlistptr->vars[varID].isUsed ) Errorc("varID %d undefined!", varID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
103 104
}

105

106
int vlistDefVarTiles(int vlistID, int gridID, int zaxisID, int timetype, int tilesetID)
107
{
108
  if ( CDI_Debug ) Message("gridID = %d  zaxisID = %d  timetype = %d", gridID, zaxisID, timetype);
109

110
  const int varID = vlistvarNewEntry(vlistID);
111

Uwe Schulzweida's avatar
Uwe Schulzweida committed
112
  vlist_t *vlistptr = vlist_to_pointer(vlistID);
113
  vlistptr->nvars++;
114 115
  vlistptr->vars[varID].gridID    = gridID;
  vlistptr->vars[varID].zaxisID   = zaxisID;
116
  vlistptr->vars[varID].timetype = timetype;
117 118
  vlistptr->vars[varID].subtypeID = tilesetID;

119
  if ( timetype < 0 )
120
    {
121 122
      Message("Unexpected time type %d, set to TIME_VARYING!", timetype);
      vlistptr->vars[varID].timetype = TIME_VARYING;
123 124 125 126 127 128 129 130
    }

  vlistAdd2GridIDs(vlistptr, gridID);
  vlistAdd2ZaxisIDs(vlistptr, zaxisID);
  vlistAdd2SubtypeIDs(vlistptr, tilesetID);

  vlistptr->vars[varID].param = cdiEncodeParam(-(varID + 1), 255, 255);
  reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
131 132

  return varID;
133 134
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
135 136
/*
@Function  vlistDefVar
Uwe Schulzweida's avatar
Uwe Schulzweida committed
137
@Title     Define a Variable
Uwe Schulzweida's avatar
Uwe Schulzweida committed
138

139
@Prototype int vlistDefVar(int vlistID, int gridID, int zaxisID, int timetype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
140
@Parameter
141 142 143
    @Item  vlistID   Variable list ID, from a previous call to @fref{vlistCreate}.
    @Item  gridID    Grid ID, from a previous call to @fref{gridCreate}.
    @Item  zaxisID   Z-axis ID, from a previous call to @fref{zaxisCreate}.
144 145
    @Item  timetype  One of the set of predefined CDI timestep types.
                     The valid CDI timestep types are @func{TIME_CONSTANT} and @func{TIME_VARYING}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
146 147

@Description
148
The function @func{vlistDefVar} adds a new variable to vlistID.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
149 150

@Result
151
@func{vlistDefVar} returns an identifier to the new variable.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
152

Uwe Schulzweida's avatar
Uwe Schulzweida committed
153 154 155 156 157 158 159 160 161 162
@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();
163
varID = vlistDefVar(vlistID, gridID, zaxisID, TIME_VARYING);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
164 165 166 167 168 169
   ...
streamDefVlist(streamID, vlistID);
   ...
vlistDestroy(vlistID);
   ...
@EndSource
Uwe Schulzweida's avatar
Uwe Schulzweida committed
170 171
@EndFunction
*/
172
int vlistDefVar(int vlistID, int gridID, int zaxisID, int timetype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
173
{
174
  // call "vlistDefVarTiles" with a trivial tile index:
175
  return vlistDefVarTiles(vlistID, gridID, zaxisID, timetype, CDI_UNDEFID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
176 177
}

178 179 180
void
cdiVlistCreateVarLevInfo(vlist_t *vlistptr, int varID)
{
181
  xassert(varID >= 0 && varID < vlistptr->nvars && vlistptr->vars[varID].levinfo == NULL);
182

183 184 185 186
  const int zaxisID = vlistptr->vars[varID].zaxisID;
  const size_t nlevs = (size_t)zaxisInqSize(zaxisID);

  vlistptr->vars[varID].levinfo = (levinfo_t*) Malloc(nlevs * sizeof(levinfo_t));
187

188 189
  for (size_t levID = 0; levID < nlevs; levID++ )
    vlistptr->vars[varID].levinfo[levID] = DEFAULT_LEVINFO((int)levID);
190 191
}

192 193 194 195 196 197
/*
@Function  vlistDefVarParam
@Title     Define the parameter number of a Variable

@Prototype void vlistDefVarParam(int vlistID, int varID, int param)
@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
198 199 200
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
    @Item  varID    Variable identifier.
    @Item  param    Parameter number.
201 202 203 204 205 206 207 208

@Description
The function @func{vlistDefVarParam} defines the parameter number of a variable.

@EndFunction
*/
void vlistDefVarParam(int vlistID, int varID, int param)
{
209
  vlistCheckVarID(__func__, vlistID, varID);
210

211
  vlist_t *vlistptr = vlist_to_pointer(vlistID);
212 213 214
  if (vlistptr->vars[varID].param != param)
    {
      vlistptr->vars[varID].param = param;
Thomas Jahns's avatar
Thomas Jahns committed
215
      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
216
    }
217 218
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
219 220
/*
@Function  vlistDefVarCode
Uwe Schulzweida's avatar
Uwe Schulzweida committed
221
@Title     Define the code number of a Variable
Uwe Schulzweida's avatar
Uwe Schulzweida committed
222 223 224

@Prototype void vlistDefVarCode(int vlistID, int varID, int code)
@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
225 226 227
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
    @Item  varID    Variable identifier.
    @Item  code     Code number.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
228 229

@Description
230
The function @func{vlistDefVarCode} defines the code number of a variable.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
231 232 233 234 235

@EndFunction
*/
void vlistDefVarCode(int vlistID, int varID, int code)
{
236
  vlistCheckVarID(__func__, vlistID, varID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
237

238 239
  vlist_t *vlistptr = vlist_to_pointer(vlistID);
  const int param = vlistptr->vars[varID].param;
240
  int pnum, pcat, pdis;
241
  cdiDecodeParam(param, &pnum, &pcat, &pdis);
242
  const int newParam = cdiEncodeParam(code, pcat, pdis);
243 244 245
  if (vlistptr->vars[varID].param != newParam)
    {
      vlistptr->vars[varID].param = newParam;
Thomas Jahns's avatar
Thomas Jahns committed
246
      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
247
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
248 249 250
}


251
void vlistInqVar(int vlistID, int varID, int *gridID, int *zaxisID, int *timetype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
252
{
253
  vlistCheckVarID(__func__, vlistID, varID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
254

255
  const vlist_t *vlistptr = vlist_to_pointer(vlistID);
256 257 258
  *gridID   = vlistptr->vars[varID].gridID;
  *zaxisID  = vlistptr->vars[varID].zaxisID;
  *timetype = vlistptr->vars[varID].timetype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
259 260 261 262

  return;
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
263 264 265 266 267 268
/*
@Function  vlistInqVarGrid
@Title     Get the Grid ID of a Variable

@Prototype int vlistInqVarGrid(int vlistID, int varID)
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
269
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
Deike Kleberg's avatar
Deike Kleberg committed
270
    @Item  varID    Variable identifier.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
271 272

@Description
273
The function @func{vlistInqVarGrid} returns the grid ID of a Variable.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
274 275

@Result
276
@func{vlistInqVarGrid} returns the grid ID of the Variable.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
277 278 279

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
280 281
int vlistInqVarGrid(int vlistID, int varID)
{
282
  vlistCheckVarID(__func__, vlistID, varID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
283

284
  const vlist_t *vlistptr = vlist_to_pointer(vlistID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
285
  return vlistptr->vars[varID].gridID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
286 287
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
288 289 290 291 292 293
/*
@Function  vlistInqVarZaxis
@Title     Get the Zaxis ID of a Variable

@Prototype int vlistInqVarZaxis(int vlistID, int varID)
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
294
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
Deike Kleberg's avatar
Deike Kleberg committed
295
    @Item  varID    Variable identifier.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
296 297 298 299 300 301 302 303 304

@Description
The function @func{vlistInqVarZaxis} returns the zaxis ID of a variable.

@Result
@func{vlistInqVarZaxis} returns the zaxis ID of the variable.

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
305 306
int vlistInqVarZaxis(int vlistID, int varID)
{
307
  vlistCheckVarID(__func__, vlistID, varID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
308

309
  const vlist_t *vlistptr = vlist_to_pointer(vlistID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
310
  return vlistptr->vars[varID].zaxisID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
311 312
}

313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328

/*
@Function  vlistInqVarSubtype
@Title     Get the Subtype ID of a Variable

@Description
The function @func{vlistInqVarSubtype} returns the subtype ID of a variable.

@Result
@func{vlistInqVarSubtype} returns the subtype ID of the variable.

@EndFunction
*/
int vlistInqVarSubtype(int vlistID, int varID)
{
  vlistCheckVarID(__func__, vlistID, varID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
329

330
  const vlist_t *vlistptr = vlist_to_pointer(vlistID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
331
  return vlistptr->vars[varID].subtypeID;
332 333 334
}


335 336 337 338 339 340
/*
@Function  vlistInqVarParam
@Title     Get the parameter number of a Variable

@Prototype int vlistInqVarParam(int vlistID, int varID)
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
341
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
Deike Kleberg's avatar
Deike Kleberg committed
342
    @Item  varID    Variable identifier.
343 344 345 346 347 348 349 350 351 352 353

@Description
The function @func{vlistInqVarParam} returns the parameter number of a variable.

@Result
@func{vlistInqVarParam} returns the parameter number of the variable.

@EndFunction
*/
int vlistInqVarParam(int vlistID, int varID)
{
354
  vlistCheckVarID(__func__, vlistID, varID);
355

356
  const vlist_t *vlistptr = vlist_to_pointer(vlistID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
357
  return vlistptr->vars[varID].param;
358 359
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
360 361
/*
@Function  vlistInqVarCode
Uwe Schulzweida's avatar
Uwe Schulzweida committed
362
@Title     Get the Code number of a Variable
Uwe Schulzweida's avatar
Uwe Schulzweida committed
363 364 365

@Prototype int vlistInqVarCode(int vlistID, int varID)
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
366
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
Deike Kleberg's avatar
Deike Kleberg committed
367
    @Item  varID    Variable identifier.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
368 369

@Description
370
The function @func{vlistInqVarCode} returns the code number of a variable.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
371 372

@Result
373
@func{vlistInqVarCode} returns the code number of the variable.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
374 375 376 377 378

@EndFunction
*/
int vlistInqVarCode(int vlistID, int varID)
{
379
  vlistCheckVarID(__func__, vlistID, varID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
380

381 382 383
  const vlist_t *vlistptr = vlist_to_pointer(vlistID);

  const int param = vlistptr->vars[varID].param;
384
  int pdis, pcat, pnum;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
385
  cdiDecodeParam(param, &pnum, &pcat, &pdis);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
386 387
  int code = pnum;
  if ( pdis != 255 ) code = -varID-1; // GRIB2 Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
388

389 390
  int tableID = vlistptr->vars[varID].tableID;
  if (code < 0 && tableID != -1)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
391
    {
392 393 394 395 396
      char name[CDI_MAX_NAME];
      int length = CDI_MAX_NAME;
      (void)cdiInqKeyString(vlistID, varID, CDI_KEY_NAME, name, &length);

      if (name[0]) tableInqParCode(tableID, name, &code);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
397 398
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
399
  return code;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
400 401 402 403
}

/*
@Function  vlistInqVarName
Uwe Schulzweida's avatar
Uwe Schulzweida committed
404
@Title     Get the name of a Variable
Uwe Schulzweida's avatar
Uwe Schulzweida committed
405

406
@Prototype void vlistInqVarName(int vlistID, int varID, char *name)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
407
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
408
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
Deike Kleberg's avatar
Deike Kleberg committed
409
    @Item  varID    Variable identifier.
410
    @Item  name     Returned variable name. The caller must allocate space for the
Deike Kleberg's avatar
Deike Kleberg committed
411
                    returned string. The maximum possible length, in characters, of
412
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
413 414

@Description
415
The function @func{vlistInqVarName} returns the name of a variable.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
416 417

@Result
418 419
@func{vlistInqVarName} returns the name of the variable to the parameter name if available,
otherwise the result is an empty string.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
420 421 422 423 424

@EndFunction
*/
void vlistInqVarName(int vlistID, int varID, char *name)
{
425 426
  int length = CDI_MAX_NAME;
  (void)cdiInqKeyString(vlistID, varID, CDI_KEY_NAME, name, &length);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
427

428
  if (!name[0])
Uwe Schulzweida's avatar
Uwe Schulzweida committed
429
    {
430 431 432 433
      vlistCheckVarID(__func__, vlistID, varID);

      vlist_t *vlistptr = vlist_to_pointer(vlistID);

434 435
      int param = vlistptr->vars[varID].param;
      int pdis, pcat, pnum;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
436
      cdiDecodeParam(param, &pnum, &pcat, &pdis);
437 438 439
      if ( pdis == 255 )
	{
	  int code = pnum;
440
	  int tableID = vlistptr->vars[varID].tableID;
441
          tableInqEntry(tableID, code, -1, name, NULL, NULL);
442
	  if (!name[0]) sprintf(name, "var%d", code);
443 444 445 446 447
	}
      else
	{
	  sprintf(name, "param%d.%d.%d", pnum, pcat, pdis);
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
448
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
449 450 451 452

  return;
}

453 454 455 456 457 458 459 460 461
/*
@Function vlistCopyVarName
@Tatle    Get the name of a Variable in a safe way

@Prototype char* vlistCopyVarName(int vlistId, int varId)
@Parameter
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
    @Item  varID    Variable identifier.

462
@Return A pointer to a malloc'ed string. Must be cleaned up with Free().
463 464 465

@Description
This is the buffer overflow immune version of vlistInqVarName().
466
The memory for the returned string is allocated to fit the string via Malloc().
467 468 469

@EndFunction
*/
470
char *vlistCopyVarName(int vlistID, int varID)
471
{
472 473 474 475 476
  // If a name is set in the variable description, use that.
  char name[CDI_MAX_NAME];
  int length = CDI_MAX_NAME;
  (void)cdiInqKeyString(vlistID, varID, CDI_KEY_NAME, name, &length);
  if (name[0]) return strdup(name);
477

478 479
  vlistCheckVarID(__func__, vlistID, varID);
  vlist_t *vlistptr = vlist_to_pointer(vlistID);
480

481 482
  // Otherwise we check if we should use the table of parameter descriptions.
  int param = vlistptr->vars[varID].param;
483 484
  int discipline, category, number;
  cdiDecodeParam(param, &number, &category, &discipline);
485
  char *result = NULL;
486
  if (discipline == 255)
487
    {
488 489
      int tableID = vlistptr->vars[varID].tableID;
      tableInqEntry(tableID, number, -1, name, NULL, NULL);
490
      if ( name[0] )
491
        result = strdup(name);
492 493 494 495 496 497
      else
        {
          //No luck, fall back to outputting a name of the format "var<num>".
          result = (char *) Malloc(3 + 3 * sizeof (int) * CHAR_BIT / 8 + 2);
          sprintf(result, "var%d", number);
        }
498 499 500
    }
  else
    {
501
      result = (char *) Malloc(5 + 2 + 3 * (3 * sizeof (int) * CHAR_BIT + 1) + 1);
502
      sprintf(result, "param%d.%d.%d", number, category, discipline);
503 504
    }
  //Finally, we fall back to outputting a name of the format "param<num>.<cat>.<dis>".
505
  return result;
506 507
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
508 509
/*
@Function  vlistInqVarLongname
Uwe Schulzweida's avatar
Uwe Schulzweida committed
510
@Title     Get the longname of a Variable
Uwe Schulzweida's avatar
Uwe Schulzweida committed
511 512 513

@Prototype void vlistInqVarLongname(int vlistID, int varID, char *longname)
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
514
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
Deike Kleberg's avatar
Deike Kleberg committed
515
    @Item  varID    Variable identifier.
516
    @Item  longname Long name of the variable. The caller must allocate space for the
Deike Kleberg's avatar
Deike Kleberg committed
517
                    returned string. The maximum possible length, in characters, of
518
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
519 520

@Description
521 522
The function @func{vlistInqVarLongname} returns the longname of a variable if available,
otherwise the result is an empty string.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
523 524

@Result
Uwe Schulzweida's avatar
Uwe Schulzweida committed
525
@func{vlistInqVarLongname} returns the longname of the variable to the parameter longname.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
526 527 528 529 530

@EndFunction
*/
void vlistInqVarLongname(int vlistID, int varID, char *longname)
{
531 532
  int length = CDI_MAX_NAME;
  (void)cdiInqKeyString(vlistID, varID, CDI_KEY_NAME, longname, &length);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
533

534 535 536
  if (!longname[0])
    {
      vlistCheckVarID(__func__, vlistID, varID);
537

538
      vlist_t *vlistptr = vlist_to_pointer(vlistID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
539

540 541
      int param = vlistptr->vars[varID].param;
      int pdis, pcat, pnum;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
542
      cdiDecodeParam(param, &pnum, &pcat, &pdis);
543 544 545
      if ( pdis == 255 )
	{
	  int code = pnum;
546
          int tableID = vlistptr->vars[varID].tableID;
547
          tableInqEntry(tableID, code, -1, NULL, longname, NULL);
548
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
549
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
550 551 552 553

  return;
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
554 555 556 557 558 559
/*
@Function  vlistInqVarStdname
@Title     Get the standard name of a Variable

@Prototype void vlistInqVarStdname(int vlistID, int varID, char *stdname)
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
560
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
Deike Kleberg's avatar
Deike Kleberg committed
561
    @Item  varID    Variable identifier.
562
    @Item  stdname  Standard name of the variable. The caller must allocate space for the
Deike Kleberg's avatar
Deike Kleberg committed
563
                    returned string. The maximum possible length, in characters, of
564
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
565 566

@Description
567 568
The function @func{vlistInqVarStdname} returns the standard name of a variable if available,
otherwise the result is an empty string.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
569 570

@Result
571
@func{vlistInqVarStdname} returns the standard name of the variable to the parameter stdname.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
572 573 574

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
575 576
void vlistInqVarStdname(int vlistID, int varID, char *stdname)
{
577
  vlistCheckVarID(__func__, vlistID, varID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
578

579 580
  const vlist_t *vlistptr = vlist_to_pointer(vlistID);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
581
  if ( vlistptr->vars[varID].stdname == NULL )
582
    stdname[0] = '\0';
Uwe Schulzweida's avatar
Uwe Schulzweida committed
583 584 585 586 587 588 589 590
  else
    strcpy(stdname, vlistptr->vars[varID].stdname);

  return;
}

/*
@Function  vlistInqVarUnits
Uwe Schulzweida's avatar
Uwe Schulzweida committed
591
@Title     Get the units of a Variable
Uwe Schulzweida's avatar
Uwe Schulzweida committed
592 593 594

@Prototype void vlistInqVarUnits(int vlistID, int varID, char *units)
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
595
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
Deike Kleberg's avatar
Deike Kleberg committed
596
    @Item  varID    Variable identifier.
597
    @Item  units    Units of the variable. The caller must allocate space for the
Deike Kleberg's avatar
Deike Kleberg committed
598
                    returned string. The maximum possible length, in characters, of
599
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
600 601

@Description
602 603
The function @func{vlistInqVarUnits} returns the units of a variable if available,
otherwise the result is an empty string.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
604 605

@Result
606
@func{vlistInqVarUnits} returns the units of the variable to the parameter units.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
607 608 609 610 611

@EndFunction
*/
void vlistInqVarUnits(int vlistID, int varID, char *units)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
612
  vlist_t *vlistptr = vlist_to_pointer(vlistID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
613

614 615 616
  vlistCheckVarID(__func__, vlistID, varID);

  units[0] = '\0';
Uwe Schulzweida's avatar
Uwe Schulzweida committed
617 618 619

  if ( vlistptr->vars[varID].units == NULL )
    {
620 621
      int param = vlistptr->vars[varID].param;
      int pdis, pcat, pnum;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
622
      cdiDecodeParam(param, &pnum, &pcat, &pdis);
623 624 625
      if ( pdis == 255 )
	{
	  int code = pnum;
626
	  int tableID = vlistptr->vars[varID].tableID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
627
          tableInqEntry(tableID, code, -1, NULL, NULL, units);
628
	}
629
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
630 631 632 633 634 635
  else
    strcpy(units, vlistptr->vars[varID].units);

  return;
}

636
// used in MPIOM !
Uwe Schulzweida's avatar
Uwe Schulzweida committed
637
int vlistInqVarID(int vlistID, int code)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
638
{
639
  const vlist_t *vlistptr = vlist_to_pointer(vlistID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
640

641
  for ( int varID = 0; varID < vlistptr->nvars; varID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
642
    {
643
      const int param = vlistptr->vars[varID].param;
644
      int pdis, pcat, pnum;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
645
      cdiDecodeParam(param, &pnum, &pcat, &pdis);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
646
      if ( pnum == code ) return varID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
647 648
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
649
  return CDI_UNDEFID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
650
}
651

Uwe Schulzweida's avatar
Uwe Schulzweida committed
652

653
size_t vlistInqVarSize(int vlistID, int varID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
654
{
655
  vlistCheckVarID(__func__, vlistID, varID);
656

657 658
  int zaxisID, gridID, timetype;
  vlistInqVar(vlistID, varID, &gridID, &zaxisID, &timetype);
659

660 661
  const size_t nlevs = (size_t)zaxisInqSize(zaxisID);
  const size_t gridsize = gridInqSize(gridID);
662

663
  return gridsize*nlevs;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
664 665 666 667
}

/*
@Function  vlistInqVarDatatype
Uwe Schulzweida's avatar
Uwe Schulzweida committed
668
@Title     Get the data type of a Variable
Uwe Schulzweida's avatar
Uwe Schulzweida committed
669 670 671

@Prototype int vlistInqVarDatatype(int vlistID, int varID)
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
672
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
Deike Kleberg's avatar
Deike Kleberg committed
673
    @Item  varID    Variable identifier.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
674 675

@Description
Uwe Schulzweida's avatar
Uwe Schulzweida committed
676
The function @func{vlistInqVarDatatype} returns the data type of a variable.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
677 678

@Result
Uwe Schulzweida's avatar
Uwe Schulzweida committed
679
@func{vlistInqVarDatatype} returns an identifier to the data type of the variable.
680
The valid CDI data types are @func{CDI_DATATYPE_PACK8}, @func{CDI_DATATYPE_PACK16}, @func{CDI_DATATYPE_PACK24},
681
@func{CDI_DATATYPE_FLT32}, @func{CDI_DATATYPE_FLT64}, @func{CDI_DATATYPE_INT8}, @func{CDI_DATATYPE_INT16} and
682
@func{CDI_DATATYPE_INT32}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
683 684 685 686 687

@EndFunction
*/
int vlistInqVarDatatype(int vlistID, int varID)
{
688
  vlistCheckVarID(__func__, vlistID, varID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
689

690
  const vlist_t *vlistptr = vlist_to_pointer(vlistID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
691
  return vlistptr->vars[varID].datatype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
692 693 694
}


695 696
int vlistInqVarNumber(int vlistID, int varID)
{
697
  vlistCheckVarID(__func__, vlistID, varID);
698

699 700
  const vlist_t *vlistptr = vlist_to_pointer(vlistID);

701
  int number = CDI_REAL;
702 703
  if ( vlistptr->vars[varID].datatype == CDI_DATATYPE_CPX32 ||
       vlistptr->vars[varID].datatype == CDI_DATATYPE_CPX64 )
704 705
    number = CDI_COMP;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
706
  return number;
707 708
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
709 710
/*
@Function  vlistDefVarDatatype
Uwe Schulzweida's avatar
Uwe Schulzweida committed
711
@Title     Define the data type of a Variable
Uwe Schulzweida's avatar
Uwe Schulzweida committed
712 713 714

@Prototype void vlistDefVarDatatype(int vlistID, int varID, int datatype)
@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
715 716
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
    @Item  varID    Variable identifier.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
717
    @Item  datatype The data type identifier.
718 719 720
                    The valid CDI data types are @func{CDI_DATATYPE_PACK8}, @func{CDI_DATATYPE_PACK16},
                    @func{CDI_DATATYPE_PACK24}, @func{CDI_DATATYPE_FLT32}, @func{CDI_DATATYPE_FLT64},
                    @func{CDI_DATATYPE_INT8}, @func{CDI_DATATYPE_INT16} and @func{CDI_DATATYPE_INT32}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
721 722

@Description
723
The function @func{vlistDefVarDatatype} defines the data type of a variable.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
724 725 726 727 728

@EndFunction
*/
void vlistDefVarDatatype(int vlistID, int varID, int datatype)
{
729
  vlistCheckVarID(__func__, vlistID, varID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
730

731 732
  vlist_t *vlistptr = vlist_to_pointer(vlistID);

733 734 735 736
  if (vlistptr->vars[varID].datatype != datatype)
    {
      vlistptr->vars[varID].datatype = datatype;

737
      if ( !vlistptr->vars[varID].missvalused )
738 739
        switch (datatype)
          {
740 741 742 743 744 745
          case CDI_DATATYPE_INT8:   vlistptr->vars[varID].missval = -SCHAR_MAX; break;
          case CDI_DATATYPE_UINT8:  vlistptr->vars[varID].missval =  UCHAR_MAX; break;
          case CDI_DATATYPE_INT16:  vlistptr->vars[varID].missval = -SHRT_MAX;  break;
          case CDI_DATATYPE_UINT16: vlistptr->vars[varID].missval =  USHRT_MAX; break;
          case CDI_DATATYPE_INT32:  vlistptr->vars[varID].missval = -INT_MAX;   break;
          case CDI_DATATYPE_UINT32: vlistptr->vars[varID].missval =  UINT_MAX;  break;
746
          }
Thomas Jahns's avatar
Thomas Jahns committed
747
      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
748
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
749 750
}

751

Uwe Schulzweida's avatar
Uwe Schulzweida committed
752 753
void vlistDefVarInstitut(int vlistID, int varID, int instID)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
754
  vlist_t *vlistptr = vlist_to_pointer(vlistID);
755 756 757
  if (vlistptr->vars[varID].instID != instID)
    {
      vlistptr->vars[varID].instID = instID;
Thomas Jahns's avatar
Thomas Jahns committed
758
      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
759
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
760 761
}

762

Uwe Schulzweida's avatar
Uwe Schulzweida committed
763 764
int vlistInqVarInstitut(int vlistID, int varID)
{
765
  const vlist_t *vlistptr = vlist_to_pointer(vlistID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
766
  return vlistptr->vars[varID].instID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
767 768
}

769

Uwe Schulzweida's avatar
Uwe Schulzweida committed
770 771
void vlistDefVarModel(int vlistID, int varID, int modelID)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
772
  vlist_t *vlistptr = vlist_to_pointer(vlistID);
773 774 775
  if (vlistptr->vars[varID].modelID != modelID)
    {
      vlistptr->vars[varID].modelID = modelID;
Thomas Jahns's avatar
Thomas Jahns committed
776
      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
777
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
778 779
}

780

Uwe Schulzweida's avatar
Uwe Schulzweida committed
781 782
int vlistInqVarModel(int vlistID, int varID)
{
783
  const vlist_t *vlistptr = vlist_to_pointer(vlistID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
784
  return vlistptr->vars[varID].modelID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
785 786
}

787

Uwe Schulzweida's avatar
Uwe Schulzweida committed
788 789
void vlistDefVarTable(int vlistID, int varID, int tableID)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
790
  vlist_t *vlistptr = vlist_to_pointer(vlistID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
791

792 793 794
  if (vlistptr->vars[varID].tableID != tableID)
    {
      vlistptr->vars[varID].tableID = tableID;
795
      const int tablenum = tableInqNum(tableID);
796

797
      const int param = vlistptr->vars[varID].param;
798 799 800
      int pnum, pcat, pdis;
      cdiDecodeParam(param, &pnum, &pcat, &pdis);
      vlistptr->vars[varID].param = cdiEncodeParam(pnum, tablenum, pdis);
Thomas Jahns's avatar
Thomas Jahns committed
801
      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
802
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
803 804
}

805

Uwe Schulzweida's avatar
Uwe Schulzweida committed
806 807
int vlistInqVarTable(int vlistID, int varID)
{
808
  const vlist_t *vlistptr = vlist_to_pointer(vlistID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
809
  return vlistptr->vars[varID].tableID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
810 811 812 813
}

/*
@Function  vlistDefVarName
Uwe Schulzweida's avatar
Uwe Schulzweida committed
814
@Title     Define the name of a Variable
Uwe Schulzweida's avatar
Uwe Schulzweida committed
815 816 817

@Prototype void vlistDefVarName(int vlistID, int varID, const char *name)
@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
818 819 820
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
    @Item  varID    Variable identifier.
    @Item  name     Name of the variable.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
821 822

@Description
823
The function @func{vlistDefVarName} defines the name of a variable.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
824 825