nakas's picture
Auto resolution now as fine as native (no oversampling); fix cfgrib fallback time handling; update UI label
23f929c
import os
import gradio as gr
import xarray as xr
from scripts.icon_regrid_to_netcdf import process as regrid_process
OUT_DIR = os.environ.get("ICON_OUT_DIR", "/data")
def run_single(param: str, fh: int):
try:
out_path = regrid_process(param=param, fh=fh, res='auto', out_dir=OUT_DIR)
ds = xr.open_dataset(out_path)
summary = {
"file": out_path,
"dims": {k: int(v) for k, v in ds.dims.items()},
"vars": list(ds.data_vars.keys()),
"coords": list(ds.coords.keys()),
"time": str(ds.time.values[0]) if "time" in ds.coords else "",
}
ds.close()
return out_path, f"Success: {summary}"
except Exception as e:
return "", f"Failed: {e}"
def read_value_from_nc(nc_path: str, map_point, param: str):
if not nc_path:
return "No dataset yet. Click Download & Convert first."
if not map_point:
return "Click on the map to select a location."
try:
# gr.Map returns [lat, lon]
if isinstance(map_point, (list, tuple)) and len(map_point) >= 2:
lat_q, lon_q = float(map_point[0]), float(map_point[1])
else:
# Fallback: parse "lat,lon"
parts = [float(x.strip()) for x in str(map_point).split(',')]
lat_q, lon_q = parts[0], parts[1]
ds = xr.open_dataset(nc_path)
var = param.lower() if param.lower() in ds.data_vars else list(ds.data_vars)[0]
lats = ds['lat'].values
lons = ds['lon'].values
# normalize lon to [-180, 180)
lon_q = ((lon_q + 180.0) % 360.0) - 180.0
import numpy as np
i = int(np.argmin(np.abs(lats - lat_q)))
j = int(np.argmin(np.abs(lons - lon_q)))
val = ds[var].isel(time=0, lat=i, lon=j).values.item()
ds.close()
return f"{var} at ({lat_q:.3f}, {lon_q:.3f}) ≈ {val:.3f}"
except Exception as e:
return f"Read failed: {e}"
with gr.Blocks(title="DWD ICON Regrid → NetCDF") as demo:
gr.Markdown("# DWD ICON Regridding Demo")
gr.Markdown("Download a DWD ICON GRIB2 field, regrid to a coarse lat/lon grid, and save as NetCDF. Then click on the map to sample the value.")
with gr.Row():
param = gr.Dropdown(
label="Parameter",
choices=["t_2m", "tot_prec", "u_10m", "v_10m", "clct", "vmax_10m"],
value="t_2m",
)
fh = gr.Slider(label="Forecast hour", minimum=0, maximum=120, step=3, value=0)
nc_state = gr.State("")
run_btn = gr.Button("Download & Convert (fine)")
out = gr.Textbox(label="Result", lines=8)
gr.Markdown("## Pick a location and read the value")
with gr.Row():
try:
map_input = gr.Map(label="Select a location", value=[50.0, 10.0])
except Exception:
map_input = gr.Textbox(label="Lat,Lon (comma)", value="50.0,10.0")
read_btn = gr.Button("Read value from NetCDF")
read_out = gr.Textbox(label="Sampled value", lines=2)
def _run(param, fh):
path, info = run_single(param, int(fh))
return path, info
run_btn.click(_run, inputs=[param, fh], outputs=[nc_state, out])
def _read(nc_path, map_val, param):
return read_value_from_nc(nc_path, map_val, param)
read_btn.click(_read, inputs=[nc_state, map_input, param], outputs=[read_out])
if __name__ == "__main__":
port = int(os.environ.get("PORT", "7860"))
demo.launch(server_name="0.0.0.0", server_port=port)