Commit 0d6f6894 authored by Uwe Schulzweida's avatar Uwe Schulzweida
Browse files

NetCDF dimension IDs do not have to start at 0 and their increment can not be...

NetCDF dimension IDs do not have to start at 0 and their increment can not be equal to 1! (bug fix).
parent 732fcc10
...@@ -3,6 +3,10 @@ ...@@ -3,6 +3,10 @@
* using CGRIBEX library version 1.9.1 * using CGRIBEX library version 1.9.1
* Version 1.9.5 released * Version 1.9.5 released
2018-06-23 Uwe Schulzweida
* NetCDF dimension IDs do not have to start at 0 and their increment can not be equal to 1! (bug fix)
2018-05-30 Uwe Schulzweida 2018-05-30 Uwe Schulzweida
* Added error code CDI_ETMOF (Too many open files) * Added error code CDI_ETMOF (Too many open files)
......
#if defined (HAVE_CONFIG_H) #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
...@@ -28,12 +28,14 @@ ...@@ -28,12 +28,14 @@
#define POSITIVE_DOWN 2 #define POSITIVE_DOWN 2
typedef struct { typedef struct {
int dimid;
int ncvarid; int ncvarid;
int dimtype; int dimtype;
size_t len; size_t len;
char name[CDI_MAX_NAME]; char name[CDI_MAX_NAME];
} }
ncdim_t; ncdim_t;
#define MAX_COORDVARS 4 #define MAX_COORDVARS 4
#define MAX_AUXVARS 4 #define MAX_AUXVARS 4
...@@ -275,7 +277,7 @@ static ...@@ -275,7 +277,7 @@ static
bool xtypeIsText(int xtype) bool xtypeIsText(int xtype)
{ {
bool isText = ( xtype == NC_CHAR ) bool isText = ( xtype == NC_CHAR )
#if defined (HAVE_NETCDF4) #ifdef HAVE_NETCDF4
|| ( xtype == NC_STRING ) || ( xtype == NC_STRING )
#endif #endif
; ;
...@@ -295,7 +297,7 @@ bool xtypeIsInt(nc_type xtype) ...@@ -295,7 +297,7 @@ bool xtypeIsInt(nc_type xtype)
{ {
bool isInt = xtype == NC_SHORT || xtype == NC_INT bool isInt = xtype == NC_SHORT || xtype == NC_INT
|| xtype == NC_BYTE || xtype == NC_BYTE
#if defined (HAVE_NETCDF4) #ifdef HAVE_NETCDF4
|| xtype == NC_USHORT || xtype == NC_UINT || xtype == NC_USHORT || xtype == NC_UINT
|| xtype == NC_UBYTE || xtype == NC_UBYTE
#endif #endif
...@@ -309,7 +311,7 @@ int cdfInqDatatype(int xtype, bool lunsigned) ...@@ -309,7 +311,7 @@ int cdfInqDatatype(int xtype, bool lunsigned)
{ {
int datatype = -1; int datatype = -1;
#if defined (HAVE_NETCDF4) #ifdef HAVE_NETCDF4
if ( xtype == NC_BYTE && lunsigned ) xtype = NC_UBYTE; if ( xtype == NC_BYTE && lunsigned ) xtype = NC_UBYTE;
#endif #endif
...@@ -319,7 +321,7 @@ int cdfInqDatatype(int xtype, bool lunsigned) ...@@ -319,7 +321,7 @@ int cdfInqDatatype(int xtype, bool lunsigned)
else if ( xtype == NC_INT ) datatype = CDI_DATATYPE_INT32; else if ( xtype == NC_INT ) datatype = CDI_DATATYPE_INT32;
else if ( xtype == NC_FLOAT ) datatype = CDI_DATATYPE_FLT32; else if ( xtype == NC_FLOAT ) datatype = CDI_DATATYPE_FLT32;
else if ( xtype == NC_DOUBLE ) datatype = CDI_DATATYPE_FLT64; else if ( xtype == NC_DOUBLE ) datatype = CDI_DATATYPE_FLT64;
#if defined (HAVE_NETCDF4) #ifdef HAVE_NETCDF4
else if ( xtype == NC_UBYTE ) datatype = CDI_DATATYPE_UINT8; else if ( xtype == NC_UBYTE ) datatype = CDI_DATATYPE_UINT8;
else if ( xtype == NC_LONG ) datatype = CDI_DATATYPE_INT32; else if ( xtype == NC_LONG ) datatype = CDI_DATATYPE_INT32;
else if ( xtype == NC_USHORT ) datatype = CDI_DATATYPE_UINT16; else if ( xtype == NC_USHORT ) datatype = CDI_DATATYPE_UINT16;
...@@ -387,7 +389,7 @@ bool cdfCheckAttText(int fileID, int ncvarid, const char *attname) ...@@ -387,7 +389,7 @@ bool cdfCheckAttText(int fileID, int ncvarid, const char *attname)
if ( status_nc == NC_NOERR if ( status_nc == NC_NOERR
&& (atttype == NC_CHAR && (atttype == NC_CHAR
#if defined (HAVE_NETCDF4) #ifdef HAVE_NETCDF4
|| atttype == NC_STRING || atttype == NC_STRING
#endif #endif
) ) ) )
...@@ -424,7 +426,7 @@ void cdfGetAttText(int fileID, int ncvarid, const char *attname, size_t attlen, ...@@ -424,7 +426,7 @@ void cdfGetAttText(int fileID, int ncvarid, const char *attname, size_t attlen,
atttext[0] = 0; atttext[0] = 0;
} }
} }
#if defined (HAVE_NETCDF4) #ifdef HAVE_NETCDF4
else if ( atttype == NC_STRING ) else if ( atttype == NC_STRING )
{ {
if ( nc_attlen == 1 ) if ( nc_attlen == 1 )
...@@ -574,13 +576,14 @@ void cdfCreateRecords(stream_t *streamptr, int tsID) ...@@ -574,13 +576,14 @@ void cdfCreateRecords(stream_t *streamptr, int tsID)
} }
static static
int cdf_time_dimid(int fileID, int ndims, int nvars) int cdf_time_dimid(int fileID, int ndims, int nvars, ncdim_t *ncdims)
{ {
char dimname[80]; char dimname[CDI_MAX_NAME];
for ( int dimid = 0; dimid < ndims; ++dimid ) for ( int dimid = 0; dimid < ndims; ++dimid )
{ {
dimname[0] = 0; dimname[0] = 0;
cdf_inq_dimname(fileID, dimid, dimname); cdf_inq_dimname(fileID, ncdims[dimid].dimid, dimname);
if ( str_is_equal(dimname, "time") || str_is_equal(dimname, "Time") ) return dimid; if ( str_is_equal(dimname, "time") || str_is_equal(dimname, "Time") ) return dimid;
} }
...@@ -589,6 +592,14 @@ int cdf_time_dimid(int fileID, int ndims, int nvars) ...@@ -589,6 +592,14 @@ int cdf_time_dimid(int fileID, int ndims, int nvars)
nc_type xtype; nc_type xtype;
int nvdims, nvatts, dimids[9]; int nvdims, nvatts, dimids[9];
cdf_inq_var(fileID, varid, NULL, &xtype, &nvdims, dimids, &nvatts); cdf_inq_var(fileID, varid, NULL, &xtype, &nvdims, dimids, &nvatts);
for ( int i = 0; i < nvdims; ++i )
for ( int dimid = 0; dimid < ndims; ++dimid )
if ( ncdims[dimid].dimid == dimids[i] )
{
dimids[i] = dimid;
break;
}
if ( nvdims == 1 ) if ( nvdims == 1 )
{ {
char sbuf[CDI_MAX_NAME]; char sbuf[CDI_MAX_NAME];
...@@ -615,6 +626,7 @@ void init_ncdims(long ndims, ncdim_t *ncdims) ...@@ -615,6 +626,7 @@ void init_ncdims(long ndims, ncdim_t *ncdims)
{ {
for ( long ncdimid = 0; ncdimid < ndims; ncdimid++ ) for ( long ncdimid = 0; ncdimid < ndims; ncdimid++ )
{ {
ncdims[ncdimid].dimid = CDI_UNDEFID;
ncdims[ncdimid].ncvarid = CDI_UNDEFID; ncdims[ncdimid].ncvarid = CDI_UNDEFID;
ncdims[ncdimid].dimtype = CDI_UNDEFID; ncdims[ncdimid].dimtype = CDI_UNDEFID;
ncdims[ncdimid].len = 0; ncdims[ncdimid].len = 0;
...@@ -884,7 +896,7 @@ void cdf_set_cdi_attr(int ncid, int ncvarid, int attnum, int cdiID, int varID) ...@@ -884,7 +896,7 @@ void cdf_set_cdi_attr(int ncid, int ncvarid, int attnum, int cdiID, int varID)
cdfGetAttInt(ncid, ncvarid, attname, attlen, attint); cdfGetAttInt(ncid, ncvarid, attname, attlen, attint);
int datatype = (atttype == NC_SHORT) ? CDI_DATATYPE_INT16 : int datatype = (atttype == NC_SHORT) ? CDI_DATATYPE_INT16 :
(atttype == NC_BYTE) ? CDI_DATATYPE_INT8 : (atttype == NC_BYTE) ? CDI_DATATYPE_INT8 :
#if defined (HAVE_NETCDF4) #ifdef HAVE_NETCDF4
(atttype == NC_UBYTE) ? CDI_DATATYPE_UINT8 : (atttype == NC_UBYTE) ? CDI_DATATYPE_UINT8 :
(atttype == NC_USHORT) ? CDI_DATATYPE_UINT16 : (atttype == NC_USHORT) ? CDI_DATATYPE_UINT16 :
(atttype == NC_UINT) ? CDI_DATATYPE_UINT32 : (atttype == NC_UINT) ? CDI_DATATYPE_UINT32 :
...@@ -1051,7 +1063,7 @@ int cdf_get_cell_varid(char *attstring, int ncid) ...@@ -1051,7 +1063,7 @@ int cdf_get_cell_varid(char *attstring, int ncid)
} }
static static
void cdf_scan_var_attr(int nvars, ncvar_t *ncvars, ncdim_t *ncdims, int timedimid, int modelID, int format) void cdf_scan_var_attr(int nvars, ncvar_t *ncvars, int ndims, ncdim_t *ncdims, int timedimid, int modelID, int format)
{ {
int ncdimid; int ncdimid;
int nvdims, nvatts; int nvdims, nvatts;
...@@ -1073,6 +1085,13 @@ void cdf_scan_var_attr(int nvars, ncvar_t *ncvars, ncdim_t *ncdims, int timedimi ...@@ -1073,6 +1085,13 @@ void cdf_scan_var_attr(int nvars, ncvar_t *ncvars, ncdim_t *ncdims, int timedimi
int *dimidsp = ncvars[ncvarid].dimids; int *dimidsp = ncvars[ncvarid].dimids;
cdf_inq_var(ncid, ncvarid, name, &xtype, &nvdims, dimidsp, &nvatts); cdf_inq_var(ncid, ncvarid, name, &xtype, &nvdims, dimidsp, &nvatts);
for ( int i = 0; i < nvdims; ++i )
for ( int dimid = 0; dimid < ndims; ++dimid )
if ( ncdims[dimid].dimid == dimidsp[i] )
{
dimidsp[i] = dimid;
break;
}
strcpy(ncvars[ncvarid].name, name); strcpy(ncvars[ncvarid].name, name);
for ( ncdimid = 0; ncdimid < nvdims; ncdimid++ ) for ( ncdimid = 0; ncdimid < nvdims; ncdimid++ )
...@@ -1081,7 +1100,7 @@ void cdf_scan_var_attr(int nvars, ncvar_t *ncvars, ncdim_t *ncdims, int timedimi ...@@ -1081,7 +1100,7 @@ void cdf_scan_var_attr(int nvars, ncvar_t *ncvars, ncdim_t *ncdims, int timedimi
ncvars[ncvarid].xtype = xtype; ncvars[ncvarid].xtype = xtype;
ncvars[ncvarid].ndims = nvdims; ncvars[ncvarid].ndims = nvdims;
#if defined (HAVE_NETCDF4) #ifdef HAVE_NETCDF4
if ( format == NC_FORMAT_NETCDF4_CLASSIC || format == NC_FORMAT_NETCDF4 ) if ( format == NC_FORMAT_NETCDF4_CLASSIC || format == NC_FORMAT_NETCDF4 )
{ {
int shuffle, deflate, deflate_level; int shuffle, deflate, deflate_level;
...@@ -2318,7 +2337,7 @@ bool cdf_read_coordinates(struct cdfLazyGrid *restrict lazyGrid, ncvar_t *ncvar, ...@@ -2318,7 +2337,7 @@ bool cdf_read_coordinates(struct cdfLazyGrid *restrict lazyGrid, ncvar_t *ncvar,
if ( ncvars[xvarid].dimids[0] == timedimid && ncvars[yvarid].dimids[0] == timedimid ) if ( ncvars[xvarid].dimids[0] == timedimid && ncvars[yvarid].dimids[0] == timedimid )
{ {
size_t ntsteps = 0; size_t ntsteps = 0;
cdf_inq_dimlen(ncvar->ncid, timedimid, &ntsteps); cdf_inq_dimlen(ncvar->ncid, ncdims[timedimid].dimid, &ntsteps);
if ( ltwarn && ntsteps > 1 ) Warning("Time varying grids unsupported, using grid at time step 1!"); if ( ltwarn && ntsteps > 1 ) Warning("Time varying grids unsupported, using grid at time step 1!");
ltwarn = false; ltwarn = false;
ntdims = 1; ntdims = 1;
...@@ -3083,7 +3102,7 @@ void cdf_define_all_vars(stream_t *streamptr, int vlistID, int instID, int model ...@@ -3083,7 +3102,7 @@ void cdf_define_all_vars(stream_t *streamptr, int vlistID, int instID, int model
stream_new_var(streamptr, gridID, zaxisID, CDI_UNDEFID); stream_new_var(streamptr, gridID, zaxisID, CDI_UNDEFID);
int varID = vlistDefVar(vlistID, gridID, zaxisID, ncvars[ncvarid].timetype); int varID = vlistDefVar(vlistID, gridID, zaxisID, ncvars[ncvarid].timetype);
#if defined (HAVE_NETCDF4) #ifdef HAVE_NETCDF4
if ( ncvars[ncvarid].deflate ) if ( ncvars[ncvarid].deflate )
vlistDefVarCompType(vlistID, varID, CDI_COMPRESS_ZIP); vlistDefVarCompType(vlistID, varID, CDI_COMPRESS_ZIP);
...@@ -3662,7 +3681,6 @@ int cdfInqContents(stream_t *streamptr) ...@@ -3662,7 +3681,6 @@ int cdfInqContents(stream_t *streamptr)
{ {
int ndims, nvars, ngatts, unlimdimid; int ndims, nvars, ngatts, unlimdimid;
int ncvarid; int ncvarid;
int ncdimid;
int *varids; int *varids;
int nvarids; int nvarids;
bool time_has_units = false; bool time_has_units = false;
...@@ -3691,7 +3709,7 @@ int cdfInqContents(stream_t *streamptr) ...@@ -3691,7 +3709,7 @@ int cdfInqContents(stream_t *streamptr)
if ( CDI_Debug ) Message("streamID = %d, fileID = %d", streamptr->self, fileID); if ( CDI_Debug ) Message("streamID = %d, fileID = %d", streamptr->self, fileID);
#if defined (HAVE_NETCDF4) #ifdef HAVE_NETCDF4
nc_inq_format(fileID, &format); nc_inq_format(fileID, &format);
#endif #endif
...@@ -3710,6 +3728,18 @@ int cdfInqContents(stream_t *streamptr) ...@@ -3710,6 +3728,18 @@ int cdfInqContents(stream_t *streamptr)
ncdim_t *ncdims = ndims ? (ncdim_t *) Malloc((size_t)ndims * sizeof(ncdim_t)) : NULL; ncdim_t *ncdims = ndims ? (ncdim_t *) Malloc((size_t)ndims * sizeof(ncdim_t)) : NULL;
init_ncdims(ndims, ncdims); init_ncdims(ndims, ncdims);
int ncdimid = 0;
size_t dimlen;
for ( int dimid = 0; dimid < NC_MAX_DIMS; ++dimid )
{
int status = nc_inq_dimlen(fileID, dimid, &dimlen);
if ( status == NC_NOERR )
{
ncdims[ncdimid++].dimid = dimid;
if ( ncdimid == ndims ) break;
}
}
#ifdef HAVE_NETCDF4 #ifdef HAVE_NETCDF4
if ( format == NC_FORMAT_NETCDF4 ) if ( format == NC_FORMAT_NETCDF4 )
{ {
...@@ -3754,12 +3784,12 @@ int cdfInqContents(stream_t *streamptr) ...@@ -3754,12 +3784,12 @@ int cdfInqContents(stream_t *streamptr)
uuidOfHGrid, uuidOfVGrid, gridfile, &number_of_grid_used); uuidOfHGrid, uuidOfVGrid, gridfile, &number_of_grid_used);
// find time dim // find time dim
int timedimid = (unlimdimid >= 0) ? unlimdimid : cdf_time_dimid(fileID, ndims, nvars); int timedimid = (unlimdimid >= 0) ? unlimdimid : cdf_time_dimid(fileID, ndims, nvars, ncdims);
streamptr->basetime.ncdimid = timedimid; streamptr->basetime.ncdimid = timedimid;
size_t ntsteps = 0; size_t ntsteps = 0;
if ( timedimid != CDI_UNDEFID ) cdf_inq_dimlen(fileID, timedimid, &ntsteps); if ( timedimid != CDI_UNDEFID ) cdf_inq_dimlen(fileID, ncdims[timedimid].dimid, &ntsteps);
if ( ntsteps > INT_MAX ) if ( ntsteps > INT_MAX )
{ {
Warning("Size limit exceeded for time dimension (limit=%d)!", INT_MAX); Warning("Size limit exceeded for time dimension (limit=%d)!", INT_MAX);
...@@ -3772,16 +3802,16 @@ int cdfInqContents(stream_t *streamptr) ...@@ -3772,16 +3802,16 @@ int cdfInqContents(stream_t *streamptr)
// read ncdims // read ncdims
for ( ncdimid = 0; ncdimid < ndims; ncdimid++ ) for ( ncdimid = 0; ncdimid < ndims; ncdimid++ )
{ {
cdf_inq_dimlen(fileID, ncdimid, &ncdims[ncdimid].len); cdf_inq_dimlen(fileID, ncdims[ncdimid].dimid, &ncdims[ncdimid].len);
cdf_inq_dimname(fileID, ncdimid, ncdims[ncdimid].name); cdf_inq_dimname(fileID, ncdims[ncdimid].dimid, ncdims[ncdimid].name);
if ( timedimid == ncdimid ) if ( timedimid == ncdimid )
ncdims[ncdimid].dimtype = T_AXIS; ncdims[ncdimid].dimtype = T_AXIS;
} }
if ( CDI_Debug ) cdf_print_vars(ncvars, nvars, "cdf_scan_var_attr"); if ( CDI_Debug ) cdf_print_vars(ncvars, nvars, "cdf_scan_var_attr");
// scan attributes of all variables // scan attributes of all variables
cdf_scan_var_attr(nvars, ncvars, ncdims, timedimid, modelID, format); cdf_scan_var_attr(nvars, ncvars, ndims, ncdims, timedimid, modelID, format);
if ( CDI_Debug ) cdf_print_vars(ncvars, nvars, "find coordinate vars"); if ( CDI_Debug ) cdf_print_vars(ncvars, nvars, "find coordinate vars");
...@@ -4132,7 +4162,7 @@ int cdfInqTimestep(stream_t * streamptr, int tsID) ...@@ -4132,7 +4162,7 @@ int cdfInqTimestep(stream_t * streamptr, int tsID)
} }
else else
{ {
#if defined (USE_TIMECACHE) #ifdef USE_TIMECACHE
if ( streamptr->basetime.timevar_cache == NULL ) if ( streamptr->basetime.timevar_cache == NULL )
{ {
streamptr->basetime.timevar_cache = (timecache_t *) Malloc(MAX_TIMECACHE_SIZE*sizeof(timecache_t)); streamptr->basetime.timevar_cache = (timecache_t *) Malloc(MAX_TIMECACHE_SIZE*sizeof(timecache_t));
...@@ -4200,7 +4230,7 @@ void cdfInqHistoryString(stream_t *streamptr, char *history) ...@@ -4200,7 +4230,7 @@ void cdfInqHistoryString(stream_t *streamptr, char *history)
{ {
cdf_get_att_text(ncid, NC_GLOBAL, "history", history); cdf_get_att_text(ncid, NC_GLOBAL, "history", history);
} }
#if defined (HAVE_NETCDF4) #ifdef HAVE_NETCDF4
else if ( atttype == NC_STRING ) else if ( atttype == NC_STRING )
{ {
// ToDo // ToDo
......
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