wolfhece 2.2.38__py3-none-any.whl → 2.2.40__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. wolfhece/Coordinates_operations.py +5 -0
  2. wolfhece/GraphNotebook.py +72 -1
  3. wolfhece/GraphProfile.py +1 -1
  4. wolfhece/MulticriteriAnalysis.py +1579 -0
  5. wolfhece/PandasGrid.py +62 -1
  6. wolfhece/PyCrosssections.py +194 -43
  7. wolfhece/PyDraw.py +891 -73
  8. wolfhece/PyGui.py +913 -72
  9. wolfhece/PyGuiHydrology.py +528 -74
  10. wolfhece/PyPalette.py +26 -4
  11. wolfhece/PyParams.py +33 -0
  12. wolfhece/PyPictures.py +2 -2
  13. wolfhece/PyVertex.py +25 -0
  14. wolfhece/PyVertexvectors.py +94 -28
  15. wolfhece/PyWMS.py +52 -36
  16. wolfhece/acceptability/acceptability.py +15 -8
  17. wolfhece/acceptability/acceptability_gui.py +507 -360
  18. wolfhece/acceptability/func.py +80 -183
  19. wolfhece/apps/version.py +1 -1
  20. wolfhece/compare_series.py +480 -0
  21. wolfhece/drawing_obj.py +12 -1
  22. wolfhece/hydrology/Catchment.py +228 -162
  23. wolfhece/hydrology/Internal_variables.py +43 -2
  24. wolfhece/hydrology/Models_characteristics.py +69 -67
  25. wolfhece/hydrology/Optimisation.py +893 -182
  26. wolfhece/hydrology/PyWatershed.py +267 -165
  27. wolfhece/hydrology/SubBasin.py +185 -140
  28. wolfhece/hydrology/cst_exchanges.py +76 -1
  29. wolfhece/hydrology/forcedexchanges.py +413 -49
  30. wolfhece/hydrology/read.py +65 -5
  31. wolfhece/hydrometry/kiwis.py +14 -7
  32. wolfhece/insyde_be/INBE_func.py +746 -0
  33. wolfhece/insyde_be/INBE_gui.py +1776 -0
  34. wolfhece/insyde_be/__init__.py +3 -0
  35. wolfhece/interpolating_raster.py +366 -0
  36. wolfhece/irm_alaro.py +1457 -0
  37. wolfhece/irm_qdf.py +889 -57
  38. wolfhece/lazviewer/laz_viewer.py +4 -1
  39. wolfhece/lifewatch.py +6 -3
  40. wolfhece/picc.py +124 -8
  41. wolfhece/pyLandUseFlanders.py +146 -0
  42. wolfhece/pydownloader.py +35 -1
  43. wolfhece/pywalous.py +225 -31
  44. wolfhece/toolshydrology_dll.py +149 -0
  45. wolfhece/wolf_array.py +63 -25
  46. {wolfhece-2.2.38.dist-info → wolfhece-2.2.40.dist-info}/METADATA +3 -1
  47. {wolfhece-2.2.38.dist-info → wolfhece-2.2.40.dist-info}/RECORD +50 -41
  48. {wolfhece-2.2.38.dist-info → wolfhece-2.2.40.dist-info}/WHEEL +0 -0
  49. {wolfhece-2.2.38.dist-info → wolfhece-2.2.40.dist-info}/entry_points.txt +0 -0
  50. {wolfhece-2.2.38.dist-info → wolfhece-2.2.40.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,3 @@
1
+ # from .acceptability import base_data_creation, Vulnerability, acceptability
2
+ #from .Parallels import parallel_gpd_clip, parallel_v2r
3
+ #from .func gpd_clip, data_modification, vector_to_raster, Comp_Vulnerability, match_vuln_modrec, VulMod, shp_to_raster
@@ -0,0 +1,366 @@
1
+ from pathlib import Path
2
+ import pandas as pd
3
+ import numpy as np
4
+ import math
5
+ import logging
6
+ import os
7
+ import subprocess
8
+ import shutil
9
+ import rasterio
10
+ from scipy.ndimage import label
11
+
12
+ from .PyTranslate import _
13
+ from .wolf_array import WolfArray, header_wolf
14
+ from .Results2DGPU import wolfres2DGPU
15
+ from .eikonal import inpaint_waterlevel, inpaint_array
16
+
17
+
18
+ class interpolating_raster():
19
+ def __init__(self):
20
+ pass
21
+
22
+ def nullvalue_for_hole(self, WA):
23
+ """
24
+ Sets the null value for a WolfArray to 0 (as per the convention in the interpolation routine).
25
+ """
26
+ WA.nullvalue = 0.
27
+ WA.set_nullvalue_in_mask()
28
+
29
+ def export_z_or_v_bin(self, fn_read, manager, name, type_hazard="z", type_extraction="danger_map", param_danger = [0,-1,1], threshold:float=0.01):
30
+ """
31
+ Reads the free surface altitude from a GPU simulation and exports it in binary format.
32
+
33
+ :param str fn_read_simu: The simulation file to read.
34
+ :param str fn_laststep: The folder ``EXTRACTED_LAST_STEP`` defined in acceptability/INBE.
35
+ :param list param_danger: The time step to extract the results gpu (in order :) to start / end / every X
36
+ :param str fn_write: The path to save the output in binary format.
37
+ :param str type_hazard: Either ``'z'`` for water level only, or ``'z_v'`` for water level and velocity.
38
+ """
39
+ where_wd = Path(manager.IN_SA_EXTRACTED)
40
+ fn_write = Path(where_wd / name )
41
+ if type_extraction == "last_step":
42
+ wolfres2DGPU_test = wolfres2DGPU(fn_read, eps = threshold)
43
+ wolfres2DGPU_test.read_oneresult(-1)
44
+ wd = wolfres2DGPU_test.get_h_for_block(1)
45
+ #wd.array[wd.array < threshold] = wd.nullvalue
46
+ top = wolfres2DGPU_test.get_top_for_block(1)
47
+ #i, j = np.where(wd.array < threshold)
48
+ #top.array[i, j] = top.nullvalue
49
+ self.nullvalue_for_hole(wd)
50
+ self.nullvalue_for_hole(top)
51
+ wd.array = wd.array + top.array
52
+ fn_write = fn_write.with_suffix('.bin')
53
+ wd.write_all(fn_write)
54
+ else:
55
+ if type_hazard == "z" :
56
+ danger_maps = wolfres2DGPU(fn_read, eps = threshold).danger_map_only_h(param_danger[0], param_danger[1], param_danger[2])
57
+ fn_write = fn_write.with_suffix('.bin')
58
+ danger_maps.write_all(fn_write)
59
+ if type_hazard == "z_v" :
60
+ danger_maps = wolfres2DGPU(fn_read, eps = threshold).danger_map(param_danger[0], param_danger[1], param_danger[2])
61
+ fn_write = fn_write.with_suffix('.bin')
62
+ danger_maps[3].write_all(fn_write)
63
+
64
+ where_v = manager.IN_SCEN_DIR_V
65
+ where_v = Path(where_v) / f"v_danger_{name}_{manager.scenario}.tif"
66
+ danger_maps[1].write_all(where_v)
67
+
68
+ def riverbed_trace(self, fn_read_simu, fn_output, threshold, type_extraction="danger_map"):
69
+ """
70
+ Recognizes the riverbed trace based on a simulation, where water depth above a given threshold is considered part of the riverbed.
71
+
72
+ :param str fn_read_simu: The simulation file to read.
73
+ :param str fn_output: The location to save the riverbed trace as a ``.tiff`` file.
74
+ :param float threshold: The water depth threshold above which the areas are considered riverbed.
75
+ """
76
+
77
+ if type_extraction == "last_step":
78
+ wolfres2DGPU_test = wolfres2DGPU(fn_read_simu)
79
+ wolfres2DGPU_test.read_oneresult(-1)
80
+ wd = wolfres2DGPU_test.get_h_for_block(1)
81
+ wd.array[wd.array > 1000] = 0
82
+ wd.array[wd.array > threshold] = 1
83
+ wd.array[wd.array < threshold] = 0
84
+ wd.as_WolfArray()
85
+ wd.nodata=0
86
+ wd.write_all(Path(fn_output))
87
+
88
+ else:
89
+ wd = wolfres2DGPU(fn_read_simu).danger_map_only_h(0,-1,1)
90
+ wd.array[wd.array > 1000] = 0
91
+ wd.array[wd.array > threshold] = 1
92
+ wd.array[wd.array < threshold] = 0
93
+ wd.as_WolfArray()
94
+ wd.nodata=0
95
+ wd.write_all(Path(fn_output))
96
+
97
+
98
+ def empty_folder(self, folder):
99
+ """
100
+ Empties the content of a directory if it exists.
101
+ """
102
+ if os.path.exists(folder):
103
+ for files in os.listdir(folder):
104
+ fn = os.path.join(folder, files)
105
+ try:
106
+ if os.path.isfile(fn) or os.path.islink(fn):
107
+ os.unlink(fn)
108
+ elif os.path.isdir(fn):
109
+ shutil.rmtree(fn)
110
+ except Exception as e:
111
+ print(f"Error when deleting file {fn}: {e}")
112
+ else:
113
+ print("The folder does not exist.")
114
+
115
+ """
116
+ This script performs two main operations:
117
+
118
+ 1. Subtraction of two raster TIFF files:
119
+ - Identifies areas with building traces by subtracting the `bathymetry.tif` from simulations
120
+ (corresponding to 'MNT_muret_bati') from `MNT` (DEM).
121
+
122
+ 2. For the identified building areas (from step 1):
123
+ - Replace the values with those from the `MNT` (ground level), ensuring it reflects the terrain, not bathymetry values.
124
+
125
+ Final Output:
126
+ - The mask should highlight building traces with corresponding DEM (`MNT`) values ("ground") inside, and its name must start with "MNT_" and include "mask" in it.
127
+
128
+ Note: the computations are perfomed with tifs .tif rasters but should be translated to .bin files in the acceptability routine
129
+ """
130
+
131
+ #----------------------------------------------------------------------------------------------------------
132
+
133
+ #1 - Soustraction bathymetry.tif (from simulations) - DEM (MNT, cfr "projet tuilage") ---------------------
134
+
135
+ def soustraction(self, fn_a, fn_b,fn_result):
136
+ with rasterio.open(fn_a) as src_a, rasterio.open(fn_b) as src_b:
137
+ if (
138
+ src_a.width != src_b.width or
139
+ src_a.height != src_b.height or
140
+ src_a.transform != src_b.transform or
141
+ src_a.crs != src_b.crs
142
+ ):
143
+ logging.error(f"{fn_a} and {fn_b} do not have the same properties, please edit them.")
144
+
145
+
146
+ data_a = src_a.read(1)
147
+ data_b = src_b.read(1)
148
+
149
+ #(A - B)
150
+ data_diff = data_a - data_b
151
+ nodata_value = src_a.nodata if src_a.nodata == src_b.nodata else None
152
+ if nodata_value is not None:
153
+ data_diff[(data_a == nodata_value) | (data_b == nodata_value)] = nodata_value
154
+
155
+ data_diff[data_diff < 0.5] = 0 #sans ce nettoyage supplémentaire, l'interpolation devient non significative, car de petites valeurs de différence peuvent subsister (cfr simus Vesdre sur 2m).
156
+ data_diff[data_diff > 5000] = 0
157
+ labeled, n = label(data_diff)
158
+ # Remove small objects
159
+ threshold = 5
160
+ sizes = np.bincount(labeled.ravel())
161
+ idx_small = np.where(sizes <= threshold)[0]
162
+ data_diff[np.isin(labeled, idx_small)] = 0
163
+
164
+ out_meta = src_a.meta.copy()
165
+ out_meta.update({
166
+ "dtype": "float32",
167
+ "driver": "GTiff"
168
+ })
169
+
170
+ with rasterio.open(fn_result, "w", **out_meta) as dst:
171
+ dst.write(data_diff, 1)
172
+
173
+
174
+ #2 - DEM (MNT) value in the buildings traces ------------------------------------------------------------------
175
+ def mask_creation_data(self, mask_file, ground_file, output_file):
176
+ with rasterio.open(mask_file) as mask_src:
177
+ mask = mask_src.read(1).astype('float32')
178
+ mask_meta = mask_src.meta
179
+
180
+ indices = np.where(mask > 0)
181
+
182
+ with rasterio.open(ground_file) as bathy_src:
183
+ bathy = bathy_src.read(1)
184
+
185
+ mask[indices] = bathy[indices]
186
+ mask[mask <= 0] = 99999.
187
+
188
+ output_meta = mask_meta.copy()
189
+ output_meta.update({"dtype": 'float32'})
190
+
191
+ with rasterio.open(output_file, "w", **output_meta) as dst:
192
+ dst.write(mask, 1)
193
+
194
+ WA_mask = WolfArray(output_file)
195
+ WA_mask.write_all(Path(Path(output_file).parent / "MNT_computed_with_mask.bin"))
196
+
197
+ def MNT_and_mask_creation_all(self, fn_bathy, fn_mtn_cropped, fn_where_buildings, fn_mask_final):
198
+ #couper_raster()
199
+ self.soustraction(fn_bathy, fn_mtn_cropped, fn_where_buildings)
200
+ self.mask_creation_data(fn_where_buildings, fn_mtn_cropped, fn_mask_final)
201
+
202
+ def empty_folder(self, folder):
203
+ """
204
+ Empties the content of a directory if it exists.
205
+ """
206
+ if os.path.exists(folder):
207
+ for files in os.listdir(folder):
208
+ fn = os.path.join(folder, files)
209
+ try:
210
+ if os.path.isfile(fn) or os.path.islink(fn):
211
+ os.unlink(fn)
212
+ elif os.path.isdir(fn):
213
+ shutil.rmtree(fn)
214
+ except Exception as e:
215
+ print(f"Error when deleting file {fn}: {e}")
216
+ else:
217
+ print("The folder does not exist.")
218
+
219
+
220
+ #-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
221
+ #une classe qui lit les routines holes.exe, pour un répertoire d'entrée (on y placera un répertoire de danger maps OU de simu, puis danger) et de sortie (on y placera INPUT....)
222
+ # Interpolation
223
+ # -------------
224
+
225
+ def batch_creation_and_interpolation_fotran_holes(self, manager, checked_paths:list[Path], iftest:bool) -> tuple[bool, list[str]]:
226
+ """Creates a batch file to launch holes.exe from the selected simulations and launches it.
227
+
228
+ - Every files in EXTRACTED_LAST_STEP are interpolated for tests (iftest==True).
229
+ - Only the check simulations of the windows are interpolated for the GUI (iftest!=True).
230
+
231
+ :param checked_paths: list of paths to the checked simulations
232
+ :param iftest: boolean to indicate if the function is called from the tests or not
233
+ """
234
+
235
+ path_LastSteps = Path(manager.IN_SA_EXTRACTED)
236
+
237
+ # Identifying the DEM and its mask
238
+ C = None # DEM mask
239
+ D = None # DEM
240
+ for file in os.listdir(Path(manager.IN_SA_DEM)):
241
+ file_path = Path(manager.IN_SA_DEM) / file
242
+ if file_path.is_file() and file.startswith("MNT_") and file_path.suffix == ".bin":
243
+ if "mask" not in file:
244
+ D = file_path
245
+ else:
246
+ C = file_path
247
+
248
+ if D is None:
249
+ return logging.error(_("DEM (.bin) not found in DEM_FILES. The file must begins by 'MNT_' and CANNOT include the word 'mask'"))
250
+
251
+ if C is None:
252
+ return logging.error(_("DEM mask (.bin) not found in DEM_FILES. The file must begins by 'MNT_' and MUST include the word 'mask'"))
253
+
254
+ path_Interp = Path(manager.IN_SA_INTERP)
255
+ path_bat_file = os.path.join(manager.IN_SCEN_DIR, "process_files.bat")
256
+
257
+ if os.path.exists(path_bat_file):
258
+ logging.info(f"The file {path_bat_file} already exists and will be replaced.")
259
+ os.remove(path_bat_file)
260
+
261
+ path_code = os.path.join(manager.IN_WATER_DEPTH, "holes.exe")
262
+
263
+ A, B = [], []
264
+ if iftest:
265
+ # no checked box in the tests
266
+ A = [path_LastSteps / f for f in os.listdir(path_LastSteps) if f.endswith('.bin') and not f.endswith('.bin.txt')]
267
+ else :
268
+ for path in checked_paths:
269
+ parts = path.name.split("sim_")
270
+ A.extend([path_LastSteps / g for g in os.listdir(path_LastSteps) if g.endswith(f"{parts[1]}.bin")])
271
+
272
+ B = [path_Interp / f.stem for f in A]
273
+
274
+ if not A or not B or not C or not D:
275
+ logging.error(("Missing files."))
276
+ return None, None
277
+
278
+ with open(path_bat_file, "w") as bat_file:
279
+ for a, b in zip(A, B):
280
+ line = f'"{path_code}" filling in="{a}" out="{b}" mask="{C}" dem="{D} avoid_last=1"\n'
281
+ bat_file.write(line)
282
+
283
+ self.empty_folder(manager.IN_SA_INTERP)
284
+ path_bat_file = manager.IN_SCEN_DIR / "process_files.bat"
285
+ subprocess.run([path_bat_file], check=True)
286
+
287
+ renamed_files = []
288
+ path_fichier = manager.IN_SA_INTERP
289
+ for file in path_fichier.glob("*.tif"):
290
+ if "_h" in file.name:
291
+ new_name = file.stem.split("_h")[0].replace(".bin", "") + ".tif"
292
+ file.rename(file.with_name(new_name))
293
+ renamed_files.append(new_name)
294
+
295
+ #deleting the other
296
+ for file in path_fichier.glob("*.tif"):
297
+ if "_combl" in file.name or file.name not in renamed_files:
298
+ file.unlink()
299
+
300
+ return True, renamed_files
301
+
302
+ def batch_creation_and_interpolation_python_eikonal(self, manager, checked_paths:list[Path], iftest:bool, ifwd=False) -> tuple[bool, list[str]]:
303
+ """Creates a batch file to launch holes.exe from the selected simulations and launches it.
304
+
305
+ - Every files in EXTRACTED_LAST_STEP are interpolated for tests (iftest==True).
306
+ - Only the check simulations of the windows are interpolated for the GUI (iftest!=True).
307
+
308
+ :param checked_paths: list of paths to the checked simulations
309
+ :param iftest: boolean to indicate if the function is called from the tests or not
310
+ """
311
+ path_LastSteps = Path(manager.IN_SA_EXTRACTED)
312
+ # Identifying the DEM and its mask
313
+ C = None # DEM mask
314
+ D = None # DEM
315
+ for file in os.listdir(Path(manager.IN_SA_DEM)):
316
+ file_path = Path(manager.IN_SA_DEM) / file
317
+ if file_path.is_file() and file.startswith("MNT_") and file_path.suffix == ".bin":
318
+ if "mask" not in file:
319
+ D = file_path
320
+ else:
321
+ C = file_path
322
+
323
+ if D is None:
324
+ return logging.error(_("DTM (.bin) not found in DTM_FILES. The file must begins by 'MNT_' and CANNOT include the word 'mask'"))
325
+
326
+ if C is None:
327
+ return logging.error(_("DEM mask (.bin) not found in DEM_FILES. The file must begins by 'MNT_' and MUST include the word 'mask'"))
328
+
329
+ path_Interp = Path(manager.IN_SA_INTERP)
330
+ path_bat_file = os.path.join(manager.IN_SCEN_DIR, "process_files.bat")
331
+
332
+ if os.path.exists(path_bat_file):
333
+ logging.info(f"The file {path_bat_file} already exists and will be replaced.")
334
+ os.remove(path_bat_file)
335
+
336
+ A, B = [], []
337
+ if iftest:
338
+ # no checked box in the tests
339
+ A = [path_LastSteps / f for f in os.listdir(path_LastSteps) if f.endswith('.bin') and not f.endswith('.bin.txt')]
340
+
341
+ else :
342
+ for path in checked_paths:
343
+ parts = path.name.split("sim_")
344
+ A.extend([path_LastSteps / g for g in os.listdir(path_LastSteps) if g.endswith(f"{parts[1]}.bin")])
345
+
346
+ B = [path_Interp / f.stem for f in A]
347
+ if not A or not B or not C or not D:
348
+ logging.error(_("Missing files."))
349
+ return None, None
350
+ renamed_files = []
351
+ for a, b in zip(A, B):
352
+ wa_a = WolfArray(a)
353
+ wa_c = WolfArray(C)
354
+ wa_d = WolfArray(D)
355
+ _t, _d, wh = inpaint_array(data = wa_a.array,
356
+ where_compute = wa_c.array.data != wa_c.array.data[0,0],
357
+ test = wa_d.array.data,
358
+ ignore_last_patches= 1)
359
+
360
+ new_name = b.with_suffix(".tif")
361
+ if ifwd == True :
362
+ wa_a = wa_a - wa_d
363
+ wa_a.write_all(new_name)
364
+ renamed_files.append(new_name.name)
365
+
366
+ return True, renamed_files