Skip to content

Commit d4d7a07

Browse files
Unstructured Scheme - Cube Creation 3D (#47)
* handle extra dims in _create_cube * add test * lint fix * address review comment
1 parent 7c01ece commit d4d7a07

File tree

2 files changed

+80
-12
lines changed

2 files changed

+80
-12
lines changed

esmf_regrid/experimental/unstructured_scheme.py

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,16 +73,11 @@ def _create_cube(data, src_cube, mesh_dim, grid_x, grid_y):
7373
# data: a masked array containing the result of the regridding operation
7474
# src_cube: the source cube which data is regrid from
7575
# mesh_dim: the dimension on src_cube which the mesh belongs to
76-
# mesh: the Mesh (or MeshCoord) object belonging to src_cube
7776
# grid_x: the coordinate on the target cube representing the x axis
7877
# grid_y: the coordinate on the target cube representing the y axis
7978

8079
new_cube = iris.cube.Cube(data)
8180

82-
# TODO: The following code assumes a 1D source cube and mesh_dim = 0.
83-
# This is therefore simple code which should be updated when we start
84-
# supporting the regridding of extra dimensions.
85-
8681
# TODO: The following code is rigid with respect to which dimensions
8782
# the x coord and y coord are assigned to. We should decide if it is
8883
# appropriate to copy the dimension ordering from the target cube
@@ -92,8 +87,37 @@ def _create_cube(data, src_cube, mesh_dim, grid_x, grid_y):
9287

9388
new_cube.metadata = copy.deepcopy(src_cube.metadata)
9489

95-
for coord in src_cube.coords(dimensions=()):
96-
new_cube.add_aux_coord(coord.copy())
90+
# TODO: Handle derived coordinates. The following code is taken from
91+
# iris, the parts dealing with derived coordinates have been
92+
# commented out for the time being.
93+
# coord_mapping = {}
94+
95+
def copy_coords(src_coords, add_method):
96+
for coord in src_coords:
97+
dims = src_cube.coord_dims(coord)
98+
if hasattr(coord, "mesh") or mesh_dim in dims:
99+
continue
100+
# Since the mesh will be replaced by a 2D grid, dims which are
101+
# beyond the mesh_dim are increased by one.
102+
dims = [dim if dim < mesh_dim else dim + 1 for dim in dims]
103+
result_coord = coord.copy()
104+
# Add result_coord to the owner of add_method.
105+
add_method(result_coord, dims)
106+
# coord_mapping[id(coord)] = result_coord
107+
108+
copy_coords(src_cube.dim_coords, new_cube.add_dim_coord)
109+
copy_coords(src_cube.aux_coords, new_cube.add_aux_coord)
110+
111+
# for factory in src_cube.aux_factories:
112+
# # TODO: Regrid dependant coordinates which span mesh_dim.
113+
# try:
114+
# result.add_aux_factory(factory.updated(coord_mapping))
115+
# except KeyError:
116+
# msg = (
117+
# "Cannot update aux_factory {!r} because of dropped"
118+
# " coordinates.".format(factory.name())
119+
# )
120+
# warnings.warn(msg)
97121

98122
return new_cube
99123

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
"""Unit tests for miscellaneous helper functions in `esmf_regrid.experimental.unstructured_scheme`."""
22

33
import iris
4+
from iris.coords import AuxCoord, DimCoord
5+
from iris.cube import Cube
46
import numpy as np
57

68
from esmf_regrid.experimental.unstructured_scheme import _create_cube
@@ -11,17 +13,56 @@ def test_create_cube_2D():
1113
data = np.ones([2, 3])
1214

1315
# Create a source cube with metadata and scalar coords
14-
src_cube = iris.cube.Cube(np.zeros(5))
16+
src_cube = Cube(np.zeros(5))
1517
src_cube.units = "K"
1618
src_cube.attributes = {"a": 1}
1719
src_cube.standard_name = "air_temperature"
18-
scalar_height = iris.coords.AuxCoord([5], units="m", standard_name="height")
19-
scalar_time = iris.coords.DimCoord([10], units="s", standard_name="time")
20+
scalar_height = AuxCoord([5], units="m", standard_name="height")
21+
scalar_time = DimCoord([10], units="s", standard_name="time")
2022
src_cube.add_aux_coord(scalar_height)
2123
src_cube.add_aux_coord(scalar_time)
2224

2325
mesh_dim = 0
2426

27+
grid_x = DimCoord(np.arange(3), standard_name="longitude")
28+
grid_y = DimCoord(np.arange(2), standard_name="latitude")
29+
30+
cube = _create_cube(data, src_cube, mesh_dim, grid_x, grid_y)
31+
src_metadata = src_cube.metadata
32+
33+
expected_cube = Cube(data)
34+
expected_cube.metadata = src_metadata
35+
expected_cube.add_dim_coord(grid_x, 1)
36+
expected_cube.add_dim_coord(grid_y, 0)
37+
expected_cube.add_aux_coord(scalar_height)
38+
expected_cube.add_aux_coord(scalar_time)
39+
assert expected_cube == cube
40+
41+
42+
def test_create_cube_4D():
43+
"""Test creation of 2D output grid."""
44+
data = np.ones([4, 2, 3, 5])
45+
46+
# Create a source cube with metadata and scalar coords
47+
src_cube = Cube(np.zeros([4, 5, 5]))
48+
src_cube.units = "K"
49+
src_cube.attributes = {"a": 1}
50+
src_cube.standard_name = "air_temperature"
51+
scalar_height = AuxCoord([5], units="m", standard_name="height")
52+
scalar_time = DimCoord([10], units="s", standard_name="time")
53+
src_cube.add_aux_coord(scalar_height)
54+
src_cube.add_aux_coord(scalar_time)
55+
first_coord = DimCoord(np.arange(4), standard_name="air_pressure")
56+
src_cube.add_dim_coord(first_coord, 0)
57+
last_coord = AuxCoord(np.arange(5), long_name="last_coord")
58+
src_cube.add_aux_coord(last_coord, 2)
59+
multidim_coord = AuxCoord(np.ones([4, 5]), long_name="2d_coord")
60+
src_cube.add_aux_coord(multidim_coord, (0, 2))
61+
ignored_coord = AuxCoord(np.arange(5), long_name="ignore")
62+
src_cube.add_aux_coord(ignored_coord, 1)
63+
64+
mesh_dim = 1
65+
2566
grid_x = iris.coords.DimCoord(np.arange(3), standard_name="longitude")
2667
grid_y = iris.coords.DimCoord(np.arange(2), standard_name="latitude")
2768

@@ -30,8 +71,11 @@ def test_create_cube_2D():
3071

3172
expected_cube = iris.cube.Cube(data)
3273
expected_cube.metadata = src_metadata
33-
expected_cube.add_dim_coord(grid_x, 1)
34-
expected_cube.add_dim_coord(grid_y, 0)
74+
expected_cube.add_dim_coord(grid_x, 2)
75+
expected_cube.add_dim_coord(grid_y, 1)
76+
expected_cube.add_dim_coord(first_coord, 0)
77+
expected_cube.add_aux_coord(last_coord, 3)
78+
expected_cube.add_aux_coord(multidim_coord, (0, 3))
3579
expected_cube.add_aux_coord(scalar_height)
3680
expected_cube.add_aux_coord(scalar_time)
3781
assert expected_cube == cube

0 commit comments

Comments
 (0)