NetCDF:开始+计数超出维度限制

时间:2017-11-02 21:43:25

标签: fortran netcdf

我在Fortran中编写了一个代码,用于读取具有4维数据[时间,级别,经度,纬度]的NetCDF文件。但是,我的代码会产生错误

NetCDF: Start+count exceeds dimension bound

我正在使用的任何4-bit NetCDF文件。例如,http://people.sc.fsu.edu/~jburkardt/f_src/netcdf/pres_temp_4D.nc处的文件具有压力和温度。我在下面粘贴我的代码。请说明出了什么问题。

PROGRAM rw_nc4d_main

  USE rw_nc4d,   ONLY: read_nc4

  IMPLICIT NONE

  CHARACTER(LEN=50) :: ncfn
  CHARACTER(LEN=15) :: vname

  ncfn = 'pres_temp_4D.nc'
  vname = 'pressure'

  CALL read_nc4(ncfn, vname)    

END PROGRAM rw_nc4d_main
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
MODULE rw_nc4d

USE netcdf

IMPLICIT NONE

CONTAINS

  SUBROUTINE read_nc4(fname,vin_name)   

    IMPLICIT NONE

    CHARACTER(LEN=*), INTENT(IN)          :: fname
    CHARACTER(LEN=*), INTENT(IN)          :: vin_name

    ! Local variables
    INTEGER                  :: ncid, var_id, ndim, nvar, nattr, unlim_id
    CHARACTER(LEN=15)        :: dname
    INTEGER                  :: dlength
    INTEGER                  :: ii, status, lx, ly, lz, lt, lzp1 
    REAL                     :: sf, ofs
    REAL, DIMENSION(:,:,:,:), ALLOCATABLE :: vin

    CALL nc_check(nf90_open(fname, nf90_nowrite, ncid))
    CALL nc_check(nf90_inquire(ncid,ndim,nvar))

    DO ii = 1, ndim
      CALL nc_check(nf90_inquire_dimension(ncid,ii,dname,len=dlength))
          SELECT CASE(TRIM(dname))
          CASE('lon', 'LON', 'longitude')
            lx = dlength
          CASE('lat', 'LAT', 'latitude' )
            ly = dlength
          CASE('lev', 'LEV',  'level'  )
            lz = dlength
          CASE('time', 'TIME'           )
            lt = dlength
          CASE('ilev', 'ILEV')
            lzp1 = dlength
          CASE DEFAULT
            WRITE(*,*)'ERROR: nc_check for dimensions!'; STOP
        END SELECT
    END DO

    ALLOCATE(vin(lt,lz,ly,lx))

    CALL nc_check(nf90_inq_varid(ncid,TRIM(vin_name),var_id))
    CALL nc_check(nf90_get_var(ncid,var_id,vin,start=(/1,1,1,1/),count=(/lt,lz,ly,lx/)),fname=TRIM(fname))

 END SUBROUTINE read_nc4

  SUBROUTINE nc_check(status,fname)

    INTEGER, INTENT(IN) :: status
    CHARACTER(LEN=*), OPTIONAL :: fname

    IF (status /= nf90_noerr) THEN
      IF (PRESENT(fname)) THEN
        WRITE(*,*)'FATAL ERROR in ',TRIM(fname),' ',TRIM(nf90_strerror(status))
      ELSE
        WRITE(*,*)'FATAL ERROR: ',TRIM(nf90_strerror(status))
      END IF
      STOP
    END IF

  END SUBROUTINE nc_check

END MODULE rw_nc4d

1 个答案:

答案 0 :(得分:4)

你有尺寸回到前面。我还怀疑您的变量的longitudelatitude与您发布的顺序相反。形状为[time, level,latitude,longitude]的变量应在Fortran中声明为var(longitude, latitude, level, time)