Skip to content

Commit 386edc7

Browse files
committed
Reinstating support for (partial) collapse of lazy coordinate points / bounds. Added some tests to catch this in the future.
1 parent 9bce3ab commit 386edc7

File tree

3 files changed

+55
-5
lines changed

3 files changed

+55
-5
lines changed

lib/iris/coords.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,6 +1172,7 @@ def collapsed(self, dims_to_collapse=None):
11721172
11731173
Replaces the points & bounds with a simple bounded region.
11741174
"""
1175+
import dask.array as da
11751176
# Ensure dims_to_collapse is a tuple to be able to pass
11761177
# through to numpy
11771178
if isinstance(dims_to_collapse, (int, np.integer)):
@@ -1210,13 +1211,17 @@ def serialize(x):
12101211
'Metadata may not be fully descriptive for {!r}.'
12111212
warnings.warn(msg.format(self.name()))
12121213

1213-
# Create bounds for the new collapsed coordinate.
1214-
item = np.concatenate(self.core_bounds()) if self.has_bounds() \
1214+
# Determine the right array method for stacking
1215+
stack_method = da.stack if self.has_bounds() \
1216+
and is_lazy_data(self.core_bounds()) \
1217+
else np.stack
1218+
1219+
item = stack_method(self.core_bounds()) if self.has_bounds() \
12151220
else self.core_points()
12161221

12171222
# Calculate the bounds and points along the right dims
1218-
bounds = np.stack([item.min(axis=dims_to_collapse),
1219-
item.max(axis=dims_to_collapse)]).T
1223+
bounds = stack_method([item.min(axis=dims_to_collapse),
1224+
item.max(axis=dims_to_collapse)]).T
12201225
points = item.mean(axis=dims_to_collapse, dtype=self.dtype)
12211226

12221227
# Create the new collapsed coordinate.

lib/iris/tests/test_analysis.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,7 @@ def test_max(self):
357357
[118, 123],
358358
[124, 129]]))
359359

360+
360361
class TestAggregator_mdtol_keyword(tests.IrisTest):
361362
def setUp(self):
362363
data = ma.array([[1, 2], [4, 5]], dtype=np.float32,

lib/iris/tests/unit/coords/test_Coord.py

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
from iris.coords import DimCoord, AuxCoord, Coord
3232
from iris.tests import mock
3333
from iris.exceptions import UnitConversionError
34+
from iris.tests.unit.coords import CoordTestMixin
3435

3536

3637
Pair = collections.namedtuple('Pair', 'points bounds')
@@ -232,7 +233,7 @@ def test_time_as_object(self):
232233
mock.sentinel.upper))])
233234

234235

235-
class Test_collapsed(tests.IrisTest):
236+
class Test_collapsed(tests.IrisTest, CoordTestMixin):
236237

237238
def test_serialize(self):
238239
# Collapse a string AuxCoord, causing it to be serialised.
@@ -300,6 +301,49 @@ def test_numeric_nd(self):
300301
[4, 10],
301302
[5, 11]]))
302303

304+
def test_lazy_nd_points(self):
305+
import dask.array as da
306+
self.setupTestArrays((3, 4))
307+
coord = AuxCoord(self.pts_lazy)
308+
309+
collapsed_coord = coord.collapsed()
310+
311+
self.assertTrue(collapsed_coord.has_lazy_points())
312+
self.assertFalse(collapsed_coord.has_lazy_bounds())
313+
314+
self.assertArrayEqual(collapsed_coord.points, da.array([55]))
315+
self.assertArrayEqual(collapsed_coord.bounds, da.array([[0, 110]]))
316+
317+
def test_lazy_nd_bounds(self):
318+
import dask.array as da
319+
320+
self.setupTestArrays((3, 4))
321+
coord = AuxCoord(self.pts_real, bounds=self.bds_lazy)
322+
323+
collapsed_coord = coord.collapsed()
324+
325+
# Note that the new points get recalculated from the lazy bounds
326+
# and so end up as lazy
327+
self.assertTrue(collapsed_coord.has_lazy_points())
328+
self.assertTrue(collapsed_coord.has_lazy_bounds())
329+
330+
self.assertArrayEqual(collapsed_coord.points, np.array([55]))
331+
self.assertArrayEqual(collapsed_coord.bounds, da.array([[-2, 112]]))
332+
333+
def test_lazy_nd_points_and_bounds(self):
334+
import dask.array as da
335+
336+
self.setupTestArrays((3, 4))
337+
coord = AuxCoord(self.pts_lazy, bounds=self.bds_lazy)
338+
339+
collapsed_coord = coord.collapsed()
340+
341+
self.assertTrue(collapsed_coord.has_lazy_points())
342+
self.assertTrue(collapsed_coord.has_lazy_bounds())
343+
344+
self.assertArrayEqual(collapsed_coord.points, da.array([55]))
345+
self.assertArrayEqual(collapsed_coord.bounds, da.array([[-2, 112]]))
346+
303347

304348
class Test_is_compatible(tests.IrisTest):
305349
def setUp(self):

0 commit comments

Comments
 (0)