def test_extrapolation(self): """ Check that extrapolation filter works """ N = 5 y = np.linspace(0, 1000, N) x = np.zeros(N) grid = gridpp.Points(y, x, x, x, gridpp.Cartesian) points = gridpp.Points([0, 100, 900, 1000], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], gridpp.Cartesian) Y = points.size() pratios = 0.1 * np.ones(Y) structure = gridpp.BarnesStructure(500) pobs = [0, 1, 1, 0] background = np.zeros(grid.size()) pbackground = np.zeros(Y) max_points = 10 output0 = gridpp.optimal_interpolation(grid, background, points, pobs, pratios, pbackground, structure, max_points, False) output1 = gridpp.optimal_interpolation(grid, background, points, pobs, pratios, pbackground, structure, max_points, True) # Turning off extrapolation should mean we don't get increments greater than 1 self.assertTrue(np.max(output0) == 1) self.assertTrue(np.max(output1) > 1) I = np.where(output1 < 1)[0] np.testing.assert_array_almost_equal(output0[I], output1[I])
def test_missing_values(self): """Check that missing values are not used in OI""" obs = np.array([1, np.nan, 2, 3, np.nan, np.nan, 4, np.nan]) N = len(obs) y = np.arange(0, N * 1000, 1000) background = np.zeros(N) points = gridpp.Points(y, np.zeros(N), np.zeros(N), np.zeros(N), gridpp.Cartesian) ratios = np.ones(N) structure = gridpp.BarnesStructure(1000, 0) analysis = gridpp.optimal_interpolation(points, background, points, obs, ratios, background, structure, 100) I = np.where(np.isnan(y) == 0)[0] points1 = gridpp.Points(y[I], np.zeros(len(I)), np.zeros(len(I)), np.zeros(len(I)), gridpp.Cartesian) analysis1 = gridpp.optimal_interpolation(points, background, points1, obs[I], ratios[I], background[I], structure, 100) np.testing.assert_array_almost_equal(analysis, analysis1)
def test_cross_validation(self): y = np.array([0, 1000, 2000, 3000]) N = len(y) obs = np.array([0, 1, 2, 3]) background = np.zeros(N) points = gridpp.Points(y, np.zeros(N), np.zeros(N), np.zeros(N), gridpp.Cartesian) ratios = np.ones(N) Icv = [0, 2, 3] points_cv = gridpp.Points(y[Icv], np.zeros(N - 1), np.zeros(N - 1), np.zeros(N - 1), gridpp.Cartesian) structure = gridpp.BarnesStructure(1000, 0) structure_cv = gridpp.CrossValidation(structure, 750) analysis = gridpp.optimal_interpolation(points, background, points_cv, obs[Icv], ratios[Icv], background[Icv], structure, 100) analysis_cv = gridpp.optimal_interpolation(points, background, points, obs, ratios, background, structure_cv, 100)
def test_invalid_arguments(self): """ Check that exception is thrown on invalid input values """ # Set up struct with valid input arguments ok_args = collections.OrderedDict({ 'grid': gridpp.Grid([[0, 0, 0]], [[0, 2500, 10000]], [[0, 0, 0]], [[0, 0, 0]], gridpp.Cartesian), 'background': np.zeros([1, 3]), 'points': gridpp.Points([0], [2500], [0], [0], gridpp.Cartesian), 'pobs': [1], 'pratios': [0.1], 'pbackground': [0], 'structure': gridpp.BarnesStructure(2500), 'max_points': 10 }) # Set up struct with invalid input arguments that will be substituted into ok_args one at a # time in order to look for an exception being raised. Use an array of different invalid # arguments for each key. x = np.zeros([3, 2]) invalid_args = { # Grid size mismatch, and coordinate-type mismatch 'grid': [ gridpp.Grid(x, x, x, x, gridpp.Cartesian), gridpp.Grid([[0, 0, 0]], [[0, 2500, 10000]]) ], # Points size mismatch, and coordinate-type mismatch 'points': [ gridpp.Points([0, 1], [0, 2500], [0, 0], [0, 0], gridpp.Cartesian), gridpp.Points([0], [2500]) ], 'pratios': [np.zeros(11)], 'pobs': [np.zeros([11])], 'background': [np.zeros([2, 11])], 'pbackground': [np.zeros(21)], 'max_points': [-1] } for key in invalid_args.keys(): for arg in invalid_args[key]: args0 = ok_args.copy() args0[key] = arg q = [args0[f] for f in args0] with self.subTest(key=key, arg=arg): with self.assertRaises(ValueError) as e: output = gridpp.optimal_interpolation(*q)
def test_cross_validation_grid(self): """ Check that the CV structure function works """ np.random.seed(1000) y, x = np.meshgrid(np.arange(0, 3500, 500), np.arange(0, 3500, 500)) Y = y.shape[0] X = y.shape[1] grid = gridpp.Grid(y, x, np.zeros(x.shape), np.zeros(x.shape), gridpp.Cartesian) background = np.random.rand(Y, X) * 0 obs = np.array([10, 20, 30]) x_o = np.array([1000, 2000, 3000]) y_o = np.array([1000, 2000, 3000]) N = len(obs) points = gridpp.Points(y_o, x_o, np.zeros(N), np.zeros(N), gridpp.Cartesian) background_o = gridpp.nearest(grid, points, background) ratios = np.ones(N) k = 0 ii = np.arange(N).astype('int') != k points_cv = gridpp.Points(y_o[ii], x_o[ii], np.zeros(N - 1), np.zeros(N - 1), gridpp.Cartesian) structure = gridpp.BarnesStructure(1000, 0) structure_cv = gridpp.CrossValidation(structure, 750) analysis = gridpp.optimal_interpolation(grid, background, points_cv, obs[ii], ratios[ii], background_o[ii], structure, 100) analysis_cv = gridpp.optimal_interpolation(points, background_o, points, obs, ratios, background_o, structure_cv, 100) self.assertAlmostEqual( gridpp.nearest(grid, points, analysis)[k], analysis_cv[k])
def test_simple_1d(self): N = 3 y = [[0, 0, 0]] x = [[0, 2500, 10000]] grid = gridpp.Grid(y, x, y, y, gridpp.Cartesian) points = gridpp.Points([0], [2500], [0], [0], gridpp.Cartesian) pratios = [0.1] structure = gridpp.BarnesStructure(2500) pobs = [1] background = np.zeros([1, N]) pbackground = [0] max_points = 10 output = gridpp.optimal_interpolation(grid, background, points, pobs, pratios, pbackground, structure, max_points) np.testing.assert_array_almost_equal( output, np.array([[np.exp(-0.5) / 1.1, 1 / 1.1, np.exp(-0.5 * 9) / 1.1]]))
def horizontal_oi(geo, background, observations, gelevs, glafs, hlength=10000., vlength=10000., wlength=0.5, elev_gradient=0, structure_function="Barnes", land_only=False, max_locations=50, epsilon=0.5, minvalue=None, maxvalue=None, interpol="bilinear"): if gridpp is None: raise Exception("You need gridpp to perform OI") glats = geo.lats glons = geo.lons def obs2vectors(my_obs): return my_obs.lons, my_obs.lats, my_obs.stids, my_obs.elevs, \ my_obs.values, my_obs.cis, my_obs.lafs vectors = np.vectorize(obs2vectors) lons, lats, stids, elevs, values, pci, lafs = vectors(observations) glats = np.transpose(glats) glons = np.transpose(glons) background = np.transpose(background) gelevs = np.transpose(gelevs) glafs = np.transpose(glafs) bgrid = gridpp.Grid(glats, glons, gelevs) points = gridpp.Points(lats, lons, elevs) if interpol == "bilinear": pbackground = gridpp.bilinear(bgrid, points, background) elif interpol == "nearest": pbackground = gridpp.nearest(bgrid, points, background, elev_gradient) else: raise NotImplementedError variance_ratios = np.full(points.size(), epsilon) if structure_function == "Barnes": # No land/sea weight when land_only = True if land_only: wlength = 0. structure = gridpp.BarnesStructure(hlength, vlength, wlength) else: raise NotImplementedError field = gridpp.optimal_interpolation(bgrid, background, points, values, variance_ratios, pbackground, structure, max_locations) field = np.asarray(field) if minvalue is not None: field[field < minvalue] = minvalue if maxvalue is not None: field[field > maxvalue] = maxvalue if land_only: no_land = np.where(glafs == 0) field[no_land] = background[no_land] return np.transpose(field)
# Downscaling gradient = -0.0065 background = gridpp.simple_gradient(bgrid_2500m, bgrid, background_2500m, gradient) points = gridpp.Points(obs_lats[index_valid_obs], obs_lons[index_valid_obs], obs_elevs[index_valid_obs]) pbackground = gridpp.bilinear(bgrid, points, background) variance_ratios = np.full(points.size(), 0.1) h = 100000 v = 200 structure = gridpp.BarnesStructure(h, v) max_points = 50 analysis = gridpp.optimal_interpolation(bgrid, background, points, obs[index_valid_obs], variance_ratios, pbackground, structure, max_points) # Plotting the increments diff = analysis - background mpl.pcolormesh(blons, blats, diff, cmap="RdBu_r", vmin=-2, vmax=2) mpl.xlim(0, 35) mpl.ylim(55, 75) mpl.gca().set_aspect(2) cb = mpl.colorbar() cb.set_label(r"Increment ($\degree C$)") mpl.savefig("analysis_increment.png", bbox_inches='tight', dpi=125) mpl.clf() # Ensemble mode with netCDF4.Dataset('analysis.nc', 'r') as file: