Skip to content

Commit

Permalink
Tests for saving other-format data into grib : ported from Iris. (#213)
Browse files Browse the repository at this point in the history
* Tests for saving other-format data into grib : ported from Iris.

* Add mo-pack as a test dependency.
  • Loading branch information
pp-mo authored Jun 24, 2020
1 parent 07a1b22 commit 4b7797f
Show file tree
Hide file tree
Showing 13 changed files with 488 additions and 0 deletions.
1 change: 1 addition & 0 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ channels:
- conda-forge
dependencies:
- iris>=2.4
- mo_pack
- python-eccodes
- pep8
12 changes: 12 additions & 0 deletions iris_grib/tests/integration/format_interop/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Copyright iris-grib contributors
#
# This file is part of iris-grib and is released under the LGPL license.
# See COPYING and COPYING.LESSER in the root of the repository for full
# licensing details.
"""
Integration tests for format interoperability.
Checks that specific features of cubes loaded from other formats are correctly
represented by grib saving.
"""
114 changes: 114 additions & 0 deletions iris_grib/tests/integration/format_interop/test_name_grib.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# Copyright iris-grib contributors
#
# This file is part of iris-grib and is released under the LGPL license.
# See COPYING and COPYING.LESSER in the root of the repository for full
# licensing details.
"""Integration tests for NAME to GRIB2 interoperability."""

# Import iris_grib.tests first so that some things can be initialised before
# importing anything else.
import iris_grib.tests as tests

import numpy as np
import warnings

import iris


def name_cb(cube, field, filename):
# NAME files give the time point at the end of the range but Iris'
# GRIB loader creates it in the middle (the GRIB file itself doesn't
# encode a time point). Here we make them consistent so we can
# easily compare them.
t_coord = cube.coord("time")
t_coord.points = t_coord.bounds[0][1]
fp_coord = cube.coord("forecast_period")
fp_coord.points = fp_coord.bounds[0][1]
# NAME contains extra vertical meta-data.
z_coord = cube.coords("height")
if z_coord:
z_coord[0].standard_name = "height"
z_coord[0].long_name = "height above ground level"


class TestNameToGRIB(tests.IrisGribTest):
def check_common(self, name_cube, grib_cube):
self.assertTrue(np.allclose(name_cube.data, grib_cube.data))
self.assertTrue(
np.allclose(
name_cube.coord("latitude").points,
grib_cube.coord("latitude").points,
)
)
self.assertTrue(
np.allclose(
name_cube.coord("longitude").points,
grib_cube.coord("longitude").points - 360,
)
)

for c in ["height", "time"]:
if name_cube.coords(c):
self.assertEqual(name_cube.coord(c), grib_cube.coord(c))

@tests.skip_data
def test_name2_field(self):
filepath = tests.get_data_path(("NAME", "NAMEII_field.txt"))
name_cubes = iris.load(filepath)

# There is a known load/save problem with numerous
# gribapi/eccodes versions and
# zero only data, where min == max.
# This may be a problem with data scaling.
for i, name_cube in enumerate(name_cubes):
data = name_cube.data
if np.min(data) == np.max(data):
msg = (
'NAMEII cube #{}, "{}" has empty data : '
"SKIPPING test for this cube, as save/load will "
"not currently work."
)
warnings.warn(msg.format(i, name_cube.name()))
continue

with self.temp_filename(".grib2") as temp_filename:
iris.save(name_cube, temp_filename)
grib_cube = iris.load_cube(temp_filename, callback=name_cb)
self.check_common(name_cube, grib_cube)
self.assertCML(
grib_cube,
self.get_result_path(
(
"integration",
"name_grib",
"NAMEII",
"{}_{}.cml".format(i, name_cube.name()),
)
),
)

@tests.skip_data
def test_name3_field(self):
filepath = tests.get_data_path(("NAME", "NAMEIII_field.txt"))
name_cubes = iris.load(filepath)
for i, name_cube in enumerate(name_cubes):
with self.temp_filename(".grib2") as temp_filename:
iris.save(name_cube, temp_filename)
grib_cube = iris.load_cube(temp_filename, callback=name_cb)

self.check_common(name_cube, grib_cube)
self.assertCML(
grib_cube,
self.get_result_path(
(
"integration",
"name_grib",
"NAMEIII",
"{}_{}.cml".format(i, name_cube.name()),
)
),
)


if __name__ == "__main__":
tests.main()
49 changes: 49 additions & 0 deletions iris_grib/tests/integration/format_interop/test_pp_grib.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Copyright iris-grib contributors
#
# This file is part of iris-grib and is released under the LGPL license.
# See COPYING and COPYING.LESSER in the root of the repository for full
# licensing details.
"""Integration tests for PP/GRIB interoperability."""

# Import iris_grib.tests first so that some things can be initialised before
# importing anything else.
import iris_grib.tests as tests

import iris


class TestBoundedTime(tests.IrisTest):
@tests.skip_data
def test_time_and_forecast_period_round_trip(self):
pp_path = tests.get_data_path(
("PP", "meanMaxMin", "200806081200__qwpb.T24.pp")
)
# Choose the first time-bounded Cube in the PP dataset.
original = [
cube
for cube in iris.load(pp_path)
if cube.coord("time").has_bounds()
][0]
# Save it to GRIB2 and re-load.
with self.temp_filename(".grib2") as grib_path:
iris.save(original, grib_path)
from_grib = iris.load_cube(grib_path)
# Avoid the downcasting warning when saving to PP.
from_grib.data = from_grib.data.astype("f4")
# Re-save to PP and re-load.
with self.temp_filename(".pp") as pp_path:
iris.save(from_grib, pp_path)
from_pp = iris.load_cube(pp_path)
self.assertEqual(original.coord("time"), from_grib.coord("time"))
self.assertEqual(
original.coord("forecast_period"),
from_grib.coord("forecast_period"),
)
self.assertEqual(original.coord("time"), from_pp.coord("time"))
self.assertEqual(
original.coord("forecast_period"), from_pp.coord("forecast_period")
)


if __name__ == "__main__":
tests.main()
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?xml version="1.0" ?>
<cubes xmlns="urn:x-iris:cubeml-0.2">
<cube dtype="float64" units="unknown">
<attributes>
<attribute name="GRIB_PARAM" value="GRIB2:d255c255n255"/>
</attributes>
<coords>
<coord>
<dimCoord bounds="[[0.0, 3.0]]" id="1d45e087" points="[3.0]" shape="(1,)" standard_name="forecast_period" units="Unit('hours')" value_type="float64"/>
</coord>
<coord>
<dimCoord bounds="[[0.0, 100.0]]" id="c87e380b" long_name="height above ground level" points="[50.0]" shape="(1,)" standard_name="height" units="Unit('m')" value_type="float64"/>
</coord>
<coord datadims="[0]">
<dimCoord id="77a50eb5" points="[52.367102, 52.368208, 52.369314, ..., 52.584984,
52.58609, 52.587196]" shape="(200,)" standard_name="latitude" units="Unit('degrees')" value_type="float64">
<geogCS earth_radius="6371229.0"/>
</dimCoord>
</coord>
<coord datadims="[1]">
<dimCoord id="f913a8b3" points="[357.9144, 357.916209, 357.918018, ...,
358.270773, 358.272582, 358.274391]" shape="(200,)" standard_name="longitude" units="Unit('degrees')" value_type="float64">
<geogCS earth_radius="6371229.0"/>
</dimCoord>
</coord>
<coord>
<dimCoord bounds="[[351249.0, 351252.0]]" id="cb784457" points="[351252.0]" shape="(1,)" standard_name="time" units="Unit('hours since 1970-01-01 00:00:00', calendar='gregorian')" value_type="float64"/>
</coord>
</coords>
<cellMethods>
<cellMethod method="mean">
<coord name="time"/>
</cellMethod>
</cellMethods>
<data checksum="0xc40545ce" dtype="float64" shape="(200, 200)"/>
</cube>
</cubes>
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?xml version="1.0" ?>
<cubes xmlns="urn:x-iris:cubeml-0.2">
<cube dtype="float64" units="unknown">
<attributes>
<attribute name="GRIB_PARAM" value="GRIB2:d255c255n255"/>
</attributes>
<coords>
<coord>
<dimCoord bounds="[[0.0, 3.0]]" id="1d45e087" points="[3.0]" shape="(1,)" standard_name="forecast_period" units="Unit('hours')" value_type="float64"/>
</coord>
<coord>
<dimCoord bounds="[[0.0, 100.0]]" id="c87e380b" long_name="height above ground level" points="[50.0]" shape="(1,)" standard_name="height" units="Unit('m')" value_type="float64"/>
</coord>
<coord datadims="[0]">
<dimCoord id="77a50eb5" points="[52.367102, 52.368208, 52.369314, ..., 52.584984,
52.58609, 52.587196]" shape="(200,)" standard_name="latitude" units="Unit('degrees')" value_type="float64">
<geogCS earth_radius="6371229.0"/>
</dimCoord>
</coord>
<coord datadims="[1]">
<dimCoord id="f913a8b3" points="[357.9144, 357.916209, 357.918018, ...,
358.270773, 358.272582, 358.274391]" shape="(200,)" standard_name="longitude" units="Unit('degrees')" value_type="float64">
<geogCS earth_radius="6371229.0"/>
</dimCoord>
</coord>
<coord>
<dimCoord bounds="[[351249.0, 351252.0]]" id="cb784457" points="[351252.0]" shape="(1,)" standard_name="time" units="Unit('hours since 1970-01-01 00:00:00', calendar='gregorian')" value_type="float64"/>
</coord>
</coords>
<cellMethods>
<cellMethod method="sum">
<coord name="time"/>
</cellMethod>
</cellMethods>
<data checksum="0x69a4721e" dtype="float64" shape="(200, 200)"/>
</cube>
</cubes>
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version="1.0" ?>
<cubes xmlns="urn:x-iris:cubeml-0.2">
<cube dtype="float64" units="unknown">
<attributes>
<attribute name="GRIB_PARAM" value="GRIB2:d255c255n255"/>
</attributes>
<coords>
<coord>
<dimCoord bounds="[[0.0, 3.0]]" id="1d45e087" points="[3.0]" shape="(1,)" standard_name="forecast_period" units="Unit('hours')" value_type="float64"/>
</coord>
<coord datadims="[0]">
<dimCoord id="77a50eb5" points="[52.367102, 52.368208, 52.369314, ..., 52.584984,
52.58609, 52.587196]" shape="(200,)" standard_name="latitude" units="Unit('degrees')" value_type="float64">
<geogCS earth_radius="6371229.0"/>
</dimCoord>
</coord>
<coord datadims="[1]">
<dimCoord id="f913a8b3" points="[357.9144, 357.916209, 357.918018, ...,
358.270773, 358.272582, 358.274391]" shape="(200,)" standard_name="longitude" units="Unit('degrees')" value_type="float64">
<geogCS earth_radius="6371229.0"/>
</dimCoord>
</coord>
<coord>
<dimCoord bounds="[[351249.0, 351252.0]]" id="cb784457" points="[351252.0]" shape="(1,)" standard_name="time" units="Unit('hours since 1970-01-01 00:00:00', calendar='gregorian')" value_type="float64"/>
</coord>
</coords>
<cellMethods>
<cellMethod method="sum">
<coord name="time"/>
</cellMethod>
</cellMethods>
<data checksum="0xfa69900c" dtype="float64" shape="(200, 200)"/>
</cube>
</cubes>
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version="1.0" ?>
<cubes xmlns="urn:x-iris:cubeml-0.2">
<cube dtype="float64" units="unknown">
<attributes>
<attribute name="GRIB_PARAM" value="GRIB2:d255c255n255"/>
</attributes>
<coords>
<coord>
<dimCoord bounds="[[0.0, 3.0]]" id="1d45e087" points="[3.0]" shape="(1,)" standard_name="forecast_period" units="Unit('hours')" value_type="float64"/>
</coord>
<coord datadims="[0]">
<dimCoord id="77a50eb5" points="[52.367102, 52.368208, 52.369314, ..., 52.584984,
52.58609, 52.587196]" shape="(200,)" standard_name="latitude" units="Unit('degrees')" value_type="float64">
<geogCS earth_radius="6371229.0"/>
</dimCoord>
</coord>
<coord datadims="[1]">
<dimCoord id="f913a8b3" points="[357.9144, 357.916209, 357.918018, ...,
358.270773, 358.272582, 358.274391]" shape="(200,)" standard_name="longitude" units="Unit('degrees')" value_type="float64">
<geogCS earth_radius="6371229.0"/>
</dimCoord>
</coord>
<coord>
<dimCoord bounds="[[351249.0, 351252.0]]" id="cb784457" points="[351252.0]" shape="(1,)" standard_name="time" units="Unit('hours since 1970-01-01 00:00:00', calendar='gregorian')" value_type="float64"/>
</coord>
</coords>
<cellMethods>
<cellMethod method="sum">
<coord name="time"/>
</cellMethod>
</cellMethods>
<data checksum="0xfa69900c" dtype="float64" shape="(200, 200)"/>
</cube>
</cubes>
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version="1.0" ?>
<cubes xmlns="urn:x-iris:cubeml-0.2">
<cube dtype="float64" units="unknown">
<attributes>
<attribute name="GRIB_PARAM" value="GRIB2:d255c255n255"/>
</attributes>
<coords>
<coord>
<dimCoord bounds="[[0.0, 4.0]]" id="1d45e087" points="[4.0]" shape="(1,)" standard_name="forecast_period" units="Unit('hours')" value_type="float64"/>
</coord>
<coord datadims="[0]">
<dimCoord id="77a50eb5" points="[50.6115, 50.6125, 50.6135, ..., 50.8085,
50.8095, 50.8105]" shape="(200,)" standard_name="latitude" units="Unit('degrees')" value_type="float64">
<geogCS earth_radius="6371229.0"/>
</dimCoord>
</coord>
<coord datadims="[1]">
<dimCoord id="f913a8b3" points="[356.3218, 356.3236, 356.3254, ..., 356.6764,
356.6782, 356.68]" shape="(200,)" standard_name="longitude" units="Unit('degrees')" value_type="float64">
<geogCS earth_radius="6371229.0"/>
</dimCoord>
</coord>
<coord>
<dimCoord bounds="[[349215.0, 349219.0]]" id="cb784457" points="[349219.0]" shape="(1,)" standard_name="time" units="Unit('hours since 1970-01-01 00:00:00', calendar='gregorian')" value_type="float64"/>
</coord>
</coords>
<cellMethods>
<cellMethod method="sum">
<coord name="time"/>
</cellMethod>
</cellMethods>
<data checksum="0x7859bf53" dtype="float64" shape="(200, 200)"/>
</cube>
</cubes>
Loading

0 comments on commit 4b7797f

Please sign in to comment.