Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion Changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,12 @@ version 3.16.2
* Fix bug whereby `Field.cyclic` is not updated after a
`Field.del_construct` operation
(https://github.com/NCAS-CMS/cf-python/issues/758)
* Fix bug that meant `cyclic()` always returned an empty
set for domains produced by `cf.Field.domain`
(https://github.com/NCAS-CMS/cf-python/issues/762)
* Changed dependency: ``cfunits>=3.3.7``
* Changed dependency: ``netCDF4>=1.6.5``

----

version 3.16.1
Expand Down
30 changes: 27 additions & 3 deletions cf/field.py
Original file line number Diff line number Diff line change
Expand Up @@ -2691,6 +2691,30 @@ def cfa_update_file_substitutions(
for c in self.constructs.filter_by_data(todict=True).values():
c.cfa_update_file_substitutions(substitutions)

def get_domain(self):
"""Return the domain.

.. versionadded:: NEXTVERSION

.. seealso:: `domain`

:Returns:

`Domain`
The domain.

**Examples**

>>> d = f.get_domain()

"""
domain = super().get_domain()

# Set axis cyclicity for the domain
domain._cyclic = self._cyclic

return domain

def radius(self, default=None):
"""Return the radius of a latitude-longitude plane defined in
spherical polar coordinates.
Expand Down Expand Up @@ -10455,9 +10479,9 @@ def convolution_filter(
new_bounds[0 : length - lower_offset, 1:] = old_bounds[
lower_offset:length, 1:
]
new_bounds[
length - lower_offset : length, 1:
] = old_bounds[length - 1, 1:]
new_bounds[length - lower_offset : length, 1:] = (
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was just from linting the files I touched in this PR. For the release we can re-lint the whole codebase since it seems we are a bit behind on linting (black edits >10 files under cf/).

old_bounds[length - 1, 1:]
)

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

Expand Down
2 changes: 1 addition & 1 deletion cf/mixin/fielddomain.py
Original file line number Diff line number Diff line change
Expand Up @@ -1909,7 +1909,7 @@ def coordinate_reference_domain_axes(self, identity=None):
def cyclic(
self, *identity, iscyclic=True, period=None, config={}, **filter_kwargs
):
"""Set the cyclicity of an axis.
"""Get or set the cyclicity of an axis.

.. versionadded:: 1.0

Expand Down
2 changes: 1 addition & 1 deletion cf/mixin/propertiesdata.py
Original file line number Diff line number Diff line change
Expand Up @@ -2934,7 +2934,7 @@ def count_masked(self):
return data.count_masked()

def cyclic(self, axes=None, iscyclic=True):
"""Set the cyclicity of an axis.
"""Get or set the cyclicity of an axis.

.. seealso:: `iscyclic`

Expand Down
2 changes: 1 addition & 1 deletion cf/mixin/propertiesdatabounds.py
Original file line number Diff line number Diff line change
Expand Up @@ -1607,7 +1607,7 @@ def cos(self, bounds=True, inplace=False, i=False):
)

def cyclic(self, axes=None, iscyclic=True):
"""Set the cyclicity of axes of the data array.
"""Get or set the cyclicity of axes of the data array.

.. seealso:: `iscyclic`

Expand Down
29 changes: 29 additions & 0 deletions cf/test/test_Domain.py
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,35 @@ def test_Domain_del_construct(self):
self.assertIsInstance(e.del_construct("domainaxis2"), cf.DomainAxis)
self.assertEqual(e.cyclic(), set())

def test_Domain_cyclic_iscyclic(self):
"""Test the `cyclic` and `iscyclic` Domain methods."""
# A field and its domain should have the same cyclic() output.
f1 = cf.example_field(1) # no cyclic axes
d1 = f1.domain
f2 = cf.example_field(2) # one cyclic axis, 'domainaxis2' ('X')
d2 = f2.domain

# Getting
self.assertEqual(d1.cyclic(), f1.cyclic())
self.assertEqual(d1.cyclic(), set())
self.assertFalse(d1.iscyclic("X"))
self.assertFalse(d1.iscyclic("Y"))
self.assertFalse(d1.iscyclic("Z"))
self.assertFalse(d1.iscyclic("T"))
self.assertEqual(d2.cyclic(), f2.cyclic())
self.assertEqual(d2.cyclic(), set(("domainaxis2",)))
self.assertTrue(d2.iscyclic("X"))
self.assertFalse(d2.iscyclic("Y"))
self.assertFalse(d2.iscyclic("Z"))
self.assertFalse(d2.iscyclic("T"))

# Setting
self.assertEqual(d2.cyclic("X", iscyclic=False), set(("domainaxis2",)))
self.assertEqual(d2.cyclic(), set())
self.assertEqual(d2.cyclic("X", period=360), set())
self.assertEqual(d2.cyclic(), set(("domainaxis2",)))
self.assertTrue(d2.iscyclic("X"))


if __name__ == "__main__":
print("Run date:", datetime.datetime.now())
Expand Down
24 changes: 24 additions & 0 deletions cf/test/test_Field.py
Original file line number Diff line number Diff line change
Expand Up @@ -2859,6 +2859,30 @@ def test_Field_pad_missing(self):
self.assertEqual(g.shape, (6, 11))
self.assertTrue(g[5, :].mask.all())

def test_Field_cyclic_iscyclic(self):
"""Test the `cyclic` and `iscyclic` Field methods."""
f1 = cf.example_field(1) # no cyclic axes
f2 = cf.example_field(2) # one cyclic axis, 'domainaxis2' ('X')

# Getting
self.assertEqual(f1.cyclic(), set())
self.assertFalse(f1.iscyclic("X"))
self.assertFalse(f1.iscyclic("Y"))
self.assertFalse(f1.iscyclic("Z"))
self.assertFalse(f1.iscyclic("T"))
self.assertEqual(f2.cyclic(), set(("domainaxis2",)))
self.assertTrue(f2.iscyclic("X"))
self.assertFalse(f2.iscyclic("Y"))
self.assertFalse(f2.iscyclic("Z"))
self.assertFalse(f2.iscyclic("T"))

# Setting
self.assertEqual(f2.cyclic("X", iscyclic=False), set(("domainaxis2",)))
self.assertEqual(f2.cyclic(), set())
self.assertEqual(f2.cyclic("X", period=360), set())
self.assertEqual(f2.cyclic(), set(("domainaxis2",)))
self.assertTrue(f2.iscyclic("X"))


if __name__ == "__main__":
print("Run date:", datetime.datetime.now())
Expand Down