Ejemplo n.º 1
0
    def test_str_definition(self):
        # should throw an error if string input is not one of the INTERPOLATION_SHORTCUTS
        with pytest.raises(InterpolationException):
            Interpolation('test')

        interp = Interpolation('nearest')
        assert interp.config[('default', )]
        assert isinstance(interp.config[('default', )], dict)
        assert interp.config[('default', )]['method'] == 'nearest'
        assert isinstance(interp.config[('default', )]['interpolators'][0],
                          Interpolator)
Ejemplo n.º 2
0
    def test_select_coordinates(self):

        reqcoords = Coordinates([[0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2]],
                                dims=['lat', 'lon', 'time', 'alt'])
        srccoords = Coordinates([[0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2]],
                                dims=['lat', 'lon', 'time', 'alt'])

        # create a few dummy interpolators that handle certain dimensions
        # (can_select is defined by default to look at dims_supported)
        class TimeLat(Interpolator):
            dims_supported = ['time', 'lat']

            def select_coordinates(self, udims, srccoords, srccoords_idx,
                                   reqcoords):
                return srccoords, srccoords_idx

        class LatLon(Interpolator):
            dims_supported = ['lat', 'lon']

            def select_coordinates(self, udims, srccoords, srccoords_idx,
                                   reqcoords):
                return srccoords, srccoords_idx

        class Lon(Interpolator):
            dims_supported = ['lon']

            def select_coordinates(self, udims, srccoords, srccoords_idx,
                                   reqcoords):
                return srccoords, srccoords_idx

        # set up a strange interpolation definition
        # we want to interpolate (lat, lon) first, then after (time, alt)
        interp = Interpolation({
            ('lat', 'lon'): {
                'method': 'myinterp',
                'interpolators': [LatLon, TimeLat]
            },
            ('time', 'alt'): {
                'method': 'myinterp',
                'interpolators': [TimeLat, Lon]
            }
        })

        coords, cidx = interp.select_coordinates(srccoords, [], reqcoords)

        assert len(coords) == len(srccoords)
        assert len(coords['lat']) == len(srccoords['lat'])
        assert cidx == ()
Ejemplo n.º 3
0
    def test_interpolator_init_type(self):
        """test constructor
        """

        # should throw an error if definition is not str, dict, or Interpolator
        with pytest.raises(TypeError):
            Interpolation(5)
Ejemplo n.º 4
0
    def _set_interpolation(self):
        """Update _interpolation property
        """

        # define interpolator with source coordinates dimensions
        if isinstance(self.interpolation, Interpolation):
            self._interpolation = self.interpolation
        else:
            self._interpolation = Interpolation(self.interpolation)
Ejemplo n.º 5
0
    def test_init_interpolators(self):

        # should set method
        interp = Interpolation('nearest')
        assert interp.config[(
            'default', )]['interpolators'][0].method == 'nearest'

        # Interpolation init should init all interpolators in the list
        interp = Interpolation({
            'default': {
                'method': 'nearest',
                'params': {
                    'spatial_tolerance': 1
                }
            }
        })
        assert interp.config[(
            'default', )]['interpolators'][0].spatial_tolerance == 1

        # should throw TraitErrors defined by Interpolator
        with pytest.raises(tl.TraitError):
            Interpolation({
                'default': {
                    'method': 'nearest',
                    'params': {
                        'spatial_tolerance': 'tol'
                    }
                }
            })

        # should not allow undefined params
        interp = Interpolation(
            {'default': {
                'method': 'nearest',
                'params': {
                    'myarg': 1
                }
            }})
        with pytest.raises(AttributeError):
            assert interp.config[(
                'default', )]['interpolators'][0].myarg == 'tol'
Ejemplo n.º 6
0
    def test_interpolate(self):
        class TestInterp(Interpolator):
            dims_supported = ['lat', 'lon']

            def interpolate(self, udims, source_coordinates, source_data,
                            eval_coordinates, output_data):
                output_data = source_data
                return output_data

        # test basic functionality
        reqcoords = Coordinates([[-.5, 1.5, 3.5], [.5, 2.5, 4.5]],
                                dims=['lat', 'lon'])
        srccoords = Coordinates([[0, 2, 4], [0, 3, 4]], dims=['lat', 'lon'])
        srcdata = UnitsDataArray(
            np.random.rand(3, 3),
            coords=[srccoords[c].coordinates for c in srccoords],
            dims=srccoords.dims)
        outdata = UnitsDataArray(
            np.zeros(srcdata.shape),
            coords=[reqcoords[c].coordinates for c in reqcoords],
            dims=reqcoords.dims)

        interp = Interpolation({
            ('lat', 'lon'): {
                'method': 'test',
                'interpolators': [TestInterp]
            }
        })
        outdata = interp.interpolate(srccoords, srcdata, reqcoords, outdata)

        assert np.all(outdata == srcdata)

        # test if data is size 1
        class TestFakeInterp(Interpolator):
            dims_supported = ['lat']

            def interpolate(self, udims, source_coordinates, source_data,
                            eval_coordinates, output_data):
                return None

        reqcoords = Coordinates([[1]], dims=['lat'])
        srccoords = Coordinates([[1]], dims=['lat'])
        srcdata = UnitsDataArray(
            np.random.rand(1),
            coords=[srccoords[c].coordinates for c in srccoords],
            dims=srccoords.dims)
        outdata = UnitsDataArray(
            np.zeros(srcdata.shape),
            coords=[reqcoords[c].coordinates for c in reqcoords],
            dims=reqcoords.dims)

        interp = Interpolation({
            ('lat', 'lon'): {
                'method': 'test',
                'interpolators': [TestFakeInterp]
            }
        })
        outdata = interp.interpolate(srccoords, srcdata, reqcoords, outdata)

        assert np.all(outdata == srcdata)
Ejemplo n.º 7
0
        def test_nearest_preview_select(self):

            # test straight ahead functionality
            reqcoords = Coordinates([[-.5, 1.5, 3.5], [.5, 2.5, 4.5]],
                                    dims=['lat', 'lon'])
            srccoords = Coordinates([[0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]],
                                    dims=['lat', 'lon'])

            interp = Interpolation('nearest_preview')

            srccoords, srccoords_index = srccoords.intersect(
                reqcoords, outer=True, return_indices=True)
            coords, cidx = interp.select_coordinates(srccoords,
                                                     srccoords_index,
                                                     reqcoords)

            assert len(coords) == len(srccoords) == len(cidx)
            assert len(coords['lat']) == len(reqcoords['lat'])
            assert len(coords['lon']) == len(reqcoords['lon'])
            assert np.all(coords['lat'].coordinates == np.array([0, 2, 4]))

            # test when selection is applied serially
            # this is equivalent to above
            reqcoords = Coordinates([[-.5, 1.5, 3.5], [.5, 2.5, 4.5]],
                                    dims=['lat', 'lon'])
            srccoords = Coordinates([[0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]],
                                    dims=['lat', 'lon'])

            interp = Interpolation({
                'lat': 'nearest_preview',
                'lon': 'nearest_preview'
            })

            srccoords, srccoords_index = srccoords.intersect(
                reqcoords, outer=True, return_indices=True)
            coords, cidx = interp.select_coordinates(srccoords,
                                                     srccoords_index,
                                                     reqcoords)

            assert len(coords) == len(srccoords) == len(cidx)
            assert len(coords['lat']) == len(reqcoords['lat'])
            assert len(coords['lon']) == len(reqcoords['lon'])
            assert np.all(coords['lat'].coordinates == np.array([0, 2, 4]))
Ejemplo n.º 8
0
    def test_dict_definition(self):

        # should handle a default definition without any dimensions specified as keys
        interp = Interpolation({
            'method': 'nearest',
            'params': {
                'spatial_tolerance': 1
            }
        })
        assert isinstance(interp.config[('default', )], dict)
        assert interp.config[('default', )]['method'] == 'nearest'
        assert isinstance(interp.config[('default', )]['interpolators'][0],
                          Interpolator)
        assert interp.config[('default', )]['params'] == {
            'spatial_tolerance': 1
        }

        # should throw an error on _parse_interpolation_method(definition)
        # if definition is not in INTERPOLATION_SHORTCUTS
        with pytest.raises(InterpolationException):
            Interpolation({('lat', 'lon'): 'test'})

        # handle string methods
        interp = Interpolation({('lat', 'lon'): 'nearest'})
        assert isinstance(interp.config[('lat', 'lon')], dict)
        assert interp.config[('lat', 'lon')]['method'] == 'nearest'
        assert isinstance(interp.config[('default', )]['interpolators'][0],
                          Interpolator)
        assert interp.config[('default', )]['params'] == {}

        # handle dict methods

        # should throw an error if method is not in dict
        with pytest.raises(InterpolationException):
            Interpolation({('lat', 'lon'): {'test': 'test'}})

        # should throw an error if method is not a string
        with pytest.raises(InterpolationException):
            Interpolation({('lat', 'lon'): {'method': 5}})

        # should throw an error if method is not one of the INTERPOLATION_SHORTCUTS and no interpolators defined
        with pytest.raises(InterpolationException):
            Interpolation({('lat', 'lon'): {'method': 'myinter'}})

        # should throw an error if params is not a dict
        with pytest.raises(TypeError):
            Interpolation({
                ('lat', 'lon'): {
                    'method': 'nearest',
                    'params': 'test'
                }
            })

        # should throw an error if interpolators is not a list
        with pytest.raises(TypeError):
            Interpolation({
                ('lat', 'lon'): {
                    'method': 'nearest',
                    'interpolators': 'test'
                }
            })

        # should throw an error if interpolators are not Interpolator classes
        with pytest.raises(TypeError):
            Interpolation({
                ('lat', 'lon'): {
                    'method': 'nearest',
                    'interpolators': [NearestNeighbor, 'test']
                }
            })

        # should throw an error if dimension is defined twice
        with pytest.raises(InterpolationException):
            Interpolation({('lat', 'lon'): 'nearest', 'lat': 'bilinear'})

        # should handle standard INTEPROLATION_SHORTCUTS
        interp = Interpolation({('lat', 'lon'): {'method': 'nearest'}})
        assert isinstance(interp.config[('lat', 'lon')], dict)
        assert interp.config[('lat', 'lon')]['method'] == 'nearest'
        assert isinstance(interp.config[('lat', 'lon')]['interpolators'][0],
                          Interpolator)
        assert interp.config[('lat', 'lon')]['params'] == {}

        # should allow custom methods if interpolators are defined
        interp = Interpolation({
            ('lat', 'lon'): {
                'method': 'myinter',
                'interpolators': [NearestNeighbor, NearestPreview]
            }
        })
        assert interp.config[('lat', 'lon')]['method'] == 'myinter'
        assert isinstance(interp.config[('lat', 'lon')]['interpolators'][0],
                          NearestNeighbor)

        # should allow params to be set
        interp = Interpolation({
            ('lat', 'lon'): {
                'method': 'myinter',
                'interpolators': [NearestNeighbor, NearestPreview],
                'params': {
                    'spatial_tolerance': 5
                }
            }
        })
        assert interp.config[('lat', 'lon')]['params'] == {
            'spatial_tolerance': 5
        }

        # set default equal to empty tuple
        interp = Interpolation({'lat': 'bilinear'})
        assert interp.config[('default', )]['method'] == INTERPOLATION_DEFAULT

        # use default with override if not all dimensions are supplied
        interp = Interpolation({'lat': 'bilinear', 'default': 'nearest'})
        assert interp.config[('default', )]['method'] == 'nearest'

        # make sure default is always the last key in the ordered config dict
        interp = Interpolation({'default': 'nearest', 'lat': 'bilinear'})
        assert list(interp.config.keys())[-1] == ('default', )
Ejemplo n.º 9
0
    def test_select_interpolator_queue(self):

        reqcoords = Coordinates([[0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2]],
                                dims=['lat', 'lon', 'time', 'alt'])
        srccoords = Coordinates([[0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2]],
                                dims=['lat', 'lon', 'time', 'alt'])

        # create a few dummy interpolators that handle certain dimensions
        # (can_select is defined by default to look at dims_supported)
        class TimeLat(Interpolator):
            dims_supported = ['time', 'lat']

            def can_select(self, udims, source_coordinates, eval_coordinates):
                return self._filter_udims_supported(udims)

            def can_interpolate(self, udims, source_coordinates,
                                eval_coordinates):
                return self._filter_udims_supported(udims)

        class LatLon(Interpolator):
            dims_supported = ['lat', 'lon']

            def can_select(self, udims, source_coordinates, eval_coordinates):
                return self._filter_udims_supported(udims)

            def can_interpolate(self, udims, source_coordinates,
                                eval_coordinates):
                return self._filter_udims_supported(udims)

        class Lon(Interpolator):
            dims_supported = ['lon']

            def can_select(self, udims, source_coordinates, eval_coordinates):
                return self._filter_udims_supported(udims)

            def can_interpolate(self, udims, source_coordinates,
                                eval_coordinates):
                return self._filter_udims_supported(udims)

        # set up a strange interpolation definition
        # we want to interpolate (lat, lon) first, then after (time, alt)
        interp = Interpolation({
            ('lat', 'lon'): {
                'method': 'myinterp',
                'interpolators': [LatLon, TimeLat]
            },
            ('time', 'alt'): {
                'method': 'myinterp',
                'interpolators': [TimeLat, Lon]
            }
        })

        # default = Nearest, which always returns () for can_select
        interpolator_queue = interp._select_interpolator_queue(
            srccoords, reqcoords, 'can_select')
        assert isinstance(interpolator_queue, OrderedDict)
        assert isinstance(interpolator_queue[('lat', 'lon')], LatLon)
        assert ('time', 'alt') not in interpolator_queue

        # should throw an error if strict is set and not all dimensions can be handled
        with pytest.raises(InterpolationException):
            interpolator_queue = interp._select_interpolator_queue(
                srccoords, reqcoords, 'can_select', strict=True)

        # default = Nearest, which can handle all dims for can_interpolate
        interpolator_queue = interp._select_interpolator_queue(
            srccoords, reqcoords, 'can_interpolate')
        assert isinstance(interpolator_queue, OrderedDict)
        assert isinstance(interpolator_queue[('lat', 'lon')], LatLon)

        if ('alt', 'time') in interpolator_queue:
            assert isinstance(interpolator_queue[('alt', 'time')],
                              NearestNeighbor)
        else:
            assert isinstance(interpolator_queue[('time', 'alt')],
                              NearestNeighbor)