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

Printing time coordinates with long time intervals #3098

Closed
DPeterK opened this issue Jul 30, 2018 · 10 comments · Fixed by #3140
Closed

Printing time coordinates with long time intervals #3098

DPeterK opened this issue Jul 30, 2018 · 10 comments · Fixed by #3140

Comments

@DPeterK
Copy link
Member

DPeterK commented Jul 30, 2018

If you print a coordinate with a long time unit interval (one of months or years), the time coordinate points are not rendered as datetimes. This is not the case for shorter time unit intervals. For example:

a = np.arange(0, 34, 3)

tc = iris.coords.DimCoord(a, standard_name='time',
                          units=cf_units.Unit('months since 1970-01-01', calendar='gregorian'))
print(tc)
DimCoord([ 0  3  6  9 12 15 18 21 24 27 30 33], standard_name='time', calendar='gregorian')

tc2 = iris.coords.DimCoord(a, standard_name='time',
                           units=cf_units.Unit('days since 1970-01-01', calendar='gregorian'))
print(tc2)
DimCoord([1970-01-01 00:00:00, 1970-01-04 00:00:00, 1970-01-07 00:00:00,
       1970-01-10 00:00:00, 1970-01-13 00:00:00, 1970-01-16 00:00:00,
       1970-01-19 00:00:00, 1970-01-22 00:00:00, 1970-01-25 00:00:00,
       1970-01-28 00:00:00, 1970-01-31 00:00:00, 1970-02-03 00:00:00], standard_name='time', calendar='gregorian')

Follows on from #2354. Thanks to @PAGWatson for originally bringing this to our attention there.

@DPeterK
Copy link
Member Author

DPeterK commented Jul 30, 2018

@PAGWatson is this the same as what you've seen?

@PAGWatson
Copy link

Thanks for following up on this. This is not quite the issue I had. I found that for a cube with a time coord with units in months, I got the following error message when I tried to print the coordinate: "ValueError: Time units with interval of "months", "years" (or singular of these) cannot be processed, got 'months'." This was in Iris 2.1.0.

@DPeterK
Copy link
Member Author

DPeterK commented Jul 30, 2018

@PAGWatson could you check the version of cf_units you're using? For reference, I'm using v1.2.0.

@PAGWatson
Copy link

Mine is 2.0.1

@DPeterK
Copy link
Member Author

DPeterK commented Jul 30, 2018

Interesting. Having upgraded cf_units I still can't reproduce your specific error. Would you mind printing the entire stacktrace here? That might shed some more light on what's going on.

@PAGWatson
Copy link

Sure, here it is:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-355-78dfe530799d> in <module>()
----> 1 print cube.coord('time')[0]

/network/home/aopp/watson/anaconda2/envs/main/lib/python2.7/site-packages/iris/coords.pyc in __str__(self)
    742             bounds = ''
    743             if self.has_bounds():
--> 744                 bounds = ', bounds=' + self._str_dates(self.bounds)
    745             result = fmt.format(self=self, cls=type(self).__name__,
    746                                 points=points, bounds=bounds,

/network/home/aopp/watson/anaconda2/envs/main/lib/python2.7/site-packages/iris/coords.pyc in _str_dates(self, dates_as_numbers)
    722 
    723     def _str_dates(self, dates_as_numbers):
--> 724         date_obj_array = self.units.num2date(dates_as_numbers)
    725         kwargs = {'separator': ', ', 'prefix': '      '}
    726         return np.core.arrayprint.array2string(date_obj_array,

/network/home/aopp/watson/anaconda2/envs/main/lib/python2.7/site-packages/cf_units/__init__.pyc in num2date(self, time_value)
   1986 
   1987         """
-> 1988         cdf_utime = self.utime()
   1989         return _num2date_to_nearest_second(time_value, cdf_utime)

/network/home/aopp/watson/anaconda2/envs/main/lib/python2.7/site-packages/cf_units/__init__.pyc in utime(self)
   1900             emsg = ('Time units with interval of "months", "years" '
   1901                     '(or singular of these) cannot be processed, got {!r}.')
-> 1902             raise ValueError(emsg.format(interval))
   1903 
   1904         #

ValueError: Time units with interval of "months", "years" (or singular of these) cannot be processed, got 'months'.

If I just type "cube.coord('time')[0]" rather than "print cube.coord('time')[0]" at the command prompt, I get the following, in case that's any help:

DimCoord(array([1800.5]), bounds=array([[1800., 1801.]]), standard_name=u'time', units=Unit('months since 1850-01-01 00:00', calendar='gregorian'), long_name=u'time', var_name='time', attributes={'realtopology': 'linear'})

@DPeterK
Copy link
Member Author

DPeterK commented Aug 14, 2018

@PAGWatson I think I've figured it out (with help from the stacktrace you provided - thanks!). The error is occurring when the time coordinate has bounds, and that gives us something to target a fix for.

Edit: really, we should have handled bounds equivalently to points way back in #2354. We didn't, so it must be time to correct that. PR incoming.

@DPeterK
Copy link
Member Author

DPeterK commented Aug 14, 2018

For what it's worth, the origin of this issue is in cftime itself, which doesn't handle months or years. This might be because the cf conventions recommend against using these units.

@PAGWatson
Copy link

Thanks for following up @dkillick. I guess if there's not an accepted way to handle converting times with units months or years to dates, then it might make sense to just leave the values as numbers, so at least an error isn't thrown? We can't always help the units used in files we get from other sources, of course.

@DPeterK
Copy link
Member Author

DPeterK commented Aug 14, 2018

it might make sense to just leave the values as numbers

@PAGWatson yup, that's my intention, at least as an interim solution 👍 There is probably a better, more robust solution that can be implemented long-term (perhaps even in cftime), but as a starting point we (a) don't get errors, and (b) get consistent behaviours between time points and bounds.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants