0

私はプログラミングが初めてで、fortran90 コードを python 2.7 に変換しています。私はこれまでのところかなりうまくやっていますが、難しいところにぶつかっています. このサブルーチンを Python で記述する必要がありますが、Fortran 表記が理解できず、Read(1,*) 行に相当する Python が何であるかについての情報が見つかりません。

どんな助けでも大歓迎です。

SUBROUTINE ReadBCoutput(filenameBC,count,timeArray,MbolArray,uArray,gArray,rArray,iArray,zArray)

! read Bruzual & Charlot (2003) stellar population synthesis models into arrays

CHARACTER*500,INTENT(IN):: filenameBC
INTEGER,INTENT(OUT):: count
REAL,DIMENSION(:),ALLOCATABLE,INTENT(OUT):: timeArray,MbolArray,uArray,gArray,rArray,iArray,zArray

REAL:: logTime,Mbol,g,uMg,gMr,gMi,gMz
REAL,DIMENSION(:),ALLOCATABLE:: timeArrayLocal,MbolArrayLocal,uArrayLocal,gArrayLocal,rArrayLocal,iArrayLocal,zArrayLocal

! open file and read off unnecessary 29 lines of comments
OPEN(1,FILE=TRIM(filenameBC),RECL=2000)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)

! now read arrays
count=0
ALLOCATE(timeArray(count))
ALLOCATE(MbolArray(count))
ALLOCATE(uArray(count))
ALLOCATE(gArray(count))
ALLOCATE(rArray(count))
ALLOCATE(iArray(count))
ALLOCATE(zArray(count))
IOEnd=0
DO WHILE(IOEnd>-1)
 READ(1,*,IOSTAT=IOEnd) logTime,Mbol,g,uMg,gMr,gMi,gMz
!print*,'filename is',filenameBC
   IF (IOEnd>-1) THEN ! not at end of file yet
     ! add new element to list
    count=count+1
    ALLOCATE(timeArrayLocal(count-1))
    ALLOCATE(MbolArrayLocal(count-1))
    ALLOCATE(uArrayLocal(count-1))
    ALLOCATE(gArrayLocal(count-1))
    ALLOCATE(rArrayLocal(count-1))
    ALLOCATE(iArrayLocal(count-1))
    ALLOCATE(zArrayLocal(count-1))
    DO countInside=1,count-1
       timeArrayLocal(countInside)=timeArray(countInside)
       MbolArrayLocal(countInside)=MbolArray(countInside)
       uArrayLocal(countInside)=uArray(countInside)
       gArrayLocal(countInside)=gArray(countInside)
       rArrayLocal(countInside)=rArray(countInside)
       iArrayLocal(countInside)=iArray(countInside)
       zArrayLocal(countInside)=zArray(countInside)
    END DO
    DEALLOCATE(timeArray)
    DEALLOCATE(MbolArray)
    DEALLOCATE(uArray)
    DEALLOCATE(gArray)
    DEALLOCATE(rArray)
    DEALLOCATE(iArray)
    DEALLOCATE(zArray)
    ALLOCATE(timeArray(count))
    ALLOCATE(MbolArray(count))
    ALLOCATE(uArray(count))
    ALLOCATE(gArray(count))
    ALLOCATE(rArray(count))
    ALLOCATE(iArray(count))
    ALLOCATE(zArray(count))
    DO countInside=1,count-1
       timeArray(countInside)=timeArrayLocal(countInside)
       MbolArray(countInside)=MbolArrayLocal(countInside)
       uArray(countInside)=uArrayLocal(countInside)
       gArray(countInside)=gArrayLocal(countInside)
       rArray(countInside)=rArrayLocal(countInside)
       iArray(countInside)=iArrayLocal(countInside)
       zArray(countInside)=zArrayLocal(countInside)
    END DO
    timeArray(count)=10**logTime
    MbolArray(count)=Mbol
    gArray(count)=g
    uArray(count)=uMg+g
    rArray(count)=g-gMr
    iArray(count)=g-gMi
    zArray(count)=g-gMz
    DEALLOCATE(uArrayLocal)
    DEALLOCATE(gArrayLocal)
    DEALLOCATE(rArrayLocal)
    DEALLOCATE(iArrayLocal)
    DEALLOCATE(zArrayLocal)
    DEALLOCATE(MbolArrayLocal)
    DEALLOCATE(timeArrayLocal)
 END IF
END DO
CLOSE(1)

END SUBROUTINE ReadBCoutput

誰かが私のためにすべてを変換してくれるとは思っていません-これが実際に何をしているのか、Pythonで何をする必要があるのか​​、何をする必要がないのかを明確にしたいだけです。私は自分で検索することができますが、ここで何を探すべきかについてはちょっと圧倒されます.

本当にありがとう!

4

2 に答える 2

4

fortran では、open(1,FILE=TRIM(filenameBC),RECL=2000)name のファイルを開きますfilenameBC。Fortran ランタイム ライブラリがそれを行うため、このTRIM部分は不要です (Python に相当するものは ですfilenameBC.rstrip())。ここのRECL=2000部分もちょっと怪しいです。ここでは何もしないと思います-実際、ファイルは"sequential"アクセスのために接続されている必要があるため、それを使用することは未定義の動作だと思います。fortran77 標準セクション 12.10.1 によると、

RECL = rl

rl は、値が正でなければならない整数式です。直接アクセス用に接続されているファイルの各レコードの長さを指定します。ファイルが定様式入出力用に接続されている場合、長さは文字数です。ファイルがフォーマットされていない入出力用に接続されている場合、長さはプロセッサー依存の単位で測定されます。既存のファイルの場合、rl の値は、ファイルに許可されているレコード長のセットに含まれている必要があります (12.2.2)。新しいファイルの場合、プロセッサは、指定された値を含む一連の許可されたレコード長でファイルを作成します。この指定子は、ファイルが直接アクセスのために接続されている場合に指定する必要があります。それ以外の場合は、省略しなければなりません。

これは、標準の新しいリビジョンで変更された可能性があります。そうであれば、行の最大長を指定していると思います。

Fortran ファイルハンドルは単なる整数です。したがって、python では次のように言います。

filehandle = open('file')
line = filehandle.readline()  #or better, `next(filehandle)` :)

Fortran では、これは次とほぼ同じです。

integer filehandle
filehandle = 1       ! pick an integer any positive one 
                     ! will do that we haven't used already,
                     ! but it's best to avoid 0,5,6 as those 
                     ! usually mean `stderr`,`stdin` and `stdout`.
open(filehandle,file='file')
read(filehandle,*) line

*基本的に、ファイルから1行を読み取ることができます。


この fortran コードには少しバグがあり、非常に非効率的であることに注意してください。たとえば、チェックIF (IOEnd>-1) THENは、ファイルの終わりではない任意の条件の下で成功します (たとえば、奇妙なエラーはexcept、python の裸のようにマスクされます)。Python では、この情報をリストにパックし、リストを動的に拡張することができます。必要な再割り当てはすべて Python が処理します。最後に、リストを numpy に変換することを選択できますndarray

疑似 Python コードでは、これは大まかに次のように変換されます。

data_list = []
with open(filenameBC.rstrip()) as fin:
    for _ in range(29): #throw away first 29 lines (I think I counted right ...)
        next(fin)
    
    for line in fin:
        data_list.append([float(x) for x in line.strip()])
    
timeArray,MbolArray,uArray,gArray,rArray,iArray,zArray = zip(*data_list)
于 2013-03-19T13:13:20.607 に答える
0

READ(1,*)あなたのファイルから何かを読んでいます....それを保存していません。つまり、ただ捨てています。これらのREAD(1,*)ステートメントはすべて、実際に必要なデータに到達するまでファイルをスクロールする方法にすぎません。(ちなみに、これをコーディングする最もコンパクトな方法ではありません。この FORTRAN コードを書いた人は、多くの点で非常に賢いかもしれませんが、それほど優れたプログラマーではありませんでした。あるいは、彼らは大急ぎだったのかもしれません。)なれ

>>> infile.readline()

FORTRAN はデータ整数、浮動小数点数などとして読み取ることができますが、Python はすべてをテキストとして読み取るだけなので、必要な数値形式にキャストする必要があることに注意してください。

ただし、 NumPyを見たい場合は、データを数値として読み取ることができるルーチンがいくつかあります:loadtxtgenfromtxt. 他にもいくつかあるかもしれませんが、それらは私が最も役に立ったものです。

于 2013-03-19T18:37:12.243 に答える