eomatch.utils.crop.crop_to_shared_valid_extent

eomatch.utils.crop.crop_to_shared_valid_extent#

eomatch.utils.crop.crop_to_shared_valid_extent(product_ds: Iterable[Dataset | DataTree]) → List[Dataset | DataTree][source]#

Crop gridded products to the lat/lon bounding box where all of them have valid measurement data.

Products’ native grids commonly only partially overlap and/or carry NaN padding well beyond their actual footprint (e.g. a diagonal swath inside a larger rectangular tile) – without this, a lot of every grid is padding that can never be compared, which dilutes any downstream alignment or analysis. Since products aren’t necessarily on the same pixel grid at this stage, the shared region (the image-collocated ROI) is computed from each product’s own valid-data lat/lon extent, deriving lat/lon from projected x/y + CRS first where it isn’t already present.

Non-gridded products (no (y, x)-like dims), a flat Dataset product spanning more than one distinct spatial grid (e.g. an un-split multi-resolution read – see _has_single_spatial_grid()), and products with no identifiable measurement variables or lat/lon, are passed through unchanged and excluded from the shared-extent calculation. If fewer than two products qualify, all products are passed through unchanged (there is nothing to collocate against). Deriving lat/lon for a product that doesn’t already have it needs the optional spatial extra (pyproj/rioxarray); if that isn’t installed, such a product is likewise excluded rather than this function raising.

A product read with a per-collection "to_datatree" processor as the last step of its own read pipeline (e.g. the RGB-preview collection_read_args in the example scripts) arrives here as an xr.DataTree rather than a flat Dataset – see _resolve_datatree_nodes(). Every one of its populated grid nodes is cropped independently (e.g. a genuinely multi-resolution read, such as Sentinel-2 at 10 m and 20 m, has more than one), each to the same final shared bbox – a product’s own contribution to that shared bbox is the union of its nodes’ individual valid extents, so e.g. Sentinel-2’s 10 m and 20 m bands (covering, near enough, the same physical scene) are matched against another product as one combined footprint, not two independently-negotiated ones. The rest of the tree (e.g. an empty root) is returned untouched. A DataTree with zero populated nodes is excluded, the same as a product with no identifiable measurement variables or lat/lon.

Parameters:

product_ds – per-sensor datasets (or, per above, DataTrees), as returned by read_products().

Returns:

new list, same order and same Dataset-vs-DataTree shape per item, cropped where applicable.

Raises:

ValueError – if two or more qualifying products’ valid extents don’t overlap.