2011-07-31 19 views
0

私のFORTRANコーディングを変更するには技術的な助けが必要です。私はインターネットを検索しましたが、私のニーズを解決できるものはありません。複数のファイルから選択したデータを読み取る

基本的に私はFORTRANプログラムを使用してシミュレーションデータを分析しています。まず、自分が望むものを理解しやすくするためにデータのフォーマットを説明します。私は10のファイルがあります。各ファイルはx、y z、1000フレームのデータを含み、各フレームは20736(x、y、z)データを含む。すべてのデータの合計サイズは10,000フレームすべてで約10 GBなので、計算中のクラッシュを避けるために、それらを小さなチャンク(10個のファイル)に分割する必要があります。各ファイルの先頭(1行目)には無視できるテキストがあり、各フレームはボックスサイズ(bx、by、bz)の情報で終わります。これは私のデータファイルのフォーマットです。

私は分析のために使用しているコーディングを添付しました。

現在のコーディングは、ファイルの後に計算ファイルを行い、フレームの後にフレームを順番に実行します。しかし、今は、特定のパターンのフレームの後にフレームをジャンプするだけで、選択したフレームで計算を行いたいと思っています。たとえば、フレーム1,4,8,12,16などを選択し、最後のフレーム(10,000)まで続けます。

2番目または3番目のファイルに含まれる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 

私は本当に事前にあなたの助けに感謝。

ありがとうございました。

答えて

0

まあ、ループ内で、mod(framenumber, 4) == 0が次の繰り返しにスキップしない限り(CYCLEステートメントはFortranでそれを行います)。そうすれば、4番目ごとのフレームだけを処理します。

また、PIではやや正確な値を使用したいと考えています。 22/7、WTF?

+0

を:: pi = datan(1.0d0)* 4.0d0 – bdforbes

0

明らかに、プログラムは、それがどのファイルを読み込んでいるのかを知る必要があります。1,2、... 10. ifileを呼び出します。次に、ファイルがあるフレーム、たとえばframe_in_fileを指定します。それからあなたはframe =(ifile-1)* frame_in_fileを持っています。 「フレーム」を処理するかどうかを決定するルールはありますか?ルールが四分の一ごとに処理される場合は、modを使用し、@jannebのように繰り返します。そうでなければ、あなたが何を求めているのか分かりません。

10個のファイルでは、ファイル名を文字列に書き込んでループで処理する方が簡単です。各ファイルを同じユニット番号で順番に開き、ループの最後で閉じることができます。これは、あなたが10未満の場合は、ファイル名に番号が常に先行ゼロを持つ2つの数字だったことを慣例使用した場合少し容易になるだろう:私は本当の(8)、パラメータを使用したい

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 
+0

ファイル名では、ほとんどのコンパイラがI0編集記述子をサポートしているため、先行ゼロなしでファイル名を簡単に作成できます。 – janneb

+0

真。しかし、あなたは字句の並び替えをやめるので、あまり良い考えではないかもしれません。ディレクトリリストは、1、10、2、3などの順序で表示されます。 – deprecated

関連する問題