Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow extraction with bounded time-coordinates. #5175

Closed
pp-mo opened this issue Feb 23, 2023 · 1 comment · Fixed by #5396
Closed

Allow extraction with bounded time-coordinates. #5175

pp-mo opened this issue Feb 23, 2023 · 1 comment · Fixed by #5396
Assignees
Labels
Good First Issue A good issue to take on if you're just getting started with Iris development

Comments

@pp-mo
Copy link
Member

pp-mo commented Feb 23, 2023

A user enquiry revealed that at least some extractions from bounded time coordinates are "banned".

There is a specific test+fail in place for these cases.
We think that this restriction can now be removed, as the various time objects all now provide reliable comparison operations. (see below)

This was revealed when trying to extract a timepoint matching one from another cube, like this ...

>>> import iris
>>> from iris.cube import Cube
>>> from iris.coords import DimCoord
>>> from cf_units import Unit
>>> 
>>> co_time = DimCoord(
...     [0., 1],
...     standard_name='time',
...     units=Unit('hours since 1970-01-01', calendar='standard')
... )
>>> 
>>> times_cube = Cube([0, 1])
>>> times_cube.add_dim_coord(co_time, (0,))
>>> print(times_cube)
unknown / (unknown)                 (time: 2)
    Dimension coordinates:
        time                             x
>>> 
>>> time_point = co_time.units.num2date(co_time.points[0])
>>> constraint = iris.Constraint(time=time_point)
>>> print(time_point)
1970-01-01 00:00:00
>>> 
>>> extract = times_cube.extract(constraint)
>>> print(extract)
unknown / (unknown)                 (scalar cube)
    Scalar coordinates:
        time                        1970-01-01 00:00:00
>>> 
>>> times_cube.coord('time').bounds = [[0., 1], [1, 2]]
>>> extract = times_cube.extract(constraint)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File ".../iris/cube.py", line 2615, in extract
    return constraint.extract(self)
  File ".../iris/_constraints.py", line 165, in extract
    resultant_CIM = self._CIM_extract(cube)
  File ".../iris/_constraints.py", line 189, in _CIM_extract
    resultant_CIM = resultant_CIM & coord_constraint.extract(cube)
  File ".../iris/_constraints.py", line 323, in extract
    r = np.array([call_func(cell) for cell in coord.cells()])
  File ".../iris/_constraints.py", line 323, in <listcomp>
    r = np.array([call_func(cell) for cell in coord.cells()])
  File ".../iris/_constraints.py", line 306, in call_func
    return c == self._coord_thing
  File ".../iris/coords.py", line 1359, in __eq__
    return self.contains_point(other)
  File ".../iris/coords.py", line 1533, in contains_point
    raise TypeError(
TypeError: Cannot determine whether a point lies within a bounded region for datetime-like objects.
>>> 

The key problem is here in iris.coords.Cell.contains_point()
It seems this "blanket ban" was introduced by #1016 in response to #984
In catching any use of a datetime-like object, as something posessing a 'timetuple' property, it also includes PartialDateTime which also provide that property (for some compatibility reasons, not made entirely clear!).

@rcomer suggests that, when this was added, it was a key problem that 'netcdftime.datetime' objects provided a seriously "broken" comparison operation.

We think that this test+fail can now be removed, as the other time objects now provide reliable comparison operations.

The objects we now have to deal with in this code are datetime.datetime, cftime.datetime (and it's deprecated subclasses..), and a PartialDateTime.

notable:

  • PartialDateTime offers comparison on selected time/date fields, e.g. PDT(year=2000, month=3) <= X < PDT(year=2011, month=6)
  • all the datatime.datetime and cftime.datetime objects are now calendar-aware and refuse (correctly) to compare if calendars don't match
    • ... we think (needs full testing!)
@trexfeathers trexfeathers added the Good First Issue A good issue to take on if you're just getting started with Iris development label Mar 1, 2023
@pp-mo pp-mo moved this from 🆕 New to 📋 Backlog in 🦊 Iris v3.7.0 Jun 27, 2023
@pp-mo pp-mo moved this from 📋 Backlog to 🆕 New in 🦊 Iris v3.7.0 Jun 27, 2023
@acchamber acchamber moved this from 🆕 New - potential tasks to 🔖Assigned in 🦊 Iris v3.7.0 Jul 26, 2023
@acchamber acchamber self-assigned this Jul 26, 2023
@pp-mo
Copy link
Member Author

pp-mo commented Jul 28, 2023

See #5396

@pp-mo pp-mo moved this from 🔖Assigned to 👀 In review in 🦊 Iris v3.7.0 Jul 28, 2023
@pp-mo pp-mo assigned trexfeathers and unassigned stephenworsley Jul 28, 2023
@github-project-automation github-project-automation bot moved this from 👀 In review to 🏁 Done in 🦊 Iris v3.7.0 Jul 31, 2023
@scitools-ci scitools-ci bot removed this from 🚴 Peloton Aug 2, 2023
@scitools-ci scitools-ci bot removed this from 🚴 Peloton Aug 9, 2023
@scitools-ci scitools-ci bot removed this from 🚴 Peloton Aug 16, 2023
@scitools-ci scitools-ci bot removed this from 🚴 Peloton Aug 23, 2023
@scitools-ci scitools-ci bot removed this from 🚴 Peloton Aug 30, 2023
@scitools-ci scitools-ci bot removed this from 🚴 Peloton Sep 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Good First Issue A good issue to take on if you're just getting started with Iris development
Projects
No open projects
Status: 🏁 Done
Development

Successfully merging a pull request may close this issue.

4 participants