Skip to content

Commit 1aa8052

Browse files
authored
Merge pull request #153 from SciTools-incubator/unstructured_scheme
Merge unstructured scheme feature branch
2 parents 792ebd1 + e0b42d2 commit 1aa8052

35 files changed

+3259
-512
lines changed

.cirrus.yml

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ env:
2020
SKIP_TEST_TASK: ""
2121
SKIP_BENCHMARK_TASK: ""
2222
# Maximum cache period (in weeks) before forcing a new cache upload.
23-
CACHE_PERIOD: "2"
23+
CACHE_PERIOD: "0"
2424
# Increment the build number to force new conda cache upload.
2525
CONDA_CACHE_BUILD: "0"
2626
# Increment the build number to force new nox cache upload.
@@ -31,6 +31,27 @@ env:
3131
PIP_CACHE_PACKAGES: "pip setuptools wheel nox pyyaml"
3232
# Conda packages to be installed.
3333
CONDA_CACHE_PACKAGES: "nox pip pyyaml"
34+
# Use specific custom iris source feature branch.
35+
IRIS_SOURCE: "github:main"
36+
# Git commit hash for iris test data.
37+
IRIS_TEST_DATA_VERSION: "2.2"
38+
# Base directory for the iris-test-data.
39+
IRIS_TEST_DATA_DIR: ${HOME}/iris-test-data
40+
OVERRIDE_TEST_DATA_REPOSITORY: ${IRIS_TEST_DATA_DIR}/test_data
41+
42+
43+
#
44+
# YAML alias for the iris-test-data cache.
45+
#
46+
iris_test_data_template: &IRIS_TEST_DATA_TEMPLATE
47+
data_cache:
48+
folder: ${IRIS_TEST_DATA_DIR}
49+
fingerprint_script:
50+
- echo "iris-test-data v${IRIS_TEST_DATA_VERSION}"
51+
populate_script:
52+
- wget --quiet https://github.com/SciTools/iris-test-data/archive/v${IRIS_TEST_DATA_VERSION}.zip -O iris-test-data.zip
53+
- unzip -q iris-test-data.zip
54+
- mv iris-test-data-${IRIS_TEST_DATA_VERSION} ${IRIS_TEST_DATA_DIR}
3455

3556

3657
#
@@ -88,10 +109,6 @@ test_task:
88109
only_if: ${SKIP_TEST_TASK} == ""
89110
auto_cancellation: true
90111
matrix:
91-
env:
92-
PY_VER: "3.6"
93-
env:
94-
PY_VER: "3.7"
95112
env:
96113
PY_VER: "3.8"
97114
COVERAGE: "true"
@@ -104,6 +121,7 @@ test_task:
104121
- echo "${CIRRUS_TASK_NAME}"
105122
- echo "${NOX_CACHE_BUILD}"
106123
- if [ -n "${IRIS_SOURCE}" ]; then echo "${IRIS_SOURCE}"; fi
124+
<< : *IRIS_TEST_DATA_TEMPLATE
107125
test_script:
108126
- export CONDA_OVERRIDE_LINUX="$(uname -r | cut -d'+' -f1)"
109127
- nox --session tests -- --verbose

README.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,59 @@
77
[![License](https://img.shields.io/github/license/SciTools-incubator/iris-esmf-regrid)](https://github.com/SciTools-incubator/iris-esmf-regrid/blob/main/LICENSE)
88
[![Contributors](https://img.shields.io/github/contributors/SciTools-incubator/iris-esmf-regrid)](https://github.com/SciTools-incubator/iris-esmf-regrid/graphs/contributors)
99
![Mark stale issues and pull requests](https://github.com/SciTools-incubator/iris-esmf-regrid/workflows/Mark%20stale%20issues%20and%20pull%20requests/badge.svg)
10+
11+
---
12+
13+
## Overview
14+
15+
This project aims to provide a bridge between [Iris](https://github.com/SciTools/iris)
16+
and [ESMF](https://github.com/esmf-org/esmf). This takes the form of regridder classes
17+
which take Iris cubes as their arguments and use ESMF to perform regridding
18+
calculations. These classes are designed to perform well on cubes which have multiple
19+
non-horizontal dimensions and lazy ([Dask](https://github.com/dask/dask)) data.
20+
Both rectilinear and curvilinear grids as well as UGRID meshes have been supported.
21+
22+
## Regridding Example
23+
24+
There are a range of regridder classes (e.g `MeshToGridESMFRegridder` and
25+
`GridToMeshESMFRegridder`). For an example of the regridding process, the
26+
`MeshToGridESMFRegridder` class works as follows:
27+
28+
```python
29+
import iris
30+
from iris.experimental.ugrid import PARSE_UGRID_ON_LOAD
31+
from esmf_regrid.experimental.unstructured_scheme import MeshToGridESMFRegridder
32+
33+
# An example such a file can be found at:
34+
# https://github.com/SciTools/iris-test-data/blob/master/test_data/NetCDF/unstructured_grid/data_C4.nc
35+
with PARSE_UGRID_ON_LOAD.context():
36+
source_mesh_cube = iris.load_cube("mesh_cube.nc")
37+
38+
# An example of such a file can be found at:
39+
# https://github.com/SciTools/iris-test-data/blob/master/test_data/NetCDF/global/xyt/SMALL_hires_wind_u_for_ipcc4.nc
40+
target_grid_cube = iris.load_cube("grid_cube.nc")
41+
42+
# Initialise the regridder with a source mesh and target grid.
43+
regridder = MeshToGridESMFRegridder(source_mesh_cube, target_grid_cube)
44+
45+
# use the initialised regridder to regrid the data from the source cube
46+
# onto a cube with the same grid as `target_grid_cube`.
47+
result = regridder(source_mesh_cube)
48+
```
49+
50+
Note that this pattern allows the reuse of an initialised regridder, saving
51+
significant amounts of time when regridding. To make use of this efficiency across
52+
sessions, we support the saving of certain regridders. We can do this as follows:
53+
54+
```python
55+
from esmf_regrid.experimental.io import load_regridder, save_regridder
56+
57+
# Save the regridder.
58+
save_regridder(regridder, "saved_regridder.nc")
59+
60+
# Load saved regridder.
61+
loaded_regridder = load_regridder("saved_regridder.nc")
62+
63+
# Use loaded regridder.
64+
result = loaded_regridder(source_mesh_cube)
65+
```

benchmarks/benchmarks/__init__.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,44 @@
11
"""Benchmark tests for iris-esmf-regrid"""
2+
3+
4+
def disable_repeat_between_setup(benchmark_object):
5+
"""
6+
Decorator for benchmarks where object persistence would be inappropriate.
7+
8+
E.g:
9+
* Data is realised during testing.
10+
11+
Can be applied to benchmark classes/methods/functions.
12+
13+
https://asv.readthedocs.io/en/stable/benchmarks.html#timing-benchmarks
14+
15+
"""
16+
# Prevent repeat runs between setup() runs - object(s) will persist after 1st.
17+
benchmark_object.number = 1
18+
# Compensate for reduced certainty by increasing number of repeats.
19+
# (setup() is run between each repeat).
20+
# Minimum 5 repeats, run up to 30 repeats / 20 secs whichever comes first.
21+
benchmark_object.repeat = (5, 30, 20.0)
22+
# ASV uses warmup to estimate benchmark time before planning the real run.
23+
# Prevent this, since object(s) will persist after first warmup run,
24+
# which would give ASV misleading info (warmups ignore ``number``).
25+
benchmark_object.warmup_time = 0.0
26+
27+
return benchmark_object
28+
29+
30+
def skip_benchmark(benchmark_object):
31+
"""
32+
Decorator for benchmarks skipping benchmarks.
33+
"""
34+
35+
def setup_cache(self):
36+
pass
37+
38+
def setup(*args):
39+
raise NotImplementedError
40+
41+
benchmark_object.setup_cache = setup_cache
42+
benchmark_object.setup = setup
43+
44+
return benchmark_object

0 commit comments

Comments
 (0)