wolfhece 2.2.16__py3-none-any.whl → 2.2.18__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 +104 -14
- wolfhece/PyGui.py +6 -0
- wolfhece/PyParams.py +29 -0
- wolfhece/PyVertexvectors.py +191 -19
- wolfhece/Results2DGPU.py +9 -0
- wolfhece/analyze_poly.py +335 -0
- wolfhece/apps/version.py +1 -1
- wolfhece/assets/mesh.py +128 -6
- wolfhece/hydrometry/kiwis_wolfgui.py +7 -8
- wolfhece/lazviewer/__init__.py +21 -12
- wolfhece/mesh2d/bc_manager.py +1 -1
- wolfhece/mesh2d/gpu_2d.py +46 -10
- wolfhece/mesh2d/wolf2dprev.py +12 -0
- wolfhece/os_check.py +16 -0
- wolfhece/pydike.py +245 -41
- wolfhece/tools2d_dll.py +6 -0
- wolfhece/wolf_array.py +427 -55
- wolfhece/wolf_texture.py +1 -0
- wolfhece/wolfresults_2D.py +578 -195
- {wolfhece-2.2.16.dist-info → wolfhece-2.2.18.dist-info}/METADATA +1 -1
- {wolfhece-2.2.16.dist-info → wolfhece-2.2.18.dist-info}/RECORD +24 -22
- {wolfhece-2.2.16.dist-info → wolfhece-2.2.18.dist-info}/WHEEL +1 -1
- {wolfhece-2.2.16.dist-info → wolfhece-2.2.18.dist-info}/entry_points.txt +0 -0
- {wolfhece-2.2.16.dist-info → wolfhece-2.2.18.dist-info}/top_level.txt +0 -0
wolfhece/analyze_poly.py
ADDED
@@ -0,0 +1,335 @@
|
|
1
|
+
import logging
|
2
|
+
|
3
|
+
import numpy as np
|
4
|
+
from shapely.geometry import Point, LineString
|
5
|
+
from typing import Literal
|
6
|
+
import pandas as pd
|
7
|
+
|
8
|
+
from .PyTranslate import _
|
9
|
+
from .drawing_obj import Element_To_Draw
|
10
|
+
from .PyVertexvectors import Triangulation, vector,Zones, zone
|
11
|
+
from .wolf_array import WolfArray, header_wolf
|
12
|
+
|
13
|
+
class Array_analysis_onepolygon():
|
14
|
+
""" Class for values analysis of an array based on a polygon.
|
15
|
+
|
16
|
+
This class select values insides a polygon and plot statistics of the values.
|
17
|
+
|
18
|
+
The class is designed to be used with the WolfArray class and the vector class from the PyVertexvectors module.
|
19
|
+
|
20
|
+
Plots of the values distribution can be generated using seaborn or plotly.
|
21
|
+
"""
|
22
|
+
|
23
|
+
def __init__(self, wa:WolfArray, polygon:vector):
|
24
|
+
|
25
|
+
self._wa = wa
|
26
|
+
self._polygon = polygon
|
27
|
+
|
28
|
+
self._selected_cells = None
|
29
|
+
self._values = None
|
30
|
+
|
31
|
+
def values(self, which:Literal['Mean', 'Std', 'Median', 'Sum', 'Volume', 'Values']) -> pd.DataFrame | float:
|
32
|
+
""" Get the values as a pandas DataFrame
|
33
|
+
|
34
|
+
:param which: Mean, Std, Median, Sum, Volume, Values
|
35
|
+
"""
|
36
|
+
|
37
|
+
authrorized = ['Mean', 'Std', 'Median', 'Sum', 'Volume', 'Values']
|
38
|
+
if which not in authrorized:
|
39
|
+
raise ValueError(f"Invalid value for 'which'. Must be one of {authrorized}.")
|
40
|
+
|
41
|
+
if self._values is None:
|
42
|
+
self.compute_values()
|
43
|
+
|
44
|
+
if self._values is None:
|
45
|
+
raise ValueError("No values computed. Please call compute_values() first.")
|
46
|
+
|
47
|
+
if which == 'Values':
|
48
|
+
return pd.DataFrame(self._values[_(which)], columns=[which])
|
49
|
+
else:
|
50
|
+
return self._values[which]
|
51
|
+
|
52
|
+
def select_cells(self, mode:Literal['polygon', 'buffer'] = 'polygon', **kwargs):
|
53
|
+
""" Select the cells inside the polygon """
|
54
|
+
|
55
|
+
if mode == 'polygon':
|
56
|
+
if 'polygon' in kwargs:
|
57
|
+
self._polygon = kwargs['polygon']
|
58
|
+
self._select_cells_polygon(self._polygon)
|
59
|
+
else:
|
60
|
+
raise ValueError("No polygon provided. Please provide a polygon to select cells.")
|
61
|
+
elif mode == 'buffer':
|
62
|
+
if 'buffer' in kwargs:
|
63
|
+
self._select_cells_buffer(kwargs['buffer'])
|
64
|
+
else:
|
65
|
+
raise ValueError("No buffer size provided. Please provide a buffer size to select cells.")
|
66
|
+
else:
|
67
|
+
raise ValueError("Invalid mode. Please use 'polygon' or 'buffer'.")
|
68
|
+
|
69
|
+
def _select_cells_polygon(self, selection_poly:vector):
|
70
|
+
""" Select the cells inside the polygon """
|
71
|
+
|
72
|
+
self._polygon = selection_poly
|
73
|
+
self._selected_cells = self._wa.get_xy_inside_polygon(self._polygon)
|
74
|
+
|
75
|
+
def _select_cells_buffer(self, buffer_size:float = 0.0):
|
76
|
+
""" Select the cells inside the buffer of the polygon """
|
77
|
+
|
78
|
+
self._polygon = self._polygon.buffer(buffer_size, inplace=False)
|
79
|
+
self._selected_cells = self._wa.get_xy_inside_polygon(self._polygon)
|
80
|
+
|
81
|
+
def compute_values(self):
|
82
|
+
""" Get the values of the array inside the polygon """
|
83
|
+
|
84
|
+
if self._selected_cells is None:
|
85
|
+
if self._polygon is None:
|
86
|
+
raise ValueError("No polygon provided. Please provide a polygon to select cells.")
|
87
|
+
|
88
|
+
self._values = self._wa.statistics(self._polygon)
|
89
|
+
|
90
|
+
def plot_values(self, show:bool = True, bins:int = 100,
|
91
|
+
engine:Literal['seaborn', 'plotly'] = 'seaborn'):
|
92
|
+
""" Plot a histogram of the values """
|
93
|
+
|
94
|
+
if engine == 'seaborn':
|
95
|
+
return self.plot_values_seaborn(show=show, bins=bins)
|
96
|
+
elif engine == 'plotly':
|
97
|
+
return self.plot_values_plotly(show=show, bins=bins)
|
98
|
+
|
99
|
+
def plot_values_seaborn(self, bins:int = 100, show:bool = True):
|
100
|
+
""" Plot a histogram of the values """
|
101
|
+
|
102
|
+
import seaborn as sns
|
103
|
+
import matplotlib.pyplot as plt
|
104
|
+
|
105
|
+
fig, ax = plt.subplots()
|
106
|
+
sns.histplot(self.values('Values'), bins=bins,
|
107
|
+
kde=True, ax=ax,
|
108
|
+
stat="density")
|
109
|
+
|
110
|
+
# Add mean, std, median values on plot
|
111
|
+
mean = self.values('Mean')
|
112
|
+
# std = self.values('Std').values[0]
|
113
|
+
median = self.values('Median')
|
114
|
+
|
115
|
+
# test noen and masked value
|
116
|
+
if mean is not None and mean is not np.ma.masked:
|
117
|
+
ax.axvline(mean, color='r', linestyle='--', label=f'Mean: {mean:.2f}')
|
118
|
+
if median is not None and median is not np.ma.masked:
|
119
|
+
ax.axvline(median, color='b', linestyle='--', label=f'Median: {median:.2f}')
|
120
|
+
|
121
|
+
ax.legend()
|
122
|
+
ax.set_xlabel('Values')
|
123
|
+
ax.set_ylabel('Frequency')
|
124
|
+
ax.set_title('Values distribution')
|
125
|
+
|
126
|
+
if show:
|
127
|
+
plt.show()
|
128
|
+
|
129
|
+
return (fig, ax)
|
130
|
+
|
131
|
+
def plot_values_plotly(self, bins:int = 100, show:bool = True):
|
132
|
+
""" Plot a histogram of the values """
|
133
|
+
|
134
|
+
import plotly.express as px
|
135
|
+
|
136
|
+
fig = px.histogram(self.values('Values'), x='Values',
|
137
|
+
nbins=bins, title='Values distribution',
|
138
|
+
histnorm='probability density')
|
139
|
+
|
140
|
+
# Add mean, std, median values on plot
|
141
|
+
mean = self.values('Mean')
|
142
|
+
median = self.values('Median')
|
143
|
+
|
144
|
+
if mean is not None and mean is not np.ma.masked:
|
145
|
+
fig.add_vline(x=mean, line_color='red', line_dash='dash', annotation_text=f'Mean: {mean:.2f}')
|
146
|
+
if median is not None and median is not np.ma.masked:
|
147
|
+
fig.add_vline(x=median, line_color='blue', line_dash='dash', annotation_text=f'Median: {median:.2f}')
|
148
|
+
|
149
|
+
fig.update_layout(xaxis_title='Values', yaxis_title='Frequency')
|
150
|
+
|
151
|
+
if show:
|
152
|
+
fig.show(renderer='browser')
|
153
|
+
|
154
|
+
return fig
|
155
|
+
|
156
|
+
|
157
|
+
class Array_analysis_polygons():
|
158
|
+
""" Class for values analysis of an array based on a polygon.
|
159
|
+
|
160
|
+
This class select values insides a polygon and plot statistics of the values.
|
161
|
+
|
162
|
+
The class is designed to be used with the WolfArray class and the vector class from the PyVertexvectors module.
|
163
|
+
|
164
|
+
Plots of the values distribution can be generated using seaborn or plotly.
|
165
|
+
"""
|
166
|
+
|
167
|
+
def __init__(self, wa:WolfArray, polygons:zone):
|
168
|
+
""" Initialize the class with a WolfArray and a zone of polygons """
|
169
|
+
|
170
|
+
self._wa = wa
|
171
|
+
self._polygons = polygons
|
172
|
+
|
173
|
+
self._zone = {polygon.myname: Array_analysis_onepolygon(self._wa, polygon) for polygon in self._polygons.myvectors}
|
174
|
+
|
175
|
+
def __getitem__(self, key):
|
176
|
+
""" Get the polygon by name """
|
177
|
+
if key in self._zone:
|
178
|
+
return self._zone[key]
|
179
|
+
else:
|
180
|
+
raise KeyError(f"Polygon {key} not found in zone.")
|
181
|
+
|
182
|
+
def plot_values(self, show:bool = True, bins:int = 100,
|
183
|
+
engine:Literal['seaborn', 'plotly'] = 'seaborn'):
|
184
|
+
""" Plot a histogram of the values """
|
185
|
+
|
186
|
+
if engine == 'seaborn':
|
187
|
+
return self.plot_values_seaborn(show=show, bins=bins)
|
188
|
+
elif engine == 'plotly':
|
189
|
+
return self.plot_values_plotly(show=show, bins=bins)
|
190
|
+
|
191
|
+
def plot_values_seaborn(self, bins:int = 100, show:bool = True):
|
192
|
+
""" Plot a histogram of the values """
|
193
|
+
return {key: pol.plot_values_seaborn(bins=bins, show=show) for key, pol in self._zone.items()}
|
194
|
+
|
195
|
+
def plot_values_plotly(self, bins:int = 100, show:bool = True):
|
196
|
+
""" Plot a histogram of the values """
|
197
|
+
|
198
|
+
return {key: pol.plot_values_plotly(bins=bins, show=show) for key, pol in self._zone.items()}
|
199
|
+
|
200
|
+
class Slope_analysis:
|
201
|
+
""" Class for slope analysis of in an array based on a trace vector.
|
202
|
+
|
203
|
+
This class allows to select cells inside a polygon or a buffer around a trace vector
|
204
|
+
and compute the slope of the dike. The slope is computed as the difference in elevation
|
205
|
+
between the trace and the cell divided by the distance to the trace.
|
206
|
+
|
207
|
+
The slope is computed for each cell inside the polygon or buffer and accessed in a Pandas Dataframe.
|
208
|
+
|
209
|
+
Plots of the slope distribution can be generated using seaborn or plotly.
|
210
|
+
|
211
|
+
The class is designed to be used with the WolfArray class and the vector class from the PyVertexvectors module.
|
212
|
+
"""
|
213
|
+
|
214
|
+
def __init__(self, wa:WolfArray, trace:vector):
|
215
|
+
|
216
|
+
self._wa = wa
|
217
|
+
self._trace = trace
|
218
|
+
|
219
|
+
self._selection_poly = None
|
220
|
+
self._buffer_size = 0.0
|
221
|
+
|
222
|
+
self._selected_cells = None
|
223
|
+
self._slopes = None
|
224
|
+
|
225
|
+
@property
|
226
|
+
def slopes(self) -> pd.DataFrame:
|
227
|
+
""" Get the slopes as a pandas DataFrame """
|
228
|
+
|
229
|
+
if self._slopes is None:
|
230
|
+
self.compute_slopes()
|
231
|
+
|
232
|
+
if self._slopes is None:
|
233
|
+
raise ValueError("No slopes computed. Please call compute_slopes() first.")
|
234
|
+
|
235
|
+
return pd.DataFrame(self._slopes, columns=['Slope [m/m]'])
|
236
|
+
|
237
|
+
def select_cells(self, mode:Literal['polygon', 'buffer'] = 'polygon', **kwargs):
|
238
|
+
""" Select the cells inside the trace """
|
239
|
+
|
240
|
+
if mode == 'polygon':
|
241
|
+
if 'polygon' in kwargs:
|
242
|
+
self._selection_poly = kwargs['polygon']
|
243
|
+
self._select_cells_polygon(self._selection_poly)
|
244
|
+
else:
|
245
|
+
raise ValueError("No polygon provided. Please provide a polygon to select cells.")
|
246
|
+
elif mode == 'buffer':
|
247
|
+
if 'buffer' in kwargs:
|
248
|
+
self._buffer_size = kwargs['buffer']
|
249
|
+
self._select_cells_buffer(self._buffer_size)
|
250
|
+
else:
|
251
|
+
raise ValueError("No buffer size provided. Please provide a buffer size to select cells.")
|
252
|
+
else:
|
253
|
+
raise ValueError("Invalid mode. Please use 'polygon' or 'buffer'.")
|
254
|
+
|
255
|
+
def _select_cells_buffer(self, buffer_size:float = 0.0):
|
256
|
+
""" Select the cells inside the buffer of the trace """
|
257
|
+
|
258
|
+
self._buffer_size = buffer_size
|
259
|
+
self._selection_poly = self._trace.buffer(self._buffer_size, inplace=False)
|
260
|
+
self._select_cells_polygon(self._selection_poly)
|
261
|
+
|
262
|
+
def _select_cells_polygon(self, selection_poly:vector):
|
263
|
+
""" Select the cells inside the polygon """
|
264
|
+
|
265
|
+
self._selection_poly = selection_poly
|
266
|
+
self._selected_cells = self._wa.get_xy_inside_polygon(self._selection_poly)
|
267
|
+
|
268
|
+
def compute_slopes(self):
|
269
|
+
""" Get the slope of the dike """
|
270
|
+
|
271
|
+
if self._selected_cells is None:
|
272
|
+
self.select_cells()
|
273
|
+
if self._selected_cells is None:
|
274
|
+
raise ValueError("No cells selected. Please call select_cells() first.")
|
275
|
+
|
276
|
+
trace_ls = self._trace.linestring
|
277
|
+
|
278
|
+
def compute_cell_slope(curxy):
|
279
|
+
i, j = self._wa.get_ij_from_xy(curxy[0], curxy[1])
|
280
|
+
pt = Point(curxy[0], curxy[1])
|
281
|
+
distance_to_trace = trace_ls.distance(pt)
|
282
|
+
elevation_on_trace = trace_ls.interpolate(trace_ls.project(pt, normalized=True), normalized=True).z
|
283
|
+
if distance_to_trace == 0.0:
|
284
|
+
return 0.0
|
285
|
+
if elevation_on_trace == -99999.0:
|
286
|
+
return 0.0
|
287
|
+
|
288
|
+
return (elevation_on_trace - self._wa.array[i, j]) / distance_to_trace
|
289
|
+
|
290
|
+
self._slopes = [compute_cell_slope(curxy) for curxy in self._selected_cells]
|
291
|
+
|
292
|
+
def plot_slopes(self, show:bool = True, bins:int = 100,
|
293
|
+
engine:Literal['seaborn', 'plotly'] = 'seaborn'):
|
294
|
+
""" Plot a histogram of the slopes """
|
295
|
+
|
296
|
+
if engine == 'seaborn':
|
297
|
+
return self.plot_slopes_seaborn(show=show, bins=bins)
|
298
|
+
elif engine == 'plotly':
|
299
|
+
return self.plot_slopes_plotly(show=show, bins=bins)
|
300
|
+
|
301
|
+
def plot_slopes_seaborn(self, bins:int = 100, show:bool = True):
|
302
|
+
""" Plot a histogram of the slopes """
|
303
|
+
|
304
|
+
import seaborn as sns
|
305
|
+
import matplotlib.pyplot as plt
|
306
|
+
|
307
|
+
fig, ax = plt.subplots()
|
308
|
+
sns.histplot(self.slopes, bins=bins,
|
309
|
+
kde=True, ax=ax,
|
310
|
+
stat="density")
|
311
|
+
|
312
|
+
ax.set_xlabel('Slope [m/m]')
|
313
|
+
ax.set_ylabel('Frequency')
|
314
|
+
ax.set_title('Slope distribution')
|
315
|
+
|
316
|
+
if show:
|
317
|
+
plt.show()
|
318
|
+
|
319
|
+
return (fig, ax)
|
320
|
+
|
321
|
+
def plot_slopes_plotly(self, bins:int = 100, show:bool = True):
|
322
|
+
""" Plot a histogram of the slopes """
|
323
|
+
|
324
|
+
import plotly.express as px
|
325
|
+
|
326
|
+
fig = px.histogram(self.slopes, x='Slope [m/m]',
|
327
|
+
nbins=bins, title='Slope distribution',
|
328
|
+
histnorm='probability density')
|
329
|
+
|
330
|
+
fig.update_layout(xaxis_title='Slope [m/m]', yaxis_title='Frequency')
|
331
|
+
|
332
|
+
if show:
|
333
|
+
fig.show(renderer='browser')
|
334
|
+
|
335
|
+
return fig
|
wolfhece/apps/version.py
CHANGED
wolfhece/assets/mesh.py
CHANGED
@@ -16,7 +16,7 @@ class Mesh2D(header_wolf):
|
|
16
16
|
self.shape = src_header.shape
|
17
17
|
self._factor = None
|
18
18
|
|
19
|
-
def plot_cells(self, ax:Axes=None, color='black', **kwargs):
|
19
|
+
def plot_cells(self, ax:Axes=None, transpose:bool= False, color='black', **kwargs):
|
20
20
|
""" Plot the grid of the mesh.
|
21
21
|
"""
|
22
22
|
|
@@ -27,13 +27,28 @@ class Mesh2D(header_wolf):
|
|
27
27
|
|
28
28
|
[xmin, xmax], [ymin, ymax] = self.get_bounds()
|
29
29
|
|
30
|
-
|
31
|
-
|
30
|
+
if transpose:
|
31
|
+
|
32
|
+
# plot the grid of the mesh in a transposed way
|
33
|
+
for x in np.linspace(xmin, xmax, endpoint=True, num=self.nbx + 1):
|
34
|
+
ax.plot([ymin, ymax], [x, x], color=color, **kwargs)
|
32
35
|
|
33
|
-
|
34
|
-
|
36
|
+
for y in np.linspace(ymin, ymax, endpoint=True, num=self.nby + 1):
|
37
|
+
ax.plot([y, y], [xmin, xmax], color=color, **kwargs)
|
38
|
+
|
39
|
+
self.set_aspect_labels_matrice(ax=ax, **kwargs)
|
40
|
+
|
41
|
+
else:
|
42
|
+
|
43
|
+
# plot the grid of the mesh
|
44
|
+
for y in np.linspace(ymin, ymax, endpoint=True, num=self.nby + 1):
|
45
|
+
ax.plot([xmin, xmax], [y, y], color=color, **kwargs)
|
46
|
+
|
47
|
+
for x in np.linspace(xmin, xmax, endpoint=True, num=self.nbx + 1):
|
48
|
+
ax.plot([x, x], [ymin, ymax], color=color, **kwargs)
|
49
|
+
|
50
|
+
self.set_aspect_labels(ax=ax, **kwargs)
|
35
51
|
|
36
|
-
self.set_aspect_labels(ax=ax, **kwargs)
|
37
52
|
return fig, ax
|
38
53
|
|
39
54
|
def plot_center_cells(self, ax:Axes=None, color='black', linestyle='--', **kwargs):
|
@@ -77,6 +92,34 @@ class Mesh2D(header_wolf):
|
|
77
92
|
|
78
93
|
return fig, ax
|
79
94
|
|
95
|
+
def set_ticks_as_matrice(self, ax:Axes=None, Fortran_type:bool = True, **kwargs):
|
96
|
+
""" Set the ticks of the axis as the row and column of a matrice """
|
97
|
+
|
98
|
+
if ax is None:
|
99
|
+
fig, ax = plt.subplots()
|
100
|
+
else:
|
101
|
+
fig = ax.figure
|
102
|
+
|
103
|
+
[xmin, xmax], [ymin, ymax] = self.get_bounds()
|
104
|
+
|
105
|
+
if Fortran_type:
|
106
|
+
x_ticks = [f'{i}' for i in range(1,self.nbx+1)]
|
107
|
+
y_ticks = [f'{i}' for i in range(1,self.nby+1)]
|
108
|
+
else:
|
109
|
+
x_ticks = [f'{i}' for i in range(self.nbx)]
|
110
|
+
y_ticks = [f'{i}' for i in range(self.nby)]
|
111
|
+
|
112
|
+
ax.set_yticks(np.linspace(xmin+self.dx/2., xmax-self.dx/2., endpoint=True, num=self.nbx))
|
113
|
+
ax.set_xticks(np.linspace(ymin+self.dy/2., ymax-self.dy/2., endpoint=True, num=self.nby))
|
114
|
+
|
115
|
+
x_ticks.reverse()
|
116
|
+
ax.set_yticklabels(x_ticks)
|
117
|
+
ax.set_xticklabels(y_ticks)
|
118
|
+
|
119
|
+
self.set_aspect_labels_matrice(ax=ax, **kwargs)
|
120
|
+
|
121
|
+
return fig, ax
|
122
|
+
|
80
123
|
def plot_circle_at_centers(self, ax:Axes=None, color='black', radius:float=None, **kwargs):
|
81
124
|
""" Plot circles at the center of the cells.
|
82
125
|
"""
|
@@ -124,6 +167,64 @@ class Mesh2D(header_wolf):
|
|
124
167
|
self.set_aspect_labels(ax=ax, **kwargs)
|
125
168
|
|
126
169
|
return fig, ax
|
170
|
+
|
171
|
+
def plot_memoryposition_at_centers(self, ax:Axes=None,
|
172
|
+
transpose=False,
|
173
|
+
Fortran_type:bool = True,
|
174
|
+
f_contiguous:bool = True,
|
175
|
+
**kwargs):
|
176
|
+
""" Plot the position of the cells at the center of the cells.
|
177
|
+
"""
|
178
|
+
|
179
|
+
if ax is None:
|
180
|
+
fig, ax = plt.subplots()
|
181
|
+
else:
|
182
|
+
fig = ax.figure
|
183
|
+
|
184
|
+
[xmin, xmax], [ymin, ymax] = self.get_bounds()
|
185
|
+
|
186
|
+
if transpose:
|
187
|
+
k = 0
|
188
|
+
if Fortran_type:
|
189
|
+
k+=1
|
190
|
+
|
191
|
+
all_y = list(np.linspace(xmin + self.dx/2., xmax - self.dx/2., endpoint=True, num=self.nbx))
|
192
|
+
all_x = list(np.linspace(ymin + self.dy/2., ymax - self.dy/2., endpoint=True, num=self.nby))
|
193
|
+
|
194
|
+
all_y.reverse()
|
195
|
+
|
196
|
+
if f_contiguous:
|
197
|
+
|
198
|
+
for x in all_x:
|
199
|
+
for y in all_y:
|
200
|
+
|
201
|
+
ax.text(x, y, f'{k}', horizontalalignment='center', verticalalignment='center', **kwargs)
|
202
|
+
k+=1
|
203
|
+
else:
|
204
|
+
|
205
|
+
for y in all_y:
|
206
|
+
for x in all_x:
|
207
|
+
|
208
|
+
ax.text(x, y, f'{k}', horizontalalignment='center', verticalalignment='center', **kwargs)
|
209
|
+
k+=1
|
210
|
+
|
211
|
+
self.set_aspect_labels_matrice(ax=ax, **kwargs)
|
212
|
+
|
213
|
+
else:
|
214
|
+
|
215
|
+
k = 0
|
216
|
+
if Fortran_type:
|
217
|
+
k+=1
|
218
|
+
|
219
|
+
for y in np.linspace(ymin + self.dy/2., ymax - self.dy/2., endpoint=True, num=self.nby):
|
220
|
+
for x in np.linspace(xmin + self.dx/2., xmax - self.dx/2., endpoint=True, num=self.nbx):
|
221
|
+
|
222
|
+
ax.text(x, y, f'{k}', horizontalalignment='center', verticalalignment='center', **kwargs)
|
223
|
+
k+=1
|
224
|
+
|
225
|
+
self.set_aspect_labels(ax=ax, **kwargs)
|
226
|
+
|
227
|
+
return fig, ax
|
127
228
|
|
128
229
|
def plot_indices_at_bordersX(self, ax:Axes=None, Fortran_type:bool = True, **kwargs):
|
129
230
|
""" Plot the indices of the cells at the borders of the cells.
|
@@ -599,6 +700,27 @@ class Mesh2D(header_wolf):
|
|
599
700
|
ax.set_xlabel('X (m)')
|
600
701
|
ax.set_ylabel('Y (m)')
|
601
702
|
return fig, ax
|
703
|
+
|
704
|
+
def set_aspect_labels_matrice(self, ax:Axes=None, **kwargs):
|
705
|
+
""" Set the aspect of the plot to be equal.
|
706
|
+
"""
|
707
|
+
if ax is None:
|
708
|
+
fig, ax = plt.subplots()
|
709
|
+
else:
|
710
|
+
fig = ax.figure
|
711
|
+
|
712
|
+
[xmin, xmax], [ymin, ymax] = self.get_bounds()
|
713
|
+
|
714
|
+
ax.set_aspect('equal')
|
715
|
+
ax.set_ylim(xmin, xmax)
|
716
|
+
ax.set_xlim(ymin, ymax)
|
717
|
+
ax.set_xlabel('columns')
|
718
|
+
ax.set_ylabel('rows')
|
719
|
+
|
720
|
+
#set x ais on the upper side
|
721
|
+
ax.xaxis.set_ticks_position('top')
|
722
|
+
ax.xaxis.set_label_position('top')
|
723
|
+
return fig, ax
|
602
724
|
|
603
725
|
def zeros(self):
|
604
726
|
""" Return a 2D array of zeros with the shape of the mesh.
|
@@ -13,14 +13,13 @@ import logging
|
|
13
13
|
|
14
14
|
from ..drawing_obj import Element_To_Draw
|
15
15
|
|
16
|
-
|
17
|
-
#
|
18
|
-
#
|
19
|
-
|
20
|
-
|
21
|
-
#
|
22
|
-
|
23
|
-
from .kiwis import hydrometry
|
16
|
+
try:
|
17
|
+
# Trying to import the hydrometry_hece module from the hydrometry_hece package
|
18
|
+
# containing the KEY access to the SPW server
|
19
|
+
from ..hydrometry_hece.kiwis_hece import hydrometry_hece as hydrometry
|
20
|
+
except:
|
21
|
+
# If the hydrometry_hece module is not found, we import the hydrometry module from the hydrometry package
|
22
|
+
from .kiwis import hydrometry
|
24
23
|
|
25
24
|
from .kiwis_gui import hydrometry_gui
|
26
25
|
from ..PyVertex import cloud_vertices, wolfvertex, Cloud_Styles, getIfromRGB, getRGBfromI
|
wolfhece/lazviewer/__init__.py
CHANGED
@@ -1,13 +1,22 @@
|
|
1
|
-
|
2
|
-
from .
|
3
|
-
from
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
1
|
+
import logging
|
2
|
+
# Check __onWindows__ variable from wolfhece/__init__.py
|
3
|
+
from ..os_check import isWindows
|
4
|
+
|
5
|
+
if not isWindows():
|
6
|
+
# If not on Windows, raise an exception
|
7
|
+
logging.info('Not on Windows, ignoring the lazviewer package')
|
8
|
+
|
9
|
+
else:
|
10
|
+
from . import _add_path
|
11
|
+
from .viewer.viewer import *
|
12
|
+
from .points.points import *
|
13
|
+
from .points.expr import *
|
14
|
+
from scipy.spatial import kdtree
|
15
|
+
|
16
|
+
try:
|
17
|
+
from .processing.estimate_normals.estimate_normals import estimate_normals
|
18
|
+
except Exception as e:
|
19
|
+
print(e)
|
20
|
+
print('Could not import estimate_normals')
|
21
|
+
print('Please installed the VC++ redistributable from https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads')
|
13
22
|
|
wolfhece/mesh2d/bc_manager.py
CHANGED
wolfhece/mesh2d/gpu_2d.py
CHANGED
@@ -101,9 +101,12 @@ class Sim_2D_GPU():
|
|
101
101
|
('qx','Initial discharge along X [m^2/s]',WOLF_ARRAY_FULL_SINGLE),
|
102
102
|
('qy','Initial discharge along Y [m^2/s]',WOLF_ARRAY_FULL_SINGLE),
|
103
103
|
('bridge_roof','Bridge/Culvert (roof el.) [m]',WOLF_ARRAY_FULL_SINGLE),
|
104
|
+
('water_surface_elevation','Water surface elevation [m]',WOLF_ARRAY_FULL_SINGLE),
|
104
105
|
]}
|
105
106
|
|
106
|
-
self.files_ic=['Initial water depth [m]',
|
107
|
+
self.files_ic=['Initial water depth [m]',
|
108
|
+
'Initial discharge along X [m^2/s]',
|
109
|
+
'Initial discharge along Y [m^2/s]']
|
107
110
|
|
108
111
|
# Files for the simulation
|
109
112
|
self.files_others={'Generic file':[
|
@@ -166,7 +169,11 @@ class Sim_2D_GPU():
|
|
166
169
|
else:
|
167
170
|
return None
|
168
171
|
|
169
|
-
def __getitem__(self, key:Literal['nap', 'bathymetry',
|
172
|
+
def __getitem__(self, key:Literal['nap', 'bathymetry',
|
173
|
+
'manning', 'infiltration_zones',
|
174
|
+
'h', 'qx', 'qy',
|
175
|
+
'bridge_roof',
|
176
|
+
'water_surface_elevation']) -> WolfArray:
|
170
177
|
""" Get an array from the simulation """
|
171
178
|
|
172
179
|
if self.is_loaded:
|
@@ -174,12 +181,33 @@ class Sim_2D_GPU():
|
|
174
181
|
descr = self._get_description_arrays()[self._get_name_arrays().index(key)]
|
175
182
|
|
176
183
|
if key not in self._cached_arrays:
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
184
|
+
if key in ['water_surface_elevation']:
|
185
|
+
|
186
|
+
top = self['bathymetry']
|
187
|
+
h = self['h']
|
188
|
+
|
189
|
+
locarray = top + h
|
190
|
+
locarray.idx = descr
|
191
|
+
locarray.nullvalue = self.nullvalues[key]
|
192
|
+
|
193
|
+
def wse_write_all():
|
194
|
+
top = self['bathymetry']
|
195
|
+
new_h = self['water_surface_elevation'] - top
|
196
|
+
|
197
|
+
# Filter negative values
|
198
|
+
new_h.array.data[new_h.array.data < 0.] = 0.
|
199
|
+
|
200
|
+
new_h.write_all(str(self.dir / "h.npy"))
|
201
|
+
|
202
|
+
locarray.write_all = wse_write_all
|
203
|
+
|
204
|
+
else:
|
205
|
+
locarray = WolfArray(srcheader=self.get_header(),
|
206
|
+
np_source=self.sim.__getattribute__(key),
|
207
|
+
idx= descr,
|
208
|
+
nullvalue=self.nullvalues[key],
|
209
|
+
whichtype=self.files_array['Characteristics'][self._get_name_arrays().index(key)][2],
|
210
|
+
masknull=False)
|
183
211
|
locarray.loaded = True
|
184
212
|
locarray.filename = str(self.dir / f"{key}.npy")
|
185
213
|
|
@@ -354,7 +382,15 @@ class Sim_2D_GPU():
|
|
354
382
|
def nullvalues(self) -> dict[str,int]:
|
355
383
|
""" Define null values for the arrays """
|
356
384
|
|
357
|
-
return {'nap':0,
|
385
|
+
return {'nap':0,
|
386
|
+
'bathymetry':99999.,
|
387
|
+
'manning':0,
|
388
|
+
'infiltration_zones':0,
|
389
|
+
'h':0.,
|
390
|
+
'qx':0.,
|
391
|
+
'qy':0.,
|
392
|
+
'bridge_roof':99999.,
|
393
|
+
'water_surface_elevation':0.}
|
358
394
|
|
359
395
|
def verify_files(self):
|
360
396
|
""" Verify the files """
|
@@ -649,4 +685,4 @@ class Sim_2D_GPU():
|
|
649
685
|
self.sim._infiltration_zones[:,:]= tmp[:,:]
|
650
686
|
|
651
687
|
tmp = np.load(self.dir / "NAP.npy")
|
652
|
-
self.sim._nap[:,:]= tmp[:,:]
|
688
|
+
self.sim._nap[:,:]= tmp[:,:]
|