Beispiel #1
0
    def test_select_single_vertice(self):
        """
        Test with a polygon that encloses a single pixel vertice,
        but no centers. That is, crosses four pixels
        """
        # Masked
        dataset = xr.Dataset({
            'first': (['lat', 'lon', 'time'], np.ones([6, 12, 3])),
            'second': (['lat', 'lon', 'time'], np.ones([6, 12, 3])),
            'lat':
            np.linspace(-75, 75, 6),
            'lon':
            np.linspace(-165, 165, 12),
            'time': [datetime(2000, x, 1) for x in range(1, 4)]
        })
        poly = ((25, 2), (27, 40), (58, 38), (54, 4))
        actual = subset.subset_spatial(dataset, region=poly)
        expected = xr.Dataset({
            'first': (['lat', 'lon', 'time'], np.ones([2, 2, 3])),
            'second': (['lat', 'lon', 'time'], np.ones([2, 2, 3])),
            'lat': [15., 45.],
            'lon': [15., 45.],
            'time': [datetime(2000, x, 1) for x in range(1, 4)]
        })

        assert_dataset_equal(expected, actual)

        # Not masked
        actual = subset.subset_spatial(dataset, region=poly, mask=False)
        assert_dataset_equal(expected, actual)
Beispiel #2
0
    def test_non_geospatial_variable(self):
        """
        Test that subsetting a dataset that contains a non-geospatial
        dataset skips such a dataset
        """
        dataset = xr.Dataset({
            'first': (['lat', 'lon', 'time'], np.ones([180, 360, 6])),
            'second': (['lat', 'lon', 'time'], np.ones([180, 360, 6])),
            'third': (['time'], np.ones([6])),
            'lat': np.linspace(-89.5, 89.5, 180),
            'lon': np.linspace(-179.5, 179.5, 360),
            'time': np.array([0, 1, 2, 3, 4, 5])})
        actual = subset.subset_spatial(dataset, "-20, -10, 20, 10")
        expected = xr.Dataset({
            'first': (['lat', 'lon', 'time'], np.ones([22, 42, 6])),
            'second': (['lat', 'lon', 'time'], np.ones([22, 42, 6])),
            'third': (['time'], np.ones([6])),
            'lat': np.linspace(-10.5, 10.5, 22),
            'lon': np.linspace(-20.5, 20.5, 42),
            'time': np.array([0, 1, 2, 3, 4, 5])})
        assert_dataset_equal(expected, actual)

        poly = "POLYGON ((6.609745636041873 45.391851854914776, 19.720614826531428 45.391851854914776, 19.720614826531428 37.06301149556095, 6.609745636041874 37.06301149556095, 6.609745636041873 45.391851854914776))"
        actual = subset.subset_spatial(dataset, poly, mask=True)
        xr.testing.assert_equal(expected.third, actual.third)
Beispiel #3
0
    def test_select_1d_lon(self):
        """
        Test with a polygon that runs over pixel boundaries in the
        longitude direction. E.g., selects a single row
        """
        # Masked
        dataset = xr.Dataset({
            'first': (['lat', 'lon', 'time'], np.ones([6, 12, 3])),
            'second': (['lat', 'lon', 'time'], np.ones([6, 12, 3])),
            'lat': np.linspace(-75, 75, 6),
            'lon': np.linspace(-165, 165, 12),
            'time': [datetime(2000, x, 1) for x in range(1, 4)]})
        poly = ((-28, 32), (-26, 58), (28, 52), (25, 33))
        actual = subset.subset_spatial(dataset, region=poly)
        expected = xr.Dataset({
            'first': (['lat', 'lon', 'time'], np.ones([1, 2, 3])),
            'second': (['lat', 'lon', 'time'], np.ones([1, 2, 3])),
            'lat': [45.],
            'lon': [-15., 15.],
            'time': [datetime(2000, x, 1) for x in range(1, 4)]})

        assert_dataset_equal(expected, actual)

        # Not masked
        actual = subset.subset_spatial(dataset, region=poly, mask=False)
        assert_dataset_equal(expected, actual)
Beispiel #4
0
    def test_select_1d_lat(self):
        """
        Test with a polyon that runs over pixel boundaries in the
        latitude direction, resulting in selecting a single column
        """
        # Masked
        dataset = xr.Dataset({
            'first': (['lat', 'lon', 'time'], np.ones([6, 12, 3])),
            'second': (['lat', 'lon', 'time'], np.ones([6, 12, 3])),
            'lat':
            np.linspace(-75, 75, 6),
            'lon':
            np.linspace(-165, 165, 12),
            'time': [datetime(2000, x, 1) for x in range(1, 4)]
        })
        poly = ((25, 2), (27, 47), (12, 50), (10, 4))
        actual = subset.subset_spatial(dataset, region=poly)
        expected = xr.Dataset({
            'first': (['lat', 'lon', 'time'], np.ones([2, 1, 3])),
            'second': (['lat', 'lon', 'time'], np.ones([2, 1, 3])),
            'lat': [15., 45.],
            'lon': [15.],
            'time': [datetime(2000, x, 1) for x in range(1, 4)]
        })

        assert_dataset_equal(expected, actual)

        # Not masked
        actual = subset.subset_spatial(dataset, region=poly, mask=False)
        assert_dataset_equal(expected, actual)
Beispiel #5
0
    def test_select_single_vertice(self):
        """
        Test with a polygon that encloses a single pixel vertice,
        but no centers. That is, crosses four pixels
        """
        # Masked
        dataset = xr.Dataset({
            'first': (['lat', 'lon', 'time'], np.ones([6, 12, 3])),
            'second': (['lat', 'lon', 'time'], np.ones([6, 12, 3])),
            'lat': np.linspace(-75, 75, 6),
            'lon': np.linspace(-165, 165, 12),
            'time': [datetime(2000, x, 1) for x in range(1, 4)]})
        poly = ((25, 2), (27, 40), (58, 38), (54, 4))
        actual = subset.subset_spatial(dataset, region=poly)
        expected = xr.Dataset({
            'first': (['lat', 'lon', 'time'], np.ones([2, 2, 3])),
            'second': (['lat', 'lon', 'time'], np.ones([2, 2, 3])),
            'lat': [15., 45.],
            'lon': [15., 45.],
            'time': [datetime(2000, x, 1) for x in range(1, 4)]})

        assert_dataset_equal(expected, actual)

        # Not masked
        actual = subset.subset_spatial(dataset, region=poly, mask=False)
        assert_dataset_equal(expected, actual)
Beispiel #6
0
    def test_select_1d_lat(self):
        """
        Test with a polyon that runs over pixel boundaries in the
        latitude direction, resulting in selecting a single column
        """
        # Masked
        dataset = xr.Dataset({
            'first': (['lat', 'lon', 'time'], np.ones([6, 12, 3])),
            'second': (['lat', 'lon', 'time'], np.ones([6, 12, 3])),
            'lat': np.linspace(-75, 75, 6),
            'lon': np.linspace(-165, 165, 12),
            'time': [datetime(2000, x, 1) for x in range(1, 4)]})
        poly = ((25, 2), (27, 47), (12, 50), (10, 4))
        actual = subset.subset_spatial(dataset, region=poly)
        expected = xr.Dataset({
            'first': (['lat', 'lon', 'time'], np.ones([2, 1, 3])),
            'second': (['lat', 'lon', 'time'], np.ones([2, 1, 3])),
            'lat': [15., 45.],
            'lon': [15.],
            'time': [datetime(2000, x, 1) for x in range(1, 4)]})

        assert_dataset_equal(expected, actual)

        # Not masked
        actual = subset.subset_spatial(dataset, region=poly, mask=False)
        assert_dataset_equal(expected, actual)
Beispiel #7
0
    def test_select_1d_lon(self):
        """
        Test with a polygon that runs over pixel boundaries in the
        longitude direction. E.g., selects a single row
        """
        # Masked
        dataset = xr.Dataset({
            'first': (['lat', 'lon', 'time'], np.ones([6, 12, 3])),
            'second': (['lat', 'lon', 'time'], np.ones([6, 12, 3])),
            'lat':
            np.linspace(-75, 75, 6),
            'lon':
            np.linspace(-165, 165, 12),
            'time': [datetime(2000, x, 1) for x in range(1, 4)]
        })
        poly = ((-28, 32), (-26, 58), (28, 52), (25, 33))
        actual = subset.subset_spatial(dataset, region=poly)
        expected = xr.Dataset({
            'first': (['lat', 'lon', 'time'], np.ones([1, 2, 3])),
            'second': (['lat', 'lon', 'time'], np.ones([1, 2, 3])),
            'lat': [45.],
            'lon': [-15., 15.],
            'time': [datetime(2000, x, 1) for x in range(1, 4)]
        })

        assert_dataset_equal(expected, actual)

        # Not masked
        actual = subset.subset_spatial(dataset, region=poly, mask=False)
        assert_dataset_equal(expected, actual)
Beispiel #8
0
    def test_select_single_center(self):
        """
        Test subset spatial with a polygon that completely fits
        inside pixel bounds
        """
        # Masked
        dataset = xr.Dataset({
            'first': (['lat', 'lon', 'time'], np.ones([6, 12, 3])),
            'second': (['lat', 'lon', 'time'], np.ones([6, 12, 3])),
            'lat': np.linspace(-75, 75, 6),
            'lon': np.linspace(-165, 165, 12),
            'time': [datetime(2000, x, 1) for x in range(1, 4)]})
        poly = ((32, 2), (34, 28), (58, 29), (54, 4))
        actual = subset.subset_spatial(dataset, region=poly)
        expected = xr.Dataset({
            'first': (['lat', 'lon', 'time'], np.ones([1, 1, 3])),
            'second': (['lat', 'lon', 'time'], np.ones([1, 1, 3])),
            'lat': [15.],
            'lon': [45.],
            'time': [datetime(2000, x, 1) for x in range(1, 4)]})

        assert_dataset_equal(expected, actual)

        # Not masked
        actual = subset.subset_spatial(dataset, region=poly, mask=False)
        assert_dataset_equal(expected, actual)
Beispiel #9
0
    def test_antimeridian_arbitrary_inverted(self):
        antimeridian_pol = str('POLYGON(('
                               '162.0703125 39.639537564366705,'
                               '-155.390625 39.774769485295465,'
                               '-155.56640625 12.726084296948184,'
                               '162.24609375 12.897489183755905,'
                               '161.89453125 26.745610382199025,'
                               '162.0703125 39.639537564366705'
                               '))')
        # Inverted lat
        dataset = xr.Dataset({
            'first': (['lat', 'lon', 'time'], np.ones([180, 360, 6])),
            'second': (['lat', 'lon', 'time'], np.ones([180, 360, 6])),
            'lat':
            np.linspace(89.5, -89.5, 180),
            'lon':
            np.linspace(-179.5, 179.5, 360)
        })

        with self.assertRaises(Exception) as cm:
            subset.subset_spatial(dataset, antimeridian_pol)
        self.assertEqual(
            str(cm.exception),
            "Spatial subsets crossing the anti-meridian are currently implemented for simple, "
            "rectangular polygons only.")
Beispiel #10
0
    def test_select_single_center(self):
        """
        Test subset spatial with a polygon that completely fits
        inside pixel bounds
        """
        # Masked
        dataset = xr.Dataset({
            'first': (['lat', 'lon', 'time'], np.ones([6, 12, 3])),
            'second': (['lat', 'lon', 'time'], np.ones([6, 12, 3])),
            'lat':
            np.linspace(-75, 75, 6),
            'lon':
            np.linspace(-165, 165, 12),
            'time': [datetime(2000, x, 1) for x in range(1, 4)]
        })
        poly = ((32, 2), (34, 28), (58, 29), (54, 4))
        actual = subset.subset_spatial(dataset, region=poly)
        expected = xr.Dataset({
            'first': (['lat', 'lon', 'time'], np.ones([1, 1, 3])),
            'second': (['lat', 'lon', 'time'], np.ones([1, 1, 3])),
            'lat': [15.],
            'lon': [45.],
            'time': [datetime(2000, x, 1) for x in range(1, 4)]
        })

        assert_dataset_equal(expected, actual)

        # Not masked
        actual = subset.subset_spatial(dataset, region=poly, mask=False)
        assert_dataset_equal(expected, actual)
Beispiel #11
0
    def test_non_geospatial_variable(self):
        """
        Test that subsetting a dataset that contains a non-geospatial
        dataset skips such a dataset
        """
        dataset = xr.Dataset({
            'first': (['lat', 'lon', 'time'], np.ones([180, 360, 6])),
            'second': (['lat', 'lon', 'time'], np.ones([180, 360, 6])),
            'third': (['time'], np.ones([6])),
            'lat':
            np.linspace(-89.5, 89.5, 180),
            'lon':
            np.linspace(-179.5, 179.5, 360),
            'time':
            np.array([0, 1, 2, 3, 4, 5])
        })
        actual = subset.subset_spatial(dataset, "-20, -10, 20, 10")
        expected = xr.Dataset({
            'first': (['lat', 'lon', 'time'], np.ones([22, 42, 6])),
            'second': (['lat', 'lon', 'time'], np.ones([22, 42, 6])),
            'third': (['time'], np.ones([6])),
            'lat':
            np.linspace(-10.5, 10.5, 22),
            'lon':
            np.linspace(-20.5, 20.5, 42),
            'time':
            np.array([0, 1, 2, 3, 4, 5])
        })
        assert_dataset_equal(expected, actual)

        poly = "POLYGON ((6.609745636041873 45.391851854914776, 19.720614826531428 45.391851854914776, 19.720614826531428 37.06301149556095, 6.609745636041874 37.06301149556095, 6.609745636041873 45.391851854914776))"
        actual = subset.subset_spatial(dataset, poly, mask=True)
        xr.testing.assert_equal(expected.third, actual.third)
Beispiel #12
0
    def test_generic_masked_inverted(self):
        """
        Test using a generic Polygon and masking
        """
        # Africa
        a = str('POLYGON((-10.8984375 35.60371874069731,-19.16015625 '
                '23.885837699861995,-20.56640625 17.14079039331665,-18.6328125 '
                '7.536764322084079,-10.72265625 0.7031073524364783,10.37109375 '
                '0.3515602939922709,10.37109375 -22.268764039073965,22.8515625 '
                '-42.29356419217007,37.79296875 -27.21555620902968,49.39453125 '
                '-3.5134210456400323,54.4921875 14.093957177836236,18.984375 '
                '35.88905007936091,-10.8984375 35.60371874069731))')

        # Inverted lat
        dataset = xr.Dataset({
            'first': (['lat', 'lon', 'time'], np.ones([180, 360, 6])),
            'second': (['lat', 'lon', 'time'], np.ones([180, 360, 6])),
            'lat': np.linspace(89.5, -89.5, 180),
            'lon': np.linspace(-179.5, 179.5, 360)})
        actual = subset.subset_spatial(dataset, a)
        # Gulf of Guinea
        gog = actual.sel(method='nearest', **{'lon': 1.2, 'lat': -1.4})
        self.assertTrue(np.isnan(gog['first']).all())
        # Africa
        self.assertTrue(1 == actual.sel(method='nearest', **{'lon': 20.7, 'lat': 6.15}))
Beispiel #13
0
def anomaly_internal(ds: xr.Dataset,
                     time_range: TimeRangeLike.TYPE = None,
                     region: PolygonLike.TYPE = None,
                     monitor: Monitor = Monitor.NONE) -> xr.Dataset:
    """
    Calculate anomaly using as reference data the mean of an optional region
    and time slice from the given dataset. If no time slice/spatial region is
    given, the operation will calculate anomaly using the mean of the whole
    dataset as the reference.

    This is done for each data array in the dataset.
    :param ds: The dataset to calculate anomalies from
    :param time_range: Time range to use for reference data
    :param region: Spatial region to use for reference data
    :param monitor: a progress monitor.
    :return: The anomaly dataset
    """
    ref = ds.copy()
    if time_range:
        time_range = TimeRangeLike.convert(time_range)
        ref = subset_temporal(ref, time_range)
    if region:
        region = PolygonLike.convert(region)
        ref = subset_spatial(ref, region)
    with monitor.observing("Calculating anomaly"):
        ref = ref.mean(keep_attrs=True, skipna=True)
        diff = ds - ref
    return diff
Beispiel #14
0
    def test_generic_masked(self):
        """
        Test using a generic Polygon and masking
        """
        # Africa
        a = str(
            'POLYGON((-10.8984375 35.60371874069731,-19.16015625 '
            '23.885837699861995,-20.56640625 17.14079039331665,-18.6328125 '
            '7.536764322084079,-10.72265625 0.7031073524364783,10.37109375 '
            '0.3515602939922709,10.37109375 -22.268764039073965,22.8515625 '
            '-42.29356419217007,37.79296875 -27.21555620902968,49.39453125 '
            '-3.5134210456400323,54.4921875 14.093957177836236,18.984375 '
            '35.88905007936091,-10.8984375 35.60371874069731))')

        dataset = xr.Dataset({
            'first': (['lat', 'lon', 'time'], np.ones([180, 360, 6])),
            'second': (['lat', 'lon', 'time'], np.ones([180, 360, 6])),
            'lat':
            np.linspace(-89.5, 89.5, 180),
            'lon':
            np.linspace(-179.5, 179.5, 360)
        })
        actual = subset.subset_spatial(dataset, a)
        # Gulf of Guinea
        gog = actual.sel(method='nearest', **{'lon': 1.2, 'lat': -1.4})
        self.assertTrue(np.isnan(gog['first']).all())
        # Africa
        self.assertTrue(
            1 == actual.sel(method='nearest', **{
                'lon': 20.7,
                'lat': 6.15
            }))
Beispiel #15
0
def anomaly_internal(ds: xr.Dataset,
                     time_range: TimeRangeLike.TYPE = None,
                     region: PolygonLike.TYPE = None,
                     monitor: Monitor = Monitor.NONE) -> xr.Dataset:
    """
    Calculate anomaly using as reference data the mean of an optional region
    and time slice from the given dataset. If no time slice/spatial region is
    given, the operation will calculate anomaly using the mean of the whole
    dataset as the reference.

    This is done for each data array in the dataset.
    :param ds: The dataset to calculate anomalies from
    :param time_range: Time range to use for reference data
    :param region: Spatial region to use for reference data
    :param monitor: a progress monitor.
    :return: The anomaly dataset
    """
    ref = ds.copy()
    if time_range:
        time_range = TimeRangeLike.convert(time_range)
        ref = subset_temporal(ref, time_range)
    if region:
        region = PolygonLike.convert(region)
        ref = subset_spatial(ref, region)
    with monitor.observing("Calculating anomaly"):
        ref = ref.mean(keep_attrs=True, skipna=True)
        diff = ds - ref
    return diff
Beispiel #16
0
    def test_antimeridian_simple(self):
        dataset = xr.Dataset({
            'first': (['lat', 'lon', 'time'], np.ones([180, 360, 6])),
            'second': (['lat', 'lon', 'time'], np.ones([180, 360, 6])),
            'lat':
            np.linspace(-89.5, 89.5, 180),
            'lon':
            np.linspace(-179.5, 179.5, 360)
        })

        # With masking
        actual = subset.subset_spatial(dataset, '170, -5, -170, 5', mask=True)
        masked = actual.sel(method='nearest', **{'lon': 0, 'lat': 0})
        self.assertTrue(np.isnan(masked['first']).all())

        # With dropping
        actual = subset.subset_spatial(dataset, '170, -5, -170, 5', mask=False)
        self.assertEqual(20, len(actual.lon))
Beispiel #17
0
    def test_antimeridian_arbitrary(self):
        antimeridian_pol = str('POLYGON(('
                               '162.0703125 39.639537564366705,'
                               '-155.390625 39.774769485295465,'
                               '-155.56640625 12.726084296948184,'
                               '162.24609375 12.897489183755905,'
                               '161.89453125 26.745610382199025,'
                               '162.0703125 39.639537564366705'
                               '))')
        dataset = xr.Dataset({
            'first': (['lat', 'lon', 'time'], np.ones([180, 360, 6])),
            'second': (['lat', 'lon', 'time'], np.ones([180, 360, 6])),
            'lat': np.linspace(-89.5, 89.5, 180),
            'lon': np.linspace(-179.5, 179.5, 360)})

        with self.assertRaises(Exception) as cm:
            subset.subset_spatial(dataset, antimeridian_pol)
        self.assertIn('anti-meridian', str(cm.exception))
Beispiel #18
0
    def test_select_from_single_pixel(self):
        """
        Test subset spatial where the input dataset has only one pixel
        """
        # Masked
        dataset = xr.Dataset({
            'first': (['lat', 'lon', 'time'], np.ones([1, 1, 3])),
            'second': (['lat', 'lon', 'time'], np.ones([1, 1, 3])),
            'lat': [45.],
            'lon': [15.],
            'time': [datetime(2000, x, 1) for x in range(1, 4)]})
        poly = ((-28, 32), (-26, 58), (28, 52), (25, 33))
        actual = subset.subset_spatial(dataset, region=poly)

        assert_dataset_equal(dataset, actual)

        # Not masked
        actual = subset.subset_spatial(dataset, region=poly, mask=False)
        assert_dataset_equal(dataset, actual)
Beispiel #19
0
    def test_antimeridian_arbitrary(self):
        pol = str(
            'POLYGON((162.0703125 39.639537564366705,-155.390625'
            '39.774769485295465,-155.56640625 12.726084296948184,162.24609375'
            '12.897489183755905,161.89453125 26.745610382199025,162.0703125'
            '39.639537564366705))')
        dataset = xr.Dataset({
            'first': (['lat', 'lon', 'time'], np.ones([180, 360, 6])),
            'second': (['lat', 'lon', 'time'], np.ones([180, 360, 6])),
            'lat':
            np.linspace(-89.5, 89.5, 180),
            'lon':
            np.linspace(-179.5, 179.5, 360)
        })

        with self.assertRaises(Exception) as err:
            subset.subset_spatial(dataset, pol)
        self.assertEqual('cannot convert geometry to a valid Polygon: ' + pol,
                         str(err.exception))
Beispiel #20
0
    def test_select_from_single_pixel(self):
        """
        Test subset spatial where the input dataset has only one pixel
        """
        # Masked
        dataset = xr.Dataset({
            'first': (['lat', 'lon', 'time'], np.ones([1, 1, 3])),
            'second': (['lat', 'lon', 'time'], np.ones([1, 1, 3])),
            'lat': [45.],
            'lon': [15.],
            'time': [datetime(2000, x, 1) for x in range(1, 4)]
        })
        poly = ((-28, 32), (-26, 58), (28, 52), (25, 33))
        actual = subset.subset_spatial(dataset, region=poly)

        assert_dataset_equal(dataset, actual)

        # Not masked
        actual = subset.subset_spatial(dataset, region=poly, mask=False)
        assert_dataset_equal(dataset, actual)
Beispiel #21
0
    def test_antimeridian_simple(self):
        dataset = xr.Dataset({
            'first': (['lat', 'lon', 'time'], np.ones([180, 360, 6])),
            'second': (['lat', 'lon', 'time'], np.ones([180, 360, 6])),
            'lat': np.linspace(-89.5, 89.5, 180),
            'lon': np.linspace(-179.5, 179.5, 360)})

        # With masking
        actual = subset.subset_spatial(dataset, '170, -5, -170, 5', mask=True)
        masked = actual.sel(method='nearest', **{'lon': 0, 'lat': 0})
        self.assertTrue(np.isnan(masked['first']).all())
Beispiel #22
0
    def test_out_of_bounds(self):
        """
        Test that an appropriate error is raised when the polygon
        wouldn't select any data from the original dataset
        """
        dataset = xr.Dataset({
            'first': (['lat', 'lon', 'time'], np.ones([1, 1, 3])),
            'second': (['lat', 'lon', 'time'], np.ones([1, 1, 3])),
            'lat': [45.],
            'lon': [15.],
            'time': [datetime(2000, x, 1) for x in range(1, 4)]})
        poly = ((32, 32), (34, 58), (56, 56), (58, 33))

        with self.assertRaises(ValueError) as err:
            subset.subset_spatial(dataset, region=poly)
        self.assertIn('Can not select', str(err.exception))

        # Not masked
        with self.assertRaises(ValueError) as err:
            subset.subset_spatial(dataset, region=poly, mask=False)
        self.assertIn('Can not select', str(err.exception))
Beispiel #23
0
    def test_antimeridian_arbitrary(self):
        antimeridian_pol = str('POLYGON(('
                               '162.0703125 39.639537564366705,'
                               '-155.390625 39.774769485295465,'
                               '-155.56640625 12.726084296948184,'
                               '162.24609375 12.897489183755905,'
                               '161.89453125 26.745610382199025,'
                               '162.0703125 39.639537564366705'
                               '))')
        dataset = xr.Dataset({
            'first': (['lat', 'lon', 'time'], np.ones([180, 360, 6])),
            'second': (['lat', 'lon', 'time'], np.ones([180, 360, 6])),
            'lat':
            np.linspace(-89.5, 89.5, 180),
            'lon':
            np.linspace(-179.5, 179.5, 360)
        })

        with self.assertRaises(Exception) as cm:
            subset.subset_spatial(dataset, antimeridian_pol)
        self.assertIn('anti-meridian', str(cm.exception))
Beispiel #24
0
    def test_out_of_bounds(self):
        """
        Test that an appropriate error is raised when the polygon
        wouldn't select any data from the original dataset
        """
        dataset = xr.Dataset({
            'first': (['lat', 'lon', 'time'], np.ones([1, 1, 3])),
            'second': (['lat', 'lon', 'time'], np.ones([1, 1, 3])),
            'lat': [45.],
            'lon': [15.],
            'time': [datetime(2000, x, 1) for x in range(1, 4)]
        })
        poly = ((32, 32), (34, 58), (56, 56), (58, 33))

        with self.assertRaises(ValueError) as err:
            subset.subset_spatial(dataset, region=poly)
        self.assertIn('Can not select', str(err.exception))

        # Not masked
        with self.assertRaises(ValueError) as err:
            subset.subset_spatial(dataset, region=poly, mask=False)
        self.assertIn('Can not select', str(err.exception))
Beispiel #25
0
    def test_antimeridian_arbitrary(self):
        pol = str(
            'POLYGON((162.0703125 39.639537564366705,-155.390625'
            '39.774769485295465,-155.56640625 12.726084296948184,162.24609375'
            '12.897489183755905,161.89453125 26.745610382199025,162.0703125'
            '39.639537564366705))')
        dataset = xr.Dataset({
            'first': (['lat', 'lon', 'time'], np.ones([180, 360, 6])),
            'second': (['lat', 'lon', 'time'], np.ones([180, 360, 6])),
            'lat':
            np.linspace(-89.5, 89.5, 180),
            'lon':
            np.linspace(-179.5, 179.5, 360)
        })

        with self.assertRaises(Exception) as cm:
            subset.subset_spatial(dataset, pol)
        self.assertEqual(
            str(cm.exception),
            "input 'region' for operation 'cate.ops.subset.subset_spatial': "
            "cannot convert value <POLYGON((162.0703125 39.63953756436670...> to PolygonLike"
        )
Beispiel #26
0
 def test_nominal(self):
     """
     Test general 'most expected' use case functionality.
     """
     dataset = xr.Dataset({
         'first': (['lat', 'lon', 'time'], np.ones([180, 360, 6])),
         'second': (['lat', 'lon', 'time'], np.ones([180, 360, 6])),
         'lat': np.linspace(-89.5, 89.5, 180),
         'lon': np.linspace(-179.5, 179.5, 360)})
     actual = subset.subset_spatial(dataset, "-20, -10, 20, 10")
     expected = xr.Dataset({
         'first': (['lat', 'lon', 'time'], np.ones([22, 42, 6])),
         'second': (['lat', 'lon', 'time'], np.ones([22, 42, 6])),
         'lat': np.linspace(-10.5, 10.5, 22),
         'lon': np.linspace(-20.5, 20.5, 42)})
     assert_dataset_equal(expected, actual)
Beispiel #27
0
 def test_inverted_dims_nominal(self):
     """
     Test if the implementation is dimension order agnostic.
     """
     # Inverted lat
     dataset = xr.Dataset({
         'first': (['lon', 'lat', 'time'], np.ones([360, 180, 6])),
         'second': (['lon', 'lat', 'time'], np.ones([360, 180, 6])),
         'lat': np.linspace(89.5, -89.5, 180),
         'lon': np.linspace(-179.5, 179.5, 360)})
     actual = subset.subset_spatial(dataset, "-20, -10, 20, 10")
     expected = xr.Dataset({
         'first': (['lon', 'lat', 'time'], np.ones([42, 22, 6])),
         'second': (['lon', 'lat', 'time'], np.ones([42, 22, 6])),
         'lat': np.linspace(10.5, -10.5, 22),
         'lon': np.linspace(-20.5, 20.5, 42)})
     assert_dataset_equal(expected, actual)
Beispiel #28
0
def _generic_index_calculation(
        ds: xr.Dataset,
        var: VarName.TYPE,
        region: PolygonLike.TYPE,
        window: int,
        file: str,
        name: str,
        threshold: float = None,
        monitor: Monitor = Monitor.NONE) -> pd.DataFrame:
    """
    A generic index calculation. Where an index is defined as an anomaly
    against the given reference of a moving average of the given window size of
    the given given region of the given variable of the given dataset.

    :param ds: Dataset from which to calculate the index
    :param var: Variable from which to calculate index
    :param region: Spatial subset from which to calculate the index
    :param window: Window size for the moving average
    :param file: Path to the reference file
    :param threshold: Absolute threshold that indicates an ENSO event
    :param name: Name of the index
    :param monitor: a progress monitor.
    :return: A dataset that contains the index timeseries
    """
    var = VarName.convert(var)
    region = PolygonLike.convert(region)

    with monitor.starting("Calculate the index", total_work=2):
        ds = select_var(ds, var)
        ds_subset = subset_spatial(ds, region)
        anom = anomaly_external(ds_subset, file, monitor=monitor.child(1))
        with monitor.child(1).observing("Calculate mean"):
            ts = anom.mean(dim=['lat', 'lon'])
        df = pd.DataFrame(data=ts[var].values,
                          columns=[name],
                          index=ts.time.values)
        retval = df.rolling(window=window, center=True).mean().dropna()

    if threshold is None:
        return retval

    retval['El Nino'] = pd.Series((retval[name] > threshold),
                                  index=retval.index)
    retval['La Nina'] = pd.Series((retval[name] < -threshold),
                                  index=retval.index)
    return retval
Beispiel #29
0
def _generic_index_calculation(ds: xr.Dataset,
                               var: VarName.TYPE,
                               region: PolygonLike.TYPE,
                               window: int,
                               file: str,
                               name: str,
                               threshold: float = None,
                               monitor: Monitor = Monitor.NONE) -> pd.DataFrame:
    """
    A generic index calculation. Where an index is defined as an anomaly
    against the given reference of a moving average of the given window size of
    the given given region of the given variable of the given dataset.

    :param ds: Dataset from which to calculate the index
    :param var: Variable from which to calculate index
    :param region: Spatial subset from which to calculate the index
    :param window: Window size for the moving average
    :param file: Path to the reference file
    :param threshold: Absolute threshold that indicates an ENSO event
    :param name: Name of the index
    :param monitor: a progress monitor.
    :return: A dataset that contains the index timeseries
    """
    var = VarName.convert(var)
    region = PolygonLike.convert(region)

    with monitor.starting("Calculate the index", total_work=2):
        ds = select_var(ds, var)
        ds_subset = subset_spatial(ds, region)
        anom = anomaly_external(ds_subset, file, monitor=monitor.child(1))
        with monitor.child(1).observing("Calculate mean"):
            ts = anom.mean(dim=['lat', 'lon'])
        df = pd.DataFrame(data=ts[var].values, columns=[name], index=ts.time)
        retval = df.rolling(window=window, center=True).mean().dropna()

    if threshold is None:
        return retval

    retval['El Nino'] = pd.Series((retval[name] > threshold),
                                  index=retval.index)
    retval['La Nina'] = pd.Series((retval[name] < -threshold),
                                  index=retval.index)
    return retval
Beispiel #30
0
 def test_inverted_dims(self):
     """
     Test if the implementation is dimension order agnostic.
     """
     dataset = xr.Dataset({
         'first': (['lon', 'lat', 'time'], np.ones([360, 180, 6])),
         'second': (['lon', 'lat', 'time'], np.ones([360, 180, 6])),
         'lat':
         np.linspace(-89.5, 89.5, 180),
         'lon':
         np.linspace(-179.5, 179.5, 360)
     })
     actual = subset.subset_spatial(dataset, "-20, -10, 20, 10")
     expected = xr.Dataset({
         'first': (['lon', 'lat', 'time'], np.ones([40, 20, 6])),
         'second': (['lon', 'lat', 'time'], np.ones([40, 20, 6])),
         'lat':
         np.linspace(-9.5, 9.5, 20),
         'lon':
         np.linspace(-19.5, 19.5, 40)
     })
     assert_dataset_equal(expected, actual)
Beispiel #31
0
 def test_nominal(self):
     """
     Test general 'most expected' use case functionality.
     """
     dataset = xr.Dataset({
         'first': (['lat', 'lon', 'time'], np.ones([180, 360, 6])),
         'second': (['lat', 'lon', 'time'], np.ones([180, 360, 6])),
         'lat':
         np.linspace(-89.5, 89.5, 180),
         'lon':
         np.linspace(-179.5, 179.5, 360)
     })
     actual = subset.subset_spatial(dataset, "-20, -10, 20, 10")
     expected = xr.Dataset({
         'first': (['lat', 'lon', 'time'], np.ones([20, 40, 6])),
         'second': (['lat', 'lon', 'time'], np.ones([20, 40, 6])),
         'lat':
         np.linspace(-9.5, 9.5, 20),
         'lon':
         np.linspace(-19.5, 19.5, 40)
     })
     assert_dataset_equal(expected, actual)