Skip to content

Commit a5d84f1

Browse files
authored
chore: O1280 regridding example (#67)
1 parent 525370a commit a5d84f1

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#!/usr/bin/env -S uv run --script
2+
#
3+
# /// script
4+
# requires-python = ">=3.12"
5+
# dependencies = [
6+
# "omfiles>=1.0.0",
7+
# "fsspec>=2025.7.0",
8+
# "s3fs",
9+
# "matplotlib",
10+
# "cartopy",
11+
# "earthkit-regrid",
12+
# ]
13+
# ///
14+
15+
import cartopy.crs as ccrs
16+
import cartopy.feature as cfeature
17+
import fsspec
18+
import matplotlib.pyplot as plt
19+
import numpy as np
20+
from earthkit.regrid import interpolate
21+
from omfiles import OmFileReader
22+
23+
ifs_spatial_file = f"openmeteo/data_spatial/ecmwf_ifs/2025/10/01/0000Z/2025-10-01T0000.om"
24+
backend = fsspec.open(
25+
f"blockcache::s3://{ifs_spatial_file}",
26+
mode="rb",
27+
s3={"anon": True, "default_block_size": 65536},
28+
blockcache={"cache_storage": "cache", "same_names": True},
29+
)
30+
with OmFileReader(backend) as reader:
31+
print("reader.is_group", reader.is_group)
32+
33+
child = reader.get_child_by_name("temperature_2m")
34+
print("child.name", child.name)
35+
36+
# Get the full data array
37+
print("child.shape", child.shape)
38+
print("child.chunks", child.chunks)
39+
data = child[:]
40+
print(f"Data shape: {data.shape}")
41+
print(f"Data range: {np.nanmin(data)} to {np.nanmax(data)}")
42+
43+
# We are using earthkit-regrid for regridding: https://earthkit-regrid.readthedocs.io/en/stable/interpolate.html#interpolate
44+
# with linear interpolation. Nearest neighbor interpolation can be obtained with`method="nearest-neighbour"`
45+
regridded = interpolate(data, in_grid={"grid": "O1280"}, out_grid={"grid": [0.1, 0.1]}, method="linear")
46+
print(f"Regridded shape: {regridded.shape}")
47+
48+
# Create plot
49+
fig = plt.figure(figsize=(12, 8))
50+
ax = plt.axes(projection=ccrs.PlateCarree()) # use PlateCarree projection
51+
52+
# Add map features
53+
ax.add_feature(cfeature.COASTLINE)
54+
ax.add_feature(cfeature.BORDERS)
55+
ax.add_feature(cfeature.OCEAN, alpha=0.3)
56+
ax.add_feature(cfeature.LAND, alpha=0.3)
57+
58+
# Create coordinate arrays
59+
# These bounds need to match the output grid of the regridding!
60+
height, width = regridded.shape
61+
lon = np.linspace(0, 360, width, endpoint=False)
62+
lat = np.linspace(90, -90, height)
63+
lon_grid, lat_grid = np.meshgrid(lon, lat)
64+
65+
# Plot the data
66+
im = ax.contourf(lon_grid, lat_grid, regridded, levels=20, transform=ccrs.PlateCarree(), cmap="viridis")
67+
plt.colorbar(im, ax=ax, shrink=0.6, label=child.name)
68+
ax.gridlines(draw_labels=True, alpha=0.3)
69+
plt.title(f"2D Map: {child.name}")
70+
ax.set_global()
71+
plt.tight_layout()
72+
73+
output_filename = f"map_ifs_{child.name.replace('/', '_')}.png"
74+
plt.savefig(output_filename, dpi=300, bbox_inches="tight")
75+
print(f"Plot saved as: {output_filename}")
76+
plt.close()

0 commit comments

Comments
 (0)