[Git][debian-gis-team/asf-search][upstream] New upstream version 10.1.2

Antonio Valentino (@antonio.valentino) gitlab at salsa.debian.org
Sun Nov 2 11:54:54 GMT 2025



Antonio Valentino pushed to branch upstream at Debian GIS Project / asf-search


Commits:
d0900dc7 by Antonio Valentino at 2025-11-02T11:46:08+00:00
New upstream version 10.1.2
- - - - -


12 changed files:

- CHANGELOG.md
- asf_search/CMR/datasets.py
- asf_search/Products/ARIAS1GUNWProduct.py
- asf_search/constants/DATASET.py
- asf_search/constants/PRODUCT_TYPE.py
- asf_search/search/baseline_search.py
- asf_search/search/search_generator.py
- setup.py
- tests/BaselineSearch/test_baseline_search.py
- + tests/yml_tests/Resources/S1A_IW_SLC__1SSV_20160528T141908_20160528T141938_011460_011746_335C_stack.yml
- tests/yml_tests/test_baseline_search.yml
- tests/yml_tests/test_search.yml


Changes:

=====================================
CHANGELOG.md
=====================================
@@ -25,6 +25,19 @@ and uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 -
 
 -->
+------
+## [v10.1.2](https://github.com/asfadmin/Discovery-asf_search/compare/v10.1.1...v10.1.2)
+### Added
+- Add `CRSD` and `RRSD` constants to `PRODUCT_TYPE`
+- Add docstrings for `DATASET.NISAR` and the various related `PRODUCT_TYPE` constants
+- Add static method `get_stack_opts_for_frame()` to `ARIAS1GUNWProduct` class, returns ARIA frame stack opts for given frame ID
+
+### Fixed
+- No longer query CMR with `L0B` directly, now properly aliased to `CRSD` and `RRSD` product types
+
+### Changed
+- Bump asf-enumeration version minimum version to 0.4.0 for Sentinel-1C support
+
 ------
 ## [v10.1.1](https://github.com/asfadmin/Discovery-asf_search/compare/v10.1.0...v10.1.1)
 ### Added


=====================================
asf_search/CMR/datasets.py
=====================================
@@ -3,7 +3,7 @@ from typing import List
 from asf_search.constants import PRODUCT_TYPE
 
 NISAR_PRODUCT_TYPES = [
-    PRODUCT_TYPE.L0B, #L4
+    PRODUCT_TYPE.CRSD, PRODUCT_TYPE.RRSD, #L0
     PRODUCT_TYPE.SME2, # L3
     PRODUCT_TYPE.GSLC, PRODUCT_TYPE.GCOV, PRODUCT_TYPE.GUNW, PRODUCT_TYPE.GOFF, # L2
     PRODUCT_TYPE.RSLC, PRODUCT_TYPE.RIFG, PRODUCT_TYPE.RUNW, PRODUCT_TYPE.ROFF,  # L1
@@ -1628,6 +1628,36 @@ collections_by_processing_level = {
         'C1256358262-ASFDEV', # Validated
         'C1257349115-ASF',
         'C3622265756-ASF',
+        'C1258125097-ASFDEV',
+        'C1258836794-ASF',
+        'C2887469134-ASF',
+
+        'C1261815276-ASFDEV', # CRSD
+        'C1273831262-ASF',
+        'C2850225137-ASF',
+        'C1261832632-ASFDEV', # Provisional
+        'C1261832671-ASF',
+        'C2853091612-ASF',
+        'C1256358463-ASFDEV', # Validate
+        'C1257349114-ASF',
+        'C3622254588-ASF',
+    ],
+    'RRSD': [
+        'C1261815274-ASFDEV', # RRSD BETA
+        'C1273831320-ASF',
+        'C3622228339-ASF',
+        'C1261832497-ASFDEV', # Provisional
+        'C1261832659-ASF',
+        'C2853089814-ASF',
+        'C1256358262-ASFDEV', # Validated
+        'C1257349115-ASF',
+        'C3622265756-ASF',
+        
+        'C1258125097-ASFDEV',
+        'C1258836794-ASF',
+        'C2887469134-ASF',
+    ],
+    'CRSD': [
         'C1261815276-ASFDEV', # CRSD
         'C1273831262-ASF',
         'C2850225137-ASF',


=====================================
asf_search/Products/ARIAS1GUNWProduct.py
=====================================
@@ -56,23 +56,28 @@ class ARIAS1GUNWProduct(S1Product):
             self.properties['fileName'] = self.properties['fileID'] + '.' + urls[0].split('.')[-1]
             self.properties['additionalUrls'] = urls[1:]
 
-    def get_stack_opts(self, opts: Optional[ASFSearchOptions] = None) -> ASFSearchOptions | None:
+    def get_stack_opts(self, opts: Optional[ASFSearchOptions] = None) -> Optional[ASFSearchOptions]:
         """
         Build search options that can be used to find an insar stack for this product
 
         :return: ASFSearchOptions describing appropriate options
         for building a stack from this product
         """
+        return ARIAS1GUNWProduct.get_stack_opts_for_frame(self.properties['frameNumber'], opts)
+
+
+    @staticmethod
+    def get_stack_opts_for_frame(frame_id: int, opts: Optional[ASFSearchOptions] = None) -> Optional[ASFSearchOptions]:
         if aria_s1_gunw is None:
             warnings.warn("Failed to import asf-enumeration package. \
                           Make sure it's installed in your current environment to perform stacking with the ARIAS1GUNWProduct type")
             return None
         stack_opts = ASFSearchOptions() if opts is None else copy(opts)
-        aria_frame = aria_s1_gunw.get_frame(self.properties['frameNumber'])
+        aria_frame = aria_s1_gunw.get_frame(frame_id)
         
         # pulled from asf-enumeration package implementation
         stack_opts.dataset = DATASET.SENTINEL1
-        stack_opts.platform = ['SA', 'SB']
+        stack_opts.platform = ['SA', 'SB', 'SC']
         stack_opts.processingLevel = PRODUCT_TYPE.SLC
         stack_opts.beamMode = BEAMMODE.IW
         stack_opts.polarization = [POLARIZATION.VV, POLARIZATION.VV_VH]


=====================================
asf_search/constants/DATASET.py
=====================================
@@ -15,3 +15,6 @@ JERS_1 = 'JERS-1'
 AIRSAR = 'AIRSAR'
 SEASAT = 'SEASAT'
 NISAR = 'NISAR'
+"""NISAR provides L and S-band SAR data to measure Earth's changing ecosystems,
+ dynamic surfaces, and ice masses with 12-day regularity
+ on ascending and descending passes."""


=====================================
asf_search/constants/PRODUCT_TYPE.py
=====================================
@@ -105,12 +105,27 @@ TROPO_ZENITH = 'TROPO-ZENITH'
 
 # NISAR
 L0B = 'L0B'
+"""Convenient alias for CRSD and RRSD Level Zero B product types"""
+
+CRSD = 'CRSD'
+RRSD = 'RRSD'
+
 RSLC = 'RSLC'
+"""Level 1 Range-Doppler Single Look Complex"""
 RIFG = 'RIFG'
+"""Level 1 Range-Doppler Wrapped Interferrogram"""
 RUNW = 'RUNW'
+"""Level 1 Range-Doppler Unwrapped Interferrogram"""
 ROFF = 'ROFF'
+"""Level 1 Range-Doppler Pixel Offsets"""
 GSLC = 'GSLC'
+"""Level 2 Geocoded Single Look Complex"""
 GCOV = 'GCOV'
+"""Level 2 Geocoded Polarimetric Covariance"""
 GUNW = 'GUNW'
+""""Level 2 Geocoded Unwrapped Inteferrogram"""
 GOFF = 'GOFF'
+"""Level 2 Geocoded Pixel Offsets"""
 SME2 = 'SME2'
+"""Level 3 Soil Moisture EASE-Grid 2.0"""
+


=====================================
asf_search/search/baseline_search.py
=====================================
@@ -57,12 +57,9 @@ def stack_from_product(
         _cast_results_to_subclass(stack, ASFProductSubclass)
 
     stack, warnings = get_baseline_from_stack(reference=reference, stack=stack)
-    stack.searchComplete = is_complete  # preserve final outcome of earlier search()
 
-    stack.sort(key=lambda product: product.properties['temporalBaseline'])
+    _post_process_stack(stack, warnings, is_complete)
 
-    for warning in warnings:
-        ASF_LOGGER.warning(f'{warning}')
 
     return stack
 
@@ -102,10 +99,12 @@ def stack_from_id(
         else:
             reference = reference_results[0]
         
-        return get_baseline_from_stack(reference=reference, stack=reference_results)[0]
+        stack, warnings = get_baseline_from_stack(reference=reference, stack=reference_results)
+        _post_process_stack(stack, warnings, reference_results.searchComplete)
+
+        return stack
     else:
         reference_results = product_search(product_list=reference_id, opts=opts)
-        reference_results.raise_if_incomplete()
 
     if len(reference_results) <= 0:
         raise ASFSearchError(f'Reference product not found: {reference_id}')
@@ -155,3 +154,10 @@ def _cast_to_subclass(product: ASFProduct, subclass: Type[ASFProduct]) -> ASFPro
         raise ValueError(f'Unable to use provided subclass {type(subclass)}, \nError Message: {e}')
 
     raise ValueError(f'Expected ASFProduct subclass constructor, got {type(subclass)}')
+
+def _post_process_stack(stack: ASFSearchResults, warnings: list, is_complete: bool):
+    """Marks whether the search completed gathering results, logs any warnings, and sorts stack by temporal baseline"""
+    stack.searchComplete = is_complete  # preserve final outcome of earlier search()
+    for warning in warnings:
+        ASF_LOGGER.warning(f'{warning}')
+    stack.sort(key=lambda product: product.properties['temporalBaseline'])


=====================================
asf_search/search/search_generator.py
=====================================
@@ -376,6 +376,8 @@ def preprocess_opts(opts: ASFSearchOptions):
     # Platform Alias logic:
     set_platform_alias(opts=opts)
 
+    set_science_product_alias(opts=opts)
+
 
 def wrap_wkt(opts: ASFSearchOptions):
     if opts.intersectsWith is not None:
@@ -448,6 +450,23 @@ def set_platform_alias(opts: ASFSearchOptions):
 
 _dataset_collection_items = dataset_collections.items()
 
+def set_science_product_alias(opts: ASFSearchOptions):
+    """Alias certain product types (primarily NISAR L0B)"""
+    if opts.processingLevel is not None:
+        processingLevelAliases = {
+            'L0B': ['CRSD', 'RRSD']
+        }
+
+        processing_levels = []
+        for processing_level in opts.processingLevel:
+            # If it's a key, *replace* it with all the values. Else just add the key:
+            if processing_level.upper() in processingLevelAliases:
+                processing_levels.extend(processingLevelAliases[processing_level.upper()])
+            else:
+                processing_levels.append(processing_level)
+
+        opts.processingLevel = processing_levels
+
 
 def as_ASFProduct(item: Dict, session: ASFSession) -> ASFProduct:
     """Returns the granule umm as the corresponding ASFProduct subclass,


=====================================
setup.py
=====================================
@@ -31,7 +31,7 @@ extra_requirements = [
 
 # Required for ARIA-S1 GUNW Stacking
 asf_enumeration = [
-    'asf-enumeration>=0.3.0'
+    'asf-enumeration>=0.4.0'
 ]
 
 


=====================================
tests/BaselineSearch/test_baseline_search.py
=====================================
@@ -34,7 +34,7 @@ def run_test_get_unprocessed_stack_params(product):
         assert [reference.properties['polarization']] == params.polarization
         assert [reference.properties['burst']['fullBurstID']] == params.fullBurstID
     elif reference.properties['sceneName'].startswith('S1-GUNW'):
-        assert params.platform == ['SA', 'SB']
+        assert params.platform == ['SA', 'SB', 'SC']
         assert DATASET.SENTINEL1 in params.dataset
         assert params.processingLevel == [PRODUCT_TYPE.SLC]
         assert params.beamMode == [BEAMMODE.IW]
@@ -107,8 +107,9 @@ def run_test_stack_from_id(stack_id: str, reference, stack, opts: ASFSearchOptio
                 )
 
                 returned_stack = stack_from_id(stack_id, opts=opts)
-
-                for idx, secondary in enumerate(returned_stack):
+                stack_files = set(x['properties']['fileID'] for x in stack)
+                filtered_stack = [x for x in returned_stack if x.properties['fileID'] in stack_files]
+                for idx, secondary in enumerate(filtered_stack):
                     if idx > 0:
                         assert (
                             secondary.properties['temporalBaseline']


=====================================
tests/yml_tests/Resources/S1A_IW_SLC__1SSV_20160528T141908_20160528T141938_011460_011746_335C_stack.yml
=====================================
The diff for this file was not included because it is too large.

=====================================
tests/yml_tests/test_baseline_search.yml
=====================================
@@ -51,4 +51,9 @@ tests:
     stack_id: 5289
     stack_reference: null
     stack: ARIAS1GUNW_stack.yml
-    dataset: 'ARIA S1 GUNW'
\ No newline at end of file
+    dataset: 'ARIA S1 GUNW'
+
+- test-stack-id S1 ID:
+    stack_reference: null
+    stack: S1A_IW_SLC__1SSV_20160528T141908_20160528T141938_011460_011746_335C_stack.yml
+    stack_id: S1A_IW_SLC__1SSV_20160528T141908_20160528T141938_011460_011746_335C-SLC


=====================================
tests/yml_tests/test_search.yml
=====================================
@@ -175,6 +175,169 @@ sentinel-1_collections: &sentinel-1_collections
   - "C1257175154-ASFDEV"
   - "C1244598379-ASFDEV"
 
+nisar_collections: &nisar_collections
+  [
+    # UAT ASFDEV
+    'C1261815181-ASFDEV',
+    'C1261832381-ASFDEV',
+    'C1256533420-ASFDEV',
+    'C1261813453-ASFDEV',
+    'C1261832466-ASFDEV',
+    'C1256524081-ASFDEV',
+    'C1261815274-ASFDEV',
+    'C1261832497-ASFDEV',
+    'C1256358262-ASFDEV',
+    'C1261815276-ASFDEV',
+    'C1261832632-ASFDEV',
+    'C1256358463-ASFDEV',
+    'C1261813489-ASFDEV',
+    'C1261832868-ASFDEV',
+    'C1273095154-ASFDEV',
+    'C1261819086-ASFDEV',
+    'C1261832940-ASFDEV',
+    'C1256381769-ASFDEV',
+    'C1261819098-ASFDEV',
+    'C1261832990-ASFDEV',
+    'C1256420738-ASFDEV',
+    'C1261819110-ASFDEV',
+    'C1261832993-ASFDEV',
+    'C1256411631-ASFDEV',
+    'C1261819167-ASFDEV',
+    'C1261833024-ASFDEV',
+    'C1256413628-ASFDEV',
+    'C1261819168-ASFDEV',
+    'C1261833025-ASFDEV',
+    'C1256432264-ASFDEV',
+    'C1261819211-ASFDEV',
+    'C1261833026-ASFDEV',
+    'C1256477304-ASFDEV',
+    'C1261819233-ASFDEV',
+    'C1261833027-ASFDEV',
+    'C1256479237-ASFDEV',
+    'C1261819245-ASFDEV',
+    'C1261833050-ASFDEV',
+    'C1256568692-ASFDEV',
+    'C1262134528-ASFDEV',
+    'C1258125097-ASFDEV',
+    'C1258290319-ASFDEV',
+    'C1258301530-ASFDEV',
+    'C1261630276-ASFDEV',
+    'C1256574227-ASFDEV',
+    'C1256579794-ASFDEV',
+    'C1256729502-ASFDEV',
+    'C1256535568-ASFDEV',
+    'C1256578011-ASFDEV',
+    'C1256802323-ASFDEV',
+    'C1256938783-ASFDEV',
+    'C1256535570-ASFDEV',
+    # UAT
+    'C1261815288-ASF',
+    'C1261832657-ASF',
+    'C1257349121-ASF',
+    'C1273831241-ASF',
+    'C1261832658-ASF',
+    'C1257349120-ASF',
+    'C1273831320-ASF',
+    'C1261832659-ASF',
+    'C1257349115-ASF',
+    'C1273831262-ASF',
+    'C1261832671-ASF',
+    'C1257349114-ASF',
+    'C1273831203-ASF',
+    'C1261833052-ASF',
+    'C1273831205-ASF',
+    'C1273831200-ASF',
+    'C1261833063-ASF',
+    'C1257349108-ASF',
+    'C1261819121-ASF',
+    'C1261833064-ASF',
+    'C1257349107-ASF',
+    'C1261819145-ASF',
+    'C1261833076-ASF',
+    'C1257349103-ASF',
+    'C1273831198-ASF',
+    'C1261833127-ASF',
+    'C1257349102-ASF',
+    'C1261819270-ASF',
+    'C1261846741-ASF',
+    'C1257349096-ASF',
+    'C1273831195-ASF',
+    'C1261846880-ASF',
+    'C1257349095-ASF',
+    'C1261819281-ASF',
+    'C1261846994-ASF',
+    'C1257349094-ASF',
+    'C1261819282-ASF',
+    'C1261847095-ASF',
+    'C1257349093-ASF',
+    'C1262135006-ASF',
+    'C1258836794-ASF',
+    'C1273831207-ASF',
+    'C1258836800-ASF',
+    'C1261712879-ASF',
+    'C1257349088-ASF',
+    'C1257349083-ASF',
+    'C1257349067-ASF',
+    'C1257349089-ASF',
+    'C1257349074-ASF',
+    'C1257349063-ASF',
+    'C1257349059-ASF',
+    'C1257349082-ASF',
+    # PROD
+    'C2850220296-ASF',
+    'C2853068083-ASF',
+    'C2727902012-ASF',
+    'C2850223384-ASF',
+    'C2853086824-ASF',
+    'C3622203972-ASF',
+    'C3622228339-ASF',
+    'C2853089814-ASF',
+    'C3622265756-ASF',
+    'C2850225137-ASF',
+    'C2853091612-ASF',
+    'C3622254588-ASF',
+    'C2850225585-ASF',
+    'C2853145197-ASF',
+    'C3622236985-ASF',
+    'C2850234202-ASF',
+    'C2853147928-ASF',
+    'C3622229381-ASF',
+    'C2850235455-ASF',
+    'C2853153429-ASF',
+    'C3622237369-ASF',
+    'C2850237619-ASF',
+    'C2853156054-ASF',
+    'C3622241997-ASF',
+    'C2850259510-ASF',
+    'C2854332392-ASF',
+    'C3622244601-ASF',
+    'C2850261892-ASF',
+    'C2854335566-ASF',
+    'C3622247503-ASF',
+    'C3622214170-ASF',
+    'C2854338529-ASF',
+    'C2727896018-ASF',
+    'C2850263910-ASF',
+    'C2854341702-ASF',
+    'C3622250865-ASF',
+    'C2850265000-ASF',
+    'C2854344945-ASF',
+    'C3622248530-ASF',
+    'C2874824964-ASF',
+    'C2887469134-ASF',
+    'C2887499907-ASF',
+    'C2887502657-ASF',
+    'C3622222871-ASF',
+    'C2727908375-ASF',
+    'C2727912431-ASF',
+    'C3622253574-ASF',
+    'C3622233495-ASF',
+    'C2727911748-ASF',
+    'C3622219145-ASF',
+    'C3622216140-ASF',
+    'C2727904608-ASF',
+  ]
+
 tests:
   - test-ASFSearch ALOS Resp 1:
       response: Alos_response_maxResults3.yml
@@ -235,6 +398,23 @@ tests:
       expected:
         - collections: *sentinel-1_collections
 
+  - test-search-build_subquery NISAR-Dataset L0B:
+      params:
+        processingLevel:
+          - L0B
+        dataset:
+          - NISAR
+      expected: [
+        {
+        processingLevel: ['CRSD'],
+        collections: *nisar_collections
+        },
+        {
+        processingLevel: ['RRSD'],
+        collections: *nisar_collections
+        }
+      ]
+
   - test-search-build_subquery S1-Platform SLC:
       params:
         platform:



View it on GitLab: https://salsa.debian.org/debian-gis-team/asf-search/-/commit/d0900dc76a65ac0943c8f2c7f22b895b4a4aa88e

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/asf-search/-/commit/d0900dc76a65ac0943c8f2c7f22b895b4a4aa88e
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20251102/a2dc1c85/attachment-0001.htm>


More information about the Pkg-grass-devel mailing list