2

I have multiple tables created with astropy.table.Table, for example:

 from astropy.table import Table
 import numpy as np
 #table 1
 ta=Table()
 ta["test1"]=np.arange(0,100.)
 #table 2
 tb=Table()
 tb["test2"]=np.arange(0,100.)

I can save them individually to .fits files using

ta.write('table1.fits')
tb.write('table2.fits')

But I would like to have them saved to the same .fits file, each of them with a different hdu. How can I do that?

Drise
  • 3,976
  • 4
  • 34
  • 61
Julia Roquette
  • 347
  • 2
  • 15

2 Answers2

5

There's a utility function astropy.io.fits.table_to_hdu.

To continue your example if you have two table objects ta and tb:

from astropy.io import fits
hdu_list = fits.HDUList([
    fits.PrimaryHDU(),
    fits.table_to_hdu(ta),
    fits.table_to_hdu(tb), 
])
hdu_list.writeto('tables.fits')
Christoph
  • 2,210
  • 1
  • 15
  • 22
1

There's an example of how to do this here. So, you could do something like the following:

import numpy as np
from astropy.io import fits

ta = Table()
ta['test1'] = np.arange(0, 100.)
col1 = fits.Column(name=ta.colnames[0], format='E', array=ta)

tb = Table()
tb['test2'] = np.arange(0, 100.)
col2 = fits.Column(name=tb.colnames[0], format='E', array=tb)

cols = fits.ColDefs([col1, col2])

hdu = fits.BinTableHDU.from_columns(cols)
hdu.writeto('table.fits')

which only has one binary table HDU, but with two columns. Alternatively, to add them as separate HDUs, you could do something like

ta = Table()
ta['test1'] = np.arange(0, 100.)
col1 = fits.Column(name=ta.colnames[0], format='E', array=ta)

hdu1 = fits.BinTableHDU.from_columns(fits.ColDefs([col1]))

tb = Table()
tb['test2'] = np.arange(0, 100.)
col2 = fits.Column(name=tb.colnames[0], format='E', array=tb)

hdu2 = fits.BinTableHDU.from_columns(fits.ColDefs([col2]))

# create a header
hdr = fits.Header()
hdr['Author'] = 'Me'
primary_hdu = fits.PrimaryHDU(header=hdr)

# put all the HDUs together
hdul = fits.HDUList([primary_hdu, hdu1, hdu2])

# write it out
hdul.writeto('table.fits')
Matt Pitkin
  • 1,193
  • 9
  • 20
  • But this example creates a `.fits` table that include the two tables as part of the same table. Even though in my simplified example I gave examples of two tables with one column, building a table with two columns based on the simpler one is not what I want. As I said in the question, I want to build a `.fits` file with each table in one hdu. – Julia Roquette Mar 20 '18 at 15:17
  • @JuliaRoquette - I've edited the answer to hopefully do what you require. Does the edited answer help? – Matt Pitkin Mar 20 '18 at 15:18
  • the edited answer help, yes. But there is a small miss-spell on it which produces an error: I checked on pyfits and the right name for the module is `ColDefs` instead of `ColsDef` that you wrote. – Julia Roquette Mar 20 '18 at 15:27
  • @Christoph's solution is a bit neater than mine, so I'd recommend that – Matt Pitkin Mar 20 '18 at 17:09
  • You don't necessarily need all this stuff either: `hdu1 = fits.BinTableHDU.from_columns(fits.ColDefs([col1]))` Much of the manual construction of FITS table structures can be simplified for example by using [Table.as_array()](http://docs.astropy.org/en/stable/api/astropy.table.Table.html#astropy.table.Table.as_array), since `BinTableHDU.from_columns` accepts a multi-field Numpy array. So `BinTableHDU.from_columns(table.as_array())` works here (I think that's what `table_to_hdu()` is mostly doing as well). – Iguananaut Mar 22 '18 at 17:08