wolfhece 2.2.20__py3-none-any.whl → 2.2.24__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- wolfhece/Coordinates_operations.py +3 -1
- wolfhece/PyDraw.py +247 -3
- wolfhece/Results2DGPU.py +157 -39
- wolfhece/__init__.py +1 -0
- wolfhece/_add_path.py +9 -0
- wolfhece/apps/check_install.py +134 -1
- wolfhece/apps/splashscreen.py +1 -1
- wolfhece/apps/version.py +1 -1
- wolfhece/cli.py +96 -1
- wolfhece/hydrology/Optimisation.py +30 -25
- wolfhece/irm_qdf.py +67 -1
- wolfhece/mesh2d/wolf2dprev.py +4 -2
- wolfhece/report/pdf.py +55 -0
- wolfhece/report/simplesimgpu.py +1409 -0
- wolfhece/tools2d_dll.py +7 -2
- wolfhece/wolf_array.py +51 -5
- wolfhece/wolf_hist.py +21 -16
- wolfhece/wolfresults_2D.py +124 -25
- {wolfhece-2.2.20.dist-info → wolfhece-2.2.24.dist-info}/METADATA +3 -1
- {wolfhece-2.2.20.dist-info → wolfhece-2.2.24.dist-info}/RECORD +23 -60
- {wolfhece-2.2.20.dist-info → wolfhece-2.2.24.dist-info}/entry_points.txt +3 -0
- wolfhece/libs/GL/gl.h +0 -1044
- wolfhece/libs/GL/glaux.h +0 -272
- wolfhece/libs/GL/glcorearb.h +0 -3597
- wolfhece/libs/GL/glext.h +0 -11771
- wolfhece/libs/GL/glu.h +0 -255
- wolfhece/libs/GL/glxext.h +0 -926
- wolfhece/libs/GL/wglext.h +0 -840
- wolfhece/libs/MSVCP140.dll +0 -0
- wolfhece/libs/WolfDll.dll +0 -0
- wolfhece/libs/Wolf_tools.dll +0 -0
- wolfhece/libs/api-ms-win-crt-heap-l1-1-0.dll +0 -0
- wolfhece/libs/api-ms-win-crt-math-l1-1-0.dll +0 -0
- wolfhece/libs/api-ms-win-crt-runtime-l1-1-0.dll +0 -0
- wolfhece/libs/fribidi-0.dll +0 -0
- wolfhece/libs/get_infos.cp310-win_amd64.pyd +0 -0
- wolfhece/libs/get_infos.cp311-win_amd64.pyd +0 -0
- wolfhece/libs/get_infos.cp312-win_amd64.pyd +0 -0
- wolfhece/libs/get_infos.cp313-win_amd64.pyd +0 -0
- wolfhece/libs/glu32.dll +0 -0
- wolfhece/libs/hdf5.dll +0 -0
- wolfhece/libs/hdf5_hl.dll +0 -0
- wolfhece/libs/libcurl.dll +0 -0
- wolfhece/libs/libpardiso600-WIN-X86-64.dll +0 -0
- wolfhece/libs/libraqm.dll +0 -0
- wolfhece/libs/msvcr100.dll +0 -0
- wolfhece/libs/netcdf.dll +0 -0
- wolfhece/libs/paho-mqtt3cs.dll +0 -0
- wolfhece/libs/vcomp100.dll +0 -0
- wolfhece/libs/vcruntime140.dll +0 -0
- wolfhece/libs/vcruntime140_1.dll +0 -0
- wolfhece/libs/verify_wolf.cp310-win_amd64.pyd +0 -0
- wolfhece/libs/verify_wolf.cp311-win_amd64.pyd +0 -0
- wolfhece/libs/verify_wolf.cp312-win_amd64.pyd +0 -0
- wolfhece/libs/verify_wolf.cp313-win_amd64.pyd +0 -0
- wolfhece/libs/wolfogl.cp310-win_amd64.pyd +0 -0
- wolfhece/libs/wolfogl.cp311-win_amd64.pyd +0 -0
- wolfhece/libs/wolfogl.cp312-win_amd64.pyd +0 -0
- wolfhece/libs/wolfogl.cp313-win_amd64.pyd +0 -0
- wolfhece/libs/zlib1.dll +0 -0
- {wolfhece-2.2.20.dist-info → wolfhece-2.2.24.dist-info}/WHEEL +0 -0
- {wolfhece-2.2.20.dist-info → wolfhece-2.2.24.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,5 @@
|
|
1
1
|
from pyproj import Transformer
|
2
|
+
from pyproj.transformer import TransformerGroup
|
2
3
|
from concurrent.futures import ProcessPoolExecutor
|
3
4
|
import numpy as np
|
4
5
|
from osgeo import gdal
|
@@ -19,7 +20,8 @@ def transform_chunk_coordinates(inputEPSG:str, outputEPSG:str, chunk:np.ndarray)
|
|
19
20
|
:type chunk: np.ndarray
|
20
21
|
"""
|
21
22
|
COO_TRANSFORMER = Transformer.from_crs(inputEPSG, outputEPSG, always_xy=True)
|
22
|
-
|
23
|
+
ret = COO_TRANSFORMER.transform(chunk[:, 0], chunk[:, 1])
|
24
|
+
return ret
|
23
25
|
|
24
26
|
def transform_coordinates(points:np.ndarray, inputEPSG:str="EPSG:3812", outputEPSG:str="EPSG:31370", chunk_size:int=1000):
|
25
27
|
"""
|
wolfhece/PyDraw.py
CHANGED
@@ -2287,6 +2287,7 @@ class WolfMapViewer(wx.Frame):
|
|
2287
2287
|
self.analyzeplot = wx.Menu()
|
2288
2288
|
self.analyzeexport = wx.Menu()
|
2289
2289
|
self.analyzeinpaint = wx.Menu()
|
2290
|
+
self.analyzesimsheet = wx.Menu()
|
2290
2291
|
|
2291
2292
|
plotvect = self.analyzeplot.Append(wx.ID_ANY, _("Plot active vector..."),
|
2292
2293
|
_("Plot the active vector and linked arrays"))
|
@@ -2299,6 +2300,17 @@ class WolfMapViewer(wx.Frame):
|
|
2299
2300
|
self.analyzemenu.Append(wx.ID_ANY,_('Export...'), self.analyzeexport)
|
2300
2301
|
self.analyzemenu.Append(wx.ID_ANY,_('Inpaint...'), self.analyzeinpaint)
|
2301
2302
|
|
2303
|
+
self.analyzemenu.AppendSeparator()
|
2304
|
+
|
2305
|
+
self.analyzemenu.Append(wx.ID_ANY,_('Report...'), self.analyzesimsheet)
|
2306
|
+
|
2307
|
+
self.analyzesimsheet.Append(wx.ID_ANY, _("Active simulation..."), _("Generate a summary PDF report for the active simulation"))
|
2308
|
+
self.analyzesimsheet.Append(wx.ID_ANY, _("All checked simulations..."), _("Generate a summary PDF report for all checked simulations"))
|
2309
|
+
self.analyzesimsheet.Append(wx.ID_ANY, _("All simulations in directory..."), _("Generate a summary PDF report for all simulations in the current directory"))
|
2310
|
+
self.analyzesimsheet.AppendSeparator()
|
2311
|
+
self.analyzesimsheet.Append(wx.ID_ANY, _("Compare checked simulations..."), _("Generate a summary PDF report for all the loaded simulations"))
|
2312
|
+
self.analyzesimsheet.Append(wx.ID_ANY, _("Compare all simulations in a directory..."), _("Generate a summary PDF report for all the simulations in a directory"))
|
2313
|
+
|
2302
2314
|
|
2303
2315
|
self.analyzeinpaint.Append(wx.ID_ANY, _("Inpaint active array..."), _("Inpaint active array"))
|
2304
2316
|
self.analyzeinpaint.Append(wx.ID_ANY, _("Inpaint waterlevel..."), _("Inpaint a waterlevel result array based on sepcified dem and dtm data"))
|
@@ -4902,7 +4914,8 @@ class WolfMapViewer(wx.Frame):
|
|
4902
4914
|
dpi:int= 300,
|
4903
4915
|
add_title:bool = False,
|
4904
4916
|
figsizes= [10.,10.],
|
4905
|
-
arrayid_as_title:bool = False
|
4917
|
+
arrayid_as_title:bool = False,
|
4918
|
+
resid_as_title:bool = False):
|
4906
4919
|
"""
|
4907
4920
|
Sauvegarde de la fenêtre d'affichage dans un fichier
|
4908
4921
|
|
@@ -4958,6 +4971,8 @@ class WolfMapViewer(wx.Frame):
|
|
4958
4971
|
pot_title = self.viewer_name
|
4959
4972
|
if arrayid_as_title:
|
4960
4973
|
pot_title = self.active_array.idx
|
4974
|
+
if resid_as_title:
|
4975
|
+
pot_title = self.active_res2d.idx
|
4961
4976
|
|
4962
4977
|
self.display_canvasogl(fig=fig,
|
4963
4978
|
ax=ax,
|
@@ -8301,6 +8316,121 @@ class WolfMapViewer(wx.Frame):
|
|
8301
8316
|
elif itemlabel == _("Load and apply mask (nap)..."):
|
8302
8317
|
self.loadnap_and_apply()
|
8303
8318
|
|
8319
|
+
elif itemlabel == _("Active simulation..."):
|
8320
|
+
if self.active_res2d is None:
|
8321
|
+
logging.warning(_('No active simulation !'))
|
8322
|
+
return
|
8323
|
+
|
8324
|
+
from .report.simplesimgpu import SimpleSimGPU_Report_wx
|
8325
|
+
|
8326
|
+
if isinstance(self.active_res2d, wolfres2DGPU):
|
8327
|
+
newsheet = SimpleSimGPU_Report_wx(Path(self.active_res2d.filename).parent, size=(800, 600))
|
8328
|
+
newsheet.Show()
|
8329
|
+
else:
|
8330
|
+
logging.warning(_('Active simulation is not a GPU simulation - Not yet implemented for CPU simulations !'))
|
8331
|
+
|
8332
|
+
elif itemlabel == _("All checked simulations..."):
|
8333
|
+
|
8334
|
+
sims = self.get_list_keys(draw_type.RES2D, checked_state=True)
|
8335
|
+
if len(sims) == 0:
|
8336
|
+
logging.warning(_('No checked simulation !'))
|
8337
|
+
return
|
8338
|
+
|
8339
|
+
from .report.simplesimgpu import SimpleSimGPU_Report_wx
|
8340
|
+
|
8341
|
+
for curkey in sims:
|
8342
|
+
curmodel = self.get_obj_from_id(curkey, draw_type.RES2D)
|
8343
|
+
if isinstance(curmodel, wolfres2DGPU):
|
8344
|
+
newsheet = SimpleSimGPU_Report_wx(Path(curmodel.filename).parent, size=(800, 600))
|
8345
|
+
newsheet.Show()
|
8346
|
+
else:
|
8347
|
+
logging.warning(_('Simulation {} is not a GPU simulation - Not yet implemented for CPU simulations !').format(curmodel.idx))
|
8348
|
+
|
8349
|
+
elif itemlabel == _("All simulations in directory..."):
|
8350
|
+
dlg = wx.DirDialog(None, _('Choose the directory containing the simulations'), style=wx.DD_DEFAULT_STYLE)
|
8351
|
+
ret = dlg.ShowModal()
|
8352
|
+
if ret == wx.ID_CANCEL:
|
8353
|
+
dlg.Destroy()
|
8354
|
+
return
|
8355
|
+
directory = Path(dlg.GetPath())
|
8356
|
+
dlg.Destroy()
|
8357
|
+
if not directory.exists():
|
8358
|
+
logging.error(_('Directory {} does not exist !').format(directory))
|
8359
|
+
wx.MessageBox(_('Directory {} does not exist !').format(directory), _('Error'), wx.OK | wx.ICON_ERROR)
|
8360
|
+
return
|
8361
|
+
if not directory.is_dir():
|
8362
|
+
logging.error(_('Path {} is not a directory !').format(directory))
|
8363
|
+
wx.MessageBox(_('Path {} is not a directory !').format(directory), _('Error'), wx.OK | wx.ICON_ERROR)
|
8364
|
+
return
|
8365
|
+
from .report.simplesimgpu import SimpleSimGPU_Reports_wx
|
8366
|
+
|
8367
|
+
|
8368
|
+
# check if we want to show all wx reports
|
8369
|
+
dlg = wx.MessageDialog(None, _('Do you want to show all reports ?'), _('Show all reports'), style=wx.YES_NO | wx.YES_DEFAULT)
|
8370
|
+
ret = dlg.ShowModal()
|
8371
|
+
dlg.Destroy()
|
8372
|
+
|
8373
|
+
newsheets = SimpleSimGPU_Reports_wx(directory, show = ret == wx.ID_YES, size=(800, 600))
|
8374
|
+
|
8375
|
+
elif itemlabel == _("Compare checked simulations..."):
|
8376
|
+
|
8377
|
+
sims = self.get_list_keys(draw_type.RES2D, checked_state=True)
|
8378
|
+
if len(sims) == 0:
|
8379
|
+
logging.warning(_('No checked simulation !'))
|
8380
|
+
return
|
8381
|
+
|
8382
|
+
elif len(sims) == 1:
|
8383
|
+
logging.warning(_('Only one checked simulation - Nothing to compare !'))
|
8384
|
+
return
|
8385
|
+
|
8386
|
+
from .report.simplesimgpu import SimpleSimGPU_Report_Compare_wx
|
8387
|
+
|
8388
|
+
sims = [self.get_obj_from_id(curkey, draw_type.RES2D) for curkey in sims]
|
8389
|
+
# conserve only GPU simulations
|
8390
|
+
sims = [Path(curmodel.filename) for curmodel in sims if isinstance(curmodel, wolfres2DGPU)]
|
8391
|
+
|
8392
|
+
# take parent if "simul_gpu_results" in sims
|
8393
|
+
sims = [sim.parent for sim in sims if 'simul_gpu_results' in str(sim)]
|
8394
|
+
|
8395
|
+
if len(sims) == 0:
|
8396
|
+
logging.warning(_('No GPU simulation to compare !'))
|
8397
|
+
return
|
8398
|
+
elif len(sims) == 1:
|
8399
|
+
logging.warning(_('Only one GPU simulation - Nothing to compare !'))
|
8400
|
+
return
|
8401
|
+
elif len(sims) > 1:
|
8402
|
+
try:
|
8403
|
+
newsheet = SimpleSimGPU_Report_Compare_wx(sims, size=(800, 600))
|
8404
|
+
newsheet.Show()
|
8405
|
+
except Exception as e:
|
8406
|
+
logging.error(_('Error in comparing simulations\n{}'.format(e)))
|
8407
|
+
|
8408
|
+
elif itemlabel == _("Compare all simulations in a directory..."):
|
8409
|
+
|
8410
|
+
dlg = wx.DirDialog(None, _('Choose the directory containing the simulations'), style=wx.DD_DEFAULT_STYLE)
|
8411
|
+
ret = dlg.ShowModal()
|
8412
|
+
if ret == wx.ID_CANCEL:
|
8413
|
+
dlg.Destroy()
|
8414
|
+
return
|
8415
|
+
|
8416
|
+
directory = Path(dlg.GetPath())
|
8417
|
+
dlg.Destroy()
|
8418
|
+
|
8419
|
+
if not directory.exists():
|
8420
|
+
logging.error(_('Directory {} does not exist !').format(directory))
|
8421
|
+
wx.MessageBox(_('Directory {} does not exist !').format(directory), _('Error'), wx.OK | wx.ICON_ERROR)
|
8422
|
+
return
|
8423
|
+
if not directory.is_dir():
|
8424
|
+
logging.error(_('Path {} is not a directory !').format(directory))
|
8425
|
+
wx.MessageBox(_('Path {} is not a directory !').format(directory), _('Error'), wx.OK | wx.ICON_ERROR)
|
8426
|
+
return
|
8427
|
+
from .report.simplesimgpu import SimpleSimGPU_Report_Compare_wx
|
8428
|
+
try:
|
8429
|
+
newsheet = SimpleSimGPU_Report_Compare_wx(directory, size= (800,600))
|
8430
|
+
newsheet.Show()
|
8431
|
+
except Exception as e:
|
8432
|
+
logging.error(_('Error in comparing simulations in directory\n{}'.format(e)))
|
8433
|
+
|
8304
8434
|
elif itemlabel == _("Inpaint active array..."):
|
8305
8435
|
|
8306
8436
|
if self.active_array is None:
|
@@ -9792,16 +9922,21 @@ class WolfMapViewer(wx.Frame):
|
|
9792
9922
|
|
9793
9923
|
# Get all checked arrays
|
9794
9924
|
checked_arrays = self.get_list_keys(drawing_type= draw_type.ARRAYS, checked_state= True)
|
9925
|
+
checked_results = self.get_list_keys(drawing_type= draw_type.RES2D, checked_state= True)
|
9926
|
+
|
9795
9927
|
old_active = self.active_array
|
9928
|
+
old_res2d = self.active_res2d
|
9796
9929
|
|
9797
|
-
if len(checked_arrays) == 0:
|
9930
|
+
if len(checked_arrays) + len(checked_results) == 0:
|
9798
9931
|
logging.warning(_('No arrays checked for export'))
|
9799
|
-
return
|
9932
|
+
return []
|
9800
9933
|
|
9801
9934
|
def uncheck_all():
|
9802
9935
|
# uncheck arrays
|
9803
9936
|
for curarray in checked_arrays:
|
9804
9937
|
self.uncheck_id(curarray, unload= False, forceresetOGL= False)
|
9938
|
+
for curres in checked_results:
|
9939
|
+
self.uncheck_id(curres, unload= False, forceresetOGL= False)
|
9805
9940
|
|
9806
9941
|
fn = str(fn)
|
9807
9942
|
ret = []
|
@@ -9811,10 +9946,21 @@ class WolfMapViewer(wx.Frame):
|
|
9811
9946
|
self.active_array = self.get_obj_from_id(curel, drawtype= draw_type.ARRAYS)
|
9812
9947
|
ret.append((self.save_canvasogl(fn + '_' + str(idx) + '.png', mpl, ds, add_title= add_title, arrayid_as_title=True), curel))
|
9813
9948
|
|
9949
|
+
for idx, curel in enumerate(checked_results):
|
9950
|
+
uncheck_all()
|
9951
|
+
self.check_id(curel)
|
9952
|
+
self.active_res2d = self.get_obj_from_id(curel, drawtype= draw_type.RES2D)
|
9953
|
+
ret.append((self.save_canvasogl(fn + '_' + str(idx + len(checked_arrays)) + '.png', mpl, ds, add_title= add_title, resid_as_title=True), curel))
|
9954
|
+
|
9814
9955
|
self.active_array = old_active
|
9956
|
+
self.active_res2d = old_res2d
|
9957
|
+
|
9815
9958
|
for curarray in checked_arrays:
|
9816
9959
|
self.check_id(curarray)
|
9817
9960
|
|
9961
|
+
for curres in checked_results:
|
9962
|
+
self.check_id(curres)
|
9963
|
+
|
9818
9964
|
self.Refresh()
|
9819
9965
|
|
9820
9966
|
return ret
|
@@ -11630,6 +11776,97 @@ class WolfMapViewer(wx.Frame):
|
|
11630
11776
|
else:
|
11631
11777
|
logging.warning(_('Reload not yet implemented for this type of object'))
|
11632
11778
|
|
11779
|
+
elif _('Rasterize active zone') in text:
|
11780
|
+
|
11781
|
+
if self.active_array is None and self.active_res2d is None:
|
11782
|
+
logging.warning(_('No active array selected'))
|
11783
|
+
return
|
11784
|
+
|
11785
|
+
if self.active_array is not None and self.active_res2d is not None:
|
11786
|
+
# Show a dialog to choose between array or res2d
|
11787
|
+
dlg = wx.SingleChoiceDialog(None, _('Choose the type of rasterization'), _('Rasterization Type'), ['Array', 'Res2D'], style=wx.CHOICEDLG_STYLE)
|
11788
|
+
ret = dlg.ShowModal()
|
11789
|
+
if ret != wx.ID_OK:
|
11790
|
+
dlg.Destroy()
|
11791
|
+
return
|
11792
|
+
choice = dlg.GetSelection()
|
11793
|
+
dlg.Destroy()
|
11794
|
+
if choice == 0:
|
11795
|
+
based_array = self.active_array
|
11796
|
+
else:
|
11797
|
+
if self.active_res2d.nb_blocks == 1:
|
11798
|
+
based_array = self.active_res2d.get_header_block(1)
|
11799
|
+
elif self.active_res2d.nb_blocks > 1:
|
11800
|
+
logging.error(_('Rasterization not implemented for multi-blocks res2d -- Convert to mono-blocks first'))
|
11801
|
+
return
|
11802
|
+
|
11803
|
+
elif self.active_array is not None:
|
11804
|
+
based_array = self.active_array
|
11805
|
+
elif self.active_res2d is not None:
|
11806
|
+
if self.active_res2d.nb_blocks == 1:
|
11807
|
+
based_array = self.active_res2d.get_header_block(1)
|
11808
|
+
elif self.active_res2d.nb_blocks > 1:
|
11809
|
+
logging.error(_('Rasterization not implemented for multi-blocks res2d -- Convert to mono-blocks first'))
|
11810
|
+
return
|
11811
|
+
|
11812
|
+
if isinstance(self.selected_object, Zones):
|
11813
|
+
if self.selected_object.active_zone is None:
|
11814
|
+
logging.warning(_('No active zone selected'))
|
11815
|
+
return
|
11816
|
+
if self.selected_object.active_zone.parent is None:
|
11817
|
+
logging.warning(_('No parent object for the active zone'))
|
11818
|
+
else:
|
11819
|
+
new_zone = based_array.rasterize_zone_along_grid(self.selected_object.active_zone, outformat= zone)
|
11820
|
+
if new_zone is not None:
|
11821
|
+
new_zone.myname = self.selected_object.active_zone.myname + '_rasterized'
|
11822
|
+
self.selected_object.active_zone.parent.add_zone(new_zone, forceparent=True)
|
11823
|
+
self.selected_object.active_zone.parent.fill_structure()
|
11824
|
+
self.selected_object.active_zone.reset_listogl()
|
11825
|
+
|
11826
|
+
elif _('Rasterize active vector') in text:
|
11827
|
+
|
11828
|
+
if self.active_array is None and self.active_res2d is None:
|
11829
|
+
logging.warning(_('No active array selected'))
|
11830
|
+
return
|
11831
|
+
|
11832
|
+
if self.active_array is not None and self.active_res2d is not None:
|
11833
|
+
# Show a dialog to choose between array or res2d
|
11834
|
+
dlg = wx.SingleChoiceDialog(None, _('Choose the type of rasterization'), _('Rasterization Type'), ['Array', 'Res2D'], style=wx.CHOICEDLG_STYLE)
|
11835
|
+
ret = dlg.ShowModal()
|
11836
|
+
if ret != wx.ID_OK:
|
11837
|
+
dlg.Destroy()
|
11838
|
+
return
|
11839
|
+
choice = dlg.GetSelection()
|
11840
|
+
dlg.Destroy()
|
11841
|
+
if choice == 0:
|
11842
|
+
based_array = self.active_array
|
11843
|
+
else:
|
11844
|
+
if self.active_res2d.nb_blocks == 1:
|
11845
|
+
based_array = self.active_res2d.get_header_block(1)
|
11846
|
+
elif self.active_res2d.nb_blocks > 1:
|
11847
|
+
logging.error(_('Rasterization not implemented for multi-blocks res2d -- Convert to mono-blocks first'))
|
11848
|
+
return
|
11849
|
+
|
11850
|
+
elif self.active_array is not None:
|
11851
|
+
based_array = self.active_array
|
11852
|
+
elif self.active_res2d is not None:
|
11853
|
+
if self.active_res2d.nb_blocks == 1:
|
11854
|
+
based_array = self.active_res2d.get_header_block(1)
|
11855
|
+
elif self.active_res2d.nb_blocks > 1:
|
11856
|
+
logging.error(_('Rasterization not implemented for multi-blocks res2d -- Convert to mono-blocks first'))
|
11857
|
+
return
|
11858
|
+
|
11859
|
+
if isinstance(self.selected_object, Zones):
|
11860
|
+
if self.selected_object.active_vector is None:
|
11861
|
+
logging.warning(_('No active vector selected'))
|
11862
|
+
return
|
11863
|
+
|
11864
|
+
vec_raster = based_array.rasterize_vector_along_grid(self.selected_object.active_vector)
|
11865
|
+
if vec_raster is not None:
|
11866
|
+
vec_raster.myname = self.selected_object.active_vector.myname + '_rasterized'
|
11867
|
+
self.selected_object.active_vector.parentzone.add_vector(vec_raster, forceparent=True, update_struct=True)
|
11868
|
+
self.selected_object.active_vector.parentzone.reset_listogl()
|
11869
|
+
|
11633
11870
|
def OnClose(self, event):
|
11634
11871
|
""" Close the application """
|
11635
11872
|
|
@@ -14419,6 +14656,9 @@ class WolfMapViewer(wx.Frame):
|
|
14419
14656
|
tracks.append(_('Load flight'))
|
14420
14657
|
tracks.append(_('Save flight'))
|
14421
14658
|
|
14659
|
+
tracks.append(_('Rasterize active zone'))
|
14660
|
+
tracks.append(_('Rasterize active vector'))
|
14661
|
+
|
14422
14662
|
# Récupération des items du menu contextuel
|
14423
14663
|
menuitems = self.popupmenu.GetMenuItems()
|
14424
14664
|
text = [cur.GetItemLabelText() for cur in menuitems]
|
@@ -14456,6 +14696,10 @@ class WolfMapViewer(wx.Frame):
|
|
14456
14696
|
self.popupmenu.Append(wx.ID_ANY, _('Convert to multi-blocks (result)'), _('Convert to multi-blocks'))
|
14457
14697
|
self.popupmenu.Append(wx.ID_ANY, _('Extract current step as IC (result)'), _('Extract current step as IC'))
|
14458
14698
|
|
14699
|
+
if isinstance(self.selected_object, Zones):
|
14700
|
+
self.popupmenu.Append(wx.ID_ANY, _('Rasterize active zone'), _('Rasterize active zone'))
|
14701
|
+
self.popupmenu.Append(wx.ID_ANY, _('Rasterize active vector'), _('Rasterize active vector'))
|
14702
|
+
|
14459
14703
|
if isinstance(self.selected_object, Zones | Bridge | Weir):
|
14460
14704
|
self.popupmenu.Append(wx.ID_ANY, _('Export to Shape file'), _('Export to Shape file'))
|
14461
14705
|
self.popupmenu.Append(wx.ID_ANY, _('Export active zone to Shape file'), _('Export active zone to Shape file'))
|
wolfhece/Results2DGPU.py
CHANGED
@@ -14,7 +14,7 @@ from os import path
|
|
14
14
|
from pathlib import Path
|
15
15
|
from scipy.sparse import csr_array
|
16
16
|
from multiprocessing import Pool
|
17
|
-
from typing import Union
|
17
|
+
from typing import Union, Literal
|
18
18
|
from tqdm import tqdm
|
19
19
|
import logging
|
20
20
|
|
@@ -26,41 +26,38 @@ from .CpGrid import CpGrid
|
|
26
26
|
from .PyPalette import wolfpalette
|
27
27
|
|
28
28
|
try:
|
29
|
-
from wolfgpu.results_store import ResultsStore, ResultType
|
29
|
+
from wolfgpu.results_store import ResultsStore, ResultType, PerformancePolicy
|
30
30
|
except ImportError:
|
31
31
|
logging.debug(_("Unable to import wolfgpu.results_store.ResultsStore. Please install wolfgpu package or add a symlink to the wolfgpu package in the wolfhece directory"))
|
32
32
|
|
33
|
-
def _load_res(x) -> tuple[
|
33
|
+
def _load_res(x) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
|
34
34
|
store:ResultsStore
|
35
35
|
i:int
|
36
36
|
|
37
|
-
store, i = x
|
38
|
-
_, _, _, _, wd_np, qx_np, qy_np = store.get_result(i+1)
|
37
|
+
store, i, mode = x
|
39
38
|
|
40
|
-
|
41
|
-
|
42
|
-
else:
|
43
|
-
return csr_array(wd_np), csr_array(qx_np), csr_array(qy_np)
|
39
|
+
_, _, _, _, wd_np, qx_np, qy_np = store.get_result(i+1, untile= mode == 'UNTILED')
|
40
|
+
return wd_np, qx_np, qy_np
|
44
41
|
|
45
|
-
|
42
|
+
|
43
|
+
def _load_res_h(x) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
|
46
44
|
store:ResultsStore
|
47
45
|
i:int
|
48
46
|
|
49
|
-
store, i = x
|
50
|
-
wd_np = store.get_named_result('h',i+1)
|
47
|
+
store, i, mode = x
|
51
48
|
|
52
|
-
|
53
|
-
|
54
|
-
else:
|
55
|
-
return csr_array(wd_np)
|
49
|
+
wd_np = store.get_named_result('h', i+1, untile= mode == 'UNTILED')
|
50
|
+
return wd_np
|
56
51
|
|
57
52
|
class Cache_Results2DGPU():
|
58
53
|
"""
|
59
54
|
Gestion en mémoire de plusieurs résultats GPU
|
60
|
-
Stockage CSR afin d'économiser la mémoire (Scipy CSR)
|
55
|
+
Stockage CSR afin d'économiser la mémoire (Scipy CSR) ou Numpy array dense
|
61
56
|
"""
|
62
57
|
|
63
|
-
def __init__(self, fname:str, start_idx:int, end_idx:int = -1,
|
58
|
+
def __init__(self, fname:str, start_idx:int, end_idx:int = -1,
|
59
|
+
only_h=False, every:int= 1,
|
60
|
+
mode:Literal['TILED', 'UNTILED'] = 'TILED', memory_max_size:int = 12 * 1024 * 1024 * 1024) -> None:
|
64
61
|
"""
|
65
62
|
Chargement de résultats sur base du répertoire de sauvegarde de la simulation GPU
|
66
63
|
|
@@ -72,74 +69,198 @@ class Cache_Results2DGPU():
|
|
72
69
|
:param start_idx: index de départ (0-based)
|
73
70
|
:param end_idx: index de fin (0-based)
|
74
71
|
:param only_h: lecture de la hauteur d'eau seulement
|
72
|
+
:param every: lecture de chaque ième résultat (1 = tous les résultats, 2 = un sur deux, etc.)
|
73
|
+
:param mode: 'TILED' pour les résultats en tuiles, 'UNTILED' pour les résultats non-tuilés
|
74
|
+
:param memory_max_size: taille mémoire maximale en octets pour le cache (par défaut 12 Go)
|
75
|
+
|
75
76
|
"""
|
76
77
|
|
77
|
-
self.
|
78
|
+
self._mode = mode
|
79
|
+
self._results:Union[dict[str,tuple[np.ndarray, np.ndarray, np.ndarray]], dict[str,np.ndarray]] # typage
|
78
80
|
|
79
81
|
# ResultsStore unique
|
80
82
|
self._result_store = ResultsStore(Path(fname), mode='r')
|
81
83
|
self._only_h = only_h
|
84
|
+
self.memory_max_size = memory_max_size
|
85
|
+
|
86
|
+
mem_one_res = self._estimate_memory_size_one_result()
|
87
|
+
logging.info(_("Estimated memory size for one result: {:.2f} MB").format(mem_one_res))
|
88
|
+
self._maximum_n_results = int(self.memory_max_size // mem_one_res) if self.memory_max_size is not None else 10_000
|
82
89
|
|
83
90
|
if end_idx == -1:
|
84
91
|
end_idx = self._result_store.nb_results
|
85
92
|
|
86
93
|
if end_idx>start_idx:
|
94
|
+
|
87
95
|
self.start_idx = int(max(start_idx,0))
|
88
96
|
self.end_idx = int(min(end_idx, self._result_store.nb_results))
|
97
|
+
self._every = int(max(every, 1))
|
98
|
+
|
99
|
+
if (self.end_idx - self.start_idx) // self._every > self._maximum_n_results:
|
100
|
+
logging.warning(_("Too many results to cache in memory. "
|
101
|
+
"Only the first {} results will be cached.").format(self._maximum_n_results))
|
102
|
+
self.end_idx = int(min(int(self.start_idx + self._maximum_n_results * self._every), self._result_store.nb_results))
|
103
|
+
|
104
|
+
self._range_to_process = list(range(self.start_idx, self.end_idx, self._every))
|
105
|
+
if self.end_idx-1 not in self._range_to_process:
|
106
|
+
self._range_to_process.append(self.end_idx-1)
|
89
107
|
|
90
108
|
# Lecture en multiprocess des résultats
|
91
109
|
if only_h:
|
92
110
|
with Pool() as pool:
|
93
|
-
_results = pool.map(_load_res_h, [(self._result_store,i) for i in
|
111
|
+
_results = pool.map(_load_res_h, [(self._result_store, i, mode) for i in self._range_to_process])
|
94
112
|
self._results = {i+1:res for i,res in enumerate(_results)}
|
95
113
|
else:
|
96
114
|
with Pool() as pool:
|
97
|
-
_results = pool.map(_load_res, [(self._result_store,i) for i in
|
115
|
+
_results = pool.map(_load_res, [(self._result_store, i, mode) for i in self._range_to_process])
|
98
116
|
self._results = {i+1:res for i,res in enumerate(_results)}
|
99
117
|
|
118
|
+
def _estimate_memory_size_one_result(self):
|
119
|
+
""" Read one result to estimate memory size """
|
120
|
+
res = self._result_store.get_result(1, untile=False)
|
121
|
+
if self._only_h:
|
122
|
+
return res[4].nbytes / 1024 / 1024
|
123
|
+
else:
|
124
|
+
return (res[4].nbytes + res[5].nbytes + res[6].nbytes) / 1024 / 1024
|
125
|
+
|
126
|
+
@property
|
127
|
+
def memory_size(self) -> int:
|
128
|
+
"""
|
129
|
+
Estimation de la taille mémoire des résultats en cache
|
130
|
+
|
131
|
+
:return: taille mémoire en Mega-octets
|
132
|
+
"""
|
133
|
+
if self._only_h:
|
134
|
+
return sum(res.nbytes for res in self._results.values()) / 1024 / 1024 # Convert to MB
|
135
|
+
else:
|
136
|
+
return sum(res[0].nbytes + res[1].nbytes + res[2].nbytes for res in self._results.values()) / 1024 / 1024 # Convert to MB
|
137
|
+
|
100
138
|
@property
|
101
139
|
def only_h(self):
|
102
140
|
return self._only_h
|
103
141
|
|
104
|
-
|
142
|
+
@property
|
143
|
+
def _tile_packer(self):
|
144
|
+
"""
|
145
|
+
Retourne le tile packer de la simulation
|
146
|
+
"""
|
147
|
+
if self._result_store is not None:
|
148
|
+
return self._result_store.tile_packer()
|
149
|
+
else:
|
150
|
+
return None
|
151
|
+
|
152
|
+
def __getitem__(self, i:int):
|
105
153
|
"""Surcharge de l'opérateur []"""
|
106
154
|
return self._results[i]
|
107
155
|
|
156
|
+
@property
|
157
|
+
def list_cached(self) -> list[int]:
|
158
|
+
"""
|
159
|
+
Retourne la liste des indices des résultats en cache
|
160
|
+
|
161
|
+
:return: liste des indices (1-based)
|
162
|
+
"""
|
163
|
+
return list(set(self._results.keys()))
|
164
|
+
|
165
|
+
def check_if_cached(self, idx:int) -> bool:
|
166
|
+
"""
|
167
|
+
Vérifie si le résultat idx est dans le cache
|
168
|
+
|
169
|
+
:param idx: index du résultat (1-based)
|
170
|
+
:return: True si le résultat est dans le cache, False sinon
|
171
|
+
"""
|
172
|
+
|
173
|
+
if idx not in self._results:
|
174
|
+
logging.info(_("Index {} not in cache").format(idx))
|
175
|
+
logging.info(_('We cache it now !'))
|
176
|
+
|
177
|
+
if self.only_h:
|
178
|
+
self._results[idx] = _load_res_h((self._result_store, idx-1, self._mode))
|
179
|
+
else:
|
180
|
+
self._results[idx] = _load_res((self._result_store, idx-1, self._mode))
|
181
|
+
|
182
|
+
return True
|
183
|
+
|
108
184
|
def get_h(self, idx:int, dense:bool=True) -> Union[np.ndarray, csr_array]:
|
109
185
|
"""
|
110
186
|
Retourne la matrice de hauteur d'eau de la position idx (0-based)
|
111
187
|
- en CSR (Scipy CSR)
|
112
188
|
- en dense (Numpy array)
|
189
|
+
|
190
|
+
:param idx: index du résultat (1-based)
|
191
|
+
:param dense: si True, retourne un Numpy array dense, sinon retourne un Scipy CSR array
|
113
192
|
"""
|
114
|
-
|
115
|
-
|
193
|
+
|
194
|
+
self.check_if_cached(idx)
|
195
|
+
|
196
|
+
if self.only_h:
|
197
|
+
if self._tile_packer is None:
|
198
|
+
untiled = self._results[idx]
|
199
|
+
else:
|
200
|
+
untiled = self._tile_packer.unpack_array(self._results[idx])
|
201
|
+
if dense:
|
202
|
+
return untiled
|
203
|
+
else:
|
204
|
+
return csr_array(untiled)
|
116
205
|
else:
|
117
|
-
|
206
|
+
if self._tile_packer is None:
|
207
|
+
untiled = self._results[idx][0]
|
208
|
+
else:
|
209
|
+
untiled = self._tile_packer.unpack_array(self._results[idx][0])
|
210
|
+
if dense:
|
211
|
+
return untiled
|
212
|
+
else:
|
213
|
+
return csr_array(untiled)
|
118
214
|
|
119
215
|
def get_qx(self,idx:int, dense:bool=True) -> Union[np.ndarray, csr_array]:
|
120
216
|
"""
|
121
217
|
Retourne la matrice de débit X d'eau de la position idx (0-based)
|
122
218
|
- en CSR (Scipy CSR)
|
123
219
|
- en dense (Numpy array)
|
220
|
+
|
221
|
+
:param idx: index du résultat (1-based)
|
222
|
+
:param dense: si True, retourne un Numpy array dense, sinon retourne un Scipy CSR array
|
124
223
|
"""
|
125
224
|
|
126
|
-
if
|
127
|
-
return self._results[idx][1].toarray() if dense else self._results[idx][1]
|
128
|
-
else:
|
225
|
+
if self.only_h:
|
129
226
|
return None
|
227
|
+
else:
|
228
|
+
self.check_if_cached(idx)
|
229
|
+
|
230
|
+
if self._tile_packer is None:
|
231
|
+
untiled = self._results[idx][1]
|
232
|
+
else:
|
233
|
+
untiled = self._tile_packer.unpack_array(self._results[idx][1])
|
234
|
+
|
235
|
+
if dense:
|
236
|
+
return untiled
|
237
|
+
else:
|
238
|
+
return csr_array(untiled)
|
130
239
|
|
131
240
|
def get_qy(self,idx:int, dense:bool=True) -> Union[np.ndarray, csr_array]:
|
132
241
|
"""
|
133
242
|
Retourne la matrice de débit Y d'eau de la position idx (0-based)
|
134
243
|
- en CSR (Scipy CSR)
|
135
244
|
- en dense (Numpy array)
|
245
|
+
|
246
|
+
:param idx: index du résultat (1-based)
|
247
|
+
:param dense: si True, retourne un Numpy array dense, sinon retourne un Scipy CSR array
|
136
248
|
"""
|
137
249
|
|
138
|
-
if
|
139
|
-
return self._results[idx][2].toarray() if dense else self._results[idx][2]
|
140
|
-
else:
|
250
|
+
if self.only_h:
|
141
251
|
return None
|
252
|
+
else:
|
253
|
+
self.check_if_cached(idx)
|
142
254
|
|
255
|
+
if self._tile_packer is None:
|
256
|
+
untiled = self._results[idx][2]
|
257
|
+
else:
|
258
|
+
untiled = self._tile_packer.unpack_array(self._results[idx][2])
|
259
|
+
|
260
|
+
if dense:
|
261
|
+
return untiled
|
262
|
+
else:
|
263
|
+
return csr_array(untiled)
|
143
264
|
|
144
265
|
class wolfres2DGPU(Wolfresults_2D):
|
145
266
|
"""
|
@@ -427,7 +548,7 @@ class wolfres2DGPU(Wolfresults_2D):
|
|
427
548
|
|
428
549
|
# stored result files are 1-based -> which+1
|
429
550
|
if self._cache is not None:
|
430
|
-
if
|
551
|
+
if not self._cache.only_h:
|
431
552
|
wd_np = self._cache.get_h(which+1, True)
|
432
553
|
qx_np = self._cache.get_qx(which+1, True)
|
433
554
|
qy_np = self._cache.get_qy(which+1, True)
|
@@ -472,9 +593,9 @@ class wolfres2DGPU(Wolfresults_2D):
|
|
472
593
|
curblock.qx.array.mask[ij] = False
|
473
594
|
curblock.qy.array.mask[ij] = False
|
474
595
|
|
475
|
-
curblock.waterdepth.
|
476
|
-
curblock.qx.
|
477
|
-
curblock.qy.
|
596
|
+
curblock.waterdepth.nbnotnull = len(ij[0])
|
597
|
+
curblock.qx.nbnotnull = curblock.waterdepth.nbnotnull
|
598
|
+
curblock.qy.nbnotnull = curblock.waterdepth.nbnotnull
|
478
599
|
|
479
600
|
# curblock.waterdepth.set_nullvalue_in_mask()
|
480
601
|
# curblock.qx.set_nullvalue_in_mask()
|
@@ -497,10 +618,7 @@ class wolfres2DGPU(Wolfresults_2D):
|
|
497
618
|
|
498
619
|
# stored result files are 1-based -> which+1
|
499
620
|
if self._cache is not None:
|
500
|
-
|
501
|
-
wd_np = self._cache.get_h(which+1, True)
|
502
|
-
else:
|
503
|
-
_, _, _, _, wd_np, qx_np, qy_np = self._result_store.get_result(which+1)
|
621
|
+
wd_np = self._cache.get_h(which+1, True)
|
504
622
|
else:
|
505
623
|
__, __, __, __, wd_np, qx_np, qy_np = self._result_store.get_result(which+1)
|
506
624
|
|