Beispiel #1
0
    def test_returns_correct_type(self):
        """Test function returns the expected list."""

        time_interval = 60
        plugin = Accumulation(accumulation_period=120)
        result = plugin._get_period_sets(time_interval, self.cubes)
        self.assertIsInstance(result, list)
    def test_returns_cubelist(self):
        """Test function returns a cubelist."""

        plugin = Accumulation(accumulation_period=60,
                              forecast_periods=self.forecast_periods)
        result = plugin.process(self.cubes)
        self.assertIsInstance(result, iris.cube.CubeList)
Beispiel #3
0
    def test_returns_expected_values_1_minute(self):
        """Test function returns the expected accumulations over a 1 minute
        aggregation period. Check that the number of accumulation cubes
        returned is the expected number."""

        expected_t0 = np.array(
            [[0.015, 0.03, 0.03, 0.03, 0.03, 0.06, 0.09, 0.09, 0.09, 0.09],
             [0.015, 0.03, 0.03, 0.03, 0.03, np.nan, np.nan, 0.09, 0.09, 0.09],
             [0., 0., 0., 0., 0., np.nan, np.nan, 0.09, 0.09, 0.09],
             [0., 0., 0., 0., 0., 0.045, 0.09, 0.09, 0.09, 0.09]])

        expected_t7 = np.array(
            [[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.015, 0.03, 0.03],
             [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.015, 0.03, 0.03],
             [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
             [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]])

        expected_mask_t0 = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                                     [0, 0, 0, 0, 0, 1, 1, 0, 0, 0],
                                     [0, 0, 0, 0, 0, 1, 1, 0, 0, 0],
                                     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])

        expected_mask_t7 = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                                     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                                     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                                     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])

        plugin = Accumulation(accumulation_period=60, accumulation_units='mm')
        result = plugin.process(self.cubes)

        self.assertArrayAlmostEqual(result[0].data, expected_t0)
        self.assertArrayAlmostEqual(result[7].data, expected_t7)
        self.assertArrayAlmostEqual(result[0].data.mask, expected_mask_t0)
        self.assertArrayAlmostEqual(result[7].data.mask, expected_mask_t7)
        self.assertEqual(len(result), 10)
    def test_returns_total_accumulation_if_no_period_specified(self):
        """Test function returns a list containing a single accumulation cube
        that is the accumulation over the whole period specified by the rates
        cubes. The results are the same as the 10 minute test above as that is
        the total span of the input rates cubes. Check that the number of
        accumulation cubes returned is the expected number."""

        expected_t0 = np.array(
            [[
                0.015, 0.045, 0.075, 0.105, 0.135, 0.195, 0.285, 0.375, 0.465,
                0.555
            ],
             [
                 0.015, 0.045, 0.075, 0.105, 0.135, np.nan, np.nan, np.nan,
                 np.nan, np.nan
             ], [0., 0., 0., 0., 0., np.nan, np.nan, np.nan, np.nan, np.nan],
             [0., 0., 0., 0., 0., 0.045, 0.135, 0.225, 0.315, 0.405]])

        expected_mask_t0 = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                                     [0, 0, 0, 0, 0, 1, 1, 1, 1, 1],
                                     [0, 0, 0, 0, 0, 1, 1, 1, 1, 1],
                                     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])

        plugin = Accumulation(accumulation_units='mm')
        result = plugin.process(self.cubes)

        self.assertArrayAlmostEqual(result[0].data, expected_t0)
        self.assertArrayAlmostEqual(result[0].data.mask, expected_mask_t0)
        self.assertEqual(len(result), 1)
    def test_returns_expected_values_10_minutes(self):
        """Test function returns the expected accumulations over the complete
        10 minute aggregation period. These are written out long hand to make
        the comparison easy. Note that the test have been constructed such that
        only the top row is expected to show a difference by including the last
        5 minutes of the accumulation, all the other results are the same as
        for the 5 minute test above. Check that the number of accumulation
        cubes returned is the expected number."""

        expected_t0 = np.array(
            [[
                0.015, 0.045, 0.075, 0.105, 0.135, 0.195, 0.285, 0.375, 0.465,
                0.555
            ],
             [
                 0.015, 0.045, 0.075, 0.105, 0.135, np.nan, np.nan, np.nan,
                 np.nan, np.nan
             ], [0., 0., 0., 0., 0., np.nan, np.nan, np.nan, np.nan, np.nan],
             [0., 0., 0., 0., 0., 0.045, 0.135, 0.225, 0.315, 0.405]])

        expected_mask_t0 = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                                     [0, 0, 0, 0, 0, 1, 1, 1, 1, 1],
                                     [0, 0, 0, 0, 0, 1, 1, 1, 1, 1],
                                     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])

        plugin = Accumulation(accumulation_period=600,
                              accumulation_units='mm',
                              forecast_periods=[600])
        result = plugin.process(self.cubes)

        self.assertArrayAlmostEqual(result[0].data, expected_t0)
        self.assertArrayAlmostEqual(result[0].data.mask, expected_mask_t0)
        self.assertEqual(len(result), 1)
Beispiel #6
0
    def test_raises_warning_for_unused_cubes(self, warning_list=None):
        """Test function raises a warning when there are insufficient cubes to
        complete the last period. In this test the accumulation period is 3
        minutes, but the total span of rates cubes covers 10 minutes, resulting
        in 3 complete periods and a final incomplete period that is not
        returned. This test checks that a warning is raised to highlight that
        there is an incomplete final period that is not returned."""

        time_interval = 60
        warning_msg = (
            "The provided cubes result in a partial period given the specified"
            " accumulation_period, i.e. the number of cubes is insufficient to"
            " give a set of complete periods. Only complete periods will be"
            " returned.")

        expected = [self.cubes[0:4], self.cubes[3:7], self.cubes[6:10]]

        plugin = Accumulation(accumulation_period=180)
        result = plugin._get_period_sets(time_interval, self.cubes)

        for index, sublist in enumerate(result):
            self.assertSequenceEqual(sublist, expected[index])
        self.assertTrue(
            any(item.category == UserWarning for item in warning_list))
        self.assertTrue(any(warning_msg in str(item) for item in warning_list))
Beispiel #7
0
    def test_returns_all_cubes_if_period_unspecified(self):
        """Test function returns a list containing the original cube list if
        the accumulation_period is not set."""

        time_interval = 60
        plugin = Accumulation()
        result = plugin._get_period_sets(time_interval, self.cubes)
        self.assertSequenceEqual(result, [self.cubes])
Beispiel #8
0
    def test_returns_expected_values_5_minutes(self):
        """Test function returns the expected accumulations over a 5 minute
        aggregation period. These are written out long hand to make the
        comparison easy. Check that the number of accumulation cubes returned
        is the expected number."""

        expected_t0 = np.array([
            [0.015, 0.045, 0.075, 0.105, 0.135, 0.18, 0.24, 0.3, 0.36, 0.42],
            [
                0.015,
                0.045,
                0.075,
                0.105,
                0.135,
                np.nan,
                np.nan,
                np.nan,
                np.nan,
                np.nan,
            ],
            [0.0, 0.0, 0.0, 0.0, 0.0, np.nan, np.nan, np.nan, np.nan, np.nan],
            [0.0, 0.0, 0.0, 0.0, 0.0, 0.045, 0.135, 0.225, 0.315, 0.405],
        ])

        expected_t1 = np.array([
            [0.0, 0.0, 0.0, 0.0, 0.0, 0.015, 0.045, 0.075, 0.105, 0.135],
            [0.0, 0.0, 0.0, 0.0, 0.0, 0.015, 0.045, 0.075, 0.105, 0.135],
            [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
            [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
        ])

        expected_mask_t0 = np.array([
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 1, 1, 1, 1, 1],
            [0, 0, 0, 0, 0, 1, 1, 1, 1, 1],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        ])

        expected_mask_t1 = np.array([
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        ])

        plugin = Accumulation(
            accumulation_period=300,
            accumulation_units="mm",
            forecast_periods=[300, 600],
        )
        result = plugin.process(self.cubes)

        self.assertArrayAlmostEqual(result[0].data, expected_t0)
        self.assertArrayAlmostEqual(result[1].data, expected_t1)
        self.assertArrayAlmostEqual(result[0].data.mask, expected_mask_t0)
        self.assertArrayAlmostEqual(result[1].data.mask, expected_mask_t1)
        self.assertEqual(len(result), 2)
Beispiel #9
0
    def test_raises_exception_for_impossible_aggregation(self):
        """Test function raises an exception when attempting to create an
        accumulation_period that cannot be created from the input cubes."""

        plugin = Accumulation(accumulation_period=119)
        msg = "The specified accumulation period "

        with self.assertRaisesRegex(ValueError, msg):
            plugin._check_inputs(self.cubes)
Beispiel #10
0
 def test_basic(self):
     """Test that the subset of cubes that are within the accumulation
     period are correctly identified. In this case, the subset of cubes
     used for each accumulation period is expected to consist of 6 cubes."""
     expected_cube_subset = self.cubes[:6]
     upper_bound_fp, = self.cubes[5].coord("forecast_period").points
     plugin = Accumulation(accumulation_period=5 * 60,
                           forecast_periods=np.array([5]) * 60)
     result = plugin._get_cube_subsets(self.cubes, upper_bound_fp)
     self.assertEqual(expected_cube_subset, result)
Beispiel #11
0
    def test_does_not_use_incomplete_period_data(self):
        """Test function returns only 2 accumulation periods when a 4 minute
        aggregation period is used with 10 minutes of input data. The trailing
        2 cubes are insufficient to create another period and so are discarded.
        A warning is raised by the chunking function and has been tested above,
        so is ignored here.
        """

        plugin = Accumulation(accumulation_period=240, forecast_periods=[240, 480])
        result = plugin.process(self.cubes)
        self.assertEqual(len(result), 2)
Beispiel #12
0
    def test_accumulation_length(self):
        """Test to check that the length of the accumulation period is
        consistent across all output cubes. Only complete periods are
        required."""

        accumulation_length = 120
        plugin = Accumulation(accumulation_period=accumulation_length,
                              forecast_periods=self.forecast_periods)
        result = plugin.process(self.cubes)
        for cube in result:
            self.assertEqual(np.diff(cube.coord("forecast_period").bounds),
                             accumulation_length)
Beispiel #13
0
    def test_default_altered_output_units(self):
        """Test the function returns accumulations in the specified units if
        they are explicitly set. Here the units are set to mm."""

        # Multiply the rates in mm/s by 60 to get accumulation over 1 minute
        expected = self.cubes[0].copy(
            data=(0.5 * (self.cubes[0].data + self.cubes[1].data) * 60))

        plugin = Accumulation(accumulation_units='mm', accumulation_period=60)
        result = plugin.process(self.cubes)

        self.assertEqual(result[0].units, 'mm')
        self.assertArrayAlmostEqual(result[0].data, expected.data)
Beispiel #14
0
    def test_raises_exception_for_unevenly_spaced_cubes(self):
        """Test function raises an exception if the input cubes are not
        spaced equally in time."""

        last_time = self.cubes[-1].coord('time').points
        self.cubes[-1].coord('time').points = last_time + 60

        msg = ("Accumulation is designed to work with rates "
               "cubes at regular time intervals.")
        plugin = Accumulation(accumulation_period=120)

        with self.assertRaisesRegex(ValueError, msg):
            plugin.process(self.cubes)
Beispiel #15
0
 def test_raises_exception_for_small_accumulation_period(self):
     """Test that if the forecast period of the upper bound cube is
     not within the list of requested forecast periods, then the
     subset of cubes returned is equal to None."""
     msg = ("The accumulation_period is less than the time interval "
            "between the rates cubes. The rates cubes provided are "
            "therefore insufficient for computing the accumulation period "
            "requested.")
     reduced_cubelist = iris.cube.CubeList([self.cubes[0], self.cubes[-1]])
     plugin = Accumulation(accumulation_period=5 * 60,
                           forecast_periods=np.array([5]) * 60)
     with self.assertRaisesRegex(ValueError, msg):
         plugin.process(reduced_cubelist)
Beispiel #16
0
 def test_specify_accumulation_period(self):
     """Test that the expected time interval is returned when the
     accumulation period is specified. Also test that the returned list of
     cubes has the expected units."""
     expected_time_interval = 60
     expected_cubes = self.cubes.copy()
     for cube in expected_cubes:
         cube.convert_units("m/s")
     accumulation_period = 60 * 60
     plugin = Accumulation(accumulation_period=accumulation_period)
     cubes, time_interval = plugin._check_inputs(self.cubes)
     self.assertEqual(cubes, expected_cubes)
     self.assertEqual(time_interval, expected_time_interval)
     self.assertEqual(plugin.accumulation_period, accumulation_period)
Beispiel #17
0
 def test_specify_forecast_period(self):
     """Test that the expected time interval is returned when the forecast
     periods are specified. Also test that the returned list of cubes has
     the expected units."""
     expected_time_interval = 60
     expected_cubes = self.cubes.copy()
     for cube in expected_cubes:
         cube.convert_units("m/s")
     forecast_periods = [600]
     plugin = Accumulation(forecast_periods=forecast_periods)
     cubes, time_interval = plugin._check_inputs(self.cubes)
     self.assertEqual(cubes, expected_cubes)
     self.assertEqual(time_interval, expected_time_interval)
     self.assertEqual(plugin.forecast_periods, forecast_periods)
Beispiel #18
0
    def test_default_output_units(self):
        """Test the function returns accumulations in the default units if no
        units are explicitly set, where the default is metres."""

        # Multiply the rates in mm/s by 60 to get accumulation over 1 minute
        # and divide by 1000 to get into metres.
        expected = self.cubes[0].copy(
            data=(0.5 * (self.cubes[0].data + self.cubes[1].data) * 60 / 1000))

        plugin = Accumulation(accumulation_period=60)
        result = plugin.process(self.cubes)

        self.assertEqual(result[0].units, 'm')
        self.assertArrayAlmostEqual(result[0].data, expected.data)
Beispiel #19
0
    def test_returns_expected_cubes(self, warning_list=None):
        """Test function returns lists containing the expected cubes for each
        period. In this test all the cubes are used as the total time span of
        precipitation rates cubes is divisible by the requested accumulation
        period."""

        time_interval = 60
        expected = [self.cubes[0:6], self.cubes[5:]]

        plugin = Accumulation(accumulation_period=300)
        result = plugin._get_period_sets(time_interval, self.cubes)

        for index, sublist in enumerate(result):
            self.assertSequenceEqual(sublist, expected[index])
Beispiel #20
0
 def test_specify_accumulation_period_and_forecast_period(self):
     """Test that the expected time interval is returned when the
     accumulation period and forecast periods are specified. Also test that
     the returned list of cubes has the expected units."""
     expected_time_interval = 60
     expected_cubes = self.cubes.copy()
     for cube in expected_cubes:
         cube.convert_units("m/s")
     accumulation_period = 20 * 60
     forecast_periods = np.array([15]) * 60
     plugin = Accumulation(accumulation_period=accumulation_period,
                           forecast_periods=forecast_periods)
     cubes, time_interval = plugin._check_inputs(self.cubes)
     self.assertEqual(cubes, expected_cubes)
     self.assertEqual(time_interval, expected_time_interval)
Beispiel #21
0
 def test_basic(self):
     """Test string representation"""
     result = str(
         Accumulation(accumulation_units="cm", accumulation_period=60))
     expected_result = ("<Accumulation: accumulation_units=cm, "
                        "accumulation_period=60s>")
     self.assertEqual(result, expected_result)
Beispiel #22
0
    def test_basic(self):
        """Check the calculations of the accumulations, where an accumulation
        is computed by finding the mean rate between each adjacent pair of
        cubes within the cube_subset and multiplying this mean rate by the
        time_interval, in order to compute an accumulation. In this case,
        as the cube_subset only contains a pair of cubes, then the
        accumulation from this pair will be the same as the total accumulation.
        """
        expected_t0 = np.array(
            [
                [0.015, 0.03, 0.03, 0.03, 0.03, 0.06, 0.09, 0.09, 0.09, 0.09],
                [0.015, 0.03, 0.03, 0.03, 0.03, np.nan, np.nan, 0.09, 0.09, 0.09],
                [0.0, 0.0, 0.0, 0.0, 0.0, np.nan, np.nan, 0.09, 0.09, 0.09],
                [0.0, 0.0, 0.0, 0.0, 0.0, 0.045, 0.09, 0.09, 0.09, 0.09],
            ]
        )

        expected_mask_t0 = np.array(
            [
                [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                [0, 0, 0, 0, 0, 1, 1, 0, 0, 0],
                [0, 0, 0, 0, 0, 1, 1, 0, 0, 0],
                [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            ]
        )
        time_interval = 60
        result = Accumulation()._calculate_accumulation(self.cubes[:2], time_interval)
        self.assertArrayAlmostEqual(result, expected_t0)
        self.assertArrayAlmostEqual(result.mask, expected_mask_t0)
Beispiel #23
0
 def test_basic(self):
     """Test that the expected time_interval is returned and that the
     returned list of cubes has the expected units."""
     expected_time_interval = 60
     expected_cubes = self.cubes.copy()
     for cube in expected_cubes:
         cube.convert_units("m/s")
     cubes, time_interval = Accumulation()._check_inputs(self.cubes)
     self.assertEqual(cubes, expected_cubes)
     self.assertEqual(time_interval, expected_time_interval)
Beispiel #24
0
    def test_times(self):
        """Test function returns the correct times for the sorted cubes."""

        expected = [
            1510286400, 1510286460, 1510286520, 1510286580, 1510286640,
            1510286700, 1510286760, 1510286820, 1510286880, 1510286940,
            1510287000
        ]
        _, times = Accumulation.sort_cubes_by_time(self.cubes)

        self.assertArrayEqual(times, expected)
Beispiel #25
0
    def test_basic(self):
        """Check that the metadata is set as expected."""
        expected_name = "lwe_thickness_of_precipitation_amount"
        expected_units = Unit("m")
        expected_time_point = [datetime.datetime(2017, 11, 10, 4, 10)]
        expected_time_bounds = [
            (
                datetime.datetime(2017, 11, 10, 4, 0),
                datetime.datetime(2017, 11, 10, 4, 10),
            )
        ]
        expected_fp_point = 600
        expected_fp_bounds = [[0, 600]]
        expected_cell_method = iris.coords.CellMethod("sum", coords="time")

        result = Accumulation()._set_metadata(self.cubes)
        self.assertEqual(result.name(), expected_name)
        self.assertEqual(result.units, expected_units)
        points = [value.point for value in result.coord("time").cells()]
        bounds = [value.bound for value in result.coord("time").cells()]
        self.assertEqual(points, expected_time_point)
        self.assertArrayAlmostEqual(
            result.coord("forecast_period").points, expected_fp_point
        )
        self.assertEqual(bounds, expected_time_bounds)
        self.assertArrayAlmostEqual(
            result.coord("forecast_period").bounds, expected_fp_bounds
        )
        self.assertEqual(result.cell_methods[0], expected_cell_method)
Beispiel #26
0
    def test_reorders(self):
        """Test function reorders a cubelist that is not time ordered."""

        expected = [cube.coord("time").points[0] for cube in self.cubes]
        self.cubes = self.cubes[::-1]
        reordered = [cube.coord("time").points[0] for cube in self.cubes]

        result, _ = Accumulation.sort_cubes_by_time(self.cubes)
        result_times = [cube.coord("time").points[0] for cube in result]

        self.assertIsInstance(result, iris.cube.CubeList)
        self.assertEqual(result_times, expected)
        self.assertNotEqual(result_times, reordered)
Beispiel #27
0
    def test_returns_masked_cubes(self):
        """Test function returns a list of masked cubes for masked input
        data."""

        result = Accumulation(forecast_periods=[600]).process(self.cubes)
        self.assertIsInstance(result[0].data, np.ma.MaskedArray)
Beispiel #28
0
 def test_accumulation_period_set(self):
     """Test the accumulation_period is set when specified."""
     plugin = Accumulation(accumulation_period=180)
     self.assertEqual(plugin.accumulation_period, 180)
Beispiel #29
0
 def test_forecast_period_set(self):
     """Test the forecast_period is set when specified."""
     plugin = Accumulation(forecast_periods=[60, 120])
     self.assertListEqual(plugin.forecast_periods, [60, 120])
Beispiel #30
0
    def test_returns_cubelist(self):
        """Test function returns a cubelist."""

        result, _ = Accumulation.sort_cubes_by_time(self.cubes)
        self.assertIsInstance(result, iris.cube.CubeList)