Commit 548d9b4a authored by Uwe Schulzweida's avatar Uwe Schulzweida
Browse files

added missing value support for cosmo GRIB files

parent 97839498
...@@ -18,8 +18,8 @@ int cdiEncodeParam(int pnum, int pcat, int pdis) ...@@ -18,8 +18,8 @@ int cdiEncodeParam(int pnum, int pcat, int pdis)
int param; int param;
int inum; int inum;
if ( pcat < 0 ) pcat = 255; if ( pcat < 0 || pcat > 255 ) pcat = 255;
if ( pdis < 0 ) pdis = 255; if ( pdis < 0 || pdis > 255 ) pdis = 255;
inum = pnum; inum = pnum;
if ( pnum < 0 ) inum = -pnum; if ( pnum < 0 ) inum = -pnum;
......
...@@ -5858,23 +5858,21 @@ int cdfInqContents(int streamID) ...@@ -5858,23 +5858,21 @@ int cdfInqContents(int streamID)
pname = vlistInqVarNamePtr(vlistID, varID); pname = vlistInqVarNamePtr(vlistID, varID);
len = strlen(pname); len = strlen(pname);
if ( len > 3 && isdigit((int) pname[3]) ) if ( len > 3 && isdigit((int) pname[3]) )
if ( memcmp("var", pname, 3) == 0 ) {
{ if ( memcmp("var", pname, 3) == 0 )
vlistDefVarCode(vlistID, varID, atoi(pname+3)); {
vlistDestroyVarName(vlistID, varID); vlistDefVarCode(vlistID, varID, atoi(pname+3));
} vlistDestroyVarName(vlistID, varID);
} }
if ( vlistInqVarCode(vlistID, varID) == -varID-1 ) }
{ else if ( len > 4 && isdigit((int) pname[4]) )
char *pname; {
pname = vlistInqVarNamePtr(vlistID, varID); if ( memcmp("code", pname, 4) == 0 )
len = strlen(pname); {
if ( len > 4 && isdigit((int) pname[4]) ) vlistDefVarCode(vlistID, varID, atoi(pname+4));
if ( memcmp("code", pname, 4) == 0 ) vlistDestroyVarName(vlistID, varID);
{ }
vlistDefVarCode(vlistID, varID, atoi(pname+4)); }
vlistDestroyVarName(vlistID, varID);
}
} }
} }
......
...@@ -204,8 +204,8 @@ int cgribexGetTimeUnit(int *isec1) ...@@ -204,8 +204,8 @@ int cgribexGetTimeUnit(int *isec1)
static static
void cgribexAddRecord(int streamID, int param, int *isec1, int *isec2, double *fsec2, void cgribexAddRecord(int streamID, int param, int *isec1, int *isec2, double *fsec2, double *fsec3,
int *isec4, long recsize, off_t position, int prec, int ztype) int *isec4, long recsize, off_t position, int prec, int ztype, int lmv)
{ {
static char func[] = "cgribexAddRecord"; static char func[] = "cgribexAddRecord";
int gridtype; int gridtype;
...@@ -436,6 +436,8 @@ void cgribexAddRecord(int streamID, int param, int *isec1, int *isec2, double *f ...@@ -436,6 +436,8 @@ void cgribexAddRecord(int streamID, int param, int *isec1, int *isec2, double *f
varDefZtype(varID, ztype); varDefZtype(varID, ztype);
if ( lmv ) varDefMissval(varID, FSEC3_MissVal);
if ( varInqInst(varID) == CDI_UNDEFID ) if ( varInqInst(varID) == CDI_UNDEFID )
{ {
int center, subcenter, instID; int center, subcenter, instID;
...@@ -475,16 +477,63 @@ void cgribexAddRecord(int streamID, int param, int *isec1, int *isec2, double *f ...@@ -475,16 +477,63 @@ void cgribexAddRecord(int streamID, int param, int *isec1, int *isec2, double *f
varID, param, zaxistype, gridID, levelID); varID, param, zaxistype, gridID, levelID);
} }
static
void MCH_get_undef(int *isec1, double *undef_pds, double *undef_eps)
{
/* 2010-01-13: Oliver Fuhrer */
if ( ISEC1_CenterID == 215 ) {
if (isec1[34] != 0 && isec1[34] != 255) {
if (isec1[34] & 2) {
if (isec1[34] & 1) {
*undef_pds = -0.99*pow(10.0,-isec1[35]);
} else {
*undef_pds = +0.99*pow(10.0,-isec1[35]);
}
*undef_eps = pow(10.0,-isec1[35]-1);
} else {
if (isec1[34] & 1) {
*undef_pds = -0.99*pow(10.0,+isec1[35]);
} else {
*undef_pds = +0.99*pow(10.0,+isec1[35]);
}
*undef_eps = pow(10.0,isec1[35]-1);
}
}
}
}
static
void cgribexDecodeHeader(int *isec0, int *isec1, int *isec2, double *fsec2,
int *isec3, double *fsec3, int *isec4, double *fsec4,
int *gribbuffer, int recsize, int *lmv)
{
int iret = 0, ipunp = 0, iword = 0;
gribExDP(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, fsec4,
ipunp, (int *) gribbuffer, recsize, &iword, "J", &iret);
*lmv = 0;
if ( ISEC1_CenterID == 215 && (isec1[34] != 0 && isec1[34] != 255) )
{
double undef_pds, undef_eps;
MCH_get_undef(isec1, &undef_pds, &undef_eps);
FSEC3_MissVal = undef_pds;
*lmv = 1;
}
}
void cgribexScanTimestep1(int streamID) void cgribexScanTimestep1(int streamID)
{ {
static char func[] = "cgribexScanTimestep1"; static char func[] = "cgribexScanTimestep1";
int *isec0, *isec1, *isec2, *isec3, *isec4; int *isec0, *isec1, *isec2, *isec3, *isec4;
double fsec2[512], fsec3[2], *fsec4 = NULL; double fsec2[512], fsec3[2], *fsec4 = NULL;
int lmv = 0;
off_t recpos = 0; off_t recpos = 0;
unsigned char *gribbuffer = NULL; unsigned char *gribbuffer = NULL;
long buffersize = 0; long buffersize = 0;
int iret = 0, ipunp = 0, iword = 0;
int status; int status;
int fileID; int fileID;
int param = 0; int param = 0;
...@@ -560,8 +609,8 @@ void cgribexScanTimestep1(int streamID) ...@@ -560,8 +609,8 @@ void cgribexScanTimestep1(int streamID)
} }
} }
gribExDP(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, fsec4, cgribexDecodeHeader(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, fsec4,
ipunp, (int *) gribbuffer, recsize, &iword, "J", &iret); (int *) gribbuffer, recsize, &lmv);
param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255); param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255);
if ( ISEC1_LevelType == 100 ) ISEC1_Level1 *= 100; if ( ISEC1_LevelType == 100 ) ISEC1_Level1 *= 100;
...@@ -644,7 +693,8 @@ void cgribexScanTimestep1(int streamID) ...@@ -644,7 +693,8 @@ void cgribexScanTimestep1(int streamID)
if ( CDI_Debug ) if ( CDI_Debug )
Message(func, "%4d %8d %4d %8d %8d %6d", nrecs, (int)recpos, param, level1, vdate, vtime); Message(func, "%4d %8d %4d %8d %8d %6d", nrecs, (int)recpos, param, level1, vdate, vtime);
cgribexAddRecord(streamID, param, isec1, isec2, fsec2, isec4, recsize, recpos, prec, ztype); cgribexAddRecord(streamID, param, isec1, isec2, fsec2, fsec3,
isec4, recsize, recpos, prec, ztype, lmv);
} }
streamptr->rtsteps = 1; streamptr->rtsteps = 1;
...@@ -717,10 +767,10 @@ int cgribexScanTimestep2(int streamID) ...@@ -717,10 +767,10 @@ int cgribexScanTimestep2(int streamID)
static char func[] = "cgribexScanTimestep2"; static char func[] = "cgribexScanTimestep2";
int *isec0, *isec1, *isec2, *isec3, *isec4; int *isec0, *isec1, *isec2, *isec3, *isec4;
double fsec2[512], fsec3[2], *fsec4 = NULL; double fsec2[512], fsec3[2], *fsec4 = NULL;
int lmv = 0;
off_t recpos = 0; off_t recpos = 0;
unsigned char *gribbuffer = NULL; unsigned char *gribbuffer = NULL;
long buffersize = 0; long buffersize = 0;
int iret = 0, ipunp = 0, iword = 0;
int status; int status;
int fileID; int fileID;
int param = 0; int param = 0;
...@@ -815,8 +865,8 @@ int cgribexScanTimestep2(int streamID) ...@@ -815,8 +865,8 @@ int cgribexScanTimestep2(int streamID)
} }
} }
gribExDP(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, fsec4, cgribexDecodeHeader(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, fsec4,
ipunp, (int *) gribbuffer, recsize, &iword, "J", &iret); (int *) gribbuffer, recsize, &lmv);
param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255); param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255);
if ( ISEC1_LevelType == 100 ) ISEC1_Level1 *= 100; if ( ISEC1_LevelType == 100 ) ISEC1_Level1 *= 100;
...@@ -984,11 +1034,11 @@ int cgribexScanTimestep(int streamID) ...@@ -984,11 +1034,11 @@ int cgribexScanTimestep(int streamID)
static char func[] = "cgribexScanTimestep"; static char func[] = "cgribexScanTimestep";
int *isec0, *isec1, *isec2, *isec3, *isec4; int *isec0, *isec1, *isec2, *isec3, *isec4;
double fsec2[512], fsec3[2], *fsec4 = NULL; double fsec2[512], fsec3[2], *fsec4 = NULL;
int lmv = 0;
long recsize = 0; long recsize = 0;
off_t recpos = 0; off_t recpos = 0;
unsigned char *gribbuffer; unsigned char *gribbuffer;
long buffersize = 0; long buffersize = 0;
int iret = 0, ipunp = 0, iword = 0;
int status; int status;
int fileID; int fileID;
int param = 0; int param = 0;
...@@ -1084,8 +1134,8 @@ int cgribexScanTimestep(int streamID) ...@@ -1084,8 +1134,8 @@ int cgribexScanTimestep(int streamID)
} }
} }
gribExDP(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, fsec4, cgribexDecodeHeader(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, fsec4,
ipunp, (int *) gribbuffer, recsize, &iword, "J", &iret); (int *) gribbuffer, recsize, &lmv);
param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255); param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255);
if ( ISEC1_LevelType == 100 ) ISEC1_Level1 *= 100; if ( ISEC1_LevelType == 100 ) ISEC1_Level1 *= 100;
...@@ -1256,7 +1306,7 @@ int cgribexScanTimestep(int streamID) ...@@ -1256,7 +1306,7 @@ int cgribexScanTimestep(int streamID)
int cgribexDecode(unsigned char *gribbuffer, int gribsize, double *data, int gridsize, int cgribexDecode(unsigned char *gribbuffer, int gribsize, double *data, int gridsize,
int unreduced, int *nmiss, int *zip, double *missval) int unreduced, int *nmiss, int *zip, double missval)
{ {
static char func[] = "cgribexDecode"; static char func[] = "cgribexDecode";
int status = 0; int status = 0;
...@@ -1273,45 +1323,44 @@ int cgribexDecode(unsigned char *gribbuffer, int gribsize, double *data, int gri ...@@ -1273,45 +1323,44 @@ int cgribexDecode(unsigned char *gribbuffer, int gribsize, double *data, int gri
if ( unreduced ) strcpy(hoper, "R"); if ( unreduced ) strcpy(hoper, "R");
else strcpy(hoper, "D"); else strcpy(hoper, "D");
FSEC3_MissVal = cdiDefaultMissval; FSEC3_MissVal = missval;
*missval = cdiDefaultMissval;
if ( (izip = gribGetZip(gribsize, gribbuffer, &unzipsize)) > 0 ) if ( (izip = gribGetZip(gribsize, gribbuffer, &unzipsize)) > 0 )
{ {
*zip = izip; *zip = izip;
if ( izip == 128 ) /* szip */ if ( izip == 128 ) /* szip */
{ {
unsigned char *itmpbuffer = NULL; unsigned char *itmpbuffer = NULL;
size_t itmpbuffersize = 0; size_t itmpbuffersize = 0;
if ( unzipsize < (long) gribsize ) if ( unzipsize < (long) gribsize )
{ {
fprintf(stderr, "Decompressed size smaller than compressed size (in %d; out %ld)!\n", fprintf(stderr, "Decompressed size smaller than compressed size (in %d; out %ld)!\n",
gribsize, unzipsize); gribsize, unzipsize);
return (status); return (status);
} }
if ( itmpbuffersize < (size_t) gribsize ) if ( itmpbuffersize < (size_t) gribsize )
{ {
itmpbuffersize = gribsize; itmpbuffersize = gribsize;
itmpbuffer = (unsigned char *) realloc(itmpbuffer, itmpbuffersize); itmpbuffer = (unsigned char *) realloc(itmpbuffer, itmpbuffersize);
} }
memcpy(itmpbuffer, gribbuffer, itmpbuffersize); memcpy(itmpbuffer, gribbuffer, itmpbuffersize);
unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */ unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
gribsize = gribUnzip(gribbuffer, unzipsize, itmpbuffer, gribsize); gribsize = gribUnzip(gribbuffer, unzipsize, itmpbuffer, gribsize);
if ( gribsize <= 0 ) if ( gribsize <= 0 )
Error(func, "Decompression problem!\n"); Error(func, "Decompression problem!\n");
free(itmpbuffer); free(itmpbuffer);
} }
else else
{ {
Error(func, "Decompression for %d not implemented!\n", izip); Error(func, "Decompression for %d not implemented!\n", izip);
} }
} }
gribExDP(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, data, gribExDP(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, data,
...@@ -1322,36 +1371,20 @@ int cgribexDecode(unsigned char *gribbuffer, int gribsize, double *data, int gri ...@@ -1322,36 +1371,20 @@ int cgribexDecode(unsigned char *gribbuffer, int gribsize, double *data, int gri
else else
*nmiss = 0; *nmiss = 0;
/* 2010-01-13: Oliver Fuhrer */ if ( ISEC1_CenterID == 215 && (isec1[34] != 0 && isec1[34] != 255) )
if (ISEC1_CenterID == 215 ) { {
int i; double undef_pds, undef_eps;
double undef_pds, undef_eps; int i;
if (isec1[34] != 0 && isec1[34] != 255) { MCH_get_undef(isec1, &undef_pds, &undef_eps);
if (isec1[34] & 2) {
if (isec1[34] & 1) { *nmiss = 0;
undef_pds = -0.99*pow(10.0,-isec1[35]);
} else {
undef_pds = +0.99*pow(10.0,-isec1[35]);
}
undef_eps = pow(10.0,-isec1[35]-1);
} else {
if (isec1[34] & 1) {
undef_pds = -0.99*pow(10.0,+isec1[35]);
} else {
undef_pds = +0.99*pow(10.0,+isec1[35]);
}
undef_eps = pow(10.0,isec1[35]-1);
}
for ( i = 0; i < gridsize; i++ ) for ( i = 0; i < gridsize; i++ )
if ( (abs(data[i]-undef_pds) < undef_eps) || IS_EQUAL(data[i],FSEC3_MissVal) ) { if ( (abs(data[i]-undef_pds) < undef_eps) || IS_EQUAL(data[i],FSEC3_MissVal) ) {
data[i] = undef_pds; data[i] = missval;
(*nmiss)++; (*nmiss)++;
} }
FSEC3_MissVal = undef_pds;
*missval = undef_pds;
} }
}
#else #else
Error(func, "CGRIBEX support not compiled in!"); Error(func, "CGRIBEX support not compiled in!");
#endif #endif
......
...@@ -6,7 +6,7 @@ int cgribexScanTimestep2(int streamID); ...@@ -6,7 +6,7 @@ int cgribexScanTimestep2(int streamID);
int cgribexScanTimestep(int streamID); int cgribexScanTimestep(int streamID);
int cgribexDecode(unsigned char *gribbuffer, int gribsize, double *data, int gridsize, int cgribexDecode(unsigned char *gribbuffer, int gribsize, double *data, int gridsize,
int unreduced, int *nmiss, int *zip, double *missval); 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 numavg,
long datasize, const double *data, int nmiss, unsigned char *gribbuffer, size_t gribbuffersize); long datasize, const double *data, int nmiss, unsigned char *gribbuffer, size_t gribbuffersize);
......
...@@ -67,7 +67,7 @@ int grbDefRecord(int streamID) ...@@ -67,7 +67,7 @@ int grbDefRecord(int streamID)
static static
int grbDecode(int filetype, unsigned char *gribbuffer, int gribsize, double *data, int gridsize, int grbDecode(int filetype, unsigned char *gribbuffer, int gribsize, double *data, int gridsize,
int unreduced, int *nmiss, int *zip, double *missval) int unreduced, int *nmiss, int *zip, double missval)
{ {
//static char func[] = "grbDecode"; //static char func[] = "grbDecode";
int status = 0; int status = 0;
...@@ -123,9 +123,10 @@ int grbReadRecord(int streamID, double *data, int *nmiss) ...@@ -123,9 +123,10 @@ int grbReadRecord(int streamID, double *data, int *nmiss)
fileRead(fileID, gribbuffer, (size_t) recsize); fileRead(fileID, gribbuffer, (size_t) recsize);
grbDecode(filetype, gribbuffer, recsize, data, gridsize, streamptr->unreduced, nmiss, &zip, &missval); printf("missval = %g\n", vlistInqVarMissval(vlistID, varID));
missval = vlistInqVarMissval(vlistID, varID);
if ( *nmiss > 0 ) vlistDefVarMissval(vlistID, varID, missval); grbDecode(filetype, gribbuffer, recsize, data, gridsize, streamptr->unreduced, nmiss, &zip, missval);
streamptr->tsteps[tsID].records[recID].zip = zip; streamptr->tsteps[tsID].records[recID].zip = zip;
...@@ -310,10 +311,10 @@ void grbReadVarDP(int streamID, int varID, double *data, int *nmiss) ...@@ -310,10 +311,10 @@ void grbReadVarDP(int streamID, int varID, double *data, int *nmiss)
fileRead(fileID, gribbuffer, recsize); fileRead(fileID, gribbuffer, recsize);
grbDecode(filetype, gribbuffer, recsize, &data[levelID*gridsize], gridsize, missval = vlistInqVarMissval(vlistID, varID);
streamptr->unreduced, &imiss, &zip, &missval);
if ( imiss > 0 ) vlistDefVarMissval(vlistID, varID, missval); grbDecode(filetype, gribbuffer, recsize, &data[levelID*gridsize], gridsize,
streamptr->unreduced, &imiss, &zip, missval);
*nmiss += imiss; *nmiss += imiss;
...@@ -371,9 +372,9 @@ void grbReadVarSliceDP(int streamID, int varID, int levelID, double *data, int * ...@@ -371,9 +372,9 @@ void grbReadVarSliceDP(int streamID, int varID, int levelID, double *data, int *
fileRead(fileID, gribbuffer, recsize); fileRead(fileID, gribbuffer, recsize);
grbDecode(filetype, gribbuffer, recsize, data, gridsize, streamptr->unreduced, nmiss, &zip, &missval); missval = vlistInqVarMissval(vlistID, varID);
if ( *nmiss > 0 ) vlistDefVarMissval(vlistID, varID, missval); grbDecode(filetype, gribbuffer, recsize, data, gridsize, streamptr->unreduced, nmiss, &zip, missval);
fileSetPos(fileID, currentfilepos, SEEK_SET); fileSetPos(fileID, currentfilepos, SEEK_SET);
......
...@@ -1521,7 +1521,7 @@ int gribapiScanTimestep(int streamID) ...@@ -1521,7 +1521,7 @@ int gribapiScanTimestep(int streamID)
int gribapiDecode(unsigned char *gribbuffer, int gribsize, double *data, int gridsize, int gribapiDecode(unsigned char *gribbuffer, int gribsize, double *data, int gridsize,
int unreduced, int *nmiss, int *zip, double *missval) int unreduced, int *nmiss, int *zip, double missval)
{ {
static char func[] = "gribapiDecode"; static char func[] = "gribapiDecode";
int status = 0; int status = 0;
...@@ -1544,8 +1544,7 @@ int gribapiDecode(unsigned char *gribbuffer, int gribsize, double *data, int gri ...@@ -1544,8 +1544,7 @@ int gribapiDecode(unsigned char *gribbuffer, int gribsize, double *data, int gri
recsize = gribsize; recsize = gribsize;
gh = grib_handle_new_from_message(NULL, (void *) gribbuffer, recsize); gh = grib_handle_new_from_message(NULL, (void *) gribbuffer, recsize);
GRIB_CHECK(grib_set_double(gh, "missingValue", GRIB_MISSVAL), 0); GRIB_CHECK(grib_set_double(gh, "missingValue", missval), 0);
*missval = GRIB_MISSVAL;
GRIB_CHECK(grib_get_long(gh, "editionNumber", &editionNumber), 0); GRIB_CHECK(grib_get_long(gh, "editionNumber", &editionNumber), 0);
......
...@@ -6,7 +6,7 @@ int gribapiScanTimestep2(int streamID); ...@@ -6,7 +6,7 @@ int gribapiScanTimestep2(int streamID);
int gribapiScanTimestep(int streamID); int gribapiScanTimestep(int streamID);
int gribapiDecode(unsigned char *gribbuffer, int gribsize, double *data, int gridsize, int gribapiDecode(unsigned char *gribbuffer, int gribsize, double *data, int gridsize,
int unreduced, int *nmiss, int *zip, double *missval); int unreduced, int *nmiss, int *zip, double missval);
size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisID, int date, int time, int numavg, size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisID, int date, int time, int numavg,
long datasize, const double *data, int nmiss, unsigned char *gribbuffer, size_t gribbuffersize, long datasize, const double *data, int nmiss, unsigned char *gribbuffer, size_t gribbuffersize,
......
...@@ -45,6 +45,8 @@ typedef struct ...@@ -45,6 +45,8 @@ typedef struct
int tableID; int tableID;
int ztype; int ztype;
int zlevel; int zlevel;
int lmissval;
double missval;
char *name; char *name;
char *longname; char *longname;
char *units; char *units;
...@@ -76,6 +78,8 @@ void paramInitEntry(int varID, int param) ...@@ -76,6 +78,8 @@ void paramInitEntry(int varID, int param)
vartable[varID].tableID = UNDEFID; vartable[varID].tableID = UNDEFID;
vartable[varID].ztype = COMPRESS_NONE; vartable[varID].ztype = COMPRESS_NONE;
vartable[varID].zlevel = 1; vartable[varID].zlevel = 1;
vartable[varID].lmissval = 0;
vartable[varID].missval = 0;
vartable[varID].name = NULL; vartable[varID].name = NULL;
vartable[varID].longname = NULL; vartable[varID].longname = NULL;
vartable[varID].units = NULL; vartable[varID].units = NULL;
...@@ -522,6 +526,8 @@ void cdiGenVars(int streamID) ...@@ -522,6 +526,8 @@ void cdiGenVars(int streamID)
vlistDefVarTimaccu(vlistID, varID, timaccu); vlistDefVarTimaccu(vlistID, varID, timaccu);
vlistDefVarZtype(vlistID, varID, ztype); vlistDefVarZtype(vlistID, varID, ztype);
if ( vartable[varid].lmissval ) vlistDefVarMissval(vlistID, varID, vartable[varid].missval);
if ( vartable[varid].name ) vlistDefVarName(vlistID, varID, vartable[varid].name); if ( vartable[varid].name ) vlistDefVarName(vlistID, varID, vartable[varid].name);
if ( vartable[varid].longname ) vlistDefVarLongname(vlistID, varID, vartable[varid].longname); if ( vartable[varid].longname ) vlistDefVarLongname(vlistID, varID, vartable[varid].longname);
if ( vartable[varid].units ) vlistDefVarUnits(vlistID, varID, vartable[varid].units); if ( vartable[varid].units ) vlistDefVarUnits(vlistID, varID, vartable[varid].units);
...@@ -813,6 +819,13 @@ int varDefZaxis(int vlistID, int zaxistype, int nlevels, double *levels, int lbo ...@@ -813,6 +819,13 @@ int varDefZaxis(int vlistID, int zaxistype, int nlevels, double *levels, int lbo
} }
void varDefMissval(int varID, double missval)
{
vartable[varID].lmissval = 1;
vartable[varID].missval = missval;
}
void varDefZtype(int varID, int ztype) void varDefZtype(int varID, int ztype)
{ {
vartable[varID].ztype = ztype; vartable[varID].ztype = ztype;
......