Plotting Target Pixel Files with Lightkurve#

Learning Goals#

By the end of this tutorial, you will:

  • Learn how to download and plot target pixel files from the data archive using Lightkurve.

  • Be able to plot the target pixel file background.

  • Be able to extract and plot flux from a target pixel file.

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.

Pixels around targeted stars are cut out and stored as target pixel files at each observing cadence. In this tutorial, we will learn how to use Lightkurve to download and understand the different photometric data stored in a target pixel file, and how to extract flux using basic aperture photometry.

It is useful to read the accompanying tutorial discussing how to use target pixel file products with Lightkurve before starting this tutorial. It is recommended that you also read the tutorial on using Kepler light curve products with Lightkurve, which will introduce you to some specifics on 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. These cutout images are called target pixel files, or TPFs. By combining the amount of flux in the pixels where the star appears, you can make a measurement of the amount of light from a star in that observation. The pixels chosen to include in this measurement are referred to as an aperture.

TPFs are typically the first port of call when studying a star with Kepler, K2, or TESS. They allow us to see where our data is coming from, and identify potential sources of noise or systematic trends. In this tutorial, we will use the Kepler mission as the main example, but these tools equally apply to TESS and K2 as well.

Imports#

This tutorial requires: - Lightkurve to work with TPF files. - Matplotlib for plotting.

[1]:
from astropy import units as u
import lightkurve as lk
import matplotlib.pyplot as plt
%matplotlib inline

1. Downloading a TPF#

A TPF contains the original imaging data from which a light curve is derived. Besides the brightness data measured by the charge-coupled device (CCD) camera, a TPF also includes post-processing information such as an estimate of the astronomical background, and a recommended pixel aperture for extracting a light curve.

First, we download a target pixel file. We will use one quarter’s worth of Kepler data for the star named Kepler-8, a star somewhat larger than the Sun, and the host of a hot Jupiter planet. To search for TPF’s that contain our object of interest we will use the search_targetpixelfile function as follows,

[2]:
search_result = lk.search_targetpixelfile("Kepler-8", author="Kepler", quarter=4, cadence="long")
search_result
[2]:
SearchResult containing 1 data products.
#missionyearauthorexptimetarget_namedistance
sarcsec
0Kepler Quarter 042010Kepler1800kplr0069222440.0
[3]:
tpf = search_result.download()

This TPF contains data for every cadence in the quarter we downloaded. Let’s focus on the first cadence for now, which we can select using zero-based indexing as follows:

[4]:
first_cadence = tpf[0]
first_cadence
[4]:
KeplerTargetPixelFile Object (ID: 6922244)

2. Flux and Background#

At each cadence the TPF has a number of photometry data properties. These are:

  • flux_bkg: the astronomical background of the image.

  • flux_bkg_err: the statistical uncertainty on the background flux.

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

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

These properties can be accessed via a TPF object as follows:

[5]:
first_cadence.flux.value
[5]:
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)

And you can plot the data as follows:

[6]:
first_cadence.plot(column='flux');
../../_images/tutorials_1-getting-started_plotting-target-pixel-files_16_0.png

Alternatively, if you are working directly with a FITS file, you can access the data in extension 1 (for example, first_cadence.hdu[1].data['FLUX']). Note that you can find all of the details on the structure and contents of TPF files in Section 2.3.2 of the Kepler Archive Manual.

When plotting data using the plot() function, what you are seeing in the TPF is the flux after the background has been removed. This background flux typically consists of zodiacal light or earthshine (especially in TESS observations). The background is typically smooth and changes on scales much larger than a single TPF. In Kepler, the background is estimated for the CCD as a whole, before being extracted from each TPF in that CCD. You can learn more about background removal in Section 4.2 of the Kepler Data Processing Handbook.

Now, let’s compare the background to the background-subtracted flux to get a sense of scale. We can do this using the plot() function’s column keyword. By default the function plots the flux, but we can change this to plot the background, as well as other data such as the error on each pixel’s flux.

[7]:
fig, axes = plt.subplots(2,2, figsize=(16,16))
first_cadence.plot(ax=axes[0,0], column='FLUX')
first_cadence.plot(ax=axes[0,1], column='FLUX_BKG')
first_cadence.plot(ax=axes[1,0], column='FLUX_ERR')
first_cadence.plot(ax=axes[1,1], column='FLUX_BKG_ERR');
../../_images/tutorials_1-getting-started_plotting-target-pixel-files_20_0.png

From looking at the color scale on both plots, you may see that the background flux is very low compared to the total flux emitted by a star. This is expected — stars are bright! But these small background corrections become important when looking at the very small scale changes caused by planets or stellar oscillations. Understanding the background is an important part of astronomy with Kepler, K2, and TESS.

If the background is particularly bright and you want to see what the TPF looks like with it included, passing the bkg=True argument to the plot() method will show the TPF with the flux added on top of the background, representing the total flux recorded by the spacecraft.

[8]:
first_cadence.plot(bkg=True);
../../_images/tutorials_1-getting-started_plotting-target-pixel-files_23_0.png

In this case, the background is low and the star is bright, so it doesn’t appear to make much of a difference.

3. Apertures#

As part of the data processing done by the Kepler pipeline, each TPF includes a recommended optimal aperture mask. This aperture mask is optimized to ensure that the stellar signal has a high signal-to-noise ratio, with minimal contamination from the background.

The optimal aperture is stored in the TPF as the pipeline_mask property. We can have a look at it by calling it here:

[9]:
first_cadence.pipeline_mask
[9]:
array([[False, False, False, False, False],
       [False, False,  True,  True, False],
       [False, False,  True,  True, False],
       [False,  True,  True,  True, False],
       [False, False, False,  True, False]])

As you can see, it is a Boolean array detailing which pixels are included. We can plot this aperture over the top of our TPF using the plot() function, and passing in the mask to the aperture_mask keyword. This will highlight the pixels included in the aperture mask using red hatched lines.

[10]:
first_cadence.plot(aperture_mask=first_cadence.pipeline_mask);
../../_images/tutorials_1-getting-started_plotting-target-pixel-files_30_0.png

You don’t necessarily have to pass in the pipeline_mask to the plot() function; it can be any mask you create yourself, provided it is the right shape. An accompanying tutorial explains how to create such custom apertures, and goes into aperture photometry in more detail. For specifics on the selection of Kepler’s optimal apertures, read the Kepler Data Processing Handbook, Section 7, Finding Optimal Apertures in Kepler Data.

4. Simple Aperture Photometry#

Finally, let’s learn how to perform simple aperture photometry (SAP) using the provided optimal aperture in pipeline_mask and the TPF.

Using the full TPF for all cadences in the quarter, we can perform aperture photometry using the to_lightcurve() method as follows:

[11]:
lc = tpf.to_lightcurve()

This method returns a LightCurve object which details the flux and flux centroid position at each cadence:

[12]:
lc
[12]:
KeplerLightCurve length=4116 LABEL="KIC 6922244" QUARTER=4 CAMPAIGN=None
timefluxflux_errcentroid_colcentroid_rowcadencenoquality
electron / selectron / spixpix
Timefloat32float32float64float64int32int32
352.3763248503528343689.14843756.631562232971191682.6803253766153190.0726135828141119140
352.396758048489643698.0781256.631830215454102682.679939392134190.0724388237138119158192
352.437624445570743694.105468756.6317877769470215682.6796255144184190.072675759928471191716
352.4580576446387643698.316406256.631948947906494682.6797879974883190.07249571597706119180
352.478490843932443687.64843756.631504535675049682.6792868410989190.07246464783114119190
352.498924043466143686.47656256.6314263343811035682.6797248240034190.07284002730125119200
352.519357243349143692.593756.631662845611572682.6797061866289190.07275265635383119210
352.5397903434568443712.019531256.6356940269470215682.6787299772047190.0731683225424111922128
352.5602236438062443683.980468756.631390571594238682.679365411703190.0730725082332119230
352.580656844504143696.761718756.632009029388428682.6796517987715190.07296984009605119240
352.601089945543243693.14843756.631709098815918682.6794946321877190.073062208751119250
352.621523246823943691.343756.631857395172119682.6793119546483190.07329265625233119268192
352.6419564484531343703.136718756.632218837738037682.6794600165127190.07310394362827119270
352.662389650307943692.906256.631864547729492682.6791962953619190.07331932569323119280
352.6828228524027543696.27343756.632040977478027682.6792754510204190.07326117409048119290
352.7032560548468643666.199218756.630620956420898682.6794975721688190.07290799818392119300
352.723689257516543683.3906256.631417751312256682.679147977405190.0734239489556119310
352.744122460542743691.41406256.631997585296631682.679107402596190.07312093294664119320
352.7645556638017343701.47656256.632231712341309682.6788244683077190.07310037302085119330
352.784988867402743693.1093756.632004737854004682.6792450021618190.07342472501742119340
352.8054219712430543694.503906256.6319146156311035682.678968872893190.07344222963226119350
.....................
441.7743825305151443155.488281256.599724292755127682.5028500825504190.28122668371682162898192
441.794816894289443164.199218756.599976062774658682.5028704829895190.28084985845067162900
441.815251158150243154.41406256.599671363830566682.503034387268190.28080193887232162910
441.835685622179943153.218756.599508762359619682.5029903397564190.2813147419433162920
441.856119986332543161.003906256.5999755859375682.5031149987257190.2808494851943162930
441.8765542506007543149.253906256.599336624145508682.5033363751197190.28077231207783162940
441.8969887149796743157.85156256.600053787231445682.503043437076190.2811413220318616295128
441.9174230795397343154.71093756.599435329437256682.5029196936422190.28074883797223162960
441.9378573441863443154.683593756.599567890167236682.5031285134896190.28106458358056162970
441.9582917089719643155.347656256.599438190460205682.502819166476190.28129772456774162980
441.999160438936143155.496093756.599555492401123682.5027229343457190.28110987603694163000
442.0195948041364343153.082031256.599308490753174682.5027122524675190.28150665607106163010
442.040029269446743162.85156256.5997772216796875682.5029172042948190.28117470942624163020
442.060463534879143167.781256.600048065185547682.5028434809847190.28150709323504163030
442.080897900421443156.332031256.599843978881836682.5027064349352190.281369540639916304128
442.101332366146443164.07031256.599811553955078682.5025883479478190.28110702349872163050
442.121766731957943160.66406256.599737167358398682.5028468248179190.28114515294416163068192
442.142200997914243157.6256.5994954109191895682.5026386061921190.28167292648035163070
442.1626354639811343155.800781256.599367618560791682.5025609327599190.2812354101034163080
442.183069830200143148.464843756.599063873291016682.502362185607190.2815430315113163090
442.2035040965274743151.56256.599262714385986682.5024686560814190.28141944952384163100

Note that this KeplerLightCurve object has fewer data columns than in light curves downloaded directly from MAST. This is because we are extracting our light curve directly from the TPF using minimal processing, whereas light curves created using the official pipeline include more processing and more columns.

We can visualize the light curve as follows:

[13]:
lc.plot();
../../_images/tutorials_1-getting-started_plotting-target-pixel-files_39_0.png

This light curve is similar to the SAP light curve we previously encountered in the light curve tutorial.

Note#

The background flux can be plotted in a similar way, using the get_bkg_lightcurve() method. This does not require an aperture, but instead sums the flux in the TPF’s FLUX_BKG column at each timestamp.

[14]:
bkg = tpf.get_bkg_lightcurve()
bkg.plot();
../../_images/tutorials_1-getting-started_plotting-target-pixel-files_42_0.png

Inspecting the background in this way is useful to identify signals which appear to be present in the background rather than in the astronomical object under study.


Exercises#

Some stars, such as the planet-hosting star Kepler-10, have been observed both with Kepler and TESS. In this exercise, download and plot both the TESS and Kepler TPFs, along with the optimal apertures. You can do this by either selecting the TPFs from the list returned by search_targetpixelfile(), or by using the mission keyword argument when searching.

Both Kepler and TESS produce target pixel file data products, but these can look different across the two missions. TESS is focused on brighter stars and has larger pixels, so a star that might occupy many pixels in Kepler may only occupy a few in TESS.

How do light curves extracted from both of them compare?

[15]:
#datalist = lk.search_targetpixelfile(...)

[16]:
#soln:
datalist = lk.search_targetpixelfile("Kepler-10")
datalist
[16]:
SearchResult containing 72 data products.
#missionyearauthorexptimetarget_namedistance
sarcsec
0Kepler Quarter 032009Kepler60kplr0119041510.0
1Kepler Quarter 032009Kepler60kplr0119041510.0
2Kepler Quarter 032009Kepler60kplr0119041510.0
3Kepler Quarter 022009Kepler60kplr0119041510.0
4Kepler Quarter 032009Kepler1800kplr0119041510.0
5Kepler Quarter 022009Kepler1800kplr0119041510.0
6Kepler Quarter 002009Kepler1800kplr0119041510.0
7Kepler Quarter 012009Kepler1800kplr0119041510.0
8Kepler Quarter 052010Kepler60kplr0119041510.0
9Kepler Quarter 052010Kepler60kplr0119041510.0
10Kepler Quarter 062010Kepler60kplr0119041510.0
11Kepler Quarter 062010Kepler60kplr0119041510.0
12Kepler Quarter 062010Kepler60kplr0119041510.0
13Kepler Quarter 072010Kepler60kplr0119041510.0
14Kepler Quarter 072010Kepler60kplr0119041510.0
15Kepler Quarter 042010Kepler60kplr0119041510.0
16Kepler Quarter 072010Kepler60kplr0119041510.0
17Kepler Quarter 052010Kepler60kplr0119041510.0
18Kepler Quarter 062010Kepler1800kplr0119041510.0
19Kepler Quarter 052010Kepler1800kplr0119041510.0
20Kepler Quarter 072010Kepler1800kplr0119041510.0
.....................
50TESS Sector 402021SPOC203777807900.0
51TESS Sector 412021SPOC203777807900.0
52TESS Sector 402021SPOC1203777807900.0
53TESS Sector 412021SPOC1203777807900.0
54TESS Sector 532022SPOC203777807900.0
55TESS Sector 552022SPOC203777807900.0
56TESS Sector 542022SPOC203777807900.0
57TESS Sector 552022SPOC1203777807900.0
58TESS Sector 542022SPOC1203777807900.0
59TESS Sector 532022SPOC1203777807900.0
60TESS Sector 752024SPOC1203777807900.0
61TESS Sector 742024SPOC1203777807900.0
62TESS Sector 812024SPOC1203777807900.0
63TESS Sector 802024SPOC1203777807900.0
64TESS Sector 152019TESS-SPOC18003777807900.0
65TESS Sector 142019TESS-SPOC18003777807900.0
66TESS Sector 262020TESS-SPOC18003777807900.0
67TESS Sector 412021TESS-SPOC6003777807900.0
68TESS Sector 402021TESS-SPOC6003777807900.0
69TESS Sector 552022TESS-SPOC6003777807900.0
70TESS Sector 542022TESS-SPOC6003777807900.0
71TESS Sector 532022TESS-SPOC6003777807900.0
Length = 72 rows
[17]:
kep = datalist[(datalist.author == "Kepler") & (datalist.exptime == 60*u.second)][0].download()
tes = datalist[(datalist.author == "SPOC") & (datalist.exptime == 120*u.second)][0].download()
[18]:
fig, axes = plt.subplots(1, 2, figsize=(14,6))
kep.plot(ax=axes[0], aperture_mask=kep.pipeline_mask, scale='log')
tes.plot(ax=axes[1], aperture_mask=tes.pipeline_mask)
fig.tight_layout();
../../_images/tutorials_1-getting-started_plotting-target-pixel-files_50_0.png
[19]:
lc_kep = kep.to_lightcurve()
lc_tes = tes.to_lightcurve()
[20]:
fig, axes = plt.subplots(1, 2, figsize=(14,6), sharey=True)
lc_kep.flatten().plot(ax=axes[0], c='k', alpha=.8)
lc_tes.flatten().plot(ax=axes[1], c='k', alpha=.8);
../../_images/tutorials_1-getting-started_plotting-target-pixel-files_52_0.png

If you plot the light curves for both missions side by side, you will see a stark difference. The Kepler data has a much smaller scatter, and repeating transits are visible. This is because Kepler’s pixels were smaller, and so could achieve a higher precision on fainter stars. TESS has larger pixels and therefore focuses on brighter stars. For stars like Kepler-10, it would be hard to detect a planet using TESS data alone.

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.

lk.show_citation_instructions()

Space Telescope Logo