Skip to content

Commit

Permalink
Prioritise dim coord in _get_lon_lat_coords() (#5029)
Browse files Browse the repository at this point in the history
* Added in dim_coord prioritisation within _get_lon_lat_coords

* Completed testing for dim coord prioritisation, added what's new entry

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* updated tests to include fixtures

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Mostly formatting changes for readability, largely suggested by Payton for better PyTest consistency.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Replaced  with  throughout

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* updated docstring in project

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
ESadek-MO and pre-commit-ci[bot] authored Oct 27, 2022
1 parent d56824c commit b5178a9
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 8 deletions.
7 changes: 7 additions & 0 deletions docs/src/whatsnew/latest.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@ This document explains the changes made to Iris for this release
:class:`~iris.coords.AuxCoord`, which avoids some specific known usage problems.
(:issue:`4860`, :pull:`5020`)

#. `@Esadek-MO`_ and `@trexfeathers`_ added dim coord
prioritisation to ``_get_lon_lat_coords()`` in :mod:`iris.analysis.cartography`.
This allows :func:`iris.analysis.cartography.area_weights` and
:func:`~iris.analysis.cartography.project` to handle cubes which contain
both dim and aux coords of the same type e.g. ``longitude`` and ``grid_longitude``.
(:issue:`3916`, :pull:`5029`).


🐛 Bugs Fixed
=============
Expand Down
26 changes: 18 additions & 8 deletions lib/iris/analysis/cartography.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,20 +169,25 @@ def rotate_pole(lons, lats, pole_lon, pole_lat):


def _get_lon_lat_coords(cube):
lat_coords = [
coord for coord in cube.coords() if "latitude" in coord.name()
]
lon_coords = [
coord for coord in cube.coords() if "longitude" in coord.name()
]
def search_for_coord(coord_iterable, coord_name):
return [
coord for coord in coord_iterable if coord_name in coord.name()
]

lat_coords = search_for_coord(
cube.dim_coords, "latitude"
) or search_for_coord(cube.coords(), "latitude")
lon_coords = search_for_coord(
cube.dim_coords, "longitude"
) or search_for_coord(cube.coords(), "longitude")
if len(lat_coords) > 1 or len(lon_coords) > 1:
raise ValueError(
"Calling `_get_lon_lat_coords` with multiple lat or lon coords"
"Calling `_get_lon_lat_coords` with multiple same-type (i.e. dim/aux) lat or lon coords"
" is currently disallowed"
)
lat_coord = lat_coords[0]
lon_coord = lon_coords[0]
return (lon_coord, lat_coord)
return lon_coord, lat_coord


def _xy_range(cube, mode=None):
Expand Down Expand Up @@ -578,6 +583,11 @@ def project(cube, target_proj, nx=None, ny=None):
An instance of :class:`iris.cube.Cube` and a list describing the
extent of the projection.
.. note::
If there are both dim and aux latitude-longitude coordinates, only
the dim coordinates will be used.
.. note::
This function assumes global data and will if necessary extrapolate
Expand Down
114 changes: 114 additions & 0 deletions lib/iris/tests/unit/analysis/cartography/test__get_lon_lat_coords.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# Copyright Iris contributors
#
# This file is part of Iris and is released under the LGPL license.
# See COPYING and COPYING.LESSER in the root of the repository for full
# licensing details.
"""Test function :func:`iris.analysis.cartography._get_lon_lat_coords"""

import pytest

from iris.analysis.cartography import _get_lon_lat_coords as g_lon_lat
from iris.coords import AuxCoord
from iris.tests.stock import lat_lon_cube


@pytest.fixture
def dim_only_cube():
return lat_lon_cube()


def test_dim_only(dim_only_cube):
t_lat, t_lon = dim_only_cube.dim_coords

lon, lat = g_lon_lat(dim_only_cube)

assert lon == t_lon
assert lat == t_lat


@pytest.fixture
def dim_aux_cube(dim_only_cube):
lat_dim, lon_dim = dim_only_cube.dim_coords

lat_aux = AuxCoord.from_coord(lat_dim)
lat_aux.standard_name = "grid_latitude"
lon_aux = AuxCoord.from_coord(lon_dim)
lon_aux.standard_name = "grid_longitude"

dim_aux_cube = dim_only_cube
dim_aux_cube.add_aux_coord(lat_aux, 0)
dim_aux_cube.add_aux_coord(lon_aux, 1)

return dim_aux_cube


def test_dim_aux(dim_aux_cube):
t_lat_dim, t_lon_dim = dim_aux_cube.dim_coords

lon, lat = g_lon_lat(dim_aux_cube)

assert lon == t_lon_dim
assert lat == t_lat_dim


@pytest.fixture
def aux_only_cube(dim_aux_cube):
lon_dim, lat_dim = dim_aux_cube.dim_coords

aux_only_cube = dim_aux_cube
aux_only_cube.remove_coord(lon_dim)
aux_only_cube.remove_coord(lat_dim)

return dim_aux_cube


def test_aux_only(aux_only_cube):
aux_lat, aux_lon = aux_only_cube.aux_coords

lon, lat = g_lon_lat(aux_only_cube)

assert lon == aux_lon
assert lat == aux_lat


@pytest.fixture
def double_dim_cube(dim_only_cube):
double_dim_cube = dim_only_cube
double_dim_cube.coord("latitude").standard_name = "grid_longitude"

return double_dim_cube


def test_double_dim(double_dim_cube):
t_error_message = "with multiple.*is currently disallowed"

with pytest.raises(ValueError, match=t_error_message):
g_lon_lat(double_dim_cube)


@pytest.fixture
def double_aux_cube(aux_only_cube):
double_aux_cube = aux_only_cube
double_aux_cube.coord("grid_latitude").standard_name = "longitude"

return double_aux_cube


def test_double_aux(double_aux_cube):
t_error_message = "with multiple.*is currently disallowed"

with pytest.raises(ValueError, match=t_error_message):
g_lon_lat(double_aux_cube)


@pytest.fixture
def missing_lat_cube(dim_only_cube):
missing_lat_cube = dim_only_cube
missing_lat_cube.remove_coord("latitude")

return missing_lat_cube


def test_missing_coord(missing_lat_cube):
with pytest.raises(IndexError):
g_lon_lat(missing_lat_cube)

0 comments on commit b5178a9

Please sign in to comment.