Using Target Pixel Files with Lightkurve#

Learning Goals#

By the end of this tutorial, you will:

  • Be able to download and plot target pixel files from the data archive using Lightkurve.

  • Be able to access target pixel file metadata.

  • Understand where to find more details about Kepler target pixel files.

Introduction#

The Kepler, K2, and TESS telescopes observe stars for long periods of time, from just under a month to four years. By doing so they observe how the brightnesses of stars change over time.

Kepler selected certain pixels around targeted stars to be downloaded from the spacecraft. These were stored as target pixel files that contain data for each observed cadence. In this tutorial, we will learn how to use Lightkurve to download these raw data, plot them, and understand their properties and units.

It is recommended that you first read the tutorial on how to use Kepler light curve products with Lightkurve. That tutorial will introduce you to some specifics of how Kepler, K2, and TESS make observations, and how these are displayed as light curves. It also introduces some important terms and concepts that are referred to in this tutorial.

Kepler observed a single field in the sky, although not all stars in this field were recorded. Instead, pixels were selected around certain targeted stars. This series of cutouts were downloaded and stored as an array of images in target pixel files, or TPFs. By summing up the amount of light (the flux) captured by the pixels in which the star appears, you can make a measurement of the brightness of a star over time.

TPFs are an important resource when studying an astronomical object with Kepler, K2, or TESS. The files allow us to understand the original images that were collected, and identify potential sources of noise or instrument-induced trends which may be less obvious in derived light curves. In this tutorial, we will use the Kepler mission as the main example, but these tools equally work for TESS and K2.

Imports#

This tutorial requires Lightkurve, which in turn uses matplotlib for plotting.

[1]:
import lightkurve as lk
%matplotlib inline

1. What is a Target Pixel File?#

The target pixel file (TPF) of a star contains an image for each observing cadence, either a 30-minute Long Cadence or one-minute Short Cadence exposure in the case of Kepler. The files also include metadata detailing how the observation was made, as well as post-processing information such as the estimated intensity of the astronomical background in each image. (Read the Kepler Archive Manual, Section 2.3.2 for more information.)

TPFs are stored in a FITS file format. The Lightkurve package allows us to work with these binary files without having to worry about the details of the file structure. For examples on how to work with FITS files directly, read this tutorial on Plotting Images from Kepler Target Pixel Files.

2. Downloading a Target Pixel File#

The TPFs of stars observed by the Kepler mission are stored on the Mikulksi Archive for Space Telescopes (MAST) archive, along with metadata about the observations, such as which charge-coupled device (CCD) was used at each time.

Lightkurve’s built-in tools allow us to search and download TPFs from the archive. As we did in the accompanying tutorial on light curves, we will start by downloading one quarter (a Kepler observing period approximately 90 days in duration) of Kepler data for the star named Kepler-8, a star somewhat larger than the Sun, and the host of a hot Jupiter planet.

Using the search_targetpixelfile function, we can find an itemized list of different TPFs available for Kepler-8.

[2]:
search_result = lk.search_targetpixelfile("Kepler-8", author="Kepler", cadence="long")
search_result
[2]:
SearchResult containing 18 data products.
#missionyearauthorexptimetarget_namedistance
sarcsec
0Kepler Quarter 002009Kepler1800kplr0069222440.0
1Kepler Quarter 012009Kepler1800kplr0069222440.0
2Kepler Quarter 022009Kepler1800kplr0069222440.0
3Kepler Quarter 032009Kepler1800kplr0069222440.0
4Kepler Quarter 042010Kepler1800kplr0069222440.0
5Kepler Quarter 052010Kepler1800kplr0069222440.0
.....................
11Kepler Quarter 112012Kepler1800kplr0069222440.0
12Kepler Quarter 122012Kepler1800kplr0069222440.0
13Kepler Quarter 132012Kepler1800kplr0069222440.0
14Kepler Quarter 142012Kepler1800kplr0069222440.0
15Kepler Quarter 162013Kepler1800kplr0069222440.0
16Kepler Quarter 152013Kepler1800kplr0069222440.0
17Kepler Quarter 172013Kepler1800kplr0069222440.0
Length = 18 rows

In this list, each row represents a different observing period. We find that Kepler recorded 18 quarters of data for this target across four years. The search_targetpixelfile() function takes several additional arguments, such as the quarter number or the mission name. You can find examples of its use in the online documentation for this function.

The search function returns a SearchResult object which has several convenient operations. For example, we can select the fourth data product in the list as follows:

[3]:
search_result[4]
[3]:
SearchResult containing 1 data products.
#missionyearauthorexptimetarget_namedistance
sarcsec
0Kepler Quarter 042010Kepler1800kplr0069222440.0

We can download this data product using the download() method.

[4]:
tpf = search_result[4].download()

This instruction is identical to the following line:

[5]:
tpf = lk.search_targetpixelfile("Kepler-8", author="Kepler", cadence="long", quarter=4).download()

The tpf_file variable we have obtained in this way is a KeplerTargetPixelFile object.

[6]:
tpf
[6]:
KeplerTargetPixelFile Object (ID: 6922244)

This file object provides a convenient way to interact with the data file that has been returned by the archive, which contains both the TPF as well as metadata about the observations.

Before diving into the properties of the KeplerTargetPixelFile, we can plot the data, also using Lightkurve.

[7]:
%matplotlib inline
tpf.plot();
../../_images/tutorials_1-getting-started_using-target-pixel-file-products_21_0.png

What you are seeing in this figure are pixels on the CCD camera, with which Kepler-8 was observed. The color indicates the amount of flux in each pixel, in electrons per second. The y-axis shows the pixel row, and the x-axis shows the pixel column. The title tells us the Kepler Input Catalogue (KIC) identification number of the target, and the observing cadence of this image. By default, plot() shows the first observation cadence in the quarter, but this can be changed by passing optional keyword arguments. You can type help(tpf.plot) to see a full list of those options.

Note#

You can also download TPF FITS files from the archive by hand, store them on your local disk, and open them using the lk.read(<filename>) function. This function will return a KeplerTargetPixelFile object just as in the above example. You can find out where Lightkurve stored a given TPF by typing tpf.path:

[8]:
tpf.path
[8]:
'/Users/chedges/.lightkurve/cache/mastDownload/Kepler/kplr006922244_lc_Q111111111111111111/kplr006922244-2010078095331_lpd-targ.fits.gz'

3. Accessing the Metadata#

Our KeplerTargetPixelFile includes the observation’s metadata, loaded from the header of the TPF files downloaded from MAST. Many of these are similar to the metadata stored in the KeplerLightCurve, which are discussed in the accompanying tutorial.

The headers containing the metadata can be accessed from the KeplerTargetPixelFile through the get_header() method.

For example, the first extension (“extension 0”) of the file provides metadata related to the star, such as its magnitude in different passbands, its movement and position on the sky, and its location on Kepler’s CCD detector:

[9]:
tpf.get_header(ext=0)
[9]:
SIMPLE  =                    T / conforms to FITS standard
BITPIX  =                    8 / array data type
NAXIS   =                    0 / number of array dimensions
EXTEND  =                    T
NEXTEND =                    2 / number of standard extensions
EXTNAME = 'PRIMARY '           / name of extension
EXTVER  =                    1 / extension version number (not format version)
ORIGIN  = 'NASA/Ames'          / institution responsible for creating this file
DATE    = '2015-09-23'         / file creation date.
CREATOR = '917482 TargetPixelExporterPipelineModule' / pipeline job and program
PROCVER = 'svn+ssh://murzim/repo/soc/tags/release/9.3.25 r60410' / SW version
FILEVER = '6.1     '           / file format version
TIMVERSN= 'OGIP/93-003'        / OGIP memo number for file format
TELESCOP= 'Kepler  '           / telescope
INSTRUME= 'Kepler Photometer'  / detector type
OBJECT  = 'KIC 6922244'        / string version of target id
KEPLERID=              6922244 / unique Kepler target identifier
CHANNEL =                   31 / CCD channel
SKYGROUP=                   31 / roll-independent location of channel
MODULE  =                   10 / CCD module
OUTPUT  =                    3 / CCD output
QUARTER =                    4 / Observing quarter
SEASON  =                    2 / mission season during which data was collected
DATA_REL=                   25 / data release version number
OBSMODE = 'long cadence'       / observing mode
MISSION = 'Kepler  '           / Mission name
TTABLEID=                   29 / target table id
RADESYS = 'ICRS    '           / reference frame of celestial coordinates
RA_OBJ  =           281.288120 / [deg] right ascension
DEC_OBJ =            42.451080 / [deg] declination
EQUINOX =               2000.0 / equinox of celestial coordinate system
PMRA    =               0.0000 / [arcsec/yr] RA proper motion
PMDEC   =               0.0000 / [arcsec/yr] Dec proper motion
PMTOTAL =               0.0000 / [arcsec/yr] total proper motion
PARALLAX=                      / [arcsec] parallax
GLON    =            71.658900 / [deg] galactic longitude
GLAT    =            19.012749 / [deg] galactic latitude
GMAG    =               13.886 / [mag] SDSS g band magnitude
RMAG    =               13.511 / [mag] SDSS r band magnitude
IMAG    =               13.424 / [mag] SDSS i band magnitude
ZMAG    =               13.413 / [mag] SDSS z band magnitude
D51MAG  =               13.700 / [mag] D51 magnitude,
JMAG    =               12.576 / [mag] J band magnitude from 2MASS
HMAG    =               12.323 / [mag] H band magnitude from 2MASS
KMAG    =               12.292 / [mag] K band magnitude from 2MASS
KEPMAG  =               13.563 / [mag] Kepler magnitude (Kp)
GRCOLOR =                0.375 / [mag] (g-r) color, SDSS bands
JKCOLOR =                0.284 / [mag] (J-K) color, 2MASS bands
GKCOLOR =                1.594 / [mag] (g-K) color, SDSS g - 2MASS K
TEFF    =                 6225 / [K] Effective temperature
LOGG    =                4.169 / [cm/s2] log10 surface gravity
FEH     =               -0.040 / [log10([Fe/H])]  metallicity
EBMINUSV=                0.096 / [mag] E(B-V) reddening
AV      =                0.297 / [mag] A_v extinction
RADIUS  =                1.451 / [solar radii] stellar radius
TMINDEX =            262064792 / unique 2MASS catalog ID
SCPID   =            262064792 / unique SCP processing ID
CHECKSUM= 'HkS5JjR5HjR5HjR5'   / HDU checksum updated 2015-09-23T02:52:42Z

This is an Astropy `astropy.io.fits.Header <https://docs.astropy.org/en/stable/io/fits/api/headers.html>`__ object, which has many convenient features. For example, you can retrieve the value of an individual keyword as follows:

[10]:
tpf.get_header(ext=0).get('QUARTER')
[10]:
4

When constructing a KeplerTargetPixelFile from a FITS file, Lightkurve carries a subset of the metadata through into user-friendly object properties for convenience, which are available through shorthands (for example, tpf.quarter). You can view these properties with the the show_properties() method:

[11]:
tpf.show_properties()
   Attribute                                                                 Description
--------------- --------------------------------------------------------------------------------------------------------------------------------------
        channel                                                                                                                                     31
         column                                                                                                                                    680
         module                                                                                                                                     10
         output                                                                                                                                      3
        quarter                                                                                                                                      4
            row                                                                                                                                    188
       targetid                                                                                                                                6922244
        mission                                                                                                                                 Kepler
        obsmode                                                                                                                           long cadence
           path /Users/chedges/.lightkurve/cache/mastDownload/Kepler/kplr006922244_lc_Q111111111111111111/kplr006922244-2010078095331_lpd-targ.fits.gz
quality_bitmask                                                                                                                                default
            hdu                                                                                                        PRIMARY, TARGETTABLES, APERTURE
      cadenceno                                                                                                                          array (4116,)
           flux                                                                                                                     array (4116, 5, 5)
       flux_bkg                                                                                                                     array (4116, 5, 5)
   flux_bkg_err                                                                                                                     array (4116, 5, 5)
       flux_err                                                                                                                     array (4116, 5, 5)
  nan_time_mask                                                                                                                          array (4116,)
  pipeline_mask                                                                                                                           array (5, 5)
      pos_corr1                                                                                                                          array (4116,)
      pos_corr2                                                                                                                          array (4116,)
        quality                                                                                                                          array (4116,)
   quality_mask                                                                                                                          array (4397,)
       campaign                                                                                                                     <class 'NoneType'>
            dec                                                                                                                        <class 'float'>
           meta                                                                                  <class 'lightkurve.targetpixelfile.HduToMetaMapping'>
             ra                                                                                                                        <class 'float'>
          shape                                                                                                                        <class 'tuple'>
           time                                                                                                       <class 'astropy.time.core.Time'>
            wcs                                                                                                                    astropy.wcs.wcs.WCS

A new piece of metadata not included in the KeplerLightCurve objects is the World Coordinate System (WCS). The WCS contains information about how pixel positions map to celestial sky coordinates. This is important when comparing a TPF from a Kepler, K2, or TESS observation to an observation of the same star with a different telescope.

You can access the WCS using tpf.wcs, which is an Astropy WCS object:

[12]:
type(tpf.wcs)
[12]:
astropy.wcs.wcs.WCS

For example, you can obtain the sky coordinates for the bottom left corner of the TPF as follows:

[13]:
tpf.wcs.pixel_to_world(0, 0)
[13]:
<SkyCoord (ICRS): (ra, dec) in deg
    (281.28757136, 42.44722193)>

Altogether, the metadata contains a lot of information, and you will rarely use it all, but it is important to know that it is available if you need it. For more details and a better overview of all of the metadata stored in a TPF, read the Kepler Archive Manual, specifically: - Section 2.3.2 Target Pixel Data - Appendix A.1: Target Pixel File Headers

4. Time, Flux, and Background#

Finally, we have the most important properties of the TPF: the time and flux information. Just like a KeplerLightCurve object, we can access the time information as an Astropy Time object as follows:

[14]:
tpf.time
[14]:
<Time object: scale='tdb' format='bkjd' value=[352.37632485 352.39675805 352.43762445 ... 442.16263546 442.18306983
 442.2035041 ]>

The pixel brightness data is available as an Astropy Quantity object named tpf.flux:

[15]:
tpf.flux
[15]:
$[[[{\rm NaN},~5.6079335,~51.491142,~84.241745,~30.221334],~ [44.04562,~76.861229,~1122.7759,~3226.2029,~454.86777],~ [25.911165,~229.07593,~9362.6543,~23606.273,~1208.775],~ [40.10083,~885.43927,~1710.2118,~2625.4871,~707.96606],~ [157.19417,~837.1344,~510.21539,~1150.1041,~183.1337]],~ [[{\rm NaN},~7.3051395,~53.120609,~83.425598,~30.498329],~ [46.440418,~74.485359,~1124.6348,~3232.8398,~452.48346],~ [24.2621,~232.48749,~9370.2432,~23596.512,~1207.9614],~ [39.246983,~889.26428,~1709.7922,~2624.9319,~709.22864],~ [157.98837,~837.04559,~509.17218,~1149.8561,~180.91991]],~ [[{\rm NaN},~8.9556961,~52.911243,~82.421761,~31.860538],~ [45.886646,~74.50666,~1124.42,~3220.2119,~452.20285],~ [26.949097,~230.85168,~9383.6201,~23591.998,~1208.7848],~ [40.328991,~888.47156,~1711.9926,~2626.6904,~711.94159],~ [160.73163,~835.27216,~509.88153,~1146.6986,~182.32607]],~ \dots,~ [[{\rm NaN},~4.9120932,~26.689028,~28.616543,~10.023705],~ [28.072544,~31.893505,~542.06342,~782.1109,~180.08565],~ [46.232319,~376.81042,~14261.941,~15128.989,~498.4819],~ [43.205341,~1070.3136,~4521.9155,~5827.8145,~856.85999],~ [192.35297,~1005.5414,~430.11401,~1020.651,~130.89424]],~ [[{\rm NaN},~2.8270299,~25.700079,~29.52319,~12.642929],~ [25.973894,~31.431316,~538.28333,~778.46442,~182.70427],~ [43.31205,~377.17438,~14264.536,~15119.578,~497.75192],~ [44.357986,~1068.8005,~4530.2197,~5830.8193,~858.05548],~ [193.50925,~1006.1519,~429.9635,~1017.7608,~130.25819]],~ [[{\rm NaN},~3.2904391,~29.979771,~31.989756,~9.3655338],~ [27.036531,~32.715042,~540.22314,~779.42993,~177.78526],~ [45.191956,~377.65054,~14264.66,~15122.454,~496.79456],~ [45.437138,~1068.2053,~4526.9604,~5830.8013,~858.00031],~ [194.59621,~1002.3592,~431.92557,~1018.8267,~129.3766]]] \; \mathrm{\frac{e^{-}}{s}}$

This object is a three-dimensional array, where each entry in the array represents one observing cadence. In our example, the flux array is composed of 4116 images, which are 5x5 pixels in size each:

[16]:
tpf.flux.shape
[16]:
(4116, 5, 5)

We can access the values of the first 5x5 pixel image as a NumPy array as follows:

[17]:
tpf.flux[0].value
[17]:
array([[          nan, 5.6079335e+00, 5.1491142e+01, 8.4241745e+01,
        3.0221334e+01],
       [4.4045620e+01, 7.6861229e+01, 1.1227759e+03, 3.2262029e+03,
        4.5486777e+02],
       [2.5911165e+01, 2.2907593e+02, 9.3626543e+03, 2.3606273e+04,
        1.2087750e+03],
       [4.0100830e+01, 8.8543927e+02, 1.7102118e+03, 2.6254871e+03,
        7.0796606e+02],
       [1.5719417e+02, 8.3713440e+02, 5.1021539e+02, 1.1501041e+03,
        1.8313370e+02]], dtype=float32)

At each cadence the TPF has four different flux-related data properties:

  • tpf.flux: the stellar brightness after the background is removed.

  • tpf.flux_err: the statistical uncertainty on the stellar flux after background removal.

  • tpf.flux_bkg: the astronomical background brightness of the image.

  • tpf.flux_bkg_err: the statistical uncertainty on the background flux.

All four of these data arrays are in units of electrons per second.

Note: for Kepler, the flux background isn’t a measurement made using the local TPF data. Instead, at each cadence, the Kepler pipeline fits a model to thousands of empty pixels across each CCD in order to estimate a continuum background across the the CCD. For more details read the Kepler Instrument Handbook, Section 2.6.2.4. In the case of TESS, local background pixels contained within a TPF are used instead.

Note: The tpf.flux values seen above have been quality-masked. This means that cadences of observations that violated the quality_bitmask parameter are removed, and so tpf.flux represents the data that you probably want to use to do your science. The quality_bitmask can also be accessed as a property of a `KeplerTargetPixelFile <https://docs.lightkurve.org/reference/api/lightkurve.KeplerTargetPixelFile.html?highlight=keplertargetpixelfile>`__. For specific details on the quality flags, read the Kepler Archive Manual, Section 2.3.1.1.

If you want to access flux and background flux measurements that have not been quality masked, you can pass a custom quality_bitmask parameter to the download() or read() method as follows:

[18]:
search = lk.search_targetpixelfile("Kepler-8", author="Kepler", cadence="long", quarter=4)
tpf = search.download(quality_bitmask=0)

You can see that the flux array of this object now has more cadences (4397) than the original one above (4116):

[19]:
tpf.flux.shape
[19]:
(4397, 5, 5)

Alternatively, we can access the unmasked contents of the original TPF FITS file at any time using the hdu property:

[20]:
tpf.hdu[1].data['FLUX'].shape
[20]:
(4397, 5, 5)

About this Notebook#

Authors: Oliver Hall (oliver.hall@esa.int), Geert Barentsen

Updated On: 2020-09-15

Citing Lightkurve and Astropy#

If you use lightkurve or astropy for published research, please cite the authors. Click the buttons below to copy BibTeX entries to your clipboard.

[21]:
lk.show_citation_instructions()
[21]:

When using Lightkurve, we kindly request that you cite the following packages:

  • lightkurve
  • astropy
  • astroquery — if you are using search_lightcurve() or search_targetpixelfile().
  • tesscut — if you are using search_tesscut().

Space Telescope Logo