Skip to content

Commit

Permalink
Merge pull request #689 from metno/oceans674
Browse files Browse the repository at this point in the history
Oceans674
  • Loading branch information
lewisblake authored Jul 6, 2022
2 parents 31284db + b4e6972 commit 367d5cb
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 7 deletions.
33 changes: 26 additions & 7 deletions pyaerocom/region.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from pyaerocom._lowlevel_helpers import BrowseDict
from pyaerocom.config import ALL_REGION_NAME
from pyaerocom.helpers_landsea_masks import load_region_mask_xr
from pyaerocom.helpers_landsea_masks import get_mask_value, load_region_mask_xr
from pyaerocom.region_defs import HTAP_REGIONS # list of HTAP regions
from pyaerocom.region_defs import REGION_DEFS # all region definitions
from pyaerocom.region_defs import OLD_AEROCOM_REGIONS, REGION_NAMES # custom names (dict)
Expand Down Expand Up @@ -142,8 +142,23 @@ def contains_coordinate(self, lat, lon):
bool
True if coordinate is contained in this region, False if not
"""
lat_ok = self.lat_range[0] <= lat <= self.lat_range[1]
lon_ok = self.lon_range[0] <= lon <= self.lon_range[1]

lat_lb = self.lat_range[0]
lat_ub = self.lat_range[1]
lon_lb = self.lon_range[0]
lon_ub = self.lon_range[1]
# latitude bounding boxes should always be defined with the southern most boundary less than the northernmost
lat_ok = lat_lb <= lat <= lat_ub
# if the longitude bounding box has a lowerbound less than the upperbound
if lon_lb < lon_ub:
# it suffices to check that lon is between these values
lon_ok = lon_lb <= lon <= lon_ub
# if the longitude lowerbound has a value lessthan the upperbound
elif lon_ub < lon_lb:
# lon is contained in the bounding box in two cases
lon_ok = lon < lon_ub or lon > lon_lb
else:
lon_ok = False # safeguard
return lat_ok * lon_ok

def mask_available(self):
Expand Down Expand Up @@ -310,7 +325,7 @@ def get_all_default_regions():

#: ToDO: check how to handle methods properly with HTAP regions...
def get_regions_coord(lat, lon, regions=None):
"""Get all regions that contain input coordinate
"""Get the region that contains an input coordinate
Note
----
Expand All @@ -332,14 +347,18 @@ def get_regions_coord(lat, lon, regions=None):
list
list of regions that contain this coordinate
"""

matches = []
if regions is None:
regions = get_all_default_regions()
ocean_mask = load_region_mask_xr("OCN")
on_ocean = get_mask_value(lat, lon, ocean_mask)
for rname, reg in regions.items():
if rname == ALL_REGION_NAME: # always True
if rname == ALL_REGION_NAME: # always True for ALL_REGION_NAME
continue
if reg.contains_coordinate(lat, lon):
# OCN needs special handling determined by the rname, not hardcoded to return OCN b/c of HTAP issues
if reg.contains_coordinate(lat, lon) and not on_ocean:
matches.append(rname)
if rname == "OCN" and on_ocean:
matches.append(rname)
if len(matches) == 0:
matches.append(ALL_REGION_NAME)
Expand Down
63 changes: 63 additions & 0 deletions tests/test_region.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import pytest

from pyaerocom.region import Region, get_regions_coord


@pytest.mark.parametrize(
"region_name, lat, lon",
[
("ALL", 0, 0),
("NAM", 39.7555, -105.2211),
("NAM", 19.5364, -155.5765),
("PAN", -37.8136, 144.9631),
("RBU", 50.4501, 30.5234),
("EUR", 59.9139, 10.7522),
],
)
def test_contains_coordinate(region_name, lat, lon):
reg = Region(region_name)
assert reg.contains_coordinate(lat, lon)


@pytest.mark.parametrize(
"region_name, lat, lon",
[
("EAS", 0, 0),
("MCA", 51.5072, 0.1276),
("MDE", 10.4806, -66.9036),
("SEA", -33.9249, 18.4241),
],
)
def test_does_not_contain_coordinate(region_name, lat, lon):
reg = Region(region_name)
assert not reg.contains_coordinate(lat, lon)


# This test needs work because Region() can accept almost any key in region_defs.py and they are not consistent.
# NAF, NAFRICA, N Africa, for example. Running in a debugger exposes the inconsistencies
@pytest.mark.parametrize(
"region_name, lat, lon",
[
("EUROPE", 48.864716, 2.349014),
("NAFRICA", 30.033333, 31.233334),
("ALL", 0.0, 0.0),
],
)
def test_get_regions_coord(region_name, lat, lon):
reg = Region(region_name)
assert reg.region_id in get_regions_coord(lat, lon)


@pytest.mark.parametrize(
"region_name, lat, lon",
[
("SAM", -33.447487, -70.673676),
("ASIA", 39.916668, 116.383331),
("OCN", 0.0, 0.0),
],
)
def test_get_regions_coord_with_supplied_regions_dict(region_name, lat, lon):
oceans, sam, asia = Region("OCN"), Region("SAM"), Region("ASIA")
candidate_regions = {"OCN": oceans, "SAM": sam, "ASIA": asia}
reg = Region(region_name)
assert reg.region_id in get_regions_coord(lat, lon, candidate_regions)

0 comments on commit 367d5cb

Please sign in to comment.