Commit 57fd0c23 authored by Uwe Schulzweida's avatar Uwe Schulzweida
Browse files

GRIBAPI: Added support for variables with same name and different gridsize.

parent 5efc8f2a
......@@ -2,6 +2,10 @@
* Version 1.9.3 released
2018-01-09 Uwe Schulzweida
* GRIBAPI: Added support for variables with same name and different gridsize.
2018-01-06 Uwe Schulzweida
* Removed CDI function vlistDefVarTimaccu()/vlistInqVarTimaccu().
......
......@@ -151,6 +151,7 @@ typedef struct
{
off_t position;
size_t size;
size_t gridsize;
int zip;
int param;
int ilevel;
......
#if defined (HAVE_CONFIG_H)
# include "config.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
......@@ -32,7 +32,7 @@ void SysError_(const char *caller, const char *fmt, ...)
va_start(args, fmt);
printf("\n");
fprintf(stderr, "Error (%s) : ", caller);
fprintf(stderr, "Error (%s): ", caller);
vfprintf(stderr, fmt, args);
fprintf(stderr, "\n");
......@@ -55,7 +55,7 @@ void Error_(const char *caller, const char *fmt, ...)
va_start(args, fmt);
printf("\n");
fprintf(stderr, "Error (%s) : ", caller);
fprintf(stderr, "Error (%s): ", caller);
vfprintf(stderr, fmt, args);
fprintf(stderr, "\n");
......@@ -118,7 +118,7 @@ void Warning_(const char *caller, const char *fmt, ...)
void cdiWarning(const char *caller, const char *fmt, va_list ap)
{
fprintf(stderr, "Warning (%s) : ", caller);
fprintf(stderr, "Warning (%s): ", caller);
vfprintf(stderr, fmt, ap);
fputc('\n', stderr);
}
......@@ -130,7 +130,7 @@ void Message_(const char *caller, const char *fmt, ...)
va_start(args, fmt);
fprintf(stdout, "%-18s : ", caller);
fprintf(stdout, "%-18s: ", caller);
vfprintf(stdout, fmt, args);
fprintf(stdout, "\n");
......
......@@ -503,6 +503,15 @@ int gribapiGetIsRotated(grib_handle *gh)
return gribGetLongDefault(gh, "gridDefinitionTemplateNumber", -1) == GRIB2_GTYPE_LATLON_ROT;
}
size_t gribapiGetGridsize(grib_handle *gh)
{
size_t gridsize;
FAIL_ON_GRIB_ERROR(grib_get_size, gh, "values", &gridsize);
return gridsize;
}
//TODO: Simplify by use of the convenience functions (gribGetLong(), gribGetLongDefault(), etc.).
void gribapiGetGrid(grib_handle *gh, grid_t *grid)
{
......
......@@ -32,6 +32,8 @@ int gribGetDatatype(grib_handle* gribHandle);
int gribapiGetParam(grib_handle *gh);
int gribapiGetGridType(grib_handle *gh);
void gribapiGetGrid(grib_handle *gh, grid_t *grid);
size_t gribapiGetGridsize(grib_handle *gh);
#ifdef HIRLAM_EXTENSIONS
void gribapiSetDataTimeRangeIndicator(grib_handle *gh, int timeRangeIndicator);
......
......@@ -33,6 +33,7 @@ typedef struct {
int level2;
int ltype;
int tsteptype;
size_t gridsize;
#ifdef HIRLAM_EXTENSIONS
// NOTE: tsteptype MUST be part of attributes used to compare variables!
// Modern NWP models (HARMONIE, HIRLAM) use timeRangeIndicator to specify
......@@ -458,6 +459,7 @@ void gribapiAddRecord(stream_t *streamptr, int param, grib_handle *gh,
record->ilevel2 = level2;
record->ltype = leveltype1;
record->tsteptype = (short)tsteptype;
record->gridsize = gribapiGetGridsize(gh);
record->tiles = tiles ? *tiles : dummy_tiles;
//FIXME: This may leave the variable name unterminated (which is the behavior that I found in the code).
......@@ -669,8 +671,9 @@ void gribapiAddRecord(stream_t *streamptr, int param, grib_handle *gh,
varID, param, zaxistype, gridID, levelID);
}
static compvar2_t gribapiVarSet(int param, int level1, int level2, int leveltype,
int tsteptype, char *name, var_tile_t tiles_data)
static
compvar2_t gribapiVarSet(int param, int level1, int level2, int leveltype, int tsteptype,
size_t gridsize, char *name, var_tile_t tiles_data)
{
compvar2_t compVar;
size_t maxlen = sizeof(compVar.name);
......@@ -682,6 +685,7 @@ static compvar2_t gribapiVarSet(int param, int level1, int level2, int leveltype
compVar.level2 = level2;
compVar.ltype = leveltype;
compVar.tsteptype = tsteptype;
compVar.gridsize = gridsize;
memset(compVar.name, 0, maxlen);
memcpy(compVar.name, name, len);
compVar.tiles = tiles_data;
......@@ -698,6 +702,7 @@ int gribapiVarCompare(compvar2_t compVar, record_t record, int flag)
compVar0.level2 = record.ilevel2;
compVar0.ltype = record.ltype;
compVar0.tsteptype = record.tsteptype;
compVar0.gridsize = record.gridsize;
memcpy(compVar0.name, record.varname, sizeof(compVar.name));
if ( flag == 0 )
......@@ -874,13 +879,10 @@ int gribapiScanTimestep1(stream_t * streamptr)
int vdate = 0, vtime = 0;
gribapiGetValidityDateTime(gh, &vdate, &vtime);
DateTime datetime = { .date = vdate, .time = vtime };
/*
printf("%d %d %d\n", vdate, vtime, leveltype1);
*/
if ( datetime0.date == 10101 && datetime0.time == 0 )
{
if( datetimeCmp(datetime, datetime0) || !nrecs ) //Do we really need this condition? I have included it in order not to change the number of times gribapiGetDataDateTime() etc. get called. But if those are sideeffect-free, this condition should be removed.
if ( datetimeCmp(datetime, datetime0) || !nrecs ) //Do we really need this condition? I have included it in order not to change the number of times gribapiGetDataDateTime() etc. get called. But if those are sideeffect-free, this condition should be removed.
{
datetime0 = datetime;
......@@ -893,7 +895,9 @@ int gribapiScanTimestep1(stream_t * streamptr)
if ( nrecs )
{
checkTimeResult result = checkTime(streamptr, gribapiVarSet(param, level1, level2, leveltype1, tsteptype, varname, tiles), &datetime, &datetime0);
size_t gridsize = gribapiGetGridsize(gh);
checkTimeResult result = checkTime(streamptr, gribapiVarSet(param, level1, level2, leveltype1, tsteptype, gridsize, varname, tiles),
&datetime, &datetime0);
if ( result == CHECKTIME_STOP )
{
break;
......@@ -1134,7 +1138,8 @@ int gribapiScanTimestep2(stream_t * streamptr)
.time = vtime
};
compvar2_t compVar = gribapiVarSet(param, level1, level2, leveltype1, tsteptype, varname, tiles);
size_t gridsize = gribapiGetGridsize(gh);
compvar2_t compVar = gribapiVarSet(param, level1, level2, leveltype1, tsteptype, gridsize, varname, tiles);
for ( recID = 0; recID < nrecords; recID++ )
if ( gribapiVarCompare(compVar, streamptr->tsteps[tsID].records[recID], 0) == 0 ) break;
......@@ -1364,7 +1369,8 @@ int gribapiScanTimestep(stream_t * streamptr)
int tsteptype = gribapiGetTsteptype(gh);
compvar2_t compVar = gribapiVarSet(param, level1, level2, leveltype1, tsteptype, varname, tiles);
size_t gridsize = gribapiGetGridsize(gh);
compvar2_t compVar = gribapiVarSet(param, level1, level2, leveltype1, tsteptype, gridsize, varname, tiles);
for ( vrecID = 0; vrecID < nrecs; vrecID++ )
{
......@@ -2350,18 +2356,13 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int zaxisID, int levelI
long ltype2 = zaxisInqLtype2(zaxisID);
double level = zaxisInqLevels(zaxisID, NULL) ? zaxisInqLevel(zaxisID, levelID) : levelID+1;
double dlevel1 = 0, dlevel2 = 0;
double dlevel1 = level, dlevel2 = 0;
if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
{
lbounds = true;
dlevel1 = zaxisInqLbound(zaxisID, levelID);
dlevel2 = zaxisInqUbound(zaxisID, levelID);
}
else
{
dlevel1 = level;
dlevel2 = 0;
}
if ( zaxistype == ZAXIS_GENERIC && ltype == 0 )
{
......
......@@ -22,9 +22,11 @@ void recordInitEntry(record_t *record)
{
record->position = CDI_UNDEFID;
record->size = 0;
record->gridsize = 0;
record->param = 0;
record->ilevel = CDI_UNDEFID;
record->used = false;
record->tsteptype = CDI_UNDEFID;
record->varID = CDI_UNDEFID;
record->levelID = CDI_UNDEFID;
memset(record->varname, 0, sizeof(record->varname));
......
......@@ -136,7 +136,7 @@ void paramInitEntry(unsigned varID, int param)
/* Test if a variable specified by the given meta-data has already
* been registered in "vartable". */
static unsigned
varGetEntry(int param, int zaxistype, int ltype1, int tsteptype, const char *name, const var_tile_t *tiles)
varGetEntry(int param, int gridID, int zaxistype, int ltype1, int tsteptype, const char *name, const var_tile_t *tiles)
{
for ( unsigned varID = 0; varID < varTablesize; varID++ )
{
......@@ -153,6 +153,7 @@ varGetEntry(int param, int zaxistype, int ltype1, int tsteptype, const char *nam
if ( (vartable[varID].zaxistype == zaxistype) &&
(vartable[varID].ltype1 == ltype1 ) &&
(vartable[varID].tsteptype == tsteptype) &&
(vartable[varID].gridID == gridID ) &&
(vt_no_of_tiles == no_of_tiles) )
{
if ( name && name[0] && vartable[varID].name && vartable[varID].name[0] )
......@@ -433,7 +434,7 @@ void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
const var_tile_t *tiles, int *tile_index)
{
unsigned varID = (cdiSplitLtype105 != 1 || zaxistype != ZAXIS_HEIGHT) ?
varGetEntry(param, zaxistype, ltype1, tsteptype, name, tiles) : (unsigned) CDI_UNDEFID;
varGetEntry(param, gridID, zaxistype, ltype1, tsteptype, name, tiles) : (unsigned) CDI_UNDEFID;
if ( varID == (unsigned) CDI_UNDEFID )
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment