wolfhece 2.2.20__py3-none-any.whl → 2.2.24__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. wolfhece/Coordinates_operations.py +3 -1
  2. wolfhece/PyDraw.py +247 -3
  3. wolfhece/Results2DGPU.py +157 -39
  4. wolfhece/__init__.py +1 -0
  5. wolfhece/_add_path.py +9 -0
  6. wolfhece/apps/check_install.py +134 -1
  7. wolfhece/apps/splashscreen.py +1 -1
  8. wolfhece/apps/version.py +1 -1
  9. wolfhece/cli.py +96 -1
  10. wolfhece/hydrology/Optimisation.py +30 -25
  11. wolfhece/irm_qdf.py +67 -1
  12. wolfhece/mesh2d/wolf2dprev.py +4 -2
  13. wolfhece/report/pdf.py +55 -0
  14. wolfhece/report/simplesimgpu.py +1409 -0
  15. wolfhece/tools2d_dll.py +7 -2
  16. wolfhece/wolf_array.py +51 -5
  17. wolfhece/wolf_hist.py +21 -16
  18. wolfhece/wolfresults_2D.py +124 -25
  19. {wolfhece-2.2.20.dist-info → wolfhece-2.2.24.dist-info}/METADATA +3 -1
  20. {wolfhece-2.2.20.dist-info → wolfhece-2.2.24.dist-info}/RECORD +23 -60
  21. {wolfhece-2.2.20.dist-info → wolfhece-2.2.24.dist-info}/entry_points.txt +3 -0
  22. wolfhece/libs/GL/gl.h +0 -1044
  23. wolfhece/libs/GL/glaux.h +0 -272
  24. wolfhece/libs/GL/glcorearb.h +0 -3597
  25. wolfhece/libs/GL/glext.h +0 -11771
  26. wolfhece/libs/GL/glu.h +0 -255
  27. wolfhece/libs/GL/glxext.h +0 -926
  28. wolfhece/libs/GL/wglext.h +0 -840
  29. wolfhece/libs/MSVCP140.dll +0 -0
  30. wolfhece/libs/WolfDll.dll +0 -0
  31. wolfhece/libs/Wolf_tools.dll +0 -0
  32. wolfhece/libs/api-ms-win-crt-heap-l1-1-0.dll +0 -0
  33. wolfhece/libs/api-ms-win-crt-math-l1-1-0.dll +0 -0
  34. wolfhece/libs/api-ms-win-crt-runtime-l1-1-0.dll +0 -0
  35. wolfhece/libs/fribidi-0.dll +0 -0
  36. wolfhece/libs/get_infos.cp310-win_amd64.pyd +0 -0
  37. wolfhece/libs/get_infos.cp311-win_amd64.pyd +0 -0
  38. wolfhece/libs/get_infos.cp312-win_amd64.pyd +0 -0
  39. wolfhece/libs/get_infos.cp313-win_amd64.pyd +0 -0
  40. wolfhece/libs/glu32.dll +0 -0
  41. wolfhece/libs/hdf5.dll +0 -0
  42. wolfhece/libs/hdf5_hl.dll +0 -0
  43. wolfhece/libs/libcurl.dll +0 -0
  44. wolfhece/libs/libpardiso600-WIN-X86-64.dll +0 -0
  45. wolfhece/libs/libraqm.dll +0 -0
  46. wolfhece/libs/msvcr100.dll +0 -0
  47. wolfhece/libs/netcdf.dll +0 -0
  48. wolfhece/libs/paho-mqtt3cs.dll +0 -0
  49. wolfhece/libs/vcomp100.dll +0 -0
  50. wolfhece/libs/vcruntime140.dll +0 -0
  51. wolfhece/libs/vcruntime140_1.dll +0 -0
  52. wolfhece/libs/verify_wolf.cp310-win_amd64.pyd +0 -0
  53. wolfhece/libs/verify_wolf.cp311-win_amd64.pyd +0 -0
  54. wolfhece/libs/verify_wolf.cp312-win_amd64.pyd +0 -0
  55. wolfhece/libs/verify_wolf.cp313-win_amd64.pyd +0 -0
  56. wolfhece/libs/wolfogl.cp310-win_amd64.pyd +0 -0
  57. wolfhece/libs/wolfogl.cp311-win_amd64.pyd +0 -0
  58. wolfhece/libs/wolfogl.cp312-win_amd64.pyd +0 -0
  59. wolfhece/libs/wolfogl.cp313-win_amd64.pyd +0 -0
  60. wolfhece/libs/zlib1.dll +0 -0
  61. {wolfhece-2.2.20.dist-info → wolfhece-2.2.24.dist-info}/WHEEL +0 -0
  62. {wolfhece-2.2.20.dist-info → wolfhece-2.2.24.dist-info}/top_level.txt +0 -0
wolfhece/_add_path.py CHANGED
@@ -3,6 +3,11 @@ import os.path
3
3
  import sys
4
4
  import platform
5
5
 
6
+ try:
7
+ import wolf_libs
8
+ except ImportError:
9
+ print("wolf_libs not found. Please install the wolf-libs package -- pip install wolf-libs.")
10
+ sys.exit(1)
6
11
 
7
12
  def _add_path():
8
13
  _root_dir = os.path.dirname(os.path.realpath(__file__))
@@ -10,6 +15,10 @@ def _add_path():
10
15
  # manual specify list of dll directories, with paths relative to _root_dir
11
16
  _dll_dirs = ['libs', 'shaders']
12
17
 
18
+ # add wolf_libs path to __dll_dirs
19
+ if wolf_libs.__path__:
20
+ _dll_dirs.insert(0, os.path.join(wolf_libs.__path__[0]))
21
+
13
22
  if platform.system() == 'Windows':
14
23
  os.environ.setdefault('PATH', '')
15
24
  paths = os.environ['PATH'].split(';')
@@ -8,6 +8,99 @@ Copyright (c) 2024 University of Liege. All rights reserved.
8
8
  This script and its content are protected by copyright law. Unauthorized
9
9
  copying or distribution of this file, via any medium, is strictly prohibited.
10
10
  """
11
+ def test_conversion_LBT72_LBT08():
12
+
13
+ from pyproj.transformer import TransformerGroup
14
+
15
+ # Créer le groupe de transformateurs
16
+ tg = TransformerGroup(31370, 3812)
17
+
18
+ # Choisir le premier transformateur (ou un autre selon ton besoin)
19
+ transformer = tg.transformers[0]
20
+
21
+ print(transformer.description)
22
+ if '(3)' in transformer.description:
23
+ # This is the Belgian Lambert 72 + BD72 to ETRS89 (3) + Belgian Lambert 2008
24
+ return True
25
+ elif '(2)' in transformer.description:
26
+ # This is the Belgian Lambert 72 + BD72 to ETRS89 (2) + Belgian Lambert 2008
27
+ return False
28
+ elif '(1)' in transformer.description:
29
+ # This is the Belgian Lambert 72 + BD72 to ETRS89 (1) + Belgian Lambert 2008
30
+ return False
31
+ else:
32
+ # This is not the expected transformer
33
+ return False
34
+
35
+ def test_conversion_LBT08_LBT72():
36
+
37
+ from pyproj.transformer import TransformerGroup
38
+
39
+ # Créer le groupe de transformateurs
40
+ tg = TransformerGroup(3812, 31370)
41
+
42
+ # Choisir le premier transformateur (ou un autre selon ton besoin)
43
+ transformer = tg.transformers[0]
44
+
45
+ print(transformer.description)
46
+ if '(3)' in transformer.description:
47
+ # This is the Belgian Lambert 72 + BD72 to ETRS89 (3) + Belgian Lambert 2008
48
+ return True
49
+ elif '(2)' in transformer.description:
50
+ # This is the Belgian Lambert 72 + BD72 to ETRS89 (2) + Belgian Lambert 2008
51
+ return False
52
+ elif '(1)' in transformer.description:
53
+ # This is the Belgian Lambert 72 + BD72 to ETRS89 (1) + Belgian Lambert 2008
54
+ return False
55
+ else:
56
+ # This is not the expected transformer
57
+ return False
58
+
59
+ def test_transform_coordinates():
60
+ from pyproj.transformer import TransformerGroup
61
+ from pyproj import Transformer
62
+ import numpy as np
63
+ from wolfhece.Coordinates_operations import transform_coordinates
64
+ tg = TransformerGroup(31370, 3812)
65
+
66
+ ret = True
67
+
68
+ ret = ret and len(tg.transformers) > 0
69
+ ret = ret and len(tg.transformers) == 3
70
+ ret = ret and '(3)' in tg.transformers[0].description
71
+ ret = ret and '(2)' in tg.transformers[1].description
72
+ ret = ret and '(1)' in tg.transformers[2].description
73
+
74
+ tg_inv = TransformerGroup(3812, 31370)
75
+ ret = ret and len(tg_inv.transformers) > 0
76
+ ret = ret and len(tg_inv.transformers) == 3
77
+ ret = ret and '(3)' in tg_inv.transformers[0].description
78
+ ret = ret and '(2)' in tg_inv.transformers[1].description
79
+ ret = ret and '(1)' in tg_inv.transformers[2].description
80
+
81
+ tr = Transformer.from_crs(31370, 3812)
82
+
83
+ points = np.array([[100000, 200000], [110000, 210000], [120000, 220000]])
84
+
85
+ transformed_points_3 = tg.transformers[0].transform(points[:, 0], points[:, 1])
86
+ transformed_points_2 = tg.transformers[1].transform(points[:, 0], points[:, 1])
87
+ transformed_points_1 = tg.transformers[2].transform(points[:, 0], points[:, 1])
88
+ transformed_points = tr.transform(points[:, 0], points[:, 1])
89
+ transform_wolf = transform_coordinates(points, inputEPSG='EPSG:31370', outputEPSG='EPSG:3812')
90
+
91
+ # Convert to numpy arrays
92
+ transformed_points_3 = np.array(transformed_points_3).T
93
+ transformed_points_2 = np.array(transformed_points_2).T
94
+ transformed_points_1 = np.array(transformed_points_1).T
95
+ transformed_points = np.array(transformed_points).T
96
+
97
+ # Assert that the transformed points are equal
98
+ ret = ret and np.all(transformed_points_3 == transform_wolf)
99
+ ret = ret and np.all(transformed_points_3 == transformed_points)
100
+ ret = ret and not np.all(transformed_points_2 == transformed_points)
101
+ ret = ret and not np.all(transformed_points_1 == transformed_points)
102
+
103
+ return ret
11
104
 
12
105
  def main():
13
106
  # Check if installation is complete
@@ -32,13 +125,53 @@ def main():
32
125
  ret += 'Error during osgeo import - GDAL/OGR not/bad installed\n Please (re)install GDAL (64 bits version) from https://github.com/cgohlke/geospatial-wheels/releases\n\n'
33
126
  ret += 'Error : ' + str(e) + '\n\n'
34
127
 
128
+ if 'pyproj' in packages:
129
+ ret += 'PyProj seems installed\n\n'
130
+ try:
131
+ conv = test_conversion_LBT72_LBT08()
132
+
133
+ if conv:
134
+ ret += 'NTv2 conversion from Lambert 72 to Lambert 2008 seems available\n\n'
135
+ else:
136
+ ret += 'NTv2 conversion from Lambert 72 to Lambert 2008 seems NOT available\n\n'
137
+ ret += 'Please check if the PROJ data files are installed correctly - See OSGOE4W instructions\n\n'
138
+ except ImportError as e:
139
+ ret += 'PyProj not installed properly\n Please install PyProj from "pip install pyproj"\n\n'
140
+ ret += 'Error : ' + str(e) + '\n\n'
141
+
142
+ try:
143
+ conv = test_conversion_LBT08_LBT72()
144
+
145
+ if conv:
146
+ ret += 'NTv2 conversion from Lambert 2008 to Lambert 72 seems available\n\n'
147
+ else:
148
+ ret += 'NTv2 conversion from Lambert 2008 to Lambert 72 seems NOT available\n\n'
149
+ ret += 'Please check if the PROJ data files are installed correctly - See OSGOE4W instructions\n\n'
150
+ except ImportError as e:
151
+ ret += 'PyProj not installed properly\n Please install PyProj from "pip install pyproj"\n\n'
152
+ ret += 'Error : ' + str(e) + '\n\n'
153
+
154
+ try:
155
+ conv = test_transform_coordinates()
156
+ if conv:
157
+ ret += 'Transform coordinates function seems working fine\n\n'
158
+ else:
159
+ ret += 'Transform coordinates function seems NOT available\n\n'
160
+ ret += 'Please check if the PROJ data files are installed correctly - See OSGOE4W instructions\n\n'
161
+ except ImportError as e:
162
+ ret += 'PyProj not installed properly\n Please install PyProj from "pip install pyproj"\n\n'
163
+ ret += 'Error : ' + str(e) + '\n\n'
164
+
165
+ else:
166
+ ret += 'PyProj not installed\n Please install PyProj from "pip install pyproj"\n\n'
167
+
35
168
  if 'wolfgpu' in packages:
36
169
  ret += 'WolfGPU seems installed\n\n'
37
170
  else:
38
171
  ret += 'WolfGPU not installed\n Please install WolfGPU if needed\n\n'
39
172
 
40
173
  # try:
41
- # from ..libs import wolfpy
174
+ # from wolf_libs import wolfpy
42
175
  # ret += 'Wolfpy accessible\n\n'
43
176
  # except ImportError as e:
44
177
  # ret += 'Wolfpy not accessible\n\n'
@@ -23,7 +23,7 @@ import time
23
23
  from wx.adv import SplashScreen as SplashScreen,SPLASH_CENTRE_ON_SCREEN,SPLASH_TIMEOUT,Sound
24
24
 
25
25
  try:
26
- from ..libs import wolfogl
26
+ from wolf_libs import wolfogl
27
27
  except ImportError:
28
28
  print("** WolfOGL not found **")
29
29
  print("Without WolfOGL, the application will not work !")
wolfhece/apps/version.py CHANGED
@@ -5,7 +5,7 @@ class WolfVersion():
5
5
 
6
6
  self.major = 2
7
7
  self.minor = 2
8
- self.patch = 20
8
+ self.patch = 24
9
9
 
10
10
  def __str__(self):
11
11
 
wolfhece/cli.py CHANGED
@@ -15,7 +15,8 @@ def check():
15
15
 
16
16
  def license():
17
17
  """ Main wolf application : License """
18
- from .libs.wolfogl import request_license
18
+ from wolf_libs.wolfogl import request_license
19
+
19
20
  from pathlib import Path
20
21
 
21
22
  if Path(__file__).parent / 'license' / 'wolf.lic':
@@ -76,6 +77,100 @@ def hydro():
76
77
  from .apps.wolfhydro import main
77
78
  main()
78
79
 
80
+ def report_gpu():
81
+ """ Application for generating GPU simulation reports """
82
+ from .report.simplesimgpu import SimpleSimGPU_Report
83
+
84
+ # récupère l'argument de la ligne de commande
85
+ from pathlib import Path
86
+ import sys
87
+ n = len(sys.argv)
88
+
89
+ if n == 3:
90
+ outpath = Path(sys.argv[2])
91
+ mydir = Path(sys.argv[1])
92
+ elif n == 2:
93
+ outpath = Path('.')
94
+ mydir = Path(sys.argv[1])
95
+ else:
96
+ print('Usage: wolf_report_gpu <directory> or wolf_report_gpu <directory> <directory_out>')
97
+
98
+ if n in [2, 3]:
99
+ if mydir.exists():
100
+ report = SimpleSimGPU_Report(mydir)
101
+ report.create_report()
102
+ report.save_report(outpath / (mydir.name + '_report.pdf'))
103
+ else:
104
+ print('Directory not found')
105
+ else:
106
+ print('Usage: wolf_report_gpu <directory>')
107
+
108
+ def reports_gpu():
109
+ """ Application for generating GPU simulation reports """
110
+ from .report.simplesimgpu import SimpleSimGPU_Report
111
+
112
+ # récupère l'argument de la ligne de commande
113
+ from pathlib import Path
114
+ import glob
115
+ import sys
116
+ n = len(sys.argv)
117
+
118
+ if n == 3:
119
+ outpath = Path(sys.argv[2])
120
+ mydir = Path(sys.argv[1])
121
+ elif n == 2:
122
+ mydir = Path(sys.argv[1])
123
+ outpath = Path('.')
124
+ else:
125
+ print('Usage: wolf_reports_gpu <directory> or wolf_reports_gpu <directory> <directory_out>')
126
+
127
+ if n in [2, 3]:
128
+ if mydir.exists():
129
+ # find all sims in the directory
130
+ sim_dirs = Path(mydir).rglob('parameters.json')
131
+ sim_dirs = [Path(d).parent for d in sim_dirs]
132
+ if not sim_dirs:
133
+ print('No simulation directories found in {}'.format(mydir))
134
+ return
135
+ # create a report for each simulation
136
+ for sim_dir in sim_dirs:
137
+ print('Creating report for {}'.format(sim_dir))
138
+ report = SimpleSimGPU_Report(sim_dir)
139
+ report.create_report()
140
+ report.save_report(outpath / (sim_dir.name + '_report.pdf'))
141
+ else:
142
+ print('Directory not found')
143
+
144
+ def report_compare():
145
+ """ Application for comparing GPU simulation reports """
146
+ from .report.simplesimgpu import SimpleSimGPU_Report_Compare
147
+
148
+ # récupère l'argument de la ligne de commande
149
+ from pathlib import Path
150
+ import sys
151
+ n = len(sys.argv)
152
+ if n == 2:
153
+ mydir = Path(sys.argv[1])
154
+ if mydir.exists():
155
+ report = SimpleSimGPU_Report_Compare(mydir)
156
+ report.create_report()
157
+ report.save_report(mydir.name + '_report_compare.pdf')
158
+ else:
159
+ print('Directory not found')
160
+ elif n > 2:
161
+ files = [Path(f) for f in sys.argv[1:]]
162
+ if all(f.exists() for f in files):
163
+ report = SimpleSimGPU_Report_Compare(files)
164
+ report.create_report()
165
+ report.save_report('report_compare.pdf')
166
+ else:
167
+ for f in files:
168
+ if not f.exists():
169
+ print('File {} not found'.format(f))
170
+ else:
171
+ print('Usage: wolf_report_compare <directory> or wolf_report_compare <file1> <file2> ...')
172
+
173
+
79
174
  def compare():
80
175
  """ Application for comparing 2D arrays """
81
176
  from .apps.wolfcompare2Darrays import main
@@ -19,6 +19,8 @@ from matplotlib.backends.backend_wxagg import (
19
19
  import shutil
20
20
  import ctypes as ct
21
21
 
22
+
23
+ import wolf_libs
22
24
  from .PostProcessHydrology import PostProcessHydrology
23
25
  from .Catchment import *
24
26
  from .Comparison import *
@@ -148,7 +150,10 @@ class Optimisation(wx.Frame):
148
150
  self.myParams = {}
149
151
  self.myParamsPy = {}
150
152
  self.nbParams = 0
151
- self.pathDll = Path(os.path.dirname(__file__)).parent
153
+
154
+ #self.pathDll = Path(os.path.dirname(__file__)).parent
155
+ # point to the wolf_libs package directory
156
+ self.pathDll = wolf_libs.__path__[0]
152
157
 
153
158
  self.callBack_proc = {}
154
159
  self.callBack_ptr = {}
@@ -234,8 +239,8 @@ class Optimisation(wx.Frame):
234
239
  self.Bind(wx.EVT_MENU, self.launch_models_propertie_with_Nash, testEquiFinClick)
235
240
  plotEquiFinClick = toolMenu.Append(wx.ID_ANY, 'Plot analysis with Nash')
236
241
  self.Bind(wx.EVT_MENU, self.plot_model_analysis, plotEquiFinClick)
237
-
238
-
242
+
243
+
239
244
 
240
245
  # Creation of the Lauch Menu
241
246
  launchMenu = wx.Menu()
@@ -2021,7 +2026,7 @@ class Optimisation(wx.Frame):
2021
2026
  myGroup = myModelDict[int(myType)]["Group"][iFile]
2022
2027
  myKey = myModelDict[int(myType)]["Key"][iFile]
2023
2028
  self.write_one_opti_param(filePath, fileName, myGroup, myKey, params[i], convers_factor=convFact[iFile])
2024
- else:
2029
+ else:
2025
2030
  self.curParams_vec_F[i] = params[i]
2026
2031
  self.update_timeDelay(i+1)
2027
2032
  refCatch.save_timeDelays([self.myParams[i+1]["junction_name"]])
@@ -2676,10 +2681,10 @@ class Optimisation(wx.Frame):
2676
2681
  logging.info("The equifinality test is finished!")
2677
2682
 
2678
2683
 
2679
- def get_best_params(self, stationOut:str,
2684
+ def get_best_params(self, stationOut:str,
2680
2685
  criterion:str="Nash", quantile:float=0.99, std:float=0.05, eps:float=0.2, rmv_near_max=1e-4, nb_rand_close:int=10,
2681
2686
  objective_fct:bool= True, apply_clustering:bool=False, objective_weight:float=1.0):
2682
- from sklearn.cluster import DBSCAN
2687
+ from sklearn.cluster import DBSCAN
2683
2688
  """
2684
2689
  Get the best parameters for a given station.
2685
2690
 
@@ -2832,10 +2837,10 @@ class Optimisation(wx.Frame):
2832
2837
  return None
2833
2838
  cur_fracts = curBasin.get_volume_fractions(interval=intervals)
2834
2839
  return cur_fracts
2835
-
2836
- def _get_flow_fractions(self, idLauncher:int=0, stationOut:str="",
2840
+
2841
+ def _get_flow_fractions(self, idLauncher:int=0, stationOut:str="",
2837
2842
  intervals:list[tuple[datetime.datetime, datetime.datetime]]=[]) -> dict[list[str], list[float]]:
2838
-
2843
+
2839
2844
  curCatch:Catchment = self.myCases[idLauncher].refCatchment
2840
2845
  cur_key = curCatch.get_key_catchmentDict(stationOut)
2841
2846
  curBasin: SubBasin = curCatch.catchmentDict[cur_key]
@@ -2844,11 +2849,11 @@ class Optimisation(wx.Frame):
2844
2849
  return None
2845
2850
  cur_fracts = curBasin.get_flow_fractions(interval=intervals, summary="mean")
2846
2851
  return cur_fracts
2847
-
2848
2852
 
2849
- def _get_punctual_reservoir_fractions(self, eval_date:datetime.datetime,
2853
+
2854
+ def _get_punctual_reservoir_fractions(self, eval_date:datetime.datetime,
2850
2855
  idLauncher:int=0, stationOut:str="") -> dict[list[str], list[float]]:
2851
-
2856
+
2852
2857
  curCatch:Catchment = self.myCases[idLauncher].refCatchment
2853
2858
  cur_key = curCatch.get_key_catchmentDict(stationOut)
2854
2859
  curBasin: SubBasin = curCatch.catchmentDict[cur_key]
@@ -2856,7 +2861,7 @@ class Optimisation(wx.Frame):
2856
2861
  logging.warning("The current module is not a SubBasin object!")
2857
2862
  return None
2858
2863
  linked_params = mc.MODELS_VAR[curBasin.model].get_all_linked_params()
2859
- i_params = self._get_key_from_type_all_parameters(list(linked_params.values()))
2864
+ i_params = self._get_key_from_type_all_parameters(list(linked_params.values()))
2860
2865
  max_params = {var_name: self.myParams[i_params[param_id]]["value"] for var_name, param_id in linked_params.items()}
2861
2866
  cur_fracts = curBasin.get_iv_fractions_one_date(max_params=max_params, eval_date=eval_date)
2862
2867
  return cur_fracts
@@ -3021,7 +3026,7 @@ class Optimisation(wx.Frame):
3021
3026
  cur_columns = [col for col in df.columns if cur_prop in col.replace(" ", "")]
3022
3027
  if cur_columns != []:
3023
3028
  corr_prop = cur_columns[0]
3024
- ax.scatter(df.loc[:,corr_prop], df.loc[:,y_label], s=0.5, c=cur_color,
3029
+ ax.scatter(df.loc[:,corr_prop], df.loc[:,y_label], s=0.5, c=cur_color,
3025
3030
  marker='o', label=cur_prop, alpha=0.4)
3026
3031
  ax.set_xlabel("% of the rain [-]")
3027
3032
  ax.set_ylabel(y_label+" [-]")
@@ -3049,10 +3054,10 @@ class Optimisation(wx.Frame):
3049
3054
  ax.set_title("Peak analysis : "+stationOut)
3050
3055
  ax.legend()
3051
3056
  fig.savefig(os.path.join(self.workingDir, "Equifinality_peaks_ratio_"+stationOut+".png"))
3052
-
3057
+
3053
3058
  else:
3054
3059
  logging.error("The file "+filename+" does not exist!")
3055
-
3060
+
3056
3061
  plt.show()
3057
3062
 
3058
3063
 
@@ -3212,7 +3217,7 @@ class Optimisation(wx.Frame):
3212
3217
 
3213
3218
  # FIXME : this function has been dashed off -> functionnal but not well written!!
3214
3219
  # TODO : to improve !!!!!!
3215
- def launch_models_propertie_with_Nash(self, event, idLauncher:int=0, idOpti:int=1, quantile_Nash:float=0.01, std_Nash:float=0.03, clustering_Nash:bool=True,
3220
+ def launch_models_propertie_with_Nash(self, event, idLauncher:int=0, idOpti:int=1, quantile_Nash:float=0.01, std_Nash:float=0.03, clustering_Nash:bool=True,
3216
3221
  save_every:int=100, restart_from_file:bool=True):
3217
3222
  """
3218
3223
  Analyse the properties of the model and compare them with the Nash coefficient.
@@ -3232,11 +3237,11 @@ class Optimisation(wx.Frame):
3232
3237
  if onlyOwnSub is None:
3233
3238
  onlyOwnSub = False
3234
3239
  doneList = []
3235
- previousLevel = 1
3240
+ previousLevel = 1
3236
3241
  # Collect sort and save the compare stations
3237
3242
  self.set_compare_stations(idLauncher=idLauncher)
3238
3243
  sortJct = self.myStations
3239
- # Get the initial number of intervals
3244
+ # Get the initial number of intervals
3240
3245
  # -> these can evolve according to the measurement available at each station
3241
3246
  is_ok = self._save_opti_intervals()
3242
3247
  all_intervals = self.all_intervals
@@ -3268,14 +3273,14 @@ class Optimisation(wx.Frame):
3268
3273
  # Reload the useful modules
3269
3274
  self.reload_hydro(idCompar=0, fromStation=stationOut, lastLevel=previousLevel, updateAll=True)
3270
3275
  ## =======
3271
- ## Init
3276
+ ## Init
3272
3277
  ## =======
3273
3278
  self.init_optimizer(idOpti)
3274
3279
  self.associate_ptr(None, idOpti=idOpti)
3275
3280
  # Get the best parameters to test
3276
3281
  all_params = self.get_best_params(stationOut=stationOut, quantile=quantile_Nash, std=std_Nash, rmv_near_max=1e-4, apply_clustering=clustering_Nash)
3277
3282
  ## =======
3278
- ## Compute
3283
+ ## Compute
3279
3284
  ## =======
3280
3285
  all_frac = []
3281
3286
  # Check if the excel file already exists and load it to check if some parameters have already been tested
@@ -3307,7 +3312,7 @@ class Optimisation(wx.Frame):
3307
3312
  cur_all_frac = (list(cur_p)
3308
3313
  + cur_timeDelays
3309
3314
  + list(frac_flow_dict.values())
3310
- + list(init_iv.values())
3315
+ + list(init_iv.values())
3311
3316
  + [p_excess, max_sim_obs, cur_obj])
3312
3317
  all_frac.append(cur_all_frac)
3313
3318
  # Periodically save the evaluations in case of trouble
@@ -3364,14 +3369,14 @@ class Optimisation(wx.Frame):
3364
3369
  # FIXME : it might be better to pass the myParams to the CaseOpti object instead to allow parallelisation
3365
3370
  def _build_type_to_key_index(self) -> dict[int, int]:
3366
3371
  return {param["type"]: i for i, param in self.myParams.items()}
3367
-
3372
+
3368
3373
  def _get_key_from_type_all_parameters(self, list_type_param: list[int]) -> dict[int | None]:
3369
3374
  type_to_key = self._build_type_to_key_index()
3370
3375
  return {cur_key: type_to_key.get(cur_key) for cur_key in list_type_param}
3371
3376
 
3372
3377
  def _get_key_from_type_parameter(self, type_param:int) -> int:
3373
3378
  return next((i for i, param in self.myParams.items() if param["type"] == type_param), None)
3374
-
3379
+
3375
3380
 
3376
3381
  def make_nd_array(self, c_pointer, shape, dtype=np.float64, order='C', own_data=True,readonly=False):
3377
3382
  arr_size = np.prod(shape[:]) * np.dtype(dtype).itemsize
@@ -3417,5 +3422,5 @@ class Optimisation(wx.Frame):
3417
3422
  # Remove the parameters that have already been tested
3418
3423
  new_params = np.array([el for el in all_params if ~np.any(np.all(np.isclose(all_params_tested, el[:-1], atol=1e-6), axis=1))])
3419
3424
  return all_data_tested, new_params
3420
-
3425
+
3421
3426
  return [], all_params
wolfhece/irm_qdf.py CHANGED
@@ -746,4 +746,70 @@ class QDF_Belgium():
746
746
  return None
747
747
  else:
748
748
  logging.error(f"Name {key} not found in the data")
749
- return None
749
+ return None
750
+
751
+
752
+ class Climate_IRM():
753
+
754
+ def __init__(self, store_path= 'irm', ins:Literal['2018', '2019', '2025', 2018, 2019, 2025] = 2018) -> None:
755
+ self.store_path = Path(store_path)
756
+ self.localities = Localities(ins)
757
+
758
+ self._climate_data = {}
759
+
760
+ def __getitem__(self, key):
761
+ return self._climate_data[key]
762
+
763
+ @classmethod
764
+ def importfromwebsite(cls, store_path= 'irm', verbose:bool= False, waitingtime:float= .01, ins:Literal['2018', '2019', '2025', 2018, 2019, 2025] = 2018, ins_code: int = None):
765
+ """ Import Excel files for one or all municipalities from the IRM website
766
+
767
+ :param store_path: Where to store the downloaded data. Directory will be created if it doesn't exists.
768
+ :param verbose: If `True`, will print some progress information.
769
+ If `False`, will do nothing.
770
+ If a callable, then will call it with a float in [0, 1].
771
+ 0 means nothing downloaded, 1 means everything downloaded.
772
+
773
+ :param waitingtime: How long to wait (in seconds) betwenn the download
774
+ of each station (will make sure we don't overwhelm IRM's website).
775
+
776
+ :param ins: The year of the INS codes to use.
777
+ :param code: Restricts the data download to a specific NIS code. `None` means full download.
778
+ """
779
+ import requests
780
+
781
+ myloc = Localities(ins)
782
+
783
+ if ins_code is not None:
784
+ codes_to_load = [ins_code]
785
+ else:
786
+ if not path.exists(store_path):
787
+ mkdir(store_path)
788
+ codes_to_load = myloc.inscode2name
789
+
790
+ for key,myins in enumerate(codes_to_load):
791
+ #chaîne URL du fichier Excel
792
+ url="https://www.meteo.be//resources//climatology//climateCity//pdf//climate_INS"+str(myins)+"_9120_fr.pdf"
793
+ #Obtention du fichiers depuis le site web de l'IRM
794
+ response=requests.get(url)
795
+
796
+ if str(response.content).find("Page not found")==-1 :
797
+
798
+ # Make sure we create the store path only if we have
799
+ # something to put inside.
800
+ if ins_code is not None and not path.exists(store_path):
801
+ mkdir(store_path)
802
+
803
+ file=open(path.join(store_path,str(myins)+".pdf"), 'wb')
804
+ file.write(response.content)
805
+ file.close()
806
+ if verbose:
807
+ if callable(verbose):
808
+ verbose(key/len(codes_to_load))
809
+ else:
810
+ print(myins)
811
+ else:
812
+ #logging.error(response.content)
813
+ logging.error(f"Failed to load IRM data: {url} --> {response}")
814
+
815
+ sleep(waitingtime)
@@ -11484,7 +11484,8 @@ class prev_sim2D():
11484
11484
  if len(lst) == 0:
11485
11485
  logging.warning('No potential BC found -- Test can not be performed -- I continue anyway')
11486
11486
  else:
11487
- if i not in lst[0] or j not in lst[1]:
11487
+ candidate_cells = list(zip(lst[0], lst[1]))
11488
+ if (i, j) not in candidate_cells:
11488
11489
  logging.error(f'Invalid indices ({i},{j}) - BC not added')
11489
11490
  return
11490
11491
 
@@ -11506,7 +11507,8 @@ class prev_sim2D():
11506
11507
  if len(lst) == 0:
11507
11508
  logging.warning('No potential BC found -- Test can not be performed -- I continue anyway')
11508
11509
  else:
11509
- if i not in lst[0] or j not in lst[1]:
11510
+ candidate_cells = list(zip(lst[0], lst[1]))
11511
+ if (i, j) not in candidate_cells:
11510
11512
  logging.error(f'Invalid indices ({i},{j}) - BC not added')
11511
11513
  return
11512
11514
 
wolfhece/report/pdf.py ADDED
@@ -0,0 +1,55 @@
1
+ """ WX Frame displaying a PDF file """
2
+ import wx
3
+ import wx.lib.sized_controls as sc
4
+ from wx.lib.pdfviewer import pdfViewer, pdfButtonPanel
5
+
6
+ from pathlib import Path
7
+
8
+ class PDFViewer(sc.SizedFrame):
9
+
10
+ def __init__(self, parent, **kwargs):
11
+ """ Initialize the PDF Viewer Frame """
12
+ super(PDFViewer, self).__init__(parent, **kwargs)
13
+
14
+ paneCont = self.GetContentsPane()
15
+ self.buttonpanel = pdfButtonPanel(paneCont, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, 0)
16
+ self.buttonpanel.SetSizerProps(expand=True)
17
+
18
+ self.viewer:pdfViewer
19
+ self.viewer = pdfViewer(paneCont, wx.ID_ANY, wx.DefaultPosition,
20
+ wx.DefaultSize,
21
+ wx.HSCROLL|wx.VSCROLL|wx.SUNKEN_BORDER)
22
+
23
+ self.viewer.SetSizerProps(expand=True, proportion=1)
24
+
25
+ # introduce buttonpanel and viewer to each other
26
+ self.buttonpanel.viewer = self.viewer
27
+ self.viewer.buttonpanel = self.buttonpanel
28
+
29
+ icon = wx.Icon()
30
+ icon_path = Path(__file__).parent.parent / "apps/wolf_logo2.bmp"
31
+ icon.CopyFromBitmap(wx.Bitmap(str(icon_path), wx.BITMAP_TYPE_ANY))
32
+ self.SetIcon(icon)
33
+
34
+
35
+ def load_pdf(self, pdf_path:str):
36
+ """ Load a PDF file into the viewer """
37
+
38
+ if not Path(pdf_path).exists():
39
+ wx.MessageBox("PDF file does not exist.", "Error", wx.OK | wx.ICON_ERROR)
40
+ return
41
+
42
+ try:
43
+ self.viewer.LoadFile(str(pdf_path))
44
+ except Exception as e:
45
+ wx.MessageBox("Failed to load PDF file.", "Error", wx.OK | wx.ICON_ERROR)
46
+
47
+ if __name__ == '__main__':
48
+ import wx.lib.mixins.inspection as WIT
49
+ app = WIT.InspectableApp(redirect=False)
50
+
51
+ pdfV = PDFViewer(None)
52
+ pdfV.load_pdf(Path(__file__).parent.parent.parent /'tests' / 'data' / 'pdf' / "dummy.pdf") # Change to your PDF file path
53
+ pdfV.Show()
54
+
55
+ app.MainLoop()