質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

FORTRAN

FORTRAN(フォートラン)は科学時術計算に向いた手続き型プログラミング言語です。 並列計算の最適化が行いやすい特性上、数値予報および気候モデルなどの大規模な計算を行う分野のスーパーコンピュータで使われています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

3回答

1782閲覧

Fortranのバイナリ出力データ(unformatted)をPythonで読む方法が分かりません

YoshitoIshii

総合スコア6

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

FORTRAN

FORTRAN(フォートラン)は科学時術計算に向いた手続き型プログラミング言語です。 並列計算の最適化が行いやすい特性上、数値予報および気候モデルなどの大規模な計算を行う分野のスーパーコンピュータで使われています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2018/05/18 08:46

編集2018/05/19 04:23

前提・実現したいこと

数値計算データを可視化するためにanacondaで描画プログラムを書いています。
以前は地球流体電脳ライブラリ(DCL)を用いて、fortranで計算したデータから以下のようなグラフを可視化できておりました。イメージ説明
今回はfortranで計算したデータをpythonを用いて読み込ませようとしているのですが、配列のデータの切り方が間違っているため、正しい描画ができません。イメージ説明

fortranで一定ステップ計算した後、下記のサブルーチンから(200回程度)出力させているのですが、20回分のデータをpythonで読み込み作図しようとしているがうまくいきません。
pythonのソースコードは以下のリンクを参照して作りました。
http://ig.hateblo.jp/entry/2014/05/30/225607

該当のソースコード

fortran

1 2 subroutine writefile(u,v,h) 3 implicit none 4 real(8),dimension(1:im ,1:jm ,1:3 ),intent(in)::u,v 5 real(8),dimension(1:im ,0:jm ,1:3 ),intent(in)::h 6 real(4),dimension(1:im ,1:jm ,1:3 ) ::uvh 7 integer::i,j,m 8 9 open(11,file='uvh.dat', status='unknown', form='unformatted') 10 11 do j=1,jm 12 do i=1,im 13 uvh(i,j,1)=real(u(i,j,2)) 14 uvh(i,j,2)=real(v(i,j,2)) 15 uvh(i,j,3)=real(h(i,j,2)) 16 enddo 17 enddo 18 write(11) (((uvh(i,j,m),i=1,im),j=1,jm),m=1,3) 19 return 20 end subroutine writefile 21 22 23*pythonのデータ読み取り箇所 24 25import numpy as np 26 27im = 202 28jm = 481 29nstep = 20 30 31# %% 0.fromfileを用いたファイル読み込み 32f90 = open('uvh.dat', 'rb') 33ary = np.fromfile(f90, np.float32,count=im*jm*3*20) 34 35# %% 1.読み込んだn番目の要素を取り出し、fortran形式の4次元配列に 36uvhpy = ary.reshape(jm,im,3,nstep, order='F') # 1要素あたり4byte×202*481*3=4×291486=1165944byte 37 38# %% 2.コンターを作図する 39import matplotlib.pyplot as plt 40 41x = np.linspace(0,50 , im) 42y = np.linspace(-60, 60, jm) 43X, Y = np.meshgrid(x, y) 44 45for i in range(nstep): 46 Z = uvhpy[:, :,2,i] 47 plt.contour(X,Y,Z) 48 plt.show() 49

試したこと

pythoでのforループをなしにして、ary内のcount=imjm3として、uvhpyを3次元配列とreshapeして描かせたら、グラフらしきものは出てきました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

多分 open(11, 云々 ,access='stream') でデータべた書きにしないと駄目なのでは?
unformatted だけだとバイナリで書き出すがレコード区切りが入る。 stream は Fortran2003 以降の属性だが、昔風には direct access 形式でもまぁ普通は行けなくもない。

あと、DO LOOP を書かずに全配列操作を使えばいいのでは?
open(11,file='uvh.dat', status='unknown', form='unformatted, access='stream')
uvh(:,:,1)=real(u(:,:,2))
uvh(:,:,2)=real(v(:,:,2))
uvh(:,:,3)=real(h(:,:,2))
write(11) uvh
これだけでいいはず。
もしくは、いちいち代入せずに
open(11,file='uvh.dat', status='unknown', form='unformatted, access='stream')
write(11) real(u(:,:,2))
write(11) real(v(:,:,2))
write(11) real(h(:,:,2))
でも同じ事だと思う。

投稿2018/05/23 18:12

curehoney

総合スコア249

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

あなたのお使いのFortrunの浮動小数点形式は4バイトなんでしょうか。
そして、その形式はPythonのそれと同一なんでしょうか。
まずそこから確認する必要があると思いますが。

投稿2018/05/18 12:39

y_waiwai

総合スコア87749

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YoshitoIshii

2018/05/19 03:51

まず、fortranのソースコードをコンパイルする際にインテルfortranを用いています。書き出しているデータは単精度実数浮動小数点値で、データ型はrea(4)、記憶域は4バイトです。 http://wwweic.eri.u-tokyo.ac.jp/computer/manual/altix/compile/Fortran/Intel_Fdoc100/main_for/mergedProjects/bldaps_for/common/bldaps_datarepov.htm 次に、pythonでのnumpyを用いた読み込みでは、データ型はnp.float32を明示しています。これは32bitで単精度の浮動小数点数として同一の対応をさせていると思います。 https://deepage.net/features/numpy-dtype.html 当方、基本がよく分かっていないので的外れな回答になっているかもしれません。ご不明な点があれば都度いただければ幸甚です。
y_waiwai

2018/05/19 13:27

なら、単純な浮動小数点数をいくつか並べた1次元配列をバイナリデータとして保存し、それをpythonで読み込んで期待する結果になるか確認することですね。 それで期待する結果になるのを確認したあと、それを2次元配列で同様にやってみる、ってことが必要なんじゃないでしょうか
guest

0

fortran

1program test 2 implicit none 3 real(4),dimension(1:10, 1:10, 1:3) :: u=0d0 4 integer :: i,j,k,m 5 open(11, file='test.dat', form='unformatted') 6 do m=1,20 7 do i=1,10 8 do j=1,10 9 u(i,j,1) = 1 10 u(i,j,2) = 2 11 u(i,j,3) = 3 12 enddo 13 enddo 14 write(11) (((u(i,j,k), i=1,10), j=1,10), k=1,3) 15 end do 16 return 17end program test

python

1import numpy as np 2from scipy.io import FortranFile 3 4im = 10 5jm = 10 6nstep = 10 7 8f90 = open('test.dat', 'rb') 9ary = np.fromfile(f90, np.float32, count=nstep*im*jm*3) 10 11uvhpy = ary.reshape(im, jm, 3, 10, order='F') # byte×202*481*3=4×291486=1165944 12print(uvhpy[:, :, 2, 0]) 13 14#----------OR---------- 15#uvhpy = ary.reshape(10, 3, jm, im) # byte×202*481*3=4×291486=1165944 16#print(uvhpy[0, 2, :, :])

事前に.transpose(0,1,3,2)を入れてみてはいかがですか?
for文で抽出する際のnumpy.arrayの次元を疑っています。
shapeが(n,1)になっていませんか?


手元でやってみたところ、再現しませんでした。
uvhpy = ary.reshape(jm,im,3,20)#, order='F')
ではなく、
uvhpy = ary.reshape(jm,im,3,20, order='F')
で正しかったのでは?

投稿2018/05/18 12:29

編集2018/05/23 21:50
mkgrei

総合スコア8560

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YoshitoIshii

2018/05/19 04:34

編集した「前提・実現したいこと」に、ご指摘いただいた uvhpy = ary.reshape(jm,im,3,20, order='F') を基にしたグラフの1枚目を掲載しました。 uvhpyの4つ目の要素は、fortranからの数値計算を何回読み込むかを意図しているつもりです。しかし複数のグラフをループで描かせたい場合は、配列の次元数を無闇に増やさず、別のデータの切り出し方を考えたほうが賢明でしょうか?
mkgrei

2018/05/19 04:58

配列の並び方が異なるので、20回だけ欲しい場合でも、書き出し分を全部読み込んでみてください。
YoshitoIshii

2018/05/20 08:02 編集

了解しました。変数aryで全てのデータを読み込みさせます。 追加で教えていただきたい点を1つだけリクエストさせてください。pythonでのreshape内部の変数を複数設定した場合(例えば(jm,im,m,nstep))、読まれるのはカッコ内の先頭からループ順番からでしょうか? 現状の問題に即すると、fortran側から計算結果を書き出したのは、外側からm,j,iの順で3重ループにしたと思っています。これをnstep回行ったと理解しています。numpy側から1次元データとして読み、データ列からreshapeを通じて配列を復元する場合、(nstep,m,j,i)と順序を変更したらうまくいくのではと考えました。 (この変数の順序ではreshapeできないよ、というエラーが出てきてワークしない結果を得ました。またfortran側の配列データにない、変数nstepをもって配列の次元数を変えてしまっているのも正確な配列復元の邪魔をしているのではないかなと思います。)
mkgrei

2018/05/23 21:56

私が少し混乱していたようです。 上のコードを2つ追記しました。 これで挙動を確認していただければわかると思います。 (nstep,3,j,i)か(i,j,3,nstep)+order='F'かですね。 読み込まれた後、軸の順番が異なることに気をつけてください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問