Skip to content

Commit 5d278fc

Browse files
committed
clib.Session: Add the virtualfile_to_data method for creating virtual files for output
1 parent ab39616 commit 5d278fc

File tree

2 files changed

+69
-0
lines changed

2 files changed

+69
-0
lines changed

doc/api/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ conversion of Python variables to GMT virtual files:
293293
clib.Session.virtualfile_from_matrix
294294
clib.Session.virtualfile_from_vectors
295295
clib.Session.virtualfile_from_grid
296+
clib.Session.virtualfile_to_data
296297

297298

298299
Low level access (these are mostly used by the :mod:`pygmt.clib` package):

pygmt/clib/session.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1609,6 +1609,74 @@ def virtualfile_from_data( # noqa: PLR0912
16091609

16101610
return file_context
16111611

1612+
@contextlib.contextmanager
1613+
def virtualfile_to_data(
1614+
self, kind: Literal["dataset", "grid", None] = None, fname: str | None = None
1615+
):
1616+
"""
1617+
Create a virtual file for storing output data in a data container or yield the
1618+
actual file name.
1619+
1620+
Parameters
1621+
----------
1622+
kind
1623+
The kind of data container to create. Valid values are ``"dataset"`` and
1624+
``"grid"`` or ``None``. Ignored if ``fname`` is specified.
1625+
fname
1626+
If given, yield the actual file name instead of the virtual file name.
1627+
1628+
Yields
1629+
------
1630+
vfile : str
1631+
Name of the virtual file or the output file name.
1632+
1633+
Examples
1634+
--------
1635+
>>> from pathlib import Path
1636+
>>> from pygmt.clib import Session
1637+
>>> from pygmt.datatypes import _GMT_DATASET, _GMT_GRID
1638+
>>> from pygmt.helpers import GMTTempFile
1639+
>>>
1640+
>>> # Create a virtual file for storing the output table.
1641+
>>> with GMTTempFile(suffix=".txt") as tmpfile:
1642+
... with open(tmpfile.name, mode="w") as fp:
1643+
... print("1.0 2.0 3.0 TEXT", file=fp)
1644+
... with Session() as lib:
1645+
... with lib.virtualfile_to_data(kind="dataset") as vouttbl:
1646+
... lib.call_module("read", f"{tmpfile.name} {vouttbl} -Td")
1647+
... ds = lib.read_virtualfile(vouttbl, kind="dataset")
1648+
>>> isinstance(ds.contents, _GMT_DATASET)
1649+
True
1650+
>>>
1651+
>>> # Create a virtual file for storing the output grid.
1652+
>>> with Session() as lib:
1653+
... with lib.virtualfile_to_data(kind="grid") as voutgrd:
1654+
... lib.call_module("read", f"@earth_relief_01d_g {voutgrd} -Tg")
1655+
... outgrd = lib.read_virtualfile(voutgrd, kind="grid")
1656+
>>> isinstance(outgrd.contents, _GMT_GRID)
1657+
True
1658+
>>>
1659+
>>> # Write data to file without creating a virtual file
1660+
>>> with GMTTempFile(suffix=".nc") as tmpfile:
1661+
... with Session() as lib:
1662+
... with lib.virtualfile_to_data(fname=tmpfile.name) as voutgrd:
1663+
... lib.call_module("read", f"@earth_relief_01d_g {voutgrd} -Tg")
1664+
... assert voutgrd == tmpfile.name
1665+
... assert Path(voutgrd).stat().st_size > 0
1666+
"""
1667+
# If fname is given, yield the output file name.
1668+
if fname is not None:
1669+
yield fname
1670+
# Otherwise, create a virtual file for storing the output data.
1671+
else:
1672+
# Determine the family and geometry from kind
1673+
family, geometry = {
1674+
"grid": ("GMT_IS_GRID", "GMT_IS_SURFACE"),
1675+
"dataset": ("GMT_IS_DATASET", "GMT_IS_PLP"),
1676+
}[kind]
1677+
with self.open_virtualfile(family, geometry, "GMT_OUT", None) as vfile:
1678+
yield vfile
1679+
16121680
def read_virtualfile(
16131681
self, vfname: str, kind: Literal["dataset", "grid", None] = None
16141682
):

0 commit comments

Comments
 (0)