wolfhece 2.1.15__py3-none-any.whl → 2.1.17__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.
wolfhece/PyDraw.py CHANGED
@@ -852,6 +852,13 @@ class WolfMapViewer(wx.Frame):
852
852
  # self.menu2d_bc = self.menuwolf2d.Append(wx.ID_ANY, _("Manage boundary conditions..."), _("BC manager"))
853
853
  self.menu2d_video = self.menuwolf2d.Append(wx.ID_ANY, _("Create video..."), _("Video/Movie"))
854
854
 
855
+ self.menuwolf2d.AppendSeparator()
856
+
857
+ self.menu2d_dangermap = self.menuwolf2d.Append(wx.ID_ANY, _("Danger map"), _("Compute the danger map"))
858
+ self.menu2d_dangermaph = self.menuwolf2d.Append(wx.ID_ANY, _("Danger map - only h"), _("Compute the danger map"))
859
+
860
+ self.menuwolf2d.AppendSeparator()
861
+
855
862
  self.menubar.Append(self.menuwolf2d, _('Results 2D'))
856
863
 
857
864
  self.menuwolf2d.Bind(wx.EVT_MENU, self.Onmenuwolf2d)
@@ -1182,6 +1189,82 @@ class WolfMapViewer(wx.Frame):
1182
1189
  if self.active_res2d is not None:
1183
1190
  self.create_video()
1184
1191
 
1192
+ elif itemlabel == _("Danger map - only h"):
1193
+ if self.active_res2d is None:
1194
+ logging.warning(_('No active 2D result !'))
1195
+ return
1196
+
1197
+ with wx.NumberEntryDialog(None, _('Danger map'), _('From step'), _('Danger map'), 1, 1, self.active_res2d.get_nbresults()) as dlg:
1198
+
1199
+ if dlg.ShowModal() == wx.ID_CANCEL:
1200
+ return
1201
+
1202
+ start_step = dlg.GetValue()
1203
+
1204
+ with wx.NumberEntryDialog(None, _('Danger map'), _('To step'), _('Danger map'), self.active_res2d.get_nbresults(), start_step, self.active_res2d.get_nbresults()) as dlg:
1205
+
1206
+ if dlg.ShowModal() == wx.ID_CANCEL:
1207
+ return
1208
+
1209
+ end_step = dlg.GetValue()
1210
+
1211
+ with wx.NumberEntryDialog(None, _('Danger map'), _('Every'), _('Danger map'), 1, 1, 60) as dlg:
1212
+
1213
+ if dlg.ShowModal() == wx.ID_CANCEL:
1214
+ return
1215
+
1216
+ every = dlg.GetValue()
1217
+
1218
+ danger_map = self.active_res2d.danger_map_only_h(start_step-1, end_step-1, every)
1219
+
1220
+ with wx.DirDialog(None, _('Choose a directory'), style=wx.DD_DEFAULT_STYLE) as dlg:
1221
+
1222
+ if dlg.ShowModal() == wx.ID_CANCEL:
1223
+ return
1224
+
1225
+ outdir = dlg.GetPath()
1226
+
1227
+ danger_map.write_all(Path(outdir) / 'danger_h.tif')
1228
+
1229
+ elif itemlabel == _("Danger map"):
1230
+ if self.active_res2d is None:
1231
+ logging.warning(_('No active 2D result !'))
1232
+ return
1233
+
1234
+ with wx.NumberEntryDialog(None, _('Danger map'), _('From step'), _('Danger map'), 1, 1, self.active_res2d.get_nbresults()) as dlg:
1235
+
1236
+ if dlg.ShowModal() == wx.ID_CANCEL:
1237
+ return
1238
+
1239
+ start_step = dlg.GetValue()
1240
+
1241
+ with wx.NumberEntryDialog(None, _('Danger map'), _('To step'), _('Danger map'), self.active_res2d.get_nbresults(), start_step, self.active_res2d.get_nbresults()) as dlg:
1242
+
1243
+ if dlg.ShowModal() == wx.ID_CANCEL:
1244
+ return
1245
+
1246
+ end_step = dlg.GetValue()
1247
+
1248
+ with wx.NumberEntryDialog(None, _('Danger map'), _('Every'), _('Danger map'), 1, 1, 60) as dlg:
1249
+
1250
+ if dlg.ShowModal() == wx.ID_CANCEL:
1251
+ return
1252
+
1253
+ every = dlg.GetValue()
1254
+
1255
+ danger_maps = self.active_res2d.danger_map(start_step-1, end_step-1, every)
1256
+
1257
+ with wx.DirDialog(None, _('Choose a directory'), style=wx.DD_DEFAULT_STYLE) as dlg:
1258
+
1259
+ if dlg.ShowModal() == wx.ID_CANCEL:
1260
+ return
1261
+
1262
+ outdir = dlg.GetPath()
1263
+
1264
+ names = ['danger_h.tif', 'danger_u.tif', 'danger_q.tif']
1265
+ for name, danger_map in zip(names, danger_maps):
1266
+ danger_map.write_all(Path(outdir) / name)
1267
+
1185
1268
  elif itemlabel == _("Setup cache..."):
1186
1269
 
1187
1270
  if self.active_res2d is None:
@@ -3,6 +3,9 @@ import wx
3
3
  from .PyTranslate import _
4
4
  from .PyDraw import WolfMapViewer
5
5
  from .RatingCurve import *
6
+ from.PyVertexvectors import vector, Zones, zone, getIfromRGB, getRGBfromI
7
+
8
+ import logging
6
9
 
7
10
 
8
11
  class selectpoint(wx.Frame):
@@ -112,32 +115,62 @@ class selectpoint(wx.Frame):
112
115
 
113
116
 
114
117
  class GuiHydrology(WolfMapViewer):
118
+ """ Mapviewer of the hydrology model -- see HydrologyModel in PyGui.py """
119
+
120
+ def __init__(self, parent=None, title='WOLF Hydrological model - viewer', w=500, h=500, treewidth=200, wolfparent=None, wxlogging=None):
121
+ """ Constructor
122
+
123
+ :param parent: parent window - wx.Frame
124
+ :param title: title of the window - str
125
+ :param w: width of the window - int
126
+ :param h: height of the window - int
127
+ :param treewidth: width of the tree - int
128
+ :param wolfparent: wolf parent instance -- PyGui.HydrologyModel
129
+ :type wolfparent: HydrologyModel
130
+ :param wxlogging: logging instance -- PyGui.WolfLog
131
+ """
115
132
 
116
- def __init__(self, parent=None, title='MyForm', w=500, h=500, treewidth=200, wolfparent=None, wxlogging=None):
117
133
  super(GuiHydrology, self).__init__(parent, title=title, w=w, h=h,
118
- treewidth=treewidth, wolfparent=wolfparent,wxlogging=wxlogging)
134
+ treewidth=treewidth,
135
+ wolfparent=wolfparent,
136
+ wxlogging=wxlogging)
119
137
 
120
- self.parent = parent
138
+ from .PyGui import HydrologyModel
121
139
 
122
- self.filemenu.Insert(0, 1100, _('New from scratch'), _('Create a new simulation from scratch...'))
140
+ self.wolfparent:HydrologyModel
123
141
 
124
- self.toolsmenu = wx.Menu()
125
- self.toolsmenu.Append(1200, _('Forced exchanges'), _('Manage the forced exchanges...'))
126
- self.toolsmenu.Append(1201, _('Crop MNT/MNS'), _('Cropping data...'))
127
- self.toolsmenu.Append(1202, _('Crop land use (COSW)'), _('Cropping data...'))
128
- self.toolsmenu.Append(1205, _('Analyze slope'), _('Slope analyzer...'))
129
- self.toolsmenu.Append(1203, _('IRM - QDF'), _('Manage data...'))
130
- self.toolsmenu.Append(1204, _('SPW - Hydrometry'), _('Manage data...'))
131
- self.menubar.Append(self.toolsmenu, _('&Tools'))
142
+ # self.filemenu.Insert(0, wx.ID_ANY, _('New from scratch'), _('Create a new simulation from scratch...'))
132
143
 
133
144
  self.modelmenu = wx.Menu()
134
- paramgen = self.modelmenu.Append(1500, _('New'), _('Wizard !'))
135
- paramgen = self.modelmenu.Append(1501, _('Interior points'), _('Interior points'))
136
- paramgen = self.modelmenu.Append(1502, _('Topology'), _('Topology manager'))
137
- paramgen = self.modelmenu.Append(1503, _('Main model'), _('General parameters'))
138
- paramgen = self.modelmenu.Append(1504, _('Basin'), _('Basin parameters'))
139
- paramgen = self.modelmenu.Append(1505, _('Subbasins'), _('Sub-Basin parameters'))
140
- self.menubar.Append(self.modelmenu, _('&Model'))
145
+ paramgen = self.modelmenu.Append(wx.ID_ANY, _('Choose outlet'), _('Wizard !'))
146
+ paramgen = self.modelmenu.Append(wx.ID_ANY, _('Interior points'), _('Interior points'))
147
+ paramgen = self.modelmenu.Append(wx.ID_ANY, _('Topology'), _('Topology manager'))
148
+ paramgen = self.modelmenu.Append(wx.ID_ANY, _('Main model'), _('General parameters'))
149
+ paramgen = self.modelmenu.Append(wx.ID_ANY, _('Basin'), _('Basin parameters'))
150
+ paramgen = self.modelmenu.Append(wx.ID_ANY, _('Subbasins'), _('Sub-Basin parameters'))
151
+ self.menubar.Append(self.modelmenu, _('&Hydrological model'))
152
+
153
+ self.toolsmenu = wx.Menu()
154
+ self.toolsmenu.Append(wx.ID_ANY, _('Forced exchanges'), _('Manage the forced exchanges...'))
155
+ self.toolsmenu.Append(wx.ID_ANY, _('Crop MNT/MNS'), _('Cropping data...'))
156
+ self.toolsmenu.Append(wx.ID_ANY, _('Crop land use (COSW)'), _('Cropping data...'))
157
+ self.toolsmenu.Append(wx.ID_ANY, _('Analyze slope'), _('Slope analyzer...'))
158
+ self.toolsmenu.Append(wx.ID_ANY, _('IRM - QDF'), _('Manage data...'))
159
+
160
+ self.toolsmenu.AppendSeparator()
161
+
162
+ self.toolsmenu.Append(wx.ID_ANY, _('Find upstream watershed'), _('Find upstream watershed based on click...'))
163
+ self.toolsmenu.Append(wx.ID_ANY, _('Find upstream watershed - limit to sub'), _('Find upstream watershed based on click but limit to subbasin...'))
164
+
165
+ self.toolsmenu.AppendSeparator()
166
+
167
+ self.toolsmenu.Append(wx.ID_ANY, _('Select upstream watershed'), _('Select upstream watershed based on click...'))
168
+ self.toolsmenu.Append(wx.ID_ANY, _('Select upstream watershed - limit to sub'), _('Select upstream watershed based on click but limit to subbasin...'))
169
+ self.toolsmenu.Append(wx.ID_ANY, _('Select upstream rivers'), _('Select upstream rivers based on click...'))
170
+ self.toolsmenu.Append(wx.ID_ANY, _('Select upstream rivers - limit to sub'), _('Select upstream rivers based on click but limit to subbasin...'))
171
+ self.toolsmenu.Append(wx.ID_ANY, _('Select downstream rivers'), _('Select downstream rivers based on click...'))
172
+
173
+ self.menubar.Append(self.toolsmenu, _('&Tools Hydrology'))
141
174
 
142
175
  # self.computemenu = wx.Menu()
143
176
  # paramgen = self.computemenu.Append(1300,_('Calibration/Optimisation'),_('Parameters calibration of the model'))
@@ -149,23 +182,169 @@ class GuiHydrology(WolfMapViewer):
149
182
  # paramgen = self.resultsmenu.Append(1401,_('Plot'),_('Plot'))
150
183
  # self.menubar.Append(self.resultsmenu,_('&Results'))
151
184
 
185
+ @property
186
+ def watershed(self):
187
+
188
+ if self.wolfparent is None:
189
+ return None
190
+
191
+ if self.wolfparent.mycatchment is None:
192
+ return None
193
+
194
+ return self.wolfparent.mycatchment.charact_watrshd
195
+
152
196
  def OnMenubar(self, event):
197
+ """ Event handler for the menubar """
153
198
 
199
+ # Call the parent event handler
154
200
  super().OnMenubar(event)
155
201
 
202
+ # If not handled by the parent, handle it here
203
+
156
204
  id = event.GetId()
157
205
  item = self.menubar.FindItemById(id)
206
+ if item is None:
207
+ return
208
+
209
+ itemlabel = item.ItemLabel
158
210
 
159
- if id == wx.ID_EXECUTE:
160
- print(_('Do anything !!'))
161
- elif id == 1503:
162
- self.parent.mainparams.Show()
163
- elif id == 1504:
164
- self.parent.basinparams.Show()
165
- # elif id==1300:
166
- # self.myoptimisation = Optimisation()
167
- # self.myoptimisation.Show()
168
- elif id == 1500:
169
- myselect = selectpoint(title=_('Outlet'), SPWstations=self.parent.SPWstations,
170
- DCENNstations=self.parent.DCENNstations)
211
+ if itemlabel == _('Choose outlet'):
212
+ myselect = selectpoint(title=_('Outlet'),
213
+ SPWstations=self.wolfparent.SPWstations,
214
+ DCENNstations=self.wolfparent.DCENNstations)
171
215
  myselect.Show()
216
+
217
+ elif itemlabel == _('Interior points'):
218
+ logging.warning(_('Not yet implemented !'))
219
+
220
+ elif itemlabel == _('Topology'):
221
+ logging.warning(_('Not yet implemented !'))
222
+
223
+ elif itemlabel == _('Main model'):
224
+ self.wolfparent.mainparams.Show()
225
+
226
+ elif itemlabel == _('Basin'):
227
+ self.wolfparent.basinparams.Show()
228
+
229
+ elif itemlabel == _('Subbasins'):
230
+ logging.warning(_('Not yet implemented !'))
231
+
232
+ elif itemlabel == _('Forced exchanges'):
233
+ logging.warning(_('Not yet implemented !'))
234
+
235
+ elif itemlabel == _('Crop MNT/MNS'):
236
+ logging.warning(_('Not yet implemented !'))
237
+
238
+ elif itemlabel == _('Crop land use (COSW)'):
239
+ logging.warning(_('Not yet implemented !'))
240
+
241
+ elif itemlabel == _('Analyze slope'):
242
+ logging.warning(_('Not yet implemented !'))
243
+
244
+ elif itemlabel == _('IRM - QDF'):
245
+ logging.warning(_('Not yet implemented !'))
246
+
247
+ elif itemlabel == _('Find upstream watershed'):
248
+ self.action = 'Find upstream watershed'
249
+
250
+ elif itemlabel == _('Find upstream watershed - limit to sub'):
251
+ self.action = 'Find upstream watershed - limit to sub'
252
+
253
+ elif itemlabel == _('Select upstream watershed'):
254
+ self.action = 'Select upstream watershed'
255
+
256
+ elif itemlabel == _('Select upstream watershed - limit to sub'):
257
+ self.action = 'Select upstream watershed - limit to sub'
258
+
259
+ elif itemlabel == _('Select upstream rivers'):
260
+ self.action = 'Select upstream rivers'
261
+
262
+ elif itemlabel == _('Select upstream rivers - limit to sub'):
263
+ self.action = 'Select upstream rivers - limit to sub'
264
+
265
+ elif itemlabel == _('Select downstream rivers'):
266
+ self.action = 'Select downstream rivers'
267
+
268
+
269
+ def OnRightDown(self, e: wx.MouseEvent):
270
+
271
+ # Call the parent event handler
272
+ super().OnRightDown(e)
273
+
274
+ if self.action is None:
275
+ logging.info(_('No action selected !'))
276
+ return
277
+
278
+ if self.action == '':
279
+ logging.info(_('No action selected !'))
280
+ return
281
+
282
+ pos = e.GetPosition()
283
+ x, y = self.getXY(pos)
284
+
285
+ alt = e.AltDown()
286
+ ctrl = e.ControlDown()
287
+ shiftdown = e.ShiftDown()
288
+
289
+ if self.active_array is None:
290
+ logging.warning(_('No active array !'))
291
+ return
292
+
293
+ if not (self.active_array.dx == self.watershed.header.dx and self.active_array.dy == self.watershed.header.dy):
294
+ logging.warning(_('Active array and watershed do not have the same resolution !'))
295
+ return
296
+
297
+ if 'Find upstream watershed' in self.action:
298
+
299
+ starting_node = self.watershed.get_node_from_xy(x,y)
300
+ up_vect = self.watershed.get_vector_from_upstream_node(starting_node, limit_to_sub='limit to sub' in self.action)
301
+
302
+ if up_vect is None:
303
+ logging.warning(_('No upstream watershed found !'))
304
+ return
305
+
306
+ def props_vec(vec:vector):
307
+ vec.myprop.color = getIfromRGB((255,0,0))
308
+ vec.myprop.width = 3
309
+ vec.myprop.transparent = False
310
+ vec.myprop.alpha = 122
311
+ vec.myprop.filled = False
312
+
313
+ if self.active_array.Operations is not None:
314
+ newzone = zone(name = str(starting_node.sub))
315
+
316
+ self.active_array.Operations.show_structure_OpsVectors()
317
+ self.active_array.Operations.myzones.add_zone(newzone, forceparent=True)
318
+ newzone.add_vector(up_vect, forceparent=True)
319
+
320
+ props_vec(up_vect)
321
+
322
+ self.active_array.Operations.myzones.prep_listogl()
323
+ self.active_array.Operations.myzones.fill_structure()
324
+
325
+ self.Refresh()
326
+ else:
327
+ logging.warning(_('No operations frame in the active array!'))
328
+
329
+ elif 'Select upstream watershed' in self.action:
330
+
331
+ xy = self.watershed.get_xy_upstream_node(self.watershed.get_node_from_xy(x,y), limit_to_sub='limit to sub' in self.action)
332
+ self.active_array.SelectionData.set_selection_from_list_xy(xy)
333
+ self.Refresh()
334
+
335
+ elif 'Select upstream rivers' in self.action:
336
+
337
+ xy = self.watershed.get_xy_upstream_node(self.watershed.get_node_from_xy(x,y),
338
+ limit_to_sub='limit to sub' in self.action,
339
+ limit_to_river=True)
340
+
341
+ self.active_array.SelectionData.set_selection_from_list_xy(xy)
342
+ self.Refresh()
343
+
344
+ elif 'Select downstream rivers' in self.action:
345
+
346
+ xy = self.watershed.get_xy_downstream_node(self.watershed.get_node_from_xy(x,y))
347
+ self.active_array.SelectionData.set_selection_from_list_xy(xy)
348
+ self.Refresh()
349
+
350
+
wolfhece/PyParams.py CHANGED
@@ -927,6 +927,7 @@ class Wolf_Param(wx.Frame):
927
927
  # priority to default parameters
928
928
  if key_Param.ADDED_JSON in param_def.keys():
929
929
  param[key_Param.ADDED_JSON] = param_def[key_Param.ADDED_JSON]
930
+
930
931
  param[key_Param.COMMENT] = param_def[key_Param.COMMENT]
931
932
  param[key_Param.TYPE] = param_def[key_Param.TYPE]
932
933
 
@@ -1223,6 +1224,7 @@ class Wolf_Param(wx.Frame):
1223
1224
  # PARAMETRE
1224
1225
  # ---------
1225
1226
  curparam = self._add_param_from_str(param, groupname, groupdict)
1227
+ curparam[key_Param.ADDED_JSON]=None
1226
1228
 
1227
1229
  def _CreateDefaultFile(self):
1228
1230
  """ Create a default file """
@@ -2266,7 +2268,8 @@ class Wolf_Param(wx.Frame):
2266
2268
  self.myparams[curGroup][curParam][key_Param.TYPE] = templateDict[key_Param.TYPE]
2267
2269
  if key_Param.ADDED_JSON in templateDict:
2268
2270
  self.myparams[curGroup][curParam][key_Param.ADDED_JSON] = templateDict[key_Param.ADDED_JSON]
2269
-
2271
+ else:
2272
+ self.myparams[curGroup][curParam][key_Param.ADDED_JSON] = None
2270
2273
  # transfert des paramètres en surplus dans le dictionnaire savedDict
2271
2274
  for i in range(nbElements+1, iterMax+1):
2272
2275
  curParam = curIncParam.replace("$n$",str(i))
@@ -729,6 +729,10 @@ class vectorproperties:
729
729
  try:
730
730
  if updateOGL:
731
731
  self.parent.parentzone.prep_listogl()
732
+
733
+ if self.parent.parentzone.parent is None:
734
+ logging.critical('Problem with OpenGL update - parent/mapviewer is None -- Track this issue')
735
+
732
736
  self.parent.parentzone.parent.mapviewer.Refresh()
733
737
  except:
734
738
  logging.warning('Problem with OpenGL update - vectorproperties.fill_property')
wolfhece/RatingCurve.py CHANGED
@@ -501,13 +501,13 @@ class SPWMIGaugingStations(Element_To_Draw):
501
501
  self.ymin = min(y)
502
502
  self.ymax = max(y)
503
503
 
504
- def _plot(self, size:float=10.):
505
- for curstation in self.mystations.values:
504
+ def _plot(self, sx=None, sy=None, xmin=None, ymin=None, xmax=None, ymax=None, size:float=10.):
505
+ for curstation in self.mystations.values():
506
506
  curstation.plot(size)
507
507
 
508
508
  class SPWDCENNGaugingStations(Element_To_Draw):
509
509
 
510
- mystations:dict
510
+ mystations:dict[int:gaugingstation]
511
511
  myrivers:dict
512
512
  gaugings:SPWGaugings
513
513
  hrefs:SPWhrefs
@@ -633,6 +633,18 @@ class SPWDCENNGaugingStations(Element_To_Draw):
633
633
 
634
634
  pass
635
635
 
636
- def plot(self,size:float=10.):
637
- for id in self.mystations:
638
- self.mystations[id].plot(size)
636
+ def plot(self, sx=None, sy=None, xmin=None, ymin=None, xmax=None, ymax=None, size:float=10.):
637
+ self._plot(size)
638
+
639
+ def find_minmax(self,update=False):
640
+ x = [cur.x for cur in self.mystations.values()]
641
+ y = [cur.y for cur in self.mystations.values()]
642
+
643
+ self.xmin = min(x)
644
+ self.xmax = max(x)
645
+ self.ymin = min(y)
646
+ self.ymax = max(y)
647
+
648
+ def _plot(self, size:float=10.):
649
+ for curstation in self.mystations.values():
650
+ curstation.plot(size)
wolfhece/Results2DGPU.py CHANGED
@@ -380,24 +380,94 @@ class wolfres2DGPU(Wolfresults_2D):
380
380
  else:
381
381
  _, _, _, _, wd_np, qx_np, qy_np = self._result_store.get_result(which+1)
382
382
  else:
383
- _, _, _, _, wd_np, qx_np, qy_np = self._result_store.get_result(which+1)
383
+ __, __, __, __, wd_np, qx_np, qy_np = self._result_store.get_result(which+1)
384
+
385
+ wd_np = wd_np.T
386
+ qx_np = qx_np.T
387
+ qy_np = qy_np.T
384
388
 
385
389
  curblock = self.myblocks[getkeyblock(1,False)]
390
+
391
+ curblock.waterdepth.array.data[:,:] = curblock.waterdepth.nullvalue
392
+ curblock.qx.array.data[:,:] = curblock.qx.nullvalue
393
+ curblock.qy.array.data[:,:] = curblock.qy.nullvalue
394
+
395
+ curblock.waterdepth.array.mask[:,:] = True
396
+ curblock.qx.array.mask[:,:] = True
397
+ curblock.qy.array.mask[:,:] = True
398
+
386
399
  if self.epsilon > 0.:
387
- curblock.waterdepth.array=ma.masked_less_equal(wd_np.astype(np.float32).T, self.epsilon)
400
+ # curblock.waterdepth.array=ma.masked_less_equal(wd_np.astype(np.float32).T, self.epsilon)
401
+
402
+ ij = np.where(wd_np >= self.epsilon)
403
+ curblock.waterdepth.array.data[ij] = wd_np[ij]
404
+ curblock.waterdepth.array.mask[ij] = False
388
405
  else:
389
- curblock.waterdepth.array=ma.masked_equal(wd_np.astype(np.float32).T, 0.)
406
+ # curblock.waterdepth.array=ma.masked_equal(wd_np.astype(np.float32).T, 0.)
407
+
408
+ ij = np.where(wd_np > 0.)
409
+ curblock.waterdepth.array.data[ij] = wd_np[ij]
410
+ curblock.waterdepth.array.mask[ij] = False
411
+
412
+ # curblock.qx.array=ma.masked_where(curblock.waterdepth.array.mask,qx_np.astype(np.float32).T)
413
+ # curblock.qy.array=ma.masked_where(curblock.waterdepth.array.mask,qy_np.astype(np.float32).T)
390
414
 
391
- curblock.qx.array=ma.masked_where(curblock.waterdepth.array.mask,qx_np.astype(np.float32).T)
392
- curblock.qy.array=ma.masked_where(curblock.waterdepth.array.mask,qy_np.astype(np.float32).T)
415
+ curblock.qx.array.data[ij] = qx_np[ij]
416
+ curblock.qy.array.data[ij] = qy_np[ij]
417
+
418
+ curblock.qx.array.mask[ij] = False
419
+ curblock.qy.array.mask[ij] = False
393
420
 
394
421
  curblock.waterdepth.count()
395
422
  curblock.qx.count()
396
423
  curblock.qy.count()
397
424
 
398
- curblock.waterdepth.set_nullvalue_in_mask()
399
- curblock.qx.set_nullvalue_in_mask()
400
- curblock.qy.set_nullvalue_in_mask()
425
+ # curblock.waterdepth.set_nullvalue_in_mask()
426
+ # curblock.qx.set_nullvalue_in_mask()
427
+ # curblock.qy.set_nullvalue_in_mask()
428
+
429
+ if self.to_filter_independent:
430
+ self.filter_independent_zones()
431
+
432
+ self.current_result = which
433
+ self.loaded=True
434
+
435
+ def _read_oneresult_only_h(self, which:int=-1):
436
+ """
437
+ Lecture d'un pas de sauvegarde
438
+
439
+ which: result number to read; 0-based; -1 == last one
440
+ """
441
+
442
+ which = self._sanitize_result_step(which)
443
+
444
+ # stored result files are 1-based -> which+1
445
+ if self._cache is not None:
446
+ if (which >= self._cache.start_idx and which < self._cache.end_idx):
447
+ wd_np = self._cache.get_h(which+1, True)
448
+ else:
449
+ _, _, _, _, wd_np, qx_np, qy_np = self._result_store.get_result(which+1)
450
+ else:
451
+ __, __, __, __, wd_np, qx_np, qy_np = self._result_store.get_result(which+1)
452
+
453
+ wd_np = wd_np.T
454
+
455
+ curblock = self.myblocks[getkeyblock(1,False)]
456
+
457
+ curblock.waterdepth.array.data[:,:] = curblock.waterdepth.nullvalue
458
+
459
+ curblock.waterdepth.array.mask[:,:] = True
460
+
461
+ if self.epsilon > 0.:
462
+ ij = np.where(wd_np >= self.epsilon)
463
+ curblock.waterdepth.array.data[ij] = wd_np[ij]
464
+ curblock.waterdepth.array.mask[ij] = False
465
+ else:
466
+ ij = np.where(wd_np > 0.)
467
+ curblock.waterdepth.array.data[ij] = wd_np[ij]
468
+ curblock.waterdepth.array.mask[ij] = False
469
+
470
+ curblock.waterdepth.count()
401
471
 
402
472
  if self.to_filter_independent:
403
473
  self.filter_independent_zones()
wolfhece/apps/version.py CHANGED
@@ -5,7 +5,7 @@ class WolfVersion():
5
5
 
6
6
  self.major = 2
7
7
  self.minor = 1
8
- self.patch = 15
8
+ self.patch = 17
9
9
 
10
10
  def __str__(self):
11
11
 
@@ -130,6 +130,33 @@ class Node_Watershed:
130
130
 
131
131
  return np.sqrt(pow(self.x-x,2)+pow(self.y-y,2))
132
132
 
133
+ def get_up_nodes(self, excluded_node:list["Node_Watershed"]=[]):
134
+ """
135
+ Get all upstream nodes
136
+ """
137
+
138
+ all_up = [self]
139
+ all_rivers = [self] if self.river else []
140
+ all_runoff = [] if self.river else [self]
141
+
142
+ for curup in self.up:
143
+
144
+ if curup in excluded_node:
145
+ continue
146
+
147
+ all_up.append(curup)
148
+ if curup.river:
149
+ all_rivers.append(curup)
150
+ else:
151
+ all_runoff.append(curup)
152
+
153
+ up, river, runoff = curup.get_up_nodes(excluded_node)
154
+ all_up.extend(up)
155
+ all_rivers.extend(river)
156
+ all_runoff.extend(runoff)
157
+
158
+ return all_up, all_rivers, all_runoff
159
+
133
160
  def get_up_nodes_same_sub(self, excluded_node:list["Node_Watershed"]=[]):
134
161
  """
135
162
  Get all upstream nodes in the same sub-basin
@@ -162,30 +189,50 @@ class Node_Watershed:
162
189
 
163
190
  return all_up, all_rivers, all_runoff
164
191
 
192
+ def get_up_runoff_nodes(self):
193
+ """
194
+ Get all upstream runoff nodes
195
+ """
196
+
197
+ all_up = [self]
198
+ for curup in self.up:
199
+ if not curup.river:
200
+ all_up += curup.get_up_runoff_nodes()
201
+
202
+ return all_up
203
+
165
204
  def get_up_runoff_nodes_same_sub(self):
166
205
  """
167
206
  Get all upstream runoff nodes in the same sub-basin
168
207
  """
169
208
 
170
- all_up = []
209
+ all_up = [self]
171
210
  for curup in self.up:
172
211
  if curup.sub == self.sub and not curup.river:
173
- all_up.append(curup)
174
-
175
212
  all_up += curup.get_up_runoff_nodes_same_sub()
176
213
 
177
214
  return all_up
178
215
 
216
+
217
+ def get_up_rivernodes(self):
218
+ """
219
+ Get all upstream river nodes
220
+ """
221
+
222
+ all_up = [self]
223
+ for curup in self.upriver:
224
+ all_up += curup.get_up_rivernodes()
225
+
226
+ return all_up
227
+
179
228
  def get_up_rivernodes_same_sub(self):
180
229
  """
181
230
  Get all upstream river nodes in the same sub-basin
182
231
  """
183
232
 
184
- all_up = []
233
+ all_up = [self]
185
234
  for curup in self.upriver:
186
235
  if curup.sub == self.sub:
187
- all_up.append(curup)
188
-
189
236
  all_up += curup.get_up_rivernodes_same_sub()
190
237
 
191
238
  return all_up
@@ -214,6 +261,28 @@ class Node_Watershed:
214
261
 
215
262
  return np.unique(all_down).tolist()
216
263
 
264
+ def get_down_nodes(self):
265
+ """
266
+ Get all downstream nodes
267
+ """
268
+
269
+ all_down = [self]
270
+ if self.down is not None:
271
+ all_down += self.down.get_down_nodes()
272
+
273
+ return all_down
274
+
275
+ def get_down_nodes_same_sub(self):
276
+ """
277
+ Get all downstream nodes in the same sub-basin
278
+ """
279
+
280
+ all_down = [self]
281
+ if self.down is not None:
282
+ if self.down.sub == self.sub:
283
+ all_down += self.down.get_down_nodes_same_sub()
284
+
285
+ return all_down
217
286
 
218
287
  class RiverSystem:
219
288
  """
@@ -1716,6 +1785,102 @@ class Watershed:
1716
1785
 
1717
1786
  return newsub
1718
1787
 
1788
+ def get_xy_downstream_node(self,
1789
+ starting_node:Node_Watershed,
1790
+ limit_to_sub:bool = False):
1791
+ """
1792
+ Récupération des coordonnées du noeud aval
1793
+ """
1794
+
1795
+ if limit_to_sub:
1796
+ down = starting_node.get_down_nodes_same_sub()
1797
+ else:
1798
+ down = starting_node.get_down_nodes()
1799
+
1800
+ return [[cur.x, cur.y] for cur in down]
1801
+
1802
+ def get_xy_upstream_node(self,
1803
+ starting_node:Node_Watershed,
1804
+ limit_to_sub:bool = False,
1805
+ limit_to_river:bool = False,
1806
+ limit_to_runoff:bool = False) -> list[list[float]]:
1807
+ """
1808
+ Récupération des coordonnées des noeuds amont
1809
+ """
1810
+
1811
+ if limit_to_sub:
1812
+
1813
+ if limit_to_river:
1814
+ up = starting_node.get_up_rivernodes_same_sub()
1815
+ elif limit_to_runoff:
1816
+ up = starting_node.get_up_runoff_nodes_same_sub()
1817
+ else:
1818
+ up, all_river, all_runoff = starting_node.get_up_nodes_same_sub()
1819
+
1820
+ else:
1821
+ if limit_to_river:
1822
+ up = starting_node.get_up_rivernodes()
1823
+ elif limit_to_runoff:
1824
+ up = starting_node.get_up_runoff_nodes()
1825
+ else:
1826
+ up, all_river, all_runoff = starting_node.get_up_nodes()
1827
+
1828
+ return [[cur.x, cur.y] for cur in up]
1829
+
1830
+ def get_array_from_upstream_node(self,
1831
+ starting_node:Node_Watershed,
1832
+ limit_to_sub:bool = False):
1833
+ """
1834
+ Récupération de l'array à partir d'un noeud amont
1835
+ """
1836
+
1837
+ up = self.get_xy_upstream_node(starting_node, limit_to_sub=limit_to_sub)
1838
+
1839
+ xmin = min([x[0] for x in up])
1840
+ xmax = max([x[0] for x in up])
1841
+ ymin = min([x[1] for x in up])
1842
+ ymax = max([x[1] for x in up])
1843
+
1844
+ newhead = header_wolf()
1845
+ newhead.dx = self.header.dx
1846
+ newhead.dy = self.header.dy
1847
+
1848
+ newhead.origx = xmin - self.header.dx/2. - self.header.dx
1849
+ newhead.origy = ymin - self.header.dy/2. - self.header.dy
1850
+
1851
+ newhead.nbx = int(np.ceil((xmax - xmin) / self.header.dx) + 3)
1852
+ newhead.nby = int(np.ceil((ymax - ymin) / self.header.dy) + 3)
1853
+
1854
+ if newhead.nbx == 0 or newhead.nby == 0:
1855
+ logging.error(_('No upstream nodes found!'))
1856
+ return None
1857
+
1858
+ newarray = WolfArray(srcheader=newhead)
1859
+ newarray.array[:,:] = 0.
1860
+
1861
+ ij = newhead.xy2ij_np(up)
1862
+
1863
+ newarray.array[ij[:,0], ij[:,1]] = 1.
1864
+
1865
+ newarray.mask_data(0.)
1866
+
1867
+ return newarray
1868
+
1869
+ def get_vector_from_upstream_node(self,
1870
+ starting_node:Node_Watershed,
1871
+ limit_to_sub:bool = False):
1872
+ """ Return a vector contouring the upstream area """
1873
+
1874
+ up_array = self.get_array_from_upstream_node(starting_node, limit_to_sub=limit_to_sub)
1875
+
1876
+ if up_array is None:
1877
+ return None
1878
+
1879
+ __, __, vect, __ = up_array.suxsuy_contour()
1880
+
1881
+ vect.find_minmax()
1882
+ return vect
1883
+
1719
1884
  def get_subwatershed(self, idx_sorted_or_name:int | str) -> SubWatershed:
1720
1885
  """
1721
1886
  Récupération d'un sous-bassin sur base de l'index trié
@@ -1030,8 +1030,8 @@ class Config_Manager_2D_GPU:
1030
1030
  # check for infiltration zones vs hydrograph
1031
1031
  hydro = cursim.infiltrations_chronology
1032
1032
  nb_zones = len(hydro[0][1])
1033
- if infiltration.array.data.max() != nb_zones:
1034
- logging.error(_('You must have {} Infiltration zones but {} are defined!'.format(nb_zones, infiltration.array.data.max())))
1033
+ if infiltration.array.max() != nb_zones:
1034
+ logging.error(_('You must have {} Infiltration zones but {} are defined!'.format(nb_zones, infiltration.array.max())))
1035
1035
  return
1036
1036
 
1037
1037
  # default reporting period
@@ -1815,11 +1815,21 @@ class UI_Manager_2D_GPU():
1815
1815
  self._txtctrl.write('\t'+curcol)
1816
1816
  self._txtctrl.write('\n')
1817
1817
 
1818
- for idx, curline in hydro._data.iterrows():
1819
- self._txtctrl.write(str(idx))
1820
- for curval in curline.values:
1821
- self._txtctrl.write('\t' + str(curval))
1822
- self._txtctrl.write('\n')
1818
+ if hydro._data.shape[0]>50:
1819
+ logging.warning(_('Too many lines in the hydrograph -- only the first 50 will be displayed !'))
1820
+
1821
+ for idx, curline in hydro._data.iloc[:50].iterrows():
1822
+ self._txtctrl.write(str(idx))
1823
+ for curval in curline.values:
1824
+ self._txtctrl.write('\t' + str(curval))
1825
+ self._txtctrl.write('\n')
1826
+
1827
+ else:
1828
+ for idx, curline in hydro._data.iterrows():
1829
+ self._txtctrl.write(str(idx))
1830
+ for curval in curline.values:
1831
+ self._txtctrl.write('\t' + str(curval))
1832
+ self._txtctrl.write('\n')
1823
1833
 
1824
1834
  except:
1825
1835
  with open(mydata, 'r', encoding='utf-8') as file:
wolfhece/wolf_array.py CHANGED
@@ -357,12 +357,23 @@ class header_wolf():
357
357
  :return : numpy array containing (i, j, [k]) indices - shape (n, 2) or (n, 3)
358
358
  """
359
359
 
360
- locxy = xy.copy()
360
+ if isinstance(xy,tuple):
361
+ if len(xy) == 2:
362
+ if (isinstance(xy[0],np.ndarray)) and (isinstance(xy[1],np.ndarray)):
363
+ if len(xy[0]) == len(xy[1]):
364
+ locxy = np.vstack((xy[0], xy[1])).T
365
+ logging.warning(_('get_ij_from_xy_array - xy is a tuple of 2 arrays, it is converted to a 2D array'))
366
+ else:
367
+ locxy = np.array(xy)
368
+ elif isinstance(xy,list):
369
+ locxy = np.array(xy)
370
+ else:
371
+ locxy = xy.copy()
361
372
 
362
373
  if forcedims2:
363
- locij = np.zeros((xy.shape[0],2), dtype=np.int32)
374
+ locij = np.zeros((locxy.shape[0],2), dtype=np.int32)
364
375
  else:
365
- locij = np.zeros(xy.shape, dtype=np.int32)
376
+ locij = np.zeros(locxy.shape, dtype=np.int32)
366
377
 
367
378
  locxy[:,0] -= self.origx
368
379
  locxy[:,1] -= self.origy
@@ -446,7 +457,7 @@ class header_wolf():
446
457
  """
447
458
  Converts array coordinates (numpy cells) to this array's world coodinates.
448
459
 
449
- :param ij = numpy array containing (i, j, [k]) indices
460
+ :param ij = numpy array containing (i, j, [k]) indices - shape (n, 2) or (n, 3)
450
461
  :param scale = scaling of the spatial resolution (dx,dy,[dz])
451
462
  :param aswolf = if True, input is one-based (as Wolf VB6 or Fortran), otherwise 0-based (default Python standard)
452
463
  :param abs = if True, add translation to results (x, y, [z]) (coordinate to global space)
@@ -464,7 +475,18 @@ class header_wolf():
464
475
  if len(ij[0]) == len(ij[1]):
465
476
  ij = np.vstack((ij[0], ij[1])).T
466
477
  logging.warning(_('get_xy_from_ij_array - ij is a tuple of 2 arrays, it is converted to a 2D array'))
467
-
478
+ else:
479
+ ij = np.array(ij)
480
+
481
+ elif isinstance(ij,list):
482
+ if len(ij) == 2:
483
+ if (isinstance(ij[0],np.ndarray)) and (isinstance(ij[1],np.ndarray)):
484
+ if len(ij[0]) == len(ij[1]):
485
+ ij = np.vstack((ij[0], ij[1])).T
486
+ logging.warning(_('get_xy_from_ij_array - ij is a list of 2 arrays, it is converted to a 2D array'))
487
+ else:
488
+ ij = np.array(ij)
489
+
468
490
  if abs:
469
491
  tr_x = self.translx
470
492
  tr_y = self.transly
@@ -529,7 +551,7 @@ class header_wolf():
529
551
 
530
552
  :return : numpy array containing (i, j, [k]) indices - shape (n, 2) or (n, 3)
531
553
  """
532
- return self.get_xy_from_ij_array(xy, scale, aswolf, abs)
554
+ return self.get_ij_from_xy_array(xy, scale, aswolf, abs)
533
555
 
534
556
  def xyz2ijk_np(self, xyz:np.ndarray, scale:float=1., aswolf:bool=False, abs:bool=True) -> np.ndarray:
535
557
  """ alias for get_xy_from_ij_array """
@@ -1192,8 +1214,10 @@ class Ops_Array(wx.Frame):
1192
1214
  self.vectmp = vector(name='tmp')
1193
1215
  self.fnsave = ''
1194
1216
 
1195
- self.myzonetmp.add_vector(self.vectmp)
1196
- self.myzones.add_zone(self.myzonetmp)
1217
+ self.myzonetmp.add_vector(self.vectmp, forceparent=True)
1218
+ self.myzones.add_zone(self.myzonetmp, forceparent=True)
1219
+
1220
+ self.myzones.mapviewer = mapviewer
1197
1221
 
1198
1222
  if self.wx_exists:
1199
1223
  self.set_GUI()
@@ -2123,14 +2147,22 @@ class Ops_Array(wx.Frame):
2123
2147
  def OnManageVectors(self, event:wx.MouseEvent):
2124
2148
  """ Open vector manager """
2125
2149
 
2150
+ self.show_structure_OpsVectors()
2151
+
2152
+ def show_structure_OpsVectors(self):
2153
+ """ Show the structure of the vector manager """
2154
+
2126
2155
  if self.mapviewer is not None:
2127
2156
  if self.mapviewer.linked:
2157
+ # The viewer is linked to other viewers
2128
2158
  if self.mapviewer.link_shareopsvect:
2129
- if self.myzones.get_mapviewer() in self.mapviewer.linkedList:
2130
- self.myzones.showstructure()
2131
- return
2159
+ # The viewer shares the vector manager with the other viewers
2160
+ if self.myzones.get_mapviewer() in self.mapviewer.linkedList:
2161
+ # The viewer is in the active linked viewers
2162
+ self.myzones.showstructure()
2163
+ return
2132
2164
 
2133
- self.myzones.showstructure()
2165
+ self.myzones.showstructure()
2134
2166
 
2135
2167
  def OnLoadvec(self, event:wx.MouseEvent):
2136
2168
  """ Load vector file """
@@ -2593,6 +2625,12 @@ class SelectionData():
2593
2625
  self.hideselection = False
2594
2626
  self.numlist_select = 0 # OpenGL list index
2595
2627
 
2628
+ def set_selection_from_list_xy(self, xylist: list[tuple[float, float]]):
2629
+ """ Set the current selection from a list of (x, y) coordinates """
2630
+
2631
+ self.myselection = xylist
2632
+ self.update_nb_nodes_selection()
2633
+
2596
2634
  @property
2597
2635
  def dx(self) -> float:
2598
2636
  """ Resolution in x """
@@ -4285,6 +4323,11 @@ class WolfArray(Element_To_Draw, header_wolf):
4285
4323
 
4286
4324
  return self.mngselection
4287
4325
 
4326
+ @property
4327
+ def Operations(self) -> Ops_Array:
4328
+ """ Return the operations on the array """
4329
+ return self.myops
4330
+
4288
4331
  @property
4289
4332
  def active_blocks(self) -> list["WolfArray"]:
4290
4333
  """ Return the active blocks """
@@ -7663,7 +7706,7 @@ class WolfArrayMB(WolfArray):
7663
7706
  """
7664
7707
 
7665
7708
  if copyarray:
7666
- arr = WolfArray(mold=arr)
7709
+ arr = WolfArray(mold=arr, nullvalue=arr.nullvalue)
7667
7710
  force_idx = True
7668
7711
 
7669
7712
  if force_idx:
@@ -2459,14 +2459,14 @@ class Wolfresults_2D(Element_To_Draw):
2459
2459
 
2460
2460
  if self.nb_blocks>1 or force_mb:
2461
2461
 
2462
- retarray = WolfArrayMB()
2462
+ retarray = WolfArrayMB(nullvalue=self[0].nullvalue)
2463
2463
  retarray.set_header(self.get_header())
2464
2464
  for i in range(self.nb_blocks):
2465
2465
  retarray.add_block(self[i], copyarray=copyarray)
2466
2466
 
2467
2467
  else:
2468
2468
  if copyarray :
2469
- retarray = WolfArray(mold=self[0])
2469
+ retarray = WolfArray(mold=self[0], nullvalue=self[0].nullvalue)
2470
2470
  else:
2471
2471
  retarray = self[0]
2472
2472
 
@@ -2824,6 +2824,24 @@ class Wolfresults_2D(Element_To_Draw):
2824
2824
  block.k.array, block.eps.array = wolfpy.r2d_getturbresults(which_step+1, nbx, nby, whichblock)
2825
2825
  block._force_update_shields = True
2826
2826
 
2827
+ def _read_oneblockresult_withoutmask_only_h(self, which_step:int=-1,whichblock:int=-1):
2828
+ """
2829
+ Lecture d'un résultat pour un bloc spécifique --> utilisation de la librairie Fortran
2830
+
2831
+ :param which_step : timestep ; 0-based; -1 == last one
2832
+ :param whichblock : block index
2833
+ """
2834
+ which_step = self._sanitize_result_step(which_step)
2835
+
2836
+ if whichblock!=-1:
2837
+ block = self.myblocks[getkeyblock(whichblock,False)]
2838
+ nbx = block.waterdepth.nbx
2839
+ nby = block.waterdepth.nby
2840
+
2841
+ # Fortran is 1-based --> which_step+1
2842
+ block.waterdepth.array, block.qx.array, block.qy.array = wolfpy.r2d_getresults(which_step+1, nbx, nby, whichblock)
2843
+ block._force_update_shields = True
2844
+
2827
2845
  def read_oneblockresult(self, which_step:int=-1, whichblock:int=-1):
2828
2846
  """
2829
2847
  Lecture d'un résultat pour un bloc spécifique et application d'un masque sur base d'nu epsilon de hauteur d'eau
@@ -2861,6 +2879,29 @@ class Wolfresults_2D(Element_To_Draw):
2861
2879
  self.myblocks[getkeyblock(whichblock,False)].k.set_nullvalue_in_mask()
2862
2880
  self.myblocks[getkeyblock(whichblock,False)].eps.set_nullvalue_in_mask()
2863
2881
 
2882
+ def _read_oneblockresult_only_h(self, which_step:int=-1, whichblock:int=-1):
2883
+ """
2884
+ Lecture d'un résultat pour un bloc spécifique et application d'un masque sur base d'nu epsilon de hauteur d'eau
2885
+
2886
+ which_step: result number to read ; 0-based; -1 == last one
2887
+ whichblock : block index ; 1-based
2888
+ """
2889
+
2890
+ which_step = self._sanitize_result_step(which_step)
2891
+
2892
+ if whichblock!=-1:
2893
+
2894
+ self._read_oneblockresult_withoutmask_only_h(which_step, whichblock)
2895
+
2896
+ if self.epsilon > 0.:
2897
+ self.myblocks[getkeyblock(whichblock,False)].waterdepth.array=ma.masked_less_equal(self.myblocks[getkeyblock(whichblock,False)].waterdepth.array,self.epsilon)
2898
+ else:
2899
+ self.myblocks[getkeyblock(whichblock,False)].waterdepth.array=ma.masked_equal(self.myblocks[getkeyblock(whichblock,False)].waterdepth.array,0.)
2900
+
2901
+ self.myblocks[getkeyblock(whichblock,False)].waterdepth.count()
2902
+
2903
+ self.myblocks[getkeyblock(whichblock,False)].waterdepth.set_nullvalue_in_mask()
2904
+
2864
2905
  def read_oneresult(self, which:int=-1):
2865
2906
  """
2866
2907
  Lecture d'un pas de sauvegarde
@@ -2884,6 +2925,29 @@ class Wolfresults_2D(Element_To_Draw):
2884
2925
  self.current_result = which
2885
2926
  self.loaded=True
2886
2927
 
2928
+ def _read_oneresult_only_h(self, which:int=-1):
2929
+ """
2930
+ Lecture d'un pas de sauvegarde
2931
+
2932
+ :param which: result number to read; 0-based; -1 == last one
2933
+ """
2934
+
2935
+ which = self._sanitize_result_step(which)
2936
+
2937
+ if exists(self.filename+'.head'):
2938
+ logging.info(_('Reading from results - step :{}'.format(which+1)))
2939
+ wolfpy.r2d_init(self.filename.ljust(255).encode('ansi'))
2940
+ for i in range(self.nb_blocks):
2941
+ self._read_oneblockresult_only_h(which, i+1)
2942
+ else:
2943
+ logging.info(_('No ".head" file --> Initial Conditions'))
2944
+
2945
+ if self.to_filter_independent:
2946
+ self.filter_independent_zones()
2947
+
2948
+ self.current_result = which
2949
+ self.loaded=True
2950
+
2887
2951
  def read_next(self):
2888
2952
  """
2889
2953
  Lecture du pas suivant
@@ -4055,6 +4119,12 @@ class Wolfresults_2D(Element_To_Draw):
4055
4119
  def danger_map(self, start:int=0, end:int=-1, every:int=1) -> Union[tuple[WolfArray, WolfArray, WolfArray], tuple[WolfArrayMB, WolfArrayMB, WolfArrayMB]]:
4056
4120
  """
4057
4121
  Create Danger Maps
4122
+
4123
+ :param start: start time step - 0-based
4124
+ :param end: end time step - 0-based
4125
+ :param every: step interval
4126
+
4127
+ :return : tuple of WolfArray or WolfArrayMB - H, U_norm, Q_norm
4058
4128
  """
4059
4129
 
4060
4130
  # Number of time steps
@@ -4069,38 +4139,38 @@ class Wolfresults_2D(Element_To_Draw):
4069
4139
  danger_map_matrix_v = self.as_WolfArray(copyarray=True)
4070
4140
  danger_map_matrix_mom = self.as_WolfArray(copyarray=True)
4071
4141
 
4072
- # Reset data -> Set null values
4073
- danger_map_matrix_h.reset()
4074
- danger_map_matrix_v.reset()
4075
- danger_map_matrix_mom.reset()
4076
-
4077
- danger_map_matrix_h.mask_reset()
4078
- danger_map_matrix_v.mask_reset()
4079
- danger_map_matrix_mom.mask_reset()
4080
-
4081
4142
  danger = [danger_map_matrix_h, danger_map_matrix_v, danger_map_matrix_mom]
4082
4143
 
4144
+ for curdanger in danger:
4145
+ curdanger.nullvalue = 0.
4146
+ curdanger.reset()
4147
+ curdanger.mask_reset()
4148
+
4083
4149
  for time_step in tqdm(range(start, end, every)):
4084
4150
 
4085
4151
  self.read_oneresult(time_step+1)
4086
4152
 
4087
4153
  if self.nb_blocks>1:
4088
4154
  for curblock in self.myblocks.keys():
4155
+
4089
4156
  # Get WolfArray
4090
4157
  wd = self.get_h_for_block(curblock)
4091
4158
  qx = self.get_qx_for_block(curblock)
4092
4159
  qy = self.get_qy_for_block(curblock)
4093
4160
 
4094
- # Math operations are overloaded
4095
- v = (qx**2.+qy**2.)**.5/wd
4096
- mom = v*wd
4161
+ ij = np.where(~wd.array.mask)
4097
4162
 
4098
- comp = [wd, v, mom]
4163
+ #
4164
+ mom = np.zeros_like(wd.array)
4165
+ v = np.zeros_like(wd.array)
4166
+ mom[ij] = (qx.array[ij]**2.+qy.array[ij]**2.)**.5
4167
+ v[ij] = mom[ij]/wd.array[ij]
4099
4168
 
4100
4169
  # Comparison
4101
- for curdanger, curcomp in zip(danger, comp):
4102
- i,j = np.where(curdanger.myblocks[curblock].array < curcomp.array)
4103
- curdanger.myblocks[curblock].array.data[i,j] = curcomp.array.data[i,j]
4170
+ for curdanger, curcomp in zip(danger, [wd.array, v, mom]):
4171
+ ij = np.where((curdanger.array < curcomp) & (~wd.array.mask))
4172
+ curdanger.array.data[ij] = curcomp[ij]
4173
+ curdanger.array.mask[ij] = False
4104
4174
 
4105
4175
  else:
4106
4176
  curblock = getkeyblock(0)
@@ -4108,25 +4178,84 @@ class Wolfresults_2D(Element_To_Draw):
4108
4178
  qx = self.get_qx_for_block(curblock)
4109
4179
  qy = self.get_qy_for_block(curblock)
4110
4180
 
4111
- v = (qx**2.+qy**2.)**.5/wd
4112
-
4113
- mom = v*wd
4181
+ ij = np.where(~wd.array.mask)
4114
4182
 
4115
- comp = [wd, v, mom]
4183
+ #
4184
+ mom = np.zeros_like(wd.array)
4185
+ v = np.zeros_like(wd.array)
4186
+ mom[ij] = (qx.array[ij]**2.+qy.array[ij]**2.)**.5
4187
+ v[ij] = mom[ij]/wd.array[ij]
4116
4188
 
4117
4189
  # Comparison
4118
- for curdanger, curcomp in zip(danger, comp):
4119
- i,j = np.where(curdanger.array < curcomp.array)
4120
- curdanger.array.data[i,j] = curcomp.array.data[i,j]
4190
+ for curdanger, curcomp in zip(danger, [wd.array, v, mom]):
4191
+ ij = np.where((curdanger.array < curcomp) & (~wd.array.mask))
4192
+ curdanger.array.data[ij] = curcomp[ij]
4193
+ curdanger.array.mask[ij] = False
4121
4194
 
4122
4195
  danger_map_matrix_h.mask_lower(self.epsilon)
4196
+
4123
4197
  if self.nb_blocks>1:
4124
4198
  for i in range(self.nb_blocks):
4125
- danger_map_matrix_v[i].array.mask = danger_map_matrix_h[i].array.mask.copy()
4126
- danger_map_matrix_mom[i].array.mask = danger_map_matrix_h[i].array.mask.copy()
4199
+ danger_map_matrix_v[i].array.mask[:,:] = danger_map_matrix_h[i].array.mask[:,:]
4200
+ danger_map_matrix_mom[i].array.mask[:,:] = danger_map_matrix_h[i].array.mask[:,:]
4127
4201
  else:
4128
- danger_map_matrix_v.array.mask = danger_map_matrix_h.array.mask.copy()
4129
- danger_map_matrix_mom.array.mask = danger_map_matrix_h.array.mask.copy()
4202
+ danger_map_matrix_v.array.mask[:,:] = danger_map_matrix_h.array.mask[:,:]
4203
+ danger_map_matrix_mom.array.mask[:,:] = danger_map_matrix_h.array.mask[:,:]
4130
4204
 
4131
4205
 
4132
4206
  return (danger_map_matrix_h, danger_map_matrix_v, danger_map_matrix_mom)
4207
+
4208
+ def danger_map_only_h(self, start:int=0, end:int=-1, every:int=1) -> WolfArray:
4209
+ """
4210
+ Create Danger Maps
4211
+
4212
+ :param start: start time step - 0-based
4213
+ :param end: end time step - 0-based
4214
+ :param every: step interval
4215
+
4216
+ :return : tuple of WolfArray or WolfArrayMB - H, U_norm, Q_norm
4217
+ """
4218
+
4219
+ # Number of time steps
4220
+ number_of_time_steps = self.get_nbresults()
4221
+ if end ==-1:
4222
+ end = number_of_time_steps
4223
+
4224
+ # Init Danger Maps basde on results type
4225
+ # If only one block --> WolfArray
4226
+ # If only multiple blocks --> WolfArrayMB
4227
+ danger_map_matrix_h = self.as_WolfArray(copyarray=True)
4228
+
4229
+ danger_map_matrix_h.nullvalue = 0.
4230
+ danger_map_matrix_h.reset()
4231
+ danger_map_matrix_h.mask_reset()
4232
+
4233
+ for time_step in tqdm(range(start, end, every)):
4234
+
4235
+ self._read_oneresult_only_h(time_step+1)
4236
+
4237
+ if self.nb_blocks>1:
4238
+ for curblock in self.myblocks.keys():
4239
+
4240
+ # Get WolfArray
4241
+ wd = self.get_h_for_block(curblock)
4242
+
4243
+ # Comparison
4244
+ ij = np.where((danger_map_matrix_h.array < wd.array.data) & (~wd.array.mask))
4245
+ danger_map_matrix_h.array.data[ij] = wd.array[ij]
4246
+ danger_map_matrix_h.array.mask[ij] = False
4247
+
4248
+ else:
4249
+ curblock = getkeyblock(0)
4250
+
4251
+ # Get WolfArray
4252
+ wd = self.get_h_for_block(curblock)
4253
+
4254
+ # Comparison
4255
+ ij = np.where((danger_map_matrix_h.array < wd.array.data) & (~wd.array.mask))
4256
+ danger_map_matrix_h.array.data[ij] = wd.array[ij]
4257
+ danger_map_matrix_h.array.mask[ij] = False
4258
+
4259
+ danger_map_matrix_h.mask_lower(self.epsilon)
4260
+
4261
+ return danger_map_matrix_h
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: wolfhece
3
- Version: 2.1.15
3
+ Version: 2.1.17
4
4
  Author-email: Pierre Archambeau <pierre.archambeau@uliege.be>
5
5
  License: AGPL-v3 License
6
6
  Project-URL: Homepage, https://uee.uliege.be/hece
@@ -6,22 +6,22 @@ wolfhece/ManageParams.py,sha256=Wgt5Zh7QBtyiwTAltPHunSLqt4XuVuRH76GTUrXabS4,219
6
6
  wolfhece/Model1D.py,sha256=-cMz-ePSYzrKVVDidiDOz6cojEZ3y6u9gIb7RPwT6Y8,476593
7
7
  wolfhece/PyConfig.py,sha256=oGSL1WsLM9uinlNP4zGBLK3uHPmBfduUi7R-VtWuRFA,8034
8
8
  wolfhece/PyCrosssections.py,sha256=f4dNYRUGZKePruaaBiTcn5vlrw8TFTj9XwTDrdiF_uU,112450
9
- wolfhece/PyDraw.py,sha256=Kfu3uoxwP6ZK9LqE5Br-GBex_bSS6k4F3tfsK-qIZvU,379565
9
+ wolfhece/PyDraw.py,sha256=ayK8YWZGOj79auURpkHaDCUreOlaAtMVq2ZpuzL3s_Q,383008
10
10
  wolfhece/PyGui.py,sha256=fqy8f3tLt7myJskVvspTQ_ZO7kaiSNKmcfFLrfr4w7M,103174
11
- wolfhece/PyGuiHydrology.py,sha256=wKhR-KthPRyzJ887NmsozmUpm2CIQIwO3IbYORCYjrE,7290
11
+ wolfhece/PyGuiHydrology.py,sha256=r8kcY2eGAQzSwVtLpyMUiBL5xBpMBsi7ovs0PgStGWw,14648
12
12
  wolfhece/PyHydrographs.py,sha256=GKK8U0byI45H9O_e4LAOOi7Aw0Tg7Q0Lx322stPg5IQ,3453
13
13
  wolfhece/PyPalette.py,sha256=Vl5RrBIC_a5-mZKUtBd5kG0mif946B7OtS3fnehkmOc,25012
14
- wolfhece/PyParams.py,sha256=V1Pe4rsBpWBA5kI5rRG7B5ijPHAdpM1i2uyxhnrwX94,96896
14
+ wolfhece/PyParams.py,sha256=Aj8kcT044abwBYU_OiEcJWcyNVqxYithNfbzdHyI-QA,97072
15
15
  wolfhece/PyPictures.py,sha256=-mJB0JL2YYiEK3D7_ssDkvYiMWK4ve9kXhozQXNeSx8,2216
16
16
  wolfhece/PyTranslate.py,sha256=4appkmNeHHZLFmUtaA_k5_5QL-5ymxnbVN4R2OblmtE,622
17
17
  wolfhece/PyVertex.py,sha256=dHTjyYYTn0F_NWerlAOBKHV79RUzEEtMJMldQtVc1Cs,40092
18
- wolfhece/PyVertexvectors.py,sha256=C0uB7MTUeNB3XNxf1R98epvcqoLJIlExvI1zwom48jA,223945
18
+ wolfhece/PyVertexvectors.py,sha256=4K0T74MUH-ycX79hFa2618vKVTu9qOSh49hlbKrydMg,224123
19
19
  wolfhece/PyWMS.py,sha256=t6jVZpTxTNSLJxABk8A79cEMWTKoRM_S_SXRipsHLzw,4493
20
- wolfhece/RatingCurve.py,sha256=YSQvSvdMHE6hSlWVBF5Oe0-Fh3waNMpOdmcymaCCTis,21706
20
+ wolfhece/RatingCurve.py,sha256=f6IGLS5aJBJD_t_k903m_yRZ60MzKNKanzD6njXZxa8,22200
21
21
  wolfhece/RatingCurveData.py,sha256=5UvnIm89BwqjnEbLCcY3CA8WoFd_xHJbooNy62fX5iY,57660
22
22
  wolfhece/RatingCurve_xml.py,sha256=vbLxSWwHPsCAsR13KaG5WVmVn_cha7-6cF4zj7Diiz8,33593
23
23
  wolfhece/ReadDataDCENN.py,sha256=4OMDBgkZ_v7OWmVhyQ-reab7MPxGhFEDY2qS8yThhdM,1240
24
- wolfhece/Results2DGPU.py,sha256=pC7jHQhzSJPmGiboNNLG619yVYaOUT_O5_yhKMzslxA,20563
24
+ wolfhece/Results2DGPU.py,sha256=-EGeWQcg_XsDh3XOqnuEnFgPSoAD4q0YUjM7u8ESRD8,23038
25
25
  wolfhece/__init__.py,sha256=FRDE8PiJAWxX9PMXsShRMZ8YADAY4WIgKMRh52rmhiw,23
26
26
  wolfhece/_add_path.py,sha256=nudniS-lsgHwXXq5o626XRDzIeYj76GoGKYt6lcu2Nc,616
27
27
  wolfhece/cli.py,sha256=rHxZGgs_R776VCWhs36pYFoiuiQycwgGTVOLK-JNzjE,1937
@@ -48,13 +48,13 @@ wolfhece/rain_SPWMI.py,sha256=YqsF-yFro3y_a6MfVRFfr-Rxi7NR1gl_i8VX7scmzes,13548
48
48
  wolfhece/test_Results2DGPU.py,sha256=NOJ_hFXrcLSQXS1dtsqXRQltqIZtDSHMz_EgAJ2_FHU,307
49
49
  wolfhece/textpillow.py,sha256=zEfLrKhfCDyMaVuQOUjHqz6MGKeQ4aewMxOsWi5-wKI,13832
50
50
  wolfhece/tools_mpl.py,sha256=q8Yc4aukPPiUcEzREvZRM_em67XqXaahdoaNt0DETfE,266
51
- wolfhece/wolf_array.py,sha256=vf3S7vIdN0ziYtpHSyQRCjwneQCKlGOdCYpZE3xQcLk,335853
51
+ wolfhece/wolf_array.py,sha256=tYzkVd4Zrvr6FotO571IfW6Kkvx9Kli9QnzbiXVwZEo,337760
52
52
  wolfhece/wolf_hist.py,sha256=JpRXvzJLUP-RkSkvth3DQWglgTMFI2ZEUDb4RYOfeeI,3284
53
53
  wolfhece/wolf_texture.py,sha256=llQ7aV8scWXIkhpri9XjaPejzoBJsGfsln2ZnlRbFkU,16270
54
54
  wolfhece/wolf_tiles.py,sha256=F2JsJHdAP8fIffNJdG_J26bonCIRtIwMmxKFqdSCRDA,10088
55
55
  wolfhece/wolf_vrt.py,sha256=un5CKzAUmzSsjLXK7YLnQEWz8FLoafXJs8oqUvS_-h0,10271
56
56
  wolfhece/wolf_zi_db.py,sha256=Ok0MxQYZMMLRJN1QY-HSplLhUzzb6gkXgBQ3ihhLQHk,12669
57
- wolfhece/wolfresults_2D.py,sha256=6VbONzD2lMFCnZ2-gyBk7pW9LcBmSWkZxiVLTMKVPIQ,159403
57
+ wolfhece/wolfresults_2D.py,sha256=6CkXD_X4pOBFce0nFZjR6VjKzLKSYqqY4UhXKzzrKuM,164515
58
58
  wolfhece/xyz_file.py,sha256=aQOcTHkHRhXHxL_WxTHwzygp6e47San7SHSpxKQU0dw,5457
59
59
  wolfhece/apps/ManageParams.py,sha256=heg5L4fMn0ettR7Bad_Q680o_JWnTbe3WFkL_9IziAk,312
60
60
  wolfhece/apps/Optimisation_hydro.py,sha256=mHazBazTUGyxPbHPXhaQim8vqIeOOuKPjH0B48VWduA,374
@@ -66,7 +66,7 @@ wolfhece/apps/check_install.py,sha256=jrKR-njqnpIh6ZJqvP6KbDUPVCfwTNQj4glQhcyzs9
66
66
  wolfhece/apps/curvedigitizer.py,sha256=avWERHuVxPnJBOD_ibczwW_XG4vAenqWS8W1zjhBox8,4898
67
67
  wolfhece/apps/isocurrent.py,sha256=4XnNWPa8mYUK7V4zdDRFrHFIXNG2AN2og3TqWKKcqjY,3811
68
68
  wolfhece/apps/splashscreen.py,sha256=LkEVMK0eCc84NeCWD3CGja7fuQ_k1PrZdyqD3GQk_8c,2118
69
- wolfhece/apps/version.py,sha256=X3iLT7rB3ADIv1WPZzMTWmvsIohdaLhJ_J-11OkQy6U,388
69
+ wolfhece/apps/version.py,sha256=YX9tmGcv0oDZgHzLyJ-fs3F4ENyIBZMuarvn4elQtAo,388
70
70
  wolfhece/apps/wolf.py,sha256=gqfm-ZaUJqNsfCzmdtemSeqLw-GVdSVix-evg5WArJI,293
71
71
  wolfhece/apps/wolf2D.py,sha256=gWD9ee2-1pw_nUxjgRaJMuSe4kUT-RWhOeoTt_Lh1mM,267
72
72
  wolfhece/apps/wolf_logo.bmp,sha256=ruJ4MA51CpGO_AYUp_dB4SWKHelvhOvd7Q8NrVOjDJk,3126
@@ -102,7 +102,7 @@ wolfhece/hydrology/Dumping.py,sha256=GKYvkKgCfJQT1XEF1ceh7evdhlpZRPcuf6VlBdH-TaM
102
102
  wolfhece/hydrology/Optimisation.py,sha256=JD72GXAWL6fwagCrCVb0qMEFuYvUlO1vDigteV4EIuA,142220
103
103
  wolfhece/hydrology/Outlet.py,sha256=fpetH2ZKnTKIBNuVclxrncc5OAxWUGI5_ed9gXh6fD4,10201
104
104
  wolfhece/hydrology/PostProcessHydrology.py,sha256=SiW5FIf8FeQL9ItWG8ODt612k5m59aogSLgpsXinr8I,6944
105
- wolfhece/hydrology/PyWatershed.py,sha256=NO2f4XVA8JxW06ysUhlAN4VYVlv3oCqhhyQ8BeTC7d4,92823
105
+ wolfhece/hydrology/PyWatershed.py,sha256=VC38Cglf23yD9lz5u5xy5lxYI9c1FW8ZLd2tmKF_d1Y,97928
106
106
  wolfhece/hydrology/RetentionBasin.py,sha256=cV-Rn-Ya7vWHnkl6pHcQ8GFx5HX-wM7uHI4_Zry-kks,82605
107
107
  wolfhece/hydrology/SubBasin.py,sha256=b5RawgPmfVWUJhkv-nEVSbdN3ytIxpov7kjBSvMrd1c,171159
108
108
  wolfhece/hydrology/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -246,7 +246,7 @@ wolfhece/report/reporting.py,sha256=LrOUI7j1vPefsGhqag1f2KpKRXR-5cH7SyGIsf6nOG0,
246
246
  wolfhece/report/wolf_report.png,sha256=NoSV58LSwb-oxCcZScRiJno-kxDwRdm_bK-fiMsKJdA,592485
247
247
  wolfhece/scenario/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
248
248
  wolfhece/scenario/check_scenario.py,sha256=nFiCscEGHyz1YvjmZoKlYrfmW03-nLiDTDdRoeE6MUs,4619
249
- wolfhece/scenario/config_manager.py,sha256=SValpikuNt_XaJXt8P7kAu6iN_N5YlohyL8ry3iT380,77389
249
+ wolfhece/scenario/config_manager.py,sha256=r3E7ZyOewoB_0M-ox3rIZ3-cO_JIbE1zD4b87pPXn6c,77957
250
250
  wolfhece/scenario/imposebc_void.py,sha256=pl7c99HQQMQT7i15fDlOOFYCdOtR5c_XIBOveOTOaLc,5273
251
251
  wolfhece/scenario/update_void.py,sha256=MmiDiwWHvuk0mpXOlMeB2ImY-d1Wi3Wfmg9hrDTAraE,7176
252
252
  wolfhece/shaders/fragment_shader_texture.glsl,sha256=w6h8d5mJqFaGbao0LGmjRcFFdcEQ3ICIl9JpuT71K5k,177
@@ -267,8 +267,8 @@ wolfhece/sounds/sonsw2.wav,sha256=pFLVt6By0_EPQNt_3KfEZ9a1uSuYTgQSX1I_Zurv9Rc,11
267
267
  wolfhece/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
268
268
  wolfhece/ui/wolf_multiselection_collapsiblepane.py,sha256=yGbU_JsF56jsmms0gh7mxa7tbNQ_SxqhpAZxhm-mTy4,14860
269
269
  wolfhece/ui/wolf_times_selection_comparison_models.py,sha256=wCxGRnE3kzEkWlWA6-3X8ADOFux_B0a5QWJ2GnXTgJw,4709
270
- wolfhece-2.1.15.dist-info/METADATA,sha256=1jd4LkINbWxRjLu3_KsyhqidpBEGHf9x-MjtBReHkME,2282
271
- wolfhece-2.1.15.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91
272
- wolfhece-2.1.15.dist-info/entry_points.txt,sha256=AIu1KMswrdsqNq_2jPtrRIU4tLjuTnj2dCY-pxIlshw,276
273
- wolfhece-2.1.15.dist-info/top_level.txt,sha256=EfqZXMVCn7eILUzx9xsEu2oBbSo9liWPFWjIHik0iCI,9
274
- wolfhece-2.1.15.dist-info/RECORD,,
270
+ wolfhece-2.1.17.dist-info/METADATA,sha256=jWnXOeve-xUr_A3ZHX9uCTDFNr8GVLlUTepoSZN0HD0,2282
271
+ wolfhece-2.1.17.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91
272
+ wolfhece-2.1.17.dist-info/entry_points.txt,sha256=AIu1KMswrdsqNq_2jPtrRIU4tLjuTnj2dCY-pxIlshw,276
273
+ wolfhece-2.1.17.dist-info/top_level.txt,sha256=EfqZXMVCn7eILUzx9xsEu2oBbSo9liWPFWjIHik0iCI,9
274
+ wolfhece-2.1.17.dist-info/RECORD,,