From a840d9a60c7afe61f8722ffaa33ba83b20beca76 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Fri, 21 Apr 2023 13:53:02 +0800 Subject: [PATCH] clib.Session: Wrap the GMT_Get_Common API function (#2500) Co-authored-by: Wei Ji <23487320+weiji14@users.noreply.github.com> --- doc/api/index.rst | 1 + pygmt/clib/session.py | 91 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) diff --git a/doc/api/index.rst b/doc/api/index.rst index 29c1ea3bdf1..9ce697b5fbd 100644 --- a/doc/api/index.rst +++ b/doc/api/index.rst @@ -302,6 +302,7 @@ Low level access (these are mostly used by the :mod:`pygmt.clib` package): clib.Session.__enter__ clib.Session.__exit__ clib.Session.get_default + clib.Session.get_common clib.Session.create_data clib.Session.put_matrix clib.Session.put_strings diff --git a/pygmt/clib/session.py b/pygmt/clib/session.py index d80ac6f1ee9..d7f1b585f8d 100644 --- a/pygmt/clib/session.py +++ b/pygmt/clib/session.py @@ -494,6 +494,97 @@ def get_default(self, name): return value.value.decode() + def get_common(self, option): + """ + Inquire if a GMT common option has been set and return its current + value if possible. + + Parameters + ---------- + option : str + The GMT common option to check. Valid options are ``"B"``, ``"I"``, + ``"J"``, ``"R"``, ``"U"``, ``"V"``, ``"X"``, ``"Y"``, ``"a"``, + ``"b"``, ``"f"``, ``"g"``, ``"h"``, ``"i"``, ``"n"``, ``"o"``, + ``"p"``, ``"r"``, ``"s"``, ``"t"``, and ``":"``. + + Returns + ------- + value : bool, int, float, or numpy.ndarray + Whether the option was set or its value. + + If the option was not set, return ``False``. Otherwise, + the return value depends on the choice of the option. + + - options ``"B"``, ``"J"``, ``"U"``, ``"g"``, ``"n"``, ``"p"``, + and ``"s"``: return ``True`` if set, else ``False`` (bool) + - ``"I"``: 2-element array for the increments (float) + - ``"R"``: 4-element array for the region (float) + - ``"V"``: the verbose level (int) + - ``"X"``: the xshift (float) + - ``"Y"``: the yshift (float) + - ``"a"``: geometry of the dataset (int) + - ``"b"``: return 0 if `-bi` was set and 1 if `-bo` was set (int) + - ``"f"``: return 0 if `-fi` was set and 1 if `-fo` was set (int) + - ``"h"``: whether to delete existing header records (int) + - ``"i"``: number of input columns (int) + - ``"o"``: number of output columns (int) + - ``"r"``: registration type (int) + - ``"t"``: 2-element array for the transparency (float) + - ``":"``: return 0 if `-:i` was set and 1 if `-:o` was set (int) + + Examples + -------- + >>> with Session() as lib: + ... lib.call_module("basemap", "-R0/10/10/15 -JX5i/2.5i -Baf -Ve") + ... region = lib.get_common("R") + ... projection = lib.get_common("J") + ... timestamp = lib.get_common("U") + ... verbose = lib.get_common("V") + ... lib.call_module("plot", "-T -Xw+1i -Yh-1i") + ... xshift = lib.get_common("X") # xshift/yshift are in inches + ... yshift = lib.get_common("Y") + ... + >>> print(region, projection, timestamp, verbose, xshift, yshift) + [ 0. 10. 10. 15.] True False 3 6.0 1.5 + >>> with Session() as lib: + ... lib.call_module("basemap", "-R0/10/10/15 -JX5i/2.5i -Baf") + ... lib.get_common("A") + ... + Traceback (most recent call last): + ... + pygmt.exceptions.GMTInvalidInput: Unknown GMT common option flag 'A'. + """ + if option not in "BIJRUVXYabfghinoprst:": + raise GMTInvalidInput(f"Unknown GMT common option flag '{option}'.") + + c_get_common = self.get_libgmt_func( + "GMT_Get_Common", + argtypes=[ctp.c_void_p, ctp.c_uint, ctp.POINTER(ctp.c_double)], + restype=ctp.c_int, + ) + value = np.empty(6) # numpy array to store the value of the option + status = c_get_common( + self.session_pointer, + ord(option), + value.ctypes.data_as(ctp.POINTER(ctp.c_double)), + ) + + # GMT_NOTSET (-1) means the option is not set + if status == self["GMT_NOTSET"]: + return False + # option is set and no other value is returned + if status == 0: + return True + # option is set and option values (in double type) are returned via the + # 'value' array. 'status' is number of valid values in the array. + if option in "IRt": + return value[:status] + if option in "XY": # only one valid element in the array + return value[0] + # option is set and the option value (in integer type) is returned via + # the function return value (i.e., 'status') + return status + def call_module(self, module, args): """ Call a GMT module with the given arguments.