wolfhece 2.1.127__py3-none-any.whl → 2.1.129__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.
@@ -104,8 +104,8 @@ class RetentionBasin():
104
104
 
105
105
  self.outletObj = None # object to compute the outlet
106
106
 
107
- self.zData = [] # height from z-v file stored
108
- self.vData = [] # volume from z-v file stored
107
+ self.zData = None # height from z-v file stored
108
+ self.vData = None # volume from z-v file stored
109
109
  self.zvInterpol = None
110
110
 
111
111
  self.timeDelay = 0.0 # [s]????? -> A vérifier!!!
@@ -663,7 +663,7 @@ class RetentionBasin():
663
663
  time_delta = datetime.timedelta(seconds=dt)
664
664
  if(rangeData==[]):
665
665
  rangeData = [beginDate,endDate]
666
- x_date = drange(beginDate, endDate, time_delta)
666
+ x_date = drange(beginDate, endDate+time_delta, time_delta)
667
667
 
668
668
  font11 = FontProperties()
669
669
  font11.set_family('serif')
@@ -698,7 +698,8 @@ class RetentionBasin():
698
698
  if(axis=="Hours"):
699
699
  ax1.plot(x, y, label = name)
700
700
  else:
701
- ax1.plot_date(x_date, y, '-', label = name)
701
+ x_plot = ph.check_drange_bug(x_date, y)
702
+ ax1.plot_date(x_plot, y, '-', label = name)
702
703
  for iInlet in self.directFluxObj :
703
704
  y = self.directFluxObj[iInlet].get_outFlow_global(typeOutFlow="Net", whichOutFlow=iInlet)
704
705
  name = self.directFluxObj[iInlet].name + " " + iInlet
@@ -708,7 +709,8 @@ class RetentionBasin():
708
709
  if(axis=="Hours"):
709
710
  ax1.plot(x, y, '-.', label = name)
710
711
  else:
711
- ax1.plot_date(x_date, y, '-.', label = name)
712
+ x_plot = ph.check_drange_bug(x_date, y)
713
+ ax1.plot_date(x_plot, y, '-.', label = name)
712
714
 
713
715
  for iOutFlow in self._outFlow:
714
716
  y = self.get_outFlow_global(typeOutFlow="Net", whichOutFlow=iOutFlow)
@@ -716,16 +718,18 @@ class RetentionBasin():
716
718
  if(axis=="Hours"):
717
719
  ax1.plot(x, y, label = self.name+" "+iOutFlow, color='k')
718
720
  else:
719
- ax1.plot_date(x_date, y, '-', label = self.name+" "+iOutFlow, color='k')
721
+ x_plot = ph.check_drange_bug(x_date, y)
722
+ ax1.plot_date(x_plot, y, '-', label = self.name+" "+iOutFlow, color='k')
720
723
 
721
724
  if(plotRaw):
722
- nameMainOut = list(self.outFlow.items())[0][0]
725
+ nameMainOut = list(self._outFlow.items())[0][0]
723
726
  y = self.get_outFlow_global(typeOutFlow="Raw", whichOutFlow=nameMainOut)
724
727
 
725
728
  if(axis=="Hours"):
726
729
  ax1.plot(x, y, '--', label = self.name+' Raw', color='k')
727
730
  else:
728
- ax1.plot(x_date, y, '--', label = self.name+' Raw', color='k')
731
+ x_plot = ph.check_drange_bug(x_date, y)
732
+ ax1.plot(x_plot, y, '--', label = self.name+' Raw', color='k')
729
733
 
730
734
  if(axis=="Hours"):
731
735
  ax1.set_xlim(x[0], x[len(x)-1])
@@ -793,7 +797,8 @@ class RetentionBasin():
793
797
  else:
794
798
  y = self.hBank*np.ones(len(x))
795
799
  else:
796
- ax2.plot_date(x_date, y, '-', label = self.name)
800
+ x_plot = ph.check_drange_bug(x_date, y)
801
+ ax2.plot_date(x_plot, y, '-', label = self.name)
797
802
  if unitReservoir == "[m^3]":
798
803
  y = self.volume*np.ones(len(x_date))
799
804
  else:
@@ -807,9 +812,11 @@ class RetentionBasin():
807
812
  ax2.grid()
808
813
  else:
809
814
  if unitReservoir == "[m^3]":
810
- ax2.plot_date(x_date, y, '--', label = "Volume max")
815
+ x_plot = ph.check_drange_bug(x_date, y)
816
+ ax2.plot_date(x_plot, y, '--', label = "Volume max")
811
817
  else:
812
- ax2.plot_date(x_date, y, '--', label = "Height max")
818
+ x_plot = ph.check_drange_bug(x_date, y)
819
+ ax2.plot_date(x_plot, y, '--', label = "Height max")
813
820
  ax2.set_xlim(rangeData[0], rangeData[1])
814
821
 
815
822
 
@@ -868,7 +875,7 @@ class RetentionBasin():
868
875
 
869
876
  if(volume==0.0):
870
877
  h=0
871
- elif(self.zData!=[]):
878
+ elif(self.zData is not None):
872
879
  if(volume>max(self.zvVtoHInterpol.x)):
873
880
  # h = max(self.zvVtoHInterpol.y)
874
881
  slope = (self.zvVtoHInterpol.y[-1]-self.zvVtoHInterpol.y[-2])/(self.zvVtoHInterpol.x[-1]-self.zvVtoHInterpol.x[-2])
@@ -888,7 +895,7 @@ class RetentionBasin():
888
895
 
889
896
  if(h==0):
890
897
  vol = 0
891
- elif(self.zData!=[]):
898
+ elif(self.zData is not None):
892
899
  if(h>max(self.zvHtoVInterpol.x)):
893
900
  # h_tmp=max(self.zvHtoVInterpol.x)
894
901
  # vol = self.zvHtoVInterpol(h_tmp)
@@ -1747,7 +1754,7 @@ class RetentionBasin():
1747
1754
  Returns the outFlow in the global time, i.e. the hydrograph to which the timeDelay is applied.
1748
1755
  """
1749
1756
  if self.type == "HelleRB" :
1750
- if whichOutFlow == self._outFlow.keys[0]:
1757
+ if whichOutFlow == list(self._outFlow.keys())[0]:
1751
1758
  tD = self.timeDelay
1752
1759
  else:
1753
1760
  tD = self.downstreamObj[whichOutFlow].timeDelay
@@ -989,6 +989,95 @@ class SubBasin:
989
989
  print("ERROR: the dates read are not consitent with the dates already recored in this subbasin!")
990
990
  sys.exit()
991
991
  return timeArray[:index], outFlow[:index]
992
+
993
+ else:
994
+ # Valid for any hydro model with an assement module at the end, there is only 1 output to consider.
995
+
996
+ print("Reading the 1 outlet file ...")
997
+ matrixData = []
998
+
999
+ # Reading the overland flow file and time
1000
+ if(fileNames is None):
1001
+ subBasinName = os.path.join(workingDir, 'Subbasin_' + str(iDSorted), 'simul_')
1002
+ fileName = subBasinName + "out.txt"
1003
+ else:
1004
+ # The file can only be a string or a list with 1 string
1005
+ if(type(fileNames)==str):
1006
+ fileName = workingDir + fileNames[0]
1007
+ elif(type(fileNames)==list and len(fileNames)==1):
1008
+ fileName = workingDir + fileNames
1009
+ else:
1010
+ print("ERROR: Expecting only 1 file name for UH model!")
1011
+ sys.exit()
1012
+
1013
+ with open(fileName, newline = '') as fileID:
1014
+ data_reader = csv.reader(fileID, delimiter='\t')
1015
+ list_data = []
1016
+ i=0
1017
+ for raw in data_reader:
1018
+ if i>1:
1019
+ list_data.append(raw)
1020
+ i += 1
1021
+ matrixData = np.array(list_data).astype("float")
1022
+ timeArray = np.zeros(len(matrixData))
1023
+ # Init of the outflow array
1024
+ outFlow = np.zeros((len(matrixData),1),dtype=ct.c_double, order='F')
1025
+
1026
+ # Init the time properties if not already done
1027
+ if self.dateBegin is None or self.dateEnd is None or self.deltaT == 0:
1028
+ self.dateBegin = datetime.datetime(year=int(matrixData[0][2]), month=int(matrixData[0][1]), day=int(matrixData[0][0]),
1029
+ hour=int(matrixData[0][3]), minute=int(matrixData[0][4]), second=int(matrixData[0][5]),
1030
+ microsecond=0, tzinfo=datetime.timezone.utc)
1031
+ self.dateEnd = datetime.datetime(year=int(matrixData[-1][2]), month=int(matrixData[-1][1]), day=int(matrixData[-1][0]),
1032
+ hour=int(matrixData[-1][3]), minute=int(matrixData[-1][4]), second=int(matrixData[-1][5]),
1033
+ microsecond=0, tzinfo=datetime.timezone.utc)
1034
+ self.deltaT = (datetime.datetime(year=int(matrixData[1][2]), month=int(matrixData[1][1]), day=int(matrixData[1][0]),
1035
+ hour=int(matrixData[1][3]), minute=int(matrixData[1][4]), second=int(matrixData[1][5]),
1036
+ microsecond=0, tzinfo=datetime.timezone.utc) - self.dateBegin).total_seconds()
1037
+
1038
+ secondsInDay = 24*60*60
1039
+ prevDate = datetime.datetime(year=int(matrixData[0][2]), month=int(matrixData[0][1]), day=int(matrixData[0][0]), hour=int(matrixData[0][3]), minute=int(matrixData[0][4]), second=int(matrixData[0][5]), microsecond=0, tzinfo=datetime.timezone.utc)
1040
+ prevDate -= tzDelta
1041
+ if(self.dateBegin!=prevDate):
1042
+ print("ERROR: The first date in hydro data does not coincide with the one expected!")
1043
+ print("Date read = ", prevDate)
1044
+ print("Date expected = ", self.dateBegin)
1045
+ sys.exit()
1046
+ timeArray[0] = datetime.datetime.timestamp(prevDate)
1047
+ outFlow[0][0] = matrixData[0][6]
1048
+
1049
+ for i in range(1,len(matrixData)):
1050
+ currDate = datetime.datetime(year=int(matrixData[i][2]), month=int(matrixData[i][1]), day=int(matrixData[i][0]),
1051
+ hour=int(matrixData[i][3]), minute=int(matrixData[i][4]), second=int(matrixData[i][5]),
1052
+ microsecond=0, tzinfo=datetime.timezone.utc)
1053
+ currDate -= tzDelta
1054
+ prevDate = datetime.datetime(year=int(matrixData[i-1][2]), month=int(matrixData[i-1][1]), day=int(matrixData[i-1][0]),
1055
+ hour=int(matrixData[i-1][3]), minute=int(matrixData[i-1][4]), second=int(matrixData[i-1][5]),
1056
+ microsecond=0, tzinfo=datetime.timezone.utc)
1057
+ prevDate -= tzDelta
1058
+ diffDate = currDate - prevDate
1059
+ diffTimeInSeconds = diffDate.days*secondsInDay + diffDate.seconds
1060
+ timeArray[i] = datetime.datetime.timestamp(currDate)
1061
+
1062
+ outFlow[i][0] = matrixData[i][6]
1063
+
1064
+ if(self.dateEnd!=currDate):
1065
+ print("ERROR: The last date in hydro data does not coincide with the one expected!")
1066
+ print("Date read = ", currDate)
1067
+ print("Date expected = ", self.dateEnd)
1068
+ sys.exit()
1069
+ if(self.deltaT!=diffTimeInSeconds):
1070
+ print("Delta t read = ", diffTimeInSeconds)
1071
+ print("Delta t expected = ", self.deltaT)
1072
+ print("ERROR: The last timestep in hydro data does not coincide with the one expected!")
1073
+ sys.exit()
1074
+ # Save time array if it does not exist yet
1075
+ # Otherwise, check the consistency of the array with the time array of the object
1076
+ if(self.time is None):
1077
+ self.time=timeArray
1078
+ elif((self.time!=timeArray).all()):
1079
+ print("ERROR: the dates read are not consitent with the dates already recored in this subbasin!")
1080
+ sys.exit()
992
1081
 
993
1082
  return timeArray, outFlow
994
1083
 
@@ -1152,7 +1241,8 @@ class SubBasin:
1152
1241
  self._outFlow[nameOutFlow]["Raw"] = self.inletsRaw + tmpHydro
1153
1242
  # Real hydrograph
1154
1243
  self._outFlow[nameOutFlow]["Net"] = self.inlets + tmpHydro
1155
- elif(self.model==cst.tom_VHM or self.model==cst.tom_2layers_linIF or self.model==cst.tom_2layers_UH):
1244
+ elif(self.model==cst.tom_VHM or self.model==cst.tom_2layers_linIF or self.model==cst.tom_2layers_UH or
1245
+ self.model==cst.tom_HBV, self.model==cst.tom_SAC_SMA, self.model==cst.tom_NAM):
1156
1246
  tmpOutFlow = np.sum(self.myHydro,1)*self.surfaceDrained/3.6
1157
1247
 
1158
1248
  # Raw hydrograph
@@ -1459,7 +1549,8 @@ class SubBasin:
1459
1549
  - the raw outlet: in black dashed line
1460
1550
  """
1461
1551
 
1462
- if(self.model==cst.tom_UH or self.model==cst.tom_2layers_linIF or self.model==cst.tom_2layers_UH or self.model==cst.tom_GR4):
1552
+ if(self.model==cst.tom_UH or self.model==cst.tom_2layers_linIF or self.model==cst.tom_2layers_UH or self.model==cst.tom_GR4 or
1553
+ self.model==cst.tom_HBV, self.model==cst.tom_SAC_SMA, self.model==cst.tom_NAM):
1463
1554
  # x = self.time/3600.0
1464
1555
  if(axis=="Hours"):
1465
1556
  x = (self.time[:]-self.time[0])/3600.0
@@ -1663,6 +1754,9 @@ class SubBasin:
1663
1754
  elif(self.model==cst.tom_2layers_linIF or self.model==cst.tom_2layers_UH):
1664
1755
  nbElements = 3
1665
1756
  lastElement = 0
1757
+ else:
1758
+ nbElements = 1
1759
+ lastElement = 0
1666
1760
 
1667
1761
  # Construction of the list of element to plot on the main hydrograph
1668
1762
  myOutFlow = self.outFlow_global
@@ -1675,7 +1769,7 @@ class SubBasin:
1675
1769
  y[:,i] = self.myHydro[:,i]*self.surfaceDrained/3.6
1676
1770
  tmpSum += self.myHydro[:,i]*self.surfaceDrained/3.6
1677
1771
  y[:,-1] = tmpSum
1678
- elif(self.model==cst.tom_GR4):
1772
+ elif(self.model==cst.tom_GR4 or self.model==cst.tom_HBV, self.model==cst.tom_SAC_SMA, self.model==cst.tom_NAM):
1679
1773
  y[:,0] = self.myHydro[:,0]*self.surfaceDrained/3.6
1680
1774
  else:
1681
1775
  print("ERROR: this model was not implemented yet!")
@@ -1703,9 +1797,11 @@ class SubBasin:
1703
1797
  y_titles.append("Overland flow")
1704
1798
  y_titles.append("Interflow")
1705
1799
  y_titles.append("Total")
1800
+ else:
1801
+ y_titles.append("Total")
1706
1802
 
1707
1803
  if(Measures is not None):
1708
- y_titles.append("Measures")
1804
+ y_titles.append("Measurement")
1709
1805
 
1710
1806
  # Colors of the plot
1711
1807
  myColors = []
@@ -1821,6 +1917,9 @@ class SubBasin:
1821
1917
  # nbElements = 3
1822
1918
  nbElements = 1
1823
1919
  lastElement = 0
1920
+ else:
1921
+ nbElements = 1
1922
+ lastElement = 0
1824
1923
 
1825
1924
 
1826
1925
  # Take into account any additionnal data given and add it to plot
@@ -1882,7 +1981,8 @@ class SubBasin:
1882
1981
  tmpSum = np.zeros(len(myOutFlow)-lastElement)
1883
1982
  # y = np.zeros((len(self.outFlow)-lastElement,nbElements))
1884
1983
  y = []
1885
- if(self.model==cst.tom_UH or self.model==cst.tom_2layers_linIF or self.model==cst.tom_2layers_UH or cst.tom_GR4):
1984
+ if(self.model==cst.tom_UH or self.model==cst.tom_2layers_linIF or self.model==cst.tom_2layers_UH or
1985
+ cst.tom_GR4 or cst.tom_HBV or cst.tom_SAC_SMA or cst.tom_NAM):
1886
1986
  if(withDelay):
1887
1987
  # y[:,0] = self.outFlow[:-1]
1888
1988
  y.append(myOutFlow[:])
@@ -1949,10 +2049,11 @@ class SubBasin:
1949
2049
  # y_titles.append("Interflow")
1950
2050
  # y_titles.append("Baseflow")
1951
2051
  # y_titles.append("Total")
1952
- y_titles.append('Débits simulés')
1953
- elif(self.model==cst.tom_UH or self.model==cst.tom_2layers_linIF or self.model==cst.tom_2layers_UH):
2052
+ y_titles.append(_('Débits simulés'))
2053
+ elif(self.model==cst.tom_UH or self.model==cst.tom_2layers_linIF or self.model==cst.tom_2layers_UH or
2054
+ self.model==cst.tom_HBV or self.model==cst.tom_SAC_SMA or self.model==cst.tom_NAM):
1954
2055
  if(ylabel==[]):
1955
- y_titles.append('Débits simulés')
2056
+ y_titles.append(_('Débits simulés'))
1956
2057
  # y_titles.append('Avec reconstruction Qout B. Vesdre')
1957
2058
  # y_titles.append('Avec Qout décrit par Le Soir au B. Vesdre')
1958
2059
  # y_titles.append('Débits nuls aux barrages')
@@ -1980,7 +2081,7 @@ class SubBasin:
1980
2081
 
1981
2082
  if(Measures is not None):
1982
2083
  # y_titles.append("Measures")
1983
- y_titles.append("Mesures")
2084
+ y_titles.append("Measurement")
1984
2085
  # y_titles.append("Débits entrant reconstruits")
1985
2086
 
1986
2087
  # Colors of the plot
@@ -2307,6 +2408,14 @@ class SubBasin:
2307
2408
  myOutFlow *= 3.6/self.surfaceDrainedHydro
2308
2409
 
2309
2410
  return myOutFlow
2411
+
2412
+
2413
+ def get_outFlow_at_time(self, time:datetime.datetime, typeOutFlow:str="Net", unit:str='m3/s', whichOutFlow="", lag:float=0.0):
2414
+ if time.tzname() != "UTC":
2415
+ logging.warning(f"Time {time} is not in UTC! Be aware that the time will keep the time zone you defined !")
2416
+
2417
+ return self.get_outFlow(typeOutFlow=typeOutFlow, unit=unit, whichOutFlow=whichOutFlow, lag=lag)[np.where(self.time==time.timestamp())][0]
2418
+
2310
2419
 
2311
2420
  def get_inlets(self, unit:str='m3/s', lag:float=0.0):
2312
2421
 
@@ -2421,13 +2530,20 @@ class SubBasin:
2421
2530
 
2422
2531
 
2423
2532
 
2424
- def plot_diff_cumulRain_with_lagtime(self, interval, lagTime, graph_title="", factor=1.5, writeDir="", lawNetRain=cst.tom_netRain_no, netRainParams={}):
2533
+ def plot_diff_cumulRain_with_lagtime(self, interval=0.0, lagTime=0.0, graph_title="", factor=1.5, writeDir="", lawNetRain=cst.tom_netRain_no, netRainParams={}):
2425
2534
  """
2426
2535
  @var interval interval to consider in the gliding sum [sec]
2427
2536
  @var lagTime time to skip before applyihng the current rain [sec]
2428
2537
  """
2429
- nbIntervals = math.ceil(interval/self.deltaT)
2430
- nbLagSteps = math.ceil(lagTime/self.deltaT)
2538
+ if interval==0:
2539
+ nbIntervals = len(self.myRain)
2540
+ else:
2541
+ nbIntervals = math.ceil(interval/self.deltaT)
2542
+
2543
+ if lagTime==0:
2544
+ nbLagSteps = 0
2545
+ else:
2546
+ nbLagSteps = math.ceil(lagTime/self.deltaT)
2431
2547
 
2432
2548
  if(lawNetRain==cst.tom_netRain_no):
2433
2549
  rain = self.myRain
@@ -19,6 +19,9 @@ tom_GR4 = 6
19
19
  measures = 5
20
20
  tom_2layers_linIF = 7
21
21
  tom_2layers_UH = 8
22
+ tom_HBV = 9
23
+ tom_SAC_SMA = 10
24
+ tom_NAM = 11
22
25
  compare_opti = -1
23
26
 
24
27