astronomyastropyfitspyfits

Copying fits-file data and/or header into a new fits-file


Similar question was asked before, but asked in an ambigous way and using a different code. My problem: I want to make an exact copy of a .fits-file header into a new file. (I need to process a fits file in way, that I change the data, keep the header the same and save the result in a new file). Here a short example code, just demonstrating the tools I use and the discrepancy I arrive at:

data_old, header_old = fits.getdata("input_file.fits", header=True)
fits.writeto('output_file.fits', data_old, header_old, overwrite=True)

I would expect now that the the files are exact copies (headers and data of both being same). But if I check for difference, e.g. in this way -

fits.printdiff("input_file.fits", "output_file.fits")

I see that the two files are not exact copies of each other. The report says:

...
Files contain different numbers of HDUs:
 a: 3
 b: 2

Primary HDU:

   Headers contain differences:
     Headers have different number of cards:
      a: 54
      b: 4
...

Extension HDU 1:

   Headers contain differences:
     Keyword GCOUNT   has different comments:
...

Why is there no exact copy? How can I do an exact copy of a header (and/or the data)? Is a key forgotten? Is there an alternative simple way of copy-pasting a fits-file-header?


Solution

  • If you just want to update the data array in an existing file while preserving the rest of the structure, have you tried the update function?

    The only issue with that is it doesn't appear to have an option to write to a new file rather than update the existing file (maybe it should have this option). However, you can still use it by first copying the existing file, and then updating the copy.

    Alternatively, you can do things more directly using the object-oriented API. Something like:

    with fits.open(filename) as hdu_list:
        hdu = hdu_list[<name or index of the HDU to update>]
        hdu.data = <new ndarray>
        # or hdu.data[<some index>] = <some value> i.e. just directly modify the existing array
        hdu.writeto('updated.fits')  # to write just that HDU to a new file, or
        # hdu_list.writeto('updated.fits')  # to write all HDUs, including the updated one, to a new file
    

    There's nothing not "pythonic" about this :)