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.
@@ -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 myvalues : valeurs des mailles
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
- usemask (optional) restreint les éléments aux éléments non masqués de la matrice
3510
- getxy (optional) retourne en plus les coordonnées des points
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
- usemask (optional) restreint les éléments aux éléments non masqués de la matrice
3541
- getxy (optional) retourne en plus les coordonnées des points
3542
- agglo (optional) agglomère le résultat en une seule liste plutôt que d'avoir autant de liste que de blocs
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 plot_h(self, xy:Union[list[float], vector], h_or_z:Literal['h', 'z', 'head'], toshow=False, figax = None):
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 water depth at one or multiple coordinates
3930
+ Plot discharge along vector
3884
3931
 
3885
- :param xy : list of coordinates
3886
- :param h_or_z : 'h' for water depth, 'z' for bed elevation, 'head' for water head
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(label)))
3954
- ax.plot(times, min, label=_('Min value - {}'.format(label)))
3955
- ax.plot(times, max, label=_('Max value - {}'.format(label)))
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 get_values_from_xy(self, x:float, y:float, aswolf=True, integrate_q = False):
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
- Retrouve les valeurs sur base de la coordonnée (x,y)
4107
+ Get water depth at one or multiple coordinates.
3970
4108
 
3971
- aswolf : (optional) si True alors ajoute 1 à i et j pour se retrouver en numérotation VB6/Fortran
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.+vy**2.)**.5
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: wolfhece
3
- Version: 2.1.118
3
+ Version: 2.1.120
4
4
  Author-email: Pierre Archambeau <pierre.archambeau@uliege.be>
5
5
  License: Copyright (c) 2024 University of Liege. All rights reserved.
6
6
  Project-URL: Homepage, https://uee.uliege.be/hece