From e12131385081eafde68564eebc9f3b10aef7fc53 Mon Sep 17 00:00:00 2001
From: Le Roux Erwan <erwan.le-roux@irstea.fr>
Date: Thu, 18 Feb 2021 15:40:45 +0100
Subject: [PATCH] [projections] first version for abstract_ensemble_fit.py and
 independent_ensemble_fit.py Try to reuse the previous code as much as
 possible.

---
 .../visualization/study_visualizer.py         |   6 +
 .../altitudes_fit/altitudes_studies.py        |   2 +-
 .../ensemble_fit/abstract_ensemble_fit.py     |  25 +-
 .../ensemble_fit/independent_ensemble_fit.py  |  48 ++
 ...ation_temporal_for_projections_ensemble.py |  97 ++--
 .../utils_projected_visualizer.py             |  50 +-
 .../visualizer_for_projection_ensemble.py     | 520 +-----------------
 .../main_projected_trends_separately.py       |  95 ----
 8 files changed, 153 insertions(+), 690 deletions(-)
 delete mode 100644 projects/projected_snowfall/trends/main_projected_trends_separately.py

diff --git a/extreme_data/meteo_france_data/scm_models_data/visualization/study_visualizer.py b/extreme_data/meteo_france_data/scm_models_data/visualization/study_visualizer.py
index d7caa81a..71b0e606 100644
--- a/extreme_data/meteo_france_data/scm_models_data/visualization/study_visualizer.py
+++ b/extreme_data/meteo_france_data/scm_models_data/visualization/study_visualizer.py
@@ -13,6 +13,8 @@ import numpy as np
 import pandas as pd
 import seaborn as sns
 
+from extreme_data.meteo_france_data.adamont_data.abstract_adamont_study import AbstractAdamontStudy
+from extreme_data.meteo_france_data.adamont_data.adamont_scenario import gcm_rcm_couple_to_str
 from extreme_data.meteo_france_data.scm_models_data.visualization.plot_utils import load_plot
 from extreme_fit.estimator.margin_estimator.utils import fitted_stationary_gev
 from extreme_fit.model.margin_model.utils import fitmethod_to_str
@@ -541,6 +543,10 @@ class StudyVisualizer(VisualizationParameters):
 
     def show_or_save_to_file(self, add_classic_title=True, no_title=False, tight_layout=False, tight_pad=None,
                              dpi=None, folder_for_variable=True):
+        if isinstance(self.study, AbstractAdamontStudy):
+            prefix = gcm_rcm_couple_to_str(self.study.gcm_rcm_couple)
+            self.plot_name = prefix + ' ' + self.plot_name
+
         assert self.plot_name is not None
         if add_classic_title:
             title = self.study.title
diff --git a/projects/altitude_spatial_model/altitudes_fit/altitudes_studies.py b/projects/altitude_spatial_model/altitudes_fit/altitudes_studies.py
index b0566196..e5162707 100644
--- a/projects/altitude_spatial_model/altitudes_fit/altitudes_studies.py
+++ b/projects/altitude_spatial_model/altitudes_fit/altitudes_studies.py
@@ -5,7 +5,7 @@ from collections import OrderedDict
 from cached_property import cached_property
 
 from extreme_data.meteo_france_data.adamont_data.abstract_adamont_study import AbstractAdamontStudy
-from extreme_data.meteo_france_data.adamont_data.adamont_scenario import scenario_to_str
+from extreme_data.meteo_france_data.adamont_data.adamont_scenario import scenario_to_str, gcm_rcm_couple_to_str
 from extreme_data.meteo_france_data.scm_models_data.abstract_study import AbstractStudy
 from extreme_data.meteo_france_data.scm_models_data.visualization.main_study_visualizer import \
     SCM_STUDY_CLASS_TO_ABBREVIATION, STUDY_CLASS_TO_ABBREVIATION
diff --git a/projects/projected_snowfall/elevation_temporal_model_for_projections/ensemble_fit/abstract_ensemble_fit.py b/projects/projected_snowfall/elevation_temporal_model_for_projections/ensemble_fit/abstract_ensemble_fit.py
index d2c9cf65..b3783021 100644
--- a/projects/projected_snowfall/elevation_temporal_model_for_projections/ensemble_fit/abstract_ensemble_fit.py
+++ b/projects/projected_snowfall/elevation_temporal_model_for_projections/ensemble_fit/abstract_ensemble_fit.py
@@ -1,4 +1,27 @@
+from typing import Dict, Tuple, List
+
+from extreme_fit.model.margin_model.utils import MarginFitMethod
+from projects.altitude_spatial_model.altitudes_fit.altitudes_studies import AltitudesStudies
+from projects.altitude_spatial_model.altitudes_fit.one_fold_analysis.altitude_group import DefaultAltitudeGroup
 
 
 class AbstractEnsembleFit(object):
-    pass
\ No newline at end of file
+
+    def __init__(self, massif_names, gcm_rcm_couple_to_altitude_studies: Dict[Tuple[str, str], AltitudesStudies],
+                 models_classes,
+                 fit_method=MarginFitMethod.extremes_fevd_mle,
+                 temporal_covariate_for_fit=None,
+                 only_models_that_pass_goodness_of_fit_test=True,
+                 confidence_interval_based_on_delta_method=False,
+                 ):
+        self.massif_names = massif_names
+        self.models_classes = models_classes
+        self.gcm_rcm_couple_to_altitude_studies = gcm_rcm_couple_to_altitude_studies
+        self.fit_method = fit_method
+        self.temporal_covariate_for_fit = temporal_covariate_for_fit
+        self.only_models_that_pass_goodness_of_fit_test = only_models_that_pass_goodness_of_fit_test
+        self.confidence_interval_based_on_delta_method = confidence_interval_based_on_delta_method
+
+
+    def plot(self):
+        raise NotImplementedError
\ No newline at end of file
diff --git a/projects/projected_snowfall/elevation_temporal_model_for_projections/ensemble_fit/independent_ensemble_fit.py b/projects/projected_snowfall/elevation_temporal_model_for_projections/ensemble_fit/independent_ensemble_fit.py
index e69de29b..9de456cc 100644
--- a/projects/projected_snowfall/elevation_temporal_model_for_projections/ensemble_fit/independent_ensemble_fit.py
+++ b/projects/projected_snowfall/elevation_temporal_model_for_projections/ensemble_fit/independent_ensemble_fit.py
@@ -0,0 +1,48 @@
+from typing import Dict, Tuple, List
+
+from extreme_fit.model.margin_model.utils import MarginFitMethod
+from projects.altitude_spatial_model.altitudes_fit.altitudes_studies import AltitudesStudies
+from projects.altitude_spatial_model.altitudes_fit.one_fold_analysis.altitude_group import DefaultAltitudeGroup
+from projects.altitude_spatial_model.altitudes_fit.one_fold_analysis.altitudes_studies_visualizer_for_non_stationary_models import \
+    AltitudesStudiesVisualizerForNonStationaryModels
+from projects.altitude_spatial_model.altitudes_fit.one_fold_analysis.one_fold_fit import OneFoldFit
+from projects.altitude_spatial_model.altitudes_fit.utils_altitude_studies_visualizer import compute_and_assign_max_abs
+from projects.projected_snowfall.elevation_temporal_model_for_projections.ensemble_fit.abstract_ensemble_fit import \
+    AbstractEnsembleFit
+
+
+class IndependentEnsembleFit(AbstractEnsembleFit):
+    """For each gcm_rcm_couple, we create a OneFoldFit"""
+
+    def __init__(self, massif_names, gcm_rcm_couple_to_altitude_studies: Dict[Tuple[str, str], AltitudesStudies], models_classes,
+                 fit_method=MarginFitMethod.extremes_fevd_mle, temporal_covariate_for_fit=None, only_models_that_pass_goodness_of_fit_test=True,
+                 confidence_interval_based_on_delta_method=False):
+        super().__init__(massif_names, gcm_rcm_couple_to_altitude_studies, models_classes, fit_method, temporal_covariate_for_fit, only_models_that_pass_goodness_of_fit_test,
+                         confidence_interval_based_on_delta_method)
+
+        # Load a classical visualizer
+        self.gcm_rcm_couple_to_visualizer = {}
+        for gcm_rcm_couple, studies in gcm_rcm_couple_to_altitude_studies.items():
+            visualizer = AltitudesStudiesVisualizerForNonStationaryModels(studies, self.models_classes,
+                                                                          False,
+                                                                          self.massif_names, self.fit_method,
+                                                                          self.temporal_covariate_for_fit,
+                                                                          self.only_models_that_pass_goodness_of_fit_test,
+                                                                          self.confidence_interval_based_on_delta_method)
+            self.gcm_rcm_couple_to_visualizer[gcm_rcm_couple] = visualizer
+
+        # Assign max
+        visualizer_list = list(self.gcm_rcm_couple_to_visualizer.values())
+        compute_and_assign_max_abs(visualizer_list)
+
+    def plot(self):
+        for v in self.gcm_rcm_couple_to_visualizer.values():
+            self.plot_one_visualizer(v)
+
+    @staticmethod
+    def plot_one_visualizer(visualizer):
+        # visualizer.studies.plot_maxima_time_series(['Vanoise'])
+        visualizer.plot_shape_map()
+        visualizer.plot_moments()
+        # visualizer.plot_qqplots()
+
diff --git a/projects/projected_snowfall/elevation_temporal_model_for_projections/main_elevation_temporal_for_projections_ensemble.py b/projects/projected_snowfall/elevation_temporal_model_for_projections/main_elevation_temporal_for_projections_ensemble.py
index f3f05a46..33baed2b 100644
--- a/projects/projected_snowfall/elevation_temporal_model_for_projections/main_elevation_temporal_for_projections_ensemble.py
+++ b/projects/projected_snowfall/elevation_temporal_model_for_projections/main_elevation_temporal_for_projections_ensemble.py
@@ -2,12 +2,25 @@ import datetime
 import time
 from typing import List
 
+import matplotlib as mpl
+
+
+mpl.rcParams['text.usetex'] = True
+mpl.rcParams['text.latex.preamble'] = [r'\usepackage{amsmath}']
+
 import matplotlib
+from extreme_fit.model.utils import set_seed_for_test
 
+from extreme_data.meteo_france_data.adamont_data.adamont.adamont_snowfall import AdamontSnowfall
+from extreme_data.meteo_france_data.adamont_data.adamont_scenario import AdamontScenario, get_gcm_rcm_couples
+from projects.projected_snowfall.elevation_temporal_model_for_projections.ensemble_fit.independent_ensemble_fit import \
+    IndependentEnsembleFit
 from projects.projected_snowfall.elevation_temporal_model_for_projections.utils_projected_visualizer import \
     load_projected_visualizer_list
 from projects.projected_snowfall.elevation_temporal_model_for_projections.visualizer_for_projection_ensemble import \
     VisualizerForProjectionEnsemble
+from spatio_temporal_dataset.coordinates.temporal_coordinates.abstract_temporal_covariate_for_fit import \
+    AnomalyTemperatureTemporalCovariate
 
 matplotlib.use('Agg')
 
@@ -17,96 +30,60 @@ from projects.altitude_spatial_model.altitudes_fit.plots.plot_histogram_altitude
 from extreme_fit.model.result_from_model_fit.result_from_extremes.abstract_extract_eurocode_return_level import \
     AbstractExtractEurocodeReturnLevel
 
-import matplotlib as mpl
 
-from extreme_fit.model.utils import set_seed_for_test
-
-mpl.rcParams['text.usetex'] = True
-mpl.rcParams['text.latex.preamble'] = [r'\usepackage{amsmath}']
 
 from projects.altitude_spatial_model.altitudes_fit.one_fold_analysis.altitude_group import altitudes_for_groups
 
-from extreme_data.meteo_france_data.scm_models_data.safran.safran import SafranSnowfall1Day, SafranSnowfall3Days, \
-    SafranSnowfall5Days, SafranSnowfall7Days
 from extreme_data.meteo_france_data.scm_models_data.utils import Season
 
 
 def main():
-    study_classes = [SafranSnowfall1Day
-                        , SafranSnowfall3Days,
-                     SafranSnowfall5Days, SafranSnowfall7Days][:1]
-    seasons = [Season.annual, Season.winter, Season.spring, Season.automn][:1]
-
+    study_classes = [AdamontSnowfall][:1]
+    scenario = AdamontScenario.rcp85
+    gcm_rcm_couples = get_gcm_rcm_couples(scenario)[:2]
+    ensemble_fit_class = [IndependentEnsembleFit]
+    temporal_covariate_for_fit = [None, AnomalyTemperatureTemporalCovariate][0]
     set_seed_for_test()
-    model_must_pass_the_test = False
     AbstractExtractEurocodeReturnLevel.ALPHA_CONFIDENCE_INTERVAL_UNCERTAINTY = 0.2
 
-    fast = False
+    fast = True
     if fast is None:
         massif_names = None
         AbstractExtractEurocodeReturnLevel.NB_BOOTSTRAP = 10
         altitudes_list = altitudes_for_groups[2:3]
     elif fast:
         AbstractExtractEurocodeReturnLevel.NB_BOOTSTRAP = 10
-        massif_names = ['Vanoise', 'Haute-Maurienne', 'Vercors'][:1]
+        massif_names = ['Vanoise'][:]
         altitudes_list = altitudes_for_groups[1:2]
     else:
         massif_names = None
         altitudes_list = altitudes_for_groups[:]
 
     start = time.time()
-    main_loop(altitudes_list, massif_names, seasons, study_classes, model_must_pass_the_test)
+    main_loop(gcm_rcm_couples, altitudes_list, massif_names, study_classes, ensemble_fit_class, scenario, temporal_covariate_for_fit)
     end = time.time()
     duration = str(datetime.timedelta(seconds=end - start))
     print('Total duration', duration)
 
 
-def main_loop(altitudes_list, massif_names, seasons, study_classes, model_must_pass_the_test):
+def main_loop(gcm_rcm_couples, altitudes_list, massif_names, study_classes, ensemble_fit_classes, scenario, temporal_covariate_for_fit):
     assert isinstance(altitudes_list, List)
     assert isinstance(altitudes_list[0], List)
-    for season in seasons:
-        for study_class in study_classes:
-            print('Inner loop', season, study_class)
-            visualizer_list = load_projected_visualizer_list(season, study_class, altitudes_list, massif_names,
-                                                             model_must_pass_the_test
-                                                             )
-            plot_visualizers(massif_names, visualizer_list)
-            for visualizer in visualizer_list:
-                plot_visualizer(massif_names, visualizer)
-            del visualizer_list
-            time.sleep(2)
-
-
-def plot_visualizers(massif_names, visualizer_list):
-    # plot_histogram_all_models_against_altitudes(massif_names, visualizer_list)
-    plot_histogram_all_trends_against_altitudes(massif_names, visualizer_list)
-    # plot_shoe_plot_ratio_interval_size_against_altitude(massif_names, visualizer_list)
-    for relative in [True, False]:
-        plot_shoe_plot_changes_against_altitude(massif_names, visualizer_list, relative=relative)
-    # plot_coherence_curves(massif_names, visualizer_list)
-    # plot_coherence_curves(['Vanoise'], visualizer_list)
-    pass
-
-
-def plot_visualizer(massif_names, visualizer):
-    # Plot time series
-    # visualizer.studies.plot_maxima_time_series(massif_names)
-    # visualizer.studies.plot_maxima_time_series(['Vanoise'])
-
-    # Plot the results for the model that minimizes the individual aic
-    plots(visualizer)
-
-    # Plot the results for the model that minimizes the total aic
-    # plot_total_aic(model_classes, visualizer)
-    pass
-
-
-def plots(visualizer: VisualizerForProjectionEnsemble):
-    # visualizer.plot_shape_map()
-    visualizer.plot_moments()
-    # visualizer.plot_qqplots()
-    # for std in [True, False]:
-    #     visualizer.studies.plot_mean_maxima_against_altitude(std=std)
+    for study_class in study_classes:
+        print('Inner loop', study_class)
+        visualizer_list = load_projected_visualizer_list(gcm_rcm_couples=gcm_rcm_couples, ensemble_fit_classes=ensemble_fit_classes,
+                                                         season=Season.annual, study_class=study_class,
+                                                         altitudes_list=altitudes_list, massif_names=massif_names,
+                                                         scenario=scenario,
+                                                         temporal_covariate_for_fit=temporal_covariate_for_fit)
+        for v in visualizer_list:
+            v.plot()
+
+        del visualizer_list
+        time.sleep(2)
+
+
+
 
 
 if __name__ == '__main__':
diff --git a/projects/projected_snowfall/elevation_temporal_model_for_projections/utils_projected_visualizer.py b/projects/projected_snowfall/elevation_temporal_model_for_projections/utils_projected_visualizer.py
index f3bd8d95..a7f70c95 100644
--- a/projects/projected_snowfall/elevation_temporal_model_for_projections/utils_projected_visualizer.py
+++ b/projects/projected_snowfall/elevation_temporal_model_for_projections/utils_projected_visualizer.py
@@ -1,44 +1,38 @@
+from extreme_data.meteo_france_data.adamont_data.adamont_scenario import AdamontScenario, rcp_scenarios
 from extreme_fit.model.margin_model.polynomial_margin_model.utils import \
     ALTITUDINAL_GEV_MODELS_BASED_ON_POINTWISE_ANALYSIS
 from projects.altitude_spatial_model.altitudes_fit.altitudes_studies import AltitudesStudies
 from projects.altitude_spatial_model.altitudes_fit.one_fold_analysis.altitudes_studies_visualizer_for_non_stationary_models import \
     AltitudesStudiesVisualizerForNonStationaryModels
+from projects.projected_snowfall.elevation_temporal_model_for_projections.visualizer_for_projection_ensemble import \
+    VisualizerForProjectionEnsemble
 
 
-def load_projected_visualizer_list(season, study_class, altitudes_list, massif_names, model_must_pass_the_test=True, **kwargs_study):
+def load_projected_visualizer_list(gcm_rcm_couples, ensemble_fit_classes,
+                                   season, study_class, altitudes_list, massif_names, model_must_pass_the_test=False,
+                                   scenario=AdamontScenario.rcp85,
+                                   temporal_covariate_for_fit=None, **kwargs_study):
     model_classes = ALTITUDINAL_GEV_MODELS_BASED_ON_POINTWISE_ANALYSIS
+    assert scenario in rcp_scenarios
     visualizer_list = []
     # Load all studies
     for altitudes in altitudes_list:
-        studies = AltitudesStudies(study_class, altitudes, season=season, **kwargs_study)
-        visualizer = AltitudesStudiesVisualizerForNonStationaryModels(studies=studies,
-                                                                      model_classes=model_classes,
-                                                                      massif_names=massif_names,
-                                                                      show=False,
-                                                                      temporal_covariate_for_fit=None,
-                                                                      confidence_interval_based_on_delta_method=False,
-                                                                      display_only_model_that_pass_anderson_test=model_must_pass_the_test
-                                                                      )
+        gcm_rcm_couple_to_altitude_studies = {}
+        for gcm_rcm_couple in gcm_rcm_couples:
+            studies = AltitudesStudies(study_class, altitudes, season=season,
+                                       scenario=scenario, gcm_rcm_couple=gcm_rcm_couple, **kwargs_study)
+            gcm_rcm_couple_to_altitude_studies[gcm_rcm_couple] = studies
+        visualizer = VisualizerForProjectionEnsemble(gcm_rcm_couple_to_altitude_studies=gcm_rcm_couple_to_altitude_studies,
+                                                     model_classes=model_classes,
+                                                     ensemble_fit_classes=ensemble_fit_classes,
+                                                     massif_names=massif_names,
+                                                     show=False,
+                                                     temporal_covariate_for_fit=temporal_covariate_for_fit,
+                                                     confidence_interval_based_on_delta_method=False,
+                                                     display_only_model_that_pass_gof_test=model_must_pass_the_test
+                                                     )
         visualizer_list.append(visualizer)
-    compute_and_assign_max_abs(visualizer_list)
 
     return visualizer_list
 
 
-def compute_and_assign_max_abs(visualizer_list):
-    # Compute the max abs for all metrics
-    d = {}
-    for method_name in AltitudesStudiesVisualizerForNonStationaryModels.moment_names:
-        for order in AltitudesStudiesVisualizerForNonStationaryModels.orders:
-            c = (method_name, order)
-            max_abs = max([
-                max([abs(e) for e in v.method_name_and_order_to_d(method_name, order).values()
-                     ]) for v in visualizer_list])
-            d[c] = max_abs
-    # Assign the max abs dictionary
-    for v in visualizer_list:
-        v._method_name_and_order_to_max_abs = d
-    # Compute the max abs for the shape parameter
-    max_abs_for_shape = max([max([abs(e) for e in v.massif_name_to_shape.values()]) for v in visualizer_list])
-    for v in visualizer_list:
-        v._max_abs_for_shape = max_abs_for_shape
diff --git a/projects/projected_snowfall/elevation_temporal_model_for_projections/visualizer_for_projection_ensemble.py b/projects/projected_snowfall/elevation_temporal_model_for_projections/visualizer_for_projection_ensemble.py
index a88cc1a9..86ffe406 100644
--- a/projects/projected_snowfall/elevation_temporal_model_for_projections/visualizer_for_projection_ensemble.py
+++ b/projects/projected_snowfall/elevation_temporal_model_for_projections/visualizer_for_projection_ensemble.py
@@ -33,7 +33,7 @@ from spatio_temporal_dataset.dataset.abstract_dataset import AbstractDataset
 
 class VisualizerForProjectionEnsemble(StudyVisualizer):
 
-    def __init__(self, gcm_rcm_couple_to_altitude_studies: Dict[str,AltitudesStudies],
+    def __init__(self, gcm_rcm_couple_to_altitude_studies: Dict[str, AltitudesStudies],
                  model_classes: List[AbstractSpatioTemporalPolynomialModel],
                  show=False,
                  ensemble_fit_classes=None,
@@ -46,513 +46,23 @@ class VisualizerForProjectionEnsemble(StudyVisualizer):
         studies = list(gcm_rcm_couple_to_altitude_studies.values())[0]
         study = studies.study
         super().__init__(study, show=show, save_to_file=not show)
-        self.ensemble_fit_classes = ensemble_fit_classes
-        self.gcm_rcm_couple_to_altitude_studies = gcm_rcm_couple_to_altitude_studies
-        self.non_stationary_models = model_classes
-        self.fit_method = fit_method
-        self.temporal_covariate_for_fit = temporal_covariate_for_fit
-        self.display_only_model_that_pass_test = display_only_model_that_pass_gof_test
-        self.massif_names = massif_names if massif_names is not None else study.all_massif_names()
-        self.massif_name_to_massif_id = {m: i for i, m in enumerate(self.massif_names)}
-        self.altitude_group = get_altitude_group_from_altitudes(studies.altitudes)
-        self.confidence_interval_based_on_delta_method = confidence_interval_based_on_delta_method
-
-        # Load ensemble_fit mapper
-        ensemble_fit_class_to_object = {}
-        for ensemble_fit_class in ensemble_fit_classes:
-            pass
-
         # Load one fold fit
         self.massif_name_to_massif_altitudes = {}
-        self._massif_name_to_one_fold_fit = {}
-        for massif_name in self.massif_names:
-            # Load valid massif altitudes
-            massif_altitudes = self.get_massif_altitudes(massif_name)
-            if self.load_condition(massif_altitudes):
-                # Save the massif altitudes only for those who pass the condition
-                self.massif_name_to_massif_altitudes[massif_name] = massif_altitudes
-                # Load dataset
-                dataset = studies.spatio_temporal_dataset(massif_name=massif_name, massif_altitudes=massif_altitudes)
-                old_fold_fit = OneFoldFit(massif_name, dataset, model_classes, self.fit_method,
-                                          self.temporal_covariate_for_fit,
-                                          type(self.altitude_group),
-                                          self.display_only_model_that_pass_test,
-                                          self.confidence_interval_based_on_delta_method)
-                self._massif_name_to_one_fold_fit[massif_name] = old_fold_fit
-        # Print number of massif without any validated fit
-        massifs_without_any_validated_fit = [massif_name
-                                             for massif_name, old_fold_fit in self._massif_name_to_one_fold_fit.items()
-                                             if not old_fold_fit.has_at_least_one_valid_model]
-        print('Not validated:', len(massifs_without_any_validated_fit), massifs_without_any_validated_fit)
-        # Cache
-        self._method_name_and_order_to_massif_name_to_value = {}
-        self._method_name_and_order_to_max_abs = {}
-        self._max_abs_for_shape = None
-
-    moment_names = ['moment', 'changes_of_moment', 'relative_changes_of_moment'][:]
-    orders = [1, 2, None][2:]
-
-    def get_massif_altitudes(self, massif_name):
-        valid_altitudes = [altitude for altitude, study in self.studies.altitude_to_study.items()
-                           if massif_name in study.study_massif_names]
-        massif_altitudes = []
-        for altitude in valid_altitudes:
-            study = self.studies.altitude_to_study[altitude]
-            annual_maxima = study.massif_name_to_annual_maxima[massif_name]
-            percentage_of_non_zeros = 100 * np.count_nonzero(annual_maxima) / len(annual_maxima)
-            if percentage_of_non_zeros > 90:
-                massif_altitudes.append(altitude)
-            # else:
-            #     print(massif_name, altitude, percentage_of_non_zeros)
-        return massif_altitudes
-
-    def load_condition(self, massif_altitudes):
-        # At least two altitudes for the estimated
-        # reference_altitude_is_in_altitudes = (self.altitude_group.reference_altitude in massif_altitudes)
-        at_least_two_altitudes = (len(massif_altitudes) >= 2)
-        # return reference_altitude_is_in_altitudes and at_least_two_altitudes
-        return at_least_two_altitudes
-
-    @property
-    def massif_name_to_one_fold_fit(self) -> Dict[str, OneFoldFit]:
-        return {massif_name: old_fold_fit for massif_name, old_fold_fit in self._massif_name_to_one_fold_fit.items()
-                if not self.display_only_model_that_pass_test
-                or old_fold_fit.has_at_least_one_valid_model}
-
-    def plot_moments(self):
-        for method_name in self.moment_names[:2]:
-            for order in self.orders:
-                # self.plot_against_years(method_name, order)
-                self.plot_map_moment(method_name, order)
-
-    def method_name_and_order_to_max_abs(self, method_name, order):
-        c = (method_name, order)
-        if c not in self._method_name_and_order_to_max_abs:
-            return None
-        else:
-            return self._method_name_and_order_to_max_abs[c]
-
-    def method_name_and_order_to_d(self, method_name, order):
-        c = (method_name, order)
-        if c not in self._method_name_and_order_to_massif_name_to_value:
-            # Compute values
-            massif_name_to_value = {}
-            for massif_name, one_fold_fit in self.massif_name_to_one_fold_fit.items():
-                value = \
-                    one_fold_fit.__getattribute__(method_name)([self.altitude_group.reference_altitude], order=order)[0]
-                massif_name_to_value[massif_name] = value
-            # Remove values
-            if any([np.isinf(v) for v in massif_name_to_value.values()]):
-                print("shape to large > 0.5, thus removing std that are infinite")
-            massif_name_to_value = {m: v for m, v in massif_name_to_value.items()
-                                    if not np.isinf(v)}
-            # Store it
-            self._method_name_and_order_to_massif_name_to_value[c] = massif_name_to_value
-        return self._method_name_and_order_to_massif_name_to_value[c]
-
-    def ratio_groups(self):
-        return [self.ratio_uncertainty_interval_size(altitude, 2019) for altitude in self.studies.altitudes]
-
-    def ratio_uncertainty_interval_size(self, altitude, year):
-        study = self.studies.altitude_to_study[altitude]
-        massif_name_to_interval = study.massif_name_to_stationary_gev_params_and_confidence(OneFoldFit.quantile_level,
-                                                                                            self.confidence_interval_based_on_delta_method)[
-            1]
-        massif_names_with_pointwise_interval = set(massif_name_to_interval)
-        valid_massif_names = set(self.massif_name_to_one_fold_fit.keys())
-        intersection_massif_names = valid_massif_names.intersection(massif_names_with_pointwise_interval)
-        ratios = []
-        for massif_name in intersection_massif_names:
-            one_fold_fit = self.massif_name_to_one_fold_fit[massif_name]
-            new_interval_size = one_fold_fit.best_confidence_interval(altitude, year).interval_size
-            old_interval_size = massif_name_to_interval[massif_name].interval_size
-            ratio = new_interval_size / old_interval_size
-            ratios.append(ratio)
-        return ratios
-
-    def plot_map_moment(self, method_name, order):
-        massif_name_to_value = self.method_name_and_order_to_d(method_name, order)
-        # Plot settings
-        moment = ' '.join(method_name.split('_'))
-        str_for_last_year = ' in 2019'
-        moment = moment.replace('moment', '{}{}'.format(OneFoldFit.get_moment_str(order=order), str_for_last_year))
-        plot_name = '{}{} '.format(OneFoldFit.folder_for_plots, moment)
-
-
-        if 'change' in method_name:
-            plot_name = plot_name.replace(str_for_last_year, '')
-            plot_name += ' between {} and {}'.format(2019 - OneFoldFit.nb_years, 2019)
-            if 'relative' not in method_name:
-                # Put the relative score as text on the plot for the change.
-                massif_name_to_text = {m: ('+' if v > 0 else '') + str(int(v)) + '\%' for m, v in
-                                       self.method_name_and_order_to_d(self.moment_names[2], order).items()}
-
-        parenthesis = self.study.variable_unit if 'relative' not in method_name else '\%'
-        ylabel = '{} ({})'.format(plot_name, parenthesis)
-
-        max_abs_change = self.method_name_and_order_to_max_abs(method_name, order)
-        add_colorbar = self.add_colorbar
-
-        is_return_level_plot = (self.moment_names.index(method_name) == 0) and (order is None)
-        if is_return_level_plot:
-
-            cmap = plt.cm.Spectral
-            cmap = remove_the_extreme_colors(cmap, epsilon=0.25)
-            cmap = get_inverse_colormap(cmap)
-            add_colorbar = True
-            max_abs_change = None
-            massif_name_to_text = {m: round(v) for m, v in massif_name_to_value.items()}
-            graduation = self.altitude_group.graduation_for_return_level
-            fontsize_label = 17
-        else:
-            # cmap = plt.cm.RdYlGn
-            cmap = [plt.cm.coolwarm, plt.cm.bwr, plt.cm.seismic][1]
-            # cmap = get_inverse_colormap(cmap)
-            # cmap = get_cmap_with_inverted_blue_and_green_channels(cmap)
-            cmap = remove_the_extreme_colors(cmap)
-            graduation = 10
-            fontsize_label = 10
-
-        negative_and_positive_values = self.moment_names.index(method_name) > 0
-        # Plot the map
-
-        self.plot_map(cmap=cmap, graduation=graduation,
-                      label=ylabel, massif_name_to_value=massif_name_to_value,
-                      plot_name=plot_name, add_x_label=True,
-                      negative_and_positive_values=negative_and_positive_values,
-                      altitude=self.altitude_group.reference_altitude,
-                      add_colorbar=add_colorbar,
-                      max_abs_change=max_abs_change,
-                      massif_name_to_text=massif_name_to_text,
-                      xlabel=self.altitude_group.xlabel,
-                      fontsize_label=fontsize_label,
-                      )
-
-
-    @property
-    def add_colorbar(self):
-        # return isinstance(self.altitude_group, (VeyHighAltitudeGroup))
-        return isinstance(self.altitude_group, (VeyHighAltitudeGroup, MidAltitudeGroup))
-
-    def plot_against_years(self, method_name, order):
-        ax = plt.gca()
-        min_altitude, *_, max_altitude = self.studies.altitudes
-        altitudes_plot = np.linspace(min_altitude, max_altitude, num=50)
-        for massif_name, one_fold_fit in self.massif_name_to_one_fold_fit.items():
-            massif_altitudes = self.studies.massif_name_to_altitudes[massif_name]
-            ind = (min(massif_altitudes) <= altitudes_plot) & (altitudes_plot <= max(massif_altitudes))
-            massif_altitudes_plot = altitudes_plot[ind]
-            values = one_fold_fit.__getattribute__(method_name)(massif_altitudes_plot, order=order)
-            massif_id = self.massif_name_to_massif_id[massif_name]
-            plot_against_altitude(massif_altitudes_plot, ax, massif_id, massif_name, values)
-        # Plot settings
-        ax.legend(prop={'size': 7}, ncol=3)
-        moment = ' '.join(method_name.split('_'))
-        moment = moment.replace('moment', '{} in 2019'.format(OneFoldFit.get_moment_str(order=order)))
-        plot_name = '{}Model {} annual maxima of {}'.format(OneFoldFit.folder_for_plots, moment,
-                                                            SCM_STUDY_CLASS_TO_ABBREVIATION[self.studies.study_class])
-        ax.set_ylabel('{} ({})'.format(plot_name, self.study.variable_unit), fontsize=15)
-        ax.set_xlabel('altitudes', fontsize=15)
-        ax.tick_params(axis='both', which='major', labelsize=13)
-        self.studies.show_or_save_to_file(plot_name=plot_name, show=self.show, no_title=True)
-        ax.clear()
-
-    # def plot_abstract_fast(self, massif_name_to_value, label, graduation=10.0, cmap=plt.cm.coolwarm, add_x_label=True,
-    #                        negative_and_positive_values=True, massif_name_to_text=None):
-    #     plot_name = '{}{}'.format(OneFoldFit.folder_for_plots, label)
-    #     self.plot_map(cmap, self.fit_method, graduation, label, massif_name_to_value, plot_name, add_x_label,
-    #                   negative_and_positive_values,
-    #                   massif_name_to_text)
-
-    @property
-    def massif_name_to_shape(self):
-        return {massif_name: one_fold_fit.best_shape
-                for massif_name, one_fold_fit in self.massif_name_to_one_fold_fit.items()}
-
-    @property
-    def massif_name_to_best_name(self):
-        return {massif_name: one_fold_fit.best_name
-                for massif_name, one_fold_fit in self.massif_name_to_one_fold_fit.items()}
-
-    def plot_best_coef_maps(self):
-        for param_name in GevParams.PARAM_NAMES:
-            coordinate_names = [AbstractCoordinates.COORDINATE_X, AbstractCoordinates.COORDINATE_T]
-            dim_to_coordinate_name = dict(zip([0, 1], coordinate_names))
-            for dim in [0, 1, (0, 1)]:
-                coordinate_name = LinearCoef.coefficient_name(dim, dim_to_coordinate_name)
-                for degree in range(4):
-                    coef_name = ' '.join([param_name + coordinate_name + str(degree)])
-                    massif_name_to_best_coef = {}
-                    for massif_name, one_fold_fit in self.massif_name_to_one_fold_fit.items():
-                        best_coef = one_fold_fit.best_coef(param_name, dim, degree)
-                        if best_coef is not None:
-                            massif_name_to_best_coef[massif_name] = best_coef
-
-                    if len(massif_name_to_best_coef) > 0:
-                        for evaluate_coordinate in [False, True][:1]:
-                            if evaluate_coordinate:
-                                coef_name += 'evaluated at coordinates'
-                                for massif_name in massif_name_to_best_coef.keys():
-                                    if AbstractCoordinates.COORDINATE_X in coordinate_name:
-                                        massif_name_to_best_coef[massif_name] *= np.power(1000, degree)
-                                    if AbstractCoordinates.COORDINATE_T in coordinate_name:
-                                        massif_name_to_best_coef[massif_name] *= np.power(2019, degree)
-                            self.plot_best_coef_map(coef_name.replace('_', ''), massif_name_to_best_coef)
-
-    def plot_best_coef_map(self, coef_name, massif_name_to_best_coef):
-        values = list(massif_name_to_best_coef.values())
-        graduation = (max(values) - min(values)) / 6
-        print(coef_name, graduation, max(values), min(values))
-        negative_and_positive_values = (max(values) > 0) and (min(values) < 0)
-        raise NotImplementedError
-        self.plot_map(massif_name_to_value=massif_name_to_best_coef,
-                      label='{}Coef/{} plot for {} {}'.format(OneFoldFit.folder_for_plots,
-                                                              coef_name,
-                                                              SCM_STUDY_CLASS_TO_ABBREVIATION[
-                                                                  type(self.study)],
-                                                              self.study.variable_unit),
-                      add_x_label=False, graduation=graduation, massif_name_to_text=self.massif_name_to_best_name,
-                      negative_and_positive_values=negative_and_positive_values)
-
-    def plot_shape_map(self):
+        self.ensemble_class_to_ensemble_fit = {}
+        for ensemble_fit_class in ensemble_fit_classes:
+            ensemble_fit = ensemble_fit_class(massif_names, gcm_rcm_couple_to_altitude_studies, model_classes,
+                                              fit_method, temporal_covariate_for_fit,
+                                              display_only_model_that_pass_gof_test,
+                                              confidence_interval_based_on_delta_method)
+            self.ensemble_class_to_ensemble_fit[ensemble_fit_class] = ensemble_fit
 
-        label = 'Shape parameter in 2019 (no unit)'
-        max_abs_change = self._max_abs_for_shape + 0.05
-        self.plot_map(massif_name_to_value=self.massif_name_to_shape,
-                      label=label,
-                      plot_name=label,
-                      fontsize_label=15,
-                      add_x_label=True, graduation=0.1,
-                      massif_name_to_text=self.massif_name_to_best_name,
-                      cmap=matplotlib.cm.get_cmap('BrBG_r'),
-                      altitude=self.altitude_group.reference_altitude,
-                      add_colorbar=self.add_colorbar,
-                      max_abs_change=max_abs_change,
-                      xlabel=self.altitude_group.xlabel,
-                      )
+    def plot(self):
+        self.plot_independent()
+        self.plot_dependent()
 
-    def plot_altitude_for_the_peak(self):
+    def plot_dependent(self):
         pass
 
-    def plot_year_for_the_peak(self, plot_mean=True):
-        t_list = self.study.ordered_years
-        return_period = 50
-        for massif_name, one_fold_fit in self.massif_name_to_one_fold_fit.items():
-            ax = plt.gca()
-            # One plot for each altitude
-            altitudes = np.arange(500, min(3000, max(self.studies.altitudes)), 500)
-            for altitude in altitudes:
-                i = 0
-                while self.studies.altitudes[i] < altitude:
-                    i += 1
-                nearest_altitude = self.studies.altitudes[i]
-                nearest_study = self.studies.altitude_to_study[nearest_altitude]
-                if massif_name in nearest_study.study_massif_names:
-                    y_list = []
-                    for t in t_list:
-                        coordinate = np.array([altitude, t])
-                        gev_params = one_fold_fit.best_function_from_fit.get_params(coordinate, is_transformed=False)
-                        if plot_mean:
-                            y = gev_params.mean
-                        else:
-                            y = gev_params.return_level(return_period=return_period)
-                        y_list.append(y)
-                    label = '{} m'.format(altitude)
-                    ax.plot(t_list, y_list, label=label)
-            ax.legend()
-            # Modify the limits of the y axis
-            lim_down, lim_up = ax.get_ylim()
-            ax_lim = (0, lim_up)
-            ax.set_ylim(ax_lim)
-            ax.set_xlabel('Year')
-            if plot_mean:
-                ylabel = 'Mean {} maxima'.format(self.study.season_name)
-            else:
-                ylabel = '{}-year return level'.format(return_period)
-            ax.set_ylabel('{} of {} in {} ({})'.format(ylabel, SCM_STUDY_CLASS_TO_ABBREVIATION[type(self.study)],
-                                                       massif_name.replace('_', ' '), self.study.variable_unit))
-            peak_year_folder = 'Peak year ' + ylabel
-            plot_name = '{}{}/Peak year for {}'.format(OneFoldFit.folder_for_plots, peak_year_folder,
-                                                       massif_name.replace('_', ''))
-            self.studies.show_or_save_to_file(plot_name=plot_name, show=self.show, no_title=True, tight_layout=True)
-            plt.close()
-
-    # Plots "altitude switch" and "peak year"
-
-    @property
-    def massif_name_to_is_decreasing_parabol(self):
-        # For the test we only activate the Mont-Blanc massif
-        d = {massif_name: False for massif_name in self.massif_name_to_one_fold_fit.keys()}
-        if max(self.study.ordered_years) < 2030:
-            for massif_name in ['Vanoise', 'Aravis', 'Beaufortain', 'Chablais']:
-                d[massif_name] = True
-        return d
-
-    @property
-    def massif_name_to_altitudes_switch_and_peak_years(self):
-        return {massif_name: self.compute_couple_peak_year_and_altitude_switch(massif_name)
-                for massif_name, is_decreasing_parabol in self.massif_name_to_is_decreasing_parabol.items()
-                if is_decreasing_parabol}
-
-    def compute_couple_peak_year_and_altitude_switch(self, massif_name):
-        # Get the altitude limits
-        altitudes = self.study.massif_name_to_altitudes[massif_name]
-        # use a step of 100m for instance
-        step = 10
-        altitudes = list(np.arange(min(altitudes), max(altitudes) + step, step))
-        # Get all the correspond peak years
-        margin_function = self.massif_name_to_one_fold_fit[massif_name].best_function_from_fit
-        peak_years = []
-        year_left = 1900
-        switch_altitudes = []
-        for altitude in altitudes:
-            year_left = self.compute_peak_year(margin_function, altitude, year_left)
-            if year_left > 2020:
-                break
-            peak_years.append(year_left)
-            switch_altitudes.append(altitude)
-        print(switch_altitudes)
-        print(peak_years)
-        return switch_altitudes, peak_years
-
-    def compute_peak_year(self, margin_function: AbstractMarginFunction, altitude, year_left):
-        year_right = year_left + 0.1
-        mean_left = margin_function.get_params(np.array([altitude, year_left])).mean
-        mean_right = margin_function.get_params(np.array([altitude, year_right])).mean
-        print(year_left, year_right, mean_left, mean_right)
-        if mean_right < mean_left:
-            return year_left
-        else:
-            return self.compute_peak_year(margin_function, altitude, year_right)
-
-    def plot_peak_year_against_altitude(self):
-        ax = plt.gca()
-        for massif_name, (altitudes, peak_years) in self.massif_name_to_altitudes_switch_and_peak_years.items():
-            ax.plot(altitudes, peak_years, label=massif_name)
-        ax.legend()
-        ax.set_xlabel('Altitude')
-        ax.set_ylabel('Peak years')
-        plot_name = 'Peak Years'
-        self.studies.show_or_save_to_file(plot_name=plot_name, show=self.show)
-        plt.close()
-
-    def plot_altitude_switch_against_peak_year(self):
-        ax = plt.gca()
-        for massif_name, (altitudes, peak_years) in self.massif_name_to_altitudes_switch_and_peak_years.items():
-            ax.plot(peak_years, altitudes, label=massif_name)
-        ax.legend()
-        ax.set_xlabel('Peak years')
-        ax.set_ylabel('Altitude')
-        plot_name = 'Switch altitude'
-        self.studies.show_or_save_to_file(plot_name=plot_name, show=self.show)
-        plt.close()
-
-    def all_trends(self, massif_names):
-        """return percents which contain decrease, significant decrease, increase, significant increase percentages"""
-        valid_massif_names = self.get_valid_names(massif_names)
-
-        nb_valid_massif_names = len(valid_massif_names)
-        nbs = np.zeros(4)
-        for one_fold in [one_fold for m, one_fold in self.massif_name_to_one_fold_fit.items()
-                         if m in valid_massif_names]:
-            # Compute nb of non stationary models
-            if one_fold.change_in_return_level_for_reference_altitude == 0:
-                continue
-            # Compute nbs
-            idx = 0 if one_fold.change_in_return_level_for_reference_altitude < 0 else 2
-            nbs[idx] += 1
-            if one_fold.is_significant:
-                nbs[idx + 1] += 1
-
-        percents = 100 * nbs / nb_valid_massif_names
-        return [nb_valid_massif_names] + list(percents)
-
-    def all_changes(self, massif_names, relative=False):
-        """return percents which contain decrease, significant decrease, increase, significant increase percentages"""
-        valid_massif_names = self.get_valid_names(massif_names)
-        changes = []
-        non_stationary_changes = []
-        non_stationary_significant_changes = []
-        for one_fold in [one_fold for m, one_fold in self.massif_name_to_one_fold_fit.items()
-                         if m in valid_massif_names]:
-            # Compute changes
-            if relative:
-                change = one_fold.relative_change_in_return_level_for_reference_altitude
-            else:
-                change = one_fold.change_in_return_level_for_reference_altitude
-            changes.append(change)
-            if change != 0:
-                non_stationary_changes.append(change)
-                if one_fold.is_significant:
-                    non_stationary_significant_changes.append(change)
-
-        moment = 'relative mean' if relative else 'Mean'
-        print('{} for {}m'.format(moment, self.altitude_group.reference_altitude), np.mean(changes))
-        return changes, non_stationary_changes, non_stationary_significant_changes
-
-    def get_valid_names(self, massif_names):
-        valid_massif_names = set(self.massif_name_to_one_fold_fit.keys())
-        if massif_names is not None:
-            valid_massif_names = valid_massif_names.intersection(set(massif_names))
-        return valid_massif_names
-
-    def model_name_to_percentages(self, massif_names, only_significant=False):
-        valid_massif_names = self.get_valid_names(massif_names)
-        nb_valid_massif_names = len(valid_massif_names)
-        best_names = [one_fold_fit.best_estimator.margin_model.name_str
-                      for m, one_fold_fit in self.massif_name_to_one_fold_fit.items()
-                      if m in valid_massif_names and (not only_significant or one_fold_fit.is_significant)]
-        counter = Counter(best_names)
-        d = {name: 100 * c / nb_valid_massif_names for name, c in counter.items()}
-        # Add 0 for the name not present
-        for name in self.model_names:
-            if name not in d:
-                d[name] = 0
-        return d
-
-    @property
-    def model_names(self):
-        massif_name = list(self.massif_name_to_one_fold_fit.keys())[0]
-        return self.massif_name_to_one_fold_fit[massif_name].model_names
-
-    def plot_qqplots(self):
-        for massif_name, one_fold_fit in self.massif_name_to_one_fold_fit.items():
-            ax = plt.gca()
-            altitudes = self.massif_name_to_massif_altitudes[massif_name]
-            massif_name_corrected = massif_name.replace('_', ' ')
-
-            all_quantiles = []
-
-            for altitude in self.studies.altitudes:
-                coordinate_for_filter = (altitude, None)
-                unconstrained_empirical_quantiles = one_fold_fit.best_estimator.sorted_empirical_standard_gumbel_quantiles(coordinate_for_filter=coordinate_for_filter)
-                n = len(unconstrained_empirical_quantiles)
-                if n > 0:
-                    assert n == 61
-                    standard_gumbel_quantiles = one_fold_fit.standard_gumbel_quantiles(n=n)
-                    ax.plot(standard_gumbel_quantiles, unconstrained_empirical_quantiles, linestyle='None',
-                            label='{} m'.format(altitude), marker='o')
-
-                    all_quantiles.extend(standard_gumbel_quantiles)
-                    all_quantiles.extend(unconstrained_empirical_quantiles)
-
-            size_label = 20
-            ax.set_xlabel("Theoretical quantile", fontsize=size_label)
-            ax.set_ylabel("Empirical quantile", fontsize=size_label)
-
-            epsilon = 0.1
-            ax_lim = [min(all_quantiles) - epsilon, max(all_quantiles) + epsilon]
-            ax.set_xlim(ax_lim)
-            ax.set_ylim(ax_lim)
-
-            ax.plot(ax_lim, ax_lim, color='k')
-            ticks = [i for i in range(ceil(ax_lim[0]), floor(ax_lim[1]) + 1)]
-            ax.set_xticks(ticks)
-            ax.set_yticks(ticks)
-            labelsize = 15
-            ax.tick_params(labelsize=labelsize)
-            plot_name = 'qqplot/{}'.format(massif_name_corrected)
-            handles, labels = ax.get_legend_handles_labels()
-            ax.legend(handles[::-1], labels[::-1], prop={'size': labelsize})
-            self.studies.show_or_save_to_file(plot_name=plot_name, show=self.show, no_title=True)
-            plt.close()
+    def plot_independent(self):
+        for ensemble_fit in self.ensemble_class_to_ensemble_fit.values():
+            ensemble_fit.plot()
diff --git a/projects/projected_snowfall/trends/main_projected_trends_separately.py b/projects/projected_snowfall/trends/main_projected_trends_separately.py
deleted file mode 100644
index 8ed7dcc6..00000000
--- a/projects/projected_snowfall/trends/main_projected_trends_separately.py
+++ /dev/null
@@ -1,95 +0,0 @@
-import time
-from typing import List
-
-import matplotlib as mpl
-import numpy as np
-
-from extreme_data.meteo_france_data.adamont_data.abstract_adamont_study import WrongYearMinOrYearMax
-from extreme_data.meteo_france_data.adamont_data.adamont.adamont_snowfall import AdamontSnowfall
-from extreme_data.meteo_france_data.adamont_data.adamont_scenario import AdamontScenario
-from extreme_data.meteo_france_data.scm_models_data.crocus.crocus import CrocusSnowLoadTotal, CrocusSnowLoad3Days
-from projects.altitude_spatial_model.altitudes_fit.plots.plot_coherence_curves import plot_coherence_curves
-from projects.altitude_spatial_model.altitudes_fit.plots.plot_histogram_altitude_studies import \
-    plot_histogram_all_models_against_altitudes, plot_histogram_all_trends_against_altitudes, \
-    plot_shoe_plot_changes_against_altitude
-
-mpl.rcParams['text.usetex'] = True
-mpl.rcParams['text.latex.preamble'] = [r'\usepackage{amsmath}']
-
-from projects.altitude_spatial_model.altitudes_fit.utils_altitude_studies_visualizer import load_visualizer_list
-
-from projects.altitude_spatial_model.altitudes_fit.one_fold_analysis.altitude_group import altitudes_for_groups
-from projects.altitude_spatial_model.altitudes_fit.one_fold_analysis.plot_total_aic import plot_individual_aic
-
-from extreme_data.meteo_france_data.scm_models_data.safran.safran import SafranSnowfall1Day, SafranSnowfall3Days, \
-    SafranSnowfall5Days, SafranSnowfall7Days, SafranDateFirstSnowfall, SafranPrecipitation1Day, SafranPrecipitation3Days
-from extreme_data.meteo_france_data.scm_models_data.utils import Season
-
-
-def main():
-    study_class = AdamontSnowfall
-    scenario = AdamontScenario.rcp85_extended
-    gcm_rcm_couples = [('CNRM-CM5', 'CCLM4-8-17'), ('CNRM-CM5', 'RCA4')][1:]
-
-    fast = True
-    if fast is None:
-        massif_names = None
-        altitudes_list = altitudes_for_groups[1:2]
-    elif fast:
-        massif_names = ['Vanoise', 'Haute-Maurienne', 'Vercors'][:1]
-        altitudes_list = altitudes_for_groups[1:3]
-    else:
-        massif_names = None
-        altitudes_list = altitudes_for_groups[:]
-
-    # One plot for each massif name
-    for massif_name in massif_names:
-        print(massif_name)
-        main_loop(altitudes_list, [massif_name], gcm_rcm_couples, study_class, scenario)
-
-
-def main_loop(altitudes_list, massif_names, gcm_rcm_couples, study_class, scenario):
-    assert isinstance(altitudes_list, List)
-    assert isinstance(altitudes_list[0], List)
-    altitudes_for_return_levels = [altitudes[-2] for altitudes in altitudes_list]
-    print(altitudes_for_return_levels)
-    season = Season.annual
-    first_year_min, first_year_max = 1951, 2010
-    nb_years = first_year_max - first_year_min + 1
-    temporal_windows = [(first_year_min + i, first_year_max + i) for i in [30 * j for j in range(4)]]
-    all_changes_in_return_levels = []
-    for gcm_rcm_couple in gcm_rcm_couples:
-        print('Inner', gcm_rcm_couple)
-        changes_in_return_levels = []
-        for temporal_window in temporal_windows:
-            year_min, year_max = temporal_window
-            try:
-                visualizer_list = load_visualizer_list(season, study_class, altitudes_list, massif_names,
-                                                       scenario=scenario, gcm_rcm_couple=gcm_rcm_couple,
-                                                       year_min=year_min, year_max=year_max)
-
-                for visualizer in visualizer_list:
-                    visualizer.studies.plot_maxima_time_series(massif_names)
-                massif_name = massif_names[0]
-                changes_for_temporal_window = [
-                    v.massif_name_to_one_fold_fit[massif_name].changes_of_moment(altitudes=[a],
-                                                                                 year=year_max,
-                                                                                 nb_years=nb_years,
-                                                                                 order=None
-                                                                                 )[0]
-                    for a, v in zip(altitudes_for_return_levels, visualizer_list)]
-
-            except WrongYearMinOrYearMax:
-                changes_for_temporal_window = [np.nan for _ in altitudes_for_return_levels]
-
-            print(changes_for_temporal_window)
-            changes_in_return_levels.append(changes_for_temporal_window)
-        changes_in_return_levels = np.array(changes_in_return_levels)
-        all_changes_in_return_levels.append(changes_in_return_levels)
-    all_changes_in_return_levels = np.array(all_changes_in_return_levels)
-
-    return all_changes_in_return_levels, temporal_windows, altitudes_for_return_levels, nb_years
-
-
-if __name__ == '__main__':
-    main()
-- 
GitLab