wolfhece 2.2.1__py3-none-any.whl → 2.2.3__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/PandasGrid.py +67 -0
- wolfhece/PyDraw.py +671 -30
- wolfhece/PyGui.py +6 -2
- wolfhece/PyHydrographs.py +2 -3
- wolfhece/PyPalette.py +10 -0
- wolfhece/PyParams.py +2 -3
- wolfhece/PyVertex.py +7 -7
- wolfhece/PyVertexvectors.py +1 -0
- wolfhece/PyWMS.py +72 -3
- wolfhece/acceptability/Parallels.py +25 -19
- wolfhece/acceptability/acceptability_gui.py +104 -131
- wolfhece/acceptability/func.py +99 -13
- wolfhece/apps/check_install.py +6 -6
- wolfhece/apps/splashscreen.py +5 -0
- wolfhece/apps/version.py +1 -1
- wolfhece/assets/__init__.py +1 -0
- wolfhece/assets/speedometer.py +135 -0
- wolfhece/dike.py +684 -0
- wolfhece/drowning_victims/Class.py +2165 -0
- wolfhece/drowning_victims/Functions.py +1019 -0
- wolfhece/drowning_victims/__init__.py +0 -0
- wolfhece/lifewatch.py +88 -0
- wolfhece/scenario/config_manager.py +4 -4
- wolfhece/wolf_array.py +58 -33
- wolfhece/wolf_texture.py +9 -2
- {wolfhece-2.2.1.dist-info → wolfhece-2.2.3.dist-info}/METADATA +3 -1
- {wolfhece-2.2.1.dist-info → wolfhece-2.2.3.dist-info}/RECORD +30 -22
- {wolfhece-2.2.1.dist-info → wolfhece-2.2.3.dist-info}/WHEEL +0 -0
- {wolfhece-2.2.1.dist-info → wolfhece-2.2.3.dist-info}/entry_points.txt +0 -0
- {wolfhece-2.2.1.dist-info → wolfhece-2.2.3.dist-info}/top_level.txt +0 -0
wolfhece/PyGui.py
CHANGED
@@ -7,14 +7,18 @@ Copyright (c) 2024 University of Liege. All rights reserved.
|
|
7
7
|
This script and its content are protected by copyright law. Unauthorized
|
8
8
|
copying or distribution of this file, via any medium, is strictly prohibited.
|
9
9
|
"""
|
10
|
+
try:
|
11
|
+
from osgeo import gdal
|
12
|
+
except ImportError as e:
|
13
|
+
print(f"Import Error: {e} - GDAL")
|
14
|
+
print("Please install GDAL for your Python version.")
|
15
|
+
|
10
16
|
try:
|
11
17
|
from os import scandir, getcwd, makedirs
|
12
18
|
from os.path import exists, join, isdir, isfile, dirname, normpath, splitext
|
13
19
|
from pathlib import Path
|
14
20
|
import numpy.ma as ma
|
15
21
|
import wx
|
16
|
-
import wx.adv
|
17
|
-
from wx.lib.busy import BusyInfo
|
18
22
|
import logging
|
19
23
|
from pathlib import Path
|
20
24
|
except ImportError as e:
|
wolfhece/PyHydrographs.py
CHANGED
@@ -55,14 +55,13 @@ class Hydrograph(pd.Series):
|
|
55
55
|
dtype=None,
|
56
56
|
name='Discharge',
|
57
57
|
copy=None,
|
58
|
-
file_path:str =''
|
59
|
-
fastpath=False) -> None:
|
58
|
+
file_path:str ='') -> None:
|
60
59
|
if file_path != '':
|
61
60
|
data =self.read_from_wolf_file(file_path)
|
62
61
|
elif isinstance(data, str):
|
63
62
|
data = self.read_from_wolf_file(data)
|
64
63
|
|
65
|
-
super().__init__(data,index,dtype, name, copy
|
64
|
+
super().__init__(data,index,dtype, name, copy)
|
66
65
|
|
67
66
|
def write_as_wolf_file(self,
|
68
67
|
file_path:str,
|
wolfhece/PyPalette.py
CHANGED
@@ -844,6 +844,16 @@ class wolfpalette(wx.Frame, LinearSegmentedColormap):
|
|
844
844
|
|
845
845
|
self.fill_segmentdata()
|
846
846
|
|
847
|
+
def defaultred_minmax(self, array: ma.masked_array, nbnotnull=99999):
|
848
|
+
"""Remplissage des valeurs de palette sur base d'une équirépartition de valeurs"""
|
849
|
+
|
850
|
+
self.nb = 2
|
851
|
+
self.values = np.asarray([np.min(array), np.max(array)], dtype=np.float64)
|
852
|
+
self.colors = np.asarray([[255, 255, 255, 255], [255, 0, 0, 255]], dtype=np.int32)
|
853
|
+
self.colorsflt = np.asarray([[0., 0., 0., 1.], [1., 1., 1., 1.]], dtype=np.float64)
|
854
|
+
|
855
|
+
self.fill_segmentdata()
|
856
|
+
|
847
857
|
def defaultblue(self):
|
848
858
|
"""Remplissage des valeurs de palette sur base d'une équirépartition de valeurs"""
|
849
859
|
|
wolfhece/PyParams.py
CHANGED
@@ -721,15 +721,14 @@ class Wolf_Param(wx.Frame):
|
|
721
721
|
#essai pour voir si le groupe existe ou non dans les params actifs
|
722
722
|
if not self.is_in_active(groupname):
|
723
723
|
page_active.Append(pg.PropertyCategory(groupname))
|
724
|
+
self.myparams[groupname] = {}
|
724
725
|
|
725
726
|
#teste si param existe
|
726
727
|
activeprop = self.prop.GetPropertyByName(groupname + paramname)
|
727
728
|
if activeprop is None:
|
728
729
|
#si non existant --> on ajoute, si existant --> rien à faire
|
729
730
|
self._insert_elem_to_page(page_active, groupname, param_def)
|
730
|
-
|
731
|
-
# #si non existant --> on ajoute, si existant --> rien à faire
|
732
|
-
# self._add_elem_to_page(page_active, groupname, param_def)
|
731
|
+
self.myparams[groupname][paramname] = param_def.copy()
|
733
732
|
|
734
733
|
else:
|
735
734
|
#recopiage de la valeur par défaut
|
wolfhece/PyVertex.py
CHANGED
@@ -630,12 +630,12 @@ class cloud_vertices(Element_To_Draw):
|
|
630
630
|
elif ';' in curhead:
|
631
631
|
# séparateur tabulation
|
632
632
|
sep = ';'
|
633
|
-
elif ' ' in curhead:
|
634
|
-
# séparateur espace
|
635
|
-
sep = ' '
|
636
633
|
elif ',' in curhead:
|
637
634
|
# séparateur espace
|
638
635
|
sep = ','
|
636
|
+
elif ' ' in curhead:
|
637
|
+
# séparateur espace
|
638
|
+
sep = ' '
|
639
639
|
headers = curhead.split(sep)
|
640
640
|
nbcols = len(headers)
|
641
641
|
else:
|
@@ -647,14 +647,14 @@ class cloud_vertices(Element_To_Draw):
|
|
647
647
|
elif ';' in curline:
|
648
648
|
# séparateur point-virgule
|
649
649
|
sep = ';'
|
650
|
-
elif ' ' in curline:
|
651
|
-
# séparateur espace
|
652
|
-
sep = ' '
|
653
|
-
curline = re.sub(' +', ' ', curline)
|
654
650
|
elif ',' in curline:
|
655
651
|
# séparateur virgule
|
656
652
|
sep = ','
|
657
653
|
curline = re.sub(' +', ' ', curline)
|
654
|
+
elif ' ' in curline:
|
655
|
+
# séparateur espace
|
656
|
+
sep = ' '
|
657
|
+
curline = re.sub(' +', ' ', curline)
|
658
658
|
|
659
659
|
curval = curline.split(sep)
|
660
660
|
nbcols = len(curval)
|
wolfhece/PyVertexvectors.py
CHANGED
wolfhece/PyWMS.py
CHANGED
@@ -16,6 +16,7 @@ import urllib.parse as ul
|
|
16
16
|
import wx
|
17
17
|
import logging
|
18
18
|
from typing import Union, Literal
|
19
|
+
from enum import Enum
|
19
20
|
|
20
21
|
from .PyTranslate import _
|
21
22
|
|
@@ -112,6 +113,7 @@ def getWalonmap(cat:Literal['IMAGERIE/ORTHO_2021', 'ALEA', 'CADMAP', 'LIDAXES',
|
|
112
113
|
return BytesIO(img.read())
|
113
114
|
except:
|
114
115
|
logging.warning(_('Impossible to get data from web services'))
|
116
|
+
pass
|
115
117
|
|
116
118
|
def getVlaanderen(cat:Literal['Adpf'],
|
117
119
|
xl:float,
|
@@ -166,6 +168,7 @@ def getVlaanderen(cat:Literal['Adpf'],
|
|
166
168
|
return BytesIO(img.read())
|
167
169
|
except:
|
168
170
|
logging.warning(_('Impossible to get data from web services'))
|
171
|
+
pass
|
169
172
|
|
170
173
|
|
171
174
|
def getIGNFrance(cat:str,epsg:str,xl,yl,xr,yr,w,h,tofile=True) -> BytesIO:
|
@@ -192,7 +195,73 @@ def getIGNFrance(cat:str,epsg:str,xl,yl,xr,yr,w,h,tofile=True) -> BytesIO:
|
|
192
195
|
else:
|
193
196
|
return BytesIO(img.read())
|
194
197
|
|
198
|
+
def getLifeWatch(cat:Literal['None'],
|
199
|
+
xl:float,
|
200
|
+
yl:float,
|
201
|
+
xr:float,
|
202
|
+
yr:float,
|
203
|
+
w:int = None,
|
204
|
+
h:int = None,
|
205
|
+
tofile=True) -> BytesIO:
|
206
|
+
|
207
|
+
wms=WebMapService(f'https://maps.elie.ucl.ac.be/cgi-bin/mapserv72?map=/maps_server/lifewatch/mapfiles/LW_Ecotopes/latest/{cat}.map&SERVICE=wms',
|
208
|
+
version='1.3.0')
|
209
|
+
|
210
|
+
ppkm = 300
|
211
|
+
if w is None and h is None:
|
212
|
+
real_w = (xr-xl)/1000
|
213
|
+
real_h = (yr-yl)/1000
|
214
|
+
w = int(real_w * ppkm)
|
215
|
+
h = int(real_h * ppkm)
|
216
|
+
elif w is None:
|
217
|
+
real_w = (xr-xl)/1000
|
218
|
+
real_h = (yr-yl)/1000
|
219
|
+
ppkm = h/real_h
|
220
|
+
w = int(real_w * ppkm)
|
221
|
+
# h = int(real_h * ppkm)
|
222
|
+
elif h is None:
|
223
|
+
real_w = (xr-xl)/1000
|
224
|
+
real_h = (yr-yl)/1000
|
225
|
+
ppkm = w/real_w
|
226
|
+
# w = int(real_w * ppkm)
|
227
|
+
h = int(real_h * ppkm)
|
228
|
+
|
229
|
+
if tofile:
|
230
|
+
img=wms.getmap(layers=['lc_hr_raster'],
|
231
|
+
# styles=['default'],
|
232
|
+
srs='EPSG:31370',
|
233
|
+
bbox=(xl,yl,xr,yr),
|
234
|
+
size=(w,h),
|
235
|
+
format='image/png',
|
236
|
+
transparent=False)
|
237
|
+
|
238
|
+
out = open('LifeWatch.png', 'wb')
|
239
|
+
out.write(img.read())
|
240
|
+
out.close()
|
241
|
+
return BytesIO(b'1')
|
242
|
+
else:
|
243
|
+
mycontents=list(wms.contents)
|
244
|
+
curcont=['lc_hr_raster'] # 'MS
|
245
|
+
curstyles=['1']
|
246
|
+
|
247
|
+
try:
|
248
|
+
img=wms.getmap(layers=curcont,
|
249
|
+
# styles=curstyles,
|
250
|
+
srs='EPSG:31370',
|
251
|
+
bbox=(xl,yl,xr,yr),
|
252
|
+
size=(w,h),
|
253
|
+
format='image/png',
|
254
|
+
transparent=False)
|
255
|
+
return BytesIO(img.read())
|
256
|
+
except:
|
257
|
+
logging.warning(_('Impossible to get data from web services'))
|
258
|
+
pass
|
259
|
+
|
195
260
|
if __name__=='__main__':
|
196
|
-
me=pyproj.CRS.from_epsg(27573)
|
197
|
-
t=pyproj.Transformer.from_crs(27573,4326)
|
198
|
-
getIGNFrance('OI.OrthoimageCoverage.HR','EPSG:27563',878000,332300,879000,333300,1000,1000)
|
261
|
+
# me=pyproj.CRS.from_epsg(27573)
|
262
|
+
# t=pyproj.Transformer.from_crs(27573,4326)
|
263
|
+
# getIGNFrance('OI.OrthoimageCoverage.HR','EPSG:27563',878000,332300,879000,333300,1000,1000)
|
264
|
+
img = getLifeWatch('',250000,160000,252000,162000,1000,1000,False)
|
265
|
+
img = Image.open(img)
|
266
|
+
img.show()
|
267
|
+
pass
|
@@ -15,14 +15,14 @@ from functools import partial
|
|
15
15
|
import os
|
16
16
|
from pathlib import Path
|
17
17
|
|
18
|
-
def parallel_gpd_clip(layer:list[str],
|
19
|
-
file_path:str,
|
20
|
-
Study_Area:str,
|
21
|
-
output_dir:str,
|
18
|
+
def parallel_gpd_clip(layer:list[str],
|
19
|
+
file_path:str,
|
20
|
+
Study_Area:str,
|
21
|
+
output_dir:str,
|
22
22
|
number_procs:int = 1):
|
23
|
-
"""
|
23
|
+
"""
|
24
24
|
Clip the layers to the study area.
|
25
|
-
|
25
|
+
|
26
26
|
Process the layers in parallel.
|
27
27
|
|
28
28
|
FIXME: The GPKG driver is it totally parallel compliant?
|
@@ -50,13 +50,15 @@ def parallel_gpd_clip(layer:list[str],
|
|
50
50
|
Study_Area=Study_Area,
|
51
51
|
output_dir=output_dir)
|
52
52
|
result_list = pool.map(prod_x, layer)
|
53
|
+
pool.close()
|
54
|
+
pool.join()
|
53
55
|
|
54
56
|
def parallel_v2r(manager:Accept_Manager,
|
55
|
-
attribute:str,
|
57
|
+
attribute:str,
|
56
58
|
pixel:float,
|
57
59
|
number_procs:int = 1,
|
58
60
|
convert_to_sparse:bool = False):
|
59
|
-
"""
|
61
|
+
"""
|
60
62
|
Convert the vector layers to raster.
|
61
63
|
|
62
64
|
Process the layers in parallel.
|
@@ -69,7 +71,7 @@ def parallel_v2r(manager:Accept_Manager,
|
|
69
71
|
:param number_procs: The number of processors to use
|
70
72
|
|
71
73
|
"""
|
72
|
-
|
74
|
+
|
73
75
|
attribute = str(attribute)
|
74
76
|
layers = manager.get_layers_in_codevulne()
|
75
77
|
|
@@ -81,18 +83,20 @@ def parallel_v2r(manager:Accept_Manager,
|
|
81
83
|
else:
|
82
84
|
pool = multiprocessing.Pool(processes=number_procs)
|
83
85
|
prod_x=partial(vector_to_raster,
|
84
|
-
manager=manager,
|
85
|
-
attribute=attribute,
|
86
|
+
manager=manager,
|
87
|
+
attribute=attribute,
|
86
88
|
pixel_size=pixel,
|
87
|
-
convert_to_sparse=convert_to_sparse)
|
88
|
-
|
89
|
+
convert_to_sparse=convert_to_sparse)
|
90
|
+
|
89
91
|
result_list = pool.map(prod_x, layers)
|
92
|
+
pool.close()
|
93
|
+
pool.join()
|
90
94
|
|
91
|
-
def parallel_datamod(manager:Accept_Manager,
|
95
|
+
def parallel_datamod(manager:Accept_Manager,
|
92
96
|
picc:gpd.GeoDataFrame,
|
93
97
|
capa:gpd.GeoDataFrame,
|
94
98
|
number_procs:int = 1):
|
95
|
-
"""
|
99
|
+
"""
|
96
100
|
Apply the data modification to the layers.
|
97
101
|
|
98
102
|
Process the layers in parallel.
|
@@ -103,7 +107,7 @@ def parallel_datamod(manager:Accept_Manager,
|
|
103
107
|
:param number_procs: The number of processors to use
|
104
108
|
|
105
109
|
"""
|
106
|
-
|
110
|
+
|
107
111
|
layers = manager.get_layers_in_clipgdb()
|
108
112
|
|
109
113
|
if number_procs == 1:
|
@@ -113,8 +117,10 @@ def parallel_datamod(manager:Accept_Manager,
|
|
113
117
|
pool = multiprocessing.Pool(processes=number_procs)
|
114
118
|
prod_x=partial(data_modification,
|
115
119
|
manager=manager,
|
116
|
-
picc=picc,
|
117
|
-
capa=capa)
|
118
|
-
|
120
|
+
picc=picc,
|
121
|
+
capa=capa)
|
122
|
+
|
119
123
|
result_list = pool.map(prod_x, layers)
|
124
|
+
pool.close()
|
125
|
+
pool.join()
|
120
126
|
|
@@ -41,7 +41,7 @@ def nullvalue_for_hole(WA):
|
|
41
41
|
WA.nullvalue = 0.
|
42
42
|
WA.set_nullvalue_in_mask()
|
43
43
|
|
44
|
-
def read_export_z_bin(fn_read, fn_write, fn_laststep):
|
44
|
+
def read_export_z_bin(fn_read, fn_write, fn_laststep, type_extraction):
|
45
45
|
"""
|
46
46
|
Reads the free surface altitude from a GPU simulation and exports it in binary format.
|
47
47
|
Inputs:
|
@@ -49,20 +49,38 @@ def read_export_z_bin(fn_read, fn_write, fn_laststep):
|
|
49
49
|
- fn_laststep: the folder EXTRACTED_LAST_STEP defined in acceptability.
|
50
50
|
- fn_write: the path to save the output in binary format.
|
51
51
|
"""
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
52
|
+
|
53
|
+
if type_extraction == "last_step":
|
54
|
+
fn_temp = os.path.join(fn_laststep, 'temp')
|
55
|
+
os.makedirs(fn_temp, exist_ok=True)
|
56
|
+
wolfres2DGPU_test = wolfres2DGPU(fn_read)
|
57
|
+
#changer ici + vérifier si bien SF ou WD (comparer ;) )
|
58
|
+
wolfres2DGPU_test.read_oneresult(-1)
|
59
|
+
wd = wolfres2DGPU_test.get_h_for_block(1)
|
60
|
+
top = wolfres2DGPU_test.get_top_for_block(1)
|
61
|
+
nullvalue_for_hole(wd)
|
62
|
+
nullvalue_for_hole(top)
|
63
|
+
wd.array = wd.array + top.array
|
64
|
+
fn_write = fn_write.with_suffix('.bin')
|
65
|
+
wd.write_all(fn_write)
|
66
|
+
shutil.rmtree(fn_temp)
|
67
|
+
|
68
|
+
if type_extraction == "danger_map":
|
69
|
+
fn_temp = os.path.join(fn_laststep, 'temp')
|
70
|
+
os.makedirs(fn_temp, exist_ok=True)
|
71
|
+
wolfres2DGPU_last = wolfres2DGPU(fn_read)
|
72
|
+
wolfres2DGPU_last.read_oneresult(-1)
|
73
|
+
danger_map_h = wolfres2DGPU(fn_read) .danger_map_only_h(0,-1,1)
|
74
|
+
top = wolfres2DGPU_last.get_top_for_block(1)
|
75
|
+
nullvalue_for_hole(danger_map_h)
|
76
|
+
nullvalue_for_hole(top)
|
77
|
+
danger_map_h.array[danger_map_h.array != 0] += top.array[danger_map_h.array != 0]
|
78
|
+
fn_write = fn_write.with_suffix('.bin')
|
79
|
+
danger_map_h.write_all(fn_write)
|
80
|
+
shutil.rmtree(fn_temp)
|
81
|
+
|
82
|
+
|
83
|
+
def riverbed_trace(fn_read_simu, fn_output, threshold, type_extraction):
|
66
84
|
"""
|
67
85
|
Recognizes the riverbed trace based on a simulation, where water depth above a given threshold is considered part of the riverbed.
|
68
86
|
Inputs:
|
@@ -70,15 +88,28 @@ def riverbed_trace(fn_read_simu, fn_output, threshold):
|
|
70
88
|
- fn_output: the location to save the riverbed trace as a .tiff file.
|
71
89
|
- threshold: the water depth threshold above which the areas are considered riverbed.
|
72
90
|
"""
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
91
|
+
|
92
|
+
|
93
|
+
if type_extraction == "last_step":
|
94
|
+
wolfres2DGPU_test = wolfres2DGPU(fn_read_simu)
|
95
|
+
wolfres2DGPU_test.read_oneresult(-1)
|
96
|
+
wd = wolfres2DGPU_test.get_h_for_block(1)
|
97
|
+
wd.array[wd.array > 1000] = 0
|
98
|
+
wd.array[wd.array > threshold] = 1
|
99
|
+
wd.array[wd.array < threshold] = 0
|
100
|
+
wd.as_WolfArray()
|
101
|
+
wd.nodata=0
|
102
|
+
wd.write_all(Path(fn_output))
|
103
|
+
|
104
|
+
if type_extraction=="danger_map":
|
105
|
+
wd = wolfres2DGPU(fn_read_simu) .danger_map_only_h(0,-1,1)
|
106
|
+
wd.array[wd.array > 1000] = 0
|
107
|
+
wd.array[wd.array > threshold] = 1
|
108
|
+
wd.array[wd.array < threshold] = 0
|
109
|
+
wd.as_WolfArray()
|
110
|
+
wd.nodata=0
|
111
|
+
wd.write_all(Path(fn_output))
|
112
|
+
|
82
113
|
|
83
114
|
def empty_folder(folder):
|
84
115
|
"""
|
@@ -158,7 +189,7 @@ def soustraction(fn_a,fn_b,fn_result):
|
|
158
189
|
#2 - DEM (MNT) value in the buildings traces ------------------------------------------------------------------
|
159
190
|
def mask_creation_data(mask_file, ground_file, output_file):
|
160
191
|
with rasterio.open(mask_file) as mask_src:
|
161
|
-
mask = mask_src.read(1)
|
192
|
+
mask = mask_src.read(1).astype('float32')
|
162
193
|
mask_meta = mask_src.meta
|
163
194
|
|
164
195
|
indices = np.where(mask > 0)
|
@@ -167,7 +198,7 @@ def mask_creation_data(mask_file, ground_file, output_file):
|
|
167
198
|
bathy = bathy_src.read(1)
|
168
199
|
|
169
200
|
mask[indices] = bathy[indices]
|
170
|
-
mask[mask <= 0] =
|
201
|
+
mask[mask <= 0] = 99999.
|
171
202
|
|
172
203
|
output_meta = mask_meta.copy()
|
173
204
|
output_meta.update({"dtype": 'float32'})
|
@@ -397,7 +428,10 @@ class AcceptabilityGui(wx.Frame):
|
|
397
428
|
def on_button_click(self, event):
|
398
429
|
self.PopupMenu(self.menu)
|
399
430
|
|
400
|
-
def
|
431
|
+
def on_button_click2(self, event2):
|
432
|
+
self.PopupMenu(self.menu2)
|
433
|
+
|
434
|
+
def onRiverbed(self, event):
|
401
435
|
"""Two options for the 'Update Riverbed' button: either the new riverbed trace
|
402
436
|
file already exists and the user selects it, or it does not exist, and the user points to
|
403
437
|
a no-overflow simulation, allowing the code to create the trace."""
|
@@ -451,11 +485,23 @@ class AcceptabilityGui(wx.Frame):
|
|
451
485
|
"Error", wx.OK | wx.ICON_ERROR
|
452
486
|
)
|
453
487
|
break
|
454
|
-
|
455
|
-
|
456
|
-
|
488
|
+
|
489
|
+
dialog = wx.SingleChoiceDialog(
|
490
|
+
parent=None,
|
491
|
+
message=f"Threshold accepted. Considering riverbed where water depth > {threshold}[m] via",
|
492
|
+
caption="Choix",
|
493
|
+
choices=["last step", "danger map"]
|
457
494
|
)
|
458
|
-
|
495
|
+
|
496
|
+
if dialog.ShowModal() == wx.ID_OK:
|
497
|
+
choix = dialog.GetStringSelection()
|
498
|
+
if choix == "last step":
|
499
|
+
type_extraction = "last step"
|
500
|
+
else:
|
501
|
+
type_extraction = "danger_map"
|
502
|
+
dialog.Destroy()
|
503
|
+
logging.info("Detecting riverbed.")
|
504
|
+
riverbed_trace(selected_folder, fn_output, threshold, type_extraction=type_extraction)
|
459
505
|
logging.info("File created.")
|
460
506
|
with wx.MessageDialog(
|
461
507
|
self,
|
@@ -545,7 +591,11 @@ class AcceptabilityGui(wx.Frame):
|
|
545
591
|
|
546
592
|
self._but_extrinterp = wx.Button(panel, label='Reading and interpolating\n free surface')
|
547
593
|
self._but_extrinterp.SetToolTip("To read the simulation, and created the hydraulic input for\n acceptability (interpolated simulated free surfaces)")
|
548
|
-
self._but_extrinterp.Bind(wx.EVT_BUTTON, self.
|
594
|
+
self._but_extrinterp.Bind(wx.EVT_BUTTON, self.on_button_click2)
|
595
|
+
self.menu2 = wx.Menu()
|
596
|
+
self.menu2.Append(1, "Interpolate the last step of the simulation.")
|
597
|
+
self.menu2.Append(2, "Interpolate the danger map of the simulation.")
|
598
|
+
self.menu2.Bind(wx.EVT_MENU, self.OnInterpolation)
|
549
599
|
sizer_hor1_1.Add(self._but_extrinterp, 1, wx.ALL | wx.EXPAND, 0)
|
550
600
|
|
551
601
|
sizer_hor1.Add(self._but_maindir, 2, wx.ALL | wx.EXPAND, 0)
|
@@ -603,7 +653,7 @@ class AcceptabilityGui(wx.Frame):
|
|
603
653
|
self.menu = wx.Menu()
|
604
654
|
self.menu.Append(1, "File of riverbed trace exists.")
|
605
655
|
self.menu.Append(2, "Point to a low discharge simulation and calculate the riverbed trace.")
|
606
|
-
self.menu.Bind(wx.EVT_MENU, self.
|
656
|
+
self.menu.Bind(wx.EVT_MENU, self.onRiverbed)
|
607
657
|
|
608
658
|
self._but_toggle_scen = wx.ToggleButton(panel, label="Accounting for scenarios")
|
609
659
|
self._but_toggle_scen.SetToolTip("To be activated to surimpose the vuln_ files, \n and so to take into account scenarios")
|
@@ -708,7 +758,7 @@ class AcceptabilityGui(wx.Frame):
|
|
708
758
|
dlg.ShowModal()
|
709
759
|
return
|
710
760
|
else :
|
711
|
-
if (self._manager._study_area
|
761
|
+
if (self._manager._study_area == None) or (self._manager._scenario == None):
|
712
762
|
logging.error(f"No study area and/or scenario selected, no check of TEMP and OUTPUT.")
|
713
763
|
with wx.MessageDialog(self, f"INPUT is well structured, but TEMP and OUTPUT have not been checked because there is no study area and scenario selected.", "Checking", wx.OK | wx.ICON_INFORMATION) as dlg:
|
714
764
|
dlg.ShowModal()
|
@@ -964,6 +1014,8 @@ class AcceptabilityGui(wx.Frame):
|
|
964
1014
|
logging.error('No hydraulic scenario selected.')
|
965
1015
|
else:
|
966
1016
|
logging.error('No folder found / selected. Please try again.')
|
1017
|
+
return
|
1018
|
+
|
967
1019
|
self._check_listbox.Clear()
|
968
1020
|
self.sims = {}
|
969
1021
|
for subdir in hydraulic_scen.iterdir():
|
@@ -1073,10 +1125,17 @@ class AcceptabilityGui(wx.Frame):
|
|
1073
1125
|
return
|
1074
1126
|
|
1075
1127
|
def OnInterpolation(self,e):
|
1076
|
-
"""Interpolates the last extracted time steps present in
|
1077
|
-
LAST_STEP_EXTRACTED using the fast marching
|
1128
|
+
"""Interpolates the last extracted time steps present in LAST_STEP_EXTRACTED using the fast marching
|
1078
1129
|
interpolation routine holes.exe, by creating a batch file
|
1079
1130
|
while performing multiple checks on the required input files."""
|
1131
|
+
menu_id = e.GetId()
|
1132
|
+
if menu_id == 1:
|
1133
|
+
type_extraction = "last_step"
|
1134
|
+
logging.info("Option 1 : last step extraction and interpolation.")
|
1135
|
+
if menu_id == 2:
|
1136
|
+
type_extraction = "danger_map"
|
1137
|
+
logging.info("Option 2 : danger map computation and interpolation.")
|
1138
|
+
|
1080
1139
|
if not hasattr(self, 'file_paths'):
|
1081
1140
|
with wx.MessageDialog(self,
|
1082
1141
|
f"Please, first load gpu simulations via the previous button.",
|
@@ -1103,7 +1162,7 @@ class AcceptabilityGui(wx.Frame):
|
|
1103
1162
|
name = parts[1]
|
1104
1163
|
fn_write = Path(path_LastSteps / name )
|
1105
1164
|
dx,dy,nbx,nby,X,Y = display_info_header(self.input_dx, self.input_nbxy, self.input_O, fn_write.with_suffix(".bin"))
|
1106
|
-
read_export_z_bin(fn_read, fn_write, path_LastSteps)
|
1165
|
+
read_export_z_bin(fn_read, fn_write, path_LastSteps, type_extraction = type_extraction)
|
1107
1166
|
else:
|
1108
1167
|
logging.info(f"Please, ensure your simulations are named with the return period, e.g sim_T4")
|
1109
1168
|
else:
|
@@ -1111,113 +1170,27 @@ class AcceptabilityGui(wx.Frame):
|
|
1111
1170
|
else:
|
1112
1171
|
logging.error('No simulation selected! Please select some in the checkbox.')
|
1113
1172
|
|
1114
|
-
C = None
|
1115
|
-
D = None
|
1116
|
-
for file in os.listdir(Path(self._manager.IN_SA_DEM)):
|
1117
|
-
file_path = Path(self._manager.IN_SA_DEM) / file
|
1118
|
-
if file_path.is_file() and file.startswith("MNT_") and file_path.suffix == ".bin":
|
1119
|
-
if "mask" not in file:
|
1120
|
-
D = file_path
|
1121
|
-
else:
|
1122
|
-
C = file_path
|
1123
|
-
if D is None:
|
1124
|
-
logging.info("DEM (.bin) not found in DEM_FILES. The file must begins by 'MNT_' and CANNOT include the word 'mask'")
|
1125
|
-
with wx.MessageDialog(self,
|
1126
|
-
f"DEM (.bin) not found in DEM_FILES. The file must begins by 'MNT_' and CANNOT include the word 'mask'",
|
1127
|
-
"Missing file",
|
1128
|
-
style=wx.OK | wx.ICON_INFORMATION) as dlg:
|
1129
|
-
dlg.ShowModal()
|
1130
|
-
return
|
1131
|
-
|
1132
|
-
if C is None:
|
1133
|
-
logging.info("DEM mask (.bin) not found in DEM_FILES. The file must begins by 'MNT_' and MUST include the word 'mask'")
|
1134
|
-
with wx.MessageDialog(self,
|
1135
|
-
f"DEM mask (.bin) not found in DEM_FILES. The file must begins by 'MNT_' and MUST include the word 'mask'",
|
1136
|
-
"Missing file",
|
1137
|
-
style=wx.OK | wx.ICON_INFORMATION) as dlg:
|
1138
|
-
dlg.ShowModal()
|
1139
|
-
return
|
1140
|
-
|
1141
|
-
if not get_header_comparison([fn_write.with_suffix(".bin"), C, D]):
|
1142
|
-
logging.info("Files in DEM_FILES do not have the same properties as the simulations files. Please, fix them.")
|
1143
|
-
with wx.MessageDialog(self,
|
1144
|
-
f"Files in DEM_FILES do not have the same properties as the simulations files. Please, fix them.",
|
1145
|
-
"Error in DEM_FILES files",
|
1146
|
-
style=wx.OK | wx.ICON_INFORMATION) as dlg:
|
1147
|
-
dlg.ShowModal()
|
1148
|
-
return
|
1149
|
-
|
1150
1173
|
checked_names = self._check_listbox.GetCheckedStrings()
|
1151
1174
|
if not checked_names:
|
1152
1175
|
logging.info("No items selected. Adding all paths.")
|
1153
1176
|
checked_paths = list(self.file_paths.values())
|
1154
|
-
message_info = "No simulations were checked in the box; so the computations will consider all of them. The interpolation of the given free surface will begin when you press OK, please wait."
|
1155
1177
|
else:
|
1156
1178
|
logging.info("Adding only the selected simulations.")
|
1157
1179
|
checked_paths = [self.file_paths[name] for name in checked_names]
|
1158
|
-
message_info = "The interpolation of the given free surface will begin (for the selected simulation(s)), please wait."
|
1159
1180
|
|
1160
1181
|
if len(self.file_paths) == 0 :
|
1161
|
-
|
1162
|
-
|
1163
|
-
|
1164
|
-
|
1165
|
-
|
1166
|
-
path_bat_file = os.path.join(self._manager.IN_SCEN_DIR, "process_files.bat")
|
1167
|
-
|
1168
|
-
if os.path.exists(path_bat_file):
|
1169
|
-
logging.info(f"The file {path_bat_file} already exists and will be replaced.")
|
1170
|
-
os.remove(path_bat_file)
|
1171
|
-
path_code = os.path.join(self._manager.IN_WATER_DEPTH, "holes.exe")
|
1172
|
-
|
1173
|
-
A=[]
|
1174
|
-
for path in checked_paths:
|
1175
|
-
parts = path.name.split("sim_")
|
1176
|
-
A.extend([os.path.join(path_LastSteps, g) for g in os.listdir(path_LastSteps) if g.endswith(f"{parts[1]}.bin")])
|
1177
|
-
B = [os.path.join(path_Interp, os.path.splitext(os.path.basename(f))[0]) for f in A]
|
1178
|
-
if not A or not B or not C or not D:
|
1179
|
-
logging.info("Missing files.")
|
1180
|
-
with wx.MessageDialog(self, f"The interpolation cannot go on, as some files are missing (see logs): please check the DEM_FILES or the EXTRACTED_LAST_STEP_WD folders.",
|
1181
|
-
"Missing files.", wx.OK | wx.ICON_INFORMATION) as dlg:
|
1182
|
-
dlg.ShowModal()
|
1183
|
-
with open(path_bat_file, "w") as bat_file:
|
1184
|
-
for a, b in zip(A, B):
|
1185
|
-
line = f'"{path_code}" filling in="{a}" out="{b}" mask="{C}" dem="{D} avoid_last=1"\n'
|
1186
|
-
bat_file.write(line)
|
1187
|
-
logging.info(message_info)
|
1188
|
-
|
1189
|
-
empty_folder(self._manager.IN_SA_INTERP)
|
1190
|
-
path_bat_file = os.path.join(self._manager.IN_SCEN_DIR, "process_files.bat")
|
1191
|
-
|
1192
|
-
if True:
|
1193
|
-
# FORTRAN HOLES.EXE
|
1194
|
-
subprocess.run([path_bat_file], check=True)
|
1195
|
-
else:
|
1196
|
-
#Python eikonal model
|
1197
|
-
from ..eikonal import inpaint_array, inpaint_waterlevel
|
1198
|
-
for a, b in zip(A, B):
|
1199
|
-
in_wa = WolfArray(a)
|
1200
|
-
mask_wa = WolfArray(C)
|
1201
|
-
dem_wa = WolfArray(D)
|
1202
|
-
inpaint_array(in_wa.array, mask_wa.array, dem_wa.array, avoid_last=1)
|
1203
|
-
in_wa.write_all(b)
|
1204
|
-
|
1205
|
-
renamed_files = []
|
1206
|
-
path_fichier=self._manager.IN_SA_INTERP
|
1207
|
-
for file in path_fichier.glob("*.tif"):
|
1208
|
-
if "_h" in file.name:
|
1209
|
-
new_name = file.stem.split("_h")[0].replace(".bin", "") + ".tif"
|
1210
|
-
file.rename(file.with_name(new_name))
|
1211
|
-
renamed_files.append(new_name)
|
1212
|
-
#deleting the other
|
1213
|
-
for file in path_fichier.glob("*.tif"):
|
1214
|
-
if "_combl" in file.name or file.name not in renamed_files:
|
1215
|
-
file.unlink()
|
1182
|
+
return logging.info("No files in EXTRACTED_LAST_STEP_WD. Please provide some or use the 'Load gpu simulation' button.")
|
1183
|
+
|
1184
|
+
interp_bool, renamed_files = self._manager.batch_creation_and_interpolation(checked_paths,None)
|
1185
|
+
|
1186
|
+
if interp_bool == True:
|
1216
1187
|
logging.info("Filling completed.")
|
1217
1188
|
with wx.MessageDialog(self, f"Filling completed. Created files : {renamed_files}",
|
1218
1189
|
"Redirecting", wx.OK | wx.ICON_INFORMATION) as dlg:
|
1219
1190
|
dlg.ShowModal()
|
1220
|
-
|
1191
|
+
update_info_header(self.input_dx,self.input_nbxy,self.input_O,self._manager.IN_SA_INTERP)
|
1192
|
+
else :
|
1193
|
+
logging.error("Something went wrong for the interpolation.")
|
1221
1194
|
|
1222
1195
|
def OnToggle(self,e):
|
1223
1196
|
"""Creates a toggle button to be activated if the scenarios vuln_ have to be taken into account."""
|