From fd5c724191a32146b6266e2423c94cc69a57cde7 Mon Sep 17 00:00:00 2001 From: Le Roux Erwan <erwan.le-roux@irstea.fr> Date: Mon, 14 Sep 2020 16:24:38 +0200 Subject: [PATCH] [contrasting] improve pointwise study. add new models based on this study. add altitude_group.py --- .../visualization/plot_utils.py | 34 +++-- .../gev_altitudinal_models.py | 59 +++++--- .../__init__.py | 0 .../cross terms/__init__.py | 0 .../cross terms/gev_with_loc_cross_term.py | 91 ++++++++++++ .../cross terms/gev_with_scale_cross_term.py | 91 ++++++++++++ .../cross terms/gev_with_shape_cross_term.py | 91 ++++++++++++ .../gev_with_constant_shape_wrt_altitude.py | 130 +++++++++++++++++ .../gev_with_linear_shape_wrt_altitude.py | 136 ++++++++++++++++++ .../polynomial_margin_model/utils.py | 55 ++++--- .../altitudes_fit/main_altitudes_studies.py | 14 +- .../one_fold_analysis/altitude_group.py | 28 ++++ ...es_visualizer_for_non_stationary_models.py | 11 +- .../one_fold_analysis/one_fold_fit.py | 10 +- .../one_fold_analysis/plot_total_aic.py | 10 +- .../snowfall_plot.py | 2 +- .../pointwise_gev_study_visualizer.py | 110 ++++++++++++-- 17 files changed, 792 insertions(+), 80 deletions(-) create mode 100644 extreme_fit/model/margin_model/polynomial_margin_model/models_based_on_pariwise_analysis/__init__.py create mode 100644 extreme_fit/model/margin_model/polynomial_margin_model/models_based_on_pariwise_analysis/cross terms/__init__.py create mode 100644 extreme_fit/model/margin_model/polynomial_margin_model/models_based_on_pariwise_analysis/cross terms/gev_with_loc_cross_term.py create mode 100644 extreme_fit/model/margin_model/polynomial_margin_model/models_based_on_pariwise_analysis/cross terms/gev_with_scale_cross_term.py create mode 100644 extreme_fit/model/margin_model/polynomial_margin_model/models_based_on_pariwise_analysis/cross terms/gev_with_shape_cross_term.py create mode 100644 extreme_fit/model/margin_model/polynomial_margin_model/models_based_on_pariwise_analysis/gev_with_constant_shape_wrt_altitude.py create mode 100644 extreme_fit/model/margin_model/polynomial_margin_model/models_based_on_pariwise_analysis/gev_with_linear_shape_wrt_altitude.py create mode 100644 projects/altitude_spatial_model/altitudes_fit/one_fold_analysis/altitude_group.py 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 0c22e10d..f94aa78a 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 @@ -7,25 +7,31 @@ from extreme_data.meteo_france_data.scm_models_data.visualization.create_shifted get_half_colormap -def plot_against_altitude(altitudes, ax, massif_id, massif_name, values, fill=False): - di = massif_id // 8 - if di == 0: - linestyle = '-' - elif di == 1: - linestyle = 'dotted' +def plot_against_altitude(x_ticks, ax, massif_id, massif_name, values, altitude=None, fill=False, massif_name_as_labels=True): + 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 else: - linestyle = '--' - colors = list(mcolors.TABLEAU_COLORS) - colors[-3:-1] = [] # remove gray and olive - color = colors[massif_id % 8] - massif_name_str = ' '.join(massif_name.split('_')) - label = massif_name_str + color = None + linestyle = None + label = '{} m'.format(altitude) if not fill: - ax.plot(altitudes, values, color=color, linewidth=2, label=label, linestyle=linestyle) + ax.plot(x_ticks, values, color=color, linewidth=2, label=label, linestyle=linestyle) else: lower_bound, upper_bound = zip(*values) # ax.fill_between(altitudes, lower_bound, upper_bound, color=color, alpha=0.2, label=label + '95\% confidence interval') - ax.fill_between(altitudes, lower_bound, upper_bound, color=color, alpha=0.2) + ax.fill_between(x_ticks, lower_bound, upper_bound, color=color, alpha=0.2) def load_plot(cmap, graduation, label, massif_name_to_value, altitude, fit_method, add_x_label=True, diff --git a/extreme_fit/model/margin_model/polynomial_margin_model/gev_altitudinal_models.py b/extreme_fit/model/margin_model/polynomial_margin_model/gev_altitudinal_models.py index 547f39f1..0ee8a285 100644 --- a/extreme_fit/model/margin_model/polynomial_margin_model/gev_altitudinal_models.py +++ b/extreme_fit/model/margin_model/polynomial_margin_model/gev_altitudinal_models.py @@ -34,16 +34,18 @@ class AbstractAltitudinalModel(AbstractSpatioTemporalPolynomialModel): @property def name_str(self): - name = self.DISTRIBUTION_STR - name += self.dim_to_str_number(GevParams.LOC, self.coordinates.idx_temporal_coordinates) - name += self.dim_to_str_number(GevParams.SCALE, self.coordinates.idx_temporal_coordinates) - shape_str_number = self.dim_to_str_number(GevParams.SHAPE, self.coordinates.idx_temporal_coordinates) - if shape_str_number != '0': - name += shape_str_number - if isinstance(self, AbstractAddCrossTermForLocation): - name += 'x' - if isinstance(self, AbstractAddCrossTermForScale): - name += 's' + name = '' + for coordinate_name, idx in zip(['s', 't'], [self.coordinates.idx_x_coordinates, self.coordinates.idx_temporal_coordinates]): + name += coordinate_name + for param_name in GevParams.PARAM_NAMES: + name += self.dim_to_str_number(param_name, idx) + if isinstance(self, AbstractAddCrossTerm): + name += 'sxt' + for c in [AbstractAddCrossTermForLocation, AbstractAddCrossTermForScale, AbstractAddCrossTermForShape]: + if isinstance(self, c): + name += '1' + else: + name += '0' return name @@ -86,6 +88,7 @@ class NonStationaryAltitudinalLocationQuadratic(AbstractAltitudinalModel): GevParams.SCALE: [(self.coordinates.idx_x_coordinates, 1)] } + class NonStationaryAltitudinalLocationCubic(AbstractAltitudinalModel): @property @@ -95,6 +98,7 @@ class NonStationaryAltitudinalLocationCubic(AbstractAltitudinalModel): GevParams.SCALE: [(self.coordinates.idx_x_coordinates, 1)] } + class NonStationaryAltitudinalLocationOrder4(AbstractAltitudinalModel): @property @@ -127,7 +131,10 @@ class NonStationaryAltitudinalLocationQuadraticScaleLinear(AbstractAltitudinalMo # Add cross terms -class AbstractAddCrossTermForLocation(AbstractAltitudinalModel): +class AbstractAddCrossTerm(AbstractAltitudinalModel): + pass + +class AbstractAddCrossTermForLocation(AbstractAddCrossTerm): # @property # def param_name_to_list_dim_and_degree_for_margin_function(self): @@ -147,7 +154,8 @@ class AbstractAddCrossTermForLocation(AbstractAltitudinalModel): d[GevParams.LOC] = [cross_term] return d -class AbstractAddCrossTermForScale(AbstractAltitudinalModel): + +class AbstractAddCrossTermForScale(AbstractAddCrossTerm): @property def param_name_to_list_dim_and_degree_for_margin_function(self): @@ -156,10 +164,27 @@ class AbstractAddCrossTermForScale(AbstractAltitudinalModel): assert 1 <= len(d[GevParams.SCALE]) <= 2 assert self.coordinates.idx_x_coordinates == d[GevParams.SCALE][0][0] insert_index = 1 - d[GevParams.SCALE].insert(insert_index, ((self.coordinates.idx_x_coordinates, self.coordinates.idx_temporal_coordinates), 1)) + d[GevParams.SCALE].insert(insert_index, + ((self.coordinates.idx_x_coordinates, self.coordinates.idx_temporal_coordinates), 1)) return d +class AbstractAddCrossTermForShape(AbstractAddCrossTerm): + + @property + def param_name_to_list_dim_and_degree_for_margin_function(self): + d = self.param_name_to_list_dim_and_degree + # The two insert below enable to check that the insert_index should indeed be 1 + # assert 1 <= len(d[GevParams.SHAPE]) <= 2 + # assert self.coordinates.idx_x_coordinates == d[GevParams.SHAPE][0][0] + if GevParams.SHAPE in d: + insert_index = 1 if self.coordinates.idx_x_coordinates == d[GevParams.SHAPE][0][0] else 0 + d[GevParams.SHAPE].insert(insert_index, + ((self.coordinates.idx_x_coordinates, self.coordinates.idx_temporal_coordinates), 1)) + else: + d[GevParams.SHAPE] = [((self.coordinates.idx_x_coordinates, self.coordinates.idx_temporal_coordinates), 1)] + return d + class NonStationaryCrossTermForLocation(AbstractAddCrossTermForLocation, StationaryAltitudinal): pass @@ -174,16 +199,19 @@ class NonStationaryAltitudinalLocationQuadraticCrossTermForLocation(AbstractAddC NonStationaryAltitudinalLocationQuadratic): pass + class NonStationaryAltitudinalLocationCubicCrossTermForLocation(AbstractAddCrossTermForLocation, NonStationaryAltitudinalLocationCubic, ): pass + class NonStationaryAltitudinalLocationOrder4CrossTermForLocation(AbstractAddCrossTermForLocation, - NonStationaryAltitudinalLocationOrder4, - ): + NonStationaryAltitudinalLocationOrder4, + ): pass + class NonStationaryAltitudinalLocationLinearScaleLinearCrossTermForLocation(AbstractAddCrossTermForLocation, NonStationaryAltitudinalLocationLinearScaleLinear): pass @@ -197,4 +225,3 @@ class NonStationaryAltitudinalLocationQuadraticScaleLinearCrossTermForLocation(A class NonStationaryAltitudinalScaleLinearCrossTermForLocation(AbstractAddCrossTermForLocation, NonStationaryAltitudinalScaleLinear): pass - diff --git a/extreme_fit/model/margin_model/polynomial_margin_model/models_based_on_pariwise_analysis/__init__.py b/extreme_fit/model/margin_model/polynomial_margin_model/models_based_on_pariwise_analysis/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/extreme_fit/model/margin_model/polynomial_margin_model/models_based_on_pariwise_analysis/cross terms/__init__.py b/extreme_fit/model/margin_model/polynomial_margin_model/models_based_on_pariwise_analysis/cross terms/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/extreme_fit/model/margin_model/polynomial_margin_model/models_based_on_pariwise_analysis/cross terms/gev_with_loc_cross_term.py b/extreme_fit/model/margin_model/polynomial_margin_model/models_based_on_pariwise_analysis/cross terms/gev_with_loc_cross_term.py new file mode 100644 index 00000000..732ee63a --- /dev/null +++ b/extreme_fit/model/margin_model/polynomial_margin_model/models_based_on_pariwise_analysis/cross terms/gev_with_loc_cross_term.py @@ -0,0 +1,91 @@ +from extreme_fit.model.margin_model.polynomial_margin_model.gev_altitudinal_models import AbstractAddCrossTermForLocation, \ + StationaryAltitudinal +from extreme_fit.model.margin_model.polynomial_margin_model.models_based_on_pariwise_analysis.gev_with_constant_shape_wrt_altitude import \ + AltitudinalShapeConstantTimeLocationLinear, AltitudinalShapeConstantTimeScaleLinear, \ + AltitudinalShapeConstantTimeShapeLinear, AltitudinalShapeConstantTimeLocShapeLinear, \ + AltitudinalShapeConstantTimeScaleShapeLinear, AltitudinalShapeConstantTimeLocScaleLinear, \ + AltitudinalShapeConstantTimeLocScaleShapeLinear +from extreme_fit.model.margin_model.polynomial_margin_model.models_based_on_pariwise_analysis.gev_with_linear_shape_wrt_altitude import \ + AltitudinalShapeLinearTimeLocScaleLinear, AltitudinalShapeLinearTimeLocationLinear, \ + AltitudinalShapeLinearTimeScaleLinear, AltitudinalShapeLinearTimeShapeLinear, \ + AltitudinalShapeLinearTimeLocShapeLinear, AltitudinalShapeLinearTimeScaleShapeLinear, \ + AltitudinalShapeLinearTimeLocScaleShapeLinear, AltitudinalShapeLinearTimeStationary + + +class StationaryAltitudinalCrossTermLoc(AbstractAddCrossTermForLocation, StationaryAltitudinal): + pass + + +class AltitudinalShapeConstantTimeLocationLinearCrossTermLoc(AbstractAddCrossTermForLocation, + AltitudinalShapeConstantTimeLocationLinear): + pass + + +class AltitudinalShapeConstantTimeScaleLinearCrossTermLoc(AbstractAddCrossTermForLocation, + AltitudinalShapeConstantTimeScaleLinear): + pass + + +class AltitudinalShapeConstantTimeShapeLinearCrossTermLoc(AbstractAddCrossTermForLocation, + AltitudinalShapeConstantTimeShapeLinear): + pass + + +class AltitudinalShapeConstantTimeLocShapeLinearCrossTermLoc(AbstractAddCrossTermForLocation, + AltitudinalShapeConstantTimeLocShapeLinear): + pass + + +class AltitudinalShapeConstantTimeScaleShapeLinearCrossTermLoc(AbstractAddCrossTermForLocation, + AltitudinalShapeConstantTimeScaleShapeLinear): + pass + + +class AltitudinalShapeConstantTimeLocScaleLinearCrossTermLoc(AbstractAddCrossTermForLocation, + AltitudinalShapeConstantTimeLocScaleLinear): + pass + + +class AltitudinalShapeConstantTimeLocScaleShapeLinearCrossTermLoc(AbstractAddCrossTermForLocation, + AltitudinalShapeConstantTimeLocScaleShapeLinear): + pass + + +class AltitudinalShapeLinearTimeStationaryCrossTermLoc(AbstractAddCrossTermForLocation, + AltitudinalShapeLinearTimeStationary): + pass + + +class AltitudinalShapeLinearTimeLocationLinearCrossTermLoc(AbstractAddCrossTermForLocation, + AltitudinalShapeLinearTimeLocationLinear): + pass + + +class AltitudinalShapeLinearTimeScaleLinearCrossTermLoc(AbstractAddCrossTermForLocation, + AltitudinalShapeLinearTimeScaleLinear): + pass + + +class AltitudinalShapeLinearTimeShapeLinearCrossTermLoc(AbstractAddCrossTermForLocation, + AltitudinalShapeLinearTimeShapeLinear): + pass + + +class AltitudinalShapeLinearTimeLocShapeLinearCrossTermLoc(AbstractAddCrossTermForLocation, + AltitudinalShapeLinearTimeLocShapeLinear): + pass + + +class AltitudinalShapeLinearTimeLocScaleLinearCrossTermLoc(AbstractAddCrossTermForLocation, + AltitudinalShapeLinearTimeLocScaleLinear): + pass + + +class AltitudinalShapeLinearTimeScaleShapeLinearCrossTermLoc(AbstractAddCrossTermForLocation, + AltitudinalShapeLinearTimeScaleShapeLinear): + pass + + +class AltitudinalShapeLinearTimeLocScaleShapeLinearCrossTermLoc(AbstractAddCrossTermForLocation, + AltitudinalShapeLinearTimeLocScaleShapeLinear): + pass diff --git a/extreme_fit/model/margin_model/polynomial_margin_model/models_based_on_pariwise_analysis/cross terms/gev_with_scale_cross_term.py b/extreme_fit/model/margin_model/polynomial_margin_model/models_based_on_pariwise_analysis/cross terms/gev_with_scale_cross_term.py new file mode 100644 index 00000000..9767235a --- /dev/null +++ b/extreme_fit/model/margin_model/polynomial_margin_model/models_based_on_pariwise_analysis/cross terms/gev_with_scale_cross_term.py @@ -0,0 +1,91 @@ +from extreme_fit.model.margin_model.polynomial_margin_model.gev_altitudinal_models import AbstractAddCrossTermForScale, \ + StationaryAltitudinal +from extreme_fit.model.margin_model.polynomial_margin_model.models_based_on_pariwise_analysis.gev_with_constant_shape_wrt_altitude import \ + AltitudinalShapeConstantTimeLocationLinear, AltitudinalShapeConstantTimeScaleLinear, \ + AltitudinalShapeConstantTimeShapeLinear, AltitudinalShapeConstantTimeLocShapeLinear, \ + AltitudinalShapeConstantTimeScaleShapeLinear, AltitudinalShapeConstantTimeLocScaleLinear, \ + AltitudinalShapeConstantTimeLocScaleShapeLinear +from extreme_fit.model.margin_model.polynomial_margin_model.models_based_on_pariwise_analysis.gev_with_linear_shape_wrt_altitude import \ + AltitudinalShapeLinearTimeLocScaleLinear, AltitudinalShapeLinearTimeLocationLinear, \ + AltitudinalShapeLinearTimeScaleLinear, AltitudinalShapeLinearTimeShapeLinear, \ + AltitudinalShapeLinearTimeLocShapeLinear, AltitudinalShapeLinearTimeScaleShapeLinear, \ + AltitudinalShapeLinearTimeLocScaleShapeLinear, AltitudinalShapeLinearTimeStationary + + +class StationaryAltitudinalCrossTermScale(AbstractAddCrossTermForScale, StationaryAltitudinal): + pass + + +class AltitudinalShapeConstantTimeLocationLinearCrossTermScale(AbstractAddCrossTermForScale, + AltitudinalShapeConstantTimeLocationLinear): + pass + + +class AltitudinalShapeConstantTimeScaleLinearCrossTermScale(AbstractAddCrossTermForScale, + AltitudinalShapeConstantTimeScaleLinear): + pass + + +class AltitudinalShapeConstantTimeShapeLinearCrossTermScale(AbstractAddCrossTermForScale, + AltitudinalShapeConstantTimeShapeLinear): + pass + + +class AltitudinalShapeConstantTimeLocShapeLinearCrossTermScale(AbstractAddCrossTermForScale, + AltitudinalShapeConstantTimeLocShapeLinear): + pass + + +class AltitudinalShapeConstantTimeScaleShapeLinearCrossTermScale(AbstractAddCrossTermForScale, + AltitudinalShapeConstantTimeScaleShapeLinear): + pass + + +class AltitudinalShapeConstantTimeLocScaleLinearCrossTermScale(AbstractAddCrossTermForScale, + AltitudinalShapeConstantTimeLocScaleLinear): + pass + + +class AltitudinalShapeConstantTimeLocScaleShapeLinearCrossTermScale(AbstractAddCrossTermForScale, + AltitudinalShapeConstantTimeLocScaleShapeLinear): + pass + + +class AltitudinalShapeLinearTimeStationaryCrossTermScale(AbstractAddCrossTermForScale, + AltitudinalShapeLinearTimeStationary): + pass + + +class AltitudinalShapeLinearTimeLocationLinearCrossTermScale(AbstractAddCrossTermForScale, + AltitudinalShapeLinearTimeLocationLinear): + pass + + +class AltitudinalShapeLinearTimeScaleLinearCrossTermScale(AbstractAddCrossTermForScale, + AltitudinalShapeLinearTimeScaleLinear): + pass + + +class AltitudinalShapeLinearTimeShapeLinearCrossTermScale(AbstractAddCrossTermForScale, + AltitudinalShapeLinearTimeShapeLinear): + pass + + +class AltitudinalShapeLinearTimeLocShapeLinearCrossTermScale(AbstractAddCrossTermForScale, + AltitudinalShapeLinearTimeLocShapeLinear): + pass + + +class AltitudinalShapeLinearTimeLocScaleLinearCrossTermScale(AbstractAddCrossTermForScale, + AltitudinalShapeLinearTimeLocScaleLinear): + pass + + +class AltitudinalShapeLinearTimeScaleShapeLinearCrossTermScale(AbstractAddCrossTermForScale, + AltitudinalShapeLinearTimeScaleShapeLinear): + pass + + +class AltitudinalShapeLinearTimeLocScaleShapeLinearCrossTermScale(AbstractAddCrossTermForScale, + AltitudinalShapeLinearTimeLocScaleShapeLinear): + pass diff --git a/extreme_fit/model/margin_model/polynomial_margin_model/models_based_on_pariwise_analysis/cross terms/gev_with_shape_cross_term.py b/extreme_fit/model/margin_model/polynomial_margin_model/models_based_on_pariwise_analysis/cross terms/gev_with_shape_cross_term.py new file mode 100644 index 00000000..281388d4 --- /dev/null +++ b/extreme_fit/model/margin_model/polynomial_margin_model/models_based_on_pariwise_analysis/cross terms/gev_with_shape_cross_term.py @@ -0,0 +1,91 @@ +from extreme_fit.model.margin_model.polynomial_margin_model.gev_altitudinal_models import AbstractAddCrossTermForShape, \ + StationaryAltitudinal +from extreme_fit.model.margin_model.polynomial_margin_model.models_based_on_pariwise_analysis.gev_with_constant_shape_wrt_altitude import \ + AltitudinalShapeConstantTimeLocationLinear, AltitudinalShapeConstantTimeScaleLinear, \ + AltitudinalShapeConstantTimeShapeLinear, AltitudinalShapeConstantTimeLocShapeLinear, \ + AltitudinalShapeConstantTimeScaleShapeLinear, AltitudinalShapeConstantTimeLocScaleLinear, \ + AltitudinalShapeConstantTimeLocScaleShapeLinear +from extreme_fit.model.margin_model.polynomial_margin_model.models_based_on_pariwise_analysis.gev_with_linear_shape_wrt_altitude import \ + AltitudinalShapeLinearTimeLocScaleLinear, AltitudinalShapeLinearTimeLocationLinear, \ + AltitudinalShapeLinearTimeScaleLinear, AltitudinalShapeLinearTimeShapeLinear, \ + AltitudinalShapeLinearTimeLocShapeLinear, AltitudinalShapeLinearTimeScaleShapeLinear, \ + AltitudinalShapeLinearTimeLocScaleShapeLinear, AltitudinalShapeLinearTimeStationary + + +class StationaryAltitudinalCrossTermShape(AbstractAddCrossTermForShape, StationaryAltitudinal): + pass + + +class AltitudinalShapeConstantTimeLocationLinearCrossTermShape(AbstractAddCrossTermForShape, + AltitudinalShapeConstantTimeLocationLinear): + pass + + +class AltitudinalShapeConstantTimeScaleLinearCrossTermShape(AbstractAddCrossTermForShape, + AltitudinalShapeConstantTimeScaleLinear): + pass + + +class AltitudinalShapeConstantTimeShapeLinearCrossTermShape(AbstractAddCrossTermForShape, + AltitudinalShapeConstantTimeShapeLinear): + pass + + +class AltitudinalShapeConstantTimeLocShapeLinearCrossTermShape(AbstractAddCrossTermForShape, + AltitudinalShapeConstantTimeLocShapeLinear): + pass + + +class AltitudinalShapeConstantTimeScaleShapeLinearCrossTermShape(AbstractAddCrossTermForShape, + AltitudinalShapeConstantTimeScaleShapeLinear): + pass + + +class AltitudinalShapeConstantTimeLocScaleLinearCrossTermShape(AbstractAddCrossTermForShape, + AltitudinalShapeConstantTimeLocScaleLinear): + pass + + +class AltitudinalShapeConstantTimeLocScaleShapeLinearCrossTermShape(AbstractAddCrossTermForShape, + AltitudinalShapeConstantTimeLocScaleShapeLinear): + pass + + +class AltitudinalShapeLinearTimeStationaryCrossTermShape(AbstractAddCrossTermForShape, + AltitudinalShapeLinearTimeStationary): + pass + + +class AltitudinalShapeLinearTimeLocationLinearCrossTermShape(AbstractAddCrossTermForShape, + AltitudinalShapeLinearTimeLocationLinear): + pass + + +class AltitudinalShapeLinearTimeScaleLinearCrossTermShape(AbstractAddCrossTermForShape, + AltitudinalShapeLinearTimeScaleLinear): + pass + + +class AltitudinalShapeLinearTimeShapeLinearCrossTermShape(AbstractAddCrossTermForShape, + AltitudinalShapeLinearTimeShapeLinear): + pass + + +class AltitudinalShapeLinearTimeLocShapeLinearCrossTermShape(AbstractAddCrossTermForShape, + AltitudinalShapeLinearTimeLocShapeLinear): + pass + + +class AltitudinalShapeLinearTimeLocScaleLinearCrossTermShape(AbstractAddCrossTermForShape, + AltitudinalShapeLinearTimeLocScaleLinear): + pass + + +class AltitudinalShapeLinearTimeScaleShapeLinearCrossTermShape(AbstractAddCrossTermForShape, + AltitudinalShapeLinearTimeScaleShapeLinear): + pass + + +class AltitudinalShapeLinearTimeLocScaleShapeLinearCrossTermShape(AbstractAddCrossTermForShape, + AltitudinalShapeLinearTimeLocScaleShapeLinear): + pass diff --git a/extreme_fit/model/margin_model/polynomial_margin_model/models_based_on_pariwise_analysis/gev_with_constant_shape_wrt_altitude.py b/extreme_fit/model/margin_model/polynomial_margin_model/models_based_on_pariwise_analysis/gev_with_constant_shape_wrt_altitude.py new file mode 100644 index 00000000..5131d80f --- /dev/null +++ b/extreme_fit/model/margin_model/polynomial_margin_model/models_based_on_pariwise_analysis/gev_with_constant_shape_wrt_altitude.py @@ -0,0 +1,130 @@ +from extreme_fit.distribution.gev.gev_params import GevParams +from extreme_fit.model.margin_model.polynomial_margin_model.gev_altitudinal_models import AbstractAltitudinalModel + + +class AltitudinalShapeConstantTimeStationary(AbstractAltitudinalModel): + + @property + def param_name_to_list_dim_and_degree(self): + return { + GevParams.LOC: [(self.coordinates.idx_x_coordinates, 1)], + GevParams.SCALE: [(self.coordinates.idx_x_coordinates, 1)] + } + + +class AltitudinalShapeConstantTimeLocationLinear(AbstractAltitudinalModel): + + @property + def param_name_to_list_dim_and_degree(self): + return { + GevParams.LOC: [(self.coordinates.idx_x_coordinates, 1), (self.coordinates.idx_temporal_coordinates, 1)], + GevParams.SCALE: [(self.coordinates.idx_x_coordinates, 1)] + } + + +class AltitudinalShapeConstantTimeScaleLinear(AbstractAltitudinalModel): + + @property + def param_name_to_list_dim_and_degree(self): + return { + GevParams.LOC: [(self.coordinates.idx_x_coordinates, 1)], + GevParams.SCALE: [(self.coordinates.idx_x_coordinates, 1), (self.coordinates.idx_temporal_coordinates, 1)] + } + + +class AltitudinalShapeConstantTimeShapeLinear(AbstractAltitudinalModel): + + @property + def param_name_to_list_dim_and_degree(self): + return { + GevParams.LOC: [(self.coordinates.idx_x_coordinates, 1)], + GevParams.SCALE: [(self.coordinates.idx_x_coordinates, 1)], + GevParams.SHAPE: [(self.coordinates.idx_temporal_coordinates, 1)] + } + + +class AltitudinalShapeConstantTimeLocShapeLinear(AbstractAltitudinalModel): + + @property + def param_name_to_list_dim_and_degree(self): + return { + GevParams.LOC: [(self.coordinates.idx_x_coordinates, 1), (self.coordinates.idx_temporal_coordinates, 1)], + GevParams.SCALE: [(self.coordinates.idx_x_coordinates, 1)], + GevParams.SHAPE: [(self.coordinates.idx_temporal_coordinates, 1)] + } + + +class AltitudinalShapeConstantTimeLocScaleLinear(AbstractAltitudinalModel): + + @property + def param_name_to_list_dim_and_degree(self): + return { + GevParams.LOC: [(self.coordinates.idx_x_coordinates, 1), (self.coordinates.idx_temporal_coordinates, 1)], + GevParams.SCALE: [(self.coordinates.idx_x_coordinates, 1), (self.coordinates.idx_temporal_coordinates, 1)], + } + + +class AltitudinalShapeConstantTimeScaleShapeLinear(AbstractAltitudinalModel): + + @property + def param_name_to_list_dim_and_degree(self): + return { + GevParams.LOC: [(self.coordinates.idx_x_coordinates, 1)], + GevParams.SCALE: [(self.coordinates.idx_x_coordinates, 1), (self.coordinates.idx_temporal_coordinates, 1)], + GevParams.SHAPE: [(self.coordinates.idx_temporal_coordinates, 1)] + } + + +class AltitudinalShapeConstantTimeLocScaleShapeLinear(AbstractAltitudinalModel): + + @property + def param_name_to_list_dim_and_degree(self): + return { + GevParams.LOC: [(self.coordinates.idx_x_coordinates, 1), (self.coordinates.idx_temporal_coordinates, 1)], + GevParams.SCALE: [(self.coordinates.idx_x_coordinates, 1), (self.coordinates.idx_temporal_coordinates, 1)], + GevParams.SHAPE: [(self.coordinates.idx_temporal_coordinates, 1)] + } + + +# Quadratic + +class AltitudinalShapeConstantTimeLocQuadratic(AbstractAltitudinalModel): + + @property + def param_name_to_list_dim_and_degree(self): + return { + GevParams.LOC: [(self.coordinates.idx_x_coordinates, 1), (self.coordinates.idx_temporal_coordinates, 2)], + GevParams.SCALE: [(self.coordinates.idx_x_coordinates, 1)], + } + + +class AltitudinalShapeConstantTimeLocQuadraticScaleLinear(AbstractAltitudinalModel): + + @property + def param_name_to_list_dim_and_degree(self): + return { + GevParams.LOC: [(self.coordinates.idx_x_coordinates, 1), (self.coordinates.idx_temporal_coordinates, 2)], + GevParams.SCALE: [(self.coordinates.idx_x_coordinates, 1), (self.coordinates.idx_temporal_coordinates, 1)], + } + + +class AltitudinalShapeConstantTimeLocQuadraticShapeLinear(AbstractAltitudinalModel): + + @property + def param_name_to_list_dim_and_degree(self): + return { + GevParams.LOC: [(self.coordinates.idx_x_coordinates, 1), (self.coordinates.idx_temporal_coordinates, 2)], + GevParams.SCALE: [(self.coordinates.idx_x_coordinates, 1)], + GevParams.SHAPE: [(self.coordinates.idx_temporal_coordinates, 1)] + } + + +class AltitudinalShapeConstantTimeLocQuadraticScaleShapeLinear(AbstractAltitudinalModel): + + @property + def param_name_to_list_dim_and_degree(self): + return { + GevParams.LOC: [(self.coordinates.idx_x_coordinates, 1), (self.coordinates.idx_temporal_coordinates, 2)], + GevParams.SCALE: [(self.coordinates.idx_x_coordinates, 1), (self.coordinates.idx_temporal_coordinates, 1)], + GevParams.SHAPE: [(self.coordinates.idx_temporal_coordinates, 1)] + } diff --git a/extreme_fit/model/margin_model/polynomial_margin_model/models_based_on_pariwise_analysis/gev_with_linear_shape_wrt_altitude.py b/extreme_fit/model/margin_model/polynomial_margin_model/models_based_on_pariwise_analysis/gev_with_linear_shape_wrt_altitude.py new file mode 100644 index 00000000..5b9f3abc --- /dev/null +++ b/extreme_fit/model/margin_model/polynomial_margin_model/models_based_on_pariwise_analysis/gev_with_linear_shape_wrt_altitude.py @@ -0,0 +1,136 @@ +from extreme_fit.distribution.gev.gev_params import GevParams +from extreme_fit.model.margin_model.polynomial_margin_model.gev_altitudinal_models import AbstractAltitudinalModel + + +class AltitudinalShapeLinearTimeStationary(AbstractAltitudinalModel): + + @property + def param_name_to_list_dim_and_degree(self): + return { + GevParams.LOC: [(self.coordinates.idx_x_coordinates, 1)], + GevParams.SCALE: [(self.coordinates.idx_x_coordinates, 1)], + GevParams.SHAPE: [(self.coordinates.idx_x_coordinates, 1)] + } + + +class AltitudinalShapeLinearTimeLocationLinear(AltitudinalShapeLinearTimeStationary): + + @property + def param_name_to_list_dim_and_degree(self): + return { + GevParams.LOC: [(self.coordinates.idx_x_coordinates, 1), (self.coordinates.idx_temporal_coordinates, 1)], + GevParams.SCALE: [(self.coordinates.idx_x_coordinates, 1)], + GevParams.SHAPE: [(self.coordinates.idx_x_coordinates, 1)] + } + + +class AltitudinalShapeLinearTimeScaleLinear(AltitudinalShapeLinearTimeStationary): + + @property + def param_name_to_list_dim_and_degree(self): + return { + GevParams.LOC: [(self.coordinates.idx_x_coordinates, 1)], + GevParams.SCALE: [(self.coordinates.idx_x_coordinates, 1), (self.coordinates.idx_temporal_coordinates, 1)], + GevParams.SHAPE: [(self.coordinates.idx_x_coordinates, 1)] + } + + +class AltitudinalShapeLinearTimeShapeLinear(AltitudinalShapeLinearTimeStationary): + + @property + def param_name_to_list_dim_and_degree(self): + return { + GevParams.LOC: [(self.coordinates.idx_x_coordinates, 1)], + GevParams.SCALE: [(self.coordinates.idx_x_coordinates, 1)], + GevParams.SHAPE: [(self.coordinates.idx_x_coordinates, 1), (self.coordinates.idx_temporal_coordinates, 1)] + } + + +class AltitudinalShapeLinearTimeLocShapeLinear(AltitudinalShapeLinearTimeStationary): + + @property + def param_name_to_list_dim_and_degree(self): + return { + GevParams.LOC: [(self.coordinates.idx_x_coordinates, 1), (self.coordinates.idx_temporal_coordinates, 1)], + GevParams.SCALE: [(self.coordinates.idx_x_coordinates, 1)], + GevParams.SHAPE: [(self.coordinates.idx_x_coordinates, 1), (self.coordinates.idx_temporal_coordinates, 1)] + } + + +class AltitudinalShapeLinearTimeLocScaleLinear(AltitudinalShapeLinearTimeStationary): + + @property + def param_name_to_list_dim_and_degree(self): + return { + GevParams.LOC: [(self.coordinates.idx_x_coordinates, 1), (self.coordinates.idx_temporal_coordinates, 1)], + GevParams.SCALE: [(self.coordinates.idx_x_coordinates, 1), (self.coordinates.idx_temporal_coordinates, 1)], + GevParams.SHAPE: [(self.coordinates.idx_x_coordinates, 1)] + } + + +class AltitudinalShapeLinearTimeScaleShapeLinear(AltitudinalShapeLinearTimeStationary): + + @property + def param_name_to_list_dim_and_degree(self): + return { + GevParams.LOC: [(self.coordinates.idx_x_coordinates, 1)], + GevParams.SCALE: [(self.coordinates.idx_x_coordinates, 1), (self.coordinates.idx_temporal_coordinates, 1)], + GevParams.SHAPE: [(self.coordinates.idx_x_coordinates, 1), (self.coordinates.idx_temporal_coordinates, 1)] + } + +class AltitudinalShapeLinearTimeLocScaleShapeLinear(AltitudinalShapeLinearTimeStationary): + + @property + def param_name_to_list_dim_and_degree(self): + return { + GevParams.LOC: [(self.coordinates.idx_x_coordinates, 1), (self.coordinates.idx_temporal_coordinates, 1)], + GevParams.SCALE: [(self.coordinates.idx_x_coordinates, 1), (self.coordinates.idx_temporal_coordinates, 1)], + GevParams.SHAPE: [(self.coordinates.idx_x_coordinates, 1), (self.coordinates.idx_temporal_coordinates, 1)] + } + + +# Quadratic + + +class AltitudinalShapeLinearTimeLocQuadratic(AbstractAltitudinalModel): + + @property + def param_name_to_list_dim_and_degree(self): + return { + GevParams.LOC: [(self.coordinates.idx_x_coordinates, 1), (self.coordinates.idx_temporal_coordinates, 2)], + GevParams.SCALE: [(self.coordinates.idx_x_coordinates, 1)], + GevParams.SHAPE: [(self.coordinates.idx_x_coordinates, 1)] + } + + +class AltitudinalShapeLinearTimeLocQuadraticScaleLinear(AbstractAltitudinalModel): + + @property + def param_name_to_list_dim_and_degree(self): + return { + GevParams.LOC: [(self.coordinates.idx_x_coordinates, 1), (self.coordinates.idx_temporal_coordinates, 2)], + GevParams.SCALE: [(self.coordinates.idx_x_coordinates, 1), (self.coordinates.idx_temporal_coordinates, 1)], + GevParams.SHAPE: [(self.coordinates.idx_x_coordinates, 1)] + } + + +class AltitudinalShapeLinearTimeLocQuadraticShapeLinear(AbstractAltitudinalModel): + + @property + def param_name_to_list_dim_and_degree(self): + return { + GevParams.LOC: [(self.coordinates.idx_x_coordinates, 1), (self.coordinates.idx_temporal_coordinates, 2)], + GevParams.SCALE: [(self.coordinates.idx_x_coordinates, 1)], + GevParams.SHAPE: [(self.coordinates.idx_x_coordinates, 1), (self.coordinates.idx_temporal_coordinates, 1)] + } + + +class AltitudinalShapeLinearTimeLocQuadraticScaleShapeLinear(AbstractAltitudinalModel): + + @property + def param_name_to_list_dim_and_degree(self): + return { + GevParams.LOC: [(self.coordinates.idx_x_coordinates, 1), (self.coordinates.idx_temporal_coordinates, 2)], + GevParams.SCALE: [(self.coordinates.idx_x_coordinates, 1), (self.coordinates.idx_temporal_coordinates, 1)], + GevParams.SHAPE: [(self.coordinates.idx_x_coordinates, 1), (self.coordinates.idx_temporal_coordinates, 1)] + } \ No newline at end of file diff --git a/extreme_fit/model/margin_model/polynomial_margin_model/utils.py b/extreme_fit/model/margin_model/polynomial_margin_model/utils.py index ea4282f8..0afdd4dd 100644 --- a/extreme_fit/model/margin_model/polynomial_margin_model/utils.py +++ b/extreme_fit/model/margin_model/polynomial_margin_model/utils.py @@ -4,17 +4,9 @@ from extreme_fit.model.margin_model.polynomial_margin_model.gev_altitudinal_mode NonStationaryCrossTermForLocation, NonStationaryAltitudinalLocationLinearCrossTermForLocation, \ NonStationaryAltitudinalLocationQuadraticCrossTermForLocation, \ NonStationaryAltitudinalLocationLinearScaleLinearCrossTermForLocation, \ - NonStationaryAltitudinalLocationQuadraticScaleLinearCrossTermForLocation, NonStationaryAltitudinalScaleLinear, \ - NonStationaryAltitudinalScaleLinearCrossTermForLocation, NonStationaryAltitudinalLocationCubicCrossTermForLocation, \ - NonStationaryAltitudinalLocationCubic, NonStationaryAltitudinalLocationOrder4CrossTermForLocation, \ - NonStationaryAltitudinalLocationOrder4 -from extreme_fit.model.margin_model.polynomial_margin_model.gev_altitudinal_models_cross_term_in_scale import \ - NonStationaryAltitudinalLocationLinearScaleQuadraticCrossTermForScale, \ - NonStationaryAltitudinalLocationQuadraticScaleQuadraticCrossTermForScale, \ - NonStationaryAltitudinalScaleLinearCrossTermForScale, \ - NonStationaryAltitudinalLocationLinearScaleLinearCrossTermForScale, \ - NonStationaryAltitudinalLocationQuadraticScaleLinearCrossTermForScale, \ - NonStationaryAltitudinalScaleQuadraticCrossTermForScale + NonStationaryAltitudinalScaleLinear, \ + NonStationaryAltitudinalLocationCubicCrossTermForLocation, \ + NonStationaryAltitudinalLocationCubic from extreme_fit.model.margin_model.polynomial_margin_model.gev_altitudinal_models_only_altitude_and_scale import \ StationaryAltitudinalOnlyScale, NonStationaryAltitudinalOnlyScaleLocationLinear, \ NonStationaryAltitudinalOnlyScaleLocationQuadratic, NonStationaryAltitudinalOnlyScaleLocationCubic, \ @@ -23,17 +15,9 @@ from extreme_fit.model.margin_model.polynomial_margin_model.gev_altitudinal_mode NonStationaryAltitudinalOnlyScaleLocationQuadraticCrossTermForLocation, \ NonStationaryAltitudinalOnlyScaleLocationCubicCrossTermForLocation, \ NonStationaryAltitudinalOnlyScaleLocationOrder4CrossTermForLocation -from extreme_fit.model.margin_model.polynomial_margin_model.gev_altitudinal_models_with_scale import \ - NonStationaryAltitudinalScaleQuadraticCrossTermForLocation, NonStationaryAltitudinalScaleQuadratic, \ - NonStationaryAltitudinalLocationLinearScaleQuadratic, NonStationaryAltitudinalLocationQuadraticScaleQuadratic, \ - NonStationaryAltitudinalLocationLinearScaleQuadraticCrossTermForLocation, \ - NonStationaryAltitudinalLocationQuadraticScaleQuadraticCrossTermForLocation from extreme_fit.model.margin_model.polynomial_margin_model.gev_altitudinal_models_with_scale_2 import \ NonStationaryAltitudinalScaleLinearCrossTermForLocation, \ - NonStationaryAltitudinalScaleLinearLocationLinearCrossTermForLocation, \ NonStationaryAltitudinalLocationQuadraticScaleLinearCrossTermForLocation, \ - NonStationaryAltitudinalScaleQuadraticLocationLinearCrossTermForLocation, \ - NonStationaryAltitudinalLocationCubicScaleQuadraticCrossTermForLocation, \ NonStationaryAltitudinalLocationCubicScaleLinearCrossTermForLocation, \ NonStationaryAltitudinalLocationCubicScaleLinear from extreme_fit.model.margin_model.polynomial_margin_model.gumbel_altitudinal_models import \ @@ -45,6 +29,16 @@ from extreme_fit.model.margin_model.polynomial_margin_model.gumbel_altitudinal_m NonStationaryGumbelAltitudinalLocationLinearScaleLinearCrossTermForLocation, \ NonStationaryGumbelAltitudinalLocationQuadraticScaleLinearCrossTermForLocation, \ NonStationaryGumbelAltitudinalScaleLinearCrossTermForLocation, NonStationaryGumbelCrossTermForLocation +from extreme_fit.model.margin_model.polynomial_margin_model.models_based_on_pariwise_analysis.gev_with_constant_shape_wrt_altitude import \ + AltitudinalShapeConstantTimeLocShapeLinear, \ + AltitudinalShapeConstantTimeLocScaleLinear, AltitudinalShapeConstantTimeScaleShapeLinear, \ + AltitudinalShapeConstantTimeLocScaleShapeLinear, AltitudinalShapeConstantTimeLocationLinear, \ + AltitudinalShapeConstantTimeScaleLinear, AltitudinalShapeConstantTimeShapeLinear +from extreme_fit.model.margin_model.polynomial_margin_model.models_based_on_pariwise_analysis.gev_with_linear_shape_wrt_altitude import \ + AltitudinalShapeLinearTimeStationary, AltitudinalShapeLinearTimeLocScaleShapeLinear, \ + AltitudinalShapeLinearTimeLocationLinear, AltitudinalShapeLinearTimeScaleLinear, \ + AltitudinalShapeLinearTimeShapeLinear, AltitudinalShapeLinearTimeLocShapeLinear, \ + AltitudinalShapeLinearTimeLocScaleLinear, AltitudinalShapeLinearTimeScaleShapeLinear from extreme_fit.model.margin_model.polynomial_margin_model.spatio_temporal_polynomial_model import \ NonStationaryLocationSpatioTemporalLinearityModel1, NonStationaryLocationSpatioTemporalLinearityModel2, \ NonStationaryLocationSpatioTemporalLinearityModel3, NonStationaryLocationSpatioTemporalLinearityModel4, \ @@ -97,6 +91,29 @@ ALTITUDINAL_GEV_MODELS_LOCATION_QUADRATIC_MINIMUM = [ ] +ALTITUDINAL_GEV_MODELS_BASED_ON_POINTWISE_ANALYSIS = [ + + # With a constant shape for the altitude (8 models) + StationaryAltitudinal, + AltitudinalShapeConstantTimeLocationLinear, + AltitudinalShapeConstantTimeScaleLinear, + AltitudinalShapeConstantTimeShapeLinear, + AltitudinalShapeConstantTimeLocShapeLinear, + AltitudinalShapeConstantTimeLocScaleLinear, + AltitudinalShapeConstantTimeScaleShapeLinear, + AltitudinalShapeConstantTimeLocScaleShapeLinear, + # With a linear shape for the altitude (8 models) + AltitudinalShapeLinearTimeStationary, + AltitudinalShapeLinearTimeLocationLinear, + AltitudinalShapeLinearTimeScaleLinear, + AltitudinalShapeLinearTimeShapeLinear, + AltitudinalShapeLinearTimeLocShapeLinear, + AltitudinalShapeLinearTimeLocScaleLinear, + AltitudinalShapeLinearTimeScaleShapeLinear, + AltitudinalShapeLinearTimeLocScaleShapeLinear, + +] + ALTITUDINAL_GEV_MODELS_LOCATION_ONLY_SCALE_ALTITUDES = [ StationaryAltitudinalOnlyScale, NonStationaryAltitudinalOnlyScaleLocationLinear, 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 87dd6ed5..ee31f000 100644 --- a/projects/altitude_spatial_model/altitudes_fit/main_altitudes_studies.py +++ b/projects/altitude_spatial_model/altitudes_fit/main_altitudes_studies.py @@ -5,7 +5,8 @@ import numpy as np from extreme_data.meteo_france_data.adamont_data.abstract_simulation_study import SimulationStudy from extreme_data.meteo_france_data.adamont_data.snowfall_simulation import SafranSnowfallSimulationRCP85 from extreme_fit.model.margin_model.polynomial_margin_model.utils import ALTITUDINAL_GEV_MODELS, \ - ALTITUDINAL_GEV_MODELS_LOCATION_QUADRATIC_MINIMUM, ALTITUDINAL_GEV_MODELS_LOCATION_ONLY_SCALE_ALTITUDES, ALTITUDINAL_GEV_MODELS_LOCATION + ALTITUDINAL_GEV_MODELS_LOCATION_QUADRATIC_MINIMUM, ALTITUDINAL_GEV_MODELS_LOCATION_ONLY_SCALE_ALTITUDES, \ + ALTITUDINAL_GEV_MODELS_LOCATION, ALTITUDINAL_GEV_MODELS_BASED_ON_POINTWISE_ANALYSIS from projects.altitude_spatial_model.altitudes_fit.one_fold_analysis.plot_total_aic import plot_total_aic, \ plot_individual_aic from spatio_temporal_dataset.coordinates.temporal_coordinates.temperature_covariate import MeanAlpsTemperatureCovariate @@ -38,7 +39,8 @@ def plot_moments(studies, massif_names=None): def plot_altitudinal_fit(studies, massif_names=None): # model_classes = ALTITUDINAL_GEV_MODELS_LOCATION_ONLY_SCALE_ALTITUDES - model_classes = ALTITUDINAL_GEV_MODELS_LOCATION_QUADRATIC_MINIMUM + # model_classes = ALTITUDINAL_GEV_MODELS_LOCATION_QUADRATIC_MINIMUM + model_classes = ALTITUDINAL_GEV_MODELS_BASED_ON_POINTWISE_ANALYSIS # model_classes = ALTITUDINAL_GEV_MODELS_LOCATION # model_classes = ALTITUDINAL_GEV_MODELS_LOCATION_CUBIC_MINIMUM # model_classes = ALTITUDINAL_GEV_MODELS_QUADRATIC @@ -73,13 +75,13 @@ def main(): study_classes = [SafranSnowfall1Day, SafranSnowfall3Days, SafranPrecipitation1Day , SafranPrecipitation3Days][:1] - # altitudes = [1500, 1800] - study_classes = [SafranSnowfall1Day, SafranSnowfallSimulationRCP85][:] + altitudes = [1800, 2100, 2400] + study_classes = [SafranSnowfall1Day][:] # Common parameters - altitudes = [600, 900, 1200, 1500, 1800, 2100, 2400, 2700, 3000, 3300, 3600] + # altitudes = [600, 900, 1200, 1500, 1800, 2100, 2400, 2700, 3000, 3300, 3600] massif_names = None - seasons = [Season.winter] + seasons = [Season.annual] for season in seasons: for study_class in study_classes: diff --git a/projects/altitude_spatial_model/altitudes_fit/one_fold_analysis/altitude_group.py b/projects/altitude_spatial_model/altitudes_fit/one_fold_analysis/altitude_group.py new file mode 100644 index 00000000..804abddf --- /dev/null +++ b/projects/altitude_spatial_model/altitudes_fit/one_fold_analysis/altitude_group.py @@ -0,0 +1,28 @@ +from enum import Enum + + +class AltitudeGroup(Enum): + low = 0 + mid = 1 + high = 2 + unspecfied = 3 + + +def altitude_group_to_reference_altitude(): + return { + AltitudeGroup.low: 1000, + AltitudeGroup.mid: 2000, + AltitudeGroup.high: 3000, + AltitudeGroup.unspecfied: 1000, + } + +def get_altitude_group_from_altitudes(altitudes): + s = set(altitudes) + if s == {900, 1200, 1500}: + return AltitudeGroup.low + elif s == {1800, 2100, 2400}: + return AltitudeGroup.mid + elif s == {2700, 3000, 3300}: + return AltitudeGroup.high + else: + return AltitudeGroup.unspecfied 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 3c7e4d70..3edeca7b 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 @@ -43,7 +43,8 @@ class AltitudesStudiesVisualizerForNonStationaryModels(StudyVisualizer): self._massif_name_to_one_fold_fit = {} for massif_name in self.massif_names: assert top_n_values_to_remove is None - dataset = studies.spatio_temporal_dataset(massif_name=massif_name, top_n_values_to_remove=top_n_values_to_remove) + dataset = studies.spatio_temporal_dataset(massif_name=massif_name, + top_n_values_to_remove=top_n_values_to_remove) old_fold_fit = OneFoldFit(massif_name, dataset, model_classes, self.fit_method, self.temporal_covariate_for_fit) self._massif_name_to_one_fold_fit[massif_name] = old_fold_fit @@ -143,7 +144,8 @@ class AltitudesStudiesVisualizerForNonStationaryModels(StudyVisualizer): def plot_shape_map(self): self.plot_abstract_fast(self.massif_name_to_shape, label='Shape parameter for {} maxima of {}'.format(self.study.season_name, - SCM_STUDY_CLASS_TO_ABBREVIATION[type(self.study)]), + SCM_STUDY_CLASS_TO_ABBREVIATION[ + type(self.study)]), add_x_label=False, graduation=0.1, massif_name_to_text=self.massif_name_to_name) def plot_altitude_for_the_peak(self): @@ -184,7 +186,8 @@ class AltitudesStudiesVisualizerForNonStationaryModels(StudyVisualizer): 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)) + 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('_', '')) @@ -260,5 +263,3 @@ class AltitudesStudiesVisualizerForNonStationaryModels(StudyVisualizer): plot_name = 'Switch altitude' self.studies.show_or_save_to_file(plot_name=plot_name, show=self.show) plt.close() - - 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 3e8b0409..62704f80 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 @@ -12,7 +12,10 @@ from extreme_fit.model.margin_model.polynomial_margin_model.gev_altitudinal_mode AltitudinalOnlyScale, StationaryAltitudinalOnlyScale from extreme_fit.model.margin_model.polynomial_margin_model.gumbel_altitudinal_models import \ StationaryGumbelAltitudinal, AbstractGumbelAltitudinalModel +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 projects.altitude_spatial_model.altitudes_fit.one_fold_analysis.altitude_group import AltitudeGroup from root_utils import classproperty from spatio_temporal_dataset.dataset.abstract_dataset import AbstractDataset @@ -22,7 +25,9 @@ class OneFoldFit(object): best_estimator_minimizes_total_aic = False 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_group=AltitudeGroup.unspecfied): + self.altitude_group = altitude_group self.massif_name = massif_name self.dataset = dataset self.models_classes = models_classes @@ -128,6 +133,7 @@ class OneFoldFit(object): def best_shape(self): # We take any altitude (altitude=1000 for instance) and any year # as the shape is constant w.r.t the altitude and the year + return self.get_gev_params(altitude=1000, year=2019).shape def best_coef(self, param_name, dim, degree): @@ -153,6 +159,8 @@ class OneFoldFit(object): return self.model_class_to_estimator_with_finite_aic[StationaryGumbelAltitudinal] elif isinstance(self.best_estimator.margin_model, AltitudinalOnlyScale): return self.model_class_to_estimator_with_finite_aic[StationaryAltitudinalOnlyScale] + elif isinstance(self.best_estimator.margin_model, AltitudinalShapeLinearTimeStationary): + return self.model_class_to_estimator_with_finite_aic[AltitudinalShapeLinearTimeStationary] else: return self.model_class_to_estimator_with_finite_aic[StationaryAltitudinal] diff --git a/projects/altitude_spatial_model/altitudes_fit/one_fold_analysis/plot_total_aic.py b/projects/altitude_spatial_model/altitudes_fit/one_fold_analysis/plot_total_aic.py index c0974137..af5bdaef 100644 --- a/projects/altitude_spatial_model/altitudes_fit/one_fold_analysis/plot_total_aic.py +++ b/projects/altitude_spatial_model/altitudes_fit/one_fold_analysis/plot_total_aic.py @@ -12,12 +12,12 @@ from projects.exceeding_snow_loads.utils import dpi_paper1_figure def plots(visualizer): visualizer.plot_shape_map() - for plot_mean in [True, False]: - visualizer.plot_year_for_the_peak(plot_mean=plot_mean) + # for plot_mean in [True, False]: + # visualizer.plot_year_for_the_peak(plot_mean=plot_mean) visualizer.plot_moments() - visualizer.plot_best_coef_maps() - visualizer.plot_peak_year_against_altitude() - visualizer.plot_altitude_switch_against_peak_year() + # visualizer.plot_best_coef_maps() + # visualizer.plot_peak_year_against_altitude() + # visualizer.plot_altitude_switch_against_peak_year() def plot_individual_aic(visualizer): diff --git a/projects/contrasting_trends_in_snow_loads/article2_snowfall_versus_time_and_altitude/snowfall_plot.py b/projects/contrasting_trends_in_snow_loads/article2_snowfall_versus_time_and_altitude/snowfall_plot.py index e98023f8..03b9c51e 100644 --- a/projects/contrasting_trends_in_snow_loads/article2_snowfall_versus_time_and_altitude/snowfall_plot.py +++ b/projects/contrasting_trends_in_snow_loads/article2_snowfall_versus_time_and_altitude/snowfall_plot.py @@ -165,7 +165,7 @@ def plot_mean(altitude_to_visualizer: Dict[int, StudyVisualizerForMeanValues], d def plot_values_against_altitudes(ax, altitudes, massif_id, massif_name, moment, study, values, visualizer): - plot_against_altitude(altitudes=altitudes, ax=ax, massif_id=massif_id, massif_name=massif_name, values=values) + plot_against_altitude(x_ticks=altitudes, ax=ax, massif_id=massif_id, massif_name=massif_name, values=values) plot_name = '{} annual maxima of {}'.format(moment, SCM_STUDY_CLASS_TO_ABBREVIATION[type(study)]) ax.set_ylabel('{} ({})'.format(plot_name, study.variable_unit), fontsize=15) ax.set_xlabel('altitudes', fontsize=15) diff --git a/projects/contrasting_trends_in_snow_loads/post thesis committee/pointwise_gev_study_visualizer.py b/projects/contrasting_trends_in_snow_loads/post thesis committee/pointwise_gev_study_visualizer.py index 4549b0de..6d848cc1 100644 --- a/projects/contrasting_trends_in_snow_loads/post thesis committee/pointwise_gev_study_visualizer.py +++ b/projects/contrasting_trends_in_snow_loads/post thesis committee/pointwise_gev_study_visualizer.py @@ -1,4 +1,5 @@ import matplotlib.pyplot as plt +import numpy as np from cached_property import cached_property from extreme_data.meteo_france_data.scm_models_data.abstract_study import AbstractStudy @@ -7,11 +8,20 @@ from extreme_data.meteo_france_data.scm_models_data.visualization.plot_utils imp from extreme_data.meteo_france_data.scm_models_data.visualization.study_visualizer import StudyVisualizer from extreme_fit.distribution.gev.gev_params import GevParams from projects.altitude_spatial_model.altitudes_fit.altitudes_studies import AltitudesStudies +from projects.contrasting_trends_in_snow_loads.article2_snowfall_versus_time_and_altitude.snowfall_plot import \ + fit_linear_regression from projects.exceeding_snow_loads.utils import paper_altitudes class PointwiseGevStudyVisualizer(AltitudesStudies): + def __init__(self, study_class, altitudes, spatial_transformation_class=None, temporal_transformation_class=None, + **kwargs_study): + super().__init__(study_class, altitudes, spatial_transformation_class, temporal_transformation_class, + **kwargs_study) + # self.altitudes_for_temporal_hypothesis = [min(self.altitudes), 2100, max(self.altitudes)] + self.altitudes_for_temporal_hypothesis = [900, 2100, 3000] + def plot_gev_params_against_altitude(self): for param_name in GevParams.PARAM_NAMES[:]: ax = plt.gca() @@ -53,15 +63,17 @@ class PointwiseGevStudyVisualizer(AltitudesStudies): def min_years_for_plot_x_axis(self): return [c[0] for c in self.year_min_and_max_list] - def plot_gev_params_against_time(self): - for altitude in self.altitudes[:]: - self._plot_gev_params_against_time(altitude) + def plot_gev_params_against_time_for_all_altitudes(self): + for altitude in self.altitudes_for_temporal_hypothesis: + self._plot_gev_params_against_time_for_one_altitude(altitude) - def _plot_gev_params_against_time(self, altitude): + def _plot_gev_params_against_time_for_one_altitude(self, altitude): for param_name in GevParams.PARAM_NAMES[:]: ax = plt.gca() for massif_name in self.study.all_massif_names()[:]: - self._plot_gev_params_against_time_one_massif(ax, massif_name, param_name, altitude) + self._plot_gev_params_against_time_for_one_altitude_and_one_massif(ax, massif_name, param_name, + altitude, + massif_name_as_labels=True) ax.legend(prop={'size': 7}, ncol=3) ax.set_xlabel('Year') ax.set_ylabel(param_name + ' for altitude={}'.format(altitude)) @@ -69,27 +81,99 @@ class PointwiseGevStudyVisualizer(AltitudesStudies): ax.set_xticks(self.min_years_for_plot_x_axis) ax.set_xticklabels(xlabels) # ax.tick_params(labelsize=5) - plot_name = '{} change /with years for altitude={}'.format(param_name, altitude) + plot_name = '{} change /all with years /for altitude={}'.format(param_name, altitude) self.show_or_save_to_file(plot_name, no_title=True, tight_layout=True, show=False) ax.clear() plt.close() - def _plot_gev_params_against_time_one_massif(self, ax, massif_name, param_name, altitude): + def _plot_gev_params_against_time_for_one_altitude_and_one_massif(self, ax, massif_name, param_name, altitude, + massif_name_as_labels): study = self.altitude_to_study[altitude] if massif_name in study.study_massif_names: gev_params_list = study.massif_name_to_gev_param_list(self.year_min_and_max_list)[massif_name] params = [gev_params.to_dict()[param_name] for gev_params in gev_params_list] - confidence_intervals = [gev_params.param_name_to_confidence_interval[param_name] for gev_params in - gev_params_list] + # params = np.array(params) + # param_normalized = params / np.sqrt(np.sum(np.power(params, 2))) + # confidence_intervals = [gev_params.param_name_to_confidence_interval[param_name] for gev_params in + # gev_params_list] massif_id = self.study.all_massif_names().index(massif_name) - plot_against_altitude(self.min_years_for_plot_x_axis, ax, massif_id, massif_name, params, fill=False) - # plot_against_altitude(self.years, ax, massif_id, massif_name, confidence_intervals, fill=True) + plot_against_altitude(self.min_years_for_plot_x_axis, ax, massif_id, massif_name, params, + altitude, False, + massif_name_as_labels) + # plot_against_altitude(self.years, ax, massif_id, massif_name, confidence_intervals, True) + + # plot for each massif against the time + + def plot_gev_params_against_time_for_all_massifs(self): + for massif_name in self.study.all_massif_names(): + self._plot_gev_params_against_time_for_one_massif(massif_name) + + def _plot_gev_params_against_time_for_one_massif(self, massif_name): + for param_name in GevParams.PARAM_NAMES[:]: + ax = plt.gca() + for altitude in self.altitudes_for_temporal_hypothesis: + self._plot_gev_params_against_time_for_one_altitude_and_one_massif(ax, massif_name, param_name, + altitude, + massif_name_as_labels=False) + ax.legend() + ax.set_xlabel('Year') + ax.set_ylabel(param_name + ' for {}'.format(massif_name)) + xlabels = ['-'.join([str(e) for e in t]) for t in self.year_min_and_max_list] + ax.set_xticks(self.min_years_for_plot_x_axis) + ax.set_xticklabels(xlabels) + plot_name = '{} change /with years /for {}'.format(param_name, massif_name) + self.show_or_save_to_file(plot_name, no_title=True, tight_layout=True, show=False) + ax.clear() + plt.close() + + # PLot for each massif the derivative against the time for each altitude + + def plot_time_derivative_against_time(self): + for param_name in GevParams.PARAM_NAMES[:]: + ax = plt.gca() + for massif_name in self.study.all_massif_names()[:]: + self._plot_gev_params_time_derivative_against_altitude_one_massif(ax, massif_name, param_name) + ax.legend(prop={'size': 7}, ncol=3) + ax.set_xlabel('Altitude') + ax.set_ylabel(param_name) + plot_name = '{} change /time derivative with altitude'.format(param_name) + self.show_or_save_to_file(plot_name, no_title=True, tight_layout=True, show=False) + ax.clear() + plt.close() + + def _plot_gev_params_time_derivative_against_altitude_one_massif(self, ax, massif_name, param_name): + altitudes = [] + time_derivatives = [] + for altitude, study in self.altitude_to_study.items(): + if (massif_name in study.study_massif_names) and ("Mercan" not in massif_name): + gev_params_list = study.massif_name_to_gev_param_list(self.year_min_and_max_list)[massif_name] + params = [gev_params.to_dict()[param_name] for gev_params in gev_params_list] + x = list(range(len(params))) + y = params + a = self.get_robust_slope(x, y) + time_derivatives.append(a) + altitudes.append(altitude) + massif_id = self.study.all_massif_names().index(massif_name) + plot_against_altitude(altitudes, ax, massif_id, massif_name, time_derivatives, fill=False) + + def get_robust_slope(self, x, y): + a, *_ = fit_linear_regression(x=x, y=y) + a_list = [a] + for i in range(len(x)): + x_copy, y_copy = x[:], y[:] + x_copy.pop(i) + y_copy.pop(i) + a, *_ = fit_linear_regression(x=x_copy, y=y_copy) + a_list.append(a) + return np.mean(np.array(a_list)) if __name__ == '__main__': - altitudes = [600, 900, 1200, 1500, 1800, 2100, 2400, 2700, 3000, 3300, 3600] + altitudes = [900, 1200, 1500, 1800, 2100, 2400, 2700, 3000, 3300] # altitudes = paper_altitudes # altitudes = [1800, 2100] visualizer = PointwiseGevStudyVisualizer(SafranSnowfall1Day, altitudes=altitudes) visualizer.plot_gev_params_against_altitude() - visualizer.plot_gev_params_against_time() + visualizer.plot_gev_params_against_time_for_all_altitudes() + visualizer.plot_gev_params_against_time_for_all_massifs() + # visualizer.plot_time_derivative_against_time() -- GitLab