diff --git a/mlair/model_modules/convolutional_networks.py b/mlair/model_modules/convolutional_networks.py index be047eb7a1c92cbb8847328c157c874bfeca93ca..d8eb6eb3403db13932a51274fdc1f563dbfb6ef3 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 8536516e66cc1dda15972fd2e91d0ef67c70dda7..372473ee22b5174a3beca91898509a3582391587 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 59927e992d432207db5b5737289a6f4d671d92f3..6ec920c1cde08c0d2fc6064528eea800fbdde2a7 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 ff29bd213f21616443ac825e575f0efaa17eeace..8443b10d4d16b71819b795c0579b4d61cb739b70 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 f5148cdc293939d5711afb57c2fa009c47b6c86d..a3f645937258604c2dbbda07b36a58d83e879065 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