diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 42ab3cd..2cb8f2d 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,7 +1,18 @@ v1.2.2 ====== +Added +----- +* `psyplot.data.open_dataset` now decodes grid_mappings attributes, +see `#17 `__ + +Changed +------- * psyplot has been moved from https://github.com/Chilipp/psyplot to https://github.com/psyplot/psyplot, see `#16 `__ +* Specifying names in `x`, `y`, `t` and `z` attributes of the `CFDecoder` class + now means that any other attribute (such as the `coordinates` or `axis` attribute) + are ignored + v1.2.1 ====== diff --git a/psyplot/data.py b/psyplot/data.py index ee2d881..3e4f2c4 100755 --- a/psyplot/data.py +++ b/psyplot/data.py @@ -646,6 +646,8 @@ def add_attrs(obj): if 'coordinates' in obj.attrs: extra_coords.update(obj.attrs['coordinates'].split()) obj.encoding['coordinates'] = obj.attrs.pop('coordinates') + if 'grid_mapping' in obj.attrs: + extra_coords.add(obj.attrs['grid_mapping']) if 'bounds' in obj.attrs: extra_coords.add(obj.attrs['bounds']) if gridfile is not None and not isinstance(gridfile, xr.Dataset): @@ -915,16 +917,26 @@ def get_variable_by_axis(self, var, axis, coords=None): if not coord_names: return ret = [] + matched = [] for coord in map(lambda dim: coords[dim], filter( lambda dim: dim in coords, chain( coord_names, var.dims))): # check for the axis attribute or whether the coordinate is in the # list of possible coordinate names - if (coord.name not in (c.name for c in ret) and - (coord.attrs.get('axis', '').lower() == axis or - coord.name in getattr(self, axis))): - ret.append(coord) - if ret: + if coord.name not in (c.name for c in ret): + if coord.name in getattr(self, axis): + matched.append(coord) + elif coord.attrs.get('axis', '').lower() == axis: + ret.append(coord) + if matched: + if len(matched) > 1: + warn("Found multiple matches for %s coordinate in the " + "coordinates: %s. I use %s" % ( + axis, ', '.join([c.name for c in matched]), + matched[0].name), + PsyPlotRuntimeWarning) + return matched[0] + elif ret: return None if len(ret) > 1 else ret[0] # If the coordinates attribute is specified but the coordinate # variables themselves have no 'axis' attribute, we interpret the diff --git a/tests/test_data.py b/tests/test_data.py index 0e451fa..9caeebe 100755 --- a/tests/test_data.py +++ b/tests/test_data.py @@ -81,6 +81,15 @@ def assertAlmostArrayEqual(self, actual, desired, rtol=1e-07, atol=0, class DecoderTest(unittest.TestCase, AlmostArrayEqualMixin): """Test the :class:`psyplot.data.CFDecoder` class""" + def test_decode_grid_mapping(self): + ds = xr.Dataset() + ds['var'] = (('x', 'y'), np.zeros((5, 4)), {'grid_mapping': 'crs'}) + ds['crs'] = ((), 1) + + self.assertNotIn('crs', ds.coords) + ds = psyd.CFDecoder.decode_coords(ds) + self.assertIn('crs', ds.coords) + def test_1D_cf_bounds(self): """Test whether the CF Conventions for 1D bounaries are correct""" final_bounds = np.arange(-180, 181, 30)