wolfhece 2.2.37__py3-none-any.whl → 2.2.39__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/Coordinates_operations.py +5 -0
- wolfhece/GraphNotebook.py +72 -1
- wolfhece/GraphProfile.py +1 -1
- wolfhece/MulticriteriAnalysis.py +1579 -0
- wolfhece/PandasGrid.py +62 -1
- wolfhece/PyCrosssections.py +194 -43
- wolfhece/PyDraw.py +891 -73
- wolfhece/PyGui.py +913 -72
- wolfhece/PyGuiHydrology.py +528 -74
- wolfhece/PyPalette.py +26 -4
- wolfhece/PyParams.py +33 -0
- wolfhece/PyPictures.py +2 -2
- wolfhece/PyVertex.py +32 -0
- wolfhece/PyVertexvectors.py +147 -75
- wolfhece/PyWMS.py +52 -36
- wolfhece/acceptability/acceptability.py +15 -8
- wolfhece/acceptability/acceptability_gui.py +507 -360
- wolfhece/acceptability/func.py +80 -183
- wolfhece/apps/version.py +1 -1
- wolfhece/compare_series.py +480 -0
- wolfhece/drawing_obj.py +12 -1
- wolfhece/hydrology/Catchment.py +228 -162
- wolfhece/hydrology/Internal_variables.py +43 -2
- wolfhece/hydrology/Models_characteristics.py +69 -67
- wolfhece/hydrology/Optimisation.py +893 -182
- wolfhece/hydrology/PyWatershed.py +267 -165
- wolfhece/hydrology/SubBasin.py +185 -140
- wolfhece/hydrology/climate_data.py +334 -0
- wolfhece/hydrology/constant.py +11 -0
- wolfhece/hydrology/cst_exchanges.py +76 -1
- wolfhece/hydrology/forcedexchanges.py +413 -49
- wolfhece/hydrology/hyetograms.py +2095 -0
- wolfhece/hydrology/read.py +65 -5
- wolfhece/hydrometry/kiwis.py +42 -26
- wolfhece/hydrometry/kiwis_gui.py +7 -2
- wolfhece/insyde_be/INBE_func.py +746 -0
- wolfhece/insyde_be/INBE_gui.py +1776 -0
- wolfhece/insyde_be/__init__.py +3 -0
- wolfhece/interpolating_raster.py +366 -0
- wolfhece/irm_alaro.py +1457 -0
- wolfhece/irm_qdf.py +889 -57
- wolfhece/lifewatch.py +6 -3
- wolfhece/picc.py +124 -8
- wolfhece/pyLandUseFlanders.py +146 -0
- wolfhece/pydownloader.py +2 -1
- wolfhece/pywalous.py +225 -31
- wolfhece/toolshydrology_dll.py +149 -0
- wolfhece/wolf_array.py +63 -25
- {wolfhece-2.2.37.dist-info → wolfhece-2.2.39.dist-info}/METADATA +3 -1
- {wolfhece-2.2.37.dist-info → wolfhece-2.2.39.dist-info}/RECORD +53 -42
- {wolfhece-2.2.37.dist-info → wolfhece-2.2.39.dist-info}/WHEEL +0 -0
- {wolfhece-2.2.37.dist-info → wolfhece-2.2.39.dist-info}/entry_points.txt +0 -0
- {wolfhece-2.2.37.dist-info → wolfhece-2.2.39.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,1776 @@
|
|
1
|
+
"""
|
2
|
+
Author: University of Liege, HECE, Damien Sansen
|
3
|
+
Date: 2025
|
4
|
+
|
5
|
+
Copyright (c) 2025 University of Liege. All rights reserved.
|
6
|
+
|
7
|
+
This script and its content are protected by copyright law. Unauthorized
|
8
|
+
copying or distribution of this file, via any medium, is strictly prohibited.
|
9
|
+
"""
|
10
|
+
|
11
|
+
import wx
|
12
|
+
import numpy as np
|
13
|
+
import logging
|
14
|
+
import shutil
|
15
|
+
import os
|
16
|
+
import sys
|
17
|
+
import glob
|
18
|
+
from osgeo import gdal, osr
|
19
|
+
import geopandas as gpd
|
20
|
+
import pandas as pd
|
21
|
+
import matplotlib.pyplot as plt
|
22
|
+
from matplotlib.figure import Figure
|
23
|
+
from pathlib import Path
|
24
|
+
from scipy.ndimage import label
|
25
|
+
from gettext import gettext as _
|
26
|
+
from shapely.geometry import Polygon
|
27
|
+
from scipy.ndimage import binary_dilation
|
28
|
+
from itertools import permutations
|
29
|
+
|
30
|
+
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
|
31
|
+
from wolfhece.wolf_array import WolfArray, header_wolf
|
32
|
+
from wolfhece.scenario.config_manager import Config_Manager_2D_GPU
|
33
|
+
from wolfhece.PyDraw import WolfMapViewer, draw_type
|
34
|
+
from wolfhece.Results2DGPU import wolfres2DGPU
|
35
|
+
from wolfhece.PyGui import MapManager
|
36
|
+
from wolfhece.interpolating_raster import interpolating_raster
|
37
|
+
from wolfhece.insyde_be.INBE_func import INBE_functions
|
38
|
+
from wolfhece.PyTranslate import _
|
39
|
+
|
40
|
+
BATHYMETRY_FOR_SIMULATION = "__bathymetry_after_scripts.tif"
|
41
|
+
|
42
|
+
#Other repository : hece_damage-------------------------------------------------------------
|
43
|
+
_root_dir = os.path.dirname(os.path.abspath(__file__))
|
44
|
+
hece_damage_path = os.path.abspath(os.path.join(_root_dir, "..", "..", "..", "hece_damage"))
|
45
|
+
sys.path.insert(0, hece_damage_path)
|
46
|
+
try:
|
47
|
+
from insyde_be.Py_INBE import PyINBE, INBE_Manager
|
48
|
+
except Exception as e:
|
49
|
+
logging.error(_(f"Problem to import insyde_be.Py_INBE: {e}"))
|
50
|
+
try:
|
51
|
+
from insyde_be.Py_INBE import PyINBE, INBE_Manager
|
52
|
+
except Exception as e:
|
53
|
+
logging.error(_(f"Problem to import insyde_be.Py_INBE: {e}"))
|
54
|
+
sys.path.pop(0) # ou sys.path = original_sys_path si tu préfères
|
55
|
+
|
56
|
+
def riverbed_trace_dilated(fn_read_simu, fn_output, threshold, type_extraction, id_begin=None, id_end=None, id_step=None):
|
57
|
+
"""
|
58
|
+
Recognizes the riverbed trace based on a simulation, where water depth above a given threshold is considered part of the riverbed.
|
59
|
+
Inputs:
|
60
|
+
- fn_read_simu: the simulation file to read.
|
61
|
+
- fn_output: the location to save the riverbed trace as a .tiff file.
|
62
|
+
- threshold: the water depth threshold above which the areas are considered riverbed.
|
63
|
+
"""
|
64
|
+
|
65
|
+
if type_extraction == "last_step":
|
66
|
+
wolfres2DGPU_test = wolfres2DGPU(fn_read_simu)
|
67
|
+
wolfres2DGPU_test.read_oneresult(-1)
|
68
|
+
wd = wolfres2DGPU_test.get_h_for_block(1)
|
69
|
+
wd.array[wd.array > 1000] = 0
|
70
|
+
wd.array[wd.array > threshold] = 1
|
71
|
+
wd.array[wd.array < threshold] = 0
|
72
|
+
wd.as_WolfArray()
|
73
|
+
wd.nodata=0
|
74
|
+
wd.write_all(Path(fn_output))
|
75
|
+
|
76
|
+
if type_extraction=="danger_map":
|
77
|
+
wd = wolfres2DGPU(fn_read_simu) .danger_map_only_h(id_begin,id_end,id_step)
|
78
|
+
wd.array[wd.array > 1000] = 0
|
79
|
+
wd.array[wd.array > threshold] = 1
|
80
|
+
wd.array[wd.array < threshold] = 0
|
81
|
+
wd.as_WolfArray()
|
82
|
+
wd.nodata=0
|
83
|
+
wd.write_all(Path(fn_output))
|
84
|
+
|
85
|
+
def dilatation_mask_river(manager_inbe):
|
86
|
+
mask_river = Path(manager_inbe.IN_RIVER_MASK_SCEN) / "Masked_River_extent.tiff"
|
87
|
+
WA_mask_river = WolfArray(mask_river)
|
88
|
+
array = binary_dilation(WA_mask_river.array)
|
89
|
+
WA_mask_river.array[:,:] = array[:,:]
|
90
|
+
out = Path(manager_inbe.IN_RIVER_MASK_SCEN_tif)
|
91
|
+
WA_mask_river.as_WolfArray()
|
92
|
+
WA_mask_river.write_all(out)
|
93
|
+
return print(f"Dilated mask river written in {Path(manager_inbe.IN_RIVER_MASK_SCEN_tif)}")
|
94
|
+
|
95
|
+
def empty_folder(folder):
|
96
|
+
"""
|
97
|
+
Empties the content of a directory if it exists.
|
98
|
+
"""
|
99
|
+
if os.path.exists(folder):
|
100
|
+
for files in os.listdir(folder):
|
101
|
+
fn = os.path.join(folder, files)
|
102
|
+
try:
|
103
|
+
if os.path.isfile(fn) or os.path.islink(fn):
|
104
|
+
os.unlink(fn)
|
105
|
+
elif os.path.isdir(fn):
|
106
|
+
shutil.rmtree(fn)
|
107
|
+
except Exception as e:
|
108
|
+
print(f"Error when deleting file {fn}: {e}")
|
109
|
+
else:
|
110
|
+
print("The folder does not exist.")
|
111
|
+
|
112
|
+
def get_transform_and_crs(tif_file):
|
113
|
+
"""
|
114
|
+
For TIFF file manipulation, reads the CRS and the geotransform, and returns them.
|
115
|
+
"""
|
116
|
+
ds = gdal.Open(tif_file)
|
117
|
+
transform = ds.GetGeoTransform()
|
118
|
+
crs_wkt = ds.GetProjection()
|
119
|
+
crs = osr.SpatialReference()
|
120
|
+
crs.ImportFromWkt(crs_wkt)
|
121
|
+
return transform, crs
|
122
|
+
|
123
|
+
def create_shapefile_from_prop_tif(fn_tif, shapefile_path):
|
124
|
+
unused, unused, width, height, unused, unused = get_header_info(fn_tif)
|
125
|
+
ds = gdal.Open(fn_tif)
|
126
|
+
width = ds.RasterXSize
|
127
|
+
height = ds.RasterYSize
|
128
|
+
gt = ds.GetGeoTransform()
|
129
|
+
|
130
|
+
originX, pixelWidth, unused, originY, unused, pixelHeight = gt
|
131
|
+
|
132
|
+
top_left = (originX, originY)
|
133
|
+
top_right = (originX + width * pixelWidth, originY)
|
134
|
+
bottom_left = (originX, originY + height * pixelHeight)
|
135
|
+
bottom_right = (originX + width * pixelWidth, originY + height * pixelHeight)
|
136
|
+
|
137
|
+
rectangle = Polygon([top_left, top_right, bottom_right, bottom_left, top_left])
|
138
|
+
|
139
|
+
sr = osr.SpatialReference()
|
140
|
+
sr.ImportFromWkt(ds.GetProjection())
|
141
|
+
crs_wkt = sr.ExportToWkt()
|
142
|
+
|
143
|
+
gdf = gpd.GeoDataFrame({'geometry': [rectangle]}, crs=crs_wkt)
|
144
|
+
gdf.to_file(shapefile_path)
|
145
|
+
ds = None
|
146
|
+
|
147
|
+
def get_header_info(fn):
|
148
|
+
"""
|
149
|
+
Reads the headers from the file at path 'fn'.
|
150
|
+
"""
|
151
|
+
class_header = header_wolf()
|
152
|
+
class_header.read_txt_header(fn)
|
153
|
+
dx,dy = class_header.dx, class_header.dy
|
154
|
+
nbx,nby = class_header.nbx, class_header.nby
|
155
|
+
X,Y = class_header.origx, class_header.origy
|
156
|
+
return dx,dy,nbx,nby,X,Y
|
157
|
+
|
158
|
+
def get_header_comparison(list_fn):
|
159
|
+
"""
|
160
|
+
Reads the headers from the files in list_fn and compares them. The result 'comp' is True if the headers are identical, and False otherwise.
|
161
|
+
"""
|
162
|
+
|
163
|
+
header_infos = [get_header_info(fn) for fn in list_fn]
|
164
|
+
variable_names = ["dx", "dy", "nbx", "nby", "X", "Y"]
|
165
|
+
for idx, name in enumerate(variable_names):
|
166
|
+
values = [header[idx] for header in header_infos]
|
167
|
+
if len(set(values)) > 1:
|
168
|
+
comp = False
|
169
|
+
else:
|
170
|
+
comp = True
|
171
|
+
return comp
|
172
|
+
|
173
|
+
|
174
|
+
def display_info_header(self_dx, self_nbxy, self_O, fn):
|
175
|
+
"""
|
176
|
+
Displays the header at the path 'fn', and update the values displayed in the window.
|
177
|
+
"""
|
178
|
+
dx,dy,nbx,nby,X,Y= get_header_info(fn)
|
179
|
+
self_dx.SetLabel(f"({dx},{dy})")
|
180
|
+
self_nbxy.SetLabel(f"({nbx},{nby})")
|
181
|
+
self_O.SetLabel(f"({X},{Y})")
|
182
|
+
return dx,dy,nbx,nby,X,Y
|
183
|
+
|
184
|
+
def vanish_info_header(self_dx, self_nbxy, self_O):
|
185
|
+
self_dx.SetLabel("")
|
186
|
+
self_nbxy.SetLabel("")
|
187
|
+
self_O.SetLabel("")
|
188
|
+
|
189
|
+
def update_info_header(self_dx, self_nbxy, self_O, fn):
|
190
|
+
"""
|
191
|
+
Upate the displayed header values by reading the simulations headers if exist.
|
192
|
+
"""
|
193
|
+
if not os.path.exists(fn):
|
194
|
+
os.makedirs(fn)
|
195
|
+
|
196
|
+
tif_files = [f for f in os.listdir(fn) if f.lower().endswith('.tif')]
|
197
|
+
tif_list_fn = [os.path.join(fn, tif_file) for tif_file in tif_files]
|
198
|
+
if tif_files:
|
199
|
+
if get_header_comparison(tif_list_fn) :
|
200
|
+
dx,dy,nbx,nby,X,Y = display_info_header(self_dx, self_nbxy, self_O, tif_list_fn[0])
|
201
|
+
return dx,dy,nbx,nby,X,Y
|
202
|
+
else:
|
203
|
+
logging.error(_("The interpolated files have different headers. Please fix it."))
|
204
|
+
return False, False, False, False, False, False
|
205
|
+
else :
|
206
|
+
vanish_info_header(self_dx, self_nbxy, self_O)
|
207
|
+
return False, False, False, False, False, False
|
208
|
+
|
209
|
+
def search_for_modif_bath_and_copy(main_gpu, from_path, path_vuln):
|
210
|
+
"""
|
211
|
+
When loading gpu simulations for last step extraction, search for modified bath_ topography file, according to
|
212
|
+
the structure coded in the scenarios manager. If they exist, their extent is copied to CHANGE_VULNE, called vuln_ and
|
213
|
+
MNTmodifs_, to enable the user to modify it later. In addition, returns True if such files exist and False if they do not.
|
214
|
+
"""
|
215
|
+
found_bath = False
|
216
|
+
scen_manager = Config_Manager_2D_GPU(main_gpu, create_ui_if_wx=False)
|
217
|
+
curtree = scen_manager.get_tree(from_path)
|
218
|
+
curdicts = scen_manager.get_dicts(curtree)
|
219
|
+
all_tif_bath = [scen_manager._select_tif_partname(curdict, 'bath_') for curdict in curdicts]
|
220
|
+
all_tif_bath = [curel for curlist in all_tif_bath if len(curlist)>0 for curel in curlist if curel.name.startswith('bath_')]
|
221
|
+
if len(all_tif_bath) :
|
222
|
+
found_bath = True
|
223
|
+
for tif_file in all_tif_bath:
|
224
|
+
found_bath = True
|
225
|
+
src_ds = gdal.Open(str(tif_file))
|
226
|
+
driver = gdal.GetDriverByName("GTiff")
|
227
|
+
|
228
|
+
xsize = src_ds.RasterXSize
|
229
|
+
ysize = src_ds.RasterYSize
|
230
|
+
geotransform = src_ds.GetGeoTransform()
|
231
|
+
projection = src_ds.GetProjection()
|
232
|
+
|
233
|
+
# MNTmodifs_ file
|
234
|
+
output_file = path_vuln / tif_file.name.replace("bath_", "MNTmodifs_")
|
235
|
+
dst_ds = driver.Create(str(output_file), xsize, ysize, 1, gdal.GDT_Float32)
|
236
|
+
dst_ds.SetGeoTransform(geotransform)
|
237
|
+
dst_ds.SetProjection(projection)
|
238
|
+
data = np.ones((ysize, xsize), dtype=np.float32)
|
239
|
+
dst_ds.GetRasterBand(1).WriteArray(data)
|
240
|
+
dst_ds.GetRasterBand(1).SetNoDataValue(0)
|
241
|
+
dst_ds = None
|
242
|
+
|
243
|
+
src_ds = None
|
244
|
+
|
245
|
+
return found_bath
|
246
|
+
|
247
|
+
def create_INPUT_OUTPUT_forScenario(maindir, study_area, scenario, simu_gpu=None, danger=None):
|
248
|
+
"""Creates folder for a new study area or/and scenario. The last argument simu_gpu is used when loading simulation (indicates path to the simulation folder),
|
249
|
+
if not used, indicate None to ignore it."""
|
250
|
+
study_area = Path(study_area).stem
|
251
|
+
base_pathwd = Path(maindir) / "INPUT" / "WATER_DEPTH" / study_area / scenario
|
252
|
+
subfolders = ["DEM_FILES", "INTERP_WD", "EXTRACTED_LAST_STEP_WD"]
|
253
|
+
os.makedirs(base_pathwd, exist_ok=True)
|
254
|
+
for folder in subfolders:
|
255
|
+
os.makedirs(os.path.join(base_pathwd, folder), exist_ok=True)
|
256
|
+
|
257
|
+
base_change = Path(maindir) / "INPUT" / "CHANGE_DEM" / study_area / scenario
|
258
|
+
os.makedirs(base_change, exist_ok=True)
|
259
|
+
|
260
|
+
base_CSV = Path(maindir) / "INPUT" / "CSVs" / study_area / scenario
|
261
|
+
os.makedirs(base_CSV, exist_ok=True)
|
262
|
+
|
263
|
+
base_river = Path(maindir) / "INPUT" / "RIVER_MASK" / study_area / scenario
|
264
|
+
os.makedirs(base_river, exist_ok=True)
|
265
|
+
|
266
|
+
base_velocity = Path(maindir) / "INPUT" / "VELOCITY" / study_area / scenario
|
267
|
+
os.makedirs(base_velocity, exist_ok=True)
|
268
|
+
|
269
|
+
if simu_gpu != None:
|
270
|
+
path_bat_gpu = Path(simu_gpu) / "bathymetry.tif"
|
271
|
+
if path_bat_gpu.exists():
|
272
|
+
create_shapefile_from_prop_tif(path_bat_gpu, Path(maindir) / "INPUT" / "STUDY_AREA" / f"{study_area}.shp")
|
273
|
+
logging.info(_("Study area file created in INPUT/STUDY_AREA."))
|
274
|
+
else :
|
275
|
+
logging.error(_(f"Error in the study area creation : no bathymetry.tif file in the given simulation folder {simu_gpu}. Please provide it in this folder and try again."))
|
276
|
+
if danger != None:
|
277
|
+
if danger.exists():
|
278
|
+
create_shapefile_from_prop_tif(danger, Path(maindir) / "INPUT" / "STUDY_AREA" / f"{study_area}.shp")
|
279
|
+
logging.info(("Study area file created in INPUT/STUDY_AREA."))
|
280
|
+
else :
|
281
|
+
logging.error(_(f"Error in the study area creation : no bathymetry.tif file in the given simulation folder {simu_gpu}. Please provide it in this folder and try again."))
|
282
|
+
|
283
|
+
|
284
|
+
|
285
|
+
INBE_Manager(main_dir=maindir, Study_area=Path(study_area).stem, scenario=scenario)
|
286
|
+
logging.info((f"Files created in INPUT and OUTPUT for the study area named '{study_area}', and the scenario named '{scenario}'"))
|
287
|
+
return
|
288
|
+
|
289
|
+
|
290
|
+
class INBEGui(wx.Frame):
|
291
|
+
""" The main frame for the damage computation with INSYDE-BE (=INBE) """
|
292
|
+
|
293
|
+
def __init__(self, parent=None, width=1024, height=500):
|
294
|
+
|
295
|
+
super(wx.Frame, self).__init__(parent, title='Damage modelling - INBE manager', size=(width, height))
|
296
|
+
|
297
|
+
self._manager = None
|
298
|
+
self._mapviewer = None
|
299
|
+
self.InitUI()
|
300
|
+
self._func = INBE_functions()
|
301
|
+
|
302
|
+
self.df_results_Ti = None
|
303
|
+
|
304
|
+
@property
|
305
|
+
def mapviewer(self):
|
306
|
+
return self._mapviewer
|
307
|
+
|
308
|
+
@mapviewer.setter
|
309
|
+
def mapviewer(self, value):
|
310
|
+
from ..PyDraw import WolfMapViewer
|
311
|
+
|
312
|
+
if not isinstance(value, WolfMapViewer):
|
313
|
+
raise TypeError("The mapviewer must be a WolfMapViewer")
|
314
|
+
|
315
|
+
self._mapviewer = value
|
316
|
+
|
317
|
+
def layout(self, self_fct):
|
318
|
+
"""Update the layers for the main buttons"""
|
319
|
+
font = self_fct.GetFont()
|
320
|
+
font.SetWeight(wx.FONTWEIGHT_BOLD)
|
321
|
+
self_fct.SetFont(font)
|
322
|
+
self_fct.SetBackgroundColour(wx.Colour(222, 209, 209))
|
323
|
+
#self_fct.Bind(wx.EVT_ENTER_WINDOW, self.OnHoverEnter)
|
324
|
+
#self_fct.Bind(wx.EVT_LEAVE_WINDOW, self.OnHoverLeave)
|
325
|
+
|
326
|
+
def on_button_click(self, event):
|
327
|
+
self.PopupMenu(self.menu)
|
328
|
+
|
329
|
+
def on_button_click2(self, event2):
|
330
|
+
self.PopupMenu(self.menu2)
|
331
|
+
|
332
|
+
def onRiverbed(self, event):
|
333
|
+
"""Two options for the 'Update Riverbed' button: either the new riverbed trace
|
334
|
+
file already exists and the user selects it, or it does not exist, and the user points to
|
335
|
+
a no-overflow simulation, allowing the code to create the trace."""
|
336
|
+
menu_id = event.GetId()
|
337
|
+
if menu_id == 1:
|
338
|
+
logging.info(_("Option 1 : the file exists, pointing towards it."))
|
339
|
+
dlg = wx.FileDialog(None, "Please select the .tiff file with the NEW trace of the riverbed.",
|
340
|
+
style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST,
|
341
|
+
wildcard="TIFF files (*.tiff)|*.tiff")
|
342
|
+
|
343
|
+
if dlg.ShowModal() == wx.ID_OK:
|
344
|
+
selected_file = Path(dlg.GetPath())
|
345
|
+
copied_file = self._manager.OUT_SCEN_DIR / "copy_file"
|
346
|
+
shutil.copy(selected_file, copied_file)
|
347
|
+
logging.info(_(f"File copied to: {copied_file}"))
|
348
|
+
|
349
|
+
new_name = Path(self._manager.IN_RIVER_MASK_SCEN) / "Masked_River_extent.tiff"
|
350
|
+
|
351
|
+
with wx.MessageDialog(self, f"Modified riverbed imported and called Masked_River_extent_scenarios.tiff.",
|
352
|
+
"File imported.", wx.OK | wx.ICON_INFORMATION) as dlg:
|
353
|
+
dlg.ShowModal()
|
354
|
+
|
355
|
+
if new_name.exists():
|
356
|
+
new_name.unlink()
|
357
|
+
|
358
|
+
copied_file.rename(new_name)
|
359
|
+
dilatation_mask_river(self._manager)
|
360
|
+
logging.info(_(f"File renamed and dilated to: {new_name}"))
|
361
|
+
else:
|
362
|
+
logging.info(_('No file selected. Please try again.'))
|
363
|
+
|
364
|
+
elif menu_id == 2: #No file, so need to create
|
365
|
+
logging.info(_("Option 2 : pointing to simulation with low discharge (no overflows!)."))
|
366
|
+
|
367
|
+
with wx.DirDialog(self, "Please select a simul_gpu_results folder of a simulation with low discharges (no overflows).", style=wx.DD_DEFAULT_STYLE) as dir_dlg:
|
368
|
+
if dir_dlg.ShowModal() == wx.ID_OK:
|
369
|
+
selected_folder = Path(dir_dlg.GetPath())
|
370
|
+
if os.path.basename(selected_folder) == "simul_gpu_results" :
|
371
|
+
logging.info(_(f"Selected folder: {selected_folder}"))
|
372
|
+
fn_output = Path(self._manager.IN_RIVER_MASK_SCEN) / "Masked_River_extent.tiff"
|
373
|
+
dlg = wx.TextEntryDialog(self, "What water depth threshold (in meters) should be used to define the riverbed trace, above which\n"
|
374
|
+
"the water depth is considered part of the riverbed? Use a dot as a decimal separator (e.g 0.3).", "Type a water depth threshold in [m] (e.g 0.3)", "")
|
375
|
+
|
376
|
+
if dlg.ShowModal() == wx.ID_OK:
|
377
|
+
while True:
|
378
|
+
try:
|
379
|
+
valeur = dlg.GetValue()
|
380
|
+
threshold = float(valeur)
|
381
|
+
if threshold < 1e-5 or threshold > 150:
|
382
|
+
wx.MessageBox(
|
383
|
+
"Error: The value must be positive > 0 and reasonable. Please, try again.",
|
384
|
+
"Error", wx.OK | wx.ICON_ERROR
|
385
|
+
)
|
386
|
+
break
|
387
|
+
|
388
|
+
dialog = wx.SingleChoiceDialog(
|
389
|
+
parent=None,
|
390
|
+
message=f"Threshold accepted. Considering riverbed where water depth > {threshold}[m] via",
|
391
|
+
caption="Choix",
|
392
|
+
choices=["last step", "danger map"]
|
393
|
+
)
|
394
|
+
|
395
|
+
if dialog.ShowModal() == wx.ID_OK:
|
396
|
+
choix = dialog.GetStringSelection()
|
397
|
+
if choix == "last step":
|
398
|
+
type_extraction = "last step"
|
399
|
+
id_begin, id_end, id_step =None, None, None
|
400
|
+
else:
|
401
|
+
type_extraction = "danger_map"
|
402
|
+
|
403
|
+
dlg_start = wx.TextEntryDialog(None, "From which time step? (integer)", "Start step")
|
404
|
+
if dlg_start.ShowModal() == wx.ID_OK:
|
405
|
+
id_begin = int(dlg_start.GetValue())
|
406
|
+
dlg_start.Destroy()
|
407
|
+
|
408
|
+
dlg_end = wx.TextEntryDialog(None, "Until which time step? (integer, enter -1 for last)", "End step")
|
409
|
+
if dlg_end.ShowModal() == wx.ID_OK:
|
410
|
+
id_end = int(dlg_end.GetValue())
|
411
|
+
dlg_end.Destroy()
|
412
|
+
|
413
|
+
dlg_step = wx.TextEntryDialog(None, "Extract every how many steps? (integer)", "Step interval")
|
414
|
+
if dlg_step.ShowModal() == wx.ID_OK:
|
415
|
+
id_step = int(dlg_step.GetValue())
|
416
|
+
dlg_step.Destroy()
|
417
|
+
|
418
|
+
dialog.Destroy()
|
419
|
+
logging.info(_("Detecting riverbed."))
|
420
|
+
riverbed_trace_dilated(selected_folder, fn_output, threshold, type_extraction, id_begin, id_end, id_step)
|
421
|
+
dilatation_mask_river(self._manager)
|
422
|
+
logging.info(_("File created."))
|
423
|
+
with wx.MessageDialog(
|
424
|
+
self,
|
425
|
+
"Masked_River_extent_scenarios.tiff successfully created and dilated.",
|
426
|
+
"File created.", wx.OK | wx.ICON_INFORMATION
|
427
|
+
) as dlg_success:
|
428
|
+
dlg_success.ShowModal()
|
429
|
+
break
|
430
|
+
except ValueError:
|
431
|
+
wx.MessageBox(
|
432
|
+
"Error: Invalid entry. Please enter a valid number (positive > 0, reasonable, using with DOT as a decimal separator).",
|
433
|
+
"Error", wx.OK | wx.ICON_ERROR
|
434
|
+
)
|
435
|
+
break
|
436
|
+
|
437
|
+
else:
|
438
|
+
logging.info(_("Cancelled."))
|
439
|
+
dlg.Destroy()
|
440
|
+
else:
|
441
|
+
logging.info(_("No folder (or wrong one) selected. Please try again (must be simul_gpu_results)."))
|
442
|
+
|
443
|
+
|
444
|
+
def layout_listbox(self, self_fct):
|
445
|
+
"""Changes the layout for the listbox : light grey."""
|
446
|
+
self_fct.SetBackgroundColour(wx.Colour(220, 220, 220))
|
447
|
+
|
448
|
+
def InitUI(self):
|
449
|
+
self.gpu_bathy = None
|
450
|
+
self.maindir = None
|
451
|
+
|
452
|
+
sizer_hor_main = wx.BoxSizer(wx.HORIZONTAL)
|
453
|
+
sizer_vert1 = wx.BoxSizer(wx.VERTICAL)
|
454
|
+
sizer_hor_threads = wx.BoxSizer(wx.HORIZONTAL)
|
455
|
+
sizer_hor1 = wx.BoxSizer(wx.HORIZONTAL)
|
456
|
+
sizer_hor2 = wx.BoxSizer(wx.HORIZONTAL)
|
457
|
+
sizer_hor3 = wx.BoxSizer(wx.HORIZONTAL)
|
458
|
+
sizer_hor4 = wx.BoxSizer(wx.HORIZONTAL)
|
459
|
+
sizer_hor5 = wx.BoxSizer(wx.HORIZONTAL)
|
460
|
+
sizer_hor_scen = wx.BoxSizer(wx.HORIZONTAL)
|
461
|
+
|
462
|
+
# 1st LINE - Loading INBE folder
|
463
|
+
panel = wx.Panel(self)
|
464
|
+
self._but_maindir = wx.Button(panel, label=_('Main Directory'))
|
465
|
+
self._but_maindir.SetFont(wx.Font(9, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD))
|
466
|
+
self._but_maindir.Bind(wx.EVT_BUTTON, self.OnMainDir)
|
467
|
+
|
468
|
+
self._listbox_studyarea = wx.ListBox(panel, choices=[], style=wx.LB_SINGLE)
|
469
|
+
self.layout_listbox(self._listbox_studyarea)
|
470
|
+
self._listbox_studyarea.Bind(wx.EVT_LISTBOX, self.OnStudyArea)
|
471
|
+
self._listbox_studyarea.SetToolTip(_("Choose the study area existed in the folder."))
|
472
|
+
|
473
|
+
self._listbox_scenario = wx.ListBox(panel, choices=[], style=wx.LB_SINGLE)
|
474
|
+
self.layout_listbox(self._listbox_scenario)
|
475
|
+
self._listbox_scenario.Bind(wx.EVT_LISTBOX, self.OnScenario)
|
476
|
+
self._listbox_scenario.SetToolTip(_("Choose the INBE scenario."))
|
477
|
+
|
478
|
+
sizer_ver_small = wx.BoxSizer(wx.VERTICAL)
|
479
|
+
self._but_checkfiles = wx.Button(panel, label=_('Check structure'))
|
480
|
+
self._but_checkfiles.Bind(wx.EVT_BUTTON, self.OnCheckFiles)
|
481
|
+
self._but_checkfiles.SetToolTip(_("Checks if the folder is correctly structured\n with INPUT and OUTPUT."))
|
482
|
+
self._but_checksim = wx.Button(panel, label=_('Check simulations'))
|
483
|
+
self._but_checksim.SetToolTip(_("Displays the loaded simulations, interpolated in INTERP_WD."))
|
484
|
+
self._but_checksim.Bind(wx.EVT_BUTTON, self.OnHydrodynInput)
|
485
|
+
self._but_checkpicc = wx.Button(panel, label=_('Check PICC'))
|
486
|
+
self._but_checkpicc.Bind(wx.EVT_BUTTON, self.OnCheckPICC)
|
487
|
+
self._but_checkpicc.SetToolTip(_("Checks if PICC exists and how much residential building ('Habitations') are read. The process may be slow. Please, be patient."))
|
488
|
+
self._but_checkpond= wx.Button(panel, label=_('Check ponderation'))
|
489
|
+
self._but_checkpond.Bind(wx.EVT_BUTTON, self.OnCheckPond)
|
490
|
+
self._but_checkpond.SetToolTip(_("Displays a graph of the computed weighting coefficient\n of the final INBE computations."))
|
491
|
+
|
492
|
+
# 2nd LINE - Hydrodynamic part
|
493
|
+
self._but_loadgpu = wx.ToggleButton(panel, label=_('Working with new\n hydraulic scenarios'))
|
494
|
+
self._but_loadgpu.SetToolTip(_("To load or change the hydraulic simulations"))
|
495
|
+
self._but_loadgpu.SetFont(wx.Font(9, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD))
|
496
|
+
self._but_loadgpu.Bind(wx.EVT_TOGGLEBUTTON, self.OnLoadingSimu)
|
497
|
+
sizer_hor2.Add(self._but_loadgpu, 1, wx.ALL | wx.EXPAND, 0)
|
498
|
+
|
499
|
+
self._check_listbox = wx.CheckListBox(panel, choices=[], style=wx.LB_MULTIPLE | wx.CHK_CHECKED)
|
500
|
+
self.layout_listbox(self._check_listbox)
|
501
|
+
self.sims = {}
|
502
|
+
sizer_hor2.Add(self._check_listbox, 1, wx.ALL | wx.EXPAND, 0)
|
503
|
+
|
504
|
+
self._but_danger = wx.Button(panel, label=_('Extract last step or\n compute danger maps ▼'))
|
505
|
+
self._but_danger.SetToolTip(_("To create the danger maps of velocities and water depth. Please be patient."))
|
506
|
+
self._but_danger.Bind(wx.EVT_BUTTON, self.on_button_click2)
|
507
|
+
self.menu2 = wx.Menu()
|
508
|
+
self.menu2.Append(1, _("Extract the last step of the simulation."))
|
509
|
+
self.menu2.Append(2, _("Compute the danger maps of the simulation."))
|
510
|
+
self.menu2.Bind(wx.EVT_MENU, self.OnDanger)
|
511
|
+
sizer_hor2.Add(self._but_danger, 1, wx.ALL | wx.EXPAND, 0)
|
512
|
+
|
513
|
+
sizer_ver_small2 = wx.BoxSizer(wx.VERTICAL)
|
514
|
+
self._but_DEM = wx.Button(panel, label=_("Check DEM, DTM for interpolation"))
|
515
|
+
self._but_DEM.SetToolTip(_("To display the existing DEM input for the interpolation of the simulated free surfaces."))
|
516
|
+
self._but_DEM.Bind(wx.EVT_BUTTON, self.OnDEM)
|
517
|
+
|
518
|
+
self._but_MNTmodifs = wx.Button(panel, label=_("Check 'MNTmodifs_' scenarios"))
|
519
|
+
self._but_MNTmodifs.SetToolTip(_("To display the existing MNTmodifs_ scenario files for the DTM input of interpolation of the simulated free surfaces."))
|
520
|
+
self._but_MNTmodifs.Bind(wx.EVT_BUTTON, self.OnCheckMNTmodifs)
|
521
|
+
|
522
|
+
sizer_hor2.Add(sizer_ver_small2, 0, wx.ALL | wx.EXPAND, 5)
|
523
|
+
|
524
|
+
self._but_extrinterp = wx.Button(panel, label=_('Read and interpolate'))
|
525
|
+
self._but_extrinterp.SetToolTip(_("Reads and interpolates the danger maps computed (if not done, use previous buttons) of wolf gpu simulations."))
|
526
|
+
self._but_extrinterp.Bind(wx.EVT_BUTTON, self.OnInterpolation)
|
527
|
+
sizer_hor2.Add(self._but_extrinterp, 1, wx.ALL | wx.EXPAND, 0)
|
528
|
+
|
529
|
+
|
530
|
+
sizer_hor1.Add(self._but_maindir, 2, wx.ALL | wx.EXPAND, 0)
|
531
|
+
sizer_hor1.Add(self._listbox_studyarea, 1, wx.ALL | wx.EXPAND, 0)
|
532
|
+
sizer_hor1.Add(self._listbox_scenario, 1, wx.ALL | wx.EXPAND, 0)
|
533
|
+
sizer_hor1.Add(sizer_ver_small, 0, wx.ALL | wx.EXPAND, 5)
|
534
|
+
|
535
|
+
#3rd line
|
536
|
+
sizer_hor_threads = wx.BoxSizer(wx.HORIZONTAL)
|
537
|
+
text_dx = wx.StaticText(panel, label=_('Resolution (dx,dy) [m]:'))
|
538
|
+
self.input_dx = wx.StaticText(panel)
|
539
|
+
self.input_dx.SetMinSize((80, -1))
|
540
|
+
text_nbxy = wx.StaticText(panel, label=_('(nbx, nby):'))
|
541
|
+
self.input_nbxy = wx.StaticText(panel)
|
542
|
+
self.input_nbxy.SetMinSize((90, -1))
|
543
|
+
text_O = wx.StaticText(panel, label=_('Origin (X,Y):'))
|
544
|
+
self.input_O = wx.StaticText(panel)
|
545
|
+
self.input_O.SetMinSize((170, -1))
|
546
|
+
text_inflation = wx.StaticText(panel, label=_('Inflation factor:'))
|
547
|
+
self._inflation = wx.SpinCtrlDouble(panel, value="1.3", min=1.2, max=2.5, inc=0.1)
|
548
|
+
self._inflation.SetToolTip(_("Inflation factor from 2020 (corresponding year of the unitary prices), to the year of analysis. Defaults to 1.3[%] (corresponds to 2023)."))
|
549
|
+
|
550
|
+
self._but_toggle_admin = wx.ToggleButton(panel, label=_('Admin mode'))
|
551
|
+
self._but_toggle_admin.SetToolTip(_("To activate admin mode. enter password."))
|
552
|
+
self.toggle_state_Admin = False
|
553
|
+
self._but_toggle_admin.Bind(wx.EVT_TOGGLEBUTTON, self.OnToggleAdmin)
|
554
|
+
|
555
|
+
sizer_hor_threads.Add(text_dx, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 1)
|
556
|
+
sizer_hor_threads.Add(self.input_dx, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 1)
|
557
|
+
sizer_hor_threads.Add(text_nbxy, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 1)
|
558
|
+
sizer_hor_threads.Add(self.input_nbxy, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 1)
|
559
|
+
sizer_hor_threads.Add(text_O, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 1)
|
560
|
+
sizer_hor_threads.Add(self.input_O, 1, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 1)
|
561
|
+
sizer_hor_threads.Add(text_inflation, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 1)
|
562
|
+
sizer_hor_threads.Add(self._inflation, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 1)
|
563
|
+
#sizer_hor_threads.Add(self._nb_process, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 1)
|
564
|
+
sizer_hor_threads.Add(self._but_toggle_admin, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 1)
|
565
|
+
|
566
|
+
# Last lines + scenarios
|
567
|
+
#------------------------
|
568
|
+
|
569
|
+
self._but_upriverbed = wx.Button(panel, label=_("Update riverbed ▼"))
|
570
|
+
self._but_upriverbed.SetToolTip(_("Select one of the two options to create the riverbed mask."))
|
571
|
+
self._but_upriverbed.Bind(wx.EVT_BUTTON, self.on_button_click)
|
572
|
+
self.menu = wx.Menu()
|
573
|
+
self.menu.Append(1, _("File of riverbed trace exists."))
|
574
|
+
self.menu.Append(2, _("Point to a low discharge simulation and calculate the riverbed trace."))
|
575
|
+
self.menu.Bind(wx.EVT_MENU, self.onRiverbed)
|
576
|
+
sizer_hor_scen.Add(self._but_upriverbed, 1, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 1)
|
577
|
+
|
578
|
+
self._check_listbox_Ti = wx.CheckListBox(panel, choices=[], style=wx.LB_MULTIPLE | wx.CHK_CHECKED)
|
579
|
+
self.layout_listbox(self._check_listbox_Ti)
|
580
|
+
self.sims_Ti = {}
|
581
|
+
sizer_hor4.Add(self._check_listbox_Ti, 1, wx.ALL | wx.EXPAND, 0)
|
582
|
+
|
583
|
+
self._but_input = wx.Button(panel, label=_('Input table creation\n by reading PICC and WOLF'))
|
584
|
+
self.layout(self._but_input)
|
585
|
+
self._but_input.Bind(wx.EVT_BUTTON, self.OnInput)
|
586
|
+
sizer_hor4.Add(self._but_input, 1, wx.ALL | wx.EXPAND, 0)
|
587
|
+
|
588
|
+
text_tri = wx.StaticText(panel, label=_('Select percentil'))
|
589
|
+
self._tri = wx.SpinCtrlDouble(panel, value="1", min=0.05, max=1, inc=0.05)
|
590
|
+
self._tri.SetToolTip(_("Percentile of the number of results to be represented in the analysis."))
|
591
|
+
text_tri.SetMinSize((100,-1))
|
592
|
+
self._tri.SetMinSize((50,-1))
|
593
|
+
sizer_hor5.Add(text_tri, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 1)
|
594
|
+
sizer_hor5.Add(self._tri, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 1)
|
595
|
+
|
596
|
+
self._but_readresults = wx.Button(panel, label=_('Read results'))
|
597
|
+
self.layout(self._but_readresults)
|
598
|
+
self._but_readresults.Bind(wx.EVT_BUTTON, self.OnReadResults)
|
599
|
+
sizer_hor5.Add(self._but_readresults, 1, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 1)
|
600
|
+
#self._but_readresults.Hide()
|
601
|
+
|
602
|
+
#self._listbox_scenario2 = wx.CheckListBox(panel, choices=[], style=wx.LB_MULTIPLE | wx.CHK_CHECKED)
|
603
|
+
#self.layout_listbox(self._listbox_scenario2)
|
604
|
+
#self.list_scen_output = {}
|
605
|
+
#self._listbox_scenario2.SetToolTip("Choose the scenarios to compare.")
|
606
|
+
#sizer_hor5.Add(self._but_setcomp, 1, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 1)
|
607
|
+
|
608
|
+
self._listbox_CompScen = wx.CheckListBox(panel, choices=[], style=wx.LB_MULTIPLE | wx.CHK_CHECKED)
|
609
|
+
self.layout_listbox(self._listbox_CompScen)
|
610
|
+
self._listbox_CompScen.SetToolTip(_("Choose the INBE scenarios to compare (minimum 2), in the same study area selected at the manager first line."))
|
611
|
+
sizer_hor5.Add(self._listbox_CompScen, 1, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 1)
|
612
|
+
|
613
|
+
|
614
|
+
self._but_setcomp = wx.Button(panel, label=_('Comparison'))
|
615
|
+
self.layout(self._but_setcomp)
|
616
|
+
self._but_setcomp.Bind(wx.EVT_BUTTON, self.OnSetComp0)
|
617
|
+
sizer_hor5.Add(self._but_setcomp, 1, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 1)
|
618
|
+
#self._but_setcomp.Hide()
|
619
|
+
|
620
|
+
|
621
|
+
|
622
|
+
self._but_default_TEMP = wx.Button(panel, label=_('Default values and\n individual damage'))
|
623
|
+
self._but_default_TEMP.SetToolTip(_("Impute the default values to the input tables, and compute the individual damage."))
|
624
|
+
self.layout(self._but_default_TEMP)
|
625
|
+
self._but_default_TEMP.Bind(wx.EVT_BUTTON, self.OnDefault_TEMP)
|
626
|
+
sizer_hor4.Add(self._but_default_TEMP, 1, wx.ALL | wx.EXPAND, 0)
|
627
|
+
|
628
|
+
self._but_combined_OUTPUT = wx.Button(panel, label=_('Combined damage'))
|
629
|
+
self._but_combined_OUTPUT.SetToolTip(_("Compute the combined damage."))
|
630
|
+
self.layout(self._but_combined_OUTPUT)
|
631
|
+
self._but_combined_OUTPUT.Bind(wx.EVT_BUTTON, self.Oncombined_OUTPUT)
|
632
|
+
sizer_hor4.Add(self._but_combined_OUTPUT, 1, wx.ALL | wx.EXPAND, 0)
|
633
|
+
|
634
|
+
#Lines order
|
635
|
+
sizer_ver_small.Add(self._but_checkfiles, 0, wx.ALL | wx.EXPAND, 1)
|
636
|
+
sizer_ver_small.Add(self._but_checksim, 0, wx.ALL | wx.EXPAND, 1)
|
637
|
+
sizer_ver_small.Add(self._but_checkpond, 0, wx.ALL | wx.EXPAND, 1)
|
638
|
+
sizer_ver_small.Add(self._but_checkpicc, 0, wx.ALL | wx.EXPAND, 1)
|
639
|
+
|
640
|
+
sizer_vert1.Add(sizer_hor1, 1, wx.EXPAND, 0)
|
641
|
+
sizer_vert1.Add(sizer_hor2, 1, wx.EXPAND, 0)
|
642
|
+
sizer_vert1.Add(sizer_hor_threads, 0, wx.EXPAND, 0)
|
643
|
+
sizer_vert1.Add(sizer_hor_scen, 1, wx.EXPAND, 0)
|
644
|
+
sizer_vert1.Add(sizer_hor3, 1, wx.EXPAND, 0)
|
645
|
+
sizer_vert1.Add(sizer_hor4, 1, wx.EXPAND, 0)
|
646
|
+
sizer_vert1.Add(sizer_hor5, 1, wx.EXPAND, 0)
|
647
|
+
sizer_hor_main.Add(sizer_vert1, proportion=1, flag=wx.EXPAND, border=0)
|
648
|
+
|
649
|
+
sizer_ver_small2.Add(self._but_MNTmodifs, 0, wx.ALL | wx.EXPAND, 1)
|
650
|
+
sizer_ver_small2.Add(self._but_DEM, 0, wx.ALL | wx.EXPAND, 1)
|
651
|
+
|
652
|
+
#Disabled if Main Directory + SA + Scenario not selected
|
653
|
+
self._but_default_TEMP.Enable(False)
|
654
|
+
self._but_danger.Enable(False)
|
655
|
+
self._but_input.Enable(False)
|
656
|
+
self._tri.Enable(False)
|
657
|
+
self._but_readresults.Enable(False)
|
658
|
+
self._but_checkfiles.Enable(False)
|
659
|
+
self._but_DEM.Enable(False)
|
660
|
+
self._but_MNTmodifs.Enable(False)
|
661
|
+
self._but_extrinterp.Enable(False)
|
662
|
+
self._but_combined_OUTPUT.Enable(False)
|
663
|
+
self._but_upriverbed.Enable(False)
|
664
|
+
self._but_checksim.Enable(False)
|
665
|
+
self._but_checkpicc.Enable(False)
|
666
|
+
self._but_loadgpu.Enable(False)
|
667
|
+
self._but_checkpond.Enable(False)
|
668
|
+
self._but_setcomp.Enable(False)
|
669
|
+
|
670
|
+
panel.SetSizer(sizer_hor_main)
|
671
|
+
panel.Layout()
|
672
|
+
|
673
|
+
|
674
|
+
def OnSims(self, e:wx.ListEvent):
|
675
|
+
""" Load sim into the mapviewer """
|
676
|
+
pass
|
677
|
+
|
678
|
+
def OnSimsDBLClick(self, e:wx.ListEvent):
|
679
|
+
""" Load sim into the mapviewer """
|
680
|
+
if self.mapviewer is None:
|
681
|
+
return
|
682
|
+
|
683
|
+
from ..PyDraw import draw_type
|
684
|
+
|
685
|
+
idx_sim = e.GetSelection()
|
686
|
+
tmppath = self._manager.get_filepath_for_return_period(self._manager.get_return_periods()[idx_sim])
|
687
|
+
if tmppath.stem not in self.mapviewer.get_list_keys(drawing_type=draw_type.ARRAYS):
|
688
|
+
self.mapviewer.add_object('array', filename=str(tmppath), id=tmppath.stem)
|
689
|
+
self.mapviewer.Refresh()
|
690
|
+
|
691
|
+
def OnCheckFiles(self, e):
|
692
|
+
""" Check the files """
|
693
|
+
if self._manager is None:
|
694
|
+
logging.error(_("No main directory selected -- Nothing to check"))
|
695
|
+
return
|
696
|
+
|
697
|
+
i=self._manager.check_inputs()
|
698
|
+
|
699
|
+
if i == False :
|
700
|
+
logging.error(_(f"Missing files in INPUT. Please provide them by following the right structure."))
|
701
|
+
with wx.MessageDialog(self, f"Missing files in INPUT. Inputs can not be created automatically : you must provide them.\nPlease read the logs and terminal to see the missing ones.", "Error", wx.OK | wx.ICON_ERROR) as dlg:
|
702
|
+
dlg.ShowModal()
|
703
|
+
return
|
704
|
+
else :
|
705
|
+
if (self._manager._study_area is None) or (self._manager._scenario is None):
|
706
|
+
logging.error(_(f"No study area and/or scenario selected, no check of OUTPUT."))
|
707
|
+
with wx.MessageDialog(self, f"INPUT is well structured, but OUTPUT has not been checked because there is no study area and scenario selected.", "Checking", wx.OK | wx.ICON_INFORMATION) as dlg:
|
708
|
+
dlg.ShowModal()
|
709
|
+
else:
|
710
|
+
logging.info(_(f"The folder is well structured."))
|
711
|
+
#t=self._manager.check_temporary()
|
712
|
+
o=self._manager.check_outputs()
|
713
|
+
with wx.MessageDialog(self, f"Main directory is checked.\nINPUT is well structured, and OUTPUT has been checked. If folders were missing, they have been created\nMain directory at {self.maindir}", "Checking", wx.OK | wx.ICON_INFORMATION) as dlg:
|
714
|
+
dlg.ShowModal()
|
715
|
+
#logging.info(f"scenario {self._manager._scenario} {self._manager.scenario} et SA {self._manager._study_area} {self._manager.Study_area}")
|
716
|
+
|
717
|
+
def OnHydrodynInput(self,e):
|
718
|
+
""" A test to check if the FILLED water depths files exist.
|
719
|
+
-If YES : the code can go on
|
720
|
+
-If NO : either need to be computed, either the code will use the baseline ones
|
721
|
+
"""
|
722
|
+
|
723
|
+
if self._manager is None:
|
724
|
+
logging.error(_("No main directory selected -- Nothing to check"))
|
725
|
+
return
|
726
|
+
|
727
|
+
if self._manager.IN_SA_INTERP is None:
|
728
|
+
with wx.MessageDialog(self, "No simulation found in the manager. Please select the simulations first.", "Error", wx.OK | wx.ICON_ERROR) as dlg:
|
729
|
+
dlg.ShowModal()
|
730
|
+
return
|
731
|
+
|
732
|
+
paths_FilledWD = self._manager.get_sims_files_for_scenario()
|
733
|
+
|
734
|
+
if len(paths_FilledWD) == 0 :
|
735
|
+
logging.info(_("There are no interpolated free surface files."))
|
736
|
+
dialog = wx.MessageDialog(None, "There are no interpolated free surface files. Please choose an action.", "Checking- Choose an option",
|
737
|
+
wx.YES_NO | wx.CANCEL | wx.ICON_QUESTION)
|
738
|
+
|
739
|
+
dialog.SetYesNoLabels("Use the ones in the scenario_baseline (assumption)", "Load other simulations")
|
740
|
+
response = dialog.ShowModal()
|
741
|
+
|
742
|
+
if response == wx.ID_YES:
|
743
|
+
logging.info(_("Decision of using baseline simulations."))
|
744
|
+
paths_FilledWD_base = self._manager.get_sims_files_for_baseline()
|
745
|
+
if len(paths_FilledWD_base) == 0 :
|
746
|
+
logging.info(_("Cannot select files in the _baseline folder (no files or no folder!)."))
|
747
|
+
else:
|
748
|
+
self._manager.copy_tif_files(paths_FilledWD_base, self._manager.IN_SA_INTERP)
|
749
|
+
|
750
|
+
elif response == wx.ID_NO:
|
751
|
+
logging.info(_("Decision of loading simulations."))
|
752
|
+
with wx.MessageDialog(self, f"Please use the 'Working with new hydraulic scenarios' button of the manager and follow the instructions.", "Redirecting",
|
753
|
+
wx.OK | wx.ICON_INFORMATION) as dlg:
|
754
|
+
dlg.ShowModal()
|
755
|
+
else:
|
756
|
+
logging.info(_("Cancelled"))
|
757
|
+
|
758
|
+
dialog.Destroy()
|
759
|
+
|
760
|
+
else:
|
761
|
+
name_paths_FilledWD = []
|
762
|
+
|
763
|
+
for names in paths_FilledWD:
|
764
|
+
logging.info(_(f"Interpolated free surface file(s) found: {names.name}. \n Reminder : the names of the simulations MUST be 'T.' or 'Q.' with '.' the return period."))
|
765
|
+
name_paths_FilledWD.append(names.name)
|
766
|
+
with wx.MessageDialog(self,
|
767
|
+
f"{len(paths_FilledWD)} file(s) of interpolated free surface found in the folder : {name_paths_FilledWD}.",
|
768
|
+
"Information",
|
769
|
+
style=wx.OK | wx.ICON_INFORMATION) as dlg:
|
770
|
+
dlg.ShowModal()
|
771
|
+
update_info_header(self.input_dx,self.input_nbxy,self.input_O,self._manager.IN_SA_INTERP)
|
772
|
+
|
773
|
+
|
774
|
+
def OnCheckPond(self,e): #Maybe later ? Idk
|
775
|
+
if self._manager is None:
|
776
|
+
logging.error(_("No main directory selected -- Nothing to check"))
|
777
|
+
return
|
778
|
+
if self._manager.IN_SA_INTERP is None:
|
779
|
+
logging.error(_("No IN_SA_INTERP attribute found in the manager."))
|
780
|
+
with wx.MessageDialog(self, "No simulation found in the manager. Please select the simulations first.", "Error", wx.OK | wx.ICON_ERROR) as dlg:
|
781
|
+
dlg.ShowModal()
|
782
|
+
return
|
783
|
+
ponds = self._manager.get_ponderations()
|
784
|
+
if isinstance(ponds, pd.DataFrame):
|
785
|
+
logging.info(_(f"Plotting the coefficients graph."))
|
786
|
+
ponds.plot(kind='bar', color='gray', edgecolor='black')
|
787
|
+
plt.ylabel("Weighting coefficients [-]")
|
788
|
+
plt.xlabel("Return period [years]")
|
789
|
+
plt.grid(axis='y', linestyle='--', alpha=0.7)
|
790
|
+
plt.show()
|
791
|
+
else:
|
792
|
+
with wx.MessageDialog(self,
|
793
|
+
"No coefficients computed, because no return period found in the interpolated simulation folder. Try after loading gpu simulations",
|
794
|
+
"Checking",
|
795
|
+
style=wx.OK | wx.ICON_INFORMATION) as dlg:
|
796
|
+
dlg.ShowModal()
|
797
|
+
|
798
|
+
def OnCheckPICC(self, e):
|
799
|
+
logging.info(_(f"Checking PICC for study area {self._manager._study_area}, in {self._manager.scenario}."))
|
800
|
+
unused, nb, unused = self._func.PICC_read(self._manager)#._study_area, self._manager.scenario)
|
801
|
+
if nb != None :
|
802
|
+
with wx.MessageDialog(self,
|
803
|
+
f"PICC Successfully read. There are {nb} residential building(s) ('Habitation') contained in\n the selected study area {self._manager._study_area}, in {self._manager.scenario}.",
|
804
|
+
"Checking PICC",
|
805
|
+
style=wx.OK | wx.ICON_INFORMATION) as dlg:
|
806
|
+
dlg.ShowModal()
|
807
|
+
else :
|
808
|
+
path = Path(self._manager.IN_DATABASE) / "PICC_Vesdre.shp"
|
809
|
+
with wx.MessageDialog(self,
|
810
|
+
f"Error while reading PICC, please ensure the file exists in {path}",
|
811
|
+
"Error checking PICC",
|
812
|
+
style=wx.OK | wx.ICON_INFORMATION) as dlg:
|
813
|
+
dlg.ShowModal()
|
814
|
+
|
815
|
+
|
816
|
+
def OnMainDir(self, e):
|
817
|
+
"""Selects the main directory to be read."""
|
818
|
+
vanish_info_header(self.input_dx,self.input_nbxy,self.input_O)
|
819
|
+
|
820
|
+
with wx.DirDialog(self, "Choose the main directory containing the data (folders INPUT and OUTPUT):",
|
821
|
+
style=wx.DD_DEFAULT_STYLE
|
822
|
+
) as dlg:
|
823
|
+
|
824
|
+
if dlg.ShowModal() == wx.ID_OK:
|
825
|
+
self._manager = INBE_Manager(main_dir=dlg.GetPath())#, Study_area="scenario_manager", scenario = "scenario_before2021")
|
826
|
+
self.maindir=dlg.GetPath()
|
827
|
+
|
828
|
+
folders = ["INPUT"]
|
829
|
+
|
830
|
+
for folder in folders:
|
831
|
+
if not os.path.isdir(os.path.join(self.maindir, folder)):
|
832
|
+
logging.error(_("INPUT folder is missing."))
|
833
|
+
wx.MessageBox(
|
834
|
+
f"Missing INPUT folder. Please organize correctly this folder {self.maindir}.",
|
835
|
+
"Error",
|
836
|
+
wx.OK | wx.ICON_ERROR
|
837
|
+
)
|
838
|
+
dlg.Destroy()
|
839
|
+
return
|
840
|
+
|
841
|
+
folders = ['RIVER_MASK', 'DATABASE', 'STUDY_AREA', 'CSVs', 'WATER_DEPTH', 'VELOCITY']
|
842
|
+
missing = []
|
843
|
+
for folder in folders:
|
844
|
+
if not os.path.isdir(os.path.join(self.maindir, "INPUT", folder)):
|
845
|
+
logging.error(_(f"INPUT/{folder} folder is missing."))
|
846
|
+
missing.append(folder)
|
847
|
+
if missing:
|
848
|
+
wx.MessageBox(
|
849
|
+
f"Missing folders : {missing}. Please organize correctly your INPUT folder in {self.maindir}.",
|
850
|
+
"Error",
|
851
|
+
wx.OK | wx.ICON_ERROR
|
852
|
+
)
|
853
|
+
dlg.Destroy()
|
854
|
+
return
|
855
|
+
|
856
|
+
folders = ["OUTPUT"]#TEMP",
|
857
|
+
for folder in folders:
|
858
|
+
if not os.path.isdir(os.path.join(self.maindir, folder)):
|
859
|
+
logging.info(_(f"Creating {folder} folder."))
|
860
|
+
os.makedirs(os.path.join(self.maindir, folder))
|
861
|
+
|
862
|
+
self._but_default_TEMP.Enable(True)
|
863
|
+
self._but_input.Enable(True)
|
864
|
+
self._but_checkfiles.Enable(True)
|
865
|
+
self._but_upriverbed.Enable(True)
|
866
|
+
self._tri.Enable(True)
|
867
|
+
self._but_readresults.Enable(True)
|
868
|
+
self._but_checksim.Enable(True)
|
869
|
+
self._but_checkpicc.Enable(True)
|
870
|
+
self._but_loadgpu.Enable(True)
|
871
|
+
self._but_checkpond.Enable(True)
|
872
|
+
self._but_combined_OUTPUT.Enable(True)
|
873
|
+
self._but_setcomp.Enable(True)
|
874
|
+
|
875
|
+
#Must be False if come back :
|
876
|
+
self._but_DEM.Enable(False)
|
877
|
+
self._but_MNTmodifs.Enable(False)
|
878
|
+
self._but_extrinterp.Enable(False)
|
879
|
+
|
880
|
+
self._listbox_scenario.Clear()
|
881
|
+
studyareas = self._manager.get_list_studyareas()
|
882
|
+
if len(studyareas) == 0 :
|
883
|
+
logging.info(_("Folder loaded but no study areas found in the folder (INPUT/STUDY_AREA). Please use the button to load hydraulic simulations in the manager."))
|
884
|
+
return
|
885
|
+
self._listbox_studyarea.Clear()
|
886
|
+
self._listbox_studyarea.InsertItems(studyareas, 0)
|
887
|
+
|
888
|
+
logging.info(_("All the directories are present"))
|
889
|
+
|
890
|
+
def OnStudyArea(self, e):
|
891
|
+
""" Change the study area """
|
892
|
+
if self._manager is None:
|
893
|
+
return
|
894
|
+
vanish_info_header(self.input_dx,self.input_nbxy,self.input_O)
|
895
|
+
self._listbox_scenario.Clear()
|
896
|
+
self.file_paths = None
|
897
|
+
study_area:str = self._manager.get_list_studyareas(with_suffix=True)[e.GetSelection()]
|
898
|
+
|
899
|
+
self._manager.change_studyarea(study_area)
|
900
|
+
list_sc, list_SA = self._manager.get_list_scenarios_extended()
|
901
|
+
self.items = list(zip(list_SA, list_sc)) # [(SA, Scenario), ...]
|
902
|
+
choices = [f"{sa} / {sc}" for sa, sc in self.items]
|
903
|
+
self._listbox_CompScen.Set(choices)
|
904
|
+
|
905
|
+
#self._listbox_CompScen.Set(list_sc_extended)#get_list_individual_T())
|
906
|
+
|
907
|
+
sc = self._manager.get_list_scenarios()
|
908
|
+
|
909
|
+
if len(sc)!=0:
|
910
|
+
self._listbox_scenario.InsertItems(sc, 0)
|
911
|
+
else :
|
912
|
+
logging.error(_("No scenario available associated with this study area."))
|
913
|
+
|
914
|
+
if self.mapviewer is not None:
|
915
|
+
tmp_path = self._manager.IN_STUDY_AREA / study_area
|
916
|
+
|
917
|
+
from ..PyDraw import draw_type
|
918
|
+
if not tmp_path.stem in self.mapviewer.get_list_keys(drawing_type=draw_type.VECTORS):
|
919
|
+
self.mapviewer.add_object('vector', filename=str(tmp_path), id=tmp_path.stem)
|
920
|
+
self.mapviewer.Refresh()
|
921
|
+
self._but_DEM.Enable(False)
|
922
|
+
self._but_MNTmodifs.Enable(False)
|
923
|
+
self._but_extrinterp.Enable(False)
|
924
|
+
|
925
|
+
def OnScenario(self, e):
|
926
|
+
""" Change the scenario """
|
927
|
+
if self._manager is None:
|
928
|
+
return
|
929
|
+
scenario = self._manager.get_list_scenarios()[e.GetSelection()]
|
930
|
+
self._but_DEM.Enable(True)
|
931
|
+
self._but_MNTmodifs.Enable(True)
|
932
|
+
self._but_extrinterp.Enable(True)
|
933
|
+
self._manager.change_scenario(scenario)
|
934
|
+
create_INPUT_OUTPUT_forScenario(self.maindir, self._manager.Study_area, self._manager.scenario, None)
|
935
|
+
update_info_header(self.input_dx,self.input_nbxy,self.input_O,self._manager.IN_SA_INTERP)
|
936
|
+
self._check_listbox_Ti.Set(self._manager.get_list_interp()) #not in accept
|
937
|
+
|
938
|
+
def OnLoadingSimu(self,e):
|
939
|
+
""" Link between INBE and simulations
|
940
|
+
-Load a hydraulic scenarios from the scenario manager
|
941
|
+
-Create scenario and study area if needed.
|
942
|
+
"""
|
943
|
+
#MAde for Vesdre & Daniela, very specific. Maybe to be kept... [xyz]
|
944
|
+
#dlg = wx.SingleChoiceDialog(
|
945
|
+
# None,
|
946
|
+
# "What do you want to load?",
|
947
|
+
# "Loading choice",
|
948
|
+
# ["Existing danger maps", "Wolf-GPU simulation"]
|
949
|
+
#)
|
950
|
+
#if dlg.ShowModal() == wx.ID_OK:
|
951
|
+
# choice = dlg.GetStringSelection()
|
952
|
+
# if choice == "Existing danger maps":
|
953
|
+
# dlg0 = wx.MessageDialog(
|
954
|
+
# None,
|
955
|
+
# "Please follow these steps:\n\n"
|
956
|
+
# "• Create a folder named after your study area (e.g., Theux).\n"
|
957
|
+
# "• Inside this folder, create a subfolder for the scenario (e.g., scenario_example).\n"
|
958
|
+
# "• In this scenario subfolder, include:\n"
|
959
|
+
# " - A water level danger map in .tif format (e.g., T2021.tif).\n"
|
960
|
+
# " - Optionally, a velocity danger map named like:\n"
|
961
|
+
# " v_danger_T2021_scenario_example.tif\n\n"
|
962
|
+
# "Then, select the scenario folder (e.g., Desktop\\Theux\\scenario_example).",
|
963
|
+
# "Information",
|
964
|
+
# wx.OK | wx.ICON_INFORMATION
|
965
|
+
# )
|
966
|
+
# dlg0.ShowModal()
|
967
|
+
# dlg0.Destroy()
|
968
|
+
#
|
969
|
+
#
|
970
|
+
# dlg_path = wx.DirDialog(
|
971
|
+
# None,
|
972
|
+
# "Please point toward the specific scenario folder (e.g Desktop\Theux\scenario_2021)."
|
973
|
+
# )
|
974
|
+
# if dlg_path.ShowModal() == wx.ID_OK:
|
975
|
+
# full_path = dlg_path.GetPath()
|
976
|
+
#
|
977
|
+
# study_area_folder = os.path.basename(os.path.dirname(full_path))
|
978
|
+
# scenario_folder = os.path.basename(full_path)
|
979
|
+
#
|
980
|
+
# tif_path = None
|
981
|
+
# for file in os.listdir(full_path):
|
982
|
+
# if file.endswith(".tif") and file.startswith("T"):
|
983
|
+
# tif_path = os.path.join(full_path, file)
|
984
|
+
# break
|
985
|
+
#
|
986
|
+
#
|
987
|
+
# create_INPUT_TEMP_OUTPUT_forScenario(self.maindir, study_area_folder, scenario_folder, danger=Path(tif_path))
|
988
|
+
#
|
989
|
+
# self._manager.change_studyarea(study_area_folder +'.shp')
|
990
|
+
# self._manager.change_scenario(scenario_folder)
|
991
|
+
# self._listbox_studyarea.Clear()
|
992
|
+
# self._listbox_studyarea.InsertItems(self._manager.get_list_studyareas(), 0)
|
993
|
+
# self._listbox_scenario.Clear()
|
994
|
+
# self._listbox_scenario.InsertItems(self._manager.get_list_scenarios(), 0)
|
995
|
+
#
|
996
|
+
# path_wd = self._manager.IN_SA_EXTRACTED
|
997
|
+
# WA_bin = WolfArray(tif_path)
|
998
|
+
# WA_bin.write_all(os.path.join(path_wd, os.path.splitext(os.path.basename(tif_path))[0] + ".bin"))
|
999
|
+
#
|
1000
|
+
# path_v = self._manager.IN_SCEN_DIR_V
|
1001
|
+
# logging.info(_(f"Scanning the folder {full_path} to get the danger map(s)."))
|
1002
|
+
# for file in os.listdir(full_path):
|
1003
|
+
# if file.startswith("v_danger_") and file.endswith(".tif"):
|
1004
|
+
# shutil.copy(os.path.join(full_path, file), path_v)
|
1005
|
+
# dlg = wx.MessageDialog(
|
1006
|
+
# None,
|
1007
|
+
# "Folders created and danger map(s) imported.",
|
1008
|
+
# "Information",
|
1009
|
+
# wx.OK | wx.ICON_INFORMATION
|
1010
|
+
# )
|
1011
|
+
# dlg.ShowModal()
|
1012
|
+
# dlg.Destroy()
|
1013
|
+
# logging.info(_("Folders created and danger map(s) imported."))
|
1014
|
+
#
|
1015
|
+
dlg = wx.DirDialog(None, "Please select the main scenario manager folder (containing the scenarios, the folder discharge, the scripts.py...), named after the STUDY AREA.\n If you cancel, this button wont be activated or will be desactivated.", style=wx.DD_DEFAULT_STYLE)
|
1016
|
+
if dlg.ShowModal() == wx.ID_OK:
|
1017
|
+
self._but_loadgpu.SetValue(True)
|
1018
|
+
main_gpu = Path(dlg.GetPath())
|
1019
|
+
study_area = main_gpu.name
|
1020
|
+
logging.info(_(f"Selected folder for GPU result such as the STUDY AREA is {study_area}"))
|
1021
|
+
dlg = wx.DirDialog(None, "Please select the scenarios folder (containing the 'simulations' folder) of the specific HYDRAULIC SCENARIO.", defaultPath=str(main_gpu), style=wx.DD_DEFAULT_STYLE)
|
1022
|
+
if dlg.ShowModal() == wx.ID_OK:
|
1023
|
+
scenario = Path(dlg.GetPath())
|
1024
|
+
hydraulic_scen=scenario.joinpath("simulations")
|
1025
|
+
scenario=scenario.name
|
1026
|
+
logging.info(_(f"Selected hydraulic scenario : {scenario}"))
|
1027
|
+
create_INPUT_OUTPUT_forScenario(self.maindir, study_area, scenario, main_gpu)
|
1028
|
+
self._manager.change_studyarea(study_area+'.shp')
|
1029
|
+
self._manager.change_scenario(scenario)
|
1030
|
+
|
1031
|
+
self._listbox_studyarea.Clear()
|
1032
|
+
self._listbox_studyarea.InsertItems(self._manager.get_list_studyareas(), 0)
|
1033
|
+
self._listbox_scenario.Clear()
|
1034
|
+
self._listbox_scenario.InsertItems(self._manager.get_list_scenarios(), 0)
|
1035
|
+
|
1036
|
+
#Blue color of selection even if not directly clicked :
|
1037
|
+
index_to_select = self._listbox_scenario.FindString(scenario)
|
1038
|
+
if index_to_select != wx.NOT_FOUND:
|
1039
|
+
self._listbox_scenario.SetSelection(index_to_select)
|
1040
|
+
self._listbox_scenario.SetItemBackgroundColour(index_to_select, wx.Colour(0, 120, 215))
|
1041
|
+
|
1042
|
+
index_to_select = self._listbox_studyarea.FindString(study_area)
|
1043
|
+
if index_to_select != wx.NOT_FOUND:
|
1044
|
+
self._listbox_studyarea.SetSelection(index_to_select)
|
1045
|
+
self._listbox_studyarea.SetItemBackgroundColour(index_to_select, wx.Colour(0, 120, 215))
|
1046
|
+
self._listbox_studyarea.Refresh()
|
1047
|
+
self._listbox_scenario.Refresh()
|
1048
|
+
|
1049
|
+
else:
|
1050
|
+
logging.error('No hydraulic scenario selected, toggle button desactivated.')
|
1051
|
+
self._but_loadgpu.SetValue(False)
|
1052
|
+
return
|
1053
|
+
else:
|
1054
|
+
logging.error('No folder found / selected. Please try again.')
|
1055
|
+
self._but_loadgpu.SetValue(False)
|
1056
|
+
return
|
1057
|
+
|
1058
|
+
self._check_listbox.Clear()
|
1059
|
+
self.sims = {}
|
1060
|
+
for subdir in hydraulic_scen.iterdir():
|
1061
|
+
if subdir.is_dir() and subdir.name.startswith("sim_"):
|
1062
|
+
self.sims[subdir.name] = subdir
|
1063
|
+
else:
|
1064
|
+
logging.info(_('No folder sim_ found / selected. Please try again.'))
|
1065
|
+
self.datadir_simulations = hydraulic_scen
|
1066
|
+
self.file_paths = {Path(sim).name: Path(sim) for sim in sorted(self.sims.keys())}
|
1067
|
+
self._check_listbox.Set(sorted(sim for sim in self.sims.keys()))
|
1068
|
+
|
1069
|
+
logging.info(_(f"GPU simulations loaded in the checkbox.\n\nPlease select the ones you want to interpolate and use the button 'Reading and interpolating free surface'."))
|
1070
|
+
message = "GPU simulations loaded in the checkbox\n\nPlease select the ones you want to interpolate and use the button 'Reading and interpolating free surface'."
|
1071
|
+
|
1072
|
+
found_bath = search_for_modif_bath_and_copy(Path(main_gpu), Path(hydraulic_scen.parent), self._manager.IN_CH_DEM_SC)
|
1073
|
+
if found_bath :
|
1074
|
+
message+= "\nIn addition, modification files for bathymetry (bath_) have been found in the gpu simulations, a copy has been made for a change in the vulnerability and DEM (see vuln_ and MNTmodifs_ in CHANGE_VULNE). Please edit them."
|
1075
|
+
logging.info(_(f"Modification files for bathymetry (bath_) have been found in the gpu simulations, a copy has been made for a change in the vulnerability and DEM (see vuln_ and MNTmodifs_ in CHANGE_VULNE). Please edit them."))
|
1076
|
+
|
1077
|
+
self.gpu_bathy = hydraulic_scen.parent / BATHYMETRY_FOR_SIMULATION # this is the last bathymetry after the scripts have been run
|
1078
|
+
self._but_extrinterp.Enable(True)
|
1079
|
+
self._but_DEM.Enable(True)
|
1080
|
+
self._but_danger.Enable(True)
|
1081
|
+
self._but_MNTmodifs.Enable(True)
|
1082
|
+
with wx.MessageDialog(self,
|
1083
|
+
message,
|
1084
|
+
"Information",
|
1085
|
+
style=wx.OK | wx.ICON_INFORMATION) as dlg:
|
1086
|
+
dlg.ShowModal()
|
1087
|
+
|
1088
|
+
def OnDanger(self,e):
|
1089
|
+
""" Specific button to extract last step or to compute the wd danger map"""
|
1090
|
+
menu_id = e.GetId()
|
1091
|
+
param_danger = [0, -1, 1]
|
1092
|
+
if menu_id == 1:
|
1093
|
+
type_extraction = "last_step"
|
1094
|
+
logging.info(_("Option 1 : last step extraction and interpolation."))
|
1095
|
+
elif menu_id == 2:
|
1096
|
+
type_extraction = "danger_map"
|
1097
|
+
logging.info(_("Option 2 : danger map computation and interpolation."))
|
1098
|
+
dlg = wx.TextEntryDialog(None,
|
1099
|
+
"Enter parameters as (e.g 0, -1, 1): from which step, until which step (-1 if latest step), by number of step",
|
1100
|
+
"Parameters", "0, -1, 1")
|
1101
|
+
if dlg.ShowModal() == wx.ID_OK:
|
1102
|
+
try:
|
1103
|
+
param_danger = [int(x.strip()) for x in dlg.GetValue().split(",")]
|
1104
|
+
except:
|
1105
|
+
wx.MessageBox("Invalid input. Use format: 0, -1, 1", "Error")
|
1106
|
+
dlg.Destroy()
|
1107
|
+
|
1108
|
+
else :
|
1109
|
+
return
|
1110
|
+
|
1111
|
+
|
1112
|
+
with wx.TextEntryDialog(
|
1113
|
+
self,
|
1114
|
+
"What threshold (in meters) do you want to apply to filter the water depth danger map?",
|
1115
|
+
"Water Depth Threshold",
|
1116
|
+
"0.01"
|
1117
|
+
) as dlg:
|
1118
|
+
threshold = None
|
1119
|
+
if dlg.ShowModal() == wx.ID_OK:
|
1120
|
+
val = dlg.GetValue().strip().replace(',', '.')
|
1121
|
+
try:
|
1122
|
+
threshold = float(val)
|
1123
|
+
if threshold <= 0:
|
1124
|
+
wx.MessageBox("Please enter a strictly positive number.", "Invalid Value", wx.ICON_ERROR)
|
1125
|
+
threshold = None
|
1126
|
+
return
|
1127
|
+
except Exception:
|
1128
|
+
wx.MessageBox("Invalid input — please enter a number (e.g., 0.01).", "Error", wx.ICON_ERROR)
|
1129
|
+
threshold = None
|
1130
|
+
return
|
1131
|
+
else :
|
1132
|
+
return
|
1133
|
+
if not hasattr(self, 'file_paths'):
|
1134
|
+
with wx.MessageDialog(self,
|
1135
|
+
f"Please, first load gpu simulations via the previous button.",
|
1136
|
+
"Attention",
|
1137
|
+
style=wx.OK | wx.ICON_ERROR) as dlg:
|
1138
|
+
dlg.ShowModal()
|
1139
|
+
return
|
1140
|
+
logging.info(_(f"Threshold for water depth selected : {threshold} [m]"))
|
1141
|
+
checked_indices = self._check_listbox.GetCheckedItems()
|
1142
|
+
checked_items = [self._check_listbox.GetString(index) for index in checked_indices]
|
1143
|
+
selected_paths = [self.file_paths[item] for item in checked_items]
|
1144
|
+
if not selected_paths:
|
1145
|
+
wx.MessageBox("No selection detected. Using all items in the list.", "Info", wx.ICON_INFORMATION)
|
1146
|
+
selected_items = list(self._check_listbox.GetStrings())
|
1147
|
+
selected_paths = [self.file_paths[item] for item in selected_items]
|
1148
|
+
path_simulations = self.datadir_simulations
|
1149
|
+
|
1150
|
+
#dx,dy,nbx,nby,X,Y = False, False, False, False, False, False
|
1151
|
+
_interpol = interpolating_raster()
|
1152
|
+
for sim_ in selected_paths:
|
1153
|
+
if sim_.name.startswith("sim_"):
|
1154
|
+
self.sims[sim_.name] = sim_
|
1155
|
+
fn_read = Path(path_simulations/ sim_ / "simul_gpu_results")
|
1156
|
+
logging.info(_(f"Found simulation folder: {sim_}"))
|
1157
|
+
parts = sim_.name.split("sim_")
|
1158
|
+
if len(parts) > 1:
|
1159
|
+
logging.info(_("Computing water depth and velocity danger maps"))
|
1160
|
+
name = parts[1]
|
1161
|
+
# dx,dy,nbx,nby,X,Y = display_info_header(self.input_dx, self.input_nbxy, self.input_O, fn_write.with_suffix(".bin"))
|
1162
|
+
_interpol.export_z_or_v_bin(fn_read, self._manager, name, type_hazard="z_v", type_extraction = type_extraction, param_danger = param_danger, threshold=threshold)
|
1163
|
+
|
1164
|
+
else:
|
1165
|
+
logging.info(_(f"Please, ensure your simulations are named with the return period, e.g sim_T4"))
|
1166
|
+
else:
|
1167
|
+
logging.info(_('No folder found / selected. Please try again...'))
|
1168
|
+
|
1169
|
+
dlg = wx.MessageDialog(self,
|
1170
|
+
"Danger maps created in INPUT\WATER_DEPTH\... and INPUT\VELOCITY\...",
|
1171
|
+
"Success.",
|
1172
|
+
wx.OK | wx.ICON_INFORMATION)
|
1173
|
+
dlg.ShowModal()
|
1174
|
+
dlg.Destroy()
|
1175
|
+
|
1176
|
+
|
1177
|
+
|
1178
|
+
def OnDEM(self,e):
|
1179
|
+
"""Import and create the inputs for the interpolation routine (name including 'MNT_...' and 'MNT_..._with_mask'.
|
1180
|
+
See function MTN_And_mask_creation_all"""
|
1181
|
+
path = self._manager.IN_SA_DEM
|
1182
|
+
names_inDEM = [f for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))]
|
1183
|
+
if len(names_inDEM) != 0 :
|
1184
|
+
dialog = wx.MessageDialog(None, f"The DEM_FILES folder is not empty and contains the files {names_inDEM}. ", "Confirmation", wx.YES_NO | wx.ICON_QUESTION)
|
1185
|
+
dialog.SetYesNoLabels("Delete and reload", "Keep and leave")
|
1186
|
+
response = dialog.ShowModal()
|
1187
|
+
if response == wx.ID_YES:
|
1188
|
+
for file_name in names_inDEM:
|
1189
|
+
file_path = os.path.join(path, file_name)
|
1190
|
+
os.remove(file_path)
|
1191
|
+
logging.info(_("Files in DEM_FILES deleted."))
|
1192
|
+
else :
|
1193
|
+
logging.info(_("No update of DEM_FILES."))
|
1194
|
+
return
|
1195
|
+
|
1196
|
+
#Avec ajout BATHT_AFTER_SCRIPT
|
1197
|
+
if self.gpu_bathy == None:
|
1198
|
+
with wx.FileDialog(self, "Please select the bathymetry file of simulation, with all the modifications (e.g. '__bathymetry_after_scripts.tif') in .tif format.", wildcard="TIFF files (*.tif)|*.tif",
|
1199
|
+
style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as dlg:
|
1200
|
+
if dlg.ShowModal() != wx.ID_OK:
|
1201
|
+
return
|
1202
|
+
self.gpu_bathy = dlg.GetPath()
|
1203
|
+
|
1204
|
+
with wx.FileDialog(self, "Please select the DEM file in .tif format (without modifications, MNTmodifs_ will be used afterwards).", wildcard="TIFF files (*.tif)|*.tif",
|
1205
|
+
style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as dlg:
|
1206
|
+
result = dlg.ShowModal()
|
1207
|
+
if result != wx.ID_OK:
|
1208
|
+
return
|
1209
|
+
|
1210
|
+
path_DEM_base = dlg.GetPath()
|
1211
|
+
logging.info(_("DEM file selected."))
|
1212
|
+
|
1213
|
+
#DEM and masked DEM creation
|
1214
|
+
path = self._manager.IN_CH_DEM_SC
|
1215
|
+
names_inCHVUL_MNTmodifs = [f for f in os.listdir(path) if os.path.isfile(os.path.join(path, f)) and f.startswith("MNTmodifs_")]
|
1216
|
+
#path_MNT_computed is the path to the DEM with the MNTmodifs if exist, or the given true DEM if not
|
1217
|
+
path_MNT_computed = Path(path_DEM_base)
|
1218
|
+
if len(names_inCHVUL_MNTmodifs) !=0:
|
1219
|
+
path_MNT_computed = Path(self._manager.IN_CH_DEM_MNT_tif.with_suffix('.tif'))
|
1220
|
+
dialog = wx.MessageDialog(None, f"Please modify the 'MNTmodifs_' files in INPUT\CHANGE_VULNE\... as in the hydraulic scenario you want to study. They are: {names_inCHVUL_MNTmodifs}", "Confirmation", wx.YES_NO | wx.ICON_QUESTION)
|
1221
|
+
dialog.SetYesNoLabels("Done, continue", "Not done, stop")
|
1222
|
+
response = dialog.ShowModal()
|
1223
|
+
|
1224
|
+
if response == wx.ID_NO:
|
1225
|
+
logging.info(_("No modifications done in MNTmodifs_ files, process stopped."))
|
1226
|
+
return
|
1227
|
+
|
1228
|
+
if os.path.exists(self._manager.IN_CH_DEM_SC):
|
1229
|
+
existence=False
|
1230
|
+
existence, fail = self._func.create_vrtIfExists(Path(path_DEM_base), Path(self._manager.IN_CH_DEM_SC), Path(self._manager.IN_CH_DEM_MNT_VRT), name="MNTmodifs_")
|
1231
|
+
if existence:
|
1232
|
+
self._manager.translate_vrt2tif(self._manager.IN_CH_DEM_MNT_VRT, self._manager.IN_CH_DEM_MNT_tif)
|
1233
|
+
logging.info(_(f"Scenarios have been applied to DEM see {self._manager.IN_CH_DEM_MNT_tif}.tif."))
|
1234
|
+
WA_mask = WolfArray(self._manager.IN_CH_DEM_MNT_tif.with_suffix('.tif'))
|
1235
|
+
WA_mask.write_all(Path(self._manager.IN_SA_DEM / "MNT_loaded.bin"))
|
1236
|
+
|
1237
|
+
else :
|
1238
|
+
logging.info(_(f"No MNTmodifs_ files in {self._manager.IN_CH_DEM_SC}. The given file {path_DEM_base} has not been modified"))
|
1239
|
+
WA_mask = WolfArray(path_DEM_base)
|
1240
|
+
WA_mask.write_all(Path(self._manager.IN_SA_DEM / "MNT_loaded.bin"))
|
1241
|
+
else:
|
1242
|
+
logging.error(_(f"Path {self._manager.IN_CH_DEM_SC} does not exist."))
|
1243
|
+
|
1244
|
+
|
1245
|
+
#self._manager.IN_CH_DEM_MNT_tif ou fn_mnt_cropped : ground + riverbed
|
1246
|
+
fn_wherebuildings_buffer = self._manager.IN_CH_DEM_SC/ "buffer_wherebuilding.tif"
|
1247
|
+
fn_mask = self._manager.IN_SA_DEM / "MNT_computed_with_mask.tif"
|
1248
|
+
_interpol = interpolating_raster()
|
1249
|
+
_interpol.MNT_and_mask_creation_all(self.gpu_bathy, path_MNT_computed, fn_wherebuildings_buffer, fn_mask)
|
1250
|
+
if fn_wherebuildings_buffer.exists():
|
1251
|
+
fn_wherebuildings_buffer.unlink()
|
1252
|
+
if fn_mask.exists():
|
1253
|
+
fn_mask.unlink()
|
1254
|
+
dlg = wx.MessageDialog(self,
|
1255
|
+
"DEM files created in INPUT\WATER_DEPTH\...\DEM_FILES.",
|
1256
|
+
"Success.",
|
1257
|
+
wx.OK | wx.ICON_INFORMATION)
|
1258
|
+
dlg.ShowModal()
|
1259
|
+
dlg.Destroy()
|
1260
|
+
return
|
1261
|
+
|
1262
|
+
def check_and_convert_rasters(self, manager, prefix, type_file, numpy_type, nodata_value, message_supp=None):
|
1263
|
+
logging.info(_(f"Checking the scenarios for {prefix}."))
|
1264
|
+
|
1265
|
+
#tif_paths = self._manager.get_modifiedrasters(name=prefix)
|
1266
|
+
tif_paths = manager.get_modifiedrasters(name=prefix)
|
1267
|
+
good, bad, bad_paths = [], [], []
|
1268
|
+
|
1269
|
+
for f in tif_paths:
|
1270
|
+
ds = gdal.Open(f)
|
1271
|
+
if ds:
|
1272
|
+
file_type = gdal.GetDataTypeName(ds.GetRasterBand(1).DataType)
|
1273
|
+
ds = None
|
1274
|
+
if file_type == type_file:
|
1275
|
+
good.append(f.stem)
|
1276
|
+
else:
|
1277
|
+
suffix_to_add = f"_{file_type}"
|
1278
|
+
new_name = f.parent / f"{f.stem}{suffix_to_add}{f.suffix}"
|
1279
|
+
if not f.stem.endswith(suffix_to_add):
|
1280
|
+
f.rename(new_name)
|
1281
|
+
else:
|
1282
|
+
new_name = f
|
1283
|
+
bad.append(new_name.stem)
|
1284
|
+
bad_paths.append(new_name)
|
1285
|
+
|
1286
|
+
if bad:
|
1287
|
+
message_intro = (
|
1288
|
+
f"Detected {prefix} scenario files:\n"
|
1289
|
+
f"{', '.join([f.stem for f in tif_paths])}\n\n"
|
1290
|
+
f"However, wrong type in file(s): {', '.join(bad)}. "
|
1291
|
+
f"Its/Their type has been added to their name (expected {type_file}).\n\n"
|
1292
|
+
f"Do you want to try to convert them to {type_file} automatically?"
|
1293
|
+
)
|
1294
|
+
|
1295
|
+
dlg = wx.MessageDialog(None, message_intro, "Warning", wx.YES_NO | wx.ICON_WARNING)
|
1296
|
+
result = dlg.ShowModal()
|
1297
|
+
dlg.Destroy()
|
1298
|
+
|
1299
|
+
if result == wx.ID_YES:
|
1300
|
+
for path in bad_paths:
|
1301
|
+
with gdal.Open(path, gdal.GA_ReadOnly) as ds:
|
1302
|
+
band = ds.GetRasterBand(1)
|
1303
|
+
arr = band.ReadAsArray()
|
1304
|
+
nodata = band.GetNoDataValue()
|
1305
|
+
geotransform = ds.GetGeoTransform()
|
1306
|
+
projection = ds.GetProjection()
|
1307
|
+
|
1308
|
+
# SPÉCIAL POUR LE CAS int8
|
1309
|
+
if type_file == "Byte":
|
1310
|
+
mask_valid = np.ones_like(arr, dtype=bool)
|
1311
|
+
if nodata is not None:
|
1312
|
+
mask_valid = arr != nodata
|
1313
|
+
|
1314
|
+
valid_values = arr[mask_valid]
|
1315
|
+
if not np.all((valid_values >= 1) & (valid_values <= 5)):
|
1316
|
+
wx.MessageBox(
|
1317
|
+
f"Impossible to change the type to int8, there exist other type of data in the raster(s) !\n {message_supp}",
|
1318
|
+
"Error", wx.OK | wx.ICON_ERROR
|
1319
|
+
)
|
1320
|
+
return
|
1321
|
+
|
1322
|
+
arr_new = arr.astype(numpy_type)
|
1323
|
+
if nodata is not None:
|
1324
|
+
arr_new[arr == nodata] = nodata_value
|
1325
|
+
else:
|
1326
|
+
arr_new[arr_new < 1] = nodata_value #if nodata doesnt exist
|
1327
|
+
|
1328
|
+
dirname, filename = os.path.split(path)
|
1329
|
+
new_filename = filename.replace(prefix, f"{prefix}AUTO_").replace(".tif", f"_to_{type_file}.tif")
|
1330
|
+
old_filename = filename.replace(prefix, f"OLD_{prefix}")
|
1331
|
+
new_path = os.path.join(dirname, new_filename)
|
1332
|
+
old_path = os.path.join(dirname, old_filename)
|
1333
|
+
|
1334
|
+
os.rename(path, old_path)
|
1335
|
+
driver = gdal.GetDriverByName("GTiff")
|
1336
|
+
out_ds = driver.Create(new_path, arr.shape[1], arr.shape[0], 1,
|
1337
|
+
gdal.GetDataTypeByName(type_file))
|
1338
|
+
out_ds.SetGeoTransform(geotransform)
|
1339
|
+
out_ds.SetProjection(projection)
|
1340
|
+
out_band = out_ds.GetRasterBand(1)
|
1341
|
+
out_band.WriteArray(arr_new)
|
1342
|
+
out_band.SetNoDataValue(nodata_value)
|
1343
|
+
out_band.FlushCache()
|
1344
|
+
out_ds = None
|
1345
|
+
|
1346
|
+
wx.MessageBox(
|
1347
|
+
f"Files converted to {type_file}. Previous ones renamed with 'OLD_...'.",
|
1348
|
+
"Information", wx.OK | wx.ICON_INFORMATION
|
1349
|
+
)
|
1350
|
+
else:
|
1351
|
+
wx.MessageBox(
|
1352
|
+
f"Detected {prefix} scenario files:\n{', '.join([f.stem for f in tif_paths])}\n Everything is fine.",
|
1353
|
+
"Information", wx.OK | wx.ICON_INFORMATION
|
1354
|
+
)
|
1355
|
+
|
1356
|
+
def OnCheckMNTmodifs(self,e):
|
1357
|
+
"""Checks if scenarios MNTmodifs_ exist in CHANGE_VULNE and test the type (float32)"""
|
1358
|
+
self.check_and_convert_rasters(self._manager, "MNTmodifs_", "Float32", np.float32, 99999.)
|
1359
|
+
return
|
1360
|
+
|
1361
|
+
def OnInterpolation(self,e):
|
1362
|
+
"""Interpolates the last extracted time steps present in LAST_STEP_EXTRACTED using the fast marching
|
1363
|
+
interpolation routine, by creating a batch file
|
1364
|
+
while performing multiple checks on the required input files."""
|
1365
|
+
_interpol = interpolating_raster()
|
1366
|
+
|
1367
|
+
if self.file_paths is None: # Si on n’a pas chargé de simulations : on recrée la structure et ce qu'on aurait eu, mais avec tous les fichiers présents
|
1368
|
+
iftest = True
|
1369
|
+
checked_paths = []
|
1370
|
+
|
1371
|
+
else :
|
1372
|
+
checked_names = self._check_listbox.GetCheckedStrings()
|
1373
|
+
if not checked_names:
|
1374
|
+
logging.info(_("No items selected. Adding all paths."))
|
1375
|
+
checked_paths = list(self.file_paths.values())
|
1376
|
+
iftest = False
|
1377
|
+
else:
|
1378
|
+
logging.info(_("Adding only the selected simulations."))
|
1379
|
+
checked_paths = [self.file_paths[name] for name in checked_names]
|
1380
|
+
iftest = False
|
1381
|
+
|
1382
|
+
if len(self.file_paths) == 0 :
|
1383
|
+
return logging.info(_("No files in EXTRACTED_LAST_STEP_WD. Please provide some or use the 'Load gpu simulation' button."))
|
1384
|
+
|
1385
|
+
#interp_bool, renamed_files = _interpol.batch_creation_and_interpolation_fotran_holes(self._manager, checked_paths, iftest)
|
1386
|
+
interp_bool, renamed_files = _interpol.batch_creation_and_interpolation_python_eikonal(self._manager, checked_paths, iftest, True)
|
1387
|
+
|
1388
|
+
if interp_bool:
|
1389
|
+
logging.info(_("Filling completed."))
|
1390
|
+
with wx.MessageDialog(self, f"Filling completed. Created files : {renamed_files}",
|
1391
|
+
"Redirecting", wx.OK | wx.ICON_INFORMATION) as dlg:
|
1392
|
+
dlg.ShowModal()
|
1393
|
+
update_info_header(self.input_dx,self.input_nbxy,self.input_O,self._manager.IN_SA_INTERP)
|
1394
|
+
self._check_listbox_Ti.Set(self._manager.get_list_interp())
|
1395
|
+
else :
|
1396
|
+
logging.error(_("Something went wrong for the interpolation."))
|
1397
|
+
|
1398
|
+
def OnToggleAdmin(self, e):
|
1399
|
+
if self.toggle_state_Admin:
|
1400
|
+
self.toggle_state_Admin = False
|
1401
|
+
self._but_toggle_admin.SetBackgroundColour(wx.NullColour)
|
1402
|
+
#self._but_setcomp.Hide()
|
1403
|
+
#self._but_readresults.Hide()
|
1404
|
+
return
|
1405
|
+
|
1406
|
+
dlg = wx.TextEntryDialog(self, "Enter developer password:", "Authentication")
|
1407
|
+
if dlg.ShowModal() == wx.ID_OK:
|
1408
|
+
password = dlg.GetValue()
|
1409
|
+
if password == "LetMeIn#":
|
1410
|
+
self.toggle_state_Admin = True
|
1411
|
+
self._but_toggle_admin.SetBackgroundColour(wx.Colour(175, 175, 175))
|
1412
|
+
#self._but_setcomp.Show()
|
1413
|
+
#self._but_readresults.Show()
|
1414
|
+
|
1415
|
+
self.mapviewer.Refresh()
|
1416
|
+
else:
|
1417
|
+
wx.MessageBox("Wrong password.", "Error")
|
1418
|
+
self.toggle_state_Admin = False
|
1419
|
+
self._but_toggle_admin.SetBackgroundColour(wx.NullColour)
|
1420
|
+
dlg.Destroy()
|
1421
|
+
|
1422
|
+
def OnInput(self, e):
|
1423
|
+
multiple = 0
|
1424
|
+
dlg1 = wx.SingleChoiceDialog(
|
1425
|
+
self,
|
1426
|
+
message="What hazard variable do you want to read in the GPU simulations?",
|
1427
|
+
caption="Hazard Variable Choice",
|
1428
|
+
choices=["only wd", "both wd and v"]
|
1429
|
+
)
|
1430
|
+
|
1431
|
+
if dlg1.ShowModal() == wx.ID_OK:
|
1432
|
+
selection1 = dlg1.GetStringSelection()
|
1433
|
+
if selection1 == "only wd" :
|
1434
|
+
hazard_choice = "wd"
|
1435
|
+
else :
|
1436
|
+
hazard_choice = "both"
|
1437
|
+
else:
|
1438
|
+
return
|
1439
|
+
|
1440
|
+
dlg1.Destroy()
|
1441
|
+
|
1442
|
+
if hazard_choice == "both":
|
1443
|
+
multiple_str = wx.GetTextFromUser(
|
1444
|
+
message="What buffer size (as the factor of the resolution dx) do you want to use\n (to capture the maximum velocity)? Enter a number between 1 and 10:",
|
1445
|
+
caption="Buffer size",
|
1446
|
+
parent=self
|
1447
|
+
)
|
1448
|
+
try:
|
1449
|
+
multiple = int(multiple_str)
|
1450
|
+
if not (1 <= multiple <= 10):
|
1451
|
+
wx.MessageBox("Value must be between 1 and 10.", "Error", wx.ICON_ERROR)
|
1452
|
+
return
|
1453
|
+
except ValueError:
|
1454
|
+
wx.MessageBox("Invalid number.", "Error", wx.ICON_ERROR)
|
1455
|
+
return
|
1456
|
+
|
1457
|
+
dlg2 = wx.SingleChoiceDialog(
|
1458
|
+
self,
|
1459
|
+
message="What operator for wd?",
|
1460
|
+
caption="Operator Choice",
|
1461
|
+
choices=["mean", "max", "median", "percentil"]
|
1462
|
+
)
|
1463
|
+
percentil=None
|
1464
|
+
if dlg2.ShowModal() == wx.ID_OK:
|
1465
|
+
operator_choice = dlg2.GetStringSelection()
|
1466
|
+
if operator_choice == "percentil":
|
1467
|
+
dlg_percentil = wx.TextEntryDialog(
|
1468
|
+
self,
|
1469
|
+
message="Enter the desired percentile (0-100):",
|
1470
|
+
caption="Percentile Input"
|
1471
|
+
)
|
1472
|
+
if dlg_percentil.ShowModal() == wx.ID_OK:
|
1473
|
+
try:
|
1474
|
+
percentil = float(dlg_percentil.GetValue())
|
1475
|
+
if not (0 <= percentil <= 100):
|
1476
|
+
wx.MessageBox("Value must be between 0 and 100", "Invalid Input", wx.ICON_ERROR)
|
1477
|
+
return
|
1478
|
+
except ValueError:
|
1479
|
+
wx.MessageBox("Please enter a valid number", "Invalid Input", wx.ICON_ERROR)
|
1480
|
+
return
|
1481
|
+
else:
|
1482
|
+
return
|
1483
|
+
else:
|
1484
|
+
return
|
1485
|
+
|
1486
|
+
dlg2.Destroy()
|
1487
|
+
|
1488
|
+
Ti_list = [self._check_listbox_Ti.GetString(i) for i in range(self._check_listbox_Ti.GetCount()) if self._check_listbox_Ti.IsChecked(i)]
|
1489
|
+
if Ti_list ==[]:
|
1490
|
+
logging.error(_("No scenario selected in the checkbox, all the simulations are selected by default."))
|
1491
|
+
Ti_list = list(self._check_listbox_Ti.GetStrings())
|
1492
|
+
logging.info(_(f"Ti_list = {Ti_list}"))
|
1493
|
+
|
1494
|
+
logging.info(_(f"Ti_list = {Ti_list}"))
|
1495
|
+
resolution = self.input_dx.GetLabel()
|
1496
|
+
values = resolution.strip("()").split(",")
|
1497
|
+
dx = float(values[0])
|
1498
|
+
|
1499
|
+
save_where_output = self._func.pre_processing_auto(Ti_list, self._manager.main_dir, self._manager._study_area, self._manager.scenario, multiple, dx, percentil, operator_wd = operator_choice, hazard = hazard_choice)
|
1500
|
+
|
1501
|
+
if len(save_where_output) == 0 :
|
1502
|
+
with wx.MessageDialog(self,
|
1503
|
+
f"Something went wrong.",
|
1504
|
+
"Error in preprocessing",
|
1505
|
+
style=wx.OK| wx.ICON_ERROR) as dlg:
|
1506
|
+
dlg.ShowModal()
|
1507
|
+
else :
|
1508
|
+
with wx.MessageDialog(self,
|
1509
|
+
f"Input tables successfully created in {save_where_output}.",
|
1510
|
+
"Preprocessing finished.",
|
1511
|
+
style=wx.OK | wx.ICON_INFORMATION) as dlg:
|
1512
|
+
dlg.ShowModal()
|
1513
|
+
|
1514
|
+
|
1515
|
+
def OnDefault_TEMP(self, e):
|
1516
|
+
""" Impute default values to inputs and run INBE on each Ti"""
|
1517
|
+
if self._manager is None:
|
1518
|
+
return
|
1519
|
+
|
1520
|
+
Ti_list = [self._check_listbox_Ti.GetString(i) for i in range(self._check_listbox_Ti.GetCount()) if self._check_listbox_Ti.IsChecked(i)]
|
1521
|
+
if Ti_list ==[]:
|
1522
|
+
logging.error(_("No scenario selected in the checkbox, all the simulations are selected by default."))
|
1523
|
+
Ti_list = list(self._check_listbox_Ti.GetStrings())
|
1524
|
+
logging.info(_(f"Ti_list = {Ti_list}"))
|
1525
|
+
|
1526
|
+
inflation = float(self._inflation.GetValue())
|
1527
|
+
type_computation = "from_wolfsimu"
|
1528
|
+
self.df_results_Ti, save_output_TEMP, save_output_defaultINPUT = self._func.computation_dfesults_forfolder(self._manager, type_computation, Ti_list, inflation)
|
1529
|
+
|
1530
|
+
if len(save_output_defaultINPUT) == 0 :
|
1531
|
+
with wx.MessageDialog(self,
|
1532
|
+
f"Something went wrong. Nothing created.",
|
1533
|
+
"Error in the computations.",
|
1534
|
+
style=wx.OK| wx.ICON_ERROR) as dlg:
|
1535
|
+
dlg.ShowModal()
|
1536
|
+
else :
|
1537
|
+
paths_in = "\n".join(str(p) for p in save_output_defaultINPUT)
|
1538
|
+
paths_temp = "\n".join(str(p) for p in save_output_TEMP)
|
1539
|
+
|
1540
|
+
dlg = wx.MessageDialog(
|
1541
|
+
self,
|
1542
|
+
"Do you want to spread the information of damage on a raster?",
|
1543
|
+
"Damage raster",
|
1544
|
+
wx.YES_NO | wx.ICON_QUESTION
|
1545
|
+
)
|
1546
|
+
|
1547
|
+
ifraster = dlg.ShowModal()
|
1548
|
+
dlg.Destroy()
|
1549
|
+
|
1550
|
+
if ifraster == wx.ID_YES:
|
1551
|
+
self._func.raster_auto(self._manager, "individual_damage", Ti_list)
|
1552
|
+
|
1553
|
+
with wx.MessageDialog(self,
|
1554
|
+
f"Default values imputed to the input in:\n{paths_in}\n\nAnd individual damage (inflation {inflation}) computed in:\n{paths_temp}.",
|
1555
|
+
"Preprocessing finished.",
|
1556
|
+
style=wx.OK | wx.ICON_INFORMATION) as dlg:
|
1557
|
+
dlg.ShowModal()
|
1558
|
+
|
1559
|
+
def Oncombined_OUTPUT(self,e):
|
1560
|
+
"""Compute the combined damage"""
|
1561
|
+
|
1562
|
+
#Option de comment combiner, majorer damage ? To do
|
1563
|
+
|
1564
|
+
ponds = self._manager.get_ponderations()
|
1565
|
+
logging.info(_("Ponderation coeficients (computed automatically based on available set of damage files):"))
|
1566
|
+
logging.info(ponds)
|
1567
|
+
if self._manager is None:
|
1568
|
+
return
|
1569
|
+
|
1570
|
+
dlg2 = wx.SingleChoiceDialog(
|
1571
|
+
self,
|
1572
|
+
message="What kind of combinaison?",
|
1573
|
+
caption="Combinaison choice",
|
1574
|
+
choices=["Weighted sum"]#, "Squared (to code)", "..."]
|
1575
|
+
)
|
1576
|
+
|
1577
|
+
if dlg2.ShowModal() == wx.ID_OK:
|
1578
|
+
operator_choice = dlg2.GetStringSelection()
|
1579
|
+
else:
|
1580
|
+
return
|
1581
|
+
|
1582
|
+
dlg2.Destroy()
|
1583
|
+
|
1584
|
+
if operator_choice != "Weighted sum":
|
1585
|
+
with wx.MessageDialog(self,
|
1586
|
+
f"Need to be coded :)",
|
1587
|
+
"Be patient.",
|
1588
|
+
style=wx.OK| wx.ICON_ERROR) as dlg:
|
1589
|
+
dlg.ShowModal()
|
1590
|
+
return
|
1591
|
+
#if df_results_Ti == None :
|
1592
|
+
# with wx.MessageDialog(self,
|
1593
|
+
# f"Please use the previous button, or code something to read the indiv damages...",
|
1594
|
+
# "Error in the computations.",
|
1595
|
+
# style=wx.OK| wx.ICON_ERROR) as dlg:
|
1596
|
+
# dlg.ShowModal()
|
1597
|
+
# return
|
1598
|
+
|
1599
|
+
unused, output_path = self._func.computation_combined_damage(ponds, self._manager)
|
1600
|
+
|
1601
|
+
dlg = wx.MessageDialog(
|
1602
|
+
self,
|
1603
|
+
"Do you want to spread the information of combined damage on a raster?",
|
1604
|
+
"Damage raster",
|
1605
|
+
wx.YES_NO | wx.ICON_QUESTION
|
1606
|
+
)
|
1607
|
+
|
1608
|
+
ifraster = dlg.ShowModal()
|
1609
|
+
dlg.Destroy()
|
1610
|
+
|
1611
|
+
if ifraster == wx.ID_YES:
|
1612
|
+
self._func.raster_auto(self._manager, "combined")
|
1613
|
+
|
1614
|
+
|
1615
|
+
with wx.MessageDialog(self,
|
1616
|
+
f"Combined damage computed, and written in {output_path}.",
|
1617
|
+
"Computations finished.",
|
1618
|
+
style=wx.OK | wx.ICON_INFORMATION) as dlg:
|
1619
|
+
dlg.ShowModal()
|
1620
|
+
|
1621
|
+
def OnReadResults(self, e):
|
1622
|
+
sort_percentil = float(self._tri.GetValue())
|
1623
|
+
cols = ["code", "d_cleaning", "d_removal", "d_non_stru", "d_structural", "d_finishing", "d_systems", "d_total"]
|
1624
|
+
|
1625
|
+
if not self._manager.OUT_COMB.exists():
|
1626
|
+
logging.error(_(f"No file {self._manager.OUT_COMB}. Please, compute it first."))
|
1627
|
+
wx.MessageBox(_(f"No file {self._manager.OUT_COMB}. Please, compute it first.", "Missing file.", wx.ICON_ERROR))
|
1628
|
+
return
|
1629
|
+
df_results = pd.read_excel(self._manager.OUT_COMB, usecols=cols)
|
1630
|
+
|
1631
|
+
|
1632
|
+
sums = df_results.sum(numeric_only=True)
|
1633
|
+
|
1634
|
+
|
1635
|
+
#summary = '\n'.join([f"{col} : {val:,.0f} €" for col, val in sums.items()])
|
1636
|
+
summary = '\n'.join([f"{col[2:].capitalize()} : {val:,.0f} €" for col, val in sums.items()])
|
1637
|
+
with wx.MessageDialog(self,
|
1638
|
+
f"Sum of damage per categories :\n\n{summary}",
|
1639
|
+
"Quick analysis.",
|
1640
|
+
style=wx.OK | wx.ICON_INFORMATION) as dlg:
|
1641
|
+
dlg.ShowModal()
|
1642
|
+
|
1643
|
+
|
1644
|
+
dlg = wx.MessageDialog(
|
1645
|
+
self,
|
1646
|
+
"Do you want to plot the damage histogram for every residential building ?",
|
1647
|
+
"Histogram creation.",
|
1648
|
+
wx.YES_NO | wx.ICON_QUESTION
|
1649
|
+
)
|
1650
|
+
ifhisto = dlg.ShowModal()
|
1651
|
+
dlg.Destroy()
|
1652
|
+
|
1653
|
+
if ifhisto == wx.ID_YES:
|
1654
|
+
self._func.plot_damage(df_results, sorted_cond = True)
|
1655
|
+
|
1656
|
+
return
|
1657
|
+
|
1658
|
+
#def OnSetComp0(self, e):
|
1659
|
+
# """Analyze two or more scenarios with a baseline"""
|
1660
|
+
# with wx.MessageDialog(
|
1661
|
+
# self,
|
1662
|
+
# "After clicking OK, please select at least two damage scenarios (individual or combined) to compare (of a same study area).\n"
|
1663
|
+
# "The first one selected will be used as the reference.\n\n"
|
1664
|
+
# "⚠ No tests coded — the user is responsible for the comparison.\n\n"
|
1665
|
+
# "The file selection dialog will reopen until you click Cancel, press Escape, or close the window.",
|
1666
|
+
# "Instructions.",
|
1667
|
+
# style=wx.OK | wx.ICON_INFORMATION
|
1668
|
+
# ) as dlg:
|
1669
|
+
# dlg.ShowModal()
|
1670
|
+
|
1671
|
+
# paths = []
|
1672
|
+
|
1673
|
+
# if self._manager is not None and self._manager.main_dir is not None:
|
1674
|
+
# defaultDir = self._manager.main_dir
|
1675
|
+
# else:
|
1676
|
+
# defaultDir = os.getcwd()
|
1677
|
+
|
1678
|
+
# while True:
|
1679
|
+
# with wx.FileDialog(
|
1680
|
+
# self,
|
1681
|
+
# "Select a damage scenario file",
|
1682
|
+
# defaultDir=defaultDir,
|
1683
|
+
# wildcard="Excel files (*.xlsx)|*.xlsx",
|
1684
|
+
# style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST
|
1685
|
+
# ) as file_dlg:
|
1686
|
+
|
1687
|
+
# if file_dlg.ShowModal() == wx.ID_CANCEL:
|
1688
|
+
# break
|
1689
|
+
|
1690
|
+
# path = file_dlg.GetPath()
|
1691
|
+
|
1692
|
+
# if path:
|
1693
|
+
# paths.append(path)
|
1694
|
+
# defaultDir = os.path.dirname(path)
|
1695
|
+
#
|
1696
|
+
# with wx.MessageDialog(
|
1697
|
+
# self,
|
1698
|
+
# f"{paths}",
|
1699
|
+
# "Scenarios selected:",
|
1700
|
+
# style=wx.OK | wx.ICON_INFORMATION
|
1701
|
+
# ) as dlg:
|
1702
|
+
# dlg.ShowModal()
|
1703
|
+
|
1704
|
+
# self._func.histo_total_from_list(paths, float(self._tri.GetValue()))
|
1705
|
+
# return
|
1706
|
+
|
1707
|
+
def OnSetComp0(self, e):
|
1708
|
+
"""Analyze two or more scenarios with a baseline"""
|
1709
|
+
#scenarios = [self._listbox_CompScen.GetString(i) for i in self._listbox_CompScen.GetCheckedItems()]
|
1710
|
+
checked_idx = self._listbox_CompScen.GetCheckedItems()
|
1711
|
+
scenarios = [self.items[i][1] for i in checked_idx]
|
1712
|
+
study_areas = [self.items[i][0] for i in checked_idx]
|
1713
|
+
|
1714
|
+
if len(scenarios) < 2:
|
1715
|
+
wx.MessageBox("Please select at least 2 scenarios.", "Not enough scenarios to compare.", wx.ICON_ERROR)
|
1716
|
+
return
|
1717
|
+
|
1718
|
+
dlg1 = wx.SingleChoiceDialog(
|
1719
|
+
self,
|
1720
|
+
message="Which of the selected scenarios is the reference for comparison ?",
|
1721
|
+
caption="Reference scenario",
|
1722
|
+
choices=scenarios
|
1723
|
+
)
|
1724
|
+
|
1725
|
+
if dlg1.ShowModal() == wx.ID_OK:
|
1726
|
+
reference = dlg1.GetStringSelection()
|
1727
|
+
else:
|
1728
|
+
return
|
1729
|
+
dlg1.Destroy()
|
1730
|
+
|
1731
|
+
#Reference = the FIRST
|
1732
|
+
idx_ref = scenarios.index(reference)
|
1733
|
+
scenarios = [scenarios[idx_ref]] + [sc for i, sc in enumerate(scenarios) if i != idx_ref]
|
1734
|
+
study_areas = [study_areas[idx_ref]] + [sa for i, sa in enumerate(study_areas) if i != idx_ref]
|
1735
|
+
|
1736
|
+
instances = [INBE_Manager(main_dir=self.maindir, Study_area=sa, scenario=sc) for sc, sa in zip(scenarios, study_areas)] #zip life
|
1737
|
+
|
1738
|
+
dlg2 = wx.SingleChoiceDialog(
|
1739
|
+
self,
|
1740
|
+
message=f"What do you want to compare (selected reference = {reference}) ?",
|
1741
|
+
caption="Comparison choice",
|
1742
|
+
choices=["Individual damage (Ti)", "Combined damage"]
|
1743
|
+
)
|
1744
|
+
|
1745
|
+
if dlg2.ShowModal() == wx.ID_OK:
|
1746
|
+
choice = dlg2.GetStringSelection()
|
1747
|
+
else:
|
1748
|
+
return
|
1749
|
+
dlg2.Destroy()
|
1750
|
+
|
1751
|
+
if choice == "Individual damage (Ti)":
|
1752
|
+
dlg3 = wx.SingleChoiceDialog(
|
1753
|
+
self,
|
1754
|
+
message="Which return period do you want to compare ?",
|
1755
|
+
caption="Comparison Choice",
|
1756
|
+
choices=instances[0].get_list_individual_T(instances[0])
|
1757
|
+
)
|
1758
|
+
|
1759
|
+
if dlg3.ShowModal() == wx.ID_OK:
|
1760
|
+
choice_T = dlg3.GetStringSelection()
|
1761
|
+
else:
|
1762
|
+
return
|
1763
|
+
dlg3.Destroy()
|
1764
|
+
|
1765
|
+
paths = [inst.OUT_SCEN_DIR / f"individual_damage_T{choice_T}.xlsx" for inst in instances]
|
1766
|
+
else:
|
1767
|
+
choice_T = None
|
1768
|
+
paths = [inst.OUT_COMB for inst in instances]
|
1769
|
+
|
1770
|
+
self._func.histo_total_from_list(paths, float(self._tri.GetValue()))
|
1771
|
+
#si len scatter_INBE_dtotal > 2 alors deux à deux avec le bon baseline [0]
|
1772
|
+
|
1773
|
+
|
1774
|
+
for instB in instances[1:]:
|
1775
|
+
self._func.scatter_INBE_dtotal(instances[0], instB, max_val=None, Ti = choice_T, quant = float(self._tri.GetValue()))
|
1776
|
+
|