Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

load_earth_relief: Add the support of data source "GEBCO" #1818

Merged
merged 39 commits into from
Oct 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
2916236
add GEBCO option for data_source
willschlitzer Mar 15, 2022
80c389f
add parametrize to test_earth_relief_fails
willschlitzer Mar 15, 2022
0d00c3d
Merge branch 'main' into load-earth-relief/multiple-sources
willschlitzer Jun 13, 2022
66ee213
Merge branch 'main' into load-earth-relief/multiple-sources
willschlitzer Aug 3, 2022
11310e3
Merge branch 'main' into load-earth-relief/multiple-sources
willschlitzer Sep 12, 2022
db7ed8b
add tests at 01d resolution with and without region set for GEBCO data
willschlitzer Sep 13, 2022
d21df89
add check and testing for invalid data source
willschlitzer Sep 13, 2022
5de32f3
Apply suggestions from code review
willschlitzer Sep 19, 2022
1b88bf2
Merge branch 'main' into load-earth-relief/multiple-sources
willschlitzer Sep 19, 2022
e1dc41f
Apply suggestions from code review
willschlitzer Sep 20, 2022
16c3ac2
update reference information, remove specific version number for SRTM…
willschlitzer Sep 20, 2022
1ff9ff8
change "relief" to "igpp"
willschlitzer Sep 20, 2022
96b7059
update igpp docstring
willschlitzer Sep 20, 2022
784ecd6
update remote file naming description
willschlitzer Sep 20, 2022
ac60440
Merge branch 'main' into load-earth-relief/multiple-sources
willschlitzer Sep 21, 2022
21d90a0
add error for old GMT version
willschlitzer Sep 22, 2022
e92927c
run make format
willschlitzer Sep 22, 2022
8ab8050
Merge branch 'main' into load-earth-relief/multiple-sources
willschlitzer Sep 22, 2022
b25fbca
fix GMT version checking
willschlitzer Sep 26, 2022
7840b3f
create dictionary or earth_relief_sources
willschlitzer Sep 26, 2022
cc84324
Merge branch 'main' into load-earth-relief/multiple-sources
willschlitzer Sep 26, 2022
758e1fc
add data source check before checking version number
willschlitzer Sep 27, 2022
bd7507b
remove redundant check
willschlitzer Sep 27, 2022
d2b192e
Apply suggestions from code review
willschlitzer Sep 28, 2022
921dd72
wording change in docstring
willschlitzer Oct 4, 2022
90374b8
Merge branch 'main' into load-earth-relief/multiple-sources
willschlitzer Oct 4, 2022
cc0dd5f
add 1d GEBCO dataset to testing.py
willschlitzer Oct 9, 2022
94e0aaf
uncomment "pull_request" in cache_data.yaml to update GitHub cache
willschlitzer Oct 9, 2022
dffbbe1
disable pylint on too-many-branches in earth_relief.py
willschlitzer Oct 9, 2022
eb86bcf
re-comment "pull_request" in cache_data.yaml
willschlitzer Oct 9, 2022
e12c227
Merge branch 'main' into load-earth-relief/multiple-sources
willschlitzer Oct 9, 2022
77831ac
Apply suggestions from code review
willschlitzer Oct 12, 2022
0567f63
move gebco file name for alaphbetizing
willschlitzer Oct 12, 2022
0862cf2
move up else statement
willschlitzer Oct 12, 2022
794d69b
change data source check
willschlitzer Oct 12, 2022
fe4ce30
add error handling for use_srtm
willschlitzer Oct 12, 2022
0238d59
Merge remote-tracking branch 'origin/load-earth-relief/multiple-sourc…
willschlitzer Oct 12, 2022
6f0a7d7
Merge branch 'main' into load-earth-relief/multiple-sources
willschlitzer Oct 12, 2022
6fa396b
change elif statement to else statement, use dict.get
willschlitzer Oct 12, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 58 additions & 18 deletions pygmt/datasets/earth_relief.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,38 @@

The grids are available in various resolutions.
"""
from pygmt.exceptions import GMTInvalidInput
from packaging.version import Version
from pygmt.clib import Session
from pygmt.exceptions import GMTInvalidInput, GMTVersionError
from pygmt.helpers import kwargs_to_strings
from pygmt.io import load_dataarray
from pygmt.src import grdcut, which


@kwargs_to_strings(region="sequence")
def load_earth_relief(resolution="01d", region=None, registration=None, use_srtm=False):
def load_earth_relief(
resolution="01d",
region=None,
registration=None,
use_srtm=False,
data_source="igpp",
):
r"""
Load Earth relief grids (topography and bathymetry) in various resolutions.
seisman marked this conversation as resolved.
Show resolved Hide resolved

The grids are downloaded to a user data directory
(usually ``~/.gmt/server/earth/earth_relief/``) the first time you invoke
this function. Afterwards, it will load the grid from the data directory.
So you'll need an internet connection the first time around.
(usually a subdirectory under ~/.gmt/server/earth/) the first time you
invoke this function. Afterwards, it will load the grid from the data
directory. So you'll need an internet connection the first time around.

These grids can also be accessed by passing in the file name
**@earth_relief**\_\ *res*\[_\ *reg*] to any grid plotting/processing
function. *res* is the grid resolution (see below), and *reg* is grid
registration type (**p** for pixel registration or **g** for gridline
registration).
This module downloads the grids that can also be accessed by
passing in the file name **@**\ *earth_relief_type*\_\ *res*\[_\ *reg*] to
any grid plotting/processing function. *res* is the grid resolution
(see below), and *reg* is grid registration type (**p** for pixel
registration or **g** for gridline registration).

Refer to :gmt-datasets:`earth-relief.html` for more details.
Refer to :gmt-datasets:`earth-relief.html` for more details about available
datasets, including version information and references.

Parameters
----------
Expand Down Expand Up @@ -55,9 +64,21 @@ def load_earth_relief(resolution="01d", region=None, registration=None, use_srtm
use_srtm : bool
By default, the land-only SRTM tiles from NASA are used to generate the
``"03s"`` and ``"01s"`` grids, and the missing ocean values are filled
by up-sampling the SRTM15+ tiles which have a resolution of 15
by up-sampling the SRTM15 tiles which have a resolution of 15
arc-second (i.e., ``"15s"``). If True, will only load the original
land-only SRTM tiles.
land-only SRTM tiles. Only works when ``data_source="igpp"``.

data_source : str
Select the source for the Earth relief data.

Available options:

- **igpp** : IGPP Global Earth Relief [Default option]. See
:gmt-datasets:`earth-relief.html`.

- **gebco** : GEBCO Global Earth Relief with only observed relief and
inferred relief via altimetric gravity. See
:gmt-datasets:`earth-gebco.html`.

Returns
-------
Expand Down Expand Up @@ -90,7 +111,7 @@ def load_earth_relief(resolution="01d", region=None, registration=None, use_srtm
... use_srtm=True,
... )
"""

# pylint: disable=too-many-branches
# earth relief data stored as single grids for low resolutions
non_tiled_resolutions = ["01d", "30m", "20m", "15m", "10m", "06m"]
# earth relief data stored as tiles for high resolutions
Expand Down Expand Up @@ -120,11 +141,30 @@ def load_earth_relief(resolution="01d", region=None, registration=None, use_srtm
f"{registration}-registered Earth relief data for "
f"resolution '{resolution}' is not supported."
)

earth_relief_sources = {"igpp": "earth_relief_", "gebco": "earth_gebco_"}
if data_source not in earth_relief_sources:
raise GMTInvalidInput(
f"Invalid earth relief 'data_source' {data_source}, "
"valid values are 'igpp' and 'gebco'."
)
if data_source != "igpp":
with Session() as lib:
if Version(lib.info["version"]) < Version("6.4.0"):
raise GMTVersionError(
f"The {data_source} option is not available for GMT"
" versions before 6.4.0."
)
# Choose earth relief data prefix
earth_relief_prefix = "earth_relief_"
if use_srtm and resolution in land_only_srtm_resolutions:
earth_relief_prefix = "srtm_relief_"
if data_source == "igpp":
earth_relief_prefix = "srtm_relief_"
else:
raise GMTInvalidInput(
f"The {data_source} option is not available if 'use_srtm=True'."
" Set data_source to 'igpp'."
)
else:
earth_relief_prefix = earth_relief_sources.get(data_source)

# different ways to load tiled and non-tiled earth relief data
# Known issue: tiled grids don't support slice operation
Expand All @@ -134,7 +174,7 @@ def load_earth_relief(resolution="01d", region=None, registration=None, use_srtm
raise GMTInvalidInput(
f"'region' is required for Earth relief resolution '{resolution}'."
)
fname = which(f"@earth_relief_{resolution}{reg}", download="a")
fname = which(f"@{earth_relief_prefix}{resolution}{reg}", download="a")
grid = load_dataarray(fname, engine="netcdf4")
else:
grid = grdcut(f"@{earth_relief_prefix}{resolution}{reg}", region=region)
Expand Down
1 change: 1 addition & 0 deletions pygmt/helpers/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ def download_test_data():
# List of datasets to download
datasets = [
# Earth relief grids
"@earth_gebco_01d_g",
"@earth_relief_01d_p",
"@earth_relief_01d_g",
"@earth_relief_30m_p",
Expand Down
78 changes: 70 additions & 8 deletions pygmt/tests/test_datasets_earth_relief.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,36 +8,56 @@
from pygmt.exceptions import GMTInvalidInput


def test_earth_relief_fails():
@pytest.mark.parametrize("data_source", ["igpp", "gebco"])
def test_earth_relief_fails(data_source):
"""
Make sure earth relief fails for invalid resolutions.
"""
resolutions = "1m 1d bla 60d 001m 03".split()
resolutions.append(60)
for resolution in resolutions:
with pytest.raises(GMTInvalidInput):
load_earth_relief(resolution=resolution)
load_earth_relief(resolution=resolution, data_source=data_source)


# Only test 01d and 30m to avoid downloading large datasets in CI
def test_earth_relief_01d():
def test_earth_relief_01d_igpp():
"""
Test some properties of the earth relief 01d data.
Test some properties of the earth relief 01d data with IGPP data.
"""
data = load_earth_relief(resolution="01d", registration="gridline")
data = load_earth_relief(
resolution="01d", registration="gridline", data_source="igpp"
)
assert data.shape == (181, 361)
npt.assert_allclose(data.lat, np.arange(-90, 91, 1))
npt.assert_allclose(data.lon, np.arange(-180, 181, 1))
npt.assert_allclose(data.min(), -8600.5)
npt.assert_allclose(data.max(), 5559.0)


def test_earth_relief_01d_with_region():
def test_earth_relief_01d_gebco():
"""
Test some properties of the earth relief 01d data with GEBCO data.
"""
data = load_earth_relief(
resolution="01d", registration="gridline", data_source="gebco"
)
assert data.shape == (181, 361)
npt.assert_allclose(data.lat, np.arange(-90, 91, 1))
npt.assert_allclose(data.lon, np.arange(-180, 181, 1))
npt.assert_allclose(data.min(), -8598)
npt.assert_allclose(data.max(), 5559.0)


def test_earth_relief_01d_with_region_srtm():
"""
Test loading low-resolution earth relief with 'region'.
Test loading low-resolution earth relief with 'region' with IGPP data.
"""
data = load_earth_relief(
resolution="01d", region=[-10, 10, -5, 5], registration="gridline"
resolution="01d",
region=[-10, 10, -5, 5],
registration="gridline",
data_source="igpp",
)
assert data.shape == (11, 21)
npt.assert_allclose(data.lat, np.arange(-5, 6, 1))
Expand All @@ -46,6 +66,23 @@ def test_earth_relief_01d_with_region():
npt.assert_allclose(data.max(), 805.5)


def test_earth_relief_01d_with_region_gebco():
"""
Test loading low-resolution earth relief with 'region' with GEBCO data.
"""
data = load_earth_relief(
resolution="01d",
region=[-10, 10, -5, 5],
registration="gridline",
data_source="gebco",
)
assert data.shape == (11, 21)
npt.assert_allclose(data.lat, np.arange(-5, 6, 1))
npt.assert_allclose(data.lon, np.arange(-10, 11, 1))
npt.assert_allclose(data.min(), -5146)
npt.assert_allclose(data.max(), 806)


def test_earth_relief_30m():
"""
Test some properties of the earth relief 30m data.
Expand Down Expand Up @@ -122,3 +159,28 @@ def test_earth_relief_invalid_resolution_registration_combination():
]:
with pytest.raises(GMTInvalidInput):
load_earth_relief(resolution=resolution, registration=registration)


def test_earth_relief_invalid_data_source():
"""
Test loading earth relief with invalid data_source argument.
"""
with pytest.raises(GMTInvalidInput):
load_earth_relief(
resolution="01d", registration="gridline", data_source="invalid_source"
)


def test_earth_relief_invalid_data_source_with_use_srtm():
"""
Test loading earth relief with use_srtm=True and an incompatible
data_source argument.
"""
with pytest.raises(GMTInvalidInput):
load_earth_relief(
resolution="03s",
region=[135, 136, 35, 36],
registration="gridline",
use_srtm=True,
data_source="gebco",
)