diff --git a/pygmt/datasets/samples.py b/pygmt/datasets/samples.py
index f6305c65d10..7e5df0f9e56 100644
--- a/pygmt/datasets/samples.py
+++ b/pygmt/datasets/samples.py
@@ -23,7 +23,7 @@ def _load_japan_quakes() -> pd.DataFrame:
The data table. The column names are "year", "month", "day", "latitude",
"longitude", "depth_km", and "magnitude" of the earthquakes.
"""
- fname = which("@tut_quakes.ngdc", download="c")
+ fname = which("@tut_quakes.ngdc", download="cache")
return pd.read_csv(
fname,
header=1,
@@ -49,7 +49,7 @@ def _load_ocean_ridge_points() -> pd.DataFrame:
data
The data table. The column names are "longitude" and "latitude".
"""
- fname = which("@ridge.txt", download="c")
+ fname = which("@ridge.txt", download="cache")
return pd.read_csv(
fname,
sep=r"\s+",
@@ -68,7 +68,7 @@ def _load_baja_california_bathymetry() -> pd.DataFrame:
data
The data table. The column names are "longitude", "latitude", and "bathymetry".
"""
- fname = which("@tut_ship.xyz", download="c")
+ fname = which("@tut_ship.xyz", download="cache")
return pd.read_csv(
fname, sep="\t", header=None, names=["longitude", "latitude", "bathymetry"]
)
@@ -83,7 +83,7 @@ def _load_usgs_quakes() -> pd.DataFrame:
data
The data table. Use ``print(data.describe())`` to see the available columns.
"""
- fname = which("@usgs_quakes_22.txt", download="c")
+ fname = which("@usgs_quakes_22.txt", download="cache")
return pd.read_csv(fname)
@@ -97,7 +97,7 @@ def _load_fractures_compilation() -> pd.DataFrame:
data
The data table. The column names are "length" and "azimuth" of the fractures.
"""
- fname = which("@fractures_06.txt", download="c")
+ fname = which("@fractures_06.txt", download="cache")
data = pd.read_csv(fname, header=None, sep=r"\s+", names=["azimuth", "length"])
return data[["length", "azimuth"]]
@@ -116,7 +116,7 @@ def _load_hotspots() -> pd.DataFrame:
The data table. The column names are "longitude", "latitude", "symbol_size", and
"place_name".
"""
- fname = which("@hotspots.txt", download="c")
+ fname = which("@hotspots.txt", download="cache")
return pd.read_csv(
fname,
sep="\t",
@@ -137,7 +137,7 @@ def _load_mars_shape() -> pd.DataFrame:
data
The data table. The column names are "longitude", "latitude", and "radius_m".
"""
- fname = which("@mars370d.txt", download="c")
+ fname = which("@mars370d.txt", download="cache")
return pd.read_csv(
fname, sep="\t", header=None, names=["longitude", "latitude", "radius_m"]
)
@@ -153,7 +153,7 @@ def _load_rock_sample_compositions() -> pd.DataFrame:
The data table. The column names are "limestone", "water", "air", and
"permittivity".
"""
- fname = which("@ternary.txt", download="c")
+ fname = which("@ternary.txt", download="cache")
return pd.read_csv(
fname,
sep=r"\s+",
@@ -173,7 +173,7 @@ def _load_notre_dame_topography() -> pd.DataFrame:
data
The data table. The column names are "x", "y", and "z".
"""
- fname = which("@Table_5_11.txt", download="c")
+ fname = which("@Table_5_11.txt", download="cache")
return pd.read_csv(fname, sep=r"\s+", header=None, names=["x", "y", "z"])
@@ -186,7 +186,7 @@ def _load_maunaloa_co2() -> pd.DataFrame:
data
The data table. The column names are "date" and "co2_ppm".
"""
- fname = which("@MaunaLoa_CO2.txt", download="c")
+ fname = which("@MaunaLoa_CO2.txt", download="cache")
return pd.read_csv(
fname, header=None, skiprows=1, sep=r"\s+", names=["date", "co2_ppm"]
)
@@ -202,7 +202,7 @@ def _load_earth_relief_holes() -> xr.DataArray:
The Earth relief grid. Coordinates are latitude and longitude in degrees. Relief
is in meters.
"""
- fname = which("@earth_relief_20m_holes.grd", download="c")
+ fname = which("@earth_relief_20m_holes.grd", download="cache")
return xr.load_dataarray(fname, engine="gmt", raster_kind="grid")
diff --git a/pygmt/helpers/caching.py b/pygmt/helpers/caching.py
index 6dc52e2fff8..4acce7143a2 100644
--- a/pygmt/helpers/caching.py
+++ b/pygmt/helpers/caching.py
@@ -134,4 +134,4 @@ def cache_data() -> None:
"@tut_ship.xyz",
"@usgs_quakes_22.txt",
]
- which(fname=datasets, download="a")
+ which(fname=datasets, download="auto")
diff --git a/pygmt/src/which.py b/pygmt/src/which.py
index 1b96ac6c61f..3dc884dd2e0 100644
--- a/pygmt/src/which.py
+++ b/pygmt/src/which.py
@@ -6,56 +6,63 @@
from typing import Literal
from pygmt._typing import PathLike
-from pygmt.alias import AliasSystem
+from pygmt.alias import Alias, AliasSystem
from pygmt.clib import Session
-from pygmt.helpers import build_arg_list, fmt_docstring, is_nonstr_iter, use_alias
+from pygmt.helpers import build_arg_list, fmt_docstring, is_nonstr_iter
@fmt_docstring
-@use_alias(G="download")
def which(
fname: PathLike | Sequence[PathLike],
+ download: Literal["auto", "cache", "local", "user"] | bool = False,
verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"]
| bool = False,
**kwargs,
) -> str | list[str]:
- r"""
+ """
Find full path to specified files.
- Reports the full paths to the files given through ``fname``. We look
- for the file in (1) the current directory, (2) in $GMT_USERDIR (if
- defined), (3) in $GMT_DATADIR (if defined), or (4) in $GMT_CACHEDIR
- (if defined).
+ Reports the full paths to the files given through ``fname``. It looks for the file
+ in (1) the current directory, (2) in $GMT_USERDIR (if defined), (3) in $GMT_DATADIR
+ (if defined), or (4) in $GMT_CACHEDIR (if defined).
- ``fname`` can also be a downloadable file (either a complete URL, an
- @file for downloading from the GMT data server, or any of the remote
- datasets at https://www.pygmt.org/latest/api/index.html#datasets).
- In these cases, use the ``download`` parameter to set the desired
- behavior. If ``download`` is not used (or ``False``), the file will
- not be found.
+ ``fname`` can also be a downloadable file (either a complete URL, an @file for
+ downloading from the GMT data server, or any of the
+ `GMT remote datasets `__.
+ In these cases, use the ``download`` parameter to set the desired behavior. If
+ ``download`` is not used (or ``False``), the file will not be found.
Full GMT docs at :gmt-docs:`gmtwhich.html`.
- $aliases
+ **Aliases:**
+
+ .. hlist::
+ :columns: 3
+
+ - G = download
- V = verbose
Parameters
----------
- fname : str or list
- One or more file names of any data type (grids, tables, etc.).
- download : bool or str
- [**a**\|\ **c**\|\ **l**\|\ **u**].
- If the ``fname`` argument is a downloadable file (either a complete
- URL, an @file for downloading from the GMT data server, or any of
- the remote datasets at
- https://www.pygmt.org/latest/api/index.html#datasets)
- we will try to download the file if it is not found in your local
- data or cache directories. If set to ``True`` or **l** is passed
- the file is downloaded to the current directory. Use **a** to place
- files in the appropriate folder under the user directory (this is
- where GMT normally places downloaded files), **c** to place it in
- the user cache directory, or **u** for the user data directory
- instead (i.e., ignoring any subdirectory structure).
+ fname
+ One or more file names to find the full path.
+ download
+ Try to download the file if it is not found in your local data or cache
+ directories and the file is downloadable. Here, downloadable files include:
+
+ - a file specified by a complete URL
+ - a GMT remote file on the GMT data server, specified with a leading ``@``.
+ - any of the `GMT remote datasets `__
+
+ Valid values are:
+
+ - ``False``: Do not download the file.
+ - ``True`` or ``"local"``: Download the file to the current directory.
+ - ``"cache"``: Download the file to the user cache directory.
+ - ``"user"``: Download the file to the user data directory but ignore any
+ subdirectory structure.
+ - ``"auto"``: Download the file to appropriate folder under the user directory
+ (this is where GMT normally places downloaded files).
$verbose
Returns
@@ -68,7 +75,13 @@ def which(
FileNotFoundError
If the file is not found.
"""
- aliasdict = AliasSystem().add_common(
+ aliasdict = AliasSystem(
+ G=Alias(
+ download,
+ name="download",
+ mapping={"auto": "a", "cache": "c", "local": "l", "user": "u"},
+ )
+ ).add_common(
V=verbose,
)
aliasdict.merge(kwargs)
diff --git a/pygmt/tests/test_datatypes_dataset.py b/pygmt/tests/test_datatypes_dataset.py
index 1d217e794a4..f170e22d7bf 100644
--- a/pygmt/tests/test_datatypes_dataset.py
+++ b/pygmt/tests/test_datatypes_dataset.py
@@ -160,7 +160,7 @@ def test_dataset_to_strings_with_none_values():
# Catch the FileNotFoundError exception so that we can focus on the bug.
tiles = ["@N30E060.earth_age_01m_g.nc", "@N30E090.earth_age_01m_g.nc"]
try:
- paths = which(fname=tiles, download="a")
+ paths = which(fname=tiles, download="auto")
assert len(paths) == 2
# 'paths' may contain an empty string or not, depending on if tiles are cached.
@@ -170,7 +170,7 @@ def test_dataset_to_strings_with_none_values():
Path(path).unlink()
with pytest.warns(expected_warning=RuntimeWarning) as record: # noqa: PT031
try:
- paths = which(fname=tiles, download="a")
+ paths = which(fname=tiles, download="auto")
assert len(record) == 1
assert len(paths) == 2
assert "" in paths
diff --git a/pygmt/tests/test_geopandas.py b/pygmt/tests/test_geopandas.py
index 3fd97579fa8..5202b2804f9 100644
--- a/pygmt/tests/test_geopandas.py
+++ b/pygmt/tests/test_geopandas.py
@@ -52,7 +52,7 @@ def fixture_gdf_ridge():
# Read shapefile into a geopandas.GeoDataFrame
shapefile = which(
fname=["@RidgeTest.shp", "@RidgeTest.shx", "@RidgeTest.dbf", "@RidgeTest.prj"],
- download="c",
+ download="cache",
)
gdf = geopandas.read_file(shapefile[0])
# Reproject the geometry
diff --git a/pygmt/tests/test_plot.py b/pygmt/tests/test_plot.py
index 20da1814cac..abfa69064eb 100644
--- a/pygmt/tests/test_plot.py
+++ b/pygmt/tests/test_plot.py
@@ -553,7 +553,7 @@ def test_plot_shapefile():
See https://github.com/GenericMappingTools/pygmt/issues/1616.
"""
datasets = ["@RidgeTest" + suffix for suffix in [".shp", ".shx", ".dbf", ".prj"]]
- which(fname=datasets, download="a")
+ which(fname=datasets, download="auto")
fig = Figure()
fig.plot(data="@RidgeTest.shp", pen="1p", frame=True)
return fig
diff --git a/pygmt/tests/test_surface.py b/pygmt/tests/test_surface.py
index a468a1e4c2b..9f25b8532cb 100644
--- a/pygmt/tests/test_surface.py
+++ b/pygmt/tests/test_surface.py
@@ -18,7 +18,7 @@ def fixture_data():
"""
Load Table 5.11 in Davis: Statistics and Data Analysis in Geology.
"""
- fname = which("@Table_5_11_mean.xyz", download="c")
+ fname = which("@Table_5_11_mean.xyz", download="cache")
return pd.read_csv(
fname, sep=r"\s+", header=None, names=["x", "y", "z"], skiprows=1
)
diff --git a/pygmt/tests/test_triangulate.py b/pygmt/tests/test_triangulate.py
index e4f19e03c92..114ebc31417 100644
--- a/pygmt/tests/test_triangulate.py
+++ b/pygmt/tests/test_triangulate.py
@@ -19,7 +19,7 @@ def fixture_dataframe():
"""
Load the table data from the sample bathymetry dataset.
"""
- fname = which("@Table_5_11_mean.xyz", download="c")
+ fname = which("@Table_5_11_mean.xyz", download="cache")
return pd.read_csv(
fname, sep=r"\s+", header=None, names=["x", "y", "z"], skiprows=1
)[:10]
diff --git a/pygmt/tests/test_which.py b/pygmt/tests/test_which.py
index 0bc453bc118..fd07b32b94b 100644
--- a/pygmt/tests/test_which.py
+++ b/pygmt/tests/test_which.py
@@ -18,7 +18,7 @@ def test_which():
Make sure `which` returns file paths for @files correctly without errors.
"""
for fname in ["tut_quakes.ngdc", "tut_bathy.nc"]:
- cached_file = which(fname=f"@{fname}", download="c")
+ cached_file = which(fname=f"@{fname}", download="cache")
assert Path(cached_file).exists()
assert Path(cached_file).name == fname
@@ -29,7 +29,7 @@ def test_which_multiple():
Make sure `which` returns file paths for multiple @files correctly.
"""
filenames = ["ridge.txt", "tut_ship.xyz"]
- cached_files = which([f"@{fname}" for fname in filenames], download="c")
+ cached_files = which([f"@{fname}" for fname in filenames], download="cache")
for cached_file in cached_files:
assert Path(cached_file).exists()
assert Path(cached_file).name in filenames
@@ -68,7 +68,7 @@ def test_which_nonascii_path(monkeypatch):
# Start a new session
begin()
# GMT should download the remote file under the new home directory.
- fname = which(fname="@static_earth_relief.nc", download="c")
+ fname = which(fname="@static_earth_relief.nc", download="cache")
assert fname.startswith(fakehome)
assert fname.endswith("static_earth_relief.nc")
end()
diff --git a/pygmt/tests/test_xarray_accessor.py b/pygmt/tests/test_xarray_accessor.py
index 6814245856e..d64de9e0689 100644
--- a/pygmt/tests/test_xarray_accessor.py
+++ b/pygmt/tests/test_xarray_accessor.py
@@ -122,7 +122,7 @@ def test_xarray_accessor_sliced_datacube():
try:
fname = which(
"https://github.com/pydata/xarray-data/raw/master/eraint_uvz.nc",
- download="u",
+ download="user",
)
with xr.open_dataset(fname, engine="netcdf4") as dataset:
grid = dataset.sel(level=500, month=1, drop=True).z