From 5b0f4b0b67e24aa6a59b6c78931fce352e2eb0e6 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Wed, 31 Jan 2024 22:44:28 +0800 Subject: [PATCH 1/2] Add load_mercury_relief to load Mercury relief dataset in various resolutions and registrations --- doc/api/index.rst | 1 + pygmt/datasets/__init__.py | 1 + pygmt/datasets/load_remote_dataset.py | 21 ++++ pygmt/datasets/mercury_relief.py | 104 ++++++++++++++++++++ pygmt/helpers/caching.py | 3 + pygmt/tests/test_datasets_mercury_relief.py | 51 ++++++++++ 6 files changed, 181 insertions(+) create mode 100644 pygmt/datasets/mercury_relief.py create mode 100644 pygmt/tests/test_datasets_mercury_relief.py diff --git a/doc/api/index.rst b/doc/api/index.rst index 5a52888262e..2309d22314b 100644 --- a/doc/api/index.rst +++ b/doc/api/index.rst @@ -227,6 +227,7 @@ and store them in GMT's user data directory. datasets.load_earth_relief datasets.load_earth_vertical_gravity_gradient datasets.load_mars_relief + datasets.load_mercury_relief datasets.load_moon_relief datasets.load_venus_relief datasets.load_sample_data diff --git a/pygmt/datasets/__init__.py b/pygmt/datasets/__init__.py index d0003fdec1a..8489b899b9f 100644 --- a/pygmt/datasets/__init__.py +++ b/pygmt/datasets/__init__.py @@ -14,6 +14,7 @@ load_earth_vertical_gravity_gradient, ) from pygmt.datasets.mars_relief import load_mars_relief +from pygmt.datasets.mercury_relief import load_mercury_relief from pygmt.datasets.moon_relief import load_moon_relief from pygmt.datasets.samples import list_sample_data, load_sample_data from pygmt.datasets.tile_map import load_tile_map diff --git a/pygmt/datasets/load_remote_dataset.py b/pygmt/datasets/load_remote_dataset.py index 1eb763ddc37..0f7fbfea806 100644 --- a/pygmt/datasets/load_remote_dataset.py +++ b/pygmt/datasets/load_remote_dataset.py @@ -272,6 +272,27 @@ class GMTRemoteDataset(NamedTuple): "14s": Resolution("14s", registrations=["pixel"], tiled=True), }, ), + "mercury_relief": GMTRemoteDataset( + title="Mercury relief", + name="mercury_relief", + long_name="USGS Mercury relief", + units="meters", + extra_attributes={}, + resolutions={ + "01d": Resolution("01d"), + "30m": Resolution("30m"), + "20m": Resolution("20m"), + "15m": Resolution("15m"), + "10m": Resolution("10m"), + "06m": Resolution("06m"), + "05m": Resolution("05m", tiled=True), + "04m": Resolution("04m", tiled=True), + "03m": Resolution("03m", tiled=True), + "02m": Resolution("02m", tiled=True), + "01m": Resolution("01m", tiled=True), + "56s": Resolution("56s", registrations=["pixel"], tiled=True), + }, + ), "venus_relief": GMTRemoteDataset( title="Venus relief", name="venus_relief", diff --git a/pygmt/datasets/mercury_relief.py b/pygmt/datasets/mercury_relief.py new file mode 100644 index 00000000000..01f3de6b034 --- /dev/null +++ b/pygmt/datasets/mercury_relief.py @@ -0,0 +1,104 @@ +""" +Function to download the Mercury relief dataset from the GMT data server, and load as +:class:`xarray.DataArray`. + +The grids are available in various resolutions. +""" +from typing import Literal + +from pygmt.datasets.load_remote_dataset import _load_remote_dataset +from pygmt.helpers import kwargs_to_strings + +__doctest_skip__ = ["load_mercury_relief"] + + +@kwargs_to_strings(region="sequence") +def load_mercury_relief( + resolution="01d", + region=None, + registration: Literal["gridline", "pixel", None] = None, +): + r""" + Load the Mercury relief dataset in various resolutions. + + .. figure:: https://www.generic-mapping-tools.org/remote-datasets/_images/GMT_mercury_relief.jpg + :width: 80% + :align: center + + Mercury relief dataset. + + The grids are downloaded to a user data directory (usually + ``~/.gmt/server/mercury/mercury_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. + + These grids can also be accessed by passing in the file name + **@mercury_relief**\_\ *res*\[_\ *reg*] to any grid processing function or plotting + method. *res* is the grid resolution (see below), and *reg* is the grid registration + type (**p** for pixel registration or **g** for gridline registration). + + The default color palette table (CPT) for this dataset is *@mercury_relief.cpt*. + It's implicitly used when passing in the file name of the dataset to any grid + plotting method if no CPT is explicitly specified. When the dataset is loaded and + plotted as an :class:`xarray.DataArray` object, the default CPT is ignored, and + GMT's default CPT (*turbo*) is used. To use the dataset-specific CPT, you need to + explicitly set ``cmap="@mercury_relief.cpt"``. + + Refer to :gmt-datasets:`mercury-relief.html` for more details about available + datasets, including version information and references. + + Parameters + ---------- + resolution : str + The grid resolution. The suffix ``d``, ``m`` and ``s`` stand for arc-degrees, + arc-minutes and arc-seconds. It can be ``"01d"``, ``"30m"``, ``"20m"``, + ``"15m"``, ``"10m"``, ``"06m"``, ``"05m"``, ``"04m"``, ``"03m"``, ``"02m"``, + ``"01m"``, and ``"56s"``. + region : str or list + The subregion of the grid to load, in the form of a list + [*xmin*, *xmax*, *ymin*, *ymax*] or a string *xmin/xmax/ymin/ymax*. Required for + grids with resolutions higher than 5 arc-minutes (i.e., ``"05m"``). + registration + Grid registration type. Either ``"pixel"`` for pixel registration or + ``"gridline"`` for gridline registration. Default is ``None``, means + ``"gridline"`` for all resolutions except for ``"52s"`` which is ``"pixel"`` + only. + + Returns + ------- + grid : :class:`xarray.DataArray` + The Mercury relief grid. Coordinates are latitude and longitude in degrees. + Relief is in meters. + + Note + ---- + The registration and coordinate system type of the returned + :class:`xarray.DataArray` grid can be accessed via the GMT accessors (i.e., + ``grid.gmt.registration`` and ``grid.gmt.gtype`` respectively). However, these + properties may be lost after specific grid operations (such as slicing) and will + need to be manually set before passing the grid to any PyGMT data processing or + plotting functions. Refer to :class:`pygmt.GMTDataArrayAccessor` for detailed + explanations and workarounds. + + Examples + -------- + >>> from pygmt.datasets import load_mercury_relief + >>> # load the default grid (gridline-registered 1 arc-degree grid) + >>> grid = load_mercury_relief() + >>> # load the 30 arc-minutes grid with "gridline" registration + >>> grid = load_mercury_relief(resolution="30m", registration="gridline") + >>> # load high-resolution (5 arc-minutes) grid for a specific region + >>> grid = load_mercury_relief( + ... resolution="05m", + ... region=[120, 160, 30, 60], + ... registration="gridline", + ... ) + """ + grid = _load_remote_dataset( + dataset_name="mercury_relief", + dataset_prefix="mercury_relief_", + resolution=resolution, + region=region, + registration=registration, + ) + return grid diff --git a/pygmt/helpers/caching.py b/pygmt/helpers/caching.py index 84847e22251..ab21504da17 100644 --- a/pygmt/helpers/caching.py +++ b/pygmt/helpers/caching.py @@ -65,6 +65,9 @@ def cache_data(): # Moon relief grids "@moon_relief_01d_g", "@N00W030.moon_relief_01m_p.nc", # Specific grid for 01m test + # Mercury relief grids + "@mercury_relief_01d_g", + "@N00W030.mercury_relief_01m_p.nc", # Specific grid for 01m test # Venus relief grids "@venus_relief_01d_g", "@N00W030.venus_relief_01m_g.nc", # Specific grid for 01m test diff --git a/pygmt/tests/test_datasets_mercury_relief.py b/pygmt/tests/test_datasets_mercury_relief.py new file mode 100644 index 00000000000..a6548ff58e1 --- /dev/null +++ b/pygmt/tests/test_datasets_mercury_relief.py @@ -0,0 +1,51 @@ +""" +Test basic functionality for loading Mercury relief datasets. +""" +import numpy as np +import numpy.testing as npt +from pygmt.datasets import load_mercury_relief + + +def test_mercury_relief_01d(): + """ + Test some properties of the Mercury relief 01d data. + """ + data = load_mercury_relief(resolution="01d") + assert data.name == "mercury_relief" + assert data.attrs["units"] == "meters" + assert data.attrs["long_name"] == "USGS Mercury relief" + assert data.shape == (181, 361) + assert data.gmt.registration == 0 + 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(), -5103.5, atol=0.5) + npt.assert_allclose(data.max(), 3416.0, atol=0.5) + + +def test_mercury_relief_01d_with_region(): + """ + Test loading low-resolution Mercury relief with 'region'. + """ + data = load_mercury_relief(resolution="01d", region=[-10, 10, -5, 5]) + assert data.shape == (11, 21) + assert data.gmt.registration == 0 + 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(), -327.0, atol=0.5) + npt.assert_allclose(data.max(), 3027.5, atol=0.5) + + +def test_mercury_relief_01m_default_registration(): + """ + Test that the grid returned by default for the 1 arc-minute resolution has + a "gridline" registration. + """ + data = load_mercury_relief(resolution="01m", region=[-10, -9, 3, 5]) + assert data.shape == (121, 61) + assert data.gmt.registration == 0 + assert data.coords["lat"].data.min() == 3.0 + assert data.coords["lat"].data.max() == 5.0 + assert data.coords["lon"].data.min() == -10.0 + assert data.coords["lon"].data.max() == -9.0 + npt.assert_allclose(data.min(), 1953.0, atol=0.5) + npt.assert_allclose(data.max(), 3721.0, atol=0.5) From e2842df5604636b2bc31501f1d3e775e6c2ba9d2 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Thu, 1 Feb 2024 12:23:47 +0800 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: Wei Ji <23487320+weiji14@users.noreply.github.com> --- pygmt/datasets/mercury_relief.py | 2 +- pygmt/helpers/caching.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pygmt/datasets/mercury_relief.py b/pygmt/datasets/mercury_relief.py index 01f3de6b034..52a8d8787db 100644 --- a/pygmt/datasets/mercury_relief.py +++ b/pygmt/datasets/mercury_relief.py @@ -61,7 +61,7 @@ def load_mercury_relief( registration Grid registration type. Either ``"pixel"`` for pixel registration or ``"gridline"`` for gridline registration. Default is ``None``, means - ``"gridline"`` for all resolutions except for ``"52s"`` which is ``"pixel"`` + ``"gridline"`` for all resolutions except for ``"56s"`` which is ``"pixel"`` only. Returns diff --git a/pygmt/helpers/caching.py b/pygmt/helpers/caching.py index ab21504da17..17e6a2a4c2b 100644 --- a/pygmt/helpers/caching.py +++ b/pygmt/helpers/caching.py @@ -62,12 +62,12 @@ def cache_data(): # Mars relief grids "@mars_relief_01d_g", "@N00W030.mars_relief_01m_g.nc", # Specific grid for 01m tes - # Moon relief grids - "@moon_relief_01d_g", - "@N00W030.moon_relief_01m_p.nc", # Specific grid for 01m test # Mercury relief grids "@mercury_relief_01d_g", "@N00W030.mercury_relief_01m_p.nc", # Specific grid for 01m test + # Moon relief grids + "@moon_relief_01d_g", + "@N00W030.moon_relief_01m_p.nc", # Specific grid for 01m test # Venus relief grids "@venus_relief_01d_g", "@N00W030.venus_relief_01m_g.nc", # Specific grid for 01m test