Skip to content

Commit

Permalink
ENH: Make coordinate detection more robust (Fixes #3416)
Browse files Browse the repository at this point in the history
This works around an issue where some ERA5 data had lat/lon with a
"positive" attribute that, according to the CF specification, should
indicate a vertical coordinate. We can fix this up by making sure each
coordinate variable is only associated with a single option, and making
use of Python's key-ordered dictionaries to prioritize the matching
order. Having lat be y and lon be x is already handled by a later block.
  • Loading branch information
dopplershift committed Mar 14, 2024
1 parent 8f510ae commit 4c26973
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 4 deletions.
9 changes: 5 additions & 4 deletions src/metpy/xarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,15 +338,16 @@ def assign_coordinates(self, coordinates):
def _generate_coordinate_map(self):
"""Generate a coordinate map via CF conventions and other methods."""
coords = self._data_array.coords.values()
# Parse all the coordinates, attempting to identify x, longitude, y, latitude,
# vertical, time
coord_lists = {'time': [], 'vertical': [], 'y': [], 'latitude': [], 'x': [],
'longitude': []}
# Parse all the coordinates, attempting to identify longitude, latitude, x, y,
# time, vertical, in that order.
coord_lists = {'longitude': [], 'latitude': [], 'x': [], 'y': [], 'time': [],
'vertical': []}
for coord_var in coords:
# Identify the coordinate type using check_axis helper
for axis in coord_lists:
if check_axis(coord_var, axis):
coord_lists[axis].append(coord_var)
break # Ensure a coordinate variable only goes to one axis

# Fill in x/y with longitude/latitude if x/y not otherwise present
for geometric, graticule in (('y', 'latitude'), ('x', 'longitude')):
Expand Down
8 changes: 8 additions & 0 deletions tests/test_xarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,14 @@ def test_missing_grid_mapping_invalid(test_var_multidim_no_xy):
assert 'metpy_crs' not in data_var.coords


def test_xy_not_vertical(test_ds):
"""Test not detecting x/y as a vertical coordinate based on metadata."""
test_ds.x.attrs['positive'] = 'up'
test_ds.y.attrs['positive'] = 'up'
data_var = test_ds.metpy.parse_cf('Temperature')
assert data_var.metpy.vertical.identical(data_var.coords['isobaric'])


def test_missing_grid_mapping_var(caplog):
"""Test behavior when we can't find the variable pointed to by grid_mapping."""
x = xr.DataArray(np.arange(3),
Expand Down

0 comments on commit 4c26973

Please sign in to comment.