From 76adfaf11571742f47078d2dead00447b977daaf Mon Sep 17 00:00:00 2001 From: Le Roux Erwan <erwan.le-roux@irstea.fr> Date: Thu, 3 Sep 2020 17:02:32 +0200 Subject: [PATCH] [contrasting] add adamont simulation study class --- .../adamont_data/abstract_simulation_study.py | 131 ++++++++++++++++++ .../adamont_data/download_adamont.py | 50 +++++-- .../adamont_data/snowfall_simulation.py | 32 +++++ .../scm_models_data/abstract_study.py | 2 + ...es_visualizer_for_non_stationary_models.py | 2 +- .../test_adamont_study.py | 13 ++ 6 files changed, 215 insertions(+), 15 deletions(-) create mode 100644 extreme_data/meteo_france_data/adamont_data/abstract_simulation_study.py create mode 100644 extreme_data/meteo_france_data/adamont_data/snowfall_simulation.py create mode 100644 test/test_extreme_data/test_meteo_france_data/test_adamont_study.py diff --git a/extreme_data/meteo_france_data/adamont_data/abstract_simulation_study.py b/extreme_data/meteo_france_data/adamont_data/abstract_simulation_study.py new file mode 100644 index 00000000..add2f790 --- /dev/null +++ b/extreme_data/meteo_france_data/adamont_data/abstract_simulation_study.py @@ -0,0 +1,131 @@ +import os.path as op +import os +from collections import OrderedDict +from datetime import datetime, timedelta +from typing import List + +import numpy as np +from netCDF4._netCDF4 import Dataset + +from extreme_data.meteo_france_data.scm_models_data.abstract_variable import AbstractVariable +from extreme_data.meteo_france_data.scm_models_data.crocus.crocus_variables import CrocusTotalSweVariable +from root_utils import classproperty + +ADAMONT_PATH = r"/home/erwan/Documents/projects/spatiotemporalextremes/local/spatio_temporal_datasets/ADAMONT" + +from cached_property import cached_property + +from extreme_data.meteo_france_data.scm_models_data.abstract_study import AbstractStudy, YEAR_MIN, YEAR_MAX +from extreme_data.meteo_france_data.scm_models_data.safran.safran_variable import SafranSnowfallVariable +from extreme_data.meteo_france_data.scm_models_data.utils import Season, FrenchRegion + + +class SimulationStudy(AbstractStudy): + scenarios = ['HISTO', 'RCP26', 'RCP45', 'RCP85'] + + def __init__(self, variable_class: type, altitude: int = 1800, year_min=YEAR_MIN, year_max=YEAR_MAX, + multiprocessing=True, orientation=None, slope=20.0, season=Season.annual, + french_region=FrenchRegion.alps, split_years=None, + scenario="HISTO", ensemble_idx=0): + super().__init__(variable_class, altitude, year_min, year_max, multiprocessing, orientation, slope, season, + french_region, split_years) + assert scenario in self.scenarios + assert 0 <= ensemble_idx <= 13 + self.scenario = scenario + self.ensemble_idx = ensemble_idx + # Assert the massif_name are in the same order + for i, massif_name in enumerate(self.all_massif_names()): + assert massif_name == self.massif_number_to_massif_name[i + 1] + + @property + def simulations_path(self): + return op.join(ADAMONT_PATH, self.parameter, self.scenario) + + @property + def parameter(self): + return self.variable_class_to_parameter[self.variable_class] + + @classproperty + def variable_class_to_parameter(cls): + return { + SafranSnowfallSimulationVariable: 'Snow', + CrocusTotalSweVariable: 'SNOWSWE', + } + + @property + def nc_path(self): + nc_file = os.listdir(self.simulations_path)[self.ensemble_idx] + return op.join(self.simulations_path, nc_file) + + @property + def massif_number_to_massif_name(self): + # from adamont_data metadata + s = """1 Chablais + 2 Aravis + 3 Mont-Blanc + 4 Bauges + 5 Beaufortain + 6 Haute-Tarentaise + 7 Chartreuse + 8 Belledonne + 9 Maurienne + 10 Vanoise + 11 Haute-Maurienne + 12 Grandes-Rousses + 13 Thabor + 14 Vercors + 15 Oisans + 16 Pelvoux + 17 Queyras + 18 Devoluy + 19 Champsaur + 20 Parpaillon + 21 Ubaye + 22 Haut_Var-Haut_Verdon + 23 Mercantour""" + l = s.split('\n') + return {int(k): m for k, m in dict([e.split() for e in l]).items()} + + @property + def dataset(self): + return Dataset(self.nc_path) + + @cached_property + def ordered_years(self): + return sorted(list(set(self.winter_year_for_each_time_step))) + + @cached_property + def winter_year_for_each_time_step(self): + start = datetime(year=2005, month=8, day=1, hour=6, minute=0, second=0) + hours_after_start = np.array(self.dataset.variables['TIME']) + dates = [start + timedelta(hours=h) for h in hours_after_start] + winter_year = [date.year if date.month < 8 else date.year + 1 for date in dates] + winter_year[-1] = winter_year[-2] + return np.array(winter_year) + + @cached_property + def year_to_variable_object(self) -> OrderedDict: + year_to_data_list = {} + for year in self.ordered_years: + year_to_data_list[year] = [] + data_list = self.dataset.variables[self.variable_class.keyword] + data_year_list = self.winter_year_for_each_time_step + assert len(data_list) == len(data_year_list) + for year_data, data in zip(data_year_list, data_list): + year_to_data_list[year_data].append(data) + year_to_variable_object = OrderedDict() + for year in self.ordered_years: + variable_array = np.array(year_to_data_list[year]) + year_to_variable_object[year] = self.variable_class(variable_array) + return year_to_variable_object + + @cached_property + def flat_mask(self): + zs_list = [int(e) for e in np.array(self.dataset.variables['ZS'])] + return np.array(zs_list) == self.altitude + + @property + def study_massif_names(self) -> List[str]: + massif_ids = np.array(self.dataset.variables['MASSIF_NUMBER'])[self.flat_mask] + return [self.massif_number_to_massif_name[massif_id] for massif_id in massif_ids] + diff --git a/extreme_data/meteo_france_data/adamont_data/download_adamont.py b/extreme_data/meteo_france_data/adamont_data/download_adamont.py index 55f7b857..1b75a25d 100644 --- a/extreme_data/meteo_france_data/adamont_data/download_adamont.py +++ b/extreme_data/meteo_france_data/adamont_data/download_adamont.py @@ -1,20 +1,42 @@ import subprocess -requests = """https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/CNRM-CM5/ALADIN53/historical/day/snowswe/SNOWSWE_PRO_CNRM-ALADIN53_CNRM-CERFACS-CNRM-CM5_HISTO_alp_1950080106_2005073106_6h.nc -https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/IPSL-CM5A/WRF331F/historical/day/snowswe/SNOWSWE_PRO_IPSL-INERIS-WRF331F_IPSL-IPSL-CM5A-MR_HISTO_alp_1951080106_2005073106_6h.nc -https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/CNRM-CM5/RCA4/historical/day/snowswe/SNOWSWE_PRO_SMHI-RCA4_CNRM-CERFACS-CNRM-CM5_HISTO_alp_1970080106_2005073106_6h.nc -https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/EC-EARTH/RCA4/historical/day/snowswe/SNOWSWE_PRO_SMHI-RCA4_ICHEC-EC-EARTH_HISTO_alp_1970080106_2005073106_6h.nc -https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/MOHC-HadGEM2/RCA4/historical/day/snowswe/SNOWSWE_PRO_SMHI-RCA4_MOHC-HadGEM2-ES_HISTO_alp_1981080106_2005073106_6h.nc -https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/IPSL-CM5A/RCA4/historical/day/snowswe/SNOWSWE_PRO_SMHI-RCA4_IPSL-IPSL-CM5A-MR_HISTO_alp_1970080106_2005073106_6h.nc -https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/MPI-ESM-LR/RCA4/historical/day/snowswe/SNOWSWE_PRO_SMHI-RCA4_MPI-M-MPI-ESM-LR_HISTO_alp_1970080106_2005073106_6h.nc -https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/MOHC-HadGEM2/RACMO22E/historical/day/snowswe/SNOWSWE_PRO_KNMI-RACMO22E_MOHC-HadGEM2-ES_HISTO_alp_1981080106_2005073106_6h.nc -https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/CNRM-CM5/CCLM4-8-17/historical/day/snowswe/SNOWSWE_PRO_CLMcom-CCLM4-8-17_CNRM-CERFACS-CNRM-CM5_HISTO_alp_1950080106_2005073106_6h.nc -https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/EC-EARTH/CCLM4-8-17/historical/day/snowswe/SNOWSWE_PRO_CLMcom-CCLM4-8-17_ICHEC-EC-EARTH_HISTO_alp_1950080106_2005073106_6h.nc -https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/MOHC-HadGEM2/CCLM4-8-17/historical/day/snowswe/SNOWSWE_PRO_CLMcom-CCLM4-8-17_MOHC-HadGEM2-ES_HISTO_alp_1981080106_2005073106_6h.nc -https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/MPI-ESM-LR/CCLM4-8-17/historical/day/snowswe/SNOWSWE_PRO_CLMcom-CCLM4-8-17_MPI-M-MPI-ESM-LR_HISTO_alp_1950080106_2005073106_6h.nc -https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/MPI-ESM-LR/REMO019/historical/day/snowswe/SNOWSWE_PRO_MPI-CSC-REMO2009_MPI-M-MPI-ESM-LR_HISTO_alp_1950080106_2005073106_6h.nc -https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/NorESM1/HIRHAM5/historical/day/snowswe/SNOWSWE_PRO_DMI-HIRHAM5_NCC-NorESM1-M_HISTO_alp_1951080106_2005073106_6h.nc """ +Go to: https://drias-prod.meteo.fr/ +On the top left, select "simulation au format netcdf" instead of "simulation au format csv" +Then, select the fact that you want to url +""" + +requests = """https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/CNRM-CM5/ALADIN53/rcp8.5/day/snow/Snow_FORCING_CNRM-ALADIN53_CNRM-CERFACS-CNRM-CM5_RCP85_alp_2005080106_2100080106_daysum.nc +https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/IPSL-CM5A/WRF331F/rcp8.5/day/snow/Snow_FORCING_IPSL-INERIS-WRF331F_IPSL-IPSL-CM5A-MR_RCP85_alp_2005080106_2100080106_daysum.nc +https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/CNRM-CM5/RCA4/rcp8.5/day/snow/Snow_FORCING_SMHI-RCA4_CNRM-CERFACS-CNRM-CM5_RCP85_alp_2005080106_2100080106_daysum.nc +https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/EC-EARTH/RCA4/rcp8.5/day/snow/Snow_FORCING_SMHI-RCA4_ICHEC-EC-EARTH_RCP85_alp_2005080106_2100080106_daysum.nc +https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/MOHC-HadGEM2/RCA4/rcp8.5/day/snow/Snow_FORCING_SMHI-RCA4_MOHC-HadGEM2-ES_RCP85_alp_2005080106_2099080106_daysum.nc +https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/IPSL-CM5A/RCA4/rcp8.5/day/snow/Snow_FORCING_SMHI-RCA4_IPSL-IPSL-CM5A-MR_RCP85_alp_2005080106_2100080106_daysum.nc +https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/MPI-ESM-LR/RCA4/rcp8.5/day/snow/Snow_FORCING_SMHI-RCA4_MPI-M-MPI-ESM-LR_RCP85_alp_2005080106_2100080106_daysum.nc +https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/MOHC-HadGEM2/RACMO22E/rcp8.5/day/snow/Snow_FORCING_KNMI-RACMO22E_MOHC-HadGEM2-ES_RCP85_alp_2005080106_2099080106_daysum.nc +https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/CNRM-CM5/CCLM4-8-17/rcp8.5/day/snow/Snow_FORCING_CLMcom-CCLM4-8-17_CNRM-CERFACS-CNRM-CM5_RCP85_alp_2005080106_2100080106_daysum.nc +https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/EC-EARTH/CCLM4-8-17/rcp8.5/day/snow/Snow_FORCING_CLMcom-CCLM4-8-17_ICHEC-EC-EARTH_RCP85_alp_2005080106_2100080106_daysum.nc +https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/MOHC-HadGEM2/CCLM4-8-17/rcp8.5/day/snow/Snow_FORCING_CLMcom-CCLM4-8-17_MOHC-HadGEM2-ES_RCP85_alp_2005080106_2099080106_daysum.nc +https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/MPI-ESM-LR/CCLM4-8-17/rcp8.5/day/snow/Snow_FORCING_CLMcom-CCLM4-8-17_MPI-M-MPI-ESM-LR_RCP85_alp_2005080106_2100080106_daysum.nc +https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/MPI-ESM-LR/REMO019/rcp8.5/day/snow/Snow_FORCING_MPI-CSC-REMO2009_MPI-M-MPI-ESM-LR_RCP85_alp_2005080106_2100080106_daysum.nc +https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/NorESM1/HIRHAM5/rcp8.5/day/snow/Snow_FORCING_DMI-HIRHAM5_NCC-NorESM1-M_RCP85_alp_2005080106_2100080106_daysum.nc +""" + +# requests = """https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/CNRM-CM5/ALADIN53/historical/day/snowswe/SNOWSWE_PRO_CNRM-ALADIN53_CNRM-CERFACS-CNRM-CM5_HISTO_alp_1950080106_2005073106_6h.nc +# https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/IPSL-CM5A/WRF331F/historical/day/snowswe/SNOWSWE_PRO_IPSL-INERIS-WRF331F_IPSL-IPSL-CM5A-MR_HISTO_alp_1951080106_2005073106_6h.nc +# https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/CNRM-CM5/RCA4/historical/day/snowswe/SNOWSWE_PRO_SMHI-RCA4_CNRM-CERFACS-CNRM-CM5_HISTO_alp_1970080106_2005073106_6h.nc +# https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/EC-EARTH/RCA4/historical/day/snowswe/SNOWSWE_PRO_SMHI-RCA4_ICHEC-EC-EARTH_HISTO_alp_1970080106_2005073106_6h.nc +# https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/MOHC-HadGEM2/RCA4/historical/day/snowswe/SNOWSWE_PRO_SMHI-RCA4_MOHC-HadGEM2-ES_HISTO_alp_1981080106_2005073106_6h.nc +# https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/IPSL-CM5A/RCA4/historical/day/snowswe/SNOWSWE_PRO_SMHI-RCA4_IPSL-IPSL-CM5A-MR_HISTO_alp_1970080106_2005073106_6h.nc +# https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/MPI-ESM-LR/RCA4/historical/day/snowswe/SNOWSWE_PRO_SMHI-RCA4_MPI-M-MPI-ESM-LR_HISTO_alp_1970080106_2005073106_6h.nc +# https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/MOHC-HadGEM2/RACMO22E/historical/day/snowswe/SNOWSWE_PRO_KNMI-RACMO22E_MOHC-HadGEM2-ES_HISTO_alp_1981080106_2005073106_6h.nc +# https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/CNRM-CM5/CCLM4-8-17/historical/day/snowswe/SNOWSWE_PRO_CLMcom-CCLM4-8-17_CNRM-CERFACS-CNRM-CM5_HISTO_alp_1950080106_2005073106_6h.nc +# https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/EC-EARTH/CCLM4-8-17/historical/day/snowswe/SNOWSWE_PRO_CLMcom-CCLM4-8-17_ICHEC-EC-EARTH_HISTO_alp_1950080106_2005073106_6h.nc +# https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/MOHC-HadGEM2/CCLM4-8-17/historical/day/snowswe/SNOWSWE_PRO_CLMcom-CCLM4-8-17_MOHC-HadGEM2-ES_HISTO_alp_1981080106_2005073106_6h.nc +# https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/MPI-ESM-LR/CCLM4-8-17/historical/day/snowswe/SNOWSWE_PRO_CLMcom-CCLM4-8-17_MPI-M-MPI-ESM-LR_HISTO_alp_1950080106_2005073106_6h.nc +# https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/MPI-ESM-LR/REMO019/historical/day/snowswe/SNOWSWE_PRO_MPI-CSC-REMO2009_MPI-M-MPI-ESM-LR_HISTO_alp_1950080106_2005073106_6h.nc +# https://climatedata.umr-cnrm.fr/public/dcsc/projects/DRIAS/ADAMONT2017/Alpes/NorESM1/HIRHAM5/historical/day/snowswe/SNOWSWE_PRO_DMI-HIRHAM5_NCC-NorESM1-M_HISTO_alp_1951080106_2005073106_6h.nc +# """ for request in requests.split('\n')[:]: command_line = 'wget {}'.format(request) diff --git a/extreme_data/meteo_france_data/adamont_data/snowfall_simulation.py b/extreme_data/meteo_france_data/adamont_data/snowfall_simulation.py new file mode 100644 index 00000000..44e0d67b --- /dev/null +++ b/extreme_data/meteo_france_data/adamont_data/snowfall_simulation.py @@ -0,0 +1,32 @@ +import numpy as np + +from extreme_data.meteo_france_data.adamont_data.abstract_simulation_study import SimulationStudy +from extreme_data.meteo_france_data.scm_models_data.abstract_study import YEAR_MIN, YEAR_MAX +from extreme_data.meteo_france_data.scm_models_data.abstract_variable import AbstractVariable +from extreme_data.meteo_france_data.scm_models_data.utils import Season, FrenchRegion + + +class SafranSnowfallSimulationVariable(AbstractVariable): + + @property + def daily_time_serie_array(self) -> np.ndarray: + return self.variable_array + + @classmethod + def keyword(cls): + return 'SNOW' + + +class SafranSnowfallSimulationRCP85(SimulationStudy): + + def __init__(self, altitude: int = 1800, year_min=YEAR_MIN, year_max=YEAR_MAX, + multiprocessing=True, orientation=None, slope=20.0, season=Season.annual, + french_region=FrenchRegion.alps, split_years=None): + super().__init__(SafranSnowfallSimulationVariable, altitude, year_min, year_max, multiprocessing, orientation, + slope, + season, french_region, split_years, "RCP85") + + +if __name__ == '__main__': + study = SafranSnowfallSimulationRCP85(altitude=1800) + print(study.year_to_annual_maxima) diff --git a/extreme_data/meteo_france_data/scm_models_data/abstract_study.py b/extreme_data/meteo_france_data/scm_models_data/abstract_study.py index c6212fef..35d40760 100644 --- a/extreme_data/meteo_france_data/scm_models_data/abstract_study.py +++ b/extreme_data/meteo_france_data/scm_models_data/abstract_study.py @@ -43,6 +43,8 @@ with redirect_stdout(f): filled_marker_legend_list = ['Filled marker =', 'Selected model is significant', 'w.r.t $\mathcal{M}_0$'] filled_marker_legend_list2 = ['Filled marker = Selected', 'model is significant', 'w.r.t $\mathcal{M}_0$'] +YEAR_MIN = 1959 +YEAR_MAX = 2019 class AbstractStudy(object): """ 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 b4aca0e7..1b57bf0c 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 @@ -150,7 +150,7 @@ class AltitudesStudiesVisualizerForNonStationaryModels(StudyVisualizer): pass def plot_year_for_the_peak(self, plot_mean=True): - t_list = 1959 + np.arange(141) + t_list = 1959 + np.arange(20 + 41) # t_list = 1800 + np.arange(400) return_period = 50 for massif_name, one_fold_fit in self.massif_name_to_one_fold_fit.items(): diff --git a/test/test_extreme_data/test_meteo_france_data/test_adamont_study.py b/test/test_extreme_data/test_meteo_france_data/test_adamont_study.py new file mode 100644 index 00000000..4f72286b --- /dev/null +++ b/test/test_extreme_data/test_meteo_france_data/test_adamont_study.py @@ -0,0 +1,13 @@ +import unittest + +from extreme_data.meteo_france_data.adamont_data.snowfall_simulation import SafranSnowfallSimulationRCP85 + + +class TestAdamontStudy(unittest.TestCase): + + def test_year_to_date(self): + study = SafranSnowfallSimulationRCP85(altitude=900) + self.assertTrue(True) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file -- GitLab