Exemple #1
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
Exemple #2
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)
Exemple #3
0
    def test_slice_data(self):
        """Test slicing the data."""
        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()

        # Too many dimensions
        data = DataArray(da.ones((1, 3) + self.source_def.shape))
        with self.assertRaises(ValueError):
            _ = resampler._slice_data(data, np.nan)

        # 2D data
        data = DataArray(da.ones(self.source_def.shape))
        p_1, p_2, p_3, p_4 = resampler._slice_data(data, np.nan)
        self.assertEqual(p_1.shape, resampler.bilinear_s.shape)
        self.assertTrue(p_1.shape == p_2.shape == p_3.shape == p_4.shape)
        self.assertTrue(
            np.all(p_1 == 1.0) and np.all(p_2 == 1.0) and np.all(p_3 == 1.0)
            and np.all(p_4 == 1.0))

        # 2D data with masking
        resampler.mask_slices[:, :] = True
        p_1, p_2, p_3, p_4 = resampler._slice_data(data, np.nan)
        self.assertTrue(
            np.all(np.isnan(p_1)) and np.all(np.isnan(p_2))
            and np.all(np.isnan(p_3)) and np.all(np.isnan(p_4)))
        # 3D data
        data = DataArray(da.ones((3, ) + self.source_def.shape))
        resampler.mask_slices[:, :] = False
        p_1, p_2, p_3, p_4 = resampler._slice_data(data, np.nan)
        self.assertEqual(p_1.shape, (3, ) + resampler.bilinear_s.shape)
        self.assertTrue(p_1.shape == p_2.shape == p_3.shape == p_4.shape)

        # 3D data with masking
        resampler.mask_slices[:, :] = True
        p_1, p_2, p_3, p_4 = resampler._slice_data(data, np.nan)
        self.assertTrue(
            np.all(np.isnan(p_1)) and np.all(np.isnan(p_2))
            and np.all(np.isnan(p_3)) and np.all(np.isnan(p_4)))
Exemple #4
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
Exemple #5
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)
Exemple #6
0
    def test_get_bil_info(self):
        """Test calculation of bilinear info."""
        from pyresample.bilinear.xarr import XArrayResamplerBilinear

        def _check_ts(t__, s__, nans):
            for i, _ in enumerate(t__):
                # Just check the exact value for one pixel
                if i == 5:
                    self.assertAlmostEqual(t__[i], 0.730659147133, 5)
                    self.assertAlmostEqual(s__[i], 0.310314173004, 5)
                # These pixels are outside the area
                elif i in nans:
                    self.assertTrue(np.isnan(t__[i]))
                    self.assertTrue(np.isnan(s__[i]))
                # All the others should have values between 0.0 and 1.0
                else:
                    self.assertTrue(t__[i] >= 0.0)
                    self.assertTrue(s__[i] >= 0.0)
                    self.assertTrue(t__[i] <= 1.0)
                    self.assertTrue(s__[i] <= 1.0)

        # Data reduction enabled (default)
        resampler = XArrayResamplerBilinear(self.source_def,
                                            self.target_def,
                                            self.radius,
                                            reduce_data=True)
        (t__, s__, slices, mask_slices, out_coords) = resampler.get_bil_info()
        _check_ts(t__.compute(), s__.compute(), [3, 10, 12, 13, 14, 15])

        # Nothing should be masked based on coordinates
        self.assertTrue(np.all(~mask_slices))
        # Four values per output location
        self.assertEqual(mask_slices.shape, (self.target_def.size, 4))

        # self.slices_{x,y} are used in self.slices dict so they
        # should be the same (object)
        self.assertTrue(isinstance(slices, dict))
        self.assertTrue(resampler.slices['x'] is resampler.slices_x)
        self.assertTrue(np.all(resampler.slices['x'] == slices['x']))
        self.assertTrue(resampler.slices['y'] is resampler.slices_y)
        self.assertTrue(np.all(resampler.slices['y'] == slices['y']))

        # self.slices_{x,y} are used in self.slices dict so they
        # should be the same (object)
        self.assertTrue(isinstance(out_coords, dict))
        self.assertTrue(resampler.out_coords['x'] is resampler.out_coords_x)
        self.assertTrue(np.all(resampler.out_coords['x'] == out_coords['x']))
        self.assertTrue(resampler.out_coords['y'] is resampler.out_coords_y)
        self.assertTrue(np.all(resampler.out_coords['y'] == out_coords['y']))

        # Also some other attributes should have been set
        self.assertTrue(t__ is resampler.bilinear_t)
        self.assertTrue(s__ is resampler.bilinear_s)
        self.assertIsNotNone(resampler.valid_output_index)
        self.assertIsNotNone(resampler.index_array)
        self.assertIsNotNone(resampler.valid_input_index)

        # Data reduction disabled
        resampler = XArrayResamplerBilinear(self.source_def,
                                            self.target_def,
                                            self.radius,
                                            reduce_data=False)
        (t__, s__, slices, mask_slices, out_coords) = resampler.get_bil_info()
        _check_ts(t__.compute(), s__.compute(), [10, 12, 13, 14, 15])
Exemple #7
0
    def test_get_bil_info(self):
        """Test calculation of bilinear info."""
        from pyresample.bilinear.xarr import XArrayResamplerBilinear

        def _check_ts(t__, s__, nans):
            for i, _ in enumerate(t__):
                # Just check the exact value for one pixel
                if i == 5:
                    self.assertAlmostEqual(t__[i], 0.730659147133, 5)
                    self.assertAlmostEqual(s__[i], 0.310314173004, 5)
                # These pixels are outside the area
                elif i in nans:
                    self.assertTrue(np.isnan(t__[i]))
                    self.assertTrue(np.isnan(s__[i]))
                # All the others should have values between 0.0 and 1.0
                else:
                    self.assertTrue(t__[i] >= 0.0)
                    self.assertTrue(s__[i] >= 0.0)
                    self.assertTrue(t__[i] <= 1.0)
                    self.assertTrue(s__[i] <= 1.0)

        # Data reduction enabled (default)
        resampler = XArrayResamplerBilinear(self.source_def,
                                            self.target_def,
                                            self.radius,
                                            reduce_data=True)
        resampler.get_bil_info()
        t__ = resampler.bilinear_t
        s__ = resampler.bilinear_s
        mask_slices = resampler.mask_slices
        _check_ts(t__, s__, [3, 10, 12, 13, 14, 15])

        # Nothing should be masked based on coordinates
        self.assertTrue(np.all(~mask_slices))
        # Four values per output location
        self.assertEqual(mask_slices.shape, (self.target_def.size, 4))

        # Also some other attributes should have been set
        self.assertTrue(t__ is resampler.bilinear_t)
        self.assertTrue(s__ is resampler.bilinear_s)
        self.assertIsNotNone(resampler._index_array)
        self.assertIsNotNone(resampler._valid_input_index)
        self.assertIsNotNone(resampler.out_coords_x)
        self.assertIsNotNone(resampler.out_coords_y)
        self.assertTrue(
            np.allclose(resampler.out_coords_x,
                        [-1070912.72, -470912.72, 129087.28, 729087.28]))
        self.assertTrue(
            np.allclose(resampler.out_coords_y,
                        [1190031.36, 590031.36, -9968.64, -609968.64]))

        # Data reduction disabled
        resampler = XArrayResamplerBilinear(self.source_def,
                                            self.target_def,
                                            self.radius,
                                            reduce_data=False)
        resampler.get_bil_info()
        t__ = resampler.bilinear_t
        s__ = resampler.bilinear_s
        mask_slices = resampler.mask_slices
        _check_ts(t__, s__, [10, 12, 13, 14, 15])

        # Target area and source data do not overlap
        resampler = XArrayResamplerBilinear(self.source_def,
                                            self.target_def_outside,
                                            self.radius,
                                            reduce_data=False)
        resampler.get_bil_info()
        self.assertEqual(resampler.bilinear_t.shape,
                         (self.target_def_outside.size, ))
        self.assertEqual(resampler.bilinear_s.shape,
                         (self.target_def_outside.size, ))
        self.assertEqual(resampler.slices_x.shape,
                         (self.target_def_outside.size, 4))
        self.assertEqual(resampler.slices_y.shape,
                         (self.target_def_outside.size, 4))
        self.assertEqual(resampler.out_coords_x.shape,
                         (self.target_def_outside.shape[1], ))
        self.assertEqual(resampler.out_coords_y.shape,
                         (self.target_def_outside.shape[0], ))
        self.assertEqual(resampler.mask_slices.shape,
                         (self.target_def_outside.size, 4))