diff --git a/CHANGELOG.md b/CHANGELOG.md index f315c6b5..49103d36 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,13 @@ and uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - --> +------ +## [v7.1.2](https://github.com/asfadmin/Discovery-asf_search/compare/v7.1.1...v7.1.2) +### Fixed +- `OPERAS1Product` subclass now properly assigned to PGE v2.0.1 results +### Changed +- `ARIAS1GUNWProduct.is_ARIAS1GUNWProduct()` removed, replaced with `ASFProduct._is_subclass()` implementation + ------ ## [v7.1.1](https://github.com/asfadmin/Discovery-asf_search/compare/v7.1.0...v7.1.1) ### Changed diff --git a/asf_search/ASFProduct.py b/asf_search/ASFProduct.py index 0b252e87..e2681ff2 100644 --- a/asf_search/ASFProduct.py +++ b/asf_search/ASFProduct.py @@ -424,3 +424,14 @@ def umm_cast(f, v): return f(v) except TypeError: return None + + @staticmethod + def _is_subclass(item: Dict) -> bool: + """ + Used to determine which subclass to use for specific edge-cases when parsing results in search methods + (Currently implemented for ARIA and OPERA subclasses). + + params: + - item (dict): the CMR UMM-G item to read from + """ + raise NotImplementedError() diff --git a/asf_search/Products/ARIAS1GUNWProduct.py b/asf_search/Products/ARIAS1GUNWProduct.py index 34be38ce..ab477bfc 100644 --- a/asf_search/Products/ARIAS1GUNWProduct.py +++ b/asf_search/Products/ARIAS1GUNWProduct.py @@ -58,7 +58,7 @@ def get_default_baseline_product_type() -> None: return None @staticmethod - def is_ARIAS1GUNWProduct(item: Dict) -> bool: + def _is_subclass(item: Dict) -> bool: platform = ASFProduct.umm_get(item['umm'], 'Platforms', 0, 'ShortName') if platform in ['SENTINEL-1A', 'SENTINEL-1B']: asf_platform = ASFProduct.umm_get(item['umm'], 'AdditionalAttributes', ('Name', 'ASF_PLATFORM'), 'Values', 0) diff --git a/asf_search/Products/OPERAS1Product.py b/asf_search/Products/OPERAS1Product.py index 86af7bbe..67055875 100644 --- a/asf_search/Products/OPERAS1Product.py +++ b/asf_search/Products/OPERAS1Product.py @@ -19,6 +19,8 @@ class OPERAS1Product(S1Product): 'polarization': {'path': ['AdditionalAttributes', ('Name', 'POLARIZATION'), 'Values']} # dual polarization is in list rather than a 'VV+VH' style format } + _subclass_concept_ids = { 'C1257995185-ASF', 'C1257995186-ASF', 'C1258354200-ASF', 'C1258354201-ASF', 'C1259974840-ASF', 'C1259976861-ASF', 'C1259981910-ASF', 'C1259982010-ASF', 'C2777436413-ASF', 'C2777443834-ASF', 'C2795135174-ASF', 'C2795135668-ASF','C1260721853-ASF', 'C1260721945-ASF', 'C2803501097-ASF', 'C2803501758-ASF' } + def __init__(self, args: Dict = {}, session: ASFSession = ASFSession()): super().__init__(args, session) @@ -78,3 +80,10 @@ def get_sort_keys(self) -> Tuple[str, str]: return (self._read_property('validityStartDate', ''), keys[1]) return keys + + @staticmethod + def _is_subclass(item: Dict) -> bool: + # not all umm products have this field set, + # but when it's available it's convenient for fast matching + concept_id = item['meta'].get('collection-concept-id') + return concept_id in OPERAS1Product._subclass_concept_ids diff --git a/asf_search/search/baseline_search.py b/asf_search/search/baseline_search.py index e4299c31..f3b46a6c 100644 --- a/asf_search/search/baseline_search.py +++ b/asf_search/search/baseline_search.py @@ -52,7 +52,7 @@ def stack_from_product( stack.sort(key=lambda product: product.properties['temporalBaseline']) for warning in warnings: - ASF_LOGGER.warn(f'{warning}') + ASF_LOGGER.warning(f'{warning}') return stack diff --git a/asf_search/search/search_generator.py b/asf_search/search/search_generator.py index f2a9b772..10b64892 100644 --- a/asf_search/search/search_generator.py +++ b/asf_search/search/search_generator.py @@ -266,6 +266,9 @@ def as_ASFProduct(item: Dict, session: ASFSession) -> ASFProduct: :returns the granule as an object of type ASFProduct """ + if ASFProductType.OPERAS1Product._is_subclass(item): + return ASFProductType.OPERAS1Product(item, session=session) + product_type_key = _get_product_type_key(item) # if there's a direct entry in our dataset to product type dict @@ -283,7 +286,7 @@ def as_ASFProduct(item: Dict, session: ASFSession) -> ASFProduct: # If the platform exists, try to match it platform = _get_platform(item=item) - if ASFProductType.ARIAS1GUNWProduct.is_ARIAS1GUNWProduct(item=item): + if ASFProductType.ARIAS1GUNWProduct._is_subclass(item=item): return dataset_to_product_types.get('ARIA S1 GUNW')(item, session=session) elif (subclass := dataset_to_product_types.get(platform)) is not None: return subclass(item, session=session) @@ -306,10 +309,10 @@ def _get_product_type_key(item: Dict) -> str: collection_shortName = ASFProduct.umm_get(item['umm'], 'CollectionReference', 'ShortName') if collection_shortName is None: - platform = _get_platform(item=item) - if ASFProductType.ARIAS1GUNWProduct.is_ARIAS1GUNWProduct(item=item): + if ASFProductType.ARIAS1GUNWProduct._is_subclass(item=item): return 'ARIA S1 GUNW' + platform = _get_platform(item=item) return platform return collection_shortName