pythonastropyfitspyfits

Pyfits or astropy.io.fits add row to binary table in fits file


How can I add a single row to binary table inside large fits file using pyfits, astropy.io.fits or maybe some other python library?

This file is used as a log, so every second a single row will be added, eventually the size of the file will reach gigabytes so reading all the file and writing it back or keeping the copy of data in memory and writing it to the file every seconds is actually impossible. With pyfits or astropy.io.fits so far I could only read everything to memory add new row and then write it back.

Example. I create fits file like this:

import numpy, pyfits
data = numpy.array([1.0])
col = pyfits.Column(name='index', format='E', array=data)
cols = pyfits.ColDefs([col])
tbhdu = pyfits.BinTableHDU.from_columns(cols)
tbhdu.writeto('test.fits')

And I want to add some new value to the column 'index', i.e. add one more row to the binary table.


Solution

  • Solution This is a trivial task for cfitsio library (method fits_insert_row(...)), so I use python module which is based on it: https://github.com/esheldon/fitsio

    And here is the solution using fitsio. To create new fits file the one can do:

    import fitsio, numpy
    from fitsio import FITS,FITSHDR
    
    fits = FITS('test.fits','rw')
    data = numpy.zeros(1, dtype=[('index','i4')])
    data[0]['index'] = 1
    fits.write(data)
    fits.close()
    

    To append a row:

    fits = FITS('test.fits','rw')
    #you can actually use the same already opened fits file, 
    #to flush the changes you just need: fits.reopen()
     data = numpy.zeros(1, dtype=[('index','i4')])
     data[0]['index'] = 2
     fits[1].append(data)
     fits.close()
    

    Thank you for your help.