wolfhece 2.2.43__py3-none-any.whl → 2.2.44__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.
wolfhece/analyze_poly.py CHANGED
@@ -58,7 +58,7 @@ class Array_analysis_onepolygon():
58
58
  self.compute_values()
59
59
 
60
60
  if which == 'Area' and 'Area' not in self._values:
61
- self._add_area2velues()
61
+ self._add_area2values()
62
62
 
63
63
  if self._values is None:
64
64
  raise ValueError("No values computed. Please call compute_values() first.")
@@ -76,7 +76,7 @@ class Array_analysis_onepolygon():
76
76
  if add_values:
77
77
  if self._values is None:
78
78
  self.compute_values()
79
- self._add_area2velues()
79
+ self._add_area2values()
80
80
 
81
81
  if self._values is None:
82
82
  raise ValueError("No values computed. Please call compute_values() first.")
@@ -147,7 +147,7 @@ class Array_analysis_onepolygon():
147
147
  else:
148
148
  self._values = self._wa.statistics(self._selected_cells)
149
149
 
150
- def _add_area2velues(self):
150
+ def _add_area2values(self):
151
151
  """ Add the area of the polygon to the values """
152
152
 
153
153
  if self._selected_cells is None:
@@ -1044,7 +1044,26 @@ class Arrays_analysis_zones():
1044
1044
  if engine == 'seaborn':
1045
1045
  return self._plot_count_strictly_positive_seaborn(show=show, merge_zones=merge_zones)
1046
1046
  elif engine == 'plotly':
1047
- return self.plot_count_strictly_positive_plotly(show=show, merge_zones=merge_zones)
1047
+ return self._plot_count_strictly_positive_plotly(show=show, merge_zones=merge_zones)
1048
+
1049
+ def save_plot_count_strictly_positive(self, filepath:Path | str,
1050
+ merge_zones:bool = False,
1051
+ dpi:int = 300):
1052
+ """ Save the plot of the count of strictly positive values for each array in each zone.
1053
+ :param filepath: path to the image file (png)
1054
+ :param merge_zones: whether to merge the zones in the plot
1055
+ :param dpi: resolution of the saved plot
1056
+ :return: None
1057
+ """
1058
+ import matplotlib.pyplot as plt
1059
+ # Force Agg backend for saving the plot
1060
+ old_back = plt.get_backend()
1061
+ plt.switch_backend('Agg')
1062
+ fig, ax = self.plot_count_strictly_positive(show=False, merge_zones=merge_zones, engine='seaborn')
1063
+ fig.savefig(filepath, bbox_inches='tight', dpi=dpi)
1064
+ plt.close(fig)
1065
+ # Restore the previous backend
1066
+ plt.switch_backend(old_back)
1048
1067
 
1049
1068
  def _plot_count_strictly_positive_seaborn(self, show:bool = True, merge_zones:bool = False):
1050
1069
  """ Plot the count of strictly positive values for each array in each zone using seaborn
@@ -1122,6 +1141,32 @@ class Arrays_analysis_zones():
1122
1141
  else:
1123
1142
  raise ValueError(f"Invalid engine '{engine}'. Must be 'seaborn' or 'plotly'.")
1124
1143
 
1144
+ def save_plot_distributed_values(self, filepath:Path | str,
1145
+ bins:list[float]= [0., .3, 1.3, -1],
1146
+ operator:Literal['Mean', 'Median', 'Sum', 'Volume', 'Area'] = 'Median',
1147
+ merge_zones:bool = False,
1148
+ dpi:int = 300):
1149
+ """ Save the plot of the distribution of values in bins for each array in each zone or merged zones.
1150
+
1151
+ :param filepath: path to the image file (png)
1152
+ :param bins: list of bin edges
1153
+ :param operator: 'Mean', 'Median', 'Sum', 'Volume', 'Area
1154
+ :param merge_zones: whether to merge the zones in the plot
1155
+ :return: None
1156
+ """
1157
+ import matplotlib.pyplot as plt
1158
+
1159
+ # Force Agg backend for saving the plot
1160
+ old_back = plt.get_backend()
1161
+ plt.switch_backend('Agg')
1162
+
1163
+ fig, ax = self.plot_distributed_values(bins, operator, show=False, merge_zones=merge_zones, engine='seaborn')
1164
+
1165
+ fig.savefig(filepath, bbox_inches='tight', dpi=dpi)
1166
+ plt.close(fig)
1167
+ # Restore the previous backend
1168
+ plt.switch_backend(old_back)
1169
+
1125
1170
  def _plot_distributed_values_seaborn(self, bins:list[float],
1126
1171
  operator:Literal['Mean', 'Median', 'Sum', 'Volume', 'Area'],
1127
1172
  show:bool = True,
@@ -1137,6 +1182,11 @@ class Arrays_analysis_zones():
1137
1182
  import seaborn as sns
1138
1183
  import matplotlib.pyplot as plt
1139
1184
 
1185
+ # Check which engine is used by matplotlib
1186
+ backend = plt.get_backend()
1187
+ if backend in ['Agg']:
1188
+ show = False
1189
+
1140
1190
  df = self._values_as_df(operator, merge_zones=merge_zones)
1141
1191
 
1142
1192
  if bins[-1] == -1:
@@ -1181,6 +1231,124 @@ class Arrays_analysis_zones():
1181
1231
 
1182
1232
  return (figs, axs)
1183
1233
 
1234
+ def _get_distributed_values(self,
1235
+ bins:list[float],
1236
+ operator:Literal['Mean', 'Median', 'Sum', 'Volume', 'Area'],
1237
+ merge_zones:bool = False):
1238
+
1239
+ """ Save the distribution of values in bins for each array in each zone as a CSV file.
1240
+
1241
+ :param bins: list of bin edges
1242
+ :param operator: 'Mean', 'Median', 'Sum', 'Volume', 'Area
1243
+ :param merge_zones: whether to merge the zones in the plot
1244
+ """
1245
+
1246
+ df = self._values_as_df(operator, merge_zones=merge_zones)
1247
+ if bins[-1] == -1:
1248
+ bins[-1] = df['Value'].max()
1249
+
1250
+ # Bin and count for each array
1251
+ result = []
1252
+ for array in df['Array'].unique():
1253
+ values = df[df['Array'] == array]['Value']
1254
+ counts, edges = np.histogram(values, bins=bins)
1255
+ for edge, count in zip(edges[:-1], counts):
1256
+ result.append({'Array': array, 'Rightmost edge': edge, 'Count': count})
1257
+
1258
+ return pd.DataFrame(result)
1259
+
1260
+ def save_distributed_values(self,
1261
+ filepath:Path | str,
1262
+ bins:list[float],
1263
+ operator:Literal['Mean', 'Median', 'Sum', 'Volume', 'Area'],
1264
+ merge_zones:bool = False):
1265
+
1266
+ """ Save the distribution of values in bins for each array in each zone as a CSV file.
1267
+
1268
+ :param filepath: path to the CSV file
1269
+ :param bins: list of bin edges
1270
+ :param operator: 'Mean', 'Median', 'Sum', 'Volume', 'Area
1271
+ :param merge_zones: whether to merge the zones in the plot
1272
+ """
1273
+
1274
+ # Ensure CSV extension
1275
+ filepath = Path(filepath)
1276
+ if filepath.suffix != '.csv':
1277
+ filepath = filepath.with_suffix('.csv')
1278
+
1279
+ result = self._get_distributed_values(bins, operator, merge_zones=merge_zones)
1280
+
1281
+ result.to_csv(filepath, index=False)
1282
+
1283
+ def save_distributed_values_table(self,
1284
+ filepath:Path | str,
1285
+ bins:list[float],
1286
+ operator:Literal['Mean', 'Median', 'Sum', 'Volume', 'Area'],
1287
+ merge_zones:bool = False):
1288
+ """ Create a table of the distribution of values in bins for each array in each zone.
1289
+
1290
+ :param filepath: path to the image file (png)
1291
+ :param bins: list of bin edges
1292
+ :param operator: 'Mean', 'Median', 'Sum', 'Volume', 'Area
1293
+ :param merge_zones: whether to merge the zones in the plot
1294
+ :return: pandas DataFrame with the counts of values in each bin for each array in each zone
1295
+ """
1296
+
1297
+ # Ensure PNG extension
1298
+ filepath = Path(filepath)
1299
+ if filepath.suffix != '.png':
1300
+ filepath = filepath.with_suffix('.png')
1301
+
1302
+ results = self._get_distributed_values(bins, operator, merge_zones=merge_zones)
1303
+
1304
+ # Calculer la borne inférieure en décalant la colonne
1305
+ results["Bin Lower Edge"] = results.groupby("Array")["Rightmost edge"].shift(1).fillna(0)
1306
+
1307
+ # Créer la chaîne de caractère de l'intervalle
1308
+ results[_("Bounds [m]")] = "]" + results["Bin Lower Edge"].map(lambda x: f"{x:.2f}") + "–" + results["Rightmost edge"].map(lambda x: f"{x:.2f}") + "]"
1309
+ # Ensure 'Count' is integer
1310
+ results['Count'] = results['Count'].astype(int)
1311
+
1312
+ table = results.pivot_table(index=_("Bounds [m]"), columns='Array', values='Count', fill_value=0, sort=False)
1313
+ # Force values as integers
1314
+ table = table.astype(int)
1315
+
1316
+ table.reset_index(inplace=True)
1317
+
1318
+
1319
+ # table.columns = pd.MultiIndex.from_tuples([(_('Arrays'),col) for col in table.columns])
1320
+
1321
+ import dataframe_image as dfi
1322
+
1323
+ # Place the column labels (Array) on the same line as the row label (Intervalle)
1324
+ styled_df = table.style.format(precision=1) \
1325
+ .set_caption(_('Count')) \
1326
+ .set_properties(**{
1327
+ 'text-align': 'center',
1328
+ 'font-size': '12px',
1329
+ 'border': '1px solid black',
1330
+ }) \
1331
+ .set_table_styles([
1332
+ {
1333
+ 'selector': 'th.col_heading.level0',
1334
+ 'props': [('vertical-align', 'middle')],
1335
+ },
1336
+ {
1337
+ 'selector': 'thead th.row_heading.level0',
1338
+ 'props': [('vertical-align', 'middle')],
1339
+ },
1340
+ {
1341
+ 'selector': 'thead th',
1342
+ 'props': [('text-align', 'center'), ('background-color', '#d9edf7'), ('color', '#31708f')],
1343
+ },
1344
+ ])
1345
+ styled_df = styled_df.hide(axis="index")
1346
+
1347
+ # Export the styled DataFrame as an image
1348
+
1349
+ # Convert to html table image
1350
+ dfi.export(styled_df, filename=filepath, dpi = 300)
1351
+
1184
1352
  def _plot_distributed_values_plotly(self, bins:list[float],
1185
1353
  operator:Literal['Mean', 'Median', 'Sum', 'Volume', 'Area'],
1186
1354
  show:bool = True,
@@ -1363,6 +1531,32 @@ class Building_Waterdepth_analysis(Arrays_analysis_zones):
1363
1531
  merge_zones = False):
1364
1532
 
1365
1533
  return super()._plot_distributed_areas_seaborn(bins, operator, show=show, merge_zones=merge_zones)
1534
+
1535
+ def save_plot_distributed_areas(self, filepath,
1536
+ bins = [0, 0.3, 1.3, -1],
1537
+ operator = 'Median',
1538
+ merge_zones = False,
1539
+ dpi = 300):
1540
+ """ Save the plot of the distribution of areas in bins for each array in each zone or merged zones.
1541
+ :param filepath: path to the image file (png)
1542
+ :param bins: list of bin edges
1543
+ :param operator: 'Mean', 'Median', 'Sum', 'Volume', 'Area
1544
+ :param merge_zones: whether to merge the zones in the plot
1545
+ :param dpi: resolution of the saved plot
1546
+ :return: None
1547
+ """
1548
+
1549
+ import matplotlib.pyplot as plt
1550
+ # Force Agg backend for saving the plot
1551
+ old_back = plt.get_backend()
1552
+ plt.switch_backend('Agg')
1553
+ fig, ax = self.plot_distributed_areas(bins, operator, show=False, merge_zones=merge_zones, engine='seaborn')
1554
+ fig.savefig(filepath, bbox_inches='tight', dpi=dpi)
1555
+ plt.close(fig)
1556
+ # Restore the previous backend
1557
+ plt.switch_backend(old_back)
1558
+
1559
+
1366
1560
  class Slope_analysis:
1367
1561
  """ Class for slope analysis of in an array based on a trace vector.
1368
1562
 
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 = 43
8
+ self.patch = 44
9
9
 
10
10
  def __str__(self):
11
11
 
wolfhece/dike.py CHANGED
@@ -13,14 +13,207 @@ from mpl_toolkits.mplot3d.art3d import Poly3DCollection
13
13
  import matplotlib.tri as tri
14
14
  import time
15
15
 
16
- from wolfpydike.dikeBreaching import pyDike
16
+ try:
17
+ from wolfpydike.dikeBreaching import pyDike, injector
18
+ except ImportError:
19
+ # Test if wolfpydike is installed and check the version
20
+ try:
21
+ import wolfpydike
22
+ version = wolfpydike.__version__
23
+ if version < '0.1.2':
24
+ raise ImportError("wolfpydike version is too old. Please update to at least version 0.1.2")
25
+ except:
26
+ raise ImportError(_("Error importing pyDike. Make sure the pydike library is installed and accessible (use 'pip install wolfpydike')."))
27
+
28
+ from wolfhece.drawing_obj import Element_To_Draw
29
+ from wolfhece.PyParams import Wolf_Param, Type_Param, Buttons, key_Param, new_json
30
+ from wolfhece.PyDraw import Triangulation
31
+ from wolfhece.wolf_array import WolfArray
32
+ from wolfhece.matplotlib_fig import Matplotlib_Figure
33
+ from wolfhece.PyTranslate import _
34
+
35
+ from wolfgpu.SimulationRunner import SimulationRunner, SimulationInjector, SimulationProxy
36
+ from wolfgpu.simple_simulation import SimulationDuration, SimpleSimulation
37
+ from wolfgpu.results_store import ResultsStore
38
+
39
+ class CoupledSimulation():
40
+ """
41
+ Class for the coupled simulation between WOLF and pydike.
42
+ """
43
+ def __init__(self):
44
+ self.filename = None
45
+ self.injectorWolf = None
46
+ self.interpMatrix = None
47
+ self.sim = SimpleSimulation()
48
+ self.store_dir = None
49
+ # WHEN INTERACTIONS BETWEEN WOLF AND PYDIKE ARE ACTIVATED
50
+ self.updateFrequency = 30 #[s] Update frequency of the topo in WOLF
51
+ self.firstUpdate = 1 #[s] Time of the first update of the topo in WOLF
52
+
53
+ class InjectorWolf(Element_To_Draw):
54
+ """
55
+ Class for the injector object.
56
+ """
57
+ def __init__(self, idx = '', plotted = True, mapviewer=None, need_for_wx = False):
58
+ super().__init__(idx, plotted, mapviewer, need_for_wx)
59
+ self.wp = None
60
+ self._injector = injector()
61
+
62
+ def set_params(self, params):
63
+ """
64
+ Set the injector parameters.
65
+ :param params: Parameters to set for the injector.
66
+ """
67
+ return self._injector.set_params(params)
68
+
69
+ def get_params(self):
70
+ """
71
+ Set the injector parameters.
72
+ :param params: Parameters to set for the injector.
73
+ """
74
+ return self._injector.get_params()
75
+
76
+ def save(self):
77
+ '''
78
+ Save the parameters in a .json text file
79
+ '''
80
+ if self.filename is None:
81
+ self.save_as()
82
+ else:
83
+ with open(self.filename, 'w') as f:
84
+ json.dump(self.get_params(), f, indent=4)
85
+
86
+ def save_as(self):
87
+ '''
88
+ Save the parameters in a .json text file
89
+ '''
90
+ filterArray = "json (*.json)|*.json|all (*.*)|*.*"
91
+ fdlg = wx.FileDialog(None, _("Where should the parameters be stored (.json file)?"), wildcard=filterArray, style=wx.FD_SAVE)
92
+ ret = fdlg.ShowModal()
93
+ if ret == wx.ID_OK:
94
+ self.filename = fdlg.GetPath()
95
+ self.save()
96
+
97
+ fdlg.Destroy()
98
+
99
+ def callback_apply(self):
100
+ """
101
+ Callback function to apply changes made in the Wolf_Param window.
102
+ Update the parameters in the dike object.
103
+ """
104
+ updated_wp = self.wp.merge_dicts()
105
+ self.from_wp_to_dict(wolf_dict=updated_wp, dict_ref=self.get_params())
106
+
107
+ def show_properties(self):
108
+ """
109
+ Show properties window
110
+ """
111
+ if self.wp is None:
112
+ self.wp = self.from_dict_to_wp(params_dict=self.get_params())
113
+ self.wp.set_callbacks(callback_update=self.callback_apply, callback_destroy=None)
114
+ self.wp._set_gui_dike(title=_('Injector parametrization'))
115
+ self.wp.hide_selected_buttons([Buttons.Reload,Buttons.Save])
116
+ self.wp.Show()
117
+
118
+ def hide_properties(self):
119
+ """
120
+ Hide properties window
121
+ """
122
+ if self.wp is not None:
123
+ self.wp.Hide()
124
+
125
+ def from_wp_to_dict(self, wolf_dict, dict_ref) -> dict:
126
+ """
127
+ Convert a Wolf_Param dictionary to a "normal" dictionary used as parameters dictionary in the injector object + updates injector attributes accordingly.
128
+ 'dict_ref' used to rename keys (=mapping).
129
+ :param wolf_dict: Dictionary containing the parameters from the Wolf_Param object.
130
+ :param dict_ref: Dictionary mapping injector parameter names (keys) to explicit names in wolf_param.
131
+ :return: Dictionary with injector parameter names as keys, containing values and metadata.
132
+ """
133
+ params_dict = {}
17
134
 
18
- from .drawing_obj import Element_To_Draw
19
- from .PyParams import Wolf_Param, Type_Param, Buttons, key_Param
20
- from .PyDraw import Triangulation
21
- from .matplotlib_fig import Matplotlib_Figure
22
- from .PyTranslate import _
135
+ for section in wolf_dict.keys():
136
+ params_dict[section] = {}
137
+ for param_data in wolf_dict[section].values():
138
+ explicit_name = param_data[key_Param.NAME] # Extract explicit name
139
+
140
+ # Search for the corresponding injector_key inside dict_ref
141
+ injector_key = None
142
+ for section_name, section_params in dict_ref.items():
143
+ for param_key, param_details in section_params.items():
144
+ if param_details.get("explicit name") == explicit_name:
145
+ injector_key = param_key # Get the correct parameter key
146
+ break
147
+ if injector_key: # Exit the outer loop if found
148
+ break
23
149
 
150
+ if injector_key is None:
151
+ print(_("Warning: No match found in dict_ref for '%s'") % explicit_name)
152
+ continue # Skip if no match is found
153
+
154
+ params_dict[section][injector_key] = {
155
+ "value": param_data[key_Param.VALUE],
156
+ "description": param_data[key_Param.COMMENT],
157
+ "explicit name": explicit_name,
158
+ "type": param_data[key_Param.TYPE],
159
+ "choices": dict_ref[section_name][injector_key].get("choices"),
160
+ "mandatory": dict_ref[section_name][injector_key].get("mandatory"),
161
+ }
162
+
163
+ self._dike.update_paramsDict(params_dict)
164
+
165
+ return
166
+
167
+ def from_dict_to_wp(self,params_dict) -> Wolf_Param:
168
+ """ Modify the Wolf_Param object to represent the injector parameters. """
169
+
170
+ wp = Wolf_Param_dike(parent = None, # Contains all the parameters of the window
171
+ title = _("Breaching of a dike"),
172
+ to_read=False,
173
+ withbuttons=True,
174
+ toShow=False,
175
+ init_GUI=False,
176
+ force_even_if_same_default = True,
177
+ filename="default_name.json",
178
+ DestroyAtClosing=False)
179
+
180
+ for current_section in params_dict.keys():
181
+ for key in params_dict[current_section].keys():
182
+
183
+ value = params_dict[current_section][key]["value"]
184
+ description = params_dict[current_section][key]["description"]
185
+ name = params_dict[current_section][key]["explicit name"]
186
+ # Parameter type
187
+ if params_dict[current_section][key]["type"] == "Float":
188
+ type_param = Type_Param.Float
189
+ elif params_dict[current_section][key]["type"] == "Integer":
190
+ type_param = Type_Param.Integer
191
+ elif params_dict[current_section][key]["type"] == "Logical":
192
+ type_param = Type_Param.Logical
193
+ elif params_dict[current_section][key]["type"] == "String":
194
+ type_param = Type_Param.String
195
+ elif params_dict[current_section][key]["type"] == "Directory":
196
+ type_param = Type_Param.Directory
197
+ elif params_dict[current_section][key]["type"] == "File":
198
+ type_param = Type_Param.File
199
+
200
+ if params_dict[current_section][key]["choices"] != None:
201
+ wp.add_param((current_section), (name), value, type_param, whichdict='Default', jsonstr=new_json(params_dict[current_section][key]["choices"]), comment=_(description))
202
+ if params_dict[current_section][key]["mandatory"]:
203
+ wp.add_param((current_section), (name), value, type_param, whichdict='Active', jsonstr=new_json(params_dict[current_section][key]["choices"]), comment=_(description))
204
+ else:
205
+ wp.add_param((current_section), (name), value, type_param, whichdict='Default', comment=_(description))
206
+ if params_dict[current_section][key]["mandatory"]:
207
+ wp.add_param((current_section), (name), value, type_param, whichdict='Active', comment=_(description))
208
+ return wp
209
+
210
+ # def read_params(self, file_name:str, store_dir: Path = None):
211
+ # '''
212
+ # Read the model parameters and store them in a dictionary + updates attributes accordingly
213
+ # :param file_name: name of the file to read
214
+ # :param store_dir: directory where to read the file
215
+ # '''
216
+ # self._dike.read_params(file_name, store_dir)
24
217
  class DikeWolf(Element_To_Draw):
25
218
 
26
219
  def __init__(self, idx = '', plotted = True, mapviewer=None, need_for_wx = False):
@@ -28,15 +221,64 @@ class DikeWolf(Element_To_Draw):
28
221
 
29
222
  self.filename = None
30
223
  self.wp = None
224
+ self.injector = None
225
+ self.interpMatrix = None
31
226
  self._dike = pyDike()
32
227
 
33
- def run(self, store_dir=None):
228
+ def run_lumped(self, params_dir=None):
34
229
  """
35
- Run the dike breaching simulation.
230
+ Run the dike breaching simulation using the lumped model.
36
231
  :param store_dir: Directory where the simulation will be run.
37
232
  """
38
233
  try:
39
- self._dike.run(store_dir=store_dir)
234
+ self._dike.run_initialization(params_dir=params_dir)
235
+ for time_idx in np.arange(0,self._dike.t_end_idx,1):
236
+ self._dike.run(time_idx)
237
+ logging.info(_("Breaching simulation done."))
238
+ except subprocess.CalledProcessError as e:
239
+ logging.error(_("Error while running the breaching simulation: %s") % e)
240
+
241
+ def set_injector(self):
242
+ """
243
+ Set the injector for the dike object.
244
+ :param injector: Injector object to be set.
245
+ """
246
+ self.injectorWolf = InjectorWolf()
247
+ self.mapviewer.add_object(newobj=self.injectorWolf, which='injector', id=_("Injector_{filename}").format(filename=self.filename))
248
+
249
+ def run_2Dcoupled(self, params_dir=None):
250
+ """
251
+ Run the dike breaching simulation coupled with WOLF.
252
+ :param store_dir: Directory where the simulation will be run.
253
+ """
254
+ if self.injectorWolf is None:
255
+ logging.error(_("Injector is not set. Please set the injector before running the simulation."))
256
+ return
257
+
258
+ # Select WOLF array file
259
+ filterArray = "Wolf array files (*.bin)|*.bin"
260
+ dlg = wx.FileDialog(self.mapviewer, _('Choose the file containing the Wolf array on which interpolation is applied'), wildcard=filterArray, style=wx.FD_FILE_MUST_EXIST)
261
+ ret=dlg.ShowModal()
262
+ if ret == wx.ID_CANCEL:
263
+ dlg.Destroy()
264
+ path_TriangArray = dlg.GetPath()
265
+ self.interpMatrix = WolfArray(fname = path_TriangArray)
266
+
267
+ # Select WOLF simulation data folder
268
+ dlg = wx.DirDialog(self.mapviewer, _('Folder containing WOLF simulation data'), style=wx.DD_DEFAULT_STYLE)
269
+ ret=dlg.ShowModal()
270
+ if ret == wx.ID_CANCEL:
271
+ dlg.Destroy()
272
+ path_sim = dlg.GetPath()
273
+ sim = SimpleSimulation.load(path_sim)
274
+
275
+ # self.mapviewer.add_object(newobj=sim, which='triangulation', id=_("Triangulation_{filename}_{index:03d}").format(filename=self.filename, index=current_idx))
276
+ # logging.info(_("Added triangulation for time index %d to viewer.") % current_idx)
277
+
278
+ try:
279
+ self._dike.run_initialization(params_dir=params_dir)
280
+ for time_idx in np.arange(0,self._dike.t_end_idx,1):
281
+ self._dike.run(time_idx)
40
282
  logging.info(_("Breaching simulation done."))
41
283
  except subprocess.CalledProcessError as e:
42
284
  logging.error(_("Error while running the breaching simulation: %s") % e)
@@ -143,9 +385,13 @@ class DikeWolf(Element_To_Draw):
143
385
  type_param = Type_Param.File
144
386
 
145
387
  if params_dict[current_section][key]["choices"] != None:
146
- wp.add_param((current_section), (name), value, type_param, whichdict='Default', jsonstr={"Values":params_dict[current_section][key]["choices"]}, comment=_(description))
388
+ wp.add_param((current_section), (name), value, type_param,
389
+ whichdict='Default', jsonstr=new_json(params_dict[current_section][key]["choices"]),
390
+ comment=_(description))
147
391
  if params_dict[current_section][key]["mandatory"]:
148
- wp.add_param((current_section), (name), value, type_param, whichdict='Active', jsonstr={"Values":params_dict[current_section][key]["choices"]}, comment=_(description))
392
+ wp.add_param((current_section), (name), value, type_param,
393
+ whichdict='Active', jsonstr=new_json(params_dict[current_section][key]["choices"]),
394
+ comment=_(description))
149
395
  else:
150
396
  wp.add_param((current_section), (name), value, type_param, whichdict='Default', comment=_(description))
151
397
  if params_dict[current_section][key]["mandatory"]:
@@ -156,22 +402,22 @@ class DikeWolf(Element_To_Draw):
156
402
  """
157
403
  Load the main outputs and/or the triangulation of the simulation.
158
404
  """
159
- filterArray = "Parameter files (*_params.json)|*_params.json"
405
+ filterArray = "Parameter files (*_paramsDike.json)|*_paramsDike.json"
160
406
  dlg = wx.FileDialog(self.mapviewer, _('Choose the file containing the simulation parametrization'), wildcard=filterArray, style=wx.FD_FILE_MUST_EXIST)
161
407
  ret=dlg.ShowModal()
162
408
  if ret == wx.ID_CANCEL:
163
409
  dlg.Destroy()
164
410
  self.param_path = dlg.GetPath()
165
- if self.param_path.endswith("_params.json"):
166
- gen_path = self.param_path.removesuffix("_params.json")
411
+ if self.param_path.endswith("_paramsDike.json"):
412
+ gen_path = self.param_path.removesuffix("_paramsDike.json")
167
413
  else:
168
- logging.warning(_("ERROR : the name of the file containing the simulation parametrization should end with '_params.json'"))
414
+ logging.warning(_("ERROR : the name of the file containing the simulation parametrization should end with '_paramsDike.json'"))
169
415
  dlg.Destroy()
170
416
  return
171
417
 
172
418
  self.param_path = Path(self.param_path)
173
- self.filename = (self.param_path.name).removesuffix("_params.json")
174
- self.read_params(file_name=self.filename+"_params", store_dir=self.param_path.parent)
419
+ self.filename = (self.param_path.name).removesuffix("_paramsDike.json")
420
+ self.read_params(file_name=self.filename, store_dir=self.param_path.parent)
175
421
 
176
422
  try:
177
423
  mainOutputs_path = Path(gen_path + '_mainOutputs.txt')
@@ -596,7 +842,7 @@ class Wolf_Param_dike(Wolf_Param):
596
842
  # read the file
597
843
  if self.wx_exists:
598
844
  #ouverture d'une boîte de dialogue
599
- file=wx.FileDialog(self,_("Choose .json file"), wildcard="json (*.json)|*.json|all (*.*)|*.*")
845
+ file=wx.FileDialog(self,_("Choose .json file"), wildcard="Parameter files (*_paramsDike.json)|*_paramsDike.json")
600
846
  if file.ShowModal() == wx.ID_CANCEL:
601
847
  return
602
848
  else:
@@ -658,7 +904,7 @@ class Wolf_Param_dike(Wolf_Param):
658
904
  type_param = Type_Param.File
659
905
 
660
906
  if params_dict[current_section][key]["choices"] != None:
661
- wp.add_param((current_section), (name), value, type_param, whichdict=whichdict, jsonstr={_("Values"):params_dict[current_section][key]["choices"]}, comment=_(description))
907
+ wp.add_param((current_section), (name), value, type_param, whichdict=whichdict, jsonstr=new_json(params_dict[current_section][key]["choices"]), comment=_(description))
662
908
  else:
663
909
  wp.add_param((current_section), (name), value, type_param, whichdict=whichdict, comment=_(description))
664
910
 
wolfhece/eikonal.py CHANGED
@@ -435,6 +435,7 @@ def inpaint_waterlevel(water_level:np.ndarray | np.ma.MaskedArray,
435
435
  :param dy: (float, optional): The mesh size in y direction.
436
436
  :param NoDataValue: (float, optional): The NoDataValue, used if mask is not explicitly provided (mask attribute or water_level as a Numpy MaskedArray). Default is 0.
437
437
  :param multiprocess: (bool, optional): Whether to use multiprocessing.
438
+ :param epsilon: (float, optional): The minimum value to consider that a water height is present.
438
439
  """
439
440
  if inplace:
440
441
  if isinstance(water_level, np.ma.MaskedArray):