4
4
5
5
import warnings
6
6
7
+ import numpy as np
7
8
import xarray as xr
8
9
from pygmt .clib import Session
9
10
from pygmt .exceptions import GMTInvalidInput
18
19
__doctest_skip__ = ["grdfill" ]
19
20
20
21
22
+ def _validate_params (
23
+ constantfill = None ,
24
+ gridfill = None ,
25
+ neighborfill = None ,
26
+ splinefill = None ,
27
+ inquire = False ,
28
+ mode = None ,
29
+ ):
30
+ """
31
+ Validate the fill/inquire parameters.
32
+
33
+ >>> _validate_params(constantfill=20.0)
34
+ >>> _validate_params(inquire=True)
35
+ >>> _validate_params(mode="c20.0")
36
+ >>> _validate_params(constantfill=20.0, gridfill="bggrid.nc")
37
+ Traceback (most recent call last):
38
+ ...
39
+ pygmt.exceptions.GMTInvalidInput: Parameters ... are mutually exclusive.
40
+ >>> _validate_params(constantfill=20.0, inquire=True)
41
+ Traceback (most recent call last):
42
+ ...
43
+ pygmt.exceptions.GMTInvalidInput: Parameters ... are mutually exclusive.
44
+ >>> _validate_params()
45
+ Traceback (most recent call last):
46
+ ...
47
+ pygmt.exceptions.GMTInvalidInput: Need to specify parameter ...
48
+ """
49
+ _fill_params = "'constantfill'/'gridfill'/'neighborfill'/'splinefill'"
50
+ # The deprecated 'mode' parameter is given.
51
+ if mode is not None :
52
+ msg = (
53
+ "The 'mode' parameter is deprecated since v0.15.0 and will be removed in "
54
+ f"v0.19.0. Use { _fill_params } instead."
55
+ )
56
+ warnings .warn (msg , FutureWarning , stacklevel = 2 )
57
+
58
+ n_given = sum (
59
+ param is not None and param is not False
60
+ for param in [constantfill , gridfill , neighborfill , splinefill , inquire , mode ]
61
+ )
62
+ if n_given > 1 : # More than one mutually exclusive parameter is given.
63
+ msg = f"Parameters { _fill_params } /'inquire'/'mode' are mutually exclusive."
64
+ raise GMTInvalidInput (msg )
65
+ if n_given == 0 : # No parameters are given.
66
+ msg = (
67
+ f"Need to specify parameter { _fill_params } for filling holes or "
68
+ "'inquire' for inquiring the bounds of each hole."
69
+ )
70
+ raise GMTInvalidInput (msg )
71
+
72
+
21
73
def _parse_fill_mode (
22
74
constantfill = None , gridfill = None , neighborfill = None , splinefill = None
23
75
) -> str | None :
@@ -40,19 +92,7 @@ def _parse_fill_mode(
40
92
's0.5'
41
93
>>> _parse_fill_mode(splinefill=True)
42
94
's'
43
- >>> _parse_fill_mode(constantfill=20, gridfill="bggrid.nc")
44
- Traceback (most recent call last):
45
- ...
46
- pygmt.exceptions.GMTInvalidInput: The ... parameters are mutually exclusive.
47
95
"""
48
- fill_params = [constantfill , gridfill , neighborfill , splinefill ]
49
- if sum (param is not None for param in fill_params ) > 1 :
50
- msg = (
51
- "The 'constantfill', 'gridfill', 'neighborfill', and 'splinefill' "
52
- "parameters are mutually exclusive."
53
- )
54
- raise GMTInvalidInput (msg )
55
-
56
96
if constantfill is not None :
57
97
return f"c{ constantfill } "
58
98
if gridfill is not None :
@@ -66,8 +106,9 @@ def _parse_fill_mode(
66
106
67
107
@fmt_docstring
68
108
# TODO(PyGMT>=0.19.0): Remove the deprecated 'no_data' parameter.
109
+ # TODO(PyGMT>=0.19.0): Remove the deprecated 'mode' parameter.
69
110
@deprecate_parameter ("no_data" , "hole" , "v0.15.0" , remove_version = "v0.19.0" )
70
- @use_alias (A = "mode" , N = "hole" , R = "region" , V = "verbose" , f = "coltypes" )
111
+ @use_alias (N = "hole" , R = "region" , V = "verbose" , f = "coltypes" )
71
112
@kwargs_to_strings (R = "sequence" )
72
113
def grdfill (
73
114
grid : str | xr .DataArray ,
@@ -76,8 +117,10 @@ def grdfill(
76
117
gridfill : str | xr .DataArray | None = None ,
77
118
neighborfill : float | bool | None = None ,
78
119
splinefill : float | bool | None = None ,
120
+ inquire : bool = False ,
121
+ mode : str | None = None ,
79
122
** kwargs ,
80
- ) -> xr .DataArray | None :
123
+ ) -> xr .DataArray | np . ndarray | None :
81
124
r"""
82
125
Interpolate across holes in a grid.
83
126
@@ -111,7 +154,11 @@ def grdfill(
111
154
hole : float
112
155
Set the node value used to identify a point as a member of a hole [Default is
113
156
NaN].
114
- mode : str
157
+ inquire
158
+ Output the bounds of each hole. The bounds are returned as a 2-D numpy array in
159
+ the form of (west, east, south, north). No grid fill takes place and ``outgrid``
160
+ is ignored.
161
+ mode
115
162
Specify the hole-filling algorithm to use. Choose from **c** for constant fill
116
163
and append the constant value, **n** for nearest neighbor (and optionally append
117
164
a search radius in pixels [default radius is :math:`r^2 = \sqrt{{ X^2 + Y^2 }}`,
@@ -128,50 +175,62 @@ def grdfill(
128
175
Returns
129
176
-------
130
177
ret
131
- Return type depends on whether the ``outgrid`` parameter is set:
178
+ If ``inquire`` is ``True``, return the bounds of each hole as a 2-D numpy array.
179
+ Otherwise, the return type depends on whether the ``outgrid`` parameter is set:
132
180
133
181
- :class:`xarray.DataArray` if ``outgrid`` is not set
134
182
- ``None`` if ``outgrid`` is set (grid output will be stored in the file set by
135
183
``outgrid``)
136
184
137
185
Example
138
186
-------
187
+ Fill holes in a bathymetric grid with a constant value of 20.
139
188
>>> import pygmt
140
189
>>> # Load a bathymetric grid with missing data
141
190
>>> earth_relief_holes = pygmt.datasets.load_sample_data(name="earth_relief_holes")
142
191
>>> # Fill the holes with a constant value of 20
143
192
>>> filled_grid = pygmt.grdfill(grid=earth_relief_holes, constantfill=20)
193
+
194
+ Inquire the bounds of each hole.
195
+ >>> pygmt.grdfill(grid=earth_relief_holes, inquire=True)
196
+ array([[1.83333333, 6.16666667, 3.83333333, 8.16666667],
197
+ [6.16666667, 7.83333333, 0.5 , 2.5 ]])
144
198
"""
145
- # TODO(PyGMT>=0.19.0): Remove the deprecated 'mode' parameter.
146
- if kwargs .get ("A" ) is not None : # The deprecated 'mode' parameter is given.
147
- warnings .warn (
148
- "The 'mode' parameter is deprecated since v0.15.0 and will be removed in "
149
- "v0.19.0. Use 'constantfill'/'gridfill'/'neighborfill'/'splinefill' "
150
- "instead." ,
151
- FutureWarning ,
152
- stacklevel = 1 ,
153
- )
154
- else :
155
- # Determine the -A option from the fill parameters.
156
- kwargs ["A" ] = _parse_fill_mode (constantfill , gridfill , neighborfill , splinefill )
199
+ # Validate the fill/inquire parameters.
200
+ _validate_params (constantfill , gridfill , neighborfill , splinefill , inquire , mode )
157
201
158
- if kwargs .get ("A" ) is None and kwargs .get ("L" ) is None :
159
- msg = "At least parameter 'mode' or 'L' must be specified."
160
- raise GMTInvalidInput (msg )
202
+ # Parse the fill parameters and return the appropriate string for the -A option.
203
+ kwargs ["A" ] = (
204
+ _parse_fill_mode (constantfill , gridfill , neighborfill , splinefill )
205
+ if mode is None
206
+ else mode
207
+ )
161
208
162
209
with Session () as lib :
163
- with (
164
- lib .virtualfile_in (check_kind = "raster" , data = grid ) as vingrd ,
165
- lib .virtualfile_in (
166
- check_kind = "raster" , data = gridfill , required_data = False
167
- ) as vbggrd ,
168
- lib .virtualfile_out (kind = "grid" , fname = outgrid ) as voutgrd ,
169
- ):
170
- if gridfill is not None :
171
- # Fill by a grid. Append the actual or virtual grid file name.
172
- kwargs ["A" ] = f"g{ vbggrd } "
173
- kwargs ["G" ] = voutgrd
174
- lib .call_module (
175
- module = "grdfill" , args = build_arg_list (kwargs , infile = vingrd )
176
- )
177
- return lib .virtualfile_to_raster (vfname = voutgrd , outgrid = outgrid )
210
+ with lib .virtualfile_in (check_kind = "raster" , data = grid ) as vingrd :
211
+ if inquire : # Inquire mode.
212
+ kwargs ["L" ] = True
213
+ with lib .virtualfile_out (kind = "dataset" ) as vouttbl :
214
+ lib .call_module (
215
+ module = "grdfill" ,
216
+ args = build_arg_list (kwargs , infile = vingrd , outfile = vouttbl ),
217
+ )
218
+ return lib .virtualfile_to_dataset (
219
+ vfname = vouttbl , output_type = "numpy"
220
+ )
221
+
222
+ # Fill mode.
223
+ with (
224
+ lib .virtualfile_in (
225
+ check_kind = "raster" , data = gridfill , required_data = False
226
+ ) as vbggrd ,
227
+ lib .virtualfile_out (kind = "grid" , fname = outgrid ) as voutgrd ,
228
+ ):
229
+ if gridfill is not None :
230
+ # Fill by a grid. Append the actual or virtual grid file name.
231
+ kwargs ["A" ] = f"g{ vbggrd } "
232
+ kwargs ["G" ] = voutgrd
233
+ lib .call_module (
234
+ module = "grdfill" , args = build_arg_list (kwargs , infile = vingrd )
235
+ )
236
+ return lib .virtualfile_to_raster (vfname = voutgrd , outgrid = outgrid )
0 commit comments