netcdf fortran 如何检索全局属性总数

问题描述

我想弄清楚如何发现一个 netcdf 文件有多少全局属性。通过这样做,我正在使用电话:

status = nf90_Inquire_Variable(ncid,NF90_GLOBAL,nAtts=natts)

为了测试它,我创建了一个简单的示例。首先,它创建一个具有全局属性文件,然后尝试读取它:

...

! create the file
call check( nf90_create("test.nc",NF90_NETCDF4,ncid) )
call check( nf90_put_att(ncid,"date","01/01/2021") )
call check( nf90_put_att(ncid,"time","00:00:00") )
call check( nf90_put_att(ncid,"seconds",1000) )
call check( nf90_close(ncid) )

 
! Read the file.
status = nf90_open("test.nc",NF90_NowRITE,ncid)
call check(status)

! how many global attributes?
status = nf90_Inquire_Variable(ncid,nAtts=natts)
call check(status)

! bye
status = nf90_close(ncid)
call check(status)

正确创建了 netcdf 文件

netcdf simpletest {

// global attributes:
        :date = "01/01/2021" ;
        :time = "00:00:00" ;
        :seconds = 1000 ;
}

但是出现以下错误

Program received signal SIGSEGV: Segmentation fault - invalid memory reference.

Backtrace for this error:
#0  0x7f34c7156d01 in ???
#1  0x7f34c7155ed5 in ???
#2  0x7f34c6e2020f in ???
#3  0x7f34c749304e in nf_inq_var_
    at /to/some/path/netcdf-fortran-4.5.1/fortran/nf_genvar.f90:181
#4  0x7f34c74ebedf in __netcdf_MOD_nf90_inquire_variable
    at /to/some/path/netcdf-fortran-4.5.1/fortran/netcdf4_variables.f90:293
Violació de segment (s'ha bolcat la memòria)

GDB 停在:

Program received signal SIGSEGV,Segmentation fault.
0x00007ffff7f5e04e in nf_inq_var (ncid=1,varid=0,name=...,xtype=1077936128,ndims=1073741824,dimids=...,natts=3,_name=256)
    at nf_genvar.f90:181
warning: Source file is more recent than executable.
181      dimids(1:ndims) = cdimids(ndims:1:-1)+1

所以在我看来我做错了什么。我是否按原意使用了原始调用

如果没有,怎么办?通过阅读 netcdf fortran 文档,我找不到它。

我正在使用以下版本:

  • gfortran 9.3
  • zlib 1.2.11
  • hdf5 1.10.5
  • netcdf-c 4.7.1
  • netcdf-fortran 4.5.1

编辑:

正如以下评论之一所建议的,我做了几个具有不同选择的最小可重复示例,因为我对选项感到有些困惑。

我还为 nc_inq_natts 调用创建了一个新的 Fortran 绑定,但重命名为 nf90_inq_natts。

  1. a fortran file which creates and read a netcdf file
  2. a c file which creates a netcdf file with 1 global attribute
  3. a fortran file which only read the file from point 2

所有文件在运行时都在调试模式下编译。

出现以下输出

创建一个文件 (C):

*** SUCCESS writing example file simple_xy.nc!

只读取 netcdf 文件(fortran):

 nf90_inquire_variable ... 
 NetCDF: Variable not found
 nf90_inq_natts ... 
 NetCDF: Not a valid ID
 Global attributes (inquire_variable(GLOBAL)):   1788528357  <-- not working
 Global attributes (inq_natts):    260315136                 <-- not working

创建和读取文件(fortran):

 nf90_inquire_variable ... 
 nf90_inq_natts ... 
 NetCDF: Not a valid ID
 Global attributes (inquire_variable(GLOBAL)):            3   <-- it works
 Global attributes (inq_natts):   1256308480                  <-- not working

结果:

  • 我无法重现我最初提到的错误。 :-/
  • nc_inq_natts 与 Fortran 混合时似乎不起作用(NetCDF:不是有效 ID)
  • nf90_inquire_variables 在同一个文件中创建 netcdf 文件时似乎可以工作 (?)。关于文档,它不应该发生。
  • 取自 github 的 C 示例按预期工作

解决方法

From a thread on the netcdfgroup mail list found by googling:
A variable ID of NF90_GLOBAL is explicitly allowed with
nf90_inquire_attribute,but not with nf90_inquire_variable.  The intended
functions for discovering global attributes are nf90_inquire and
nf90_inquire_attribute.  With a bit of study,the F90 documentation on this
topic seems rather clear to me.

Attempting to use nf90_inquire_variable for global attributes is a
mis-application of that function.  Furthermore,that function is probably
returning the appropriate error code in this case,as documented:  "The
variable ID is invalid for the specified netCDF dataset."

即将调用的函数更改为 nf90_inquire_attribute