Skip to content

Commit 3c61fea

Browse files
committed
Merge branch 'refactor/virtualfile_in' into refactor/validate_data_input
2 parents 60f1758 + f8293cd commit 3c61fea

12 files changed

+62
-36
lines changed

pygmt/clib/session.py

+22-4
Original file line numberDiff line numberDiff line change
@@ -1772,9 +1772,10 @@ def virtualfile_in( # noqa: PLR0912
17721772
x=None,
17731773
y=None,
17741774
z=None,
1775-
required_z=False,
17761775
required_data=True,
1776+
ncols=2,
17771777
extra_arrays=None,
1778+
required_z=False,
17781779
):
17791780
"""
17801781
Store any data inside a virtual file.
@@ -1794,11 +1795,17 @@ def virtualfile_in( # noqa: PLR0912
17941795
data input.
17951796
x/y/z : 1-D arrays or None
17961797
x, y, and z columns as numpy arrays.
1797-
required_z : bool
1798-
State whether the 'z' column is required.
17991798
required_data : bool
18001799
Set to True when 'data' is required, or False when dealing with
18011800
optional virtual files. [Default is True].
1801+
ncols
1802+
Number of minimum required columns.
1803+
required_z : bool
1804+
State whether the 'z' column is required.
1805+
1806+
.. deprecated:: v0.16.0
1807+
The parameter 'required_z' will be removed in v0.20.0. Use parameter
1808+
'ncols' instead. E.g., ``required_z=True`` is equivalent to ``ncols=3``.
18021809
extra_arrays : list of 1-D arrays
18031810
Optional. A list of numpy arrays in addition to x, y, and z. All of these
18041811
arrays must be of the same size as the x/y/z arrays.
@@ -1833,6 +1840,17 @@ def virtualfile_in( # noqa: PLR0912
18331840
... print(fout.read().strip())
18341841
<vector memory>: N = 3 <7/9> <4/6> <1/3>
18351842
"""
1843+
# TODO(PyGMT>=0.20.0): Remove the deprecated 'required_z' parameter.
1844+
if required_z is True:
1845+
warnings.warn(
1846+
"The parameter 'required_z' is deprecated and will be removed in "
1847+
"v0.20.0. Use parameter 'ncols' instead. E.g., ``required_z=True`` is "
1848+
"equivalent to ``ncols=3``.",
1849+
category=FutureWarning,
1850+
stacklevel=1,
1851+
)
1852+
ncols = 3
1853+
18361854
# Specify either data or x/y/z.
18371855
if data is not None and any(v is not None for v in (x, y, z)):
18381856
msg = "Too much data. Use either data or x/y/z."
@@ -1912,7 +1930,7 @@ def virtualfile_in( # noqa: PLR0912
19121930
_data = data.T
19131931

19141932
# Check if _data to be passed to the virtualfile_from_ function is valid.
1915-
_validate_data_input(data=_data, kind=kind, required_z=required_z)
1933+
_validate_data_input(data=_data, kind=kind, ncols=ncols)
19161934

19171935
# Finally create the virtualfile from the data, to be passed into GMT
19181936
file_context = _virtualfile_from(_data)

pygmt/helpers/utils.py

+11-13
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
]
4646

4747

48-
def _validate_data_input(data: Any, kind: Kind, required_z: bool = False) -> None:
48+
def _validate_data_input(data: Any, kind: Kind, ncols=2) -> None:
4949
"""
5050
Check if the data to be passed to the virtualfile_from_ functions is valid.
5151
@@ -67,7 +67,8 @@ def _validate_data_input(data: Any, kind: Kind, required_z: bool = False) -> Non
6767
Traceback (most recent call last):
6868
...
6969
pygmt.exceptions.GMTInvalidInput: Must provide both x and y.
70-
>>> _validate_data_input(data=[[1, 2, 3], [4, 5, 6]], kind="empty", required_z=True)
70+
>>> _validate_data_input(data=[[1, 2, 3], [4, 5, 6]], kind="empty", ncols=3)
71+
>>> _validate_data_input(x=[1, 2, 3], y=[4, 5, 6], ncols=3)
7172
Traceback (most recent call last):
7273
...
7374
pygmt.exceptions.GMTInvalidInput: Must provide x, y, and z.
@@ -78,7 +79,7 @@ def _validate_data_input(data: Any, kind: Kind, required_z: bool = False) -> Non
7879
>>> import pandas as pd
7980
>>> import xarray as xr
8081
>>> data = np.arange(8).reshape((4, 2))
81-
>>> _validate_data_input(data=data, kind="matrix", required_z=True)
82+
>>> _validate_data_input(data=data, ncols=3, kind="matrix")
8283
Traceback (most recent call last):
8384
...
8485
pygmt.exceptions.GMTInvalidInput: Need at least 3 columns but 2 column(s) are given.
@@ -88,16 +89,16 @@ def _validate_data_input(data: Any, kind: Kind, required_z: bool = False) -> Non
8889
8990
>>> _validate_data_input(
9091
... data=pd.DataFrame(data, columns=["x", "y"]),
92+
... ncols=3,
9193
... kind="vectors",
92-
... required_z=True,
9394
... )
9495
Traceback (most recent call last):
9596
...
9697
pygmt.exceptions.GMTInvalidInput: Need at least 3 columns but 2 column(s) are given.
9798
>>> _validate_data_input(
9899
... data=xr.Dataset(pd.DataFrame(data, columns=["x", "y"])),
100+
... ncols=3,
99101
... kind="vectors",
100-
... required_z=True,
101102
... )
102103
Traceback (most recent call last):
103104
...
@@ -108,28 +109,25 @@ def _validate_data_input(data: Any, kind: Kind, required_z: bool = False) -> Non
108109
GMTInvalidInput
109110
If the data input is not valid.
110111
"""
111-
# Determine the required number of columns based on the required_z flag.
112-
required_cols = 3 if required_z else 1
113-
114112
match kind:
115113
case "empty": # data = [x, y], [x, y, z], [x, y, z, ...]
116114
if len(data) < 2 or any(v is None for v in data[:2]):
117115
msg = "Must provide both x and y."
118116
raise GMTInvalidInput(msg)
119-
if required_z and (len(data) < 3 or data[:3] is None):
117+
if ncols >= 3 and (len(data) < 3 or data[:3] is None):
120118
msg = "Must provide x, y, and z."
121119
raise GMTInvalidInput(msg)
122120
case "matrix": # 2-D numpy.ndarray
123-
if (actual_cols := data.shape[1]) < required_cols:
124-
msg = f"Need at least {required_cols} columns but {actual_cols} column(s) are given."
121+
if (actual_cols := data.shape[1]) < ncols:
122+
msg = f"Need at least {ncols} columns but {actual_cols} column(s) are given."
125123
raise GMTInvalidInput(msg)
126124
case "vectors":
127125
# "vectors" means the original data is either dictionary, list, tuple,
128126
# pandas.DataFrame, pandas.Series, xarray.Dataset, or xarray.DataArray.
129127
# The original data is converted to a list of vectors or a 2-D numpy.ndarray
130128
# in the virtualfile_in function.
131-
if (actual_cols := len(data)) < required_cols:
132-
msg = f"Need at least {required_cols} columns but {actual_cols} column(s) are given."
129+
if (actual_cols := len(data)) < ncols:
130+
msg = f"Need at least {ncols} columns but {actual_cols} column(s) are given."
133131
raise GMTInvalidInput(msg)
134132

135133

pygmt/src/blockm.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ def _blockm(
5555
with Session() as lib:
5656
with (
5757
lib.virtualfile_in(
58-
check_kind="vector", data=data, x=x, y=y, z=z, required_z=True
58+
check_kind="vector", data=data, x=x, y=y, z=z, ncols=3
5959
) as vintbl,
6060
lib.virtualfile_out(kind="dataset", fname=outfile) as vouttbl,
6161
):

pygmt/src/contour.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ def contour(self, data=None, x=None, y=None, z=None, **kwargs):
145145

146146
with Session() as lib:
147147
with lib.virtualfile_in(
148-
check_kind="vector", data=data, x=x, y=y, z=z, required_z=True
148+
check_kind="vector", data=data, x=x, y=y, z=z, ncols=3
149149
) as vintbl:
150150
lib.call_module(
151151
module="contour", args=build_arg_list(kwargs, infile=vintbl)

pygmt/src/nearneighbor.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ def nearneighbor(
141141
with Session() as lib:
142142
with (
143143
lib.virtualfile_in(
144-
check_kind="vector", data=data, x=x, y=y, z=z, required_z=True
144+
check_kind="vector", data=data, x=x, y=y, z=z, ncols=3
145145
) as vintbl,
146146
lib.virtualfile_out(kind="grid", fname=outgrid) as voutgrd,
147147
):

pygmt/src/plot3d.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,5 @@ def plot3d( # noqa: PLR0912
259259
kwargs["S"] = "u0.2c"
260260

261261
with Session() as lib:
262-
with lib.virtualfile_in(
263-
check_kind="vector", data=data, required_z=True
264-
) as vintbl:
262+
with lib.virtualfile_in(check_kind="vector", data=data, ncols=3) as vintbl:
265263
lib.call_module(module="plot3d", args=build_arg_list(kwargs, infile=vintbl))

pygmt/src/project.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ def project(
245245
x=x,
246246
y=y,
247247
z=z,
248-
required_z=False,
248+
ncols=2,
249249
required_data=False,
250250
) as vintbl,
251251
lib.virtualfile_out(kind="dataset", fname=outfile) as vouttbl,

pygmt/src/surface.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ def surface(
155155
with Session() as lib:
156156
with (
157157
lib.virtualfile_in(
158-
check_kind="vector", data=data, x=x, y=y, z=z, required_z=True
158+
check_kind="vector", data=data, x=x, y=y, z=z, ncols=3
159159
) as vintbl,
160160
lib.virtualfile_out(kind="grid", fname=outgrid) as voutgrd,
161161
):

pygmt/src/triangulate.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ def regular_grid(
138138
with Session() as lib:
139139
with (
140140
lib.virtualfile_in(
141-
check_kind="vector", data=data, x=x, y=y, z=z, required_z=False
141+
check_kind="vector", data=data, x=x, y=y, z=z, ncols=2
142142
) as vintbl,
143143
lib.virtualfile_out(kind="grid", fname=outgrid) as voutgrd,
144144
):
@@ -238,7 +238,7 @@ def delaunay_triples(
238238
with Session() as lib:
239239
with (
240240
lib.virtualfile_in(
241-
check_kind="vector", data=data, x=x, y=y, z=z, required_z=False
241+
check_kind="vector", data=data, x=x, y=y, z=z, ncols=2
242242
) as vintbl,
243243
lib.virtualfile_out(kind="dataset", fname=outfile) as vouttbl,
244244
):

pygmt/src/wiggle.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,6 @@ def wiggle(
108108

109109
with Session() as lib:
110110
with lib.virtualfile_in(
111-
check_kind="vector", data=data, x=x, y=y, z=z, required_z=True
111+
check_kind="vector", data=data, x=x, y=y, z=z, ncols=3
112112
) as vintbl:
113113
lib.call_module(module="wiggle", args=build_arg_list(kwargs, infile=vintbl))

pygmt/src/xyz2grd.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ def xyz2grd(
149149
with Session() as lib:
150150
with (
151151
lib.virtualfile_in(
152-
check_kind="vector", data=data, x=x, y=y, z=z, required_z=True
152+
check_kind="vector", data=data, x=x, y=y, z=z, ncols=3
153153
) as vintbl,
154154
lib.virtualfile_out(kind="grid", fname=outgrid) as voutgrd,
155155
):

pygmt/tests/test_clib_virtualfile_in.py

+19-7
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,7 @@ def test_virtualfile_in_required_z_matrix(array_func, kind):
4141
)
4242
data = array_func(dataframe)
4343
with clib.Session() as lib:
44-
with lib.virtualfile_in(
45-
data=data, required_z=True, check_kind="vector"
46-
) as vfile:
44+
with lib.virtualfile_in(data=data, ncols=3, check_kind="vector") as vfile:
4745
with GMTTempFile() as outfile:
4846
lib.call_module("info", [vfile, f"->{outfile.name}"])
4947
output = outfile.read(keep_tabs=True)
@@ -64,10 +62,26 @@ def test_virtualfile_in_required_z_matrix_missing():
6462
data = np.ones((5, 2))
6563
with clib.Session() as lib:
6664
with pytest.raises(GMTInvalidInput):
67-
with lib.virtualfile_in(data=data, required_z=True, check_kind="vector"):
65+
with lib.virtualfile_in(data=data, ncols=3, check_kind="vector"):
6866
pass
6967

7068

69+
# TODO(PyGMT>=0.20.0): Remove this test for the deprecated 'required_z' parameter.
70+
def test_virtualfile_in_required_z_deprecated():
71+
"""
72+
Same as test_virtualfile_in_required_z_matrix_missing but using the deprecated
73+
'required_z' parameter.
74+
"""
75+
data = np.ones((5, 2))
76+
with clib.Session() as lib:
77+
with pytest.raises(GMTInvalidInput): # noqa: PT012
78+
with pytest.warns(FutureWarning):
79+
with lib.virtualfile_in(
80+
data=data, required_z=True, check_kind="vector"
81+
):
82+
pass
83+
84+
7185
def test_virtualfile_in_fail_non_valid_data(data):
7286
"""
7387
Should raise an exception if too few or too much data is given.
@@ -90,9 +104,7 @@ def test_virtualfile_in_fail_non_valid_data(data):
90104
continue
91105
with clib.Session() as lib:
92106
with pytest.raises(GMTInvalidInput):
93-
lib.virtualfile_in(
94-
x=variable[0], y=variable[1], z=variable[2], required_z=True
95-
)
107+
lib.virtualfile_in(x=variable[0], y=variable[1], z=variable[2], ncols=3)
96108

97109
# Should also fail if given too much data
98110
with clib.Session() as lib:

0 commit comments

Comments
 (0)