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

GMTDataArrayAccessor: Fallback to default grid registration and gtype if the grid source file doesn't exist #2009

Merged
merged 15 commits into from
Feb 20, 2023
Merged
24 changes: 16 additions & 8 deletions pygmt/accessors.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"""
GMT accessor methods.
"""
from pathlib import Path

import xarray as xr
from pygmt.exceptions import GMTInvalidInput
from pygmt.src.grdinfo import grdinfo
Expand Down Expand Up @@ -50,16 +52,22 @@ class GMTDataArrayAccessor:

def __init__(self, xarray_obj):
self._obj = xarray_obj
try:
self._source = self._obj.encoding["source"] # filepath to NetCDF source
# Get grid registration and grid type from the last two columns of
# the shortened summary information of `grdinfo`.
self._registration, self._gtype = map(
int, grdinfo(self._source, per_column="n").split()[-2:]
)
except (KeyError, ValueError):

self._source = self._obj.encoding.get("source")
if self._source is not None and Path(self._source).exists():
try:
# Get grid registration and grid type from the last two columns
# of the shortened summary information of `grdinfo`.
self._registration, self._gtype = map(
int, grdinfo(self._source, per_column="n").split()[-2:]
)
except ValueError:
self._registration = 0 # Default to Gridline registration
self._gtype = 0 # Default to Cartesian grid type
else:
self._registration = 0 # Default to Gridline registration
self._gtype = 0 # Default to Cartesian grid type
del self._source

@property
def registration(self):
Expand Down
31 changes: 31 additions & 0 deletions pygmt/tests/test_accessor.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
"""
import os
import sys
from pathlib import Path

import pytest
import xarray as xr
from packaging.version import Version
from pygmt import __gmt_version__, which
from pygmt.datasets import load_earth_relief
from pygmt.exceptions import GMTInvalidInput


Expand Down Expand Up @@ -101,3 +103,32 @@ def test_accessor_sliced_datacube():
assert grid.gmt.gtype == 1 # geographic coordinate type
finally:
os.remove(fname)


def test_accessor_grid_source_file_not_exist():
"""
Check that the accessor fallbacks to the default registration and gtype
when the grid source file (i.e., grid.encoding["source"]) doesn't exist.
"""
# load the 05m earth relief grid, which is stored as tiles
seisman marked this conversation as resolved.
Show resolved Hide resolved
grid = load_earth_relief(
resolution="05m", region=[0, 5, -5, 5], registration="pixel"
)
# registration and gtype are correct
seisman marked this conversation as resolved.
Show resolved Hide resolved
assert grid.gmt.registration == 1
assert grid.gmt.gtype == 1
# the source grid file is defined but doesn't exist
seisman marked this conversation as resolved.
Show resolved Hide resolved
assert grid.encoding["source"].endswith(".nc")
assert not Path(grid.encoding["source"]).exists()

# For a sliced grid, fallback to default registration and gtype,
# because the source grid file doesn't exist.
sliced_grid = grid[1:3, 1:3]
assert sliced_grid.gmt.registration == 0
assert sliced_grid.gmt.gtype == 0

# Still possible to manually set registration and gtype
sliced_grid.gmt.registration = 1
sliced_grid.gmt.gtype = 1
assert sliced_grid.gmt.registration == 1
assert sliced_grid.gmt.gtype == 1