Source code for pyiem.era5land
"""Helpers for IEM's ERA5-Land processing.
This is heavily weighted to what IEMRE is doing.
"""
from typing import Optional
import numpy as np
from affine import Affine
from pyiem import iemre
DX = 0.1
DY = 0.1
def _roundup(val: float) -> float:
"""Round up to the nearest 0.1"""
return np.ceil(val / 0.1) * 0.1
def _rounddown(val: float) -> float:
"""Round down to the nearest 0.1"""
return np.floor(val / 0.1) * 0.1
DOMAINS = {"conus": {}, "china": {}, "europe": {}, "sa": {}}
for _dom, meta in DOMAINS.items():
meta["WEST"] = _roundup(iemre.DOMAINS[_dom]["west_edge"])
meta["EAST"] = _rounddown(iemre.DOMAINS[_dom]["east_edge"])
meta["SOUTH"] = _roundup(iemre.DOMAINS[_dom]["south_edge"])
meta["NORTH"] = _rounddown(iemre.DOMAINS[_dom]["north_edge"])
meta["XAXIS"] = np.arange(meta["WEST"], meta["EAST"] + 0.01, DX)
meta["YAXIS"] = np.arange(meta["SOUTH"], meta["NORTH"] + 0.01, DY)
meta["WEST_EDGE"] = meta["XAXIS"][0] - DX / 2.0
meta["EAST_EDGE"] = meta["XAXIS"][-1] + DX / 2.0
meta["SOUTH_EDGE"] = meta["YAXIS"][0] - DY / 2.0
meta["NORTH_EDGE"] = meta["YAXIS"][-1] + DY / 2.0
# netcdf storage is bottom up
meta["AFFINE_NC"] = Affine(
DX,
0.0,
meta["WEST_EDGE"],
0.0,
DY,
meta["SOUTH_EDGE"],
)
meta["NX"] = len(meta["XAXIS"])
meta["NY"] = len(meta["YAXIS"])
[docs]
def find_ij(
lon: float, lat: float, domain: str = "conus"
) -> tuple[Optional[int], Optional[int]]:
"""Find the grid cell for the provided lon/lat"""
_meta = DOMAINS[domain]
if (
lon < _meta["WEST_EDGE"]
or lon > _meta["EAST_EDGE"]
or lat < _meta["SOUTH_EDGE"]
or lat > _meta["NORTH_EDGE"]
):
return None, None
i = int((lon - _meta["WEST_EDGE"]) / DX)
j = int((lat - _meta["SOUTH_EDGE"]) / DY)
return i, j