wolfhece 2.2.42__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/ChatwWOLF.py +200 -0
- wolfhece/Model1D.py +1785 -11
- wolfhece/PyCrosssections.py +1536 -699
- wolfhece/PyDraw.py +61 -8
- wolfhece/PyVertexvectors.py +64 -22
- wolfhece/RatingCurve_xml.py +15 -1
- wolfhece/analyze_poly.py +198 -4
- wolfhece/apps/version.py +1 -1
- wolfhece/dike.py +265 -19
- wolfhece/eikonal.py +1 -0
- wolfhece/pywalous.py +146 -2
- wolfhece/wolf_array.py +242 -29
- {wolfhece-2.2.42.dist-info → wolfhece-2.2.44.dist-info}/METADATA +2 -2
- {wolfhece-2.2.42.dist-info → wolfhece-2.2.44.dist-info}/RECORD +17 -16
- {wolfhece-2.2.42.dist-info → wolfhece-2.2.44.dist-info}/WHEEL +0 -0
- {wolfhece-2.2.42.dist-info → wolfhece-2.2.44.dist-info}/entry_points.txt +0 -0
- {wolfhece-2.2.42.dist-info → wolfhece-2.2.44.dist-info}/top_level.txt +0 -0
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.
|
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.
|
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
|
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.
|
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
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
|
-
|
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
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
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
|
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.
|
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,
|
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,
|
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 (*
|
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("
|
166
|
-
gen_path = self.param_path.removesuffix("
|
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 '
|
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("
|
174
|
-
self.read_params(file_name=self.filename
|
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="
|
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=
|
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):
|