从多个文件中读取所选数据

时间:2011-07-31 11:03:01

标签: fortran

我需要一些技术帮助来修改我的FORTRAN编码。我在互联网上搜索过,但我无法解决这个问题。

基本上我正在使用FORTRAN程序分析模拟数据。首先,我将解释我的数据格式,以便于理解我想要的内容。我有10个文件。每个文件包含x,y z,1000帧的数据,每帧包含20736(x,y,z)数据。由于所有10,000帧的所有数据的总大小约为10 GB,因此我必须将它们分成小块(10个文件)以避免计算过程中出现任何崩溃。在每个文件的开头(第一行),有一个可以忽略的文本,每个框架以框大小(bx,by,bz)的信息结束。这是我的数据文件的格式。

我附上了我用于分析的编码。

当前编码将按顺序执行文件和帧后的计算文件。但是现在我只想通过一帧一帧地跳帧来对所选帧进行计算。例如,我选择帧1,4,8,12,16 ......等等,直到最后一帧(10,000)。

我不知道如何选择超过1000的帧,这些帧落在第二或第三个文件中。

我在下面显示了我的代码:


module all_parameter
integer,parameter :: MAXATOM=20736
integer,parameter :: nat = 20736                    
integer, parameter :: startFiles=31
integer, parameter :: endFiles=40
integer,parameter :: NO_OF_FILES=10
integer,parameter :: FRAMES_IN=1000
integer, parameter :: totalFrames = ( NO_OF_FILES * FRAMES_IN )
integer :: i, j, k, IFram, nhb, nlipid, jjj
integer :: BIN, iat, jat
!real :: DELR, fnid, GNRM, RCUT, rlower, rupper
real :: junk, dR, bx, by, bz, bbx
real :: only_head, only_tail, only_water
real :: mass_head, mass_tail, mass_water
character*4 at(MAXATOM)
real,dimension(MAXATOM) :: x, y, z
real,dimension(3) :: rcm
real,dimension(MAXATOM) :: rx, ry, rz 
real,dimension(MAXATOM) :: mass

integer, parameter :: startlipid=1
integer, parameter :: endlipid=64
integer, parameter :: lipidNo=64

real, parameter :: PI = (22.0/7.0)
real, dimension(startlipid:endlipid) :: array_UniVekLx, array_UniVekLy, array_UniVekLz
integer ::  no, no2, c71, c72, c80, c81
real        ::  p1x, p1y, p1z, p2x, p2y, p2z, vekx, veky, vekz
real        ::  mag_vekp1p2,  unit_vekx, unit_veky, unit_vekz
real        ::  sum_UniVekLx, sum_UniVekLy, sum_UniVekLz
real        ::  avg_frame_vekx, avg_frame_veky, avg_frame_vekz
real        ::  xx, yy, zz, frame_MagLipVek, theta,theta2, uni_frame_Vekx, uni_frame_Veky, uni_frame_Vekz
real        ::  xxx, yyy, zzz,UniVekLx, UniVekLy, UniVekLz, FrameAvgUniVekMag
real        ::  avg_UniVekLx, avg_UniVekLy,avg_UniVekLz, MagLipVek

end module all_parameter



PROGRAM order_parameter
use all_parameter
implicit none
!=========================================================================
! Open files to be read and to write on
!=========================================================================
!
    ! Topology file     !CHANGE

open(unit=31,status="old",file="../malto_thermoNEW_Ori_50ns-set1.traj ")
open(unit=32,status="old",file="../malto_thermoNEW_Ori_50ns-set2.traj ")
open(unit=33,status="old",file="../malto_thermoNEW_Ori_50ns-set3.traj ")
open(unit=34,status="old",file="../malto_thermoNEW_Ori_50ns-set4.traj ")
open(unit=35,status="old",file="../malto_thermoNEW_Ori_50ns-set5.traj ")
open(unit=36,status="old",file="../malto_thermoNEW_Ori_50ns-set6.traj ")
open(unit=37,status="old",file="../malto_thermoNEW_Ori_50ns-set7.traj ")
open(unit=38,status="old",file="../malto_thermoNEW_Ori_50ns-set8.traj ")
open(unit=39,status="old",file="../malto_thermoNEW_Ori_50ns-set9.traj ")
open(unit=40,status="old",file="../malto_thermoNEW_Ori_50ns-set10.traj ")

! Open New Files
open(unit=51,status="unknown",file="BOXinfo.dat ")
open(unit=75,status="unknown",file="magnitude_theta_lipid-thermo-malto.dat")

do k = startlipid, endlipid
array_UniVekLx(k) =0.0
array_UniVekLy(k) =0.0
array_UniVekLz(k) =0.0
end  do


 ! READ COORDINATES IN FRAMES FROM TRAJ file

INPUTFILES: do jjj = startFiles, endFiles
! LOOP OVER FRAMES
IFram = 1
read(jjj,'(a)') junk

!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
        !IFram = 1
WHOLE: do while ( IFram <= FRAMES_IN)   
read(jjj,'(10F8.3)') (x(i),y(i),z(i),i = 1,nat)  ! reading TRAJ file 

        read(jjj,'(3F8.3)') bx,by,bz   
        write(51,'(a,3F8.3)') 'BOXINFO', bx,by,bz


        ! LOOP OVER ATOMS

        loop1: do j = startlipid, endlipid !nat in lipids
            loop2: do i = 45, 45 !,3    !atoms in a lipid

                no= i + (j-1)*81
                !no2= (no + 18)

                c71=no
                c72=(no+3)
                    p1x=((x(c71) + x(c72))/2.0 )
                    p1y=((y(c71) + y(c72))/2.0 )
                    p1z=((z(c71) + z(c72))/2.0 )
                    .       
                    .
                    .
                    .

            enddo loop2 ! going to next lipid
        !CLOSE LOOP OVER ATOMS
        enddo loop1  ! going to next frame , before that



!CLOSE LOOP OVER A FRAME
IFram = IFram + 1

enddo WHOLE


!CLOSE LOOP OVER ALL FILES
  enddo INPUTFILES

 end program order_parameter

我非常感谢你的帮助。

感谢。

2 个答案:

答案 0 :(得分:0)

好吧,在循环中,除非mod(framenumber, 4) == 0跳到下一次迭代(CYCLE语句在Fortran中执行)。这样,你只会每隔四帧处理一次。

此外,您希望为PI使用更精确的值。 22/7,WTF?

答案 1 :(得分:0)

显然程序需要知道它正在读取哪个文件,1,2 ... 10.称之为ifile。然后是带有文件的框架,比如说frame_in_file。然后你有frame =(ifile-1)* frame_in_file。您是否有规则来决定是否要处理“框架”?如果规则是每四个处理一次,请按照建议的@janneb使用mod和cycle。否则,我不确定你在问什么。

使用十个文件,将文件名写入字符串并使用循环处理它们会更容易,依次打开每个文件并使用相同的单元号并在循环结束时关闭。如果您使用约定文件名中的数字始终为两位数,如果小于10则前导零,这会更容易一些:

do ifile=1, 10
   write (filename, '( "myfile_number", I2.2, ".data" )' ) ifile
   open (unit=30, file=filename, ...)
   loop: read from the file...
      calculate overall frame number ...
      cycle out of read loop if unsuitable frame...
      process the frame...
   end read loop
   close (unit=30)
end do