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

added support for netcdf attribute valid_range

parent e9ae4e3f
2011-10-25 Uwe Schulzweida <Uwe.Schulzweida@zmaw.de>
* added support for netcdf attribute valid_range [request: Etienne Tourigny]
2011-10-17 Uwe Schulzweida <Uwe.Schulzweida@zmaw.de>
* Version 1.5.3 released
* using CGRIBEX library version 1.5.1
2011-10-11 Uwe Schulzweida <Uwe.Schulzweida@zmaw.de>
......@@ -24,10 +29,6 @@
* correct netCDF dimension order of unstructured grids (bug fix) [report: Ralf Mueller]
2011-08-25 Uwe Schulzweida <Uwe.Schulzweida@zmaw.de>
* using CGRIBEX library version 1.5.1
2011-08-22 Uwe Schulzweida <Uwe.Schulzweida@zmaw.de>
* Version 1.5.2 released
......
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.68 for cdi 1.5.3.
# Generated by GNU Autoconf 2.68 for cdi 1.5.4.
#
# Report bugs to <http://code.zmaw.de/projects/cdi>.
#
......@@ -570,8 +570,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='cdi'
PACKAGE_TARNAME='cdi'
PACKAGE_VERSION='1.5.3'
PACKAGE_STRING='cdi 1.5.3'
PACKAGE_VERSION='1.5.4'
PACKAGE_STRING='cdi 1.5.4'
PACKAGE_BUGREPORT='http://code.zmaw.de/projects/cdi'
PACKAGE_URL=''
 
......@@ -1391,7 +1391,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures cdi 1.5.3 to adapt to many kinds of systems.
\`configure' configures cdi 1.5.4 to adapt to many kinds of systems.
 
Usage: $0 [OPTION]... [VAR=VALUE]...
 
......@@ -1461,7 +1461,7 @@ fi
 
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of cdi 1.5.3:";;
short | recursive ) echo "Configuration of cdi 1.5.4:";;
esac
cat <<\_ACEOF
 
......@@ -1611,7 +1611,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
cdi configure 1.5.3
cdi configure 1.5.4
generated by GNU Autoconf 2.68
 
Copyright (C) 2010 Free Software Foundation, Inc.
......@@ -2326,7 +2326,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
 
It was created by cdi $as_me 1.5.3, which was
It was created by cdi $as_me 1.5.4, which was
generated by GNU Autoconf 2.68. Invocation command line was
 
$ $0 $@
......@@ -3258,7 +3258,7 @@ fi
 
# Define the identity of the package.
PACKAGE='cdi'
VERSION='1.5.3'
VERSION='1.5.4'
 
 
cat >>confdefs.h <<_ACEOF
......@@ -27015,7 +27015,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by cdi $as_me 1.5.3, which was
This file was extended by cdi $as_me 1.5.4, which was
generated by GNU Autoconf 2.68. Invocation command line was
 
CONFIG_FILES = $CONFIG_FILES
......@@ -27081,7 +27081,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
cdi config.status 1.5.3
cdi config.status 1.5.4
configured by $0, generated by GNU Autoconf 2.68,
with options \\"\$ac_cs_config\\"
 
......
# Process this file with autoconf to produce a configure script.
AC_INIT([cdi], [1.5.3], [http://code.zmaw.de/projects/cdi])
AC_INIT([cdi], [1.5.4], [http://code.zmaw.de/projects/cdi])
echo "configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}"
......
......@@ -88,11 +88,14 @@ typedef struct {
int natts;
int *atts;
int deflate;
int lunsigned;
int lvalidrange;
size_t vlen;
double *vdata;
double missval;
double addoffset;
double scalefactor;
double validrange[2];
char name[MAXNAMELEN];
char longname[MAXNAMELEN];
char stdname[MAXNAMELEN];
......@@ -160,7 +163,7 @@ int isTimeUnits(const char *timeunits)
if ( *ptu )
{
while ( isspace(*ptu) ) ptu++;
if ( memcmp(ptu, "as", 2) == 0 )
timetype = TAXIS_ABSOLUTE;
else if ( memcmp(ptu, "since", 5) == 0 )
......@@ -275,7 +278,7 @@ int splitBasetime(const char *timeunits, taxis_t *taxis)
(*taxis).rtime = rtime;
if ( CDI_Debug )
Message("rdate = %d rtime = %d", rdate, rtime);
Message("rdate = %d rtime = %d", rdate, rtime);
}
}
}
......@@ -366,11 +369,14 @@ void cdfGetAttText(int fileID, int ncvarid, char *attname, int attlen, char *att
#if defined (HAVE_LIBNETCDF)
static
int cdfInqDatatype(int xtype)
int cdfInqDatatype(int xtype, int lunsigned)
{
int datatype = -1;
if ( xtype == NC_BYTE && lunsigned ) xtype = NC_UBYTE;
if ( xtype == NC_BYTE ) datatype = DATATYPE_INT8;
else if ( xtype == NC_UBYTE ) datatype = DATATYPE_UINT8;
/* else if ( xtype == NC_CHAR ) datatype = DATATYPE_UINT8; */
else if ( xtype == NC_SHORT ) datatype = DATATYPE_INT16;
else if ( xtype == NC_INT ) datatype = DATATYPE_INT32;
......@@ -378,7 +384,6 @@ int cdfInqDatatype(int xtype)
else if ( xtype == NC_DOUBLE ) datatype = DATATYPE_FLT64;
#if defined (HAVE_NETCDF4)
else if ( xtype == NC_LONG ) datatype = DATATYPE_INT32;
else if ( xtype == NC_UBYTE ) datatype = DATATYPE_UINT8;
else if ( xtype == NC_USHORT ) datatype = DATATYPE_UINT16;
else if ( xtype == NC_UINT ) datatype = DATATYPE_UINT32;
else if ( xtype == NC_INT64 ) datatype = DATATYPE_FLT64;
......@@ -408,7 +413,7 @@ int cdfDefDatatype(int datatype, int filetype)
else if ( datatype == DATATYPE_UINT16 ) xtype = NC_USHORT;
else if ( datatype == DATATYPE_UINT32 ) xtype = NC_UINT;
#else
else if ( datatype == DATATYPE_UINT8 ) xtype = NC_SHORT;
else if ( datatype == DATATYPE_UINT8 ) xtype = NC_BYTE;
else if ( datatype == DATATYPE_UINT16 ) xtype = NC_INT;
else if ( datatype == DATATYPE_UINT32 ) xtype = NC_INT;
#endif
......@@ -420,7 +425,7 @@ int cdfDefDatatype(int datatype, int filetype)
if ( datatype == DATATYPE_INT8 ) xtype = NC_BYTE;
else if ( datatype == DATATYPE_INT16 ) xtype = NC_SHORT;
else if ( datatype == DATATYPE_INT32 ) xtype = NC_INT;
else if ( datatype == DATATYPE_UINT8 ) xtype = NC_SHORT;
else if ( datatype == DATATYPE_UINT8 ) xtype = NC_BYTE;
else if ( datatype == DATATYPE_UINT16 ) xtype = NC_INT;
else if ( datatype == DATATYPE_UINT32 ) xtype = NC_INT;
else if ( datatype == DATATYPE_FLT64 ) xtype = NC_DOUBLE;
......@@ -515,7 +520,7 @@ int cdfCopyRecord(int streamID2, int streamID1)
gridID = vlistInqVarGrid(vlistID1, ivarID);
datasize = gridInqSize(gridID);
datasize = gridInqSize(gridID);
/* bug fix for constant netCDF fields */
if ( datasize < 1048576 ) datasize = 1048576;
......@@ -685,7 +690,7 @@ void cdfDefVarSzip(int ncid, int ncvarid)
{
lwarn = FALSE;
Warning("netCDF4/Szip compression not compiled in!");
}
}
}
else
Error("nc_def_var_szip failed, status = %d", retval);
......@@ -726,10 +731,10 @@ void cdfDefVarMissval(int streamID, int varID, int dtype, int lcheck)
xtype = cdfDefDatatype(dtype, streamptr->filetype);
cdf_put_att_double(fileID, ncvarid, "_FillValue", (nc_type) xtype, 1L, &missval);
cdf_put_att_double(fileID, ncvarid, "_FillValue", (nc_type) xtype, 1, &missval);
if ( cdiNcMissingValue == 1 )
cdf_put_att_double(fileID, ncvarid, "missing_value", (nc_type) xtype, 1L, &missval);
cdf_put_att_double(fileID, ncvarid, "missing_value", (nc_type) xtype, 1, &missval);
if ( lcheck && streamptr->ncmode == 2 ) cdf_enddef(fileID);
......@@ -1319,10 +1324,10 @@ int checkGridName(int type, char *axisname, int fileID, int vlistID, int gridID,
}
if ( checkname ) iz++;
if ( iz > 99 ) break;
}
if ( iz ) sprintf(&axisname[strlen(axisname)], "_%d", iz+1);
return (iz);
......@@ -1442,7 +1447,7 @@ void cdfDefXaxis(int streamID, int gridID)
if ( gridIsRotated(gridID) )
{
double north_pole = gridInqXpole(gridID);
cdf_put_att_double(fileID, ncvarid, "north_pole", NC_DOUBLE, 1L, &north_pole);
cdf_put_att_double(fileID, ncvarid, "north_pole", NC_DOUBLE, 1, &north_pole);
}
*/
}
......@@ -1571,7 +1576,7 @@ void cdfDefYaxis(int streamID, int gridID)
if ( gridIsRotated(gridID) )
{
double north_pole = gridInqYpole(gridID);
cdf_put_att_double(fileID, ncvarid, "north_pole", NC_DOUBLE, 1L, &north_pole);
cdf_put_att_double(fileID, ncvarid, "north_pole", NC_DOUBLE, 1, &north_pole);
}
*/
}
......@@ -2006,7 +2011,7 @@ void cdfDefUnstructured(int streamID, int gridID)
nvertex = gridInqNvertex(gridID);
if ( nvertex > 0 ) cdf_def_dim(fileID, vertname, nvertex, &nvdimID);
if ( gridInqXvalsPtr(gridID) )
{
cdf_def_var(fileID, xaxisname, (nc_type) xtype, 1, &dimID, &ncxvarid);
......@@ -2102,7 +2107,7 @@ void cdfDefVCT(int streamID, int zaxisID)
int ilev = zaxisInqVctSize(zaxisID)/2;
int mlev = ilev - 1;
size_t start;
size_t count = 1;
size_t count = 1;
int ncdimid, ncdimid2;
int hyaiid, hybiid, hyamid, hybmid;
double mval;
......@@ -2456,10 +2461,10 @@ void cdfDefPole(int streamID, int gridID)
if ( ncerr == NC_NOERR )
{
cdf_put_att_text(fileID, ncvarid, "grid_mapping_name", strlen(mapname), mapname);
cdf_put_att_double(fileID, ncvarid, "grid_north_pole_latitude", NC_DOUBLE, 1L, &ypole);
cdf_put_att_double(fileID, ncvarid, "grid_north_pole_longitude", NC_DOUBLE, 1L, &xpole);
cdf_put_att_double(fileID, ncvarid, "grid_north_pole_latitude", NC_DOUBLE, 1, &ypole);
cdf_put_att_double(fileID, ncvarid, "grid_north_pole_longitude", NC_DOUBLE, 1, &xpole);
if ( angle > 0 )
cdf_put_att_double(fileID, ncvarid, "north_pole_grid_longitude", NC_DOUBLE, 1L, &angle);
cdf_put_att_double(fileID, ncvarid, "north_pole_grid_longitude", NC_DOUBLE, 1, &angle);
}
cdf_enddef(fileID);
......@@ -2488,8 +2493,8 @@ void cdfDefMapping(int streamID, int gridID)
{
cdf_put_att_text(fileID, ncvarid, "grid_mapping_name", strlen(mapname), mapname);
/*
cdf_put_att_double(fileID, ncvarid, "grid_north_pole_latitude", NC_DOUBLE, 1L, &ypole);
cdf_put_att_double(fileID, ncvarid, "grid_north_pole_longitude", NC_DOUBLE, 1L, &xpole);
cdf_put_att_double(fileID, ncvarid, "grid_north_pole_latitude", NC_DOUBLE, 1, &ypole);
cdf_put_att_double(fileID, ncvarid, "grid_north_pole_longitude", NC_DOUBLE, 1, &xpole);
*/
}
......@@ -2512,9 +2517,9 @@ void cdfDefMapping(int streamID, int gridID)
gridInqLaea(gridID, &a, &lon_0, &lat_0);
cdf_put_att_text(fileID, ncvarid, "grid_mapping_name", strlen(mapname), mapname);
cdf_put_att_double(fileID, ncvarid, "earth_radius", NC_DOUBLE, 1L, &a);
cdf_put_att_double(fileID, ncvarid, "longitude_of_projection_origin", NC_DOUBLE, 1L, &lon_0);
cdf_put_att_double(fileID, ncvarid, "latitude_of_projection_origin", NC_DOUBLE, 1L, &lat_0);
cdf_put_att_double(fileID, ncvarid, "earth_radius", NC_DOUBLE, 1, &a);
cdf_put_att_double(fileID, ncvarid, "longitude_of_projection_origin", NC_DOUBLE, 1, &lon_0);
cdf_put_att_double(fileID, ncvarid, "latitude_of_projection_origin", NC_DOUBLE, 1, &lat_0);
}
cdf_enddef(fileID);
......@@ -2537,11 +2542,11 @@ void cdfDefMapping(int streamID, int gridID)
cdf_put_att_text(fileID, ncvarid, "grid_mapping_name", strlen(mapname), mapname);
if ( radius > 0 )
cdf_put_att_double(fileID, ncvarid, "earth_radius", NC_DOUBLE, 1L, &radius);
cdf_put_att_double(fileID, ncvarid, "longitude_of_central_meridian", NC_DOUBLE, 1L, &lon_0);
cdf_put_att_double(fileID, ncvarid, "latitude_of_projection_origin", NC_DOUBLE, 1L, &lat_0);
cdf_put_att_double(fileID, ncvarid, "earth_radius", NC_DOUBLE, 1, &radius);
cdf_put_att_double(fileID, ncvarid, "longitude_of_central_meridian", NC_DOUBLE, 1, &lon_0);
cdf_put_att_double(fileID, ncvarid, "latitude_of_projection_origin", NC_DOUBLE, 1, &lat_0);
if ( IS_EQUAL(lat_1, lat_2) )
cdf_put_att_double(fileID, ncvarid, "standard_parallel", NC_DOUBLE, 1L, &lat_1);
cdf_put_att_double(fileID, ncvarid, "standard_parallel", NC_DOUBLE, 1, &lat_1);
else
{
double lat_1_2[2];
......@@ -2667,7 +2672,7 @@ int cdfDefVar(int streamID, int varID)
int ndims = 0;
int len;
int timeID;
int xtype;
int xtype, dtype;
int gridtype, gridsize;
int gridindex, zaxisindex;
int tablenum;
......@@ -2859,7 +2864,8 @@ int cdfDefVar(int streamID, int varID)
/* if ( streamptr->ncmode == 2 ) cdf_redef(fileID); */
xtype = cdfDefDatatype(vlistInqVarDatatype(vlistID, varID), streamptr->filetype);
dtype = vlistInqVarDatatype(vlistID, varID);
xtype = cdfDefDatatype(dtype, streamptr->filetype);
cdf_def_var(fileID, name, (nc_type) xtype, ndims, dims, &ncvarid);
......@@ -2930,7 +2936,7 @@ int cdfDefVar(int streamID, int varID)
cdf_put_att_text(fileID, ncvarid, "units", strlen(units), units);
if ( code > 0 && pdis == 255 )
cdf_put_att_int(fileID, ncvarid, "code", NC_INT, 1L, &code);
cdf_put_att_int(fileID, ncvarid, "code", NC_INT, 1, &code);
if ( pdis != 255 )
{
......@@ -2943,7 +2949,7 @@ int cdfDefVar(int streamID, int varID)
{
tablenum = tableInqNum(tableID);
if ( tablenum > 0 )
cdf_put_att_int(fileID, ncvarid, "table", NC_INT, 1L, &tablenum);
cdf_put_att_int(fileID, ncvarid, "table", NC_INT, 1, &tablenum);
}
if ( gridtype != GRID_GENERIC && gridtype != GRID_LONLAT &&
......@@ -3018,7 +3024,7 @@ int cdfDefVar(int streamID, int varID)
axis[iax++] = '-';
axis[iax++] = '-';
cdf_put_att_text(fileID, ncvarid, "axis", iax, axis);
cdf_put_att_int(fileID, ncvarid, "truncation", NC_INT, 1L, &gridTruncation);
cdf_put_att_int(fileID, ncvarid, "truncation", NC_INT, 1, &gridTruncation);
}
/* if ( xtype == NC_BYTE || xtype == NC_SHORT || xtype == NC_INT ) */
......@@ -3042,11 +3048,18 @@ int cdfDefVar(int streamID, int varID)
if ( xtype == (int) NC_FLOAT ) astype = NC_FLOAT;
cdf_put_att_double(fileID, ncvarid, "add_offset", (nc_type) astype, 1L, &addoffset);
cdf_put_att_double(fileID, ncvarid, "scale_factor", (nc_type) astype, 1L, &scalefactor);
cdf_put_att_double(fileID, ncvarid, "add_offset", (nc_type) astype, 1, &addoffset);
cdf_put_att_double(fileID, ncvarid, "scale_factor", (nc_type) astype, 1, &scalefactor);
}
}
if ( dtype == DATATYPE_UINT8 && xtype == NC_BYTE )
{
int validrange[2] = {0, 255};
cdf_put_att_int(fileID, ncvarid, "valid_range", NC_SHORT, 2, validrange);
cdf_put_att_text(fileID, ncvarid, "_Unsigned", 4, "true");
}
streamptr->vars[varID].ncvarid = ncvarid;
if ( vlistInqVarMissvalUsed(vlistID, varID) )
......@@ -3391,6 +3404,8 @@ int cdfReadVarSliceDP(int streamID, int varID, int levelID, double *data, int *n
int dimorder[3];
int ixyz;
int swapxy = FALSE;
int lvalidrange;
double validrange[2];
double missval;
int laddoffset, lscalefactor;
double addoffset, scalefactor;
......@@ -3501,10 +3516,28 @@ int cdfReadVarSliceDP(int streamID, int varID, int levelID, double *data, int *n
free(tdata);
}
if ( vlistInqVarDatatype(vlistID, varID) == DATATYPE_UINT8 )
{
nc_type xtype;
cdf_inq_vartype(fileID, ncvarid, &xtype);
if ( xtype == NC_BYTE )
{
for ( i = 0; i < gridsize; i++ )
if ( data[i] < 0 ) data[i] += 255;
}
}
*nmiss = 0;
if ( vlistInqVarMissvalUsed(vlistID, varID) == TRUE )
if ( vlistInqVarMissvalUsed(vlistID, varID) == TRUE )
{
missval = vlistInqVarMissval(vlistID, varID);
lvalidrange = vlistInqVarValidrange(vlistID, varID, validrange);
// printf("readvarslice: validrange %d %g %g\n", lvalidrange, validrange[0], validrange[1]);
if ( lvalidrange )
for ( i = 0; i < gridsize; i++ )
if ( data[i] < validrange[0] || data[i] > validrange[1] ) data[i] = missval;
// printf("XXX %31.0f %31.0f %31.0f %31.0f\n", missval, (float)data[0]);
for ( i = 0; i < gridsize; i++ )
if ( DBL_IS_EQUAL(data[i], missval) ) *nmiss += 1;
......@@ -3557,6 +3590,7 @@ int cdfWriteVarSliceDP(int streamID, int varID, int levelID, const double *data,
size_t size, xsize, ysize;
size_t start[4];
size_t count[4];
int nvals;
int ndims = 0;
int idim;
int timeID;
......@@ -3658,9 +3692,10 @@ int cdfWriteVarSliceDP(int streamID, int varID, int levelID, const double *data,
if ( nmiss > 0 ) cdfDefVarMissval(streamID, varID, dtype, 1);
nvals = gridInqSize(gridID);
/* if ( dtype == DATATYPE_INT8 || dtype == DATATYPE_INT16 || dtype == DATATYPE_INT32 ) */
{
int nvals;
int laddoffset, lscalefactor;
double addoffset, scalefactor;
double missval;
......@@ -3672,8 +3707,6 @@ int cdfWriteVarSliceDP(int streamID, int varID, int levelID, const double *data,
missval = vlistInqVarMissval(vlistID, varID);
nvals = gridInqSize(gridID);
if ( laddoffset || lscalefactor )
{
mdata = (double *) malloc(nvals*sizeof(double));
......@@ -3712,6 +3745,17 @@ int cdfWriteVarSliceDP(int streamID, int varID, int levelID, const double *data,
mdata = (double *) malloc(nvals*sizeof(double));
for ( i = 0; i < nvals; i++ ) mdata[i] = NINT(data[i]);
}
if ( dtype == DATATYPE_UINT8 )
{
nc_type xtype;
cdf_inq_vartype(fileID, ncvarid, &xtype);
if ( xtype == NC_BYTE )
{
for ( i = 0; i < nvals; ++i )
if ( mdata[i] > 126 ) mdata[i] -= 255;
}
}
}
if ( CDF_Debug )
......@@ -3736,8 +3780,6 @@ int cdfWriteVarSliceDP(int streamID, int varID, int levelID, const double *data,
if ( swapxy )
{
int nvals;
nvals = gridInqSize(gridID);
sdata = (double *) malloc(nvals*sizeof(double));
for ( int j = 0; j < (int)ysize; ++j )
for ( int i = 0; i < (int)xsize; ++i )
......@@ -3953,7 +3995,7 @@ void init_ncvars(long nvars, ncvar_t *ncvars)
long ncvarid;
for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
{
{
ncvars[ncvarid].ignore = FALSE;
ncvars[ncvarid].isvar = UNDEFID;
ncvars[ncvarid].islon = FALSE;
......@@ -4002,6 +4044,8 @@ void init_ncvars(long nvars, ncvar_t *ncvars)
ncvars[ncvarid].natts = 0;
ncvars[ncvarid].atts = NULL;
ncvars[ncvarid].deflate = 0;
ncvars[ncvarid].lunsigned = 0;
ncvars[ncvarid].lvalidrange = 0;
}
}
......@@ -4617,6 +4661,30 @@ void scanVarAttributes(int fileID, int nvars, ncvar_t *ncvars, ncdim_t *ncdims,
ncvars[ncvarid].defmiss = TRUE;
/* cdfSetVar(ncvars, ncvarid, TRUE); */
}
else if ( strcmp(attname, "valid_range") == 0 && attlen == 2 )
{
cdfGetAttDouble(fileID, ncvarid, attname, 2, ncvars[ncvarid].validrange);
ncvars[ncvarid].lvalidrange = TRUE;
if ( ((int)ncvars[ncvarid].validrange[0]) == 0 && ((int)ncvars[ncvarid].validrange[1]) == 255 )
ncvars[ncvarid].lunsigned = TRUE;
/* cdfSetVar(ncvars, ncvarid, TRUE); */
}
else if ( strcmp(attname, "_Unsigned") == 0 && atttype == NC_CHAR )
{
cdfGetAttText(fileID, ncvarid, attname, attstringlen-1, attstring);
strtolower(attstring);
if ( memcmp(attstring, "true", 4) == 0 )
{
ncvars[ncvarid].lunsigned = TRUE;
/*
ncvars[ncvarid].lvalidrange = TRUE;
ncvars[ncvarid].validrange[0] = 0;
ncvars[ncvarid].validrange[1] = 255;
*/
}
/* cdfSetVar(ncvars, ncvarid, TRUE); */
}
else if ( strcmp(attname, "cdi") == 0 && atttype == NC_CHAR )
{
cdfGetAttText(fileID, ncvarid, attname, attstringlen-1, attstring);
......@@ -5799,12 +5867,16 @@ void define_all_vars(int fileID, int streamID, int vlistID, int instID, int mode
if ( ncvars[ncvarid].longname[0] ) vlistDefVarLongname(vlistID, varID, ncvars[ncvarid].longname);
if ( ncvars[ncvarid].stdname[0] ) vlistDefVarStdname(vlistID, varID, ncvars[ncvarid].stdname);
if ( ncvars[ncvarid].units[0] ) vlistDefVarUnits(vlistID, varID, ncvars[ncvarid].units);
if ( ncvars[ncvarid].lvalidrange )
vlistDefVarValidrange(vlistID, varID, ncvars[ncvarid].validrange);
if ( IS_NOT_EQUAL(ncvars[ncvarid].addoffset, 0) )
vlistDefVarAddoffset(vlistID, varID, ncvars[ncvarid].addoffset);
if ( IS_NOT_EQUAL(ncvars[ncvarid].scalefactor, 1) )
vlistDefVarScalefactor(vlistID, varID, ncvars[ncvarid].scalefactor);
vlistDefVarDatatype(vlistID, varID, cdfInqDatatype(ncvars[ncvarid].xtype));
vlistDefVarDatatype(vlistID, varID, cdfInqDatatype(ncvars[ncvarid].xtype, ncvars[ncvarid].lunsigned));
vlistDefVarInstitut(vlistID, varID, instID);
vlistDefVarModel(vlistID, varID, modelID);
......@@ -6325,7 +6397,7 @@ int cdfInqContents(int streamID)
continue;
}
if ( cdfInqDatatype(ncvars[ncvarid].xtype) == -1 )
if ( cdfInqDatatype(ncvars[ncvarid].xtype, ncvars[ncvarid].lunsigned) == -1 )
{
ncvars[ncvarid].isvar = 0;
Warning("Variable %s has an unsupported data type, skipped!", ncvars[ncvarid].name);
......
......@@ -63,6 +63,7 @@ typedef struct
int timaccu;
int xyz;
int missvalused; /* TRUE if missval is defined */
int lvalidrange;
char *name;
char *longname;
char *stdname;
......@@ -70,6 +71,7 @@ typedef struct
double missval;
double scalefactor;
double addoffset;
double validrange[2];
levinfo_t *levinfo;
int comptype; // compression type
int complevel; // compression level
......@@ -113,6 +115,12 @@ int vlistHasTime(int vlistID);
int vlistDelAtts(int vlistID, int varID);
int vlistCopyVarAtts(int vlistID1, int varID_1, int vlistID2, int varID_2);
/* vlistDefVarValidrange: Define the valid range of a Variable */
void vlistDefVarValidrange(int vlistID, int varID, const double *validrange);
/* vlistInqVarValidrange: Get the valid range of a Variable */
int vlistInqVarValidrange(int vlistID, int varID, double *validrange);
#endif /* _VLIST_H */
/*
* Local Variables:
......
......@@ -46,6 +46,7 @@ void vlistvarInitEntry(int vlistID, int varID)
vlistptr->vars[varID].complevel = 1;
vlistptr->vars[varID].atts.nalloc = MAX_ATTRIBUTES;
vlistptr->vars[varID].atts.nelems = 0;
vlistptr->vars[varID].lvalidrange = 0;
}
static
......@@ -1076,8 +1077,22 @@ double vlistInqVarMissval(int vlistID, int varID)
return (vlistptr->vars[varID].missval);
}
/*
@Function vlistDefVarMissval
@Title Define the missing value of a Variable
double vlistInqVarScalefactor(int vlistID, int varID)
@Prototype void vlistDefVarMissval(int vlistID, int varID, double missval)
@Parameter
@Item vlistID Variable list ID, from a previous call to @fref{vlistCreate}.
@Item varID Variable identifier.
@Item missval Missing value.
@Description
The function @func{vlistDefVarMissval} defines the missing value of a variable.
@EndFunction
*/
void vlistDefVarMissval(int vlistID, int varID, double missval)
{
vlist_t *vlistptr;
......@@ -1085,11 +1100,12 @@ double vlistInqVarScalefactor(int vlistID, int varID)
vlistCheckVarID(__func__, vlistID, varID);
return (vlistptr->vars[varID].scalefactor);
vlistptr->vars[varID].missval = missval;
vlistptr->vars[varID].missvalused = TRUE;
}
double vlistInqVarAddoffset(int vlistID, int varID)
int vlistInqVarValidrange(int vlistID, int varID, double *validrange)
{
vlist_t *vlistptr;
......@@ -1097,25 +1113,31 @@ double vlistInqVarAddoffset(int vlistID, int varID)
vlistCheckVarID(__func__, vlistID, varID);
return (vlistptr->vars[varID].addoffset);
if ( validrange != NULL && vlistptr->vars[varID].lvalidrange )
{
validrange[0] = vlistptr->vars[varID].validrange[0];
validrange[1] = vlistptr->vars[varID].validrange<