GMT Classic and Modern Runtime Modes

Updated June 17, 2017 Paul Wessel

Background and Motivation

GMT has always had a pretty steep learning curve. The hardest aspects have risen to the top of the "rookie error" list:

  1. The GMT "cake-baking": Handling the use of -O and -K to manage overlays.
  2. The PostScript redirection: Creating versus appending to a file.
  3. Reusing the current region (-R) and projection (-J) in multi-step scripts.
  4. Converting the PostScript plot to more desirable graphic formats.

While pondering these facts, we have also started to gain experience with the MATLAB and Octave toolboxes and to plan the preliminary design of the Python package. We were noticing that the resulting scripts look too much like the GMT shell command-line versions, setting users up for more rookie errors. Meanwhile, we are also aware that there are tens of thousands of existing GMT scripts that we do not want to break by introducing radical changes. The solution is to introduce a new GMT "run mode", which is maintained internally. Depending on how GMT is started it will either be running in classic or modern mode. Classic mode is the GMT scripting in use for decades and it will remain the default mode for command-line work. The modern mode invokes simpler rules that eliminate the possibility of the listed rookie errors and simplify scripting considerably across all interfaces. It also imposes a structure and hence not every single classic strict can be represented in modern mode. Consequently, modern mode is less flexible but much easier to use, and we expect it will serve the needs of almost all GMT users. The modern mode is presently being prototyped and tested in the GMT trunk. Once finalized, we will release as a new version GMT 5.5 or even 6.0, depending on the extent of the changes.

GMT modern mode (User perspective)

Here are the basic rules for modern mode:

  1. A GMT modern mode script starts and terminates using the special commands
    1. gmt begin [ name [ format ]] (enters modern mode and optionally names the session [gmtsession] and sets the default graphics format [pdf])
    2. gmt end (terminates modern mode)
  2. Redirection of PostScript output is no longer possible as it is written directly to a hidden temporary file.
  3. GMT configuration (gmt.conf), history (gmt.history) and plot files are placed in a temporary and hidden working directory so multiple scripts can run simultaneously without interference.
  4. The -O -K options are disabled and their use will trigger an error. GMT modern mode handles plot layering under the hood.
  5. The -R option has been extended to allow more flexibility. In addition to taking the usual limits, you can give
    1. -Re for exact: Determine map region from the input files (datasets or grids). Only available for modules that expect input data [Default].
    2. -Ra for auto: As exact, but will round to reasonable bounds that are multiples of increments].
    3. -R codes: Specify ISO codes for countries and continents, with rounding and extension modifiers (basically, the pscoast -E region specification has been moved to -R).
  6. The first PostScript -producing module must be given valid -R -J settings.
    1. If no -R given then we imply -Ra. If no input data then we issue an error.
    2. If no -J is given then we select a plain lon-lat (-JQ) [if we know or may assume geographic data] or Cartesian (-JX) 15 cm wide projection.
  7. Overlays: If -R is not given but required we supply the previous -R automatically. This information is guaranteed to exist by rule 6.1.
  8. Overlays: If -J is not given but required we supply the previous -J automatically. This information is guaranteed to exist by rule 6.2.
  9. Giving -B selects automatic frame drawing and annotations, i.e., -B under modern mode equals -Baf under classic (while under classic, -B means "use previous -B option").
  10. If coastline resolution in pscoast is not specified via -D then the default is -Da (auto-determine most suitable resolution).
  11. Region settings for data (not plot) domains are not automatic and are required at the start of a data workflow. Subsequently, we can automatically supply the precious data domain. Data regions (with grid increments and registration) and plot region histories are now kept separately.

GMT scripts can make one or many illustrations (or none, of course). Under modern mode, plot specifics are managed by a new gmt figure command:

gmt figure [ prefix ] [ formats ] [ options ]

Each new gmt figure call will

  1. Increment the number of figures the current session will make.
  2. Direct all PostScript output to this figure until another gmt figure command is issued.
  3. Set the name of each figure (extensions are automatically added given the chosen format(s)).
  4. Set the desired output format(s) for each figure [PDF].
  5. Optionally supply specific psconvert options to be used for this figure [ PS_CONVERT setting].

When gmt end is executed it calls psconvert which completes the hidden PostScript plots and turns them into the desired products. Users are still allowed to call gmt psconvert to do custom things and will in that case not necessarily use gmt figure at all. However, we expect that vast majority of scripts to use gmt figure. Since the PostScript file is hidden, psconvert requires -F to set the final plot name. Finally, if gmt figure is not used and no psconvert is called to handle the single hidden illustration, the default action of gmt end is to make a PDF plot using the session's name (default is "gmtsession" unless changed by gmt begin). Note: Because the PostScript file is hidden, psconvert 's -T option now allows the format p for plain PostScript (while e still means EPS (Encapsulated PostScript).

Allowable graphics formats

The gmt begin and gmt figure commands will accept the following graphics formats:

  1. bmp (MicroSoft BitMap)
  2. eps (Encapsulate PostScript File)
  3. jpg (Joint Photographic Experts Group format)
  4. pdf (Portable Document Format) [Default]
  5. png (Portable Network Graphics)
  6. ppm (Portable Pixel Map)
  7. ps (PostScript)
  8. tif (Tagged Image Format File)

While gmt begin can take only one default format specification, gmt figure can accept a comma-separated list of formats.

Examples of single plots

To illustrate the new modes, here is a hypothetical bash script in classic mode that makes a PDF map:

gmt grdimage -Chot -I data.nc -JQ15c -P -K > my_map.ps
gmt pscoast -Rdata.nc -J -O -Baf -Gred -K >> my_map.ps
gmt pstext -F+f12p labels.txt -R -J -O -K >> my_map.ps
gmt psxy -W2p lines.txt -R -J -O >> my_map.ps
gmt psconvert -Tf -P -A my_map.ps

Using the modern mode we will instead write

gmt begin my_map                     # Enter modern mode, label the session "my_map" 
gmt grdimage -Chot -I data.nc -P     # Initialize plot, set -R -J the first time (automatically)
gmt pscoast -B -Gred                 # Overlay coastlines and map frame
gmt pstext -F+f12p labels.txt        # Place some labels
gmt psxy -W2p lines.txt              # Add some lines
gmt end                              # Produce my_map.pdf and terminate modern mode

A comparable GMT/MATLAB toolbox example:

gmt ('grdimage', '-P -Chot -I+ data.nc'); % Initialize plot, set -R -J the first time (automatically)
gmt ('pscoast', '-B -Gred');             % Overlay coastlines
gmt ('pstext', '-F+f12p', labels);       % Place some labels
I = gmt ('psxy', '-W2p', lines);         % Finalize, rip PS to image which is returned, delete hidden PS

Coding becomes much shorter by avoiding the repetitive -O -K -R -J options and the PostScript redirection and is therefore simpler to explain.

Examples of multiple plots

The next bash script illustrates how to make two PDF plots and one PNG from two separate maps of Norway and Sweden:

gmt begin
gmt figure norway pdf,png
gmt pscoast -RNO+r1 -Gred -B -JM6ih -N1/thick
gmt figure sweden pdf
gmt pscoast -RSE+r1 -Gred -B -N1/thick
gmt end

The implicit calls to psconvert isseud by gmt end will consult the (new) GMT defaults PS_CONVERT, which may be used to set things like the -A -E, etc., by setting a comma-separated list of options without their leading hyphen (e.g., A1c,E100).

Example of new automatic region and projection

Consider a data file called stuff.txt that has line coordinates in the 0-10 range for both x and y. A quick plot can be obtained via

gmt begin
gmt psxy stuff.txt -P -B
gmt end

Being the first plot (and only) layer, the missing -R forces a determination based on the content of stuff.txt (rule 6.1) while the missing -J defaults to -JQ15c (rule 6.2).

Implementation (Developers perspective)

These notes are for the developers and explain in some details how the modern mode is implemented.

  1. The cake-baking options -O -K are still used under the hood but are not exposed to users.
  2. A PostScript -producing module knows if it should start a new plot (use -K in classic parlance) or append to an existing plot due (use -O in classic parlance) by determining the absence or presence of the hidden PostScript file.
  3. Because we cannot know when the last layer has been added, all hidden PostScript plots are incomplete (i.e., missing the final PostScript trailer). However, psconvert knows this because such files have extension .ps- and we automatically complete the file before conversion. Such completed files are renamed to have extension .ps+.
  4. gmt figure numbers the hidden plot files from 1 and up, whereas single-plot scripts not using gmt figure has an ID of 0.
  5. External interfaces can select modern or classic mode in the GMT_Create_Session call. The developers of these interfaces can decide what they want to offer but presumably this is the modern mode.

All modules have a new #define setting such as this (taken from psbasemap):

#define THIS_MODULE_NEEDS "RJ"

which informs the API machinery that this module requires -R -J to operate. There are two ways for these to be set:

  1. The user provides them as is normally done at the start of any plot.
  2. if the first layer and either -R or -J are missing we auto-supply them (Rules 6.1-2).
  3. For plot overlays, we recover these settings from the history and auto-apply them if no explicit -R -J were given.

For some modules, THIS_MODULE_NEEDS may have the letters g or d in lieu of R. These codes add an extra check:

  1. g (grid) follows the rules for R first, but if that fails it will supply -R thegrid using the input grid file.
  2. d (dataset) also follows the rules for R first, but if that fails it will determine a suitable -R region by running gmt info on the input data and round to a reasonable region.

Modules that plot grids all are given a THIS_MODULE_NEEDS of g, while modules that plot vector data will typically have d, with any remaining modules that require -R will have R.

These settings normally take place during module initialization (by the function gmt_init_module) which is called before GMT_Parse_Common and the module parse functions are run. Thus, the missing options are simply added to the options linked list before parsing takes place. However, there are several modules for which -R -J are not initially required but the user's other options may trigger their need. One example is psscale -DJTC ...options... which does require -R -J to set up the justification, while another is mapproject whose needs depend on options like -A or -G. Because this need is only discovered after parsing has taken place such modules will call gmt_set_missing_options before returning from parse to only add them when required.