diff --git a/Changelog.rst b/Changelog.rst index f0d5f95692..a274abce9b 100644 --- a/Changelog.rst +++ b/Changelog.rst @@ -16,6 +16,9 @@ version 3.17.0 * Fix bug that caused `Data._axes` to be incorrect after a call to `cf.Field.collapse` (https://github.com/NCAS-CMS/cf-python/issues/857) +* Fix bug that caused wrong directions from + `cf.DimensionCoordinate.direction` + (https://github.com/NCAS-CMS/cf-python/issues/859) * Changed dependency: ``Python>=3.9.0`` * Changed dependency: ``numpy>=2.0.0`` * Changed dependency: ``cfdm>=1.12.0.0, <1.12.1.0`` diff --git a/cf/dimensioncoordinate.py b/cf/dimensioncoordinate.py index 3b16f053a8..a70e0ffeae 100644 --- a/cf/dimensioncoordinate.py +++ b/cf/dimensioncoordinate.py @@ -131,9 +131,9 @@ def _infer_direction(self): """Return True if a coordinate is increasing, otherwise return False. - A dimension coordinate construct is considered to be increasing if - its data array values are increasing in index space, or if it has - no data nor bounds. + A dimension coordinate construct is considered to be + increasing if its data array values are not strictly + decreasing in index space, or if it has no data nor bounds. If the direction can not be inferred from the data not bounds then the coordinate's units are used. @@ -168,12 +168,12 @@ def _infer_direction(self): c = data._get_cached_elements() if c: try: - return bool(c.get(0) < c.get(1)) + return bool(c.get(0) <= c.get(1)) except TypeError: pass data = data[:2].compute() - return bool(data.item(0) < data.item(1)) + return bool(data.item(0) <= data.item(1)) # Still here? data = self.get_bounds_data(None, _fill_value=False) @@ -182,12 +182,12 @@ def _infer_direction(self): c = data._get_cached_elements() if c: try: - return bool(c.get(0) < c.get(1)) + return bool(c.get(0) <= c.get(1)) except TypeError: pass b = data[0].compute() - return bool(b.item(0) < b.item(1)) + return bool(b.item(0) <= b.item(1)) # Still here? Then infer the direction from the units. return not self.Units.ispressure diff --git a/cf/test/test_DimensionCoordinate.py b/cf/test/test_DimensionCoordinate.py index 35694b6aeb..19cf90fa3d 100644 --- a/cf/test/test_DimensionCoordinate.py +++ b/cf/test/test_DimensionCoordinate.py @@ -809,6 +809,30 @@ def test_DimensionCoordinate_anchor(self): self.assertEqual(e[0].array, d[0].array - 360) + def test_DimensionCoordinate_direction(self): + """Test DimensionCoordinate.direction""" + d = self.dim.copy() + + # Test the use case of + # https://github.com/NCAS-CMS/cf-python/issues/859 + # + # Create a coordinate with all equal values + d.data[...] = d[0].array + for i, x in enumerate(d.array): + d.bounds.data[i, :] = x + + d._custom["direction"] = None # Force a re-calculation of direction + self.assertTrue(d.direction()) + d._custom["direction"] = None + self.assertTrue(d[0].direction()) + + d.del_bounds() + d._custom["direction"] = None + self.assertTrue(d.direction()) + d._custom["direction"] = None + self.assertTrue(d[0].direction()) + + if __name__ == "__main__": print("Run date:", datetime.datetime.now()) cf.environment()