Skip to content

Commit

Permalink
Merge from main
Browse files Browse the repository at this point in the history
  • Loading branch information
sandorkertesz committed Dec 9, 2024
2 parents b4e3825 + cacf289 commit 66800d6
Show file tree
Hide file tree
Showing 13 changed files with 132 additions and 20 deletions.
16 changes: 16 additions & 0 deletions docs/gridspec.rst
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,19 @@ Example:
{"grid": "H512", "ordering": "ring"}
{"grid": "H512"}
ORCA grid
------------------------------------------

The ``grid`` format is::

eORCAXXX_subtype

The ``subtype`` must be "T", "U", "V" or "W".

Example:

.. code-block::
{"grid": "eORCA025_T"}
1 change: 1 addition & 0 deletions docs/inventory/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ The pages below contain all the **source and target gridspec** combinations for
healpix_ring
healpix_nested
regular_ll
orca
9 changes: 9 additions & 0 deletions docs/inventory/orca.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.. _orca_inventory:

orca
==============

.. note::
Currently, only the ``linear`` and ``nearest-neighbour`` interpolation methods are supported for ORCA grids.

.. module-output:: generate_inventory_rst orca "ORCA"
8 changes: 8 additions & 0 deletions docs/release_notes/version_0.3_updates.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
Version 0.3 Updates
/////////////////////////

Version 0.3.5
===============

Fixes
++++++++++++++++
- added support for ORCA input grids in :func:`interpolate`. See the :ref:`ORCA inventory <orca_inventory>` for the list of available ORCA source grids.


Version 0.3.4
===============

Expand Down
4 changes: 2 additions & 2 deletions src/earthkit/regrid/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,8 +262,8 @@ def load(self, path):
)

for name, entry in index["matrix"].items():
# it is possible that the inventory is already updated with new
# a gridspecs type, but a given earthkit-regrid version is not
# it is possible that the inventory is already updated with a new
# gridspecs type, but a given earthkit-regrid version is not
# yet supporting it. In this case loading the index should not crash.
try:
in_gs = GridSpec.from_dict(entry["input"])
Expand Down
18 changes: 17 additions & 1 deletion src/earthkit/regrid/gridspec.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

HEALPIX_PATTERN = re.compile(r"[Hh]\d+")
RGG_PATTERN = re.compile(r"[OoNn]\d+")

ORCA_PATTERN = re.compile(r"eORCA\d+_[TUVW]")

# NOTE: this is a temporary code until the full gridspec
# implementation is available via earthkit-geo.
Expand Down Expand Up @@ -424,8 +424,24 @@ def type_match(grid):
return False


class NamedGridSpec(GridSpec):
@staticmethod
def type_match(grid):
return isinstance(grid, str)


class OrcaGridSpec(GridSpec):
@staticmethod
def type_match(grid):
if isinstance(grid, str):
return ORCA_PATTERN.match(grid)
return False


GRIDSPEC_TYPES = {
"regular_ll": LLGridSpec,
"reduced_gg": ReducedGGGridSpec,
"healpix": HealpixGridSpec,
"orca": OrcaGridSpec,
# "_named": NamedGridSpec,
}
5 changes: 5 additions & 0 deletions src/earthkit/regrid/utils/matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ def healpix(entry):
return d


def orca(entry):
d = {"grid": entry["unstructuredGridType"] + "_" + entry["unstructuredGridSubtype"]}
return d


def make_sha(d):
m = hashlib.sha256()
m.update(json.dumps(d, sort_keys=True).encode("utf-8"))
Expand Down
27 changes: 27 additions & 0 deletions tests/data/local/db/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,33 @@
"version": 16,
"method": "grid-box-average"
}
},
"df20c8b83afc369370e615d3380482d384cedf033af66d3962b40292c83cbb9f": {
"input": {
"grid": "eORCA025_T",
"shape": [
1740494
],
"global": 1
},
"output": {
"grid": "O96",
"shape": [
40320
],
"area": [
89.2842,
0,
-89.2842,
359.1
],
"global": 1
},
"interpolation": {
"engine": "mir",
"version": 16,
"method": "linear"
}
}
}
}
3 changes: 3 additions & 0 deletions tests/test_gridspec.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
({"grid": "H128"}, {"grid": [1, 1]}),
({"grid": "H128", "ordering": "ring"}, {"grid": [1, 1]}),
({"grid": (5, 5)}, {"grid": (10, 10)}),
({"grid": "eORCA025_T"}, {"grid": "O96"}),
],
)
def test_gridspec_ok(gs_in, gs_out):
Expand Down Expand Up @@ -117,6 +118,8 @@ def test_gridspec_ok(gs_in, gs_out):
({"grid": "N32", "shape": 6599680}, {"grid": [10, 10]}, None),
({"grid": "N32", "area": [90, 0, -90, 359.999]}, {"grid": [10, 10]}, None),
({"grid": "N32", "area": [90, -0.1, -90, 360]}, {"grid": [10, 10]}, None),
({"grid": "ORCA025_T"}, {"grid": "O96"}, ValueError),
({"grid": "eORCA025_U"}, {"grid": "O96"}, None),
],
)
def test_gridspec_bad(gs_in, gs_out, err):
Expand Down
27 changes: 25 additions & 2 deletions tests/test_local.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ def test_local_index():
index_path = DB.index_file_path()
with open(index_path, "r") as f:
d = json.load(f)
assert len(d["matrix"]) == 16
assert len(d["matrix"]) == 17

assert len(DB) == 15
assert len(DB) == 16

# r = DB.find_entry({"grid": [5, 5]}, {"grid": [10, 10]}, method)
# assert r
Expand All @@ -63,6 +63,9 @@ def test_local_index():
r = DB.find_entry({"grid": "O64"}, {"grid": [10, 10]}, method)
assert r is None

r = DB.find_entry({"grid": "eORCA025_T"}, {"grid": "O96"}, method)
assert r


@pytest.mark.parametrize("method", METHODS)
def test_local_ll_to_ll(method):
Expand Down Expand Up @@ -136,6 +139,23 @@ def test_local_healpix_nested_to_ll(method):
assert np.allclose(v_res.flatten(), v_ref)


# TODO: implement this test
# @pytest.mark.parametrize("method", ["linear", "nearest-neighbour"])
# def test_local_orca_to_ll(method):
# v_in = np.load(file_in_testdir("in_eorca025_t.npz"))["arr_0"]
# v_ref = np.load(file_in_testdir(f"out_eorca025_t_10x10_{method}.npz"))["arr_0"]
# v_res = interpolate(
# v_in,
# {"grid": "eORCA025_T"},
# {"grid": [10, 10]},
# matrix_source=DB_PATH,
# method=method,
# )

# assert v_res.shape == (19, 36)
# assert np.allclose(v_res.flatten(), v_ref)


@pytest.mark.parametrize(
"gs_in, gs_out",
[
Expand Down Expand Up @@ -181,6 +201,7 @@ def test_local_healpix_nested_to_ll(method):
),
({"grid": "H4"}, {"grid": [10, 10]}),
({"grid": "H4", "ordering": "ring"}, {"grid": [10, 10]}),
({"grid": "eORCA025_T"}, {"grid": "O96"}),
],
)
def test_local_gridspec_ok(gs_in, gs_out):
Expand Down Expand Up @@ -217,6 +238,8 @@ def test_local_gridspec_ok(gs_in, gs_out):
({"grid": "N32", "area": [90, 0, -90, 359.999]}, {"grid": [10, 10]}, None),
({"grid": "N32", "area": [90, -0.1, -90, 360]}, {"grid": [10, 10]}, None),
({"grid": "H4", "ordering": "any"}, {"grid": [10, 10]}, ValueError),
({"grid": "ORCA025_T"}, {"grid": "O96"}, ValueError),
({"grid": "eORCA025_U"}, {"grid": "O96"}, None),
],
)
def test_local_gridspec_bad(gs_in, gs_out, err):
Expand Down
9 changes: 4 additions & 5 deletions tools/manage/build_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,15 +94,14 @@
]
}

in_grids = {
"N_rgg": [256],
}
in_grids = {"orca": ["eORCA025_T"]}

out_grids = {
"O_rgg": [400],
# "O_rgg": [96],
"N_rgg": [320],
}

build_root_dir = "_build_20241123"
build_root_dir = "_build_20241208"
build_dir = os.path.join(build_root_dir, "db")

# extra = [["0.25x0.25", "N320"], ["O1280", "N320"], ["5x5", "10x10"]]
Expand Down
19 changes: 10 additions & 9 deletions tools/manage/test_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,16 @@
This script generates and runs tests for newly built (partial) matrix inventory.
"""

build_root_dir = "_build_20241021"
build_root_dir = "_build_20241208"
db_dir = os.path.join(build_root_dir, "db")
index_file = os.path.join(build_root_dir, "index", "index.json")
test_dir = os.path.join(build_root_dir, "test")

# methods = ["linear", "nearest-neighbour"]
# build_matrix_dirs = ["matrices_linear", "matrices_nn"]
methods = ["linear", "nearest-neighbour"]
build_matrix_dirs = ["matrices_linear", "matrices_nn"]

methods = ["grid-box-average"]
build_matrix_dirs = ["matrices_grid-box-average"]
# methods = ["grid-box-average"]
# build_matrix_dirs = ["matrices_grid-box-average"]


def build_test_dir():
Expand All @@ -49,6 +49,7 @@ def build_test_dir():
count = 0
for m_dir in build_matrix_dirs:
m_dir = os.path.join(db_dir, m_dir)
print(f"Looking for matrices in {m_dir}")
for d in glob.glob(m_dir + "/*"):
if os.path.isdir(d):
print(f"Linking {d}")
Expand All @@ -71,15 +72,15 @@ def build_test_dir():
build_test_dir()

# TODO: make the tests automatic
gs_in = {"grid": "N256"}
gs_out = {"grid": "O400"}
gs_in = {"grid": "eORCA025_T"}
gs_out = {"grid": "O96"}
cnt = 0
for method in methods:
v = np.ones(348528)
v = np.ones(1740494)
r = earthkit.regrid.interpolate(
v, gs_in, gs_out, matrix_source=test_dir, method=method
)
assert len(r) == 654400
assert len(r) == 40320
cnt += 1

print(f"Tests passed: {cnt}")
6 changes: 5 additions & 1 deletion tools/utils/grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ def make_H_nested(g):
return f"H{g}_nested"


def make_other(g):
return f"{g}"


makers = {
k: globals()[f"make_{k}"] for k in ["ll", "O_rgg", "N_rgg", "H_ring", "H_nested"]
}
Expand All @@ -36,7 +40,7 @@ def make_H_nested(g):
def make_grid_id(grids):
r = []
for k, v in grids.items():
m = makers[k]
m = makers.get(k, make_other)
for x in v:
r.append(m(x))
return r

0 comments on commit 66800d6

Please sign in to comment.