From 59b8ae9d84290f3639978c4a4da8bc12b832e32c Mon Sep 17 00:00:00 2001
From: Le Roux Erwan <erwan.le-roux@irstea.fr>
Date: Mon, 22 Feb 2021 17:48:06 +0100
Subject: [PATCH] [projections] add box plot without significance. refactor a
 bit the str for the plots. add inquiry for the pattern 85 that we obtain for
 one couple

---
 ...es_visualizer_for_non_stationary_models.py | 16 +++++----
 .../one_fold_analysis/one_fold_fit.py         |  9 +++++
 .../plots/plot_histogram_altitude_studies.py  | 34 ++++++++-----------
 ...ation_temporal_for_projections_ensemble.py | 14 +++-----
 .../visualizer_for_projection_ensemble.py     |  4 +--
 root_utils.py                                 |  6 ++++
 6 files changed, 46 insertions(+), 37 deletions(-)

diff --git a/projects/altitude_spatial_model/altitudes_fit/one_fold_analysis/altitudes_studies_visualizer_for_non_stationary_models.py b/projects/altitude_spatial_model/altitudes_fit/one_fold_analysis/altitudes_studies_visualizer_for_non_stationary_models.py
index dbdd61e5..5ab36a43 100644
--- a/projects/altitude_spatial_model/altitudes_fit/one_fold_analysis/altitudes_studies_visualizer_for_non_stationary_models.py
+++ b/projects/altitude_spatial_model/altitudes_fit/one_fold_analysis/altitudes_studies_visualizer_for_non_stationary_models.py
@@ -192,9 +192,7 @@ class AltitudesStudiesVisualizerForNonStationaryModels(StudyVisualizer):
 
         if 'change' in method_name:
             plot_name = plot_name.replace(str_for_last_year, '')
-            add_str = ' between +${}^o\mathrm{C}$ and +${}^o\mathrm{C}$' if self.temporal_covariate_for_fit is AnomalyTemperatureTemporalCovariate \
-                else ' between {} and {}'
-            plot_name += add_str.format(self.first_one_fold_fit.covariate_before, self.first_one_fold_fit.covariate_after,  **d_temperature)
+            plot_name += self.first_one_fold_fit.between_covariate_str
 
             if 'relative' not in method_name:
                 # Put the relative score as text on the plot for the change.
@@ -481,7 +479,7 @@ class AltitudesStudiesVisualizerForNonStationaryModels(StudyVisualizer):
         percents = 100 * nbs / nb_valid_massif_names
         return [nb_valid_massif_names] + list(percents)
 
-    def all_changes(self, massif_names, relative=False):
+    def all_changes(self, massif_names, relative=False, with_significance=True):
         """return percents which contain decrease, significant decrease, increase, significant increase percentages"""
         valid_massif_names = self.get_valid_names(massif_names)
         changes = []
@@ -497,12 +495,16 @@ class AltitudesStudiesVisualizerForNonStationaryModels(StudyVisualizer):
             changes.append(change)
             if change != 0:
                 non_stationary_changes.append(change)
-                if one_fold.is_significant:
-                    non_stationary_significant_changes.append(change)
+                if with_significance:
+                    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
+        if with_significance:
+            return changes, non_stationary_changes, non_stationary_significant_changes
+        else:
+            return changes, non_stationary_changes
 
     def get_valid_names(self, massif_names):
         valid_massif_names = set(self.massif_name_to_one_fold_fit.keys())
diff --git a/projects/altitude_spatial_model/altitudes_fit/one_fold_analysis/one_fold_fit.py b/projects/altitude_spatial_model/altitudes_fit/one_fold_analysis/one_fold_fit.py
index 72045b2b..29fd516c 100644
--- a/projects/altitude_spatial_model/altitudes_fit/one_fold_analysis/one_fold_fit.py
+++ b/projects/altitude_spatial_model/altitudes_fit/one_fold_analysis/one_fold_fit.py
@@ -153,6 +153,15 @@ class OneFoldFit(object):
         else:
             raise NotImplementedError
 
+    @property
+    def between_covariate_str(self):
+        d_temperature = {'C': '{C}'}
+        s = ' between +${}^o\mathrm{C}$ and +${}^o\mathrm{C}$' if self.temporal_covariate_for_fit is AnomalyTemperatureTemporalCovariate \
+            else ' between {} and {}'
+        s = s.format(self.covariate_before, self.covariate_after,
+                                 **d_temperature)
+        return s
+
     def relative_changes_of_moment(self, altitudes, order=1):
         relative_changes = []
         for altitude in altitudes:
diff --git a/projects/altitude_spatial_model/altitudes_fit/plots/plot_histogram_altitude_studies.py b/projects/altitude_spatial_model/altitudes_fit/plots/plot_histogram_altitude_studies.py
index 2fc0942f..394d25f7 100644
--- a/projects/altitude_spatial_model/altitudes_fit/plots/plot_histogram_altitude_studies.py
+++ b/projects/altitude_spatial_model/altitudes_fit/plots/plot_histogram_altitude_studies.py
@@ -4,6 +4,9 @@ from typing import List
 import numpy as np
 
 import matplotlib
+
+from extreme_data.meteo_france_data.adamont_data.abstract_adamont_study import AbstractAdamontStudy
+
 matplotlib.use('Agg')
 import matplotlib.pyplot as plt
 
@@ -180,18 +183,19 @@ def plot_shoe_plot_ratio_interval_size_against_altitude(massif_names, visualizer
 
 def plot_shoe_plot_changes_against_altitude(massif_names, visualizer_list: List[
     AltitudesStudiesVisualizerForNonStationaryModels],
-                                            relative=False):
+                                            relative=False, with_significance=True):
     visualizer = visualizer_list[0]
 
-    all_changes = [v.all_changes(massif_names, relative=relative) for v in visualizer_list]
+    all_changes = [v.all_changes(massif_names, relative=relative, with_significance=with_significance) for v in visualizer_list]
     all_changes = list(zip(*all_changes))
     labels = ['All massifs', 'Massifs with a selected model\n'
                              'temporally non-stationary',
               'Massifs with a selected model\n'
               'temporally non-stationary and significant']
-    # colors = ['darkmagenta', 'darkviolet', 'mediumorchid']
-    # colors = ['mediumblue', 'royalblue', 'lightskyblue']
     colors = ['darkgreen', 'forestgreen', 'limegreen']
+    if not with_significance:
+        labels = labels[:-1]
+        colors = colors[:-1]
     nb_massifs = [len(v.get_valid_names(massif_names)) for v in visualizer_list]
 
     plt.close()
@@ -200,17 +204,6 @@ def plot_shoe_plot_changes_against_altitude(massif_names, visualizer_list: List[
     size = 8
     legend_fontsize = 10
     labelsize = 10
-    linewidth = 3
-
-    # x = np.array([4 * width * (i + 1) for i in range(len(nb_massifs))])
-    # for j, (changes, label, color) in enumerate(list(zip(all_changes, labels, colors)), -1):
-    #     positions = x + j * width
-    #     bplot = ax.boxplot(list(changes), positions=positions, widths=width, patch_artist=True, showmeans=True)
-    #     for patch in bplot['boxes']:
-    #         patch.set_facecolor(color)
-    # x = np.array([3 * width * (i + 1) for i in range(len(nb_massifs))])
-    # for j, (changes, label, color) in list(enumerate(list(zip(all_changes, labels, colors)), -1))[1:]:
-    #     positions = x + (j + 0.5) * width
 
     x = np.array([4 * width * (i + 1) for i in range(len(nb_massifs))])
     for j, (changes, label, color) in enumerate(list(zip(all_changes, labels, colors)), -1):
@@ -225,7 +218,8 @@ def plot_shoe_plot_changes_against_altitude(massif_names, visualizer_list: List[
 
     start = 'Relative changes' if relative else 'Changes'
     unit = '\%' if relative else visualizer.study.variable_unit
-    ax.set_ylabel('{} of {}-year return levels between 1959 and 2019 ({})'.format(start, OneFoldFit.return_period,
+    ax.set_ylabel('{} of {}-year return levels {} ({})'.format(start, OneFoldFit.return_period,
+                                                               visualizer.first_one_fold_fit.between_covariate_str,
                                                                                   unit),
                   fontsize=legend_fontsize)
     ax.set_xlabel('Elevation (m)', fontsize=legend_fontsize + 5)
@@ -238,9 +232,11 @@ def plot_shoe_plot_changes_against_altitude(massif_names, visualizer_list: List[
 
     shift = 2 * width
     ax.set_xlim((min(x) - shift, max(x) + shift))
-    upper_limit_for_legend = 50 if relative else 0
-    lim_down, lim_up = ax.get_ylim()
-    ax.set_ylim(lim_down, lim_up + upper_limit_for_legend)
+
+    if not isinstance(visualizer.study, AbstractAdamontStudy):
+        upper_limit_for_legend = 50 if relative else 0
+        lim_down, lim_up = ax.get_ylim()
+        ax.set_ylim(lim_down, lim_up + upper_limit_for_legend)
 
     # Plot a zero horizontal line
     lim_left, lim_right = ax.get_xlim()
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 37a5cdc3..74d80cc3 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
@@ -37,24 +37,24 @@ from extreme_data.meteo_france_data.scm_models_data.utils import Season
 
 def main():
     study_classes = [AdamontSnowfall][:1]
-    scenario = AdamontScenario.rcp85
+    scenario = AdamontScenario.rcp45
     gcm_rcm_couples = get_gcm_rcm_couples(scenario)
     ensemble_fit_class = [IndependentEnsembleFit]
     temporal_covariate_for_fit = [TimeTemporalCovariate, AnomalyTemperatureTemporalCovariate][1]
     set_seed_for_test()
     AbstractExtractEurocodeReturnLevel.ALPHA_CONFIDENCE_INTERVAL_UNCERTAINTY = 0.2
 
-    fast = False
+    fast = True
     if fast is None:
         massif_names = None
-        gcm_rcm_couples = gcm_rcm_couples[:1]
+        gcm_rcm_couples = gcm_rcm_couples[:2]
         AbstractExtractEurocodeReturnLevel.NB_BOOTSTRAP = 10
-        altitudes_list = altitudes_for_groups[1:2]
+        altitudes_list = altitudes_for_groups[:2]
     elif fast:
         AbstractExtractEurocodeReturnLevel.NB_BOOTSTRAP = 10
         massif_names = None
         gcm_rcm_couples = [('EC-EARTH', 'RACMO22E')]
-        altitudes_list = altitudes_for_groups[:1]
+        altitudes_list = altitudes_for_groups[1:2]
     else:
         massif_names = None
         altitudes_list = altitudes_for_groups[:]
@@ -72,8 +72,6 @@ def main_loop(gcm_rcm_couples, altitudes_list, massif_names, study_classes, ense
               temporal_covariate_for_fit):
     assert isinstance(altitudes_list, List)
     assert isinstance(altitudes_list[0], List)
-    gof_test = False
-    print('Goodness of fit test ?', gof_test)
     print('Covariate is {}'.format(temporal_covariate_for_fit))
     for study_class in study_classes:
         print('Inner loop', study_class)
@@ -86,8 +84,6 @@ def main_loop(gcm_rcm_couples, altitudes_list, massif_names, study_classes, ense
             ensemble_fit_classes=ensemble_fit_classes,
             massif_names=massif_names,
             temporal_covariate_for_fit=temporal_covariate_for_fit,
-            confidence_interval_based_on_delta_method=False,
-            display_only_model_that_pass_gof_test=gof_test,
             remove_physically_implausible_models=True,
         )
         visualizer.plot()
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 5c69fa54..79c75e4d 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
@@ -101,8 +101,8 @@ class MetaVisualizerForProjectionEnsemble(object):
                                for independent_ensemble_fit in self.ensemble_fits(IndependentEnsembleFit)
                                ]
             plot_histogram_all_trends_against_altitudes(self.massif_names, visualizer_list, with_significance=with_significance)
-            # for relative in [True, False]:
-            #     plot_shoe_plot_changes_against_altitude(self.massif_names, visualizer_list, relative=relative)
+            for relative in [True, False]:
+                plot_shoe_plot_changes_against_altitude(self.massif_names, visualizer_list, relative=relative, with_significance=with_significance)
 
     def ensemble_fits(self, ensemble_class):
         return [ensemble_class_to_ensemble_fit[ensemble_class]
diff --git a/root_utils.py b/root_utils.py
index 0b362aa3..1e1ce75e 100644
--- a/root_utils.py
+++ b/root_utils.py
@@ -1,4 +1,5 @@
 import datetime
+import math
 import os.path as op
 import subprocess
 
@@ -12,6 +13,11 @@ for c in [' ', ':', '-']:
 NB_CORES = 7
 
 
+def batch_nb_cores(iterable, nb_cores):
+    batchsize = math.ceil(len(iterable) / nb_cores)
+    return batch(iterable, batchsize)
+
+
 def batch(iterable, batchsize=1):
     l = len(iterable)
     for ndx in range(0, l, batchsize):
-- 
GitLab