Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
13 changes: 11 additions & 2 deletions src/eopf_geozarr/conversion/s1_ingest.py
Original file line number Diff line number Diff line change
Expand Up @@ -743,12 +743,21 @@ def ingest_s1tiling_acquisition(


def consolidate_s1_store(store_path: str | Path, orbit_direction: str) -> None:
"""Consolidate metadata at orbit direction and root levels.
"""Consolidate metadata for every orbit-direction group and the root.

Must be called AFTER all ingestions complete — consolidated metadata
caches array shapes and will become stale if called mid-ingestion.

Consolidates *every* orbit group present, not just ``orbit_direction``: the
pipeline ingests acquisitions one orbit at a time after stripping all
consolidated metadata (so ``time`` can resize), so consolidating only the
passed orbit would leave the other orbit's group unconsolidated on disk
(readers opening that orbit standalone then fall back to a listing).
``orbit_direction`` is retained for logging / caller compatibility.
"""
zarr.consolidate_metadata(str(store_path), path=orbit_direction, zarr_format=3)
root = zarr.open_group(str(store_path), mode="r", zarr_format=3)
for orbit_name, _ in root.groups():
zarr.consolidate_metadata(str(store_path), path=orbit_name, zarr_format=3)
zarr.consolidate_metadata(str(store_path), zarr_format=3)
log.info(
"Metadata consolidated",
Expand Down
20 changes: 20 additions & 0 deletions tests/test_s1_rtc_ingest.py
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,26 @@ def test_consolidate_after_all_ingestions(
r10m = root["ascending"]["r10m"]
assert r10m["vv"].shape[0] == 2

def test_consolidate_all_orbits_present(
self, s1_geotiff_dir: Path, s1_store_path: Path
) -> None:
"""``consolidate_s1_store`` must leave EVERY orbit group consolidated on disk, not just the
one passed. The pipeline ingests acquisitions one orbit at a time after stripping all
consolidated metadata (so ``time`` can resize), so consolidating only the passed orbit left
staging cubes asc✓/desc✗. Each orbit group is checked **standalone**: a consolidated root
synthesises the child's view, so ``root[orbit].metadata.consolidated_metadata`` is a
false-green (non-None even when ``<orbit>/zarr.json`` lacks it).
"""
vv1, vh1, mask1 = self._get_acq_paths(s1_geotiff_dir, "20230115t061234")
vv2, vh2, mask2 = self._get_acq_paths(s1_geotiff_dir, "20230127t061235")
ingest_s1tiling_acquisition(vv1, vh1, mask1, s1_store_path, "ascending")
ingest_s1tiling_acquisition(vv2, vh2, mask2, s1_store_path, "descending")
consolidate_s1_store(s1_store_path, "descending") # only one orbit passed

for orbit in ("ascending", "descending"):
grp = zarr.open_group(str(s1_store_path / orbit), mode="r", zarr_format=3)
assert grp.metadata.consolidated_metadata is not None, f"{orbit} orbit not consolidated"

def _get_acq_paths(self, geotiff_dir: Path, stamp: str) -> tuple[Path, Path, Path]:
vv = geotiff_dir / f"s1a_32TQM_vv_ASC_037_{stamp}_GammaNaughtRTC.tif"
vh = geotiff_dir / f"s1a_32TQM_vh_ASC_037_{stamp}_GammaNaughtRTC.tif"
Expand Down