Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
dd3abe1
add grdmask for required arguments
Chuan1937 Feb 25, 2026
67da3c5
Merge branch 'main' into grdmask1
Chuan1937 Feb 25, 2026
caedc1a
add grdmask doc api
Chuan1937 Feb 25, 2026
44d969c
Update pygmt/src/grdmask.py
Chuan1937 Feb 25, 2026
fdee109
Update pygmt/src/grdmask.py
Chuan1937 Feb 25, 2026
7f0ddff
change grdmask category
Chuan1937 Feb 25, 2026
68123cf
Update pygmt/src/grdmask.py
Chuan1937 Feb 25, 2026
e70ca8c
show the value of mask
Chuan1937 Feb 25, 2026
1b0e057
change parameter name from mask_values to outside, edge, inside.
Chuan1937 Feb 26, 2026
7a166e9
reset the N parameter
Chuan1937 Feb 26, 2026
da0cc55
set a private function
Chuan1937 Mar 2, 2026
d9b3478
Merge branch 'main' into grdmask1
Chuan1937 Mar 2, 2026
6302abe
Update pygmt/src/grdmask.py
Chuan1937 Mar 2, 2026
1d6d753
Update pygmt/src/grdmask.py
Chuan1937 Mar 2, 2026
d4293de
delete docs
Chuan1937 Mar 2, 2026
a0ded64
fix type error
Chuan1937 Mar 2, 2026
871bcff
Update pygmt/src/grdmask.py
Chuan1937 Mar 3, 2026
a0519e6
Update pygmt/src/grdmask.py
Chuan1937 Mar 3, 2026
7d98d67
simplified code logic
Chuan1937 Mar 3, 2026
ad23794
Update pygmt/src/grdmask.py
Chuan1937 Mar 3, 2026
8e2a998
Update pygmt/src/grdmask.py
Chuan1937 Mar 3, 2026
21b543d
check output
Chuan1937 Mar 3, 2026
115733d
Merge branch 'main' into grdmask1
Chuan1937 Mar 3, 2026
68e654f
Merge branch 'main' into grdmask1
Chuan1937 Mar 4, 2026
53b3346
Update pygmt/src/grdmask.py
Chuan1937 Mar 4, 2026
8e9a3b6
Update pygmt/src/grdmask.py
Chuan1937 Mar 4, 2026
2a19936
Update pygmt/src/grdmask.py
Chuan1937 Mar 4, 2026
09bf961
Merge branch 'main' into grdmask1
Chuan1937 Mar 4, 2026
813b8e2
fix format
Chuan1937 Mar 4, 2026
1eb9667
fix static type error
Chuan1937 Mar 4, 2026
a1ba800
Update pygmt/src/grdmask.py
Chuan1937 Mar 4, 2026
05e9635
Update pygmt/src/grdmask.py
Chuan1937 Mar 4, 2026
f9a87fe
Update pygmt/src/grdmask.py
Chuan1937 Mar 4, 2026
b63a8de
Update pygmt/src/grdmask.py
Chuan1937 Mar 4, 2026
4bafead
Update pygmt/src/grdmask.py
Chuan1937 Mar 6, 2026
e65774a
Update pygmt/src/grdmask.py
Chuan1937 Mar 6, 2026
ee32aca
Update pygmt/src/grdmask.py
Chuan1937 Mar 6, 2026
8851b91
Update pygmt/src/grdmask.py
Chuan1937 Mar 6, 2026
fe5348e
Update pygmt/src/grdmask.py
Chuan1937 Mar 6, 2026
7919391
Update pygmt/src/grdmask.py
Chuan1937 Mar 6, 2026
6c74bb0
Merge branch 'main' into grdmask1
Chuan1937 Mar 6, 2026
38a814e
fix alias_n
Chuan1937 Mar 6, 2026
210e92d
Update pygmt/src/grdmask.py
Chuan1937 Mar 6, 2026
b548821
Update pygmt/src/grdmask.py
Chuan1937 Mar 6, 2026
5c818d6
fix check
Chuan1937 Mar 6, 2026
5990c16
fix static
Chuan1937 Mar 6, 2026
35ab3cc
Merge branch 'main' into grdmask1
Chuan1937 Mar 7, 2026
7486ef9
fix outside
Chuan1937 Mar 7, 2026
223b0bc
add test and check for mask_values
Chuan1937 Mar 8, 2026
3949572
Merge branch 'main' into grdmask1
Chuan1937 Mar 12, 2026
02ef75d
Merge branch 'main' into grdmask1
Chuan1937 Mar 18, 2026
223e71c
rewarp and fix layout
Chuan1937 Mar 18, 2026
596f7a6
fix check
Chuan1937 Mar 18, 2026
3b576f8
fix check
Chuan1937 Mar 18, 2026
64432b2
fix typo
Chuan1937 Mar 18, 2026
efb23e3
Update pygmt/src/grdmask.py
Chuan1937 Mar 19, 2026
7a165da
Update pygmt/src/grdmask.py
Chuan1937 Mar 19, 2026
f344dab
Merge branch 'main' into grdmask1
Chuan1937 Mar 19, 2026
2253679
use GMTValueError instead of ValueError for invalid input to grdmask.
Chuan1937 Mar 19, 2026
b4eb6f9
use GMTValueError in test_grdmask
Chuan1937 Mar 19, 2026
403a200
Merge branch 'main' into grdmask1
seisman Mar 21, 2026
6fb81cf
Update pygmt/src/grdmask.py
Chuan1937 Mar 22, 2026
fe2a546
Update pygmt/src/grdmask.py
Chuan1937 Mar 22, 2026
df24648
Update pygmt/src/grdmask.py
Chuan1937 Mar 22, 2026
5ace7d1
Update pygmt/src/grdmask.py
Chuan1937 Mar 22, 2026
151b3a8
use parse
Chuan1937 Mar 22, 2026
682d72c
typecheck
Chuan1937 Mar 22, 2026
cff6ad8
make format
Chuan1937 Mar 22, 2026
1bd98ac
Update pygmt/src/grdmask.py
Chuan1937 Mar 22, 2026
64c8918
remove intermediate variable
Chuan1937 Mar 22, 2026
cef981e
add type ignore
Chuan1937 Mar 22, 2026
3dec2b5
fix condition check
Chuan1937 Mar 22, 2026
7f65f39
Merge branch 'main' into grdmask1
Chuan1937 Mar 23, 2026
32dff85
add doctests
Chuan1937 Mar 24, 2026
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
1 change: 1 addition & 0 deletions doc/api/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ Operations on tabular data
blockmedian
blockmode
filter1d
grdmask
nearneighbor
project
select
Expand Down
1 change: 1 addition & 0 deletions pygmt/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
grdhisteq,
grdinfo,
grdlandmask,
grdmask,
grdpaste,
grdproject,
grdsample,
Expand Down
1 change: 1 addition & 0 deletions pygmt/src/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from pygmt.src.grdimage import grdimage
from pygmt.src.grdinfo import grdinfo
from pygmt.src.grdlandmask import grdlandmask
from pygmt.src.grdmask import grdmask
from pygmt.src.grdpaste import grdpaste
from pygmt.src.grdproject import grdproject
from pygmt.src.grdsample import grdsample
Expand Down
202 changes: 202 additions & 0 deletions pygmt/src/grdmask.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
"""
grdmask - Create mask grid from polygons or point coverage.
"""

from collections.abc import Sequence
from typing import Literal

import xarray as xr
from pygmt._typing import PathLike
from pygmt.alias import Alias, AliasSystem
from pygmt.clib import Session
from pygmt.exceptions import GMTParameterError, GMTValueError
from pygmt.helpers import build_arg_list, fmt_docstring

__doctest_skip__ = ["grdmask"]


def _alias_option_N( # noqa: N802
outside: float | None = None,
edge: float | Literal["z", "id"] | None = None,
inside: float | Literal["z", "id"] | None = None,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's almost done, but we still miss one parameter:

use -Np to use a running number as polygon ID; optionally append start of the sequence [0].

Not sure what the most suitable name for it is yet. Maybe id_start?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think so

) -> Alias:
"""
Return an Alias object for the -N option.

Builds the -N parameter string for grdmask based on the inside, edge, and
outside values. Handles special modes "z" (use z-value from polygon data)
and "id" (use running polygon ID).

Examples
--------
>>> def parse(**kwargs):
... return AliasSystem(N=_alias_option_N(**kwargs)).get("N")
>>> parse()
>>> parse(outside=1, edge=2, inside=3)
'1/2/3'
>>> parse(outside=3)
'3/0/1'
>>> parse(inside="z")
'z'
>>> parse(outside=1, inside="z")
'z/1'
>>> parse(edge="z", inside="z")
'Z'
>>> parse(inside="id")
'p'
>>> parse(edge="id", inside="id")
'P'
>>> parse(edge="z")
Traceback (most recent call last):
...
pygmt.exceptions.GMTValueError: Invalid edge: 'z'. edge='z' requires inside='z'.
>>> parse(inside="z", edge="id")
Traceback (most recent call last):
...
pygmt.exceptions.GMTValueError: Invalid edge: 'id'. edge='id' requires inside='id'.
"""
# All three are None, return None (GMT uses default 0/0/1)
if all(v is None for v in (outside, inside, edge)):
return Alias(None, name="mask_values")

_inside_modes = {"z": "z", "id": "p"}
# Validate combinations
if edge in _inside_modes and inside != edge:
raise GMTValueError(
edge, description="edge", reason=f"edge={edge!r} requires inside={edge!r}."
)

if inside in _inside_modes and edge is not None and edge != inside:
raise GMTValueError(
edge,
description="edge",
reason=f"inside={inside!r} and edge={edge!r} must be the same.",
)

# Build -N argument
if inside in _inside_modes: # Mode: -Nz, -NZ, -Np, or -NP
mode = _inside_modes[inside] # type: ignore[index]
if edge == inside:
mode = mode.upper()
mask_values = mode if outside is None else [mode, outside]
else: # Build the full mask with defaults for any missing values.
mask_values = [
0 if outside is None else outside,
0 if edge is None else edge,
1 if inside is None else inside,
]
return Alias(mask_values, name="mask_values", sep="/", size=(2, 3))


@fmt_docstring
def grdmask(
data,
outgrid: PathLike | None = None,
spacing: Sequence[float | str] | None = None,
region: Sequence[float | str] | str | None = None,
outside: float | None = None,
edge: float | Literal["z", "id"] | None = None,
inside: float | Literal["z", "id"] | None = None,
verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"]
| bool = False,
**kwargs,
) -> xr.DataArray | None:
"""
Create mask grid from polygons or point coverage.

Reads one or more files containing polygon or data point coordinates, and creates a
grid where nodes that fall inside, on the edge, or outside the polygons (or within
the search radius from data points) are assigned values based on ``outside``,
``edge``, and ``inside`` parameters.

The mask grid can be used to mask out specific regions in other grids using
:func:`pygmt.grdmath` or similar tools. For masking based on coastline features,
consider using :func:`pygmt.grdlandmask` instead.

Full GMT docs at :gmt-docs:`grdmask.html`.

**Aliases**

.. hlist::
:columns: 3

- G = outgrid
- I = spacing
- N = outside/edge/inside
- R = region
- V = verbose

Parameters
----------
data
Pass in either a file name to an ASCII data table, a 2-D $table_classes
containg the polygon(s) or data points. Input can be:

- **Polygon mode**: One or more files containing closed polygon coordinates
- **Point coverage mode**: Data points (used with ``search_radius`` parameter)
$outgrid
$spacing
outside
edge
inside
Set the value assigned to nodes outside, on the edge, or inside the polygons.
Can be any number, or one of ``None``, ``"NaN"``, and ``np.nan`` for NaN.

``inside`` can also be set to one of the following values:

- ``"z"``: Use the z-value from polygon data (segment header ``-Zzval``,
``-Lheader``, or via ``-aZ=name``).
- ``"id"``: Use a running polygon ID number.

To treat edges as inside, use the same value as ``inside``.
$region
$verbose

Returns
-------
ret
Return type depends on whether the ``outgrid`` parameter is set:

- :class:`xarray.DataArray` if ``outgrid`` is not set
- ``None`` if ``outgrid`` is set (grid output will be stored in the file set by
``outgrid``)

Example
-------
>>> import pygmt
>>> import numpy as np
>>> # Create a simple polygon as a triangle
>>> polygon = np.array([[125, 30], [130, 30], [130, 35], [125, 30]])
>>> # Create a mask grid with 1 arc-degree spacing
>>> mask = pygmt.grdmask(data=polygon, spacing=1, region=[125, 130, 30, 35])
>>> mask.values
array([[0., 0., 0., 0., 0., 0.],
[0., 0., 1., 1., 1., 0.],
[0., 0., 0., 1., 1., 0.],
[0., 0., 0., 0., 1., 0.],
[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.]])
"""
if kwargs.get("I", spacing) is None or kwargs.get("R", region) is None:
raise GMTParameterError(required=["region", "spacing"])

aliasdict = AliasSystem(
I=Alias(spacing, name="spacing", sep="/", size=2),
N=_alias_option_N(outside=outside, edge=edge, inside=inside),
).add_common(
R=region,
V=verbose,
)
aliasdict.merge(kwargs)

with Session() as lib:
with (
lib.virtualfile_in(check_kind="vector", data=data) as vintbl,
lib.virtualfile_out(kind="grid", fname=outgrid) as voutgrd,
):
aliasdict["G"] = voutgrd
lib.call_module(
module="grdmask",
args=build_arg_list(aliasdict, infile=vintbl),
)
return lib.virtualfile_to_raster(vfname=voutgrd, outgrid=outgrid)
Loading
Loading