Skip to content
Merged
484 changes: 256 additions & 228 deletions lib/iris/aux_factory.py

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions lib/iris/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,20 @@ def assertXMLElement(self, obj, reference_filename):
def assertArrayEqual(self, a, b, err_msg=''):
np.testing.assert_array_equal(a, b, err_msg=err_msg)

def assertRaisesRegexp(self, *args, **kwargs):
"""
Emulate the old :meth:`unittest.TestCase.assertRaisesRegexp`.

Because the original function is now deprecated in Python 3.
Now calls :meth:`six.assertRaisesRegex()` (no final "p") instead.
It is the same, except for providing an additional 'msg' argument.

"""
# Note: invoke via parent class to avoid recursion as, in Python 2,
# "six.assertRaisesRegex" calls getattr(self, 'assertRaisesRegexp').
return six.assertRaisesRegex(super(IrisTest_nometa, self),
*args, **kwargs)

def _assertMaskedArray(self, assertion, a, b, strict, **kwargs):
# Define helper function to extract unmasked values as a 1d
# array.
Expand Down
20 changes: 20 additions & 0 deletions lib/iris/tests/integration/aux_factory/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# (C) British Crown Copyright 2017, Met Office
#
# This file is part of Iris.
#
# Iris is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the
# Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Iris is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Iris. If not, see <http://www.gnu.org/licenses/>.
"""Integration tests for the :mod:`iris.aux_factory` package."""

from __future__ import (absolute_import, division, print_function)
from six.moves import (filter, input, map, range, zip) # noqa
189 changes: 189 additions & 0 deletions lib/iris/tests/integration/aux_factory/test_OceanSigmaZFactory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
# (C) British Crown Copyright 2017, Met Office
#
# This file is part of Iris.
#
# Iris is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the
# Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Iris is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Iris. If not, see <http://www.gnu.org/licenses/>.
"""
Integratation tests for the
`iris.aux_factory.OceanSigmaZFactory` class.

"""

from __future__ import (absolute_import, division, print_function)
from six.moves import (filter, input, map, range, zip) # noqa

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

import itertools

import numpy as np

from iris._lazy_data import as_lazy_data
from iris.tests.stock import ocean_sigma_z as stock_sample_osz
import iris.util


class Test_sample(tests.IrisTest):
def setUp(self):
self.cube = stock_sample_osz()
# Snapshot result, printed with ...
# >>> np.set_printoptions(linewidth=180,
# formatter={'float':lambda x:'{:-09.3f}'.format(x)})
# >>> print repr(coord.points)
self.basic_derived_result = np.array(
[[[[-0000.632, -0000.526, -0000.421, -0000.316],
[-0000.789, -0000.684, -0000.579, -0000.474],
[-0000.947, -0000.842, -0000.737, -0000.632]],
[[-0014.358, -0014.264, -0014.169, -0014.074],
[-0014.501, -0014.406, -0014.311, -0014.216],
[-0014.643, -0014.548, -0014.453, -0014.358]],
[[-0082.993, -0082.951, -0082.908, -0082.866],
[-0083.056, -0083.014, -0082.972, -0082.929],
[-0083.119, -0083.077, -0083.035, -0082.993]],
[[-0368.400, -0368.400, -0368.400, -0368.400],
[-0368.400, -0368.400, -0368.400, -0368.400],
[-0368.400, -0368.400, -0368.400, -0368.400]],
[[-1495.600, -1495.600, -1495.600, -1495.600],
[-1495.600, -1495.600, -1495.600, -1495.600],
[-1495.600, -1495.600, -1495.600, -1495.600]]],

[[[-0000.842, -0000.737, -0000.632, -0000.526],
[-0001.000, -0000.895, -0000.789, -0000.684],
[-0001.158, -0001.053, -0000.947, -0000.842]],
[[-0014.548, -0014.453, -0014.358, -0014.264],
[-0014.690, -0014.595, -0014.501, -0014.406],
[-0014.832, -0014.737, -0014.643, -0014.548]],
[[-0083.077, -0083.035, -0082.993, -0082.951],
[-0083.140, -0083.098, -0083.056, -0083.014],
[-0083.203, -0083.161, -0083.119, -0083.077]],
[[-0368.400, -0368.400, -0368.400, -0368.400],
[-0368.400, -0368.400, -0368.400, -0368.400],
[-0368.400, -0368.400, -0368.400, -0368.400]],
[[-1495.600, -1495.600, -1495.600, -1495.600],
[-1495.600, -1495.600, -1495.600, -1495.600],
[-1495.600, -1495.600, -1495.600, -1495.600]]]])

self.derived_coord_name = \
'sea_surface_height_above_reference_ellipsoid'

def _check_result(self, cube, expected_result=None, **kwargs):
if expected_result is None:
expected_result = self.basic_derived_result
coord = cube.coord(self.derived_coord_name)
result = coord.points
self.assertArrayAllClose(result, expected_result, atol=0.005, **kwargs)

def test_basic(self):
self._check_result(self.cube)

def _lazy_testcube(self):
cube = self.cube
for dep_name in ('depth', 'layer_depth', 'ocean_sigma_z_coordinate'):
coord = cube.coord(dep_name)
coord.points = as_lazy_data(coord.points, coord.shape)
return cube

def test_nonlazy_cube_has_lazy_derived(self):
# Check same results when key coords are made lazy.
cube = self.cube
self.assertEqual(
cube.coord('depth').has_lazy_points(),
False)
self.assertEqual(
cube.coord(self.derived_coord_name).has_lazy_points(),
True)

def test_lazy_cube_same_result(self):
cube = self._lazy_testcube()
self.assertEqual(
cube.coord('depth').has_lazy_points(),
True)
self.assertEqual(
cube.coord(self.derived_coord_name).has_lazy_points(),
True)
self._check_result(cube)

def test_transpose(self):
# Check it works with all possible dimension orders.
for dims_list in itertools.permutations(range(self.cube.ndim)):
cube = self.cube.copy()
cube.transpose(dims_list)
expected = self.basic_derived_result.transpose(dims_list)
msg = 'Unexpected result when cube transposed by {}'
msg = msg.format(dims_list)
self._check_result(cube, expected,
err_msg=msg)

def test_lazy_transpose(self):
# Check lazy calc works with all possible dimension orders.
for dims_list in itertools.permutations(range(self.cube.ndim)):
cube = self._lazy_testcube().copy()
cube.transpose(dims_list)
expected = self.basic_derived_result.transpose(dims_list)
msg = 'Unexpected result when cube transposed by {}'
msg = msg.format(dims_list)
self._check_result(cube, expected,
err_msg=msg)

def test_extra_dims(self):
# Insert some extra cube dimensions + check it still works.
cube = self.cube
cube = iris.util.new_axis(cube)
cube = iris.util.new_axis(cube)
cube = iris.util.new_axis(cube)
# N.B. shape is now (1, 1, 1, t, z, y, x)
cube.transpose((0, 3, 1, 4, 5, 2, 6))
# N.B. shape is now (1, t, 1, z, y, 1, x)
# Should get same original result, as derived dims are the same.
self._check_result(cube)

def test_no_sigma(self):
# Check it still works when 'sigma' is removed.
# NOTE: the unit test for this does not cover all cases because it
# doesn't provide a time dimension.

# Set all sigma points to zero + snapshot the resulting derived points.
trial_cube = self.cube.copy()
trial_cube.coord('ocean_sigma_z_coordinate').points[:] = 0.0
expected = trial_cube.coord(self.derived_coord_name).points

# Remove sigma altogether + check the result is the same.
cube = self.cube
cube.remove_coord('ocean_sigma_z_coordinate')
self._check_result(cube, expected)

def test_no_eta(self):
# Check it still works when 'eta' is removed.
# NOTE: the unit test for this does not cover all cases because it
# doesn't provide a time dimension.

# Set all sigma points to zero + snapshot the resulting derived points.
trial_cube = self.cube.copy()
trial_cube.coord('sea_surface_height').points[:] = 0.0
expected = trial_cube.coord(self.derived_coord_name).points
# Check this has no variation between the two timepoints.
self.assertArrayAllClose(expected[0], expected[1])
# Take first time, as no sigma --> result *has* no time dimension.
expected = expected[0]

# Remove eta altogether + check the result is the same.
cube = self.cube
cube.remove_coord('sea_surface_height')
self._check_result(cube, expected)


if __name__ == "__main__":
tests.main()
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
</attributes>
<coords>
<coord datadims="[0, 1]">
<auxCoord id="9041e969" points="[[nan, nan, 260.259246826, 260.259246826],
[nan, nan, 377.580688477, 374.184997559],
[nan, nan, 494.902130127, 488.110778809],
[nan, nan, 612.223571777, 602.036560059]]" shape="(4, 4)" standard_name="altitude" units="Unit('m')" value_type="float64">
<auxCoord id="9041e969" points="[[--, --, 260.259246826, 260.259246826],
[--, --, 377.580688477, 374.184997559],
[--, --, 494.902130127, 488.110778809],
[--, --, 612.223571777, 602.036560059]]" shape="(4, 4)" standard_name="altitude" units="Unit('m')" value_type="float64">
<attributes>
<attribute name="positive" value="up"/>
</attributes>
Expand Down
62 changes: 31 additions & 31 deletions lib/iris/tests/results/analysis/regrid/linear_masked_altitude.cml
Original file line number Diff line number Diff line change
Expand Up @@ -8,60 +8,60 @@
<coord datadims="[1, 2, 3]">
<auxCoord bounds="[[[[403.764, 416.477],
[377.318, 390.072],
[nan, nan],
[nan, nan],
[nan, nan]],
[--, --],
[--, --],
[--, --]],

[[347.89, 360.689],
[323.018, 335.855],
[nan, nan],
[nan, nan],
[nan, nan]],
[--, --],
[--, --],
[--, --]],

[[354.309, 367.098],
[327.01, 339.841],
[nan, nan],
[nan, nan],
[nan, nan]],
[--, --],
[--, --],
[--, --]],

[[425.557, 438.236],
[393.536, 406.265],
[nan, nan],
[nan, nan],
[nan, nan]]],
[--, --],
[--, --],
[--, --]]],


[[[416.477, 435.548],
[390.072, 409.203],
[nan, nan],
[nan, nan],
[nan, nan]],
[--, --],
[--, --],
[--, --]],

[[360.689, 379.888],
[335.855, 355.111],
[nan, nan],
[nan, nan],
[nan, nan]],
[--, --],
[--, --],
[--, --]],

[[367.098, 386.282],
[339.841, 359.088],
[nan, nan],
[nan, nan],
[nan, nan]],
[--, --],
[--, --],
[--, --]],

[[438.236, 457.257],
[406.265, 425.359],
[nan, nan],
[nan, nan],
[nan, nan]]]]" id="9041e969" points="[[[408.531, 382.101, nan, nan, nan],
[352.689, 327.832, nan, nan, nan],
[359.105, 331.822, nan, nan, nan],
[430.311, 398.309, nan, nan, nan]],
[--, --],
[--, --],
[--, --]]]]" id="9041e969" points="[[[408.531, 382.101, --, --, --],
[352.689, 327.832, --, --, --],
[359.105, 331.822, --, --, --],
[430.311, 398.309, --, --, --]],

[[424.423, 398.043, nan, nan, nan],
[368.688, 343.878, nan, nan, nan],
[375.091, 347.861, nan, nan, nan],
[446.161, 414.22, nan, nan, nan]]]" shape="(2, 4, 5)" standard_name="altitude" units="Unit('m')" value_type="float32">
[[424.423, 398.043, --, --, --],
[368.688, 343.878, --, --, --],
[375.091, 347.861, --, --, --],
[446.161, 414.22, --, --, --]]]" shape="(2, 4, 5)" standard_name="altitude" units="Unit('m')" value_type="float32">
<attributes>
<attribute name="positive" value="up"/>
</attributes>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
</attributes>
<coords>
<coord datadims="[0, 1]">
<auxCoord id="9041e969" points="[[nan, nan, 260.259246826, 260.259246826],
[nan, nan, 377.580688477, 374.184997559],
[nan, nan, 494.902130127, 488.110778809],
[nan, nan, 612.223571777, 602.036560059]]" shape="(4, 4)" standard_name="altitude" units="Unit('m')" value_type="float64">
<auxCoord id="9041e969" points="[[--, --, 260.259246826, 260.259246826],
[--, --, 377.580688477, 374.184997559],
[--, --, 494.902130127, 488.110778809],
[--, --, 612.223571777, 602.036560059]]" shape="(4, 4)" standard_name="altitude" units="Unit('m')" value_type="float64">
<attributes>
<attribute name="positive" value="up"/>
</attributes>
Expand Down
Loading