wolfhece 2.0.44__py3-none-any.whl → 2.0.46__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.
@@ -1173,32 +1173,33 @@ class profile(vector):
1173
1173
 
1174
1174
  return copied_profile
1175
1175
 
1176
- def color_active_profile(self, width: float = 3., color: list = [255, 0, 0]):
1176
+ def color_active_profile(self, width: float = 3., color: list = [255, 0, 0], plot_opengl = True):
1177
1177
  """
1178
1178
  This method colors and thickens the active profile
1179
1179
  (default width : 3, default color: red).
1180
1180
  """
1181
1181
  self.myprop.width = width
1182
1182
  self.myprop.color = getIfromRGB(color)
1183
+ if plot_opengl:
1184
+ self.parentzone.plot(True) # FIXME (Parent zone)
1183
1185
 
1184
- self.parentzone.plot(True)
1185
-
1186
- def highlightning(self, width: float = 3., color: list = [255, 0, 0]):
1186
+ def highlightning(self, width: float = 3., color: list = [255, 0, 0] , plot_opengl = True):
1187
1187
  """Alias for color_active_profile"""
1188
1188
  self.color_active_profile(width, color)
1189
1189
 
1190
- def uncolor_active_profile(self):
1190
+ def uncolor_active_profile(self, plot_opengl = True):
1191
1191
  """
1192
1192
  This method resets the width and the color of the active profile to 1 and black.
1193
1193
  """
1194
1194
  self.myprop.width = 1
1195
1195
  self.myprop.color = getIfromRGB([0, 0, 0])
1196
1196
 
1197
- self.parentzone.plot(True)
1197
+ if plot_opengl:
1198
+ self.parentzone.plot(True)
1198
1199
 
1199
- def withdrawing(self):
1200
+ def withdrawing(self , plot_opengl = True):
1200
1201
  """Alias for uncolor_active_profile"""
1201
- self.uncolor_active_profile()
1202
+ self.uncolor_active_profile(plot_opengl)
1202
1203
 
1203
1204
  def ManningStrickler_profile(self, slope: float =1.e-3, nManning: float =0., KStrickler: float=0.):
1204
1205
  """
wolfhece/PyDraw.py CHANGED
@@ -1178,7 +1178,7 @@ class WolfMapViewer(wx.Frame):
1178
1178
  if wx.TheClipboard.Open():
1179
1179
  self.Paint()
1180
1180
 
1181
- if self.canvas.SetCurrent(self.context):
1181
+ if self.SetCurrentContext():
1182
1182
 
1183
1183
  # Récupération du buffer OpenGL
1184
1184
  glPixelStorei(GL_PACK_ALIGNMENT, 1)
@@ -1341,7 +1341,7 @@ class WolfMapViewer(wx.Frame):
1341
1341
  myax.clear()
1342
1342
 
1343
1343
 
1344
- if self.canvas.SetCurrent(self.context):
1344
+ if self.SetCurrentContext():
1345
1345
  glPixelStorei(GL_PACK_ALIGNMENT, 1)
1346
1346
  data = glReadPixels(0,0,self.canvaswidth, self.canvasheight, GL_RGBA,GL_UNSIGNED_BYTE)
1347
1347
  myimage: Image.Image
@@ -1547,7 +1547,7 @@ class WolfMapViewer(wx.Frame):
1547
1547
 
1548
1548
  self.Paint()
1549
1549
 
1550
- if self.canvas.SetCurrent(self.context):
1550
+ if self.SetCurrentContext():
1551
1551
  glPixelStorei(GL_PACK_ALIGNMENT, 1)
1552
1552
  data = glReadPixels(0, 0, self.canvaswidth, self.canvasheight, GL_RGBA, GL_UNSIGNED_BYTE)
1553
1553
  myimage: Image.Image
@@ -1578,7 +1578,7 @@ class WolfMapViewer(wx.Frame):
1578
1578
  fn = dlg.GetPath()
1579
1579
  dlg.Destroy()
1580
1580
 
1581
- if self.canvas.SetCurrent(self.context):
1581
+ if self.SetCurrentContext():
1582
1582
  glPixelStorei(GL_PACK_ALIGNMENT, 1)
1583
1583
  data = glReadPixels(0, 0, self.canvaswidth, self.canvasheight, GL_RGBA, GL_UNSIGNED_BYTE)
1584
1584
  myimage: Image.Image
@@ -4739,7 +4739,7 @@ class WolfMapViewer(wx.Frame):
4739
4739
 
4740
4740
  def thread_update_blender(self):
4741
4741
  print("Update blender")
4742
- if self.canvas.SetCurrent(self.context):
4742
+ if self.SetCurrentContext():
4743
4743
  self.update_blender_sculpting()
4744
4744
  t = threading.Timer(10.0, self.thread_update_blender)
4745
4745
  t.start()
@@ -5961,7 +5961,7 @@ class WolfMapViewer(wx.Frame):
5961
5961
  """
5962
5962
  return self.active_profile
5963
5963
 
5964
- def plot_cs(self, x:float, y:float):
5964
+ def plot_cross(self, x:float, y:float):
5965
5965
 
5966
5966
  # Search for cross sections (List of profiles)
5967
5967
  if self.active_cs is None:
@@ -6059,8 +6059,7 @@ class WolfMapViewer(wx.Frame):
6059
6059
 
6060
6060
  # Profile plots
6061
6061
  elif self.action == 'Plot cross section':
6062
-
6063
- self.plot_cs(x, y)
6062
+ self.plot_cross(x, y)
6064
6063
 
6065
6064
  elif self.action == 'Set 1D profile':
6066
6065
  if self.active_cs is None:
@@ -7649,7 +7648,7 @@ class WolfMapViewer(wx.Frame):
7649
7648
  def get_MVP_Viewport_matrix(self):
7650
7649
  """ Get the modelview projection matrix """
7651
7650
 
7652
- if self.canvas.SetCurrent(self.context):
7651
+ if self.SetCurrentContext():
7653
7652
  modelview = glGetFloatv(GL_MODELVIEW_MATRIX)
7654
7653
  projection = glGetFloatv(GL_PROJECTION_MATRIX)
7655
7654
  viewport = glGetIntegerv(GL_VIEWPORT)
@@ -7659,6 +7658,14 @@ class WolfMapViewer(wx.Frame):
7659
7658
 
7660
7659
  return None, None, None
7661
7660
 
7661
+ def SetCurrentContext(self):
7662
+ """ Set the current OGL context if exists otherwise return False """
7663
+
7664
+ if self.context is None:
7665
+ return False
7666
+
7667
+ return self.canvas.SetCurrent(self.context)
7668
+
7662
7669
  def Paint(self):
7663
7670
 
7664
7671
  if self.currently_readresults:
@@ -7673,7 +7680,7 @@ class WolfMapViewer(wx.Frame):
7673
7680
  self.xmax = self.mousex + self.width / 2.
7674
7681
  self.ymax = self.mousey + self.height / 2.
7675
7682
 
7676
- if self.canvas.SetCurrent(self.context):
7683
+ if self.SetCurrentContext():
7677
7684
 
7678
7685
  bkg_color = self.bkg_color
7679
7686
 
@@ -317,27 +317,30 @@ class Triangulation(Element_To_Draw):
317
317
  def plot(self, sx=None, sy=None, xmin=None, ymin=None, xmax=None, ymax=None, size=None ):
318
318
 
319
319
  if self.id_list == -99999:
320
- self.id_list = glGenLists(1)
320
+ try:
321
+ self.id_list = glGenLists(1)
321
322
 
322
- glNewList(self.id_list, GL_COMPILE)
323
+ glNewList(self.id_list, GL_COMPILE)
323
324
 
324
- glPolygonMode(GL_FRONT_AND_BACK,GL_LINE)
325
+ glPolygonMode(GL_FRONT_AND_BACK,GL_LINE)
325
326
 
326
- for curtri in self.tri:
327
- glBegin(GL_LINE_STRIP)
327
+ for curtri in self.tri:
328
+ glBegin(GL_LINE_STRIP)
328
329
 
329
- glColor3ub(int(0),int(0),int(0))
330
+ glColor3ub(int(0),int(0),int(0))
330
331
 
331
- glVertex2d(self.pts[curtri[0]][0], self.pts[curtri[0]][1])
332
- glVertex2d(self.pts[curtri[1]][0], self.pts[curtri[1]][1])
333
- glVertex2d(self.pts[curtri[2]][0], self.pts[curtri[2]][1])
334
- glVertex2d(self.pts[curtri[0]][0], self.pts[curtri[0]][1])
332
+ glVertex2d(self.pts[curtri[0]][0], self.pts[curtri[0]][1])
333
+ glVertex2d(self.pts[curtri[1]][0], self.pts[curtri[1]][1])
334
+ glVertex2d(self.pts[curtri[2]][0], self.pts[curtri[2]][1])
335
+ glVertex2d(self.pts[curtri[0]][0], self.pts[curtri[0]][1])
335
336
 
336
- glEnd()
337
+ glEnd()
337
338
 
338
- glPolygonMode(GL_FRONT_AND_BACK,GL_LINE)
339
+ glPolygonMode(GL_FRONT_AND_BACK,GL_LINE)
339
340
 
340
- glEndList()
341
+ glEndList()
342
+ except:
343
+ logging.warning('Problem with OpenGL plot - Triangulation.plot')
341
344
  else:
342
345
  glCallList(self.id_list)
343
346
 
@@ -519,7 +522,7 @@ class vectorproperties:
519
522
 
520
523
  if len(linesextra)>4:
521
524
  self.attachedimage = Path(linesextra[4])
522
- self.imagevisible = linesextra[5]
525
+ self.imagevisible = linesextra[5].lower() == 'true'
523
526
 
524
527
  def load_extra(self, lines:list[str]) -> int:
525
528
  """ Load extra properties from lines """
@@ -1539,9 +1542,15 @@ class vector:
1539
1542
  logging.warning(_('No mapviewer available for image plot'))
1540
1543
  return
1541
1544
 
1542
- if self.myprop.imagevisible and self.myprop.textureimage is not None:
1545
+ if self.myprop.imagevisible:
1546
+
1547
+ if self.myprop.textureimage is None:
1548
+ self.myprop.load_unload_image()
1543
1549
 
1544
- self.myprop.textureimage.paint()
1550
+ if self.myprop.textureimage is not None:
1551
+ self.myprop.textureimage.paint()
1552
+ else:
1553
+ logging.warning(_('No image texture available for plot'))
1545
1554
 
1546
1555
  def _get_textfont(self):
1547
1556
  """ Retunr a 'Text_Infos' instance for the legend """
@@ -2434,18 +2443,21 @@ class zone:
2434
2443
  :param prep: True = préparation des listes OpenGL ; False = affichage direct
2435
2444
  """
2436
2445
  if prep:
2437
- if self.idgllist==-99999:
2438
- self.idgllist = glGenLists(1)
2446
+ try:
2447
+ if self.idgllist==-99999:
2448
+ self.idgllist = glGenLists(1)
2439
2449
 
2440
- self.has_legend = False
2441
- self.has_image = False
2450
+ self.has_legend = False
2451
+ self.has_image = False
2442
2452
 
2443
- glNewList(self.idgllist,GL_COMPILE)
2444
- for curvect in self.myvectors:
2445
- curvect.plot()
2446
- self.has_legend |= curvect.myprop.legendvisible
2447
- self.has_image |= curvect.myprop.imagevisible
2448
- glEndList()
2453
+ glNewList(self.idgllist,GL_COMPILE)
2454
+ for curvect in self.myvectors:
2455
+ curvect.plot()
2456
+ self.has_legend |= curvect.myprop.legendvisible
2457
+ self.has_image |= curvect.myprop.imagevisible
2458
+ glEndList()
2459
+ except:
2460
+ logging.error(_('OpenGL error in zone.plot'))
2449
2461
  else:
2450
2462
  if self.idgllist!=-99999:
2451
2463
  glCallList(self.idgllist)
@@ -3794,7 +3806,7 @@ class Zones(wx.Frame, Element_To_Draw):
3794
3806
  if find_minmax:
3795
3807
  self.find_minmax(True)
3796
3808
 
3797
- if plotted:
3809
+ if plotted and self.has_OGLContext:
3798
3810
  self.prep_listogl()
3799
3811
 
3800
3812
  @property
wolfhece/apps/version.py CHANGED
@@ -5,7 +5,7 @@ class WolfVersion():
5
5
 
6
6
  self.major = 2
7
7
  self.minor = 0
8
- self.patch = 44
8
+ self.patch = 46
9
9
 
10
10
  def __str__(self):
11
11
 
wolfhece/drawing_obj.py CHANGED
@@ -108,3 +108,13 @@ class Element_To_Draw:
108
108
  self.ymax=0. # spatial extension - upper right corner Y
109
109
 
110
110
  pass
111
+
112
+ @property
113
+ def has_OGLContext(self):
114
+ """
115
+ Test if the object has a canvas
116
+ """
117
+ if self.mapviewer is None:
118
+ return False
119
+
120
+ return self.mapviewer.SetCurrentContext()
@@ -55,6 +55,10 @@ class Catchment:
55
55
  subBasinCloud:cloud_vertices # cloud of points containing the true coordinates (used in simulation) of all subbasin outlets
56
56
  iP_Cloud:cloud_vertices # cloud of points containing the given coordinates (given in param files) of all subbasin outlets
57
57
 
58
+ subBasinDict:dict[int:SubBasin]
59
+
60
+ catchmentDict:dict[Union[str, int], Union[SubBasin, RetentionBasin]] # dictionnary containing all the elements of the catchment
61
+ subBasinDict:dict[int, SubBasin] # dictionnary containing all the subbasins
58
62
 
59
63
  def __init__(self, _name, _workingDir, _plotAllSub, _plotNothing, _initWithResults=True, _catchmentFileName="", _rbFileName="", _tz=0, version=cst.VERSION_WOLFHYDRO):
60
64
  "This is the constructor of the class Catchment in which all the caractertics and the network of sub-basins will be created"
@@ -1118,8 +1122,10 @@ class Catchment:
1118
1122
  excelData = np.zeros((len(self.time),iIndex+nbInlets))
1119
1123
  sheetName = curRB.name
1120
1124
  excelData[:,0] = curRB.time
1121
- excelData[:,1] = curRB.get_outFlow_noDelay()
1122
- excelData[:,2] = curRB.get_inlets_noDelay(unit="m3/s")
1125
+ excelData[:,1] = curRB.get_outFlow(unit="m3/s")
1126
+ # excelData[:,2] = curRB.get_inlets_noDelay(unit="m3/s")
1127
+ excelData[:,2] = curRB.get_inlets(unit="m3/s") + curRB.get_direct_insideRB_inlets(unit="m3/s")
1128
+
1123
1129
  i = iIndex
1124
1130
  for iInlet in curRB.intletsObj:
1125
1131
  curIn = curRB.intletsObj[iInlet]
@@ -1963,9 +1969,9 @@ class Catchment:
1963
1969
  lastLevel = len(self.topologyDict)
1964
1970
  prefix = "Level "
1965
1971
  nameSub = list(self.topologyDict[prefix+str(lastLevel)].items())[0][0]
1966
- myArray[:,1] = self.topologyDict[prefix+str(lastLevel)][nameSub].get_outFlow_noDelay(unit='mm/h')
1972
+ myArray[:,1] = self.topologyDict[prefix+str(lastLevel)][nameSub].evaluate_objective_function(unit='mm/h')
1967
1973
  else:
1968
- myArray[:,1] = self.catchmentDict[self.junctionOut].get_outFlow_noDelay(unit='mm/h')
1974
+ myArray[:,1] = self.catchmentDict[self.junctionOut].evaluate_objective_function(unit='mm/h')
1969
1975
 
1970
1976
 
1971
1977
  # pointerData = myData.ctypes.data_as(ct.POINTER(ct.c_double))
@@ -2054,7 +2060,8 @@ class Catchment:
2054
2060
  if blockKey is not None:
2055
2061
  self.catchmentDict[blockKey].alreadyUsed = True
2056
2062
 
2057
- self.myEffSubBasins, self.myEffSortSubBasins = self.catchmentDict[junctionName].activate(effSubs=[], effSubsSort=[], mask=mask, onlyItself=onlyItself)
2063
+ self.myEffSubBasins, self.myEffSortSubBasins = self.catchmentDict[junctionName].activate(
2064
+ effSubs=[], effSubsSort=[], mask=mask, onlyItself=onlyItself)
2058
2065
 
2059
2066
  self.write_eff_subBasin()
2060
2067
 
@@ -2204,6 +2211,24 @@ class Catchment:
2204
2211
 
2205
2212
 
2206
2213
  return timeDelays
2214
+
2215
+
2216
+ def get_timeDelays_inlets(self, ref:str = "") -> dict[str, float]:
2217
+
2218
+
2219
+ if(ref==""):
2220
+ junctionKey = self.junctionOut
2221
+ else:
2222
+ junctionKey = self.get_key_catchmentDict(name=ref)
2223
+ if junctionKey is None:
2224
+ logging.error("ERROR : Wrong reference to extract timeDelay !")
2225
+ return
2226
+
2227
+ junctionKey = self.junctionOut
2228
+ refObj = self.catchmentDict[junctionKey]
2229
+ time_delays_inlets = refObj.get_timeDelays_inlets()
2230
+
2231
+ return time_delays_inlets
2207
2232
 
2208
2233
 
2209
2234
  ## Procedure that force all SubBasins to write their timeDelays and all upstream elements
@@ -2416,6 +2441,305 @@ class Catchment:
2416
2441
  if self.charact_watrshd.to_update_times:
2417
2442
  self.charact_watrshd.update_times(self.time_wolf_array)
2418
2443
 
2444
+
2445
+ def get_all_x_production(self, selection_by_iD: list = [], to_save:bool=True, to_plot:bool=False) -> dict:
2446
+ """
2447
+ Retrieves the x production values for all sub-basins or a specific selection of sub-basins.
2448
+
2449
+ Args:
2450
+ selection_by_iD (list, optional): A list of sub-basin IDs to retrieve x production values for.
2451
+ If empty, retrieves x production values for all sub-basins.
2452
+ Defaults to [].
2453
+
2454
+ Returns:
2455
+ dict: A dictionary containing the sub-basin names or IDs as keys and their corresponding x production values as values.
2456
+ """
2457
+
2458
+ all_x = {}
2459
+
2460
+ if selection_by_iD == []:
2461
+ for iBasin in range(1, len(self.subBasinDict) + 1):
2462
+ curBasin: SubBasin = self.subBasinDict[iBasin]
2463
+ all_x[curBasin.name] = curBasin.collect_x_from_production()
2464
+ else:
2465
+ for curID in selection_by_iD:
2466
+ cur_key = self.get_key_catchmentDict(curID)
2467
+ curBasin: SubBasin = self.catchmentDict[cur_key]
2468
+ all_x[curID] = curBasin.collect_x_from_production()
2469
+
2470
+ if to_save:
2471
+ rd.write_excel_from_dict(all_x, path=self.workingDir, fileName="PostProcess/all_x.xlsx", time=self.time)
2472
+
2473
+ return all_x
2474
+
2475
+
2476
+ def get_all_fractions(self, plt_dict:dict[str:np.array]={},selection_by_iD: list = [],
2477
+ to_save:bool=True, to_plot:bool=False,
2478
+ summary:str=None, summary_interval:list[datetime.datetime]=None,
2479
+ add_info:dict[dict[str,float]]={}) -> dict:
2480
+ """
2481
+ Retrieves the physical flux fractions values for all sub-basins or a specific selection of sub-basins.
2482
+
2483
+ Args:
2484
+ selection_by_iD (list, optional): A list of sub-basin IDs to retrieve fractions values for.
2485
+ If empty, retrieves fractions values for all sub-basins.
2486
+ Defaults to [].
2487
+
2488
+ Returns:
2489
+ dict: A dictionary containing the sub-basin names or IDs as keys and their corresponding fractions values as values.
2490
+ """
2491
+
2492
+ all_fractions = {}
2493
+
2494
+ if selection_by_iD == []:
2495
+ all_fractions = {curBasin.name: curBasin.collect_fractions() for curBasin in self.subBasinDict.values()}
2496
+
2497
+ else:
2498
+ for curID in selection_by_iD:
2499
+ cur_key = self.get_key_catchmentDict(curID)
2500
+ curBasin: SubBasin = self.catchmentDict[cur_key]
2501
+ all_fractions[curID] = curBasin.collect_fractions()
2502
+
2503
+ if summary is not None:
2504
+ summary_fractions = {}
2505
+ summary_dict = {}
2506
+ if selection_by_iD == []:
2507
+ summary_fractions = {curBasin.name: curBasin.get_summary_fractions(summary=summary, interval=summary_interval)
2508
+ for curBasin in self.subBasinDict.values()}
2509
+ else:
2510
+ for curID in selection_by_iD:
2511
+ cur_key = self.get_key_catchmentDict(curID)
2512
+ curBasin: SubBasin = self.catchmentDict[cur_key]
2513
+ summary_fractions[curID] = curBasin.get_summary_fractions(summary=summary, interval=summary_interval)
2514
+
2515
+ summary_dict["Stations"] = [cur_name for cur_name in summary_fractions]
2516
+ # Get columns names and remove all duplicates with set
2517
+ all_columns = list(set(cur_key for cur_dict in summary_fractions.values() for cur_key in cur_dict.keys()))
2518
+
2519
+ for cur_dict in summary_fractions.values():
2520
+ for cur_key in all_columns:
2521
+ if cur_key not in summary_dict:
2522
+ summary_dict[cur_key] = []
2523
+ if not cur_key in cur_dict:
2524
+ summary_dict[cur_key].append(np.nan)
2525
+ else:
2526
+ summary_dict[cur_key].append(cur_dict[cur_key])
2527
+
2528
+ if add_info!={}:
2529
+ for key_add, add_dict in add_info.items():
2530
+ summary_dict[key_add] = []
2531
+ for key in summary_dict["Stations"]:
2532
+ if key in add_dict:
2533
+ summary_dict[key_add].append(add_dict[key])
2534
+ else:
2535
+ summary_dict[key_add].append(np.nan)
2536
+
2537
+
2538
+
2539
+ # summary_dict = {cur_key: [cur_dict[cur_key] for cur_dict in summary_fractions.values() if cur_key in cur_dict]
2540
+ # for cur_dict in summary_fractions.values() for cur_key in cur_dict}
2541
+ # all_fractions["Summary"] = summary_dict
2542
+
2543
+ if to_save:
2544
+ rd.write_excel_from_dict(all_fractions, path=self.workingDir, fileName="PostProcess/all_frac.xlsx", time=self.time, summary=summary_dict)
2545
+
2546
+ if to_plot:
2547
+ self.plot_all_fractions(all_fractions)
2548
+
2549
+ return all_fractions
2550
+
2551
+
2552
+ def plot_all_fractions(self, all_fractions:dict[str:np.array]={}, selection_by_iD:list=[], to_show:bool=False, writeDir:str="", range_data:list[datetime.datetime]=[]):
2553
+
2554
+ if(writeDir==""):
2555
+ writeDir = os.path.join(self.workingDir, "PostProcess")
2556
+
2557
+ if selection_by_iD == []:
2558
+ for curBasin in self.subBasinDict.values():
2559
+ curBasin.plot_all_fractions(all_fractions=all_fractions, to_show=False, writeDir=writeDir, range_data=range_data)
2560
+ else:
2561
+ for curID in selection_by_iD:
2562
+ cur_key = self.get_key_catchmentDict(curID)
2563
+ curBasin: SubBasin = self.catchmentDict[cur_key]
2564
+ curBasin.plot_all_fractions(to_show=False, writeDir=writeDir, range_data=range_data)
2565
+
2566
+ if to_show:
2567
+ plt.show()
2568
+
2569
+ return
2570
+
2571
+ def get_all_iv_production(self, selection_by_iD: list = [], to_save:bool=True) -> dict:
2572
+ """
2573
+ Retrieves the x production values for all sub-basins or a specific selection of sub-basins.
2574
+
2575
+ Args:
2576
+ selection_by_iD (list, optional): A list of sub-basin IDs to retrieve x production values for.
2577
+ If empty, retrieves x production values for all sub-basins.
2578
+ Defaults to [].
2579
+
2580
+ Returns:
2581
+ dict: A dictionary containing the sub-basin names or IDs as keys and their corresponding x production values as values.
2582
+ """
2583
+
2584
+ all_iv = {}
2585
+
2586
+ if selection_by_iD == []:
2587
+ for iBasin in range(1, len(self.subBasinDict) + 1):
2588
+ curBasin: SubBasin = self.subBasinDict[iBasin]
2589
+ all_iv[curBasin.name] = curBasin.collect_all_internal_variables()
2590
+ else:
2591
+ for curID in selection_by_iD:
2592
+ cur_key = self.get_key_catchmentDict(curID)
2593
+ curBasin: SubBasin = self.catchmentDict[cur_key]
2594
+ all_iv[curID] = curBasin.collect_all_internal_variables()
2595
+
2596
+ if to_save:
2597
+ rd.write_excel_from_dict(all_iv, path=self.workingDir, fileName="PostProcess/all_iv.xlsx", time=self.time)
2598
+
2599
+ return all_iv
2600
+
2601
+
2602
+ def activate_all_internal_variables(self, selection_by_iD: list = [])->dict:
2603
+ """
2604
+ Activates all internal variables for all sub-basins or a specific selection of sub-basins.
2605
+
2606
+ Args:
2607
+ selection_by_iD (list, optional): A list of sub-basin IDs to activate internal variables for.
2608
+ If empty, activates internal variables for all sub-basins.
2609
+ Defaults to [].
2610
+
2611
+ Returns:
2612
+ dict: A dictionary containing the sub-basin names or IDs as keys and their corresponding internal variables as values.
2613
+ """
2614
+
2615
+ if selection_by_iD == []:
2616
+ for iBasin in range(1, len(self.subBasinDict) + 1):
2617
+ curBasin: SubBasin = self.subBasinDict[iBasin]
2618
+ curBasin.activate_all_internal_variables()
2619
+ else:
2620
+ for curID in selection_by_iD:
2621
+ cur_key = self.get_key_catchmentDict(curID)
2622
+ curBasin: SubBasin = self.catchmentDict[cur_key]
2623
+ curBasin.activate_all_internal_variables()
2624
+
2625
+
2626
+ def check_presence_of_iv(self, selection_by_iD: list = []) -> dict:
2627
+ """
2628
+ Checks the presence of internal variables for all sub-basins or a specific selection of sub-basins.
2629
+
2630
+ Args:
2631
+ selection_by_iD (list, optional): A list of sub-basin IDs to check the presence of internal variables for.
2632
+ If empty, checks the presence of internal variables for all sub-basins.
2633
+ Defaults to [].
2634
+
2635
+ Returns:
2636
+ dict: A dictionary containing the sub-basin names or IDs as keys and their corresponding internal variables as values.
2637
+ """
2638
+
2639
+ all_x = {}
2640
+
2641
+ if selection_by_iD == []:
2642
+ for iBasin in range(1, len(self.subBasinDict) + 1):
2643
+ curBasin: SubBasin = self.subBasinDict[iBasin]
2644
+ all_x[curBasin.name] = curBasin.check_presence_of_iv()
2645
+ else:
2646
+ for curID in selection_by_iD:
2647
+ cur_key = self.get_key_catchmentDict(curID)
2648
+ curBasin: SubBasin = self.catchmentDict[cur_key]
2649
+ all_x[curID] = curBasin.check_presence_of_iv()
2650
+
2651
+ return all_x
2652
+
2653
+
2654
+ def get_all_Qtest(self, selection_by_iD: list = [], nb_atttempts:int=-1) :
2655
+
2656
+ if selection_by_iD == []:
2657
+ q_test = [curBasin.get_all_Qtest(nb_atttempts) for curBasin in self.subBasinDict.values()]
2658
+ else:
2659
+ # for curID in selection_by_iD:
2660
+ # cur_key = self.get_key_catchmentDict(curID)
2661
+ # curBasin: SubBasin = self.catchmentDict[cur_key]
2662
+ # q_test = curBasin.get_all_Qtest(nb_atttempts)
2663
+ q_test = [
2664
+ self.catchmentDict[self.get_key_catchmentDict(curID)].get_all_Qtest(nb_atttempts)
2665
+ for curID in selection_by_iD ]
2666
+
2667
+ return q_test
2668
+
2669
+
2670
+ def _get_simulation_intervals(self):
2671
+ """
2672
+ This procedure is getting the simulation intervals of the current module.
2673
+ """
2674
+
2675
+ nb_interv = self.paramsInput.get_param("Simulation intervals", "Nb", default_value=0)
2676
+ simulation_intervals = []
2677
+ for i in range(1, nb_interv+1):
2678
+ str_di = self.paramsInput.get_param("Simulation intervals", "Date begin "+str(i))
2679
+ di = datetime.datetime.strptime(str_di, cst.DATE_FORMAT_HYDRO).replace(tzinfo=datetime.timezone.utc)
2680
+ str_df = self.paramsInput.get_param("Simulation intervals", "Date end "+str(i))
2681
+ df = datetime.datetime.strptime(str_df, cst.DATE_FORMAT_HYDRO).replace(tzinfo=datetime.timezone.utc)
2682
+ simulation_intervals.append((di,df))
2683
+
2684
+ return simulation_intervals
2685
+
2686
+
2687
+ def _set_simulation_intervals(self, simulation_intervals:list[tuple[datetime.datetime,datetime.datetime]]):
2688
+ """
2689
+ This procedure is setting the simulation intervals of the current module.
2690
+ """
2691
+
2692
+ self.paramsInput.change_param("Simulation intervals", "Nb", len(simulation_intervals))
2693
+ for i, interval in enumerate(simulation_intervals):
2694
+ self.paramsInput.change_param("Simulation intervals", "Date begin "+str(i+1), interval[0].strftime(cst.DATE_FORMAT_HYDRO))
2695
+ self.paramsInput.change_param("Simulation intervals", "Date end "+str(i+1), interval[1].strftime(cst.DATE_FORMAT_HYDRO))
2696
+
2697
+ self.paramsInput.SavetoFile(None)
2698
+ self.paramsInput.Reload(None)
2699
+
2700
+
2701
+ @property
2702
+ def simulation_intervals(self) ->list[tuple[datetime.datetime,datetime.datetime]]:
2703
+ return self._get_simulation_intervals()
2704
+
2705
+
2706
+ @simulation_intervals.setter
2707
+ def simulation_intervals(self, value:list[tuple[datetime.datetime,datetime.datetime]]):
2708
+ self._set_simulation_intervals(value)
2709
+
2710
+
2711
+ def _get_temporal_parameters(self) ->tuple[datetime.datetime, datetime.datetime]:
2712
+ """
2713
+ This procedure is getting the temporal parameters of the current module.
2714
+ """
2715
+
2716
+ return (self.dateBegin, self.dateEnd)
2717
+
2718
+
2719
+ def _set_temporal_parameters(self, simulation_intervals:tuple[datetime.datetime,datetime.datetime]):
2720
+ """
2721
+ This procedure is setting the temporal parameters of the current module.
2722
+ """
2723
+
2724
+ self.dateBegin = simulation_intervals[0]
2725
+ self.dateEnd = simulation_intervals[1]
2726
+
2727
+ self.paramsInput.change_param("Temporal Parameters", "Start date time", self.dateBegin.strftime(cst.DATE_FORMAT_HYDRO))
2728
+ self.paramsInput.change_param("Temporal Parameters", "End date time", self.dateEnd.strftime(cst.DATE_FORMAT_HYDRO))
2729
+
2730
+ self.paramsInput.SavetoFile(None)
2731
+ self.paramsInput.Reload(None)
2732
+
2733
+
2734
+ @property
2735
+ def temporal_parameters(self) ->tuple[datetime.datetime, datetime.datetime]:
2736
+ return self._get_temporal_parameters()
2737
+
2738
+
2739
+ @temporal_parameters.setter
2740
+ def temporal_parameters(self, value:tuple[datetime.datetime,datetime.datetime]):
2741
+ self._set_temporal_parameters(value)
2742
+
2419
2743
 
2420
2744
  def make_nd_array(self, c_pointer, shape, dtype=np.float64, order='C', own_data=True,readonly=False):
2421
2745
  arr_size = np.prod(shape[:]) * np.dtype(dtype).itemsize