diff --git a/Changelog.rst b/Changelog.rst index 20102713b6..13bddcb81b 100644 --- a/Changelog.rst +++ b/Changelog.rst @@ -1,3 +1,13 @@ +version NEXTVERSION +------------------- + +**2025-??-??** + +* New keyword parameter to `cf.DimensionCoordinate.create_bounds`: + ``inplace`` (https://github.com/NCAS-CMS/cf-python/issues/855) + +---- + version 3.17.0 -------------- diff --git a/cf/dimensioncoordinate.py b/cf/dimensioncoordinate.py index a70e0ffeae..644709bbda 100644 --- a/cf/dimensioncoordinate.py +++ b/cf/dimensioncoordinate.py @@ -533,18 +533,25 @@ def create_regular(cls, args, units=None, standard_name=None, bounds=True): return coordinate def create_bounds( - self, bound=None, cellsize=None, flt=0.5, max=None, min=None + self, + bound=None, + cellsize=None, + flt=0.5, + max=None, + min=None, + inplace=False, ): """Create cell bounds. - Creates new cell bounds, irrespective of whether the cells - already have cell bounds. The new bounds are not set on the - dimension coordinate construct, but if that is desired they - may always be added with the `set_bounds` method, for - instance: + When the operation is *not* in-place (the default), new bounds + will be created and returned, regardless of whether or not + bounds already exist, but the bounds are not set on the + dimension coordinate construct. - >>> b = d.create_bounds() - >>> d.set_bounds(b) + If the operation is in-place (i.e. the *inplace* parameter is + True) then the newly created bounds will be set on the + dimension coordinate construct and `None` is returned, but + only if there are no existing bounds. By default, Voronoi cells are created by defining cell bounds that are half way between adjacent coordinate values. For @@ -640,10 +647,13 @@ def create_bounds( ``-90``: ``min=-90``, or ``min=cf.Data(-90, 'degrees_north')``. + {{inplace: `bool`, optional}} + :Returns: - `Bounds` - The new coordinate cell bounds. + `Bounds` or `None` + The new coordinate cell bounds, or `None` if the + operation was in-place. **Examples** @@ -756,6 +766,13 @@ def create_bounds( cftime.DatetimeGregorian(1985, 12, 1, 0, 0, 0, 0)]] """ + if inplace and self.has_bounds(): + raise ValueError( + "Can't create dimension coordinate bounds in-place when " + "bounds already exist. Existing bounds may be removed " + "with the 'del_bounds' method." + ) + array = self.array size = array.size @@ -907,6 +924,10 @@ def create_bounds( # Create coordinate bounds object bounds = Bounds(data=Data(bounds, units=self.Units), copy=False) + if inplace: + self.set_bounds(bounds) + return + return bounds def del_cell_characteristics(self, default=ValueError()): diff --git a/cf/test/test_DimensionCoordinate.py b/cf/test/test_DimensionCoordinate.py index 67dc932bff..3fbcb22a92 100644 --- a/cf/test/test_DimensionCoordinate.py +++ b/cf/test/test_DimensionCoordinate.py @@ -544,6 +544,15 @@ def test_DimensionCoordinate_create_bounds(self): ).all() ) + # In-place + self.assertFalse(d.has_bounds()) + self.assertIsNone(d.create_bounds(inplace=True)) + self.assertTrue(d.has_bounds()) + + # Fail when inplace=True and bounds already exist + with self.assertRaises(ValueError): + d.create_bounds(inplace=True) + # Cellsize units must be equivalent to the coordinate units, # or if the cell has no units then they are assumed to be # the same as the coordinates: