wolfhece 2.1.118__py3-none-any.whl → 2.1.120__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 +893 -177
- wolfhece/PyVertexvectors.py +304 -0
- wolfhece/apps/check_install.py +39 -0
- wolfhece/apps/version.py +1 -1
- wolfhece/lazviewer/_add_path.py +17 -17
- wolfhece/lazviewer/laz_viewer.py +422 -128
- wolfhece/lazviewer/libs/qt_plugins/platforms/qwindows.dll +0 -0
- wolfhece/lazviewer/viewer/qt.conf +2 -0
- wolfhece/lazviewer/viewer/viewer.py +28 -8
- wolfhece/matplotlib_fig.py +83 -1
- wolfhece/opengl/py3d.py +10 -4
- wolfhece/wolfresults_2D.py +484 -21
- {wolfhece-2.1.118.dist-info → wolfhece-2.1.120.dist-info}/METADATA +1 -1
- {wolfhece-2.1.118.dist-info → wolfhece-2.1.120.dist-info}/RECORD +17 -15
- {wolfhece-2.1.118.dist-info → wolfhece-2.1.120.dist-info}/WHEEL +0 -0
- {wolfhece-2.1.118.dist-info → wolfhece-2.1.120.dist-info}/entry_points.txt +0 -0
- {wolfhece-2.1.118.dist-info → wolfhece-2.1.120.dist-info}/top_level.txt +0 -0
wolfhece/wolfresults_2D.py
CHANGED
@@ -41,6 +41,7 @@ from .pyviews import WolfViews
|
|
41
41
|
from .mesh2d.wolf2dprev import prev_parameters_simul, blocks_file
|
42
42
|
from .GraphNotebook import PlotPanel
|
43
43
|
from .CpGrid import CpGrid
|
44
|
+
from .matplotlib_fig import Matplotlib_Figure
|
44
45
|
|
45
46
|
|
46
47
|
try:
|
@@ -1458,6 +1459,38 @@ VIEWS_COMPLEX = [views_2D.T_WD_Q,
|
|
1458
1459
|
|
1459
1460
|
VIEWS_VECTOR_FIELD = [views_2D.VECTOR_FIELD_Q, views_2D.VECTOR_FIELD_U]
|
1460
1461
|
|
1462
|
+
|
1463
|
+
class Extractable_results(Enum):
|
1464
|
+
# (h,qx,qy,vx,vy,vabs,fr,h+top,top)
|
1465
|
+
H = (_('Water depth [m]'), 0)
|
1466
|
+
Z = (_('Water level [m]'), 7)
|
1467
|
+
HEAD = (_('Head [m]'), None)
|
1468
|
+
FROUDE = (_('Froude [-]'), 6)
|
1469
|
+
VX = (_('Velocity X [ms-1]'), 3)
|
1470
|
+
VY = (_('Velocity Y [ms-1]'), 4)
|
1471
|
+
V_NORM = (_('Velocity norm [ms-1]'), 5)
|
1472
|
+
QX = (_('Specific discharge X [m2s-1]'), 1)
|
1473
|
+
QY = (_('Specific discharge Y [m2s-1]'), 2)
|
1474
|
+
TOP = (_('TopoBathymetry [m]'), 8)
|
1475
|
+
# INT_QX = (_('Discharge X [m3s-1]'), None)
|
1476
|
+
# INT_QY = (_('Discharge Y [m3s-1]'), None)
|
1477
|
+
|
1478
|
+
@classmethod
|
1479
|
+
def get_from_key(cls,key):
|
1480
|
+
for cur in Extractable_results:
|
1481
|
+
if cur.value[0] == key:
|
1482
|
+
return cur
|
1483
|
+
|
1484
|
+
return None
|
1485
|
+
|
1486
|
+
@classmethod
|
1487
|
+
def get_list(cls):
|
1488
|
+
return [cur.value[0] for cur in Extractable_results]
|
1489
|
+
|
1490
|
+
ER_DIRECT_ACCESS = [Extractable_results.H, Extractable_results.QX, Extractable_results.QY, Extractable_results.VX,
|
1491
|
+
Extractable_results.VY, Extractable_results.V_NORM, Extractable_results.FROUDE, Extractable_results.Z,
|
1492
|
+
Extractable_results.TOP]
|
1493
|
+
|
1461
1494
|
class OneWolfResult:
|
1462
1495
|
"""
|
1463
1496
|
Stockage des résultats d'un bloc de modèle WOLF2D
|
@@ -3464,7 +3497,7 @@ class Wolfresults_2D(Element_To_Draw):
|
|
3464
3497
|
:param agglo (optional) agglomère le résultat en une seule liste plutôt que d'avoir autant de liste que de blocs
|
3465
3498
|
:param getxy (optional) retourne en plus les coordonnées des points
|
3466
3499
|
|
3467
|
-
:return
|
3500
|
+
:return: valeurs, valeurs d'élévation, coordonnées des points (si getxy=True)
|
3468
3501
|
|
3469
3502
|
"""
|
3470
3503
|
myvalues={}
|
@@ -3502,12 +3535,16 @@ class Wolfresults_2D(Element_To_Draw):
|
|
3502
3535
|
else:
|
3503
3536
|
return myvalues,None
|
3504
3537
|
|
3505
|
-
def get_all_values_insidepoly(self,myvect:vector, usemask=True, agglo=True, getxy=False):
|
3538
|
+
def get_all_values_insidepoly(self, myvect:vector, usemask:bool= True, agglo:bool= True, getxy:bool= False):
|
3506
3539
|
"""
|
3507
3540
|
Récupération de toutes les valeurs dans un polygone
|
3508
3541
|
|
3509
|
-
|
3510
|
-
|
3542
|
+
:param myvect: polygone
|
3543
|
+
:param usemask: (optional) restreint les éléments aux éléments non masqués de la matrice
|
3544
|
+
:param agglo: (optional) agglomère le résultat en une seule liste plutôt que d'avoir autant de liste que de blocs
|
3545
|
+
:param getxy: (optional) retourne en plus les coordonnées des points
|
3546
|
+
|
3547
|
+
:return: valeurs, coordonnées des points (si getxy=True)
|
3511
3548
|
"""
|
3512
3549
|
|
3513
3550
|
myvalues={}
|
@@ -3532,14 +3569,19 @@ class Wolfresults_2D(Element_To_Draw):
|
|
3532
3569
|
else:
|
3533
3570
|
return myvalues
|
3534
3571
|
|
3535
|
-
def get_all_values_underpoly(self,myvect:vector, usemask=True, agglo=True, getxy=False, integrate_q = False):
|
3572
|
+
def get_all_values_underpoly(self,myvect:vector, usemask:bool= True, agglo:bool= True, getxy:bool= False, integrate_q:bool = False):
|
3536
3573
|
"""
|
3537
|
-
Récupération de toutes les valeurs sous la polyligne
|
3574
|
+
Récupération de toutes les valeurs sous la polyligne.
|
3575
|
+
|
3538
3576
|
Les valeurs retrounées sont identiques à la fonction "get_values_from_xy" soit (h,qx,qy,vx,vy,vabs,fr,h+top,top),(i+1,j+1,curblock.idx+1)
|
3539
3577
|
|
3540
|
-
|
3541
|
-
|
3542
|
-
|
3578
|
+
:param myvect: polygone
|
3579
|
+
:param usemask :(optional) restreint les éléments aux éléments non masqués de la matrice
|
3580
|
+
:param getxy: (optional) retourne en plus les coordonnées des points
|
3581
|
+
:param agglo: (optional) agglomère le résultat en une seule liste plutôt que d'avoir autant de liste que de blocs
|
3582
|
+
:param integrate_q: (optional) pour intégrer les débits
|
3583
|
+
|
3584
|
+
:return: valeurs, coordonnées des points (si getxy=True)
|
3543
3585
|
"""
|
3544
3586
|
myvalues={}
|
3545
3587
|
mypoints = self.get_xy_under_polyline(myvect)
|
@@ -3878,17 +3920,96 @@ class Wolfresults_2D(Element_To_Draw):
|
|
3878
3920
|
|
3879
3921
|
return fig,ax
|
3880
3922
|
|
3881
|
-
def
|
3923
|
+
def plot_q_wx(self,
|
3924
|
+
vect:Union[vector, list[vector]],
|
3925
|
+
x_or_y:Union[str, list[str]] = 'border',
|
3926
|
+
toshow=False,
|
3927
|
+
absolute=True,
|
3928
|
+
fig:Matplotlib_Figure = None):
|
3882
3929
|
"""
|
3883
|
-
Plot
|
3930
|
+
Plot discharge along vector
|
3884
3931
|
|
3885
|
-
:param
|
3886
|
-
:param
|
3932
|
+
:param vector : wolf polyline -- will be splitted according to spatial step size
|
3933
|
+
:param x_or_y : 'x' for qx, 'y' for qy - integration axis or 'border' for q normal at border
|
3887
3934
|
:param toshow : show the plot
|
3935
|
+
:param absolute : plot absolute value of discharge
|
3888
3936
|
:param figax : tuple of matplotlib figure and axis
|
3889
3937
|
|
3890
3938
|
"""
|
3891
3939
|
|
3940
|
+
nb = self.get_nbresults()
|
3941
|
+
times, steps = self.times, self.timesteps
|
3942
|
+
|
3943
|
+
if fig is None:
|
3944
|
+
fig:Matplotlib_Figure
|
3945
|
+
else:
|
3946
|
+
assert isinstance(fig, Matplotlib_Figure), 'Expected a WOLF Matplotlib_Figure'
|
3947
|
+
|
3948
|
+
if isinstance(vect, vector):
|
3949
|
+
assert x_or_y in ['x', 'y', 'border'], 'x_or_y must be "x", "y" or "border"'
|
3950
|
+
|
3951
|
+
q=[]
|
3952
|
+
for i in tqdm(range(nb)):
|
3953
|
+
self.read_oneresult(i)
|
3954
|
+
if x_or_y in ['x', 'y']:
|
3955
|
+
q.append(self._plot_one_q(vect, x_or_y, absolute))
|
3956
|
+
elif x_or_y == 'border':
|
3957
|
+
if i==0:
|
3958
|
+
myhead = self.get_header_block(1)
|
3959
|
+
vect_raster = myhead.rasterize_vector(vect)
|
3960
|
+
q.append(self._plot_one_q_raster_splitting(vect_raster, absolute, to_rasterize = False))
|
3961
|
+
|
3962
|
+
fig.plot(times,q, c='blue', label=vect.myname)
|
3963
|
+
|
3964
|
+
else:
|
3965
|
+
|
3966
|
+
assert len(vect) == len(x_or_y), 'Exepected same length for vect and x_or_y'
|
3967
|
+
for cur in x_or_y:
|
3968
|
+
assert cur in ['x', 'y', 'border'], 'x_or_y must be "x", "y" or "border"'
|
3969
|
+
|
3970
|
+
q={int:list}
|
3971
|
+
vect_raster = []
|
3972
|
+
myhead = self.get_header_block(1)
|
3973
|
+
|
3974
|
+
for i in range(len(vect)):
|
3975
|
+
q[i]= []
|
3976
|
+
if x_or_y[i] == 'border':
|
3977
|
+
vect_raster.append(myhead.rasterize_vector(vect[i]))
|
3978
|
+
|
3979
|
+
for i in tqdm(range(nb)):
|
3980
|
+
self.read_oneresult(i)
|
3981
|
+
|
3982
|
+
for idx, (curvec, orient) in enumerate(zip(vect, x_or_y)):
|
3983
|
+
|
3984
|
+
if orient in ['x', 'y']:
|
3985
|
+
q[idx].append(self._plot_one_q(curvec, orient, absolute))
|
3986
|
+
elif orient == 'border':
|
3987
|
+
cur_vect_raster = vect_raster[idx]
|
3988
|
+
q[idx].append(self._plot_one_q_raster_splitting(cur_vect_raster, absolute, to_rasterize = False))
|
3989
|
+
|
3990
|
+
for i in range(len(vect)):
|
3991
|
+
fig.plot(times,q[i], label=vect[i].myname)
|
3992
|
+
|
3993
|
+
fig.cur_ax.set_xlabel(_('Time [s]'))
|
3994
|
+
fig.cur_ax.set_ylabel(_('Discharge/Flow rate [$m^3s^{-1}$]'))
|
3995
|
+
fig.cur_ax.legend(loc=2)
|
3996
|
+
|
3997
|
+
if toshow:
|
3998
|
+
fig.Show()
|
3999
|
+
|
4000
|
+
return fig
|
4001
|
+
|
4002
|
+
def get_values_xyorpoly_depr(self, xy:Union[list[float], vector], h_or_z:Literal['h', 'z', 'head']):
|
4003
|
+
"""
|
4004
|
+
** DEPRECATED : Will be removed in future version -- Please use get_values_xyorpoly instead **
|
4005
|
+
|
4006
|
+
Get water depth at one or multiple coordinates
|
4007
|
+
|
4008
|
+
:param xy : list of coordinates
|
4009
|
+
:param h_or_z : 'h' for water depth, 'z' for bed elevation, 'head' for water head
|
4010
|
+
|
4011
|
+
"""
|
4012
|
+
|
3892
4013
|
nb = self.get_nbresults(force_update_timessteps=True)
|
3893
4014
|
times, steps = self.times, self.timesteps
|
3894
4015
|
|
@@ -3937,6 +4058,23 @@ class Wolfresults_2D(Element_To_Draw):
|
|
3937
4058
|
|
3938
4059
|
vals.append(values)
|
3939
4060
|
|
4061
|
+
return times, steps, vals, label, label_y
|
4062
|
+
|
4063
|
+
def plot_h(self, xy:Union[list[float], vector], h_or_z:Literal['h', 'z', 'head'], toshow=False, figax = None):
|
4064
|
+
"""
|
4065
|
+
**DEPRECATED : Will be removed in future version -- Please use plot_results_mpl instead**
|
4066
|
+
|
4067
|
+
Plot water depth at one or multiple coordinates
|
4068
|
+
|
4069
|
+
:param xy : list of coordinates
|
4070
|
+
:param h_or_z : 'h' for water depth, 'z' for bed elevation, 'head' for water head
|
4071
|
+
:param toshow : show the plot
|
4072
|
+
:param figax : tuple of matplotlib figure and axis
|
4073
|
+
|
4074
|
+
"""
|
4075
|
+
|
4076
|
+
times, steps, vals, legend, label_y = self.get_values_xyorpoly_depr(xy, h_or_z)
|
4077
|
+
|
3940
4078
|
if figax is None:
|
3941
4079
|
fig, ax = plt.subplots()
|
3942
4080
|
else:
|
@@ -3950,9 +4088,9 @@ class Wolfresults_2D(Element_To_Draw):
|
|
3950
4088
|
min.append(curvals.min())
|
3951
4089
|
max.append(curvals.max())
|
3952
4090
|
|
3953
|
-
ax.plot(times, means, label=_('Mean value - {}'.format(
|
3954
|
-
ax.plot(times, min, label=_('Min value - {}'.format(
|
3955
|
-
ax.plot(times, max, label=_('Max value - {}'.format(
|
4091
|
+
ax.plot(times, means, label=_('Mean value - {}'.format(legend)))
|
4092
|
+
ax.plot(times, min, label=_('Min value - {}'.format(legend)))
|
4093
|
+
ax.plot(times, max, label=_('Max value - {}'.format(legend)))
|
3956
4094
|
|
3957
4095
|
ax.set_xlabel(_('Time [s]'))
|
3958
4096
|
ax.set_ylabel(label_y)
|
@@ -3964,11 +4102,332 @@ class Wolfresults_2D(Element_To_Draw):
|
|
3964
4102
|
|
3965
4103
|
return fig,ax
|
3966
4104
|
|
3967
|
-
def
|
4105
|
+
def get_all_values_xyorpoly_series(self, xy:Union[list[float], vector], for_steps:tuple[int] | list[int] = (0,-1,1)):
|
3968
4106
|
"""
|
3969
|
-
|
4107
|
+
Get water depth at one or multiple coordinates.
|
3970
4108
|
|
3971
|
-
|
4109
|
+
:param xy : list of coordinates
|
4110
|
+
:param for_steps : tuple of start, end and step -- 0-based -- default is all steps (0,-1,1)
|
4111
|
+
|
4112
|
+
:return: (times, steps), values -- numpy arrays
|
4113
|
+
"""
|
4114
|
+
|
4115
|
+
assert isinstance(xy, vector) or isinstance(xy, list), 'Expected a vector or a list of coordinates'
|
4116
|
+
if isinstance(for_steps, tuple):
|
4117
|
+
assert len(for_steps) == 3, 'Expected a tuple of 3 integers -- start, end and step'
|
4118
|
+
else:
|
4119
|
+
assert isinstance(for_steps, list), 'Expected a list of integers'
|
4120
|
+
|
4121
|
+
# Récupération du nombre de résultats
|
4122
|
+
nb = self.get_nbresults(force_update_timessteps=True)
|
4123
|
+
|
4124
|
+
# Définition des bornes -- tests de validité
|
4125
|
+
if isinstance(for_steps, tuple):
|
4126
|
+
first, last, step = for_steps
|
4127
|
+
|
4128
|
+
if last == -1:
|
4129
|
+
last = nb
|
4130
|
+
|
4131
|
+
assert last > first, 'Expected end step greater than start step'
|
4132
|
+
|
4133
|
+
if first < 0:
|
4134
|
+
first = 0
|
4135
|
+
if last > nb:
|
4136
|
+
last = nb
|
4137
|
+
|
4138
|
+
all_steps = np.arange(0, nb, step)
|
4139
|
+
if step > 1 and last < nb:
|
4140
|
+
if all_steps[-1] != last:
|
4141
|
+
all_steps = np.append(all_steps, last)
|
4142
|
+
|
4143
|
+
else:
|
4144
|
+
all_steps = list(set(for_steps))
|
4145
|
+
all_steps.sort()
|
4146
|
+
|
4147
|
+
filter(lambda x: x >= 0 and x < nb, all_steps)
|
4148
|
+
|
4149
|
+
# Récupération des temps et des pas
|
4150
|
+
times = np.asarray([self.times[i] for i in all_steps])
|
4151
|
+
steps = np.asarray([self.timesteps[i] for i in all_steps])
|
4152
|
+
|
4153
|
+
pg_bar = None
|
4154
|
+
if self.wx_exists:
|
4155
|
+
pg_bar = wx.ProgressDialog(_('Extracting values'), _('Extracting values for each step'), len(all_steps)-1, style=wx.PD_ELAPSED_TIME | wx.PD_REMAINING_TIME | wx.PD_AUTO_HIDE)
|
4156
|
+
|
4157
|
+
# extraction des valeurs pour chaque pas de temps souhaité
|
4158
|
+
tmp_vals=[]
|
4159
|
+
if isinstance(xy, vector):
|
4160
|
+
|
4161
|
+
for i, curstep in tqdm(enumerate(all_steps)):
|
4162
|
+
self.read_oneresult(curstep)
|
4163
|
+
locvals = self.get_all_values_insidepoly(xy, getxy= False)
|
4164
|
+
|
4165
|
+
if pg_bar:
|
4166
|
+
pg_bar.Update(i)
|
4167
|
+
|
4168
|
+
vals = []
|
4169
|
+
for values in locvals:
|
4170
|
+
vals.append(np.asarray([cur for cur in values.T[0]]))
|
4171
|
+
|
4172
|
+
tmp_vals.append(vals)
|
4173
|
+
|
4174
|
+
else:
|
4175
|
+
for i, curstep in tqdm(enumerate(all_steps)):
|
4176
|
+
self.read_oneresult(curstep)
|
4177
|
+
|
4178
|
+
tmp_vals.append([self.get_values_from_xy(x,y)[0] for x,y in xy])
|
4179
|
+
|
4180
|
+
if pg_bar:
|
4181
|
+
pg_bar.Update(i)
|
4182
|
+
|
4183
|
+
return (times, steps), tmp_vals
|
4184
|
+
|
4185
|
+
def get_values_xyorpoly_series(self, xy:Union[list[float], vector], which:Extractable_results, for_steps:tuple[int] | list[int] = (0,-1,1)):
|
4186
|
+
"""
|
4187
|
+
Get water depth at one or multiple coordinates.
|
4188
|
+
|
4189
|
+
:param xy : list of coordinates
|
4190
|
+
:param which : which results to plot -- see Extractable_results Enum
|
4191
|
+
:param for_steps : tuple of start, end and step -- 0-based -- default is all steps (0,-1,1)
|
4192
|
+
|
4193
|
+
:return: (times, steps), values -- numpy arrays
|
4194
|
+
"""
|
4195
|
+
|
4196
|
+
assert which in Extractable_results, 'Expected a valid Extractable_results'
|
4197
|
+
assert isinstance(xy, vector) or isinstance(xy, list), 'Expected a vector or a list of coordinates'
|
4198
|
+
if isinstance(for_steps, tuple):
|
4199
|
+
assert len(for_steps) == 3, 'Expected a tuple of 3 integers -- start, end and step'
|
4200
|
+
else:
|
4201
|
+
assert isinstance(for_steps, list), 'Expected a list of integers'
|
4202
|
+
|
4203
|
+
(times, steps), tmp_vals = self.get_all_values_xyorpoly_series(xy, for_steps)
|
4204
|
+
|
4205
|
+
vals = []
|
4206
|
+
if which in ER_DIRECT_ACCESS:
|
4207
|
+
idx = which.value[1]
|
4208
|
+
for step in tmp_vals:
|
4209
|
+
vals.append(np.asarray([node[idx] for node in step]))
|
4210
|
+
elif which == Extractable_results.HEAD:
|
4211
|
+
for step in tmp_vals:
|
4212
|
+
vals.append(np.asarray([node[7]+node[5]**2./2/9.81 for node in step]))
|
4213
|
+
|
4214
|
+
return (times, steps), vals
|
4215
|
+
|
4216
|
+
def plot_some_values(self, xy:Union[list[float], vector], which:Extractable_results, toshow=False, figax = None, for_steps:tuple[int] | list[int] = (0,-1,1), x_axis:Literal['time', 'step'] = 'time'):
|
4217
|
+
"""
|
4218
|
+
Plot some results at one or multiple coordinates defined by a vector or a list of coordinates
|
4219
|
+
or a polygon
|
4220
|
+
|
4221
|
+
:param xy : list of coordinates or vector
|
4222
|
+
:param which : which results to plot -- see Extractable_results Enum
|
4223
|
+
:param toshow : show the plot
|
4224
|
+
:param figax : tuple of matplotlib figure and axis
|
4225
|
+
:param for_steps : tuple of start, end and step -- 0-based -- default is all steps (0,-1,1)
|
4226
|
+
|
4227
|
+
"""
|
4228
|
+
|
4229
|
+
assert which in Extractable_results, 'Expected a valid Extractable_results'
|
4230
|
+
assert x_axis in ['time', 'step'], 'Expected "time" or "step" for x_axis'
|
4231
|
+
|
4232
|
+
(times, steps), vals = self.get_values_xyorpoly_series(xy, which, for_steps)
|
4233
|
+
|
4234
|
+
means= []
|
4235
|
+
median = []
|
4236
|
+
min = []
|
4237
|
+
max = []
|
4238
|
+
for curvals in vals:
|
4239
|
+
means.append(curvals.mean())
|
4240
|
+
median.append(np.median(curvals))
|
4241
|
+
min.append(curvals.min())
|
4242
|
+
max.append(curvals.max())
|
4243
|
+
|
4244
|
+
legend = xy.myname if isinstance(xy, vector) else _('Selected nodes')
|
4245
|
+
|
4246
|
+
x_label = _('Time [s]') if x_axis == 'time' else _('Step [-]')
|
4247
|
+
|
4248
|
+
if isinstance(figax, Matplotlib_Figure):
|
4249
|
+
fig, ax = figax.get_figax()
|
4250
|
+
|
4251
|
+
if x_axis == 'time':
|
4252
|
+
figax.plot(times, means, label=_('Mean value - {}'.format(legend)))
|
4253
|
+
figax.plot(times, median, label=_('Median value - {}'.format(legend)))
|
4254
|
+
figax.plot(times, min, label=_('Min value - {}'.format(legend)))
|
4255
|
+
figax.plot(times, max, label=_('Max value - {}'.format(legend)))
|
4256
|
+
|
4257
|
+
elif x_axis == 'step':
|
4258
|
+
figax.plot(steps, means, label=_('Mean value - {}'.format(legend)))
|
4259
|
+
figax.plot(steps, median, label=_('Median value - {}'.format(legend)))
|
4260
|
+
figax.plot(steps, min, label=_('Min value - {}'.format(legend)))
|
4261
|
+
figax.plot(steps, max, label=_('Max value - {}'.format(legend)))
|
4262
|
+
|
4263
|
+
figax.cur_ax.set_xlabel(x_label)
|
4264
|
+
figax.cur_ax.set_ylabel(which.value[0])
|
4265
|
+
|
4266
|
+
else:
|
4267
|
+
if figax is None:
|
4268
|
+
fig, ax = plt.subplots()
|
4269
|
+
else:
|
4270
|
+
fig, ax = figax
|
4271
|
+
|
4272
|
+
if x_axis == 'time':
|
4273
|
+
ax.plot(times, means, label=_('Mean value - {}'.format(legend)))
|
4274
|
+
ax.plot(times, median, label=_('Median value - {}'.format(legend)))
|
4275
|
+
ax.plot(times, min, label=_('Min value - {}'.format(legend)))
|
4276
|
+
ax.plot(times, max, label=_('Max value - {}'.format(legend)))
|
4277
|
+
elif x_axis == 'step':
|
4278
|
+
ax.plot(steps, means, label=_('Mean value - {}'.format(legend)))
|
4279
|
+
ax.plot(steps, median, label=_('Median value - {}'.format(legend)))
|
4280
|
+
ax.plot(steps, min, label=_('Min value - {}'.format(legend)))
|
4281
|
+
ax.plot(steps, max, label=_('Max value - {}'.format(legend)))
|
4282
|
+
|
4283
|
+
ax.set_xlabel(x_label)
|
4284
|
+
ax.set_ylabel(which.value[0])
|
4285
|
+
|
4286
|
+
fig.tight_layout()
|
4287
|
+
|
4288
|
+
if toshow:
|
4289
|
+
fig.show()
|
4290
|
+
|
4291
|
+
return fig,ax
|
4292
|
+
|
4293
|
+
def plot_violin_values(self, xy:Union[list[float], vector], which:Extractable_results, toshow=False, figax = None, for_steps:tuple[int] | list[int] = (0,-1,1), x_axis:Literal['time', 'step'] = 'time'):
|
4294
|
+
"""
|
4295
|
+
Plot some results at one or multiple coordinates defined by a vector or a list of coordinates
|
4296
|
+
or a polygon
|
4297
|
+
|
4298
|
+
:param xy : list of coordinates or vector
|
4299
|
+
:param which : which results to plot -- see Extractable_results Enum
|
4300
|
+
:param toshow : show the plot
|
4301
|
+
:param figax : tuple of matplotlib figure and axis
|
4302
|
+
:param for_steps : tuple of start, end and step -- 0-based -- default is all steps (0,-1,1)
|
4303
|
+
|
4304
|
+
"""
|
4305
|
+
|
4306
|
+
assert which in Extractable_results, 'Expected a valid Extractable_results'
|
4307
|
+
assert x_axis in ['time', 'step'], 'Expected "time" or "step" for x_axis'
|
4308
|
+
|
4309
|
+
(times, steps), vals = self.get_values_xyorpoly_series(xy, which, for_steps)
|
4310
|
+
|
4311
|
+
legend = xy.myname if isinstance(xy, vector) else _('Selected nodes')
|
4312
|
+
|
4313
|
+
x_label = _('Time [s]') if x_axis == 'time' else _('Step [-]')
|
4314
|
+
|
4315
|
+
if isinstance(figax, Matplotlib_Figure):
|
4316
|
+
fig, ax = figax.get_figax()
|
4317
|
+
|
4318
|
+
if x_axis == 'time':
|
4319
|
+
figax.violinplot(vals)
|
4320
|
+
|
4321
|
+
elif x_axis == 'step':
|
4322
|
+
figax.violinplot(vals)
|
4323
|
+
|
4324
|
+
figax.cur_ax.set_xlabel(x_label)
|
4325
|
+
figax.cur_ax.set_ylabel(which.value[0])
|
4326
|
+
|
4327
|
+
else:
|
4328
|
+
if figax is None:
|
4329
|
+
fig, ax = plt.subplots()
|
4330
|
+
else:
|
4331
|
+
fig, ax = figax
|
4332
|
+
|
4333
|
+
if x_axis == 'time':
|
4334
|
+
ax.violinplot(vals)
|
4335
|
+
elif x_axis == 'step':
|
4336
|
+
ax.violinplot(vals)
|
4337
|
+
|
4338
|
+
ax.set_xlabel(x_label)
|
4339
|
+
ax.set_ylabel(which.value[0])
|
4340
|
+
|
4341
|
+
fig.tight_layout()
|
4342
|
+
|
4343
|
+
if toshow:
|
4344
|
+
fig.show()
|
4345
|
+
|
4346
|
+
return fig,ax
|
4347
|
+
|
4348
|
+
def export_some_values_to_csv(self, xy:Union[list[float], vector],
|
4349
|
+
which:Extractable_results,
|
4350
|
+
filename: str | Path,
|
4351
|
+
for_steps:tuple[int] | list[int] = (0,-1,1),
|
4352
|
+
erase_if_exists:bool = True,
|
4353
|
+
only_stats:bool = True):
|
4354
|
+
""" Export some results at one or multiple coordinates defined by a vector or a list of coordinates
|
4355
|
+
or a polygon as CSV file
|
4356
|
+
"""
|
4357
|
+
|
4358
|
+
assert which in Extractable_results, 'Expected a valid Extractable_results'
|
4359
|
+
|
4360
|
+
filename = Path(filename)
|
4361
|
+
filename = filename.with_suffix('.csv')
|
4362
|
+
|
4363
|
+
if erase_if_exists and filename.exists():
|
4364
|
+
filename.unlink()
|
4365
|
+
|
4366
|
+
(times, steps), vals = self.get_values_xyorpoly_series(xy, which, for_steps)
|
4367
|
+
|
4368
|
+
mean= []
|
4369
|
+
median = []
|
4370
|
+
min = []
|
4371
|
+
max = []
|
4372
|
+
for curvals in vals:
|
4373
|
+
curvals:np.ndarray
|
4374
|
+
mean.append(curvals.mean())
|
4375
|
+
median.append(np.median(curvals))
|
4376
|
+
min.append(curvals.min())
|
4377
|
+
max.append(curvals.max())
|
4378
|
+
|
4379
|
+
with open(filename.with_stem(filename.stem + '_stats'), 'a') as f:
|
4380
|
+
if isinstance(xy, list):
|
4381
|
+
f.write(_('Selected nodes') + '\n')
|
4382
|
+
f.write('X [m]\tY [m]'+ '\n')
|
4383
|
+
for cur in xy:
|
4384
|
+
f.write(f'{cur[0]}\t{cur[1]}\n')
|
4385
|
+
|
4386
|
+
f.write('\n\n')
|
4387
|
+
|
4388
|
+
f.write(f'{which.value[0]}\n')
|
4389
|
+
|
4390
|
+
columns = [_('Time [s]'), _('Step [-]'), _('Average'), _('Median'), _('Minimum'), _('Maximum')]
|
4391
|
+
f.write('\t'.join(columns) + '\n')
|
4392
|
+
|
4393
|
+
for i in range(len(times)):
|
4394
|
+
f.write(f'{times[i]}\t{steps[i]}\t{mean[i]}\t{median[i]}\t{min[i]}\t{max[i]}\n')
|
4395
|
+
|
4396
|
+
if not only_stats:
|
4397
|
+
|
4398
|
+
with open(filename, 'a') as f:
|
4399
|
+
if isinstance(xy, list):
|
4400
|
+
f.write(_('Selected nodes'))
|
4401
|
+
f.write('X [m]\tY [m]')
|
4402
|
+
for cur in xy:
|
4403
|
+
f.write(f'{cur[0]}\t{cur[1]}')
|
4404
|
+
|
4405
|
+
f.write('\n')
|
4406
|
+
|
4407
|
+
f.write(f'Time [s]\tStep [-]\t{which.value[0]}\n')
|
4408
|
+
|
4409
|
+
for i in range(len(times)):
|
4410
|
+
f.write(f'{times[i]}\t{steps[i]}\t{vals[i]}\n')
|
4411
|
+
|
4412
|
+
return True
|
4413
|
+
|
4414
|
+
def get_values_from_xy(self, x:float, y:float, aswolf:bool = True, integrate_q:bool = False):
|
4415
|
+
"""
|
4416
|
+
Retrouve les valeurs sur base de la coordonnée (x,y).
|
4417
|
+
|
4418
|
+
Les valeurs retournées sont (h,qx,qy,vx,vy,vabs,fr,h+top,top), (i+1,j+1,curblock.idx+1)
|
4419
|
+
|
4420
|
+
Si aucun résultat n'existe à l'emplacement souhaité, les valeurs sont (-1,-1,-1,-1,-1,-1,-1),('-','-','-')
|
4421
|
+
|
4422
|
+
Le test de validité est basé sur la valeur de la hauteur d'eau strictement positive et
|
4423
|
+
topographie positive et non égale à 99999.
|
4424
|
+
|
4425
|
+
:param x : coordonnée x
|
4426
|
+
:param y : coordonnée y
|
4427
|
+
:param aswolf : (optional) si True alors ajoute 1 à i et j pour se retrouver en numérotation VB6/Fortran
|
4428
|
+
:param integrate_q : (optional) si True alors intègre le débit sur la maille (multiplie par la taille de maille perpendiculaire au sens du débit)
|
4429
|
+
|
4430
|
+
:return : tuple of values and indices
|
3972
4431
|
"""
|
3973
4432
|
h=-1
|
3974
4433
|
qx=-1
|
@@ -3985,12 +4444,12 @@ class Wolfresults_2D(Element_To_Draw):
|
|
3985
4444
|
qx = curblock.qx.array[i,j]
|
3986
4445
|
qy = curblock.qy.array[i,j]
|
3987
4446
|
|
3988
|
-
exists = top>0.
|
4447
|
+
exists = top > 0. and top != 99999.
|
3989
4448
|
|
3990
4449
|
if(h>0.):
|
3991
4450
|
vx = qx/h
|
3992
4451
|
vy = qy/h
|
3993
|
-
vabs=(vx**2
|
4452
|
+
vabs=(vx**2. + vy**2.)**.5
|
3994
4453
|
fr = vabs/(9.81*h)**.5
|
3995
4454
|
exists=True
|
3996
4455
|
|
@@ -4043,6 +4502,10 @@ class Wolfresults_2D(Element_To_Draw):
|
|
4043
4502
|
def get_value(self, x:float, y:float, nullvalue=-1):
|
4044
4503
|
"""
|
4045
4504
|
Return the value of the current array at (X,Y) position
|
4505
|
+
|
4506
|
+
:param x: x coordinate
|
4507
|
+
:param y: y coordinate
|
4508
|
+
:param nullvalue: value to return if no value is found
|
4046
4509
|
"""
|
4047
4510
|
h=-1
|
4048
4511
|
exists=False
|