From 83de8e96cdcc13074ed35f0108cec34cd2717c62 Mon Sep 17 00:00:00 2001 From: Keewis Date: Tue, 1 Sep 2020 00:14:59 +0200 Subject: [PATCH 01/11] return None if the wrapped data is not a quantity --- pint_xarray/accessors.py | 2 +- pint_xarray/tests/test_accessors.py | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/pint_xarray/accessors.py b/pint_xarray/accessors.py index 303aae14..b1f97afa 100644 --- a/pint_xarray/accessors.py +++ b/pint_xarray/accessors.py @@ -244,7 +244,7 @@ def magnitude(self): @property def units(self): - return self.da.data.units + return getattr(self.da.data, "units", None) @units.setter def units(self, units): diff --git a/pint_xarray/tests/test_accessors.py b/pint_xarray/tests/test_accessors.py index 8867af8a..3003ba43 100644 --- a/pint_xarray/tests/test_accessors.py +++ b/pint_xarray/tests/test_accessors.py @@ -123,6 +123,17 @@ def test_roundtrip_data(self, example_unitless_da): assert_equal(result, orig) +class TestPropertiesDataArray: + def test_units_getattr(self, example_quantity_da): + da = example_quantity_da + assert isinstance(da.pint.units, Unit) + assert da.pint.units == unit_registry.m + + def test_unit_getattr_unitless(self, example_unitless_da): + da = example_unitless_da + assert da.pint.units is None + + @pytest.fixture() def example_unitless_ds(): users = np.linspace(0, 10, 20) From 91b7262a9328a77d9d33e3bf7d2dd018b45fd51b Mon Sep 17 00:00:00 2001 From: Keewis Date: Tue, 1 Sep 2020 00:16:40 +0200 Subject: [PATCH 02/11] fix the units setattr --- pint_xarray/accessors.py | 6 ++---- pint_xarray/tests/test_accessors.py | 10 ++++++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/pint_xarray/accessors.py b/pint_xarray/accessors.py index b1f97afa..5b13f282 100644 --- a/pint_xarray/accessors.py +++ b/pint_xarray/accessors.py @@ -4,7 +4,7 @@ import pint from pint.quantity import Quantity from pint.unit import Unit -from xarray import DataArray, register_dataarray_accessor, register_dataset_accessor +from xarray import register_dataarray_accessor, register_dataset_accessor from xarray.core.npcompat import IS_NEP18_ACTIVE from . import conversion @@ -249,9 +249,7 @@ def units(self): @units.setter def units(self, units): quantity = conversion.array_attach_units(self.da.data, units) - self.da = DataArray( - dim=self.da.dims, data=quantity, coords=self.da.coords, attrs=self.da.attrs - ) + self.da.data = quantity @property def dimensionality(self): diff --git a/pint_xarray/tests/test_accessors.py b/pint_xarray/tests/test_accessors.py index 3003ba43..55ef3615 100644 --- a/pint_xarray/tests/test_accessors.py +++ b/pint_xarray/tests/test_accessors.py @@ -129,10 +129,20 @@ def test_units_getattr(self, example_quantity_da): assert isinstance(da.pint.units, Unit) assert da.pint.units == unit_registry.m + def test_units_setattr(self, example_quantity_da): + da = example_quantity_da + with pytest.raises(ValueError): + da.pint.units = "s" + def test_unit_getattr_unitless(self, example_unitless_da): da = example_unitless_da assert da.pint.units is None + def test_unit_setattr_unitless(self, example_unitless_da): + da = example_unitless_da + da.pint.units = unit_registry.s + assert da.pint.units == unit_registry.s + @pytest.fixture() def example_unitless_ds(): From 3ba112ed2647555c2727659a7b6ba5f60ff21e19 Mon Sep 17 00:00:00 2001 From: Keewis Date: Tue, 1 Sep 2020 00:26:59 +0200 Subject: [PATCH 03/11] add docstrings to the units and dimensionality properties --- pint_xarray/accessors.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/pint_xarray/accessors.py b/pint_xarray/accessors.py index 5b13f282..71b46ee9 100644 --- a/pint_xarray/accessors.py +++ b/pint_xarray/accessors.py @@ -244,15 +244,39 @@ def magnitude(self): @property def units(self): + """get the units of the wrapped data + + Returns + ------- + units : pint.Unit or None + the units of the wrapped data. If it is not a quantity, the units + are :py:obj:`None`. + """ return getattr(self.da.data, "units", None) @units.setter def units(self, units): + """set the units of the wrapped data in-place + + Raises + ------ + ValueError + If the data already is a quantity, or the units are not a + :py:class:`pint.Unit` instance. + """ quantity = conversion.array_attach_units(self.da.data, units) self.da.data = quantity @property def dimensionality(self): + """get the dimensionality of the data + + Returns + ------- + dimensionality : str or None + The dimensionality of the data. If it is not a quantity, the + dimensionality is :py:obj:`None`. + """ return self.da.data.dimensionality @property From 84932703c2494cb5309b431874e579ed0d7ab913 Mon Sep 17 00:00:00 2001 From: Keewis Date: Tue, 1 Sep 2020 00:27:29 +0200 Subject: [PATCH 04/11] return a dimensionality of None for non-quantities --- pint_xarray/accessors.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pint_xarray/accessors.py b/pint_xarray/accessors.py index 71b46ee9..cce29619 100644 --- a/pint_xarray/accessors.py +++ b/pint_xarray/accessors.py @@ -277,7 +277,7 @@ def dimensionality(self): The dimensionality of the data. If it is not a quantity, the dimensionality is :py:obj:`None`. """ - return self.da.data.dimensionality + return getattr(self.da.data, "dimensionality", None) @property def registry(self): From 7ace89aa6779842f9b1fbd7c6a337f6f14f9e16b Mon Sep 17 00:00:00 2001 From: Keewis Date: Tue, 1 Sep 2020 00:39:55 +0200 Subject: [PATCH 05/11] fix the magnitude property --- pint_xarray/accessors.py | 7 ++++++- pint_xarray/tests/test_accessors.py | 14 ++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/pint_xarray/accessors.py b/pint_xarray/accessors.py index cce29619..1bde4168 100644 --- a/pint_xarray/accessors.py +++ b/pint_xarray/accessors.py @@ -240,7 +240,12 @@ def dequantify(self): @property def magnitude(self): - return self.da.data.magnitude + """get the magnitude of the wrapped data + + If not a quantity, will return the data itself. + """ + data = self.da.data + return getattr(data, "magnitude", data) @property def units(self): diff --git a/pint_xarray/tests/test_accessors.py b/pint_xarray/tests/test_accessors.py index 55ef3615..4a41a04a 100644 --- a/pint_xarray/tests/test_accessors.py +++ b/pint_xarray/tests/test_accessors.py @@ -124,10 +124,20 @@ def test_roundtrip_data(self, example_unitless_da): class TestPropertiesDataArray: + def test_magnitude_getattr(self, example_quantity_da): + da = example_quantity_da + actual = da.pint.magnitude + assert not isinstance(actual, Quantity) + + def test_magnitude_getattr_unitless(self, example_unitless_da): + da = example_unitless_da + xr.testing.assert_duckarray_equal(da.pint.magnitude, da.data) + def test_units_getattr(self, example_quantity_da): da = example_quantity_da - assert isinstance(da.pint.units, Unit) - assert da.pint.units == unit_registry.m + actual = da.pint.units + assert isinstance(actual, Unit) + assert actual == unit_registry.m def test_units_setattr(self, example_quantity_da): da = example_quantity_da From 79a1b082c9b43d985a1c74d4362cee914e68aa8c Mon Sep 17 00:00:00 2001 From: Keewis Date: Tue, 1 Sep 2020 00:41:32 +0200 Subject: [PATCH 06/11] update whats-new.rst --- docs/whats-new.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/whats-new.rst b/docs/whats-new.rst index 4863d6a6..8c219a08 100644 --- a/docs/whats-new.rst +++ b/docs/whats-new.rst @@ -9,4 +9,7 @@ What's new - rewrite :py:meth:`DataArray.pint.quantify`, :py:meth:`Dataset.pint.quantify`, :py:meth:`DataArray.pint.dequantify` and :py:meth:`Dataset.pint.dequantify` (:pull:`17`) -- expose :py:func:`pint_xarray.testing.assert_units_equal` as public API (:pull:`24`) \ No newline at end of file +- expose :py:func:`pint_xarray.testing.assert_units_equal` as public API (:pull:`24`) +- fix the :py:attr:`DataArray.pint.units`, :py:attr:`DataArray.pint.magnitude` + and :py:attr:`DataArray.pint.dimensionality` properties and add docstrings for + all three. (:pull:`31`) From 7dc0fed8240cae698537fa92087e61b5b322c4f7 Mon Sep 17 00:00:00 2001 From: Keewis Date: Fri, 4 Sep 2020 14:42:17 +0200 Subject: [PATCH 07/11] shorten the property docstrings --- pint_xarray/accessors.py | 31 +++---------------------------- 1 file changed, 3 insertions(+), 28 deletions(-) diff --git a/pint_xarray/accessors.py b/pint_xarray/accessors.py index 3086d526..681b4914 100644 --- a/pint_xarray/accessors.py +++ b/pint_xarray/accessors.py @@ -230,48 +230,23 @@ def dequantify(self): @property def magnitude(self): - """get the magnitude of the wrapped data - - If not a quantity, will return the data itself. - """ + """the magnitude of the data or the data itself if not a quantity.""" data = self.da.data return getattr(data, "magnitude", data) @property def units(self): - """get the units of the wrapped data - - Returns - ------- - units : pint.Unit or None - the units of the wrapped data. If it is not a quantity, the units - are :py:obj:`None`. - """ + """the units of the data or :py:obj:`None` if not a quantity.""" return getattr(self.da.data, "units", None) @units.setter def units(self, units): - """set the units of the wrapped data in-place - - Raises - ------ - ValueError - If the data already is a quantity, or the units are not a - :py:class:`pint.Unit` instance. - """ quantity = conversion.array_attach_units(self.da.data, units) self.da.data = quantity @property def dimensionality(self): - """get the dimensionality of the data - - Returns - ------- - dimensionality : str or None - The dimensionality of the data. If it is not a quantity, the - dimensionality is :py:obj:`None`. - """ + """get the dimensionality of the data or :py:obj:`None` if not a quantity.""" return getattr(self.da.data, "dimensionality", None) @property From db1b8c8cc2a12704bb170db0821816617e3ae5e1 Mon Sep 17 00:00:00 2001 From: Keewis Date: Fri, 4 Sep 2020 14:50:07 +0200 Subject: [PATCH 08/11] fix the name of the unitless tests --- pint_xarray/tests/test_accessors.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pint_xarray/tests/test_accessors.py b/pint_xarray/tests/test_accessors.py index 4a41a04a..685b0e34 100644 --- a/pint_xarray/tests/test_accessors.py +++ b/pint_xarray/tests/test_accessors.py @@ -144,11 +144,11 @@ def test_units_setattr(self, example_quantity_da): with pytest.raises(ValueError): da.pint.units = "s" - def test_unit_getattr_unitless(self, example_unitless_da): + def test_units_getattr_unitless(self, example_unitless_da): da = example_unitless_da assert da.pint.units is None - def test_unit_setattr_unitless(self, example_unitless_da): + def test_units_setattr_unitless(self, example_unitless_da): da = example_unitless_da da.pint.units = unit_registry.s assert da.pint.units == unit_registry.s From 8af972494cac6d24e0758a83ce9454ef13ee54da Mon Sep 17 00:00:00 2001 From: Keewis Date: Fri, 4 Sep 2020 14:51:51 +0200 Subject: [PATCH 09/11] mention that units can only be set if the data is not a quantity --- pint_xarray/accessors.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pint_xarray/accessors.py b/pint_xarray/accessors.py index 681b4914..8b13f753 100644 --- a/pint_xarray/accessors.py +++ b/pint_xarray/accessors.py @@ -236,7 +236,10 @@ def magnitude(self): @property def units(self): - """the units of the data or :py:obj:`None` if not a quantity.""" + """the units of the data or :py:obj:`None` if not a quantity. + + The units can only be set if the data is not already a quantity. + """ return getattr(self.da.data, "units", None) @units.setter From 6bdfd00b78347e935a17275291c169b914eae659 Mon Sep 17 00:00:00 2001 From: Keewis Date: Fri, 4 Sep 2020 16:52:18 +0200 Subject: [PATCH 10/11] reword the docstring dealing with setting the units --- pint_xarray/accessors.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pint_xarray/accessors.py b/pint_xarray/accessors.py index 8b13f753..8a6dfc6f 100644 --- a/pint_xarray/accessors.py +++ b/pint_xarray/accessors.py @@ -238,7 +238,7 @@ def magnitude(self): def units(self): """the units of the data or :py:obj:`None` if not a quantity. - The units can only be set if the data is not already a quantity. + Setting the units is possible, but only if the data is not already a quantity. """ return getattr(self.da.data, "units", None) From ae0ce7f254bab2d62f760f20b56badffc8b33f91 Mon Sep 17 00:00:00 2001 From: Keewis Date: Sat, 12 Sep 2020 13:04:46 +0200 Subject: [PATCH 11/11] don't assign a name to the constructed quantity --- pint_xarray/accessors.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pint_xarray/accessors.py b/pint_xarray/accessors.py index 8a6dfc6f..fa97aac7 100644 --- a/pint_xarray/accessors.py +++ b/pint_xarray/accessors.py @@ -244,8 +244,7 @@ def units(self): @units.setter def units(self, units): - quantity = conversion.array_attach_units(self.da.data, units) - self.da.data = quantity + self.da.data = conversion.array_attach_units(self.da.data, units) @property def dimensionality(self):