Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
d8ed342
feat: Phase 0 — S1 GRD RTC design, S1Tiling integration, and real-dat…
emmanuelmathot Mar 23, 2026
5b488af
phase 0: integrate all lessons learned into plan and docs
emmanuelmathot Mar 23, 2026
7482f7d
phase 1: S1 RTC Pydantic models aligned with S2 pattern
emmanuelmathot Mar 23, 2026
dcf0dab
refactor: improve Pydantic model definitions and streamline imports i…
emmanuelmathot Mar 23, 2026
319611b
docs: update Phase 1 checklist, add Phase 1 findings, link tracking i…
emmanuelmathot Mar 24, 2026
1dd5685
fix: standardize spatial dimensions to lowercase in S1 RTC models and…
emmanuelmathot Mar 24, 2026
5c7ce91
fix: add 1D spatial coordinate arrays and use lowercase dimension nam…
emmanuelmathot Mar 24, 2026
cdfd48b
feat: add detailed implementation plan for Phase 2 GeoTIFF ingestion …
emmanuelmathot Mar 24, 2026
de5f563
fix: update Phase 2 GeoTIFF ingestion plan to include 1D spatial coor…
emmanuelmathot Mar 24, 2026
6a4d333
feat: Phase 2 — S1 GRD RTC GeoTIFF ingestion pipeline
emmanuelmathot Mar 24, 2026
a8ddcdb
refactor: use zcm.Multiscales typed model per reviewer feedback
emmanuelmathot Mar 24, 2026
78fba35
fix: configure ruff TC001 for Pydantic runtime-evaluated base classes
emmanuelmathot Mar 24, 2026
1e891e5
feat: implement S1Tiling conditions ingestion and discovery commands …
emmanuelmathot Mar 24, 2026
f749368
feat(stac): add build_s1_rtc_stac_item and generate-stac-s1 CLI (#173)
lhoupert Jun 3, 2026
3e7a3fd
Revert "feat(stac): add build_s1_rtc_stac_item and generate-stac-s1 C…
lhoupert Jun 3, 2026
22e39cd
fix(s1-ingest): discover multi-frame acquisitions with a masked times…
lhoupert Jun 9, 2026
897ee19
chore: merge main into s1-tiling (#190)
lhoupert Jun 16, 2026
c3834cb
Merge origin/main into s1-tiling (align with #199: zarr-cm 0.4.1 + py…
lhoupert Jul 8, 2026
31093d0
feat(s1-rtc): STAC item builders + ingest fixes for TiTiler rendering…
lhoupert Jul 14, 2026
b0d31be
style(s1): satisfy ruff lint and format checks
lhoupert Jul 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
471 changes: 471 additions & 0 deletions .github/prompts/phase2-geotiff-ingestion-plan.md

Large diffs are not rendered by default.

823 changes: 823 additions & 0 deletions .github/prompts/s1-grd-rtc-implementation-plan-v2.md

Large diffs are not rendered by default.

407 changes: 407 additions & 0 deletions analysis/inspect_s1tiling_geotiff.py

Large diffs are not rendered by default.

631 changes: 631 additions & 0 deletions analysis/s1_grd_rtc_prototype.py

Large diffs are not rendered by default.

699 changes: 699 additions & 0 deletions analysis/s1_real_geotiff_to_zarr.py

Large diffs are not rendered by default.

406 changes: 406 additions & 0 deletions analysis/s1tiling_docker_instructions.md

Large diffs are not rendered by default.

123 changes: 123 additions & 0 deletions analysis/s1tiling_eodag4_patch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
#!/usr/bin/env python3
"""
Patch S1Tiling 1.4.0 for EODAG 4.0.0 compatibility.

EODAG 4.0.0 introduced several breaking changes for S1Tiling:
1. `productType` kwarg to dag.search() was renamed to `collection`.
Having both causes cop_dataspace to fail silently → falls back to peps.
2. Product properties use STAC names (sat:orbit_state, platform, etc.)
instead of legacy EODAG names (orbitDirection, platformSerialIdentifier, etc.)
3. cop_dataspace OData v4 rejects `polarizationChannels` and `sensorMode`.
4. cop_dataspace requires UPPERCASE orbit direction ("DESCENDING" not "descending").
5. `relativeOrbitNumber` search param silently returns 0 results on cop_dataspace.

This script patches:
- S1FileManager.py: fixes the search() call (issues 1, 3, 4, 5)
- s1/product.py: adds legacy→STAC property name fallback (issue 2)

Usage (inside the Docker container):
python3 /patch/s1tiling_eodag4_patch.py
"""

import pathlib
import re

S1T_PKG = pathlib.Path("/opt/S1TilingEnv/lib/python3.10/site-packages/s1tiling/libs")


def patch_s1filemanager() -> None:
"""Fix search() call: add collection param, remove unsupported kwargs."""
fpath = S1T_PKG / "S1FileManager.py"
src = fpath.read_text()

# Replace productType with collection (EODAG 4.0.0 rename).
# Keeping productType alongside collection causes cop_dataspace to fail
# silently, making EODAG fall back to peps.
src = src.replace(
"productType=product_type,",
"collection=product_type,",
1, # only first occurrence
)

# Remove polarizationChannels (unsupported by cop_dataspace OData)
src = re.sub(r"\n\s*# If we have eodag.*\n", "\n", src)
src = re.sub(r"\n\s*polarizationChannels=dag_polarization_param,", "", src)

# Remove sensorMode="IW" (unsupported by cop_dataspace OData)
src = re.sub(r'\n\s*sensorMode="IW",', "", src)

# Remove relativeOrbitNumber (not supported by cop_dataspace OData —
# returns 0 results silently). S1Tiling has post-search filtering for
# relative orbits when len(relative_orbit_list) > 1, and when list
# has exactly 1 element, orbitNumber=None was passed anyway for most configs.
src = re.sub(
r"\n\s*relativeOrbitNumber=dag_orbit_list_param,.*",
"",
src,
)

# cop_dataspace OData requires UPPERCASE orbit direction values
# ("DESCENDING" not "descending"). S1Tiling's k_dir_assoc produces lowercase.
src = src.replace(
"{ 'ASC': 'ascending', 'DES': 'descending' }",
"{ 'ASC': 'ASCENDING', 'DES': 'DESCENDING' }",
)

fpath.write_text(src)
print(f" Patched {fpath.name}")


def patch_product_property() -> None:
"""Add STAC property name fallback to product_property()."""
fpath = S1T_PKG / "s1" / "product.py"
src = fpath.read_text()

old = (
"def product_property(prod: EOProduct, key: str, default=None):\n"
' """\n'
" Returns the required (EODAG) product property, "
"or default in the property isn't found.\n"
' """\n'
" res = prod.properties.get(key, default)\n"
" return res"
)

new = (
"def product_property(prod: EOProduct, key: str, default=None):\n"
' """\n'
" Returns the required (EODAG) product property, "
"or default in the property isn't found.\n"
" EODAG 4.0.0 uses STAC property names; "
"fall back to them for legacy keys.\n"
' """\n'
" _FALLBACK = {\n"
' "orbitDirection": "sat:orbit_state",\n'
' "platformSerialIdentifier": "platform",\n'
' "relativeOrbitNumber": "sat:relative_orbit",\n'
' "orbitNumber": "sat:absolute_orbit",\n'
' "polarizationChannels": "sar:polarizations",\n'
' "startTimeFromAscendingNode": "start_datetime",\n'
' "completionTimeFromAscendingNode": "end_datetime",\n'
" }\n"
" res = prod.properties.get(key, None)\n"
" if res is None and key in _FALLBACK:\n"
" res = prod.properties.get(_FALLBACK[key], default)\n"
' if key == "polarizationChannels" and isinstance(res, list):\n'
' res = "+".join(res)\n'
" return res if res is not None else default"
)

if old not in src:
print(f" WARNING: product_property() not found in {fpath.name}, skipping")
return

src = src.replace(old, new)
fpath.write_text(src)
print(f" Patched {fpath.name}")


if __name__ == "__main__":
print("Applying S1Tiling EODAG 4.0.0 compatibility patches...")
patch_s1filemanager()
patch_product_property()
print("Done.")
Loading
Loading