From 01c08f79cc04cacdb573a149fbf58ab0eaf20f94 Mon Sep 17 00:00:00 2001
From: Le Roux Erwan <erwan.le-roux@irstea.fr>
Date: Thu, 25 Mar 2021 08:55:54 +0100
Subject: [PATCH] [projection snowfall] add
 main_sensitivity_one_altitude_range.py. add detail plot for each massif for
 the return level

---
 .../cmip5/climate_explorer_cimp5.py           |   3 -
 .../adamont_data/cmip5/temperature_to_year.py |  22 ++--
 .../scm_models_data/safran/safran_variable.py |   6 +-
 .../visualization/plot_utils.py               |  31 ++---
 .../visualizer_for_sensitivity.py             |  49 +++++---
 ...es_visualizer_for_non_stationary_models.py |  12 +-
 .../main_altitudes_studies.py                 |  37 +++---
 .../discussion/main_sensitivity.py            |   4 +-
 .../main_sensitivity_one_altitude_range.py    | 108 ++++++++++++++++++
 9 files changed, 206 insertions(+), 66 deletions(-)
 create mode 100644 projects/projected_extreme_snowfall/discussion/main_sensitivity_one_altitude_range.py

diff --git a/extreme_data/meteo_france_data/adamont_data/cmip5/climate_explorer_cimp5.py b/extreme_data/meteo_france_data/adamont_data/cmip5/climate_explorer_cimp5.py
index 0372adc4..87166420 100644
--- a/extreme_data/meteo_france_data/adamont_data/cmip5/climate_explorer_cimp5.py
+++ b/extreme_data/meteo_france_data/adamont_data/cmip5/climate_explorer_cimp5.py
@@ -58,10 +58,7 @@ def years_and_global_mean_temps(gcm, scenario, year_min=None, year_max=None, ano
         download_dat(dat_filepath, txt_filepath)
     # Transform nc file into csv file
     if not op.exists(csv_filepath):
-        print('compute csv')
         dat_to_csv(csv_filepath, txt_filepath, gcm)
-    else:
-        print('read from existing csv')
 
     # Load csv file
     df = pd.read_csv(csv_filepath, index_col=0)
diff --git a/extreme_data/meteo_france_data/adamont_data/cmip5/temperature_to_year.py b/extreme_data/meteo_france_data/adamont_data/cmip5/temperature_to_year.py
index c6abcb19..61872585 100644
--- a/extreme_data/meteo_france_data/adamont_data/cmip5/temperature_to_year.py
+++ b/extreme_data/meteo_france_data/adamont_data/cmip5/temperature_to_year.py
@@ -91,28 +91,34 @@ def plot_nb_data(is_temperature_interval, is_shift_interval):
 
 def get_interval_limits(is_temperature_interval, is_shift_interval):
     if is_temperature_interval:
-        temp_min = np.arange(0, 2, 0.5)
-        temp_max = temp_min + 1
+        temp_min = np.arange(0, 4, 0.5)
+        temp_max = temp_min + 1.0
         left_limit, right_limit = temp_min, temp_max
     else:
         shift = 25
         nb = 3
-        year_min = [2006 + shift * i for i in range(nb)]
-        year_max = [2050 + shift * i for i in range(nb)]
+        year_min = [1959 + shift * i for i in range(nb)]
+        year_max = [2020 + shift * i for i in range(nb)]
         left_limit, right_limit = year_min, year_max
     if not is_shift_interval:
         min_interval_left = min(left_limit)
         left_limit = [min_interval_left for _ in right_limit]
-    return left_limit[:3], right_limit[:3]
+    idx = None
+    if idx is None:
+        return left_limit, right_limit
+    else:
+        return left_limit[:idx], right_limit[:idx]
 
 
 def get_ticks_labels_for_interval(is_temperature_interval, is_shift_interval):
     left_limits, right_limits = get_interval_limits(is_temperature_interval, is_shift_interval)
-    ticks_labels = [' +${}^o\mathrm{C}$ and +${}^o\mathrm{C}$'.format(left_limit, right_limit, **{'C': '{C}'})
+    left_limits = [int(l) if int(l) == l else l for l in left_limits]
+    right_limits = [int(l) if int(l) == l else l for l in right_limits]
+    ticks_labels = [' ${}$-${}^o\mathrm{C}$'.format(left_limit, right_limit, **{'C': '{C}'})
                     if is_temperature_interval else '{} and {}'.format(left_limit, right_limit)
                     for left_limit, right_limit in zip(left_limits, right_limits)]
-    prefix = 'Maxima between \n'
-    ticks_labels = [prefix + l for l in ticks_labels]
+    # prefix = 'Maxima between \n'
+    ticks_labels = [l for l in ticks_labels]
     return ticks_labels
 
 
diff --git a/extreme_data/meteo_france_data/scm_models_data/safran/safran_variable.py b/extreme_data/meteo_france_data/scm_models_data/safran/safran_variable.py
index 485560d4..fe1bdfff 100644
--- a/extreme_data/meteo_france_data/scm_models_data/safran/safran_variable.py
+++ b/extreme_data/meteo_france_data/scm_models_data/safran/safran_variable.py
@@ -63,15 +63,15 @@ class SafranSnowfallVariable(AbstractVariable):
         return snowfall_in_consecutive_days
 
 
-
-
 class SafranSnowfallVariableNotCenterOnDay(SafranSnowfallVariable):
+    NAME = 'Snowfall MeteoFranceRate 6hto5h'
 
     def get_snowfall_rates(self, variable_array):
         return variable_array[:-1]
 
 
 class SafranSnowfallVariableCenterOnDay(SafranSnowfallVariable):
+    NAME = 'Snowfall MeteoFranceRate CenterOnDay'
 
     def daily_snowfall(self, hourly_snowfall, nb_days):
         hourly_snowfall_without_first_and_last_days = hourly_snowfall[18:-6]
@@ -86,12 +86,12 @@ class SafranSnowfallVariableCenterOnDay(SafranSnowfallVariable):
 
 
 class SafranSnowfallVariableCenterOnDayMeanRate(SafranSnowfallVariableCenterOnDay):
+    NAME = 'Snowfall MyRate CenterOnDay'
 
     def get_snowfall_rates(self, variable_array):
         return 0.5 * (variable_array[:-1] + variable_array[1:])
 
 
-
 class SafranDateFirstSnowfallVariable(SafranSnowfallVariable):
     NAME = 'Date First Snow'
     UNIT = 'days'
diff --git a/extreme_data/meteo_france_data/scm_models_data/visualization/plot_utils.py b/extreme_data/meteo_france_data/scm_models_data/visualization/plot_utils.py
index 75e0f219..8a1c9141 100644
--- a/extreme_data/meteo_france_data/scm_models_data/visualization/plot_utils.py
+++ b/extreme_data/meteo_france_data/scm_models_data/visualization/plot_utils.py
@@ -10,19 +10,7 @@ from extreme_data.meteo_france_data.scm_models_data.visualization.create_shifted
 def plot_against_altitude(x_ticks, ax, massif_id, massif_name, values, altitude=None, fill=False, massif_name_as_labels=True,
                           elevation_as_xaxis=True, legend=False):
     if massif_name_as_labels:
-        di = massif_id // 8
-        if di == 0:
-            linestyle = '-.'
-        elif di == 1:
-            linestyle = 'dotted'
-        else:
-            linestyle = '--'
-        colors = list(mcolors.TABLEAU_COLORS)
-        colors[-3:-1] = []  # remove gray and olive
-        color = colors[massif_id % 8]
-        # Label
-        massif_name_str = ' '.join(massif_name.split('_'))
-        label = massif_name_str
+        color, linestyle, label = get_color_and_linestyle_from_massif_id(massif_id, massif_name)
     else:
         color = None
         linestyle = None
@@ -40,6 +28,23 @@ def plot_against_altitude(x_ticks, ax, massif_id, massif_name, values, altitude=
         ax.fill_between(x_ticks, lower_bound, upper_bound, color=color, alpha=0.2)
 
 
+def get_color_and_linestyle_from_massif_id(massif_id, massif_name):
+    di = massif_id // 8
+    if di == 0:
+        linestyle = '-.'
+    elif di == 1:
+        linestyle = 'dotted'
+    else:
+        linestyle = '--'
+    colors = list(mcolors.TABLEAU_COLORS)
+    colors[-3:-1] = []  # remove gray and olive
+    color = colors[massif_id % 8]
+    # Label
+    massif_name_str = ' '.join(massif_name.split('_'))
+    label = massif_name_str
+    return color, linestyle, label
+
+
 def load_plot(cmap, graduation, label, massif_name_to_value, altitude, add_x_label=True,
               negative_and_positive_values=True, massif_name_to_text=None, add_colorbar=True, max_abs_change=None,
               xlabel=None, fontsize_label=10):
diff --git a/extreme_trend/ensemble_fit/visualizer_for_sensitivity.py b/extreme_trend/ensemble_fit/visualizer_for_sensitivity.py
index d24fed25..07968587 100644
--- a/extreme_trend/ensemble_fit/visualizer_for_sensitivity.py
+++ b/extreme_trend/ensemble_fit/visualizer_for_sensitivity.py
@@ -6,7 +6,10 @@ import numpy as np
 
 from extreme_data.meteo_france_data.adamont_data.cmip5.temperature_to_year import get_interval_limits, \
     get_year_min_and_year_max, get_ticks_labels_for_interval
+from extreme_data.meteo_france_data.scm_models_data.abstract_study import AbstractStudy
 from extreme_data.meteo_france_data.scm_models_data.utils import Season
+from extreme_data.meteo_france_data.scm_models_data.visualization.plot_utils import \
+    get_color_and_linestyle_from_massif_id
 from extreme_fit.model.margin_model.polynomial_margin_model.spatio_temporal_polynomial_model import \
     AbstractSpatioTemporalPolynomialModel
 from extreme_fit.model.margin_model.utils import MarginFitMethod
@@ -15,7 +18,7 @@ from extreme_trend.ensemble_fit.independent_ensemble_fit.independent_ensemble_fi
 from extreme_trend.ensemble_fit.together_ensemble_fit.together_ensemble_fit import TogetherEnsembleFit
 from extreme_trend.ensemble_fit.visualizer_for_projection_ensemble import VisualizerForProjectionEnsemble
 from extreme_trend.one_fold_fit.altitude_group import get_altitude_class_from_altitudes, \
-    get_linestyle_for_altitude_class
+    get_linestyle_for_altitude_class, get_altitude_group_from_altitudes
 from spatio_temporal_dataset.coordinates.temporal_coordinates.temperature_covariate import \
     AnomalyTemperatureWithSplineTemporalCovariate
 
@@ -92,32 +95,44 @@ class VisualizerForSensivity(object):
     def sensitivity_plot_return_levels(self, merge_visualizer_str):
         ax = plt.gca()
         for altitudes in self.altitudes_list:
-            altitude_class = get_altitude_class_from_altitudes(altitudes)
-            self.interval_plot_return_levels(ax, altitude_class, merge_visualizer_str)
+            altitude_group = get_altitude_class_from_altitudes(altitudes)
+            self.interval_plot_return_levels(ax, altitude_group, merge_visualizer_str)
 
         ticks_labels = get_ticks_labels_for_interval(self.is_temperature_interval, self.is_shift_interval)
         name = 'Return levels at the end of the interval'
+        if len(self.altitudes_list) == 1:
+            altitude_group = get_altitude_group_from_altitudes(self.altitudes_list[0])
+            name += ' at {} m'.format(altitude_group.reference_altitude)
         ax.set_ylabel(name)
-        ax.set_xlabel('Interval used to compute the trends ')
+        ax.set_xlabel('Interval for the maxima used to compute the trends ')
         ax.set_xticks(self.right_limits)
         ax.set_xticklabels(ticks_labels)
-        lim_left, lim_right = ax.get_xlim()
-        ax.legend(prop={'size': 7}, loc='upper center', ncol=2)
-        # ax.set_ylim((0, 122))
-        # ax.set_yticks([i * 10 for i in range(11)])
         self.save_plot(merge_visualizer_str, name)
 
     def interval_plot_return_levels(self, ax, altitude_class, merge_visualizer_str):
-        linestyle = get_linestyle_for_altitude_class(altitude_class)
 
         mean_return_levels = []
-        for v in self.right_limit_to_visualizer.values():
+        massif_names = AbstractStudy.all_massif_names() if self.massif_names is None else self.massif_names
+        massif_name_to_tuple_list = {m: [] for m in massif_names}
+        for r, v in self.right_limit_to_visualizer.items():
             merge_visualizer = self.get_merge_visualizer(altitude_class, v, merge_visualizer_str)
-            mean_return_level = merge_visualizer.mean_return_level(self.massif_names)
-            mean_return_levels.append(mean_return_level)
-
-        label = altitude_class().formula
-        ax.plot(self.right_limits, mean_return_levels, linestyle=linestyle, label=label, color='orange')
+            massif_name_to_return_level = merge_visualizer.massif_name_to_return_level(massif_names)
+            for massif_name, return_level in massif_name_to_return_level.items():
+                massif_name_to_tuple_list[massif_name].append((r, return_level))
+            mean_return_levels.append(np.mean(list(massif_name_to_return_level.values())))
+
+        for massif_id, massif_name in enumerate(AbstractStudy.all_massif_names()):
+            if len(massif_name_to_tuple_list[massif_name]) > 0:
+                x, y = zip(*massif_name_to_tuple_list[massif_name])
+            else:
+                x, y = [], []
+            color, linestyle, label = get_color_and_linestyle_from_massif_id(massif_id, massif_name)
+            ax.plot(x, y, color=color, linestyle=linestyle, label=label)
+
+        ax.plot(self.right_limits, mean_return_levels, label="Mean", color='k', linewidth=4)
+        down, up = ax.get_ylim()
+        ax.set_ylim((down, up * 1.3))
+        ax.legend(prop={'size': 7}, ncol=3, loc="upper center")
 
     def interval_plot_changes(self, ax, altitude_class, merge_visualizer_str, relative):
         linestyle = get_linestyle_for_altitude_class(altitude_class)
@@ -141,7 +156,7 @@ class VisualizerForSensivity(object):
         ticks_labels = get_ticks_labels_for_interval(self.is_temperature_interval, self.is_shift_interval)
         name = 'relative changes' if relative else "changes"
         ax.set_ylabel(name)
-        ax.set_xlabel('Interval used to compute the trends ')
+        ax.set_xlabel('Interval for the maxima used to compute the trends ')
         ax.set_xticks(self.right_limits)
         ax.set_xticklabels(ticks_labels)
         lim_left, lim_right = ax.get_xlim()
@@ -172,7 +187,7 @@ class VisualizerForSensivity(object):
 
         ticks_labels = get_ticks_labels_for_interval(self.is_temperature_interval, self.is_shift_interval)
         ax.set_ylabel('Percentages of massifs (\%)')
-        ax.set_xlabel('Interval used to compute the trends ')
+        ax.set_xlabel('Interval used for the maxima to compute the trends ')
         ax.set_xticks(self.right_limits)
         ax.set_xticklabels(ticks_labels)
         ax.legend(prop={'size': 7}, loc='upper center', ncol=2)
diff --git a/extreme_trend/one_fold_fit/altitudes_studies_visualizer_for_non_stationary_models.py b/extreme_trend/one_fold_fit/altitudes_studies_visualizer_for_non_stationary_models.py
index 73b674f5..f856a926 100644
--- a/extreme_trend/one_fold_fit/altitudes_studies_visualizer_for_non_stationary_models.py
+++ b/extreme_trend/one_fold_fit/altitudes_studies_visualizer_for_non_stationary_models.py
@@ -462,13 +462,13 @@ class AltitudesStudiesVisualizerForNonStationaryModels(StudyVisualizer):
         self.studies.show_or_save_to_file(plot_name=plot_name, show=self.show)
         plt.close()
 
-    def mean_return_level(self, massif_names):
+    def massif_name_to_return_level(self, massif_names):
         valid_massif_names = self.get_valid_names(massif_names)
-        return_levels = []
-        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]:
-            return_levels.append(one_fold.return_level_last_temporal_coordinate)
-        return np.mean(return_levels)
+        massif_name_to_return_level = {}
+        for m, one_fold in self.massif_name_to_one_fold_fit.items():
+            if m in valid_massif_names:
+                massif_name_to_return_level[m] = one_fold.return_level_last_temporal_coordinate
+        return massif_name_to_return_level
 
     def all_trends(self, massif_names, with_significance=True, with_relative_change=False):
         """return percents which contain decrease, significant decrease, increase, significant increase percentages"""
diff --git a/projects/past_extreme_snowfall/section_data_and_results/main_altitudes_studies.py b/projects/past_extreme_snowfall/section_data_and_results/main_altitudes_studies.py
index bef9ed2e..1801c8d2 100644
--- a/projects/past_extreme_snowfall/section_data_and_results/main_altitudes_studies.py
+++ b/projects/past_extreme_snowfall/section_data_and_results/main_altitudes_studies.py
@@ -1,18 +1,20 @@
 import datetime
 import time
 from typing import List
-
-
 import matplotlib as mpl
-
-from extreme_trend.one_fold_fit.utils_altitude_studies_visualizer import load_visualizer_list
-
 mpl.rcParams['text.usetex'] = True
 mpl.rcParams['text.latex.preamble'] = [r'\usepackage{amsmath}']
 
 import matplotlib
 matplotlib.use('Agg')
 
+
+from extreme_data.meteo_france_data.scm_models_data.safran.safran_max_snowf import SafranSnowfall2020, \
+    SafranSnowfall2019
+from extreme_trend.one_fold_fit.utils_altitude_studies_visualizer import load_visualizer_list
+
+
+
 from extreme_trend.one_fold_fit.plots.plot_histogram_altitude_studies import \
     plot_shoe_plot_changes_against_altitude, plot_histogram_all_trends_against_altitudes, \
     plot_histogram_all_models_against_altitudes
@@ -29,14 +31,19 @@ from extreme_trend.one_fold_fit.plots.plot_coherence_curves import plot_coherenc
 from extreme_trend.one_fold_fit.altitude_group import altitudes_for_groups
 
 from extreme_data.meteo_france_data.scm_models_data.safran.safran import SafranSnowfall1Day, SafranSnowfall3Days, \
-    SafranSnowfall5Days, SafranSnowfall7Days
+    SafranSnowfall5Days, SafranSnowfall7Days, SafranSnowfallCenterOnDay1day, SafranSnowfallNotCenterOnDay1day, \
+    SafranSnowfallCenterOnDay1dayMeanRate
 from extreme_data.meteo_france_data.scm_models_data.utils import Season
 
 
 def main():
+
     study_classes = [SafranSnowfall1Day
                      , SafranSnowfall3Days,
                      SafranSnowfall5Days, SafranSnowfall7Days][:1]
+    study_classes = [SafranSnowfall2019, SafranSnowfall2020, SafranSnowfallCenterOnDay1day,
+                     SafranSnowfallNotCenterOnDay1day,
+                     SafranSnowfallCenterOnDay1dayMeanRate, SafranSnowfall1Day][1:2]
     seasons = [Season.annual, Season.winter, Season.spring, Season.automn][:1]
 
     set_seed_for_test()
@@ -70,8 +77,8 @@ def main_loop(altitudes_list, massif_names, seasons, study_classes, model_must_p
         for study_class in study_classes:
             print('Inner loop', season, study_class)
             visualizer_list = load_visualizer_list(season, study_class, altitudes_list, massif_names,
-                                                   model_must_pass_the_test
-                                                )
+                                                   model_must_pass_the_test,
+                                                year_max=2019)
             plot_visualizers(massif_names, visualizer_list)
             for visualizer in visualizer_list:
                 plot_visualizer(massif_names, visualizer)
@@ -80,12 +87,12 @@ def main_loop(altitudes_list, massif_names, seasons, study_classes, model_must_p
 
 
 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, with_significance=True)
+    # plot_histogram_all_models_against_altitudes(massif_names, visualizer_list)
+    plot_histogram_all_trends_against_altitudes(massif_names, visualizer_list, with_significance=False)
     # 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(['Vanoise'], visualizer_list)
+        plot_shoe_plot_changes_against_altitude(massif_names, visualizer_list, relative=relative, with_significance=False)
+    # plot_coherence_curves(['Vanoise'], visualizer_list)
     pass
 
 
@@ -94,11 +101,13 @@ def plot_visualizer(massif_names, visualizer):
     # visualizer.studies.plot_maxima_time_series(massif_names)
     # visualizer.studies.plot_maxima_time_series(['Vanoise'])
 
-    visualizer.plot_shape_map()
+    # visualizer.plot_shape_map()
     visualizer.plot_moments()
-    visualizer.plot_qqplots()
+    # visualizer.plot_qqplots()
+
     # for std in [True, False]:
     #     visualizer.studies.plot_mean_maxima_against_altitude(std=std)
+    pass
 
 if __name__ == '__main__':
     main()
diff --git a/projects/projected_extreme_snowfall/discussion/main_sensitivity.py b/projects/projected_extreme_snowfall/discussion/main_sensitivity.py
index ddc3dc94..6ed567ff 100644
--- a/projects/projected_extreme_snowfall/discussion/main_sensitivity.py
+++ b/projects/projected_extreme_snowfall/discussion/main_sensitivity.py
@@ -45,10 +45,10 @@ def main():
     set_seed_for_test()
     AbstractExtractEurocodeReturnLevel.ALPHA_CONFIDENCE_INTERVAL_UNCERTAINTY = 0.2
 
-    fast = False
+    fast = None
     scenarios = [AdamontScenario.rcp85]
     scenarios = rcp_scenarios[1:]
-    scenarios = rcm_scenarios_extended[1:]
+    scenarios = rcm_scenarios_extended[2:][::-1]
 
     if fast in [None, True]:
         scenarios = scenarios[:1]
diff --git a/projects/projected_extreme_snowfall/discussion/main_sensitivity_one_altitude_range.py b/projects/projected_extreme_snowfall/discussion/main_sensitivity_one_altitude_range.py
new file mode 100644
index 00000000..d421a5c7
--- /dev/null
+++ b/projects/projected_extreme_snowfall/discussion/main_sensitivity_one_altitude_range.py
@@ -0,0 +1,108 @@
+import datetime
+import time
+from typing import List
+import matplotlib
+
+
+matplotlib.use('Agg')
+import matplotlib as mpl
+
+mpl.rcParams['text.usetex'] = True
+mpl.rcParams['text.latex.preamble'] = [r'\usepackage{amsmath}']
+
+from extreme_trend.ensemble_fit.abstract_ensemble_fit import AbstractEnsembleFit
+from extreme_trend.ensemble_fit.together_ensemble_fit.together_ensemble_fit import TogetherEnsembleFit
+
+from extreme_trend.ensemble_fit.independent_ensemble_fit.independent_ensemble_fit import IndependentEnsembleFit
+from extreme_trend.ensemble_fit.visualizer_for_projection_ensemble import VisualizerForProjectionEnsemble
+from extreme_trend.ensemble_fit.visualizer_for_sensitivity import VisualizerForSensivity
+from spatio_temporal_dataset.coordinates.temporal_coordinates.temperature_covariate import \
+    AnomalyTemperatureWithSplineTemporalCovariate
+
+from extreme_fit.model.margin_model.polynomial_margin_model.utils import \
+    ALTITUDINAL_GEV_MODELS_BASED_ON_POINTWISE_ANALYSIS
+
+from extreme_fit.model.utils import set_seed_for_test
+
+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, get_gcm_rcm_couples, \
+    rcp_scenarios, rcm_scenarios_extended
+from spatio_temporal_dataset.coordinates.temporal_coordinates.abstract_temporal_covariate_for_fit import \
+    TimeTemporalCovariate
+
+from extreme_fit.model.result_from_model_fit.result_from_extremes.abstract_extract_eurocode_return_level import \
+    AbstractExtractEurocodeReturnLevel
+
+from extreme_trend.one_fold_fit.altitude_group import altitudes_for_groups
+
+from extreme_data.meteo_france_data.scm_models_data.utils import Season
+
+
+def main():
+    start = time.time()
+    study_class = AdamontSnowfall
+    ensemble_fit_classes = [IndependentEnsembleFit, TogetherEnsembleFit][1:]
+    set_seed_for_test()
+    AbstractExtractEurocodeReturnLevel.ALPHA_CONFIDENCE_INTERVAL_UNCERTAINTY = 0.2
+
+    fast = False
+    scenarios = [AdamontScenario.rcp85]
+    scenarios = rcp_scenarios[1:]
+    scenarios = rcm_scenarios_extended[:][::-1]
+
+    if fast in [None, True]:
+        scenarios = scenarios[:1]
+
+    for scenario in scenarios:
+        gcm_rcm_couples = get_gcm_rcm_couples(scenario)
+        if fast is None:
+            massif_names = None
+            gcm_rcm_couples = gcm_rcm_couples[:2]
+            AbstractExtractEurocodeReturnLevel.NB_BOOTSTRAP = 10
+            altitudes_list = altitudes_for_groups[:1]
+        elif fast:
+            massif_names = ['Vanoise', 'Haute-Maurienne', 'Vercors', 'Ubaye']
+            gcm_rcm_couples = gcm_rcm_couples[4:6]
+            AbstractExtractEurocodeReturnLevel.NB_BOOTSTRAP = 10
+            altitudes_list = altitudes_for_groups[1:3]
+        else:
+            massif_names = None
+            altitudes_list = altitudes_for_groups[:]
+
+        assert isinstance(gcm_rcm_couples, list)
+
+        assert isinstance(altitudes_list, List)
+        assert isinstance(altitudes_list[0], List)
+        print('Scenario is', scenario)
+
+        model_classes = ALTITUDINAL_GEV_MODELS_BASED_ON_POINTWISE_ANALYSIS
+        assert scenario is not AdamontScenario.histo
+        remove_physically_implausible_models = True
+        temp_cov = True
+        temporal_covariate_for_fit = AnomalyTemperatureWithSplineTemporalCovariate if temp_cov else TimeTemporalCovariate
+        print('Covariate is {}'.format(temporal_covariate_for_fit))
+
+        for altitudes in altitudes_list:
+            sub_altitudes_list = [altitudes]
+            print(sub_altitudes_list)
+            for is_temperature_interval in [True, False][:1]:
+                for is_shift_interval in [True, False][1:]:
+                    visualizer = VisualizerForSensivity(
+                        sub_altitudes_list, gcm_rcm_couples, study_class, Season.annual, scenario,
+                        model_classes=model_classes,
+                        ensemble_fit_classes=ensemble_fit_classes,
+                        massif_names=massif_names,
+                        temporal_covariate_for_fit=temporal_covariate_for_fit,
+                        remove_physically_implausible_models=remove_physically_implausible_models,
+                        is_temperature_interval=is_temperature_interval,
+                        is_shift_interval=is_shift_interval,
+                    )
+                    visualizer.plot()
+
+    end = time.time()
+    duration = str(datetime.timedelta(seconds=end - start))
+    print('Total duration', duration)
+
+
+if __name__ == '__main__':
+    main()
-- 
GitLab