Landsat Thermal Data Explained

On this page

Problem statement

Landsat has measured thermal infrared since 1982, which makes it the only source of surface temperature at neighbourhood resolution with a forty-year record. That record is stitched together from four generations of instruments with different resolutions, band designs and quirks, carried by satellites whose orbits have not all stayed where they started. A composite or a trend built across them inherits all of that unless it is handled explicitly.

Quick answer

Satellite Sensor Thermal band Acquired at Level-2 asset Notes
Landsat 5 TM 6 120 m lwir 1984–2012
Landsat 7 ETM+ 6 60 m lwir scan-line gaps from 2003; orbit drifted after 2017
Landsat 8 TIRS 10 (11) 100 m lwir11 band 11 affected by stray light
Landsat 9 TIRS-2 10 (11) 100 m lwir11 from 2021

All Collection 2 Level-2 surface temperature products are delivered resampled to 30 m, in Kelvin with scale 0.00341802 and offset 149.0.

import pandas as pd, pystac_client

cat = pystac_client.Client.open("https://planetarycomputer.microsoft.com/api/stac/v1")
rows = []
for year in (2001, 2008, 2015, 2019, 2021, 2023):
    for it in cat.search(collections=["landsat-c2-l2"], bbox=[-3.72, 40.40, -3.68, 40.43],
                         datetime=f"{year}-06-01/{year}-08-31").items():
        rows.append({"year": year, "platform": it.properties["platform"],
                     "utc": it.datetime.hour + it.datetime.minute / 60})
df = pd.DataFrame(rows)
table = df.groupby(["year", "platform"]).utc.agg(["count", "median"])
table["median"] = table["median"].map(lambda h: f"{int(h):02d}:{round(h % 1 * 60):02d}")
print("Summer scenes over central Madrid and their median acquisition time (UTC)")
print(table.to_string())
Summer scenes over central Madrid and their median acquisition time (UTC)
                count median
year platform               
2001 landsat-5      4  10:35
     landsat-7      6  10:44
2008 landsat-5      2  10:42
     landsat-7      4  10:45
2015 landsat-7      5  10:55
     landsat-8      6  10:55
2019 landsat-7      6  10:43
     landsat-8      5  10:55
2021 landsat-7      5  09:58
     landsat-8      6  10:55
2023 landsat-7      9  08:43
     landsat-8      6  10:55
     landsat-9      6  10:55

The acquisition time of Landsat 7 moves earlier from year to year after its orbit was lowered and it drifted; Landsat 8 and 9 keep their time. Until 2019 all of them passed within a quarter of an hour of each other. In 2021 a Landsat 7 scene was taken an hour earlier than a Landsat 8 scene of the same week; by 2023, more than two hours earlier, at 08:43 UTC.

Band 10, native resolution, Landsat 7's gaps

1. Use band 10 for Landsat 8 and 9

Band 11 of TIRS suffers from stray light; the Collection 2 surface temperature product uses band 10 only, which is what the lwir11 asset contains.

2. Remember the native resolution

60 m (Landsat 7), 100 m (Landsat 8/9) or 120 m (Landsat 5), all resampled to 30 m. Features smaller than two or three native pixels are not resolved even though the file has 30 m pixels.

3. Handle Landsat 7's gaps and drift

The scan-line corrector failed in May 2003: every Landsat 7 scene since then has wedge-shaped gaps. After 2017 its orbit drifted to earlier crossing times. Mask the gaps and avoid mixing late Landsat 7 scenes with other sensors in one composite.

4. Use the right asset name per platform

lwir11 on Landsat 8/9, lwir on 5/7 in the Planetary Computer's Collection 2 items. Code that assumes one name silently skips the other satellites.

5. For long records, calibrate across sensors

Surface temperatures from TM, ETM+ and TIRS are designed to be consistent, but residual differences of a degree or so exist. Trend studies check overlaps between satellites.

Landsat thermal sensors from Landsat 5 to Landsat 9 with their native resolutions and known issues. four instrument generations1984Landsat 5 TM, 120 m1999Landsat 7 ETM+, 60 m2003L7 scan-line gaps2013Landsat 8 TIRS, 100 m2021Landsat 9 TIRS-2After 2017 Landsat 7 drifted to earlier crossing times spatialworkflow.io
Forty years of thermal data from four instrument generations.

Hidden resolution and scene counts by satellite

Example 1 β€” the resolution the pixels do not show

import numpy as np, rasterio, rasterio.warp, planetary_computer
it = next(i for i in cat.search(collections=["landsat-c2-l2"], bbox=[-3.72, 40.40, -3.68, 40.43],
                                datetime="2023-07-01/2023-07-31").items()
          if i.properties["platform"] == "landsat-9")
with rasterio.open(planetary_computer.sign(it.assets["lwir11"].href)) as src:
    xs, ys = rasterio.warp.transform("EPSG:4326", src.crs, [-3.70], [40.415])
    r, c = src.index(xs[0], ys[0])
    a = src.read(1, window=((r, r + 30), (c, c + 30))).astype(float) * 0.00341802 + 149 - 273.15
lag1 = np.corrcoef(a[:, :-1].ravel(), a[:, 1:].ravel())[0, 1]
lag4 = np.corrcoef(a[:, :-4].ravel(), a[:, 4:].ravel())[0, 1]
print(f"{it.id}: correlation of LST between neighbouring 30 m pixels {lag1:.2f}, "
      f"pixels 120 m apart {lag4:.2f}")
LC09_L2SP_201032_20230721_02_T1: correlation of LST between neighbouring 30 m pixels 0.98, pixels 120 m apart 0.75

Neighbouring 30 m pixels correlate at 0.98 because they share most of one 100 m measurement; four pixels apart the correlation is still 0.75. They are not independent observations until well beyond the native footprint.

Example 2 β€” Landsat 7 scan-line gaps

l7 = next(i for i in cat.search(collections=["landsat-c2-l2"], bbox=[-3.72, 40.40, -3.68, 40.43],
                                datetime="2010-07-01/2010-07-31").items()
          if i.properties["platform"] == "landsat-7")
with rasterio.open(planetary_computer.sign(l7.assets["lwir"].href)) as src:
    xs, ys = rasterio.warp.transform("EPSG:4326", src.crs, [-3.70], [40.415])
    r, c = src.index(xs[0], ys[0])
    a = src.read(1, window=((r - 300, r + 300), (c - 300, c + 300)))
print(f"{l7.id}: {np.mean(a == 0):.0%} of a 18 Γ— 18 km window is fill (scan-line gaps)")
LE07_L2SP_201032_20100701_02_T1: 2% of a 18 Γ— 18 km window is fill (scan-line gaps)

Every post-2003 Landsat 7 scene has these gaps. Near the centre of a scene, where Madrid sits here, they are narrow β€” 2% of the window; they widen towards the scene edges, where they take out much more. A composite of several scenes fills them, because the gaps fall in different places each time.

Example 3 β€” scenes per summer by satellite

print(df.groupby(["year", "platform"]).size().unstack(fill_value=0).to_string())
platform  landsat-5  landsat-7  landsat-8  landsat-9
year                                                
2001              4          6          0          0
2008              2          4          0          0
2015              0          5          6          0
2019              0          6          5          0
2021              0          5          6          0
2023              0          9          6          6

Two satellites at a time give a scene every eight days per path; overlapping paths add more. The number of usable summer scenes β€” after clouds β€” decides how good a composite can be.

Median summer acquisition time over Madrid for Landsat 7 and Landsat 8 in several years, in hours UTC. median summer acquisition time, UTCLandsat 7, 201510:55Landsat 7, 201910:43Landsat 7, 202109:58Landsat 7, 202308:43Landsat 8/9, every year10:55Two hours earlier by 2023: a cooler part of the morning spatialworkflow.io
Landsat 7 drifted earlier; Landsat 8 and 9 kept their time.

Why thermal bands are coarser

Why thermal bands are coarser

Thermal radiation carries far less energy per wavelength interval than reflected sunlight, so thermal detectors need larger pixels to collect enough signal. Landsat's thermal resolution has always been two to four times coarser than its optical bands.

Why the Level-2 product is single-band

Split-window methods use two thermal bands to correct for the atmosphere. Landsat 8's band 11 was found to be contaminated by stray light, so the Collection 2 algorithm uses band 10 with atmospheric profiles from reanalysis and emissivity from ASTER. That keeps the method consistent with the single-band Landsat 5 and 7.

Why orbit drift matters for temperature

Surface temperature rises steeply through the morning. A satellite that drifts to an earlier crossing time measures systematically cooler surfaces, so a trend built on it can show cooling that is only a change of hour.

Summer Landsat scenes over central Madrid by satellite and year. summer scenes by satelliteyearL5L7L8L9200146β€”β€”200824β€”β€”2015β€”56β€”2019β€”65β€”2023β€”9 (drifted)66Neighbouring 30 m pixels correlate at 0.98; four pixels apart still 0.75 spatialworkflow.io
Two satellites at a time; after 2017 one of them is taking morning pictures.

Tiers, night scenes and uncertainty layers

  • Tier 1 vs Tier 2: Tier 2 scenes have poorer geolocation; urban work should prefer Tier 1.
  • Night scenes exist for some Landsat acquisitions but are rare and not in routine Level-2 processing.
  • ST uncertainty: the product includes an uncertainty band (ST_QA) in Kelvin; large values flag doubtful pixels.
  • Landsat Next plans more thermal bands at better resolution later in the decade.
  • Harmonised composites across sensors should record which platform supplied each observation.

FAQ

What resolution is Landsat thermal data?

Acquired at 120 m (Landsat 5), 60 m (Landsat 7) or 100 m (Landsat 8/9); delivered at 30 m.

Which band gives surface temperature on Landsat 8?

Band 10, delivered as ST_B10 (lwir11 on the Planetary Computer).

Why not use band 11?

It is affected by stray light; the official product uses band 10 only.

What happened to Landsat 7's overpass time?

Its orbit was lowered and it drifted to earlier crossing times, so late scenes are taken earlier in the morning.

Can I mix Landsat 7 and 8 in one composite?

Before about 2017 with care; afterwards, not without accounting for the time difference.

How do I handle Landsat 7's stripes?

Mask the fill pixels and composite several scenes so the gaps are filled by other dates.