def test_get_sample_from_bil_info(self): """Test bilinear interpolation as a whole.""" from pyresample.bilinear.xarr import XArrayResamplerBilinear resampler = XArrayResamplerBilinear(self.source_def, self.target_def, self.radius) _ = resampler.get_bil_info() # Sample from data1 res = resampler.get_sample_from_bil_info(self.data1) res = res.compute() # Check couple of values self.assertEqual(res.values[1, 1], 1.) self.assertTrue(np.isnan(res.values[0, 3])) # Check that the values haven't gone down or up a lot self.assertAlmostEqual(np.nanmin(res.values), 1.) self.assertAlmostEqual(np.nanmax(res.values), 1.) # Check that dimensions are the same self.assertEqual(res.dims, self.data1.dims) # Sample from data1, custom fill value res = resampler.get_sample_from_bil_info(self.data1, fill_value=-1.0) res = res.compute() self.assertEqual(np.nanmin(res.values), -1.) # Sample from integer data res = resampler.get_sample_from_bil_info(self.data1.astype(np.uint8), fill_value=None) res = res.compute() # Five values should be filled with zeros, which is the # default fill_value for integer data self.assertEqual(np.sum(res == 0), 6)
def test_get_sample_from_bil_info(self): """Test bilinear interpolation as a whole.""" import dask.array as da from xarray import DataArray from pyresample.bilinear.xarr import XArrayResamplerBilinear resampler = XArrayResamplerBilinear(self.source_def, self.target_def, self.radius) resampler.get_bil_info() # Sample from data1 res = resampler.get_sample_from_bil_info(self.data1) res = res.compute() # Check couple of values self.assertEqual(res.values[1, 1], 1.) self.assertTrue(np.isnan(res.values[0, 3])) # Check that the values haven't gone down or up a lot self.assertAlmostEqual(np.nanmin(res.values), 1.) self.assertAlmostEqual(np.nanmax(res.values), 1.) # Check that dimensions are the same self.assertEqual(res.dims, self.data1.dims) # Sample from data1, custom fill value res = resampler.get_sample_from_bil_info(self.data1, fill_value=-1.0) res = res.compute() self.assertEqual(np.nanmin(res.values), -1.) # Sample from integer data res = resampler.get_sample_from_bil_info(self.data1.astype(np.uint8), fill_value=None) res = res.compute() # Five values should be filled with zeros, which is the # default fill_value for integer data self.assertEqual(np.sum(res == 0), 6) # Output coordinates should have been set self.assertTrue(isinstance(resampler._out_coords, dict)) self.assertTrue( np.all(resampler._out_coords['x'] == resampler.out_coords_x)) self.assertTrue( np.all(resampler._out_coords['y'] == resampler.out_coords_y)) # 3D data data = da.moveaxis(da.dstack((self.data1, self.data1)), -1, 0) data = DataArray(data, dims=('bands', 'y', 'x')) res = resampler.get_sample_from_bil_info(data) assert res.shape == (2, ) + self.target_def.shape assert res.dims == data.dims
class BilinearResampler(BaseResampler): """Resample using bilinear.""" def __init__(self, source_geo_def, target_geo_def): super(BilinearResampler, self).__init__(source_geo_def, target_geo_def) self.resampler = None def precompute(self, mask=None, radius_of_influence=50000, epsilon=0, reduce_data=True, nprocs=1, cache_dir=False, **kwargs): """Create bilinear coefficients and store them for later use. Note: The `mask` keyword should be provided if geolocation may be valid where data points are invalid. This defaults to the `mask` attribute of the `data` numpy masked array passed to the `resample` method. """ del kwargs if self.resampler is None: kwargs = dict(source_geo_def=self.source_geo_def, target_geo_def=self.target_geo_def, radius_of_influence=radius_of_influence, neighbours=32, epsilon=epsilon, reduce_data=reduce_data) self.resampler = XArrayResamplerBilinear(**kwargs) try: self.load_bil_info(cache_dir, **kwargs) LOG.debug("Loaded bilinear parameters") except IOError: LOG.debug("Computing bilinear parameters") self.resampler.get_bil_info() self.save_bil_info(cache_dir, **kwargs) def load_bil_info(self, cache_dir, **kwargs): if cache_dir: filename = self._create_cache_filename(cache_dir, prefix='resample_lut_bil_', **kwargs) cache = np.load(filename) for elt in ['bilinear_s', 'bilinear_t', 'valid_input_index', 'index_array']: if isinstance(cache[elt], tuple): setattr(self.resampler, elt, cache[elt][0]) else: setattr(self.resampler, elt, cache[elt]) cache.close() else: raise IOError def save_bil_info(self, cache_dir, **kwargs): if cache_dir: filename = self._create_cache_filename(cache_dir, prefix='resample_lut_bil_', **kwargs) LOG.info('Saving kd_tree neighbour info to %s', filename) cache = {'bilinear_s': self.resampler.bilinear_s, 'bilinear_t': self.resampler.bilinear_t, 'valid_input_index': self.resampler.valid_input_index, 'index_array': self.resampler.index_array} np.savez(filename, **cache) def compute(self, data, fill_value=None, **kwargs): """Resample the given data using bilinear interpolation""" del kwargs if fill_value is None: fill_value = data.attrs.get('_FillValue') target_shape = self.target_geo_def.shape res = self.resampler.get_sample_from_bil_info(data, fill_value=fill_value, output_shape=target_shape) return res
class BilinearResampler(BaseResampler): """Resample using bilinear.""" def __init__(self, source_geo_def, target_geo_def): """Init BilinearResampler.""" super(BilinearResampler, self).__init__(source_geo_def, target_geo_def) self.resampler = None def precompute(self, mask=None, radius_of_influence=50000, epsilon=0, reduce_data=True, cache_dir=False, **kwargs): """Create bilinear coefficients and store them for later use. Note: The `mask` keyword should be provided if geolocation may be valid where data points are invalid. This defaults to the `mask` attribute of the `data` numpy masked array passed to the `resample` method. """ del kwargs if self.resampler is None: kwargs = dict(source_geo_def=self.source_geo_def, target_geo_def=self.target_geo_def, radius_of_influence=radius_of_influence, neighbours=32, epsilon=epsilon, reduce_data=reduce_data) self.resampler = XArrayResamplerBilinear(**kwargs) try: self.load_bil_info(cache_dir, **kwargs) LOG.debug("Loaded bilinear parameters") except IOError: LOG.debug("Computing bilinear parameters") self.resampler.get_bil_info() self.save_bil_info(cache_dir, **kwargs) def load_bil_info(self, cache_dir, **kwargs): """Load bilinear resampling info from cache directory.""" if cache_dir: filename = self._create_cache_filename(cache_dir, prefix='bil_lut-', **kwargs) for val in BIL_COORDINATES.keys(): try: cache = da.from_zarr(filename, val) if val == 'valid_input_index': # valid input index array needs to be boolean cache = cache.astype(np.bool) # Compute the cache arrays cache = cache.compute() except ValueError: raise IOError setattr(self.resampler, val, cache) else: raise IOError def save_bil_info(self, cache_dir, **kwargs): """Save bilinear resampling info to cache directory.""" if cache_dir: filename = self._create_cache_filename(cache_dir, prefix='bil_lut-', **kwargs) LOG.info('Saving BIL neighbour info to %s', filename) zarr_out = xr.Dataset() for idx_name, coord in BIL_COORDINATES.items(): var = getattr(self.resampler, idx_name) if isinstance(var, np.ndarray): var = da.from_array(var, chunks=CHUNK_SIZE) var = var.rechunk(CHUNK_SIZE) zarr_out[idx_name] = (coord, var) zarr_out.to_zarr(filename) def compute(self, data, fill_value=None, **kwargs): """Resample the given data using bilinear interpolation.""" del kwargs if fill_value is None: fill_value = data.attrs.get('_FillValue') target_shape = self.target_geo_def.shape res = self.resampler.get_sample_from_bil_info(data, fill_value=fill_value, output_shape=target_shape) return update_resampled_coords(data, res, self.target_geo_def)