From 71c92a844c5e39917284938769eb0abc3774770f Mon Sep 17 00:00:00 2001 From: David Hassell Date: Tue, 8 Mar 2022 13:14:05 +0000 Subject: [PATCH 1/4] dask: Data.cyclic --- cf/data/data.py | 51 ++++++++++++++++++++++++++++++++++++++++++-- cf/test/test_Data.py | 28 ++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 2 deletions(-) diff --git a/cf/data/data.py b/cf/data/data.py index 535bcd7011..47dd6ecf4c 100644 --- a/cf/data/data.py +++ b/cf/data/data.py @@ -8778,20 +8778,67 @@ def count_masked(self): """ return self._size - self.count() + @daskified(_DASKIFIED_VERBOSE) def cyclic(self, axes=None, iscyclic=True): - """Returns or sets the axes of the data array which are cyclic. + """Get or set the cyclic axes. + + Some methods treat the first and last elements of a cyclic + axis as adjacent and physically connected, such as + `convolution_filter`, `__getitem__` and `__setitem__`. Some + methods may make a cyclic axis non-cyclis, such as `halo`. :Parameters: axes: (sequence of) `int`, optional + Select the axes to to have their cyclicity set. By + default, or if *axes* is `None` or an empty sequence, + no axes are modified. iscyclic: `bool` + Specify whether to make the the axes cyclic or + non-cyclic. By default (True), the axes are set as + cyclic. :Returns: `set` + The cyclic axes prior to the change, or the current + cylcic axes if no axes are specified. - **Examples:** + **Examples** + + >>> d = cf.Data(np.arange(12).reshape(3, 4)) + >>> d.cyclic() + set() + >>> d.cyclic(0) + set() + >>> d.cyclic() + {0} + >>> d.cyclic(0, iscyclic=False) + {0} + >>> d.cyclic() + set() + >>> d.cyclic([0, 1]) + set() + >>> d.cyclic() + {0, 1} + >>> d.cyclic([0, 1], iscyclic=False) + {0, 1} + >>> d.cyclic() + set() + + >>> print(d.array) + [[ 0 1 2 3] + [ 4 5 6 7] + [ 8 9 10 11]] + >>> d[0, -1:2] + Traceback (most recent call last): + ... + IndexError: Can't take a cyclic slice of a non-cyclic axis + >>> d.cyclic(1) + set() + >>> d[0, -1:2] + """ cyclic_axes = self._cyclic diff --git a/cf/test/test_Data.py b/cf/test/test_Data.py index c693d7ca55..c80e2292ab 100644 --- a/cf/test/test_Data.py +++ b/cf/test/test_Data.py @@ -3850,6 +3850,34 @@ def test_Data__bool__(self): with self.assertRaises(ValueError): bool(cf.Data([1, 2])) + def test_Data_cyclic(self): + d = cf.Data(np.arange(12).reshape(3, 4)) + self.assertEqual(d.cyclic(), set()) + self.assertEqual(d.cyclic(0), set()) + self.assertEqual(d.cyclic(), {0}) + self.assertEqual(d.cyclic(1), {0}) + self.assertEqual(d.cyclic(), {0, 1}) + self.assertEqual(d.cyclic(0, iscyclic=False), {0, 1}) + self.assertEqual(d.cyclic(), {1}) + self.assertEqual(d.cyclic(1, iscyclic=False), {1}) + self.assertEqual(d.cyclic(), set()) + self.assertEqual(d.cyclic([0, 1]), set()) + self.assertEqual(d.cyclic(), {0, 1}) + self.assertEqual(d.cyclic([0, 1], iscyclic=False), {0, 1}) + self.assertEqual(d.cyclic(), set()) + + # Invalid axis + with self.assertRaises(ValueError): + d.cyclic(2) + + # Scalar data + d = cf.Data(9) + self.assertEqual(d.cyclic(), set()) + + # Scalar data invalid axis + with self.assertRaises(ValueError): + d.cyclic(0) + if __name__ == "__main__": print("Run date:", datetime.datetime.now()) From 3276f2f4cdd3091805f9b42d7913965ed422f75b Mon Sep 17 00:00:00 2001 From: David Hassell Date: Wed, 16 Mar 2022 17:17:24 +0000 Subject: [PATCH 2/4] Typo Co-authored-by: Sadie L. Bartholomew --- cf/data/data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cf/data/data.py b/cf/data/data.py index 47dd6ecf4c..092009592f 100644 --- a/cf/data/data.py +++ b/cf/data/data.py @@ -8785,7 +8785,7 @@ def cyclic(self, axes=None, iscyclic=True): Some methods treat the first and last elements of a cyclic axis as adjacent and physically connected, such as `convolution_filter`, `__getitem__` and `__setitem__`. Some - methods may make a cyclic axis non-cyclis, such as `halo`. + methods may make a cyclic axis non-cyclic, such as `halo`. :Parameters: From 28787f45fe5ff13401fb7573f44e631fc0917f94 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Wed, 16 Mar 2022 17:18:22 +0000 Subject: [PATCH 3/4] Typo Co-authored-by: Sadie L. Bartholomew --- cf/data/data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cf/data/data.py b/cf/data/data.py index 092009592f..54f20ea370 100644 --- a/cf/data/data.py +++ b/cf/data/data.py @@ -8790,7 +8790,7 @@ def cyclic(self, axes=None, iscyclic=True): :Parameters: axes: (sequence of) `int`, optional - Select the axes to to have their cyclicity set. By + Select the axes to have their cyclicity set. By default, or if *axes* is `None` or an empty sequence, no axes are modified. From 696554c0e4ddac3325938b47c4599a9cbd707e1c Mon Sep 17 00:00:00 2001 From: David Hassell Date: Wed, 16 Mar 2022 17:18:48 +0000 Subject: [PATCH 4/4] Typo Co-authored-by: Sadie L. Bartholomew --- cf/data/data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cf/data/data.py b/cf/data/data.py index 54f20ea370..f63978b648 100644 --- a/cf/data/data.py +++ b/cf/data/data.py @@ -8795,7 +8795,7 @@ def cyclic(self, axes=None, iscyclic=True): no axes are modified. iscyclic: `bool` - Specify whether to make the the axes cyclic or + Specify whether to make the axes cyclic or non-cyclic. By default (True), the axes are set as cyclic.