Пример #1
0
 def test_wind_speed_data_check(self):
     """
     Test that the plugin returns an iris.cube.CubeList
     of wind_speed cubes with the expected data, where the plugin
     returns a cubelist of, firstly, the predictor and, secondly the
     variance.
     The ensemble mean is the predictor.
     """
     predictor_data = np.array([[2.9999862, 10.49998827, 17.99999034],
                                [25.4999924, 32.99999447, 40.49999654],
                                [47.99999861, 55.50000068, 63.00000275]])
     variance_data = np.array([[0., 0., 0.], [0., 0., 0.], [0., 0., 0.]])
     calibration_method = "ensemble model output_statistics"
     distribution = "truncated gaussian"
     desired_units = "m s^-1"
     plugin = Plugin(calibration_method, distribution, desired_units)
     result = plugin.process(self.current_wind_speed_forecast_cube,
                             self.historic_wind_speed_forecast_cube,
                             self.wind_speed_truth_cube)
     self.assertArrayAlmostEqual(result[0][0].data, predictor_data)
     self.assertArrayAlmostEqual(result[1][0].data, variance_data)
Пример #2
0
    def test_basic(self):
        """Ensure that the optimised_coeffs are returned as a dictionary,
           and the coefficient names are returned as a list."""
        current_forecast = self.current_temperature_forecast_cube

        historic_forecasts = self.historic_temperature_forecast_cube

        truth = self.temperature_truth_cube

        distribution = "gaussian"
        desired_units = "degreesC"

        plugin = Plugin(distribution, desired_units)
        result = plugin.estimate_coefficients_for_ngr(current_forecast,
                                                      historic_forecasts,
                                                      truth)
        optimised_coeffs, coeff_names = result
        self.assertIsInstance(optimised_coeffs, dict)
        self.assertIsInstance(coeff_names, list)
        for key in optimised_coeffs.keys():
            self.assertEqual(len(optimised_coeffs[key]), len(coeff_names))
Пример #3
0
    def test_basic_mean_predictor(self):
        """
        Test that the plugin returns a list containing the initial guess
        for the calibration coefficients, when the ensemble mean is used
        as the predictor.
        """
        cube = self.cube

        current_forecast_predictor = cube.collapsed("realization",
                                                    iris.analysis.MEAN)
        truth = cube.collapsed("realization", iris.analysis.MAX)
        distribution = "gaussian"
        desired_units = "degreesC"
        predictor_of_mean_flag = "mean"
        estimate_coefficients_from_linear_model_flag = False

        plugin = Plugin(distribution, desired_units)
        result = plugin.compute_initial_guess(
            truth, current_forecast_predictor, predictor_of_mean_flag,
            estimate_coefficients_from_linear_model_flag)
        self.assertIsInstance(result, list)
    def test_realizations_predictor_estimate_coefficients(self):
        """
        Test that the plugin returns the expected values for the initial guess
        for the calibration coefficients, when the ensemble mean is used
        as the predictor. The coefficients are estimated using a linear model.
        In this case, the result of the linear regression is for an intercept
        of 0.333333 with different weights for the realizations because
        some of the realizations are closer to the truth, in this instance.
        """
        data = [0., 1., 0.333333, 0., 0.333333, 0.666667]
        predictor_of_mean_flag = "realizations"
        estimate_coefficients_from_linear_model_flag = True

        plugin = Plugin(self.distribution, self.desired_units)
        result = plugin.compute_initial_guess(
            self.truth,
            self.current_forecast_predictor_realizations,
            predictor_of_mean_flag,
            estimate_coefficients_from_linear_model_flag,
            no_of_realizations=self.no_of_realizations)
        self.assertArrayAlmostEqual(result, data)
Пример #5
0
    def test_realizations_predictor_max_iterations(self):
        """
        Test that the plugin returns a list of coefficients
        equal to specific values, when the ensemble realizations are the
        predictor assuming a truncated normal distribution and the value
        specified for the max_iterations is overridden. The coefficients are
        calculated by minimising the CRPS and using a set default value for
        the initial guess.
        """
        predictor_of_mean_flag = "realizations"
        max_iterations = 1000
        distribution = "truncated_gaussian"

        plugin = Plugin(tolerance=self.tolerance,
                        max_iterations=max_iterations)
        result = plugin.process(self.initial_guess_for_realization,
                                self.forecast_predictor_realizations,
                                self.truth, self.forecast_variance,
                                predictor_of_mean_flag, distribution)
        self.assertEMOSCoefficientsAlmostEqual(
            result, self.expected_realizations_coefficients)
Пример #6
0
    def test_calibrated_variance_realizations(self):
        """
        Test that the plugin returns values for the calibrated forecasts,
        which match the expected values when the individual ensemble
        realizations are used as the predictor.
        """
        data = np.array([[34.333333, 34.333333, 34.333333],
                         [34.333333, 34.333333, 34.333333],
                         [34.333333, 34.333333, 34.333333]])

        cube = self.current_temperature_forecast_cube

        predictor_cube = cube.copy()
        variance_cube = cube.collapsed("realization", iris.analysis.VARIANCE)

        plugin = Plugin(cube,
                        self.coeffs_from_realizations,
                        predictor_of_mean_flag="realizations")
        _, forecast_variance = plugin._apply_params(predictor_cube,
                                                    variance_cube)
        self.assertArrayAlmostEqual(forecast_variance.data, data, decimal=4)
Пример #7
0
    def test_statsmodels_realizations(self, warning_list=None):
        """
        Test that the plugin raises the desired warning if the statsmodels
        module is not found for when the predictor is the ensemble
        realizations.
        """
        import imp
        try:
            statsmodels_found = imp.find_module('statsmodels')
            statsmodels_found = True
        except ImportError:
            statsmodels_found = False

        cube = self.cube

        historic_forecasts = CubeList([])
        for index in [1.0, 2.0, 3.0, 4.0, 5.0]:
            temp_cube = cube.copy()
            temp_cube.coord("time").points = (temp_cube.coord("time").points -
                                              index)
            historic_forecasts.append(temp_cube)
        historic_forecasts.concatenate_cube()

        current_forecast_predictor = cube
        truth = cube.collapsed("realization", iris.analysis.MAX)
        distribution = "gaussian"
        desired_units = "degreesC"
        predictor_of_mean_flag = "realizations"
        no_of_realizations = 3
        estimate_coefficients_from_linear_model_flag = True

        if not statsmodels_found:
            plugin = Plugin(distribution,
                            desired_units,
                            predictor_of_mean_flag=predictor_of_mean_flag)
            self.assertTrue(len(warning_list) == 1)
            self.assertTrue(
                any(item.category == ImportWarning for item in warning_list))
            self.assertTrue(
                "The statsmodels can not be imported" in str(warning_list[0]))
Пример #8
0
    def test_calibrated_predictor_realizations(self):
        """
        Test that the plugin returns values for the calibrated forecasts,
        which match the expected values when the individual ensemble
        realizations are used as the predictor.
        """
        data = np.array([[239.904142, 251.659267, 263.414393],
                         [275.169518, 286.92465, 298.67975],
                         [310.43488, 322.19, 333.94516]],
                        dtype=np.float32)

        cube = self.current_temperature_forecast_cube
        cube1 = cube.copy()
        cube2 = cube.copy()

        cube2.coord("time").points = cube2.coord("time").points + 3
        cube2.data += 3

        cube = concatenate_cubes(CubeList([cube1, cube2]))

        optimised_coeffs = {}

        for time_slice in cube.slices_over("time"):
            the_date = datetime_from_timestamp(time_slice.coord("time").points)
            optimised_coeffs[the_date] = np.array(
                [5, 1, 0, 0.57, 0.6, 0.6], dtype=np.float32)
        self.coeff_names = ["gamma", "delta", "a", "beta"]

        predictor_cube = cube.copy()
        variance_cube = cube.collapsed("realization", iris.analysis.VARIANCE)

        predictor_of_mean_flag = "realizations"

        plugin = Plugin(self.cube, optimised_coeffs,
                        self.coeff_names)
        forecast_predictor, _, _ = plugin._apply_params(
            predictor_cube, variance_cube, optimised_coeffs,
            self.coeff_names, predictor_of_mean_flag)
        self.assertArrayAlmostEqual(forecast_predictor[0].data, data,
                                    decimal=4)
    def test_coefficient_values_truncated_gaussian_distribution_realization(
            self):
        """Ensure that the values for the optimised_coefficients match the
        expected values, and the coefficient names also match
        expected values for a truncated Gaussian distribution where the
        realizations are used as the predictor of the mean."""
        import imp
        try:
            imp.find_module('statsmodels')
            statsmodels_found = True
        except ImportError:
            statsmodels_found = False

        if statsmodels_found:
            data = [
                0.11821805, -0.00474737, 0.17631301, 0.17178835, 0.66749225,
                0.72287342
            ]
        else:
            data = [
                2.05550997, 0.10577237, 0.00028531, 0.53208837, 0.67233013,
                0.53704241
            ]

        distribution = "truncated gaussian"
        current_cycle = "20171110T0000Z"
        predictor_of_mean_flag = "realizations"
        expected_coeff_names = ([
            'gamma', 'delta', 'alpha', 'beta0', 'beta1', 'beta2'
        ])

        plugin = Plugin(distribution,
                        current_cycle,
                        predictor_of_mean_flag=predictor_of_mean_flag)
        result = plugin.estimate_coefficients_for_ngr(
            self.historic_wind_speed_forecast_cube, self.wind_speed_truth_cube)

        self.assertArrayAlmostEqual(result.data, data)
        self.assertArrayEqual(
            result.coord("coefficient_name").points, expected_coeff_names)
    def test_coefficient_values_for_gaussian_distribution(self):
        """Ensure that the values for the optimised_coefficients match the
        expected values, and the coefficient names also match
        expected values for a Gaussian distribution."""
        data = [
            4.55819380e-06, -8.02401974e-09, 1.66667055e+00, 1.00000011e+00
        ]

        distribution = "gaussian"
        current_cycle = "20171110T0000Z"
        desired_units = "Celsius"

        plugin = Plugin(distribution,
                        current_cycle,
                        desired_units=desired_units)
        result = plugin.estimate_coefficients_for_ngr(
            self.historic_temperature_forecast_cube,
            self.temperature_truth_cube)

        self.assertArrayAlmostEqual(result.data, data)
        self.assertArrayEqual(
            result.coord("coefficient_name").points, self.coeff_names)
    def test_mean_predictor_estimate_coefficients(self):
        """
        Test that the plugin returns the expected values for the initial guess
        for the calibration coefficients, when the ensemble mean is used
        as the predictor. The coefficients are estimated using a linear model.
        """
        data = np.array([1, 1, 2.66663, 1], dtype=np.float32)

        current_forecast_predictor = self.cube.collapsed(
            "realization", iris.analysis.MEAN)
        truth = self.cube.collapsed("realization", iris.analysis.MAX)
        distribution = "gaussian"
        desired_units = "degreesC"
        predictor_of_mean_flag = "mean"
        estimate_coefficients_from_linear_model_flag = True

        plugin = Plugin(distribution, desired_units)
        result = plugin.compute_initial_guess(
            truth, current_forecast_predictor, predictor_of_mean_flag,
            estimate_coefficients_from_linear_model_flag)

        self.assertArrayAlmostEqual(result, data, decimal=5)
    def test_basic_mean_predictor_value_check(self):
        """
        Test that the plugin returns the expected values for the initial guess
        for the calibration coefficients, when the ensemble mean is used
        as the predictor. As coefficients are not estimated using a
        linear model, the default values for the initial guess are used.
        """
        data = [1, 1, 0, 1]

        current_forecast_predictor = self.cube.collapsed(
            "realization", iris.analysis.MEAN)
        truth = self.cube.collapsed("realization", iris.analysis.MAX)
        distribution = "gaussian"
        desired_units = "degreesC"
        predictor_of_mean_flag = "mean"
        estimate_coefficients_from_linear_model_flag = False

        plugin = Plugin(distribution, desired_units)
        result = plugin.compute_initial_guess(
            truth, current_forecast_predictor, predictor_of_mean_flag,
            estimate_coefficients_from_linear_model_flag)
        self.assertArrayAlmostEqual(result, data)
    def test_basic_realizations_predictor(self):
        """
        Test that the plugin returns a list containing the initial guess
        for the calibration coefficients, when the individual ensemble
        realizations are used as predictors.
        """
        current_forecast_predictor = self.cube.copy()
        truth = self.cube.collapsed("realization", iris.analysis.MAX)
        distribution = "gaussian"
        desired_units = "degreesC"
        predictor_of_mean_flag = "realizations"
        no_of_realizations = 3
        estimate_coefficients_from_linear_model_flag = False

        plugin = Plugin(distribution, desired_units)
        result = plugin.compute_initial_guess(
            truth,
            current_forecast_predictor,
            predictor_of_mean_flag,
            estimate_coefficients_from_linear_model_flag,
            no_of_realizations=no_of_realizations)
        self.assertIsInstance(result, np.ndarray)
    def test_truth_unit_conversion(self):
        """Ensure the expected optimised coefficients are generated,
        even if the input truth cube has different units."""
        data = [
            4.55819380e-06, -8.02401974e-09, 1.66667055e+00, 1.00000011e+00
        ]

        truth = self.temperature_truth_cube

        truth.convert_units("Fahrenheit")

        distribution = "gaussian"
        current_cycle = "20171110T0000Z"
        desired_units = "degreesC"

        plugin = Plugin(distribution,
                        current_cycle,
                        desired_units=desired_units)
        result = plugin.estimate_coefficients_for_ngr(
            self.historic_temperature_forecast_cube, truth)

        self.assertArrayAlmostEqual(result.data, data, decimal=5)
Пример #15
0
    def test_basic_truncated_normal_realizations_predictor(self):
        """Test that the plugin returns a numpy array."""
        initial_guess = [5, 1, 0, 1, 1, 1]
        initial_guess = np.array(initial_guess, dtype=np.float32)
        cube = set_up_temperature_cube()

        forecast_predictor = cube.copy()
        forecast_variance = cube.collapsed(
            "realization", iris.analysis.VARIANCE)
        truth = cube.collapsed("realization", iris.analysis.MAX)

        predictor_of_mean_flag = "realizations"

        plugin = Plugin()
        distribution = "truncated gaussian"
        result = plugin.crps_minimiser_wrapper(
            initial_guess, forecast_predictor, truth, forecast_variance,
            predictor_of_mean_flag, distribution)
        self.assertIsInstance(result, np.ndarray)
        self.assertArrayAlmostEqual(
            result, [6.24021609e+00, 1.35694934e+00, 1.84642787e-03,
                     5.55444682e-01, 5.04367388e-01, 6.68575194e-01])
 def test_output_coefficients_realizations(self):
     """
     Test that the plugin returns a tuple containing cubes with the
     expected coefficient names when using ensemble realizations as the
     predictor of the mean.
     """
     cube = self.current_temperature_forecast_cube
     optimised_coeffs = {}
     the_date = datetime_from_timestamp(cube.coord("time").points)
     optimised_coeffs[the_date] = np.array([
         4.55819380e-06, -8.02401974e-09, 1.66667055e+00, 1.00000011e+00,
         1.00000011e+00, 1.00000011e+00
     ])
     plugin = Plugin(cube,
                     optimised_coeffs,
                     self.coeff_names,
                     predictor_of_mean_flag="realizations")
     _, _, coefficients = plugin.apply_params_entry()
     for result, coeff_name, coeff in zip(coefficients, self.coeff_names,
                                          optimised_coeffs[the_date]):
         self.assertEqual(result.long_name, coeff_name)
         self.assertArrayAlmostEqual(result.data, coeff)
Пример #17
0
    def test_calibrated_variance_realizations(self):
        """
        Test that the plugin returns values for the calibrated forecasts,
        which match the expected values when the individual ensemble
        realizations are used as the predictor.
        """
        data = np.array([[34.333333, 34.333333, 34.333333],
                         [34.333333, 34.333333, 34.333333],
                         [34.333333, 34.333333, 34.333333]])

        cube = self.current_temperature_forecast_cube
        cube1 = cube.copy()
        cube2 = cube.copy()

        cube2.coord("time").points = cube2.coord("time").points + 3
        cube2.data += 3

        cube = concatenate_cubes(CubeList([cube1, cube2]))

        optimised_coeffs = {}

        for time_slice in cube.slices_over("time"):
            the_date = datetime_from_timestamp(time_slice.coord("time").points)
            optimised_coeffs[the_date] = np.array(
                [5, 1, 0, 0.57, 0.6, 0.6])
        self.coeff_names = ["gamma", "delta", "a", "beta"]

        predictor_cube = cube.copy()
        variance_cube = cube.collapsed("realization", iris.analysis.VARIANCE)

        predictor_of_mean_flag = "realizations"

        plugin = Plugin(self.cube, optimised_coeffs,
                        self.coeff_names)
        _, forecast_variance, _ = plugin._apply_params(
            predictor_cube, variance_cube, optimised_coeffs,
            self.coeff_names, predictor_of_mean_flag)
        self.assertArrayAlmostEqual(forecast_variance[0].data, data,
                                    decimal=4)
Пример #18
0
    def test_truth_data_is_fake_catch_warning(self, warning_list=None):
        """
        Ensure that a ValueError with the expected text is generated,
        if the input data is None, rather than a cube.
        """
        current_forecast = self.current_temperature_forecast_cube

        historic_forecasts = self.historic_temperature_forecast_cube

        truth = "fake"

        distribution = "gaussian"
        desired_units = "degreesC"

        plugin = Plugin(distribution, desired_units)

        plugin.estimate_coefficients_for_ngr(current_forecast,
                                             historic_forecasts, truth)
        self.assertTrue(len(warning_list) == 1)
        self.assertTrue(
            any(item.category == UserWarning for item in warning_list))
        self.assertTrue("is not a Cube or CubeList" in str(warning_list[0]))
Пример #19
0
    def test_calibrated_predictor_realizations(self):
        """
        Test that the plugin returns values for the calibrated forecasts,
        which match the expected values when the individual ensemble
        realizations are used as the predictor.
        """
        data = np.array([[239.904142, 251.659267, 263.414393],
                         [275.169518, 286.92465, 298.67975],
                         [310.43488, 322.19, 333.94516]],
                        dtype=np.float32)

        cube = self.current_temperature_forecast_cube

        predictor_cube = cube.copy()
        variance_cube = cube.collapsed("realization", iris.analysis.VARIANCE)

        plugin = Plugin(cube,
                        self.coeffs_from_realizations,
                        predictor_of_mean_flag="realizations")
        forecast_predictor, _ = plugin._apply_params(predictor_cube,
                                                     variance_cube)
        self.assertArrayAlmostEqual(forecast_predictor.data, data, decimal=4)
    def test_coefficient_values_for_gaussian_distribution_realizations(self):
        """Ensure that the values for the optimised_coefficients match the
        expected values, and the coefficient names also match
        expected values for a Gaussian distribution where the
        realizations are used as the predictor of the mean."""
        import imp
        try:
            imp.find_module('statsmodels')
            statsmodels_found = True
        except ImportError:
            statsmodels_found = False

        if statsmodels_found:
            data = [-0.00114, -0.00006, 1.00037, -0.00196, 0.99999, -0.00315]
        else:
            data = [
                4.30804737e-02, 1.39042785e+00, 8.99047025e-04, 2.02661310e-01,
                9.27197381e-01, 3.17407626e-01
            ]

        distribution = "gaussian"
        current_cycle = "20171110T0000Z"
        desired_units = "Celsius"
        predictor_of_mean_flag = "realizations"
        expected_coeff_names = ([
            'gamma', 'delta', 'alpha', 'beta0', 'beta1', 'beta2'
        ])

        plugin = Plugin(distribution,
                        current_cycle,
                        desired_units=desired_units,
                        predictor_of_mean_flag=predictor_of_mean_flag)
        result = plugin.estimate_coefficients_for_ngr(
            self.historic_temperature_forecast_cube,
            self.temperature_truth_cube)
        self.assertArrayAlmostEqual(result.data, data, decimal=5)
        self.assertArrayEqual(
            result.coord("coefficient_name").points, expected_coeff_names)
Пример #21
0
 def test_wind_speed_data_check(self):
     """
     Test that the plugin returns an iris.cube.CubeList
     of wind_speed cubes with the expected data, where the plugin
     returns a cubelist of, firstly, the predictor and, secondly the
     variance.
     The ensemble mean is the predictor.
     """
     predictor_data = np.array(
         [[2.9999862, 10.499988, 17.999989],
          [25.49999, 32.999992, 40.499992], [47.999996, 55.499996, 63.]],
         dtype=np.float32)
     variance_data = np.array([[0., 0., 0.], [0., 0., 0.], [0., 0., 0.]],
                              dtype=np.float32)
     calibration_method = "ensemble model output_statistics"
     distribution = "truncated gaussian"
     desired_units = "m s^-1"
     plugin = Plugin(calibration_method, distribution, desired_units)
     calibrated_predictor, calibrated_variance = plugin.process(
         self.current_wind_speed_forecast_cube,
         self.historic_wind_speed_forecast_cube, self.wind_speed_truth_cube)
     self.assertArrayAlmostEqual(calibrated_predictor.data, predictor_data)
     self.assertArrayAlmostEqual(calibrated_variance.data, variance_data)
Пример #22
0
    def test_mean_predictor_estimate_coefficients_nans(self):
        """
        Test that the plugin returns the expected values for the initial guess
        for the calibration coefficients, when the ensemble mean is used
        as the predictor, when one value from the input data is set to NaN.
        The coefficients are estimated using a linear model,
        where there is an offset of one between the truth and the forecast
        during the training period. Therefore, in this case the result of the
        linear regression is a gradient of 1 and an intercept of 1.
        """
        data = np.array([0., 1., 1., 1.], dtype=np.float32)
        estimate_coefficients_from_linear_model_flag = True

        self.current_forecast_predictor_mean.data = (
            self.current_forecast_predictor_mean.data.filled())
        self.current_forecast_predictor_mean.data[0][0] = np.nan

        plugin = Plugin(self.distribution, self.desired_units)
        result = plugin.compute_initial_guess(
            self.truth, self.current_forecast_predictor_mean,
            self.predictor_of_mean_flag,
            estimate_coefficients_from_linear_model_flag)
        self.assertArrayAlmostEqual(result, data)
    def test_calibrated_variance_statsmodels_realizations(self):
        """
        Test that the plugin returns the expected values for the calibrated
        ensemble variance when the ensemble realizations are used as the
        predictor. The input coefficients have been generated using
        statsmodels. Check that the calibrated variance is similar to when the
        ensemble mean is used as the predictor.
        """
        cube = self.current_temperature_forecast_cube

        predictor_cube = cube.copy()
        variance_cube = cube.collapsed("realization", iris.analysis.VARIANCE)

        plugin = Plugin(cube, self.coeffs_from_statsmodels_realizations,
                        predictor_of_mean_flag="realizations")
        _, forecast_variance = plugin._apply_params(
            predictor_cube, variance_cube)
        self.assertCalibratedVariablesAlmostEqual(
            forecast_variance.data,
            self.expected_calibrated_variance_statsmodels_realizations)
        self.assertArrayAlmostEqual(
            forecast_variance.data,
            self.expected_calibrated_variance_mean, decimal=0)
Пример #24
0
    def test_truth_data_length_zero_catch_warning(self, warning_list=None):
        """
        Ensure that a ValueError with the expected text is generated,
        if the input data is None, rather than a cube.
        """
        current_forecast = self.current_temperature_forecast_cube

        historic_forecasts = self.historic_temperature_forecast_cube

        truth = iris.cube.CubeList([])

        distribution = "gaussian"
        desired_units = "degreesC"

        plugin = Plugin(distribution, desired_units)

        plugin.estimate_coefficients_for_ngr(current_forecast,
                                             historic_forecasts, truth)
        warning_msg = ("Insufficient input data present to estimate "
                       "coefficients using NGR.")
        self.assertTrue(
            any(item.category == UserWarning for item in warning_list))
        self.assertTrue(any(warning_msg in str(item) for item in warning_list))
Пример #25
0
    def test_truth_data_has_wrong_time_catch_warning(self, warning_list=None):
        """
        Ensure that a ValueError with the expected text is generated,
        if the input data is None, rather than a cube.
        """
        current_forecast = self.current_temperature_forecast_cube

        historic_forecasts = self.historic_temperature_forecast_cube

        truth = self.temperature_truth_cube
        truth.coord("forecast_reference_time").points += 10

        distribution = "gaussian"
        desired_units = "degreesC"

        plugin = Plugin(distribution, desired_units)

        plugin.estimate_coefficients_for_ngr(current_forecast,
                                             historic_forecasts, truth)
        warning_msg = "Unable to calibrate for the time points"
        self.assertTrue(
            any(item.category == UserWarning for item in warning_list))
        self.assertTrue(any(warning_msg in str(item) for item in warning_list))
Пример #26
0
    def test_statsmodels_mean(self):
        """
        Test that the plugin raises no warnings if the statsmodels module
        is not found for when the predictor is the ensemble mean.
        """
        warnings.simplefilter("always")
        import imp
        try:
            statsmodels_found = imp.find_module('statsmodels')
            statsmodels_found = True
        except ImportError:
            statsmodels_found = False

        cube = self.cube

        historic_forecasts = CubeList([])
        for index in [1.0, 2.0, 3.0, 4.0, 5.0]:
            temp_cube = cube.copy()
            temp_cube.coord("time").points = (temp_cube.coord("time").points -
                                              index)
            historic_forecasts.append(temp_cube)
        historic_forecasts.concatenate_cube()

        current_forecast_predictor = cube
        truth = cube.collapsed("realization", iris.analysis.MAX)
        distribution = "gaussian"
        desired_units = "degreesC"
        predictor_of_mean_flag = "mean"
        no_of_members = 3
        estimate_coefficients_from_linear_model_flag = True

        if not statsmodels_found:
            with warnings.catch_warnings(record=True) as warning_list:
                plugin = Plugin(distribution,
                                desired_units,
                                predictor_of_mean_flag=predictor_of_mean_flag)
                self.assertTrue(len(warning_list) == 0)
Пример #27
0
    def test_members_predictor_estimate_coefficients(self):
        """
        Test that the plugin returns the expected values for the initial guess
        for the calibration coefficients, when the ensemble mean is used
        as the predictor. The coefficients are estimated using a linear model.
        """
        warnings.simplefilter("always")
        import imp
        try:
            statsmodels_found = imp.find_module('statsmodels')
            statsmodels_found = True
        except ImportError:
            statsmodels_found = False

        if statsmodels_found:
            data = [1., 1., 0.13559322, -0.11864407, 0.42372881, 0.69491525]
        else:
            data = [1, 1, 0, 1, 1, 1]

        cube = self.cube

        current_forecast_predictor = cube
        truth = cube.collapsed("realization", iris.analysis.MAX)
        distribution = "gaussian"
        desired_units = "degreesC"
        predictor_of_mean_flag = "members"
        no_of_members = 3
        estimate_coefficients_from_linear_model_flag = True

        plugin = Plugin(distribution, desired_units)
        result = plugin.compute_initial_guess(
            truth,
            current_forecast_predictor,
            predictor_of_mean_flag,
            estimate_coefficients_from_linear_model_flag,
            no_of_members=no_of_members)
        self.assertArrayAlmostEqual(result, data)
Пример #28
0
    def test_normal_catch_warnings_percentage_change(self):
        """
        Test that two warnings are generated if the minimisation
        does not result in a convergence. The first warning reports a that
        the minimisation did not result in convergence, whilst the second
        warning reports that the percentage change in the final iteration was
        greater than the tolerated value.
        The ensemble mean is the predictor.
        """
        warnings.simplefilter("always")
        initial_guess = [500, 100, 0, 100]
        initial_guess = np.array(initial_guess, dtype=np.float32)
        cube = set_up_temperature_cube()

        forecast_predictor = cube.collapsed("realization", iris.analysis.MEAN)
        forecast_variance = cube.collapsed("realization",
                                           iris.analysis.VARIANCE)
        truth = cube.collapsed("realization", iris.analysis.MAX)

        predictor_of_mean_flag = "mean"

        plugin = Plugin()
        distribution = "gaussian"
        with warnings.catch_warnings(record=True) as warning_list:
            warnings.simplefilter("always")
            result = plugin.crps_minimiser_wrapper(initial_guess,
                                                   forecast_predictor, truth,
                                                   forecast_variance,
                                                   predictor_of_mean_flag,
                                                   distribution)
            self.assertTrue(len(warning_list) == 2)
            self.assertTrue(
                any(item.category == UserWarning for item in warning_list))
            self.assertTrue("Minimisation did not result in convergence after"
                            in str(warning_list[0]))
            self.assertTrue("The final iteration resulted in a percentage "
                            "change" in str(warning_list[1]))
    def test_calibrated_variance(self):
        """
        Test that the plugin returns values for the calibrated variance,
        which match the expected values.
        """
        data = np.array([[2.07777316e-11, 2.07777316e-11, 2.07777316e-11],
                         [2.07777316e-11, 2.07777316e-11, 2.07777316e-11],
                         [2.07777316e-11, 2.07777316e-11, 2.07777316e-11]])

        cube = self.current_temperature_forecast_cube
        cube1 = cube.copy()
        cube2 = cube.copy()

        cube2.coord("time").points = cube2.coord("time").points + 3
        cube2.data += 3

        cube = concatenate_cubes(CubeList([cube1, cube2]))

        optimised_coeffs = {}

        for time_slice in cube.slices_over("time"):
            the_date = datetime_from_timestamp(time_slice.coord("time").points)
            optimised_coeffs[the_date] = self.default_optimised_coeffs

        predictor_cube = cube.collapsed("realization", iris.analysis.MEAN)
        variance_cube = cube.collapsed("realization", iris.analysis.VARIANCE)

        predictor_of_mean_flag = "mean"

        plugin = Plugin(self.cube, optimised_coeffs, self.coeff_names)
        _, forecast_variance, _ = plugin._apply_params(predictor_cube,
                                                       variance_cube,
                                                       optimised_coeffs,
                                                       self.coeff_names,
                                                       predictor_of_mean_flag)
        self.assertArrayAlmostEqual(forecast_variance[0].data, data)
Пример #30
0
    def test_basic_truncated_normal_mean_predictor(self):
        """
        Test that the plugin returns a numpy float value.
        The ensemble mean is the predictor.
        """
        initial_guess = [5, 1, 0, 1]
        initial_guess = np.array(initial_guess, dtype=np.float32)
        cube = set_up_temperature_cube()

        forecast_predictor = cube.collapsed("realization", iris.analysis.MEAN)
        forecast_variance = cube.collapsed(
            "realization", iris.analysis.VARIANCE)
        truth = cube.collapsed("realization", iris.analysis.MAX)

        predictor_of_mean_flag = "mean"

        plugin = Plugin()
        distribution = "truncated gaussian"
        result = plugin.crps_minimiser_wrapper(
            initial_guess, forecast_predictor, truth, forecast_variance,
            predictor_of_mean_flag, distribution)
        self.assertIsInstance(result, np.ndarray)
        self.assertArrayAlmostEqual(
            result, [-0.08169791, -0.09784413, 0.00822535, 1.00956199])