Esempio n. 1
0
    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)
Esempio n. 2
0
    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
Esempio n. 3
0
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
Esempio n. 4
0
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)