diff --git a/pygmt/accessors.py b/pygmt/accessors.py index 2b91c8bf294..30195736d83 100644 --- a/pygmt/accessors.py +++ b/pygmt/accessors.py @@ -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 @@ -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): diff --git a/pygmt/tests/test_accessor.py b/pygmt/tests/test_accessor.py index 79389eaca5c..d9bb684d69b 100644 --- a/pygmt/tests/test_accessor.py +++ b/pygmt/tests/test_accessor.py @@ -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 @@ -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 + grid = load_earth_relief( + resolution="05m", region=[0, 5, -5, 5], registration="pixel" + ) + # Registration and gtype are correct + assert grid.gmt.registration == 1 + assert grid.gmt.gtype == 1 + # The source grid file is defined but doesn't exist + 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