Question

The following is a snippet of code from my program:

def get_data(self):
    self.position = self.hfile.tell()/self.sizeof_data


    try:
        self.iq = scipy.fromfile(self.hfile, dtype=self.datatype, count=self.block_length)


    except MemoryError:
        print "End of File"
    else:
        self.iq_fft = self.dofft(self.iq)
    x = self.iq_fft

        maximum = np.argmax(x)
        average = np.mean(x)

    print "\nAvage Value: ", average 

        #set up Get Data loop
        loops = self.files/self.block_length
        self.counter += 1
        count = self.counter
        count += 1
        print "\nCOUNT: ", count
        #print "\nloop: ", loops

    if count == loop:
        raise SystemExit #Exits program gracefully
    else:   
        self.get_data()



def dofft(self, iq):
    N = len(iq)

    iq_fft = scipy.fftpack.fftshift(scipy.fft(iq))       # fft and shift axis


    iq_fft = scipy.log10(abs((iq_fft))) # convert to decibels, adjust power
    # adding 1e-15 (-300 dB) to protect against value errors if an item in iq_fft is 0

    return iq_fft

It works great unless loop is greater than 989, then the whole thing blows up. I have seen some talk about how in Python recursion is limited to 999, so I know that's the problem, but how can I rewrite the loop to avoid the error? The loop has potential to get pretty large so I don't think using the setrecursionlimit() function is a good idea.

Was it helpful?

Solution

I don't understand why you wrote this as recursion when it's clearly an iterative process (reading a file block by block, as I understand it).

def get_data(self):
    for count in range(self.files/self.block_length):
        self.position = self.hfile.tell()/self.sizeof_data

        try:
            self.iq = scipy.fromfile(self.hfile, dtype=self.datatype, count=self.block_length)
        except MemoryError:
            print "End of File"

        self.iq_fft = self.dofft(self.iq)
        x = self.iq_fft

        maximum = np.argmax(x)
        average = np.mean(x)

        print "\nAverage Value: ", average 

        self.counter += 1
        print "\nCOUNT: ", count
    raise SystemExit

OTHER TIPS

It's a bit hard to tell exactly what you are trying to accomplish, but it looks like you need something like

import scipy as sp
import scipy.fftpack as sf

def db_fft(block):
    res = sp.fft(block)         # compute FFT
    res = sf.fftshift(res)      # shift axis
    res = sp.log10(abs((res)))  # convert to db, adjust power
    return res

class BlockFFT:
    def __init__(self, fname, dtype=sp.float64, blocksize=256*256):
        self.hfile     = open(fname, "rb")
        self.dtype     = dtype      # data type
        self.blocksize = blocksize  # number of items per step

    def next(self):
        try:
            block = scipy.fromfile(self.hfile, dtype=self.dtype, count=self.blocksize)
            fft   = db_fft(block)
            return fft, sp.argmax(fft), sp.mean(fft)
        except MemoryError:
            self.hfile.close()
            raise StopIteration()

def main():
    for fft, max_, avg_ in BlockFFT("myfile.dat"):
        # now do something with it
        pass

if __name__=="__main__":
    main()

Maybe this:

while count != loop
    #run whatever is in get data
else
    raise SystemExit

If you provided more information, though, I might go for a for loop instead.

Get your function to return a bound function then run it until no function is returned. You can bind a function using partial in functools.

from functools import partial
def yourfunc(test):
    # code
    if answer:
        return answer
    return partial(yourfunc,boundvariable)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top