Skip to content

Commit 981fcd0

Browse files
Merge pull request #769 from sadielbartholomew/cyclic-sets-domain
Override `cfdm.Field.get_domain` to store axes cyclicity
2 parents 393b351 + ddc992f commit 981fcd0

File tree

7 files changed

+87
-7
lines changed

7 files changed

+87
-7
lines changed

Changelog.rst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,12 @@ version 3.16.2
4444
* Fix bug whereby `Field.cyclic` is not updated after a
4545
`Field.del_construct` operation
4646
(https://github.com/NCAS-CMS/cf-python/issues/758)
47+
* Fix bug that meant `cyclic()` always returned an empty
48+
set for domains produced by `cf.Field.domain`
49+
(https://github.com/NCAS-CMS/cf-python/issues/762)
4750
* Changed dependency: ``cfunits>=3.3.7``
4851
* Changed dependency: ``netCDF4>=1.6.5``
49-
52+
5053
----
5154

5255
version 3.16.1

cf/field.py

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2691,6 +2691,30 @@ def cfa_update_file_substitutions(
26912691
for c in self.constructs.filter_by_data(todict=True).values():
26922692
c.cfa_update_file_substitutions(substitutions)
26932693

2694+
def get_domain(self):
2695+
"""Return the domain.
2696+
2697+
.. versionadded:: NEXTVERSION
2698+
2699+
.. seealso:: `domain`
2700+
2701+
:Returns:
2702+
2703+
`Domain`
2704+
The domain.
2705+
2706+
**Examples**
2707+
2708+
>>> d = f.get_domain()
2709+
2710+
"""
2711+
domain = super().get_domain()
2712+
2713+
# Set axis cyclicity for the domain
2714+
domain._cyclic = self._cyclic
2715+
2716+
return domain
2717+
26942718
def radius(self, default=None):
26952719
"""Return the radius of a latitude-longitude plane defined in
26962720
spherical polar coordinates.
@@ -10455,9 +10479,9 @@ def convolution_filter(
1045510479
new_bounds[0 : length - lower_offset, 1:] = old_bounds[
1045610480
lower_offset:length, 1:
1045710481
]
10458-
new_bounds[
10459-
length - lower_offset : length, 1:
10460-
] = old_bounds[length - 1, 1:]
10482+
new_bounds[length - lower_offset : length, 1:] = (
10483+
old_bounds[length - 1, 1:]
10484+
)
1046110485

1046210486
coord.set_bounds(self._Bounds(data=new_bounds))
1046310487

cf/mixin/fielddomain.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1909,7 +1909,7 @@ def coordinate_reference_domain_axes(self, identity=None):
19091909
def cyclic(
19101910
self, *identity, iscyclic=True, period=None, config={}, **filter_kwargs
19111911
):
1912-
"""Set the cyclicity of an axis.
1912+
"""Get or set the cyclicity of an axis.
19131913
19141914
.. versionadded:: 1.0
19151915

cf/mixin/propertiesdata.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2934,7 +2934,7 @@ def count_masked(self):
29342934
return data.count_masked()
29352935

29362936
def cyclic(self, axes=None, iscyclic=True):
2937-
"""Set the cyclicity of an axis.
2937+
"""Get or set the cyclicity of an axis.
29382938
29392939
.. seealso:: `iscyclic`
29402940

cf/mixin/propertiesdatabounds.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1607,7 +1607,7 @@ def cos(self, bounds=True, inplace=False, i=False):
16071607
)
16081608

16091609
def cyclic(self, axes=None, iscyclic=True):
1610-
"""Set the cyclicity of axes of the data array.
1610+
"""Get or set the cyclicity of axes of the data array.
16111611
16121612
.. seealso:: `iscyclic`
16131613

cf/test/test_Domain.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,35 @@ def test_Domain_del_construct(self):
428428
self.assertIsInstance(e.del_construct("domainaxis2"), cf.DomainAxis)
429429
self.assertEqual(e.cyclic(), set())
430430

431+
def test_Domain_cyclic_iscyclic(self):
432+
"""Test the `cyclic` and `iscyclic` Domain methods."""
433+
# A field and its domain should have the same cyclic() output.
434+
f1 = cf.example_field(1) # no cyclic axes
435+
d1 = f1.domain
436+
f2 = cf.example_field(2) # one cyclic axis, 'domainaxis2' ('X')
437+
d2 = f2.domain
438+
439+
# Getting
440+
self.assertEqual(d1.cyclic(), f1.cyclic())
441+
self.assertEqual(d1.cyclic(), set())
442+
self.assertFalse(d1.iscyclic("X"))
443+
self.assertFalse(d1.iscyclic("Y"))
444+
self.assertFalse(d1.iscyclic("Z"))
445+
self.assertFalse(d1.iscyclic("T"))
446+
self.assertEqual(d2.cyclic(), f2.cyclic())
447+
self.assertEqual(d2.cyclic(), set(("domainaxis2",)))
448+
self.assertTrue(d2.iscyclic("X"))
449+
self.assertFalse(d2.iscyclic("Y"))
450+
self.assertFalse(d2.iscyclic("Z"))
451+
self.assertFalse(d2.iscyclic("T"))
452+
453+
# Setting
454+
self.assertEqual(d2.cyclic("X", iscyclic=False), set(("domainaxis2",)))
455+
self.assertEqual(d2.cyclic(), set())
456+
self.assertEqual(d2.cyclic("X", period=360), set())
457+
self.assertEqual(d2.cyclic(), set(("domainaxis2",)))
458+
self.assertTrue(d2.iscyclic("X"))
459+
431460

432461
if __name__ == "__main__":
433462
print("Run date:", datetime.datetime.now())

cf/test/test_Field.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2859,6 +2859,30 @@ def test_Field_pad_missing(self):
28592859
self.assertEqual(g.shape, (6, 11))
28602860
self.assertTrue(g[5, :].mask.all())
28612861

2862+
def test_Field_cyclic_iscyclic(self):
2863+
"""Test the `cyclic` and `iscyclic` Field methods."""
2864+
f1 = cf.example_field(1) # no cyclic axes
2865+
f2 = cf.example_field(2) # one cyclic axis, 'domainaxis2' ('X')
2866+
2867+
# Getting
2868+
self.assertEqual(f1.cyclic(), set())
2869+
self.assertFalse(f1.iscyclic("X"))
2870+
self.assertFalse(f1.iscyclic("Y"))
2871+
self.assertFalse(f1.iscyclic("Z"))
2872+
self.assertFalse(f1.iscyclic("T"))
2873+
self.assertEqual(f2.cyclic(), set(("domainaxis2",)))
2874+
self.assertTrue(f2.iscyclic("X"))
2875+
self.assertFalse(f2.iscyclic("Y"))
2876+
self.assertFalse(f2.iscyclic("Z"))
2877+
self.assertFalse(f2.iscyclic("T"))
2878+
2879+
# Setting
2880+
self.assertEqual(f2.cyclic("X", iscyclic=False), set(("domainaxis2",)))
2881+
self.assertEqual(f2.cyclic(), set())
2882+
self.assertEqual(f2.cyclic("X", period=360), set())
2883+
self.assertEqual(f2.cyclic(), set(("domainaxis2",)))
2884+
self.assertTrue(f2.iscyclic("X"))
2885+
28622886

28632887
if __name__ == "__main__":
28642888
print("Run date:", datetime.datetime.now())

0 commit comments

Comments
 (0)