Beispiel #1
0
    def test_catch_warnings_percentage_change(self, warning_list=None):
        """
        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.
        """
        initial_guess = np.array([5000, 1, 0, 1], dtype=np.float64)

        predictor_of_mean_flag = "mean"
        distribution = "truncated_gaussian"

        plugin = Plugin(tolerance=self.tolerance, max_iterations=5)

        plugin.process(initial_guess, self.forecast_predictor_mean, self.truth,
                       self.forecast_variance, predictor_of_mean_flag,
                       distribution)
        warning_msg_min = "Minimisation did not result in convergence after"
        warning_msg_iter = "The final iteration resulted in a percentage "
        self.assertTrue(
            any(item.category == UserWarning for item in warning_list))
        self.assertTrue(
            any(warning_msg_min in str(item) for item in warning_list))
        self.assertTrue(
            any(warning_msg_iter in str(item) for item in warning_list))
Beispiel #2
0
    def test_basic_members_predictor(self):
        """
        Test that the plugin returns a numpy float array with ensemble members
        as predictor.
        """
        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)

        forecast_predictor_data = (
            convert_cube_data_to_2d(forecast_predictor).astype(np.float32))
        forecast_variance_data = (forecast_variance.data.flatten().astype(
            np.float32))
        truth_data = truth.data.flatten().astype(np.float32)

        sqrt_pi = np.sqrt(np.pi).astype(np.float32)

        predictor_of_mean_flag = "members"

        plugin = Plugin()
        result = plugin.normal_crps_minimiser(initial_guess,
                                              forecast_predictor_data,
                                              truth_data,
                                              forecast_variance_data, sqrt_pi,
                                              predictor_of_mean_flag)

        self.assertIsInstance(result, np.float64)
        self.assertAlmostEqual(result, 4886.94724835)
Beispiel #3
0
    def test_basic_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_wind_speed_cube()

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

        forecast_predictor_data = (forecast_predictor.data.flatten().astype(
            np.float32))
        forecast_variance_data = (forecast_variance.data.flatten().astype(
            np.float32))
        truth_data = truth.data.flatten().astype(np.float32)

        sqrt_pi = np.sqrt(np.pi).astype(np.float32)

        predictor_of_mean_flag = "mean"

        plugin = Plugin()
        result = plugin.truncated_normal_crps_minimiser(
            initial_guess, forecast_predictor_data, truth_data,
            forecast_variance_data, sqrt_pi, predictor_of_mean_flag)

        self.assertIsInstance(result, np.float64)
        self.assertAlmostEqual(result, 13.182782882390779)
    def test_truncated_normal_mean_predictor_max_iterations(self):
        """
        Test that the plugin returns a list of coefficients
        equal to specific values, when the ensemble mean is the predictor
        assuming a truncated normal distribution and the value specified
        for the MAX_ITERATIONS is overriden. The coefficients are
        calculated by minimising the CRPS and using a set default value for
        the initial guess.
        """
        warnings.simplefilter("always")
        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()
        plugin.MAX_ITERATIONS = 400
        distribution = "truncated gaussian"
        result = plugin.crps_minimiser_wrapper(
            initial_guess, forecast_predictor, truth, forecast_variance,
            predictor_of_mean_flag, distribution)
        self.assertArrayAlmostEqual(
            result, [-0.303343, -0.022553, 0.008502, 1.009565])
Beispiel #5
0
    def test_normal_mean_predictor_keyerror(self):
        """
        Test that the minimisation has resulted in a KeyError, if the
        distribution that has been requested was not within the dictionary
        containing the minimisation functions.
        """
        initial_guess = [
            -8.70808509e-06, 7.23255721e-06, 2.66662740e+00, 1.00000012e+00
        ]
        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 = "foo"
        msg = "Distribution requested"
        with self.assertRaisesRegexp(KeyError, msg):
            plugin.crps_minimiser_wrapper(initial_guess, forecast_predictor,
                                          truth, forecast_variance,
                                          predictor_of_mean_flag, distribution)
Beispiel #6
0
    def test_basic_mean_predictor_bad_value(self):
        """
        Test that the plugin returns a numpy float64 value
        and that the value matches the BAD_VALUE, when the appropriate
        condition is found.
        The ensemble mean is the predictor.
        """
        initial_guess = [1e65, 1e65, 1e65, 1e65]
        initial_guess = np.array(initial_guess, dtype=np.float32)
        cube = set_up_wind_speed_cube()

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

        forecast_predictor_data = (forecast_predictor.data.flatten().astype(
            np.float32))
        forecast_variance_data = (forecast_variance.data.flatten().astype(
            np.float32))
        truth_data = truth.data.flatten().astype(np.float32)

        sqrt_pi = np.sqrt(np.pi).astype(np.float32)

        predictor_of_mean_flag = "mean"

        plugin = Plugin()
        result = plugin.truncated_normal_crps_minimiser(
            initial_guess, forecast_predictor_data, truth_data,
            forecast_variance_data, sqrt_pi, predictor_of_mean_flag)

        self.assertIsInstance(result, np.float64)
        self.assertAlmostEqual(result, plugin.BAD_VALUE)
Beispiel #7
0
    def test_basic_truncated_normal_members_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 = "members"

        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
        ])
Beispiel #8
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])
Beispiel #9
0
    def test_truncated_normal_members_predictor_max_iterations(self):
        """
        Test that the plugin returns a list of coefficients
        equal to specific values, when the ensemble members are the predictor
        assuming a truncated normal distribution and the value specified
        for the MAX_ITERATIONS is overriden. The coefficients are
        calculated by minimising the CRPS and using a set default value for
        the initial guess.
        """
        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 = "members"

        plugin = Plugin()
        plugin.MAX_ITERATIONS = 400
        distribution = "truncated gaussian"
        result = plugin.crps_minimiser_wrapper(initial_guess,
                                               forecast_predictor, truth,
                                               forecast_variance,
                                               predictor_of_mean_flag,
                                               distribution)
        self.assertArrayAlmostEqual(
            result, [5.375955, 1.45785, 0.002567, 0.193423, 0.55406, 0.811599])
Beispiel #10
0
    def test_truncated_normal_members_predictor_keyerror(self):
        """
        Test that the minimisation has resulted in a successful convergence,
        and that the object returned is an OptimizeResult object, when the
        ensemble members are the predictor.
        """
        initial_guess = [
            -8.70808509e-06, 7.23255721e-06, 2.66662740e+00, 1.00000012e+00
        ]
        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 = "members"

        plugin = Plugin()
        distribution = "foo"
        msg = "Distribution requested"
        with self.assertRaisesRegexp(KeyError, msg):
            plugin.crps_minimiser_wrapper(initial_guess, forecast_predictor,
                                          truth, forecast_variance,
                                          predictor_of_mean_flag, distribution)
Beispiel #11
0
    def test_truncated_normal_catch_warnings(self, warning_list=None):
        """
        Test that a warning is generated if the minimisation
        does not result in a convergence.
        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.assertTrue(len(warning_list) == 1)
        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]))
Beispiel #12
0
    def test_truncated_normal_catch_warnings_percentage_change(
            self, warning_list=None):
        """
        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.
        """
        initial_guess = [5000, 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.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]))
Beispiel #13
0
    def test_basic_realizations_predictor(self):
        """
        Test that the plugin returns a numpy array.
        The ensemble realizations are the predictor.
        """
        initial_guess = [5, 1, 0, 1, 1, 1]
        initial_guess = np.array(initial_guess, dtype=np.float32)
        cube = set_up_wind_speed_cube()

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

        forecast_predictor_data = (
            convert_cube_data_to_2d(
                forecast_predictor).astype(np.float32))
        forecast_variance_data = (
            forecast_variance.data.flatten().astype(np.float32))
        truth_data = truth.data.flatten().astype(np.float32)

        sqrt_pi = np.sqrt(np.pi).astype(np.float32)

        predictor_of_mean_flag = "realizations"

        plugin = Plugin()
        result = plugin.truncated_normal_crps_minimiser(
            initial_guess, forecast_predictor_data, truth_data,
            forecast_variance_data, sqrt_pi, predictor_of_mean_flag)

        self.assertIsInstance(result, np.float64)
        self.assertAlmostEqual(result, 533.487612959)
Beispiel #14
0
    def test_basic_mean_predictor(self):
        """
        Test that the plugin returns a numpy float value with
        mean as 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)

        forecast_predictor_data = (forecast_predictor.data.flatten().astype(
            np.float32))
        forecast_variance_data = (forecast_variance.data.flatten().astype(
            np.float32))
        truth_data = truth.data.flatten().astype(np.float32)

        sqrt_pi = np.sqrt(np.pi).astype(np.float32)

        predictor_of_mean_flag = "mean"

        plugin = Plugin()
        result = plugin.normal_crps_minimiser(initial_guess,
                                              forecast_predictor_data,
                                              truth_data,
                                              forecast_variance_data, sqrt_pi,
                                              predictor_of_mean_flag)

        self.assertIsInstance(result, np.float64)
        self.assertAlmostEqual(result, 16.607763767419634)
    def test_basic_realizations_predictor(self):
        """
        Test that the plugin returns a numpy array with the expected
        coefficients. The ensemble realizations are the predictor.
        """
        predictor_of_mean_flag = "realizations"
        distribution = "truncated_gaussian"

        plugin = Plugin()
        result = plugin.process(self.initial_guess_for_realization,
                                self.forecast_predictor_realizations,
                                self.truth, self.forecast_variance,
                                predictor_of_mean_flag, distribution)
        self.assertIsInstance(result, np.ndarray)
        self.assertEMOSCoefficientsAlmostEqual(
            result, self.expected_realizations_coefficients)
 def test_basic_mean_predictor(self):
     """
     Test that the plugin returns a numpy array with the expected
     coefficients. The ensemble mean is the predictor.
     """
     predictor_of_mean_flag = "mean"
     distribution = "gaussian"
     plugin = Plugin()
     result = plugin.process(self.initial_guess_for_mean,
                             self.forecast_predictor_mean, self.truth,
                             self.forecast_variance, predictor_of_mean_flag,
                             distribution)
     self.assertIsInstance(result, np.ndarray)
     self.assertEqual(result.dtype, np.float32)
     self.assertEMOSCoefficientsAlmostEqual(result,
                                            self.expected_mean_coefficients)
Beispiel #17
0
    def test_basic_realizations_predictor(self):
        """
        Test that the plugin returns a numpy float value. The ensemble
        realizations are the predictor. The result indicates the minimum value
        for the CRPS that was achieved by the minimisation.
        """
        predictor_of_mean_flag = "realizations"

        plugin = Plugin()
        result = plugin.calculate_truncated_normal_crps(
            self.initial_guess_for_realization,
            self.forecast_predictor_data_realizations, self.truth_data,
            self.forecast_variance_data, self.sqrt_pi, predictor_of_mean_flag)

        self.assertIsInstance(result, np.float64)
        self.assertAlmostEqual(result, 0.1670167)
    def test_mean_predictor_keyerror(self):
        """
        Test that the minimisation has resulted in a KeyError, if the
        distribution that has been requested was not within the dictionary
        containing the minimisation functions.
        """
        predictor_of_mean_flag = "mean"
        distribution = "foo"

        plugin = Plugin()
        msg = "Distribution requested"
        with self.assertRaisesRegex(KeyError, msg):
            plugin.process(self.initial_guess_for_mean,
                           self.forecast_predictor_mean, self.truth,
                           self.forecast_variance, predictor_of_mean_flag,
                           distribution)
    def test_realizations_predictor_keyerror(self):
        """
        Test that an exception is raised when the distribution requested is
        not an available option when the predictor_of_mean_flag is the
        ensemble realizations.
        """
        predictor_of_mean_flag = "realizations"
        distribution = "foo"

        plugin = Plugin()
        msg = "Distribution requested"
        with self.assertRaisesRegex(KeyError, msg):
            plugin.process(self.initial_guess_for_realization,
                           self.forecast_predictor_realizations, self.truth,
                           self.forecast_variance, predictor_of_mean_flag,
                           distribution)
Beispiel #20
0
    def test_catch_warnings(self, warning_list=None):
        """
        Test that a warning is generated if the minimisation
        does not result in a convergence. The ensemble mean is the predictor.
        """
        predictor_of_mean_flag = "mean"
        distribution = "truncated_gaussian"

        plugin = Plugin(tolerance=self.tolerance, max_iterations=10)
        plugin.process(self.initial_guess_for_mean,
                       self.forecast_predictor_mean, self.truth,
                       self.forecast_variance, predictor_of_mean_flag,
                       distribution)
        warning_msg = "Minimisation did not result in convergence after"
        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 #21
0
    def test_basic_mean_predictor(self):
        """
        Test that the plugin returns a numpy float value with the
        mean as the predictor. The result indicates the minimum value for the
        CRPS that was achieved by the minimisation.
        """
        predictor_of_mean_flag = "mean"

        plugin = Plugin()
        result = plugin.calculate_normal_crps(self.initial_guess_for_mean,
                                              self.forecast_predictor_data,
                                              self.truth_data,
                                              self.forecast_variance_data,
                                              self.sqrt_pi,
                                              predictor_of_mean_flag)

        self.assertIsInstance(result, np.float64)
        self.assertAlmostEqual(result, 0.2609063)
Beispiel #22
0
 def setUp(self):
     """Set up expected output."""
     super().setUp()
     self.tolerance = 1e-4
     self.plugin = Plugin(tolerance=self.tolerance)
     self.expected_mean_coefficients = ([0.0459, 0.6047, 0.3965, 0.958])
     self.expected_realizations_coefficients = ([
         0.0265, 0.2175, 0.2692, 0.0126, 0.5965, 0.7952
     ])
Beispiel #23
0
    def test_basic_mean_predictor_bad_value(self):
        """
        Test that the plugin returns a numpy float64 value
        and that the value matches the BAD_VALUE, when the appropriate
        condition is found. The ensemble mean is the predictor. The initial
        guess is specifically set to float32 precision for the purpose for
        generating the BAD_VALUE for the unit test.
        """
        initial_guess = np.array([1e65, 1e65, 1e65, 1e65], dtype=np.float32)

        predictor_of_mean_flag = "mean"

        plugin = Plugin()
        result = plugin.calculate_truncated_normal_crps(
            initial_guess, self.forecast_predictor_data, self.truth_data,
            self.forecast_variance_data, self.sqrt_pi, predictor_of_mean_flag)

        self.assertIsInstance(result, np.float64)
        self.assertAlmostEqual(result, plugin.BAD_VALUE)
Beispiel #24
0
 def setUp(self):
     """Set up expected output.
     The coefficients are in the order [gamma, delta, alpha, beta].
     """
     super().setUp()
     self.tolerance = 1e-4
     self.plugin = Plugin(tolerance=self.tolerance)
     self.expected_mean_coefficients = ([0.0023, 0.8070, -0.0008, 1.0009])
     self.expected_realizations_coefficients = ([
         -0.1373, 0.1141, 0.0409, 0.414, 0.2056, 0.8871
     ])
    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(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)
Beispiel #26
0
class Test_process_truncated_gaussian_distribution(
        SetupTruncatedGaussianInputs, EnsembleCalibrationAssertions):
    """
    Test minimising the CRPS for a truncated gaussian distribution.
    Either the ensemble mean or the individual ensemble realizations are used
    as the predictors.
    """
    def setUp(self):
        """Set up expected output."""
        super().setUp()
        self.tolerance = 1e-4
        self.plugin = Plugin(tolerance=self.tolerance)
        self.expected_mean_coefficients = ([0.0459, 0.6047, 0.3965, 0.958])
        self.expected_realizations_coefficients = ([
            0.0265, 0.2175, 0.2692, 0.0126, 0.5965, 0.7952
        ])

    @ManageWarnings(ignored_messages=[
        "Collapsing a non-contiguous coordinate.",
        "The final iteration resulted in", "invalid value encountered in",
        "divide by zero encountered in"
    ],
                    warning_types=[
                        UserWarning, UserWarning, RuntimeWarning,
                        RuntimeWarning
                    ])
    def test_basic_mean_predictor(self):
        """
        Test that the plugin returns a numpy array. The ensemble mean
        is the predictor.
        """
        predictor_of_mean_flag = "mean"
        distribution = "truncated_gaussian"

        result = self.plugin.process(self.initial_guess_for_mean,
                                     self.forecast_predictor_mean, self.truth,
                                     self.forecast_variance,
                                     predictor_of_mean_flag, distribution)
        self.assertIsInstance(result, np.ndarray)
        self.assertEMOSCoefficientsAlmostEqual(result,
                                               self.expected_mean_coefficients)

    @ManageWarnings(ignored_messages=[
        "Collapsing a non-contiguous coordinate.",
        "Minimisation did not result in convergence",
        "invalid value encountered in", "divide by zero encountered in"
    ],
                    warning_types=[
                        UserWarning, UserWarning, RuntimeWarning,
                        RuntimeWarning
                    ])
    def test_basic_realizations_predictor(self):
        """
        Test that the plugin returns a numpy array with the expected
        coefficients. The ensemble realizations are the predictor.
        """
        predictor_of_mean_flag = "realizations"
        distribution = "truncated_gaussian"

        result = self.plugin.process(self.initial_guess_for_realization,
                                     self.forecast_predictor_realizations,
                                     self.truth, self.forecast_variance,
                                     predictor_of_mean_flag, distribution)
        self.assertIsInstance(result, np.ndarray)
        self.assertEMOSCoefficientsAlmostEqual(
            result, self.expected_realizations_coefficients)

    @ManageWarnings(
        ignored_messages=["Collapsing a non-contiguous coordinate."])
    def test_mean_predictor_keyerror(self):
        """
        Test that an exception is raised when the distribution requested is
        not an available option when the predictor_of_mean_flag is the
        ensemble mean.
        """
        predictor_of_mean_flag = "mean"
        distribution = "foo"

        msg = "Distribution requested"
        with self.assertRaisesRegex(KeyError, msg):
            self.plugin.process(self.initial_guess_for_mean,
                                self.forecast_predictor_mean, self.truth,
                                self.forecast_variance, predictor_of_mean_flag,
                                distribution)

    @ManageWarnings(ignored_messages=[
        "Collapsing a non-contiguous coordinate.",
        "Minimisation did not result in convergence",
        "The final iteration resulted in", "invalid value encountered in",
        "divide by zero encountered in"
    ],
                    warning_types=[
                        UserWarning, UserWarning, UserWarning, RuntimeWarning,
                        RuntimeWarning
                    ])
    def test_mean_predictor_max_iterations(self):
        """
        Test that the plugin returns a list of coefficients
        equal to specific values, when the ensemble mean is 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 = "mean"
        max_iterations = 400
        distribution = "truncated_gaussian"

        plugin = Plugin(tolerance=self.tolerance,
                        max_iterations=max_iterations)
        result = plugin.process(self.initial_guess_for_mean,
                                self.forecast_predictor_mean, self.truth,
                                self.forecast_variance, predictor_of_mean_flag,
                                distribution)
        self.assertEMOSCoefficientsAlmostEqual(result,
                                               self.expected_mean_coefficients)

    @ManageWarnings(ignored_messages=[
        "Collapsing a non-contiguous coordinate.",
        "Minimisation did not result in convergence",
        "invalid value encountered in", "divide by zero encountered in"
    ],
                    warning_types=[
                        UserWarning, UserWarning, RuntimeWarning,
                        RuntimeWarning
                    ])
    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)

    @ManageWarnings(
        record=True,
        ignored_messages=["Collapsing a non-contiguous coordinate."])
    def test_catch_warnings(self, warning_list=None):
        """
        Test that a warning is generated if the minimisation
        does not result in a convergence. The ensemble mean is the predictor.
        """
        predictor_of_mean_flag = "mean"
        distribution = "truncated_gaussian"

        plugin = Plugin(tolerance=self.tolerance, max_iterations=10)
        plugin.process(self.initial_guess_for_mean,
                       self.forecast_predictor_mean, self.truth,
                       self.forecast_variance, predictor_of_mean_flag,
                       distribution)
        warning_msg = "Minimisation did not result in convergence after"
        self.assertTrue(
            any(item.category == UserWarning for item in warning_list))
        self.assertTrue(any(warning_msg in str(item) for item in warning_list))

    @ManageWarnings(
        record=True,
        ignored_messages=["Collapsing a non-contiguous coordinate."])
    def test_catch_warnings_percentage_change(self, warning_list=None):
        """
        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.
        """
        initial_guess = np.array([5000, 1, 0, 1], dtype=np.float64)

        predictor_of_mean_flag = "mean"
        distribution = "truncated_gaussian"

        plugin = Plugin(tolerance=self.tolerance, max_iterations=5)

        plugin.process(initial_guess, self.forecast_predictor_mean, self.truth,
                       self.forecast_variance, predictor_of_mean_flag,
                       distribution)
        warning_msg_min = "Minimisation did not result in convergence after"
        warning_msg_iter = "The final iteration resulted in a percentage "
        self.assertTrue(
            any(item.category == UserWarning for item in warning_list))
        self.assertTrue(
            any(warning_msg_min in str(item) for item in warning_list))
        self.assertTrue(
            any(warning_msg_iter in str(item) for item in warning_list))
Beispiel #27
0
 def setUp(self):
     """Set up values for tests."""
     self.distribution = "gaussian"
     self.current_cycle = "20171110T0000Z"
     self.minimiser = repr(ContinuousRankedProbabilityScoreMinimisers())
     self.coeff_names = ["gamma", "delta", "alpha", "beta"]