From 41962e308766da74d6bd1a29fd7db871e9a02333 Mon Sep 17 00:00:00 2001 From: Lukas Pilz Date: Thu, 27 Jan 2022 16:40:25 +0100 Subject: [PATCH 1/5] Retaining global attrs on MetPyDatasetAccessor.quantify() now --- src/metpy/xarray.py | 4 ++-- tests/test_xarray.py | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/metpy/xarray.py b/src/metpy/xarray.py index a055618a21a..27956c80256 100644 --- a/src/metpy/xarray.py +++ b/src/metpy/xarray.py @@ -1000,11 +1000,11 @@ def quantify(self): by this operation. Do not utilize on moderate- to large-sized remote datasets before subsetting! """ - return self._dataset.map(lambda da: da.metpy.quantify()) + return self._dataset.map(lambda da: da.metpy.quantify(), keep_attrs=True) def dequantify(self): """Return new dataset with variables cast to magnitude and units on attribute.""" - return self._dataset.map(lambda da: da.metpy.dequantify()) + return self._dataset.map(lambda da: da.metpy.dequantify(), keep_attrs=True) def _assign_axis(attributes, axis): diff --git a/tests/test_xarray.py b/tests/test_xarray.py index a8dfe5e3f8e..7be47a1c155 100644 --- a/tests/test_xarray.py +++ b/tests/test_xarray.py @@ -191,6 +191,7 @@ def test_dataset_quantify(test_ds_generic): result['test'].data, units.Quantity(test_ds_generic['test'].data) ) + assert result.attrs == test_ds_generic.attrs def test_dataset_dequantify(): @@ -198,11 +199,12 @@ def test_dataset_dequantify(): original = xr.Dataset({ 'test': ('x', units.Quantity([280, 290, 300], 'K')), 'x': np.arange(3) - }) + }, attrs={'test': 'test'}) result = original.metpy.dequantify() assert isinstance(result['test'].data, np.ndarray) assert result['test'].attrs['units'] == 'kelvin' np.testing.assert_array_almost_equal(result['test'].data, original['test'].data.magnitude) + assert result.attrs == original.attrs def test_radian_projection_coords(): From b9ba83231af6f0ae670aa4a67bdafdcad706c8d2 Mon Sep 17 00:00:00 2001 From: Lukas Pilz Date: Thu, 27 Jan 2022 21:51:34 +0100 Subject: [PATCH 2/5] Fixed failing tests --- tests/test_xarray.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_xarray.py b/tests/test_xarray.py index 7be47a1c155..8d0a94dcf91 100644 --- a/tests/test_xarray.py +++ b/tests/test_xarray.py @@ -199,7 +199,7 @@ def test_dataset_dequantify(): original = xr.Dataset({ 'test': ('x', units.Quantity([280, 290, 300], 'K')), 'x': np.arange(3) - }, attrs={'test': 'test'}) + }, attrs={'test_': 'test'}) result = original.metpy.dequantify() assert isinstance(result['test'].data, np.ndarray) assert result['test'].attrs['units'] == 'kelvin' From d79fdf02451f915875199f816e990ab60e584e1a Mon Sep 17 00:00:00 2001 From: Lukas Pilz Date: Thu, 27 Jan 2022 22:36:30 +0100 Subject: [PATCH 3/5] Fixed failing tests and extended test coverage I found the culprit - it's the keep_attrs kwarg. For some reason the kwarg does not only keep the dataset's attributes (like insinuated in the documentation) but also the dataarrays' attributes. This does not work for us, as we explicitly want to change the dataarrays' attributes (quantify removes 'units' attr and dequantify adds it). I also extended the test coverage to include an actual unit in the test_ds_generic. Otherwise (in the dimensionless case), tests/test_xarray.py:189 will never fail. --- src/metpy/xarray.py | 10 ++++++++-- tests/test_xarray.py | 8 ++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/metpy/xarray.py b/src/metpy/xarray.py index 27956c80256..1b46039753d 100644 --- a/src/metpy/xarray.py +++ b/src/metpy/xarray.py @@ -1000,11 +1000,17 @@ def quantify(self): by this operation. Do not utilize on moderate- to large-sized remote datasets before subsetting! """ - return self._dataset.map(lambda da: da.metpy.quantify(), keep_attrs=True) + _attr_save = self._dataset.attrs.copy() + dataset = self._dataset.map(lambda da: da.metpy.quantify()) + dataset.attrs = _attr_save + return dataset def dequantify(self): """Return new dataset with variables cast to magnitude and units on attribute.""" - return self._dataset.map(lambda da: da.metpy.dequantify(), keep_attrs=True) + _attr_save = self._dataset.attrs.copy() + dataset = self._dataset.map(lambda da: da.metpy.dequantify()) + dataset.attrs = _attr_save + return dataset def _assign_axis(attributes, axis): diff --git a/tests/test_xarray.py b/tests/test_xarray.py index 8d0a94dcf91..ca5522df6db 100644 --- a/tests/test_xarray.py +++ b/tests/test_xarray.py @@ -35,7 +35,7 @@ def test_ds_generic(): 'c': xr.DataArray(np.arange(3), dims='c'), 'd': xr.DataArray(np.arange(5), dims='d'), 'e': xr.DataArray(np.arange(5), dims='e') - }, dims=['a', 'b', 'c', 'd', 'e'], name='test').to_dataset() + }, dims=['a', 'b', 'c', 'd', 'e'], attrs={'units': 'kelvin'}, name='test').to_dataset() @pytest.fixture @@ -165,7 +165,7 @@ def test_quantify(test_ds_generic): original = test_ds_generic['test'].values result = test_ds_generic['test'].metpy.quantify() assert isinstance(result.data, units.Quantity) - assert result.data.units == units.dimensionless + assert result.data.units == units.kelvin assert 'units' not in result.attrs np.testing.assert_array_almost_equal(result.data, units.Quantity(original)) @@ -185,7 +185,7 @@ def test_dataset_quantify(test_ds_generic): """Test quantify method for converting data to Quantity on Datasets.""" result = test_ds_generic.metpy.quantify() assert isinstance(result['test'].data, units.Quantity) - assert result['test'].data.units == units.dimensionless + assert result['test'].data.units == units.kelvin assert 'units' not in result['test'].attrs np.testing.assert_array_almost_equal( result['test'].data, @@ -199,7 +199,7 @@ def test_dataset_dequantify(): original = xr.Dataset({ 'test': ('x', units.Quantity([280, 290, 300], 'K')), 'x': np.arange(3) - }, attrs={'test_': 'test'}) + }, attrs={'test': 'test'}) result = original.metpy.dequantify() assert isinstance(result['test'].data, np.ndarray) assert result['test'].attrs['units'] == 'kelvin' From ce75e1a28f61865a3edc717fbc08fb74898d0ff6 Mon Sep 17 00:00:00 2001 From: Lukas Pilz Date: Mon, 31 Jan 2022 17:17:58 +0100 Subject: [PATCH 4/5] Better attribute assignment --- src/metpy/xarray.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/metpy/xarray.py b/src/metpy/xarray.py index 1b46039753d..82955899f93 100644 --- a/src/metpy/xarray.py +++ b/src/metpy/xarray.py @@ -1000,17 +1000,11 @@ def quantify(self): by this operation. Do not utilize on moderate- to large-sized remote datasets before subsetting! """ - _attr_save = self._dataset.attrs.copy() - dataset = self._dataset.map(lambda da: da.metpy.quantify()) - dataset.attrs = _attr_save - return dataset + return self._dataset.map(lambda da: da.metpy.quantify()).assign_attrs(self._dataset.attrs) def dequantify(self): """Return new dataset with variables cast to magnitude and units on attribute.""" - _attr_save = self._dataset.attrs.copy() - dataset = self._dataset.map(lambda da: da.metpy.dequantify()) - dataset.attrs = _attr_save - return dataset + return self._dataset.map(lambda da: da.metpy.dequantify()).assign_attrs(self._dataset.attrs) def _assign_axis(attributes, axis): From 1046fa2f235188c3246f694b0b8571258d399ca8 Mon Sep 17 00:00:00 2001 From: Lukas Pilz Date: Mon, 31 Jan 2022 17:27:16 +0100 Subject: [PATCH 5/5] Fixed flake8 complaint --- src/metpy/xarray.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/metpy/xarray.py b/src/metpy/xarray.py index 82955899f93..5abef048515 100644 --- a/src/metpy/xarray.py +++ b/src/metpy/xarray.py @@ -1000,11 +1000,15 @@ def quantify(self): by this operation. Do not utilize on moderate- to large-sized remote datasets before subsetting! """ - return self._dataset.map(lambda da: da.metpy.quantify()).assign_attrs(self._dataset.attrs) + return self._dataset.map(lambda da: da.metpy.quantify()).assign_attrs( + self._dataset.attrs + ) def dequantify(self): """Return new dataset with variables cast to magnitude and units on attribute.""" - return self._dataset.map(lambda da: da.metpy.dequantify()).assign_attrs(self._dataset.attrs) + return self._dataset.map(lambda da: da.metpy.dequantify()).assign_attrs( + self._dataset.attrs + ) def _assign_axis(attributes, axis):