Load the valid and quality data masks from a Sentinel 2 scene.
Parameters:
-
fpath
(str | pathlib.Path
)
–
The path to the directory containing the TIFF files.
-
reference_geobox
(odc.geo.geobox.GeoBox
)
–
The reference geobox to reproject, resample and crop the masks data to.
Returns:
-
xarray.Dataset
–
xr.Dataset: A merged xarray Dataset containing two data masks:
- 'valid_data_mask': A mask indicating valid (1) and no data (0).
- 'quality_data_mask': A mask indicating high quality (1) and low quality (0).
Source code in darts-acquisition/src/darts_acquisition/s2.py
| @stopuhr.funkuhr("Loading Sentinel 2 masks", printer=logger.debug, print_kwargs=["fpath"])
def load_s2_masks(fpath: str | Path, reference_geobox: GeoBox) -> xr.Dataset:
"""Load the valid and quality data masks from a Sentinel 2 scene.
Args:
fpath (str | Path): The path to the directory containing the TIFF files.
reference_geobox (GeoBox): The reference geobox to reproject, resample and crop the masks data to.
Returns:
xr.Dataset: A merged xarray Dataset containing two data masks:
- 'valid_data_mask': A mask indicating valid (1) and no data (0).
- 'quality_data_mask': A mask indicating high quality (1) and low quality (0).
"""
# Convert to Path object if a string is provided
fpath = fpath if isinstance(fpath, Path) else Path(fpath)
logger.debug(f"Loading data masks from {fpath.resolve()}")
# TODO: SCL band in SR file
try:
scl_path = next(fpath.glob("*_SCL*.tif"))
except StopIteration:
logger.warning("Found no data quality mask (SCL). No masking will occur.")
valid_data_mask = (odc.geo.xr.xr_zeros(reference_geobox, dtype="uint8") + 1).to_dataset(name="valid_data_mask")
valid_data_mask.attrs = {"data_source": "s2", "long_name": "Valid Data Mask"}
quality_data_mask = odc.geo.xr.xr_zeros(reference_geobox, dtype="uint8").to_dataset(name="quality_data_mask")
quality_data_mask.attrs = {"data_source": "s2", "long_name": "Quality Data Mask"}
qa_ds = xr.merge([valid_data_mask, quality_data_mask])
return qa_ds
# See scene classes here: https://custom-scripts.sentinel-hub.com/custom-scripts/sentinel-2/scene-classification/
da_scl = xr.open_dataarray(scl_path)
da_scl = da_scl.odc.reproject(reference_geobox, sampling="nearest")
# Match crs
da_scl = da_scl.rio.write_crs(reference_geobox.crs)
da_scl = xr.Dataset({"scl": da_scl.sel(band=1).fillna(0).drop_vars("band").astype("uint8")})
da_scl = convert_masks(da_scl)
return da_scl
|