Skip to content

Commit 503db4a

Browse files
committed
Use Kai's offset and scale_factor logic for all encoding
1 parent 452968c commit 503db4a

File tree

2 files changed

+27
-12
lines changed

2 files changed

+27
-12
lines changed

xarray/coding/times.py

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1401,18 +1401,6 @@ def encode(self, variable: Variable, name: T_Name = None) -> Variable:
14011401
if "units" in encoding and not has_timedelta64_encoding_dtype(encoding):
14021402
dtype = encoding.pop("dtype", None)
14031403
units = encoding.pop("units", None)
1404-
1405-
# in the case of packed data we need to encode into
1406-
# float first, the correct dtype will be established
1407-
# via CFScaleOffsetCoder/CFMaskCoder
1408-
set_dtype_encoding = None
1409-
if "add_offset" in encoding or "scale_factor" in encoding:
1410-
set_dtype_encoding = dtype
1411-
dtype = data.dtype if data.dtype.kind == "f" else "float64"
1412-
1413-
# retain dtype for packed data
1414-
if set_dtype_encoding is not None:
1415-
safe_setitem(encoding, "dtype", set_dtype_encoding, name=name)
14161404
else:
14171405
resolution, _ = np.datetime_data(variable.dtype)
14181406
dtype = np.int64
@@ -1422,6 +1410,19 @@ def encode(self, variable: Variable, name: T_Name = None) -> Variable:
14221410
# Remove dtype encoding if it exists to prevent it from
14231411
# interfering downstream in NonStringCoder.
14241412
encoding.pop("dtype", None)
1413+
1414+
# in the case of packed data we need to encode into
1415+
# float first, the correct dtype will be established
1416+
# via CFScaleOffsetCoder/CFMaskCoder
1417+
set_dtype_encoding = None
1418+
if "add_offset" in encoding or "scale_factor" in encoding:
1419+
set_dtype_encoding = dtype
1420+
dtype = data.dtype if data.dtype.kind == "f" else "float64"
1421+
1422+
# retain dtype for packed data
1423+
if set_dtype_encoding is not None:
1424+
safe_setitem(encoding, "dtype", set_dtype_encoding, name=name)
1425+
14251426
data, units = encode_cf_timedelta(data, units, dtype)
14261427
safe_setitem(attrs, "units", units, name=name)
14271428
return Variable(dims, data, attrs, encoding, fastpath=True)

xarray/tests/test_coding_times.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2004,3 +2004,17 @@ def test_literal_timedelta_encode_invalid_attribute(attribute) -> None:
20042004
variable = Variable(["time"], timedeltas, attrs=attrs)
20052005
with pytest.raises(ValueError, match="failed to prevent"):
20062006
conventions.encode_cf_variable(variable)
2007+
2008+
2009+
def test_literal_timedelta_coding_mask_and_scale() -> None:
2010+
attrs = {
2011+
"units": "nanoseconds",
2012+
"dtype": "timedelta64[ns]",
2013+
"_FillValue": np.int16(-1),
2014+
"add_offset": 100000.0,
2015+
}
2016+
encoded = Variable(["time"], np.array([0, -1, 1], "int16"), attrs=attrs)
2017+
decoded = conventions.decode_cf_variable("foo", encoded)
2018+
result = conventions.encode_cf_variable(decoded, name="foo")
2019+
assert_identical(encoded, result)
2020+
assert encoded.dtype == result.dtype

0 commit comments

Comments
 (0)