wolfhece 2.0.17__py3-none-any.whl → 2.0.19__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/CpGrid.py +10 -13
- wolfhece/PyCrosssections.py +18 -13
- wolfhece/PyDraw.py +80 -8
- wolfhece/PyHydrographs.py +2 -2
- wolfhece/PyParams.py +113 -35
- wolfhece/PyPictures.py +48 -45
- wolfhece/PyVertex.py +149 -18
- wolfhece/PyVertexvectors.py +40 -33
- wolfhece/apps/curvedigitizer.py +4 -1
- wolfhece/apps/wolfcompare2Darrays.py +11 -7
- wolfhece/clientserver/clientserver.py +62 -0
- wolfhece/friction_law.py +39 -34
- wolfhece/ftp/downloader.py +8 -7
- wolfhece/gpuview.py +14 -13
- wolfhece/hydrology/Catchment.py +2 -2
- wolfhece/hydrology/PyWatershed.py +2 -2
- wolfhece/hydrology/SubBasin.py +13 -11
- wolfhece/hydrometry/kiwis_gui.py +9 -9
- wolfhece/irm_qdf.py +12 -10
- wolfhece/lazviewer/laz_viewer.py +4 -1
- wolfhece/mar/Interface_MAR_WOLF_objet.py +260 -161
- wolfhece/opengl/py3d.py +4 -4
- wolfhece/pyshields.py +4 -4
- wolfhece/pythonfortran/example_makendarray.py +46 -41
- wolfhece/pythonfortran/example_numpy_memory.py +87 -83
- wolfhece/pythonfortran/tools.py +1 -1
- wolfhece/scenario/imposebc_void.py +2 -3
- wolfhece/scenario/update_void.py +6 -6
- wolfhece/wolf_array.py +47 -18
- wolfhece/wolfresults_2D.py +2 -4
- {wolfhece-2.0.17.dist-info → wolfhece-2.0.19.dist-info}/METADATA +7 -1
- {wolfhece-2.0.17.dist-info → wolfhece-2.0.19.dist-info}/RECORD +36 -41
- wolfhece/apps/wolfBernoulli.py +0 -18
- wolfhece/bernoulli/ModelJockgrim.py +0 -226
- wolfhece/bernoulli/NetworkOpenGL.py +0 -6461
- wolfhece/bernoulli/ReadNeupotzData.py +0 -223
- wolfhece/bernoulli/opti_results_interactive_plot.py +0 -212
- wolfhece/debug.py +0 -8
- /wolfhece/{bernoulli → clientserver}/__init__.py +0 -0
- {wolfhece-2.0.17.dist-info → wolfhece-2.0.19.dist-info}/WHEEL +0 -0
- {wolfhece-2.0.17.dist-info → wolfhece-2.0.19.dist-info}/entry_points.txt +0 -0
- {wolfhece-2.0.17.dist-info → wolfhece-2.0.19.dist-info}/top_level.txt +0 -0
wolfhece/CpGrid.py
CHANGED
@@ -4,19 +4,16 @@ import wx.grid
|
|
4
4
|
from .PyTranslate import _
|
5
5
|
|
6
6
|
class CpGrid(wx.grid.Grid):
|
7
|
-
"""
|
8
|
-
like copy, paste, and delete functionality.
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
restored with Ctrl+z, or pasted with Ctrl+v.
|
18
|
-
Delete or backspace key will also perform this action.
|
19
|
-
Ctrl+z - Undo the last paste or delete action.
|
7
|
+
"""
|
8
|
+
A Full Copy and Paste enabled grid class which implements Excel like copy, paste, and delete functionality.
|
9
|
+
|
10
|
+
- Ctrl+c : Copy range of selected cells.
|
11
|
+
- Ctrl+v : Paste copy selection at point of currently selected cell.
|
12
|
+
- If paste selection is larger than copy selection, copy selection will be replicated to fill paste region if it is a modulo number of copy rows and/or columns, otherwise just the copy selection will be pasted.
|
13
|
+
- Ctrl+x : Delete current selection.
|
14
|
+
- Deleted selection can be restored with Ctrl+z, or pasted with Ctrl+v.
|
15
|
+
- Delete or backspace key will also perform this action.
|
16
|
+
- Ctrl+z : Undo the last paste or delete action.
|
20
17
|
|
21
18
|
"""
|
22
19
|
|
wolfhece/PyCrosssections.py
CHANGED
@@ -393,7 +393,7 @@ class profile(vector):
|
|
393
393
|
self.myvertices[-1].y-self.myvertices[0].y])
|
394
394
|
self.orient = self.orient /np.linalg.norm(self.orient)
|
395
395
|
|
396
|
-
def get_xy_from_s(self,s) ->
|
396
|
+
def get_xy_from_s(self,s) -> tuple[float, float]:
|
397
397
|
"""
|
398
398
|
Récupération d'un tuple (x,y) sur base d'une distance 2D 's' orientée dans l'axe de la section
|
399
399
|
"""
|
@@ -672,7 +672,7 @@ class profile(vector):
|
|
672
672
|
|
673
673
|
return length
|
674
674
|
|
675
|
-
def get_sz(self, cumul=True) ->
|
675
|
+
def get_sz(self, cumul=True) -> tuple[np.ndarray, np.ndarray]:
|
676
676
|
"""
|
677
677
|
Retourne 2 vecteurs avec la position curvi 2D et l'altitude des points
|
678
678
|
"""
|
@@ -729,7 +729,7 @@ class profile(vector):
|
|
729
729
|
curvert = wolfvertex(xy[i,0],xy[i,1],sz[i,1])
|
730
730
|
self.add_vertex(curvert)
|
731
731
|
|
732
|
-
def get_sz_banksbed(self, cumul=True, force:bool=False) ->
|
732
|
+
def get_sz_banksbed(self, cumul=True, force:bool=False) -> tuple[float, float, float, float, float, float]:
|
733
733
|
"""
|
734
734
|
Retourne les positions des points de référence mais avec la coordonnée curvi 2D
|
735
735
|
- (sleft, sbed, sright, zleft, zbed, zright)
|
@@ -791,10 +791,10 @@ class profile(vector):
|
|
791
791
|
|
792
792
|
return sleft,sbed,sright,zleft,zbed,zright
|
793
793
|
|
794
|
-
def get_s3d_banksbed(self, force:bool=False)->
|
794
|
+
def get_s3d_banksbed(self, force:bool=False)-> tuple[float, float, float]:
|
795
795
|
"""
|
796
796
|
Retourne les coordonnée curvi 3D des points de référence
|
797
|
-
|
797
|
+
- (sleft, sbed, sright)
|
798
798
|
"""
|
799
799
|
|
800
800
|
if self.prepared and not force:
|
@@ -1678,11 +1678,11 @@ class crosssections(Element_To_Draw):
|
|
1678
1678
|
|
1679
1679
|
L'objet stocke ses informations dans un dictionnaire : self.myprofiles
|
1680
1680
|
Les clés de chaque entrée sont:
|
1681
|
-
['index'] : integer
|
1682
|
-
['left'] : wolfvertex
|
1683
|
-
['bed'] : wolfvertex
|
1684
|
-
['right'] : wolfvertex
|
1685
|
-
['cs'] : profile (surcharge de vector)
|
1681
|
+
- ['index'] : integer
|
1682
|
+
- ['left'] : wolfvertex
|
1683
|
+
- ['bed'] : wolfvertex
|
1684
|
+
- ['right'] : wolfvertex
|
1685
|
+
- ['cs'] : profile (surcharge de vector)
|
1686
1686
|
|
1687
1687
|
Pour le moment, il est possible de lire les fichiers et d'effectuer cerrains traitements (tri selon vecteur, export gltf...).
|
1688
1688
|
|
@@ -1694,6 +1694,7 @@ class crosssections(Element_To_Draw):
|
|
1694
1694
|
- cloud_all
|
1695
1695
|
|
1696
1696
|
@remark !! La classe n'est pas encore prévue pour créer des sections en travers!!
|
1697
|
+
|
1697
1698
|
"""
|
1698
1699
|
|
1699
1700
|
myprofiles:dict
|
@@ -2419,8 +2420,10 @@ class crosssections(Element_To_Draw):
|
|
2419
2420
|
self.multils = self.asshapely_ls()
|
2420
2421
|
|
2421
2422
|
def sort_along(self,vecsupport:LineString,name:str,downfirst=True):
|
2422
|
-
"""
|
2423
|
-
|
2423
|
+
"""
|
2424
|
+
Sélectionne les sections qui intersectent un vecteur support
|
2425
|
+
et les trie selon l'abscisse curviligne
|
2426
|
+
"""
|
2424
2427
|
|
2425
2428
|
curdict = self.sorted[name]={}
|
2426
2429
|
curdict['support'] = vecsupport
|
@@ -2989,7 +2992,9 @@ class Interpolator():
|
|
2989
2992
|
return xy,z
|
2990
2993
|
|
2991
2994
|
class Interpolators():
|
2992
|
-
"""
|
2995
|
+
"""
|
2996
|
+
Classe de gestion des interpolations sur sections en travers
|
2997
|
+
"""
|
2993
2998
|
|
2994
2999
|
def __init__(self, banks:Zones, cs:crosssections, ds=1.) -> None:
|
2995
3000
|
"""
|
wolfhece/PyDraw.py
CHANGED
@@ -1002,10 +1002,20 @@ class WolfMapViewer(wx.Frame):
|
|
1002
1002
|
self.active_array.interpolate_on_triangulation(self.active_tri.pts, self.active_tri.tri, )
|
1003
1003
|
|
1004
1004
|
def compare_cloud2array(self):
|
1005
|
+
"""
|
1006
|
+
Compare the active cloud points to the active array
|
1007
|
+
|
1008
|
+
"""
|
1009
|
+
|
1010
|
+
if self.active_array is None :
|
1011
|
+
logging.warning(_('No active array -- Please activate an array first'))
|
1012
|
+
return
|
1005
1013
|
|
1006
|
-
if self.
|
1014
|
+
if self.active_cloud is None:
|
1015
|
+
logging.warning(_('No active cloud -- Please activate a cloud first'))
|
1016
|
+
return
|
1007
1017
|
|
1008
|
-
|
1018
|
+
self.active_array.compare_cloud(self.active_cloud)
|
1009
1019
|
|
1010
1020
|
def compare_tri2array(self):
|
1011
1021
|
|
@@ -1748,7 +1758,8 @@ class WolfMapViewer(wx.Frame):
|
|
1748
1758
|
'2012-2013': 'ORTHO_2012_2013',
|
1749
1759
|
'2015': 'ORTHO_2015', '2016': 'ORTHO_2016', '2017': 'ORTHO_2017',
|
1750
1760
|
'2018': 'ORTHO_2018', '2019': 'ORTHO_2019', '2020': 'ORTHO_2020',
|
1751
|
-
'2021': 'ORTHO_2021'
|
1761
|
+
'2021': 'ORTHO_2021', '2022 printemps': 'ORTHO_2022_PRINTEMPS', '2022 été': 'ORTHO_2022_ETE',
|
1762
|
+
'2023 été': 'ORTHO_2023_ETE'}}
|
1752
1763
|
for idx, (k, item) in enumerate(orthos.items()):
|
1753
1764
|
for kdx, (m, subitem) in enumerate(item.items()):
|
1754
1765
|
self.add_object(which='wmsback',
|
@@ -2429,6 +2440,13 @@ class WolfMapViewer(wx.Frame):
|
|
2429
2440
|
else:
|
2430
2441
|
logging.info(_('Bad parameter in project file - array : ')+ curname[key_Param.VALUE])
|
2431
2442
|
|
2443
|
+
if 'cloud' in myproject.myparams.keys():
|
2444
|
+
for curid, curname in zip(myproject.myparams['cloud'].keys(), myproject.myparams['cloud'].values()):
|
2445
|
+
if exists(curname[key_Param.VALUE]):
|
2446
|
+
mycloud = cloud_vertices(curname[key_Param.VALUE])
|
2447
|
+
self.add_object('cloud', newobj=mycloud, id=curid)
|
2448
|
+
else:
|
2449
|
+
logging.info(_('Bad parameter in project file - cloud : ')+ curname[key_Param.VALUE])
|
2432
2450
|
|
2433
2451
|
if 'wolf2d' in myproject.myparams.keys():
|
2434
2452
|
for curid, curname in zip(myproject.myparams['wolf2d'].keys(), myproject.myparams['wolf2d'].values()):
|
@@ -3005,15 +3023,66 @@ class WolfMapViewer(wx.Frame):
|
|
3005
3023
|
|
3006
3024
|
elif itemlabel == _("Plot active vector..."):
|
3007
3025
|
|
3026
|
+
|
3008
3027
|
if self.active_vector is None:
|
3028
|
+
logging.warning(_('No active vector !'))
|
3009
3029
|
return
|
3010
3030
|
|
3031
|
+
add_cloud = False
|
3032
|
+
if self.active_cloud is not None:
|
3033
|
+
dlg = wx.MessageDialog(self, _('Do you want to plot the cloud ?'), style=wx.YES_NO)
|
3034
|
+
|
3035
|
+
if dlg.ShowModal() == wx.ID_YES:
|
3036
|
+
add_cloud = True
|
3037
|
+
|
3038
|
+
prox = wx.TextEntryDialog(None,_('Proximity [m] ?'), value = '5.0')
|
3039
|
+
ret = prox.ShowModal()
|
3040
|
+
if ret == wx.ID_CANCEL:
|
3041
|
+
prox.Destroy()
|
3042
|
+
return
|
3043
|
+
try:
|
3044
|
+
proxval = float(prox.GetValue())
|
3045
|
+
except:
|
3046
|
+
prox.Destroy()
|
3047
|
+
logging.warning(_('Bad value -- Rety'))
|
3048
|
+
return
|
3049
|
+
|
3050
|
+
tol = wx.TextEntryDialog(None,_('Tolerance [m] ?'), value = '0.5')
|
3051
|
+
ret = tol.ShowModal()
|
3052
|
+
if ret == wx.ID_CANCEL:
|
3053
|
+
tol.Destroy()
|
3054
|
+
return
|
3055
|
+
try:
|
3056
|
+
tolval = float(tol.GetValue())
|
3057
|
+
except:
|
3058
|
+
tol.Destroy()
|
3059
|
+
logging.warning(_('Bad value -- Rety'))
|
3060
|
+
return
|
3061
|
+
|
3062
|
+
else:
|
3063
|
+
add_cloud = False
|
3064
|
+
|
3065
|
+
dlg.Destroy()
|
3066
|
+
|
3011
3067
|
fig, ax = self.active_vector.plot_mpl(True, False)
|
3012
3068
|
|
3013
3069
|
linkedarrays = self.get_linked_arrays()
|
3014
3070
|
|
3015
3071
|
self.active_vector.plot_linked(fig, ax, linkedarrays)
|
3016
3072
|
|
3073
|
+
if add_cloud:
|
3074
|
+
s, z = self.active_cloud.projectontrace(self.active_vector, return_cloud=False, proximity= proxval)
|
3075
|
+
|
3076
|
+
ax.scatter( s, z, c='black', s=1.0)
|
3077
|
+
|
3078
|
+
for curs, curz in zip(s,z):
|
3079
|
+
ax.plot([curs, curs], [curz-tolval, curz+tolval], 'k--', linewidth=0.5)
|
3080
|
+
ax.plot([curs-.1, curs+.1], [curz+tolval, curz+tolval], c='black', linewidth=0.5)
|
3081
|
+
ax.plot([curs-.1, curs+.1], [curz-tolval, curz-tolval], c='black', linewidth=0.5)
|
3082
|
+
|
3083
|
+
fig.canvas.draw()
|
3084
|
+
fig.canvas.flush_events()
|
3085
|
+
|
3017
3086
|
elif itemlabel == _("Export arrays as Geotif..."):
|
3018
3087
|
|
3019
3088
|
self.export_results_as('geotiff')
|
@@ -4268,9 +4337,10 @@ class WolfMapViewer(wx.Frame):
|
|
4268
4337
|
filterall = "all (*.*)|*.*"
|
4269
4338
|
filterres2d = "all (*.*)|*.*"
|
4270
4339
|
filterVector = "vec (*.vec)|*.vec|vecz (*.vecz)|*.vecz|dxf (*.dxf)|*.dxf|shp (*.shp)|*.shp|all (*.*)|*.*"
|
4271
|
-
filterCloud = "xyz (*.xyz)|*.xyz|dxf (*.dxf)|*.dxf|text (*.txt)|*.txt|all (*.*)|*.*"
|
4340
|
+
filterCloud = "xyz (*.xyz)|*.xyz|dxf (*.dxf)|*.dxf|text (*.txt)|*.txt|shp (*.shp)|*.shp|all (*.*)|*.*"
|
4272
4341
|
filtertri = "tri (*.tri)|*.tri|text (*.txt)|*.txt|dxf (*.dxf)|*.dxf|gltf (*.gltf)|*.gltf|gltf binary (*.glb)|*.glb|*.*'all (*.*)|*.*"
|
4273
4342
|
filterCs = "vecz WOLF (*.vecz)|*.vecz|txt 2022 (*.txt)|*.txt|WOLF (*.sxy)|*.sxy|text 2000 (*.txt)|*.txt|all (*.*)|*.*"
|
4343
|
+
filterimage = "Geotif (*.tif)|*.tif|all (*.*)|*.*"
|
4274
4344
|
|
4275
4345
|
if filename == '' and newobj is None:
|
4276
4346
|
# ouverture d'une boîte de dialogue
|
@@ -4303,9 +4373,9 @@ class WolfMapViewer(wx.Frame):
|
|
4303
4373
|
|
4304
4374
|
# FIXME : particularize filters for wmsback and wmsfore
|
4305
4375
|
elif which.lower() == 'wmsback':
|
4306
|
-
file = wx.FileDialog(self, "Choose file", wildcard=
|
4376
|
+
file = wx.FileDialog(self, "Choose file", wildcard=filterimage)
|
4307
4377
|
elif which.lower() == 'wmsfore':
|
4308
|
-
file = wx.FileDialog(self, "Choose file", wildcard=
|
4378
|
+
file = wx.FileDialog(self, "Choose file", wildcard=filterimage)
|
4309
4379
|
|
4310
4380
|
if file.ShowModal() == wx.ID_CANCEL:
|
4311
4381
|
file.Destroy()
|
@@ -4718,12 +4788,13 @@ class WolfMapViewer(wx.Frame):
|
|
4718
4788
|
newobj.mapviewer = self
|
4719
4789
|
|
4720
4790
|
elif which.lower() == 'cloud':
|
4791
|
+
|
4721
4792
|
curdict = self.myclouds
|
4722
4793
|
curtree = self.myitemscloud
|
4723
4794
|
if newobj is None:
|
4724
4795
|
|
4725
4796
|
loadhead = False
|
4726
|
-
if not filename.endswith('.dxf'):
|
4797
|
+
if not filename.endswith('.dxf') and not filename.endswith('.shp'):
|
4727
4798
|
with open(filename,'r') as f:
|
4728
4799
|
text=f.read().splitlines()
|
4729
4800
|
tmphead=''
|
@@ -4738,7 +4809,7 @@ class WolfMapViewer(wx.Frame):
|
|
4738
4809
|
|
4739
4810
|
with wx.lib.busy.BusyInfo(_('Importing cloud points')):
|
4740
4811
|
wait = wx.BusyCursor()
|
4741
|
-
newobj = cloud_vertices(filename,header=loadhead)
|
4812
|
+
newobj = cloud_vertices(filename, header=loadhead)
|
4742
4813
|
del wait
|
4743
4814
|
|
4744
4815
|
self.myclouds.append(newobj)
|
@@ -6681,6 +6752,7 @@ class WolfMapViewer(wx.Frame):
|
|
6681
6752
|
self.active_tile = None
|
6682
6753
|
self.active_particle_system = None
|
6683
6754
|
self.active_vertex = None
|
6755
|
+
self.active_cloud = None
|
6684
6756
|
|
6685
6757
|
elif key == ord('C'):
|
6686
6758
|
|
wolfhece/PyHydrographs.py
CHANGED
wolfhece/PyParams.py
CHANGED
@@ -110,10 +110,9 @@ class Wolf_Param(wx.Frame):
|
|
110
110
|
**FR**
|
111
111
|
Gestion des paramètres au format WOLF.
|
112
112
|
|
113
|
-
Fichier texte
|
114
|
-
-------------
|
113
|
+
**Fichier texte**
|
115
114
|
|
116
|
-
Les fichiers '
|
115
|
+
Les fichiers '.param' sont des fichiers texte contenant des paramètres de type nom=valeur et compatibles avec les codes Fortran.
|
117
116
|
L'extension '.param.default' est utilisée pour stocker les paramètres par défaut.
|
118
117
|
|
119
118
|
Une autre extension est possible mais un fichier '.default' sera créé automatiquement si ce fichier n'existe pas.
|
@@ -124,8 +123,7 @@ class Wolf_Param(wx.Frame):
|
|
124
123
|
|
125
124
|
Les lignes débutant par '%' sont des commentaires. Il est possible d'ajouter du code JSON dans un commentaire. Pour cela, il faut ajouter '%json' au début de la ligne suivi d'un dictionnaire (e.g. %json{"Values":{'key1':1, 'key2':2}, "Full_Comment":"fullcomment"} ).
|
126
125
|
|
127
|
-
Organisation Python
|
128
|
-
-------------------
|
126
|
+
**Organisation Python**
|
129
127
|
|
130
128
|
L'objet Python est basé sur des dictionnaires Python. Un dictionnaire par groupe de paramètres.
|
131
129
|
|
@@ -138,14 +136,12 @@ class Wolf_Param(wx.Frame):
|
|
138
136
|
- comment : commentaire du paramètre (str) -- helpful to understand the parameter
|
139
137
|
- added_json : dictionnaire contenant des informations supplémentaires (optionnel) -- permet de stocker des informations supplémentaires sur le paramètre (ex : valeurs possibles, commentaires étendus, ...)
|
140
138
|
|
141
|
-
Dictionnaires
|
142
|
-
-------------
|
139
|
+
**Dictionnaires**
|
143
140
|
|
144
141
|
Il existe un dictionnaire de valeurs par défaut "myparams_default". Pour l'interaction Python-Fortran, c'est le Fortran qui écrit ces paramètres.
|
145
142
|
Il existe un dictionnaire de paramètres actifs "myparams". Il est utilisé pour stocker les paramètres modifiés par l'utilisateur. Normalement, seuls les paramètres modifiés par l'utilisateur sont stockés dans ce dictionnaire et sont écrits sur disque.
|
146
143
|
|
147
|
-
Groupe/Paramètre incrémentable
|
148
|
-
------------------------------
|
144
|
+
**Groupe/Paramètre incrémentable**
|
149
145
|
|
150
146
|
Il est également possible de définir des groupes ou des paramètres incrémentables.
|
151
147
|
Pour cela, dans le nom du groupe/paramètre, il faut ajouter, à l'emplacement souhaité du **numéro** du groupe/paramètre, des informations entre '$...$' :
|
@@ -160,14 +156,12 @@ class Wolf_Param(wx.Frame):
|
|
160
156
|
|
161
157
|
Les informations génériques sont stockées dans les dictionnaires "myIncGroup" et "myIncParam".
|
162
158
|
|
163
|
-
UI
|
164
|
-
--
|
159
|
+
**UI**
|
165
160
|
|
166
161
|
Une interface graphique est disponible pour modifier les paramètres. Elle est basée sur "wxPython" et la classe "wxPropertyGrid".
|
167
162
|
L'attribut wx_exists permet de savoir si wxPython est en cours d'excution ou non.
|
168
163
|
|
169
|
-
Accès aux données
|
170
|
-
-----------------
|
164
|
+
**Accès aux données**
|
171
165
|
|
172
166
|
Les paramètres sont accessibles via la procédure __getitem__ en fournissant un tuple (groupname, paramname).
|
173
167
|
Il est possible de modifier un paramètre via la procédure __setitem__.
|
@@ -186,10 +180,9 @@ class Wolf_Param(wx.Frame):
|
|
186
180
|
**EN**
|
187
181
|
Management of parameters in WOLF format.
|
188
182
|
|
189
|
-
Text File
|
190
|
-
----------
|
183
|
+
**Text File**
|
191
184
|
|
192
|
-
'
|
185
|
+
'.param' files are text files containing parameters in the name=value format and compatible with Fortran codes.
|
193
186
|
The '.param.default' extension is used to store default parameters.
|
194
187
|
|
195
188
|
Another extension is possible, but a '.default' file will be automatically created if this file does not exist.
|
@@ -200,8 +193,7 @@ class Wolf_Param(wx.Frame):
|
|
200
193
|
|
201
194
|
Lines starting with '%' are comments. It is possible to add JSON code in a comment. To do this, add '%json' at the beginning of the line followed by a dictionary (e.g., %json{"Values":{'key1':1, 'key2':2}, "Full_Comment":"fullcomment"}).
|
202
195
|
|
203
|
-
Python Organization
|
204
|
-
-------------------
|
196
|
+
**Python Organization**
|
205
197
|
|
206
198
|
The Python object is based on Python dictionaries. One dictionary per parameter group.
|
207
199
|
|
@@ -214,14 +206,12 @@ class Wolf_Param(wx.Frame):
|
|
214
206
|
- comment: parameter comment (str) -- helpful to understand the parameter
|
215
207
|
- added_json: dictionary containing additional information (optional) -- used to store additional information about the parameter (e.g., possible values, extended comments, ...)
|
216
208
|
|
217
|
-
Dictionaries
|
218
|
-
-------------
|
209
|
+
**Dictionaries**
|
219
210
|
|
220
211
|
There is a default values dictionary "myparams_default." For Python-Fortran interaction, Fortran writes these parameters.
|
221
212
|
There is an active parameters dictionary "myparams." It is used to store parameters modified by the user. Normally, only parameters modified by the user are stored in this dictionary and written to disk.
|
222
213
|
|
223
|
-
Incrementable Group/Parameter
|
224
|
-
------------------------------
|
214
|
+
**Incrementable Group/Parameter**
|
225
215
|
|
226
216
|
It is also possible to define incrementable groups or parameters.
|
227
217
|
To do this, in the group/parameter name, add information between '$...$' at the desired **number** location of the group/parameter:
|
@@ -236,14 +226,12 @@ class Wolf_Param(wx.Frame):
|
|
236
226
|
|
237
227
|
Generic information is stored in the "myIncGroup" and "myIncParam" dictionaries.
|
238
228
|
|
239
|
-
UI
|
240
|
-
--
|
229
|
+
**UI**
|
241
230
|
|
242
231
|
A graphical interface is available to modify parameters. It is based on "wxPython" and the "wxPropertyGrid" class.
|
243
232
|
The wx_exists attribute indicates whether wxPython is currently running or not.
|
244
233
|
|
245
|
-
Data Access
|
246
|
-
-----------------
|
234
|
+
**Data Access**
|
247
235
|
|
248
236
|
Parameters are accessible via the __getitem__ method by providing a tuple (groupname, paramname).
|
249
237
|
It is possible to modify a parameter via the __setitem__ method.
|
@@ -258,7 +246,7 @@ class Wolf_Param(wx.Frame):
|
|
258
246
|
- for an incrementable parameter, by providing the necessary data in a string $n(refname,min,max)$ or $n(groupname,refname,min,max)$
|
259
247
|
- if the targeted group does not exist, it will be created if all information is available.
|
260
248
|
- only add an incrementable parameter via the add_IncParam method.
|
261
|
-
|
249
|
+
|
262
250
|
"""
|
263
251
|
|
264
252
|
# Définition des propriétés
|
@@ -283,7 +271,8 @@ class Wolf_Param(wx.Frame):
|
|
283
271
|
withbuttons: bool = True,
|
284
272
|
DestroyAtClosing:bool = True,
|
285
273
|
toShow:bool = True,
|
286
|
-
init_GUI:bool = True
|
274
|
+
init_GUI:bool = True,
|
275
|
+
force_even_if_same_default:bool = False):
|
287
276
|
"""
|
288
277
|
Initialisation
|
289
278
|
|
@@ -297,7 +286,7 @@ class Wolf_Param(wx.Frame):
|
|
297
286
|
:param withbuttons : if True, buttons will be displayed
|
298
287
|
:param DestroyAtClosing : if True, the frame will be destroyed when closed
|
299
288
|
:param toShow : if True, the frame will be displayed
|
300
|
-
|
289
|
+
:param force_even_if_same_default : if True, the parameter will be displayed even if the default and active parameters are the same
|
301
290
|
|
302
291
|
Callbacks (see 'set_callbacks'):
|
303
292
|
- callback : callback function when 'apply' is pressed
|
@@ -317,7 +306,7 @@ class Wolf_Param(wx.Frame):
|
|
317
306
|
self._callbackdestroy:function = None
|
318
307
|
|
319
308
|
self.wx_exists = wx.App.Get() is not None # test if wx App is running
|
320
|
-
self.show_in_active_if_default =
|
309
|
+
self.show_in_active_if_default = force_even_if_same_default
|
321
310
|
|
322
311
|
if to_read:
|
323
312
|
self.ReadFile(filename)
|
@@ -469,6 +458,8 @@ class Wolf_Param(wx.Frame):
|
|
469
458
|
self.SetAutoLayout(1)
|
470
459
|
self.sizer.Fit(self)
|
471
460
|
|
461
|
+
self.SetSize(0,0,w,h)
|
462
|
+
|
472
463
|
#affichage de la page
|
473
464
|
self.Show(toShow)
|
474
465
|
|
@@ -530,9 +521,13 @@ class Wolf_Param(wx.Frame):
|
|
530
521
|
page_active.Append(pg.PropertyCategory(groupname))
|
531
522
|
|
532
523
|
#teste si param existe
|
533
|
-
|
524
|
+
activeprop = self.prop.GetPropertyByName(groupname + paramname)
|
525
|
+
if activeprop is None:
|
534
526
|
#si non existant --> on ajoute, si existant --> rien à faire
|
535
|
-
self.
|
527
|
+
self._insert_elem_to_page(page_active, groupname, param_def)
|
528
|
+
# if not self.is_in_active(groupname, paramname):
|
529
|
+
# #si non existant --> on ajoute, si existant --> rien à faire
|
530
|
+
# self._add_elem_to_page(page_active, groupname, param_def)
|
536
531
|
|
537
532
|
else:
|
538
533
|
#recopiage de la valeur par défaut
|
@@ -583,6 +578,16 @@ class Wolf_Param(wx.Frame):
|
|
583
578
|
# populate the property grid
|
584
579
|
self.Populate()
|
585
580
|
|
581
|
+
def _get_prop_names(self, page:pg.PropertyGridPage) -> list[str]:
|
582
|
+
""" Return the names of the properties in a page """
|
583
|
+
|
584
|
+
return [prop.GetName() for prop in page.GetPyIterator(pg.PG_ITERATE_ALL)]
|
585
|
+
|
586
|
+
def _is_in_propperty_page(self, page:pg.PropertyGridPage, group:str, param:str="") -> bool:
|
587
|
+
""" Test if a parameter is in a page """
|
588
|
+
|
589
|
+
return (group + param) in self._get_prop_names(page)
|
590
|
+
|
586
591
|
def ApplytoMemory(self, event:wx.MouseEvent):
|
587
592
|
""" Transfert des données en mémoire --> remplissage des dictionnaires """
|
588
593
|
|
@@ -597,7 +602,19 @@ class Wolf_Param(wx.Frame):
|
|
597
602
|
if not self._callback is None:
|
598
603
|
self._callback()
|
599
604
|
else:
|
600
|
-
|
605
|
+
if self.wx_exists:
|
606
|
+
dlg = wx.MessageDialog(self,'Nothing to do!')
|
607
|
+
dlg.ShowModal()
|
608
|
+
|
609
|
+
@property
|
610
|
+
def page_active(self) -> pg.PropertyGridPage:
|
611
|
+
""" Return the active page """
|
612
|
+
return self.prop.GetPage(0)
|
613
|
+
|
614
|
+
@property
|
615
|
+
def page_default(self) -> pg.PropertyGridPage:
|
616
|
+
""" Return the default page """
|
617
|
+
return self.prop.GetPage(1)
|
601
618
|
|
602
619
|
def _Apply1ParamtoMemory(self,
|
603
620
|
group:str,
|
@@ -637,7 +654,8 @@ class Wolf_Param(wx.Frame):
|
|
637
654
|
val_default = self.prop.GetPropertyByName(PREFIX_DEFAULT + group + param_name).m_value
|
638
655
|
|
639
656
|
# on tente de rcupérer la valeur active mais il ets possible qu'elle n'existe pas si sa valeur est identique à la valeur par défaut
|
640
|
-
if self.
|
657
|
+
if self._is_in_propperty_page(self.page_active, group, param_name):
|
658
|
+
# if self.is_in_active(group, param_name):
|
641
659
|
val_active = self.prop.GetPropertyByName(group + param_name).m_value
|
642
660
|
else:
|
643
661
|
val_active = val_default
|
@@ -653,7 +671,8 @@ class Wolf_Param(wx.Frame):
|
|
653
671
|
else:
|
654
672
|
# La valeur par défaut n'existe pas --> on prend la valeur active car c'est certainement une valeur incrémentable ou d'un groupe incrémentable
|
655
673
|
# Si la valeur n'est pas présente, on ne fait rien
|
656
|
-
if self.
|
674
|
+
if self._is_in_propperty_page(self.page_active, group, param_name):
|
675
|
+
# if self.is_in_active(group, param_name):
|
657
676
|
val_active = self.prop.GetPropertyByName(group + param_name).m_value
|
658
677
|
val_active = self.value_as_type(val_active, dict_param_def[key_Param.TYPE])
|
659
678
|
|
@@ -687,7 +706,9 @@ class Wolf_Param(wx.Frame):
|
|
687
706
|
|
688
707
|
#gestion des paramètres actifs
|
689
708
|
for group, params in self.myparams.items():
|
709
|
+
|
690
710
|
page_active.Append(pg.PropertyCategory(group))
|
711
|
+
|
691
712
|
for param_name, param in params.items():
|
692
713
|
param:dict
|
693
714
|
if self.is_in_default(group, param_name):
|
@@ -713,6 +734,63 @@ class Wolf_Param(wx.Frame):
|
|
713
734
|
self.prop.ShowHeader()
|
714
735
|
self.prop.Refresh()
|
715
736
|
|
737
|
+
def _insert_elem_to_page(self, page:pg.PropertyGridPage, group:str, param:dict, param_def:dict = None, prefix:str=''):
|
738
|
+
""" Insert an element to a page """
|
739
|
+
|
740
|
+
param_name = param[key_Param.NAME]
|
741
|
+
locname = prefix + group + param_name
|
742
|
+
|
743
|
+
# Get parent item based on group name
|
744
|
+
parent = page.GetPropertyByName(group)
|
745
|
+
assert parent is not None, "Group {} not found in page".format(group)
|
746
|
+
assert isinstance(parent, pg.PropertyCategory), "Parent is not a PropertyCategory"
|
747
|
+
|
748
|
+
if param_def is not None:
|
749
|
+
# priority to default parameters
|
750
|
+
if key_Param.ADDED_JSON in param_def.keys():
|
751
|
+
param[key_Param.ADDED_JSON] = param_def[key_Param.ADDED_JSON]
|
752
|
+
param[key_Param.COMMENT] = param_def[key_Param.COMMENT]
|
753
|
+
param[key_Param.TYPE] = param_def[key_Param.TYPE]
|
754
|
+
|
755
|
+
if key_Param.ADDED_JSON in param.keys() and param[key_Param.ADDED_JSON] is not None:
|
756
|
+
# Ajout des choix via chaîne JSON
|
757
|
+
list_keys = [ k for k in param[key_Param.ADDED_JSON]['Values'].keys()]
|
758
|
+
list_values = [ k for k in param[key_Param.ADDED_JSON]['Values'].values()]
|
759
|
+
|
760
|
+
page.AppendIn(parent, pg.EnumProperty(param_name, name=locname, labels=list_keys, values=list_values, value=int(param[key_Param.VALUE])))
|
761
|
+
|
762
|
+
self.prop.SetPropertyHelpString(locname , param[key_Param.ADDED_JSON]['Full_Comment'])
|
763
|
+
else:
|
764
|
+
|
765
|
+
locvalue = self[(group, param_name)]
|
766
|
+
|
767
|
+
if isinstance(locvalue, float):
|
768
|
+
page.AppendIn(parent, pg.FloatProperty(label = param_name, name = locname, value = locvalue))
|
769
|
+
|
770
|
+
elif isinstance(locvalue, int):
|
771
|
+
# bool is also an int
|
772
|
+
if isinstance(locvalue, bool):
|
773
|
+
page.AppendIn(parent, pg.BoolProperty(label=param_name, name = locname, value = locvalue))
|
774
|
+
else:
|
775
|
+
page.AppendIn(parent, pg.IntProperty(label = param_name, name = locname, value = locvalue))
|
776
|
+
|
777
|
+
elif param[key_Param.TYPE]==Type_Param.File:
|
778
|
+
page.AppendIn(parent, pg.FileProperty(label=param_name, name = locname, value = param[key_Param.VALUE]))
|
779
|
+
|
780
|
+
elif param[key_Param.TYPE]==Type_Param.Directory:
|
781
|
+
page.AppendIn(parent, pg.DirProperty(label = param_name, name = locname, value = locvalue))
|
782
|
+
|
783
|
+
elif param[key_Param.TYPE]==Type_Param.Color:
|
784
|
+
page.AppendIn(parent, pg.ColourProperty(label = param_name, name = locname, value = locvalue))
|
785
|
+
|
786
|
+
elif param[key_Param.TYPE]==Type_Param.Fontname:
|
787
|
+
page.AppendIn(parent, pg.FontProperty(label = param_name, name = locname, value = locvalue))
|
788
|
+
|
789
|
+
else:
|
790
|
+
page.AppendIn(parent, pg.StringProperty(label = param_name, name = locname, value = locvalue))
|
791
|
+
|
792
|
+
self.prop.SetPropertyHelpString(locname, param[key_Param.COMMENT])
|
793
|
+
|
716
794
|
def _add_elem_to_page(self, page:pg.PropertyGridPage, group:str, param:dict, param_def:dict = None, prefix:str=''):
|
717
795
|
""" Add an element to a page """
|
718
796
|
|