7

I wrote out a matrix in Fortran as follows:

real(kind=kind(0.0d0)), dimension(256,256,256) :: dense

[...CALCULATION...]

inquire(iolength=reclen)dense
open(unit=8,file=fname,&
form='unformatted',access='direct',recl=reclen)
write(unit=8,rec=1)dense(:,:,:) 
close(unit=8)

I want to read this back into Python. Everything I've seen is for 2D NxN arrays not 3D arrays. In Matlab I can read it as:

fid =    fopen(nfilename,'rb');
mesh_raw = fread(fid,ndim*ndim*ndim,'double');
fclose(fid);
mesh_reshape = reshape(mesh_raw,[ndim ndim ndim]);

I just need the equivalent in Python - presumably there is a similar load/reshape tool available. If there is a more friendly compact way to write it out for Python to understand, I am open to suggestions. It will presumably look something this: . I am just unfamiliar with the equivalent syntax for my case. A good reference would suffice. Thanks.

Community
  • 1
  • 1
Griff
  • 2,064
  • 5
  • 31
  • 47
  • struct.unpack seems like the way to go but I'm not sure what to do for my case. – Griff Dec 11 '12 at 19:57
  • Do any of [these methods using scipy/numpy](http://www.scipy.org/Cookbook/InputOutput#head-b0de67a6dbb3b1ba2584c65263552dc519225cb1) help you? – Jonas Schäfer Dec 11 '12 at 20:02
  • You will find the solution here: http://stackoverflow.com/questions/10475839/reading-a-direct-access-fortran-unformatted-file-in-python – milancurcic Dec 11 '12 at 20:10

2 Answers2

8

Using IRO-bot's link I modified/made this for my script (nothing but numpy magic):

def readslice(inputfilename,ndim):
    shape = (ndim,ndim,ndim)
    fd = open(fname, 'rb')
    data = np.fromfile(file=fd, dtype=np.double).reshape(shape)
    fd.close()
    return data

I did a mean,max,min & sum on the cube and it matches my fortran code. Thanks for your help.

Griff
  • 2,064
  • 5
  • 31
  • 47
  • Just make sure you take into account array dimension ordering difference between Fortran (column major) and Python (row major). – milancurcic Dec 11 '12 at 21:11
  • Isn't there a command to tell it to reorder as fortran at the end of .reshape(shape)? – Griff Dec 12 '12 at 00:51
  • In the case of Fortran array being declared as dimension(im,jm,km), you would want to read it from Python as np.fromfile(file=fd, dtype=np.double).reshape((km,jm,im)). In the case of im=jm=km, you don't need any extra steps, but remember that last index varies fastest. – milancurcic Dec 12 '12 at 04:06
0

I can't see anything but a direct read working here. Python doesn't do a great job of 2-D arrays, let alone 3-d, but this bit of code should work.

fin=open('filename.dat','rb')
output=[]
for x in range(0,ndim):
    xarr=[]
    for y in range(0,ndim):
        yarr=[]
        for z in range(0,ndim):
            yarr.append(struct.unpack('i', fin.read(4)))
        xarr.append(yarr)
   output.append(xarr)
PearsonArtPhoto
  • 38,970
  • 17
  • 111
  • 142