From 17e663ffc156ee929bb44a363946f8ee28ce46f5 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Mon, 10 Oct 2022 09:53:11 +0100 Subject: [PATCH 1/4] dask: Field.halo --- cf/data/data.py | 11 +++- cf/field.py | 98 +++++++++++++++++++------------- cf/mixin/propertiesdata.py | 46 +++++++++------ cf/mixin/propertiesdatabounds.py | 46 ++++++++++----- 4 files changed, 126 insertions(+), 75 deletions(-) diff --git a/cf/data/data.py b/cf/data/data.py index 944c5840bf..9a1870691c 100644 --- a/cf/data/data.py +++ b/cf/data/data.py @@ -7282,7 +7282,6 @@ def insert_dimension(self, position=0, inplace=False): return d @daskified(_DASKIFIED_VERBOSE) - @_deprecated_kwarg_check("size") @_inplace_enabled(default=False) @_manage_log_level_via_verbosity def halo( @@ -7470,6 +7469,16 @@ def halo( """ from dask.array.core import concatenate + if size is not None: + _DEPRECATION_ERROR_KWARGS( + self, + "halo", + {"size": None}, + message="Use the 'depth' parameter instead.", + version="TODODASKVER", + removed_at="5.0.0", + ) # pragma: no cover + d = _inplace_enabled_define_and_cleanup(self) ndim = d.ndim diff --git a/cf/field.py b/cf/field.py index 1d4fe57f5e..2f60595e3d 100644 --- a/cf/field.py +++ b/cf/field.py @@ -13421,12 +13421,13 @@ def grad_xy(self, x_wrap=None, one_sided_at_boundary=False, radius=None): @_manage_log_level_via_verbosity def halo( self, - size, + depth, axes=None, tripolar=None, fold_index=-1, inplace=False, verbose=None, + size=None, ): """Expand the field construct by adding a halo to its data. @@ -13454,42 +13455,43 @@ def halo( :Parameters: - size: `int` or `dict` + depth: `int` or `dict` Specify the size of the halo for each axis. - If *size* is a non-negative `int` then this is the halo - size that is applied to all of the axes defined by the - *axes* parameter. + If *depth* is a non-negative `int` then this is the + halo size that is applied to all of the axes defined + by the *axes* parameter. Alternatively, halo sizes may be assigned to axes individually by providing a `dict` for which a key - specifies an axis (by passing the axis description to a - call of the field construct's `domain_axis` method. For - example, for a value of ``'X'``, the domain axis construct - returned by ``f.domain_axis('X')``) with a corresponding - value of the halo size for that axis. Axes not specified - by the dictionary are not expanded, and the *axes* - parameter must not also be set. + specifies an axis (by passing the axis description to + a call of the field construct's `domain_axis` + method. For example, for a value of ``'X'``, the + domain axis construct returned by + ``f.domain_axis('X')``) with a corresponding value of + the halo size for that axis. Axes not specified by the + dictionary are not expanded, and the *axes* parameter + must not also be set. *Parameter example:* Specify a halo size of 1 for all otherwise selected - axes: ``size=1`` + axes: ``1`` *Parameter example:* - Specify a halo size of zero ``size=0``. This results in + Specify a halo size of zero: ``0``. This results in no change to the data shape. *Parameter example:* - For data with three dimensions, specify a halo size of 3 - for the first dimension and 1 for the second dimension: - ``size={0: 3, 1: 1}``. This is equivalent to ``size={0: - 3, 1: 1, 2: 0}`` + For data with three dimensions, specify a halo size + of 3 for the first dimension and 1 for the second + dimension: ``{0: 3, 1: 1}``. This is equivalent to + ``{0: 3, 1: 1, 2: 0}`` *Parameter example:* Specify a halo size of 2 for the "longitude" and - "latitude" axes: ``size=2, axes=['latutude', - 'longitude']``, or equivalently ``size={'latutude': 2, - 'longitude': 2}``. + "latitude" axes: ``depth=2, axes=['latutude', + 'longitude']``, or equivalently ``depth={'latutude': + 2, 'longitude': 2}``. axes: (sequence of) `str` or `int`, optional Select the domain axes to be expanded, defined by the @@ -13523,27 +13525,28 @@ def halo( tripolar: `dict`, optional A dictionary defining the "X" and "Y" axes of a global - tripolar domain. This is necessary because in the global - tripolar case the "X" and "Y" axes need special treatment, - as described above. It must have keys ``'X'`` and ``'Y'``, - whose values identify the corresponding domain axis - construct by passing the value to a call of the field - construct's `domain_axis` method. For example, for a value - of ``'ncdim%i'``, the domain axis construct returned by + tripolar domain. This is necessary because in the + global tripolar case the "X" and "Y" axes need special + treatment, as described above. It must have keys + ``'X'`` and ``'Y'``, whose values identify the + corresponding domain axis construct by passing the + value to a call of the field construct's `domain_axis` + method. For example, for a value of ``'ncdim%i'``, the + domain axis construct returned by ``f.domain_axis('ncdim%i')``. - The "X" and "Y" axes must be a subset of those identified - by the *size* or *axes* parameter. + The "X" and "Y" axes must be a subset of those + identified by the *depth* or *axes* parameter. See the *fold_index* parameter. *Parameter example:* Define the "X" and Y" axes by their netCDF dimension - names: ``tripolar={'X': 'ncdim%i', 'Y': 'ncdim%j'}`` + names: ``{'X': 'ncdim%i', 'Y': 'ncdim%j'}`` *Parameter example:* Define the "X" and Y" axes by positions 2 and 1 - respectively of the data: ``tripolar={'X': 2, 'Y': 1}`` + respectively of the data: ``{'X': 2, 'Y': 1}`` fold_index: `int`, optional Identify which index of the "Y" axis corresponds to the @@ -13556,6 +13559,9 @@ def halo( {{verbose: `int` or `str` or `None`, optional}} + size: deprecated at version TODODASKVER + Use the *depth* parameter instead. + :Returns: `Field` or `None` @@ -13646,21 +13652,31 @@ def halo( """ f = _inplace_enabled_define_and_cleanup(self) - # Set the halo size for each axis. + if size is not None: + _DEPRECATION_ERROR_KWARGS( + self, + "halo", + {"size": None}, + message="Use the 'depth' parameter instead.", + version="TODODASKVER", + removed_at="5.0.0", + ) # pragma: no cover + + # Set the halo depth for each axis. data_axes = f.get_data_axes(default=()) - if isinstance(size, dict): + if isinstance(depth, dict): if axes is not None: raise ValueError( - "Can't set existing axes when size is a dict." + "Can't set existing axes when depth is a dict." ) axis_halo = { - self.domain_axis(k, key=True): v for k, v in size.items() + self.domain_axis(k, key=True): v for k, v in depth.items() } if not set(data_axes).issuperset(axis_halo): raise ValueError( - f"Can't apply halo: Bad axis specification: {size!r}" + f"Can't apply halo: Bad axis specification: {depth!r}" ) else: if axes is None: @@ -13669,7 +13685,7 @@ def halo( if isinstance(axes, (str, int)): axes = (axes,) - axis_halo = {self.domain_axis(k, key=True): size for k in axes} + axis_halo = {self.domain_axis(k, key=True): depth for k in axes} if tripolar: # Find the X and Y axes of a tripolar grid @@ -13702,10 +13718,10 @@ def halo( tripolar_axes = {X: "X", Y: "Y"} # Add halos to the field construct's data - size = {data_axes.index(axis): h for axis, h, in axis_halo.items()} + depth = {data_axes.index(axis): h for axis, h, in axis_halo.items()} f.data.halo( - size=size, + depth, tripolar=tripolar, fold_index=fold_index, inplace=True, @@ -13738,7 +13754,7 @@ def halo( } c.halo( - size=construct_size, + construct_size, tripolar=construct_tripolar, fold_index=fold_index, inplace=True, diff --git a/cf/mixin/propertiesdata.py b/cf/mixin/propertiesdata.py index 4776b7f926..a1c70cdcd0 100644 --- a/cf/mixin/propertiesdata.py +++ b/cf/mixin/propertiesdata.py @@ -16,6 +16,7 @@ ) from ..functions import ( _DEPRECATION_ERROR_ATTRIBUTE, + _DEPRECATION_ERROR_KWARGS, _DEPRECATION_ERROR_METHOD, default_netCDF_fillvals, ) @@ -4857,12 +4858,13 @@ def get_filenames(self): @_manage_log_level_via_verbosity def halo( self, - size, + depth, axes=None, tripolar=None, fold_index=-1, inplace=False, verbose=None, + size=None, ): """Expand the data by adding a halo. @@ -4887,10 +4889,10 @@ def halo( :Parameters: - size: `int` or `dict` + depth: `int` or `dict` Specify the size of the halo for each axis. - If *size* is a non-negative `int` then this is the + If *depth* is a non-negative `int` then this is the halo size that is applied to all of the axes defined by the *axes* parameter. @@ -4904,22 +4906,22 @@ def halo( *Parameter example:* Specify a halo size of 1 for all otherwise selected - axes: ``size=1`` + axes: ``1`` *Parameter example:* - Specify a halo size of zero ``size=0``. This results - in no change to the data shape. + Specify a halo size of zero: ``0``. This results in + no change to the data shape. *Parameter example:* For data with three dimensions, specify a halo size of 3 for the first dimension and 1 for the second - dimension: ``size={0: 3, 1: 1}``. This is equivalent - to ``size={0: 3, 1: 1, 2: 0}`` + dimension: ``{0: 3, 1: 1}``. This is equivalent to + ``{0: 3, 1: 1, 2: 0}`` *Parameter example:* Specify a halo size of 2 for the first and last - dimensions `size=2, axes=[0, -1]`` or equivalently - ``size={0: 2, -1: 2}``. + dimensions `depth=2, axes=[0, -1]`` or equivalently + ``depth={0: 2, -1: 2}``. axes: (sequence of) `int` Select the domain axes to be expanded, defined by @@ -4937,14 +4939,13 @@ def halo( positions in the data. The "X" and "Y" axes must be a subset of those - identified by the *size* or *axes* parameter. + identified by the *depth* or *axes* parameter. See the *fold_index* parameter. *Parameter example:* Define the "X" and Y" axes by positions 2 and 1 - respectively of the data: ``tripolar={'X': 2, 'Y': - 1}`` + respectively of the data: ``{'X': 2, 'Y': 1}`` fold_index: `int`, optional Identify which index of the "Y" axis corresponds to @@ -4957,6 +4958,9 @@ def halo( {{verbose: `int` or `str` or `None`, optional}} + size: deprecated at version TODODASKVER + Use the *depth* parameter instead. + :Returns: `{{class}}` or `None` @@ -4965,19 +4969,25 @@ def halo( **Examples** - TODO + TODO """ - _kwargs = [f"{k}={v!r}" for k, v in locals().items()] - _ = f"{self.__class__.__name__}.halo(" - logger.info("{}{}".format(_, (",\n" + " " * len(_)).join(_kwargs))) + if size is not None: + _DEPRECATION_ERROR_KWARGS( + self, + "halo", + {"size": None}, + message="Use the 'depth' parameter instead.", + version="TODODASKVER", + removed_at="5.0.0", + ) # pragma: no cover v = _inplace_enabled_define_and_cleanup(self) data = v.get_data(None) if data is not None: data.halo( - size=size, + depth, axes=axes, tripolar=tripolar, fold_index=fold_index, diff --git a/cf/mixin/propertiesdatabounds.py b/cf/mixin/propertiesdatabounds.py index e73636234e..8be813dff9 100644 --- a/cf/mixin/propertiesdatabounds.py +++ b/cf/mixin/propertiesdatabounds.py @@ -11,6 +11,7 @@ ) from ..functions import ( _DEPRECATION_ERROR_ATTRIBUTE, + _DEPRECATION_ERROR_KWARGS, _DEPRECATION_ERROR_METHOD, bounds_combination_mode, ) @@ -2295,12 +2296,13 @@ def override_units(self, units, inplace=False, i=False): @_manage_log_level_via_verbosity def halo( self, - size, + depth, axes=None, tripolar=None, fold_index=-1, inplace=False, verbose=None, + size=None, ): """Expand the data by adding a halo. @@ -2327,10 +2329,10 @@ def halo( :Parameters: - size: `int` or `dict` + depth: `int` or `dict` Specify the size of the halo for each axis. - If *size* is a non-negative `int` then this is the halo + If *depth* is a non-negative `int` then this is the halo size that is applied to all of the axes defined by the *axes* parameter. @@ -2343,22 +2345,22 @@ def halo( *Parameter example:* Specify a halo size of 1 for all otherwise selected - axes: ``size=1`` + axes: ``1`` *Parameter example:* - Specify a halo size of zero ``size=0``. This results in + Specify a halo size of zero: ``0``. This results in no change to the data shape. *Parameter example:* - For data with three dimensions, specify a halo size of 3 - for the first dimension and 1 for the second dimension: - ``size={0: 3, 1: 1}``. This is equivalent to ``size={0: - 3, 1: 1, 2: 0}`` + For data with three dimensions, specify a halo size + of 3 for the first dimension and 1 for the second + dimension: ``{0: 3, 1: 1}``. This is equivalent to + ``{0: 3, 1: 1, 2: 0}`` *Parameter example:* Specify a halo size of 2 for the first and last - dimensions `size=2, axes=[0, -1]`` or equivalently - ``size={0: 2, -1: 2}``. + dimensions `depth=2, axes=[0, -1]`` or equivalently + ``depth={0: 2, -1: 2}``. axes: (sequence of) `int` Select the domain axes to be expanded, defined by their @@ -2374,14 +2376,14 @@ def halo( whose values identify the corresponding domain axis construct by their integer positions in the data. - The "X" and "Y" axes must be a subset of those identified - by the *size* or *axes* parameter. + The "X" and "Y" axes must be a subset of those + identified by the *depth* or *axes* parameter. See the *fold_index* parameter. *Parameter example:* Define the "X" and Y" axes by positions 2 and 1 - respectively of the data: ``tripolar={'X': 2, 'Y': 1}`` + respectively of the data: ``{'X': 2, 'Y': 1}`` fold_index: `int`, optional Identify which index of the "Y" axis corresponds to the @@ -2394,8 +2396,12 @@ def halo( {{verbose: `int` or `str` or `None`, optional}} + size: deprecated at version TODODASKVER + Use the *depth* parameter instead. + :Returns: + `{{class}}` or `None` The expanded data, or `None` if the operation was in-place. @@ -2404,13 +2410,23 @@ def halo( TODO """ + if size is not None: + _DEPRECATION_ERROR_KWARGS( + self, + "halo", + {"size": None}, + message="Use the 'depth' parameter instead.", + version="TODODASKVER", + removed_at="5.0.0", + ) # pragma: no cover + return self._apply_superclass_data_oper( _inplace_enabled_define_and_cleanup(self), "halo", bounds=True, interior_ring=True, inplace=inplace, - size=size, + depth=depth, axes=axes, tripolar=tripolar, fold_index=fold_index, From a7ff8ec5862ae566a5fd204d4e8574a55c951ad5 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Mon, 10 Oct 2022 10:10:53 +0100 Subject: [PATCH 2/4] api change note --- cf/field.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cf/field.py b/cf/field.py index 2f60595e3d..6a9f381b5b 100644 --- a/cf/field.py +++ b/cf/field.py @@ -13652,6 +13652,7 @@ def halo( """ f = _inplace_enabled_define_and_cleanup(self) + # TODODASKAPI if size is not None: _DEPRECATION_ERROR_KWARGS( self, From 3d50f214a5bcf1eef821005c95cf14366dae9aa9 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Wed, 26 Oct 2022 15:08:55 +0100 Subject: [PATCH 3/4] Typo Co-authored-by: Sadie L. Bartholomew --- cf/field.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cf/field.py b/cf/field.py index 6a9f381b5b..36d4e9d21e 100644 --- a/cf/field.py +++ b/cf/field.py @@ -13490,7 +13490,7 @@ def halo( *Parameter example:* Specify a halo size of 2 for the "longitude" and "latitude" axes: ``depth=2, axes=['latutude', - 'longitude']``, or equivalently ``depth={'latutude': + 'longitude']``, or equivalently ``depth={'latitude': 2, 'longitude': 2}``. axes: (sequence of) `str` or `int`, optional From 5c5130869cb7d4d2415e66d6488bd6da9baf1025 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Wed, 26 Oct 2022 15:09:08 +0100 Subject: [PATCH 4/4] Typo Co-authored-by: Sadie L. Bartholomew --- cf/mixin/propertiesdatabounds.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cf/mixin/propertiesdatabounds.py b/cf/mixin/propertiesdatabounds.py index 8be813dff9..7cb4904ec5 100644 --- a/cf/mixin/propertiesdatabounds.py +++ b/cf/mixin/propertiesdatabounds.py @@ -2359,7 +2359,7 @@ def halo( *Parameter example:* Specify a halo size of 2 for the first and last - dimensions `depth=2, axes=[0, -1]`` or equivalently + dimensions ``depth=2, axes=[0, -1]`` or equivalently ``depth={0: 2, -1: 2}``. axes: (sequence of) `int`