Skip to content

Commit 0cb1836

Browse files
committed
Encode/decode time information to cdms2
1 parent 10425da commit 0cb1836

File tree

2 files changed

+33
-23
lines changed

2 files changed

+33
-23
lines changed

xray/convert.py

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,26 @@
33
import numpy as np
44

55
from .core.dataarray import DataArray
6-
6+
from .conventions import (
7+
maybe_encode_timedelta, maybe_encode_datetime, decode_cf)
78

89
ignored_attrs = set(['name', 'tileIndex'])
910

1011

11-
def _get_cdms2_attrs(var):
12-
return dict((k, v) for k, v in var.attributes.items()
13-
if k not in ignored_attrs)
14-
15-
1612
def from_cdms2(variable):
1713
"""Convert a cdms2 variable into an DataArray
1814
"""
15+
def get_cdms2_attrs(var):
16+
return dict((k, v) for k, v in var.attributes.items()
17+
if k not in ignored_attrs)
18+
1919
values = np.asarray(variable)
2020
name = variable.id
21-
coords = [(v.id, np.asarray(v), _get_cdms2_attrs(v))
21+
coords = [(v.id, np.asarray(v), get_cdms2_attrs(v))
2222
for v in variable.getAxisList()]
23-
attrs = _get_cdms2_attrs(variable)
24-
return DataArray(values, coords=coords, name=name, attrs=attrs)
25-
26-
27-
def _set_cdms2_attrs(var, attrs):
28-
for k, v in attrs.items():
29-
setattr(var, k, v)
23+
attrs = get_cdms2_attrs(variable)
24+
dataarray = DataArray(values, coords=coords, name=name, attrs=attrs)
25+
return decode_cf(dataarray.to_dataset())[dataarray.name]
3026

3127

3228
def to_cdms2(dataarray):
@@ -35,13 +31,21 @@ def to_cdms2(dataarray):
3531
# we don't want cdms2 to be a hard dependency
3632
import cdms2
3733

34+
def encode(var):
35+
return maybe_encode_timedelta(maybe_encode_datetime(var))
36+
37+
def set_cdms2_attrs(var, attrs):
38+
for k, v in attrs.items():
39+
setattr(var, k, v)
40+
3841
axes = []
3942
for dim in dataarray.dims:
40-
coord = dataarray.coords[dim]
43+
coord = encode(dataarray.coords[dim])
4144
axis = cdms2.createAxis(coord.values, id=dim)
42-
_set_cdms2_attrs(axis, coord.attrs)
45+
set_cdms2_attrs(axis, coord.attrs)
4346
axes.append(axis)
4447

45-
var = cdms2.createVariable(dataarray.values, axes=axes, id=dataarray.name)
46-
_set_cdms2_attrs(var, dataarray.attrs)
47-
return var
48+
var = encode(dataarray)
49+
cdms2_var = cdms2.createVariable(var.values, axes=axes, id=dataarray.name)
50+
set_cdms2_attrs(cdms2_var, var.attrs)
51+
return cdms2_var

xray/test/test_dataarray.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,18 +1002,24 @@ def test_to_and_from_cdms2(self):
10021002
raise unittest.SkipTest('cdms2 not installed')
10031003

10041004
original = DataArray(np.arange(6).reshape(2, 3),
1005-
[('xxx', [-2, 2], {'units': 'meters'}),
1006-
('yyy', [3, 4, 5])],
1005+
[('distance', [-2, 2], {'units': 'meters'}),
1006+
('time', pd.date_range('2000-01-01', periods=3))],
10071007
name='foo', attrs={'baz': 123})
1008+
expected_coords = [Coordinate('distance', [-2, 2]),
1009+
Coordinate('time', [0, 1, 2])]
10081010
actual = original.to_cdms2()
10091011
self.assertArrayEqual(actual, original)
10101012
self.assertEqual(actual.id, original.name)
10111013
self.assertItemsEqual(actual.getAxisIds(), original.dims)
1012-
for axis, coord in zip(actual.getAxisList(), original.coords.values()):
1014+
for axis, coord in zip(actual.getAxisList(), expected_coords):
10131015
self.assertEqual(axis.id, coord.name)
1014-
self.assertArrayEqual(axis, coord)
1016+
self.assertArrayEqual(axis, coord.values)
10151017
self.assertEqual(actual.baz, original.attrs['baz'])
10161018

1019+
component_times = actual.getAxis(1).asComponentTime()
1020+
self.assertEqual(len(component_times), 3)
1021+
self.assertEqual(str(component_times[0]), '2000-1-1 0:0:0.0')
1022+
10171023
roundtripped = DataArray.from_cdms2(actual)
10181024
self.assertDataArrayIdentical(original, roundtripped)
10191025

0 commit comments

Comments
 (0)