Skip to content

Sentinel-1 GRD γ0T RTC GeoZarr V3 — Implementation Tracker #139

@emmanuelmathot

Description

@emmanuelmathot

Overview

Implementation of Sentinel-1 GRD γ0T RTC time-series GeoZarr V3 stores in the data-model codebase. S1Tiling (CNES/OTB) produces γ0T RTC GeoTIFFs on the S2 MGRS grid; this work converts those GeoTIFFs into GeoZarr V3 stores following the EOPF hierarchy.

Design document: .github/prompts/s1-grd-rtc-implementation-plan-v2.md (on s1-tiling branch)
Working branch: s1-tiling

Implementation Phases

Devlog

2026-03-23 — Phase 1 complete

Delivered: Pydantic-zarr V3 schema for S1 GRD RTC stores, aligned with the S2 model pattern.

Files:

  • src/eopf_geozarr/data_api/s1_rtc.py — 316 lines, model hierarchy (Root → OrbitGroup → Resolution → Arrays)
  • tests/_test_data/s1_rtc_examples/s1-grd-rtc-31TCH.json — realistic fixture (MGRS 31TCH, 3 timesteps, sharding codecs)
  • tests/test_data_api/test_s1_rtc.py — 11 tests (round-trip, structure, 5 negative cases)

Key decisions:

  • Uses pyz.v3 (Zarr V3) instead of pyz.v2 (Zarr V2) used by S2
  • extra="allow" on attrs models for forward compatibility
  • Conditions group uses dict[str, ArraySpec] (dynamic keys per orbit)
  • Both ascending/descending optional with at-least-one validator

PR #138 opened as draft for review by pydantic-zarr schema maintainers.

Open questions for reviewers:

  1. Should attrs models inherit from a shared base with S2?
  2. Is extra="allow" the right choice, or lock down all fields?
  3. Should multiscales use the typed zarr_cm model instead of dict[str, Any]?
  4. Should conditions enforce a regex pattern beyond gamma_area_ prefix?

2026-03-22 — Phase 0 complete

Delivered: End-to-end prototype from S1Tiling Docker → GeoTIFF → GeoZarr V3.

  • S1Tiling 1.4.0 ran on 3 acquisitions over MGRS 31TCH (orbits 008, 037, 110)
  • Discovered EODAG 4.0.0 breaking changes (5 issues, monkey-patch created)
  • Real-data conversion validated: 10980×10980 sharded arrays, border_mask, gamma_area conditions
  • Inner chunk divisibility constraint: 10980 % 512 ≠ 0, solution: best_chunk_size() → 366
  • Store size: ~1.8 GB for 3 timesteps across all overview levels
  • xarray readback verified for all levels

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions