diff --git a/experiment/paper_past_snow_loads/check_mle_convergence_for_trends/without_maximum/__init__.py b/experiment/paper_past_snow_loads/check_mle_convergence_for_trends/without_maximum/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/experiment/paper_past_snow_loads/check_mle_convergence_for_trends/without_maximum/main_fit_without_maximum.py b/experiment/paper_past_snow_loads/check_mle_convergence_for_trends/without_maximum/main_fit_without_maximum.py
new file mode 100644
index 0000000000000000000000000000000000000000..7184ee5786e451933be9f2e60dec5fda0a3d3bb2
--- /dev/null
+++ b/experiment/paper_past_snow_loads/check_mle_convergence_for_trends/without_maximum/main_fit_without_maximum.py
@@ -0,0 +1,20 @@
+from typing import Dict
+
+from experiment.meteo_france_data.scm_models_data.crocus.crocus import CrocusSnowLoadTotal
+from experiment.meteo_france_data.scm_models_data.visualization.study_visualization.main_study_visualizer import \
+    ALL_ALTITUDES_WITHOUT_NAN
+from experiment.paper_past_snow_loads.check_mle_convergence_for_trends.without_maximum.study_visualizer_for_fit_witout_maximum import \
+    StudyVisualizerForFitWithoutMaximum
+
+
+def fit_without_maximum_value(altitude_to_visualizer: Dict[int, StudyVisualizerForFitWithoutMaximum]):
+    for v in altitude_to_visualizer.values():
+        v.maximum_value_test()
+
+
+if __name__ == '__main__':
+    altitudes = ALL_ALTITUDES_WITHOUT_NAN[:]
+    altitude_to_visualizer = {altitude: StudyVisualizerForFitWithoutMaximum(CrocusSnowLoadTotal(altitude=altitude),
+                                                                            multiprocessing=True)
+                              for altitude in altitudes}
+    fit_without_maximum_value(altitude_to_visualizer)
diff --git a/experiment/paper_past_snow_loads/check_mle_convergence_for_trends/without_maximum/study_visualizer_for_fit_witout_maximum.py b/experiment/paper_past_snow_loads/check_mle_convergence_for_trends/without_maximum/study_visualizer_for_fit_witout_maximum.py
new file mode 100644
index 0000000000000000000000000000000000000000..898d5840556f9e4ab4da45f5f3164e5b9c1c858c
--- /dev/null
+++ b/experiment/paper_past_snow_loads/check_mle_convergence_for_trends/without_maximum/study_visualizer_for_fit_witout_maximum.py
@@ -0,0 +1,61 @@
+from typing import Dict, Tuple
+
+import matplotlib
+import numpy as np
+from cached_property import cached_property
+
+from experiment.meteo_france_data.plot.create_shifted_cmap import get_shifted_map
+from experiment.meteo_france_data.scm_models_data.abstract_study import AbstractStudy
+from experiment.paper_past_snow_loads.study_visualizer_for_non_stationary_trends import \
+    StudyVisualizerForNonStationaryTrends
+from experiment.trend_analysis.abstract_score import MeanScore
+
+
+class StudyVisualizerForFitWithoutMaximum(StudyVisualizerForNonStationaryTrends):
+
+    def __init__(self, study: AbstractStudy, **kwargs):
+        super().__init__(study, **kwargs)
+
+    @cached_property
+    def massif_name_to_maximum_index_for_non_null_values(self) -> Tuple[Dict, Dict]:
+        d = super().massif_name_to_non_null_years_and_maxima
+        d_without_maximum = {}
+        d_maximum = {}
+        for m, (years, maxima) in d.items():
+            idx = np.argmax(maxima)
+            maximum = maxima[idx]
+            maxima = np.delete(maxima, idx)
+            years = np.delete(years, idx)
+            d_without_maximum[m] = (years, maxima)
+            d_maximum[m] = maximum
+        return d_without_maximum, d_maximum
+
+    @property
+    def massif_name_to_maximum(self) -> Dict:
+        return self.massif_name_to_maximum_index_for_non_null_values[1]
+
+    @cached_property
+    def massif_name_to_non_null_years_and_maxima(self):
+        return self.massif_name_to_maximum_index_for_non_null_values[0]
+
+    def maximum_value_test(self):
+        diff = []
+        for massif_name, maximum in self.massif_name_to_maximum.items():
+            t = self.massif_name_to_trend_test_that_minimized_aic[massif_name]
+            msg = '{} {}m'.format(massif_name, self.study.altitude)
+            upper_bound = t.unconstrained_estimator_gev_params.density_upper_bound
+            if not np.isinf(upper_bound):
+                diff.append(upper_bound - maximum)
+            assert maximum <= upper_bound, msg
+        if len(diff) > 1:
+            print('{} mean difference={}'.format(self.study.altitude, min(diff)))
+
+
+
+
+
+
+
+
+
+
diff --git a/extreme_fit/distribution/gev/gev_params.py b/extreme_fit/distribution/gev/gev_params.py
index f19b54d2be18d3cf1bdea61cd63086b7ffeb6512..eb957c3564ba25d5c70edbe2261910caa5a62cf0 100644
--- a/extreme_fit/distribution/gev/gev_params.py
+++ b/extreme_fit/distribution/gev/gev_params.py
@@ -130,4 +130,22 @@ class GevParams(AbstractParams):
         if self.shape == 0:
             return x
         else:
-            return np.log(1 + self.shape * x) / self.shape
\ No newline at end of file
+            return np.log(1 + self.shape * x) / self.shape
+
+    @property
+    def bound(self):
+        return self.location - (self.scale / self.shape)
+
+    @property
+    def density_upper_bound(self):
+        if self.shape >= 0:
+            return np.inf
+        else:
+            return self.bound
+
+    @property
+    def density_lower_bound(self):
+        if self.shape <= 0:
+            return np.inf
+        else:
+            return self.bound
\ No newline at end of file