wolfhece 2.2.17__py3-none-any.whl → 2.2.20__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 +75 -10
- wolfhece/PyGui.py +6 -0
- wolfhece/PyVertexvectors.py +233 -23
- wolfhece/Results2DGPU.py +14 -2
- wolfhece/__init__.py +14 -1
- wolfhece/analyze_poly.py +335 -0
- wolfhece/apps/version.py +1 -1
- wolfhece/assets/tree.py +0 -0
- wolfhece/lazviewer/__init__.py +21 -12
- wolfhece/mesh2d/bc_manager.py +1 -1
- wolfhece/mesh2d/cst_2D_boundary_conditions.py +1 -1
- wolfhece/mesh2d/gpu_2d.py +46 -10
- wolfhece/mesh2d/simple_2d.py +94 -69
- wolfhece/mesh2d/wolf2dprev.py +12 -0
- wolfhece/os_check.py +16 -0
- wolfhece/pydike.py +245 -41
- wolfhece/scenario/config_manager.py +13 -0
- wolfhece/tools2d_dll.py +6 -0
- wolfhece/wolf_array.py +392 -48
- wolfhece/wolf_texture.py +1 -0
- wolfhece/wolfresults_2D.py +23 -1
- {wolfhece-2.2.17.dist-info → wolfhece-2.2.20.dist-info}/METADATA +1 -1
- {wolfhece-2.2.17.dist-info → wolfhece-2.2.20.dist-info}/RECORD +26 -23
- {wolfhece-2.2.17.dist-info → wolfhece-2.2.20.dist-info}/WHEEL +1 -1
- {wolfhece-2.2.17.dist-info → wolfhece-2.2.20.dist-info}/entry_points.txt +0 -0
- {wolfhece-2.2.17.dist-info → wolfhece-2.2.20.dist-info}/top_level.txt +0 -0
wolfhece/wolf_array.py
CHANGED
@@ -2097,7 +2097,19 @@ class Ops_Array(wx.Frame):
|
|
2097
2097
|
|
2098
2098
|
self.labelling = wx.Button(self.tools, wx.ID_ANY, _("Labelling"), wx.DefaultPosition,wx.DefaultSize, 0)
|
2099
2099
|
|
2100
|
+
stats_sizer = wx.BoxSizer(wx.HORIZONTAL)
|
2101
|
+
stats_sizer2 = wx.BoxSizer(wx.HORIZONTAL)
|
2102
|
+
|
2100
2103
|
self.statistics = wx.Button(self.tools, wx.ID_ANY, _("Statistics"), wx.DefaultPosition,wx.DefaultSize, 0)
|
2104
|
+
self.plot_stats = wx.Button(self.tools, wx.ID_ANY, _("Plot statistics\nCurrent zoom"), wx.DefaultPosition,wx.DefaultSize, 0)
|
2105
|
+
self.plot_stats_zone = wx.Button(self.tools, wx.ID_ANY, _("Plot statistics\nCurrent zone"), wx.DefaultPosition,wx.DefaultSize, 0)
|
2106
|
+
self.plot_stats_vector = wx.Button(self.tools, wx.ID_ANY, _("Plot statistics\nCurrent vector"), wx.DefaultPosition,wx.DefaultSize, 0)
|
2107
|
+
|
2108
|
+
stats_sizer.Add(self.statistics, 1, wx.EXPAND)
|
2109
|
+
stats_sizer.Add(self.plot_stats, 1, wx.EXPAND)
|
2110
|
+
|
2111
|
+
stats_sizer2.Add(self.plot_stats_zone, 1, wx.EXPAND)
|
2112
|
+
stats_sizer2.Add(self.plot_stats_vector, 1, wx.EXPAND)
|
2101
2113
|
|
2102
2114
|
self.clean = wx.Button(self.tools, wx.ID_ANY, _("Clean"), wx.DefaultPosition,wx.DefaultSize, 0)
|
2103
2115
|
|
@@ -2117,7 +2129,8 @@ class Ops_Array(wx.Frame):
|
|
2117
2129
|
Toolssizer.Add(self.labelling, 1, wx.EXPAND)
|
2118
2130
|
Toolssizer.Add(self.clean, 1, wx.EXPAND)
|
2119
2131
|
Toolssizer.Add(self.extract_selection, 1, wx.EXPAND)
|
2120
|
-
Toolssizer.Add(
|
2132
|
+
Toolssizer.Add(stats_sizer, 1, wx.EXPAND)
|
2133
|
+
Toolssizer.Add(stats_sizer2, 1, wx.EXPAND)
|
2121
2134
|
Toolssizer.Add(cont_sizer, 1, wx.EXPAND)
|
2122
2135
|
|
2123
2136
|
self.ApplyTools.SetToolTip(_("Apply Nullvalue into memory/object"))
|
@@ -2127,6 +2140,7 @@ class Ops_Array(wx.Frame):
|
|
2127
2140
|
self.clean.SetToolTip(_("Clean the array\n\nRemove small isolated patches of data"))
|
2128
2141
|
self.extract_selection.SetToolTip(_("Extract the current selection"))
|
2129
2142
|
self.statistics.SetToolTip(_("Compute statistics on the array\n\nResults are displayed in a dialog box"))
|
2143
|
+
self.plot_stats.SetToolTip(_("Plot statistics on the array\n\nResults are displayed in a separate figure"))
|
2130
2144
|
|
2131
2145
|
self.tools.SetSizer(Toolssizer)
|
2132
2146
|
self.tools.Layout()
|
@@ -2500,6 +2514,9 @@ class Ops_Array(wx.Frame):
|
|
2500
2514
|
self.clean.Bind(wx.EVT_BUTTON, self.OnClean)
|
2501
2515
|
self.labelling.Bind(wx.EVT_BUTTON, self.OnLabelling)
|
2502
2516
|
self.statistics.Bind(wx.EVT_BUTTON, self.OnStatistics)
|
2517
|
+
self.plot_stats.Bind(wx.EVT_BUTTON, self.OnPlotStatistics)
|
2518
|
+
self.plot_stats_zone.Bind(wx.EVT_BUTTON, self.OnPlotStatisticsZone)
|
2519
|
+
self.plot_stats_vector.Bind(wx.EVT_BUTTON, self.OnPlotStatisticsVector)
|
2503
2520
|
self.extract_selection.Bind(wx.EVT_BUTTON, self.OnExtractSelection)
|
2504
2521
|
self._contour_int.Bind(wx.EVT_BUTTON, self.OnContourInt)
|
2505
2522
|
self._contour_list.Bind(wx.EVT_BUTTON, self.OnContourList)
|
@@ -3008,6 +3025,86 @@ class Ops_Array(wx.Frame):
|
|
3008
3025
|
|
3009
3026
|
ret_frame.Show()
|
3010
3027
|
|
3028
|
+
def OnPlotStatistics(self, event:wx.MouseEvent):
|
3029
|
+
""" Plot statistics on the current zoom"""
|
3030
|
+
|
3031
|
+
from .analyze_poly import Array_analysis_onepolygon
|
3032
|
+
|
3033
|
+
logging.info(_('Plotting statistics on the current zoom'))
|
3034
|
+
if self.parentarray.nbnotnull > 50_000:
|
3035
|
+
logging.info(_('Quite large array - please wait a bit...'))
|
3036
|
+
|
3037
|
+
analyzer = Array_analysis_onepolygon(self.parentarray, self.mapviewer.get_bounds_as_polygon())
|
3038
|
+
|
3039
|
+
try:
|
3040
|
+
analyzer.plot_values(engine = 'plotly')
|
3041
|
+
except:
|
3042
|
+
logging.error(_('Error in plotly engine - Try seaborn engine'))
|
3043
|
+
logging.info(_('If you have not installed plotly, please install it with "pip install plotly"'))
|
3044
|
+
try:
|
3045
|
+
analyzer.plot_values(engine = 'seaborn')
|
3046
|
+
except:
|
3047
|
+
logging.error('Error in seaborn engine')
|
3048
|
+
|
3049
|
+
logging.info(_('Done !'))
|
3050
|
+
|
3051
|
+
def OnPlotStatisticsZone(self, event:wx.MouseEvent):
|
3052
|
+
""" Plot statistics on the current zone """
|
3053
|
+
|
3054
|
+
if self.mapviewer is not None:
|
3055
|
+
if self.mapviewer.active_zone is not None:
|
3056
|
+
from .analyze_poly import Array_analysis_polygons
|
3057
|
+
|
3058
|
+
logging.info(_('Plotting statistics on the current zone'))
|
3059
|
+
|
3060
|
+
analyzer = Array_analysis_polygons(self.parentarray, self.mapviewer.active_zone)
|
3061
|
+
try:
|
3062
|
+
analyzer.plot_values(engine = 'plotly')
|
3063
|
+
except:
|
3064
|
+
logging.error(_('Error in plotly engine - Try seaborn engine'))
|
3065
|
+
logging.info(_('If you have not installed plotly, please install it with "pip install plotly"'))
|
3066
|
+
try:
|
3067
|
+
analyzer.plot_values(engine = 'seaborn')
|
3068
|
+
except:
|
3069
|
+
logging.error('Error in seaborn engine')
|
3070
|
+
|
3071
|
+
logging.info(_('Done !'))
|
3072
|
+
|
3073
|
+
else:
|
3074
|
+
logging.error(_('No active zone to plot statistics'))
|
3075
|
+
logging.info(_('Please select a zone to plot statistics'))
|
3076
|
+
else:
|
3077
|
+
logging.error(_('No active mapviewer to plot statistics'))
|
3078
|
+
|
3079
|
+
def OnPlotStatisticsVector(self, event:wx.MouseEvent):
|
3080
|
+
""" Plot statistics on the current vector """
|
3081
|
+
|
3082
|
+
if self.mapviewer is not None:
|
3083
|
+
if self.mapviewer.active_vector is not None:
|
3084
|
+
from .analyze_poly import Array_analysis_onepolygon
|
3085
|
+
|
3086
|
+
logging.info(_('Plotting statistics on the current vector'))
|
3087
|
+
|
3088
|
+
# Get the active vector
|
3089
|
+
analyzer = Array_analysis_onepolygon(self.parentarray, self.mapviewer.active_vector)
|
3090
|
+
try:
|
3091
|
+
analyzer.plot_values(engine = 'plotly')
|
3092
|
+
except:
|
3093
|
+
logging.error(_('Error in plotly engine - Try seaborn engine'))
|
3094
|
+
logging.info(_('If you have not installed plotly, please install it with "pip install plotly"'))
|
3095
|
+
try:
|
3096
|
+
analyzer.plot_values(engine = 'seaborn')
|
3097
|
+
except:
|
3098
|
+
logging.error('Error in seaborn engine')
|
3099
|
+
|
3100
|
+
logging.info(_('Done !'))
|
3101
|
+
|
3102
|
+
else:
|
3103
|
+
logging.error(_('No active vector to plot statistics'))
|
3104
|
+
logging.info(_('Please select a vector to plot statistics'))
|
3105
|
+
else:
|
3106
|
+
logging.error(_('No active mapviewer to plot statistics'))
|
3107
|
+
|
3011
3108
|
def OnExtractSelection(self, event:wx.MouseEvent):
|
3012
3109
|
""" Extract the current selection """
|
3013
3110
|
|
@@ -4953,7 +5050,10 @@ class SelectionData():
|
|
4953
5050
|
self.myselection = 'all'
|
4954
5051
|
self.update_nb_nodes_selection()
|
4955
5052
|
|
4956
|
-
def interp2Dpolygons(self, working_zone:zone,
|
5053
|
+
def interp2Dpolygons(self, working_zone:zone,
|
5054
|
+
method:Literal["nearest", "linear", "cubic"] = None,
|
5055
|
+
resetplot:bool = True,
|
5056
|
+
keep:Literal['all', 'below', 'above'] = 'all'):
|
4957
5057
|
"""
|
4958
5058
|
Interpolation sous tous les polygones d'une zone
|
4959
5059
|
cf parent.interp2Dpolygon
|
@@ -4970,12 +5070,15 @@ class SelectionData():
|
|
4970
5070
|
method = dlg.GetStringSelection()
|
4971
5071
|
dlg.Destroy()
|
4972
5072
|
|
4973
|
-
self.parent.interpolate_on_polygons(working_zone, method)
|
5073
|
+
self.parent.interpolate_on_polygons(working_zone, method, keep)
|
4974
5074
|
|
4975
5075
|
if resetplot:
|
4976
5076
|
self.parent.reset_plot()
|
4977
5077
|
|
4978
|
-
def interp2Dpolygon(self, working_vector:vector,
|
5078
|
+
def interp2Dpolygon(self, working_vector:vector,
|
5079
|
+
method:Literal["nearest", "linear", "cubic"] = None,
|
5080
|
+
resetplot:bool = True,
|
5081
|
+
keep:Literal['all', 'below', 'above'] = 'all'):
|
4979
5082
|
"""
|
4980
5083
|
Interpolation sous un polygone
|
4981
5084
|
cf parent.interp2Dpolygon
|
@@ -4992,7 +5095,7 @@ class SelectionData():
|
|
4992
5095
|
method = dlg.GetStringSelection()
|
4993
5096
|
dlg.Destroy()
|
4994
5097
|
|
4995
|
-
self.parent.interpolate_on_polygon(working_vector, method)
|
5098
|
+
self.parent.interpolate_on_polygon(working_vector, method, keep)
|
4996
5099
|
|
4997
5100
|
if resetplot:
|
4998
5101
|
self.parent.reset_plot()
|
@@ -5232,7 +5335,10 @@ class SelectionDataMB(SelectionData):
|
|
5232
5335
|
|
5233
5336
|
logging.error(_('Not yet implemented for Multi-Blocks'))
|
5234
5337
|
|
5235
|
-
def interp2Dpolygons(self, working_zone:zone,
|
5338
|
+
def interp2Dpolygons(self, working_zone:zone,
|
5339
|
+
method:Literal["nearest", "linear", "cubic"] = None,
|
5340
|
+
resetplot:bool = True,
|
5341
|
+
keep:Literal['all', 'below', 'above'] = 'all'):
|
5236
5342
|
"""
|
5237
5343
|
Interpolation sous tous les polygones d'une zone
|
5238
5344
|
cf parent.interp2Dpolygon
|
@@ -5249,11 +5355,15 @@ class SelectionDataMB(SelectionData):
|
|
5249
5355
|
method = dlg.GetStringSelection()
|
5250
5356
|
dlg.Destroy()
|
5251
5357
|
|
5252
|
-
self.parent.interpolate_on_polygons(working_zone, method)
|
5358
|
+
self.parent.interpolate_on_polygons(working_zone, method, keep)
|
5253
5359
|
|
5254
|
-
|
5360
|
+
if resetplot:
|
5361
|
+
self.parent.reset_plot()
|
5255
5362
|
|
5256
|
-
def interp2Dpolygon(self, working_vector:vector,
|
5363
|
+
def interp2Dpolygon(self, working_vector:vector,
|
5364
|
+
method:Literal["nearest", "linear", "cubic"] = None,
|
5365
|
+
resetplot:bool = True,
|
5366
|
+
keep:Literal['all', 'below', 'above'] = 'all'):
|
5257
5367
|
"""
|
5258
5368
|
Interpolation sous un polygone
|
5259
5369
|
cf parent.interp2Dpolygon
|
@@ -5270,9 +5380,10 @@ class SelectionDataMB(SelectionData):
|
|
5270
5380
|
method = dlg.GetStringSelection()
|
5271
5381
|
dlg.Destroy()
|
5272
5382
|
|
5273
|
-
self.parent.interpolate_on_polygon(working_vector, method)
|
5383
|
+
self.parent.interpolate_on_polygon(working_vector, method, keep)
|
5274
5384
|
|
5275
|
-
|
5385
|
+
if resetplot:
|
5386
|
+
self.parent.reset_plot()
|
5276
5387
|
|
5277
5388
|
def interp2Dpolylines(self, working_zone:zone, resetplot:bool = True):
|
5278
5389
|
"""
|
@@ -5529,6 +5640,24 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
5529
5640
|
|
5530
5641
|
self.add_ops_sel() # Ajout d'un gestionnaire de sélection et d'opérations
|
5531
5642
|
|
5643
|
+
def __getstate__(self):
|
5644
|
+
""" Récupération de l'état de l'objet pour la sérialisation """
|
5645
|
+
state = self.__dict__.copy()
|
5646
|
+
|
5647
|
+
# Remove the OpenGL reference to avoid bad references
|
5648
|
+
if 'mygrid' in state:
|
5649
|
+
state['mygrid'] = {}
|
5650
|
+
""" If not empty, the OpenGL list is not properly serialized.
|
5651
|
+
During "delete_lists" routine, tghe OpenGL can produce an error.
|
5652
|
+
"""
|
5653
|
+
if 'shaded' in state:
|
5654
|
+
state['shaded'] = None # Avoid serializing the shaded WolfArray
|
5655
|
+
return state
|
5656
|
+
|
5657
|
+
def __setstate__(self, state):
|
5658
|
+
""" Récupération de l'état de l'objet pour la désérialisation """
|
5659
|
+
self.__dict__.update(state)
|
5660
|
+
|
5532
5661
|
def set_opacity(self, alpha:float):
|
5533
5662
|
""" Set the transparency of the array """
|
5534
5663
|
|
@@ -6124,17 +6253,17 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
6124
6253
|
|
6125
6254
|
if inside_polygon is not None:
|
6126
6255
|
ij = self.get_ij_inside_polygon(inside_polygon)
|
6127
|
-
vals = self.array[ij]
|
6256
|
+
vals = self.array[ij[:,0], ij[:,1]]
|
6128
6257
|
elif self.SelectionData.nb == 0 or self.SelectionData.myselection == 'all':
|
6129
6258
|
logging.info(_('No selection -- statistics on the whole array'))
|
6130
|
-
vals = self.array[~self.array.mask] # all values
|
6259
|
+
vals = self.array[~self.array.mask].ravel().data # all values
|
6131
6260
|
else:
|
6132
6261
|
vals = self.SelectionData.get_values_sel()
|
6133
6262
|
|
6134
|
-
mean = np.mean(vals)
|
6135
|
-
std = np.std(vals)
|
6136
|
-
median = np.median(vals)
|
6137
|
-
sum = np.sum(vals)
|
6263
|
+
mean = np.ma.mean(vals)
|
6264
|
+
std = np.ma.std(vals)
|
6265
|
+
median = np.ma.median(vals)
|
6266
|
+
sum = np.ma.sum(vals)
|
6138
6267
|
vol = sum * self.dx * self.dy
|
6139
6268
|
|
6140
6269
|
return {_('Mean'): mean, _('Std'): std, _('Median'): median, _('Sum'): sum, _('Volume'): vol, _('Values'): vals}
|
@@ -6806,7 +6935,9 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
6806
6935
|
|
6807
6936
|
plt.show()
|
6808
6937
|
|
6809
|
-
def interpolate_on_polygon(self, working_vector: vector,
|
6938
|
+
def interpolate_on_polygon(self, working_vector: vector,
|
6939
|
+
method:Literal["nearest", "linear", "cubic"]="linear",
|
6940
|
+
keep:Literal['all', 'below', 'above'] = 'all'):
|
6810
6941
|
"""
|
6811
6942
|
Interpolation sous un polygone
|
6812
6943
|
|
@@ -6818,6 +6949,14 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
6818
6949
|
depuis les vertices 3D du polygone
|
6819
6950
|
"""
|
6820
6951
|
|
6952
|
+
if keep not in ['all', 'below', 'above']:
|
6953
|
+
logging.error(_('keep must be "all", "below" or "above"'))
|
6954
|
+
raise ValueError
|
6955
|
+
|
6956
|
+
if method not in ['nearest', 'linear', 'cubic']:
|
6957
|
+
logging.error(_('method must be "nearest", "linear" or "cubic"'))
|
6958
|
+
raise ValueError
|
6959
|
+
|
6821
6960
|
if self.mngselection is None:
|
6822
6961
|
destxy = self.get_xy_inside_polygon(working_vector)
|
6823
6962
|
if len(destxy)==0:
|
@@ -6841,6 +6980,9 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
6841
6980
|
else:
|
6842
6981
|
destxy = self.SelectionData.myselection
|
6843
6982
|
|
6983
|
+
# if isinstance(destxy, list):
|
6984
|
+
# destxy = np.asarray(destxy)
|
6985
|
+
|
6844
6986
|
if len(destxy)==0:
|
6845
6987
|
logging.debug(_('No points to interpolate'))
|
6846
6988
|
return
|
@@ -6851,7 +6993,13 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
6851
6993
|
|
6852
6994
|
newvalues = griddata(xyz[:, :2], xyz[:, 2], destxy, method=method, fill_value=-99999.)
|
6853
6995
|
|
6854
|
-
|
6996
|
+
if keep == 'all':
|
6997
|
+
locmask = np.where(newvalues != -99999.)
|
6998
|
+
elif keep == 'below':
|
6999
|
+
locmask = np.where((newvalues != -99999.) & (newvalues < self.array.data[destij[:, 0], destij[:, 1]]))
|
7000
|
+
elif keep == 'above':
|
7001
|
+
locmask = np.where((newvalues != -99999.) & (newvalues > self.array.data[destij[:, 0], destij[:, 1]]))
|
7002
|
+
|
6855
7003
|
self.array.data[destij[locmask][:, 0], destij[locmask][:, 1]] = newvalues[locmask]
|
6856
7004
|
|
6857
7005
|
def rasterize_vector_valuebyid(self, working_vector: vector, id,
|
@@ -6910,14 +7058,16 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
6910
7058
|
for curzone in working_zones.myzones:
|
6911
7059
|
self.rasterize_zone_valuebyid(curzone, id, method)
|
6912
7060
|
|
6913
|
-
def interpolate_on_polygons(self, working_zone:zone,
|
7061
|
+
def interpolate_on_polygons(self, working_zone:zone,
|
7062
|
+
method:Literal["nearest", "linear", "cubic"]="linear",
|
7063
|
+
keep:Literal['all', 'below', 'above'] = 'all'):
|
6914
7064
|
"""
|
6915
7065
|
Interpolation sous plusieurs polygones d'une même zone
|
6916
7066
|
|
6917
7067
|
"""
|
6918
7068
|
|
6919
7069
|
for curvec in working_zone.myvectors:
|
6920
|
-
self.interpolate_on_polygon(curvec, method)
|
7070
|
+
self.interpolate_on_polygon(curvec, method, keep)
|
6921
7071
|
|
6922
7072
|
def interpolate_on_polyline(self, working_vector:vector, usemask=True):
|
6923
7073
|
"""
|
@@ -6994,7 +7144,9 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
6994
7144
|
|
6995
7145
|
def interpolate_on_triangulation(self, coords, triangles,
|
6996
7146
|
grid_x=None, grid_y = None,
|
6997
|
-
mask_tri=None,
|
7147
|
+
mask_tri=None,
|
7148
|
+
interp_method:Literal['matplotlib','scipy'] = 'matplotlib',
|
7149
|
+
keep:Literal['all', 'below', 'above'] = 'all'):
|
6998
7150
|
"""
|
6999
7151
|
Interpolation sur une triangulation.
|
7000
7152
|
|
@@ -7003,7 +7155,8 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
7003
7155
|
- dans les mailles contenues dans la triangulation sinon
|
7004
7156
|
|
7005
7157
|
Matplotlib is used by default, but Scipy(griddata) can be used as well. If Matplotlib crashes, try with Scipy.
|
7006
|
-
|
7158
|
+
|
7159
|
+
**Matplotlib is more strict on the quality of the triangulation.**
|
7007
7160
|
|
7008
7161
|
:param coords: numpy.array of vertices - shape (n,3)
|
7009
7162
|
:param triangles: numpy.array of triangles - shape (m,3)
|
@@ -7011,6 +7164,7 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
7011
7164
|
:param grid_y: numpy.array of y values where the interpolation will be done -- if None, the grid is created from the array
|
7012
7165
|
:param mask_tri: numpy.array of mask for the triangles
|
7013
7166
|
:param interp_method: method for the interpolation -- 'matplotlib' or 'scipy'
|
7167
|
+
:param keep: 'all' to keep all values, 'below' to keep only values below the current array, 'above' to keep only values above the current array
|
7014
7168
|
|
7015
7169
|
For matplotlib algo, see : https://matplotlib.org/stable/gallery/images_contours_and_fields/triinterp_demo.html
|
7016
7170
|
For scipy algo, see : https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.griddata.html
|
@@ -7019,6 +7173,7 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
7019
7173
|
|
7020
7174
|
|
7021
7175
|
if interp_method =='matplotlib':
|
7176
|
+
# FIXME : This part could be optimized, I think
|
7022
7177
|
|
7023
7178
|
import matplotlib.tri as mtri
|
7024
7179
|
|
@@ -7027,6 +7182,9 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
7027
7182
|
try:
|
7028
7183
|
if self.mngselection is not None:
|
7029
7184
|
if self.mngselection.myselection != [] and self.mngselection.myselection != 'all':
|
7185
|
+
# interpolation only in the selected cells
|
7186
|
+
|
7187
|
+
# Convert coordinates to indices
|
7030
7188
|
ij = np.asarray([self.get_ij_from_xy(x, y) for x, y in self.mngselection.myselection])
|
7031
7189
|
|
7032
7190
|
try:
|
@@ -7037,17 +7195,60 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
7037
7195
|
interplin = mtri.LinearTriInterpolator(triang, coords[:,2]) # Interpolation et récupération dans le numpy.array de l'objet Wolf
|
7038
7196
|
except:
|
7039
7197
|
raise Warning(_('Bad triangulation - try with another method like Scipy'))
|
7198
|
+
|
7040
7199
|
newvalues = np.ma.masked_array([interplin(x, y) for x, y in self.mngselection.myselection])
|
7041
7200
|
|
7042
|
-
|
7043
|
-
|
7201
|
+
if newvalues.mask.shape!=():
|
7202
|
+
# We have a mask
|
7203
|
+
|
7204
|
+
nonmasked_values = np.where(~newvalues.mask)
|
7205
|
+
ij = ij[nonmasked_values]
|
7206
|
+
newvalues = newvalues[nonmasked_values]
|
7207
|
+
|
7208
|
+
if keep == 'below':
|
7209
|
+
newvalues = np.ma.masked_array(newvalues, mask=(newvalues > self.array.data[ij[:, 0], ij[:, 1]]))
|
7210
|
+
|
7211
|
+
nonmasked_values = np.where(~newvalues.mask)
|
7212
|
+
ij = ij[np.where(~newvalues.mask)]
|
7213
|
+
newvalues = newvalues[nonmasked_values]
|
7214
|
+
|
7215
|
+
elif keep == 'above':
|
7216
|
+
newvalues = np.ma.masked_array(newvalues[nonmasked_values], mask=(newvalues[nonmasked_values] < self.array.data[ij[:, 0], ij[:, 1]]))
|
7217
|
+
|
7218
|
+
nonmasked_values = np.where(~newvalues.mask)
|
7219
|
+
ij = ij[np.where(~newvalues.mask)]
|
7220
|
+
newvalues = newvalues[nonmasked_values]
|
7221
|
+
|
7222
|
+
self.array.data[ij[:, 0], ij[:, 1]] = newvalues
|
7223
|
+
else:
|
7224
|
+
# No mask --> boolean
|
7225
|
+
|
7226
|
+
if keep == 'below':
|
7227
|
+
newvalues = np.ma.masked_array(newvalues, mask=(newvalues > self.array.data[ij[:, 0], ij[:, 1]]))
|
7228
|
+
|
7229
|
+
nonmasked_values = np.where(~newvalues.mask)
|
7230
|
+
ij = ij[np.where(~newvalues.mask)]
|
7231
|
+
newvalues = newvalues[nonmasked_values]
|
7232
|
+
|
7233
|
+
elif keep == 'above':
|
7234
|
+
newvalues = np.ma.masked_array(newvalues, mask=(newvalues < self.array.data[ij[:, 0], ij[:, 1]]))
|
7235
|
+
|
7236
|
+
nonmasked_values = np.where(~newvalues.mask)
|
7237
|
+
ij = ij[np.where(~newvalues.mask)]
|
7238
|
+
newvalues = newvalues[nonmasked_values]
|
7239
|
+
|
7240
|
+
self.array.data[ij[:, 0], ij[:, 1]] = newvalues
|
7044
7241
|
|
7045
7242
|
elif self.mngselection.myselection == 'all' and (grid_x is None and grid_y is None):
|
7243
|
+
# interpolation in all the cells
|
7244
|
+
|
7245
|
+
# Creating a grid for all cells
|
7046
7246
|
decalx = self.origx + self.translx
|
7047
7247
|
decaly = self.origy + self.transly
|
7048
7248
|
x = np.arange(self.dx / 2. + decalx, float(self.nbx) * self.dx + self.dx / 2 + decalx, self.dx)
|
7049
7249
|
y = np.arange(self.dy / 2. + decaly, float(self.nby) * self.dy + self.dy / 2 + decaly, self.dy)
|
7050
7250
|
grid_x, grid_y = np.meshgrid(x, y, indexing='ij')
|
7251
|
+
grid_ij = self.xy2ij_np(np.concatenate([grid_x.ravel()[:, np.newaxis], grid_y.ravel()[:, np.newaxis]], axis=1))
|
7051
7252
|
|
7052
7253
|
try:
|
7053
7254
|
# Opérateur d'interpolation linéaire
|
@@ -7057,11 +7258,32 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
7057
7258
|
interplin = mtri.LinearTriInterpolator(triang, coords[:,2])
|
7058
7259
|
except:
|
7059
7260
|
raise Warning(_('Bad triangulation - try with another method like Scipy'))
|
7261
|
+
|
7060
7262
|
# Interpolation et récupération dans le numpy.array de l'objet Wolf
|
7061
|
-
newvalues = interplin(grid_x,grid_y)
|
7062
|
-
|
7263
|
+
newvalues = interplin(grid_x,grid_y)
|
7264
|
+
|
7265
|
+
nonmasked_values = np.where(~newvalues.mask)
|
7266
|
+
ij = grid_ij[nonmasked_values]
|
7267
|
+
newvalues = newvalues[nonmasked_values]
|
7268
|
+
|
7269
|
+
if keep == 'below':
|
7270
|
+
newvalues = np.ma.masked_array(newvalues, mask=(newvalues > self.array.data[grid_ij[:, 0], grid_ij[:, 1]]))
|
7271
|
+
|
7272
|
+
nonmasked_values = np.where(~newvalues.mask)
|
7273
|
+
ij = grid_ij[nonmasked_values]
|
7274
|
+
newvalues = newvalues[nonmasked_values]
|
7275
|
+
|
7276
|
+
elif keep == 'above':
|
7277
|
+
newvalues = np.ma.masked_array(newvalues, mask=(newvalues < self.array.data[grid_ij[:, 0], grid_ij[:, 1]]))
|
7278
|
+
|
7279
|
+
nonmasked_values = np.where(~newvalues.mask)
|
7280
|
+
ij = grid_ij[nonmasked_values]
|
7281
|
+
newvalues = newvalues[nonmasked_values]
|
7282
|
+
|
7283
|
+
self.array.data[ij[:, 0], ij[:, 1]] = newvalues
|
7284
|
+
|
7063
7285
|
elif (grid_x is not None and grid_y is not None):
|
7064
|
-
|
7286
|
+
# Working on an imposed grid
|
7065
7287
|
|
7066
7288
|
# Opérateur d'interpolation linéaire
|
7067
7289
|
try:
|
@@ -7069,16 +7291,56 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
7069
7291
|
if mask_tri is not None:
|
7070
7292
|
triang.set_mask(mask_tri)
|
7071
7293
|
interplin = mtri.LinearTriInterpolator(triang, coords[:,2]) # Interpolation et récupération dans le numpy.array de l'objet Wolf
|
7072
|
-
newvalues = np.ma.masked_array([interplin(x, y) for x, y in zip(grid_x.
|
7294
|
+
newvalues = np.ma.masked_array([interplin(x, y) for x, y in zip(grid_x.ravel(),grid_y.ravel())])
|
7073
7295
|
except:
|
7074
7296
|
raise Warning(_('Bad triangulation - try with another method like Scipy'))
|
7075
7297
|
|
7298
|
+
# newvalues is a vector of values
|
7299
|
+
|
7300
|
+
# ij is a vector of indices
|
7301
|
+
ij = np.asarray([self.get_ij_from_xy(x, y) for x, y in zip(grid_x.ravel(),grid_y.ravel())])
|
7302
|
+
|
7076
7303
|
if newvalues.mask.shape!=():
|
7077
|
-
|
7078
|
-
|
7304
|
+
|
7305
|
+
nonmasked_values = np.where(~newvalues.mask)
|
7306
|
+
ij = ij[nonmasked_values]
|
7307
|
+
newvalues = newvalues[nonmasked_values]
|
7308
|
+
|
7309
|
+
if keep == 'below':
|
7310
|
+
newvalues = np.ma.masked_array(newvalues, mask=(newvalues > self.array.data[ij[:, 0], ij[:, 1]]))
|
7311
|
+
|
7312
|
+
nonmasked_values = np.where(~newvalues.mask)
|
7313
|
+
ij = ij[nonmasked_values]
|
7314
|
+
newvalues = newvalues[nonmasked_values]
|
7315
|
+
|
7316
|
+
elif keep == 'above':
|
7317
|
+
|
7318
|
+
newvalues = np.ma.masked_array(newvalues, mask=(newvalues < self.array.data[ij[:, 0], ij[:, 1]]))
|
7319
|
+
|
7320
|
+
nonmasked_values = np.where(~newvalues.mask)
|
7321
|
+
ij = ij[nonmasked_values]
|
7322
|
+
newvalues = newvalues[nonmasked_values]
|
7323
|
+
|
7324
|
+
self.array.data[ij[:, 0], ij[:, 1]] = newvalues
|
7079
7325
|
else:
|
7080
|
-
|
7326
|
+
|
7327
|
+
if keep == 'below':
|
7328
|
+
newvalues = np.ma.masked_array(newvalues, mask=(newvalues > self.array.data[ij[:, 0], ij[:, 1]]))
|
7329
|
+
nonmasked_values = np.where(~newvalues.mask)
|
7330
|
+
ij = ij[nonmasked_values]
|
7331
|
+
newvalues = newvalues[nonmasked_values]
|
7332
|
+
elif keep == 'above':
|
7333
|
+
newvalues = np.ma.masked_array(newvalues, mask=(newvalues < self.array.data[ij[:, 0], ij[:, 1]]))
|
7334
|
+
nonmasked_values = np.where(~newvalues.mask)
|
7335
|
+
ij = ij[nonmasked_values]
|
7336
|
+
newvalues = newvalues[nonmasked_values]
|
7337
|
+
|
7338
|
+
self.array.data[ij[:, 0], ij[:, 1]] = newvalues
|
7339
|
+
|
7081
7340
|
else:
|
7341
|
+
# Working on the whole array
|
7342
|
+
|
7343
|
+
# Creating a grid for all cells
|
7082
7344
|
decalx = self.origx + self.translx
|
7083
7345
|
decaly = self.origy + self.transly
|
7084
7346
|
x = np.arange(self.dx / 2. + decalx, float(self.nbx) * self.dx + self.dx / 2 + decalx, self.dx)
|
@@ -7092,12 +7354,25 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
7092
7354
|
triang.set_mask(mask_tri)
|
7093
7355
|
interplin = mtri.LinearTriInterpolator(triang, coords[:,2])
|
7094
7356
|
# Interpolation et récupération dans le numpy.array de l'objet Wolf
|
7357
|
+
|
7358
|
+
# newvalues is an array
|
7095
7359
|
newvalues = interplin(grid_x,grid_y).astype(np.float32)
|
7096
|
-
|
7360
|
+
|
7361
|
+
assert newvalues.shape == (self.nbx, self.nby), _('Bad shape for newvalues')
|
7362
|
+
|
7363
|
+
if keep == 'below':
|
7364
|
+
newvalues = np.ma.masked_array(newvalues, mask=(newvalues > self.array.data))
|
7365
|
+
elif keep == 'above':
|
7366
|
+
newvalues = np.ma.masked_array(newvalues, mask=(newvalues < self.array.data))
|
7367
|
+
|
7368
|
+
nonmasked_values = np.where(~newvalues.mask)
|
7369
|
+
|
7370
|
+
self.array.data[nonmasked_values] = newvalues[nonmasked_values]
|
7097
7371
|
except:
|
7098
7372
|
raise Warning(_('Bad triangulation - try with another method like Scipy'))
|
7099
7373
|
else:
|
7100
7374
|
if grid_x is None and grid_y is None:
|
7375
|
+
|
7101
7376
|
decalx = self.origx + self.translx
|
7102
7377
|
decaly = self.origy + self.transly
|
7103
7378
|
x = np.arange(self.dx / 2. + decalx, float(self.nbx) * self.dx + self.dx / 2 + decalx, self.dx)
|
@@ -7108,22 +7383,80 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
7108
7383
|
triang = mtri.Triangulation(coords[:,0],coords[:,1],triangles)
|
7109
7384
|
interplin = mtri.LinearTriInterpolator(triang, coords[:,2])
|
7110
7385
|
# Interpolation et récupération dans le numpy.array de l'objet Wolf
|
7111
|
-
newvalues = np.ma.masked_array([interplin(x, y) for x, y in zip(grid_x.
|
7386
|
+
newvalues = np.ma.masked_array([interplin(x, y) for x, y in zip(grid_x.ravel(), grid_y.ravel())])
|
7112
7387
|
# newvalues = interplin(grid_x,grid_y).astype(np.float32)
|
7113
|
-
|
7388
|
+
|
7389
|
+
nonmasked_values = np.where(~newvalues.mask)
|
7390
|
+
grid_x = grid_x.ravel()[nonmasked_values]
|
7391
|
+
grid_y = grid_y.ravel()[nonmasked_values]
|
7392
|
+
newvalues = newvalues[nonmasked_values]
|
7393
|
+
|
7394
|
+
# make a shape (n, 2) from grid_x and grid_y
|
7395
|
+
grid_x = grid_x[:, np.newaxis]
|
7396
|
+
grid_y = grid_y[:, np.newaxis]
|
7397
|
+
# concatenate grid_x and grid_y
|
7398
|
+
grid_ij = self.xy2ij_np(np.concatenate([grid_x, grid_y], axis=1))
|
7399
|
+
|
7400
|
+
if keep == 'below':
|
7401
|
+
newvalues = np.ma.masked_array(newvalues, mask=(newvalues > self.array.data[grid_ij[:,0], grid_ij[:,1]]))
|
7402
|
+
|
7403
|
+
nonmasked_values = np.where(~newvalues.mask)
|
7404
|
+
grid_ij = grid_ij[nonmasked_values]
|
7405
|
+
newvalues = newvalues[nonmasked_values]
|
7406
|
+
|
7407
|
+
elif keep == 'above':
|
7408
|
+
newvalues = np.ma.masked_array(newvalues, mask=(newvalues < self.array.data[grid_ij[:,0], grid_ij[:,1]]))
|
7409
|
+
|
7410
|
+
nonmasked_values = np.where(~newvalues.mask)
|
7411
|
+
grid_ij = grid_ij[nonmasked_values]
|
7412
|
+
newvalues = newvalues[nonmasked_values]
|
7413
|
+
|
7414
|
+
self.array.data[grid_ij[:,0], grid_ij[:,1]] = newvalues
|
7415
|
+
|
7114
7416
|
else:
|
7115
|
-
ij = np.asarray([self.get_ij_from_xy(x, y) for x, y in zip(grid_x.
|
7417
|
+
ij = np.asarray([self.get_ij_from_xy(x, y) for x, y in zip(grid_x.ravel(),grid_y.ravel())])
|
7116
7418
|
|
7117
7419
|
# Opérateur d'interpolation linéaire
|
7118
7420
|
triang = mtri.Triangulation(coords[:,0],coords[:,1],triangles)
|
7119
7421
|
interplin = mtri.LinearTriInterpolator(triang, coords[:,2]) # Interpolation et récupération dans le numpy.array de l'objet Wolf
|
7120
|
-
newvalues = np.ma.masked_array([interplin(x, y) for x, y in zip(grid_x.
|
7422
|
+
newvalues = np.ma.masked_array([interplin(x, y) for x, y in zip(grid_x.ravel(), grid_y.ravel())])
|
7121
7423
|
|
7122
7424
|
if newvalues.mask.shape!=():
|
7123
|
-
|
7124
|
-
|
7425
|
+
nonmasked_values = np.where(~newvalues.mask)
|
7426
|
+
ij = ij[nonmasked_values]
|
7427
|
+
newvalues = newvalues[nonmasked_values]
|
7428
|
+
|
7429
|
+
if keep == 'below':
|
7430
|
+
newvalues = np.ma.masked_array(newvalues, mask=(newvalues > self.array.data[ij[:, 0], ij[:, 1]]))
|
7431
|
+
|
7432
|
+
nonmasked_values = np.where(~newvalues.mask)
|
7433
|
+
ij = ij[nonmasked_values]
|
7434
|
+
newvalues = newvalues[nonmasked_values]
|
7435
|
+
|
7436
|
+
elif keep == 'above':
|
7437
|
+
newvalues = np.ma.masked_array(newvalues, mask=(newvalues < self.array.data[ij[:, 0], ij[:, 1]]))
|
7438
|
+
|
7439
|
+
nonmasked_values = np.where(~newvalues.mask)
|
7440
|
+
ij = ij[nonmasked_values]
|
7441
|
+
newvalues = newvalues[nonmasked_values]
|
7442
|
+
|
7443
|
+
self.array.data[ij[:, 0], ij[:, 1]] = newvalues
|
7125
7444
|
else:
|
7126
|
-
|
7445
|
+
if keep == 'below':
|
7446
|
+
newvalues = np.ma.masked_array(newvalues, mask=(newvalues > self.array.data[ij[:, 0], ij[:, 1]]))
|
7447
|
+
|
7448
|
+
nonmasked_values = np.where(~newvalues.mask)
|
7449
|
+
ij = ij[nonmasked_values]
|
7450
|
+
newvalues = newvalues[nonmasked_values]
|
7451
|
+
|
7452
|
+
elif keep == 'above':
|
7453
|
+
newvalues = np.ma.masked_array(newvalues, mask=(newvalues < self.array.data[ij[:, 0], ij[:, 1]]))
|
7454
|
+
|
7455
|
+
nonmasked_values = np.where(~newvalues.mask)
|
7456
|
+
ij = ij[nonmasked_values]
|
7457
|
+
newvalues = newvalues[nonmasked_values]
|
7458
|
+
|
7459
|
+
self.array.data[ij[:, 0], ij[:, 1]] = newvalues
|
7127
7460
|
|
7128
7461
|
#on force les valeurs masquées à nullvalue afin que l'interpolation n'applique pas ses effets dans cette zone
|
7129
7462
|
self.array.data[self.array.mask]= self.nullvalue
|
@@ -7131,13 +7464,15 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
7131
7464
|
use_scipy=True
|
7132
7465
|
|
7133
7466
|
if interp_method != 'matplotlib' or use_scipy:
|
7467
|
+
# We need to convert the triangle to a vector to call the interpolation
|
7468
|
+
|
7134
7469
|
for curtri in triangles:
|
7135
7470
|
curvec = vector(is2D=False)
|
7136
7471
|
for curpt in curtri:
|
7137
|
-
curvec.add_vertex(wolfvertex(coords[curpt,0],coords[curpt,1], coords[curpt,2]))
|
7472
|
+
curvec.add_vertex(wolfvertex(coords[curpt,0], coords[curpt,1], coords[curpt,2]))
|
7138
7473
|
curvec.close_force()
|
7139
7474
|
|
7140
|
-
self.interpolate_on_polygon(curvec, "linear")
|
7475
|
+
self.interpolate_on_polygon(curvec, "linear", keep)
|
7141
7476
|
|
7142
7477
|
self.reset_plot()
|
7143
7478
|
return
|
@@ -8558,7 +8893,7 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
8558
8893
|
:param step_factor: step factor for the discretization of myvect (<1 for thinner, >1 for coarser)
|
8559
8894
|
"""
|
8560
8895
|
|
8561
|
-
if step_factor
|
8896
|
+
if step_factor>1.0:
|
8562
8897
|
logging.warning("Step_factor greater than 1.0 may lead to lots of missing (i,j) even if faster")
|
8563
8898
|
else:
|
8564
8899
|
def mod_fix(x, y, tol=1e-10):
|
@@ -10054,7 +10389,12 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
10054
10389
|
nbx = curlist['nbx']
|
10055
10390
|
nby = curlist['nby']
|
10056
10391
|
first = curlist['firstlist']
|
10057
|
-
|
10392
|
+
|
10393
|
+
try:
|
10394
|
+
glDeleteLists(first, nbx * nby)
|
10395
|
+
except Exception as e:
|
10396
|
+
logging.error(_('OpenGL error in WolfArray.delete_lists -- Please report this case with the data file and the context in which the error occured'))
|
10397
|
+
logging.error(e)
|
10058
10398
|
|
10059
10399
|
logging.debug(str(first)+' '+str(nbx * nby))
|
10060
10400
|
|
@@ -11214,7 +11554,9 @@ class WolfArrayMB(WolfArray):
|
|
11214
11554
|
|
11215
11555
|
self.reset_plot()
|
11216
11556
|
|
11217
|
-
def interpolate_on_polygon(self, working_vector: vector,
|
11557
|
+
def interpolate_on_polygon(self, working_vector: vector,
|
11558
|
+
method:Literal["nearest", "linear", "cubic"]="linear",
|
11559
|
+
keep:Literal['all', 'below', 'above'] = 'all'):
|
11218
11560
|
"""
|
11219
11561
|
Interpolation sous un polygone
|
11220
11562
|
|
@@ -11227,12 +11569,14 @@ class WolfArrayMB(WolfArray):
|
|
11227
11569
|
"""
|
11228
11570
|
|
11229
11571
|
for curblock in self.myblocks.values():
|
11230
|
-
curblock.interpolate_on_polygon(working_vector, method)
|
11572
|
+
curblock.interpolate_on_polygon(working_vector, method, keep)
|
11231
11573
|
|
11232
|
-
def interpolate_on_polygons(self, working_zone: zone,
|
11574
|
+
def interpolate_on_polygons(self, working_zone: zone,
|
11575
|
+
method:Literal["nearest", "linear", "cubic"]="linear",
|
11576
|
+
keep:Literal['all', 'below', 'above'] = 'all'):
|
11233
11577
|
|
11234
11578
|
for curvector in working_zone.myvectors:
|
11235
|
-
self.interpolate_on_polygon(curvector, method)
|
11579
|
+
self.interpolate_on_polygon(curvector, method, keep)
|
11236
11580
|
|
11237
11581
|
def interpolate_on_polyline(self, working_vector:vector, usemask=True):
|
11238
11582
|
"""
|