Skip to content

Commit 7f6efc9

Browse files
authored
Merge pull request #117 from EOPF-Explorer/fix-scale-translate
fix: sentinel-2 multiscales translation, scale values, and spatial bbox consistency
2 parents d41360f + fe1de96 commit 7f6efc9

5 files changed

Lines changed: 119 additions & 58 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,3 +214,4 @@ uv.lock
214214

215215
# VCS versioning
216216
src/eopf_geozarr/_version.py
217+
analysis/.edh_token

src/eopf_geozarr/s2_optimization/s2_multiscale.py

Lines changed: 70 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -378,13 +378,21 @@ def add_multiscales_metadata_to_parent(
378378
log.info("No CRS found, skipping multiscales metadata", base_path=group.path)
379379
return None
380380

381-
native_bounds = None
382-
try:
383-
native_bounds = first_dataset.rio.bounds()
384-
except (AttributeError, TypeError):
385-
x_coords = first_dataset.x.values
386-
y_coords = first_dataset.y.values
387-
native_bounds = (x_coords.min(), y_coords.min(), x_coords.max(), y_coords.max())
381+
# Calculate bounds directly from coordinates for consistency with the data arrays
382+
if "x" not in first_dataset.coords or "y" not in first_dataset.coords:
383+
log.error(
384+
"Missing x/y coordinates in dataset, cannot determine bounds", base_path=group.path
385+
)
386+
return None
387+
388+
x_coords = first_dataset.x.values
389+
y_coords = first_dataset.y.values
390+
native_bounds = (
391+
float(x_coords.min()),
392+
float(y_coords.min()),
393+
float(x_coords.max()),
394+
float(y_coords.max()),
395+
)
388396

389397
# Create overview_levels structure following the multiscales v1.0 specification
390398
overview_levels: list[OverviewLevelJSON] = []
@@ -424,8 +432,10 @@ def add_multiscales_metadata_to_parent(
424432
y_coords = dataset.coords["y"].values
425433

426434
if len(x_coords) > 1 and len(y_coords) > 1:
435+
# Calculate pixel size from actual coordinate spacing
427436
pixel_size_x = float(np.abs(x_coords[1] - x_coords[0]))
428437
pixel_size_y = float(np.abs(y_coords[1] - y_coords[0]))
438+
429439
x_min = float(x_coords.min())
430440
y_max = float(y_coords.max())
431441
transform = (pixel_size_x, 0.0, x_min, 0.0, -pixel_size_y, y_max)
@@ -456,10 +466,60 @@ def add_multiscales_metadata_to_parent(
456466
zoom_for_height = max(0, int(np.ceil(np.log2(height / tile_width))))
457467
zoom = max(zoom_for_width, zoom_for_height)
458468

459-
# Calculate relative scale and translation vs first resolution
469+
# Calculate relative scale and translation vs parent resolution
460470
finest_res_meters = res_order[all_resolutions[0]]
461-
relative_scale = res_meters / finest_res_meters
462-
relative_translation = (res_meters - finest_res_meters) / 2
471+
472+
# Fix for issue #114: Translation values should be 0
473+
relative_translation = 0.0
474+
475+
# Calculate proper relative scale based on actual parent-child dimension ratios
476+
if res_name == all_resolutions[0]: # Base resolution
477+
relative_scale = 1.0
478+
else:
479+
# Define derivation chain to find parent resolution
480+
derivation_chain = {
481+
"r10m": None,
482+
"r20m": "r10m",
483+
"r60m": "r10m",
484+
"r120m": "r60m",
485+
"r360m": "r120m",
486+
"r720m": "r360m",
487+
}
488+
489+
parent_res = derivation_chain.get(res_name)
490+
if parent_res and parent_res in res_groups:
491+
# Get actual dimensions of parent and child
492+
parent_dataset = res_groups[parent_res]
493+
parent_var = next(iter(parent_dataset.data_vars.values()))
494+
parent_height, parent_width = parent_var.shape[-2:]
495+
496+
# Current (child) dimensions
497+
child_height, child_width = height, width
498+
499+
# Calculate actual scale ratio based on dimensions
500+
# Use the larger of the two ratios to be conservative
501+
scale_x = parent_width / child_width if child_width > 0 else 1.0
502+
scale_y = parent_height / child_height if child_height > 0 else 1.0
503+
relative_scale = max(scale_x, scale_y)
504+
505+
log.info(
506+
"Calculated dynamic scale ratio",
507+
level=res_name,
508+
parent=parent_res,
509+
parent_dims=(parent_height, parent_width),
510+
child_dims=(child_height, child_width),
511+
scale_x=scale_x,
512+
scale_y=scale_y,
513+
relative_scale=relative_scale,
514+
)
515+
else:
516+
# Fallback to absolute resolution ratio
517+
relative_scale = res_meters / finest_res_meters
518+
log.warning(
519+
"Using fallback scale calculation",
520+
level=res_name,
521+
relative_scale=relative_scale,
522+
)
463523

464524
# Get chunks in the correct format
465525
var_chunks = dataset.data_vars[first_var.name].chunks

tests/_test_data/optimized_geozarr_examples/S2A_MSIL2A_20251008T100041_N0511_R122_T32TQM_20251008T122613.json

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4716,8 +4716,8 @@
47164716
2.0
47174717
],
47184718
"translation": [
4719-
5.0,
4720-
5.0
4719+
0.0,
4720+
0.0
47214721
]
47224722
}
47234723
},
@@ -4734,8 +4734,8 @@
47344734
6.0
47354735
],
47364736
"translation": [
4737-
25.0,
4738-
25.0
4737+
0.0,
4738+
0.0
47394739
]
47404740
}
47414741
},
@@ -4748,12 +4748,12 @@
47484748
],
47494749
"transform": {
47504750
"scale": [
4751-
12.0,
4752-
12.0
4751+
2.0,
4752+
2.0
47534753
],
47544754
"translation": [
4755-
55.0,
4756-
55.0
4755+
0.0,
4756+
0.0
47574757
]
47584758
}
47594759
},
@@ -4766,12 +4766,12 @@
47664766
],
47674767
"transform": {
47684768
"scale": [
4769-
36.0,
4770-
36.0
4769+
3.0,
4770+
3.0
47714771
],
47724772
"translation": [
4773-
175.0,
4774-
175.0
4773+
0.0,
4774+
0.0
47754775
]
47764776
}
47774777
},
@@ -4784,12 +4784,12 @@
47844784
],
47854785
"transform": {
47864786
"scale": [
4787-
72.0,
4788-
72.0
4787+
2.0065789473684212,
4788+
2.0065789473684212
47894789
],
47904790
"translation": [
4791-
355.0,
4792-
355.0
4791+
0.0,
4792+
0.0
47934793
]
47944794
}
47954795
}

tests/_test_data/optimized_geozarr_examples/S2B_MSIL1C_20250113T103309_N0511_R108_T32TLQ_20250113T122458.json

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4316,8 +4316,8 @@
43164316
2.0
43174317
],
43184318
"translation": [
4319-
5.0,
4320-
5.0
4319+
0.0,
4320+
0.0
43214321
]
43224322
}
43234323
},
@@ -4334,8 +4334,8 @@
43344334
6.0
43354335
],
43364336
"translation": [
4337-
25.0,
4338-
25.0
4337+
0.0,
4338+
0.0
43394339
]
43404340
}
43414341
},
@@ -4348,12 +4348,12 @@
43484348
],
43494349
"transform": {
43504350
"scale": [
4351-
12.0,
4352-
12.0
4351+
2.0,
4352+
2.0
43534353
],
43544354
"translation": [
4355-
55.0,
4356-
55.0
4355+
0.0,
4356+
0.0
43574357
]
43584358
}
43594359
},
@@ -4366,12 +4366,12 @@
43664366
],
43674367
"transform": {
43684368
"scale": [
4369-
36.0,
4370-
36.0
4369+
3.0,
4370+
3.0
43714371
],
43724372
"translation": [
4373-
175.0,
4374-
175.0
4373+
0.0,
4374+
0.0
43754375
]
43764376
}
43774377
},
@@ -4384,12 +4384,12 @@
43844384
],
43854385
"transform": {
43864386
"scale": [
4387-
72.0,
4388-
72.0
4387+
2.0065789473684212,
4388+
2.0065789473684212
43894389
],
43904390
"translation": [
4391-
355.0,
4392-
355.0
4391+
0.0,
4392+
0.0
43934393
]
43944394
}
43954395
}

tests/_test_data/optimized_geozarr_examples/S2C_MSIL2A_20250811T112131_N0511_R037_T29TPF_20250811T152216.json

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4716,8 +4716,8 @@
47164716
2.0
47174717
],
47184718
"translation": [
4719-
5.0,
4720-
5.0
4719+
0.0,
4720+
0.0
47214721
]
47224722
}
47234723
},
@@ -4734,8 +4734,8 @@
47344734
6.0
47354735
],
47364736
"translation": [
4737-
25.0,
4738-
25.0
4737+
0.0,
4738+
0.0
47394739
]
47404740
}
47414741
},
@@ -4748,12 +4748,12 @@
47484748
],
47494749
"transform": {
47504750
"scale": [
4751-
12.0,
4752-
12.0
4751+
2.0,
4752+
2.0
47534753
],
47544754
"translation": [
4755-
55.0,
4756-
55.0
4755+
0.0,
4756+
0.0
47574757
]
47584758
}
47594759
},
@@ -4766,12 +4766,12 @@
47664766
],
47674767
"transform": {
47684768
"scale": [
4769-
36.0,
4770-
36.0
4769+
3.0,
4770+
3.0
47714771
],
47724772
"translation": [
4773-
175.0,
4774-
175.0
4773+
0.0,
4774+
0.0
47754775
]
47764776
}
47774777
},
@@ -4784,12 +4784,12 @@
47844784
],
47854785
"transform": {
47864786
"scale": [
4787-
72.0,
4788-
72.0
4787+
2.0065789473684212,
4788+
2.0065789473684212
47894789
],
47904790
"translation": [
4791-
355.0,
4792-
355.0
4791+
0.0,
4792+
0.0
47934793
]
47944794
}
47954795
}

0 commit comments

Comments
 (0)