diff --git a/extreme_fit/model/margin_model/linear_margin_model/abstract_temporal_linear_margin_model.py b/extreme_fit/model/margin_model/linear_margin_model/abstract_temporal_linear_margin_model.py index b7b198b9105b972591f8427a77254d069d4dfa3d..b0179e88b5613bfac9318660ec4c08280329ce36 100644 --- a/extreme_fit/model/margin_model/linear_margin_model/abstract_temporal_linear_margin_model.py +++ b/extreme_fit/model/margin_model/linear_margin_model/abstract_temporal_linear_margin_model.py @@ -1,5 +1,3 @@ -from enum import Enum - import numpy as np import pandas as pd @@ -73,7 +71,7 @@ class AbstractTemporalLinearMarginModel(LinearMarginModel): if self.fit_method == MarginFitMethod.extremes_fevd_bayesian: return self.extremes_fevd_bayesian_fit(x, df_coordinates_temp) else: - return self.run_fevd_fixed(df_coordinates_temp=df_coordinates_temp, + return self.run_fevd_fixed(df_coordinates_temp=df_coordinates_temp, method=FEVD_MARGIN_FIT_METHOD_TO_ARGUMENT_STR[self.fit_method], x=x) def extreme_fevd_mle_exp_fit(self, x, df_coordinates_temp): diff --git a/projects/contrasting_trends_in_snow_loads/altitunal_fit/altitudes_studies.py b/projects/contrasting_trends_in_snow_loads/altitunal_fit/altitudes_studies.py new file mode 100644 index 0000000000000000000000000000000000000000..308394641054f3cbc455cc3d0b6f3b4a89f9deb2 --- /dev/null +++ b/projects/contrasting_trends_in_snow_loads/altitunal_fit/altitudes_studies.py @@ -0,0 +1,58 @@ +import pandas as pd +from collections import OrderedDict + +from cached_property import cached_property + +from extreme_data.meteo_france_data.scm_models_data.abstract_study import AbstractStudy +from spatio_temporal_dataset.coordinates.spatial_coordinates.abstract_spatial_coordinates import \ + AbstractSpatialCoordinates +from spatio_temporal_dataset.coordinates.spatio_temporal_coordinates.abstract_spatio_temporal_coordinates import \ + AbstractSpatioTemporalCoordinates +from spatio_temporal_dataset.coordinates.temporal_coordinates.generated_temporal_coordinates import \ + ConsecutiveTemporalCoordinates +from spatio_temporal_dataset.dataset.abstract_dataset import AbstractDataset + + +class AltitudesStudies(object): + + def __init__(self, study_class, altitudes, transformation_class=None, **kwargs_study): + self.transformation_class = transformation_class + self.altitudes = altitudes + self.altitude_to_study = OrderedDict() + for altitude in self.altitudes: + study = study_class(altitude=altitude, **kwargs_study) + self.altitude_to_study[altitude] = study + + @cached_property + def study(self) -> AbstractStudy: + return list(self.altitude_to_study.values())[0] + + def get_dataset(self, massif_name, slicer) -> AbstractDataset: + pass + + # Coordinates Loader + + @cached_property + def temporal_coordinates(self): + return ConsecutiveTemporalCoordinates.from_nb_temporal_steps(nb_temporal_steps=self.study.nb_years, + start=self.study.year_min, + transformation_class=self.transformation_class) + + @cached_property + def spatial_coordinates(self): + return AbstractSpatialCoordinates.from_list_x_coordinates(x_coordinates=self.altitudes, + transformation_class=self.transformation_class) + + def random_s_split_temporal(self, train_split_ratio): + return AbstractSpatioTemporalCoordinates.get_random_s_split_temporal( + spatial_coordinates=self.spatial_coordinates, + temporal_coordinates=self.temporal_coordinates, + train_split_ratio=train_split_ratio) + + def spatio_temporal_coordinates(self, slicer_class: type, s_split_spatial: pd.Series = None, + s_split_temporal: pd.Series = None): + return AbstractSpatioTemporalCoordinates(slicer_class=slicer_class, s_split_spatial=s_split_spatial, + s_split_temporal=s_split_temporal, + transformation_class=self.transformation_class, + spatial_coordinates=self.spatial_coordinates, + temporal_coordinates=self.temporal_coordinates) diff --git a/projects/contrasting_trends_in_snow_loads/altitunal_fit/two_fold_estimation.py b/projects/contrasting_trends_in_snow_loads/altitunal_fit/two_fold_estimation.py new file mode 100644 index 0000000000000000000000000000000000000000..8ac122df6edcedb2a2707c24d7e730a8e394e7e5 --- /dev/null +++ b/projects/contrasting_trends_in_snow_loads/altitunal_fit/two_fold_estimation.py @@ -0,0 +1,6 @@ + +class TwoFoldEstimation(object): + + + def __init__(self): + pass diff --git a/spatio_temporal_dataset/coordinates/abstract_coordinates.py b/spatio_temporal_dataset/coordinates/abstract_coordinates.py index 76a211f1d2055e7964d72cde18c8894eb18b03e4..ae69b412c953f4b82a3d7a9cfc6298a39907f7c4 100644 --- a/spatio_temporal_dataset/coordinates/abstract_coordinates.py +++ b/spatio_temporal_dataset/coordinates/abstract_coordinates.py @@ -108,11 +108,15 @@ class AbstractCoordinates(object): # Create a spatial split s_split_spatial = s_split_from_df(df, cls.COORDINATE_X, cls.SPATIAL_SPLIT, train_split_ratio, True) # Create a temporal split - s_split_temporal = s_split_from_df(df, cls.COORDINATE_T, cls.TEMPORAL_SPLIT, train_split_ratio, False) + s_split_temporal = cls.temporal_s_split_from_df(df, train_split_ratio) return cls(df=df, slicer_class=slicer_class, s_split_spatial=s_split_spatial, s_split_temporal=s_split_temporal, transformation_class=transformation_class) + @classmethod + def temporal_s_split_from_df(cls, df, train_split_ratio): + return s_split_from_df(df, cls.COORDINATE_T, cls.TEMPORAL_SPLIT, train_split_ratio, False) + @classmethod def from_csv(cls, csv_path: str = None): assert csv_path is not None @@ -266,8 +270,7 @@ class AbstractCoordinates(object): # Modify the temporal coordinates to enforce the stationarity df_temporal_coordinates.loc[ind_to_modify] = starting_point # Load the temporal transformation object - temporal_transformation = self.temporal_coordinates.transformation_class( - df_temporal_coordinates) # type: AbstractTransformation + temporal_transformation = self.temporal_coordinates.transformation_class(df_temporal_coordinates) # type: AbstractTransformation # Return the result of the temporal transformation df = temporal_transformation.transform_df(df_temporal_coordinates) # Potentially transform the time covariate into another covariate diff --git a/spatio_temporal_dataset/coordinates/spatial_coordinates/abstract_spatial_coordinates.py b/spatio_temporal_dataset/coordinates/spatial_coordinates/abstract_spatial_coordinates.py index f6b3daec64d87f148ebade5b256a2cbfb2bba5dd..21d12f35525a9d6ce0e5623f5a534c36e292c9ce 100644 --- a/spatio_temporal_dataset/coordinates/spatial_coordinates/abstract_spatial_coordinates.py +++ b/spatio_temporal_dataset/coordinates/spatial_coordinates/abstract_spatial_coordinates.py @@ -6,6 +6,11 @@ from spatio_temporal_dataset.slicer.spatial_slicer import SpatialSlicer class AbstractSpatialCoordinates(AbstractCoordinates): + @classmethod + def from_list_x_coordinates(cls, x_coordinates, train_split_ratio: float = None, transformation_class: type = None): + df = pd.DataFrame({cls.COORDINATE_X: x_coordinates}) + return cls.from_df(df, train_split_ratio, transformation_class) + @classmethod def from_df(cls, df: pd.DataFrame, train_split_ratio: float = None, transformation_class: type = None): assert cls.COORDINATE_X in df.columns diff --git a/spatio_temporal_dataset/coordinates/spatio_temporal_coordinates/abstract_spatio_temporal_coordinates.py b/spatio_temporal_dataset/coordinates/spatio_temporal_coordinates/abstract_spatio_temporal_coordinates.py index 14c0b01aea0cd40eba13e42ad68129fe245f3c81..1d7985541a5dc1fe2fe6906a3c9a0f39f3d8145a 100644 --- a/spatio_temporal_dataset/coordinates/spatio_temporal_coordinates/abstract_spatio_temporal_coordinates.py +++ b/spatio_temporal_dataset/coordinates/spatio_temporal_coordinates/abstract_spatio_temporal_coordinates.py @@ -14,11 +14,14 @@ from spatio_temporal_dataset.slicer.spatio_temporal_slicer import SpatioTemporal class AbstractSpatioTemporalCoordinates(AbstractCoordinates): - def __init__(self, df: pd.DataFrame, slicer_class: type, + def __init__(self, df: pd.DataFrame = None, slicer_class: type = SpatioTemporalSlicer, s_split_spatial: pd.Series = None, s_split_temporal: pd.Series = None, transformation_class: type = None, spatial_coordinates: AbstractSpatialCoordinates = None, temporal_coordinates: AbstractTemporalCoordinates = None): + if df is None: + assert spatial_coordinates is not None and temporal_coordinates is not None + df = self.get_df_from_spatial_and_temporal_coordinates(spatial_coordinates, temporal_coordinates) super().__init__(df, slicer_class, s_split_spatial, s_split_temporal, None) # Spatial coordinates' if spatial_coordinates is None: @@ -47,6 +50,20 @@ class AbstractSpatioTemporalCoordinates(AbstractCoordinates): def temporal_coordinates(self): return self._temporal_coordinates + @classmethod + def from_spatial_coordinates_and_temporal_coordinates(cls, spatial_coordinates: AbstractSpatialCoordinates, + temporal_coordinates: AbstractTemporalCoordinates): + df = cls.get_df_from_spatial_and_temporal_coordinates(spatial_coordinates, temporal_coordinates) + return cls(df=df, slicer_class=SpatioTemporalSlicer, + spatial_coordinates=spatial_coordinates, temporal_coordinates=temporal_coordinates) + + @classmethod + def get_random_s_split_temporal(cls, spatial_coordinates: AbstractSpatialCoordinates, + temporal_coordinates: AbstractTemporalCoordinates, + train_split_ratio): + df = cls.get_df_from_spatial_and_temporal_coordinates(spatial_coordinates, temporal_coordinates) + return cls.temporal_s_split_from_df(df, train_split_ratio) + @classmethod def get_df_from_df_spatial_and_coordinate_t_values(cls, coordinate_t_values, df_spatial): df_time_steps = [] @@ -59,14 +76,13 @@ class AbstractSpatioTemporalCoordinates(AbstractCoordinates): return df_time_steps @classmethod - def from_spatial_coordinates_and_temporal_coordinates(cls, spatial_coordinates: AbstractSpatialCoordinates, - temporal_coordinates: AbstractTemporalCoordinates): - df_spatial = spatial_coordinates.df_spatial_coordinates(transformed=False) - coordinate_t_values = temporal_coordinates.df_temporal_coordinates(transformed=False).iloc[:, 0].values + def get_df_from_spatial_and_temporal_coordinates(cls, spatial_coordinates, temporal_coordinates, transformed=False): + # Transformed is False, so that the value in the spatio temporal datasets are still readable + df_spatial = spatial_coordinates.df_spatial_coordinates(transformed=transformed) + coordinate_t_values = temporal_coordinates.df_temporal_coordinates(transformed=transformed).iloc[:, 0].values df = cls.get_df_from_df_spatial_and_coordinate_t_values(df_spatial=df_spatial, coordinate_t_values=coordinate_t_values) - return cls(df=df, slicer_class=SpatioTemporalSlicer, - spatial_coordinates=spatial_coordinates, temporal_coordinates=temporal_coordinates) + return df @classmethod def from_df(cls, df: pd.DataFrame, train_split_ratio: float = None, transformation_class: type = None): diff --git a/test/test_projects/test_contrasting/__init__.py b/test/test_projects/test_contrasting/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/test/test_projects/test_contrasting/test_altitudes_studies.py b/test/test_projects/test_contrasting/test_altitudes_studies.py new file mode 100644 index 0000000000000000000000000000000000000000..be3fe72b6f9d4fbae7184fadac582f492a66af89 --- /dev/null +++ b/test/test_projects/test_contrasting/test_altitudes_studies.py @@ -0,0 +1,29 @@ +import unittest + +from extreme_data.meteo_france_data.scm_models_data.safran.safran import SafranSnowfall1Day +from projects.contrasting_trends_in_snow_loads.altitunal_fit.altitudes_studies import AltitudesStudies +from spatio_temporal_dataset.slicer.split import Split, small_s_split_from_ratio +from spatio_temporal_dataset.slicer.temporal_slicer import TemporalSlicer +import pandas as pd + + +class TestAltitudesStudies(unittest.TestCase): + + def setUp(self) -> None: + super().setUp() + altitudes = [900, 1200] + study_class = SafranSnowfall1Day + self.studies = AltitudesStudies(study_class, altitudes, year_min=1959, year_max=1962) + + def test_spatio_temporal_coordinates_with_temporal_split(self): + s_split_temporal = self.studies.random_s_split_temporal(train_split_ratio=0.75) + coordinates = self.studies.spatio_temporal_coordinates(slicer_class=TemporalSlicer, + s_split_temporal=s_split_temporal) + train_values = coordinates.coordinates_values(split=Split.train_temporal) + self.assertEqual(train_values.shape, (6, 2)) + test_values = coordinates.coordinates_values(split=Split.test_temporal) + self.assertEqual(test_values.shape, (2, 2)) + + +if __name__ == '__main__': + unittest.main() \ No newline at end of file