Metadata
!pip install georeader-spaceml fsspec gcsfs
import os
# Donwload key from next line link to access the buckets and requester pays requests to public bucket (this is needed to query Sentinel-2 data)
os.environ["GS_NO_SIGN_REQUEST"] = "YES"
%%time
from georeader.readers import S2_SAFE_reader
safe_file = "S2B_MSIL1C_20220527T030539_N0400_R075_T49SGV_20220527T051042.SAFE"
s2_safe_folder = S2_SAFE_reader.s2_public_bucket_path(safe_file)
print(f"File is located at: {s2_safe_folder}")
s2obj = S2_SAFE_reader.s2loader(s2_safe_folder, out_res=10)
s2obj
footprint = s2obj.footprint(crs="epsg:4326")
footprint
Metadata files in S2 images¶
There are two metadata files in Sentinel-2 images, these are saved in the attributes:
* s2obj.metadata_msi
. In this file we have the solar irradiance, scale factor U, quantification values and radio add offsets.
* s2obj.metadata_tl
. Here we have the solar and viewing angles. This file is specific of L1C images
s2obj.metadata_msi
s2obj.solar_irradiance()
s2obj.scale_factor_U()
s2obj.quantification_value()
When reading the data we automatically apply the radio offsets
s2obj.radio_add_offsets()
s2obj.metadata_tl
# Trigger reading of metadata to inspect angles
s2obj.read_metadata_tl()
s2obj.mean_saa
s2obj.mean_sza
s2obj.mean_vaa
s2obj.mean_vza
The sza
and vza
attributes are GeoTensor
objects
s2obj.sza
from georeader.plot import show
import matplotlib.pyplot as plt
fig, ax = plt.subplots(2,2,figsize=(10,10), tight_layout=True)
show(s2obj.vza["B12"], add_colorbar_next_to=True, add_scalebar=True,
ax=ax[0,0],title="VZA B12")
show(s2obj.vaa["B12"], add_colorbar_next_to=True, add_scalebar=True,
ax=ax[0,1],title="VAA B12")
show(s2obj.sza, add_colorbar_next_to=True, add_scalebar=True,
ax=ax[1,0],title="SZA")
show(s2obj.saa, add_colorbar_next_to=True, add_scalebar=True,
ax=ax[1,1],title="SAA")
Load Spectral Response function¶
# reads SRF from S2_SAFE_reader.SRF_FILE_DEFAULT
srf = S2_SAFE_reader.read_srf(s2obj.mission)
srf
fig, ax = plt.subplots(1,1,figsize=(14,4))
for idx, b in enumerate(S2_SAFE_reader.BANDS_S2):
mask_zero = srf[b] <=1e-4
ax.plot(srf.index[~mask_zero],
srf[b][~mask_zero], label=f"{s2obj.mission}_{b}")
ax.legend()
ax.set_xlabel("wavelength (nm)")
Reflectance to radiance conversion¶
We want the pixels of our images in spectral radiances with units \(W·sr^{-1}·m^{−2}·nm^{−1}\). Spectral raciances are (watts per steradian per square meter per nanometer).
According to this https://gis.stackexchange.com/questions/285996/convert-sentinel-2-1c-product-from-reflectance-to-radiance the formula to convert digital numbers (DN) in ToA images is:
toaBandX = (pixelValueBandX + radioAddOffsetBandX ) / 10000
radianceBandX = ((toaBandX * cos(incidenceAngle) * solarIrradianceBandX) / (pi * d2))
where d2 is the earth-sun distance correction. d2 is 1.0/U
The values for incidenceAngle, solarIrradianceBandX and U can be found in the 2 metadata files included in the download.
- In
metadata_msi
we can find thesolarIrradianceBandX
, theradioAddOffsetBandX
andU
. See xml content bellow! - In
metadata_tl
we can find theincidenceAngle
(which I assume is the solar zenith angle).
If \(J\) is the Julian day of the day of acquisition (day of the year), d2 can be computed as:
d2 = (1-e* cos(0.9856 * (J-4) * pi/180))^2
Where e=0.01673 is the Earth's orbit eccentricity
We're going to read an small crop of the image and convert it to radiances
%%time
from georeader import read
s2obj.bands = ["B04","B08", "B12"]
tensor = read.read_from_center_coords(s2obj, footprint.centroid.coords[0],shape=(512, 1024), crs_center_coords="epsg:4326", trigger_load=True)
tensor_toa = tensor / 10_000.
tensor_toa = tensor / 10_000.
show(tensor_toa)
tensor_radiance = s2obj.DN_to_radiance(tensor)
tensor_radiance.values
# Make sense since radiance in B12 is much lower than in B04
tensor_radiance.values[:, 100, 100]
Licence¶
The georeader package is published under a GNU Lesser GPL v3 licence
If you find this work useful please cite:
@article{ruzicka_starcop_2023,
title = {Semantic segmentation of methane plumes with hyperspectral machine learning models},
volume = {13},
issn = {2045-2322},
url = {https://www.nature.com/articles/s41598-023-44918-6},
doi = {10.1038/s41598-023-44918-6},
number = {1},
journal = {Scientific Reports},
author = {Růžička, Vít and Mateo-Garcia, Gonzalo and Gómez-Chova, Luis and Vaughan, Anna, and Guanter, Luis and Markham, Andrew},
month = nov,
year = {2023},
pages = {19999},
}