|
16 | 16 | bounds_combination_mode, |
17 | 17 | normalize_slice, |
18 | 18 | ) |
19 | | -from ..query import Query, wi |
| 19 | +from ..query import Query, wi, wo |
20 | 20 | from ..units import Units |
21 | 21 |
|
22 | 22 | logger = logging.getLogger(__name__) |
@@ -245,8 +245,8 @@ def _indices(self, config, data_axes, ancillary_mask, kwargs): |
245 | 245 | tuples of domain axis identifier combinations, each |
246 | 246 | of which has of a `Data` object containing the |
247 | 247 | ancillary mask to apply to those domain axes |
248 | | - immediately after the subspace has been created |
249 | | - by the ``'indices'``. This dictionary will always be |
| 248 | + immediately after the subspace has been created by |
| 249 | + the ``'indices'``. This dictionary will always be |
250 | 250 | empty if the *ancillary_mask* parameter is False. |
251 | 251 |
|
252 | 252 | """ |
@@ -456,6 +456,30 @@ def _indices(self, config, data_axes, ancillary_mask, kwargs): |
456 | 456 | if debug: |
457 | 457 | logger.debug(" 1-d CASE 2:") # pragma: no cover |
458 | 458 |
|
| 459 | + arg0, arg1 = value.value |
| 460 | + if arg0 > arg1: |
| 461 | + # Query has swapped operands (i.e. arg0 > |
| 462 | + # arg1) => Create a new equivalant Query |
| 463 | + # that has arg0 < arg1, for a new |
| 464 | + # arg1. E.g. for a period of 360, |
| 465 | + # cf.wi(355, 5) is transformed to |
| 466 | + # cf.wi(355, 365). |
| 467 | + # |
| 468 | + # This is done (effectively) by repeatedly |
| 469 | + # adding the cyclic period to arg1 until |
| 470 | + # it is greater than arg0, taking into |
| 471 | + # account any units that have been set. |
| 472 | + period = item.period() |
| 473 | + value = value.copy() |
| 474 | + value.set_condition_units(period.Units) |
| 475 | + arg0, arg1 = value.value |
| 476 | + n = ((arg0 - arg1) / period).ceil() |
| 477 | + arg1 = arg1 + n * period |
| 478 | + if value.operator == "wi": |
| 479 | + value = wi(arg0, arg1) |
| 480 | + else: |
| 481 | + value = wo(arg0, arg1) |
| 482 | + |
459 | 483 | size = item.size |
460 | 484 | if item.increasing: |
461 | 485 | anchor = value.value[0] |
@@ -2020,12 +2044,18 @@ def cyclic( |
2020 | 2044 |
|
2021 | 2045 | # Check for axes that are currently marked as non-cyclic, |
2022 | 2046 | # but are in fact cyclic. |
2023 | | - if ( |
2024 | | - len(cyclic) < len(self.domain_axes(todict=True)) |
2025 | | - and self.autocyclic() |
2026 | | - ): |
2027 | | - cyclic.update(self._cyclic) |
2028 | | - self._cyclic = cyclic |
| 2047 | + # |
| 2048 | + # Note: We have to do a "dry run" on the 'autocyclic' call |
| 2049 | + # in the if test in order to prevent corrupting |
| 2050 | + # self._cyclic in the case that an axis tested by |
| 2051 | + # autocyclic is already marked as cylcic, but |
| 2052 | + # nonetheless autocyclic returns False (sounds |
| 2053 | + # niche, but this really happens!). |
| 2054 | + if len(cyclic) < len( |
| 2055 | + self.domain_axes(todict=True) |
| 2056 | + ) and self.autocyclic(config={"dry_run": True}): |
| 2057 | + self.autocyclic() |
| 2058 | + cyclic = self._cyclic.copy() |
2029 | 2059 |
|
2030 | 2060 | return cyclic |
2031 | 2061 |
|
|
0 commit comments