Skip to content

Commit

Permalink
Refractor build_arg_string to also deal with infile and outfile (Gene…
Browse files Browse the repository at this point in the history
  • Loading branch information
seisman authored and Josh Sixsmith committed Dec 21, 2022
1 parent 11438a8 commit b4d36f2
Show file tree
Hide file tree
Showing 44 changed files with 111 additions and 111 deletions.
48 changes: 33 additions & 15 deletions pygmt/helpers/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,12 @@ def dummy_context(arg):
yield arg


def build_arg_string(kwargs):
def build_arg_string(kwdict, infile=None, outfile=None):
r"""
Transform keyword arguments into a GMT argument string.
Convert a dict and optional input/output files into a GMT argument string.
Make sure all arguments have been previously converted to a string
representation using the ``kwargs_to_strings`` decorator. The only
Make sure all values in ``kwdict`` have been previously converted to a
string representation using the ``kwargs_to_strings`` decorator. The only
exceptions are True, False and None.
Any lists or tuples left will be interpreted as multiple entries for the
Expand All @@ -138,14 +138,19 @@ def build_arg_string(kwargs):
Parameters
----------
kwargs : dict
Parsed keyword arguments.
kwdict : dict
A dict containing parsed keyword arguments.
infile : str or pathlib.Path
The input file.
outfile : str or pathlib.Path
The output file.
Returns
-------
args : str
The space-delimited argument string with '-' inserted before each
keyword. The arguments are sorted alphabetically.
keyword. The arguments are sorted alphabetically, with optional input
file at the begining and optioanl output file at the end.
Examples
--------
Expand Down Expand Up @@ -191,29 +196,42 @@ def build_arg_string(kwargs):
... )
... )
-BWSne+tBlank\040Space -Baf -F+t"Empty\040\040Spaces" -l'Void\040Space'
>>> print(
... build_arg_string(
... dict(A="0", B=True, C="rainbow"),
... infile="input.txt",
... outfile="output.txt",
... )
... )
input.txt -A0 -B -Crainbow ->output.txt
"""
gmt_args = []

for key in kwargs:
for key in kwdict:
if len(key) > 2: # raise an exception for unrecognized options
raise GMTInvalidInput(f"Unrecognized parameter '{key}'.")
if kwargs[key] is None or kwargs[key] is False:
if kwdict[key] is None or kwdict[key] is False:
pass # Exclude arguments that are None and False
elif is_nonstr_iter(kwargs[key]):
for value in kwargs[key]:
elif is_nonstr_iter(kwdict[key]):
for value in kwdict[key]:
_value = str(value).replace(" ", r"\040")
gmt_args.append(rf"-{key}{_value}")
elif kwargs[key] is True:
elif kwdict[key] is True:
gmt_args.append(f"-{key}")
else:
if key != "J": # non-projection parameters
_value = str(kwargs[key]).replace(" ", r"\040")
_value = str(kwdict[key]).replace(" ", r"\040")
else:
# special handling if key == "J" (projection)
# remove any spaces in PROJ4 string
_value = str(kwargs[key]).replace(" ", "")
_value = str(kwdict[key]).replace(" ", "")
gmt_args.append(rf"-{key}{_value}")
return " ".join(sorted(gmt_args))
gmt_args = sorted(gmt_args)
if infile:
gmt_args = [str(infile)] + gmt_args
if outfile:
gmt_args.append("->" + str(outfile))
return " ".join(gmt_args)


def is_nonstr_iter(value):
Expand Down
6 changes: 4 additions & 2 deletions pygmt/src/blockm.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,10 @@ def _blockm(block_method, data, x, y, z, outfile, **kwargs):
with table_context as infile:
if outfile is None:
outfile = tmpfile.name
arg_str = " ".join([infile, build_arg_string(kwargs), "->" + outfile])
lib.call_module(module=block_method, args=arg_str)
lib.call_module(
module=block_method,
args=build_arg_string(kwargs, infile=infile, outfile=outfile),
)

# Read temporary csv output to a pandas table
if outfile == tmpfile.name: # if user did not set outfile, return pd.DataFrame
Expand Down
3 changes: 1 addition & 2 deletions pygmt/src/contour.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,5 +132,4 @@ def contour(self, data=None, x=None, y=None, z=None, **kwargs):
check_kind="vector", data=data, x=x, y=y, z=z, required_z=True
)
with file_context as fname:
arg_str = " ".join([fname, build_arg_string(kwargs)])
lib.call_module("contour", arg_str)
lib.call_module("contour", build_arg_string(kwargs, infile=fname))
8 changes: 3 additions & 5 deletions pygmt/src/grd2cpt.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,12 +166,10 @@ def grd2cpt(grid, **kwargs):
file_context = lib.virtualfile_from_data(check_kind="raster", data=grid)
with file_context as infile:
if "H" not in kwargs: # if no output is set
arg_str = " ".join([infile, build_arg_string(kwargs)])
arg_str = build_arg_string(kwargs, infile=infile)
if "H" in kwargs: # if output is set
outfile = kwargs.pop("H")
outfile, kwargs["H"] = kwargs["H"], True
if not outfile or not isinstance(outfile, str):
raise GMTInvalidInput("'output' should be a proper file name.")
arg_str = " ".join(
[infile, build_arg_string(kwargs), f"-H > {outfile}"]
)
arg_str = build_arg_string(kwargs, infile=infile, outfile=outfile)
lib.call_module("grd2cpt", arg_str)
5 changes: 3 additions & 2 deletions pygmt/src/grd2xyz.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,9 @@ def grd2xyz(grid, output_type="pandas", outfile=None, **kwargs):
with file_context as infile:
if outfile is None:
outfile = tmpfile.name
arg_str = " ".join([infile, build_arg_string(kwargs), "->" + outfile])
lib.call_module("grd2xyz", arg_str)
lib.call_module(
"grd2xyz", build_arg_string(kwargs, infile=infile, outfile=outfile)
)

# Read temporary csv output to a pandas table
if outfile == tmpfile.name: # if user did not set outfile, return pd.DataFrame
Expand Down
3 changes: 1 addition & 2 deletions pygmt/src/grdclip.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@ def grdclip(grid, **kwargs):
if "G" not in kwargs: # if outgrid is unset, output to tempfile
kwargs.update({"G": tmpfile.name})
outgrid = kwargs["G"]
arg_str = " ".join([infile, build_arg_string(kwargs)])
lib.call_module("grdclip", arg_str)
lib.call_module("grdclip", build_arg_string(kwargs, infile=infile))

return load_dataarray(outgrid) if outgrid == tmpfile.name else None
3 changes: 1 addition & 2 deletions pygmt/src/grdcontour.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,5 +100,4 @@ def grdcontour(self, grid, **kwargs):
with Session() as lib:
file_context = lib.virtualfile_from_data(check_kind="raster", data=grid)
with file_context as fname:
arg_str = " ".join([fname, build_arg_string(kwargs)])
lib.call_module("grdcontour", arg_str)
lib.call_module("grdcontour", build_arg_string(kwargs, infile=fname))
3 changes: 1 addition & 2 deletions pygmt/src/grdcut.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ def grdcut(grid, **kwargs):
if "G" not in kwargs: # if outgrid is unset, output to tempfile
kwargs.update({"G": tmpfile.name})
outgrid = kwargs["G"]
arg_str = " ".join([infile, build_arg_string(kwargs)])
lib.call_module("grdcut", arg_str)
lib.call_module("grdcut", build_arg_string(kwargs, infile=infile))

return load_dataarray(outgrid) if outgrid == tmpfile.name else None
3 changes: 1 addition & 2 deletions pygmt/src/grdfill.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ def grdfill(grid, **kwargs):
if "G" not in kwargs: # if outgrid is unset, output to tempfile
kwargs.update({"G": tmpfile.name})
outgrid = kwargs["G"]
arg_str = " ".join([infile, build_arg_string(kwargs)])
lib.call_module("grdfill", arg_str)
lib.call_module("grdfill", build_arg_string(kwargs, infile=infile))

return load_dataarray(outgrid) if outgrid == tmpfile.name else None
3 changes: 1 addition & 2 deletions pygmt/src/grdfilter.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,6 @@ def grdfilter(grid, **kwargs):
if "G" not in kwargs: # if outgrid is unset, output to tempfile
kwargs.update({"G": tmpfile.name})
outgrid = kwargs["G"]
arg_str = " ".join([infile, build_arg_string(kwargs)])
lib.call_module("grdfilter", arg_str)
lib.call_module("grdfilter", build_arg_string(kwargs, infile=infile))

return load_dataarray(outgrid) if outgrid == tmpfile.name else None
3 changes: 1 addition & 2 deletions pygmt/src/grdgradient.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,6 @@ def grdgradient(grid, **kwargs):
if "G" not in kwargs: # if outgrid is unset, output to tempfile
kwargs.update({"G": tmpfile.name})
outgrid = kwargs["G"]
arg_str = " ".join([infile, build_arg_string(kwargs)])
lib.call_module("grdgradient", arg_str)
lib.call_module("grdgradient", build_arg_string(kwargs, infile=infile))

return load_dataarray(outgrid) if outgrid == tmpfile.name else None
3 changes: 1 addition & 2 deletions pygmt/src/grdhisteq.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,7 @@ def _grdhisteq(grid, output_type, **kwargs):
with Session() as lib:
file_context = lib.virtualfile_from_data(check_kind="raster", data=grid)
with file_context as infile:
arg_str = " ".join([infile, build_arg_string(kwargs)])
lib.call_module("grdhisteq", arg_str)
lib.call_module("grdhisteq", build_arg_string(kwargs, infile=infile))

if output_type == "file":
return None
Expand Down
3 changes: 1 addition & 2 deletions pygmt/src/grdimage.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,5 +171,4 @@ def grdimage(self, grid, **kwargs):
kwargs["I"] = stack.enter_context(shading_context)

fname = stack.enter_context(file_context)
arg_str = " ".join([fname, build_arg_string(kwargs)])
lib.call_module("grdimage", arg_str)
lib.call_module("grdimage", build_arg_string(kwargs, infile=fname))
6 changes: 3 additions & 3 deletions pygmt/src/grdinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,9 @@ def grdinfo(grid, **kwargs):
with Session() as lib:
file_context = lib.virtualfile_from_data(check_kind="raster", data=grid)
with file_context as infile:
arg_str = " ".join(
[infile, build_arg_string(kwargs), "->" + outfile.name]
lib.call_module(
"grdinfo",
build_arg_string(kwargs, infile=infile, outfile=outfile.name),
)
lib.call_module("grdinfo", arg_str)
result = outfile.read()
return result
3 changes: 1 addition & 2 deletions pygmt/src/grdlandmask.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ def grdlandmask(**kwargs):
if "G" not in kwargs: # if outgrid is unset, output to tempfile
kwargs.update({"G": tmpfile.name})
outgrid = kwargs["G"]
arg_str = build_arg_string(kwargs)
lib.call_module("grdlandmask", arg_str)
lib.call_module("grdlandmask", build_arg_string(kwargs))

return load_dataarray(outgrid) if outgrid == tmpfile.name else None
3 changes: 1 addition & 2 deletions pygmt/src/grdproject.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@ def grdproject(grid, **kwargs):
if "G" not in kwargs: # if outgrid is unset, output to tempfile
kwargs.update({"G": tmpfile.name})
outgrid = kwargs["G"]
arg_str = " ".join([infile, build_arg_string(kwargs)])
lib.call_module("grdproject", arg_str)
lib.call_module("grdproject", build_arg_string(kwargs, infile=infile))

return load_dataarray(outgrid) if outgrid == tmpfile.name else None
3 changes: 1 addition & 2 deletions pygmt/src/grdsample.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ def grdsample(grid, **kwargs):
if "G" not in kwargs: # if outgrid is unset, output to tempfile
kwargs.update({"G": tmpfile.name})
outgrid = kwargs["G"]
arg_str = " ".join([infile, build_arg_string(kwargs)])
lib.call_module("grdsample", arg_str)
lib.call_module("grdsample", build_arg_string(kwargs, infile=infile))

return load_dataarray(outgrid) if outgrid == tmpfile.name else None
6 changes: 3 additions & 3 deletions pygmt/src/grdtrack.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,10 +300,10 @@ def grdtrack(points, grid, newcolname=None, outfile=None, **kwargs):
kwargs.update({"G": grdfile})
if outfile is None: # Output to tmpfile if outfile is not set
outfile = tmpfile.name
arg_str = " ".join(
[csvfile, build_arg_string(kwargs), "->" + outfile]
lib.call_module(
module="grdtrack",
args=build_arg_string(kwargs, infile=csvfile, outfile=outfile),
)
lib.call_module(module="grdtrack", args=arg_str)

# Read temporary csv output to a pandas table
if outfile == tmpfile.name: # if user did not set outfile, return pd.DataFrame
Expand Down
3 changes: 1 addition & 2 deletions pygmt/src/grdview.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,5 +137,4 @@ def grdview(self, grid, **kwargs):
f"Unrecognized data type for drapegrid: {type(drapegrid)}"
)
fname = stack.enter_context(file_context)
arg_str = " ".join([fname, build_arg_string(kwargs)])
lib.call_module("grdview", arg_str)
lib.call_module("grdview", build_arg_string(kwargs, infile=fname))
6 changes: 4 additions & 2 deletions pygmt/src/grdvolume.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,10 @@ def grdvolume(grid, output_type="pandas", outfile=None, **kwargs):
with file_context as infile:
if outfile is None:
outfile = tmpfile.name
arg_str = " ".join([infile, build_arg_string(kwargs), "->" + outfile])
lib.call_module("grdvolume", arg_str)
lib.call_module(
"grdvolume",
build_arg_string(kwargs, infile=infile, outfile=outfile),
)

# Read temporary csv output to a pandas table
if outfile == tmpfile.name: # if user did not set outfile, return pd.DataFrame
Expand Down
3 changes: 1 addition & 2 deletions pygmt/src/histogram.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,5 +148,4 @@ def histogram(self, data, **kwargs):
with Session() as lib:
file_context = lib.virtualfile_from_data(check_kind="vector", data=data)
with file_context as infile:
arg_str = " ".join([infile, build_arg_string(kwargs)])
lib.call_module("histogram", arg_str)
lib.call_module("histogram", build_arg_string(kwargs, infile=infile))
3 changes: 1 addition & 2 deletions pygmt/src/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,4 @@ def image(self, imagefile, **kwargs):
"""
kwargs = self._preprocess(**kwargs) # pylint: disable=protected-access
with Session() as lib:
arg_str = " ".join([imagefile, build_arg_string(kwargs)])
lib.call_module("image", arg_str)
lib.call_module("image", build_arg_string(kwargs, infile=imagefile))
5 changes: 2 additions & 3 deletions pygmt/src/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,9 @@ def info(data, **kwargs):
file_context = lib.virtualfile_from_data(check_kind="vector", data=data)
with GMTTempFile() as tmpfile:
with file_context as fname:
arg_str = " ".join(
[fname, build_arg_string(kwargs), "->" + tmpfile.name]
lib.call_module(
"info", build_arg_string(kwargs, infile=fname, outfile=tmpfile.name)
)
lib.call_module("info", arg_str)
result = tmpfile.read()

if any(arg in kwargs for arg in ["C", "I", "T"]):
Expand Down
3 changes: 1 addition & 2 deletions pygmt/src/legend.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,5 +87,4 @@ def legend(self, spec=None, position="JTR+jTR+o0.2c", box="+gwhite+p1p", **kwarg
specfile = spec
else:
raise GMTInvalidInput(f"Unrecognized data type: {type(spec)}")
arg_str = " ".join([specfile, build_arg_string(kwargs)])
lib.call_module("legend", arg_str)
lib.call_module("legend", build_arg_string(kwargs, infile=specfile))
4 changes: 2 additions & 2 deletions pygmt/src/makecpt.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,8 @@ def makecpt(**kwargs):
if "H" not in kwargs: # if no output is set
arg_str = build_arg_string(kwargs)
elif "H" in kwargs: # if output is set
outfile = kwargs.pop("H")
outfile, kwargs["H"] = kwargs.pop("H"), True
if not outfile or not isinstance(outfile, str):
raise GMTInvalidInput("'output' should be a proper file name.")
arg_str = " ".join([build_arg_string(kwargs), f"-H > {outfile}"])
arg_str = build_arg_string(kwargs, outfile=outfile)
lib.call_module(module="makecpt", args=arg_str)
3 changes: 1 addition & 2 deletions pygmt/src/meca.py
Original file line number Diff line number Diff line change
Expand Up @@ -464,5 +464,4 @@ def update_pointers(data_pointers):
else:
raise GMTInvalidInput(f"Unrecognized data type: {type(spec)}")
with file_context as fname:
arg_str = " ".join([fname, build_arg_string(kwargs)])
lib.call_module("meca", arg_str)
lib.call_module("meca", build_arg_string(kwargs, infile=fname))
5 changes: 3 additions & 2 deletions pygmt/src/nearneighbor.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@ def nearneighbor(data=None, x=None, y=None, z=None, **kwargs):
if "G" not in kwargs: # if outgrid is unset, output to tmpfile
kwargs.update({"G": tmpfile.name})
outgrid = kwargs["G"]
arg_str = " ".join([infile, build_arg_string(kwargs)])
lib.call_module(module="nearneighbor", args=arg_str)
lib.call_module(
module="nearneighbor", args=build_arg_string(kwargs, infile=infile)
)

return load_dataarray(outgrid) if outgrid == tmpfile.name else None
3 changes: 1 addition & 2 deletions pygmt/src/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,5 +266,4 @@ def plot(self, data=None, x=None, y=None, size=None, direction=None, **kwargs):
)

with file_context as fname:
arg_str = " ".join([fname, build_arg_string(kwargs)])
lib.call_module("plot", arg_str)
lib.call_module("plot", build_arg_string(kwargs, infile=fname))
3 changes: 1 addition & 2 deletions pygmt/src/plot3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,5 +242,4 @@ def plot3d(
)

with file_context as fname:
arg_str = " ".join([fname, build_arg_string(kwargs)])
lib.call_module("plot3d", arg_str)
lib.call_module("plot3d", build_arg_string(kwargs, infile=fname))
6 changes: 2 additions & 4 deletions pygmt/src/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,11 +233,9 @@ def project(data=None, x=None, y=None, z=None, outfile=None, **kwargs):

# Run project on the temporary (csv) data table
with table_context as infile:
arg_str = " ".join(
[infile, build_arg_string(kwargs), "->" + outfile]
)
arg_str = build_arg_string(kwargs, infile=infile, outfile=outfile)
else:
arg_str = " ".join([build_arg_string(kwargs), "->" + outfile])
arg_str = build_arg_string(kwargs, outfile=outfile)
lib.call_module(module="project", args=arg_str)

# if user did not set outfile, return pd.DataFrame
Expand Down
4 changes: 1 addition & 3 deletions pygmt/src/rose.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,4 @@ def rose(self, data=None, length=None, azimuth=None, **kwargs):
)

with file_context as fname:
arg_str = " ".join([fname, build_arg_string(kwargs)])

lib.call_module("rose", arg_str)
lib.call_module("rose", build_arg_string(kwargs, infile=fname))
6 changes: 4 additions & 2 deletions pygmt/src/select.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,10 @@ def select(data=None, outfile=None, **kwargs):
with table_context as infile:
if outfile is None:
outfile = tmpfile.name
arg_str = " ".join([infile, build_arg_string(kwargs), "->" + outfile])
lib.call_module(module="gmtselect", args=arg_str)
lib.call_module(
module="gmtselect",
args=build_arg_string(kwargs, infile=infile, outfile=outfile),
)

# Read temporary csv output to a pandas table
if outfile == tmpfile.name: # if user did not set outfile, return pd.DataFrame
Expand Down
Loading

0 comments on commit b4d36f2

Please sign in to comment.