From 336374456b0ce7a865a0a7111db28d5922deda2f Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Mon, 10 Apr 2023 09:45:18 +0800 Subject: [PATCH 1/7] clib.Session: Wrap the GMT_Get_Common API function --- pygmt/clib/session.py | 83 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/pygmt/clib/session.py b/pygmt/clib/session.py index d80ac6f1ee9..fa3b45fe873 100644 --- a/pygmt/clib/session.py +++ b/pygmt/clib/session.py @@ -494,6 +494,89 @@ 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 or int, float or numpy.ndarray + Whether the option was set or its value. + + If the option was not set, return ``False``. Otherwise, + value depends on the choice of the option. + + - options ``"B"``, ``"J"``, ``"U"``, ``"g"``, ``"n"``, ``"p"``, + and ``"s"``: return ``True`` + - ``"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"``: the option was set for input or output (int) + - ``"f"``: the option was set for input or output (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) + - ``":"``: the option was set for input or output (int) + + Examples + -------- + >>> with Session() as lib: + ... lib.call_module("basemap", "-R0/10/10/15 -JX5i/2.5i -Baf") + ... region = lib.get_common("R") + ... projection = lib.get_common("J") + ... timestamp = lib.get_common("U") + ... 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, xshift, yshift) + [ 0. 10. 10. 15.] True False 6.0 1.5 + """ + if option not in "BIJRUVXYabfghinoprst:": + raise GMTInvalidInput(f"Unknown GMT 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 interger 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. From 7048cde3dc56503b67bb15af98d5fd175c0cbc66 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Tue, 18 Apr 2023 09:08:37 +0800 Subject: [PATCH 2/7] Improve test coverage --- pygmt/clib/session.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/pygmt/clib/session.py b/pygmt/clib/session.py index fa3b45fe873..68e5f4e9760 100644 --- a/pygmt/clib/session.py +++ b/pygmt/clib/session.py @@ -535,16 +535,24 @@ def get_common(self, option): Examples -------- >>> with Session() as lib: - ... lib.call_module("basemap", "-R0/10/10/15 -JX5i/2.5i -Baf") + ... 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, xshift, yshift) - [ 0. 10. 10. 15.] True False 6.0 1.5 + >>> 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 option flag 'A'. """ if option not in "BIJRUVXYabfghinoprst:": raise GMTInvalidInput(f"Unknown GMT option flag '{option}'.") @@ -573,7 +581,7 @@ def get_common(self, option): 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 interger type) is returned via + # option is set and the option value (in integer type) is returned via # the function return value (i.e., 'status') return status From 537a67ddbfe43f09952be4e62e4f1952ad61b91f Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Tue, 18 Apr 2023 13:11:36 +0800 Subject: [PATCH 3/7] Minor fixes --- pygmt/clib/session.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pygmt/clib/session.py b/pygmt/clib/session.py index 68e5f4e9760..2157aa70d3c 100644 --- a/pygmt/clib/session.py +++ b/pygmt/clib/session.py @@ -509,11 +509,11 @@ def get_common(self, option): Returns ------- - value : bool or int, float or numpy.ndarray + value : bool, int, float, or numpy.ndarray Whether the option was set or its value. If the option was not set, return ``False``. Otherwise, - value depends on the choice of the option. + the return value depends on the choice of the option. - options ``"B"``, ``"J"``, ``"U"``, ``"g"``, ``"n"``, ``"p"``, and ``"s"``: return ``True`` @@ -555,7 +555,7 @@ def get_common(self, option): pygmt.exceptions.GMTInvalidInput: Unknown GMT option flag 'A'. """ if option not in "BIJRUVXYabfghinoprst:": - raise GMTInvalidInput(f"Unknown GMT option flag '{option}'.") + raise GMTInvalidInput(f"Unknown GMT common option flag '{option}'.") c_get_common = self.get_libgmt_func( "GMT_Get_Common", From 49b825cd9d87e2c90364613cf6778d915426abd3 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Tue, 18 Apr 2023 14:52:05 +0800 Subject: [PATCH 4/7] Fix the broken doctests --- pygmt/clib/session.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pygmt/clib/session.py b/pygmt/clib/session.py index 2157aa70d3c..fa662b83d82 100644 --- a/pygmt/clib/session.py +++ b/pygmt/clib/session.py @@ -552,7 +552,7 @@ def get_common(self, option): ... Traceback (most recent call last): ... - pygmt.exceptions.GMTInvalidInput: Unknown GMT option flag 'A'. + pygmt.exceptions.GMTInvalidInput: Unknown GMT common option flag 'A'. """ if option not in "BIJRUVXYabfghinoprst:": raise GMTInvalidInput(f"Unknown GMT common option flag '{option}'.") From 41295c2052a448bc903018df7ff06ef53df941f9 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Fri, 21 Apr 2023 10:25:13 +0800 Subject: [PATCH 5/7] Fix docstrings for -b, -f and -: --- pygmt/clib/session.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pygmt/clib/session.py b/pygmt/clib/session.py index fa662b83d82..792cf59ec6f 100644 --- a/pygmt/clib/session.py +++ b/pygmt/clib/session.py @@ -523,14 +523,14 @@ def get_common(self, option): - ``"X"``: the xshift (float) - ``"Y"``: the yshift (float) - ``"a"``: geometry of the dataset (int) - - ``"b"``: the option was set for input or output (int) - - ``"f"``: the option was set for input or output (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) - - ``":"``: the option was set for input or output (int) + - ``":"``: return 0 if `-:i` was set and 1 if `-:o` was set (int) Examples -------- From 9fb950db28755243a3785bd67d464f747579bc34 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Fri, 21 Apr 2023 12:01:39 +0800 Subject: [PATCH 6/7] Add get_common to API docs --- doc/api/index.rst | 1 + 1 file changed, 1 insertion(+) 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 From a894e20406e3c90b889e3867d4f171768b835027 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Fri, 21 Apr 2023 12:04:47 +0800 Subject: [PATCH 7/7] Update pygmt/clib/session.py Co-authored-by: Wei Ji <23487320+weiji14@users.noreply.github.com> --- pygmt/clib/session.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pygmt/clib/session.py b/pygmt/clib/session.py index 792cf59ec6f..d7f1b585f8d 100644 --- a/pygmt/clib/session.py +++ b/pygmt/clib/session.py @@ -516,7 +516,7 @@ def get_common(self, option): the return value depends on the choice of the option. - options ``"B"``, ``"J"``, ``"U"``, ``"g"``, ``"n"``, ``"p"``, - and ``"s"``: return ``True`` + 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)