Skip to content

Commit 527cb92

Browse files
committed
subspace query swapped operands
1 parent f3d9141 commit 527cb92

3 files changed

Lines changed: 36 additions & 16 deletions

File tree

Changelog.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ Version NEXTVERSION
1212
* Fix bug in `cf.Field.collapse` that causes a ``ValueError`` to be raised
1313
for missing external cell measures data
1414
(https://github.com/NCAS-CMS/cf-python/issues/885)
15+
* Fix `cf.Field.subspace` for a cyclic axis so that a query range
16+
provided by `cf.wi` or `cf.wo` is also treated cyclicly
17+
(https://github.com/NCAS-CMS/cf-python/issues/887)
1518
* New dependency: ``distributed>=2025.5.1``
1619

1720
----

cf/mixin/fielddomain.py

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -455,25 +455,26 @@ def _indices(self, config, data_axes, ancillary_mask, kwargs):
455455
if debug:
456456
logger.debug(" 1-d CASE 2:") # pragma: no cover
457457

458-
# Adjust value so it's in the range [c[0],
459-
# c[0]+period)
460458
value0, value1 = value.value
461-
print (value.value, value0, value1)
462459
if value1 < value0:
460+
# Query has swapped operands (i.e. arg0 >
461+
# arg1) => Create a new equivalant Query
462+
# that has the arg0 < arg1. E.g. for a
463+
# period of 360, cf.wi(355, 5) is
464+
# transformed to cf.wi(355, 365).
465+
#
466+
# This is done (effectively) by repeatedly
467+
# adding the cyclic period to arg1 until
468+
# it is greater than arg0, taking into
469+
# account any units that are in play.
463470
period = item.period()
464-
d = self._Data(value.value)
465-
print(repr(d))
466-
d.Units= period.Units
467-
468-
print (-d.diff())
469-
n = (-d.diff()/period).ceil()
470-
print(repr(n))
471-
value0 = (d[0]).datum()
472-
value1 = (d[1] + n * period).datum()
473-
print(repr(d))
474-
value = wi(value0, value1, units=d.Units)
475-
476-
print(repr(value), item.period())
471+
value = value.copy()
472+
value.set_condition_units(period.Units)
473+
value0, value1 = value.value
474+
n = ((value0 - value1) / period).ceil()
475+
value1 = value1 + n * period
476+
value = wi(value0, value1)
477+
477478
size = item.size
478479
if item.increasing:
479480
anchor = value.value[0]

cf/test/test_Field.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1286,6 +1286,14 @@ def test_Field_indices(self):
12861286
a[..., [0, 1, 6, 7, 8]] = np.ma.masked
12871287
self.assertTrue(cf.functions._numpy_allclose(g.array, a), g.array)
12881288

1289+
for q in (cf.wi(315, 45), cf.wi(-45, -675)):
1290+
# Cyclic cf.wi with swapped operands (increasing coords)
1291+
indices = f.indices(grid_longitude=q)
1292+
g = f[indices]
1293+
self.assertEqual(g.shape, (1, 10, 3))
1294+
x = g.dimension_coordinate("X").array
1295+
self.assertTrue((x == [-40, 0, 40]).all())
1296+
12891297
# wi (decreasing)
12901298
f.flip("X", inplace=True)
12911299

@@ -1342,6 +1350,14 @@ def test_Field_indices(self):
13421350
(x == [0, 40, 80, 120, 160, 200, 240, 280, 320][::-1]).all()
13431351
)
13441352

1353+
for q in (cf.wi(315, 45), cf.wi(-45, -675)):
1354+
# Cyclic cf.wi with swapped operands (decreasing coords)
1355+
indices = f.indices(grid_longitude=q)
1356+
g = f[indices]
1357+
self.assertEqual(g.shape, (1, 10, 3))
1358+
x = g.dimension_coordinate("X").array
1359+
self.assertTrue((x == [40, 0, -40]).all())
1360+
13451361
# wo
13461362
f = f0.copy()
13471363

0 commit comments

Comments
 (0)