Skip to content

Commit 8cc7df1

Browse files
refactor: use zcm.Multiscales typed model per reviewer feedback
- Replace dict[str, Any] multiscales field with zcm.Multiscales import - Remove inline MultiscalesTransform/ScaleLevel/Multiscales classes - Update test assertions for Pydantic model attribute access
1 parent e45d2ad commit 8cc7df1

2 files changed

Lines changed: 11 additions & 38 deletions

File tree

src/eopf_geozarr/data_api/s1_rtc.py

Lines changed: 9 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,16 @@
1515
├── ascending/
1616
│ ├── zarr.json # zarr_conventions, multiscales, proj:, spatial:
1717
│ ├── r10m/ # native resolution dataset
18-
│ │ ├── vv/ # (time, y, x) float32
19-
│ │ ├── vh/ # (time, y, x) float32
20-
│ │ ├── border_mask/ # (time, y, x) uint8
18+
│ │ ├── vv/ # (time, Y, X) float32
19+
│ │ ├── vh/ # (time, Y, X) float32
20+
│ │ ├── border_mask/ # (time, Y, X) uint8
2121
│ │ ├── time/ # (time,) int64 datetime
2222
│ │ ├── absolute_orbit/
2323
│ │ ├── relative_orbit/
2424
│ │ └── platform/
2525
│ ├── r20m/ … r720m/ # overview levels (vv, vh, border_mask only)
2626
│ └── conditions/
27-
│ └── gamma_area_{orbit}/ # (y, x) float32
27+
│ └── gamma_area_{orbit}/ # (Y, X) float32
2828
└── descending/
2929
└── (same structure)
3030
"""
@@ -40,6 +40,7 @@
4040
from zarr_cm import spatial as spatial_cm
4141

4242
from eopf_geozarr.data_api.geozarr.common import DatasetAttrs
43+
from eopf_geozarr.data_api.geozarr.multiscales.zcm import Multiscales
4344
from eopf_geozarr.pyz.v3 import ArraySpec, GroupSpec
4445

4546
# ============================================================================
@@ -61,33 +62,6 @@
6162
# ============================================================================
6263

6364

64-
class MultiscalesTransform(BaseModel):
65-
"""Scale/translation transform between resolution levels."""
66-
67-
scale: tuple[float, ...] | None = None
68-
translation: tuple[float, ...] | None = None
69-
70-
71-
class MultiscalesScaleLevel(BaseModel):
72-
"""A single resolution level in the multiscales layout."""
73-
74-
asset: str
75-
derived_from: str | None = None
76-
transform: MultiscalesTransform | None = None
77-
resampling_method: str | None = None
78-
79-
model_config = {"extra": "allow"}
80-
81-
82-
class Multiscales(BaseModel):
83-
"""Typed multiscales metadata (layout + optional resampling_method)."""
84-
85-
layout: tuple[MultiscalesScaleLevel, ...]
86-
resampling_method: str | None = None
87-
88-
model_config = {"extra": "allow"}
89-
90-
9165
class S1RtcOrbitGroupAttrs(BaseModel):
9266
"""Attributes for an orbit-direction group (ascending or descending).
9367
@@ -167,7 +141,7 @@ class S1RtcConditionsAttrs(BaseModel):
167141
class S1RtcNativeResolutionMembers(TypedDict, closed=True, total=False): # type: ignore[call-arg]
168142
"""Members for the native resolution dataset (r10m).
169143
170-
Data variables (time, y, x) plus 1-D coordinate variables (time,).
144+
Data variables (time, Y, X) plus 1-D coordinate variables (time,).
171145
All fields optional since not all arrays are present during incremental construction.
172146
"""
173147

@@ -301,9 +275,9 @@ class S1RtcRoot(GroupSpec[DatasetAttrs, S1RtcRootMembers]): # type: ignore[type
301275
├── ascending/
302276
│ ├── zarr.json # zarr_conventions, multiscales, proj:, spatial:
303277
│ ├── r10m/
304-
│ │ ├── vv/ # (time, y, x) float32
305-
│ │ ├── vh/ # (time, y, x) float32
306-
│ │ ├── border_mask/ # (time, y, x) uint8
278+
│ │ ├── vv/ # (time, Y, X) float32
279+
│ │ ├── vh/ # (time, Y, X) float32
280+
│ │ ├── border_mask/ # (time, Y, X) uint8
307281
│ │ ├── time/ # (time,) int64
308282
│ │ ├── absolute_orbit/
309283
│ │ ├── relative_orbit/

tests/test_data_api/test_s1_rtc.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,8 @@ def test_s1_rtc_orbit_attrs(s1_rtc_json_example: dict[str, object]) -> None:
7676
assert attrs.proj_code.startswith("EPSG:")
7777
assert attrs.spatial_dimensions == ["y", "x"]
7878
assert len(attrs.spatial_bbox) == 4
79-
layout = attrs.multiscales["layout"]
80-
assert len(layout) == 6
81-
assert layout[0]["asset"] == "r10m"
79+
assert len(attrs.multiscales.layout) == 6
80+
assert attrs.multiscales.layout[0].asset == "r10m"
8281

8382

8483
def test_s1_rtc_rejects_no_orbit(s1_rtc_json_example: dict[str, object]) -> None:

0 commit comments

Comments
 (0)