wolfhece 2.2.27__py3-none-any.whl → 2.2.29__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/PyConfig.py +27 -3
- wolfhece/PyDraw.py +202 -22
- wolfhece/PyPalette.py +18 -0
- wolfhece/PyVertexvectors.py +156 -25
- wolfhece/PyWMS.py +6 -3
- wolfhece/__init__.py +27 -0
- wolfhece/acceptability/acceptability.py +25 -20
- wolfhece/acceptability/acceptability_gui.py +150 -92
- wolfhece/acceptability/func.py +169 -82
- wolfhece/apps/version.py +1 -1
- wolfhece/irm_qdf.py +71 -7
- wolfhece/lb7208_ntv2/__init__.py +0 -0
- wolfhece/lb7208_ntv2/be_ign_README.txt +36 -0
- wolfhece/lb7208_ntv2/be_ign_bd72lb72_etrs89lb08.tif +0 -0
- wolfhece/lb7208_ntv2/be_ign_hBG18.tif +0 -0
- wolfhece/mesh2d/gpu_2d.py +11 -2
- wolfhece/report/common.py +496 -0
- wolfhece/report/compare_arrays.py +1054 -0
- wolfhece/report/simplesimgpu.py +26 -101
- wolfhece/report/tools.py +121 -16
- wolfhece/scenario/config_manager.py +265 -8
- wolfhece/ui/wolf_multiselection_collapsiblepane.py +153 -1
- wolfhece/wolf_array.py +116 -64
- wolfhece/wolf_texture.py +4 -0
- {wolfhece-2.2.27.dist-info → wolfhece-2.2.29.dist-info}/METADATA +1 -1
- {wolfhece-2.2.27.dist-info → wolfhece-2.2.29.dist-info}/RECORD +29 -23
- {wolfhece-2.2.27.dist-info → wolfhece-2.2.29.dist-info}/WHEEL +0 -0
- {wolfhece-2.2.27.dist-info → wolfhece-2.2.29.dist-info}/entry_points.txt +0 -0
- {wolfhece-2.2.27.dist-info → wolfhece-2.2.29.dist-info}/top_level.txt +0 -0
@@ -110,6 +110,8 @@ class GPU_2D_file(Enum):
|
|
110
110
|
MANNING = _gpu_file('manning' , np.float32, GPU_2D_file_extensions.NPY.value)
|
111
111
|
COMPUTATION_MASK = _gpu_file('nap' , np.uint8 , GPU_2D_file_extensions.NPY.value)
|
112
112
|
INFILTRATION = _gpu_file('infiltration_zones', np.int32, GPU_2D_file_extensions.NPY.value)
|
113
|
+
ROOF = _gpu_file('bridge_roof' , np.float32, GPU_2D_file_extensions.NPY.value)
|
114
|
+
# DECK = _gpu_file('bridge_deck' , np.float32, GPU_2D_file_extensions.NPY.value)
|
113
115
|
|
114
116
|
# répertoire de sortie des simulations GPU
|
115
117
|
RESULT_DIR = 'simul_gpu_results'
|
@@ -240,6 +242,8 @@ class Config_Manager_2D_GPU:
|
|
240
242
|
self._epsilon = 0.01
|
241
243
|
self._filter_independent = True
|
242
244
|
|
245
|
+
self._active_simulation = None
|
246
|
+
|
243
247
|
self.load_data()
|
244
248
|
|
245
249
|
def find_wolfgpu(self):
|
@@ -559,15 +563,172 @@ class Config_Manager_2D_GPU:
|
|
559
563
|
|
560
564
|
logging.info(_('Hydrographs...'))
|
561
565
|
hydro = self.get_hydrographs()
|
562
|
-
|
566
|
+
if len(hydro) == 0:
|
567
|
+
logging.info(_('No hydrographs found !'))
|
568
|
+
log += _('No hydrographs found !') + '\n'
|
569
|
+
else:
|
570
|
+
try:
|
571
|
+
nb = hydro[0].data.shape[1]
|
572
|
+
|
573
|
+
logging.info(_('Number of hydrographs : {}'.format(len(hydro))))
|
574
|
+
for curhydro in hydro:
|
575
|
+
if curhydro.data.shape[1] != nb:
|
576
|
+
loclog = _('Bad number of columns for {} !'.format(curhydro[0]._filename))
|
577
|
+
log += loclog + '\n'
|
578
|
+
logging.warning(loclog)
|
579
|
+
except Exception as e:
|
580
|
+
logging.error(_('Error while checking hydrographs: {}').format(e))
|
581
|
+
log += _('Error while checking hydrographs: {}').format(e) + '\n'
|
582
|
+
|
583
|
+
return log
|
584
|
+
|
585
|
+
def check_one_simulation(self) -> str:
|
586
|
+
"""
|
587
|
+
Check consistency of one simulation
|
588
|
+
|
589
|
+
"""
|
590
|
+
|
591
|
+
if self._active_simulation is None:
|
592
|
+
logging.error(_('No active simulation !'))
|
593
|
+
return _('No active simulation !')
|
594
|
+
|
595
|
+
logging.info(_('Checking consistency of one simulation...\n'))
|
563
596
|
|
564
|
-
logging.info(_('
|
565
|
-
|
566
|
-
|
567
|
-
|
597
|
+
logging.info(_('NPY files...'))
|
598
|
+
numpyfiles = self._active_simulation[GPU_2D_file_extensions.NPY.value]
|
599
|
+
numpynames = [file.name.lower() for file in numpyfiles]
|
600
|
+
|
601
|
+
logging.info(_('Number of numpy files : {}'.format(len(numpyfiles))))
|
602
|
+
|
603
|
+
if self._header.nbx == 0 or self._header.nby == 0:
|
604
|
+
logging.error(_('No header found !'))
|
605
|
+
logging.info(_('Trying to get header from first numpy file...'))
|
606
|
+
try:
|
607
|
+
wa = WolfArray(numpyfiles[0])
|
608
|
+
self._header = wa.get_header()
|
609
|
+
except Exception as e:
|
610
|
+
logging.error(_('Error while getting header from first numpy file: {}').format(e))
|
611
|
+
return _('Error while getting header from first numpy file: {}').format(e)
|
612
|
+
|
613
|
+
log = ''
|
614
|
+
for curnpy in numpyfiles:
|
615
|
+
|
616
|
+
# test if the shape of the numpy file is the same as the tif file
|
617
|
+
# using memmap to avoid loading the whole array in memory -> faster
|
618
|
+
arr = np.lib.format.open_memmap(curnpy, mode='r')
|
619
|
+
|
620
|
+
if arr.shape != (self._header.nbx, self._header.nby):
|
621
|
+
loclog = _('Bad shape for {} !'.format(curnpy))
|
568
622
|
log += loclog + '\n'
|
569
623
|
logging.warning(loclog)
|
570
624
|
|
625
|
+
del(arr)
|
626
|
+
|
627
|
+
logging.info(_('Hydrographs...'))
|
628
|
+
hydro = self.get_hydrographs()
|
629
|
+
if len(hydro) == 0:
|
630
|
+
logging.info(_('No hydrographs found !'))
|
631
|
+
log += _('No hydrographs found !') + '\n'
|
632
|
+
else:
|
633
|
+
try:
|
634
|
+
nb = hydro[0].data.shape[1]
|
635
|
+
|
636
|
+
logging.info(_('Number of hydrographs : {}'.format(len(hydro))))
|
637
|
+
for curhydro in hydro:
|
638
|
+
if curhydro.data.shape[1] != nb:
|
639
|
+
loclog = _('Bad number of columns for {} !'.format(curhydro[0]._filename))
|
640
|
+
log += loclog + '\n'
|
641
|
+
logging.warning(loclog)
|
642
|
+
except Exception as e:
|
643
|
+
logging.error(_('Error while checking hydrographs: {}').format(e))
|
644
|
+
log += _('Error while checking hydrographs: {}').format(e) + '\n'
|
645
|
+
|
646
|
+
for curfile in GPU_2D_file:
|
647
|
+
if curfile.value.extension == '.npy':
|
648
|
+
if curfile.value.name + curfile.value.extension not in numpynames:
|
649
|
+
loclog = _('Missing file {} !').format(curfile.value.name + curfile.value.extension)
|
650
|
+
log += loclog + '\n'
|
651
|
+
logging.warning(loclog)
|
652
|
+
else:
|
653
|
+
try:
|
654
|
+
wa = WolfArray(numpyfiles[numpynames.index(curfile.value.name + curfile.value.extension)])
|
655
|
+
if wa.dtype != curfile.value.type:
|
656
|
+
loclog = _('Bad dtype for {} ! Expected {}, got {}').format(
|
657
|
+
curfile.value.name + curfile.value.extension,
|
658
|
+
curfile.value.type, wa.dtype)
|
659
|
+
log += loclog + '\n'
|
660
|
+
logging.warning(loclog)
|
661
|
+
del(wa)
|
662
|
+
except Exception as e:
|
663
|
+
loclog = _('Error while checking {}: {}').format(
|
664
|
+
curfile.value.name + curfile.value.extension, e)
|
665
|
+
log += loclog + '\n'
|
666
|
+
logging.error(loclog)
|
667
|
+
|
668
|
+
if 'nap.npy' in numpynames:
|
669
|
+
nap = WolfArray(numpyfiles[numpynames.index('nap.npy')])
|
670
|
+
else:
|
671
|
+
nap = None
|
672
|
+
logging.error(_('No nap file found !'))
|
673
|
+
log += _('No nap file found !') + '\n'
|
674
|
+
|
675
|
+
if nap is not None:
|
676
|
+
if 'infiltration_zones.npy' in numpynames:
|
677
|
+
# Check if infiltration zones are consistent
|
678
|
+
infil_zones = WolfArray(numpyfiles[numpynames.index('infiltration_zones.npy')])
|
679
|
+
|
680
|
+
if np.any(infil_zones.array[nap.array == 0] != 0):
|
681
|
+
loclog = _('Infiltration zones are not consistent with the nap file !')
|
682
|
+
log += loclog + '\n'
|
683
|
+
|
684
|
+
# find all non zero infiltration zones
|
685
|
+
non_zero_infil_zones = list(set(np.unique(infil_zones.array[nap.array == 1])))
|
686
|
+
if len(non_zero_infil_zones) == 0:
|
687
|
+
loclog = _('No infiltration zones found !')
|
688
|
+
log += loclog + '\n'
|
689
|
+
else:
|
690
|
+
if non_zero_infil_zones[0] == 0:
|
691
|
+
#pop
|
692
|
+
non_zero_infil_zones.pop(0)
|
693
|
+
if len(non_zero_infil_zones) == 0:
|
694
|
+
loclog = _('No infiltration zones found !')
|
695
|
+
log += loclog + '\n'
|
696
|
+
|
697
|
+
elif non_zero_infil_zones[0] !=1:
|
698
|
+
loclog = _('Infiltration zones should start at 1 ! Found {} instead.').format(non_zero_infil_zones[0])
|
699
|
+
log += loclog + '\n'
|
700
|
+
logging.warning(loclog)
|
701
|
+
|
702
|
+
# increments
|
703
|
+
if not all([non_zero_infil_zones[i] - non_zero_infil_zones[i-1] == 1 for i in range(1, len(non_zero_infil_zones))]):
|
704
|
+
loclog = _('Infiltration zones are not consecutive !')
|
705
|
+
log += loclog + '\n'
|
706
|
+
logging.warning(loclog)
|
707
|
+
del(infil_zones)
|
708
|
+
|
709
|
+
if 'bathymetry.npy' in numpynames:
|
710
|
+
# Check if infiltration zones are consistent
|
711
|
+
bath = WolfArray(numpyfiles[numpynames.index('bathymetry.npy')])
|
712
|
+
|
713
|
+
if np.any(bath.array[nap.array == 0] != 99999.):
|
714
|
+
loclog = _("Some bathymetry's cells are different of 99999 outside the computation domain !\n")
|
715
|
+
loclog += _('This may lead to unexpected results !')
|
716
|
+
log += loclog + '\n'
|
717
|
+
|
718
|
+
del(bath)
|
719
|
+
|
720
|
+
for file in ['h.npy', 'qx.npy', 'qy.npy']:
|
721
|
+
if file in numpynames:
|
722
|
+
# Check if infiltration zones are consistent
|
723
|
+
bath = WolfArray(numpyfiles[numpynames.index(file)])
|
724
|
+
|
725
|
+
if np.any(bath.array[nap.array == 0] != 0.):
|
726
|
+
loclog = _("Some cells are different of 0.0 outside the computation domain in {}!\n").format(file)
|
727
|
+
loclog += _('This may lead to unexpected results !')
|
728
|
+
log += loclog + '\n'
|
729
|
+
|
730
|
+
del(bath)
|
731
|
+
|
571
732
|
return log
|
572
733
|
|
573
734
|
# Analyze files
|
@@ -671,7 +832,13 @@ class Config_Manager_2D_GPU:
|
|
671
832
|
ok &= (GPU_2D_file.PARAMETERS.value.name+GPU_2D_file.PARAMETERS.value.extension).lower() in [cur.name.lower() for cur in curdict[GPU_2D_file_extensions.JSON.value]]
|
672
833
|
|
673
834
|
if ok:
|
674
|
-
|
835
|
+
try:
|
836
|
+
json_data = json.load(open(curdict['path'] / (GPU_2D_file.PARAMETERS.value.name+GPU_2D_file.PARAMETERS.value.extension), 'r'))
|
837
|
+
except json.JSONDecodeError as e:
|
838
|
+
logging.error(_('Error decoding JSON file: {}').format(e))
|
839
|
+
curdict['missing'].append(GPU_2D_file_extensions.JSON.value)
|
840
|
+
ok = False
|
841
|
+
return
|
675
842
|
|
676
843
|
else:
|
677
844
|
curdict['missing'].append(GPU_2D_file_extensions.JSON.value)
|
@@ -1182,6 +1349,22 @@ class Config_Manager_2D_GPU:
|
|
1182
1349
|
else:
|
1183
1350
|
logging.error(_("No 'bathymetry.tif' file found in the root directory !"))
|
1184
1351
|
|
1352
|
+
def create_void_dtm(self):
|
1353
|
+
""" create void dtm file """
|
1354
|
+
if (self.workingdir / 'bathymetry.tif').exists():
|
1355
|
+
locheader = self.get_header()
|
1356
|
+
dtm = WolfArray(srcheader=locheader, whichtype= WOLF_ARRAY_FULL_SINGLE)
|
1357
|
+
dtm.array.data[:,:] = 99999.
|
1358
|
+
dtm.nullvalue = 99999.
|
1359
|
+
dtm.write_all(str(self.workingdir / 'dtm.tif'))
|
1360
|
+
|
1361
|
+
if (self.workingdir / 'dtm.tif').exists():
|
1362
|
+
logging.info(_('dtm.tif created and set to 99999. ! -- Please edit it !'))
|
1363
|
+
else:
|
1364
|
+
logging.error(_("dtm.tif not created ! -- Does 'bathymetry.tif' or any '.tif' file exist in the root directory ?"))
|
1365
|
+
else:
|
1366
|
+
logging.error(_("No 'bathymetry.tif' file found in the root directory !"))
|
1367
|
+
|
1185
1368
|
def create_void_roof(self):
|
1186
1369
|
""" create void roof file """
|
1187
1370
|
|
@@ -1382,6 +1565,7 @@ class Config_Manager_2D_GPU:
|
|
1382
1565
|
logging.error(_('Infiltration .tif must be a full integer array ! -- The array will be ignored !'))
|
1383
1566
|
infiltration = WolfArray(srcheader=bat.get_header(), whichtype= WOLF_ARRAY_FULL_INTEGER)
|
1384
1567
|
infiltration.array.data[:,:] = 0
|
1568
|
+
|
1385
1569
|
else:
|
1386
1570
|
infiltration = WolfArray(srcheader=bat.get_header(), whichtype= WOLF_ARRAY_FULL_INTEGER)
|
1387
1571
|
infiltration.array.data[:,:] = 0
|
@@ -1494,6 +1678,20 @@ class Config_Manager_2D_GPU:
|
|
1494
1678
|
else:
|
1495
1679
|
cursim.qy = np.zeros((self._header.nbx, self._header.nby), dtype=np.float32)
|
1496
1680
|
|
1681
|
+
|
1682
|
+
# check if infiltration array is strictly inside nap
|
1683
|
+
if not np.all(cursim.nap[infiltration.array.data[infiltration.array.data > 0]] == 1):
|
1684
|
+
logging.warning(_('Infiltration zones must be strictly inside the NAP !'))
|
1685
|
+
logging.warning(_('Infiltration zones outside NAP will be set to 0 !'))
|
1686
|
+
|
1687
|
+
#count number of infiltration zones outside NAP
|
1688
|
+
nb_outside = np.sum(infiltration.array.data[(infiltration.array.data > 0) & (cursim.nap == 0)])
|
1689
|
+
logging.warning(_('Number of infiltration zones outside NAP: {}').format(nb_outside))
|
1690
|
+
# index infiltration zones outside NAP
|
1691
|
+
indices = list(set(infiltration.array.data[(infiltration.array.data > 0) & (cursim.nap == 0)]))
|
1692
|
+
logging.warning(_('Indices of infiltration zones outside NAP: {}').format(indices))
|
1693
|
+
infiltration.array.data[(infiltration.array.data > 0) & (cursim.nap == 0)] = 0
|
1694
|
+
|
1497
1695
|
cursim.infiltration_zones = np.asarray(infiltration.array.data, dtype=np.int32)
|
1498
1696
|
|
1499
1697
|
if roof.nbnotnull == 0:
|
@@ -1753,10 +1951,18 @@ class UI_Manager_2D_GPU():
|
|
1753
1951
|
self._reload.Bind(wx.EVT_BUTTON,self.onupdate_structure)
|
1754
1952
|
self._reload.SetToolTip(_('reScan the directory and reload the entire structure'))
|
1755
1953
|
|
1954
|
+
tif_sizer = wx.BoxSizer(wx.HORIZONTAL)
|
1756
1955
|
self._create_void_infil = wx.Button(self._frame,label = _('Create .tif infiltration zones'))
|
1757
1956
|
self._create_void_infil.Bind(wx.EVT_BUTTON,self.oncreate_void_infil)
|
1758
1957
|
self._create_void_infil.SetToolTip(_('Create a void infiltration zones file based on bathymetry.tif'))
|
1759
1958
|
|
1959
|
+
self._create_dtm = wx.Button(self._frame,label = _('Create .tif DTM'))
|
1960
|
+
self._create_dtm.Bind(wx.EVT_BUTTON,self.oncreate_dtm)
|
1961
|
+
self._create_dtm.SetToolTip(_('Create a DTM file based on bathymetry.tif\n\n - bathymetry.tif must be present in the root directory'))
|
1962
|
+
|
1963
|
+
tif_sizer.Add(self._create_void_infil, 1, wx.EXPAND)
|
1964
|
+
tif_sizer.Add(self._create_dtm, 1, wx.EXPAND)
|
1965
|
+
|
1760
1966
|
bridge_sizer = wx.BoxSizer(wx.HORIZONTAL)
|
1761
1967
|
self._create_void_roof = wx.Button(self._frame,label = _('Create .tif bridge/culvert roof elevation'))
|
1762
1968
|
self._create_void_roof.Bind(wx.EVT_BUTTON,self.oncreate_void_roof)
|
@@ -1797,6 +2003,10 @@ class UI_Manager_2D_GPU():
|
|
1797
2003
|
self._checkconsistency.Bind(wx.EVT_BUTTON,self.oncheck_consistency)
|
1798
2004
|
self._checkconsistency.SetToolTip(_('Check consistency of the scenario\n\n - bathymetry.tif\n - manning.tif\n - infiltration.tif\n - hydrographs\n - initial conditions\n - boundary conditions\n - scripts'))
|
1799
2005
|
|
2006
|
+
self._checkonesimulation = wx.Button(self._frame,label = _('Check one simulation'))
|
2007
|
+
self._checkonesimulation.Bind(wx.EVT_BUTTON,self.oncheck_one_simulation)
|
2008
|
+
self._checkonesimulation.SetToolTip(_('Check consistency of one simulation'))
|
2009
|
+
|
1800
2010
|
self._createsim = wx.Button(self._frame,label = _('Create simulation(s)'))
|
1801
2011
|
self._createsim.Bind(wx.EVT_BUTTON,self.oncreate_simulation)
|
1802
2012
|
self._createsim.SetToolTip(_('Create simulation(s) from selected hydrographs'))
|
@@ -1840,14 +2050,19 @@ class UI_Manager_2D_GPU():
|
|
1840
2050
|
|
1841
2051
|
# buttons -> sizer
|
1842
2052
|
sizer_buttons.Add(self._reload,1,wx.EXPAND)
|
1843
|
-
sizer_buttons.Add(
|
2053
|
+
sizer_buttons.Add(tif_sizer,1,wx.EXPAND)
|
1844
2054
|
sizer_buttons.Add(bridge_sizer,1,wx.EXPAND)
|
1845
2055
|
sizer_buttons.Add(self._create_void_scripts,1,wx.EXPAND)
|
1846
2056
|
sizer_buttons.Add(self._check_prefix,1,wx.EXPAND)
|
1847
2057
|
sizer_buttons.Add(self._create_vrt,1,wx.EXPAND)
|
1848
2058
|
sizer_buttons.Add(self._translate_vrt,1,wx.EXPAND)
|
1849
2059
|
sizer_buttons.Add(self._apply_scripts,1,wx.EXPAND)
|
1850
|
-
|
2060
|
+
|
2061
|
+
_sizer_check = wx.BoxSizer(wx.HORIZONTAL)
|
2062
|
+
_sizer_check.Add(self._checkconsistency, 1, wx.EXPAND)
|
2063
|
+
_sizer_check.Add(self._checkonesimulation, 1, wx.EXPAND)
|
2064
|
+
|
2065
|
+
sizer_buttons.Add(_sizer_check,1,wx.EXPAND)
|
1851
2066
|
sizer_buttons.Add(self._create_vec,1,wx.EXPAND)
|
1852
2067
|
sizer_buttons.Add(self.listsims,1,wx.EXPAND)
|
1853
2068
|
sizer_buttons.Add(self._createsim,1,wx.EXPAND)
|
@@ -1910,6 +2125,12 @@ class UI_Manager_2D_GPU():
|
|
1910
2125
|
self._parent.create_void_infil()
|
1911
2126
|
self.reload()
|
1912
2127
|
|
2128
|
+
def oncreate_dtm(self, e:wx.MouseEvent):
|
2129
|
+
""" Création d'un fichier DTM vide """
|
2130
|
+
|
2131
|
+
self._parent.create_void_dtm()
|
2132
|
+
self.reload()
|
2133
|
+
|
1913
2134
|
def oncreate_void_roof(self, e:wx.MouseEvent):
|
1914
2135
|
""" Création d'un fichier de toit de pont vide """
|
1915
2136
|
|
@@ -2101,6 +2322,40 @@ class UI_Manager_2D_GPU():
|
|
2101
2322
|
else:
|
2102
2323
|
self._txtctrl.WriteText(log)
|
2103
2324
|
|
2325
|
+
def oncheck_one_simulation(self, e:wx.MouseEvent):
|
2326
|
+
""" Vérification de la cohérence d'une simulation
|
2327
|
+
"""
|
2328
|
+
self._txtctrl.Clear()
|
2329
|
+
log = self._parent.check_one_simulation()
|
2330
|
+
if log == '':
|
2331
|
+
self._txtctrl.WriteText("\n\n".join([_("All seems fine !")]))
|
2332
|
+
else:
|
2333
|
+
self._txtctrl.WriteText("\n\n".join([log]))
|
2334
|
+
|
2335
|
+
# Info on Python Environment and wolfgpu Path and version
|
2336
|
+
# -------------------------------------------------------
|
2337
|
+
|
2338
|
+
import sys
|
2339
|
+
# Python Environment
|
2340
|
+
self._txtctrl.write(_('\nPython Environment\n'))
|
2341
|
+
self._txtctrl.write('-------------------\n')
|
2342
|
+
self._txtctrl.write('Python version : {}\n'.format(sys.version))
|
2343
|
+
self._txtctrl.write('Python path : {}\n'.format(sys.executable))
|
2344
|
+
self._txtctrl.write('Python version info : {}\n'.format(sys.version_info))
|
2345
|
+
|
2346
|
+
# Test if wolfgpu.exe exists in script directory
|
2347
|
+
# wolfgpu Path and version
|
2348
|
+
self._txtctrl.write('\nWolfgpu Path and version\n')
|
2349
|
+
self._txtctrl.write('------------------------\n')
|
2350
|
+
|
2351
|
+
wolfgpu = self._parent.wolfgpu
|
2352
|
+
if wolfgpu.exists():
|
2353
|
+
self._txtctrl.write('Wolfgpu.exe found in : {}\n'.format(self._parent.wolfgpu.parent))
|
2354
|
+
else:
|
2355
|
+
self._txtctrl.write('Wolfgpu.exe not found !\n')
|
2356
|
+
self._parent.wolfgpu = None
|
2357
|
+
|
2358
|
+
|
2104
2359
|
def oncheck_consistency(self,e:wx.MouseEvent):
|
2105
2360
|
""" Vérification de la cohérence des fichiers """
|
2106
2361
|
|
@@ -2401,10 +2656,12 @@ class UI_Manager_2D_GPU():
|
|
2401
2656
|
self._txtctrl.SetBackgroundColour(wx.WHITE)
|
2402
2657
|
self._txtctrl.SetForegroundColour(wx.BLACK)
|
2403
2658
|
|
2659
|
+
self._parent._active_simulation = None
|
2404
2660
|
if isinstance(mydata, dict):
|
2405
2661
|
self._txtctrl.write(_('Yous have selected : {}\n\n'.format(str(mydata['path']))))
|
2406
2662
|
|
2407
2663
|
if mydata[IS_SIMUL]:
|
2664
|
+
self._parent._active_simulation = mydata
|
2408
2665
|
self._txtctrl.write(_('GPU SIMULATION\n\n'))
|
2409
2666
|
|
2410
2667
|
if ctrl and not shift and not alt:
|
@@ -211,6 +211,8 @@ class Wolf_MultipleSelection(wx.Dialog):
|
|
211
211
|
assert len(self.delete_if_transfer) == len(values_dict), "delete_if_transfer must be a list of len(values_dict)"
|
212
212
|
for i, values in enumerate(values_dict.values()):
|
213
213
|
assert isinstance(self.delete_if_transfer[i], bool), "delete_if_transfer must be a list of boolean"
|
214
|
+
else:
|
215
|
+
self.delete_if_transfer = None
|
214
216
|
|
215
217
|
super().__init__(parent, title=title)
|
216
218
|
|
@@ -339,6 +341,145 @@ class Wolf_MultipleSelection(wx.Dialog):
|
|
339
341
|
if self.callback is not None:
|
340
342
|
self.callback(self)
|
341
343
|
|
344
|
+
class Wolf_CompareArrays_Selection(Wolf_MultipleSelection):
|
345
|
+
"""
|
346
|
+
Dialog with multiple 'collapsiblepanes' containing 2 lists to select multiple items
|
347
|
+
This class is a specific case of Wolf_MultipleSelection for comparing arrays
|
348
|
+
"""
|
349
|
+
def __init__(self,
|
350
|
+
parent,
|
351
|
+
title,
|
352
|
+
values_dict:dict,
|
353
|
+
callback = None,
|
354
|
+
info:str='',
|
355
|
+
cmdApply:bool=False,
|
356
|
+
styles = wx.LB_EXTENDED,
|
357
|
+
destroyOK = False,
|
358
|
+
**kwargs):
|
359
|
+
"""
|
360
|
+
:param parent : wx.Window
|
361
|
+
:param title : str - title of the frame
|
362
|
+
:param values_dict : dict - {'label1':[item1, item2, ...], 'label2':[item1, item2, ...], ...}
|
363
|
+
:param callback : function - callback function when OK or Apply button is pressed
|
364
|
+
:param info : str - information to display upper the collapsiblepanes
|
365
|
+
:param cmdApply : bool - if True, Apply button is displayed
|
366
|
+
:param styles : wx.ListBox styles - wx constant or list of wx constants
|
367
|
+
:param kwargs : dict - other arguments for wx.Frame (example : max_selected_items=[1, 2, 3], delete_if_transfer=[True, False, True])
|
368
|
+
"""
|
369
|
+
super().__init__(parent=parent,
|
370
|
+
title=title,
|
371
|
+
values_dict=values_dict,
|
372
|
+
callback=callback,
|
373
|
+
info=info,
|
374
|
+
cmdApply=cmdApply,
|
375
|
+
styles=styles,
|
376
|
+
destroyOK=destroyOK,
|
377
|
+
max_selected_items=[1]*len(values_dict),
|
378
|
+
delete_if_transfer=[True]*len(values_dict),
|
379
|
+
**kwargs)
|
380
|
+
|
381
|
+
# add some UI specific to the compare arrays selection
|
382
|
+
|
383
|
+
# textbox for a threshold value
|
384
|
+
self.threshold_label = wx.StaticText(self, label="Threshold value [m]:")
|
385
|
+
self.threshold_value = wx.TextCtrl(self, value="0.01", style=wx.TE_PROCESS_ENTER | wx.TE_CENTER)
|
386
|
+
self.threshold_value.Bind(wx.EVT_TEXT_ENTER, self._on_threshold_enter)
|
387
|
+
self.threshold_value.Bind(wx.EVT_KILL_FOCUS, self._on_threshold_enter)
|
388
|
+
self.threshold_value.SetToolTip("Enter a threshold value - All differences below this threshold will be considered as equal")
|
389
|
+
# add the threshold label and value to the sizer
|
390
|
+
sizer = self.GetSizer()
|
391
|
+
|
392
|
+
sizer_threshold = wx.BoxSizer(wx.HORIZONTAL)
|
393
|
+
sizer_threshold.Add(self.threshold_label, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5)
|
394
|
+
sizer_threshold.Add(self.threshold_value, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
|
395
|
+
sizer.Add(sizer_threshold, proportion=0, flag=wx.EXPAND | wx.ALL, border=5)
|
396
|
+
|
397
|
+
# textbox for a minimal area value
|
398
|
+
self.min_area_label = wx.StaticText(self, label="Minimal area value [m²]:")
|
399
|
+
self.min_area_value = wx.TextCtrl(self, value="2.0", style=wx.TE_PROCESS_ENTER | wx.TE_CENTER)
|
400
|
+
self.min_area_value.Bind(wx.EVT_TEXT_ENTER, self._on_min_area_enter)
|
401
|
+
self.min_area_value.Bind(wx.EVT_KILL_FOCUS, self._on_min_area_enter)
|
402
|
+
self.min_area_value.SetToolTip("Enter a minimal area value - All patches below this area will be ignored")
|
403
|
+
# add the minimal area label and value to the sizer
|
404
|
+
sizer_min_area = wx.BoxSizer(wx.HORIZONTAL)
|
405
|
+
sizer_min_area.Add(self.min_area_label, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5)
|
406
|
+
sizer_min_area.Add(self.min_area_value, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
|
407
|
+
sizer.Add(sizer_min_area, proportion=0, flag=wx.EXPAND | wx.ALL, border=5)
|
408
|
+
# Maximum patches to include in the report
|
409
|
+
self.max_patches_label = wx.StaticText(self, label="Maximum patches to include in the report:")
|
410
|
+
self.max_patches_value = wx.TextCtrl(self, value="10", style=wx.TE_PROCESS_ENTER | wx.TE_CENTER)
|
411
|
+
self.max_patches_value.Bind(wx.EVT_TEXT_ENTER, self._on_max_patches_enter)
|
412
|
+
self.max_patches_value.Bind(wx.EVT_KILL_FOCUS, self._on_max_patches_enter)
|
413
|
+
self.max_patches_value.SetToolTip("Enter a maximum number of patches to include in the report - If more patches are found, only the first ones will be included")
|
414
|
+
# add the maximum patches label and value to the sizer
|
415
|
+
sizer_max_patches = wx.BoxSizer(wx.HORIZONTAL)
|
416
|
+
sizer_max_patches.Add(self.max_patches_label, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5)
|
417
|
+
sizer_max_patches.Add(self.max_patches_value, proportion=1, flag= wx.EXPAND | wx.ALL, border=5)
|
418
|
+
sizer.Add(sizer_max_patches, proportion=0, flag=wx.EXPAND | wx.ALL, border=5)
|
419
|
+
# add the sizer to the main sizer
|
420
|
+
self.SetSizer(sizer)
|
421
|
+
self.Fit()
|
422
|
+
self.Layout()
|
423
|
+
|
424
|
+
|
425
|
+
def _on_threshold_enter(self, event):
|
426
|
+
""" Callback when the threshold value is changed """
|
427
|
+
try:
|
428
|
+
value = float(self.threshold_value.GetValue())
|
429
|
+
if value < 0:
|
430
|
+
self.threshold_value.SetValue("0.01")
|
431
|
+
except ValueError as e:
|
432
|
+
wx.MessageBox(f"Invalid threshold value: {e}", "Error", wx.OK | wx.ICON_ERROR)
|
433
|
+
self.threshold_value.SetValue("0.01")
|
434
|
+
event.Skip()
|
435
|
+
|
436
|
+
def _on_min_area_enter(self, event):
|
437
|
+
""" Callback when the minimal area value is changed """
|
438
|
+
try:
|
439
|
+
value = float(self.min_area_value.GetValue())
|
440
|
+
if value < 0:
|
441
|
+
self.min_area_value.SetValue("2.0")
|
442
|
+
except ValueError as e:
|
443
|
+
wx.MessageBox(f"Invalid minimal area value: {e}", "Error", wx.OK | wx.ICON_ERROR)
|
444
|
+
self.min_area_value.SetValue("2.0")
|
445
|
+
event.Skip()
|
446
|
+
|
447
|
+
def _on_max_patches_enter(self, event):
|
448
|
+
""" Callback when the maximum patches value is changed """
|
449
|
+
try:
|
450
|
+
value = int(self.max_patches_value.GetValue())
|
451
|
+
if value < 1:
|
452
|
+
self.max_patches_value.SetValue("10")
|
453
|
+
except ValueError as e:
|
454
|
+
wx.MessageBox(f"Invalid maximum patches value: {e}", "Error", wx.OK | wx.ICON_ERROR)
|
455
|
+
self.max_patches_value.SetValue("10")
|
456
|
+
event.Skip()
|
457
|
+
|
458
|
+
def get_threshold(self):
|
459
|
+
""" Get the threshold value """
|
460
|
+
try:
|
461
|
+
return float(self.threshold_value.GetValue())
|
462
|
+
except ValueError:
|
463
|
+
wx.MessageBox("Invalid threshold value", "Error", wx.OK | wx.ICON_ERROR)
|
464
|
+
return 0.01
|
465
|
+
|
466
|
+
def get_min_area(self):
|
467
|
+
""" Get the minimal area value """
|
468
|
+
try:
|
469
|
+
return float(self.min_area_value.GetValue())
|
470
|
+
except ValueError:
|
471
|
+
wx.MessageBox("Invalid minimal area value", "Error", wx.OK | wx.ICON_ERROR)
|
472
|
+
return 2.0
|
473
|
+
|
474
|
+
def get_max_patches(self):
|
475
|
+
""" Get the maximum patches value """
|
476
|
+
try:
|
477
|
+
return int(self.max_patches_value.GetValue())
|
478
|
+
except ValueError:
|
479
|
+
wx.MessageBox("Invalid maximum patches value", "Error", wx.OK | wx.ICON_ERROR)
|
480
|
+
return 10
|
481
|
+
|
482
|
+
|
342
483
|
if __name__ == "__main__":
|
343
484
|
# Utilisation de la classe Wolf_MultipleSelection
|
344
485
|
app = wx.App()
|
@@ -351,6 +492,17 @@ if __name__ == "__main__":
|
|
351
492
|
callback=None,
|
352
493
|
styles=[wx.LB_SINGLE, wx.LB_EXTENDED, wx.LB_EXTENDED],
|
353
494
|
max_selected_items=[1, -1, -1],)
|
354
|
-
|
495
|
+
|
496
|
+
fram2 = Wolf_CompareArrays_Selection(None,
|
497
|
+
title="Exemple de Wolf_CompareArrays_Selection",
|
498
|
+
values_dict={'domain':["Item 1", "Item 2", "Item 3", "Item 4"],
|
499
|
+
'u':["Item 3", "Item 4", "Item 5", "Item 6"],
|
500
|
+
'v':["Item v1", "Item v2", "Item v3", "Item v4"]},
|
501
|
+
info="You can define : \n - the domain\n - u\n -v",
|
502
|
+
callback=None,
|
503
|
+
styles=[wx.LB_SINGLE, wx.LB_SINGLE, wx.LB_SINGLE],
|
504
|
+
destroyOK=True)
|
505
|
+
|
506
|
+
fram2.ShowModal()
|
355
507
|
pass
|
356
508
|
app.MainLoop()
|