Example #1
0
 def test_fail_different_coord_system(self):
     # Check error with mismatched coord systems.
     cube = sample_2d_latlons(regional=True, rotated=True)
     cube.coord(axis='x').coord_system = None
     with self.assertRaisesRegexp(ValueError,
                                  'must have same coordinate system'):
         gridcell_angles(cube)
Example #2
0
 def test_fail_different_coord_system(self):
     # Check error with mismatched coord systems.
     cube = sample_2d_latlons(regional=True, rotated=True)
     cube.coord(axis="x").coord_system = None
     with self.assertRaisesRegex(ValueError,
                                 "must have same coordinate system"):
         gridcell_angles(cube)
Example #3
0
 def test_2d_discontigous_masked(self):
     # Test a 2D coordinate which is discontiguous but masked at
     # discontiguities.
     cube = sample_2d_latlons()
     make_bounds_discontiguous_at_point(cube, 3, 4)
     iplt._check_bounds_contiguity_and_mask(cube.coord('longitude'),
                                            cube.data)
Example #4
0
 def test_2d_plain_latlon_on_polar_map(self):
     # Test 2d vector plotting onto a different projection.
     u_cube, v_cube = self._latlon_uv_cubes(sample_2d_latlons())
     ax = plt.axes(projection=ccrs.NorthPolarStereo())
     self.plot('latlon_2d_polar', u_cube, v_cube,
               coords=('longitude', 'latitude'))
     ax.coastlines(color='red')
     self.check_graphic()
Example #5
0
 def test_2d_plain_latlon_on_polar_map(self):
     # Test 2d vector plotting onto a different projection.
     u_cube, v_cube = self._latlon_uv_cubes(sample_2d_latlons())
     ax = plt.axes(projection=ccrs.NorthPolarStereo())
     self.plot('latlon_2d_polar', u_cube, v_cube,
               coords=('longitude', 'latitude'))
     ax.coastlines(color='red')
     self.check_graphic()
Example #6
0
 def test_2d_plain_latlon(self):
     # Test 2d vector plotting with implicit (PlateCarree) coord system.
     u_cube, v_cube = self._latlon_uv_cubes(sample_2d_latlons())
     ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=180))
     self.plot('latlon_2d', u_cube, v_cube,
               coords=('longitude', 'latitude'))
     ax.coastlines(color='red')
     ax.set_global()
     self.check_graphic()
    def _check_angles_calculation(self, angles_in_degrees=True,
                                  nan_angles_mask=None):
        # Check basic maths on a 2d latlon grid.
        u_cube = sample_2d_latlons(regional=True, transformed=True)
        u_cube.units = 'ms-1'
        u_cube.rename('dx')
        u_cube.data[...] = 0
        v_cube = u_cube.copy()
        v_cube.name('dy')

        # Define 6 different vectors, repeated in each data row.
        in_vu = np.array([(0, 1), (2, -1), (-1, -1), (-3, 1), (2, 0), (0, 0)])
        in_angs = np.rad2deg(np.arctan2(in_vu[..., 0], in_vu[..., 1]))
        in_mags = np.sqrt(np.sum(in_vu * in_vu, axis=1))
        v_cube.data[...] = in_vu[..., 0]
        u_cube.data[...] = in_vu[..., 1]

        # Define 5 different test rotation angles, one for each data row.
        rotation_angles = np.array([0., -45., 135, -140., 90.])
        ang_cube_data = np.broadcast_to(rotation_angles[:, None],
                                        u_cube.shape)
        ang_cube = u_cube.copy()
        if angles_in_degrees:
            ang_cube.units = 'degrees'
        else:
            ang_cube.units = 'radians'
            ang_cube_data = np.deg2rad(ang_cube_data)
        ang_cube.data[:] = ang_cube_data

        if nan_angles_mask is not None:
            ang_cube.data[nan_angles_mask] = np.nan

        # Rotate all vectors by all the given angles.
        result = rotate_grid_vectors(u_cube, v_cube, ang_cube)
        out_u, out_v = [cube.data for cube in result]

        # Check that vector magnitudes were unchanged.
        out_mags = np.sqrt(out_u * out_u + out_v * out_v)
        expect_mags = in_mags[None, :]
        self.assertArrayAllClose(out_mags, expect_mags)

        # Check that vector angles are all as expected.
        out_angs = np.rad2deg(np.arctan2(out_v, out_u))
        expect_angs = in_angs[None, :] + rotation_angles[:, None]
        ang_diffs = out_angs - expect_angs
        # Fix for null vectors, and +/-360 differences.
        ang_diffs[np.abs(out_mags) < 0.001] = 0.0
        ang_diffs = ang_diffs % 360.0
        # Check that any differences are very small.
        self.assertArrayAllClose(ang_diffs, 0.0)

        # Check that results are always masked arrays, masked at NaN angles.
        self.assertTrue(np.ma.isMaskedArray(out_u))
        self.assertTrue(np.ma.isMaskedArray(out_v))
        if nan_angles_mask is not None:
            self.assertArrayEqual(out_u.mask, nan_angles_mask)
            self.assertArrayEqual(out_v.mask, nan_angles_mask)
    def _check_angles_calculation(self,
                                  angles_in_degrees=True,
                                  nan_angles_mask=None):
        # Check basic maths on a 2d latlon grid.
        u_cube = sample_2d_latlons(regional=True, transformed=True)
        u_cube.units = "ms-1"
        u_cube.rename("dx")
        u_cube.data[...] = 0
        v_cube = u_cube.copy()
        v_cube.name("dy")

        # Define 6 different vectors, repeated in each data row.
        in_vu = np.array([(0, 1), (2, -1), (-1, -1), (-3, 1), (2, 0), (0, 0)])
        in_angs = np.rad2deg(np.arctan2(in_vu[..., 0], in_vu[..., 1]))
        in_mags = np.sqrt(np.sum(in_vu * in_vu, axis=1))
        v_cube.data[...] = in_vu[..., 0]
        u_cube.data[...] = in_vu[..., 1]

        # Define 5 different test rotation angles, one for each data row.
        rotation_angles = np.array([0.0, -45.0, 135, -140.0, 90.0])
        ang_cube_data = np.broadcast_to(rotation_angles[:, None], u_cube.shape)
        ang_cube = u_cube.copy()
        if angles_in_degrees:
            ang_cube.units = "degrees"
        else:
            ang_cube.units = "radians"
            ang_cube_data = np.deg2rad(ang_cube_data)
        ang_cube.data[:] = ang_cube_data

        if nan_angles_mask is not None:
            ang_cube.data[nan_angles_mask] = np.nan

        # Rotate all vectors by all the given angles.
        result = rotate_grid_vectors(u_cube, v_cube, ang_cube)
        out_u, out_v = [cube.data for cube in result]

        # Check that vector magnitudes were unchanged.
        out_mags = np.sqrt(out_u * out_u + out_v * out_v)
        expect_mags = in_mags[None, :]
        self.assertArrayAllClose(out_mags, expect_mags)

        # Check that vector angles are all as expected.
        out_angs = np.rad2deg(np.arctan2(out_v, out_u))
        expect_angs = in_angs[None, :] + rotation_angles[:, None]
        ang_diffs = out_angs - expect_angs
        # Fix for null vectors, and +/-360 differences.
        ang_diffs[np.abs(out_mags) < 0.001] = 0.0
        ang_diffs = ang_diffs % 360.0
        # Check that any differences are very small.
        self.assertArrayAllClose(ang_diffs, 0.0)

        # Check that results are always masked arrays, masked at NaN angles.
        self.assertTrue(np.ma.isMaskedArray(out_u))
        self.assertTrue(np.ma.isMaskedArray(out_v))
        if nan_angles_mask is not None:
            self.assertArrayEqual(out_u.mask, nan_angles_mask)
            self.assertArrayEqual(out_v.mask, nan_angles_mask)
Example #9
0
 def test_2d_plain_latlon(self):
     # Test 2d vector plotting with implicit (PlateCarree) coord system.
     u_cube, v_cube = self._latlon_uv_cubes(sample_2d_latlons())
     ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=180))
     self.plot('latlon_2d', u_cube, v_cube,
               coords=('longitude', 'latitude'))
     ax.coastlines(color='red')
     ax.set_global()
     self.check_graphic()
Example #10
0
 def test_2d_rotated_latlon(self):
     # Test plotting vectors in a rotated latlon coord system.
     u_cube, v_cube = self._latlon_uv_cubes(
         sample_2d_latlons(rotated=True))
     ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=180))
     self.plot('2d_rotated', u_cube, v_cube,
               coords=('longitude', 'latitude'))
     ax.coastlines(color='red')
     ax.set_global()
     self.check_graphic()
Example #11
0
 def setUp(self):
     # Make a small "normal" contiguous-bounded cube to test on.
     # This one is regional.
     self.standard_regional_cube = sample_2d_latlons(
         regional=True, transformed=True)
     # Record the standard correct angle answers.
     result_cube = gridcell_angles(self.standard_regional_cube)
     result_cube.convert_units('degrees')
     self.standard_result_cube = result_cube
     self.standard_small_cube_results = result_cube.data
Example #12
0
 def test_2d_rotated_latlon(self):
     # Test plotting vectors in a rotated latlon coord system.
     u_cube, v_cube = self._latlon_uv_cubes(
         sample_2d_latlons(rotated=True))
     ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=180))
     self.plot('2d_rotated', u_cube, v_cube,
               coords=('longitude', 'latitude'))
     ax.coastlines(color='red')
     ax.set_global()
     self.check_graphic()
 def test_2d_discontigous_unmasked(self):
     # Test a 2D coordinate which is discontiguous and unmasked at
     # discontiguities.
     cube = sample_2d_latlons()
     make_bounds_discontiguous_at_point(cube, 3, 4)
     msg = 'coordinate are not contiguous'
     cube.data[3, 4] = ma.nomask
     with self.assertRaisesRegexp(ValueError, msg):
         _check_bounds_contiguity_and_mask(cube.coord('longitude'),
                                           cube.data)
Example #14
0
 def test_2d_discontigous_unmasked(self):
     # Test a 2D coordinate which is discontiguous and unmasked at
     # discontiguities.
     cube = sample_2d_latlons()
     make_bounds_discontiguous_at_point(cube, 3, 4)
     msg = 'coordinate are not contiguous'
     cube.data[3, 4] = ma.nomask
     with self.assertRaisesRegexp(ValueError, msg):
         iplt._check_bounds_contiguity_and_mask(cube.coord('longitude'),
                                                cube.data)
Example #15
0
 def setUp(self):
     # Make a small "normal" contiguous-bounded cube to test on.
     # This one is regional.
     self.standard_regional_cube = sample_2d_latlons(regional=True,
                                                     transformed=True)
     # Record the standard correct angle answers.
     result_cube = gridcell_angles(self.standard_regional_cube)
     result_cube.convert_units("degrees")
     self.standard_result_cube = result_cube
     self.standard_small_cube_results = result_cube.data
Example #16
0
 def test_2d_plain_latlon_on_polar_map(self):
     # Test 2d vector plotting onto a different projection.
     u_cube, v_cube = self._latlon_uv_cubes(sample_2d_latlons())
     ax = plt.axes(projection=ccrs.NorthPolarStereo())
     self.plot("latlon_2d_polar",
               u_cube,
               v_cube,
               coords=("longitude", "latitude"))
     ax.coastlines(resolution="110m", color="red")
     self.check_graphic()
Example #17
0
 def test_2d_rotated_latlon(self):
     # Test plotting vectors in a rotated latlon coord system.
     u_cube, v_cube = self._latlon_uv_cubes(sample_2d_latlons(rotated=True))
     ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=180))
     self.plot("2d_rotated",
               u_cube,
               v_cube,
               coords=("longitude", "latitude"))
     ax.coastlines(resolution="110m", color="red")
     ax.set_global()
     self.check_graphic()
 def test_2d_contiguous_atol(self):
     # Check the atol is passed correctly.
     cube = sample_2d_latlons()
     with mock.patch('iris.coords.Coord._discontiguity_in_bounds'
                     ) as discontiguity_check:
         # Discontiguity returns two objects that are unpacked in
         # `_check_bounds_contiguity_and_mask`.
         discontiguity_check.return_value = [True, None]
         _check_bounds_contiguity_and_mask(cube.coord('longitude'),
                                           cube.data, atol=1e-3)
     discontiguity_check.assert_called_with(atol=1e-3)
Example #19
0
 def test_2d_plain_latlon(self):
     # Test 2d vector plotting with implicit (PlateCarree) coord system.
     u_cube, v_cube = self._latlon_uv_cubes(sample_2d_latlons())
     ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=180))
     self.plot("latlon_2d",
               u_cube,
               v_cube,
               coords=("longitude", "latitude"))
     ax.coastlines(resolution="110m", color="red")
     ax.set_global()
     self.check_graphic()
Example #20
0
 def test_fail_unsupported_coord_system(self):
     # Test plotting vectors in a rotated latlon coord system.
     u_cube, v_cube = self._latlon_uv_cubes(sample_2d_latlons())
     patch_coord_system = Mercator()
     for cube in u_cube, v_cube:
         for coord in cube.coords():
             coord.coord_system = patch_coord_system
     re_msg = ('Can only plot .* lat-lon projection, .* '
               'This .* translates as Cartopy.*Mercator')
     with self.assertRaisesRegexp(ValueError, re_msg):
         self.plot('2d_rotated', u_cube, v_cube,
                   coords=('longitude', 'latitude'))
Example #21
0
 def test_2d_contiguous_atol(self):
     # Check the atol is passed correctly.
     cube = sample_2d_latlons()
     with mock.patch('iris.coords.Coord._discontiguity_in_bounds'
                     ) as discontiguity_check:
         # Discontiguity returns two objects that are unpacked in
         # `_check_bounds_contiguity_and_mask`.
         discontiguity_check.return_value = [True, None]
         iplt._check_bounds_contiguity_and_mask(cube.coord('longitude'),
                                                cube.data,
                                                atol=1e-3)
     discontiguity_check.assert_called_with(atol=1e-3)
Example #22
0
 def test_fail_unsupported_coord_system(self):
     # Test plotting vectors in a rotated latlon coord system.
     u_cube, v_cube = self._latlon_uv_cubes(sample_2d_latlons())
     patch_coord_system = Mercator()
     for cube in u_cube, v_cube:
         for coord in cube.coords():
             coord.coord_system = patch_coord_system
     re_msg = ('Can only plot .* lat-lon projection, .* '
               'This .* translates as Cartopy.*Mercator')
     with self.assertRaisesRegexp(ValueError, re_msg):
         self.plot('2d_rotated', u_cube, v_cube,
                   coords=('longitude', 'latitude'))
Example #23
0
 def test_fail_unsupported_coord_system(self):
     # Test plotting vectors in a rotated latlon coord system.
     u_cube, v_cube = self._latlon_uv_cubes(sample_2d_latlons())
     patch_coord_system = Mercator()
     for cube in u_cube, v_cube:
         for coord in cube.coords():
             coord.coord_system = patch_coord_system
     re_msg = (r"Can only plot .* lat-lon projection, .* "
               r"This .* translates as Cartopy \+proj=merc .*")
     with self.assertRaisesRegex(ValueError, re_msg):
         self.plot("2d_rotated",
                   u_cube,
                   v_cube,
                   coords=("longitude", "latitude"))
Example #24
0
 def test_nonlatlon_coord_system(self):
     # Check with points specified in an unexpected coord system.
     cube = sample_2d_latlons(regional=True, rotated=True)
     result = gridcell_angles(cube)
     self.assertArrayAllClose(result.data, self.standard_small_cube_results)
     # Check that the result has transformed (true-latlon) coordinates.
     self.assertEqual(len(result.coords()), 2)
     x_coord = result.coord(axis="x")
     y_coord = result.coord(axis="y")
     self.assertEqual(x_coord.shape, cube.shape)
     self.assertEqual(y_coord.shape, cube.shape)
     self.assertIsNotNone(cube.coord_system)
     self.assertIsNone(x_coord.coord_system)
     self.assertIsNone(y_coord.coord_system)
Example #25
0
 def test_nonlatlon_coord_system(self):
     # Check with points specified in an unexpected coord system.
     cube = sample_2d_latlons(regional=True, rotated=True)
     result = gridcell_angles(cube)
     self.assertArrayAllClose(result.data,
                              self.standard_small_cube_results)
     # Check that the result has transformed (true-latlon) coordinates.
     self.assertEqual(len(result.coords()), 2)
     x_coord = result.coord(axis='x')
     y_coord = result.coord(axis='y')
     self.assertEqual(x_coord.shape, cube.shape)
     self.assertEqual(y_coord.shape, cube.shape)
     self.assertIsNotNone(cube.coord_system)
     self.assertIsNone(x_coord.coord_system)
     self.assertIsNone(y_coord.coord_system)
Example #26
0
    def test_unbounded_global(self):
        # For a contiguous global grid, a result based on points, i.e. with the
        # bounds removed, should be a reasonable match for the 'ideal' one
        # based on the bounds.

        # Make a global cube + calculate ideal bounds-based results.
        global_cube = sample_2d_latlons(transformed=True)
        result_cube = gridcell_angles(global_cube)
        result_cube.convert_units("degrees")
        global_cube_results = result_cube.data

        # Check a points-based calculation on the same basic grid.
        co_x, co_y = (global_cube.coord(axis=ax) for ax in ("x", "y"))
        for coord in (co_x, co_y):
            coord.bounds = None
        result = gridcell_angles(co_x, co_y)
        # In this case, the match is actually rather poor (!).
        self.assertArrayAllClose(result.data, global_cube_results, atol=7.5)
        # Leaving off first + last columns again gives a decent result.
        self.assertArrayAllClose(result.data[:, 1:-1],
                                 global_cube_results[:, 1:-1])
Example #27
0
    def test_angles_from_grid(self):
        # Check it will gets angles from 'u_cube', and pass any kwargs on to
        # the angles routine.
        u_cube = sample_2d_latlons(regional=True, transformed=True)
        u_cube = u_cube[:2, :3]
        u_cube.units = 'ms-1'
        u_cube.rename('dx')
        u_cube.data[...] = 1.0
        v_cube = u_cube.copy()
        v_cube.name('dy')
        v_cube.data[...] = 0.0

        # Setup a fake angles result from the inner call to 'gridcell_angles'.
        angles_result_data = np.array([[0.0, 90.0, 180.0],
                                       [-180.0, -90.0, 270.0]])
        angles_result_cube = Cube(angles_result_data, units='degrees')
        angles_kwargs = {'this': 2}
        angles_call_patch = self.patch(
                'iris.analysis._grid_angles.gridcell_angles',
                Mock(return_value=angles_result_cube))

        # Call the routine.
        result = rotate_grid_vectors(u_cube, v_cube,
                                     grid_angles_kwargs=angles_kwargs)

        self.assertEqual(angles_call_patch.call_args_list,
                         [mock_call(u_cube, this=2)])

        out_u, out_v = [cube.data for cube in result]
        # Records what results should be for the various n*90deg rotations.
        expect_u = np.array([[1.0, 0.0, -1.0],
                             [-1.0, 0.0, 0.0]])
        expect_v = np.array([[0.0, 1.0, 0.0],
                             [0.0, -1.0, -1.0]])
        # Check results are as expected.
        self.assertArrayAllClose(out_u, expect_u)
        self.assertArrayAllClose(out_v, expect_v)
Example #28
0
    def test_angles_from_grid(self):
        # Check it will gets angles from 'u_cube', and pass any kwargs on to
        # the angles routine.
        u_cube = sample_2d_latlons(regional=True, transformed=True)
        u_cube = u_cube[:2, :3]
        u_cube.units = "ms-1"
        u_cube.rename("dx")
        u_cube.data[...] = 1.0
        v_cube = u_cube.copy()
        v_cube.name("dy")
        v_cube.data[...] = 0.0

        # Setup a fake angles result from the inner call to 'gridcell_angles'.
        angles_result_data = np.array([[0.0, 90.0, 180.0],
                                       [-180.0, -90.0, 270.0]])
        angles_result_cube = Cube(angles_result_data, units="degrees")
        angles_kwargs = {"this": 2}
        angles_call_patch = self.patch(
            "iris.analysis._grid_angles.gridcell_angles",
            Mock(return_value=angles_result_cube),
        )

        # Call the routine.
        result = rotate_grid_vectors(u_cube,
                                     v_cube,
                                     grid_angles_kwargs=angles_kwargs)

        self.assertEqual(angles_call_patch.call_args_list,
                         [mock_call(u_cube, this=2)])

        out_u, out_v = [cube.data for cube in result]
        # Records what results should be for the various n*90deg rotations.
        expect_u = np.array([[1.0, 0.0, -1.0], [-1.0, 0.0, 0.0]])
        expect_v = np.array([[0.0, 1.0, 0.0], [0.0, -1.0, -1.0]])
        # Check results are as expected.
        self.assertArrayAllClose(out_u, expect_u)
        self.assertArrayAllClose(out_v, expect_v)
Example #29
0
    def test_unbounded_global(self):
        # For a contiguous global grid, a result based on points, i.e. with the
        # bounds removed, should be a reasonable match for the 'ideal' one
        # based on the bounds.

        # Make a global cube + calculate ideal bounds-based results.
        global_cube = sample_2d_latlons(transformed=True)
        result_cube = gridcell_angles(global_cube)
        result_cube.convert_units('degrees')
        global_cube_results = result_cube.data

        # Check a points-based calculation on the same basic grid.
        co_x, co_y = (global_cube.coord(axis=ax)
                      for ax in ('x', 'y'))
        for coord in (co_x, co_y):
            coord.bounds = None
        result = gridcell_angles(co_x, co_y)
        # In this case, the match is actually rather poor (!).
        self.assertArrayAllClose(result.data,
                                 global_cube_results,
                                 atol=7.5)
        # Leaving off first + last columns again gives a decent result.
        self.assertArrayAllClose(result.data[:, 1:-1],
                                 global_cube_results[:, 1:-1])
 def test_2d_contiguous(self):
     # Test that a 2D coordinate which is contiguous does not throw
     # an error.
     cube = sample_2d_latlons()
     _check_bounds_contiguity_and_mask(cube.coord('longitude'), cube.data)
 def test_2d_discontigous_masked(self):
     # Test that a 2D coordinate which is discontiguous but masked at
     # discontiguities doesn't error.
     cube = sample_2d_latlons()
     make_bounds_discontiguous_at_point(cube, 3, 4)
     _check_bounds_contiguity_and_mask(cube.coord('longitude'), cube.data)
Example #32
0
 def test_2d_contiguous(self):
     # Test a 2D coordinate which is contiguous.
     cube = sample_2d_latlons()
     iplt._check_bounds_contiguity_and_mask(cube.coord('longitude'),
                                            cube.data)
Example #33
0
def full2d_global():
    return sample_2d_latlons(transformed=True)
Example #34
0
 def test_2d_discontigous_masked(self):
     # Test that a 2D coordinate which is discontiguous but masked at
     # discontiguities doesn't error.
     cube = sample_2d_latlons()
     make_bounds_discontiguous_at_point(cube, 3, 4)
     _check_bounds_contiguity_and_mask(cube.coord("longitude"), cube.data)
Example #35
0
def full2d_global():
    return sample_2d_latlons(transformed=True)
Example #36
0
 def test_2d_contiguous(self):
     # Test that a 2D coordinate which is contiguous does not throw
     # an error.
     cube = sample_2d_latlons()
     _check_bounds_contiguity_and_mask(cube.coord("longitude"), cube.data)