Converting time units

1,702 views
Skip to first unread message

Chris Roberts

unread,
Nov 25, 2013, 9:30:43 AM11/25/13
to scitoo...@googlegroups.com
Hi all,

Does anyone know how to convert the time coordinate of a cube to a different base unit (e.g. days since X -> hours since X)?

Thanks,
Chris
 

Andrew Dawson

unread,
Nov 25, 2013, 9:53:36 AM11/25/13
to scitoo...@googlegroups.com
Sure. Here's an example to demonstrate. First we'll create a time dimension coordinate:

time_coord = iris.coords.DimCoord([[0, 31, 59], standard_name='time', units=iris.unit.Unit('days since 2013-01-01 00:00:0.0', calendar='gregorian'))
print time_coord.points
print time_coord.units
print time_coord

which prints:

[ 0 31 59]
days since 2013-01-01 00:00:0.0
DimCoord([datetime.datetime(2013, 1, 1, 0, 0),
          datetime
.datetime(2013, 2, 1, 0, 0),
          datetime
.datetime(2013, 3, 1, 0, 0)], standard_name='time', calendar='gregorian')

Now we can change the units of the time coordinate:

time_coord.convert_units('hours since 2000-01-01 00:00:0.0')
print time_coord.points
print time_coord.units
print time_coord

which now prints:

[ 113976.  114720.  115392.]
hours since 2000-01-01 00:00:0.0
DimCoord([datetime.datetime(2013, 1, 1, 0, 0),
          datetime
.datetime(2013, 2, 1, 0, 0),
          datetime
.datetime(2013, 3, 1, 0, 0)], standard_name='time', calendar='gregorian')

So you can see the units have changed, and hence the values stored in the coordinate, but the date/time these refer to is unchanged. To apply this to a cube you would need to convert the units of its time dimension:

time_coord = cube.coord('time')   # use the name of your time coordinate
time_coord
.convert_units('hours since ...')   # use the reference time you want

Hope that helps.

Chris Roberts

unread,
Nov 26, 2013, 9:52:30 AM11/26/13
to scitoo...@googlegroups.com
Hi Andrew,

Unfortunately this method does not work for the CMIP5 model data I am using. Here is an example of the error I am receiving for HadGEM2-ES:

>>> tcoord = cube.coord('time')
>>> tcoord    
AuxCoord(array([  1.50000000e+01,   4.50000000e+01,   7.50000000e+01, ...,
         
2.07285000e+05,   2.07315000e+05,   2.07345000e+05]), bounds=array([[  0.00000000e+00,   3.00000000e+01],
       
[  3.00000000e+01,   6.00000000e+01],
       
[  6.00000000e+01,   9.00000000e+01],
       
...,
       
[  2.07270000e+05,   2.07300000e+05],
       
[  2.07300000e+05,   2.07330000e+05],
       
[  2.07330000e+05,   2.07360000e+05]]), standard_name=u'time', units=Unit('days since 1859-12-01', calendar='360_day'), long_name=u'time', var_name='time')

>>> tcoord.convert_units('days since 1859-12-01')
Traceback (most recent call last):
 
File "<stdin>", line 1, in <module>
 
File "/opt/ukmo/iris/default/linux64/site-packages/iris/coords.py", line 629, in convert_units
   
self.points = self.units.convert(self.points, unit)
 
File "/opt/ukmo/iris/default/linux64/site-packages/iris/unit.py", line 1824, in convert
   
(self, other))
ValueError: Unable to convert from 'days since 1859-12-01' to 'days since 1859-12-01'.


Does anyone have a work around for this? For example, would it be possible to delete the time coordinate and replace it with a new coordinate that had the correct units and same calendar?


Thanks in advance,
Chris

Andrew Dawson

unread,
Nov 26, 2013, 10:09:19 AM11/26/13
to scitoo...@googlegroups.com
Hi Chris

I see your problem and it should be simple enough to fix. My example assumed the use of the Gregorian calendar, which is the default for time units. I notice your data uses a 360 day calendar. The thing is when you do this:

tcoord.convert_units('days since 1859-12-01')

Iris will try and convert the string 'days since 1859-12-01' to an iris.unit.Unit object, and since you haven't told it anything about calendar it will assume a Gregorian calendar. When you try and convert the units from a 360 day to Gregorian calendar it will fail because those are not compatible. All you need to do is define your new unit in full including the calendar:

new_time_unit = iris.unit.Unit('days since 1859-12-01', calendar='360_day')
tcoord
.convert_units(new_time_unit)

This makes sure the units are compatible and the conversion should go ahead.

Chris Roberts

unread,
Nov 26, 2013, 10:26:46 AM11/26/13
to scitoo...@googlegroups.com
This worked!

Thanks,
Chris
Reply all
Reply to author
Forward
0 new messages