[Numpy-discussion] example reading binary Fortran file
Neil Martinsen-Burrell
nmb at wartburg.edu
Fri May 29 22:55:50 EDT 2009
On 2009-05-29 10:12 , David Froger wrote:
> I think the FortranFile class is not intended to read arrays written
> with the syntax 'write(11) array1, array2, array3' (correct me if I'm
> wrong). This is the use in the laboratory where I'm currently
> completing a phd.
You're half wrong. FortranFile can read arrays written as above, but it
sees them as a single real array. So, with the attached Fortran program::
In [1]: from fortranfile import FortranFile
In [2]: f = FortranFile('uxuyp.bin', endian='<') # Original bug was
incorrect byte order
In [3]: u = f.readReals()
In [4]: u.shape
Out[4]: (20,)
In [5]: u
Out[5]:
array([ 101., 111., 102., 112., 103., 113., 104., 114., 105.,
115., 201., 211., 202., 212., 203., 213., 204., 214.,
205., 215.], dtype=float32)
In [6]: ux = u[:10].reshape(2,5); uy = u[10:].reshape(2,5)
In [7]: p = f.readReals().reshape(2,5)
In [8]: ux, uy, p
Out[8]:
(array([[ 101., 111., 102., 112., 103.],
[ 113., 104., 114., 105., 115.]], dtype=float32),
array([[ 201., 211., 202., 212., 203.],
[ 213., 204., 214., 205., 215.]], dtype=float32),
array([[ 301., 311., 302., 312., 303.],
[ 313., 304., 314., 305., 315.]], dtype=float32))
What doesn't currently work is to have arrays of mixed types in the same
write statement, e.g.
integer :: index(10)
real :: x(10,10)
...
write(13) x, index
To address the original problem, I've changed the code to default to the
native byte-ordering (f.ENDIAN='@') and to be more informative about
what happened in the error. In the latest version (attached):
In [1]: from fortranfile import FortranFile
In [2]: f = FortranFile('uxuyp.bin', endian='>') # incorrect endian-ness
In [3]: u = f.readReals()
IOError: Could not read enough data. Wanted 1342177280 bytes, got 132
and hopefully when people see crazy big numbers like 1.34e9 they will
think of byte order problems.
> I'm going to dive into struc, FotranFile etc.. to propose something
> convenient for people who have to read unformatted binary fortran file
> very often.
Awesome! The thoughts banging around in my head right now are that some
sort of mini-language that encapsulates the content of the declarations
and the write statements should allow one to tease out exactly which
struct call will unpack the right information. f2py has some fortran
parsing capabilities, so you might be able to use the fortran itself as
the mini-language. Something like
spec = fortranfile.OutputSpecification(\
"""real(4),dimension(2,5):: ux,uy
write(11) ux,uy""")
ux, uy = fortranfile.FortranFile('uxuyp.bin').readSpec(spec)
Best of luck. Peace,
-Neil
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: fortranfile.py
URL: <http://mail.python.org/pipermail/numpy-discussion/attachments/20090529/f24fb616/attachment.ksh>
More information about the NumPy-Discussion
mailing list