def setUp(self): ThreeDimCube.setUp(self) self.cube.coord("longitude")._points = np.linspace(0, 360, 4, endpoint=False) self.cube.coord("longitude").circular = True self.cube.coord("longitude").units = "degrees" self.interpolator = RectilinearInterpolator(self.cube, ["longitude"], LINEAR, extrapolation_mode="nan") self.cube_reverselons = self.cube[:, :, ::-1] self.interpolator_reverselons = RectilinearInterpolator( self.cube_reverselons, ["longitude"], LINEAR, extrapolation_mode="nan", ) self.testpoints_fully_wrapped = ([[180, 270]], [[-180, -90]]) self.testpoints_partially_wrapped = ([[180, 90]], [[-180, 90]]) self.testpoints_fully_wrapped_twice = ( [np.linspace(-360, 360, 100)], [(np.linspace(-360, 360, 100) + 360) % 360], )
def test_interpolate_data_nan_extrapolation_not_needed(self): # No extrapolation for a single length dimension. interpolator = RectilinearInterpolator(self.cube, ["latitude"], LINEAR, extrapolation_mode="nan") result = interpolator([[0]]) self.assertArrayEqual(result.data, self.cube.data)
def _extrapolation_dtype(self, dtype): self.cube.data = self.cube.data.astype(dtype) interpolator = RectilinearInterpolator(self.cube, ["latitude"], LINEAR, extrapolation_mode="nan") result = interpolator([[-1]]) self.assertTrue(np.all(np.isnan(result.data)))
def test_interpolate_data_dtype_casting(self): data = self.data.astype(int) self.cube.data = data self.interpolator = RectilinearInterpolator(self.cube, ["latitude"], LINEAR, EXTRAPOLATE) result = self.interpolator([[0.125]]) self.assertEqual(result.data.dtype, np.float64)
def test_interpolate_data_error_on_extrapolation(self): msg = "One of the requested xi is out of bounds in dimension 0" interpolator = RectilinearInterpolator(self.cube, ["latitude"], LINEAR, extrapolation_mode="error") with self.assertRaisesRegex(ValueError, msg): interpolator([[-1]])
def check_expected(): # Check a simple case is equivalent to extracting the first row. self.interpolator = RectilinearInterpolator( self.cube, ["latitude"], LINEAR, EXTRAPOLATE) expected = self.data[:, 0:1, :] result = self.interpolator([[0]]) self.assertArrayEqual(result.data, expected)
def test_multi_dim_coord_interpolation(self): msg = "Interpolation coords must be 1-d for rectilinear interpolation." with self.assertRaisesRegex(ValueError, msg): interpolator = RectilinearInterpolator( self.cube, ["foo", "bar"], LINEAR, EXTRAPOLATE ) interpolator([[15], [10]])
def test_interpolator_overspecified(self): # Over specification by means of interpolating over two coordinates # mapped to the same dimension. msg = ("Coordinates repeat a data dimension - " "the interpolation would be over-specified") with self.assertRaisesRegex(ValueError, msg): RectilinearInterpolator(self.cube, ["wibble", "height"], LINEAR, EXTRAPOLATE)
def test_interpolate_non_monotonic(self): self.cube.add_aux_coord( iris.coords.AuxCoord([0, 3, 2], long_name="non-monotonic"), 1) msg = ("Cannot interpolate over the non-monotonic coordinate " "non-monotonic.") with self.assertRaisesRegex(ValueError, msg): RectilinearInterpolator(self.cube, ["non-monotonic"], LINEAR, EXTRAPOLATE)
def test_interpolate_data_unsupported_extrapolation(self): msg = "Extrapolation mode 'unsupported' not supported" with self.assertRaisesRegex(ValueError, msg): RectilinearInterpolator( self.cube, ["latitude"], LINEAR, extrapolation_mode="unsupported", )
def test_unsorted_datadim_mapping(self): # Currently unsorted data dimension mapping is not supported as the # indexing is not yet clever enough to remap the interpolated # coordinates. self.cube.transpose((0, 2, 1)) interpolator = RectilinearInterpolator(self.cube, ["latitude"], LINEAR, EXTRAPOLATE) msg = "Currently only increasing data_dims is supported." with self.assertRaisesRegex(NotImplementedError, msg): interpolator([0])
def interpolator(self, method=LINEAR): data = np.arange(12).reshape(4, 3) cube = iris.cube.Cube(data) time_coord = iris.coords.DimCoord(np.arange(0.0, 48.0, 12.0), 'time', units='hours since epoch') height_coord = iris.coords.DimCoord(np.arange(3), 'altitude', units='m') cube.add_dim_coord(time_coord, 0) cube.add_dim_coord(height_coord, 1) return RectilinearInterpolator(cube, ['time'], method, EXTRAPOLATE)
def test_fully_wrapped_not_circular(self): cube = stock.lat_lon_cube() new_long = cube.coord("longitude").copy( cube.coord("longitude").points + 710) cube.remove_coord("longitude") cube.add_dim_coord(new_long, 1) interpolator = RectilinearInterpolator(cube, ["longitude"], LINEAR, EXTRAPOLATE) res = interpolator([-10]) self.assertArrayEqual(res.data, cube[:, 1].data)
def test_interpolator_overspecified_scalar(self): # Over specification by means of interpolating over one dimension # coordinate and a scalar coordinate (not mapped to a dimension). self.cube.add_aux_coord(iris.coords.AuxCoord(1, long_name="scalar"), None) msg = ("Coordinates repeat a data dimension - " "the interpolation would be over-specified") with self.assertRaisesRegex(ValueError, msg): RectilinearInterpolator(self.cube, ["wibble", "scalar"], LINEAR, EXTRAPOLATE)
def test_properties(self): interpolator = RectilinearInterpolator(self.cube, ["latitude"], LINEAR, EXTRAPOLATE) self.assertEqual(interpolator.method, LINEAR) self.assertEqual(interpolator.extrapolation_mode, EXTRAPOLATE) # Access to cube property of the RectilinearInterpolator instance. self.assertEqual(interpolator.cube, self.cube) # Access to the resulting coordinate which we are interpolating over. self.assertEqual(interpolator.coords, [self.cube.coord("latitude")])
def test_orthogonal_cube(self): interpolator = RectilinearInterpolator(self.cube, ['grid_latitude'], LINEAR, EXTRAPOLATE) result_cube = interpolator([1]) # Explicit mask comparison to ensure mask retention. # Masked value input self.assertTrue(self.cube.data.mask[0, 0, 0, 0]) # Mask retention on output self.assertTrue(result_cube.data.mask[0, 0, 0]) self.assertCML(result_cube, ('experimental', 'analysis', 'interpolate', 'LinearInterpolator', 'orthogonal_cube_with_factory.cml'))
def test_src_cube_data_loaded(self): # RectilinearInterpolator operates using a snapshot of the source cube. # If the source cube has lazy data when the interpolator is # instantiated we want to make sure the source cube's data is # loaded as a consequence of interpolation to avoid the risk # of loading it again and again. # Modify self.cube to have lazy data. self.cube.data = as_lazy_data(self.data) self.assertTrue(self.cube.has_lazy_data()) # Perform interpolation and check the data has been loaded. interpolator = RectilinearInterpolator(self.cube, ["latitude"], LINEAR, EXTRAPOLATE) interpolator([[1.5]]) self.assertFalse(self.cube.has_lazy_data())
def setUp(self): """ thingness / (1) (wibble: 2; latitude: 1) Dimension coordinates: wibble x - latitude - x Auxiliary coordinates: height x - bar - x foo - x Scalar coordinates: longitude: 0 """ ThreeDimCube.setUp(self) self.cube = self.cube[:, 0:1, 0] self.interpolator = RectilinearInterpolator(self.cube, ["latitude"], LINEAR, EXTRAPOLATE)
def test_collapse_scalar(self): interpolator = RectilinearInterpolator(self.cube, ['wibble'], LINEAR, EXTRAPOLATE) result = interpolator([0], collapse_scalar=True) self.assertEqual(result.shape, (3, 4))
def test_interpolate_bad_coord_name(self): with self.assertRaises(iris.exceptions.CoordinateNotFoundError): RectilinearInterpolator(self.cube, ["doesnt exist"], LINEAR, EXTRAPOLATE)
def setUp(self): ThreeDimCube.setUp(self) coords = ["height", "longitude"] self.interpolator = RectilinearInterpolator(self.cube, coords, LINEAR, EXTRAPOLATE)
def setUp(self): ThreeDimCube.setUp(self) self.interpolator = RectilinearInterpolator(self.cube, ["latitude", "longitude"], LINEAR, EXTRAPOLATE)
def test_no_collapse_scalar(self): interpolator = RectilinearInterpolator(self.cube, ["wibble"], LINEAR, EXTRAPOLATE) result = interpolator([0], collapse_scalar=False) self.assertEqual(result.shape, (1, 3, 4))
def test_interpolate_data_nan_extrapolation(self): interpolator = RectilinearInterpolator(self.cube, ["latitude"], LINEAR, extrapolation_mode="nan") result = interpolator([[1001]]) self.assertTrue(np.all(np.isnan(result.data)))