Naresh
Naresh

Reputation: 643

Reading complex binary file in python

I am rather new to python programming so please be a big simple with your answer.

I have a .raw file which is 2b/2b complex short int format. Its actually a 2-D raster file. I want to read and seperate both real and complex parts. Lets say the raster is [MxN] size.

Please let me know if question is not clear.

Cheers N

Upvotes: 0

Views: 4388

Answers (2)

martineau
martineau

Reputation: 123531

You could do it with the struct module. Here's a simple example based on the file formatting information you mentioned in a comment:

import struct

def read_complex_array(filename, M, N):
    row_fmt = '={}h'.format(N)  # "=" prefix means integers in native byte-order
    row_len = struct.calcsize(row_fmt)
    result = []
    with open(filename, "rb" ) as input:
        for col in xrange(M):
            reals = struct.unpack(row_fmt, input.read(row_len))
            imags = struct.unpack(row_fmt, input.read(row_len))
            cmplx = [complex(r,i) for r,i in zip(reals, imags)]
            result.append(cmplx)
    return result

This will return a list of complex-number lists, as can be seen in this output from a trivial test I ran:

[
  [  0.0+  1.0j    1.0+  2.0j    2.0+  3.0j    3.0+  4.0j],
  [256.0+257.0j  257.0+258.0j  258.0+259.0j  259.0+260.0j],
  [512.0+513.0j  513.0+514.0j  514.0+515.0j  515.0+516.0j]
]

Both the real and imaginary parts of complex numbers in Python are usually represented as a pair of machine-level double precision floating point numbers.

You could also use the array module. Here's the same thing using it:

import array

def read_complex_array2(filename, M, N):
    result = []
    with open(filename, "rb" ) as input:
        for col in xrange(M):
            reals = array.array('h')
            reals.fromfile(input, N)
            # reals.byteswap()  # if necessary
            imags = array.array('h')
            imags.fromfile(input, N)
            # imags.byteswap()  # if necessary
            cmplx = [complex(r,i) for r,i in zip(reals, imags)]
            result.append(cmplx)
    return result

As you can see, they're very similar, so it's not clear there's a big advantage to using one over the other. I suspect the array based version might be faster, but that would have to be determined by actually timing it with some real data to be able to say with any certainty.

Upvotes: 2

cleg
cleg

Reputation: 5022

Take a look at Hachoir library. It's designed for this purposes, and does it's work really good.

Upvotes: 0

Related Questions