wolfhece 2.1.128__py3-none-any.whl → 2.2.1__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 (44) hide show
  1. wolfhece/PyDraw.py +109 -46
  2. wolfhece/PyGui.py +3 -0
  3. wolfhece/PyGuiHydrology.py +24 -24
  4. wolfhece/PyPalette.py +27 -11
  5. wolfhece/PyParams.py +5 -1
  6. wolfhece/PyVertexvectors.py +52 -7
  7. wolfhece/Results2DGPU.py +17 -0
  8. wolfhece/acceptability/acceptability_gui.py +29 -18
  9. wolfhece/acceptability/func.py +23 -21
  10. wolfhece/apps/version.py +2 -2
  11. wolfhece/eikonal.py +1 -1
  12. wolfhece/hydrology/Catchment.py +113 -12
  13. wolfhece/hydrology/Comparison.py +54 -52
  14. wolfhece/hydrology/Optimisation.py +309 -178
  15. wolfhece/hydrology/PostProcessHydrology.py +6 -3
  16. wolfhece/hydrology/RetentionBasin.py +21 -14
  17. wolfhece/hydrology/SubBasin.py +128 -12
  18. wolfhece/hydrology/constant.py +3 -0
  19. wolfhece/hydrology/cst_exchanges.py +364 -38
  20. wolfhece/hydrology/plot_hydrology.py +34 -18
  21. wolfhece/hydrology/read.py +16 -6
  22. wolfhece/lagrangian/particle_system_ui.py +1 -1
  23. wolfhece/lagrangian/particles.py +1 -1
  24. wolfhece/lazviewer/processing/estimate_normals/estimate_normals.cp310-win_amd64.pyd +0 -0
  25. wolfhece/lazviewer/vfuncsdir/vfuncs.cp310-win_amd64.pyd +0 -0
  26. wolfhece/lazviewer/viewer/viewer.exe +0 -0
  27. wolfhece/lazviewer/viewer/viewer_np1_23_5.exe +0 -0
  28. wolfhece/libs/WolfDll.dll +0 -0
  29. wolfhece/libs/Wolf_tools.dll +0 -0
  30. wolfhece/libs/get_infos.cp310-win_amd64.pyd +0 -0
  31. wolfhece/libs/verify_wolf.cp310-win_amd64.pyd +0 -0
  32. wolfhece/libs/wolfogl.cp310-win_amd64.pyd +0 -0
  33. wolfhece/radar/wolfradar.py +75 -22
  34. wolfhece/shapes/__init__.py +0 -0
  35. wolfhece/shapes/circle.py +335 -0
  36. wolfhece/tools2d_dll.py +359 -0
  37. wolfhece/wolf_array.py +3 -2
  38. wolfhece/wolfresults_2D.py +162 -33
  39. {wolfhece-2.1.128.dist-info → wolfhece-2.2.1.dist-info}/METADATA +15 -9
  40. {wolfhece-2.1.128.dist-info → wolfhece-2.2.1.dist-info}/RECORD +43 -39
  41. wolfhece/libs/wolfpy.cp310-win_amd64.pyd +0 -0
  42. {wolfhece-2.1.128.dist-info → wolfhece-2.2.1.dist-info}/WHEEL +0 -0
  43. {wolfhece-2.1.128.dist-info → wolfhece-2.2.1.dist-info}/entry_points.txt +0 -0
  44. {wolfhece-2.1.128.dist-info → wolfhece-2.2.1.dist-info}/top_level.txt +0 -0
@@ -7,34 +7,32 @@ Copyright (c) 2025 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
- from .acceptability import Base_data_creation, Database_to_raster, Vulnerability, Acceptability
11
- from .acceptability import steps_base_data_creation, steps_vulnerability, steps_acceptability
12
- from .func import Accept_Manager
13
- from ..wolf_array import WolfArray, header_wolf
14
- from ..scenario.config_manager import Config_Manager_2D_GPU
15
- from ..PyDraw import WolfMapViewer, draw_type
16
- from ..Results2DGPU import wolfres2DGPU
17
- from ..PyGui import MapManager
18
-
19
10
  import wx
20
- import wx.lib.dialogs
11
+ import numpy as np
21
12
  import logging
22
13
  import subprocess
23
- import matplotlib
24
14
  import shutil
25
15
  import os
26
16
  import geopandas as gpd
17
+ import pandas as pd
27
18
  import matplotlib.pyplot as plt
28
19
  from matplotlib.figure import Figure
29
20
  from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
30
21
  from matplotlib.backends.backend_wxagg import NavigationToolbar2WxAgg as NavigationToolbar2Wx
31
22
  from pathlib import Path
32
23
  from scipy.ndimage import label
33
- import pandas as pd
34
24
  from gettext import gettext as _
35
25
  import rasterio
36
26
  from shapely.geometry import Polygon
37
- import numpy as np
27
+
28
+ from .acceptability import Base_data_creation, Database_to_raster, Vulnerability, Acceptability
29
+ from .acceptability import steps_base_data_creation, steps_vulnerability, steps_acceptability
30
+ from .func import Accept_Manager
31
+ from ..wolf_array import WolfArray, header_wolf
32
+ from ..scenario.config_manager import Config_Manager_2D_GPU
33
+ from ..PyDraw import WolfMapViewer, draw_type
34
+ from ..Results2DGPU import wolfres2DGPU
35
+ from ..PyGui import MapManager
38
36
 
39
37
  def nullvalue_for_hole(WA):
40
38
  """
@@ -710,7 +708,7 @@ class AcceptabilityGui(wx.Frame):
710
708
  dlg.ShowModal()
711
709
  return
712
710
  else :
713
- if (self._manager._study_area == None) or (self._manager._scenario == None):
711
+ if (self._manager._study_area is None) or (self._manager._scenario is None):
714
712
  logging.error(f"No study area and/or scenario selected, no check of TEMP and OUTPUT.")
715
713
  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:
716
714
  dlg.ShowModal()
@@ -1075,7 +1073,8 @@ class AcceptabilityGui(wx.Frame):
1075
1073
  return
1076
1074
 
1077
1075
  def OnInterpolation(self,e):
1078
- """Interpolates the last extracted time steps present in LAST_STEP_EXTRACTED using the fast marching
1076
+ """Interpolates the last extracted time steps present in
1077
+ LAST_STEP_EXTRACTED using the fast marching
1079
1078
  interpolation routine holes.exe, by creating a batch file
1080
1079
  while performing multiple checks on the required input files."""
1081
1080
  if not hasattr(self, 'file_paths'):
@@ -1121,7 +1120,7 @@ class AcceptabilityGui(wx.Frame):
1121
1120
  D = file_path
1122
1121
  else:
1123
1122
  C = file_path
1124
- if D == None:
1123
+ if D is None:
1125
1124
  logging.info("DEM (.bin) not found in DEM_FILES. The file must begins by 'MNT_' and CANNOT include the word 'mask'")
1126
1125
  with wx.MessageDialog(self,
1127
1126
  f"DEM (.bin) not found in DEM_FILES. The file must begins by 'MNT_' and CANNOT include the word 'mask'",
@@ -1130,7 +1129,7 @@ class AcceptabilityGui(wx.Frame):
1130
1129
  dlg.ShowModal()
1131
1130
  return
1132
1131
 
1133
- if C == None:
1132
+ if C is None:
1134
1133
  logging.info("DEM mask (.bin) not found in DEM_FILES. The file must begins by 'MNT_' and MUST include the word 'mask'")
1135
1134
  with wx.MessageDialog(self,
1136
1135
  f"DEM mask (.bin) not found in DEM_FILES. The file must begins by 'MNT_' and MUST include the word 'mask'",
@@ -1189,7 +1188,19 @@ class AcceptabilityGui(wx.Frame):
1189
1188
 
1190
1189
  empty_folder(self._manager.IN_SA_INTERP)
1191
1190
  path_bat_file = os.path.join(self._manager.IN_SCEN_DIR, "process_files.bat")
1192
- subprocess.run([path_bat_file], check=True)
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)
1193
1204
 
1194
1205
  renamed_files = []
1195
1206
  path_fichier=self._manager.IN_SA_INTERP
@@ -287,14 +287,14 @@ class Accept_Manager():
287
287
 
288
288
  self.scenario:str = str(self._scenario)
289
289
 
290
-
290
+
291
291
  self.IN_SA_BASE = self.IN_WATER_DEPTH / self.SA.stem / "Scenario_baseline"
292
292
  self.IN_SA_BASE_INTERP = self.IN_SA_BASE / "INTERP_WD"
293
-
293
+
294
294
  self.IN_SCEN_DIR = self.IN_WATER_DEPTH / self.SA.stem / self.scenario
295
295
  self.IN_SA_INTERP = self.IN_SCEN_DIR / "INTERP_WD"
296
296
  self.IN_SA_EXTRACTED = self.IN_SCEN_DIR / "EXTRACTED_LAST_STEP_WD"
297
- self.IN_SA_DEM = self.IN_SCEN_DIR / "DEM_FILES"
297
+ self.IN_SA_DEM = self.IN_SCEN_DIR / "DEM_FILES"
298
298
  self.IN_CH_SA_SC = self.IN_CH_VULN /self.SA.stem / self.scenario
299
299
  self.IN_CH_SA_SC_MNT_VRT = self.IN_CH_SA_SC / "__MNT_assembly.vrt"
300
300
  self.IN_CH_SA_SC_MNT_tif = self.IN_CH_SA_SC / "MNTassembly"
@@ -312,19 +312,19 @@ class Accept_Manager():
312
312
 
313
313
  self.OUT_WITHVULN = self.OUT_SCEN_DIR / "vuln_ scenarios"
314
314
  self.OUT_VULN_VRT = self.OUT_WITHVULN / "__vuln_assembly.vrt"
315
- self.OUT_VULN_S = self.OUT_WITHVULN / "Vulnerability_scenarios"
315
+ self.OUT_VULN_S = self.OUT_WITHVULN / "Vulnerability_scenarios"
316
316
  self.OUT_VULN_Stif = self.OUT_WITHVULN / "Vulnerability_scenarios.tif"
317
317
  self.OUT_MASKED_RIVER_S = self.OUT_WITHVULN / "Masked_River_extent_scenarios.tiff"
318
318
  self.OUT_ACCEPT_Stif = self.OUT_WITHVULN / "Acceptability_scenarios.tiff"
319
319
  self.OUT_ACCEPT_RESAMP_Stif = self.OUT_WITHVULN / "Acceptability_scenarios_resampled.tiff"
320
-
320
+
321
321
  self.OUT_BASELINE = self.OUT_SCEN_DIR / "baseline"
322
322
  self.OUT_VULN = self.OUT_BASELINE / "Vulnerability_baseline.tiff"
323
323
  self.OUT_CODE = self.OUT_BASELINE / "Vulnerability_Code_baseline.tiff"
324
324
  self.OUT_MASKED_RIVER = self.OUT_BASELINE / "Masked_River_extent_baseline.tiff"
325
325
  self.OUT_ACCEPT = self.OUT_BASELINE / "Acceptability_baseline.tiff"
326
326
  self.OUT_ACCEPT_RESAMP = self.OUT_BASELINE / "Acceptability_baseline_resampled.tiff"
327
-
327
+
328
328
  else:
329
329
  self.scenario = None
330
330
 
@@ -472,7 +472,7 @@ class Accept_Manager():
472
472
  sims = self.get_sims_files_for_scenario()
473
473
 
474
474
  if len(sims)==0:
475
- logging.info("No simulations found at this stage")
475
+ logging.info("No simulations found at this stage")
476
476
  return None
477
477
 
478
478
  if "_h.tif" in sims[0].name:
@@ -561,7 +561,7 @@ class Accept_Manager():
561
561
  os.path.join(os.path.dirname(path), os.path.basename(path).replace("Q", "T"))
562
562
  for path in sims
563
563
  ]
564
-
564
+
565
565
  if len(sims)==0:
566
566
  logging.info("No simulations found at this stage.")
567
567
  return []
@@ -570,22 +570,22 @@ class Accept_Manager():
570
570
  # searching for the position of the return period in the name
571
571
  idx_T = [Path(cursim).name.find("T") for cursim in sims_modif]
572
572
  idx_h = [Path(cursim).name.find(".tif") for cursim in sims_modif]
573
-
573
+
574
574
  # create the list of return periods -- only the numeric part
575
575
  sims = [int(Path(cursim).name[idx_T[i]+1:idx_h[i]]) for i, cursim in enumerate(sims_modif)]
576
576
  return sorted(sims)
577
-
577
+
578
578
  def get_modifiedrasters(self):
579
579
  folder = Path(self.IN_CH_SA_SC)
580
580
  vuln_tiff_files = [str(file.name) for file in folder.rglob("*.tiff") if file.name.startswith('vuln_')]
581
581
  vuln_tif_files = [str(file.name)for file in folder.rglob("*.tif") if file.name.startswith('vuln_')]
582
- vuln_files = vuln_tiff_files + vuln_tif_files
582
+ vuln_files = vuln_tiff_files + vuln_tif_files
583
583
 
584
584
  folder = Path(self.IN_CH_SA_SC)
585
585
  mnt_tiff_files = [str(file.name) for file in folder.rglob("*.tiff") if file.name.startswith('MNTmodifs_')]
586
586
  mnt_tif_files = [str(file.name) for file in folder.rglob("*.tif") if file.name.startswith('MNTmodifs_')]
587
587
  mnt_files = mnt_tiff_files + mnt_tif_files
588
-
588
+
589
589
  return vuln_files + mnt_files
590
590
 
591
591
  def get_ponderations(self) -> pd.DataFrame:
@@ -732,7 +732,7 @@ class Accept_Manager():
732
732
  self.OUT_SCEN_DIR.mkdir(parents=True, exist_ok=True)
733
733
  self.OUT_WITHVULN.mkdir(parents=True, exist_ok=True)
734
734
  self.OUT_BASELINE.mkdir(parents=True, exist_ok=True)
735
-
735
+
736
736
 
737
737
  return True
738
738
 
@@ -898,15 +898,15 @@ class Accept_Manager():
898
898
 
899
899
  if len(code) == 0:
900
900
  logging.error("The code rasters do not exist")
901
- return False
901
+ return ["The code rasters do not exist"]
902
902
 
903
903
  if len(vuln) == 0:
904
904
  logging.error("The vulnerability rasters do not exist")
905
- return False
905
+ return ["The vulnerability rasters do not exist"]
906
906
 
907
907
  if len(code) != len(vuln):
908
908
  logging.error("The number of code and vulnerability rasters do not match")
909
- return False
909
+ return ["The number of code and vulnerability rasters do not match"]
910
910
 
911
911
  # we take a reference raster
912
912
  ref = gdal.Open(str(code[0]))
@@ -1026,7 +1026,7 @@ class Accept_Manager():
1026
1026
  dataset = None
1027
1027
 
1028
1028
  logging.info("All the existing .tif files have been copied to the destination directory.")
1029
-
1029
+
1030
1030
  def wich_river_trace(self):
1031
1031
  """ Searches for existing riverbed traces: if none ending with '_scenarios' are found, it selects the baseline trace."""
1032
1032
  trace = None
@@ -1037,8 +1037,8 @@ class Accept_Manager():
1037
1037
  else :
1038
1038
  logging.error("No Masked_River_extent files. Please provide them.")
1039
1039
  return trace
1040
-
1041
-
1040
+
1041
+
1042
1042
 
1043
1043
 
1044
1044
  def clip_layer(layer:str,
@@ -1503,7 +1503,7 @@ def match_vulnerability2sim(inRas:Path, outRas:Path, MODREC:Path):
1503
1503
  :param MODREC: the MODREC/simulation extent file
1504
1504
 
1505
1505
  """
1506
-
1506
+
1507
1507
  inRas = str(inRas)
1508
1508
  outRas = str(outRas)
1509
1509
  MODREC = str(MODREC)
@@ -1524,7 +1524,7 @@ def update_accept(accept, model_h, ij, bounds, loc_accept):
1524
1524
  for idx in range(len(bounds)):
1525
1525
  for i,j in ij:
1526
1526
  #lit dans wd vs Ti où on est et associe son score d'accept
1527
- if bounds[idx,0] < model_h[i,j] <= bounds[idx,1]:
1527
+ if bounds[idx,0] < model_h[i,j] <= bounds[idx,1]:
1528
1528
  accept[i,j] = loc_accept[idx]
1529
1529
 
1530
1530
  def compute_acceptability(manager:Accept_Manager,
@@ -1666,6 +1666,8 @@ def shp_to_raster(vector_fn:str | Path, raster_fn:str | Path, pixel_size:float =
1666
1666
  layer = source_layer,
1667
1667
  burn_values = [1],
1668
1668
  options=["ALL_TOUCHED=TRUE"])
1669
+
1670
+ target_ds.FlushCache()
1669
1671
  target_ds = None
1670
1672
  vector_fn = raster_fn = None
1671
1673
 
wolfhece/apps/version.py CHANGED
@@ -4,8 +4,8 @@ class WolfVersion():
4
4
  def __init__(self):
5
5
 
6
6
  self.major = 2
7
- self.minor = 1
8
- self.patch = 128
7
+ self.minor = 2
8
+ self.patch = 1
9
9
 
10
10
  def __str__(self):
11
11
 
wolfhece/eikonal.py CHANGED
@@ -78,7 +78,7 @@ def __solve_eikonal_with_data(sources:list[list[int,int]],
78
78
  # store the fixed points
79
79
  # - fix sources points
80
80
  # - fix every first element of the heap after pop
81
- fixed = np.zeros(speed.shape, dtype = np.bool8)
81
+ fixed = np.zeros(speed.shape, dtype = np.uint8)
82
82
 
83
83
  # fix the border
84
84
  fixed[:, 0] = True
@@ -33,8 +33,8 @@ else:
33
33
  print(_('Note: do not forget to install the graphviz app and add it to the PATH to make it work'))
34
34
  # --------------------------------
35
35
 
36
- from ..wolf_texture import genericImagetexture
37
- from ..PyDraw import WolfMapViewer
36
+ # from ..wolf_texture import genericImagetexture
37
+ # from ..PyDraw import WolfMapViewer
38
38
  from .SubBasin import *
39
39
  from .RetentionBasin import *
40
40
  from .read import *
@@ -67,7 +67,8 @@ class Catchment:
67
67
  iP_Cloud:cloud_vertices # cloud of points containing the given coordinates (given in param files) of all subbasin outlets
68
68
 
69
69
  catchmentDict:dict[Union[str, int], Union[SubBasin, RetentionBasin]] # dictionnary containing all the elements of the catchment
70
- subBasinDict:dict[int, SubBasin] # dictionnary containing all the subbasins
70
+ subBasinDict:dict[int, SubBasin] # dictionnary containing all the subbasins with the convention dict{ID Interior Point : SubBasin object}
71
+ retentionBasinDict:dict[str, RetentionBasin] # dictionnary containing all the anthropogenic modules
71
72
 
72
73
  def __init__(self, _name, _workingDir, _plotAllSub, _plotNothing, _initWithResults=True, _catchmentFileName="", _rbFileName="", _tz=0, version=cst.VERSION_WOLFHYDRO):
73
74
  "This is the constructor of the class Catchment in which all the caractertics and the network of sub-basins will be created"
@@ -1390,6 +1391,75 @@ class Catchment:
1390
1391
  writer.close()
1391
1392
 
1392
1393
 
1394
+
1395
+ def save_hydro_for_2D(self, fileName:str="Hydros_2_simul2D.txt", directory:str="", format:str='%1.5e'):
1396
+ """
1397
+ Procedure that saves the data in an text file that can be read and used in a 2D model.
1398
+
1399
+ Args:
1400
+ fileName (str, optional): The name of the file to save the data to. Defaults to "Hydros_2_simul2D.txt".
1401
+ directory (str, optional): The directory to save the file in. Defaults to an empty string.
1402
+
1403
+ Returns:
1404
+ None
1405
+ """
1406
+ # Writes subbasins' hydrographs
1407
+ if(directory==""):
1408
+ directory = join(self.workingDir,"PostProcess")
1409
+
1410
+ cur_file = join(directory,fileName)
1411
+ time = np.reshape(self.time - self.time[0],(len(self.time),1))
1412
+ # Extract the data for the hydrological and anthropogenic modules
1413
+ data_subs = [cur_sub.outFlow for cur_sub in sorted(self.subBasinDict.values(), key=lambda sub: sub.iDSorted)]
1414
+ data_anth = [cur_anth.get_outFlow(whichOutFlow=name) for cur_anth in self.retentionBasinDict.values() for name in cur_anth.get_outFlow_names()]
1415
+ # Extract the column names according to their sorted subbasin indices
1416
+ col_time = ["Time [s]"]
1417
+ col_subs = [cur_sub.name for cur_sub in sorted(self.subBasinDict.values(), key=lambda sub: sub.iDSorted)]
1418
+ col_anth = [" : ".join([cur_anth.name, name])
1419
+ for cur_anth in self.retentionBasinDict.values()
1420
+ for name in cur_anth.get_outFlow_names()]
1421
+
1422
+
1423
+ all_data = np.concatenate((time, np.array(data_subs).T, np.array(data_anth).T), axis=1)
1424
+ all_columns = "\t".join(col_time+col_subs+col_anth)
1425
+
1426
+ # Save the data in a text file
1427
+ np.savetxt(cur_file, all_data, delimiter='\t', newline="\n", header=all_columns, fmt=format)
1428
+
1429
+
1430
+ def save_own_hydro_for_2D(self, fileName:str="HydrosSub_2_simul2D.txt", directory:str="", format:str='%1.5e'):
1431
+ """
1432
+ Saves subbasins' hydrographs from their own drained surface only (not taking into account the
1433
+ surface drained by the inlets or upstream elements) to a text file that can be read and used in a 2D model.
1434
+
1435
+ Args:
1436
+ fileName (str, optional): Name of the output file. Defaults to "HydrosSub_2_simul2D.txt".
1437
+ directory (str, optional): Directory where the file will be saved. Defaults to an empty string.
1438
+ format (str, optional): Format string for the data values. Defaults to '%1.5e'.
1439
+
1440
+ Returns:
1441
+ None
1442
+ """
1443
+ # Writes subbasins' hydrographs
1444
+ if(directory==""):
1445
+ directory = join(self.workingDir,"PostProcess")
1446
+
1447
+ cur_file = join(directory,fileName)
1448
+ time = np.reshape(self.time - self.time[0],(len(self.time),1))
1449
+ # Extract the data for the hydrological and anthropogenic modules
1450
+ data_subs = [cur_sub.get_myHydro(unit="m3/s") for cur_sub in sorted(self.subBasinDict.values(), key=lambda sub: sub.iDSorted)]
1451
+ # Extract the column names according to their sorted subbasin indices
1452
+ col_time = ["Time [s]"]
1453
+ col_subs = [cur_sub.name for cur_sub in sorted(self.subBasinDict.values(), key=lambda sub: sub.iDSorted)]
1454
+
1455
+
1456
+ all_data = np.concatenate((time, np.array(data_subs).T), axis=1)
1457
+ all_columns = "\t".join(col_time+col_subs)
1458
+
1459
+ # Save the data in a text file
1460
+ np.savetxt(cur_file, all_data, delimiter='\t', newline="\n", header=all_columns, fmt=format)
1461
+
1462
+
1393
1463
  def save_characteristics(self):
1394
1464
  "Procedure that saves the data in an Excel file."
1395
1465
  # Writes subbasins' main characteristics
@@ -1857,8 +1927,8 @@ class Catchment:
1857
1927
  # paramsInput.ApplytoMemory(None)
1858
1928
  paramsInput.SavetoFile(None)
1859
1929
 
1860
-
1861
- def _correct_Umax_from_old_model(self, adapt_with_rain:bool=True):
1930
+
1931
+ def _correct_Umax_from_old_model(self, adapt_with_rain:bool=True, k_opt:float=0.0, U_max_opt=0.0):
1862
1932
  fileName = "simul_soil.param"
1863
1933
  which="Umax"
1864
1934
 
@@ -1870,8 +1940,10 @@ class Catchment:
1870
1940
 
1871
1941
  paramsInput = Wolf_Param(to_read=False,toShow=False)
1872
1942
  paramsInput.ReadFile(fileToModif)
1873
-
1874
- if adapt_with_rain:
1943
+
1944
+ if U_max_opt>0.0:
1945
+ maxRain = U_max_opt
1946
+ elif adapt_with_rain:
1875
1947
  myInterval = paramsInput.get_param("Distributed production model parameters", "Time span soil", default_value=0.0)
1876
1948
  if myInterval==0.0:
1877
1949
  nbIntervals = len(myBasin.myRain)-1
@@ -1885,10 +1957,13 @@ class Catchment:
1885
1957
  if maxRain==0.0:
1886
1958
  logging.warning("The Umax is not adapted with the rain and its value is 0.0. It might be better to put 'adapt_with_rain' to True.")
1887
1959
 
1888
- k = paramsInput.get_param("Horton parameters", "k", default_value=0.0)
1889
- if k==0.0:
1890
- continue
1891
-
1960
+ if k_opt==0.0:
1961
+ k = paramsInput.get_param("Horton parameters", "k", default_value=0.0)
1962
+ if k==0.0:
1963
+ continue
1964
+ else:
1965
+ k = k_opt
1966
+
1892
1967
  U_max = maxRain/k
1893
1968
 
1894
1969
  paramsInput.change_param("Distributed production model parameters", which, U_max)
@@ -1899,7 +1974,7 @@ class Catchment:
1899
1974
 
1900
1975
 
1901
1976
 
1902
- def plot_all_diff_cumulRain_with_lagtime(self, interval, lagTime, selection_by_iD=[], graph_title="", show=True, writeDir="", lawNetRain=0, netRainParams={}):
1977
+ def plot_all_diff_cumulRain_with_lagtime(self, interval=0, lagTime=0, selection_by_iD=[], graph_title="", show=True, writeDir="", lawNetRain=0, netRainParams={}):
1903
1978
  """
1904
1979
 
1905
1980
  """
@@ -2835,6 +2910,32 @@ class Catchment:
2835
2910
  self._set_temporal_parameters(value)
2836
2911
 
2837
2912
 
2913
+ def _set_IC_qif(self, keys:list[str], values:np.ndarray):
2914
+ assert len(keys) == len(values), "The number of keys should be equal to the number of values !"
2915
+ # assert len(keys) == len(self.subBasinDict), "The number of keys should be equal to the number of sub-basins !"
2916
+ # assert len(values) == len(self.subBasinDict), "The number of values should be equal to the number of sub-basins !"
2917
+ fileName = "simul_if.param"
2918
+ group = "Initial conditions"
2919
+ key = "Outflow"
2920
+
2921
+ for iBasin in range(1,len(self.subBasinDict)+1):
2922
+ if self.subBasinDict[iBasin].name in keys:
2923
+ index = np.where(np.array(keys) == self.subBasinDict[iBasin].name)[0][0]
2924
+ else:
2925
+ logging.warning(f"The sub-basin {self.subBasinDict[iBasin].name} is not in the keys list !")
2926
+ continue
2927
+ myBasin = self.subBasinDict[iBasin]
2928
+ dirID = myBasin.iDSorted
2929
+
2930
+ fileToModif = os.path.join(self.workingDir, "Subbasin_" + str(dirID), fileName)
2931
+
2932
+ paramsInput = Wolf_Param(to_read=False,toShow=False)
2933
+ paramsInput.ReadFile(fileToModif)
2934
+ paramsInput.change_param(group, key, values[index])
2935
+ paramsInput.SavetoFile(None)
2936
+ paramsInput.Reload(None)
2937
+
2938
+
2838
2939
  def make_nd_array(self, c_pointer, shape, dtype=np.float64, order='C', own_data=True,readonly=False):
2839
2940
  arr_size = np.prod(shape[:]) * np.dtype(dtype).itemsize
2840
2941