wolfhece 2.2.23__py3-none-any.whl → 2.2.24__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.
@@ -1,4 +1,5 @@
1
1
  from pyproj import Transformer
2
+ from pyproj.transformer import TransformerGroup
2
3
  from concurrent.futures import ProcessPoolExecutor
3
4
  import numpy as np
4
5
  from osgeo import gdal
@@ -19,7 +20,8 @@ def transform_chunk_coordinates(inputEPSG:str, outputEPSG:str, chunk:np.ndarray)
19
20
  :type chunk: np.ndarray
20
21
  """
21
22
  COO_TRANSFORMER = Transformer.from_crs(inputEPSG, outputEPSG, always_xy=True)
22
- return COO_TRANSFORMER.transform(chunk[:, 0], chunk[:, 1])
23
+ ret = COO_TRANSFORMER.transform(chunk[:, 0], chunk[:, 1])
24
+ return ret
23
25
 
24
26
  def transform_coordinates(points:np.ndarray, inputEPSG:str="EPSG:3812", outputEPSG:str="EPSG:31370", chunk_size:int=1000):
25
27
  """
wolfhece/PyDraw.py CHANGED
@@ -4914,7 +4914,8 @@ class WolfMapViewer(wx.Frame):
4914
4914
  dpi:int= 300,
4915
4915
  add_title:bool = False,
4916
4916
  figsizes= [10.,10.],
4917
- arrayid_as_title:bool = False):
4917
+ arrayid_as_title:bool = False,
4918
+ resid_as_title:bool = False):
4918
4919
  """
4919
4920
  Sauvegarde de la fenêtre d'affichage dans un fichier
4920
4921
 
@@ -4970,6 +4971,8 @@ class WolfMapViewer(wx.Frame):
4970
4971
  pot_title = self.viewer_name
4971
4972
  if arrayid_as_title:
4972
4973
  pot_title = self.active_array.idx
4974
+ if resid_as_title:
4975
+ pot_title = self.active_res2d.idx
4973
4976
 
4974
4977
  self.display_canvasogl(fig=fig,
4975
4978
  ax=ax,
@@ -9919,16 +9922,21 @@ class WolfMapViewer(wx.Frame):
9919
9922
 
9920
9923
  # Get all checked arrays
9921
9924
  checked_arrays = self.get_list_keys(drawing_type= draw_type.ARRAYS, checked_state= True)
9925
+ checked_results = self.get_list_keys(drawing_type= draw_type.RES2D, checked_state= True)
9926
+
9922
9927
  old_active = self.active_array
9928
+ old_res2d = self.active_res2d
9923
9929
 
9924
- if len(checked_arrays) == 0:
9930
+ if len(checked_arrays) + len(checked_results) == 0:
9925
9931
  logging.warning(_('No arrays checked for export'))
9926
- return
9932
+ return []
9927
9933
 
9928
9934
  def uncheck_all():
9929
9935
  # uncheck arrays
9930
9936
  for curarray in checked_arrays:
9931
9937
  self.uncheck_id(curarray, unload= False, forceresetOGL= False)
9938
+ for curres in checked_results:
9939
+ self.uncheck_id(curres, unload= False, forceresetOGL= False)
9932
9940
 
9933
9941
  fn = str(fn)
9934
9942
  ret = []
@@ -9938,10 +9946,21 @@ class WolfMapViewer(wx.Frame):
9938
9946
  self.active_array = self.get_obj_from_id(curel, drawtype= draw_type.ARRAYS)
9939
9947
  ret.append((self.save_canvasogl(fn + '_' + str(idx) + '.png', mpl, ds, add_title= add_title, arrayid_as_title=True), curel))
9940
9948
 
9949
+ for idx, curel in enumerate(checked_results):
9950
+ uncheck_all()
9951
+ self.check_id(curel)
9952
+ self.active_res2d = self.get_obj_from_id(curel, drawtype= draw_type.RES2D)
9953
+ ret.append((self.save_canvasogl(fn + '_' + str(idx + len(checked_arrays)) + '.png', mpl, ds, add_title= add_title, resid_as_title=True), curel))
9954
+
9941
9955
  self.active_array = old_active
9956
+ self.active_res2d = old_res2d
9957
+
9942
9958
  for curarray in checked_arrays:
9943
9959
  self.check_id(curarray)
9944
9960
 
9961
+ for curres in checked_results:
9962
+ self.check_id(curres)
9963
+
9945
9964
  self.Refresh()
9946
9965
 
9947
9966
  return ret
@@ -11757,6 +11776,97 @@ class WolfMapViewer(wx.Frame):
11757
11776
  else:
11758
11777
  logging.warning(_('Reload not yet implemented for this type of object'))
11759
11778
 
11779
+ elif _('Rasterize active zone') in text:
11780
+
11781
+ if self.active_array is None and self.active_res2d is None:
11782
+ logging.warning(_('No active array selected'))
11783
+ return
11784
+
11785
+ if self.active_array is not None and self.active_res2d is not None:
11786
+ # Show a dialog to choose between array or res2d
11787
+ dlg = wx.SingleChoiceDialog(None, _('Choose the type of rasterization'), _('Rasterization Type'), ['Array', 'Res2D'], style=wx.CHOICEDLG_STYLE)
11788
+ ret = dlg.ShowModal()
11789
+ if ret != wx.ID_OK:
11790
+ dlg.Destroy()
11791
+ return
11792
+ choice = dlg.GetSelection()
11793
+ dlg.Destroy()
11794
+ if choice == 0:
11795
+ based_array = self.active_array
11796
+ else:
11797
+ if self.active_res2d.nb_blocks == 1:
11798
+ based_array = self.active_res2d.get_header_block(1)
11799
+ elif self.active_res2d.nb_blocks > 1:
11800
+ logging.error(_('Rasterization not implemented for multi-blocks res2d -- Convert to mono-blocks first'))
11801
+ return
11802
+
11803
+ elif self.active_array is not None:
11804
+ based_array = self.active_array
11805
+ elif self.active_res2d is not None:
11806
+ if self.active_res2d.nb_blocks == 1:
11807
+ based_array = self.active_res2d.get_header_block(1)
11808
+ elif self.active_res2d.nb_blocks > 1:
11809
+ logging.error(_('Rasterization not implemented for multi-blocks res2d -- Convert to mono-blocks first'))
11810
+ return
11811
+
11812
+ if isinstance(self.selected_object, Zones):
11813
+ if self.selected_object.active_zone is None:
11814
+ logging.warning(_('No active zone selected'))
11815
+ return
11816
+ if self.selected_object.active_zone.parent is None:
11817
+ logging.warning(_('No parent object for the active zone'))
11818
+ else:
11819
+ new_zone = based_array.rasterize_zone_along_grid(self.selected_object.active_zone, outformat= zone)
11820
+ if new_zone is not None:
11821
+ new_zone.myname = self.selected_object.active_zone.myname + '_rasterized'
11822
+ self.selected_object.active_zone.parent.add_zone(new_zone, forceparent=True)
11823
+ self.selected_object.active_zone.parent.fill_structure()
11824
+ self.selected_object.active_zone.reset_listogl()
11825
+
11826
+ elif _('Rasterize active vector') in text:
11827
+
11828
+ if self.active_array is None and self.active_res2d is None:
11829
+ logging.warning(_('No active array selected'))
11830
+ return
11831
+
11832
+ if self.active_array is not None and self.active_res2d is not None:
11833
+ # Show a dialog to choose between array or res2d
11834
+ dlg = wx.SingleChoiceDialog(None, _('Choose the type of rasterization'), _('Rasterization Type'), ['Array', 'Res2D'], style=wx.CHOICEDLG_STYLE)
11835
+ ret = dlg.ShowModal()
11836
+ if ret != wx.ID_OK:
11837
+ dlg.Destroy()
11838
+ return
11839
+ choice = dlg.GetSelection()
11840
+ dlg.Destroy()
11841
+ if choice == 0:
11842
+ based_array = self.active_array
11843
+ else:
11844
+ if self.active_res2d.nb_blocks == 1:
11845
+ based_array = self.active_res2d.get_header_block(1)
11846
+ elif self.active_res2d.nb_blocks > 1:
11847
+ logging.error(_('Rasterization not implemented for multi-blocks res2d -- Convert to mono-blocks first'))
11848
+ return
11849
+
11850
+ elif self.active_array is not None:
11851
+ based_array = self.active_array
11852
+ elif self.active_res2d is not None:
11853
+ if self.active_res2d.nb_blocks == 1:
11854
+ based_array = self.active_res2d.get_header_block(1)
11855
+ elif self.active_res2d.nb_blocks > 1:
11856
+ logging.error(_('Rasterization not implemented for multi-blocks res2d -- Convert to mono-blocks first'))
11857
+ return
11858
+
11859
+ if isinstance(self.selected_object, Zones):
11860
+ if self.selected_object.active_vector is None:
11861
+ logging.warning(_('No active vector selected'))
11862
+ return
11863
+
11864
+ vec_raster = based_array.rasterize_vector_along_grid(self.selected_object.active_vector)
11865
+ if vec_raster is not None:
11866
+ vec_raster.myname = self.selected_object.active_vector.myname + '_rasterized'
11867
+ self.selected_object.active_vector.parentzone.add_vector(vec_raster, forceparent=True, update_struct=True)
11868
+ self.selected_object.active_vector.parentzone.reset_listogl()
11869
+
11760
11870
  def OnClose(self, event):
11761
11871
  """ Close the application """
11762
11872
 
@@ -14546,6 +14656,9 @@ class WolfMapViewer(wx.Frame):
14546
14656
  tracks.append(_('Load flight'))
14547
14657
  tracks.append(_('Save flight'))
14548
14658
 
14659
+ tracks.append(_('Rasterize active zone'))
14660
+ tracks.append(_('Rasterize active vector'))
14661
+
14549
14662
  # Récupération des items du menu contextuel
14550
14663
  menuitems = self.popupmenu.GetMenuItems()
14551
14664
  text = [cur.GetItemLabelText() for cur in menuitems]
@@ -14583,6 +14696,10 @@ class WolfMapViewer(wx.Frame):
14583
14696
  self.popupmenu.Append(wx.ID_ANY, _('Convert to multi-blocks (result)'), _('Convert to multi-blocks'))
14584
14697
  self.popupmenu.Append(wx.ID_ANY, _('Extract current step as IC (result)'), _('Extract current step as IC'))
14585
14698
 
14699
+ if isinstance(self.selected_object, Zones):
14700
+ self.popupmenu.Append(wx.ID_ANY, _('Rasterize active zone'), _('Rasterize active zone'))
14701
+ self.popupmenu.Append(wx.ID_ANY, _('Rasterize active vector'), _('Rasterize active vector'))
14702
+
14586
14703
  if isinstance(self.selected_object, Zones | Bridge | Weir):
14587
14704
  self.popupmenu.Append(wx.ID_ANY, _('Export to Shape file'), _('Export to Shape file'))
14588
14705
  self.popupmenu.Append(wx.ID_ANY, _('Export active zone to Shape file'), _('Export active zone to Shape file'))
wolfhece/Results2DGPU.py CHANGED
@@ -14,7 +14,7 @@ from os import path
14
14
  from pathlib import Path
15
15
  from scipy.sparse import csr_array
16
16
  from multiprocessing import Pool
17
- from typing import Union
17
+ from typing import Union, Literal
18
18
  from tqdm import tqdm
19
19
  import logging
20
20
 
@@ -26,41 +26,38 @@ from .CpGrid import CpGrid
26
26
  from .PyPalette import wolfpalette
27
27
 
28
28
  try:
29
- from wolfgpu.results_store import ResultsStore, ResultType
29
+ from wolfgpu.results_store import ResultsStore, ResultType, PerformancePolicy
30
30
  except ImportError:
31
31
  logging.debug(_("Unable to import wolfgpu.results_store.ResultsStore. Please install wolfgpu package or add a symlink to the wolfgpu package in the wolfhece directory"))
32
32
 
33
- def _load_res(x) -> tuple[csr_array, csr_array, csr_array]:
33
+ def _load_res(x) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
34
34
  store:ResultsStore
35
35
  i:int
36
36
 
37
- store, i = x
38
- _, _, _, _, wd_np, qx_np, qy_np = store.get_result(i+1)
37
+ store, i, mode = x
39
38
 
40
- if isinstance(wd_np, csr_array) and isinstance(qx_np, csr_array) and isinstance(qy_np, csr_array):
41
- return wd_np, qx_np, qy_np
42
- else:
43
- return csr_array(wd_np), csr_array(qx_np), csr_array(qy_np)
39
+ _, _, _, _, wd_np, qx_np, qy_np = store.get_result(i+1, untile= mode == 'UNTILED')
40
+ return wd_np, qx_np, qy_np
44
41
 
45
- def _load_res_h(x) -> tuple[csr_array, csr_array, csr_array]:
42
+
43
+ def _load_res_h(x) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
46
44
  store:ResultsStore
47
45
  i:int
48
46
 
49
- store, i = x
50
- wd_np = store.get_named_result('h',i+1)
47
+ store, i, mode = x
51
48
 
52
- if isinstance(wd_np, csr_array):
53
- return wd_np
54
- else:
55
- return csr_array(wd_np)
49
+ wd_np = store.get_named_result('h', i+1, untile= mode == 'UNTILED')
50
+ return wd_np
56
51
 
57
52
  class Cache_Results2DGPU():
58
53
  """
59
54
  Gestion en mémoire de plusieurs résultats GPU
60
- Stockage CSR afin d'économiser la mémoire (Scipy CSR)
55
+ Stockage CSR afin d'économiser la mémoire (Scipy CSR) ou Numpy array dense
61
56
  """
62
57
 
63
- def __init__(self, fname:str, start_idx:int, end_idx:int = -1, only_h=False) -> None:
58
+ def __init__(self, fname:str, start_idx:int, end_idx:int = -1,
59
+ only_h=False, every:int= 1,
60
+ mode:Literal['TILED', 'UNTILED'] = 'TILED', memory_max_size:int = 12 * 1024 * 1024 * 1024) -> None:
64
61
  """
65
62
  Chargement de résultats sur base du répertoire de sauvegarde de la simulation GPU
66
63
 
@@ -72,74 +69,198 @@ class Cache_Results2DGPU():
72
69
  :param start_idx: index de départ (0-based)
73
70
  :param end_idx: index de fin (0-based)
74
71
  :param only_h: lecture de la hauteur d'eau seulement
72
+ :param every: lecture de chaque ième résultat (1 = tous les résultats, 2 = un sur deux, etc.)
73
+ :param mode: 'TILED' pour les résultats en tuiles, 'UNTILED' pour les résultats non-tuilés
74
+ :param memory_max_size: taille mémoire maximale en octets pour le cache (par défaut 12 Go)
75
+
75
76
  """
76
77
 
77
- self._results:Union[dict[str,tuple[csr_array, csr_array, csr_array]], dict[str,csr_array]] # typage
78
+ self._mode = mode
79
+ self._results:Union[dict[str,tuple[np.ndarray, np.ndarray, np.ndarray]], dict[str,np.ndarray]] # typage
78
80
 
79
81
  # ResultsStore unique
80
82
  self._result_store = ResultsStore(Path(fname), mode='r')
81
83
  self._only_h = only_h
84
+ self.memory_max_size = memory_max_size
85
+
86
+ mem_one_res = self._estimate_memory_size_one_result()
87
+ logging.info(_("Estimated memory size for one result: {:.2f} MB").format(mem_one_res))
88
+ self._maximum_n_results = int(self.memory_max_size // mem_one_res) if self.memory_max_size is not None else 10_000
82
89
 
83
90
  if end_idx == -1:
84
91
  end_idx = self._result_store.nb_results
85
92
 
86
93
  if end_idx>start_idx:
94
+
87
95
  self.start_idx = int(max(start_idx,0))
88
96
  self.end_idx = int(min(end_idx, self._result_store.nb_results))
97
+ self._every = int(max(every, 1))
98
+
99
+ if (self.end_idx - self.start_idx) // self._every > self._maximum_n_results:
100
+ logging.warning(_("Too many results to cache in memory. "
101
+ "Only the first {} results will be cached.").format(self._maximum_n_results))
102
+ self.end_idx = int(min(int(self.start_idx + self._maximum_n_results * self._every), self._result_store.nb_results))
103
+
104
+ self._range_to_process = list(range(self.start_idx, self.end_idx, self._every))
105
+ if self.end_idx-1 not in self._range_to_process:
106
+ self._range_to_process.append(self.end_idx-1)
89
107
 
90
108
  # Lecture en multiprocess des résultats
91
109
  if only_h:
92
110
  with Pool() as pool:
93
- _results = pool.map(_load_res_h, [(self._result_store,i) for i in range(self.start_idx, self.end_idx)])
111
+ _results = pool.map(_load_res_h, [(self._result_store, i, mode) for i in self._range_to_process])
94
112
  self._results = {i+1:res for i,res in enumerate(_results)}
95
113
  else:
96
114
  with Pool() as pool:
97
- _results = pool.map(_load_res, [(self._result_store,i) for i in range(self.start_idx, self.end_idx)])
115
+ _results = pool.map(_load_res, [(self._result_store, i, mode) for i in self._range_to_process])
98
116
  self._results = {i+1:res for i,res in enumerate(_results)}
99
117
 
118
+ def _estimate_memory_size_one_result(self):
119
+ """ Read one result to estimate memory size """
120
+ res = self._result_store.get_result(1, untile=False)
121
+ if self._only_h:
122
+ return res[4].nbytes / 1024 / 1024
123
+ else:
124
+ return (res[4].nbytes + res[5].nbytes + res[6].nbytes) / 1024 / 1024
125
+
126
+ @property
127
+ def memory_size(self) -> int:
128
+ """
129
+ Estimation de la taille mémoire des résultats en cache
130
+
131
+ :return: taille mémoire en Mega-octets
132
+ """
133
+ if self._only_h:
134
+ return sum(res.nbytes for res in self._results.values()) / 1024 / 1024 # Convert to MB
135
+ else:
136
+ return sum(res[0].nbytes + res[1].nbytes + res[2].nbytes for res in self._results.values()) / 1024 / 1024 # Convert to MB
137
+
100
138
  @property
101
139
  def only_h(self):
102
140
  return self._only_h
103
141
 
104
- def __getitem__(self,i:int):
142
+ @property
143
+ def _tile_packer(self):
144
+ """
145
+ Retourne le tile packer de la simulation
146
+ """
147
+ if self._result_store is not None:
148
+ return self._result_store.tile_packer()
149
+ else:
150
+ return None
151
+
152
+ def __getitem__(self, i:int):
105
153
  """Surcharge de l'opérateur []"""
106
154
  return self._results[i]
107
155
 
156
+ @property
157
+ def list_cached(self) -> list[int]:
158
+ """
159
+ Retourne la liste des indices des résultats en cache
160
+
161
+ :return: liste des indices (1-based)
162
+ """
163
+ return list(set(self._results.keys()))
164
+
165
+ def check_if_cached(self, idx:int) -> bool:
166
+ """
167
+ Vérifie si le résultat idx est dans le cache
168
+
169
+ :param idx: index du résultat (1-based)
170
+ :return: True si le résultat est dans le cache, False sinon
171
+ """
172
+
173
+ if idx not in self._results:
174
+ logging.info(_("Index {} not in cache").format(idx))
175
+ logging.info(_('We cache it now !'))
176
+
177
+ if self.only_h:
178
+ self._results[idx] = _load_res_h((self._result_store, idx-1, self._mode))
179
+ else:
180
+ self._results[idx] = _load_res((self._result_store, idx-1, self._mode))
181
+
182
+ return True
183
+
108
184
  def get_h(self, idx:int, dense:bool=True) -> Union[np.ndarray, csr_array]:
109
185
  """
110
186
  Retourne la matrice de hauteur d'eau de la position idx (0-based)
111
187
  - en CSR (Scipy CSR)
112
188
  - en dense (Numpy array)
189
+
190
+ :param idx: index du résultat (1-based)
191
+ :param dense: si True, retourne un Numpy array dense, sinon retourne un Scipy CSR array
113
192
  """
114
- if not self.only_h:
115
- return self._results[idx][0].toarray() if dense else self._results[idx][0]
193
+
194
+ self.check_if_cached(idx)
195
+
196
+ if self.only_h:
197
+ if self._tile_packer is None:
198
+ untiled = self._results[idx]
199
+ else:
200
+ untiled = self._tile_packer.unpack_array(self._results[idx])
201
+ if dense:
202
+ return untiled
203
+ else:
204
+ return csr_array(untiled)
116
205
  else:
117
- return self._results[idx].toarray() if dense else self._results[idx]
206
+ if self._tile_packer is None:
207
+ untiled = self._results[idx][0]
208
+ else:
209
+ untiled = self._tile_packer.unpack_array(self._results[idx][0])
210
+ if dense:
211
+ return untiled
212
+ else:
213
+ return csr_array(untiled)
118
214
 
119
215
  def get_qx(self,idx:int, dense:bool=True) -> Union[np.ndarray, csr_array]:
120
216
  """
121
217
  Retourne la matrice de débit X d'eau de la position idx (0-based)
122
218
  - en CSR (Scipy CSR)
123
219
  - en dense (Numpy array)
220
+
221
+ :param idx: index du résultat (1-based)
222
+ :param dense: si True, retourne un Numpy array dense, sinon retourne un Scipy CSR array
124
223
  """
125
224
 
126
- if not self.only_h:
127
- return self._results[idx][1].toarray() if dense else self._results[idx][1]
128
- else:
225
+ if self.only_h:
129
226
  return None
227
+ else:
228
+ self.check_if_cached(idx)
229
+
230
+ if self._tile_packer is None:
231
+ untiled = self._results[idx][1]
232
+ else:
233
+ untiled = self._tile_packer.unpack_array(self._results[idx][1])
234
+
235
+ if dense:
236
+ return untiled
237
+ else:
238
+ return csr_array(untiled)
130
239
 
131
240
  def get_qy(self,idx:int, dense:bool=True) -> Union[np.ndarray, csr_array]:
132
241
  """
133
242
  Retourne la matrice de débit Y d'eau de la position idx (0-based)
134
243
  - en CSR (Scipy CSR)
135
244
  - en dense (Numpy array)
245
+
246
+ :param idx: index du résultat (1-based)
247
+ :param dense: si True, retourne un Numpy array dense, sinon retourne un Scipy CSR array
136
248
  """
137
249
 
138
- if not self.only_h:
139
- return self._results[idx][2].toarray() if dense else self._results[idx][2]
140
- else:
250
+ if self.only_h:
141
251
  return None
252
+ else:
253
+ self.check_if_cached(idx)
142
254
 
255
+ if self._tile_packer is None:
256
+ untiled = self._results[idx][2]
257
+ else:
258
+ untiled = self._tile_packer.unpack_array(self._results[idx][2])
259
+
260
+ if dense:
261
+ return untiled
262
+ else:
263
+ return csr_array(untiled)
143
264
 
144
265
  class wolfres2DGPU(Wolfresults_2D):
145
266
  """
@@ -427,7 +548,7 @@ class wolfres2DGPU(Wolfresults_2D):
427
548
 
428
549
  # stored result files are 1-based -> which+1
429
550
  if self._cache is not None:
430
- if (which >= self._cache.start_idx and which < self._cache.end_idx) and (not self._cache.only_h):
551
+ if not self._cache.only_h:
431
552
  wd_np = self._cache.get_h(which+1, True)
432
553
  qx_np = self._cache.get_qx(which+1, True)
433
554
  qy_np = self._cache.get_qy(which+1, True)
@@ -472,9 +593,9 @@ class wolfres2DGPU(Wolfresults_2D):
472
593
  curblock.qx.array.mask[ij] = False
473
594
  curblock.qy.array.mask[ij] = False
474
595
 
475
- curblock.waterdepth.count()
476
- curblock.qx.count()
477
- curblock.qy.count()
596
+ curblock.waterdepth.nbnotnull = len(ij[0])
597
+ curblock.qx.nbnotnull = curblock.waterdepth.nbnotnull
598
+ curblock.qy.nbnotnull = curblock.waterdepth.nbnotnull
478
599
 
479
600
  # curblock.waterdepth.set_nullvalue_in_mask()
480
601
  # curblock.qx.set_nullvalue_in_mask()
@@ -497,10 +618,7 @@ class wolfres2DGPU(Wolfresults_2D):
497
618
 
498
619
  # stored result files are 1-based -> which+1
499
620
  if self._cache is not None:
500
- if (which >= self._cache.start_idx and which < self._cache.end_idx):
501
- wd_np = self._cache.get_h(which+1, True)
502
- else:
503
- _, _, _, _, wd_np, qx_np, qy_np = self._result_store.get_result(which+1)
621
+ wd_np = self._cache.get_h(which+1, True)
504
622
  else:
505
623
  __, __, __, __, wd_np, qx_np, qy_np = self._result_store.get_result(which+1)
506
624
 
@@ -8,6 +8,99 @@ Copyright (c) 2024 University of Liege. All rights reserved.
8
8
  This script and its content are protected by copyright law. Unauthorized
9
9
  copying or distribution of this file, via any medium, is strictly prohibited.
10
10
  """
11
+ def test_conversion_LBT72_LBT08():
12
+
13
+ from pyproj.transformer import TransformerGroup
14
+
15
+ # Créer le groupe de transformateurs
16
+ tg = TransformerGroup(31370, 3812)
17
+
18
+ # Choisir le premier transformateur (ou un autre selon ton besoin)
19
+ transformer = tg.transformers[0]
20
+
21
+ print(transformer.description)
22
+ if '(3)' in transformer.description:
23
+ # This is the Belgian Lambert 72 + BD72 to ETRS89 (3) + Belgian Lambert 2008
24
+ return True
25
+ elif '(2)' in transformer.description:
26
+ # This is the Belgian Lambert 72 + BD72 to ETRS89 (2) + Belgian Lambert 2008
27
+ return False
28
+ elif '(1)' in transformer.description:
29
+ # This is the Belgian Lambert 72 + BD72 to ETRS89 (1) + Belgian Lambert 2008
30
+ return False
31
+ else:
32
+ # This is not the expected transformer
33
+ return False
34
+
35
+ def test_conversion_LBT08_LBT72():
36
+
37
+ from pyproj.transformer import TransformerGroup
38
+
39
+ # Créer le groupe de transformateurs
40
+ tg = TransformerGroup(3812, 31370)
41
+
42
+ # Choisir le premier transformateur (ou un autre selon ton besoin)
43
+ transformer = tg.transformers[0]
44
+
45
+ print(transformer.description)
46
+ if '(3)' in transformer.description:
47
+ # This is the Belgian Lambert 72 + BD72 to ETRS89 (3) + Belgian Lambert 2008
48
+ return True
49
+ elif '(2)' in transformer.description:
50
+ # This is the Belgian Lambert 72 + BD72 to ETRS89 (2) + Belgian Lambert 2008
51
+ return False
52
+ elif '(1)' in transformer.description:
53
+ # This is the Belgian Lambert 72 + BD72 to ETRS89 (1) + Belgian Lambert 2008
54
+ return False
55
+ else:
56
+ # This is not the expected transformer
57
+ return False
58
+
59
+ def test_transform_coordinates():
60
+ from pyproj.transformer import TransformerGroup
61
+ from pyproj import Transformer
62
+ import numpy as np
63
+ from wolfhece.Coordinates_operations import transform_coordinates
64
+ tg = TransformerGroup(31370, 3812)
65
+
66
+ ret = True
67
+
68
+ ret = ret and len(tg.transformers) > 0
69
+ ret = ret and len(tg.transformers) == 3
70
+ ret = ret and '(3)' in tg.transformers[0].description
71
+ ret = ret and '(2)' in tg.transformers[1].description
72
+ ret = ret and '(1)' in tg.transformers[2].description
73
+
74
+ tg_inv = TransformerGroup(3812, 31370)
75
+ ret = ret and len(tg_inv.transformers) > 0
76
+ ret = ret and len(tg_inv.transformers) == 3
77
+ ret = ret and '(3)' in tg_inv.transformers[0].description
78
+ ret = ret and '(2)' in tg_inv.transformers[1].description
79
+ ret = ret and '(1)' in tg_inv.transformers[2].description
80
+
81
+ tr = Transformer.from_crs(31370, 3812)
82
+
83
+ points = np.array([[100000, 200000], [110000, 210000], [120000, 220000]])
84
+
85
+ transformed_points_3 = tg.transformers[0].transform(points[:, 0], points[:, 1])
86
+ transformed_points_2 = tg.transformers[1].transform(points[:, 0], points[:, 1])
87
+ transformed_points_1 = tg.transformers[2].transform(points[:, 0], points[:, 1])
88
+ transformed_points = tr.transform(points[:, 0], points[:, 1])
89
+ transform_wolf = transform_coordinates(points, inputEPSG='EPSG:31370', outputEPSG='EPSG:3812')
90
+
91
+ # Convert to numpy arrays
92
+ transformed_points_3 = np.array(transformed_points_3).T
93
+ transformed_points_2 = np.array(transformed_points_2).T
94
+ transformed_points_1 = np.array(transformed_points_1).T
95
+ transformed_points = np.array(transformed_points).T
96
+
97
+ # Assert that the transformed points are equal
98
+ ret = ret and np.all(transformed_points_3 == transform_wolf)
99
+ ret = ret and np.all(transformed_points_3 == transformed_points)
100
+ ret = ret and not np.all(transformed_points_2 == transformed_points)
101
+ ret = ret and not np.all(transformed_points_1 == transformed_points)
102
+
103
+ return ret
11
104
 
12
105
  def main():
13
106
  # Check if installation is complete
@@ -32,17 +125,57 @@ def main():
32
125
  ret += 'Error during osgeo import - GDAL/OGR not/bad installed\n Please (re)install GDAL (64 bits version) from https://github.com/cgohlke/geospatial-wheels/releases\n\n'
33
126
  ret += 'Error : ' + str(e) + '\n\n'
34
127
 
128
+ if 'pyproj' in packages:
129
+ ret += 'PyProj seems installed\n\n'
130
+ try:
131
+ conv = test_conversion_LBT72_LBT08()
132
+
133
+ if conv:
134
+ ret += 'NTv2 conversion from Lambert 72 to Lambert 2008 seems available\n\n'
135
+ else:
136
+ ret += 'NTv2 conversion from Lambert 72 to Lambert 2008 seems NOT available\n\n'
137
+ ret += 'Please check if the PROJ data files are installed correctly - See OSGOE4W instructions\n\n'
138
+ except ImportError as e:
139
+ ret += 'PyProj not installed properly\n Please install PyProj from "pip install pyproj"\n\n'
140
+ ret += 'Error : ' + str(e) + '\n\n'
141
+
142
+ try:
143
+ conv = test_conversion_LBT08_LBT72()
144
+
145
+ if conv:
146
+ ret += 'NTv2 conversion from Lambert 2008 to Lambert 72 seems available\n\n'
147
+ else:
148
+ ret += 'NTv2 conversion from Lambert 2008 to Lambert 72 seems NOT available\n\n'
149
+ ret += 'Please check if the PROJ data files are installed correctly - See OSGOE4W instructions\n\n'
150
+ except ImportError as e:
151
+ ret += 'PyProj not installed properly\n Please install PyProj from "pip install pyproj"\n\n'
152
+ ret += 'Error : ' + str(e) + '\n\n'
153
+
154
+ try:
155
+ conv = test_transform_coordinates()
156
+ if conv:
157
+ ret += 'Transform coordinates function seems working fine\n\n'
158
+ else:
159
+ ret += 'Transform coordinates function seems NOT available\n\n'
160
+ ret += 'Please check if the PROJ data files are installed correctly - See OSGOE4W instructions\n\n'
161
+ except ImportError as e:
162
+ ret += 'PyProj not installed properly\n Please install PyProj from "pip install pyproj"\n\n'
163
+ ret += 'Error : ' + str(e) + '\n\n'
164
+
165
+ else:
166
+ ret += 'PyProj not installed\n Please install PyProj from "pip install pyproj"\n\n'
167
+
35
168
  if 'wolfgpu' in packages:
36
169
  ret += 'WolfGPU seems installed\n\n'
37
170
  else:
38
171
  ret += 'WolfGPU not installed\n Please install WolfGPU if needed\n\n'
39
172
 
40
- try:
41
- from wolf_libs import wolfpy
42
- ret += 'Wolfpy accessible\n\n'
43
- except ImportError as e:
44
- ret += 'Wolfpy not accessible\n\n'
45
- ret += 'Error : ' + str(e) + '\n\n'
173
+ # try:
174
+ # from wolf_libs import wolfpy
175
+ # ret += 'Wolfpy accessible\n\n'
176
+ # except ImportError as e:
177
+ # ret += 'Wolfpy not accessible\n\n'
178
+ # ret += 'Error : ' + str(e) + '\n\n'
46
179
 
47
180
  try:
48
181
  from ..PyGui import MapManager
wolfhece/apps/version.py CHANGED
@@ -5,7 +5,7 @@ class WolfVersion():
5
5
 
6
6
  self.major = 2
7
7
  self.minor = 2
8
- self.patch = 23
8
+ self.patch = 24
9
9
 
10
10
  def __str__(self):
11
11
 
wolfhece/irm_qdf.py CHANGED
@@ -746,4 +746,70 @@ class QDF_Belgium():
746
746
  return None
747
747
  else:
748
748
  logging.error(f"Name {key} not found in the data")
749
- return None
749
+ return None
750
+
751
+
752
+ class Climate_IRM():
753
+
754
+ def __init__(self, store_path= 'irm', ins:Literal['2018', '2019', '2025', 2018, 2019, 2025] = 2018) -> None:
755
+ self.store_path = Path(store_path)
756
+ self.localities = Localities(ins)
757
+
758
+ self._climate_data = {}
759
+
760
+ def __getitem__(self, key):
761
+ return self._climate_data[key]
762
+
763
+ @classmethod
764
+ def importfromwebsite(cls, store_path= 'irm', verbose:bool= False, waitingtime:float= .01, ins:Literal['2018', '2019', '2025', 2018, 2019, 2025] = 2018, ins_code: int = None):
765
+ """ Import Excel files for one or all municipalities from the IRM website
766
+
767
+ :param store_path: Where to store the downloaded data. Directory will be created if it doesn't exists.
768
+ :param verbose: If `True`, will print some progress information.
769
+ If `False`, will do nothing.
770
+ If a callable, then will call it with a float in [0, 1].
771
+ 0 means nothing downloaded, 1 means everything downloaded.
772
+
773
+ :param waitingtime: How long to wait (in seconds) betwenn the download
774
+ of each station (will make sure we don't overwhelm IRM's website).
775
+
776
+ :param ins: The year of the INS codes to use.
777
+ :param code: Restricts the data download to a specific NIS code. `None` means full download.
778
+ """
779
+ import requests
780
+
781
+ myloc = Localities(ins)
782
+
783
+ if ins_code is not None:
784
+ codes_to_load = [ins_code]
785
+ else:
786
+ if not path.exists(store_path):
787
+ mkdir(store_path)
788
+ codes_to_load = myloc.inscode2name
789
+
790
+ for key,myins in enumerate(codes_to_load):
791
+ #chaîne URL du fichier Excel
792
+ url="https://www.meteo.be//resources//climatology//climateCity//pdf//climate_INS"+str(myins)+"_9120_fr.pdf"
793
+ #Obtention du fichiers depuis le site web de l'IRM
794
+ response=requests.get(url)
795
+
796
+ if str(response.content).find("Page not found")==-1 :
797
+
798
+ # Make sure we create the store path only if we have
799
+ # something to put inside.
800
+ if ins_code is not None and not path.exists(store_path):
801
+ mkdir(store_path)
802
+
803
+ file=open(path.join(store_path,str(myins)+".pdf"), 'wb')
804
+ file.write(response.content)
805
+ file.close()
806
+ if verbose:
807
+ if callable(verbose):
808
+ verbose(key/len(codes_to_load))
809
+ else:
810
+ print(myins)
811
+ else:
812
+ #logging.error(response.content)
813
+ logging.error(f"Failed to load IRM data: {url} --> {response}")
814
+
815
+ sleep(waitingtime)
@@ -11484,7 +11484,8 @@ class prev_sim2D():
11484
11484
  if len(lst) == 0:
11485
11485
  logging.warning('No potential BC found -- Test can not be performed -- I continue anyway')
11486
11486
  else:
11487
- if i not in lst[0] or j not in lst[1]:
11487
+ candidate_cells = list(zip(lst[0], lst[1]))
11488
+ if (i, j) not in candidate_cells:
11488
11489
  logging.error(f'Invalid indices ({i},{j}) - BC not added')
11489
11490
  return
11490
11491
 
@@ -11506,7 +11507,8 @@ class prev_sim2D():
11506
11507
  if len(lst) == 0:
11507
11508
  logging.warning('No potential BC found -- Test can not be performed -- I continue anyway')
11508
11509
  else:
11509
- if i not in lst[0] or j not in lst[1]:
11510
+ candidate_cells = list(zip(lst[0], lst[1]))
11511
+ if (i, j) not in candidate_cells:
11510
11512
  logging.error(f'Invalid indices ({i},{j}) - BC not added')
11511
11513
  return
11512
11514
 
wolfhece/wolf_array.py CHANGED
@@ -1384,6 +1384,34 @@ class header_wolf():
1384
1384
 
1385
1385
  return newvector
1386
1386
 
1387
+ def rasterize_zone_along_grid(self, zone2raster:zone, outformat:Union[np.ndarray, vector]=zone) -> Union[np.ndarray,zone]:
1388
+ """ Rasterize a zone according to the grid
1389
+
1390
+ :param zone2raster: zone to rasterize
1391
+ :param outformat: output format (np.ndarray or zone)
1392
+ """
1393
+
1394
+ assert outformat in [np.ndarray, zone], _('outformat must be np.ndarray or zone')
1395
+
1396
+ if outformat is zone:
1397
+ out_vec = vector
1398
+ else:
1399
+ out_vec = np.ndarray
1400
+ new_vecs = []
1401
+ for vec in zone2raster.myvectors:
1402
+ new_vecs.append(self.rasterize_vector_along_grid(vec, outformat=out_vec))
1403
+
1404
+ if outformat is np.ndarray:
1405
+ return np.vstack(new_vecs)
1406
+ elif outformat is zone:
1407
+ # create new zone
1408
+ newzone = zone()
1409
+ for vec, oldvec in zip(new_vecs, zone2raster.myvectors):
1410
+ vec.myname = oldvec.myname # keep the original name
1411
+ newzone.add_vector(vec, forceparent=True)
1412
+ return newzone
1413
+
1414
+
1387
1415
  def rasterize_vector(self, vector2raster:vector, outformat:Union[np.ndarray, vector]=vector) -> Union[np.ndarray,vector]:
1388
1416
  """ DEPRECATED since 2.2.8 -- use rasterize_vector_along_grid instead.
1389
1417
 
@@ -4155,6 +4155,10 @@ class Wolfresults_2D(Element_To_Draw):
4155
4155
  :param to_rasterize : pour rasteriser le vecteur selon la grille de calcul
4156
4156
  """
4157
4157
 
4158
+ if self.nb_blocks > 1:
4159
+ logging.error(_('This method is not implemented for multi-block results - Need to be implemented !'))
4160
+ return []
4161
+
4158
4162
  myhead = self.get_header_block(1)
4159
4163
  if to_rasterize:
4160
4164
  myvect = myhead.rasterize_vector_along_grid(myvect)
@@ -6129,4 +6133,123 @@ class Wolfresults_2D(Element_To_Draw):
6129
6133
  qx_avg.array.mask[:,:] = h_avg.array.mask[:,:]
6130
6134
  qy_avg.array.mask[:,:] = h_avg.array.mask[:,:]
6131
6135
 
6132
- return h_avg, qx_avg, qy_avg
6136
+ return h_avg, qx_avg, qy_avg
6137
+
6138
+ def danger_map_velocity_with_directions(self, start:int=0, end:int=-1, every:int=1, callback=None) -> Union[tuple[WolfArray, WolfArray, WolfArray, WolfArray], tuple[WolfArrayMB, WolfArrayMB, WolfArrayMB, WolfArrayMB]]:
6139
+ """
6140
+ Create Danger Map of velocity magnitudes and also retain their directions
6141
+
6142
+ :param start: start time step - 0-based
6143
+ :param end: end time step - 0-based
6144
+ :param every: step interval
6145
+ :param callback: optional callback to update progress
6146
+
6147
+ :return : tuple of WolfArray or WolfArrayMB - H, U_norm, U_x, U_y
6148
+ """
6149
+
6150
+ # Number of time steps
6151
+ number_of_time_steps = self.get_nbresults()
6152
+ if end ==-1:
6153
+ end = number_of_time_steps
6154
+
6155
+ # Init Danger Maps basde on results type
6156
+ # If only one block --> WolfArray
6157
+ # If only multiple blocks --> WolfArrayMB
6158
+ danger_map_matrix_h = self.as_WolfArray(copyarray=True)
6159
+ danger_map_matrix_v = self.as_WolfArray(copyarray=True)
6160
+ danger_map_matrix_vx = self.as_WolfArray(copyarray=True)
6161
+ danger_map_matrix_vy = self.as_WolfArray(copyarray=True)
6162
+
6163
+ danger_init = [danger_map_matrix_h, danger_map_matrix_v, danger_map_matrix_vx, danger_map_matrix_vy]
6164
+
6165
+ for curdanger in danger_init:
6166
+ curdanger.nullvalue = 0.
6167
+ curdanger.reset()
6168
+ curdanger.mask_reset()
6169
+
6170
+ to_compute = np.arange(start, end, every)
6171
+ #add the end
6172
+ if end not in to_compute:
6173
+ to_compute = np.append(to_compute, end)
6174
+ for time_step in tqdm(to_compute):
6175
+
6176
+ if callback is not None:
6177
+ callback(time_step, "Step {} / {}".format(time_step+1, end))
6178
+
6179
+ self.read_oneresult(time_step+1)
6180
+
6181
+ if self.nb_blocks>1:
6182
+ for curblock in self.myblocks.keys():
6183
+
6184
+ # Get WolfArray
6185
+ wd = self.get_h_for_block(curblock)
6186
+ qx = self.get_qx_for_block(curblock)
6187
+ qy = self.get_qy_for_block(curblock)
6188
+
6189
+ ij = np.where(~wd.array.mask)
6190
+
6191
+ v = np.zeros_like(wd.array)
6192
+ vy = np.zeros_like(wd.array)
6193
+ vx = np.zeros_like(wd.array)
6194
+
6195
+ v[ij] = ((qx.array[ij]**2.+qy.array[ij]**2.)**.5)/wd.array[ij]
6196
+ vy[ij] = qy.array[ij]/wd.array[ij]
6197
+ vx[ij] = qx.array[ij]/wd.array[ij]
6198
+
6199
+ # Comparison
6200
+ ij = np.where((danger_map_matrix_h.array < wd.array.data) & (~wd.array.mask))
6201
+ danger_map_matrix_h.array.data[ij] = wd.array[ij]
6202
+ danger_map_matrix_h.array.mask[ij] = False
6203
+
6204
+ # Comparison
6205
+ ij = np.where((danger_map_matrix_v.array < v) & (~wd.array.mask))
6206
+ danger_map_matrix_v.array.data[ij] = v[ij]
6207
+ danger_map_matrix_vx.array.data[ij] = vx[ij]
6208
+ danger_map_matrix_vy.array.data[ij] = vy[ij]
6209
+ danger_map_matrix_v.array.mask[ij] = False
6210
+ danger_map_matrix_vx.array.mask[ij] = False
6211
+ danger_map_matrix_vy.array.mask[ij] = False
6212
+
6213
+ else:
6214
+ curblock = getkeyblock(0)
6215
+ wd = self.get_h_for_block(curblock)
6216
+ qx = self.get_qx_for_block(curblock)
6217
+ qy = self.get_qy_for_block(curblock)
6218
+
6219
+ ij = np.where(~wd.array.mask)
6220
+
6221
+ v = np.zeros_like(wd.array)
6222
+ vy = np.zeros_like(wd.array)
6223
+ vx = np.zeros_like(wd.array)
6224
+
6225
+ v[ij] = ((qx.array[ij]**2.+qy.array[ij]**2.)**.5)/wd.array[ij]
6226
+ vy[ij] = qy.array[ij]/wd.array[ij]
6227
+ vx[ij] = qx.array[ij]/wd.array[ij]
6228
+
6229
+ # Comparison
6230
+ ij = np.where((danger_map_matrix_h.array < wd.array.data) & (~wd.array.mask))
6231
+ danger_map_matrix_h.array.data[ij] = wd.array[ij]
6232
+ danger_map_matrix_h.array.mask[ij] = False
6233
+
6234
+ # Comparison
6235
+ ij = np.where((danger_map_matrix_v.array < v) & (~wd.array.mask))
6236
+ danger_map_matrix_v.array.data[ij] = v[ij]
6237
+ danger_map_matrix_vx.array.data[ij] = vx[ij]
6238
+ danger_map_matrix_vy.array.data[ij] = vy[ij]
6239
+ danger_map_matrix_v.array.mask[ij] = False
6240
+ danger_map_matrix_vx.array.mask[ij] = False
6241
+ danger_map_matrix_vy.array.mask[ij] = False
6242
+
6243
+ danger_map_matrix_h.mask_lower(self.epsilon)
6244
+
6245
+ if self.nb_blocks>1:
6246
+ for i in range(self.nb_blocks):
6247
+ danger_map_matrix_v[i].array.mask[:,:] = danger_map_matrix_h[i].array.mask[:,:]
6248
+ danger_map_matrix_vx[i].array.mask[:,:] = danger_map_matrix_h[i].array.mask[:,:]
6249
+ danger_map_matrix_vy[i].array.mask[:,:] = danger_map_matrix_h[i].array.mask[:,:]
6250
+ else:
6251
+ danger_map_matrix_v.array.mask[:,:] = danger_map_matrix_h.array.mask[:,:]
6252
+ danger_map_matrix_vx.array.mask[:,:] = danger_map_matrix_h.array.mask[:,:]
6253
+ danger_map_matrix_vy.array.mask[:,:] = danger_map_matrix_h.array.mask[:,:]
6254
+
6255
+ return (danger_map_matrix_h, danger_map_matrix_v, danger_map_matrix_vx, danger_map_matrix_vy)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wolfhece
3
- Version: 2.2.23
3
+ Version: 2.2.24
4
4
  Author-email: Pierre Archambeau <pierre.archambeau@uliege.be>
5
5
  Project-URL: Homepage, https://uee.uliege.be/hece
6
6
  Project-URL: Issues, https://uee.uliege.be/hece
@@ -1,4 +1,4 @@
1
- wolfhece/Coordinates_operations.py,sha256=YyWlAwKManb-ReQrmP37rEXxehunUCihmkeDYX6qTAQ,8037
1
+ wolfhece/Coordinates_operations.py,sha256=KaIcP1b0IpKSLaynZgfvwkD6wsMKLmZo-kxeLfv9-8c,8101
2
2
  wolfhece/CpGrid.py,sha256=_piG1u-ua7NzWh_PHJYTmxuPJ43ZfeYKNEQgZIJwDJ8,10660
3
3
  wolfhece/GraphNotebook.py,sha256=2TR8qjEwpMtl34QWgYNVe_PgTnuwhUxT5f9Y2zrmN2U,28257
4
4
  wolfhece/GraphProfile.py,sha256=OCgJo0YFFBI6H1z-5egJsOOoWF_iziiza0-bbPejNMc,69656
@@ -8,7 +8,7 @@ wolfhece/Model1D.py,sha256=snEmu8Uj2YGcp1ybPnly-4A389XRnuOujGduqInNcgw,477001
8
8
  wolfhece/PandasGrid.py,sha256=YIleVkUkoP2MjtQBZ9Xgwk61zbgMj4Pmjj-clVTfPRs,2353
9
9
  wolfhece/PyConfig.py,sha256=Y0wtSIFpAMYa7IByh7hbW-WEOVjNsQEduq7vhIYdZQw,16716
10
10
  wolfhece/PyCrosssections.py,sha256=igU_ELrg5VrHU6RNbF5tHxPyVImpR3xdpfopJYc7haw,114711
11
- wolfhece/PyDraw.py,sha256=Okx2Uv4zOeCxtYYAGx6T7SGZh4taamdCMvZ6QqruLxE,655901
11
+ wolfhece/PyDraw.py,sha256=3ZKNrXhdHYNjuFKV47l7vHFMcqWElQUxDuM8XX1R5zk,662179
12
12
  wolfhece/PyGui.py,sha256=DqMTDsC9GthnMdYOXvkMKfl5pNciExVzxG4ogptWf6g,146010
13
13
  wolfhece/PyGuiHydrology.py,sha256=sKafpOopBg50L5llZCI_fZtbebVTDtxvoRI6-osUwhg,14745
14
14
  wolfhece/PyHydrographs.py,sha256=1P5XAURNqCvtSsMQXhOn1ihjTpr725sRsZdlCEhhk6M,3730
@@ -23,7 +23,7 @@ wolfhece/RatingCurve.py,sha256=bUjIrQjvIjkD4V-z8bZmA6pe1ILtYNM0-3fT6YUY1RU,22498
23
23
  wolfhece/RatingCurveData.py,sha256=5UvnIm89BwqjnEbLCcY3CA8WoFd_xHJbooNy62fX5iY,57660
24
24
  wolfhece/RatingCurve_xml.py,sha256=cUjReVMHFKtakA2wVey5zz6lCgHlSr72y7ZfswZDvTM,33891
25
25
  wolfhece/ReadDataDCENN.py,sha256=vm-I4YMryvRldjXTvRYEUCxZsjb_tM7U9yj6OaPyD0k,1538
26
- wolfhece/Results2DGPU.py,sha256=kVEbP61PfcsMwyJT1pvXgUxpPfVVxlP_8saXWzsYAbg,27021
26
+ wolfhece/Results2DGPU.py,sha256=GTu7PMuwfH-xH8J7sVr6zq2CTkGKF24fG1ujEW62PtM,31598
27
27
  wolfhece/__init__.py,sha256=Gd96hBcXEFUUssyRgJAGC1vCmNR30S66m_80KjcXzGA,946
28
28
  wolfhece/_add_path.py,sha256=mAyu85CQHk0KgUI6ZizweeQiw1Gdyea9OEjGLC6lLA4,916
29
29
  wolfhece/analyze_poly.py,sha256=jsCUsd0ZJtTwSk5hekcXj8i0tGhH-WCfNkrBtPRJpCc,12715
@@ -39,7 +39,7 @@ wolfhece/gpuview.py,sha256=Jql8pLZ0PpvZ_ScT-U4jsXANZ9j4-m_RWhsLA2HISuQ,24544
39
39
  wolfhece/images_tiles.py,sha256=w5BX6kRqA0wW9TWyKrJUIRl-XyqHclq_kp5ET2VA0Sg,3227
40
40
  wolfhece/import_ascfiles.py,sha256=6Zl8qBR9c6VtyziookQ8YE9KC0GtW_J9WFt5ubyGp-s,4465
41
41
  wolfhece/ins.py,sha256=uUeLMS1n3GPnfJhxl0Z2l-UXpmPUgthuwct282OOEzk,36184
42
- wolfhece/irm_qdf.py,sha256=DMdDEAYbgYxApObm6w-dZbBmA8ec6PghBLXR2lUEZLc,27457
42
+ wolfhece/irm_qdf.py,sha256=MjDn6dCaJ6JgeH0RkMiHqWXLPeTZ_Fd7nH_7q5jvbQg,30269
43
43
  wolfhece/ismember.py,sha256=fkLvaH9fhx-p0QrlEzqa6ySO-ios3ysjAgXVXzLgSpY,2482
44
44
  wolfhece/lagrange_multiplier.py,sha256=0G-M7b2tGzLx9v0oNYYq4_tLAiHcs_39B4o4W3TUVWM,6567
45
45
  wolfhece/lifewatch.py,sha256=Q_Wy6VGkrD-xxY0fv3PKpT8U8oXxNMgiLlrAE3bMheo,16340
@@ -60,13 +60,13 @@ wolfhece/rain_SPWMI.py,sha256=qCfcmF7LajloOaCwnTrrSMzyME03YyilmRUOqrPrv3U,13846
60
60
  wolfhece/textpillow.py,sha256=map7HsGYML_o5NHRdFg2s_TVQed_lDnpYNDv27MM0Vw,14130
61
61
  wolfhece/tools2d_dll.py,sha256=TfvvmyZUqEZIH0uHwUCJf0bdmCks_AiidDt23Unsp5w,13550
62
62
  wolfhece/tools_mpl.py,sha256=gQ3Jg1iuZiecmMqa5Eli2ZLSkttu68VXL8YmMDBaEYU,564
63
- wolfhece/wolf_array.py,sha256=avAoanXV6vcbOH4j2RjZuRmjarvbLE6MlXtKqHCWirs,517578
63
+ wolfhece/wolf_array.py,sha256=5TyRd6XEWDJHvXfPPgsFKbBFmZbQ-68wS57mHqymqrk,518644
64
64
  wolfhece/wolf_hist.py,sha256=fTEb60Q4TEwobdZsRU4CFXAId1eOKdWAqF8lnF1xEWc,3590
65
65
  wolfhece/wolf_texture.py,sha256=8BcVSezLEogTHYmtA4yfSPzaw6UpAeYYySVaAowIKtQ,20858
66
66
  wolfhece/wolf_tiles.py,sha256=v-HohqaWuMYdn75XLnA22dlloAG90iwnIqrgnB0ASQ4,10488
67
67
  wolfhece/wolf_vrt.py,sha256=wbxXVN7TL9zgdyF79S-4e3pje6wJEAgBEfF_Y8kkzxs,14271
68
68
  wolfhece/wolf_zi_db.py,sha256=baE0niMCzybWGSvPJc5FNxo9ZxsGfU4p-FmfiavFHAs,12967
69
- wolfhece/wolfresults_2D.py,sha256=iRTrukQntMfy2XUc2v4deNNJTZdboqEb_QvSjsu6bjM,240103
69
+ wolfhece/wolfresults_2D.py,sha256=0c3akPDFETE0Uq0JiZ0FZEx6Rxiy9JB5s9P6sDei0E0,245735
70
70
  wolfhece/xyz_file.py,sha256=1pzLFmmdHca4yBVR9Jitic6N82rY28mRytGC1zMbY28,6615
71
71
  wolfhece/acceptability/Parallels.py,sha256=2wVkfJYor4yl7VYiAZiGGTFwtAab2z66ZfRtBliVweE,4088
72
72
  wolfhece/acceptability/__init__.py,sha256=hfgoPKLDpX7drN1Vpvux-_5Lfyc_7feT2C2zQr5v-Os,258
@@ -82,13 +82,13 @@ wolfhece/apps/WolfPython2.png,sha256=VMPV-M-3BCOg8zOJss8bXwPmzRYZy8Fo-XtnVYNgbaw
82
82
  wolfhece/apps/WolfPython3.png,sha256=3G84zx14HnlB9YXMY4VUAO7IB3eu7JFvi4Kpmc_4zBE,403298
83
83
  wolfhece/apps/__init__.py,sha256=OzzKItATWV0mDkz_LC2L3w5sgT2rt8ExXXCbR_FwvlY,24
84
84
  wolfhece/apps/acceptability.py,sha256=hMIxTRNQARTTWJJaakb6kEK9udNh-w64VDgxxezVk3k,790
85
- wolfhece/apps/check_install.py,sha256=-lDn9mVS9Pq9b2jWT0uo-hqM6_IXwr0UrW0rWIEMJ9E,3992
85
+ wolfhece/apps/check_install.py,sha256=DmyFC5Thz29UFQlokD7dbhlWPDeWstiukcBPuXofnsk,9753
86
86
  wolfhece/apps/check_version.py,sha256=Zze7ltzcM2ZzIGMwkcASIjapCG8CEzzW9kwNscA3NhM,1768
87
87
  wolfhece/apps/curvedigitizer.py,sha256=lEJJwgAfulrrWQc-U6ij6sj59hWN3SZl4Yu1kQxVzzA,9106
88
88
  wolfhece/apps/hydrometry.py,sha256=lhhJsFeb4zGL4bNQTs0co85OQ_6ssL1Oy0OUJCzhfYE,656
89
89
  wolfhece/apps/isocurrent.py,sha256=dagmGR8ja9QQ1gwz_8fU-N052hIw-W0mWGVkzLu6C7I,4247
90
90
  wolfhece/apps/splashscreen.py,sha256=EdGDN9NhudIiP7c3gVqj7dp4MWFB8ySizM_tpMnsgpE,3091
91
- wolfhece/apps/version.py,sha256=geYky3SvOR_9WIk1PDzpLRmFH1-xzccADG2iDWg8JCc,388
91
+ wolfhece/apps/version.py,sha256=3qfyNsaI-v1qzANbydpCOlZTJHZhiWyeJf0VzXFEr_Y,388
92
92
  wolfhece/apps/wolf.py,sha256=mRnjYsUu4KIsRuamdQWAINFMuwN4eJgMo9erG-hkZ70,729
93
93
  wolfhece/apps/wolf2D.py,sha256=4z_OPQ3IgaLtjexjMKX9ppvqEYyjFLt1hcfFABy3-jU,703
94
94
  wolfhece/apps/wolf_logo.bmp,sha256=ruJ4MA51CpGO_AYUp_dB4SWKHelvhOvd7Q8NrVOjDJk,3126
@@ -227,7 +227,7 @@ wolfhece/mesh2d/config_manager.py,sha256=DcdxCIIs_dyC6ayJOBULeY364LONogL9PBaqBtC
227
227
  wolfhece/mesh2d/cst_2D_boundary_conditions.py,sha256=r43pHHdCtmNp5R2zh1Ckb7EzwQDf6C4YMLwRFTl4KMc,5006
228
228
  wolfhece/mesh2d/gpu_2d.py,sha256=GGOAW3c3c2CKtDyxSJJdX_1A1QfMFC5CU4MjzhAbR5o,25551
229
229
  wolfhece/mesh2d/simple_2d.py,sha256=wqENJwpUPxKQcpGIcymQXUj2KgkGWCVH6cs4Os9h9Gs,112581
230
- wolfhece/mesh2d/wolf2dprev.py,sha256=N50tmed97OgNATEp9DPEXQlcbqy3fjWkvAvyhmTsWmI,493023
230
+ wolfhece/mesh2d/wolf2dprev.py,sha256=oK9r94CYJaeOBSv4s4mkuhLA8rCsnrkjG2sGW_zR1x0,493127
231
231
  wolfhece/models/5_coul.pal,sha256=OI1UqcNIDBpJn2k_VDel__r-hKjjvdob0eqinGCI3QY,160
232
232
  wolfhece/models/6_coul.pal,sha256=z7NK2dg0tAQBUweRQV54dIwJbPM1U5y1AR2LLw19Idw,148
233
233
  wolfhece/models/7_coul.pal,sha256=XTnnUyCE8ONokScB2YzYDnSTft7E6sppmr7P-XwMsCE,205
@@ -300,8 +300,8 @@ wolfhece/ui/wolf_multiselection_collapsiblepane.py,sha256=8PlMYrb_8jI8h9F0_EagpM
300
300
  wolfhece/ui/wolf_times_selection_comparison_models.py,sha256=ORy7fz4dcp691qKzaOZHrRLZ0uXNhL-LIHxmpDGL6BI,5007
301
301
  wolfhece/wintab/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
302
302
  wolfhece/wintab/wintab.py,sha256=8A-JNONV6ujgsgG3lM5Uw-pVgglPATwKs86oBzzljoc,7179
303
- wolfhece-2.2.23.dist-info/METADATA,sha256=Rol51FGEuEGXU8Pxmu4d5jXHO5uH1jOg_WrBNa3jNzU,2729
304
- wolfhece-2.2.23.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
305
- wolfhece-2.2.23.dist-info/entry_points.txt,sha256=Jr187pyvA3EeJiQLjZK9yo6mJX7IAn6ygZU9T8qF_gQ,658
306
- wolfhece-2.2.23.dist-info/top_level.txt,sha256=EfqZXMVCn7eILUzx9xsEu2oBbSo9liWPFWjIHik0iCI,9
307
- wolfhece-2.2.23.dist-info/RECORD,,
303
+ wolfhece-2.2.24.dist-info/METADATA,sha256=JLouSaSwr1t-Z7Z5N97nSIHCJjjhAyKHUlToNAHGAAA,2729
304
+ wolfhece-2.2.24.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
305
+ wolfhece-2.2.24.dist-info/entry_points.txt,sha256=Jr187pyvA3EeJiQLjZK9yo6mJX7IAn6ygZU9T8qF_gQ,658
306
+ wolfhece-2.2.24.dist-info/top_level.txt,sha256=EfqZXMVCn7eILUzx9xsEu2oBbSo9liWPFWjIHik0iCI,9
307
+ wolfhece-2.2.24.dist-info/RECORD,,