用Python编写Fortran无格式文件

时间:2013-02-20 16:46:59

标签: python fortran hdf5 dataformat paraview

我有一些由Fortran77编写的单精度little-endian无格式数据文件。我正在使用Python使用以下命令读取这些文件:

import numpy as np
original_data = np.dtype('float32')
f = open(file_name,'rb')                                                                                                 
original_data = np.fromfile(f,dtype='float32',count=-1)                                                                            
f.close()

在Python中进行一些数据操作之后,我(我正在尝试)使用Python使用以下命令以原始格式将它们写回:

out_file = open(output_file,"wb")                                                                                             
s = struct.pack('f'*len(manipulated_data), *manipulated_data)                                                                     
out_file.write(s)
out_file.close()

但它似乎没有起作用。任何想法是什么是使用Python以原始的fortran无格式格式编写数据的正确方法?

问题详情:

我能够使用Fortran中的操作数据读取最终文件。但是,我想使用软件(Paraview)可视化这些数据。为此我转换了* h5格式的无格式数据文件。我能够使用h5实用程序以h5格式转换原始数据和操作数据。但是当Paraview能够读取从原始数据创建的* h5文件时,Paraview无法读取从操纵数据创建的* h5文件。我猜测翻译中丢失了一些东西。

这就是我在Fortran中打开Python编写的文件的方法(单精度数据):

open (in_file_id,FILE=in_file,form='unformatted',access='direct',recl=4*n*n*n)

这就是我正在写Fortran的原始无格式数据:

open(out_file_id,FILE=out_file,form="unformatted")

这些信息是否足够?

2 个答案:

答案 0 :(得分:2)

您是否尝试过使用受控数据数组的.tofile方法?它将以C顺序写入数组,但能够编写纯二进制文件。

.tofile的文档也暗示这与:

相同
with open(outfile, 'wb') as fout:
    fout.write(manipulated_data.tostring())

答案 1 :(得分:2)

这是创建一个无格式的顺序访问文件:

open(out_file_id,FILE=out_file,form="unformatted")

假设您只使用real a(n,n,n)编写单个数组write(out_file_id)a,您应该看到文件大小为4 * n ^ 3 + 8个字节。额外的8个字节是在记录的开头和结尾重复的4字节整数(= 4n ^ 3)。

第二种形式:

open (in_file_id,FILE=in_file,form='unformatted',access='direct',recl=4*n*n*n)

打开直接访问,没有这些标题。现在写你有write(unit,rec=1)a。如果您使用直接访问读取顺序访问文件,它将无错误地读取,但您将获取该整数标头作为浮点数(垃圾)读取(1,1) ,1)数组值,然后其他一切都被移位。你说你可以用fortran阅读,但是你是否希望看到你真的在阅读你的期望?

最好的解决方法是修复原始的fortran代码,以便使用无格式的直接访问来进行读写。这为您提供了“普通”原始二进制文件,没有标题。

或者在你的python中,你需要首先读取4字节整数,然后读取你的数据。在输出时,您可以将整数标头放回或取消,具体取决于您的paraview过滤器所期望的内容。

----------这是python读取/修改/写入包含单个记录的无格式顺序fortran文件:

import struct
import numpy as np
f=open('infile','rb')
recl=struct.unpack('i',f.read(4))[0]
numval=recl/np.dtype('float32').itemsize
data=np.fromfile(f,dtype='float32',count=numval)
endrec=struct.unpack('i',f.read(4))[0]
if endrec is not recl: print "error unexpected end rec"
f.close()
f=open('outfile') 
f.write(struct.pack('i',recl))
for i in range(0,len(data)):data[i] = data[i]**2  #example data modification
data.tofile(f)
f.write(struct.pack('i',recl)

只循环多个记录..请注意,此处的数据被读取为向量并假定为所有浮点数。当然,如果它需要知道要使用的实际数据类型.. 另请注意,您可能需要根据平台处理字节顺序问题。