-
Notifications
You must be signed in to change notification settings - Fork 224
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add IPython to GMT Legacy Tests CI environment #2283
Conversation
To fix errors like `pygmt.exceptions.GMTError: Notebook display is selected, but IPython is not available. Make sure you have IPython installed, or run the script in a Jupyter notebook`.
Traceback for the 22 failing tests from https://github.com/GenericMappingTools/pygmt/actions/runs/3796568197/jobs/6456779355#step:11:720. Most should be fixed by #2281, some look like actual differences in functions between GMT 6.3 and 6.4, others are to do with the _______________________ [doctest] pygmt.src.coast.coast ________________________
256 ... frame="a",
257 ... # Set the color of the land to "darkgreen"
258 ... land="darkgreen",
259 ... # Set the color of the water to "lightblue"
260 ... water="lightblue",
261 ... # Draw national borders with a 1-point black line
262 ... borders="1/1p,black",
263 ... )
264 >>> # Show the plot
265 >>> fig.show()
Expected nothing
Got:
<IPython.core.display.Image object>
/home/runner/work/pygmt/pygmt/pygmt/src/coast.py:265: DocTestFailure
_____________________ [doctest] pygmt.src.grd2cpt.grd2cpt ______________________
197 >>> # load the 30 arc-minutes grid with "gridline" registration
198 >>> grid = pygmt.datasets.load_earth_relief("30m", registration="gridline")
199 >>> # create a plot
200 >>> fig = pygmt.Figure()
201 >>> # create a CPT from the grid object with grd2cpt
202 >>> pygmt.grd2cpt(grid=grid)
203 >>> # plot the grid object, the CPT will be automatically used
204 >>> fig.grdimage(grid=grid)
205 >>> # show the plot
206 >>> fig.show()
Expected nothing
Got:
<IPython.core.display.Image object>
/home/runner/work/pygmt/pygmt/pygmt/src/grd2cpt.py:206: DocTestFailure
_____________________ [doctest] pygmt.src.grd2xyz.grd2xyz ______________________
247 -------
248 >>> import pygmt
249 >>> # Load a grid of @earth_relief_30m data, with an x-range of 10 to 30,
250 >>> # and a y-range of 15 to 25
251 >>> grid = pygmt.datasets.load_earth_relief(
252 ... resolution="30m", region=[10, 30, 15, 25]
253 ... )
254 >>> # Create a pandas DataFrame with the xyz data from an input grid
255 >>> xyz_dataframe = pygmt.grd2xyz(grid=grid, output_type="pandas")
256 >>> xyz_dataframe.head(n=2)
Differences (unified diff with -expected +actual):
@@ -1,3 +1,3 @@
- lon lat elevation
-0 10.25 24.75 903.5
-1 10.75 24.75 820.0
+ lon lat elevation
+0 10.0 25.0 863.0
+1 10.5 25.0 985.5
/home/runner/work/pygmt/pygmt/pygmt/src/grd2xyz.py:256: DocTestFailure
_____________________ [doctest] pygmt.src.grdclip.grdclip ______________________
103 Example
104 -------
105 >>> import pygmt
106 >>> # Load a grid of @earth_relief_30m data, with an x-range of 10 to 30,
107 >>> # and a y-range of 15 to 25
108 >>> grid = pygmt.datasets.load_earth_relief(
109 ... resolution="30m", region=[10, 30, 15, 25]
110 ... )
111 >>> # Report the minimum and maximum data values
112 >>> [grid.data.min(), grid.data.max()]
Expected:
[179.0, 2103.0]
Got:
[170.0, 2275.5]
/home/runner/work/pygmt/pygmt/pygmt/src/grdclip.py:112: DocTestFailure
__________________ [doctest] pygmt.src.grdcontour.grdcontour ___________________
174 ... interval=250,
175 ... # set the interval for annotated contour lines at 1,000 meters
176 ... annotation=1000,
177 ... # add a frame for the plot
178 ... frame="a",
179 ... # set the projection to Mercator for the 10 cm figure
180 ... projection="M10c",
181 ... )
182 >>> # show the plot
183 >>> fig.show()
Expected nothing
Got:
<IPython.core.display.Image object>
/home/runner/work/pygmt/pygmt/pygmt/src/grdcontour.py:183: DocTestFailure
----------------------------- Captured stderr call -----------------------------
Notice: NOTICE]: Remote data courtesy of GMT data server oceania [http://oceania.generic-mapping-tools.org]
Notice: NOTICE]: SRTM15 Earth Relief at 15x15 arc minutes reduced by Gaussian Cartesian filtering (27.8 km fullwidth) [Tozer et al., 2019].
Notice: NOTICE]: -> Download grid file [1.4M]: earth_relief_15m_g.grd
_____________ [doctest] pygmt.src.grdhisteq.grdhisteq.compute_bins _____________
329 >>> import pygmt
330 >>> # Load a grid of @earth_relief_30m data, with an x-range of 10 to
331 >>> # 30, and a y-range of 15 to 25
332 >>> grid = pygmt.datasets.load_earth_relief(
333 ... resolution="30m", region=[10, 30, 15, 25]
334 ... )
335 >>> # Find elevation intervals that splits the data range into 5
336 >>> # divisions, each of which have an equal area in the original grid.
337 >>> bins = pygmt.grdhisteq.compute_bins(grid=grid, divisions=5)
338 >>> print(bins)
Differences (unified diff with -expected +actual):
@@ -1,7 +1,7 @@
start stop
-bin_id
-0 179.0 397.5
-1 397.5 475.5
-2 475.5 573.5
-3 573.5 710.5
-4 710.5 2103.0
+bin_id
+0 170.0 389.0
+1 389.0 470.5
+2 470.5 571.0
+3 571.0 705.0
+4 705.0 2275.5
/home/runner/work/pygmt/pygmt/pygmt/src/grdhisteq.py:338: DocTestFailure
____________________ [doctest] pygmt.src.grdimage.grdimage _____________________
245 >>> import pygmt
246 >>> # load the 30 arc-minutes grid with "gridline" registration
247 >>> grid = pygmt.datasets.load_earth_relief("30m", registration="gridline")
248 >>> # create a new plot with pygmt.Figure()
249 >>> fig = pygmt.Figure()
250 >>> # pass in the grid and set the CPT to "geo"
251 >>> # set the projection to Mollweide and the size to 10 cm
252 >>> fig.grdimage(grid=grid, cmap="geo", projection="W10c", frame="ag")
253 >>> # show the plot
254 >>> fig.show()
Expected nothing
Got:
<IPython.core.display.Image object>
/home/runner/work/pygmt/pygmt/pygmt/src/grdimage.py:254: DocTestFailure
___________________ [doctest] pygmt.src.grdvolume.grdvolume ____________________
104 ... resolution="30m", region=[10, 30, 15, 25]
105 ... )
106 >>> # Create a pandas dataframe that contains the contour, area, volume,
107 >>> # and maximum mean height above the plane specified by the given
108 >>> # contour and below the surface; set the minimum contour z-value to
109 >>> # 200, the maximum to 400, and the interval to 50.
110 >>> output_dataframe = pygmt.grdvolume(
111 ... grid=grid, contour=[200, 400, 50], output_type="pandas"
112 ... )
113 >>> print(output_dataframe)
Differences (unified diff with -expected +actual):
@@ -1,6 +1,6 @@
- 0 1 2 3
- 0 200 2.144285e+12 7.972228e+14 371.789489
- 1 250 2.104042e+12 6.908183e+14 328.329232
- 2 300 2.014978e+12 5.877195e+14 291.675420
- 3 350 1.892109e+12 4.897545e+14 258.840510
- 4 400 1.744792e+12 3.988316e+14 228.584026
+ 0 1 2 3
+0 200 2.318187e+12 8.533727e+14 368.120722
+1 250 2.272471e+12 7.383936e+14 324.929840
+2 300 2.162074e+12 6.273066e+14 290.141086
+3 350 2.018302e+12 5.222640e+14 258.764032
+4 400 1.857370e+12 4.252699e+14 228.963499
/home/runner/work/pygmt/pygmt/pygmt/src/grdvolume.py:113: DocTestFailure
_______________________ [doctest] pygmt.src.solar.solar ________________________
129 ... terminator="day_night",
130 ... # pass the datetime object
131 ... terminator_datetime=date,
132 ... # fill the night-section with navyblue at 75% transparency
133 ... fill="navyblue@75",
134 ... # draw the terminator with a 1-point black line
135 ... pen="1p,black",
136 ... )
137 >>> # show the plot
138 >>> fig.show()
Expected nothing
Got:
<IPython.core.display.Image object>
/home/runner/work/pygmt/pygmt/pygmt/src/solar.py:138: DocTestFailure
________________________ test_earth_relief_fails[gebco] ________________________
data_source = 'gebco'
@pytest.mark.parametrize("data_source", ["igpp", "gebco", "gebcosi", "synbath"])
def test_earth_relief_fails(data_source):
"""
Make sure earth relief fails for invalid resolutions.
"""
resolutions = "1m 1d bla 60d 001m 03".split()
resolutions.append(60)
for resolution in resolutions:
with pytest.raises(GMTInvalidInput):
> load_earth_relief(resolution=resolution, data_source=data_source)
../pygmt/tests/test_datasets_earth_relief.py:20:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../pygmt/helpers/decorators.py:734: in new_module
return module_func(*args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
resolution = '1m', region = None, registration = None, data_source = 'gebco'
use_srtm = False
@kwargs_to_strings(region="sequence")
def load_earth_relief(
resolution="01d",
region=None,
registration=None,
data_source="igpp",
use_srtm=False,
):
r"""
Load Earth relief grids (topography and bathymetry) in various resolutions.
The grids are downloaded to a user data directory
(usually a subdirectory under ~/.gmt/server/earth/) the first time you
invoke this function. Afterwards, it will load the grid from the data
directory. So you'll need an internet connection the first time around.
This module downloads the grids that can also be accessed by
passing in the file name **@**\ *earth_relief_type*\_\ *res*\[_\ *reg*] to
any grid plotting/processing function. *earth_relief_type* is the GMT name
for the dataset. The available options are **earth_relief**\,
**earth_gebco**\, **earth_gebcosi**\, and **earth_synbath**\. *res* is the
grid resolution (see below), and *reg* is grid registration type
(**p** for pixel registration or **g** for gridline registration).
Refer to :gmt-datasets:`earth-relief.html` for more details about available
datasets, including version information and references.
Parameters
----------
resolution : str
The grid resolution. The suffix ``d``, ``m`` and ``s`` stand for
arc-degrees, arc-minutes, and arc-seconds. It can be ``"01d"``,
``"30m"``, ``"20m"``, ``"15m"``, ``"10m"``, ``"06m"``, ``"05m"``,
``"04m"``, ``"03m"``, ``"02m"``, ``"01m"``, ``"30s"``, ``"15s"``,
``"03s"``, or ``"01s"``.
region : str or list
The subregion of the grid to load, in the form of a list
[*xmin*, *xmax*, *ymin*, *ymax*] or a string *xmin/xmax/ymin/ymax*.
Required for Earth relief grids with resolutions higher than 5
arc-minutes (i.e., ``"05m"``).
registration : str
Grid registration type. Either ``"pixel"`` for pixel registration or
``"gridline"`` for gridline registration. Default is ``"gridline"``
for all resolutions except ``"15s"`` which is ``"pixel"`` only.
data_source : str
Select the source for the Earth relief data.
Available options:
- **igpp** : IGPP Global Earth Relief [Default option]. See
:gmt-datasets:`earth-relief.html`.
- **synbath** : IGPP Global Earth Relief dataset that uses
stastical properties of young seafloor to provide more realistic
relief of young areas with small seamounts.
- **gebco** : GEBCO Global Earth Relief with only observed relief and
inferred relief via altimetric gravity. See
:gmt-datasets:`earth-gebco.html`.
- **gebcosi** : GEBCO Global Earth Relief that gives sub-ice (si)
elevations.
use_srtm : bool
By default, the land-only SRTM tiles from NASA are used to generate the
``"03s"`` and ``"01s"`` grids, and the missing ocean values are filled
by up-sampling the SRTM15 tiles which have a resolution of 15
arc-seconds (i.e., ``"15s"``). If True, will only load the original
land-only SRTM tiles. Only works when ``data_source="igpp"``.
Returns
-------
grid : :class:`xarray.DataArray`
The Earth relief grid. Coordinates are latitude and longitude in
degrees. Relief is in meters.
Note
----
The :class:`xarray.DataArray` grid doesn't support slice operation, for
Earth relief data with resolutions of 5 arc-minutes or higher, which are
stored as smaller tiles.
Examples
--------
>>> from pygmt.datasets import load_earth_relief
>>> # load the default grid (gridline-registered 1 arc-degree grid)
>>> grid = load_earth_relief()
>>> # load the 30 arc-minutes grid with "gridline" registration
>>> grid = load_earth_relief(resolution="30m", registration="gridline")
>>> # load high-resolution (5 arc-minutes) grid for a specific region
>>> grid = load_earth_relief(
... resolution="05m",
... region=[120, 160, 30, 60],
... registration="gridline",
... )
>>> # load the original 3 arc-seconds land-only SRTM tiles from NASA
>>> grid = load_earth_relief(
... resolution="03s",
... region=[135, 136, 35, 36],
... registration="gridline",
... use_srtm=True,
... )
"""
# resolutions of original land-only SRTM tiles from NASA
land_only_srtm_resolutions = ["03s", "01s"]
earth_relief_sources = {
"igpp": "earth_relief_",
"gebco": "earth_gebco_",
"gebcosi": "earth_gebcosi_",
"synbath": "earth_synbath_",
}
if data_source not in earth_relief_sources:
raise GMTInvalidInput(
f"Invalid earth relief 'data_source' {data_source}, "
"valid values are 'igpp', 'gebco', 'gebcosi' and 'synbath'."
)
if data_source != "igpp":
with Session() as lib:
if Version(lib.info["version"]) < Version("6.4.0"):
> raise GMTVersionError(
f"The {data_source} option is not available for GMT"
" versions before 6.4.0."
)
E pygmt.exceptions.GMTVersionError: The gebco option is not available for GMT versions before 6.4.0.
../pygmt/datasets/earth_relief.py:140: GMTVersionError
_______________________ test_earth_relief_fails[gebcosi] _______________________
data_source = 'gebcosi'
@pytest.mark.parametrize("data_source", ["igpp", "gebco", "gebcosi", "synbath"])
def test_earth_relief_fails(data_source):
"""
Make sure earth relief fails for invalid resolutions.
"""
resolutions = "1m 1d bla 60d 001m 03".split()
resolutions.append(60)
for resolution in resolutions:
with pytest.raises(GMTInvalidInput):
> load_earth_relief(resolution=resolution, data_source=data_source)
../pygmt/tests/test_datasets_earth_relief.py:20:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../pygmt/helpers/decorators.py:734: in new_module
return module_func(*args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
resolution = '1m', region = None, registration = None, data_source = 'gebcosi'
use_srtm = False
@kwargs_to_strings(region="sequence")
def load_earth_relief(
resolution="01d",
region=None,
registration=None,
data_source="igpp",
use_srtm=False,
):
r"""
Load Earth relief grids (topography and bathymetry) in various resolutions.
The grids are downloaded to a user data directory
(usually a subdirectory under ~/.gmt/server/earth/) the first time you
invoke this function. Afterwards, it will load the grid from the data
directory. So you'll need an internet connection the first time around.
This module downloads the grids that can also be accessed by
passing in the file name **@**\ *earth_relief_type*\_\ *res*\[_\ *reg*] to
any grid plotting/processing function. *earth_relief_type* is the GMT name
for the dataset. The available options are **earth_relief**\,
**earth_gebco**\, **earth_gebcosi**\, and **earth_synbath**\. *res* is the
grid resolution (see below), and *reg* is grid registration type
(**p** for pixel registration or **g** for gridline registration).
Refer to :gmt-datasets:`earth-relief.html` for more details about available
datasets, including version information and references.
Parameters
----------
resolution : str
The grid resolution. The suffix ``d``, ``m`` and ``s`` stand for
arc-degrees, arc-minutes, and arc-seconds. It can be ``"01d"``,
``"30m"``, ``"20m"``, ``"15m"``, ``"10m"``, ``"06m"``, ``"05m"``,
``"04m"``, ``"03m"``, ``"02m"``, ``"01m"``, ``"30s"``, ``"15s"``,
``"03s"``, or ``"01s"``.
region : str or list
The subregion of the grid to load, in the form of a list
[*xmin*, *xmax*, *ymin*, *ymax*] or a string *xmin/xmax/ymin/ymax*.
Required for Earth relief grids with resolutions higher than 5
arc-minutes (i.e., ``"05m"``).
registration : str
Grid registration type. Either ``"pixel"`` for pixel registration or
``"gridline"`` for gridline registration. Default is ``"gridline"``
for all resolutions except ``"15s"`` which is ``"pixel"`` only.
data_source : str
Select the source for the Earth relief data.
Available options:
- **igpp** : IGPP Global Earth Relief [Default option]. See
:gmt-datasets:`earth-relief.html`.
- **synbath** : IGPP Global Earth Relief dataset that uses
stastical properties of young seafloor to provide more realistic
relief of young areas with small seamounts.
- **gebco** : GEBCO Global Earth Relief with only observed relief and
inferred relief via altimetric gravity. See
:gmt-datasets:`earth-gebco.html`.
- **gebcosi** : GEBCO Global Earth Relief that gives sub-ice (si)
elevations.
use_srtm : bool
By default, the land-only SRTM tiles from NASA are used to generate the
``"03s"`` and ``"01s"`` grids, and the missing ocean values are filled
by up-sampling the SRTM15 tiles which have a resolution of 15
arc-seconds (i.e., ``"15s"``). If True, will only load the original
land-only SRTM tiles. Only works when ``data_source="igpp"``.
Returns
-------
grid : :class:`xarray.DataArray`
The Earth relief grid. Coordinates are latitude and longitude in
degrees. Relief is in meters.
Note
----
The :class:`xarray.DataArray` grid doesn't support slice operation, for
Earth relief data with resolutions of 5 arc-minutes or higher, which are
stored as smaller tiles.
Examples
--------
>>> from pygmt.datasets import load_earth_relief
>>> # load the default grid (gridline-registered 1 arc-degree grid)
>>> grid = load_earth_relief()
>>> # load the 30 arc-minutes grid with "gridline" registration
>>> grid = load_earth_relief(resolution="30m", registration="gridline")
>>> # load high-resolution (5 arc-minutes) grid for a specific region
>>> grid = load_earth_relief(
... resolution="05m",
... region=[120, 160, 30, 60],
... registration="gridline",
... )
>>> # load the original 3 arc-seconds land-only SRTM tiles from NASA
>>> grid = load_earth_relief(
... resolution="03s",
... region=[135, 136, 35, 36],
... registration="gridline",
... use_srtm=True,
... )
"""
# resolutions of original land-only SRTM tiles from NASA
land_only_srtm_resolutions = ["03s", "01s"]
earth_relief_sources = {
"igpp": "earth_relief_",
"gebco": "earth_gebco_",
"gebcosi": "earth_gebcosi_",
"synbath": "earth_synbath_",
}
if data_source not in earth_relief_sources:
raise GMTInvalidInput(
f"Invalid earth relief 'data_source' {data_source}, "
"valid values are 'igpp', 'gebco', 'gebcosi' and 'synbath'."
)
if data_source != "igpp":
with Session() as lib:
if Version(lib.info["version"]) < Version("6.4.0"):
grid : :class:`xarray.DataArray`
The Earth relief grid. Coordinates are latitude and longitude in
degrees. Relief is in meters.
Note
----
The :class:`xarray.DataArray` grid doesn't support slice operation, for
Earth relief data with resolutions of 5 arc-minutes or higher, which are
stored as smaller tiles.
Examples
--------
>>> from pygmt.datasets import load_earth_relief
>>> # load the default grid (gridline-registered 1 arc-degree grid)
>>> grid = load_earth_relief()
>>> # load the 30 arc-minutes grid with "gridline" registration
>>> grid = load_earth_relief(resolution="30m", registration="gridline")
>>> # load high-resolution (5 arc-minutes) grid for a specific region
>>> grid = load_earth_relief(
... resolution="05m",
... region=[120, 160, 30, 60],
... registration="gridline",
... )
>>> # load the original 3 arc-seconds land-only SRTM tiles from NASA
>>> grid = load_earth_relief(
... resolution="03s",
... region=[135, 136, 35, 36],
... registration="gridline",
... use_srtm=True,
... )
"""
# resolutions of original land-only SRTM tiles from NASA
land_only_srtm_resolutions = ["03s", "01s"]
earth_relief_sources = {
"igpp": "earth_relief_",
"gebco": "earth_gebco_",
"gebcosi": "earth_gebcosi_",
"synbath": "earth_synbath_",
}
if data_source not in earth_relief_sources:
raise GMTInvalidInput(
f"Invalid earth relief 'data_source' {data_source}, "
"valid values are 'igpp', 'gebco', 'gebcosi' and 'synbath'."
)
if data_source != "igpp":
with Session() as lib:
if Version(lib.info["version"]) < Version("6.4.0"):
> raise GMTVersionError(
f"The {data_source} option is not available for GMT"
" versions before 6.4.0."
)
E pygmt.exceptions.GMTVersionError: The synbath option is not available for GMT versions before 6.4.0.
../pygmt/datasets/earth_relief.py:140: GMTVersionError |
Using both `--doctest-plus` and `--doctest-modules` is redundant as only `--doctest-plus` will be used, see https://github.com/astropy/pytest-doctestplus/tree/v0.12.1#setup-and-configuration.
This reverts commit ae99d15.
Thinking about using |
It's past midnight for me so I won't work on this until ~8hours later. Feel free to push any changes and/or merge if required. To be honest, we probably don't need this in PyGMT v0.8.0 since it's non user-facing, but will leave it up to you @seisman and @yvonnefroehlich. |
Actually, most of the failing inline tests are due to the changes of default registration returned by Take the Here is the diff result:
This inline example was added in PR #1713 on Jan 29, 2022. At that time, we were still using GMT 6.3.0, so the default grid registration is "pixel" (c.f. #1929) and the output of the inline example was correct. After we bumped to GMT 6.4, the default grid registration changed to "gridline", so the output of the inline example is outdated and should be updated. |
Here is the output for different grid registrations:
|
I think we should still run the inline doctests because these inline doctests can help us tracking if there are any upstream changes in GMT 6.3/6.4. Commit a5fbe5a reverts the change from doctest-modules to doctest-plus. After #2284 is merged, we should only see the 5 failures due to the missing IPython, which can be fixed later. So I'm changing the milestone to 0.9.0. |
To fix errors like `pygmt.exceptions.GMTError: Notebook display is selected, but IPython is not available. Make sure you have IPython installed, or run the script in a Jupyter notebook`.
Ok, I've re-added
So I've added the However, the pygmt/.github/workflows/ci_tests.yaml Lines 136 to 139 in 6072b00
Let me see if I can find the correct syntax. The |
Hopefully this is the correct syntax/logic.
Do you think we should split this PR into two or three smaller PRs? |
Let's do two, I can cherry-pick out the patches to Edit: done in #2288. |
Description of proposed changes
To fix errors like
pygmt.exceptions.GMTError: Notebook display is selected, but IPython is not available. Make sure you have IPython installed, or run the script in a Jupyter notebook
in the GMT Legacy Tests (i.e. GMT 6.3 Continuous Integration tests ran on Wednesday).Note that the addition
<IPython.core.display.Image object>
to the doctests will fix bothmake test_no_image
andmake fulltest
.Addresses #2281 (comment), patches #1833.
Reminders
make format
andmake check
to make sure the code follows the style guide.doc/api/index.rst
.Slash Commands
You can write slash commands (
/command
) in the first line of a comment to performspecific operations. Supported slash commands are:
/format
: automatically format and lint the code/test-gmt-dev
: run full tests on the latest GMT development version