Source code for eoio.readers.flex.subset

"""
eoio.readers.flex.subset
========================

Subset resolution for FLEX products.

Classes
-------
.. autosummary::
   :toctree: generated/

   FLEXSubset

Functions
---------
.. autosummary::
   :toctree: generated/

   build_subset
"""

from __future__ import annotations
from dataclasses import dataclass, field
from typing import Dict, Mapping, Optional
import numpy as np
import xarray as xr

from eoio.readers.flex.grid import FlexGrid
from eoio.readers.subset.roi_subset import ResolvedROISubset, ROISubsetResolver
from eoio.readers.subset.wavelength_subset import WavelengthSubsetResolver

__all__ = ["FLEXSubset", "build_subset"]


[docs] @dataclass(frozen=True) class FLEXSubset: """ Resolved subsetting information for a FLEX read. :param x_indices: column indices to keep, or ``None`` for all. :param y_indices: row indices to keep, or ``None`` for all. :param wavelength_indices: indices to keep for each wavelength dimension, e.g. ``{"wavelength_olci": array([...])}``. The same wavelength criteria are applied to every spectral grid in the product, each on its own wavelengths. :param roi: resolved ROI (in the product CRS), or ``None``. """ x_indices: Optional[np.ndarray] = None y_indices: Optional[np.ndarray] = None wavelength_indices: Dict[str, np.ndarray] = field(default_factory=dict) roi: Optional[ResolvedROISubset] = None
[docs] def build_subset(grid: FlexGrid, wavelengths: Mapping[str, xr.DataArray], subset: Mapping) -> FLEXSubset: """ Resolve a user subset request against the product grid and wavelength coordinates. :param grid: product grid. :param wavelengths: wavelength coordinate (1-D array-like with ``.size``) for each wavelength dimension. :param subset: subset request with optional ``roi``, ``roi_crs`` and ``wavelength`` keys. :returns: resolved subset. """ roi_subset = None x_idx = y_idx = None if subset.get("roi") is not None: roi_subset = ROISubsetResolver(subset["roi"], subset["roi_crs"], grid.epsg, grid.bounds).run() xmin, ymin, xmax, ymax = roi_subset.clip_box # type: ignore[misc] x, y = grid.x, grid.y # keep every pixel that overlaps the ROI bounding box x_idx = np.where((x + grid.dx / 2 >= xmin) & (x - grid.dx / 2 <= xmax))[0] y_idx = np.where((y + grid.dy / 2 >= ymin) & (y - grid.dy / 2 <= ymax))[0] wavelength_indices: Dict[str, np.ndarray] = {} if subset.get("wavelength") is not None: for dim, wvl in wavelengths.items(): resolved = WavelengthSubsetResolver(wvl, subset["wavelength"]).run() wavelength_indices[dim] = np.asarray(resolved.variable_indices, dtype=int) return FLEXSubset(x_indices=x_idx, y_indices=y_idx, wavelength_indices=wavelength_indices, roi=roi_subset)
if __name__ == "__main__": pass