gmt
gmt copied to clipboard
Image is not cropped by `gmt end` via the API
The API can be used to create an image file with exactly the same instructions as a script. However, with or without the A option on the gmt begin
line, the figure is not cropped when gmt end show
is called.
Take this simple script:
gmt begin toto_script jpg
gmt basemap -BWESN -Bxa30mg30m -Bya20mg20m -JM7.27/42.27/16.25c -R5.5/41.425/9.0/43.1r
gmt end show
resulting in this image:
The same instructions via the API:
int main () {
void *API;
/* Initialize the GMT session */
if ((API = GMT_Create_Session ("GMT_plot", 2, 0, NULL)) == NULL)
return EXIT_FAILURE;
GMT_Call_Module(API, "begin", GMT_MODULE_CMD, "toto_api jpg");
GMT_Call_Module(API, "basemap", GMT_MODULE_CMD, "-BWESN -Bxa30mg30m -Bya20mg20m -JM7.27/42.27/16.25c -R5.5/41.425/9.0/43.1r");
GMT_Call_Module(API, "end", GMT_MODULE_CMD, "show");
/* Destroy session */
if (GMT_Destroy_Session (API))
return EXIT_FAILURE;
}
produce a different image, not cropped:
Running gmt end show -Vd
reveals the difference between script and API processing:
From script:
end [DEBUG]: psconvert: '/home/sarzeaud/.gmt/sessions/gmt_session.14414/gmt_0.ps-' -Tj -Ftoto -A
From C program (-A option is missing):
end [DEBUG]: psconvert: '/home/sarzeaud/.gmt/sessions/gmt_session.14414/gmt_0.ps-' -Tj -Ftoto
The result is the same whether or not we use the A option on the gmt begin
line.
System information
- Operating system: Debian stretch
- GMT version (
gmt --version
): 6.2.0_d266c30_2020.11.25
Thanks for this clear example, @sarzeaud. FYI, the API is mostly exercised by the gmt modules but probably more so by the external wrappers (gmtmex, GMT.jl, and PyGMT). We do not know how many like you are writing C code calling the API but we do know there are many pathways through the API that are not tested much. Even this simple example that shows a typical GMT command line thing (tested thousands of times by users probably) can fail when tried to be replicated by the C API. I will debug this and figure it out. I just wanted to let you know not to be too disappointed when you find these seemingly simple errors since I am probably the only one who are debugging them. You can see a handful of similar C examples called src/testapi*.c in the distro - including your recent spectrum1d entry - and in addition to your C code, if you are able to cast the whole bug test as we do (via a script in test/api that calls the testapi_* program) then we can more quickly add the script and test to the repo. For tests that make lots (such as yours) we also place an original PostScript plot that we measure against (this would be the PS version of your command line example with GMT_MEDIA=letter) and then our tests will flag it as failing.
OK, this is what happens.
gmtinit_process_figures()
calls
auto_size = gmtinit_check_if_autosize (API, fig[k].ID); /* Determine if the PostScript file has auto size enabled */
and in it it returns false because this test turns out to be false
if (strstr (file, "32767 32767")) return true; /* Max paper size means auto-sized media */
So, the problem is that somewhere it's missing that call that sets the wall size paper size.
BTW, this C example can very easily be reproduced from the Julia command line as (and no GMT.
would be necessary if run from a .jl file)
API = GMT.GMT_Create_Session("GMT", 2, GMT.GMT_SESSION_NOEXIT + GMT.GMT_SESSION_EXTERNAL + GMT.GMT_SESSION_COLMAJOR);
GMT.GMT_Call_Module(API, "begin", GMT.GMT_MODULE_CMD, "toto jpg");
GMT.GMT_Call_Module(API, "basemap", GMT.GMT_MODULE_CMD, "-BWESN -Bxa30mg30m -Bya20mg20m -JM7.27/42.27/16.25c -R5.5/41.425/9.0/43.1r");
GMT.GMT_Call_Module(API, "end", GMT.GMT_MODULE_CMD, "show");
GMT.GMT_Destroy_Session(API)
First of all, I will never ever be disappointed when I find a bug in GMT, because you really are making a great job with the GMT. And I am a developer too, I know how difficult it is to test all the ways a program will be used before it is effectively used by many people... To give the context, I have developed since 2005 the CTGeoS soft, which is used by Shom in France to make models of gravity and magnetic anomalies from global models and marine datasets. This soft is half java (to visualize models and data) and half C (to make the necessary computations), about 50,000 lines each, and the C part extensively uses GMT. In java, visualization uses home made classes to improve interactivity, but there is the possibility to make nice plots of what the user sees, and I also use GMT for that, in quite an automated manner. I have recently transform the old way of using GMT (system calls) by a new one based on the API, and for the C part it was a complete success. It is faster, and the code is much shorter. The problems that I find come from the java part, but I have nearly finished and I don't think I will find many more problems. Tomorrow, I will have a look at the way you do the bug tests, to see if I can help. Thanks again for your help, and your incredible responsiveness.
Looking at this now. One reason it fails is that while the script calls gmt begin which calls GMT_Create_Session for the first time, the C code separately calls GMT_Create_Session first, then calls the begin module. While GMT_Create_Session can accept the GMT_SESSION_RUNMODE argument it is not used here (0 is passed) but that does not seem to make a difference (I think). Still need to look more at the paths taken through this but other meetings are sneaking up on me... If I run this in debug and execute the first GMT_Create_Session call then restart the run (so the session directory already exists) then it works. So clearly tied to this initiation of the session prior to begin somehow.
I'm guessing that **GMT_MODERN ** is not set when
case GMTCASE_PS_MEDIA:
if (GMT->current.setting.run_mode == GMT_MODERN && !strcmp (lower_value, "auto")) {
gmtinit_setautopagesize (GMT);
break;
and the 11x11 m paper size is not set
Yes, but if I thinker with this so it gets set then almost all tests fail... So need a more sensible solution. Part one is that GMT_SESSION_RUNMODE must be given to GMT_Create_Session to establish a modern mode environment, rather that 0. this sets the run_mode internally and then I can at least have something to work with. But the next step is unclear and I may have to use API->external to distinguish command line calls (where gmt.c is involved and calls Create_Session) and just GMT_Call_Module (which results in no GMT_Create_Session. That is the key difference: what gmt.c does.
Just a comment to myself that as of Oct 13, 2021, the example C code still produces the same image with no cropping (GMT 6.3.0).