diff --git a/experiment/meteo_france_SCM_study/abstract_extended_study.py b/experiment/meteo_france_SCM_study/abstract_extended_study.py index 8d62a5b7d7588a92429eb99fd1862ba3d151916f..e59c9a538661520c867a1ee3932518bc7ff63b88 100644 --- a/experiment/meteo_france_SCM_study/abstract_extended_study.py +++ b/experiment/meteo_france_SCM_study/abstract_extended_study.py @@ -19,8 +19,8 @@ class AbstractExtendedStudy(AbstractStudy): return len(self.region_names) @property - def safran_massif_names(self): - return self.region_names + super().safran_massif_names + def study_massif_names(self): + return self.region_names + super().study_massif_names @property def massif_name_to_region_name(self): @@ -58,7 +58,7 @@ class AbstractExtendedStudy(AbstractStudy): def _year_to_extended_time_serie(self, aggregation_function) -> OrderedDict: year_to_extended_time_serie = OrderedDict() for year, old_time_serie in super()._year_to_daily_time_serie_array.items(): - new_time_serie = np.zeros([len(old_time_serie), len(self.safran_massif_names)]) + new_time_serie = np.zeros([len(old_time_serie), len(self.study_massif_names)]) new_time_serie[:, self.nb_region_names:] = old_time_serie for i, region_name in enumerate(self.region_names): massifs_ids_belong_to_region = self.region_name_to_massif_ids[region_name] diff --git a/experiment/meteo_france_SCM_study/abstract_study.py b/experiment/meteo_france_SCM_study/abstract_study.py index b0beb53de09a3a7ab35a42956a64aa087da486b6..37c067a355dd5b64e73180227cb5794bfe3e73d6 100644 --- a/experiment/meteo_france_SCM_study/abstract_study.py +++ b/experiment/meteo_france_SCM_study/abstract_study.py @@ -1,17 +1,19 @@ +import io import os -import numpy as np -from PIL import Image, ImageDraw import os.path as op from collections import OrderedDict +from contextlib import redirect_stdout from typing import List, Dict, Tuple import matplotlib.pyplot as plt +import numpy as np import pandas as pd from PIL import Image +from PIL import ImageDraw from netCDF4 import Dataset from experiment.meteo_france_SCM_study.abstract_variable import AbstractVariable -from experiment.meteo_france_SCM_study.massif import safran_massif_names_from_datasets +from experiment.meteo_france_SCM_study.altitude import ALTITUDES, ZS_INT_23, ZS_INT_MASK from experiment.meteo_france_SCM_study.visualization.utils import get_km_formatter from extreme_estimator.extreme_models.margin_model.margin_function.abstract_margin_function import \ AbstractMarginFunction @@ -22,12 +24,19 @@ from spatio_temporal_dataset.coordinates.spatial_coordinates.abstract_spatial_co from spatio_temporal_dataset.spatio_temporal_observations.annual_maxima_observations import AnnualMaxima from utils import get_full_path, cached_property +f = io.StringIO() +with redirect_stdout(f): + from simpledbf import Dbf5 + class AbstractStudy(object): - ALTITUDES = [1800, 2400] + """ + Les fichiers netcdf sont autodocumentés (on peut les comprendre avec ncdump -h notamment). + """ + REANALYSIS_FOLDER = 'alp_flat/reanalysis' def __init__(self, variable_class: type, altitude: int = 1800, year_min=1000, year_max=3000): - assert altitude in self.ALTITUDES, altitude + assert altitude in ALTITUDES, altitude self.altitude = altitude self.model_name = None self.variable_class = variable_class @@ -43,18 +52,18 @@ class AbstractStudy(object): @property def df_all_daily_time_series_concatenated(self) -> pd.DataFrame: - df_list = [pd.DataFrame(time_serie, columns=self.safran_massif_names) for time_serie in + df_list = [pd.DataFrame(time_serie, columns=self.study_massif_names) for time_serie in self.year_to_daily_time_serie_array.values()] df_concatenated = pd.concat(df_list) return df_concatenated @property def observations_annual_maxima(self) -> AnnualMaxima: - return AnnualMaxima(df_maxima_gev=pd.DataFrame(self.year_to_annual_maxima, index=self.safran_massif_names)) + return AnnualMaxima(df_maxima_gev=pd.DataFrame(self.year_to_annual_maxima, index=self.study_massif_names)) @property def df_annual_total(self) -> pd.DataFrame: - return pd.DataFrame(self.year_to_annual_total, index=self.safran_massif_names).transpose() + return pd.DataFrame(self.year_to_annual_total, index=self.study_massif_names).transpose() def annual_aggregation_function(self, *args, **kwargs): raise NotImplementedError() @@ -65,10 +74,10 @@ class AbstractStudy(object): def year_to_dataset_ordered_dict(self) -> OrderedDict: # Map each year to the correspond netCDF4 Dataset year_to_dataset = OrderedDict() - nc_files = [(int(f.split('_')[-2][:4]), f) for f in os.listdir(self.safran_full_path) if f.endswith('.nc')] + nc_files = [(int(f.split('_')[-2][:4]), f) for f in os.listdir(self.study_full_path) if f.endswith('.nc')] for year, nc_file in sorted(nc_files, key=lambda t: t[0]): if self.year_min <= year < self.year_max: - year_to_dataset[year] = Dataset(op.join(self.safran_full_path, nc_file)) + year_to_dataset[year] = Dataset(op.join(self.study_full_path, nc_file)) return year_to_dataset @property @@ -111,7 +120,13 @@ class AbstractStudy(object): self.year_to_dataset_ordered_dict.items()} year_to_daily_time_serie_array = OrderedDict() for year in self.year_to_dataset_ordered_dict.keys(): - year_to_daily_time_serie_array[year] = year_to_variable[year].daily_time_serie_array + # Check daily data + daily_time_serie = year_to_variable[year].daily_time_serie_array + assert daily_time_serie.shape[0] in [365, 366] + assert daily_time_serie.shape[1] == len(ZS_INT_MASK) + # Filter only the data corresponding to the altitude of interest + daily_time_serie = daily_time_serie[:, self.altitude_mask] + year_to_daily_time_serie_array[year] = daily_time_serie return year_to_daily_time_serie_array @property @@ -121,17 +136,27 @@ class AbstractStudy(object): ########## @property - def safran_massif_names(self) -> List[str]: - return self.original_safran_massif_names + def study_massif_names(self) -> List[str]: + return self.altitude_to_massif_names[self.altitude] - @property - def original_safran_massif_names(self) -> List[str]: - # Load the names of the massif as defined by SAFRAN - return safran_massif_names_from_datasets(list(self.year_to_dataset_ordered_dict.values()), self.altitude) + @cached_property + def all_massif_names(self) -> List[str]: + """ + Pour l'identification des massifs, le numéro de la variable massif_num correspond à celui de l'attribut num_opp + """ + metadata_path = op.join(self.full_path, self.REANALYSIS_FOLDER, 'metadata') + dbf = Dbf5(op.join(metadata_path, 'massifs_alpes.dbf')) + df = dbf.to_dataframe().copy() # type: pd.DataFrame + dbf.f.close() + df.sort_values(by='num_opp', inplace=True) + all_massif_names = list(df['nom']) + # Correct a massif name + all_massif_names[all_massif_names.index('Beaufortin')] = 'Beaufortain' + return all_massif_names @property def original_safran_massif_id_to_massif_name(self) -> Dict[int, str]: - return {massif_id: massif_name for massif_id, massif_name in enumerate(self.original_safran_massif_names)} + return {massif_id: massif_name for massif_id, massif_name in enumerate(self.all_massif_names)} @cached_property def massifs_coordinates(self) -> AbstractSpatialCoordinates: @@ -143,10 +168,14 @@ class AbstractStudy(object): return AbstractSpatialCoordinates.from_df(df_centroid) def load_df_centroid(self) -> pd.DataFrame: + # Load df_centroid containing all the massif names df_centroid = pd.read_csv(op.join(self.map_full_path, 'coordonnees_massifs_alpes.csv')) df_centroid.set_index('NOM', inplace=True) + # Check that the names of massifs are the same + symmetric_difference = set(df_centroid.index).symmetric_difference(self.all_massif_names) + assert len(symmetric_difference) == 0, symmetric_difference # Sort the column in the order of the SAFRAN dataset - df_centroid = df_centroid.loc[self.original_safran_massif_names] + df_centroid = df_centroid.reindex(self.all_massif_names, axis=0) return df_centroid @property @@ -250,6 +279,36 @@ class AbstractStudy(object): """ Some properties """ + @cached_property + def massif_name_to_altitudes(self) -> Dict[str, List[int]]: + s = ZS_INT_23 + [0] + zs_list = [] + zs_all_list = [] + for a, b in zip(s[:-1], s[1:]): + zs_list.append(a) + if a > b: + zs_all_list.append(zs_list) + zs_list = [] + return dict(zip(self.all_massif_names, zs_all_list)) + + @cached_property + def altitude_to_massif_names(self) -> Dict[int, List[str]]: + altitude_to_massif_names = {altitude: [] for altitude in ALTITUDES} + for massif_name in self.massif_name_to_altitudes.keys(): + for altitude in self.massif_name_to_altitudes[massif_name]: + altitude_to_massif_names[altitude].append(massif_name) + return altitude_to_massif_names + + @property + def missing_massif_name(self): + return set(self.all_massif_names) - set(self.altitude_to_massif_names[self.altitude]) + + @cached_property + def altitude_mask(self): + altitude_mask = ZS_INT_MASK == self.altitude + assert np.sum(altitude_mask) == len(self.altitude_to_massif_names[self.altitude]) + return altitude_mask + @property def title(self): return "{} at altitude {}m".format(self.variable_name, self.altitude) @@ -262,6 +321,8 @@ class AbstractStudy(object): def variable_unit(self): return self.variable_class.UNIT + """ Some path properties """ + @property def relative_path(self) -> str: return r'local/spatio_temporal_datasets' @@ -270,11 +331,6 @@ class AbstractStudy(object): def full_path(self) -> str: return get_full_path(relative_path=self.relative_path) - @property - def safran_full_path(self) -> str: - assert self.model_name in ['Safran', 'Crocus'] - return op.join(self.full_path, 'safran-crocus_{}'.format(self.altitude), self.model_name) - @property def map_full_path(self) -> str: return op.join(self.full_path, 'map') @@ -282,3 +338,13 @@ class AbstractStudy(object): @property def result_full_path(self) -> str: return op.join(self.full_path, 'results') + + @property + def study_full_path(self) -> str: + assert self.model_name in ['Safran', 'Crocus'] + study_folder = 'meteo' if self.model_name is 'Safran' else 'pro' + return op.join(self.full_path, self.REANALYSIS_FOLDER, study_folder) + + + + diff --git a/experiment/meteo_france_SCM_study/altitude.py b/experiment/meteo_france_SCM_study/altitude.py new file mode 100644 index 0000000000000000000000000000000000000000..3b78a5babd478dff13554ac2d861d162767f1c4e --- /dev/null +++ b/experiment/meteo_france_SCM_study/altitude.py @@ -0,0 +1,44 @@ + +""" +ZS was extracted from a netcdf file +""" +import numpy as np + +ZS = """[ 300. 600. 900. 1200. 1500. 1800. 2100. 2400. 2700. 3000. 3300. 300. +600. 900. 1200. 1500. 1800. 2100. 2400. 2700. 3000. 300. 600. 900. +1200. 1500. 1800. 2100. 2400. 2700. 3000. 3300. 3600. 3900. 4200. 4500. +4800. 0. 300. 600. 900. 1200. 1500. 1800. 2100. 2400. 300. 600. +900. 1200. 1500. 1800. 2100. 2400. 2700. 3000. 600. 900. 1200. 1500. +1800. 2100. 2400. 2700. 3000. 3300. 3600. 3900. 0. 300. 600. 900. +1200. 1500. 1800. 2100. 0. 300. 600. 900. 1200. 1500. 1800. 2100. +2400. 2700. 3000. 0. 300. 600. 900. 1200. 1500. 1800. 2100. 2400. +2700. 3000. 3300. 300. 600. 900. 1200. 1500. 1800. 2100. 2400. 2700. +3000. 3300. 3600. 3900. 900. 1200. 1500. 1800. 2100. 2400. 2700. 3000. +3300. 3600. 3900. 600. 900. 1200. 1500. 1800. 2100. 2400. 2700. 3000. +3300. 3600. 900. 1200. 1500. 1800. 2100. 2400. 2700. 3000. 3300. 0. +300. 600. 900. 1200. 1500. 1800. 2100. 2400. 0. 300. 600. 900. +1200. 1500. 1800. 2100. 2400. 2700. 3000. 3300. 3600. 3900. 4200. 900. +1200. 1500. 1800. 2100. 2400. 2700. 3000. 3300. 3600. 3900. 4200. 900. +1200. 1500. 1800. 2100. 2400. 2700. 3000. 3300. 300. 600. 900. 1200. +1500. 1800. 2100. 2400. 2700. 3000. 600. 900. 1200. 1500. 1800. 2100. +2400. 2700. 3000. 3300. 3600. 600. 900. 1200. 1500. 1800. 2100. 2400. +2700. 3000. 3300. 600. 900. 1200. 1500. 1800. 2100. 2400. 2700. 3000. +3300. 3600. 0. 300. 600. 900. 1200. 1500. 1800. 2100. 2400. 2700. +3000. 3300. 300. 600. 900. 1200. 1500. 1800. 2100. 2400. 2700. 3000. +3300. 300. 600. 900. 1200. 1500. 1800. 2100. 2400. 2700. 3000.]""" + +ZS_INT = [int(float(e)) for e in ZS[1:-1].split()] +ALTITUDES = sorted(set(ZS_INT)) + + +# Create a ZS_INT with only the 23 first massifs +ZS_INT_23 = ZS_INT[:-10].copy() + +# Create a ZS_INT with np.nan all altitudes corresponding to the 24th massif +ZS_INT_MASK = np.array(ZS_INT) +ZS_INT_MASK[-10:] = np.nan + + + + + diff --git a/experiment/meteo_france_SCM_study/crocus/crocus.py b/experiment/meteo_france_SCM_study/crocus/crocus.py index 98084eca108ef31cd95b3f816783a0dc0c233c73..940d7c22af2f743d4915c4b3e11771b46dcf8789 100644 --- a/experiment/meteo_france_SCM_study/crocus/crocus.py +++ b/experiment/meteo_france_SCM_study/crocus/crocus.py @@ -67,8 +67,8 @@ class CrocusDaysWithSnowOnGround(Crocus): if __name__ == '__main__': - for variable_clas in [CrocusSweVariable, CrocusDepthVariable]: - study = Crocus(variable_class=variable_clas, altitude=2400) + for variable_class in [CrocusSweVariable, CrocusDepthVariable]: + study = Crocus(variable_class=variable_class, altitude=2400) d = study.year_to_dataset_ordered_dict[1960] time_arr = np.array(d.variables['time']) print(time_arr) diff --git a/experiment/meteo_france_SCM_study/crocus/crocus_variables.py b/experiment/meteo_france_SCM_study/crocus/crocus_variables.py index 3bc06074e14098bf451cb211210351d86964141c..cd4f2e7238239a09a5979a8e58a741f33370ba1b 100644 --- a/experiment/meteo_france_SCM_study/crocus/crocus_variables.py +++ b/experiment/meteo_france_SCM_study/crocus/crocus_variables.py @@ -13,18 +13,7 @@ class CrocusVariable(AbstractVariable): @property def daily_time_serie_array(self) -> np.ndarray: - time_serie_every_6_hours = np.array(self.dataset.variables[self.variable_name])[:, 0, :] - if self.altitude == 2400: - time_serie_daily = time_serie_every_6_hours - else: - nb_days = len(time_serie_every_6_hours) // 4 - # The first value of each day is selected (in order to be comparable to an instantaneous value) - time_serie_daily = np.array([time_serie_every_6_hours[4 * i] for i in range(nb_days)]) - # Take the mean over a full day (WARNING: by doing that I am potentially destroying some maxima) - # (I could also create a special mode where I take the maximum instead of the mean here) - # time_serie_daily = np.array([np.mean(time_serie_every_6_hours[4 * i:4 * (i + 1)], axis=0) - # for i in range(nb_days)]) - return time_serie_daily + return np.array(self.dataset.variables[self.variable_name]) class CrocusSweVariable(CrocusVariable): @@ -32,7 +21,7 @@ class CrocusSweVariable(CrocusVariable): UNIT = 'kg/m2 or mm' def __init__(self, dataset, altitude): - super().__init__(dataset, altitude, 'SNOWSWE') + super().__init__(dataset, altitude, 'SWE_1DY_ISBA') class CrocusDepthVariable(CrocusVariable): @@ -40,5 +29,5 @@ class CrocusDepthVariable(CrocusVariable): UNIT = 'm' def __init__(self, dataset, altitude): - super().__init__(dataset, altitude, "SNOWDEPTH") + super().__init__(dataset, altitude, "SD_1DY_ISBA") diff --git a/experiment/meteo_france_SCM_study/new_safran_study.py b/experiment/meteo_france_SCM_study/new_safran_study.py deleted file mode 100644 index 5e72ba92a99e11d2ea42ce0d5ab626064c3ec4b3..0000000000000000000000000000000000000000 --- a/experiment/meteo_france_SCM_study/new_safran_study.py +++ /dev/null @@ -1,31 +0,0 @@ -import numpy as np - -from experiment.meteo_france_SCM_study.abstract_study import AbstractStudy -import os.path as op - -from experiment.meteo_france_SCM_study.safran.safran_variable import SafranSnowfallVariable - - -class NewStudy(AbstractStudy): - - - @property - def safran_full_path(self) -> str: - return op.join(self.full_path, 'alp_flat/reanalysis/meteo') - # return op.join(self.full_path, 'alp_flat/reanalysis/pro') - -if __name__ == '__main__': - study = NewStudy(SafranSnowfallVariable) - d = study.year_to_dataset_ordered_dict[1958] - print(d) - s = study.year_to_daily_time_serie_array[1958].shape - print(s) - print(s[1] / 23) - print(d.variables['massif']) - print(np.array(d.variables['massif'])) - - for item in ['LAT', 'LON', 'ZS', 'massif']: - a = np.array(d.variables[item]) - print(a) - s = set(a) - print(len(s)) diff --git a/experiment/meteo_france_SCM_study/safran/safran.py b/experiment/meteo_france_SCM_study/safran/safran.py index d34ed4ed8c9c5b4897d4caeab15894843642bbb3..7e4d928270f049da9c8290bf4c72bcb550aaa5ad 100644 --- a/experiment/meteo_france_SCM_study/safran/safran.py +++ b/experiment/meteo_france_SCM_study/safran/safran.py @@ -70,12 +70,15 @@ class SafranTemperature(Safran): if __name__ == '__main__': - study = SafranSnowfall(altitude=2400) - for year, dataset in study.year_to_dataset_ordered_dict.items(): - print('{}: {}'.format(year, dataset.massifsList)) + study = SafranSnowfall(altitude=1800) d = study.year_to_dataset_ordered_dict[1958] - print(d.variables['time']) - print(study.year_to_daily_time_serie_array[1958].shape) + # print(d.variables['time']) + # print(study.all_massif_names) + # print(study.massif_name_to_altitudes) + # print(study.year_to_daily_time_serie_array[1958].shape) + print(study.missing_massif_name) + + # print(len(d.variables['time'])) # print(study.year_to_annual_total) # print(study.df_annual_total.columns) diff --git a/experiment/meteo_france_SCM_study/visualization/studies_visualization/studies.py b/experiment/meteo_france_SCM_study/visualization/studies_visualization/studies.py index 784f1bc013b3df92333cca8098dca4b25074a402..7a64c33e0b390b9df33f015b8627149b1e121d56 100644 --- a/experiment/meteo_france_SCM_study/visualization/studies_visualization/studies.py +++ b/experiment/meteo_france_SCM_study/visualization/studies_visualization/studies.py @@ -2,6 +2,7 @@ from collections import OrderedDict from typing import Dict from experiment.meteo_france_SCM_study.abstract_study import AbstractStudy +from experiment.meteo_france_SCM_study.altitude import ALTITUDES class Studies(object): @@ -11,11 +12,11 @@ class Studies(object): def __init__(self, study_type, altitude_list=None) -> None: # Load altitude_list attribute if altitude_list is None: - altitude_list = AbstractStudy.ALTITUDES + altitude_list = ALTITUDES else: assert isinstance(altitude_list, list) assert len(altitude_list) > 0 - assert all([altitudes in AbstractStudy.ALTITUDES for altitudes in altitude_list]) + assert all([altitudes in ALTITUDES for altitudes in altitude_list]) altitude_list = sorted(altitude_list) self.altitude_list = altitude_list # Load altitude_to_study attribute diff --git a/experiment/meteo_france_SCM_study/visualization/studies_visualization/studies_visualizer.py b/experiment/meteo_france_SCM_study/visualization/studies_visualization/studies_visualizer.py index da944dafb05d30a61b4c13de159c67f6a7ef8e23..e10979f8c0aaa7b484c819652f6c2f3bd5aa1cc2 100644 --- a/experiment/meteo_france_SCM_study/visualization/studies_visualization/studies_visualizer.py +++ b/experiment/meteo_france_SCM_study/visualization/studies_visualization/studies_visualizer.py @@ -23,7 +23,7 @@ class StudiesVisualizer(object): assert isinstance(self.first_study, AbstractExtendedStudy) massif_names = self.first_study.region_names else: - massif_names = self.first_study.safran_massif_names + massif_names = self.first_study.study_massif_names # Load the dictionary that maps each massif_name to its corresponding time series mean_series = [] for study in self.studies.altitude_to_study.values(): diff --git a/experiment/meteo_france_SCM_study/visualization/study_visualization/main_study_visualizer.py b/experiment/meteo_france_SCM_study/visualization/study_visualization/main_study_visualizer.py index eaf5c6578fb91eec75cb080fae47396e77ef9159..43e3d2eda4e46801f2205187a48a28b3219ba2f6 100644 --- a/experiment/meteo_france_SCM_study/visualization/study_visualization/main_study_visualizer.py +++ b/experiment/meteo_france_SCM_study/visualization/study_visualization/main_study_visualizer.py @@ -19,7 +19,7 @@ def study_iterator(study_class, only_first_one=False, both_altitude=False, verbo if verbose: print('Loading studies....') for nb_day in nb_days: - for alti in AbstractStudy.ALTITUDES[::1]: + for alti in [1800]: if verbose: print('alti: {}, nb_day: {}'.format(alti, nb_day)) study = study_class(altitude=alti, nb_consecutive_days=nb_day) if is_safran_study \ @@ -51,7 +51,7 @@ def extended_visualization(): def annual_mean_vizu_compare_durand_study(safran=True, take_mean_value=True, altitude=1800): if safran: - for study_class in [SafranTotalPrecip, SafranRainfall, SafranSnowfall, SafranTemperature][2:3]: + for study_class in [SafranTotalPrecip, SafranRainfall, SafranSnowfall, SafranTemperature][-1:]: study = study_class(altitude=altitude, year_min=1958, year_max=2002) study_visualizer = StudyVisualizer(study) study_visualizer.visualize_annual_mean_values(take_mean_value=True) @@ -69,10 +69,10 @@ def max_stable_process_vizu_compare_gaume_study(altitude=1800, nb_days=1): def normal_visualization(temporal_non_stationarity=False): - save_to_file = False + save_to_file = True only_first_one = True # for study_class in SCM_STUDIES[:1]: - for study_class in [CrocusDepth, SafranSnowfall, SafranRainfall, SafranTemperature][:1]: + for study_class in [CrocusDepth, SafranSnowfall, SafranRainfall, SafranTemperature][:]: for study in study_iterator(study_class, only_first_one=only_first_one): study_visualizer = StudyVisualizer(study, save_to_file=save_to_file, temporal_non_stationarity=temporal_non_stationarity) # study_visualizer.visualize_independent_margin_fits(threshold=[None, 20, 40, 60][0]) @@ -91,13 +91,13 @@ def complete_analysis(only_first_one=False): study_visualizer.visualize_all_experimental_law() print('Study normal') for study in study_iterator(study_class, only_first_one=only_first_one): - study_visualizer = StudyVisualizer(study, save_to_file=True) - study_visualizer.visualize_linear_margin_fit() + study_visualizer = StudyVisualizer(study, save_to_file=True) + study_visualizer.visualize_linear_margin_fit() if __name__ == '__main__': - # annual_mean_vizu_compare_durand_study(safran=True, take_mean_value=True, altitude=2400) - # normal_visualization(temporal_non_stationarity=False) + annual_mean_vizu_compare_durand_study(safran=True, take_mean_value=True, altitude=2100) + # normal_visualization(temporal_non_stationarity=True) # max_stable_process_vizu_compare_gaume_study(altitude=1800, nb_days=1) - extended_visualization() + # extended_visualization() # complete_analysis() diff --git a/experiment/meteo_france_SCM_study/visualization/study_visualization/study_visualizer.py b/experiment/meteo_france_SCM_study/visualization/study_visualization/study_visualizer.py index d07642b7bbe13d5286f92204810efe9f24c64e9c..d1dad192052b48a3c8ef9f4b057f2b2d6ce948e2 100644 --- a/experiment/meteo_france_SCM_study/visualization/study_visualization/study_visualizer.py +++ b/experiment/meteo_france_SCM_study/visualization/study_visualization/study_visualizer.py @@ -111,15 +111,15 @@ class StudyVisualizer(object): visualize_function(ax, 0) else: nb_columns = 5 - nb_rows = 1 if self.only_first_row else math.ceil(len(self.study.safran_massif_names) / nb_columns) + nb_rows = 1 if self.only_first_row else math.ceil(len(self.study.study_massif_names) / nb_columns) fig, axes = plt.subplots(nb_rows, nb_columns, figsize=self.figsize) fig.subplots_adjust(hspace=self.subplot_space, wspace=self.subplot_space) if self.only_first_row: - for massif_id, massif_name in enumerate(self.study.safran_massif_names[:nb_columns]): + for massif_id, massif_name in enumerate(self.study.study_massif_names[:nb_columns]): ax = axes[massif_id] visualize_function(ax, massif_id) else: - for massif_id, massif_name in enumerate(self.study.safran_massif_names): + for massif_id, massif_name in enumerate(self.study.study_massif_names): row_id, column_id = massif_id // nb_columns, massif_id % nb_columns ax = axes[row_id, column_id] visualize_function(ax, massif_id) @@ -204,7 +204,7 @@ class StudyVisualizer(object): extraticks = [float(float_to_str_with_only_some_significant_digits(t, nb_digits=2)) for t in extraticks] set_ticks_function(extraticks) if not self.only_one_graph: - ax.set_title(self.study.safran_massif_names[massif_id]) + ax.set_title(self.study.study_massif_names[massif_id]) ax.legend() def get_all_massif_data(self, massif_id): @@ -241,7 +241,7 @@ class StudyVisualizer(object): ax.plot(x, y, color=color_mean) ax.set_ylabel('mean with sliding window of size {}'.format(self.window_size_for_smoothing), color=color_mean) ax.set_xlabel('year') - ax.set_title(self.study.safran_massif_names[massif_id]) + ax.set_title(self.study.study_massif_names[massif_id]) def visualize_brown_resnick_fit(self): pass @@ -391,11 +391,13 @@ class StudyVisualizer(object): massif_name_to_value = OrderedDict() df_annual_total = self.study.df_annual_total - for massif_id, massif_name in enumerate(self.study.safran_massif_names): + for massif_name in self.study.study_massif_names: # We take the mean over all the annual values, otherwise we take the max value = df_annual_total.loc[:, massif_name] value = value.mean() if take_mean_value else value.max() massif_name_to_value[massif_name] = value + print(len(massif_name_to_value)) + print(massif_name_to_value) self.study.visualize_study(ax=ax, massif_name_to_value=massif_name_to_value, show=self.show, add_text=True, label=self.study.variable_name) @@ -409,12 +411,12 @@ class StudyVisualizer(object): def df_gev_mle(self) -> pd.DataFrame: # Fit a margin_fits on each massif massif_to_gev_mle = {massif_name: GevMleFit(self.df_maxima_gev.loc[massif_name]).gev_params.summary_serie - for massif_name in self.study.safran_massif_names} - return pd.DataFrame(massif_to_gev_mle, columns=self.study.safran_massif_names) + for massif_name in self.study.study_massif_names} + return pd.DataFrame(massif_to_gev_mle, columns=self.study.study_massif_names) def df_gpd_mle(self, threshold) -> pd.DataFrame: # Fit a margin fit on each massif massif_to_gev_mle = {massif_name: GpdMleFit(self.study.df_all_daily_time_series_concatenated[massif_name], threshold=threshold).gpd_params.summary_serie - for massif_name in self.study.safran_massif_names} - return pd.DataFrame(massif_to_gev_mle, columns=self.study.safran_massif_names) + for massif_name in self.study.study_massif_names} + return pd.DataFrame(massif_to_gev_mle, columns=self.study.study_massif_names) diff --git a/test/test_experiment/test_meteo_france_SCM_study/test_SCM_study.py b/test/test_experiment/test_meteo_france_SCM_study/test_SCM_study.py index 09c1148191fb88df0664130fca7bf2b70c64e2f6..3686f7662a4aa80aba976a20e24ac637955fd1c5 100644 --- a/test/test_experiment/test_meteo_france_SCM_study/test_SCM_study.py +++ b/test/test_experiment/test_meteo_france_SCM_study/test_SCM_study.py @@ -10,7 +10,6 @@ from experiment.meteo_france_SCM_study.safran.safran import SafranSnowfall, Exte from experiment.meteo_france_SCM_study.visualization.study_visualization.study_visualizer import StudyVisualizer from test.test_utils import load_scm_studies - class TestSCMAllStudy(unittest.TestCase): def test_extended_run(self): @@ -24,7 +23,6 @@ class TestSCMAllStudy(unittest.TestCase): for study in load_scm_studies(): time_serie = study.year_to_daily_time_serie_array[1958] self.assertTrue(time_serie.ndim == 2, msg='for {} ndim={}'.format(study.__repr__(), time_serie.ndim)) - self.assertTrue(time_serie.shape[1] in [21, 23]) self.assertTrue(len(time_serie) in [365, 366], msg="current time serie length for {} is {}".format(study.__repr__(), len(time_serie))) @@ -54,7 +52,7 @@ class TestSCMSafranSnowfall(TestSCMStudy): def test_massif_safran(self): df_centroid = pd.read_csv(op.join(self.study.map_full_path, 'coordonnees_massifs_alpes.csv')) # Assert that the massif names are the same between SAFRAN and the coordinate file - assert not set(self.study.safran_massif_names).symmetric_difference(set(df_centroid['NOM'])) + assert not set(self.study.study_massif_names).symmetric_difference(set(df_centroid['NOM'])) class TestSCMPrecipitation(TestSCMStudy): @@ -68,8 +66,8 @@ class TestSCMPrecipitation(TestSCMStudy): # (some small differences probably due to the fact that SAFRAN model has evolved since then) # Test for the mean total precipitation (rainfall + snowfall) between 1958 and 2002 self.check({ - "Mercantour": 1346, - 'Chablais': 1928, + "Mercantour": 1281, + 'Chablais': 1922, }) def round(self, f): @@ -86,12 +84,12 @@ class TestSafranTemperature(TestSCMStudy): # Test based on Durand paper # Test for the mean temperature between 1958 and 2002 self.check({ - "Mercantour": 5.1, - 'Chablais': 3.4, + "Mercantour": 5.3, + 'Chablais': 3.5, }) def round(self, f): - return round(f, 1) + return round(float(f), 1) if __name__ == '__main__':