How to save a LightCurve in FITS format?

Once you have detrended or altered a lightcurve in some way, you may want to save it as a FITS file. This allows you to easily share the file with your collaborators or submit your lightcurves as a MAST High Level Science Product (HLSP). Lightkurve provides a to_fits() method which will easily convert your LightCurve object into a fits file.

Below is a brief demostration showing how to_fits() works.

Note: if you are considering contributing a HLSP you may want to read the guidelines for contributing fits files. These include which fits headers are required/suggested for your HLSP to be accepted.

Example: editing and writing a lightcurve

First we’ll obtain a random Kepler lightcurve from MAST.

In [2]:
from lightkurve import search_lightcurvefile
lcf = search_lightcurvefile(757076, quarter=3).download()

Now we’ll make some edits to the lightcurve. Below we use the PDCSAP flux from MAST, remove NaN values and clip out any outliers.

In [3]:
lc = lcf.PDCSAP_FLUX.remove_nans().remove_outliers()
lc.scatter();
../_images/tutorials_2.08-making-fits-files_4_0.png

Now we can use the to_fits method to save the lightcurve to a file called output.fits.

In [4]:
hdu = lc.to_fits(path='output.fits', overwrite=True)

Let’s take a look at the file and check that it behaved as we expect

In [5]:
from astropy.io import fits
hdu = fits.open('output.fits')
hdu
Out[5]:
[<astropy.io.fits.hdu.image.PrimaryHDU object at 0x7f2f1b73cf28>, <astropy.io.fits.hdu.table.BinTableHDU object at 0x7f2f1b714cf8>]

hdu is a set of astropy.io.fits objects, which is what we would expect. Lets take a look at the header of the first extension.

In [6]:
hdu[0].header
Out[6]:
SIMPLE  =                    T / conforms to FITS standards
BITPIX  =                    8 / array data type
NAXIS   =                    0 / number of array dimensions
EXTEND  =                    T / file contains extensions
NEXTEND =                    2 / number of standard extensions
EXTNAME = 'PRIMARY '           / name of extension
EXTVER  =                    1 / extension version number (not format version)
ORIGIN  = 'Unofficial data product' / institution responsible for file
DATE    = '2018-10-23'         / file creation date.
CREATOR = 'lightkurve'         / pipeline job and program used t
TELESCOP= 'KEPLER  '           / telescope
INSTRUME= 'Kepler Photometer'  / detector type
OBJECT  = '757076  '           / string version of target id
KEPLERID=               757076 / unique Kepler target identifier
CHANNEL =                   56 / CCD channel
RADESYS = 'ICRS    '           / reference frame of celestial coordinates
RA_OBJ  =            291.03872 / [deg] right ascension
DEC_OBJ =             36.59813 / [deg] declination
EQUINOX =                 2000 / equinox of celestial coordinate system
PROCVER = '1.0b20  '
QUARTER =                    3
MISSION = 'Kepler  '
DATE-OBS= '2009-09-18T17:53:34.165'
CHECKSUM= 'QTohRTnhQTnhQTnh'   / HDU checksum updated 2018-10-23T14:23:32
DATASUM = '0       '           / data unit checksum updated 2018-10-23T14:23:32

Looks like it has all the correct information about the target. What about the second extension?

In [7]:
hdu[1].header
Out[7]:
XTENSION= 'BINTABLE'           / binary table extension
BITPIX  =                    8 / array data type
NAXIS   =                    2 / number of array dimensions
NAXIS1  =                   28 / length of dimension 1
NAXIS2  =                 4133 / length of dimension 2
PCOUNT  =                    0 / number of group parameters
GCOUNT  =                    1 / number of groups
TFIELDS =                    5 / number of table fields
TTYPE1  = 'TIME    '
TFORM1  = 'D       '
TUNIT1  = 'bkjd    '
TTYPE2  = 'FLUX    '
TFORM2  = 'E       '
TUNIT2  = 'counts  '
TTYPE3  = 'FLUX_ERR'
TFORM3  = 'E       '
TUNIT3  = 'counts  '
TTYPE4  = 'CADENCENO'
TFORM4  = 'J       '
TTYPE5  = 'SAP_QUALITY'
TFORM5  = 'K       '
EXTNAME = 'LIGHTCURVE'
CHECKSUM= 'JEK1MDH1JDH1JDH1'   / HDU checksum updated 2018-10-23T14:23:32
DATASUM = '2548479009'         / data unit checksum updated 2018-10-23T14:23:32

This extension has 4 columns, TIME, FLUX, FLUX_ERR and CADENCENO. This is great! What about if we wanted to add new keywords to our fits file? HLSP products require some extra keywords. Let’s add some keywords to explain who made the data, and what our HLSP is.

In [8]:
hdu = lc.to_fits(path='output.fits',
                 overwrite=True,
                 HLSPLEAD='Kepler/K2 GO office',
                 HLSPNAME='TUTORIAL',
                 CITATION='HEDGES2018')
In [9]:
hdu[0].header
Out[9]:
SIMPLE  =                    T / conforms to FITS standards
BITPIX  =                    8 / array data type
NAXIS   =                    0 / number of array dimensions
EXTEND  =                    T / file contains extensions
NEXTEND =                    2 / number of standard extensions
EXTNAME = 'PRIMARY '           / name of extension
EXTVER  =                    1 / extension version number (not format version)
ORIGIN  = 'Unofficial data product' / institution responsible for file
DATE    = '2018-10-23'         / file creation date.
CREATOR = 'lightkurve'         / pipeline job and program used t
TELESCOP= 'KEPLER  '           / telescope
INSTRUME= 'Kepler Photometer'  / detector type
OBJECT  = '757076  '           / string version of target id
KEPLERID=               757076 / unique Kepler target identifier
CHANNEL =                   56 / CCD channel
RADESYS = 'ICRS    '           / reference frame of celestial coordinates
RA_OBJ  =            291.03872 / [deg] right ascension
DEC_OBJ =             36.59813 / [deg] declination
EQUINOX =                 2000 / equinox of celestial coordinate system
PROCVER = '1.0b20  '
QUARTER =                    3
HLSPLEAD= 'Kepler/K2 GO office'
HLSPNAME= 'TUTORIAL'
CITATION= 'HEDGES2018'
MISSION = 'Kepler  '
DATE-OBS= '2009-09-18T17:53:34.165'
CHECKSUM= 'mDIAm9I3mCI9m9I9'   / HDU checksum updated 2018-10-23T14:23:38
DATASUM = '0       '           / data unit checksum updated 2018-10-23T14:23:38

Now our new keywords are included in the primary header! What about if we want to add more data columns to our fits file? We can simply add this in the same way. Let’s add the data quality to our fits file.

In [10]:
hdu = lc.to_fits(path='output.fits',
                 overwrite=True,
                 HLSPLEAD='Kepler/K2 GO office',
                 HLSPNAME='TUTORIAL',
                 CITATION='HEDGES2018',
                 QUALITY=lc.quality)
In [11]:
hdu[1].header
Out[11]:
XTENSION= 'BINTABLE'           / binary table extension
BITPIX  =                    8 / array data type
NAXIS   =                    2 / number of array dimensions
NAXIS1  =                   36 / length of dimension 1
NAXIS2  =                 4133 / length of dimension 2
PCOUNT  =                    0 / number of group parameters
GCOUNT  =                    1 / number of groups
TFIELDS =                    6 / number of table fields
TTYPE1  = 'TIME    '
TFORM1  = 'D       '
TUNIT1  = 'bkjd    '
TTYPE2  = 'FLUX    '
TFORM2  = 'E       '
TUNIT2  = 'counts  '
TTYPE3  = 'FLUX_ERR'
TFORM3  = 'E       '
TUNIT3  = 'counts  '
TTYPE4  = 'CADENCENO'
TFORM4  = 'J       '
TTYPE5  = 'QUALITY '
TFORM5  = 'K       '
TTYPE6  = 'SAP_QUALITY'
TFORM6  = 'K       '
EXTNAME = 'LIGHTCURVE'
CHECKSUM= 'eoG5glG4elG4elG4'   / HDU checksum updated 2018-10-23T14:23:40
DATASUM = '2652111809'         / data unit checksum updated 2018-10-23T14:23:40

Now the quality from our lightcurve appears in the second extension. Once all your lightcurves are saved as fits files and you have a README file, you can consider submitting your data produces to MAST.