netcdf4-python
netcdf4-python copied to clipboard
NetCDF: String match to name in use
- the version of the software with which you are encountering an issue
>>> import netCDF4 as ncf
>>> print(ncf.__version__)
1.5.3
>>> print(ncf.getlibversion())
4.7.3 of Feb 19 2020 19:16:51 $
- environmental information (i.e. Operating System, compiler info, java version, python version, etc.)
>uname -srvon
Linux atmos1 3.10.0-1062.12.1.el7.x86_64 #1 SMP Thu Dec 12 06:44:49 EST 2019 GNU/Linux
>python --version
Python 3.8.1
Installed via conda
- a description of the issue with the steps needed to reproduce it
Code to reproduce
import netCDF4 as ncf
print(ncf.__version__)
print(ncf.getlibversion())
f = ncf.Dataset('test.nc', 'w')
f.createDimension('test', 6)
var = f.createVariable('test', 'f', ('test',))
var[:] = 0
f.setncattr('NAME', 1)
Output and Error from commands:
1.5.3
4.7.3 of Feb 19 2020 19:16:51 $
Traceback (most recent call last):
File "test.py", line 9, in <module>
f.setncattr('NAME', 1)
File "netCDF4/_netCDF4.pyx", line 2844, in netCDF4._netCDF4.Dataset.setncattr
File "netCDF4/_netCDF4.pyx", line 1617, in netCDF4._netCDF4._set_att
File "netCDF4/_netCDF4.pyx", line 1887, in netCDF4._netCDF4._ensure_nc_success
AttributeError: NetCDF: String match to name in use
Oddly, I can add name, but not NAME in python. The error seems to point to the underlying library, but I compiled a small program against the same library without a problem. The steps to make the program, compile it, and run it are below. Along with outputs
Commands to reproduce:
cat << EOF > test.cdl
netcdf GRIDCRO2D.12US2.35L {
dimensions:
LAT= 1 ;
variables:
float LAT(LAT) ;
LAT:long_name = "LAT " ;
LAT:units = "DEGREES " ;
// global attributes:
:NAME = "test" ;
data:
LAT =
22.84721;
}
EOF
ncgen -lc test.cdl > test.c
gcc -o test -I/work/ROMO/anaconda_envs/basic38/include -L/work/ROMO/anaconda_envs/basic38/lib -lnetcdf -lhdf5 -lhdf5_hl -lmfhdf -ldf -ljpeg test.c
./test
ncdump test.nc
Output from commands:
netcdf test {
dimensions:
LAT = 1 ;
variables:
float LAT(LAT) ;
LAT:long_name = "LAT " ;
LAT:units = "DEGREES " ;
// global attributes:
:NAME = "test" ;
data:
LAT = 22.84721 ;
}
I'm guessing this is a "special" attribute issue, but the CAMx metadata has the property. So, I am trying to find a work around.
Thank you for any insights here.
You C example will fail the same way as the python example if you specify the netCDF4 format (ncgen -lc -4 test.cdl > test.c). There must be a private attribute NAME that's used by HDF5. @WardF or @edwardhartnett, can you confirm this?
The only workaround I can suggest now is to use the old netCDF3 format (i.e. format='NETCDF3_64BIT). That must be what CAMx uses?
Thank you! That helps a lot. I am sorry to have confused the issue. As always, I am grateful for your help and quick response!
Leaving this open for now until we decide whether it's a netcdf-c bug or not.
I'll take a look on our end; the rest of my day is spent in meetings, but I'll see what I can figure out.
@WardF - have you had a chance to check on this yet?
having the same issue
Indeed NAME is a reserved attribute name. From nc4internal.c:
/** @internal List of reserved attributes. This list must be in sorted
* order for binary search. */
static const NC_reservedatt NC_reserved[NRESERVED] = {
{NC_ATT_CLASS, READONLYFLAG|DIMSCALEFLAG}, /*CLASS*/
{NC_ATT_DIMENSION_LIST, READONLYFLAG|DIMSCALEFLAG}, /*DIMENSION_LIST*/
{NC_ATT_NAME, READONLYFLAG|DIMSCALEFLAG}, /*NAME*/
{NC_ATT_REFERENCE_LIST, READONLYFLAG|DIMSCALEFLAG}, /*REFERENCE_LIST*/
{NC_ATT_FORMAT, READONLYFLAG}, /*_Format*/
{ISNETCDF4ATT, READONLYFLAG|NAMEONLYFLAG}, /*_IsNetcdf4*/
{NCPROPS, READONLYFLAG|NAMEONLYFLAG|MATERIALIZEDFLAG},/*_NCProperties*/
{NC_ATT_COORDINATES, READONLYFLAG|DIMSCALEFLAG|MATERIALIZEDFLAG},/*_Netcdf4Coordinates*/
{NC_ATT_DIMID_NAME, READONLYFLAG|DIMSCALEFLAG|MATERIALIZEDFLAG},/*_Netcdf4Dimid*/
{SUPERBLOCKATT, READONLYFLAG|NAMEONLYFLAG},/*_SuperblockVersion*/
{NC_ATT_NC3_STRICT_NAME, READONLYFLAG|MATERIALIZEDFLAG}, /*_nc3_strict*/
};
Unfortunately this is not under our control, the first 4 reserved names are part of the HDF5 dimension scale API, which is used for dimensions in netCDF/HDF5 files.
The only way to really fix this is to catch the definition of a "NAME" attribute, and then really name it _netcdf_NAME in the file, and then, when reading the file, intercept "_netcdf_NAME" and present it to the user as attribute "NAME".