From dbe4784be8a528f045c3fb25c03f2e42b308e92d Mon Sep 17 00:00:00 2001 From: BRAUN REMI Date: Mon, 4 Nov 2024 13:01:14 +0100 Subject: [PATCH] FIX: By default, try to assign a constellation (in a pure dummy way) to any `Product` created FIX: Add ways of knowing if a constellation is a real one or not (i.e. CUSTOM or template such as Maxar) --- CHANGES.md | 2 ++ CI/SCRIPTS/test_others.py | 10 ++++++++++ eoreader/products/product.py | 31 +++++++++++++++++++++++++++---- eoreader/reader.py | 21 +++++++++++++++++++++ 4 files changed, 60 insertions(+), 4 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index a8e8f801..fa5000f3 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,6 +4,8 @@ - FIX: Handle ICEYE products with missing quicklook - FIX: Fix Sentinel-1 name with weird PDFs names (i.e. ending with `.SAFE-report...`) +- FIX: By default, try to assign a constellation (in a pure dummy way) to any `Product` created +- FIX: Add ways of knowing if a constellation is a real one or not (i.e. CUSTOM or template such as Maxar) ## 0.21.6 (2024-10-17) diff --git a/CI/SCRIPTS/test_others.py b/CI/SCRIPTS/test_others.py index c2c6d2e7..0e600800 100644 --- a/CI/SCRIPTS/test_others.py +++ b/CI/SCRIPTS/test_others.py @@ -448,3 +448,13 @@ def test_deprecation(): # Check deprecation for resolution keyword with pytest.deprecated_call(): prod_green1.load(SWIR_1, resolution=2.0, window=window) + + +def test_constellations(): + real_const = Constellation.get_real_constellations() + assert Constellation.SPOT45 not in real_const + assert Constellation.MAXAR not in real_const + assert Constellation.CUSTOM not in real_const + + assert Constellation.is_real_constellation(Constellation.S2) + assert not Constellation.is_real_constellation(Constellation.MAXAR) diff --git a/eoreader/products/product.py b/eoreader/products/product.py index b9fe48e0..ab84201d 100644 --- a/eoreader/products/product.py +++ b/eoreader/products/product.py @@ -194,7 +194,9 @@ def __init__( self._mask_false = 0 self._mask_nodata = 255 - self.constellation = kwargs.get("constellation") + self.constellation = kwargs.get( + "constellation", self._get_constellation_dummy() + ) """Product constellation, such as Sentinel-2""" # Set the resolution, needs to be done when knowing the product type @@ -257,6 +259,11 @@ def __init__( # Constellation and satellite ID if not self.constellation: self.constellation = self._get_constellation() + if self.constellation is None: + raise InvalidProductError( + f"Impossible to set a constellation to the given product! {self.name}" + ) + self.constellation_id = ( self.constellation if isinstance(self.constellation, str) @@ -418,9 +425,25 @@ def _set_instrument(self) -> None: @classmethod def _get_constellation(cls) -> Constellation: - class_module = cls.__module__.split(".")[-1] - constellation_id = class_module.replace("_product", "").upper() - return getattr(Constellation, constellation_id) + return cls._get_constellation_dummy(raise_ex=True) + + @classmethod + def _get_constellation_dummy(cls, raise_ex: bool = False) -> Constellation: + try: + class_module = cls.__module__.split(".")[-1] + constellation_id = class_module.replace("_product", "").upper() + const = getattr(Constellation, constellation_id) + except AttributeError as ex: + if raise_ex: + raise ex + else: + const = None + + # In Dummy, don't set generic constellations! + if const not in Constellation.get_real_constellations(): + const = None + + return const def _get_name(self) -> str: """ diff --git a/eoreader/reader.py b/eoreader/reader.py index bce48510..68a90a32 100644 --- a/eoreader/reader.py +++ b/eoreader/reader.py @@ -239,6 +239,27 @@ class Constellation(ListEnum): CUSTOM = "CUSTOM" """Custom stack""" + @classmethod + def get_real_constellations(cls): + """ + Get only constellations of existing satellite (discard CUSTOM, templates etc) + """ + not_real = [cls.MAXAR, cls.SPOT45, cls.CUSTOM] + return {const for const in cls.__members__.values() if const not in not_real} + + @classmethod + def is_real_constellation(cls, const: Constellation): + """ + Is the given constellation a real one? + + Args: + const (Constellation): Constellation to check + + Returns: + + """ + return cls.convert_from(const)[0] in cls.get_real_constellations() + CONSTELLATION_REGEX = { Constellation.S1: r"S1[ABCD]_(IW|EW|SM|WV|S\d)_(RAW|SLC|GRD|OCN)[FHM_]_[0-2]S[SD][HV]_\d{8}T\d{6}_\d{8}T\d{6}_\d{6}_.{11}(_COG|)",