diff --git a/extreme_data/meteo_france_data/scm_models_data/abstract_study.py b/extreme_data/meteo_france_data/scm_models_data/abstract_study.py
index 9376dc8c6f680dc22c0ed24aca238869726cef5e..feaef969992ea98f44d21b7286a1d04133a73e29 100644
--- a/extreme_data/meteo_france_data/scm_models_data/abstract_study.py
+++ b/extreme_data/meteo_france_data/scm_models_data/abstract_study.py
@@ -100,8 +100,8 @@ class AbstractStudy(object):
         assert slope in SLOPES
         self.orientation = orientation
         self.slope = slope
-        # Add some options
-        self.fit_method = MarginFitMethod.is_mev_gev_fit
+        # Add some cache for computation
+        self._cache_for_pointwise_fit = {}
 
     """ Time """
 
@@ -878,11 +878,17 @@ class AbstractStudy(object):
         d, _ = self._massif_name_to_stationary_gev_params_and_confidence(quantile_level=None)
         return d
 
-    @cached_property
-    def massif_name_to_stationary_gev_params_and_confidence_for_return_level_100(self):
-        return self._massif_name_to_stationary_gev_params_and_confidence(quantile_level=0.99)
+    def massif_name_to_stationary_gev_params_and_confidence(self, quantile_level,
+                                                            confidence_interval_based_on_delta_method):
+        t = (quantile_level, confidence_interval_based_on_delta_method)
+        if t in self._cache_for_pointwise_fit:
+            return self._cache_for_pointwise_fit[t]
+        else:
+            res = self._massif_name_to_stationary_gev_params_and_confidence(*t)
+            self._cache_for_pointwise_fit[t] = res
+            return res
 
-    def _massif_name_to_stationary_gev_params_and_confidence(self, quantile_level=None):
+    def _massif_name_to_stationary_gev_params_and_confidence(self, quantile_level=None, confidence_interval_based_on_delta_method=True):
         """ at least 90% of values must be above zero"""
         massif_name_to_stationary_gev_params = {}
         massif_name_to_confidence = {}
@@ -891,7 +897,8 @@ class AbstractStudy(object):
             if percentage_of_non_zeros > 90:
                 gev_params, confidence = fitted_stationary_gev_with_uncertainty_interval(annual_maxima,
                                                                                          fit_method=MarginFitMethod.extremes_fevd_mle,
-                                                                                         quantile_level=quantile_level)
+                                                                                         quantile_level=quantile_level,
+                                                                                         confidence_interval_based_on_delta_method=confidence_interval_based_on_delta_method)
                 if -0.5 <= gev_params.shape <= 0.5:
                     massif_name_to_stationary_gev_params[massif_name] = gev_params
                     massif_name_to_confidence[massif_name] = confidence
diff --git a/extreme_data/meteo_france_data/scm_models_data/utils_function.py b/extreme_data/meteo_france_data/scm_models_data/utils_function.py
index ed545b2f6c1fc7351e05f62ee78b787d7046ae0f..58b2554094955c9dcfe979a1c3e362f9bd9276c5 100644
--- a/extreme_data/meteo_france_data/scm_models_data/utils_function.py
+++ b/extreme_data/meteo_france_data/scm_models_data/utils_function.py
@@ -1,22 +1,51 @@
+from multiprocessing import Pool
+
+import numpy as np
+from sklearn.utils import resample
+
 from extreme_fit.estimator.margin_estimator.utils import _fitted_stationary_gev
 from extreme_fit.model.margin_model.linear_margin_model.temporal_linear_margin_models import StationaryTemporalModel
 from extreme_fit.model.margin_model.utils import MarginFitMethod
+from extreme_fit.model.result_from_model_fit.result_from_extremes.abstract_extract_eurocode_return_level import \
+    AbstractExtractEurocodeReturnLevel
 from extreme_fit.model.result_from_model_fit.result_from_extremes.confidence_interval_method import \
     ConfidenceIntervalMethodFromExtremes
 from extreme_fit.model.result_from_model_fit.result_from_extremes.eurocode_return_level_uncertainties import \
     EurocodeConfidenceIntervalFromExtremes
+from root_utils import NB_CORES
 
 
 def fitted_stationary_gev_with_uncertainty_interval(x_gev, fit_method=MarginFitMethod.is_mev_gev_fit,
                                                     model_class=StationaryTemporalModel,
                                                     starting_year=None,
-                                                    quantile_level=0.98):
+                                                    quantile_level=0.98,
+                                                    confidence_interval_based_on_delta_method=True):
     estimator, gev_param = _fitted_stationary_gev(fit_method, model_class, starting_year, x_gev)
     if quantile_level is not None:
         EurocodeConfidenceIntervalFromExtremes.quantile_level = quantile_level
         coordinate = estimator.dataset.coordinates.df_all_coordinates.iloc[0].values
-        confidence_interval = EurocodeConfidenceIntervalFromExtremes.from_estimator_extremes(estimator, ConfidenceIntervalMethodFromExtremes.ci_mle,
-                                                                       coordinate)
+        if confidence_interval_based_on_delta_method:
+            confidence_interval = EurocodeConfidenceIntervalFromExtremes.from_estimator_extremes(estimator, ConfidenceIntervalMethodFromExtremes.ci_mle,
+                                                                           coordinate)
+        else:
+            # Bootstrap method
+            nb_bootstrap = AbstractExtractEurocodeReturnLevel.NB_BOOTSTRAP
+            x_gev_list = [resample(x_gev) for _ in range(nb_bootstrap)]
+            arguments = [(fit_method, model_class, starting_year, x, quantile_level) for x in x_gev_list]
+            multiprocess = True
+            if multiprocess:
+                with Pool(NB_CORES) as p:
+                    return_level_list = p.map(_compute_return_level, arguments)
+            else:
+                return_level_list = [_compute_return_level(argument) for argument in arguments]
+            confidence_interval = tuple([np.quantile(return_level_list, q)
+                                         for q in AbstractExtractEurocodeReturnLevel.bottom_and_upper_quantile])
+            mean_estimate = gev_param.quantile(quantile_level)
+            confidence_interval = EurocodeConfidenceIntervalFromExtremes(mean_estimate, confidence_interval)
     else:
         confidence_interval = None
     return gev_param, confidence_interval
+
+def _compute_return_level(t):
+    fit_method, model_class, starting_year, x, quantile_level = t
+    return _fitted_stationary_gev(fit_method, model_class, starting_year, x)[1].quantile(quantile_level)
\ No newline at end of file
diff --git a/extreme_fit/estimator/margin_estimator/abstract_margin_estimator.py b/extreme_fit/estimator/margin_estimator/abstract_margin_estimator.py
index f4791e07d45dd8e23303b6241191fe88ce2aeefd..f233fa0ae67efe0cd7d16f5984298ccdc6c8c93c 100644
--- a/extreme_fit/estimator/margin_estimator/abstract_margin_estimator.py
+++ b/extreme_fit/estimator/margin_estimator/abstract_margin_estimator.py
@@ -88,6 +88,18 @@ class LinearMarginEstimator(AbstractMarginEstimator):
         sorted_empirical_quantiles = sorted(sorted_empirical_quantiles)
         return sorted_empirical_quantiles
 
+    def coordinate_values_to_maxima_from_standard_gumbel_quantiles(self, standard_gumbel_quantiles, split=Split.all):
+        coordinate_values_to_maxima = {}
+        coordinate_values = self.dataset.df_coordinates(split=split).values
+        assert len(standard_gumbel_quantiles) == len(coordinate_values)
+        for quantile, coordinate in zip(standard_gumbel_quantiles, coordinate_values):
+            gev_param = self.function_from_fit.get_params(
+                coordinate=coordinate,
+                is_transformed=False)
+            maximum = gev_param.gumbel_inverse_standardization(quantile)
+            coordinate_values_to_maxima[tuple(coordinate)] = np.array([maximum])
+        return coordinate_values_to_maxima
+
     def deviance(self, split=Split.all):
         return 2 * self.nllh(split=split)
 
diff --git a/extreme_fit/model/result_from_model_fit/result_from_extremes/abstract_extract_eurocode_return_level.py b/extreme_fit/model/result_from_model_fit/result_from_extremes/abstract_extract_eurocode_return_level.py
index aa9b8afb76d6f61c76623a4041a7a546b7b750a6..ac2c6d9d213698a7d890f57120677dce18c74b43 100644
--- a/extreme_fit/model/result_from_model_fit/result_from_extremes/abstract_extract_eurocode_return_level.py
+++ b/extreme_fit/model/result_from_model_fit/result_from_extremes/abstract_extract_eurocode_return_level.py
@@ -16,6 +16,13 @@ from root_utils import classproperty
 
 class AbstractExtractEurocodeReturnLevel(object):
     ALPHA_CONFIDENCE_INTERVAL_UNCERTAINTY = 0.05
+    NB_BOOTSTRAP = 1000
+
+    @classproperty
+    def bottom_and_upper_quantile(cls):
+        bottom_quantile = cls.ALPHA_CONFIDENCE_INTERVAL_UNCERTAINTY / 2
+        bottom_and_upper_quantile = (bottom_quantile, 1 - bottom_quantile)
+        return bottom_and_upper_quantile
 
     def __init__(self, estimator: LinearMarginEstimator, ci_method, temporal_covariate, quantile_level=EUROCODE_QUANTILE):
         self.ci_method = ci_method
@@ -100,7 +107,5 @@ class ExtractEurocodeReturnLevelFromMyBayesianExtremes(AbstractExtractEurocodeRe
     @property
     def confidence_interval(self):
         # Bottom and upper quantile correspond to the quantile
-        bottom_quantile = self.ALPHA_CONFIDENCE_INTERVAL_UNCERTAINTY / 2
-        bottom_and_upper_quantile = (bottom_quantile, 1 - bottom_quantile)
         return [np.quantile(self.posterior_eurocode_return_level_samples_for_temporal_covariate, q=q)
-                for q in bottom_and_upper_quantile]
+                for q in self.bottom_and_upper_quantile]
diff --git a/projects/altitude_spatial_model/altitudes_fit/main_altitudes_studies.py b/projects/altitude_spatial_model/altitudes_fit/main_altitudes_studies.py
index be76e1c31dab2037ac1a1fc18282c19284efe92b..f0b704dfcd5e009ea0bb96e7c8a36aa3fbf037c7 100644
--- a/projects/altitude_spatial_model/altitudes_fit/main_altitudes_studies.py
+++ b/projects/altitude_spatial_model/altitudes_fit/main_altitudes_studies.py
@@ -4,6 +4,7 @@ from typing import List
 import matplotlib as mpl
 
 from extreme_data.meteo_france_data.scm_models_data.crocus.crocus import CrocusSnowLoadTotal, CrocusSnowLoad3Days
+from extreme_fit.model.utils import set_seed_for_test
 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, \
@@ -26,13 +27,15 @@ def main():
     study_classes = [SafranSnowfall1Day, SafranSnowfall3Days, SafranSnowfall5Days, SafranSnowfall7Days][:1]
     seasons = [Season.annual, Season.winter, Season.spring, Season.automn][:1]
 
-    fast = True
+    set_seed_for_test()
+
+    fast = None
     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[:]
+    elif fast:
+        massif_names = ['Vanoise', 'Haute-Maurienne', 'Vercors'][:1]
+        altitudes_list = altitudes_for_groups[3:]
     else:
         massif_names = None
         altitudes_list = altitudes_for_groups[:]
@@ -46,7 +49,8 @@ def main_loop(altitudes_list, massif_names, seasons, study_classes):
     for season in seasons:
         for study_class in study_classes:
             print('Inner loop', season, study_class)
-            visualizer_list = load_visualizer_list(season, study_class, altitudes_list, massif_names)
+            visualizer_list = load_visualizer_list(season, study_class, altitudes_list, massif_names
+                                                   )
             plot_visualizers(massif_names, visualizer_list)
             for visualizer in visualizer_list:
                 plot_visualizer(massif_names, visualizer)
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 8b7f57f6e0fec896c9a6e71fe4ed4bb8484c536d..f41da81eb03b1d8c973f7ad56e5a75b626ef4372 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
@@ -40,16 +40,18 @@ class AltitudesStudiesVisualizerForNonStationaryModels(StudyVisualizer):
                  fit_method=MarginFitMethod.extremes_fevd_mle,
                  temporal_covariate_for_fit=None,
                  display_only_model_that_pass_anderson_test=True,
+                 confidence_interval_based_on_delta_method=False
                  ):
         super().__init__(studies.study, show=show, save_to_file=not show)
         self.studies = 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_anderson_test = display_only_model_that_pass_anderson_test
+        self.display_only_model_that_pass_test = display_only_model_that_pass_anderson_test
         self.massif_names = massif_names if massif_names is not None else self.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(self.studies.altitudes)
+        self.confidence_interval_based_on_delta_method = confidence_interval_based_on_delta_method
         # Load one fold fit
         self.massif_name_to_massif_altitudes = {}
         self._massif_name_to_one_fold_fit = {}
@@ -64,7 +66,8 @@ class AltitudesStudiesVisualizerForNonStationaryModels(StudyVisualizer):
                 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_anderson_test)
+                                          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
@@ -103,7 +106,7 @@ class AltitudesStudiesVisualizerForNonStationaryModels(StudyVisualizer):
     @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_anderson_test
+                if not self.display_only_model_that_pass_test
                 or old_fold_fit.has_at_least_one_valid_model}
 
     def plot_moments(self):
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 35c892f12500108b5ba88c723ec94becc3a40ebb..82a1d73830059d01c6463d621dd6e982fdc588d8 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
@@ -1,8 +1,11 @@
+from multiprocessing import Pool
+
 import numpy.testing as npt
 import numpy as np
 import rpy2
 from cached_property import cached_property
 from scipy.stats import chi2
+from sklearn.utils import resample
 
 from extreme_fit.distribution.gev.gev_params import GevParams
 from extreme_fit.distribution.gumbel.gumbel_gof import goodness_of_fit_anderson
@@ -18,14 +21,18 @@ from extreme_fit.model.margin_model.polynomial_margin_model.gumbel_altitudinal_m
 from extreme_fit.model.margin_model.polynomial_margin_model.models_based_on_pariwise_analysis.gev_with_linear_shape_wrt_altitude import \
     AltitudinalShapeLinearTimeStationary
 from extreme_fit.model.margin_model.utils import MarginFitMethod
+from extreme_fit.model.result_from_model_fit.result_from_extremes.abstract_extract_eurocode_return_level import \
+    AbstractExtractEurocodeReturnLevel
 from extreme_fit.model.result_from_model_fit.result_from_extremes.confidence_interval_method import \
     ConfidenceIntervalMethodFromExtremes
 from extreme_fit.model.result_from_model_fit.result_from_extremes.eurocode_return_level_uncertainties import \
     EurocodeConfidenceIntervalFromExtremes
 from projects.altitude_spatial_model.altitudes_fit.one_fold_analysis.altitude_group import AbstractAltitudeGroup, \
     DefaultAltitudeGroup
-from root_utils import classproperty
+from root_utils import classproperty, NB_CORES
 from spatio_temporal_dataset.dataset.abstract_dataset import AbstractDataset
+from spatio_temporal_dataset.slicer.split import Split
+from spatio_temporal_dataset.spatio_temporal_observations.annual_maxima_observations import AnnualMaxima
 
 
 class OneFoldFit(object):
@@ -36,11 +43,14 @@ class OneFoldFit(object):
     nb_years = 60
 
     def __init__(self, massif_name: str, dataset: AbstractDataset, models_classes,
-                 fit_method=MarginFitMethod.extremes_fevd_mle, temporal_covariate_for_fit=None,
+                 fit_method=MarginFitMethod.extremes_fevd_mle,
+                 temporal_covariate_for_fit=None,
                  altitude_class=DefaultAltitudeGroup,
-                 only_models_that_pass_anderson_test=True,
+                 only_models_that_pass_goodness_of_fit_test=True,
+                 confidence_interval_based_on_delta_method=False,
                  ):
-        self.only_models_that_pass_anderson_test = only_models_that_pass_anderson_test
+        self.confidence_interval_based_on_delta_method = confidence_interval_based_on_delta_method
+        self.only_models_that_pass_goodness_of_fit_test = only_models_that_pass_goodness_of_fit_test
         self.altitude_group = altitude_class()
         self.massif_name = massif_name
         self.dataset = dataset
@@ -51,16 +61,19 @@ class OneFoldFit(object):
         # Fit Estimators
         self.model_class_to_estimator = {}
         for model_class in models_classes:
-            self.model_class_to_estimator[model_class] = fitted_linear_margin_estimator_short(model_class=model_class,
-                                                                                              dataset=self.dataset,
-                                                                                              fit_method=self.fit_method,
-                                                                                              temporal_covariate_for_fit=self.temporal_covariate_for_fit)
+            self.model_class_to_estimator[model_class] = self.fitted_linear_margin_estimator(model_class, self.dataset)
 
         # Best estimator definition
         self.best_estimator_class_for_total_aic = None
         # Cached object
         self._folder_to_goodness = {}
 
+    def fitted_linear_margin_estimator(self, model_class, dataset):
+        return fitted_linear_margin_estimator_short(model_class=model_class,
+                                                    dataset=dataset,
+                                                    fit_method=self.fit_method,
+                                                    temporal_covariate_for_fit=self.temporal_covariate_for_fit)
+
     @classproperty
     def folder_for_plots(cls):
         return 'Total aic/' if cls.best_estimator_minimizes_total_aic else ''
@@ -129,7 +142,7 @@ class OneFoldFit(object):
 
     @cached_property
     def sorted_estimators_with_stationary(self):
-        if self.only_models_that_pass_anderson_test:
+        if self.only_models_that_pass_goodness_of_fit_test:
             return [e for e in self.sorted_estimators
                     if self.goodness_of_fit_test(e)
                     # and self.sensitivity_of_fit_test_top_maxima(e)
@@ -148,7 +161,7 @@ class OneFoldFit(object):
 
     @cached_property
     def sorted_estimators_without_stationary(self):
-        if self.only_models_that_pass_anderson_test:
+        if self.only_models_that_pass_goodness_of_fit_test:
             return [e for e in self._sorted_estimators_without_stationary if self.goodness_of_fit_test(e)]
         else:
             return self._sorted_estimators_without_stationary
@@ -240,13 +253,22 @@ class OneFoldFit(object):
 
     @property
     def is_significant(self) -> bool:
-        stationary_model_classes = [StationaryAltitudinal, StationaryGumbelAltitudinal,
-                                    AltitudinalShapeLinearTimeStationary]
-        if any([isinstance(self.best_estimator.margin_model, c)
-                for c in stationary_model_classes]):
-            return False
+        if self.confidence_interval_based_on_delta_method:
+            stationary_model_classes = [StationaryAltitudinal, StationaryGumbelAltitudinal,
+                                        AltitudinalShapeLinearTimeStationary]
+            if any([isinstance(self.best_estimator.margin_model, c)
+                    for c in stationary_model_classes]):
+                return False
+            else:
+                return self.likelihood_ratio > chi2.ppf(q=1 - self.SIGNIFICANCE_LEVEL, df=self.degree_freedom_chi2)
         else:
-            return self.likelihood_ratio > chi2.ppf(q=1 - self.SIGNIFICANCE_LEVEL, df=self.degree_freedom_chi2)
+            # Bootstrap based significance
+            print('new significance is used')
+            sign_of_changes = [self.sign_of_change(f) for f in self.bootstrap_fitted_functions_from_fit]
+            if self.sign_of_change(self.best_function_from_fit) > 0:
+                return np.quantile(sign_of_changes, self.SIGNIFICANCE_LEVEL) > 0
+            else:
+                return np.quantile(sign_of_changes, 1 - self.SIGNIFICANCE_LEVEL) < 0
 
     # @property
     # def goodness_of_fit_anderson_test(self):
@@ -272,7 +294,7 @@ class OneFoldFit(object):
                                                              fit_method=self.fit_method,
                                                              temporal_covariate_for_fit=self.temporal_covariate_for_fit)
         # Compare sign of change
-        has_not_opposite_sign = self.sign_of_change(estimator) * self.sign_of_change(new_estimator) >= 0
+        has_not_opposite_sign = self.sign_of_change(estimator.function_from_fit) * self.sign_of_change(new_estimator.function_from_fit) >= 0
         return has_not_opposite_sign
 
     def sensitivity_of_fit_test_last_years(self, estimator: LinearMarginEstimator):
@@ -287,16 +309,16 @@ class OneFoldFit(object):
                                                              fit_method=self.fit_method,
                                                              temporal_covariate_for_fit=self.temporal_covariate_for_fit)
         # Compare sign of change
-        has_not_opposite_sign = self.sign_of_change(estimator) * self.sign_of_change(new_estimator) >= 0
+        has_not_opposite_sign = self.sign_of_change(estimator.function_from_fit) * self.sign_of_change(new_estimator.function_from_fit) >= 0
         # if not has_not_opposite_sign:
         # print('Last years', self.massif_name, model_class, self.sign_of_change(estimator), self.sign_of_change(new_estimator))
         return has_not_opposite_sign
 
-    def sign_of_change(self, estimator):
+    def sign_of_change(self, function_from_fit):
         return_levels = []
         for year in [2019 - self.nb_years, 2019]:
             coordinate = np.array([self.altitude_plot, year])
-            return_level = estimator.function_from_fit.get_params(
+            return_level = function_from_fit.get_params(
                 coordinate=coordinate,
                 is_transformed=False).return_level(return_period=self.return_period)
             return_levels.append(return_level)
@@ -314,7 +336,54 @@ class OneFoldFit(object):
         return standard_gumbel_quantiles
 
     def best_confidence_interval(self, altitude, year) -> EurocodeConfidenceIntervalFromExtremes:
-        EurocodeConfidenceIntervalFromExtremes.quantile_level = self.quantile_level
-        return EurocodeConfidenceIntervalFromExtremes.from_estimator_extremes(estimator_extremes=self.best_estimator,
-                                                                              ci_method=ConfidenceIntervalMethodFromExtremes.ci_mle,
-                                                                              coordinate=np.array([altitude, year]))
+        coordinate = np.array([altitude, year])
+        if self.confidence_interval_based_on_delta_method:
+            EurocodeConfidenceIntervalFromExtremes.quantile_level = self.quantile_level
+            return EurocodeConfidenceIntervalFromExtremes.from_estimator_extremes(
+                estimator_extremes=self.best_estimator,
+                ci_method=ConfidenceIntervalMethodFromExtremes.ci_mle,
+                coordinate=coordinate)
+        else:
+            print('nb of bootstrap for confidence interval=', AbstractExtractEurocodeReturnLevel.NB_BOOTSTRAP)
+            mean_estimate = self.get_return_level(self.best_function_from_fit, coordinate)
+            bootstrap_return_levels = [self.get_return_level(f, coordinate) for f in self.bootstrap_fitted_functions_from_fit]
+            print(mean_estimate, bootstrap_return_levels)
+            confidence_interval = tuple([np.quantile(bootstrap_return_levels, q)
+                                         for q in AbstractExtractEurocodeReturnLevel.bottom_and_upper_quantile])
+            print(mean_estimate, confidence_interval)
+            return EurocodeConfidenceIntervalFromExtremes(mean_estimate, confidence_interval)
+
+    def get_return_level(self, function_from_fit, coordinate):
+        return function_from_fit.get_params(coordinate).return_level(self.return_period)
+
+    @property
+    def bootstrap_data(self):
+        bootstrap = []
+        for _ in range(AbstractExtractEurocodeReturnLevel.NB_BOOTSTRAP):
+            residuals = self.best_estimator.sorted_empirical_standard_gumbel_quantiles(split=Split.all)
+            resample_residuals = resample(residuals)
+            coordinate_values_to_maxima = self.best_estimator. \
+                coordinate_values_to_maxima_from_standard_gumbel_quantiles(standard_gumbel_quantiles=resample_residuals)
+            bootstrap.append(coordinate_values_to_maxima)
+
+        return bootstrap
+
+    @cached_property
+    def bootstrap_fitted_functions_from_fit(self):
+        multiprocess = True
+        if multiprocess:
+            with Pool(NB_CORES) as p:
+                functions_from_fit = p.map(self.fit_one_bootstrap_estimator, self.bootstrap_data)
+        else:
+            functions_from_fit = []
+            for coordinate_values_to_maxima in self.bootstrap_data:
+                estimator = self.fit_one_bootstrap_estimator(coordinate_values_to_maxima)
+                functions_from_fit.append(estimator)
+        return functions_from_fit
+
+    def fit_one_bootstrap_estimator(self, coordinate_values_to_maxima):
+        coordinates = self.dataset.coordinates
+        observations = AnnualMaxima.from_coordinates(coordinates, coordinate_values_to_maxima)
+        dataset = AbstractDataset(observations=observations, coordinates=coordinates)
+        model_class = type(self.best_margin_model)
+        return self.fitted_linear_margin_estimator(model_class, dataset).function_from_fit
diff --git a/projects/altitude_spatial_model/altitudes_fit/plots/plot_coherence_curves.py b/projects/altitude_spatial_model/altitudes_fit/plots/plot_coherence_curves.py
index 7e47ac6edc0622b8bd379672c8ec6957ae0b6f27..9b7c74c7915bdacf1285bacb46df1024446e1148 100644
--- a/projects/altitude_spatial_model/altitudes_fit/plots/plot_coherence_curves.py
+++ b/projects/altitude_spatial_model/altitudes_fit/plots/plot_coherence_curves.py
@@ -126,23 +126,32 @@ def load_all_list(massif_name, visualizer_list, altitudinal_model=True, year=201
 
         if massif_name in visualizer.massif_name_to_one_fold_fit:
             if altitudinal_model:
+                # Piecewise altitudinal temporal model
                 min_altitude, *_, max_altitude = visualizer.massif_name_to_massif_altitudes[massif_name]
                 one_fold_fit = visualizer.massif_name_to_one_fold_fit[massif_name]
-                altitudes_list = list(range(min_altitude, max_altitude, 10))
+                step = 300
+                altitudes_list = list(range(min_altitude, max_altitude + step, step))
                 gev_params_list = [one_fold_fit.get_gev_params(altitude, year) for altitude in altitudes_list]
                 confidence_interval_values = [one_fold_fit.best_confidence_interval(altitude, year) for altitude in
                                               altitudes_list]
             else:
+                # Pointwise distribution
                 assert OneFoldFit.return_period == 100, 'change the call below'
                 altitudes_list, study_list_valid = zip(*[(a, s) for a, s in visualizer.studies.altitude_to_study.items()
                                                          if massif_name in
-                                                         s.massif_name_to_stationary_gev_params_and_confidence_for_return_level_100[
+                                                         s.massif_name_to_stationary_gev_params_and_confidence
+                                                             (OneFoldFit.quantile_level,
+                                                             visualizer.confidence_interval_based_on_delta_method)[
                                                              0]])
                 gev_params_list = [
-                    study.massif_name_to_stationary_gev_params_and_confidence_for_return_level_100[0][massif_name]
+                    study.massif_name_to_stationary_gev_params_and_confidence
+                                                             (OneFoldFit.quantile_level,
+                                                             visualizer.confidence_interval_based_on_delta_method)[0][massif_name]
                     for study in study_list_valid]
                 confidence_interval_values = [
-                    study.massif_name_to_stationary_gev_params_and_confidence_for_return_level_100[1][massif_name]
+                    study.massif_name_to_stationary_gev_params_and_confidence
+                                                             (OneFoldFit.quantile_level,
+                                                             visualizer.confidence_interval_based_on_delta_method)[1][massif_name]
                     for study in study_list_valid]
 
             # Checks
diff --git a/projects/altitude_spatial_model/altitudes_fit/utils_altitude_studies_visualizer.py b/projects/altitude_spatial_model/altitudes_fit/utils_altitude_studies_visualizer.py
index 3eaf91fece20944a2fda1dd21d8fb637bbc8eb65..9ce6d3825a4c8f521016fcbbabe578c3bc835f53 100644
--- a/projects/altitude_spatial_model/altitudes_fit/utils_altitude_studies_visualizer.py
+++ b/projects/altitude_spatial_model/altitudes_fit/utils_altitude_studies_visualizer.py
@@ -16,6 +16,7 @@ def load_visualizer_list(season, study_class, altitudes_list, massif_names, **kw
                                                                       massif_names=massif_names,
                                                                       show=False,
                                                                       temporal_covariate_for_fit=None,
+                                                                      confidence_interval_based_on_delta_method=False
                                                                       )
         visualizer_list.append(visualizer)
     compute_and_assign_max_abs(visualizer_list)