예제 #1
0
class Test_apply_ice(IrisTest):
    """Test the apply_ice method."""
    def setUp(self):
        """Create test cubes and plugin instance.
        The cube coordinates look like this:
        Dimension coordinates:
            projection_y_coordinate: 3;
            projection_x_coordinate: 3;
        Scalar coordinates:
            time: 2015-11-23 07:00:00
            forecast_reference_time: 2015-11-23 07:00:00
            forecast_period: 0 seconds

        self.vii_cube:
            Has extra coordinate of length(3) "threshold" containing
            points [0.5, 1., 2.] kg m-2.
        """
        (_, self.fg_cube, _, _, self.ice_cube) = set_up_lightning_test_cubes(
            validity_time=dt(2015, 11, 23, 7), fg_frt=dt(2015, 11, 23, 7))
        self.plugin = Plugin()
        self.ice_threshold_coord = find_threshold_coordinate(self.ice_cube)

    def test_basic(self):
        """Test that the method returns the expected cube type"""
        result = self.plugin.apply_ice(self.fg_cube, self.ice_cube)
        self.assertIsInstance(result, Cube)

    def test_input(self):
        """Test that the method does not modify the input cubes."""
        cube_a = self.fg_cube.copy()
        cube_b = self.ice_cube.copy()
        self.plugin.apply_ice(cube_a, cube_b)
        self.assertArrayAlmostEqual(cube_a.data, self.fg_cube.data)
        self.assertArrayAlmostEqual(cube_b.data, self.ice_cube.data)

    def test_missing_threshold_low(self):
        """Test that the method raises an error if the ice_cube doesn't
        have a threshold coordinate for 0.5."""
        self.ice_threshold_coord.points = [0.4, 1.0, 2.0]
        msg = r"No matching prob\(Ice\) cube for threshold 0.5"
        with self.assertRaisesRegex(ConstraintMismatchError, msg):
            self.plugin.apply_ice(self.fg_cube, self.ice_cube)

    def test_missing_threshold_mid(self):
        """Test that the method raises an error if the ice_cube doesn't
        have a threshold coordinate for 1.0."""
        self.ice_threshold_coord.points = [0.5, 0.9, 2.0]
        msg = r"No matching prob\(Ice\) cube for threshold 1."
        with self.assertRaisesRegex(ConstraintMismatchError, msg):
            self.plugin.apply_ice(self.fg_cube, self.ice_cube)

    def test_missing_threshold_high(self):
        """Test that the method raises an error if the ice_cube doesn't
        have a threshold coordinate for 2.0."""
        self.ice_threshold_coord.points = [0.5, 1.0, 4.0]
        msg = r"No matching prob\(Ice\) cube for threshold 2."
        with self.assertRaisesRegex(ConstraintMismatchError, msg):
            self.plugin.apply_ice(self.fg_cube, self.ice_cube)

    def test_ice_null(self):
        """Test that small VII probs do not increase moderate lightning risk"""
        self.ice_cube.data[:, 1, 1] = 0.0
        self.ice_cube.data[0, 1, 1] = 0.5
        self.fg_cube.data[1, 1] = 0.25
        expected = self.fg_cube.copy()
        # expected.data contains all ones except:
        expected.data[1, 1] = 0.25
        result = self.plugin.apply_ice(self.fg_cube, self.ice_cube)
        self.assertArrayAlmostEqual(result.data, expected.data)

    def test_ice_zero(self):
        """Test that zero VII probs do not increase zero lightning risk"""
        self.ice_cube.data[:, 1, 1] = 0.0
        self.fg_cube.data[1, 1] = 0.0
        expected = self.fg_cube.copy()
        # expected.data contains all ones except:
        expected.data[1, 1] = 0.0
        result = self.plugin.apply_ice(self.fg_cube, self.ice_cube)
        self.assertArrayAlmostEqual(result.data, expected.data)

    def test_ice_small(self):
        """Test that small VII probs do increase zero lightning risk"""
        self.ice_cube.data[:, 1, 1] = 0.0
        self.ice_cube.data[0, 1, 1] = 0.5
        self.fg_cube.data[1, 1] = 0.0
        expected = self.fg_cube.copy()
        # expected.data contains all ones except:
        expected.data[1, 1] = 0.05
        result = self.plugin.apply_ice(self.fg_cube, self.ice_cube)
        self.assertArrayAlmostEqual(result.data, expected.data)

    def test_ice_large(self):
        """Test that large VII probs do increase zero lightning risk"""
        self.ice_cube.data[:, 1, 1] = 1.0
        self.fg_cube.data[1, 1] = 0.0
        expected = self.fg_cube.copy()
        # expected.data contains all ones except:
        expected.data[1, 1] = 0.9
        result = self.plugin.apply_ice(self.fg_cube, self.ice_cube)
        self.assertArrayAlmostEqual(result.data, expected.data)

    def test_ice_large_with_fc(self):
        """Test that large VII probs do increase zero lightning risk when
        forecast lead time is non-zero (three forecast_period points)"""
        self.ice_cube.data[:, 1, 1] = 1.0
        self.fg_cube.data[1, 1] = 0.0
        frt_point = self.fg_cube.coord("forecast_reference_time").points[0]
        fg_cube_input = CubeList([])
        for fc_time in np.array([1, 2.5, 3]) * 3600:  # seconds
            fg_cube_next = self.fg_cube.copy()
            fg_cube_next.coord("time").points = [frt_point + fc_time]
            fg_cube_next.coord("forecast_period").points = [fc_time]
            fg_cube_input.append(squeeze(fg_cube_next))
        fg_cube_input = fg_cube_input.merge_cube()
        expected = fg_cube_input.copy()
        # expected.data contains all ones except:
        expected.data[0, 1, 1] = 0.54
        expected.data[1, 1, 1] = 0.0
        expected.data[2, 1, 1] = 0.0
        result = self.plugin.apply_ice(fg_cube_input, self.ice_cube)
        self.assertArrayAlmostEqual(result.data, expected.data)
예제 #2
0
class Test_apply_ice(IrisTest):
    """Test the apply_ice method."""
    def setUp(self):
        """Create cubes with a single zero prob(precip) point.
        The cubes look like this:
        precipitation_amount / (kg m^-2)
        Dimension coordinates:
            time: 1;
            projection_y_coordinate: 3;
            projection_x_coordinate: 3;
        Auxiliary coordinates:
            forecast_period (on time coord): 0.0 hours (simulates nowcast data)
        Scalar coordinates:
            forecast_reference_time: 2015-11-23 03:00:00
        Data:
        self.fg_cube:
            All points contain float(1.)
            Cube name is "probability_of_lightning".
        self.ice_cube:
            With extra coordinate of length(3) "threshold" containing
            points [0.5, 1., 2.] kg m^-2.
            Time and forecast_period dimensions "sqeezed" to be Scalar coords.
            All points contain float(0.)
            Cube name is "probability_of_vertical_integral_of_ice".
        """
        self.fg_cube = add_forecast_reference_time_and_forecast_period(
            set_up_cube_with_no_realizations(zero_point_indices=[],
                                             num_grid_points=3),
            fp_point=0.0)
        self.fg_cube.rename("probability_of_lightning")
        self.ice_cube = squeeze(
            add_forecast_reference_time_and_forecast_period(set_up_cube(
                num_realization_points=3,
                zero_point_indices=[],
                num_grid_points=3),
                                                            fp_point=0.0))
        threshold_coord = self.ice_cube.coord('realization')
        threshold_coord.points = [0.5, 1.0, 2.0]
        threshold_coord.rename('threshold')
        threshold_coord.units = cf_units.Unit('kg m^-2')
        self.ice_cube.data = np.zeros_like(self.ice_cube.data)
        self.ice_cube.rename("probability_of_vertical_integral_of_ice")
        self.plugin = Plugin()

    def test_basic(self):
        """Test that the method returns the expected cube type"""
        result = self.plugin.apply_ice(self.fg_cube, self.ice_cube)
        self.assertIsInstance(result, Cube)

    def test_input(self):
        """Test that the method does not modify the input cubes."""
        cube_a = self.fg_cube.copy()
        cube_b = self.ice_cube.copy()
        self.plugin.apply_ice(cube_a, cube_b)
        self.assertArrayAlmostEqual(cube_a.data, self.fg_cube.data)
        self.assertArrayAlmostEqual(cube_b.data, self.ice_cube.data)

    def test_missing_threshold_low(self):
        """Test that the method raises an error if the ice_cube doesn't
        have a threshold coordinate for 0.5."""
        self.ice_cube.coord('threshold').points = [0.4, 1., 2.]
        msg = (r"No matching prob\(Ice\) cube for threshold 0.5")
        with self.assertRaisesRegex(ConstraintMismatchError, msg):
            self.plugin.apply_ice(self.fg_cube, self.ice_cube)

    def test_missing_threshold_mid(self):
        """Test that the method raises an error if the ice_cube doesn't
        have a threshold coordinate for 1.0."""
        self.ice_cube.coord('threshold').points = [0.5, 0.9, 2.]
        msg = (r"No matching prob\(Ice\) cube for threshold 1.")
        with self.assertRaisesRegex(ConstraintMismatchError, msg):
            self.plugin.apply_ice(self.fg_cube, self.ice_cube)

    def test_missing_threshold_high(self):
        """Test that the method raises an error if the ice_cube doesn't
        have a threshold coordinate for 2.0."""
        self.ice_cube.coord('threshold').points = [0.5, 1., 4.]
        msg = (r"No matching prob\(Ice\) cube for threshold 2.")
        with self.assertRaisesRegex(ConstraintMismatchError, msg):
            self.plugin.apply_ice(self.fg_cube, self.ice_cube)

    def test_ice_null(self):
        """Test that small VII probs do not increase moderate lightning risk"""
        self.ice_cube.data[:, 1, 1] = 0.
        self.ice_cube.data[0, 1, 1] = 0.5
        self.fg_cube.data[0, 1, 1] = 0.25
        expected = self.fg_cube.copy()
        # expected.data contains all ones except:
        expected.data[0, 1, 1] = 0.25
        result = self.plugin.apply_ice(self.fg_cube, self.ice_cube)
        self.assertArrayAlmostEqual(result.data, expected.data)

    def test_ice_zero(self):
        """Test that zero VII probs do not increase zero lightning risk"""
        self.ice_cube.data[:, 1, 1] = 0.
        self.fg_cube.data[0, 1, 1] = 0.
        expected = self.fg_cube.copy()
        # expected.data contains all ones except:
        expected.data[0, 1, 1] = 0.
        result = self.plugin.apply_ice(self.fg_cube, self.ice_cube)
        self.assertArrayAlmostEqual(result.data, expected.data)

    def test_ice_small(self):
        """Test that small VII probs do increase zero lightning risk"""
        self.ice_cube.data[:, 1, 1] = 0.
        self.ice_cube.data[0, 1, 1] = 0.5
        self.fg_cube.data[0, 1, 1] = 0.
        expected = self.fg_cube.copy()
        # expected.data contains all ones except:
        expected.data[0, 1, 1] = 0.05
        result = self.plugin.apply_ice(self.fg_cube, self.ice_cube)
        self.assertArrayAlmostEqual(result.data, expected.data)

    def test_ice_large(self):
        """Test that large VII probs do increase zero lightning risk"""
        self.ice_cube.data[:, 1, 1] = 1.
        self.fg_cube.data[0, 1, 1] = 0.
        expected = self.fg_cube.copy()
        # expected.data contains all ones except:
        expected.data[0, 1, 1] = 0.9
        result = self.plugin.apply_ice(self.fg_cube, self.ice_cube)
        self.assertArrayAlmostEqual(result.data, expected.data)

    def test_ice_large_with_fc(self):
        """Test that large VII probs do increase zero lightning risk when
        forecast lead time is non-zero (two forecast_period points)"""
        self.ice_cube.data[:, 1, 1] = 1.
        self.fg_cube.data[0, 1, 1] = 0.
        self.fg_cube.coord('forecast_period').points = [1.]  # hours
        fg_cube_next = self.fg_cube.copy()
        time_pt, = self.fg_cube.coord('time').points
        fg_cube_next.coord('time').points = [time_pt + 2.]  # hours
        fg_cube_next.coord('forecast_period').points = [3.]  # hours
        self.fg_cube = CubeList([squeeze(self.fg_cube),
                                 squeeze(fg_cube_next)]).merge_cube()
        expected = self.fg_cube.copy()
        # expected.data contains all ones except:
        expected.data[0, 1, 1] = 0.54
        expected.data[1, 1, 1] = 0.0
        result = self.plugin.apply_ice(self.fg_cube, self.ice_cube)
        self.assertArrayAlmostEqual(result.data, expected.data)