wolfhece 2.2.39__py3-none-any.whl → 2.2.41__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
@@ -1219,6 +1219,221 @@ class Sim_Explorer(wx.Frame):
1219
1219
  self._step_num.Set([str(i) for i in self._all_times_steps[1]])
1220
1220
 
1221
1221
 
1222
+ class Sim_VideoCreation(wx.Dialog):
1223
+
1224
+ def __init__(self, parent, title, mapviewer:"WolfMapViewer", sim:Wolfresults_2D):
1225
+ super(Sim_VideoCreation, self).__init__(parent, title=title, size=(350, 250), style = wx.DEFAULT_DIALOG_STYLE & ~ (wx.RESIZE_BORDER | wx.MAXIMIZE_BOX | wx.MINIMIZE_BOX | wx.CLOSE_BOX))
1226
+
1227
+ self.mapviewer = mapviewer
1228
+ self.active_res2d:Wolfresults_2D = sim
1229
+
1230
+ self._framerate = 25
1231
+ self._start_step = 1
1232
+ self._end_step = self.active_res2d.get_nbresults()
1233
+ self._interval = 1
1234
+ self._fn = str(Path(self.active_res2d.filename).parent / f'{Path(self.active_res2d.filename).stem}.avi')
1235
+
1236
+ self._fontsize = 16
1237
+ self._fontcolor = (255, 255, 255, 255)
1238
+ self._timeposition = 'top-left' # 'top-right', 'bottom-left', 'bottom-right', 'top-center', 'bottom-center'
1239
+
1240
+ panel = wx.Panel(self)
1241
+ vbox = wx.BoxSizer(wx.VERTICAL)
1242
+
1243
+ hbox1 = wx.BoxSizer(wx.HORIZONTAL)
1244
+ st1 = wx.StaticText(panel, -1, _('File name'))
1245
+ hbox1.Add(st1, 1, wx.EXPAND|wx.ALIGN_LEFT|wx.ALL, 5)
1246
+ tc1 = wx.TextCtrl(panel, -1, self._fn)
1247
+ hbox1.Add(tc1,1,wx.EXPAND|wx.ALIGN_LEFT|wx.ALL,5)
1248
+ vbox.Add(hbox1,0,wx.EXPAND|wx.ALIGN_LEFT|wx.ALL,5)
1249
+ self.tc1 = tc1
1250
+
1251
+ # Add a button to choose the file name
1252
+ btn_browse = wx.Button(panel, -1, _('Browse'))
1253
+ hbox1.Add(btn_browse, 0, wx.EXPAND|wx.ALIGN_LEFT|wx.ALL,5)
1254
+ self.btn_browse = btn_browse
1255
+ self.btn_browse.Bind(wx.EVT_BUTTON, self.OnBrowse)
1256
+
1257
+ hbox2 = wx.BoxSizer(wx.HORIZONTAL)
1258
+ st2 = wx.StaticText(panel, -1, _('Frame rate [nb_images/second]'), style=wx.ALIGN_CENTER)
1259
+ hbox2.Add(st2, 1, wx.EXPAND|wx.ALIGN_LEFT|wx.ALL, 5)
1260
+ tc2 = wx.TextCtrl(panel, -1, str(self._framerate))
1261
+ hbox2.Add(tc2,1,wx.EXPAND|wx.ALIGN_LEFT|wx.ALL,5)
1262
+ vbox.Add(hbox2,0,wx.EXPAND|wx.ALIGN_LEFT|wx.ALL,5)
1263
+ self.tc2 = tc2
1264
+
1265
+ hbox3 = wx.BoxSizer(wx.HORIZONTAL)
1266
+ st3 = wx.StaticText(panel, -1, _('First step'), style=wx.ALIGN_CENTER)
1267
+ hbox3.Add(st3, 1, wx.EXPAND|wx.ALIGN_LEFT|wx.ALL, 5)
1268
+ tc3 = wx.TextCtrl(panel, -1, str(self._start_step))
1269
+ hbox3.Add(tc3,1,wx.EXPAND|wx.ALIGN_LEFT|wx.ALL,5)
1270
+ vbox.Add(hbox3,0,wx.EXPAND|wx.ALIGN_LEFT|wx.ALL,5)
1271
+ self.tc3 = tc3
1272
+
1273
+ hbox4 = wx.BoxSizer(wx.HORIZONTAL)
1274
+ st4 = wx.StaticText(panel, -1, _('Final step'), style=wx.ALIGN_CENTER)
1275
+ hbox4.Add(st4, 1, wx.EXPAND|wx.ALIGN_LEFT|wx.ALL, 5)
1276
+ tc4 = wx.TextCtrl(panel, -1, str(self._end_step))
1277
+ hbox4.Add(tc4,1,wx.EXPAND|wx.ALIGN_LEFT|wx.ALL,5)
1278
+ vbox.Add(hbox4,0,wx.EXPAND|wx.ALIGN_LEFT|wx.ALL,5)
1279
+ self.tc4 = tc4
1280
+
1281
+ hbox5 = wx.BoxSizer(wx.HORIZONTAL)
1282
+ st5 = wx.StaticText(panel, -1, _('Interval'), style=wx.ALIGN_CENTER)
1283
+ hbox5.Add(st5, 1, wx.EXPAND|wx.ALIGN_LEFT|wx.ALL, 5)
1284
+ tc5 = wx.TextCtrl(panel, -1, str(self._interval))
1285
+ hbox5.Add(tc5,1,wx.EXPAND|wx.ALIGN_LEFT|wx.ALL,5)
1286
+ vbox.Add(hbox5,0,wx.EXPAND|wx.ALIGN_LEFT|wx.ALL,5)
1287
+ self.tc5 = tc5
1288
+
1289
+ hbox7 = wx.BoxSizer(wx.HORIZONTAL)
1290
+ st7 = wx.StaticText(panel, -1, _("Font size (for time stamp)"), style=wx.ALIGN_CENTER)
1291
+ hbox7.Add(st7, 1, wx.EXPAND|wx.ALIGN_LEFT|wx.ALL, 5)
1292
+ tc7 = wx.TextCtrl(panel, -1, str(self._fontsize))
1293
+ hbox7.Add(tc7,1,wx.EXPAND|wx.ALIGN_LEFT|wx.ALL,5)
1294
+ vbox.Add(hbox7,0,wx.EXPAND|wx.ALIGN_LEFT|wx.ALL,5)
1295
+ self.tc7 = tc7
1296
+
1297
+ hbox8 = wx.BoxSizer(wx.HORIZONTAL)
1298
+ st8 = wx.StaticText(panel, -1, _("Font color (R,G,B,A)"), style=wx.ALIGN_CENTER)
1299
+ hbox8.Add(st8, 1, wx.EXPAND|wx.ALIGN_LEFT|wx.ALL, 5)
1300
+ tc8 = wx.ColourPickerCtrl(panel, -1, wx.Colour(*self._fontcolor))
1301
+ hbox8.Add(tc8,1,wx.EXPAND|wx.ALIGN_LEFT|wx.ALL,5)
1302
+ vbox.Add(hbox8,0,wx.EXPAND|wx.ALIGN_LEFT|wx.ALL,5)
1303
+ self.tc8 = tc8
1304
+
1305
+ hbox9 = wx.BoxSizer(wx.HORIZONTAL)
1306
+ st9 = wx.StaticText(panel, -1, _("Time position"), style=wx.ALIGN_CENTER)
1307
+ hbox9.Add(st9, 1, wx.EXPAND|wx.ALIGN_LEFT|wx.ALL, 5)
1308
+ choices = ['top-left', 'top-right', 'bottom-left', 'bottom-right', 'top-center', 'bottom-center']
1309
+ tc9 = wx.Choice(panel, -1, choices=choices)
1310
+ hbox9.Add(tc9, 1, wx.EXPAND|wx.ALIGN_LEFT|wx.ALL, 5)
1311
+ vbox.Add(hbox9, 0, wx.EXPAND|wx.ALIGN_LEFT|wx.ALL, 5)
1312
+ self.tc9 = tc9
1313
+
1314
+ hbox6 = wx.BoxSizer(wx.HORIZONTAL)
1315
+ btn1 = wx.Button(panel, -1, _('Ok'))
1316
+ hbox6.Add(btn1,1,wx.EXPAND|wx.ALIGN_LEFT|wx.ALL,5)
1317
+ self.btn1 = btn1
1318
+
1319
+ btn2 = wx.Button(panel, -1, _('Cancel'))
1320
+ hbox6.Add(btn2,1,wx.EXPAND|wx.ALIGN_LEFT|wx.ALL,5)
1321
+ self.btn2 = btn2
1322
+ vbox.Add(hbox6,0,wx.EXPAND|wx.ALIGN_LEFT|wx.ALL,5)
1323
+ panel.SetSizer(vbox)
1324
+ vbox.Fit(self)
1325
+
1326
+ self.btn1.Bind(wx.EVT_BUTTON, self.OnOk)
1327
+ self.btn2.Bind(wx.EVT_BUTTON, self.OnCancel)
1328
+
1329
+ # Add validation to the text controls
1330
+ self.tc2.Bind(wx.EVT_TEXT, self.OnValidate)
1331
+ self.tc3.Bind(wx.EVT_TEXT, self.OnValidate)
1332
+ self.tc4.Bind(wx.EVT_TEXT, self.OnValidate)
1333
+ self.tc5.Bind(wx.EVT_TEXT, self.OnValidate)
1334
+ self.tc7.Bind(wx.EVT_TEXT, self.OnValidate)
1335
+ self.tc8.Bind(wx.EVT_COLOURPICKER_CHANGED, self.OnValidate)
1336
+ self.tc9.SetSelection(0)
1337
+ self.tc9.Bind(wx.EVT_CHOICE, self.OnValidate)
1338
+
1339
+ icon = wx.Icon()
1340
+ icon_path = Path(__file__).parent / "apps/wolf_logo2.bmp"
1341
+ icon.CopyFromBitmap(wx.Bitmap(str(icon_path), wx.BITMAP_TYPE_ANY))
1342
+ self.SetIcon(icon)
1343
+ self.CenterOnScreen()
1344
+ self.Show()
1345
+
1346
+ def OnBrowse(self, event):
1347
+ """ Browse a file name to save the video """
1348
+ with wx.FileDialog(self, _("Save video file"), wildcard="MP4 files (*.mp4)|*.mp4|AVI files (*.avi)|*.avi|All files (*.*)|*.*",
1349
+ style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) as fileDialog:
1350
+ if fileDialog.ShowModal() == wx.ID_CANCEL:
1351
+ return # the user changed idea...
1352
+
1353
+ self._fn = fileDialog.GetPath()
1354
+ self.tc1.SetValue(self._fn)
1355
+
1356
+ def get_values(self):
1357
+ """ Return the values set in the dialog """
1358
+ return self._fn, self._framerate, self._start_step, self._end_step, self._interval, self._fontsize, self._fontcolor, self._timeposition
1359
+
1360
+ def OnValidate(self, event):
1361
+ """ Validate the text controls to be sure that the values are correct """
1362
+ try:
1363
+ framerate = int(self.tc2.GetValue())
1364
+ if framerate <= 0:
1365
+ framerate = 25
1366
+ self.tc2.SetValue(str(framerate))
1367
+ self._framerate = framerate
1368
+ except:
1369
+ self.tc2.SetValue(str(self._framerate))
1370
+ try:
1371
+ start_step = int(self.tc3.GetValue())
1372
+ if start_step < 1:
1373
+ start_step = 1
1374
+ self.tc3.SetValue(str(start_step))
1375
+ if start_step > self.active_res2d.get_nbresults():
1376
+ start_step = self.active_res2d.get_nbresults()
1377
+ self.tc3.SetValue(str(start_step))
1378
+ self._start_step = start_step
1379
+
1380
+ except:
1381
+ self.tc3.SetValue(str(self._start_step))
1382
+ try:
1383
+ end_step = int(self.tc4.GetValue())
1384
+ if end_step < 1:
1385
+ end_step = 1
1386
+ self.tc4.SetValue(str(end_step))
1387
+ if end_step > self.active_res2d.get_nbresults():
1388
+ end_step = self.active_res2d.get_nbresults()
1389
+ self.tc4.SetValue(str(end_step))
1390
+ self._end_step = end_step
1391
+ except:
1392
+ self.tc4.SetValue(str(self._end_step))
1393
+ try:
1394
+ interval = int(self.tc5.GetValue())
1395
+ if interval < 1:
1396
+ interval = 1
1397
+ self.tc5.SetValue(str(interval))
1398
+ self._interval = interval
1399
+ except:
1400
+ self.tc5.SetValue(str(self._interval))
1401
+
1402
+ try:
1403
+ fontsize = int(self.tc7.GetValue())
1404
+ if fontsize < 1:
1405
+ fontsize = 16
1406
+ self.tc7.SetValue(str(fontsize))
1407
+ self._fontsize = fontsize
1408
+ except:
1409
+ self.tc7.SetValue(str(self._fontsize))
1410
+
1411
+ try:
1412
+ color = self.tc8.GetColour()
1413
+ self._fontcolor = (color.Red(), color.Green(), color.Blue(), color.Alpha())
1414
+ except:
1415
+ self.tc8.SetColour(wx.Colour(*self._fontcolor))
1416
+
1417
+ try:
1418
+ pos_idx = self.tc9.GetSelection()
1419
+ choices = ['top-left', 'top-right', 'bottom-left', 'bottom-right', 'top-center', 'bottom-center']
1420
+ if pos_idx < 0 or pos_idx >= len(choices):
1421
+ pos_idx = 0
1422
+ self.tc9.SetSelection(pos_idx)
1423
+ self._timeposition = choices[pos_idx]
1424
+ except:
1425
+ self.tc9.SetSelection(0)
1426
+
1427
+ def OnOk(self, event):
1428
+ """ Create the video file """
1429
+ self.OnValidate(None)
1430
+ self.EndModal(wx.ID_OK)
1431
+
1432
+ def OnCancel(self, event):
1433
+ """ Cancel the video creation """
1434
+ self.EndModal(wx.ID_CANCEL)
1435
+
1436
+
1222
1437
  class Drowning_Explorer(wx.Frame):
1223
1438
 
1224
1439
  def __init__(self, parent, title, mapviewer:any, sim:Drowning_victim_Viewer):
@@ -2530,7 +2745,7 @@ class WolfMapViewer(wx.Frame):
2530
2745
  self.InitUI()
2531
2746
 
2532
2747
  self._tmp_vector_distance = None # distance computation the vector
2533
- self._distances = Zones(mapviewer=self, idx=_('Distances/Areas'))
2748
+ self._distances = Zones(mapviewer=self, idx=_('Distances/Areas'), parent = self)
2534
2749
  self._distances.add_zone(zone(name='memory distances', parent=self._distances)) # distances memory
2535
2750
 
2536
2751
  self.menu_alaro_forecasts()
@@ -5370,112 +5585,98 @@ class WolfMapViewer(wx.Frame):
5370
5585
  logging.error(_('Please install opencv-python'))
5371
5586
  return
5372
5587
 
5373
- if fn=='':
5374
- dlg = wx.FileDialog(parent = None,
5375
- message = _('Choose file name'),
5376
- wildcard = 'AVI video file (*.avi)|*.avi',
5377
- style = wx.FD_SAVE)
5378
- ret = dlg.ShowModal()
5379
- if ret == wx.ID_CANCEL:
5380
- dlg.Destroy()
5381
- return
5382
- fn = dlg.GetPath()
5383
- dlg.Destroy()
5384
-
5385
- if not fn.endswith('.avi'):
5386
- fn+='.avi'
5387
-
5388
- if framerate<1:
5389
- dlg = wx.NumberEntryDialog(None, _("Frame rate [nb_images/second]"), _('Frame rate'), _('Frame rate'), 24, 1, 100)
5390
-
5391
- ret = dlg.ShowModal()
5588
+ dlg = Sim_VideoCreation(None, title = _('Video creation'), sim= self.active_res2d, mapviewer=self)
5392
5589
 
5393
- if ret == wx.ID_CANCEL:
5394
- dlg.Destroy()
5395
- return
5396
-
5397
- framerate = int(dlg.GetValue())
5590
+ ret = dlg.ShowModal()
5591
+ if ret == wx.ID_CANCEL:
5398
5592
  dlg.Destroy()
5593
+ return
5399
5594
 
5595
+ fn, framerate, start_step, end_step, interval, fontsize, fontcolor, timeposition = dlg.get_values()
5596
+ dlg.Destroy()
5400
5597
 
5401
5598
  times,steps = self.active_res2d.get_times_steps()
5402
5599
 
5403
- el_time = str(timedelta(seconds=int(times[self.active_res2d.current_result])))
5404
-
5405
- fig:Figure
5406
- fig, ax = self.get_mpl_plot([self.mousex, self.mousey],
5407
- self.width,
5408
- self.height,
5409
- title=_('Current time {:0>8} s'.format(el_time)),
5410
- toshow=False)
5411
-
5412
- video = cv2.VideoWriter(fn, cv2.VideoWriter_fourcc(*'XVID'), framerate, fig.canvas.get_width_height())
5413
-
5414
- nb = self.active_res2d.get_nbresults()
5415
- cid = max(self.active_res2d.current_result,1)
5416
-
5417
- self.active_res2d.mypal.automatic=False
5418
-
5419
- if start_step==0:
5420
- dlg = wx.NumberEntryDialog(None, _("First step"), _('From'), _('from'), cid, 1, nb)
5421
-
5422
- ret = dlg.ShowModal()
5423
-
5424
- if ret == wx.ID_CANCEL:
5425
- dlg.Destroy()
5426
- return
5427
-
5428
- start_step = int(dlg.GetValue())
5429
- dlg.Destroy()
5430
-
5431
- if end_step==0:
5432
- dlg = wx.NumberEntryDialog(None, _("Final step"), _('To'), _('To'), nb, 1, nb)
5433
-
5434
- ret = dlg.ShowModal()
5600
+ framesize = (int(self.canvaswidth), int(self.canvasheight))
5601
+ video = cv2.VideoWriter(fn, cv2.VideoWriter_fourcc(*'XVID'), framerate, framesize)
5435
5602
 
5436
- if ret == wx.ID_CANCEL:
5437
- dlg.Destroy()
5438
- return
5439
-
5440
- end_step = int(dlg.GetValue())
5441
- dlg.Destroy()
5442
-
5443
- if every==0:
5444
- dlg = wx.NumberEntryDialog(None, _("Interval"), _('Interval'), _('Interval'), 1, 1, end_step-start_step)
5445
-
5446
- ret = dlg.ShowModal()
5447
-
5448
- if ret == wx.ID_CANCEL:
5449
- dlg.Destroy()
5450
- return
5603
+ el_time = str(timedelta(seconds=int(times[self.active_res2d.current_result])))
5451
5604
 
5452
- interval = int(dlg.GetValue())
5453
- dlg.Destroy()
5605
+ zones_time = Zones(mapviewer=self)
5606
+ self.add_object('vector', newobj=zones_time, ToCheck=True, id='__VideoTime__')
5607
+ zone_time = zone(name='Time')
5608
+ vec_time = vector(name='Time')
5609
+
5610
+ zones_time.add_zone(zone_time, forceparent=True)
5611
+ zone_time.add_vector(vec_time, forceparent=True)
5612
+
5613
+ if timeposition == 'top-center':
5614
+ x = (self.xmax+self.xmin)/2.
5615
+ y = self.ymax - 0.05*(self.ymax-self.ymin)
5616
+ elif timeposition == 'bottom-center':
5617
+ x = (self.xmax+self.xmin)/2.
5618
+ y = self.ymin + 0.05*(self.ymax-self.ymin)
5619
+ elif timeposition == 'top-left':
5620
+ x = self.xmin + 0.15*(self.xmax-self.xmin)
5621
+ y = self.ymax - 0.05*(self.ymax-self.ymin)
5622
+ elif timeposition == 'bottom-left':
5623
+ x = self.xmin + 0.15*(self.xmax-self.xmin)
5624
+ y = self.ymin + 0.05*(self.ymax-self.ymin)
5625
+ elif timeposition == 'top-right':
5626
+ x = self.xmax - 0.15*(self.xmax-self.xmin)
5627
+ y = self.ymax - 0.05*(self.ymax-self.ymin)
5628
+ elif timeposition == 'bottom-right':
5629
+ x = self.xmax - 0.15*(self.xmax-self.xmin)
5630
+ y = self.ymin + 0.05*(self.ymax-self.ymin)
5631
+ else:
5632
+ x = (self.xmax+self.xmin)/2.
5633
+ y = self.ymax - 0.05*(self.ymax-self.ymin)
5454
5634
 
5455
- self.read_one_result(start_step)
5635
+ vec_time.add_vertex(wolfvertex(x,y))
5636
+ vec_time.set_legend_position(x,y)
5637
+ vec_time.set_legend_text('Time {:0>8} s'.format(el_time))
5638
+ vec_time.set_legend_visible(True)
5639
+ vec_time.myprop.legendfontsize = fontsize
5640
+ vec_time.myprop.legendcolor = getIfromRGB(fontcolor)
5456
5641
 
5457
5642
  for curmodel in self.iterator_over_objects(draw_type.RES2D):
5458
5643
  curmodel: Wolfresults_2D
5459
5644
  curmodel.step_interval_results = interval
5460
5645
 
5461
- for idx in tqdm(range(start_step, end_step, interval)):
5646
+ all_steps = range(0, int((end_step-start_step) // interval) + 1)
5647
+
5648
+ pgbar = wx.ProgressDialog(_('Video creation'),
5649
+ _('Creating video...'),
5650
+ maximum = len(all_steps),
5651
+ parent = None,
5652
+ style = wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME | wx.PD_ESTIMATED_TIME | wx.PD_REMAINING_TIME)
5653
+ pgbar.Show()
5654
+
5655
+ self.read_one_result(start_step-1)
5656
+ for idx in tqdm(all_steps, desc=_('Creating video')):
5462
5657
 
5463
- image = Image.frombytes('RGB', fig.canvas.get_width_height(),fig.canvas.tostring_rgb())
5658
+ image = self.get_canvas_as_image()
5464
5659
 
5465
5660
  video.write(cv2.cvtColor(np.asarray(image),cv2.COLOR_RGB2BGR))
5466
5661
 
5467
5662
  self.simul_next_step()
5468
5663
 
5469
5664
  el_time = str(timedelta(seconds=int(times[self.active_res2d.current_result])))
5665
+ vec_time.set_legend_text('Time {:0>8} s'.format(el_time))
5470
5666
 
5471
- self.display_canvasogl(fig=fig,
5472
- ax=ax[0],
5473
- title=_('Current time {:0>8} s'.format(el_time)))
5667
+ if not pgbar.WasCancelled():
5668
+ pgbar.Update(idx)
5669
+ else:
5670
+ break
5671
+
5672
+ pgbar.Destroy()
5673
+ video.release()
5474
5674
 
5475
5675
  for curmodel in self.iterator_over_objects(draw_type.RES2D):
5476
5676
  curmodel: Wolfresults_2D
5477
5677
  curmodel.step_interval_results = 1
5478
5678
 
5679
+ self.removeobj_from_id('__VideoTime__')
5479
5680
 
5480
5681
  def get_canvas_as_image(self) -> Image.Image:
5481
5682
  """
@@ -5493,7 +5694,11 @@ class WolfMapViewer(wx.Frame):
5493
5694
 
5494
5695
  return myimage
5495
5696
 
5496
- def copy_canvasogl(self, mpl:bool= True, ds:float= 0., figsizes= [10.,10.], palette:wolfpalette = None):
5697
+ def copy_canvasogl(self,
5698
+ mpl:bool= True,
5699
+ ds:float= 0.,
5700
+ figsizes= [10.,10.],
5701
+ palette:wolfpalette = None):
5497
5702
  """
5498
5703
  Generate image based on UI context and copy to the Clipboard
5499
5704
 
@@ -5811,7 +6016,7 @@ class WolfMapViewer(wx.Frame):
5811
6016
  'Opengl setcurrent -- maybe a conflict with an existing opengl32.dll file - please rename the opengl32.dll in the libs directory and retry')
5812
6017
 
5813
6018
  def reporting(self, dir=''):
5814
- """ Firsdt attempr to create a reporting.
6019
+ """ First attempt to create a reporting.
5815
6020
  !! Must be improved !!
5816
6021
  """
5817
6022
  if dir == '':
@@ -6940,6 +7145,14 @@ class WolfMapViewer(wx.Frame):
6940
7145
 
6941
7146
  """
6942
7147
 
7148
+ msg = _('This function will force a null border of 1 cell on each array to avoid issues with the contouring algorithm')
7149
+ dlg = wx.MessageDialog(None, msg, _('Warning'), wx.OK | wx.CANCEL | wx.ICON_WARNING)
7150
+ result = dlg.ShowModal()
7151
+ dlg.Destroy()
7152
+ if result != wx.ID_OK:
7153
+ logging.info(_('Operation cancelled by user'))
7154
+ return None
7155
+
6943
7156
  # création de l'instance de Zones
6944
7157
  new_zones = Zones(idx = 'contour' if id is None else id.lower(), mapviewer=self)
6945
7158
 
@@ -6948,6 +7161,7 @@ class WolfMapViewer(wx.Frame):
6948
7161
  if isinstance(curarray, WolfArray):
6949
7162
 
6950
7163
  curarray.nullify_border(1)
7164
+ curarray.reset_plot()
6951
7165
 
6952
7166
  new_zone = zone(name = curarray.idx)
6953
7167
  new_zones.add_zone(new_zone, forceparent=True)
@@ -8295,6 +8509,9 @@ class WolfMapViewer(wx.Frame):
8295
8509
  def read_one_result(self, which:int):
8296
8510
  """
8297
8511
  Lecture d'un résultat spécific pour les modèles ajoutés et plottés
8512
+
8513
+ :param which: result index (0-based) -- -1 for last result
8514
+ 0 = first result
8298
8515
  """
8299
8516
  self.currently_readresults = True
8300
8517
 
@@ -9597,7 +9814,7 @@ class WolfMapViewer(wx.Frame):
9597
9814
  elif itemlabel == _("Add distances to viewer..."):
9598
9815
 
9599
9816
  if self._distances is not None:
9600
- self.add_object('vector', newobj=self._distances, ToCheck=True, id='Distances')
9817
+ self.add_object('vector', newobj=self._distances, ToCheck=True, id='Distances',)
9601
9818
 
9602
9819
  elif itemlabel == _("Create bridge and export gltf..."):
9603
9820
 
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 = 39
8
+ self.patch = 41
9
9
 
10
10
  def __str__(self):
11
11
 
wolfhece/eva/pyseries.py CHANGED
@@ -1277,8 +1277,31 @@ class EVA_Serie:
1277
1277
  k+=1
1278
1278
 
1279
1279
 
1280
- def plot_classified_flowrate_curve(self, fig:Figure=None, ax:Axes=None, label='', textvalues=True, show=False) -> tuple[Figure,Axes]:
1280
+ def plot_classified_flowrate_curve(self, fig:Figure=None, ax:Axes=None, label='', textvalues=True, show=False) -> tuple[Figure,Axes, dict]:
1281
+ """
1282
+ Plot classified flow rate curve.
1283
+
1284
+ Characteristics returned in dict are:
1285
+ - DCE : Débit journalier dépassé en moyenne 355 jours par an
1286
+ - DC10 : Débit journalier dépassé en moyenne 10 mois par an
1287
+ - Q347 : Débit atteint ou dépassé, en moyenne, pendant 347 jours par an
1288
+ - DM : Débit atteint ou dépassé, en moyenne, pendant 50% du temps - débit médian
1289
+ - DCC : Débit journalier qui est dépassé 10 jours par an
1290
+
1291
+ Previous lines are keys of characteristics dict.
1281
1292
 
1293
+ Each characteristic is a dict with:
1294
+ - 'help' : explanation of characteristic
1295
+ - 'x' : number of days with exceedance
1296
+ - 'value' : discharge value
1297
+
1298
+ :param fig: Matplotlib figure
1299
+ :param ax: Matplotlib axis
1300
+ :param label: label for the curve
1301
+ :param textvalues: if True, text of characteristics are added
1302
+ :param show: if True, plt.show() is called
1303
+ :return: fig, ax, resdict
1304
+ """
1282
1305
  if ax is None:
1283
1306
  fig,ax = plt.subplots(1,1)
1284
1307
 
@@ -1114,8 +1114,10 @@ class hydrometry():
1114
1114
  while curfrom<todate:
1115
1115
  logging.info('Getting data from {0} to {1}'.format(curfrom, curend))
1116
1116
  tmpts = self.timeseries(stationname, stationcode, dir = dir, fromdate= curfrom, todate= curend, ts_name= ts_name, ts_id= ts_id, timezone=timezone)
1117
- if len(tmpts)>0:
1118
- locts.append(tmpts)
1117
+
1118
+ if isinstance(tmpts, pd.Series):
1119
+ if len(tmpts)>0:
1120
+ locts.append(tmpts)
1119
1121
 
1120
1122
  curfrom = curend
1121
1123
  curend = curfrom+timedelta(seconds=200000 * cursec)
@@ -1145,7 +1147,7 @@ class hydrometry():
1145
1147
  df.index = pd.to_datetime(df.index,format="%Y-%m-%dT%H:%M:%S.%f%z")
1146
1148
 
1147
1149
  except Exception as e:
1148
- logging.error('Error in timeseries :', e)
1150
+ logging.error('Error in timeseries ! - Check if the server is responding.')
1149
1151
  return pd.DataFrame()
1150
1152
 
1151
1153
  return df.squeeze()
@@ -17,6 +17,7 @@ import matplotlib.pyplot as plt
17
17
  import pandas as pd
18
18
  from datetime import datetime as dt, timedelta
19
19
  import logging
20
+ import numpy as np
20
21
 
21
22
  #Test de la présence de la fonction de traduction i18n "gettext" et définition le cas échéant pour ne pas créer d'erreur d'exécution
22
23
  import os
@@ -472,7 +473,7 @@ class hydrometry_gui(wx.Frame):
472
473
  for curdata, curname in zip(data,tsname):
473
474
  if curdata is not None:
474
475
  if len(curdata)>1:
475
- if datumsizebv[0]!='':
476
+ if datumsizebv[0]!='' and not np.isnan(datumsizebv[0]):
476
477
  ax.step(curdata.index, curdata+float(datumsizebv[0]), where='post', label=curname)
477
478
  else:
478
479
  ax.step(curdata.index, curdata, where='post', label=curname)
@@ -537,6 +537,9 @@ class xyz_laz_grids():
537
537
  """ Ensemble de grids """
538
538
 
539
539
  def __init__(self, dir_grids:str, create:bool=False) -> None:
540
+
541
+ dir_grids = str(dir_grids)
542
+
540
543
  self.grids:list[xyz_laz_grid] = []
541
544
  self.colors = Classification_LAZ()
542
545
  self.colors.init_2023()
@@ -747,7 +750,7 @@ class xyz_laz_grids():
747
750
 
748
751
  return figmpl
749
752
 
750
- def create_from_laz(self, dir_laz:str, shape:str=None, ds:float = 50, force_format = np.float64):
753
+ def create_from_laz(self, dir_laz:Path, shape:str=None, ds:float = 50, force_format = np.float64):
751
754
 
752
755
  try:
753
756
  from ..PyVertexvectors import Zones
@@ -142,7 +142,7 @@ class Calculator(wx.Frame):
142
142
  checked_state=None)
143
143
 
144
144
  for id_array in id_arrays:
145
- self._memory[id_array] = self._mapviewer.get_obj_from_id(id_array, drawtype=draw_type.ARRAYS)
145
+ self._memory[id_array] = self._mapviewer.get_obj_from_id(id_array, drawing_type=draw_type.ARRAYS)
146
146
 
147
147
  if len(variables) > 0:
148
148
  for var in variables:
wolfhece/pydownloader.py CHANGED
@@ -19,6 +19,7 @@ from enum import Enum
19
19
  from typing import Union, Optional, List
20
20
  from collections import namedtuple
21
21
  import logging
22
+ import urllib.parse
22
23
 
23
24
  class DownloadType(Enum):
24
25
  """ Enum to define the type of download. """
@@ -43,6 +44,9 @@ class DownloadFiles(Enum):
43
44
  CSVFILES = ('csv',)
44
45
  DXFFILES = ('dxf',)
45
46
  ZIPFILES = ('zip',)
47
+ LAZFILES = ('laz',)
48
+ LISTFILES = ('lst',)
49
+ LAZBIN = ('bin',)
46
50
 
47
51
  class DonwloadDirectories(Enum):
48
52
  """ Enum to define the directories for downloads. """
@@ -51,6 +55,10 @@ class DonwloadDirectories(Enum):
51
55
 
52
56
  GITLAB_EXAMPLE = 'https://gitlab.uliege.be/HECE/wolf_examples/-/raw/main'
53
57
  GITLAB_EXAMPLE_GPU = 'https://gitlab.uliege.be/HECE/wolfgpu_examples/-/raw/main'
58
+
59
+ GITLAB_MODREC_DATA_VESDRE = 'https://gitlab.uliege.be/api/v4/projects/4933'
60
+ GITLAB_MODREC_DATA_VESDRE_FILES = 'https://gitlab.uliege.be/api/v4/projects/4933/repository/files/'
61
+
54
62
  DATADIR = Path(__file__).parent / 'data' / 'downloads'
55
63
 
56
64
  def clean_url(url: str) -> str:
@@ -80,7 +88,12 @@ def clean_url(url: str) -> str:
80
88
  raise ValueError(f"Invalid URL: {url}. Must start with http://, https://, or ftp://")
81
89
  return cleaned_url.strip()
82
90
 
83
- def download_file(url: str, destination: Union[str, Path] = None, download_type: DownloadType = DownloadType.HTTP, load_from_cache:bool = True):
91
+ def download_file(url: str,
92
+ destination: Union[str, Path] = None,
93
+ download_type: DownloadType = DownloadType.HTTP,
94
+ load_from_cache:bool = True,
95
+ token:str = None,
96
+ file_type:DownloadType = None) -> Path:
84
97
  """ Download a file from the specified URL to the destination path.
85
98
 
86
99
  :param url: The URL of the file to download.
@@ -95,11 +108,13 @@ def download_file(url: str, destination: Union[str, Path] = None, download_type:
95
108
 
96
109
  url = str(url).strip()
97
110
  # Clean the URL
98
- url = clean_url(url)
111
+ if file_type is None:
112
+ url = clean_url(url)
99
113
 
100
114
  if destination is None:
101
115
  try:
102
- destination = DATADIR / Path(url).parent.name / Path(url).name
116
+ url_cleaned = url.replace('/raw?ref=main', '').replace('%2F', '/')
117
+ destination = DATADIR / Path(url_cleaned).parent.name / Path(url_cleaned).name
103
118
  except:
104
119
  destination = DATADIR / Path(url).name
105
120
  # create the directory if it does not exist
@@ -110,11 +125,19 @@ def download_file(url: str, destination: Union[str, Path] = None, download_type:
110
125
  if suffix.startswith('.'):
111
126
  suffix = suffix[1:]
112
127
 
113
- # Find the download type based on the URL suffix
114
- for file_type_enum in DownloadFiles:
115
- if suffix in file_type_enum.value:
116
- file_type = file_type_enum
117
- break
128
+ if file_type is None:
129
+ # Find the download type based on the URL suffix
130
+ for file_type_enum in DownloadFiles:
131
+ if suffix in file_type_enum.value:
132
+
133
+ if suffix == 'bin' and '_xyz.bin' in url:
134
+ # special case for LAZ bin files
135
+ file_type_enum = DownloadFiles.LAZBIN
136
+
137
+ file_type = file_type_enum
138
+ break
139
+ else:
140
+ suffix = file_type.value[0]
118
141
 
119
142
  # Create a list of files to download based on the download type
120
143
  # by replacing suffix in the url with the appropriate file extensions
@@ -124,6 +147,7 @@ def download_file(url: str, destination: Union[str, Path] = None, download_type:
124
147
  if ext.startswith('.'):
125
148
  ext = ext[1:]
126
149
  to_download.append(url.replace(suffix, f'{ext}'))
150
+
127
151
  to_destination.append(destination.with_suffix(f'.{ext}'))
128
152
 
129
153
 
@@ -131,6 +155,15 @@ def download_file(url: str, destination: Union[str, Path] = None, download_type:
131
155
 
132
156
  for url, destination in zip(to_download, to_destination):
133
157
 
158
+ if token is not None:
159
+ # Requête HTTP avec le token
160
+ headers = {
161
+ "PRIVATE-TOKEN": token
162
+ }
163
+ else:
164
+ headers = {}
165
+
166
+
134
167
  if load_from_cache and destination.exists():
135
168
  logging.info(f"File {destination} already exists. Skipping download.")
136
169
  continue
@@ -139,7 +172,7 @@ def download_file(url: str, destination: Union[str, Path] = None, download_type:
139
172
  raise ValueError(f"Invalid URL: {url}. Must start with http:// or https://")
140
173
 
141
174
  try:
142
- response = requests.get(url)
175
+ response = requests.get(url, headers=headers)
143
176
  response.raise_for_status()
144
177
  with open(destination, 'wb') as file:
145
178
  file.write(response.content)
@@ -254,7 +287,134 @@ def toys_gpu_dataset(dir:str, dirweb:str = None, load_from_cache:bool = True):
254
287
 
255
288
  return download_gpu_simulation(f"{GITLAB_EXAMPLE_GPU}/{dirweb}", DATADIR / dir, load_from_cache=load_from_cache)
256
289
 
290
+ def toys_laz_grid(dir:str, file:str, load_from_cache:bool = True):
291
+ """ Download toy LAZ or GRIDWOLF files from the WOLFHECE dataset.
292
+
293
+ :param dir: The directory where the file will be saved.
294
+ :param file: The name of the file to download.
295
+ :type dir: str
296
+ :type file: str
297
+ :return: The path to the downloaded directory.
298
+ """
299
+ url = f"{GITLAB_EXAMPLE}/{dir}/{file}"
300
+ destination = DATADIR / dir / file
301
+ lst = download_file(url, destination, load_from_cache=load_from_cache)
302
+
303
+ with open(lst, 'r') as f:
304
+ lines = f.read().splitlines()
305
+
306
+ for line in lines:
307
+ line = line.strip().replace('\\', '/')
308
+ if line:
309
+ url = f"{GITLAB_EXAMPLE}/{dir}/{line}"
310
+ destination = DATADIR / dir / line
311
+ download_file(url, destination, load_from_cache=load_from_cache)
312
+
313
+ return DATADIR / dir
314
+
315
+ def laz_grid_from_url(url:str, dir:str, file:str, load_from_cache:bool = True):
316
+ """ Download toy LAZ or GRIDWOLF files from an external URL.
317
+
318
+ :param url: The base URL where the files are located.
319
+ :param dir: The directory where the file will be saved.
320
+ :param file: The name of the file to download.
321
+ :type url: str
322
+ :type dir: str
323
+ :type file: str
324
+ :return: The path to the downloaded directory.
325
+ """
326
+ url = f"{url}/{dir}/{file}"
327
+ destination = DATADIR / dir / file
328
+ lst = download_file(url, destination, load_from_cache=load_from_cache)
329
+
330
+ if not Path(lst).exists():
331
+ raise FileNotFoundError(f"The file {lst} does not exist. -- Check the URL and file name.")
332
+
333
+ with open(lst, 'r') as f:
334
+ lines = f.read().splitlines()
335
+
336
+ for line in lines:
337
+ line = line.strip().replace('\\', '/')
338
+ if line:
339
+ url = f"{GITLAB_EXAMPLE}/{dir}/{line}"
340
+ destination = DATADIR / dir / line
341
+ download_file(url, destination, load_from_cache=load_from_cache)
342
+
343
+ return DATADIR / dir
344
+
345
+ def check_status(url:str, token:str = None) -> bool:
346
+ """ Check the status of a URL.
347
+
348
+ :param url: The URL to check.
349
+ :param token: The private token for authentication (if required).
350
+ :type url: str
351
+ :type token: str
352
+ :return: True if the URL is accessible, False otherwise.
353
+ :rtype: bool
354
+ """
355
+ url = str(url).strip()
356
+ url = clean_url(url)
357
+
358
+ if not url.startswith(('http://', 'https://')):
359
+ raise ValueError(f"Invalid URL: {url}. Must start with http:// or https://")
360
+
361
+ try:
362
+ if token is not None:
363
+ headers = {
364
+ "PRIVATE-TOKEN": token
365
+ }
366
+ else:
367
+ headers = {}
368
+
369
+ response = requests.head(url, headers=headers)
370
+ return response.status_code == 200
371
+ except requests.RequestException as e:
372
+ logging.error(f"Error checking URL {url}: {e}")
373
+ return False
374
+
375
+ def download_modrec_vesdre_file(directory:str, filename:str,
376
+ token:str = None, load_from_cache:bool = True,
377
+ file_type:DownloadFiles = None) -> Path:
378
+
379
+ """ Download a file from the ModRec Vesdre dataset.
380
+
381
+ :param directory: The directory where the file is located (relative to the repository root).
382
+ :param filename: The name of the file to download.
383
+ :param token: The private token for authentication (if required).
384
+ :param load_from_cache: If True, will not download the file if it already exists.
385
+ :type directory: str
386
+ :type filename: str
387
+ :type token: str
388
+ :type load_from_cache: bool
389
+ :return: The path to the downloaded file.
390
+ :rtype: Path
391
+ """
392
+
393
+ # Find the download type based on the URL suffix
394
+ if file_type is None:
395
+ suffix = Path(filename).suffix.lower().replace('.', '')
396
+
397
+ for file_type_enum in DownloadFiles:
398
+ if suffix in file_type_enum.value:
399
+
400
+ if suffix == 'bin' and '_xyz.bin' in filename:
401
+ # special case for LAZ bin files
402
+ file_type_enum = DownloadFiles.LAZBIN
403
+
404
+ file_type = file_type_enum
405
+ break
406
+
407
+ file_path_encoded = urllib.parse.quote_plus(directory + '/' + filename)
408
+ url = f"{GITLAB_MODREC_DATA_VESDRE_FILES}{file_path_encoded}/raw?ref=main"
409
+ destination = DATADIR / 'Vesdre' / file_path_encoded.replace('%2F', '/')
410
+ return download_file(url, destination, token=token, load_from_cache=load_from_cache, file_type=file_type)
411
+
257
412
  if __name__ == "__main__":
413
+ token = '' # Add your GitLab private token here if needed
414
+ dir = 'LAZ_Vesdre/2023/grids_flt32/237500_145500'
415
+ file_path = "237500_145500_237500_145000_xyz.bin"
416
+ print(download_modrec_vesdre_file(dir, file_path, token=token, load_from_cache=False))
417
+
258
418
  # Example usage
259
419
  print(download_file(r'https:\\gitlab.uliege.be\HECE\wolf_examples\-\raw\main\Extract_part_array\extraction.vec'))
260
420
  print(download_file('https://gitlab.uliege.be/HECE/wolf_examples/-/raw/main/Extract_part_array/extraction.vec'))
@@ -2500,7 +2500,15 @@ class UI_Manager_2D_GPU():
2500
2500
 
2501
2501
  pgbar = wx.ProgressDialog(_('Creating simulations ...'), _('Please wait ...'), maximum=len(hydro), parent=self._frame, style = wx.PD_APP_MODAL | wx.PD_AUTO_HIDE)
2502
2502
 
2503
- allsims = self._parent.create_simulation(Path(path), hydro, destroy_if_exists, preserve_ic, callback=pgbar.Update)
2503
+ try:
2504
+ allsims = self._parent.create_simulation(Path(path), hydro, destroy_if_exists, preserve_ic, callback=pgbar.Update)
2505
+ except Exception as e:
2506
+ logging.error(_('Error while creating simulations !'))
2507
+ logging.error(str(e))
2508
+ dlg = wx.MessageDialog(None, _('Error while creating simulations !\n\n{}'.format(str(e))), _('Error'), wx.OK | wx.ICON_ERROR)
2509
+ dlg.ShowModal()
2510
+ dlg.Destroy()
2511
+ allsims = None
2504
2512
 
2505
2513
  pgbar.Destroy()
2506
2514
 
wolfhece/wolf_array.py CHANGED
@@ -9235,7 +9235,13 @@ class WolfArray(Element_To_Draw, header_wolf):
9235
9235
  newArray.origz = self.origz
9236
9236
  newArray.translz = self.translz
9237
9237
 
9238
- if type(other) == float:
9238
+ if type(other) in [float, int]:
9239
+
9240
+ if type(other) == int and self.wolftype in [WOLF_ARRAY_FULL_DOUBLE, WOLF_ARRAY_FULL_SINGLE]:
9241
+ other = float(other)
9242
+ elif type(other) == float and self.wolftype in [WOLF_ARRAY_FULL_INTEGER, WOLF_ARRAY_FULL_INTEGER16, WOLF_ARRAY_FULL_INTEGER16_2, WOLF_ARRAY_FULL_INTEGER8, WOLF_ARRAY_FULL_UINTEGER8]:
9243
+ other = int(other)
9244
+
9239
9245
  if other != 0.:
9240
9246
  newArray.array = np.ma.masked_array(self.array + other, self.array.mask, dtype=self.array.dtype)
9241
9247
  else:
@@ -9264,7 +9270,13 @@ class WolfArray(Element_To_Draw, header_wolf):
9264
9270
  newArray.origz = self.origz
9265
9271
  newArray.translz = self.translz
9266
9272
 
9267
- if type(other) == float:
9273
+ if type(other) in [float, int]:
9274
+
9275
+ if type(other) == int and self.wolftype in [WOLF_ARRAY_FULL_DOUBLE, WOLF_ARRAY_FULL_SINGLE]:
9276
+ other = float(other)
9277
+ elif type(other) == float and self.wolftype in [WOLF_ARRAY_FULL_INTEGER, WOLF_ARRAY_FULL_INTEGER16, WOLF_ARRAY_FULL_INTEGER16_2, WOLF_ARRAY_FULL_INTEGER8, WOLF_ARRAY_FULL_UINTEGER8]:
9278
+ other = int(other)
9279
+
9268
9280
  if other != 0.:
9269
9281
  newArray.array = np.ma.masked_array(self.array * other, self.array.mask, dtype=self.array.dtype)
9270
9282
  else:
@@ -9296,7 +9308,13 @@ class WolfArray(Element_To_Draw, header_wolf):
9296
9308
  newArray.origz = self.origz
9297
9309
  newArray.translz = self.translz
9298
9310
 
9299
- if type(other) == float:
9311
+ if type(other) in [float, int]:
9312
+
9313
+ if type(other) == int and self.wolftype in [WOLF_ARRAY_FULL_DOUBLE, WOLF_ARRAY_FULL_SINGLE]:
9314
+ other = float(other)
9315
+ elif type(other) == float and self.wolftype in [WOLF_ARRAY_FULL_INTEGER, WOLF_ARRAY_FULL_INTEGER16, WOLF_ARRAY_FULL_INTEGER16_2, WOLF_ARRAY_FULL_INTEGER8, WOLF_ARRAY_FULL_UINTEGER8]:
9316
+ other = int(other)
9317
+
9300
9318
  if other != 0.:
9301
9319
  newArray.array = np.ma.masked_array(self.array - other, self.array.mask, dtype=self.array.dtype)
9302
9320
  else:
@@ -9325,7 +9343,18 @@ class WolfArray(Element_To_Draw, header_wolf):
9325
9343
  newArray.origz = self.origz
9326
9344
  newArray.translz = self.translz
9327
9345
 
9328
- newArray.array = np.ma.masked_array(self.array ** other, self.array.mask, dtype=self.array.dtype)
9346
+ if type(other) in [float, int]:
9347
+
9348
+ if type(other) == int and self.wolftype in [WOLF_ARRAY_FULL_DOUBLE, WOLF_ARRAY_FULL_SINGLE]:
9349
+ other = float(other)
9350
+ elif type(other) == float and self.wolftype in [WOLF_ARRAY_FULL_INTEGER, WOLF_ARRAY_FULL_INTEGER16, WOLF_ARRAY_FULL_INTEGER16_2, WOLF_ARRAY_FULL_INTEGER8, WOLF_ARRAY_FULL_UINTEGER8]:
9351
+ other = int(other)
9352
+
9353
+ newArray.array = np.ma.masked_array(self.array ** other, self.array.mask, dtype=self.array.dtype)
9354
+ else:
9355
+ logging.error(_('Power operator only implemented for scalars'))
9356
+ newArray.array[:,:] = 0
9357
+
9329
9358
  newArray.count()
9330
9359
 
9331
9360
  assert newArray.array.dtype == self.array.dtype, _('Bad dtype')
@@ -9350,9 +9379,17 @@ class WolfArray(Element_To_Draw, header_wolf):
9350
9379
  newArray.origz = self.origz
9351
9380
  newArray.translz = self.translz
9352
9381
 
9353
- if type(other) == float:
9382
+ if type(other) in [float, int]:
9383
+
9384
+ if type(other) == int and self.wolftype in [WOLF_ARRAY_FULL_DOUBLE, WOLF_ARRAY_FULL_SINGLE]:
9385
+ other = float(other)
9386
+ elif type(other) == float and self.wolftype in [WOLF_ARRAY_FULL_INTEGER, WOLF_ARRAY_FULL_INTEGER16, WOLF_ARRAY_FULL_INTEGER16_2, WOLF_ARRAY_FULL_INTEGER8, WOLF_ARRAY_FULL_UINTEGER8]:
9387
+ other = int(other)
9388
+
9354
9389
  if other != 0.:
9355
9390
  newArray.array = np.ma.masked_array(self.array / other, self.array.mask, dtype=self.array.dtype)
9391
+ else:
9392
+ logging.error(_('Division by 0 -- Nothing to do !'))
9356
9393
  else:
9357
9394
  newArray.array = np.ma.masked_array(np.where(other == 0., 0., self.array / other.array), self.array.mask, dtype=self.array.dtype)
9358
9395
  newArray.count()
@@ -5431,7 +5431,7 @@ class Wolfresults_2D(Element_To_Draw):
5431
5431
  head[ij]= z[ij] + v[ij]**2./2/9.81
5432
5432
 
5433
5433
  # Fill the time of arrival
5434
- danger_map_matrix_toa[curblock].array[(danger_map_matrix_toa.array == DEFAULT_TOA) & (wd.array > hmin)] = cur_time
5434
+ danger_map_matrix_toa[curblock].array[(danger_map_matrix_toa.array == DEFAULT_TOA) & (wd.array > hmin) & (~wd.array.mask)] = cur_time
5435
5435
 
5436
5436
  # Fill the time of maximum
5437
5437
  # Searching where wd > h_max
@@ -5466,7 +5466,7 @@ class Wolfresults_2D(Element_To_Draw):
5466
5466
  head[ij]= z[ij] + v[ij]**2./2/9.81
5467
5467
 
5468
5468
  # Fill the time of arrival
5469
- danger_map_matrix_toa.array[(danger_map_matrix_toa.array == DEFAULT_TOA) & (wd.array > hmin)] = cur_time
5469
+ danger_map_matrix_toa.array[(danger_map_matrix_toa.array == DEFAULT_TOA) & (wd.array > hmin) & (~wd.array.mask)] = cur_time
5470
5470
 
5471
5471
  # Fill the time of maximum
5472
5472
  # Searching where wd > h_max
@@ -5616,7 +5616,7 @@ class Wolfresults_2D(Element_To_Draw):
5616
5616
  danger_toa = danger_map_matrix_toa[i].array
5617
5617
  res_toa = result[5][i].array
5618
5618
 
5619
- ij = np.where((danger_toa.data == DEFAULT_TOA) & (res_toa.data > 0.))
5619
+ ij = np.where(((danger_toa.data == DEFAULT_TOA) & (res_toa.data > 0.) & (~res_toa.mask)) | (danger_toa.data > res_toa.data))
5620
5620
  danger_toa.data[ij] = res_toa.data[ij]
5621
5621
  danger_toa.mask[ij] = False
5622
5622
 
@@ -5657,7 +5657,7 @@ class Wolfresults_2D(Element_To_Draw):
5657
5657
  danger_toa = danger_map_matrix_toa.array
5658
5658
  res_toa = result[5].array
5659
5659
 
5660
- ij = np.where((danger_toa.data == DEFAULT_TOA) & (res_toa.data > 0.))
5660
+ ij = np.where(((danger_toa.data == DEFAULT_TOA) & (res_toa.data > DEFAULT_TOA) & (~res_toa.mask)) | (danger_toa.data > res_toa.data))
5661
5661
  danger_toa.data[ij] = res_toa.data[ij]
5662
5662
  danger_toa.mask[ij] = False
5663
5663
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wolfhece
3
- Version: 2.2.39
3
+ Version: 2.2.41
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
@@ -9,7 +9,7 @@ wolfhece/MulticriteriAnalysis.py,sha256=vGmkzYagZohNe0XjwGJ6VUXcDPjOt80lNFthXpzx
9
9
  wolfhece/PandasGrid.py,sha256=etfVhIHzja4Z1EUY6BcDOKX-w7V-Xou1yaf0NMqmclo,4599
10
10
  wolfhece/PyConfig.py,sha256=13DDWjJdohYHwn1uRVHB0s8Jcwq_b9pwcwbAr8NlZyc,19667
11
11
  wolfhece/PyCrosssections.py,sha256=6K9xhupnIVXzLdsLTPN9e1v0xck9BdWZd0-EgpWg9us,133277
12
- wolfhece/PyDraw.py,sha256=XjIi5yDcl56C5fFHQUFdJvyU7r8jJ9z7aRVPOZijQcI,727297
12
+ wolfhece/PyDraw.py,sha256=d74OkFrQjN_41xk2jtlY53Pk2OgUD39gwUoOwmybKHU,737432
13
13
  wolfhece/PyGui.py,sha256=GpVRxNpR8WNDFyHnDvhtHFFsq_cZZlyVgSkFiS-ARYI,185342
14
14
  wolfhece/PyGuiHydrology.py,sha256=dmBlRO8AljsvCPH6eVt0l9ZLx7g5j7Ubl9Srk7ECwyA,34693
15
15
  wolfhece/PyHydrographs.py,sha256=1P5XAURNqCvtSsMQXhOn1ihjTpr725sRsZdlCEhhk6M,3730
@@ -56,7 +56,7 @@ wolfhece/pyGui1D.py,sha256=9g7OS3YiKsqy--6y0cBD7x2gaqTTYFXWkxImpgnTA20,121937
56
56
  wolfhece/pyLandUseFlanders.py,sha256=4R4J4BgP1-W0sebnb-TBreStZx3DKOh1zYj_dg23Ac4,8657
57
57
  wolfhece/pybridges.py,sha256=bFAqjL4ColeJtwvyCPGQ8VllWoq1RbVWXxFrdfrvqm8,65954
58
58
  wolfhece/pydike.py,sha256=dRb6qGkqoTXjf107KcajcIk1F_FuMPaOZLSwixT3dgA,11196
59
- wolfhece/pydownloader.py,sha256=DvWkOWIaIg-qsyzyx-SwP0xc6epUZ-gv2khTJZN8d3U,10393
59
+ wolfhece/pydownloader.py,sha256=jdyOpIZPGgHlo6MakklLHIqsTmDMrbDVeKchSpij_K4,16245
60
60
  wolfhece/pylogging.py,sha256=4TI8hgBB65z-zpvU5Rfa2jkPXPhJaqXjHVPwbcdzTNc,4528
61
61
  wolfhece/pypolygons_scen.py,sha256=NWaNeK0RSUeOkgukeogK9FLmQiDjGZ9yhqs9208fojM,46237
62
62
  wolfhece/pyshields.py,sha256=KMtUO5kD0lisKnJD1NsDz-qaY5DpFcmS4O3WkXtUSmo,27898
@@ -67,13 +67,13 @@ wolfhece/textpillow.py,sha256=7hgfsLYAaE_rNKD-g8xsON8sdWvoV8vbqnGGxIayShE,14137
67
67
  wolfhece/tools2d_dll.py,sha256=TfvvmyZUqEZIH0uHwUCJf0bdmCks_AiidDt23Unsp5w,13550
68
68
  wolfhece/tools_mpl.py,sha256=gQ3Jg1iuZiecmMqa5Eli2ZLSkttu68VXL8YmMDBaEYU,564
69
69
  wolfhece/toolshydrology_dll.py,sha256=cIGyhxV8H5f7GXhDqAamM7uC0W0hQTou3eTkqZdnqBE,5656
70
- wolfhece/wolf_array.py,sha256=vhsxF79jcdK1tY1GFjCWx8YupC8D9r-C7nZ9Is2pMO4,574421
70
+ wolfhece/wolf_array.py,sha256=T0E46C-hmjJCGp66eHhOGohT_Wo7Jhp0hU6S_EPXYg4,576614
71
71
  wolfhece/wolf_hist.py,sha256=fTEb60Q4TEwobdZsRU4CFXAId1eOKdWAqF8lnF1xEWc,3590
72
72
  wolfhece/wolf_texture.py,sha256=Pt1j_lX74p70Fj3y3qYxYMuN8gghVd8_ih1vFhTIdkA,23884
73
73
  wolfhece/wolf_tiles.py,sha256=v-HohqaWuMYdn75XLnA22dlloAG90iwnIqrgnB0ASQ4,10488
74
74
  wolfhece/wolf_vrt.py,sha256=wbxXVN7TL9zgdyF79S-4e3pje6wJEAgBEfF_Y8kkzxs,14271
75
75
  wolfhece/wolf_zi_db.py,sha256=kz1TofsPfuBQqwYEM32wZl4b-jqgAygorZSm2JnGJ_k,42450
76
- wolfhece/wolfresults_2D.py,sha256=0c3akPDFETE0Uq0JiZ0FZEx6Rxiy9JB5s9P6sDei0E0,245735
76
+ wolfhece/wolfresults_2D.py,sha256=BTewbH0zX55iLLbY3KuHVMAOCsvif2FMvF1SQMJFgf0,245893
77
77
  wolfhece/xyz_file.py,sha256=1pzLFmmdHca4yBVR9Jitic6N82rY28mRytGC1zMbY28,6615
78
78
  wolfhece/acceptability/Parallels.py,sha256=2wVkfJYor4yl7VYiAZiGGTFwtAab2z66ZfRtBliVweE,4088
79
79
  wolfhece/acceptability/__init__.py,sha256=hfgoPKLDpX7drN1Vpvux-_5Lfyc_7feT2C2zQr5v-Os,258
@@ -95,7 +95,7 @@ wolfhece/apps/curvedigitizer.py,sha256=lEJJwgAfulrrWQc-U6ij6sj59hWN3SZl4Yu1kQxVz
95
95
  wolfhece/apps/hydrometry.py,sha256=lhhJsFeb4zGL4bNQTs0co85OQ_6ssL1Oy0OUJCzhfYE,656
96
96
  wolfhece/apps/isocurrent.py,sha256=dagmGR8ja9QQ1gwz_8fU-N052hIw-W0mWGVkzLu6C7I,4247
97
97
  wolfhece/apps/splashscreen.py,sha256=EdGDN9NhudIiP7c3gVqj7dp4MWFB8ySizM_tpMnsgpE,3091
98
- wolfhece/apps/version.py,sha256=K0KiOex_hrmAhFyclrpkhVQPRpY51D6WWi2IXhErAlc,388
98
+ wolfhece/apps/version.py,sha256=g5JvLHmxA33m1kAYqdyNA-LqHE0IxUtstI8t7gQzqQA,388
99
99
  wolfhece/apps/wolf.py,sha256=mRnjYsUu4KIsRuamdQWAINFMuwN4eJgMo9erG-hkZ70,729
100
100
  wolfhece/apps/wolf2D.py,sha256=4z_OPQ3IgaLtjexjMKX9ppvqEYyjFLt1hcfFABy3-jU,703
101
101
  wolfhece/apps/wolf_logo.bmp,sha256=ruJ4MA51CpGO_AYUp_dB4SWKHelvhOvd7Q8NrVOjDJk,3126
@@ -131,7 +131,7 @@ wolfhece/eva/bootstrap.py,sha256=Ys4xTDIvG_QtxCKWLYzb3_XAZU441jGX7fHIbd9Mvr0,840
131
131
  wolfhece/eva/hydrogramme_mono.py,sha256=uZFIgJJ-JogMFzt7D7OnyVaHvgxCQJPZz9W9FgnuthA,8138
132
132
  wolfhece/eva/joint_models.py,sha256=RqPLb0g775zJIe3X3nwaf1g1dqnEIUbJjPMae_J_nmM,5863
133
133
  wolfhece/eva/mixture_models.py,sha256=Eq9fU7GjbSLHqCE5mdkIC5oAJhv6aNxY9kwnqlcOmc8,16221
134
- wolfhece/eva/pyseries.py,sha256=Oz2QCPGrbebAwQL1Vl-kc4t1OkzS-pCuj5rZwDGEJ-I,118536
134
+ wolfhece/eva/pyseries.py,sha256=iUTM31qZefT-iKRvMEmVfWXEZMr3_h0ypPqwFQ1Zm9E,119590
135
135
  wolfhece/fonts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
136
136
  wolfhece/fonts/arial.ttf,sha256=lXZrWPfYabD6LPbm_rJsGyHN8mMfHFhj_JvSBtXG6O4,915212
137
137
  wolfhece/fonts/helvetica.ttf,sha256=X4Zd3zdUmuRGMLE6UB-BMIbirpdK3Ia5czfNnuSx5P8,317968
@@ -161,8 +161,8 @@ wolfhece/hydrology/read.py,sha256=H-sK4hU23snrZC3BDLUHJqUTUBwvQ48ZFgxE-6PxDYg,11
161
161
  wolfhece/hydrology/slope_manager.py,sha256=vlek0z8qcqB61eleiksyOe3QR1vpbtwfeowy6ms7_Fg,5580
162
162
  wolfhece/hydrology/wolfMap_treatment.py,sha256=eAxr24zJGwmDof1aZpcxewVvv_bWDvoO8t9Wwf99Mlo,10606
163
163
  wolfhece/hydrometry/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
164
- wolfhece/hydrometry/kiwis.py,sha256=rhfvRKlKEKIDiwnGfHnT5oDa-I-RHU2ikPqD25urdHw,65463
165
- wolfhece/hydrometry/kiwis_gui.py,sha256=s4xCsqkKvI1YcIZ4X2A7hV11zyJFI8Q_4i82jOO6_ys,25060
164
+ wolfhece/hydrometry/kiwis.py,sha256=aXf9QpbDld2K3jWOYLVcGj5Y_GBs2wFCUv7HGVHTK3w,65557
165
+ wolfhece/hydrometry/kiwis_gui.py,sha256=bXUfIRlP0Cmcoe-sw-0KaFLoAUfQ8yCVPBX-xLSfuBs,25113
166
166
  wolfhece/hydrometry/kiwis_wolfgui.py,sha256=GPa5YNp2V2ZlxYQjPiCXERgPuWB_zij4ec2yHpRvoFA,4027
167
167
  wolfhece/icons/folder_open.png,sha256=ykBlU2FtGcpjAu1YO4_eGlDg2svgs_IAs-4d5O2e3AM,2329
168
168
  wolfhece/icons/folder_plus.png,sha256=Z1Jcs87Z6pNcudxGDTNhC_hgolSSaXe6_fmQE_n-ero,1963
@@ -183,7 +183,7 @@ wolfhece/lagrangian/particles.py,sha256=sqp-_gfsIt8s3GNcI1eKaeOBMSo2C-wPrL7FpjkE
183
183
  wolfhece/lagrangian/velocity_field.py,sha256=oGVjNm98gEpawreFIrC1lDyC5bEhkk2CsyYAlF1Kq50,10574
184
184
  wolfhece/lazviewer/__init__.py,sha256=AmgfF1EhRVEfEZZI4qLIS8WbInvbDLL2dx-Mkd1pDE4,770
185
185
  wolfhece/lazviewer/_add_path.py,sha256=XgMEXRhFhx9-B1hUsP7Zr199zNljYwT5dGMYSB9jRa4,639
186
- wolfhece/lazviewer/laz_viewer.py,sha256=QECvVMSshgO4C7ulBTBcB4oPwLCU8WP8x6W026RWf5w,81621
186
+ wolfhece/lazviewer/laz_viewer.py,sha256=NzJfOqN7yV-RAPrpxn8UgU0KplKf7jFpWpwrodX0WtU,81662
187
187
  wolfhece/lazviewer/libs/Qt5Core.dll,sha256=sTJ_ctYFY9KHMNytF-lzH_078zIvnKTjN-71FDkOWPw,4924928
188
188
  wolfhece/lazviewer/libs/Qt5Gui.dll,sha256=07BeaOeYByraGkKYeDiSDYLawHM8tyd55pVJlKbZ4Y0,5436416
189
189
  wolfhece/lazviewer/libs/Qt5Network.dll,sha256=U-9FiLE9LUKru8r8EQxTnwwlMpwS8JzUtenhkKTCox0,1038336
@@ -235,7 +235,7 @@ wolfhece/mar/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
235
235
  wolfhece/mar/commontools.py,sha256=SiSxpv5BFYEBCEydsE4ZmBuot3KTy0UYMx2aa-4fbuQ,52549
236
236
  wolfhece/mar/interface_MAR_WOLF.py,sha256=MWeXaHLDT4Eo9jZOAvz013lmpgGYT1v9VUYGAgBgSRU,21454
237
237
  wolfhece/math_parser/__init__.py,sha256=Mi7YTrlJtcflyrRdZHHgE-uNPUFfOWmsf8FsOwKBRPI,27961
238
- wolfhece/math_parser/calculator.py,sha256=Avyx-ikIwsficqd-Q4erX6U0zGQ3cAWfADyq6_uHpB0,7493
238
+ wolfhece/math_parser/calculator.py,sha256=NYPcNWMBhbnYTK3tqEnbn1vyAcyw_ogNDki1SN7Do_4,7497
239
239
  wolfhece/mesh2d/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
240
240
  wolfhece/mesh2d/bc_manager.py,sha256=BmNT-M0uWe5--AhxiS4EWziHad4RL-D7wUySqXTICsY,54237
241
241
  wolfhece/mesh2d/cell_tracker.py,sha256=mPmnD5lEf3gLPuLqtAIo-Gp-ipAwQdPxzjWOGt0b7jM,8958
@@ -290,7 +290,7 @@ wolfhece/report/tools.py,sha256=ZA4PfHQXgvDtTnrSZh-oSwhQT_cQtb49LuZB8VI7nyI,9685
290
290
  wolfhece/report/wolf_report.png,sha256=NoSV58LSwb-oxCcZScRiJno-kxDwRdm_bK-fiMsKJdA,592485
291
291
  wolfhece/scenario/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
292
292
  wolfhece/scenario/check_scenario.py,sha256=d-LWa_FxmPxTSc_H1lDHwqLB6TCqj1IUrRJhatfPMMA,5623
293
- wolfhece/scenario/config_manager.py,sha256=qosuoNOVbBuDuBUjupX5MFygYG2YJyr2AFgxxFqqdLo,126593
293
+ wolfhece/scenario/config_manager.py,sha256=K4KLL2ZFhlZl88uxFL4A4t_W6qan2zeBehlnjvi709w,126969
294
294
  wolfhece/scenario/imposebc_void.py,sha256=PqA_99hKcaqK5zsK6IRIc5Exgg3WVpgWU8xpwNL49zQ,5571
295
295
  wolfhece/scenario/update_void.py,sha256=Yb7TMIUx9Gzm9_6qRMJnF39Uqi17dIkMmscSXo2WaTs,10033
296
296
  wolfhece/shaders/fragment_shader_texture.glsl,sha256=w6h8d5mJqFaGbao0LGmjRcFFdcEQ3ICIl9JpuT71K5k,177
@@ -319,8 +319,8 @@ wolfhece/ui/wolf_multiselection_collapsiblepane.py,sha256=u4C7CXe_bUyGKx7c_Bi0x9
319
319
  wolfhece/ui/wolf_times_selection_comparison_models.py,sha256=ORy7fz4dcp691qKzaOZHrRLZ0uXNhL-LIHxmpDGL6BI,5007
320
320
  wolfhece/wintab/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
321
321
  wolfhece/wintab/wintab.py,sha256=8A-JNONV6ujgsgG3lM5Uw-pVgglPATwKs86oBzzljoc,7179
322
- wolfhece-2.2.39.dist-info/METADATA,sha256=PlUu_DvltuzTlOWhl76oPplEuXVSNZWszz1LIxnEPyQ,2785
323
- wolfhece-2.2.39.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
324
- wolfhece-2.2.39.dist-info/entry_points.txt,sha256=Jr187pyvA3EeJiQLjZK9yo6mJX7IAn6ygZU9T8qF_gQ,658
325
- wolfhece-2.2.39.dist-info/top_level.txt,sha256=EfqZXMVCn7eILUzx9xsEu2oBbSo9liWPFWjIHik0iCI,9
326
- wolfhece-2.2.39.dist-info/RECORD,,
322
+ wolfhece-2.2.41.dist-info/METADATA,sha256=r3CK5pZVkd6vWy34yNRUNSs-yzagEy7TbSM1vrGbG7c,2785
323
+ wolfhece-2.2.41.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
324
+ wolfhece-2.2.41.dist-info/entry_points.txt,sha256=Jr187pyvA3EeJiQLjZK9yo6mJX7IAn6ygZU9T8qF_gQ,658
325
+ wolfhece-2.2.41.dist-info/top_level.txt,sha256=EfqZXMVCn7eILUzx9xsEu2oBbSo9liWPFWjIHik0iCI,9
326
+ wolfhece-2.2.41.dist-info/RECORD,,