wolfhece 2.2.37__py3-none-any.whl → 2.2.39__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 (53) 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 +32 -0
  14. wolfhece/PyVertexvectors.py +147 -75
  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/climate_data.py +334 -0
  29. wolfhece/hydrology/constant.py +11 -0
  30. wolfhece/hydrology/cst_exchanges.py +76 -1
  31. wolfhece/hydrology/forcedexchanges.py +413 -49
  32. wolfhece/hydrology/hyetograms.py +2095 -0
  33. wolfhece/hydrology/read.py +65 -5
  34. wolfhece/hydrometry/kiwis.py +42 -26
  35. wolfhece/hydrometry/kiwis_gui.py +7 -2
  36. wolfhece/insyde_be/INBE_func.py +746 -0
  37. wolfhece/insyde_be/INBE_gui.py +1776 -0
  38. wolfhece/insyde_be/__init__.py +3 -0
  39. wolfhece/interpolating_raster.py +366 -0
  40. wolfhece/irm_alaro.py +1457 -0
  41. wolfhece/irm_qdf.py +889 -57
  42. wolfhece/lifewatch.py +6 -3
  43. wolfhece/picc.py +124 -8
  44. wolfhece/pyLandUseFlanders.py +146 -0
  45. wolfhece/pydownloader.py +2 -1
  46. wolfhece/pywalous.py +225 -31
  47. wolfhece/toolshydrology_dll.py +149 -0
  48. wolfhece/wolf_array.py +63 -25
  49. {wolfhece-2.2.37.dist-info → wolfhece-2.2.39.dist-info}/METADATA +3 -1
  50. {wolfhece-2.2.37.dist-info → wolfhece-2.2.39.dist-info}/RECORD +53 -42
  51. {wolfhece-2.2.37.dist-info → wolfhece-2.2.39.dist-info}/WHEEL +0 -0
  52. {wolfhece-2.2.37.dist-info → wolfhece-2.2.39.dist-info}/entry_points.txt +0 -0
  53. {wolfhece-2.2.37.dist-info → wolfhece-2.2.39.dist-info}/top_level.txt +0 -0
@@ -13,8 +13,7 @@ import os
13
13
  import logging
14
14
  from datetime import datetime as date
15
15
  from datetime import timezone
16
- from struct import unpack, calcsize, unpack_from
17
- from pathlib import Path
16
+ from struct import unpack, calcsize, unpack_from, pack
18
17
 
19
18
 
20
19
  # Constants
@@ -145,12 +144,16 @@ def read_bin(path, fileName, format="", nbBytes=[], uniform_format=-1, hydro=Fal
145
144
  all_bytes = file.read()
146
145
  nbL = int.from_bytes(all_bytes[:4], byteorder='little', signed=True)
147
146
  nbC = int.from_bytes(all_bytes[4:8], byteorder='little', signed=True)
148
- Data = unpack(format*nbL, all_bytes[8:])
147
+ z = all_bytes[8:8+nbL*calcsize(format)]
148
+ flat_data = unpack(format[0] + format[1:]*nbL, z)
149
+ data = [list(flat_data[i * (nbC+1) : (i + 1) * (nbC+1)]) for i in range(nbL)]
150
+ # data = np.array(flat_data, dtype=np.float64).reshape(nbL, nbC+1)
149
151
  else:
150
- Data = read_bin_old(path, fileName, nbBytes=nbBytes, uniform_format=uniform_format, hydro=hydro)
152
+ data = read_bin_old(path, fileName, nbBytes=nbBytes, uniform_format=uniform_format, hydro=hydro)
151
153
 
152
154
 
153
- return Data
155
+ return data
156
+
154
157
 
155
158
 
156
159
  def read_binary_file(path, fileName, format="", buffer_size=-1, init_offset=8):
@@ -196,6 +199,8 @@ def read_binary_file(path, fileName, format="", buffer_size=-1, init_offset=8):
196
199
  file.seek(offset - len(buffer), 1)
197
200
  # break
198
201
 
202
+ #print(f"Number of values read: {len(values_list)} / {nbL}")
203
+
199
204
  return values_list
200
205
 
201
206
 
@@ -321,3 +326,58 @@ def check_path(fileName:str, prefix:str="", applyCWD:bool=True) -> tuple[bool, s
321
326
  return info, fileName
322
327
 
323
328
  return info, os.path.normpath(finalName)
329
+
330
+
331
+ def write_binary_file(path:str, fileName:str, data:list, format:str=""):
332
+ if not data:
333
+ raise ValueError("Data cannot be empty")
334
+
335
+ if format == "":
336
+ # Default format
337
+ format = "<bbhbbbd"
338
+ elif "<" not in format:
339
+ logging.warning("Format should start with '<' if you are on Windows.")
340
+
341
+ nbL = len(data)
342
+ nbC = len(format.replace("<", "")) - 1
343
+
344
+ with open(os.path.join(path, fileName), 'wb') as file:
345
+ # Write header: number of rows and columns as 4-byte little-endian signed integers
346
+ file.write(nbL.to_bytes(4, byteorder='little', signed=True))
347
+ file.write(nbC.to_bytes(4, byteorder='little', signed=True))
348
+
349
+ # Write the data rows
350
+ for row in data:
351
+ if len(row) != nbC+1:
352
+ raise ValueError(f"Each row must have {nbC} values according to the format.")
353
+ binary_row = pack(format, *row)
354
+ file.write(binary_row)
355
+
356
+
357
+ def read_txt_file(path:str, fileName:str, sep:str="\t", header:int=2) -> tuple[np.array, np.array]:
358
+ """
359
+ Read a text file and return the data as two numpy arrays.
360
+
361
+ Args:
362
+ path (str): The path to the text file.
363
+ fileName (str): The name of the text file.
364
+ sep (str): The separator used in the text file. Default is tab.
365
+ header (int): The number of header lines to skip. Default is 0.
366
+
367
+ Returns:
368
+ tuple: A tuple containing two numpy arrays: time and values.
369
+ """
370
+ data = np.loadtxt(os.path.join(path, fileName), delimiter=sep, skiprows=header)
371
+ # time = data[:, :-1]
372
+ # values = data[:, -1]
373
+
374
+ return data
375
+
376
+
377
+ def write_txt_file(path:str, fileName:str, data:np.array, sep:str="\t", header:str=None, format:list=['%d']*6+['%.15f']) -> None:
378
+
379
+ if header is None:
380
+ header = f"{data.shape[0]:d}\n{data.shape[1]:d}"
381
+
382
+ full_name = os.path.join(path, fileName)
383
+ np.savetxt(full_name, data, header=header, fmt=format, comments='',delimiter=sep)
@@ -424,7 +424,7 @@ class hydrometry():
424
424
  self.get_groups()
425
425
  self.save_struct()
426
426
  except Exception as e:
427
- print('Error in hydrometry init :', e)
427
+ logging.error('Error in hydrometry init :', e)
428
428
  self.realstations = None
429
429
  pass
430
430
 
@@ -547,6 +547,9 @@ class hydrometry():
547
547
 
548
548
  def _get_sites_pythonlist(self):
549
549
  """ Obtention des sites en liste python """
550
+ if self.sites is None:
551
+ logging.warning('No sites available - Please check the hydrometry instance')
552
+ return []
550
553
 
551
554
  list_name_code = [curname+' --- '+curno for curname,curno in zip(self.sites[kiwis_site_fields.site_name.value].values,self.sites[kiwis_site_fields.site_no.value].values)]
552
555
  return list_name_code
@@ -649,7 +652,7 @@ class hydrometry():
649
652
  return ([],[],[])
650
653
  else:
651
654
  return ([curname + ' - ' + str(curid) for curname, curid in zip(stations_r[station_fields.STATION_NAME.value].values,
652
- stations_r[station_fields.STATION_ID.value].values)],
655
+ stations_r[station_fields.STATION_NO.value].values)],
653
656
  stations_r[station_fields.STATION_LOCAL_X.value].values,
654
657
  stations_r[station_fields.STATION_LOCAL_Y.value].values)
655
658
 
@@ -941,12 +944,16 @@ class hydrometry():
941
944
  elif stationcode!='':
942
945
  id=self.get_stationid(code=stationcode)
943
946
 
944
- json_data = requests.get(self._get_commandstr(kiwis_command.getTimeseriesList)
945
- +'&station_id='+str(id)
946
- +'&format=json'
947
- ,verify=True,
948
- headers=self._header,
949
- timeout=TIMEOUT).json()
947
+ try:
948
+ json_data = requests.get(self._get_commandstr(kiwis_command.getTimeseriesList)
949
+ +'&station_id='+str(id)
950
+ +'&format=json'
951
+ ,verify=True,
952
+ headers=self._header,
953
+ timeout=TIMEOUT).json()
954
+ except requests.exceptions.RequestException as e:
955
+ logging.error(f"Error fetching timeseries list: {e}")
956
+ return id, None
950
957
 
951
958
  try:
952
959
  if json_data[0] == 'No matches.':
@@ -1041,7 +1048,7 @@ class hydrometry():
1041
1048
  if timezone=='Europe/Brussels' or timezone=='local':
1042
1049
  timezone=''
1043
1050
 
1044
- nb = (todate - fromdate).days*24 * (3600/interval)
1051
+ nb = int((todate - fromdate).days*24 * (3600/interval))
1045
1052
  cursec = interval
1046
1053
  # id = ''
1047
1054
  if ts_id == '':
@@ -1105,8 +1112,8 @@ class hydrometry():
1105
1112
  curend = curfrom+timedelta(seconds=200000 * cursec)
1106
1113
  locts=[]
1107
1114
  while curfrom<todate:
1108
- print(curfrom, curend)
1109
- tmpts = self.timeseries(stationname, stationcode, dir, curfrom, curend, ts_name, ts_id, timezone=timezone)
1115
+ logging.info('Getting data from {0} to {1}'.format(curfrom, curend))
1116
+ tmpts = self.timeseries(stationname, stationcode, dir = dir, fromdate= curfrom, todate= curend, ts_name= ts_name, ts_id= ts_id, timezone=timezone)
1110
1117
  if len(tmpts)>0:
1111
1118
  locts.append(tmpts)
1112
1119
 
@@ -1115,22 +1122,31 @@ class hydrometry():
1115
1122
  if curend>todate:
1116
1123
  curend=todate
1117
1124
 
1125
+ if len(locts)==0:
1126
+ logging.warning('No data found for timeseries {0} for station {1} ({2}) between {3} and {4}'.format(ts_name, stationname, stationcode, fromdate, todate))
1127
+ return pd.DataFrame()
1128
+
1118
1129
  return pd.concat(locts)
1119
1130
  else:
1120
- json_data = requests.get(self._get_commandstr(kiwis_command.getTimeseriesValues)
1121
- +"&"+urllib.parse.urlencode({
1122
- "ts_id":str(ts_id),
1123
- "from":fromdate.strftime("%Y-%m-%dT%H:%M:%S"),
1124
- "to":todate.strftime("%Y-%m-%dT%H:%M:%S"),
1125
- # "format":"json",
1126
- "timezone":timezone})
1127
- ,verify=True,
1128
- headers=self._header,
1129
- timeout=TIMEOUT).json()
1131
+ try:
1132
+ json_data = requests.get(self._get_commandstr(kiwis_command.getTimeseriesValues)
1133
+ +"&"+urllib.parse.urlencode({
1134
+ "ts_id":str(ts_id),
1135
+ "from":fromdate.strftime("%Y-%m-%dT%H:%M:%S"),
1136
+ "to":todate.strftime("%Y-%m-%dT%H:%M:%S"),
1137
+ # "format":"json",
1138
+ "timezone":timezone})
1139
+ ,verify=True,
1140
+ headers=self._header,
1141
+ timeout=TIMEOUT).json()
1130
1142
 
1131
- df = pd.DataFrame(json_data[0]['data'], columns = json_data[0]['columns'].split(','))
1132
- df.set_index('Timestamp', inplace = True)
1133
- df.index = pd.to_datetime(df.index,format="%Y-%m-%dT%H:%M:%S.%f%z")
1143
+ df = pd.DataFrame(json_data[0]['data'], columns = json_data[0]['columns'].split(','))
1144
+ df.set_index('Timestamp', inplace = True)
1145
+ df.index = pd.to_datetime(df.index,format="%Y-%m-%dT%H:%M:%S.%f%z")
1146
+
1147
+ except Exception as e:
1148
+ logging.error('Error in timeseries :', e)
1149
+ return pd.DataFrame()
1134
1150
 
1135
1151
  return df.squeeze()
1136
1152
 
@@ -1210,8 +1226,8 @@ class hydrometry():
1210
1226
  curend = curfrom+timedelta(seconds=200000 * cursec)
1211
1227
  locts=[]
1212
1228
  while curfrom<todate:
1213
- print(curfrom, curend)
1214
- locts.append(self.timeseries(stationname,stationcode,dir,curfrom,curend,ts_name,ts_id))
1229
+ logging.info('Getting data from {0} to {1}'.format(curfrom, curend))
1230
+ locts.append(self.timeseries(stationname,stationcode, dir = dir, fromdate= curfrom, todate= curend, ts_name= ts_name, ts_id= ts_id))
1215
1231
  curfrom = curend
1216
1232
  curend = curfrom+timedelta(seconds=200000 * cursec)
1217
1233
  if curend>todate:
@@ -274,6 +274,10 @@ class hydrometry_gui(wx.Frame):
274
274
  """
275
275
  to_exclude = ['alarm', 'batterie']
276
276
 
277
+ if len(self.listbox2.GetSelections())==0:
278
+ logging.error(_('No station selected'))
279
+ return
280
+
277
281
  #treat only the first one if multiple selections
278
282
  stationname, stationcode = self._getname_code_fromindex(self.listbox2.GetSelections()[0])
279
283
 
@@ -584,11 +588,12 @@ class hydrometry_gui(wx.Frame):
584
588
  if stationname is None:
585
589
  return
586
590
 
587
- for curdata, curname in zip(data,tsname):
591
+ for curdata, curname in zip(data, tsname):
588
592
  if curdata is not None:
589
593
  if len(curdata)>1:
590
594
  curdata.to_csv('{}-{}.csv'.format(stationcode,curname), date_format="%Y%m%d%H%M%S%z", sep=";")
591
- if datumsizebv[0]!='':
595
+
596
+ if datumsizebv[0]!='' and 'hauteur' in curname.lower():
592
597
  curdata:pd.Series
593
598
  zdata = curdata.copy()
594
599
  zdata += float(datumsizebv[0])