Skip to content

Commit c02a935

Browse files
authored
Merge pull request #745 from davidhassell/getitem-cyclic
Improve `cf.Field.__getitem__` performance by not re-calculating axis cyclicity
2 parents 5fed753 + f696627 commit c02a935

File tree

4 files changed

+33
-1
lines changed

4 files changed

+33
-1
lines changed

Changelog.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ version NEXT
1111
(https://github.com/NCAS-CMS/cf-python/issues/715)
1212
* Improve `cf.Field.collapse` performance by lazily computing reduced
1313
axis coordinates (https://github.com/NCAS-CMS/cf-python/issues/741)
14+
* Improve `cf.Field.__getitem__` performance by not re-calculating
15+
axis cyclicity (https://github.com/NCAS-CMS/cf-python/issues/744)
1416
* Fix misleading error message when it is not possible to create area
1517
weights requested from `cf.Field.collapse`
1618
(https://github.com/NCAS-CMS/cf-python/issues/731)

cf/field.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,22 @@ def __getitem__(self, indices):
441441
for axis, size in zip(data_axes, new_data.shape):
442442
domain_axes[axis].set_size(size)
443443

444+
# Record which axes were cyclic before the subspace
445+
org_cyclic = [data_axes.index(axis) for axis in new.cyclic()]
446+
447+
# Set the subspaced data
448+
new.set_data(new_data, axes=data_axes, copy=False)
449+
450+
# Update axis cylcicity. Note that this can only entail
451+
# setting an originally cyclic axis to be non-cyclic. Doing
452+
# this now enables us to disable the (possibly very slow)
453+
# automatic check for cyclicity on the 'set_construct' calls
454+
# below.
455+
if org_cyclic:
456+
new_cyclic = new_data.cyclic()
457+
[new.cyclic(i, iscyclic=False) for i in org_cyclic if i not in new_cyclic]
458+
459+
444460
# ------------------------------------------------------------
445461
# Subspace constructs with data
446462
# ------------------------------------------------------------
@@ -507,6 +523,7 @@ def __getitem__(self, indices):
507523
key=key,
508524
axes=construct_axes,
509525
copy=False,
526+
autocyclic={"no-op": True},
510527
)
511528

512529
new.set_data(new_data, axes=data_axes, copy=False)

cf/mixin/fielddomain.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1109,10 +1109,15 @@ def autocyclic(self, key=None, coord=None, verbose=None, config={}):
11091109
11101110
:Returns:
11111111
1112-
`bool`
1112+
`bool` or `None`
1113+
`True` if the dimension is cyclic, `False` if it isn't,
1114+
or `None` if no checks were done.
11131115
11141116
"""
11151117
noop = config.get("no-op")
1118+
if noop:
1119+
# Don't do anything
1120+
return
11161121

11171122
if "cyclic" in config:
11181123
if not config["cyclic"]:

cf/test/test_Field.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,14 @@ def test_Field__getitem__(self):
663663
self.assertTrue(np.allclose(f[:, -3:].array, g[:, :3].array))
664664
self.assertTrue(f[:, :4].equals(g[:, 3:]))
665665

666+
# Test setting of axis cyclicity
667+
f.cyclic("grid_longitude", iscyclic=True)
668+
self.assertEqual(f.data.cyclic(), {1})
669+
g = f[0, :]
670+
self.assertEqual(g.data.cyclic(), {1})
671+
g = f[:, 0]
672+
self.assertEqual(g.data.cyclic(), set())
673+
666674
def test_Field__setitem__(self):
667675
f = self.f.copy().squeeze()
668676

0 commit comments

Comments
 (0)