From a2500f2edbc6c8e2a850787c384b07357a28b6c5 Mon Sep 17 00:00:00 2001
From: Le Roux Erwan <erwan.le-roux@irstea.fr>
Date: Mon, 22 Mar 2021 16:54:44 +0100
Subject: [PATCH] [projection swe] add test_ensemble_fit.py. start margin model
 with effect

---
 .../margin_model_with_effect/__init__.py      |  0
 .../abstract_margin_model_with_effect.py      |  5 ++
 .../margin_model_with_gcm_effect.py           | 11 +++
 .../gev_altitudinal_models.py                 | 19 -----
 .../visualizer_for_projection_ensemble.py     |  9 ++-
 .../results/main_projections_ensemble.py      |  6 +-
 test/test_extreme_trend/test_ensemble_fit.py  | 80 +++++++++++++++++++
 7 files changed, 104 insertions(+), 26 deletions(-)
 create mode 100644 extreme_fit/model/margin_model/linear_margin_model/margin_model_with_effect/__init__.py
 create mode 100644 extreme_fit/model/margin_model/linear_margin_model/margin_model_with_effect/abstract_margin_model_with_effect.py
 create mode 100644 extreme_fit/model/margin_model/linear_margin_model/margin_model_with_effect/margin_model_with_gcm_effect.py
 create mode 100644 test/test_extreme_trend/test_ensemble_fit.py

diff --git a/extreme_fit/model/margin_model/linear_margin_model/margin_model_with_effect/__init__.py b/extreme_fit/model/margin_model/linear_margin_model/margin_model_with_effect/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/extreme_fit/model/margin_model/linear_margin_model/margin_model_with_effect/abstract_margin_model_with_effect.py b/extreme_fit/model/margin_model/linear_margin_model/margin_model_with_effect/abstract_margin_model_with_effect.py
new file mode 100644
index 00000000..72552ac7
--- /dev/null
+++ b/extreme_fit/model/margin_model/linear_margin_model/margin_model_with_effect/abstract_margin_model_with_effect.py
@@ -0,0 +1,5 @@
+
+
+class AbstractMarginModelWithEffect(object):
+    pass
+
diff --git a/extreme_fit/model/margin_model/linear_margin_model/margin_model_with_effect/margin_model_with_gcm_effect.py b/extreme_fit/model/margin_model/linear_margin_model/margin_model_with_effect/margin_model_with_gcm_effect.py
new file mode 100644
index 00000000..79e53610
--- /dev/null
+++ b/extreme_fit/model/margin_model/linear_margin_model/margin_model_with_effect/margin_model_with_gcm_effect.py
@@ -0,0 +1,11 @@
+from extreme_fit.model.margin_model.linear_margin_model.margin_model_with_effect.abstract_margin_model_with_effect import \
+    AbstractMarginModelWithEffect
+from extreme_fit.model.margin_model.polynomial_margin_model.gev_altitudinal_models import StationaryAltitudinal
+
+
+class MarginModelWithGcmEffect(AbstractMarginModelWithEffect):
+    pass
+
+
+class StationaryAltitudinalWithGCMEffect(MarginModelWithGcmEffect, StationaryAltitudinal):
+    pass
diff --git a/extreme_fit/model/margin_model/polynomial_margin_model/gev_altitudinal_models.py b/extreme_fit/model/margin_model/polynomial_margin_model/gev_altitudinal_models.py
index 4ec8e209..57319c10 100644
--- a/extreme_fit/model/margin_model/polynomial_margin_model/gev_altitudinal_models.py
+++ b/extreme_fit/model/margin_model/polynomial_margin_model/gev_altitudinal_models.py
@@ -56,27 +56,8 @@ class AbstractAltitudinalModel(AbstractSpatioTemporalPolynomialModel):
             s = '0'
         else:
             s = ','.join(l)
-        # return '$ \\boldsymbol{ \\mathcal{M}_{%s} }$' % s
         return '$ \\boldsymbol{%s}$' % s
 
-
-    # @property
-    # def name_str(self):
-    #     name = ''
-    #     for coordinate_name, idx in zip(['s', 't'], [self.coordinates.idx_x_coordinates, self.coordinates.idx_temporal_coordinates]):
-    #         name += coordinate_name
-    #         for param_name in GevParams.PARAM_NAMES:
-    #             name += self.dim_to_str_number(param_name, idx)
-    #     if isinstance(self, AbstractAddCrossTerm):
-    #         name += 'sxt'
-    #         for c in [AbstractAddCrossTermForLocation, AbstractAddCrossTermForScale, AbstractAddCrossTermForShape]:
-    #             if isinstance(self, c):
-    #                 name += '1'
-    #             else:
-    #                 name += '0'
-    #     return name
-
-
 class StationaryAltitudinal(AbstractAltitudinalModel):
 
     @property
diff --git a/extreme_trend/ensemble_fit/visualizer_for_projection_ensemble.py b/extreme_trend/ensemble_fit/visualizer_for_projection_ensemble.py
index bf53041d..a75e81b0 100644
--- a/extreme_trend/ensemble_fit/visualizer_for_projection_ensemble.py
+++ b/extreme_trend/ensemble_fit/visualizer_for_projection_ensemble.py
@@ -156,10 +156,11 @@ class VisualizerForProjectionEnsemble(object):
         for ensemble_fit in self.ensemble_fits(IndependentEnsembleFit):
             for gcm_rcm_couple in self.gcm_rcm_couples:
                 visualizer = ensemble_fit.gcm_rcm_couple_to_visualizer[gcm_rcm_couple]
-                one_fold_fit = visualizer.massif_name_to_one_fold_fit[massif_name]
-                coef = one_fold_fit.best_coef(param_name, 0, degree)
-                altitude = visualizer.altitude_group.reference_altitude
-                gcm_rcm_couple_to_data[gcm_rcm_couple].append((altitude, coef))
+                if massif_name in visualizer.massif_name_to_one_fold_fit:
+                    one_fold_fit = visualizer.massif_name_to_one_fold_fit[massif_name]
+                    coef = one_fold_fit.best_coef(param_name, 0, degree)
+                    altitude = visualizer.altitude_group.reference_altitude
+                    gcm_rcm_couple_to_data[gcm_rcm_couple].append((altitude, coef))
         # Plot
         ax = plt.gca()
         for gcm_rcm_couple, data in gcm_rcm_couple_to_data.items():
diff --git a/projects/projected_extreme_snowfall/results/main_projections_ensemble.py b/projects/projected_extreme_snowfall/results/main_projections_ensemble.py
index 3de38f49..01b20911 100644
--- a/projects/projected_extreme_snowfall/results/main_projections_ensemble.py
+++ b/projects/projected_extreme_snowfall/results/main_projections_ensemble.py
@@ -41,7 +41,7 @@ def main():
     study_class = AdamontSnowfall
     ensemble_fit_classes = [IndependentEnsembleFit, TogetherEnsembleFit][1:]
     temporal_covariate_for_fit = [TimeTemporalCovariate,
-                                  AnomalyTemperatureWithSplineTemporalCovariate][0]
+                                  AnomalyTemperatureWithSplineTemporalCovariate][1]
     set_seed_for_test()
     AbstractExtractEurocodeReturnLevel.ALPHA_CONFIDENCE_INTERVAL_UNCERTAINTY = 0.2
 
@@ -61,8 +61,8 @@ def main():
             AbstractExtractEurocodeReturnLevel.NB_BOOTSTRAP = 10
             altitudes_list = altitudes_for_groups[:1]
         else:
-            massif_names = None
-            altitudes_list = altitudes_for_groups[:]
+            massif_names = ['Vanoise']
+            altitudes_list = altitudes_for_groups[3:]
 
         assert isinstance(gcm_rcm_couples, list)
 
diff --git a/test/test_extreme_trend/test_ensemble_fit.py b/test/test_extreme_trend/test_ensemble_fit.py
new file mode 100644
index 00000000..beab3a98
--- /dev/null
+++ b/test/test_extreme_trend/test_ensemble_fit.py
@@ -0,0 +1,80 @@
+import unittest
+
+from extreme_data.meteo_france_data.adamont_data.adamont.adamont_safran import AdamontSnowfall
+from extreme_data.meteo_france_data.adamont_data.adamont_scenario import AdamontScenario
+from extreme_data.meteo_france_data.scm_models_data.altitudes_studies import AltitudesStudies
+from extreme_fit.model.margin_model.linear_margin_model.margin_model_with_effect.margin_model_with_gcm_effect import \
+    StationaryAltitudinalWithGCMEffect
+from extreme_fit.model.margin_model.polynomial_margin_model.gev_altitudinal_models import StationaryAltitudinal
+from extreme_fit.model.margin_model.polynomial_margin_model.models_based_on_pariwise_analysis.gev_with_constant_shape_wrt_altitude import \
+    AltitudinalShapeConstantTimeLocationLinear, AltitudinalShapeConstantTimeScaleLinear, \
+    AltitudinalShapeConstantTimeLocScaleLinear
+from extreme_trend.ensemble_fit.together_ensemble_fit.together_ensemble_fit import TogetherEnsembleFit
+from spatio_temporal_dataset.coordinates.temporal_coordinates.abstract_temporal_covariate_for_fit import \
+    TimeTemporalCovariate
+from spatio_temporal_dataset.coordinates.temporal_coordinates.temperature_covariate import \
+    AnomalyTemperatureWithSplineTemporalCovariate
+
+
+class TestEnsembleFit(unittest.TestCase):
+
+    def setUp(self) -> None:
+        super().setUp()
+        self.altitudes = [1200, 1500, 1800]
+        self.massif_names = ["Vanoise"]
+        study_class = AdamontSnowfall
+        gcm_rcm_couples = [('CNRM-CM5', 'ALADIN53'), ('EC-EARTH', 'CCLM4-8-17')]
+        scenario = AdamontScenario.rcp85
+        self.gcm_rcm_couple_to_altitude_studies = {
+            c: AltitudesStudies(study_class, self.altitudes,
+                                gcm_rcm_couple=c, scenario=scenario) for c in gcm_rcm_couples
+        }
+
+    def test_basic_ensemble_together_fit(self):
+        model_classes = [StationaryAltitudinal,
+                         AltitudinalShapeConstantTimeLocationLinear,
+                         AltitudinalShapeConstantTimeScaleLinear,
+                         AltitudinalShapeConstantTimeLocScaleLinear
+                         ][:]
+
+        for temporal_covariate in [TimeTemporalCovariate,
+                                   AnomalyTemperatureWithSplineTemporalCovariate]:
+            ensemble_fit = TogetherEnsembleFit(massif_names=self.massif_names,
+                                               gcm_rcm_couple_to_altitude_studies=self.gcm_rcm_couple_to_altitude_studies,
+                                               models_classes=model_classes,
+                                               temporal_covariate_for_fit=temporal_covariate,
+                                               only_models_that_pass_goodness_of_fit_test=False)
+
+            _ = ensemble_fit.visualizer.massif_name_to_one_fold_fit[self.massif_names[0]].best_function_from_fit
+        self.assertTrue(True)
+
+    def test_ensembe_fit_with_effect(self):
+        model_classes = [StationaryAltitudinal,
+                         StationaryAltitudinalWithGCMEffect][:1]
+
+        for temporal_covariate in [TimeTemporalCovariate,
+                                   AnomalyTemperatureWithSplineTemporalCovariate]:
+            ensemble_fit = TogetherEnsembleFit(massif_names=self.massif_names,
+                                               gcm_rcm_couple_to_altitude_studies=self.gcm_rcm_couple_to_altitude_studies,
+                                               models_classes=model_classes,
+                                               temporal_covariate_for_fit=temporal_covariate,
+                                               only_models_that_pass_goodness_of_fit_test=False)
+
+            model_class_to_estimator = ensemble_fit.visualizer.massif_name_to_one_fold_fit[self.massif_names[0]].model_class_to_estimator
+            model_class_to_expected_number_params = {
+                StationaryAltitudinal: 5,
+                StationaryAltitudinalWithGCMEffect: 6,
+            }
+            for model_class in model_classes:
+                expected = model_class_to_expected_number_params[model_class]
+                found = model_class_to_estimator[model_class].margin_model.nb_params
+                self.assertEqual(expected, found)
+
+            # _ = ensemble_fit.visualizer.massif_name_to_one_fold_fit[self.massif_names[0]].best_function_from_fit
+
+
+        self.assertTrue(True)
+
+
+if __name__ == '__main__':
+    unittest.main()
-- 
GitLab