爱气象,爱气象家园! 

气象家园

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

搜索
查看: 10222|回复: 21

[求助] 求助Fortran读取直接二进制文件

[复制链接]

新浪微博达人勋

发表于 2014-12-29 23:47:17 | 显示全部楼层 |阅读模式

登录后查看更多精彩内容~

您需要 登录 才可以下载或查看,没有帐号?立即注册 新浪微博登陆

x
我有1948-2013年共66年的相对湿度月平均资料,现在想做一个多年月平均。具体计算部分应该没什么问题,大家帮我看看文件的读写有什么问题。之前用的是form='binary',结果运行出来的数据个数比正确的个数多了一些,现在换form=‘unformatted’,结果更离谱了,大家帮忙看看问题出在哪。十分感谢!下面是程序。

program ex
integer i,j,k,t,t1,irec,error
integer,parameter :: nx=144,ny=73,nz=17,nt=792,ntt=12
real air(nx,ny,nz,nt),mair(nx,ny,nz,ntt)
open(10,file='E:/data/mon.mean.grd/air.mon.mean.grd',form='unformatted',status='old',access='direct',recl=nx*ny*4)
open(11,file='E:/data/mon.mean.out/air.out.txt',form='formatted')
!读数据
irec=0
do t=1,nt
  do k=1,nz
    irec=irec+1
    read(10,rec=irec,iostat=error) ((air(i,j,k,t),i=1,nx),j=1,ny)
    if(error<0) exit
  end do
end do

!计算1948-2013年共66年各月平均(12*66=792)
do i=1,nx
  do j=1,ny
    do k=1,nz
    do t1=1,ntt
       t=t1
       mair(i,j,k,t1)=0
      do while(t<=792)
        mair(i,j,k,t1)= mair(i,j,k,t1)+air(i,j,k,t)
        t=t+12
      end do
      mair(i,j,k,t1)=mair(i,j,k,t1)/66
     end do
   end do
  end do
end do

!写数据
do t=1,ntt
  do k=1,nz
write(11,*)  ((mair(i,j,k,t),i=1,nx),j=1,ny)
end do
end do
end













密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2014-12-30 09:00:13 | 显示全部楼层
结果出错可能是
1、原数据中有缺测点,读进去就成了-9.99e6,导致最后计算出错
2、     mair(i,j,k,t1)=mair(i,j,k,t1)/66 应该为 real(66)
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2014-12-30 10:13:06 | 显示全部楼层
本帖最后由 冬日情愫+ 于 2014-12-30 10:16 编辑

说一下我个人的看法:1、mair(i,j,k,t1)=mair(i,j,k,t1)/66这个应该没有问题,因为mair已经定义成实数了,所以66不用写成实数形式(如66.0)。2、我记得以前我自己读直接格式读取grd格式的时候没有将记录长度乘以4直接是recl=nx*ny,记得印象中好想用visual fortran6.5是不需要乘以4的,不过楼主可以测试一下,是否需要乘以4.
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2014-12-30 10:25:31 | 显示全部楼层
同意楼上看法,cvf不需要*4
binary也应该没问题,如果想知道错在哪里可以把你使用的语句给出。
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2014-12-30 11:02:45 | 显示全部楼层
原数据是对的么?或者你可以用grads做月的年平均。
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2014-12-30 19:52:20 | 显示全部楼层
冬日情愫+ 发表于 2014-12-30 10:13
说一下我个人的看法:1、mair(i,j,k,t1)=mair(i,j,k,t1)/66这个应该没有问题,因为mair已经定义成实数了, ...

我用的是Intel Fortran ,不知道要不要乘以4呢?
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2014-12-30 19:59:57 | 显示全部楼层
lqouc 发表于 2014-12-30 10:25
同意楼上看法,cvf不需要*4
binary也应该没问题,如果想知道错在哪里可以把你使用的语句给出。

用binary的语句如下:
do t=1,nt
   do k=1,nz
          read(10,file='E:/data/mon.mean.grd/air.mon.mean.grd‘,form=‘binary’) ((air(i,j,k,t),i=1,nx),j=1,ny)
        end do
end do
计算结果看起来是数值是对的,但就是个数不对,正确结果应该是144*73*17*12个数据 但我计算出来的数据个数要多一些 您知道这是为什么吗
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2014-12-30 20:03:37 | 显示全部楼层
若...初 发表于 2014-12-30 11:02
原数据是对的么?或者你可以用grads做月的年平均。

原数据是从网上下载的.nc数据,我用grads转成了.grd方便Fortran计算,转化程序如下。因为接下来还要利用Fortran做进一步计算,所以就没有用grads做月平均。
'reinit'
'sdfopen E:/data/mon.mean.nc/air.mon.mean.nc'
'set gxout fwrite'
'set fwrite E:/data/mon.mean.grd/air.mon.mean.grd'
tt=1
while(tt<=792)
'set t 'tt
zz=1
while(zz<=17)
'set x 1 144'
'set y 1 73'
'set z 'zz
'd air'
zz=zz+1
endwhile
tt=tt+1
endwhile
'disable fwrite'
;
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2014-12-30 20:18:38 | 显示全部楼层
冬日情愫+ 发表于 2014-12-30 10:13
说一下我个人的看法:1、mair(i,j,k,t1)=mair(i,j,k,t1)/66这个应该没有问题,因为mair已经定义成实数了, ...

谢谢指点,我试过了,不乘以4得到的结果和’form=binary‘的结果一样,应该是对的,但得到的数据的个数还是不对啊,费解。
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2014-12-30 22:03:42 | 显示全部楼层
lqouc 发表于 2014-12-30 10:25
同意楼上看法,cvf不需要*4
binary也应该没问题,如果想知道错在哪里可以把你使用的语句给出。

刚才才发现,数据个数是对的,我用excel打开的时候中间某些行有些空的单元格,我之前没发现,这样的数据以后用的时候会不会出错啊。
密码修改失败请联系微信:mofangbao
您需要登录后才可以回帖 登录 | 立即注册 新浪微博登陆

本版积分规则

Copyright ©2011-2014 bbs.06climate.com All Rights Reserved.  Powered by Discuz! (京ICP-10201084)

本站信息均由会员发表,不代表气象家园立场,禁止在本站发表与国家法律相抵触言论

快速回复 返回顶部 返回列表