Commit a1077994 authored by Uwe Schulzweida's avatar Uwe Schulzweida
Browse files

added GRIB1 support for timerange 1,2,3,4,5

parent 94e7be8f
2010-01-25 Uwe Schulzweida <Uwe.Schulzweida@zmaw.de>
* added GRIB1 support for timerange 1,2,3,4,5
2010-01-14 Uwe Schulzweida <Uwe.Schulzweida@zmaw.de>
* cdfDefVar: define add_offset and scale_factor always together
......@@ -17,7 +21,7 @@
2009-12-29 Uwe Schulzweida <Uwe.Schulzweida@zmaw.de>
* using EXSE library version 1.2.0
* using EXSE library version 1.2.0 (complex numbers with EXTRA)
2009-12-15 Uwe Schulzweida <Uwe.Schulzweida@zmaw.de>
......
......@@ -164,10 +164,13 @@ extern "C" {
#define TSTEP_MAX 4
#define TSTEP_MIN 5
#define TSTEP_DIFF 6
#define TSTEP_RANGE 7
#define TSTEP_INSTANT2 8
#define TSTEP_INSTANT3 9
/* CALENDAR types */
#define CALENDAR_STANDARD 0 /* don't change this value (used also in griblib)! */
#define CALENDAR_STANDARD 0 /* don't change this value (used also in cgribexlib)! */
#define CALENDAR_PROLEPTIC 1
#define CALENDAR_360DAYS 2
#define CALENDAR_365DAYS 3
......@@ -432,10 +435,14 @@ void vlistDefVarScalefactor(int vlistID, int varID, double scalefactor);
double vlistInqVarScalefactor(int vlistID, int varID);
void vlistDefVarAddoffset(int vlistID, int varID, double addoffset);
double vlistInqVarAddoffset(int vlistID, int varID);
void vlistDefVarTsteptype(int vlistID, int varID, int tsteptype);
int vlistInqVarTsteptype(int vlistID, int varID);
void vlistDefVarTimave(int vlistID, int varID, int timave);
int vlistInqVarTimave(int vlistID, int varID);
void vlistDefVarTimaccu(int vlistID, int varID, int timaccu);
int vlistInqVarTimaccu(int vlistID, int varID);
int vlistInqVarSize(int vlistID, int varID);
int vlistInqVarID(int vlistID, int code);
......
......@@ -202,6 +202,44 @@ int cgribexGetTimeUnit(int *isec1)
return (timeunit);
}
static
int cgribexTimeIsFC(int *isec1)
{
int isFC = TRUE;
if ( ISEC1_TimeRange == 10 && ISEC1_TimePeriod1 == 0 && ISEC1_TimePeriod2 == 0 )
isFC = FALSE;
return (isFC);
}
static
int cgribexGetTsteptype(int timerange)
{
static char func[] = "cgribexGetTsteptype";
int tsteptype = 0;
static int lprint = TRUE;
switch ( timerange )
{
case 0: tsteptype = TSTEP_INSTANT; break;
case 1: tsteptype = TSTEP_INSTANT2; break;
case 2: tsteptype = TSTEP_RANGE; break;
case 3: tsteptype = TSTEP_AVG; break;
case 4: tsteptype = TSTEP_ACCUM; break;
case 5: tsteptype = TSTEP_DIFF; break;
case 10: tsteptype = TSTEP_INSTANT3; break;
default:
if ( lprint )
{
Message(func, "Time range %d unsupported", timerange);
lprint = FALSE;
}
}
return (tsteptype);
}
static
void cgribexAddRecord(int streamID, int param, int *isec1, int *isec2, double *fsec2, double *fsec3,
......@@ -215,6 +253,7 @@ void cgribexAddRecord(int streamID, int param, int *isec1, int *isec2, double *f
int tsID, recID;
int level1, level2;
int numavg;
int tsteptype;
int lbounds = 0;
record_t *record;
grid_t grid;
......@@ -228,7 +267,8 @@ void cgribexAddRecord(int streamID, int param, int *isec1, int *isec2, double *f
recID = recordNewEntry(streamID, tsID);
record = &streamptr->tsteps[tsID].records[recID];
numavg = ISEC1_AvgNum;
tsteptype = cgribexGetTsteptype(ISEC1_TimeRange);
numavg = ISEC1_AvgNum;
level1 = ISEC1_Level1;
level2 = ISEC1_Level2;
......@@ -429,7 +469,7 @@ void cgribexAddRecord(int streamID, int param, int *isec1, int *isec2, double *f
if ( prec < 0 ) prec = DATATYPE_PACK;
varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2,
prec, &varID, &levelID, numavg, ISEC1_LevelType, NULL, NULL, NULL);
prec, &varID, &levelID, tsteptype, numavg, ISEC1_LevelType, NULL, NULL, NULL);
(*record).varID = varID;
(*record).levelID = levelID;
......@@ -632,7 +672,7 @@ void cgribexScanTimestep1(int streamID)
rdate = gribRefDate(isec1);
rtime = gribRefTime(isec1);
tunit = cgribexGetTimeUnit(isec1);
fcast = gribTimeIsFC(isec1);
fcast = cgribexTimeIsFC(isec1);
}
else
{
......@@ -786,6 +826,7 @@ int cgribexScanTimestep2(int streamID)
int nrecords, nrecs, recID, rindex;
long recsize = 0;
int warn_numavg = TRUE;
int tsteptype;
int taxisID = -1;
TAXIS *taxis;
int vlistID;
......@@ -885,13 +926,14 @@ int cgribexScanTimestep2(int streamID)
if ( taxisInqType(taxisID) == TAXIS_RELATIVE )
{
taxis->type = TAXIS_RELATIVE;
taxis->unit = cgribexGetTimeUnit(isec1);
taxis->rdate = gribRefDate(isec1);
taxis->rtime = gribRefTime(isec1);
taxis->unit = cgribexGetTimeUnit(isec1);
}
else
{
taxis->type = TAXIS_ABSOLUTE;
taxis->unit = cgribexGetTimeUnit(isec1);
}
taxis->vdate = vdate;
taxis->vtime = vtime;
......@@ -900,6 +942,8 @@ int cgribexScanTimestep2(int streamID)
datetime0.time = vtime;
}
tsteptype = cgribexGetTsteptype(ISEC1_TimeRange);
if ( ISEC1_AvgNum )
{
if ( taxis->numavg && warn_numavg &&
......@@ -1001,6 +1045,9 @@ int cgribexScanTimestep2(int streamID)
gridChangeType(gridID, GRID_TRAJECTORY);
}
if ( tsteptype != vlistInqVarTsteptype(vlistID, varID) )
vlistDefVarTsteptype(vlistID, varID, tsteptype);
rindex++;
}
......@@ -1162,13 +1209,14 @@ int cgribexScanTimestep(int streamID)
if ( taxisInqType(taxisID) == TAXIS_RELATIVE )
{
taxis->type = TAXIS_RELATIVE;
taxis->unit = cgribexGetTimeUnit(isec1);
taxis->rdate = gribRefDate(isec1);
taxis->rtime = gribRefTime(isec1);
taxis->unit = cgribexGetTimeUnit(isec1);
}
else
{
taxis->type = TAXIS_ABSOLUTE;
taxis->unit = cgribexGetTimeUnit(isec1);
}
taxis->vdate = vdate;
taxis->vtime = vtime;
......@@ -1466,25 +1514,26 @@ void cgribexDefParam(int *isec1, int param)
}
static
void cgribexDefTime(int *isec1, int date, int time, int numavg, int timeID)
void cgribexDefTime(int *isec1, int date, int time, int tsteptype, int numavg, int taxisID)
{
int year, month, day, hour, minute, second;
int century = 0;
int timetype = -1;
int timerange = 0;
if ( timeID != -1 ) timetype = taxisInqType(timeID);
if ( taxisID != -1 ) timetype = taxisInqType(taxisID);
if ( timetype == TAXIS_RELATIVE )
{
int factor = 1;
int rdate, rtime;
int julday1, secofday1, julday2, secofday2, days, secs;
int ival;
int ip, ip1 = 0, ip2 = 0;
int calendar;
calendar = taxisInqCalendar(timeID);
rdate = taxisInqRdate(timeID);
rtime = taxisInqRtime(timeID);
calendar = taxisInqCalendar(taxisID);
rdate = taxisInqRdate(taxisID);
rtime = taxisInqRtime(taxisID);
cdiDecodeDate(rdate, &year, &month, &day);
cdiDecodeTime(rtime, &hour, &minute, &second);
......@@ -1516,7 +1565,7 @@ void cgribexDefTime(int *isec1, int date, int time, int numavg, int timeID)
*/
encode_juldaysec(calendar, year, month, day, hour, minute, &julday1, &secofday1);
switch (taxisInqTunit(timeID))
switch (taxisInqTunit(taxisID))
{
case TUNIT_MINUTE: factor = 60; ISEC1_TimeUnit = ISEC1_TABLE4_MINUTE; break;
case TUNIT_QUARTER: factor = 900; ISEC1_TimeUnit = ISEC1_TABLE4_QUARTER; break;
......@@ -1533,17 +1582,38 @@ void cgribexDefTime(int *isec1, int date, int time, int numavg, int timeID)
encode_juldaysec(calendar, year, month, day, hour, minute, &julday2, &secofday2);
(void) julday_sub(julday1, secofday1, julday2, secofday2, &days, &secs);
/* ival = (int) ((days*86400.0 + secs)/factor); */
/* ip = (int) ((days*86400.0 + secs)/factor); */
if ( (int) fmod(days*86400.0 + secs, factor) )
ival = -1;
ip = -1;
else
ival = (int) ((days*86400.0 + secs)/factor);
ip = (int) ((days*86400.0 + secs)/factor);
if ( ival < 0 || ival > 255 ) timetype = TAXIS_ABSOLUTE;
switch ( tsteptype )
{
case TSTEP_INSTANT: timerange = 0; ip1 = ip; ip2 = 0; break;
case TSTEP_INSTANT2: timerange = 1; ip1 = 0; ip2 = 0; break;
case TSTEP_RANGE: timerange = 2; ip1 = 0; ip2 = ip; break;
case TSTEP_AVG: timerange = 3; ip1 = 0; ip2 = ip; break;
case TSTEP_ACCUM: timerange = 4; ip1 = 0; ip2 = ip; break;
case TSTEP_DIFF: timerange = 5; ip1 = 0; ip2 = ip; break;
case TSTEP_INSTANT3:
default: timerange = 10; ip1 = ip; ip2 = 0; break;
}
// printf("timerange: %d %d %d\n", timerange, ip1, ip2);
if ( timerange == 10 )
{
if ( ip < 0 || ip > 0xffff ) timetype = TAXIS_ABSOLUTE;
}
else
{
if ( ip < 0 || ip > 0xff ) timetype = TAXIS_ABSOLUTE;
}
ISEC1_TimeRange = 0;
ISEC1_TimePeriod1 = ival;
ISEC1_TimeRange = timerange;
ISEC1_TimePeriod1 = ip1;
ISEC1_TimePeriod2 = ip2;
}
if ( timetype == TAXIS_ABSOLUTE )
......@@ -1576,23 +1646,26 @@ void cgribexDefTime(int *isec1, int date, int time, int numavg, int timeID)
ISEC1_Minute = minute;
/* ISEC1_TimeUnit = 0; */
switch (taxisInqTunit(timeID))
switch (taxisInqTunit(taxisID))
{
case TUNIT_MINUTE: ISEC1_TimeUnit = ISEC1_TABLE4_MINUTE; break;
case TUNIT_QUARTER: ISEC1_TimeUnit = ISEC1_TABLE4_QUARTER; break;
case TUNIT_HOUR: ISEC1_TimeUnit = ISEC1_TABLE4_HOUR; break;
case TUNIT_DAY: ISEC1_TimeUnit = ISEC1_TABLE4_DAY; break;
case default: ISEC1_TimeUnit = ISEC1_TABLE4_MINUTE; break;
}
/*
if ( numavg > 0 )
ISEC1_TimeRange = 0;
else
ISEC1_TimeRange = 10;
*/
ISEC1_TimeRange = 10;
ISEC1_TimePeriod1 = 0;
ISEC1_TimePeriod2 = 0;
}
ISEC1_TimePeriod2 = 0;
ISEC1_AvgNum = numavg;
ISEC1_AvgMiss = 0;
ISEC1_Century = century;
......@@ -2020,7 +2093,8 @@ void cgribexDefaultSec4(int *isec4)
#endif
size_t cgribexEncode(int varID, int levelID, int vlistID, int gridID, int zaxisID, int date, int time, int numavg,
size_t cgribexEncode(int varID, int levelID, int vlistID, int gridID, int zaxisID,
int date, int time, int tsteptype, int numavg,
long datasize, const double *data, int nmiss, unsigned char *gribbuffer, size_t gribbuffersize)
{
static char func[] = "cgribexEncode";
......@@ -2049,7 +2123,7 @@ size_t cgribexEncode(int varID, int levelID, int vlistID, int gridID, int zaxisI
datatype = vlistInqVarDatatype(vlistID, varID);
cgribexDefParam(isec1, param);
cgribexDefTime(isec1, date, time, numavg, vlistInqTaxis(vlistID));
cgribexDefTime(isec1, date, time, tsteptype, numavg, vlistInqTaxis(vlistID));
cgribexDefGrid(isec1, isec2, gridID);
cgribexDefLevel(isec1, isec2, fsec2, zaxisID, levelID);
cgribexDefMask(isec3);
......
......@@ -8,7 +8,8 @@ int cgribexScanTimestep(int streamID);
int cgribexDecode(unsigned char *gribbuffer, int gribsize, double *data, int gridsize,
int unreduced, int *nmiss, int *zip, double missval);
size_t cgribexEncode(int varID, int levelID, int vlistID, int gridID, int zaxisID, int date, int time, int numavg,
size_t cgribexEncode(int varID, int levelID, int vlistID, int gridID, int zaxisID,
int date, int time, int tsteptype, int numavg,
long datasize, const double *data, int nmiss, unsigned char *gribbuffer, size_t gribbuffersize);
#endif /* _STREAM_CGRIBEX_H */
......@@ -303,7 +303,7 @@ void extAddRecord(int streamID, int param, int level, int xysize,
leveltype = ZAXIS_GENERIC;
varAddRecord(recID, param, gridID, leveltype, 0, level, 0,
extInqDatatype(prec, number), &varID, &levelID, 0, 0, NULL, NULL, NULL);
extInqDatatype(prec, number), &varID, &levelID, 0, 0, 0, NULL, NULL, NULL);
(*record).varID = varID;
(*record).levelID = levelID;
......
......@@ -381,7 +381,8 @@ void grbReadVarSliceDP(int streamID, int varID, int levelID, double *data, int *
}
static
size_t grbEncode(int filetype, int varID, int levelID, int vlistID, int gridID, int zaxisID, int date, int time, int numavg,
size_t grbEncode(int filetype, int varID, int levelID, int vlistID, int gridID, int zaxisID,
int date, int time, int tsteptype, int numavg,
long datasize, const double *data, int nmiss, unsigned char *gribbuffer, size_t gribbuffersize,
int ljpeg, void *gribHandle)
{
......@@ -389,7 +390,7 @@ size_t grbEncode(int filetype, int varID, int levelID, int vlistID, int gridID,
if ( filetype == FILETYPE_GRB )
{
nbytes = cgribexEncode(varID, levelID, vlistID, gridID, zaxisID, date, time, numavg,
nbytes = cgribexEncode(varID, levelID, vlistID, gridID, zaxisID, date, time, tsteptype, numavg,
datasize, data, nmiss, gribbuffer, gribbuffersize);
}
else
......@@ -445,6 +446,7 @@ int grbWriteVarSliceDP(int streamID, int varID, int levelID, const double *data,
int tsID;
int vlistID;
int date, time;
int tsteptype;
int numavg = 0;
size_t nbytes;
int filetype;
......@@ -457,16 +459,17 @@ int grbWriteVarSliceDP(int streamID, int varID, int levelID, const double *data,
stream_check_ptr(func, streamptr);
filetype = streamptr->filetype;
filetype = streamptr->filetype;
fileID = streamInqFileID(streamID);
vlistID = streamInqVlist(streamID);
gridID = vlistInqVarGrid(vlistID, varID);
zaxisID = vlistInqVarZaxis(vlistID, varID);
fileID = streamInqFileID(streamID);
vlistID = streamInqVlist(streamID);
gridID = vlistInqVarGrid(vlistID, varID);
zaxisID = vlistInqVarZaxis(vlistID, varID);
tsteptype = vlistInqVarTsteptype(vlistID, varID);
tsID = streamptr->curTsID;
date = streamptr->tsteps[tsID].taxis.vdate;
time = streamptr->tsteps[tsID].taxis.vtime;
tsID = streamptr->curTsID;
date = streamptr->tsteps[tsID].taxis.vdate;
time = streamptr->tsteps[tsID].taxis.vtime;
if ( vlistInqVarTimave(vlistID, varID) )
numavg = streamptr->tsteps[tsID].taxis.numavg;
......@@ -498,7 +501,7 @@ int grbWriteVarSliceDP(int streamID, int varID, int levelID, const double *data,
}
}
nbytes = grbEncode(filetype, varID, levelID, vlistID, gridID, zaxisID, date, time, numavg,
nbytes = grbEncode(filetype, varID, levelID, vlistID, gridID, zaxisID, date, time, tsteptype, numavg,
datasize, data, nmiss, gribbuffer, gribbuffersize, ljpeg, gh);
if ( streamptr->ztype == COMPRESS_SZIP )
......
......@@ -492,7 +492,7 @@ void gribapiAddRecord(int streamID, int param, grib_handle *gh,
// fprintf(stderr, "param %d name %s %s %s\n", param, name, longname, units);
varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2,
prec, &varID, &levelID, numavg, leveltype,
prec, &varID, &levelID, 0, numavg, leveltype,
name, longname, units);
(*record).varID = varID;
......
......@@ -765,7 +765,7 @@ void iegAddRecord(int streamID, int param, int *pdb, int *gdb, double *vct,
datatype = iegInqDatatype(prec);
varAddRecord(recID, param, gridID, leveltype, lbounds, level1, level2,
datatype, &varID, &levelID, 0, 0, NULL, NULL, NULL);
datatype, &varID, &levelID, 0, 0, 0, NULL, NULL, NULL);
(*record).varID = varID;
(*record).levelID = levelID;
......
......@@ -317,7 +317,7 @@ void srvAddRecord(int streamID, int param, int level, int xsize, int ysize,
datatype = srvInqDatatype(prec);
varAddRecord(recID, param, gridID, leveltype, 0, level, 0,
datatype, &varID, &levelID, 0, 0, NULL, NULL, NULL);
datatype, &varID, &levelID, 0, 0, 0, NULL, NULL, NULL);
(*record).varID = varID;
(*record).levelID = levelID;
......
......@@ -30,6 +30,7 @@ typedef struct
{
int param;
int prec;
int tsteptype;
int timave;
int timaccu;
int gridID;
......@@ -65,6 +66,7 @@ void paramInitEntry(int varID, int param)
{
vartable[varID].param = param;
vartable[varID].prec = 0;
vartable[varID].tsteptype = TSTEP_INSTANT;
vartable[varID].timave = 0;
vartable[varID].timaccu = 0;
vartable[varID].gridID = UNDEFID;
......@@ -262,7 +264,7 @@ int paramNewEntry (int param)
void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
int level1, int level2, int prec,
int *pvarID, int *plevelID, int numavg, int ltype,
int *pvarID, int *plevelID, int tsteptype, int numavg, int ltype,
const char *name, const char *longname, const char *units)
{
static char func[] = "varAddRecord";
......@@ -281,6 +283,7 @@ void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
vartable[varID].zaxistype = zaxistype;
vartable[varID].ltype = ltype;
vartable[varID].lbounds = lbounds;
if ( tsteptype > 0 ) vartable[varID].tsteptype = tsteptype;
if ( numavg ) vartable[varID].timave = 1;
if ( name ) if ( name[0] ) vartable[varID].name = strdup(name);
......@@ -382,6 +385,7 @@ void cdiGenVars(int streamID)
int instID, modelID, tableID;
int param, nlevels, zaxistype, lindex, ltype;
int prec;
int tsteptype;
int timave, timaccu;
int lbounds;
int ztype;
......@@ -442,6 +446,7 @@ void cdiGenVars(int streamID)
instID = vartable[varid].instID;
modelID = vartable[varid].modelID;
tableID = vartable[varid].tableID;
tsteptype = vartable[varid].tsteptype;
timave = vartable[varid].timave;
timaccu = vartable[varid].timaccu;
ztype = vartable[varid].ztype;
......@@ -522,6 +527,7 @@ void cdiGenVars(int streamID)
vlistDefVarParam(vlistID, varID, param);
vlistDefVarDatatype(vlistID, varID, prec);
vlistDefVarTsteptype(vlistID, varID, tsteptype);
vlistDefVarTimave(vlistID, varID, timave);
vlistDefVarTimaccu(vlistID, varID, timaccu);
vlistDefVarZtype(vlistID, varID, ztype);
......
......@@ -8,7 +8,7 @@
void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
int level1, int level2, int prec,
int *pvarID, int *plevelID, int numavg, int ltype,
int *pvarID, int *plevelID, int tsteptype, int numavg, int ltype,
const char *name, const char *longname, const char *units);
void varDefVCT(size_t vctsize, double *vctptr);
......
......@@ -53,10 +53,11 @@ typedef struct
int instID;
int modelID;
int tableID;
int tsteptype; /* Time step type: TSTEP_INSTANT, TSTEP_AVG ... */
int timave;
int timaccu;
int func;
int missvalused; /* TRUE if missval is defined */
int missvalused; /* TRUE if missval is defined */
char *name;
char *longname;
char *stdname;
......
......@@ -22,6 +22,7 @@ static void vlistvarInitEntry(int vlistID, int varID)
vlistptr->vars[varID].param = 0;
vlistptr->vars[varID].timeID = CDI_UNDEFID;
vlistptr->vars[varID].datatype = CDI_UNDEFID;
vlistptr->vars[varID].tsteptype = TSTEP_INSTANT;
vlistptr->vars[varID].timave = 0;
vlistptr->vars[varID].timaccu = 0;
vlistptr->vars[varID].gridID = CDI_UNDEFID;
......@@ -1167,6 +1168,26 @@ void vlistDefVarAddoffset(int vlistID, int varID, double addoffset)
}
void vlistDefVarTsteptype(int vlistID, int varID, int tsteptype)
{
vlist_t *vlistptr;
vlistptr = vlist_to_pointer(vlistID);
vlistptr->vars[varID].tsteptype = tsteptype;
}
int vlistInqVarTsteptype(int vlistID, int varID)
{
vlist_t *vlistptr;
vlistptr = vlist_to_pointer(vlistID);
return (vlistptr->vars[varID].tsteptype);
}
void vlistDefVarTimave(int vlistID, int varID, int timave)
{
vlist_t *vlistptr;
......
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