From 0ed937cd029db5f048ea291779d3a1caea5d8d06 Mon Sep 17 00:00:00 2001 From: leufen1 <l.leufen@fz-juelich.de> Date: Tue, 18 Jan 2022 16:51:14 +0100 Subject: [PATCH] added some tests --- mlair/model_modules/convolutional_networks.py | 2 +- .../model_modules/fully_connected_networks.py | 2 +- mlair/model_modules/recurrent_networks.py | 2 +- mlair/run_modules/pre_processing.py | 3 +- test/test_helpers/test_statistics.py | 73 ++++++++++++++++++- 5 files changed, 77 insertions(+), 5 deletions(-) diff --git a/mlair/model_modules/convolutional_networks.py b/mlair/model_modules/convolutional_networks.py index be047eb7..d8eb6eb3 100644 --- a/mlair/model_modules/convolutional_networks.py +++ b/mlair/model_modules/convolutional_networks.py @@ -11,7 +11,7 @@ from mlair.model_modules.advanced_paddings import PadUtils, Padding2D, Symmetric import tensorflow.keras as keras -class CNN(AbstractModelClass): +class CNN(AbstractModelClass): # pragma: no cover _activation = {"relu": keras.layers.ReLU, "tanh": partial(keras.layers.Activation, "tanh"), "sigmoid": partial(keras.layers.Activation, "sigmoid"), diff --git a/mlair/model_modules/fully_connected_networks.py b/mlair/model_modules/fully_connected_networks.py index 8536516e..372473ee 100644 --- a/mlair/model_modules/fully_connected_networks.py +++ b/mlair/model_modules/fully_connected_networks.py @@ -192,7 +192,7 @@ class FCN_64_32_16(FCN): super()._update_model_name() -class BranchedInputFCN(AbstractModelClass): +class BranchedInputFCN(AbstractModelClass): # pragma: no cover """ A customisable fully connected network (64, 32, 16, window_lead_time), where the last layer is the output layer depending on the window_lead_time parameter. diff --git a/mlair/model_modules/recurrent_networks.py b/mlair/model_modules/recurrent_networks.py index 59927e99..6ec920c1 100644 --- a/mlair/model_modules/recurrent_networks.py +++ b/mlair/model_modules/recurrent_networks.py @@ -10,7 +10,7 @@ from mlair.model_modules.loss import var_loss, custom_loss import tensorflow.keras as keras -class RNN(AbstractModelClass): +class RNN(AbstractModelClass): # pragma: no cover """ """ diff --git a/mlair/run_modules/pre_processing.py b/mlair/run_modules/pre_processing.py index ff29bd21..8443b10d 100644 --- a/mlair/run_modules/pre_processing.py +++ b/mlair/run_modules/pre_processing.py @@ -327,7 +327,8 @@ class PreProcessing(RunEnvironment): experiment_path = self.data_store.get("experiment_path") transformation_path = os.path.join(experiment_path, "data", "transformation") transformation_file = os.path.join(transformation_path, "transformation.pickle") - if not os.path.exists(transformation_file): + calculate_fresh_transformation = self.data_store.get_default("calculate_fresh_transformation", True) + if not os.path.exists(transformation_file) or calculate_fresh_transformation: path_config.check_path_and_create(transformation_path) with open(transformation_file, "wb") as f: dill.dump(transformation_opts, f, protocol=4) diff --git a/test/test_helpers/test_statistics.py b/test/test_helpers/test_statistics.py index f5148cdc..a3f64593 100644 --- a/test/test_helpers/test_statistics.py +++ b/test/test_helpers/test_statistics.py @@ -5,7 +5,9 @@ import xarray as xr from mlair.helpers.statistics import standardise, standardise_inverse, standardise_apply, centre, centre_inverse, \ centre_apply, apply_inverse_transformation, min_max, min_max_inverse, min_max_apply, log, log_inverse, log_apply, \ - create_single_bootstrap_realization, calculate_average, create_n_bootstrap_realizations + create_single_bootstrap_realization, calculate_average, create_n_bootstrap_realizations, mean_squared_error, \ + mean_absolute_error, calculate_error_metrics +from mlair.helpers.testing import check_nested_equality lazy = pytest.lazy_fixture @@ -255,3 +257,72 @@ class TestCreateBootstrapRealizations: dim_name_model='model', n_boots=1000, dim_name_boots='boots') assert isinstance(boot_data, xr.DataArray) assert boot_data.shape == (1000,) + + +class TestMeanSquaredError: + + def test_mean_squared_error(self): + assert mean_squared_error(10, 3) == 49 + assert np.testing.assert_almost_equal(mean_squared_error(np.array([10, 20, 15]), np.array([5, 25, 15])), 50./3) is None + + def test_mean_squared_error_xarray(self): + d1 = np.array([np.array([1, 2, 3, 4, 5]), np.array([1, 2, 3, 4, 5]), np.array([1, 2, 3, 4, 5])]) + d2 = np.array([np.array([2, 4, 3, 4, 6]), np.array([2, 3, 3, 4, 5]), np.array([0, 1, 3, 4, 5])]) + shape = d1.shape + coords = {'index': range(shape[0]), 'value': range(shape[1])} + x_array1 = xr.DataArray(d1, coords=coords, dims=coords.keys()) + x_array2 = xr.DataArray(d2, coords=coords, dims=coords.keys()) + expected = xr.DataArray(np.array([1, 2, 0, 0, 1./3]), coords={"value": [0, 1, 2, 3, 4]}, dims=["value"]) + assert xr.testing.assert_equal(mean_squared_error(x_array1, x_array2, "index"), expected) is None + expected = xr.DataArray(np.array([1.2, 0.4, 0.4]), coords={"index": [0, 1, 2]}, dims=["index"]) + assert xr.testing.assert_equal(mean_squared_error(x_array1, x_array2, "value"), expected) is None + + +class TestMeanAbsoluteError: + + def test_mean_absolute_error(self): + assert mean_absolute_error(10, 3) == 7 + assert np.testing.assert_almost_equal(mean_absolute_error(np.array([10, 20, 15]), np.array([5, 25, 15])), 10./3) is None + + def test_mean_absolute_error_xarray(self): + d1 = np.array([np.array([1, 2, 3, 4, 5]), np.array([1, 2, 3, 4, 5]), np.array([1, 2, 3, 4, 5])]) + d2 = np.array([np.array([2, 4, 3, 4, 6]), np.array([2, 3, 3, 4, 5]), np.array([0, 1, 3, 4, 5])]) + shape = d1.shape + coords = {'index': range(shape[0]), 'value': range(shape[1])} + x_array1 = xr.DataArray(d1, coords=coords, dims=coords.keys()) + x_array2 = xr.DataArray(d2, coords=coords, dims=coords.keys()) + expected = xr.DataArray(np.array([1, 4./3, 0, 0, 1./3]), coords={"value": [0, 1, 2, 3, 4]}, dims=["value"]) + assert xr.testing.assert_equal(mean_absolute_error(x_array1, x_array2, "index"), expected) is None + expected = xr.DataArray(np.array([0.8, 0.4, 0.4]), coords={"index": [0, 1, 2]}, dims=["index"]) + assert xr.testing.assert_equal(mean_absolute_error(x_array1, x_array2, "value"), expected) is None + + +class TestCalculateErrorMetrics: + + def test_calculate_error_metrics(self): + d1 = np.array([np.array([1, 2, 3, 4, 5]), np.array([1, 2, 3, 4, 5]), np.array([1, 2, 3, 4, 5])]) + d2 = np.array([np.array([2, 4, 3, 4, 6]), np.array([2, 3, 3, 4, 5]), np.array([0, 1, 3, 4, 5])]) + shape = d1.shape + coords = {'index': range(shape[0]), 'value': range(shape[1])} + x_array1 = xr.DataArray(d1, coords=coords, dims=coords.keys()) + x_array2 = xr.DataArray(d2, coords=coords, dims=coords.keys()) + expected = {"mse": xr.DataArray(np.array([1, 2, 0, 0, 1./3]), coords={"value": [0, 1, 2, 3, 4]}, dims=["value"]), + "rmse": np.sqrt(xr.DataArray(np.array([1, 2, 0, 0, 1./3]), coords={"value": [0, 1, 2, 3, 4]}, dims=["value"])), + "mae": xr.DataArray(np.array([1, 4./3, 0, 0, 1./3]), coords={"value": [0, 1, 2, 3, 4]}, dims=["value"]), + "n": xr.DataArray(np.array([3, 3, 3, 3, 3]), coords={"value": [0, 1, 2, 3, 4]}, dims=["value"])} + assert check_nested_equality(expected, calculate_error_metrics(x_array1, x_array2, "index")) is True + + expected = {"mse": xr.DataArray(np.array([1.2, 0.4, 0.4]), coords={"index": [0, 1, 2]}, dims=["index"]), + "rmse": np.sqrt(xr.DataArray(np.array([1.2, 0.4, 0.4]), coords={"index": [0, 1, 2]}, dims=["index"])), + "mae": xr.DataArray(np.array([0.8, 0.4, 0.4]), coords={"index": [0, 1, 2]}, dims=["index"]), + "n": xr.DataArray(np.array([5, 5, 5]), coords={"index": [0, 1, 2]}, dims=["index"])} + assert check_nested_equality(expected, calculate_error_metrics(x_array1, x_array2, "value")) is True + + + + # expected = xr.DataArray(np.array([1.2, 0.4, 0.4]), coords={"index": [0, 1, 2]}, dims=["index"]) + # assert xr.testing.assert_equal(mean_squared_error(x_array1, x_array2, "value"), expected) is None + # + # + # expected = xr.DataArray(np.array([0.8, 0.4, 0.4]), coords={"index": [0, 1, 2]}, dims=["index"]) + # assert xr.testing.assert_equal(mean_absolute_error(x_array1, x_array2, "value"), expected) is None \ No newline at end of file -- GitLab