Skip to content

Commit

Permalink
Wrap grdinfo aliases (GenericMappingTools#799)
Browse files Browse the repository at this point in the history
*Wrap grdinfo R, C, D, F, I, L, T, and M aliases
*Move grdinfo function to grdinfo.py

Co-authored-by: Dongdong Tian <[email protected]>
Co-authored-by: actions-bot <[email protected]>
Co-authored-by: Wei Ji <[email protected]>
  • Loading branch information
4 people authored and Josh Sixsmith committed Dec 21, 2022
1 parent b501532 commit 9b5506c
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 56 deletions.
3 changes: 2 additions & 1 deletion pygmt/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@
# Import modules to make the high-level GMT Python API
from pygmt import datasets
from pygmt.figure import Figure
from pygmt.modules import GMTDataArrayAccessor, config, grdinfo
from pygmt.modules import GMTDataArrayAccessor, config
from pygmt.session_management import begin as _begin
from pygmt.session_management import end as _end
from pygmt.src import (
blockmedian,
grdcut,
grdfilter,
grdinfo,
grdtrack,
info,
makecpt,
Expand Down
51 changes: 2 additions & 49 deletions pygmt/modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,54 +4,7 @@
import xarray as xr
from pygmt.clib import Session
from pygmt.exceptions import GMTInvalidInput
from pygmt.helpers import (
GMTTempFile,
build_arg_string,
data_kind,
dummy_context,
fmt_docstring,
use_alias,
)


@fmt_docstring
@use_alias(V="verbose")
def grdinfo(grid, **kwargs):
"""
Get information about a grid.
Can read the grid from a file or given as an xarray.DataArray grid.
Full option list at :gmt-docs:`grdinfo.html`
Parameters
----------
grid : str or xarray.DataArray
The file name of the input grid or the grid loaded as a DataArray.
{V}
Returns
-------
info : str
A string with information about the grid.
"""
kind = data_kind(grid, None, None)
with GMTTempFile() as outfile:
with Session() as lib:
if kind == "file":
file_context = dummy_context(grid)
elif kind == "grid":
file_context = lib.virtualfile_from_grid(grid)
else:
raise GMTInvalidInput("Unrecognized data type: {}".format(type(grid)))
with file_context as infile:
arg_str = " ".join(
[infile, build_arg_string(kwargs), "->" + outfile.name]
)
lib.call_module("grdinfo", arg_str)
result = outfile.read()
return result
from pygmt.src.grdinfo import grdinfo


class config: # pylint: disable=invalid-name
Expand Down Expand Up @@ -149,7 +102,7 @@ def __init__(self, xarray_obj):
# From the shortened summary information of `grdinfo`,
# get grid registration in column 10, and grid type in column 11
self._registration, self._gtype = map(
int, grdinfo(self._source, C="n", o="10,11").split()
int, grdinfo(self._source, per_column="n", o="10,11").split()
)
except KeyError:
self._registration = 0 # Default to Gridline registration
Expand Down
1 change: 1 addition & 0 deletions pygmt/src/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from pygmt.src.grdcut import grdcut
from pygmt.src.grdfilter import grdfilter
from pygmt.src.grdimage import grdimage
from pygmt.src.grdinfo import grdinfo
from pygmt.src.grdtrack import grdtrack
from pygmt.src.grdview import grdview
from pygmt.src.image import image
Expand Down
127 changes: 127 additions & 0 deletions pygmt/src/grdinfo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
"""
grdinfo - Retrieve info about grid file.
"""
from pygmt.clib import Session
from pygmt.exceptions import GMTInvalidInput
from pygmt.helpers import (
GMTTempFile,
build_arg_string,
data_kind,
dummy_context,
fmt_docstring,
kwargs_to_strings,
use_alias,
)


@fmt_docstring
@use_alias(
C="per_column",
D="tiles",
F="geographic",
I="spacing",
L="force_scan",
M="minmax_pos",
R="region",
T="nearest_multiple",
V="verbose",
)
@kwargs_to_strings(D="sequence", I="sequence", R="sequence")
def grdinfo(grid, **kwargs):
r"""
Get information about a grid.
Can read the grid from a file or given as an xarray.DataArray grid.
Full option list at :gmt-docs:`grdinfo.html`
Parameters
----------
grid : str or xarray.DataArray
The file name of the input grid or the grid loaded as a DataArray.
This is the only required argument.
{R}
per_column : str or bool
**n**\|\ **t**.
Formats the report using tab-separated fields on a single line. The
output is name *w e s n z0 z1 dx dy nx ny* [ *x0 y0 x1 y1* ]
[ *med scale* ] [ *mean std rms* ] [ *n_nan* ] *registration gtype*.
The data in brackets are outputted depending on the ``force_scan``
and ``minmax_pos`` arguments. Use **t** to place file name at the end
of the output record or, **n** or ``True`` to only output numerical
columns. The registration is either 0 (gridline) or 1 (pixel), while
gtype is either 0 (Cartesian) or 1 (geographic). The default value is
``False``. This cannot be called if ``geographic`` is also set.
tiles : str or list
*xoff*\ [/*yoff*][**+i**].
Divide a single grid's domain (or the ``region`` domain, if no grid
given) into tiles of size dx times dy (set via ``spacing``). You can
specify overlap between tiles by appending *xoff*\ [/*yoff*]. If the
single grid is given you may use the modifier **+i** to ignore tiles
that have no data within each tile subregion. Default output is text
region strings. Use ``per_column`` to instead report four columns with
xmin xmax ymin ymax per tile, or use ``per_column="t"`` to also have
the region string appended as trailing text.
geographic : bool
Report grid domain and x/y-increments in world mapping format
The default value is ``False``. This cannot be called if
``per_column`` is also set.
spacing : str or list
*dx*\ [/*dy*]\|\ **b**\|\ **i**\|\ **r**.
Report the min/max of the region to the nearest multiple of dx and dy,
and output this in the form w/e/s/n (unless ``per_column`` is set). To
report the actual grid region, append **r**. For a grid produced by
the img supplement (a Cartesian Mercator grid), the exact geographic
region is given with **i** (if not found then we return the actual
grid region instead). If no argument is given then we report the grid
increment in the form *xinc*\ [/*yinc*]. If **b** is given we write
each grid's bounding box polygon instead. Finally, if ``tiles`` is in
effect then *dx* and *dy* are the dimensions of the desired tiles.
force_scan : int or str
**0**\|\ **1**\|\ **2**\|\ **p**\|\ **a**.
**0**\ : Report range of z after actually scanning the data, not just
reporting what the header says.
**1**\ : Report median and L1 scale of z (L1 scale = 1.4826 * Median
Absolute Deviation (MAD)).
**2**\ : Report mean, standard deviation, and root-mean-square (rms)
of z.
**p**\ : Report mode (LMS) and LMS scale of z.
**a**\ : Include all of the above.
minxmax_pos : bool
Include the x/y values at the location of the minimum and maximum
z-values.
nearest_multiple : str
[*dz*]\ [**+a**\ [*alpha*]]\ [**+s**].
Determine min and max z-value. If *dz* is provided then we first round
these values off to multiples of *dz*. To exclude the two tails of the
distribution when determining the min and max you can add **+a** to
set the *alpha* value (in percent): We then sort the grid, exclude the
data in the 0.5*\ *alpha* and 100 - 0.5*\ *alpha* tails, and revise
the min and max. To force a symmetrical range about zero, using
minus/plus the max absolute value of the two extremes, append **+s**\ .
We report the result via the text string *zmin/zmax* or *zmin/zmax/dz*
(if *dz* was given) as expected by :meth:`pygmt.makecpt`.
{V}
Returns
-------
info : str
A string with information about the grid.
"""
kind = data_kind(grid, None, None)
with GMTTempFile() as outfile:
with Session() as lib:
if kind == "file":
file_context = dummy_context(grid)
elif kind == "grid":
file_context = lib.virtualfile_from_grid(grid)
else:
raise GMTInvalidInput("Unrecognized data type: {}".format(type(grid)))
with file_context as infile:
arg_str = " ".join(
[infile, build_arg_string(kwargs), "->" + outfile.name]
)
lib.call_module("grdinfo", arg_str)
result = outfile.read()
return result
4 changes: 2 additions & 2 deletions pygmt/tests/test_grdcut.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def test_grdcut_file_in_file_out():
result = grdcut("@earth_relief_01d", outgrid=tmpfile.name, region="0/180/0/90")
assert result is None # return value is None
assert os.path.exists(path=tmpfile.name) # check that outgrid exists
result = grdinfo(tmpfile.name, C=True)
result = grdinfo(tmpfile.name, per_column=True)
assert result == "0 180 0 90 -8182 5651.5 1 1 180 90 1 1\n"


Expand Down Expand Up @@ -60,7 +60,7 @@ def test_grdcut_dataarray_in_file_out(grid):
with GMTTempFile(suffix=".nc") as tmpfile:
result = grdcut(grid, outgrid=tmpfile.name, region="0/180/0/90")
assert result is None # grdcut returns None if output to a file
result = grdinfo(tmpfile.name, C=True)
result = grdinfo(tmpfile.name, per_column=True)
assert result == "0 180 0 90 -8182 5651.5 1 1 180 90 1 1\n"


Expand Down
4 changes: 2 additions & 2 deletions pygmt/tests/test_grdfilter.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def test_grdfilter_dataarray_in_file_out(grid):
with GMTTempFile(suffix=".nc") as tmpfile:
result = grdfilter(grid, outgrid=tmpfile.name, filter="g600", distance="4")
assert result is None # grdfilter returns None if output to a file
result = grdinfo(tmpfile.name, C=True)
result = grdinfo(tmpfile.name, per_column=True)
assert (
result == "-180 180 -90 90 -6147.47265625 5164.11572266 1 1 360 180 1 1\n"
)
Expand Down Expand Up @@ -88,7 +88,7 @@ def test_grdfilter_file_in_file_out():
)
assert result is None # return value is None
assert os.path.exists(path=tmpfile.name) # check that outgrid exists
result = grdinfo(tmpfile.name, C=True)
result = grdinfo(tmpfile.name, per_column=True)
assert result == "0 180 0 90 -6147.49072266 5164.06005859 1 1 180 90 1 1\n"


Expand Down
17 changes: 15 additions & 2 deletions pygmt/tests/test_grdinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ def test_grdinfo():
Make sure grd info works as expected.
"""
grid = load_earth_relief(registration="gridline")
result = grdinfo(grid, L=0, C="n")
result = grdinfo(grid=grid, force_scan=0, per_column="n")
assert result.strip() == "-180 180 -90 90 -8592.5 5559 1 1 361 181 0 1"


def test_grdinfo_file():
"""
Test grdinfo with file input.
"""
result = grdinfo("@earth_relief_01d", L=0, C="n")
result = grdinfo(grid="@earth_relief_01d", force_scan=0, per_column="n")
assert result.strip() == "-180 180 -90 90 -8182 5651.5 1 1 360 180 1 1"


Expand All @@ -31,3 +31,16 @@ def test_grdinfo_fails():
"""
with pytest.raises(GMTInvalidInput):
grdinfo(np.arange(10).reshape((5, 2)))


def test_grdinfo_region():
"""
Check that the region argument works in grdinfo.
"""
result = grdinfo(
grid="@earth_relief_01d",
force_scan=0,
per_column="n",
region=[-170, 170, -80, 80],
)
assert result.strip() == "-170 170 -80 80 -8182 5651.5 1 1 340 160 1 1"

0 comments on commit 9b5506c

Please sign in to comment.