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