5

私は Python をまったく初めて使用し、視覚化コードを Python でゼロから作成しています (IDL のような高価な専用プログラムの使用を避けるため)。今まで IDL と gnuplot を使ってきました。私ができるようにしたいのはこれです:

Pythonで読み取れるようにしたいfortranを使用して、フォーマットされていない直接アクセスファイルに2次元配列を書き込みます。正確なテストコードを以下に示します。実際のコードは巨大な並列コードですが、データ出力はほぼ同じ形式です。

program binary_out
implicit none
integer :: i,j,t,rec_array
double precision, dimension(100,100) :: fn
double precision, parameter :: p=2*3.1415929
INQUIRE(IOLENGTH=rec_array) fn
open(unit=10,file='test',status='new',form='unformatted',access='direct',recl=rec_array)                                                                           
   fn=0
   write(10,rec=1) fn
do t=1,3
do i=1,100
   do j=1,100
      fn(i,j)=sin(i*p*t/100)*cos(j*p*t/100)
   enddo
enddo
   write(10,rec=t+1) fn
enddo
close(10)
end program binary_out

プログラムは、t = 1 の場合はゼロを返し、t の値が増加すると「島」の数が増加するはずです。しかし、以下に示すPythonコードを使用してそれを読むと、ゼロが得られます。ゼロの最初の書き込みステートメントを削除すると、Python コードで使用する「タイムスライス」の値に関係なく、最初のタイム スライスが取得されます。私がこれまでに持っているコードは次のとおりです。

#!/usr/bin/env python
import scipy
import glob
import numpy as np
import matplotlib.pyplot as plt
import os, sys
from pylab import *

def readslice(inputfilename,field,nx,ny,timeslice):
   f=open(inputfilename,'r')
   f.seek(timeslice*nx*ny)
   field=np.fromfile(inputfilename,dtype='d',count=nx*ny)
   field=np.reshape(field,(nx,ny))
   return field

a=np.dtype('d')
a=readslice('test',a,100,100,2)

im=plt.imshow(a)
plt.show()

timeslice が i に等しい場合、def readslice が i 番目のレコードを読み取れるようにします。そのために f.seek を使用しようとしましたが、うまくいかないようです。numpy.fromfile は、最初のレコード自体から読み取りを開始するようです。ファイル内の特定のポイントから読み取るように numpy.fromfile を作成するにはどうすればよいですか?

私はまだ Python スタイルに慣れようとしており、ドキュメントを掘り下げています。どんな助けや指針も大歓迎です。

4

2 に答える 2

6

Here is a python code that will work for you:

def readslice(inputfilename,nx,ny,timeslice):
   f = open(inputfilename,'rb')
   f.seek(8*timeslice*nx*ny)
   field = np.fromfile(f,dtype='float64',count=nx*ny)
   field = np.reshape(field,(nx,ny))
   f.close()
   return field

In your original code, you were passing file name as first argument to np.fromfile instead of file object f. Thus, np.fromfile created a new file object instead of using the one that you intended. This is the reason why it kept reading from the beginning of the file. In addition, f.seek takes the number of bytes as argument, not the number of elements. I hardcoded it to 8 to fit your data, but you can make this general if you wish. Also, field argument in readslice was redundant. Hope this helps.

于 2012-05-07T06:52:37.823 に答える
1

すべての FORTRAN ランタイムが同じというわけではありません。フレーム レコードもあれば、そうでないものもあり、フレーミングを記録するものすべてが同じ方法で行うとは確信が持てません。もちろん、通常は自分で書き込んだレコードを読み返すことができますが、ある FORTRAN ランタイムから別の FORTRAN ランタイムへの相互運用性は存在しない可能性があります。

おそらく、選択した FORTRAN で小さなテスト プログラムを作成して、本番コードと同様のレコードをいくつか書き込んでから、お気に入りのバイナリ ファイル エディターを使用して結果を抽出する必要があります。

次に、実際に何が書かれているのかを理解したら、Python struct モジュールなどを使用して元に戻します。

bpe: http://sourceforge.net/projects/bpe/

于 2012-05-07T03:58:21.683 に答える