Skip to content

Commit

Permalink
Merge pull request #153 from SciTools-incubator/unstructured_scheme
Browse files Browse the repository at this point in the history
Merge unstructured scheme feature branch
  • Loading branch information
bjlittle committed Feb 23, 2022
2 parents 792ebd1 + e0b42d2 commit 1aa8052
Show file tree
Hide file tree
Showing 35 changed files with 3,259 additions and 512 deletions.
28 changes: 23 additions & 5 deletions .cirrus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ env:
SKIP_TEST_TASK: ""
SKIP_BENCHMARK_TASK: ""
# Maximum cache period (in weeks) before forcing a new cache upload.
CACHE_PERIOD: "2"
CACHE_PERIOD: "0"
# Increment the build number to force new conda cache upload.
CONDA_CACHE_BUILD: "0"
# Increment the build number to force new nox cache upload.
Expand All @@ -31,6 +31,27 @@ env:
PIP_CACHE_PACKAGES: "pip setuptools wheel nox pyyaml"
# Conda packages to be installed.
CONDA_CACHE_PACKAGES: "nox pip pyyaml"
# Use specific custom iris source feature branch.
IRIS_SOURCE: "github:main"
# Git commit hash for iris test data.
IRIS_TEST_DATA_VERSION: "2.2"
# Base directory for the iris-test-data.
IRIS_TEST_DATA_DIR: ${HOME}/iris-test-data
OVERRIDE_TEST_DATA_REPOSITORY: ${IRIS_TEST_DATA_DIR}/test_data


#
# YAML alias for the iris-test-data cache.
#
iris_test_data_template: &IRIS_TEST_DATA_TEMPLATE
data_cache:
folder: ${IRIS_TEST_DATA_DIR}
fingerprint_script:
- echo "iris-test-data v${IRIS_TEST_DATA_VERSION}"
populate_script:
- wget --quiet https://github.com/SciTools/iris-test-data/archive/v${IRIS_TEST_DATA_VERSION}.zip -O iris-test-data.zip
- unzip -q iris-test-data.zip
- mv iris-test-data-${IRIS_TEST_DATA_VERSION} ${IRIS_TEST_DATA_DIR}


#
Expand Down Expand Up @@ -88,10 +109,6 @@ test_task:
only_if: ${SKIP_TEST_TASK} == ""
auto_cancellation: true
matrix:
env:
PY_VER: "3.6"
env:
PY_VER: "3.7"
env:
PY_VER: "3.8"
COVERAGE: "true"
Expand All @@ -104,6 +121,7 @@ test_task:
- echo "${CIRRUS_TASK_NAME}"
- echo "${NOX_CACHE_BUILD}"
- if [ -n "${IRIS_SOURCE}" ]; then echo "${IRIS_SOURCE}"; fi
<< : *IRIS_TEST_DATA_TEMPLATE
test_script:
- export CONDA_OVERRIDE_LINUX="$(uname -r | cut -d'+' -f1)"
- nox --session tests -- --verbose
Expand Down
56 changes: 56 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,59 @@
[![License](https://img.shields.io/github/license/SciTools-incubator/iris-esmf-regrid)](https://github.com/SciTools-incubator/iris-esmf-regrid/blob/main/LICENSE)
[![Contributors](https://img.shields.io/github/contributors/SciTools-incubator/iris-esmf-regrid)](https://github.com/SciTools-incubator/iris-esmf-regrid/graphs/contributors)
![Mark stale issues and pull requests](https://github.com/SciTools-incubator/iris-esmf-regrid/workflows/Mark%20stale%20issues%20and%20pull%20requests/badge.svg)

---

## Overview

This project aims to provide a bridge between [Iris](https://github.com/SciTools/iris)
and [ESMF](https://github.com/esmf-org/esmf). This takes the form of regridder classes
which take Iris cubes as their arguments and use ESMF to perform regridding
calculations. These classes are designed to perform well on cubes which have multiple
non-horizontal dimensions and lazy ([Dask](https://github.com/dask/dask)) data.
Both rectilinear and curvilinear grids as well as UGRID meshes have been supported.

## Regridding Example

There are a range of regridder classes (e.g `MeshToGridESMFRegridder` and
`GridToMeshESMFRegridder`). For an example of the regridding process, the
`MeshToGridESMFRegridder` class works as follows:

```python
import iris
from iris.experimental.ugrid import PARSE_UGRID_ON_LOAD
from esmf_regrid.experimental.unstructured_scheme import MeshToGridESMFRegridder

# An example such a file can be found at:
# https://github.com/SciTools/iris-test-data/blob/master/test_data/NetCDF/unstructured_grid/data_C4.nc
with PARSE_UGRID_ON_LOAD.context():
source_mesh_cube = iris.load_cube("mesh_cube.nc")

# An example of such a file can be found at:
# https://github.com/SciTools/iris-test-data/blob/master/test_data/NetCDF/global/xyt/SMALL_hires_wind_u_for_ipcc4.nc
target_grid_cube = iris.load_cube("grid_cube.nc")

# Initialise the regridder with a source mesh and target grid.
regridder = MeshToGridESMFRegridder(source_mesh_cube, target_grid_cube)

# use the initialised regridder to regrid the data from the source cube
# onto a cube with the same grid as `target_grid_cube`.
result = regridder(source_mesh_cube)
```

Note that this pattern allows the reuse of an initialised regridder, saving
significant amounts of time when regridding. To make use of this efficiency across
sessions, we support the saving of certain regridders. We can do this as follows:

```python
from esmf_regrid.experimental.io import load_regridder, save_regridder

# Save the regridder.
save_regridder(regridder, "saved_regridder.nc")

# Load saved regridder.
loaded_regridder = load_regridder("saved_regridder.nc")

# Use loaded regridder.
result = loaded_regridder(source_mesh_cube)
```
43 changes: 43 additions & 0 deletions benchmarks/benchmarks/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,44 @@
"""Benchmark tests for iris-esmf-regrid"""


def disable_repeat_between_setup(benchmark_object):
"""
Decorator for benchmarks where object persistence would be inappropriate.
E.g:
* Data is realised during testing.
Can be applied to benchmark classes/methods/functions.
https://asv.readthedocs.io/en/stable/benchmarks.html#timing-benchmarks
"""
# Prevent repeat runs between setup() runs - object(s) will persist after 1st.
benchmark_object.number = 1
# Compensate for reduced certainty by increasing number of repeats.
# (setup() is run between each repeat).
# Minimum 5 repeats, run up to 30 repeats / 20 secs whichever comes first.
benchmark_object.repeat = (5, 30, 20.0)
# ASV uses warmup to estimate benchmark time before planning the real run.
# Prevent this, since object(s) will persist after first warmup run,
# which would give ASV misleading info (warmups ignore ``number``).
benchmark_object.warmup_time = 0.0

return benchmark_object


def skip_benchmark(benchmark_object):
"""
Decorator for benchmarks skipping benchmarks.
"""

def setup_cache(self):
pass

def setup(*args):
raise NotImplementedError

benchmark_object.setup_cache = setup_cache
benchmark_object.setup = setup

return benchmark_object

0 comments on commit 1aa8052

Please sign in to comment.