Dear netCDF group,
I have encountered some problems with netCDF c++ data types since upgrading to
Ubuntu 16.04. In short, the first 6 data types defined in ncType.h work fine
(e.g. nc_BYTE, nc_CHAR, nc_SHORT, nc_INT, nc_FLOAT and nc_DOUBLE), but the rest
(including types that I need for my software, nc_STRING, nc_UINT) throw
NcBadType errors when nc_inq_type is called (from NcType::getName() for
example).
Previously I was using netCDF 4.1.3 and netCDF c++ 4.2.1 on Ubuntu 14.04 and
Win7, and everything worked fine. The netCDF version available by the Ubuntu
16.04 package manager is 4.4.0, and the netCDF c++ version remains 4.2.1.
The problem is summarised in the attached example, which I compile via:
g++ --std=c++11 types_test.cpp -lnetcdf_c++4 -lnetcdf
The output I get on Ubuntu 16.04 with netCDF 4.40 is:
$
encountered bad type when making a string variable
encountered bad type when making a uint variable
myType = byte
myType = char
myType = short
myType = int
myType = float
myType = double
Type with enum value: 7 throws NcBadType
Type with enum value: 8 throws NcBadType
Type with enum value: 9 throws NcBadType
Type with enum value: 10 throws NcBadType
Type with enum value: 11 throws NcBadType
Type with enum value: 12 throws NcBadType
Type with enum value: 13 throws NcBadType
Type with enum value: 14 throws NcBadType
Type with enum value: 15 throws NcBadType
Type with enum value: 16 throws NcBadType
myType = nc_BYTE
myType = nc_CHAR
myType = nc_SHORT
myType = nc_INT
myType = nc_FLOAT
myType = nc_DOUBLE
myType = nc_UBYTE
myType = nc_USHORT
myType = nc_UINT
myType = nc_INT64
myType = nc_UINT64
myType = nc_STRING
Type with enum value: 13 throws NcBadId
Type with enum value: 14 throws NcBadId
Type with enum value: 15 throws NcBadId
Type with enum value: 16 throws NcBadId
$
The output I get on Ubuntu 14.04 with netCDF 4.1.3 is:
$
myType = byte
myType = char
myType = short
myType = int
myType = float
myType = double
myType = ubyte
myType = ushort
myType = uint
myType = int64
myType = uint64
myType = string
Type with enum value: 13 throws NcBadType
Type with enum value: 14 throws NcBadType
Type with enum value: 15 throws NcBadType
Type with enum value: 16 throws NcBadType
myType = nc_BYTE
myType = nc_CHAR
myType = nc_SHORT
myType = nc_INT
myType = nc_FLOAT
myType = nc_DOUBLE
myType = nc_UBYTE
myType = nc_USHORT
myType = nc_UINT
myType = nc_INT64
myType = nc_UINT64
myType = nc_STRING
Type with enum value: 13 throws NcBadId
Type with enum value: 14 throws NcBadId
Type with enum value: 15 throws NcBadId
Type with enum value: 16 throws NcBadId
$
Is the problem something to do with not have a valid ncid, as the comments from
ncType.cpp allude too?
// Returns the type name.
string NcType::getName() const{
char charName[NC_MAX_NAME+1];
size_t *sizep=NULL;
/* We cannot call nc_inq_type without a valid
netcdf file ID (ncid), which is not *groupid*.
Working around this for now. */
ncCheck(nc_inq_type(g_ncid,myId,charName,sizep),__FILE__,__LINE__);
return string(charName);
};
Any help would be greatly appreciated!
Best regards,
Daniel
#include <iostream>
#include <string>
#include <vector>
#include <netcdf>
int main(void)
{
netCDF::NcFile ncFile("test.nc", netCDF::NcFile::replace);
try
{
std::vector<float> myFloats = { 1., 2., 3., 4., 5. };
auto ncDim = ncFile.addDim("myFloatsDim", myFloats.size());
auto ncVar = ncFile.addVar("myFloats", netCDF::ncFloat,
{ncDim});
ncVar.putVar(myFloats.data());
}
catch (netCDF::exceptions::NcBadType)
{
std::cout << "encountered bad type when making a float
variable" << std::endl;
}
try
{
std::vector<std::string> myStrings = { "a", "bb", "ccc", "dddd"
};
auto ncDim = ncFile.addDim("myStringsDim", myStrings.size());
auto ncVar = ncFile.addVar("myStrings", netCDF::ncString,
{ncDim});
std::vector<const char *> myChars;
for ( auto s : myStrings )
myChars.push_back( s.c_str() );
ncVar.putVar(myChars.data());
}
catch (netCDF::exceptions::NcBadType)
{
std::cout << "encountered bad type when making a string
variable" << std::endl;
}
try
{
std::vector<unsigned int> myUints = { 1, 2, 3, 4, 5 };
auto ncDim = ncFile.addDim("myUintsDim", myUints.size());
auto ncVar = ncFile.addVar("myUints", netCDF::ncUint, {ncDim});
ncVar.putVar(myUints.data());
}
catch (netCDF::exceptions::NcBadType)
{
std::cout << "encountered bad type when making a uint variable"
<< std::endl;
}
for (size_t i=1; i<17; ++i)
{
try
{
netCDF::NcType * myType = new netCDF::NcType(i);
std::cout << "myType = " << myType->getName() <<
std::endl;
}
catch (netCDF::exceptions::NcBadType)
{
std::cout << "Type with enum value: " << i << " throws
NcBadType" << std::endl;
}
}
for (size_t i=1; i<17; ++i)
{
try
{
netCDF::NcType myType(i);
std::cout << "myType = " << myType.getTypeClassName()
<< std::endl;
}
catch (netCDF::exceptions::NcBadId)
{
std::cout << "Type with enum value: " << i << " throws
NcBadId" << std::endl;
}
}
return 0;
}