pythonfor-loopfits

Loading multiple fits files through one line


I have 200 fits files that I need to load in and average out to create a map. However, I was wondering if there is a way to do this all in one line rather than 200 "fits.open" lines. I saw it somewhere but I cannot recall where.

The file names go as Coadd000_5.fits, Coadd001_5.fits, Coadd002_5.fits, Coadd003_5.fits ... Coadd199_5.fits.

So it has to be something similar to

hdulist2 = fits.open('/Users/alibinesh/Desktop/Data/actpolS2Lensing/actPolS2LensProducts/realKappaCoadd' + xyz + '_5.fit')

or something similar to that. Would I have to do a for loop with i going from 0 to 199?


Solution

  • You may be trying to remember the list comprehension which is a neat, readable way of doing for loops.

    mylist = [ deal_with( 'realKappaCoadd%03d_5.fit' % i ) for i in range(200) ]
    

    (file path shortened for readability)

    Any time you find yourself wanting to initialize an empty list and then .append() to it in a for loop, think "list comprehension" to do it in one line. Or "generator expression", which is a closely-related syntax but one which evaluates lazily (that would allow you to process thing "depth-first" while superficially appearing to go breadth-first, but I doubt there's any real advantage to that in your case).

    You might also find it useful to iterate over the output of glob which will find all filenames matching a certain pattern:

    import glob
    list_of_filenames = sorted( glob.glob( 'realKappaCoadd*_5.fit' ) )
    mylist = [ deal_with( filename ) for filename in list_of_filenames ]
    

    Since (from comments) it seems that opening a fits file entails a lot of overhead, you probably only want one open at a time. Therefore you should operate efficiently "depth-first", completely finishing your business with one file before moving on to the next. IMO the most readable way of doing that is to put all the necessary steps for one file, in sequence, in your deal_with function:

    def deal_with(single_filename):
        file_handle = fits.open(single_filename)
        result = do_whatever_processing(file_handle)
        # ...
        # if necessary, explicitly close the file here
        return result