S2TheiaProduct#
- class S2TheiaProduct(product_path: str | CloudPath | Path, archive_path: str | CloudPath | Path | None = None, output_path: str | CloudPath | Path | None = None, remove_tmp: bool = False, **kwargs)[source]#
Bases:
OpticalProduct
Class of Sentinel-2 Theia Products. See here for more information.
- __init__(product_path: str | CloudPath | Path, archive_path: str | CloudPath | Path | None = None, output_path: str | CloudPath | Path | None = None, remove_tmp: bool = False, **kwargs) None [source]#
- clean_tmp()#
Clean the temporary directory of the current product
- clear()#
Clear this product’s cache
- get_band_paths(band_list: list, pixel_size: float | None = None, **kwargs) dict [source]#
Return the paths of required bands.
For Theia products, FRE bands are given because, it is written in the <documentation https://labo.obs-mip.fr/multitemp/sentinel-2/theias-sentinel-2-l2a-product-format/>_ that “After having compiled the user feedback, it is likely that we will only distribute « FRE » files to reduce the data volume.”
>>> from eoreader.reader import Reader >>> from eoreader.bands import * >>> path = r"SENTINEL2A_20190625-105728-756_L2A_T31UEQ_C_V2-2" >>> prod = Reader().open(path) >>> prod.get_band_paths([GREEN, RED]) { <SpectralBandNames.GREEN: 'GREEN'>: 'SENTINEL2A_20190625-105728-756_L2A_T31UEQ_C_V2-2/SENTINEL2A_20190625-105728-756_L2A_T31UEQ_C_V2-2_FRE_B3.tif', <SpectralBandNames.RED: 'RED'>: 'SENTINEL2A_20190625-105728-756_L2A_T31UEQ_C_V2-2/SENTINEL2A_20190625-105728-756_L2A_T31UEQ_C_V2-2_FRE_B4.tif' }
- get_date(as_date: bool = False) str | date #
Get the product’s acquisition date.
>>> from eoreader.reader import Reader >>> path = r"S2A_MSIL1C_20200824T110631_N0209_R137_T30TTK_20200824T150432.SAFE.zip" >>> prod = Reader().open(path) >>> prod.get_date(as_date=True) datetime.datetime(2020, 8, 24, 0, 0) >>> prod.get_date(as_date=False) '20200824'
- get_datetime(as_datetime: bool = False) str | datetime [source]#
Get the product’s acquisition datetime, with format
YYYYMMDDTHHMMSS
<->%Y%m%dT%H%M%S
>>> from eoreader.reader import Reader >>> path = r"SENTINEL2A_20190625-105728-756_L2A_T31UEQ_C_V2-2" >>> prod = Reader().open(path) >>> prod.get_datetime(as_datetime=True) datetime.datetime(2019, 6, 25, 10, 57, 28, 756000), fetched from metadata, so we have the ms >>> prod.get_datetime(as_datetime=False) '20190625T105728'
- get_default_band() BandNames #
Get default band:
GREEN
for optical data as every optical satellite has a GREEN band.>>> from eoreader.reader import Reader >>> path = r"S2A_MSIL1C_20200824T110631_N0209_R137_T30TTK_20200824T150432.SAFE.zip" >>> prod = Reader().open(path) >>> prod.get_default_band() <SpectralBandNames.GREEN: 'GREEN'>
- Returns:
Default band
- Return type:
- get_default_band_path(**kwargs) CloudPath | Path #
Get default band (
GREEN
for optical data) path.>>> from eoreader.reader import Reader >>> path = r"S2A_MSIL1C_20200824T110631_N0209_R137_T30TTK_20200824T150432.SAFE.zip" >>> prod = Reader().open(path) >>> prod.get_default_band_path() 'zip+file://S2A_MSIL1C_20200824T110631_N0209_R137_T30TTK_20200824T150432.SAFE.zip!/S2A_MSIL1C_20200824T110631_N0209_R137_T30TTK_20200824T150432.SAFE/GRANULE/L1C_T30TTK_A027018_20200824T111345/IMG_DATA/T30TTK_20200824T110631_B03.jp2'
- Parameters:
kwargs – Additional arguments
- Returns:
Default band path
- Return type:
AnyPathType
- get_existing_band_paths() dict #
Return the existing band paths (orthorectified if needed).
>>> from eoreader.reader import Reader >>> path = r"S2A_MSIL1C_20200824T110631_N0209_R137_T30TTK_20200824T150432.SAFE.zip" >>> prod = Reader().open(path) >>> prod.get_existing_band_paths() { <SpectralBandNames.CA: 'COASTAL_AEROSOL'>: 'zip+file://S2A_MSIL1C_20200824T110631_N0209_R137_T30TTK_20200824T150432.SAFE.zip!/S2A_MSIL1C_20200824T110631_N0209_R137_T30TTK_20200824T150432.SAFE/GRANULE/L1C_T30TTK_A027018_20200824T111345/IMG_DATA/T30TTK_20200824T110631_B01.jp2', ..., <SpectralBandNames.SWIR_2: 'SWIR_2'>: 'zip+file://S2A_MSIL1C_20200824T110631_N0209_R137_T30TTK_20200824T150432.SAFE.zip!/S2A_MSIL1C_20200824T110631_N0209_R137_T30TTK_20200824T150432.SAFE/GRANULE/L1C_T30TTK_A027018_20200824T111345/IMG_DATA/T30TTK_20200824T110631_B12.jp2' }
- Returns:
Dictionary containing the path of each queried band
- Return type:
- get_existing_bands() list #
Return the existing band.
>>> from eoreader.reader import Reader >>> path = r"S2A_MSIL1C_20200824T110631_N0209_R137_T30TTK_20200824T150432.SAFE.zip" >>> prod = Reader().open(path) >>> prod.get_existing_bands() [<SpectralBandNames.CA: 'COASTAL_AEROSOL'>, <SpectralBandNames.BLUE: 'BLUE'>, <SpectralBandNames.GREEN: 'GREEN'>, <SpectralBandNames.RED: 'RED'>, <SpectralBandNames.VRE_1: 'VEGETATION_RED_EDGE_1'>, <SpectralBandNames.VRE_2: 'VEGETATION_RED_EDGE_2'>, <SpectralBandNames.VRE_3: 'VEGETATION_RED_EDGE_3'>, <SpectralBandNames.NIR: 'NIR'>, <SpectralBandNames.NNIR: 'NARROW_NIR'>, <SpectralBandNames.WV: 'WATER_VAPOUR'>, <SpectralBandNames.CIRRUS: 'CIRRUS'>, <SpectralBandNames.SWIR_1: 'SWIR_1'>, <SpectralBandNames.SWIR_2: 'SWIR_2'>]
- Returns:
List of existing bands in the products
- Return type:
- get_mask_path(mask_id: str, res_id: str) CloudPath | Path [source]#
Get mask path from its id and file_id (
R1
for 10m resolution,R2
for 20m resolution)Accepted mask IDs:
DFP
: Defective pixels (do not always exist ! Will raiseInvalidProductError
if not)EDG
: Nodata pixels maskSAT
: Saturated pixels maskMG2
: Geophysical mask (classification)IAB
: Mask where water vapor and TOA pixels have been interpolatedCLM
: Cloud mask
- get_quicklook_path() str [source]#
Get quicklook path if existing (some providers are providing one quicklook, such as creodias)
- Returns:
Quicklook path
- Return type:
- get_raw_band_paths(**kwargs) dict #
Return the raw band paths.
- Parameters:
kwargs – Additional arguments
- Returns:
Dictionary containing the path of each queried band
- Return type:
- has_band(band: BandNames | str) bool #
Does this product has the specified band ?
By band, we mean:
satellite band
index
DEM band
cloud band
>>> from eoreader.reader import Reader >>> from eoreader.bands import * >>> path = r"S2A_MSIL1C_20200824T110631_N0209_R137_T30TTK_20200824T150432.SAFE.zip" >>> prod = Reader().open(path) >>> prod.has_band(GREEN) True >>> prod.has_band(TIR_2) False >>> prod.has_band(NDVI) True >>> prod.has_band(SHADOWS) False >>> prod.has_band(HILLSHADE) True
- has_bands(bands: list | BandNames | str) bool #
Does this product has the specified bands ?
By band, we mean:
satellite band
index
DEM band
cloud band
See
has_band
for a code example.
- load(bands: list | BandNames | str, pixel_size: float | None = None, size: list | tuple | None = None, **kwargs) Dataset #
Open the bands and compute the wanted index.
- For Optical data:
The bands will be purged of nodata and invalid pixels (if specified with the CLEAN_OPTICAL keyword), the nodata will be set to -9999 and the bands will be DataArrays in float32.
- For SAR data:
The bands will be purged of nodata (not over the sea), the nodata will be set to 0 to respect SNAP’s behavior and the bands will be DataArray in float32.
Bands that come out this function at the same time are collocated and therefore have the same shapes. This can be broken if you load data separately. Its is best to always load DEM data with some real bands.
>>> from eoreader.reader import Reader >>> from eoreader.bands import * >>> path = r"S2A_MSIL1C_20200824T110631_N0209_R137_T30TTK_20200824T150432.SAFE.zip" >>> prod = Reader().open(path) >>> bands = prod.load([GREEN, NDVI], pixel_size=20)
- Parameters:
- Returns:
Dataset with a variable per band
- Return type:
xr.Dataset
- open_mask(mask_id: str, band: BandNames | str, pixel_size: float | None = None, size: list | tuple | None = None, **kwargs) ndarray [source]#
Open a Sentinel-2 THEIA mask as a numpy array.
Opens the saturation and defective mask to the correct bit ID corresponding to the given band.
Opens the nodata binary mask
Opens the other masks as is
Do not open cloud mask with this function. Use
load
instead.See here for more information.
Accepted mask IDs:
DFP
: Defective pixelsEDG
: Nodata pixels maskSAT
: Saturated pixels maskMG2
: Geophysical mask (classification)IAB
: Mask where water vapor and TOA pixels have been interpolated
>>> from eoreader.bands import * >>> from eoreader.reader import Reader >>> path = r"SENTINEL2B_20190401-105726-885_L2A_T31UEQ_D_V2-0.zip" >>> prod = Reader().open(path) >>> prod.open_mask("EDG", GREEN) array([[[0, ..., 0]]], dtype=uint8)
- Parameters:
- Returns:
Mask array
- Return type:
np.ndarray
- read_mtd()#
Read metadata and outputs the metadata XML root and its namespaces as a dict.
>>> from eoreader.reader import Reader >>> path = r"S1A_IW_GRDH_1SDV_20191215T060906_20191215T060931_030355_0378F7_3696.zip" >>> prod = Reader().open(path) >>> prod.read_mtd() (<Element product at 0x1832895d788>, '')
- Returns:
Metadata XML root and its namespace
- Return type:
(etree._Element, dict)
- stack(bands: list, pixel_size: float | None = None, size: list | tuple | None = None, stack_path: str | CloudPath | Path | None = None, save_as_int: bool = False, **kwargs) DataArray #
Stack bands and index of a products.
>>> from eoreader.reader import Reader >>> from eoreader.bands import * >>> path = r"S2A_MSIL1C_20200824T110631_N0209_R137_T30TTK_20200824T150432.SAFE.zip" >>> prod = Reader().open(path) >>> stack = prod.stack([NDVI, MNDWI, GREEN], pixel_size=20) # In meters
- Parameters:
bands (list) – Bands and index combination
pixel_size (float) – Stack pixel size. . If not specified, use the product pixel size.
size (Union[tuple, list]) – Size of the array (width, height). Not used if pixel_size is provided.
stack_path (AnyPathStrType) – Stack path
save_as_int (bool) – Convert stack to uint16 to save disk space (and therefore multiply the values by 10.000)
**kwargs – Other arguments passed to
load
orrioxarray.to_raster()
(such ascompress
)
- Returns:
Stack as a DataArray
- Return type:
xr.DataArray
- to_band(raw_bands: list | BandNames | str | int) list #
Convert any raw band identifier to a usable band.
Bands can be called with their name, ID or mapped name. For example, for Sentinel-3 OLCI you can use 7, Oa07 or YELLOW. For Landsat-8, you can use BLUE or 2.
- archive_path#
Archive path, same as the product path if not specified. Useful when you want to know where both the extracted and archived version of your product are stored.
- bands#
Band mapping between band wrapping names such as
GREEN
and band real number such as03
for Sentinel-2.
- condensed_name#
Condensed name, the filename with only useful data to keep the name unique (ie.
20191215T110441_S2_30TXP_L2A_122756
). Used to shorten names and paths.
- constellation#
Product constellation, such as Sentinel-2
- constellation_id#
Constellation ID, i.e.
S2
forSentinel-2
- corresponding_ref#
The corresponding reference products to the current one (if the product is not a reference but has a reference data corresponding to it). A list because of multiple ref in case of non-stackable products (S3, S1…)
- crs = <methodtools._LruCacheWire object>#
- date#
Acquisition date.
- datetime#
Acquisition datetime.
- default_transform = <methodtools._LruCacheWire object>#
- extent = <methodtools._LruCacheWire object>#
- filename#
Product filename
- get_mean_viewing_angles = <methodtools._LruCacheWire object>#
- get_orbit_direction = <methodtools._LruCacheWire object>#
- instrument#
Product instrument, such as MSI for Sentinel-2 data.
- is_archived#
Is the archived product is processed (a products is considered as archived if its products path is a directory).
- is_ortho#
True if the images are orthorectified and the footprint is retrieved easily.
- is_reference#
If the product is a reference, used for algorithms that need pre and post data, such as fire detection.
- is_stacked#
True if the bands are stacked (like for VHR data).
- name#
Product true name (as specified in the metadata)
- needs_extraction#
Does this product needs to be extracted to be processed ? (
True
by default).
- nodata#
Product nodata, set to -9999 by default
- property output: CloudPath | Path#
Output directory of the product, to write orthorectified data for example.
- path#
Usable path to the product, either extracted or archived path, according to the satellite.
- pixel_size#
For SAR data, it is important to distinguish (square) pixel spacing from actual resolution. (see this <https://natural-resources.canada.ca/maps-tools-and-publications/satellite-imagery-and-air-photos/tutorial-fundamentals-remote-sensing/satellites-and-sensors/spatial-resolution-pixel-size-and-scale/9407> for more information). For optical data, those two terms have usually the same meaning (for a fully zoomed raster).
- product_type#
Product type, satellite-related field, such as L1C or L2A for Sentinel-2 data.
- resolution#
Default resolution in meters of the current product. For SAR product, we use Ground Range resolution as we will automatically orthorectify the tiles.
- sensor_type#
Sensor type, SAR or optical.
- split_name#
Split name, to retrieve every information from its true name (dates, tile, product type…).
- tile_name#
Tile if possible (for data that can be piled, for example S2 and Landsats).