Skip to content

Commit

Permalink
Merge pull request #239 from simonrp84/landsat_rsr
Browse files Browse the repository at this point in the history
Update Landsat RSR reader, add support for Landsat-9 OLI+TIRS
  • Loading branch information
adybbroe authored Oct 29, 2024
2 parents 01b55aa + 279c2c2 commit a756733
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 92 deletions.
18 changes: 15 additions & 3 deletions doc/platforms_supported.rst
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,17 @@ have been included in Pyspectral.
- `rsr_viirs_Suomi-NPP.h5`
- GSICS_
* - Landsat-8 oli
- `rsr_oli_Landsat-8.h5`
- NASA-Landsat-OLI_
- `rsr_oli_tirs_Landsat-8.h5`
- NASA-Landsat-8-OLI_
* - Landsat-8 tirs
- `rsr_oli_tirs_Landsat-8.h5`
- NASA-Landsat-8-TIRS_
* - Landsat-9 oli-2
- `rsr_oli_tirs_Landsat-9.h5`
- NASA-Landsat-9-OLI_
* - Landsat-9 tirs-2
- `rsr_oli_tirs_Landsat-9.h5`
- NASA-Landsat-9-TIRS_
* - FY-3D mersi-2
- `rsr_mersi-2_FY-3D.h5`
- CMA_ (Acquired via personal contact)
Expand Down Expand Up @@ -125,7 +134,10 @@ have been included in Pyspectral.
.. _ESA-Sentinel-OLCI: https://sentinel.esa.int/documents/247904/322304/OLCI+SRF+%28NetCDF%29/15cfd7a6-b7bc-4051-87f8-c35d765ae43a
.. _ESA-Sentinel-SLSTR: https://sentinel.esa.int/web/sentinel/technical-guides/sentinel-3-slstr/instrument/measured-spectral-response-function-data
.. _ESA-Sentinel-MSI: https://earth.esa.int/documents/247904/685211/S2-SRF_COPE-GSEG-EOPG-TN-15-0007_3.0.xlsx
.. _NASA-Landsat-OLI: https://landsat.gsfc.nasa.gov/wp-content/uploads/2013/06/Ball_BA_RSR.v1.1-1.xlsx
.. _NASA-Landsat-8-OLI: https://landsat.gsfc.nasa.gov/wp-content/uploads/2014/09/Ball_BA_RSR.v1.2.xlsx
.. _NASA-Landsat-9-OLI: https://landsat.gsfc.nasa.gov/wp-content/uploads/2024/03/L9_OLI2_Ball_BA_RSR.v2-1.xlsx
.. _NASA-Landsat-8-TIRS: https://landsat.gsfc.nasa.gov/wp-content/uploads/2013/06/TIRS_Relative_Spectral_Responses.BA_.v1.xlsx
.. _NASA-Landsat-9-TIRS: https://landsat.gsfc.nasa.gov/wp-content/uploads/2021-10/L9_TIRS2_Relative_Spectral_Responses.BA.v1.0.xlsx
.. _NESDIS: https://ncc.nesdis.noaa.gov/J1VIIRS/J1VIIRSSpectralResponseFunctions.php
.. _CMA: http://www.cma.gov.cn/en2014/
.. _NWPSAF-MetImage: https://nwpsaf.eu/downloads/rtcoef_rttov12/ir_srf/rtcoef_metopsg_1_metimage_srf.html
Expand Down
10 changes: 10 additions & 0 deletions pyspectral/etc/pyspectral.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,16 @@ download_from_internet: True
# Envisat-aatsr:
# path: /path/to/original/envisat/aatsr/data

# Landsat-8-oli_tirs:
# path: D:\sat_data\
# oli: Ball_BA_RSR.v1.2.xlsx
# tirs: TIRS_Relative_Spectral_Responses.BA_.v1.xlsx

# Landsat-9-oli_tirs:
# path: D:\sat_data\
# oli: L9_OLI2_Ball_BA_RSR.v2-1.xlsx
# tirs: L9_TIRS2_Relative_Spectral_Responses.BA.v1.0.xlsx

# Sentinel-3A-slstr:
# path: /path/to/original/sentinel-3a/slstr/data
# ch1: SLSTR_FM02_S1_20150122.nc
Expand Down
7 changes: 4 additions & 3 deletions pyspectral/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@
'Electro-L-N2': 'msu-gs',
'Sentinel-3A': ['olci', 'slstr'],
'Sentinel-3B': ['olci', 'slstr'],
'Landsat-8': 'oli',
'Landsat-8': 'oli_tirs',
'Landsat-9': 'oli_tirs',
'Meteosat-10': 'seviri',
'Meteosat-11': 'seviri',
'Meteosat-8': 'seviri',
Expand All @@ -108,10 +109,10 @@
'avhrr-2': 'avhrr/2',
'avhrr-3': 'avhrr/3'}

HTTP_PYSPECTRAL_RSR = "https://zenodo.org/records/13833977/files/pyspectral_rsr_data.tgz"
HTTP_PYSPECTRAL_RSR = "https://zenodo.org/records/14008148/files/pyspectral_rsr_data.tgz"

RSR_DATA_VERSION_FILENAME = "PYSPECTRAL_RSR_VERSION"
RSR_DATA_VERSION = "v1.4.0"
RSR_DATA_VERSION = "v1.4.1"


ATM_CORRECTION_LUT_VERSION = {}
Expand Down
85 changes: 0 additions & 85 deletions rsr_convert_scripts/oli_reader.py

This file was deleted.

124 changes: 124 additions & 0 deletions rsr_convert_scripts/oli_tirs_reader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2017-2024 Pytroll developers
#
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

"""Landsat-8/9 OLI/TIRS reader.
This reader generates spectral responses for OLI and TIRS instruments aboard Landsat-8 and -9.
We assume that the instruments are one combined instrument from the user perspective, called `oli_tirs` rather
than generating RSRs for the two instruments separately.
The original spectral response data can be found at the links below.
Landsat-8/OLI:
= https://landsat.gsfc.nasa.gov/wp-content/uploads/2014/09/Ball_BA_RSR.v1.2.xlsx
Landsat-9/OLI-2:
= https://landsat.gsfc.nasa.gov/wp-content/uploads/2024/03/L9_OLI2_Ball_BA_RSR.v2-1.xlsx
Landsat-8/TIRS:
= https://landsat.gsfc.nasa.gov/wp-content/uploads/2013/06/TIRS_Relative_Spectral_Responses.BA_.v1.xlsx
Landsat-9/TIRS-2:
= https://landsat.gsfc.nasa.gov/wp-content/uploads/2021-10/L9_TIRS2_Relative_Spectral_Responses.BA.v1.0.xlsx
"""

import logging
from pathlib import Path

import numpy as np
import pandas as pd

from pyspectral.raw_reader import InstrumentRSR
from pyspectral.utils import convert2hdf5 as tohdf5

LOG = logging.getLogger(__name__)

OLI_BAND_NAMES = {"B1": "CoastalAerosol",
"B2": "Blue",
"B3": "Green",
"B4": "Red",
"B5": "NIR",
"B6": "Cirrus",
"B7": "SWIR1",
"B8": "SWIR2",
"B9": "Pan"}

TIRS_SHEETNAMES_L8 = {"B10": "TIRS BA RSR",
"B11": "TIRS BA RSR"}
TIRS_BAND_NAMES_L8 = {"B10": "TIRS1 10.8um band average",
"B11": "TIRS2 12.0um band average"}

TIRS_SHEETNAMES_L9 = {"B10": "TIRS Band 10 BA RSR",
"B11": "TIRS Band 11 BA RSR"}
TIRS_BAND_NAMES_L9 = {"B10": "Band 10 Band=Average RSR",
"B11": "Band 11 Band-Average RSR"}


class OliRSR(InstrumentRSR):
"""Class for Landsat OLI RSR."""

def __init__(self, bandname, platform_name):
"""Read the Landsat OLI relative spectral responses for all channels."""
super(OliRSR, self).__init__(bandname, platform_name)
self.instrument = "oli_tirs"
self._get_options_from_config()
self.band = bandname
opts = self.options[f"{platform_name}-{self.instrument}"]
if bandname in OLI_BAND_NAMES:
self.path = Path(opts["path"]) / Path(opts["oli"])
elif bandname in TIRS_BAND_NAMES_L8:
self.path = Path(opts["path"]) / Path(opts["tirs"])
else:
raise ValueError(f"Unknown band name: {bandname}")

LOG.debug(f"Filename: {self.path}")
if self.path.exists():
self._load()
else:
raise IOError("Couldn't find an existing file for this band: " +
str(self.bandname))

def _load(self, scale=0.001):
"""Load the Landsat OLI relative spectral responses."""
if self.band in OLI_BAND_NAMES:
df = pd.read_excel(self.path, engine="openpyxl", sheet_name=OLI_BAND_NAMES[self.band])
wvl = np.array(df["Wavelength"]) / 1000.
resp = np.array(df["BA RSR [watts]"])
else:
if self.platform_name == "Landsat-8":
sheet_name = TIRS_SHEETNAMES_L8[self.band]
band_name = TIRS_BAND_NAMES_L8[self.band]
elif self.platform_name == "Landsat-9":
sheet_name = TIRS_SHEETNAMES_L9[self.band]
band_name = TIRS_BAND_NAMES_L9[self.band]
else:
raise ValueError(f"Unknown platform: {self.platform_name}")
df = pd.read_excel(self.path, engine="openpyxl", sheet_name=sheet_name)

wvl = np.array(df["wavelength [um]"]) / 1000.
resp = np.array(df[band_name])

# Cut unneeded points
pts = np.argwhere(resp > 0.002)
wvl = np.squeeze(wvl[pts])
resp = np.squeeze(resp[pts])

self.rsr = {"wavelength": wvl,
"response": resp}


if __name__ == "__main__":
bands = sorted(OLI_BAND_NAMES.keys()) + sorted(TIRS_BAND_NAMES_L8.keys())
for platform_name in ["Landsat-8", "Landsat-9"]:
tohdf5(OliRSR, platform_name, bands)
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Copyright (c) 2013-2022 Pytroll
# Copyright (c) 2013-2024 Pytroll
#
#
# This program is free software: you can redistribute it and/or modify
Expand Down Expand Up @@ -71,6 +71,7 @@
'matplotlib': ['matplotlib'],
'pandas': ['pandas'],
'tqdm': ['tqdm'],
'openpyxl': ['openpyxl'],
'test': test_requires,
'dask': dask_extra},
scripts=['bin/plot_rsr.py', 'bin/composite_rsr_plot.py',
Expand Down

0 comments on commit a756733

Please sign in to comment.