wolfhece 2.0.12__py3-none-any.whl → 2.0.13__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 CHANGED
@@ -1680,22 +1680,25 @@ class WolfMapViewer(wx.Frame):
1680
1680
  self.mimicme()
1681
1681
 
1682
1682
  def setsizecanvas(self,width,height):
1683
+ """ Redimensionne la fenêtre graphique """
1683
1684
  self.canvas.SetClientSize(width, height)
1684
1685
 
1685
1686
  def updatescalefactors(self):
1687
+ """ Mise à jour des facteurs d'échelle """
1686
1688
  width, height = self.canvas.GetSize()
1687
1689
 
1688
1690
  self.sx = 1
1689
1691
  self.sy = 1
1690
- if width > 0:
1692
+ if self.width > 0 and width >0 :
1691
1693
  self.sx = float(width) / self.width
1692
- if height > 0:
1694
+ if self.height > 0 and height > 0 :
1693
1695
  self.sy = float(height) / self.height
1694
1696
 
1695
1697
  self.sx = min(self.sx, self.sy)
1696
1698
  self.sy = self.sx
1697
1699
 
1698
1700
  def add_viewer_and_link(self):
1701
+ """ Ajout d'une nouvelle fenêtre de visualisation et liaison avec la fenêtre courante """
1699
1702
  dlg = wx.TextEntryDialog(self, _('Enter a caption for the new window'))
1700
1703
 
1701
1704
  ret = dlg.ShowModal()
@@ -1707,6 +1710,8 @@ class WolfMapViewer(wx.Frame):
1707
1710
  newcap = dlg.GetValue()
1708
1711
  dlg.Destroy()
1709
1712
  newview = WolfMapViewer(None, newcap, w=600, h=600, wxlogging=self.wxlogging, wolfparent=self.wolfparent)
1713
+ newview.add_grid()
1714
+ newview.add_WMS()
1710
1715
 
1711
1716
  if self.linkedList is None:
1712
1717
  self.linkedList = [self]
@@ -1718,11 +1723,15 @@ class WolfMapViewer(wx.Frame):
1718
1723
  curview.linkedList = self.linkedList
1719
1724
  curview.link_shareopsvect = False
1720
1725
 
1726
+ logging.info(_('New viewer added and linked'))
1727
+
1721
1728
  def add_grid(self):
1729
+ """ Ajout d'une grille """
1722
1730
  mygrid = Grid(1000.)
1723
1731
  self.add_object('vector', newobj=mygrid, ToCheck=False, id='Grid')
1724
1732
 
1725
1733
  def add_WMS(self):
1734
+ """ Ajout de couches WMS """
1726
1735
  xmin = 0
1727
1736
  xmax = 0
1728
1737
  ymin = 0
@@ -5523,11 +5532,17 @@ class WolfMapViewer(wx.Frame):
5523
5532
  self.active_zone = self.active_vector.parentzone
5524
5533
  self.active_zones.expand_tree(self.active_zone)
5525
5534
 
5526
- elif self.action == 'select node by node':
5527
- currray: WolfArray
5528
- curarray = self.active_array
5529
- curarray.mngselection.add_node_to_selection(x, y)
5530
- curarray.mngselection.update_nb_nodes_sections()
5535
+ elif 'select node by node' in self.action:
5536
+
5537
+ if 'results' in self.action:
5538
+ curobj:Wolfresults_2D
5539
+ curobj = self.active_res2d.mngselection
5540
+ else:
5541
+ curobj: WolfArray
5542
+ curobj = self.active_array.mngselection
5543
+
5544
+ curobj.add_node_to_selection(x, y)
5545
+ curobj.update_nb_nodes_sections()
5531
5546
  self.Paint()
5532
5547
 
5533
5548
  elif 'select by tmp vector' in self.action or 'select by vector' in self.action:
@@ -6214,7 +6229,7 @@ class WolfMapViewer(wx.Frame):
6214
6229
  elif self.action == 'select active vector2':
6215
6230
  self.end_action(_('End of vector selection'))
6216
6231
 
6217
- elif self.action == 'select node by node':
6232
+ elif 'select node by node' in self.action:
6218
6233
  self.end_action(_('End of node by node selection'))
6219
6234
 
6220
6235
  self.copyfrom = None
@@ -6618,6 +6633,20 @@ class WolfMapViewer(wx.Frame):
6618
6633
  if key == wx.WXK_DELETE:
6619
6634
  self.removeobj()
6620
6635
 
6636
+ elif key == wx.WXK_ESCAPE:
6637
+
6638
+ logging.info(_('Escape key pressed -- Set all active objects and "action" to None'))
6639
+
6640
+ self.action = None
6641
+ self.active_array = None
6642
+ self.active_vector = None
6643
+ self.active_zone = None
6644
+ self.active_zones = None
6645
+ self.active_res2d = None
6646
+ self.active_tile = None
6647
+ self.active_particle_system = None
6648
+ self.active_vertex = None
6649
+
6621
6650
  elif key == ord('C'):
6622
6651
 
6623
6652
  self.copy_canvasogl(mpl = False)
@@ -6712,6 +6741,9 @@ class WolfMapViewer(wx.Frame):
6712
6741
  if self.active_array is not None:
6713
6742
  self.active_array.myops.select_node_by_node()
6714
6743
 
6744
+ if self.active_res2d is not None:
6745
+ self.active_res2d.properties.select_node_by_node()
6746
+
6715
6747
  elif key == ord('V'): # V
6716
6748
  if self.active_array is not None:
6717
6749
  self.active_array.myops.select_vector_inside_manager()
@@ -6907,8 +6939,6 @@ class WolfMapViewer(wx.Frame):
6907
6939
  # Dessin du Front
6908
6940
  self._plotting(draw_type.WMSFORE)
6909
6941
 
6910
- # glFinish()
6911
-
6912
6942
  # Gestion des BC (si actif)
6913
6943
  if self.active_bc is not None:
6914
6944
  self.active_bc.plot()
@@ -6918,7 +6948,7 @@ class WolfMapViewer(wx.Frame):
6918
6948
  # except:
6919
6949
  # pass
6920
6950
 
6921
- glFlush()
6951
+ # glFlush()
6922
6952
  self.canvas.SwapBuffers()
6923
6953
  else:
6924
6954
  raise NameError(
wolfhece/PyGui.py CHANGED
@@ -27,7 +27,7 @@ except:
27
27
  from .PyConfig import WolfConfiguration, ConfigurationKeys
28
28
  from .pylogging import create_wxlogwindow
29
29
 
30
- # FIXME : Is it necessary to override wx.Frame ? WolfMapManager is a wx.Frame.
30
+ # FIXME : Is it necessary to override wx.Frame ? WolfMapManager is a wx.Frame.
31
31
  # Is it sufficient to run a wx.App ?
32
32
  class GenMapManager(wx.Frame):
33
33
  mapviewer:WolfMapViewer
@@ -75,12 +75,12 @@ class GenMapManager(wx.Frame):
75
75
  """
76
76
  Setup of a WolfMapViewer
77
77
  """
78
- self.mapviewer = WolfMapViewer(None,
79
- title=title,
80
- wolfparent= wolfparent,
78
+ self.mapviewer = WolfMapViewer(None,
79
+ title=title,
80
+ wolfparent= wolfparent,
81
81
  wxlogging=self.mylogs)
82
- self.add_grid()
83
- self.add_WMS()
82
+ self.mapviewer.add_grid()
83
+ self.mapviewer.add_WMS()
84
84
 
85
85
  def get_mapviewer(self):
86
86
  # Retourne une instance WolfMapViewer
@@ -89,45 +89,53 @@ class GenMapManager(wx.Frame):
89
89
  def get_configuration(self):
90
90
  return self._configuration
91
91
 
92
- def add_grid(self):
93
- mygrid=Grid(1000.)
94
- self.mapviewer.add_object('vector',newobj=mygrid,ToCheck=False,id='Grid')
95
-
96
- def add_WMS(self):
97
- xmin=0
98
- xmax=0
99
- ymin=0
100
- ymax=0
101
- orthos={'IMAGERIE':{'1971':'ORTHO_1971','1994-2000':'ORTHO_1994_2000',
102
- '2006-2007':'ORTHO_2006_2007',
103
- '2009-2010':'ORTHO_2009_2010',
104
- '2012-2013':'ORTHO_2012_2013',
105
- '2015':'ORTHO_2015','2016':'ORTHO_2016','2017':'ORTHO_2017',
106
- '2018':'ORTHO_2018','2019':'ORTHO_2019','2020':'ORTHO_2020',
107
- '2021':'ORTHO_2021'}}
108
- for idx,(k,item) in enumerate(orthos.items()):
109
- for kdx,(m,subitem) in enumerate(item.items()):
110
- self.mapviewer.add_object(which='wmsback',
111
- newobj=imagetexture('PPNC',m,k,subitem,
112
- self.mapviewer,xmin,xmax,ymin,ymax,-99999,1024),
113
- ToCheck=False,id='PPNC '+m)
114
-
115
- self.mapviewer.add_object(which='wmsback',
116
- newobj=imagetexture('PPNC','Orthos France','OI.OrthoimageCoverage.HR','',
117
- self.mapviewer,xmin,xmax,ymin,ymax,-99999,1024,France=True,epsg='EPSG:27563'),
118
- ToCheck=False,id='Orthos France')
119
-
120
- forelist={'EAU':{'Aqualim':'RES_LIMNI_DGARNE','Alea':'ALEA_INOND','Lidaxes':'LIDAXES','Juillet 2021':'ZONES_INONDEES','Juillet 2021 IDW':'ZONES_INONDEES$IDW'},
121
- 'LIMITES':{'Secteurs Statistiques':'LIMITES_QS_STATBEL'},
122
- 'INSPIRE':{'Limites administratives':'AU_wms'},
123
- 'PLAN_REGLEMENT':{'Plan Percellaire':'CADMAP_2021_PARCELLES'}}
124
-
125
- for idx,(k,item) in enumerate(forelist.items()):
126
- for kdx,(m,subitem) in enumerate(item.items()):
127
- self.mapviewer.add_object(which='wmsfore',
128
- newobj=imagetexture('PPNC',m,k,subitem,
129
- self.mapviewer,xmin,xmax,ymin,ymax,-99999,1024),
130
- ToCheck=False,id=m)
92
+ # def add_grid(self, tomapviewer:WolfMapViewer=None):
93
+ # """ Add a grid to the mapviewer """
94
+ # mygrid=Grid(1000.)
95
+
96
+ # if tomapviewer is None:
97
+ # tomapviewer = self.mapviewer
98
+ # tomapviewer.add_object('vector',newobj=mygrid,ToCheck=False,id='Grid')
99
+
100
+ # def add_WMS(self, tomapviewer:WolfMapViewer=None):
101
+ # """ Add WMS layers to the mapviewer """
102
+ # if tomapviewer is None:
103
+ # tomapviewer = self.mapviewer
104
+
105
+ # xmin=0
106
+ # xmax=0
107
+ # ymin=0
108
+ # ymax=0
109
+ # orthos={'IMAGERIE':{'1971':'ORTHO_1971','1994-2000':'ORTHO_1994_2000',
110
+ # '2006-2007':'ORTHO_2006_2007',
111
+ # '2009-2010':'ORTHO_2009_2010',
112
+ # '2012-2013':'ORTHO_2012_2013',
113
+ # '2015':'ORTHO_2015','2016':'ORTHO_2016','2017':'ORTHO_2017',
114
+ # '2018':'ORTHO_2018','2019':'ORTHO_2019','2020':'ORTHO_2020',
115
+ # '2021':'ORTHO_2021'}}
116
+ # for idx,(k,item) in enumerate(orthos.items()):
117
+ # for kdx,(m,subitem) in enumerate(item.items()):
118
+ # tomapviewer.add_object(which='wmsback',
119
+ # newobj=imagetexture('PPNC',m,k,subitem,
120
+ # tomapviewer,xmin,xmax,ymin,ymax,-99999,1024),
121
+ # ToCheck=False,id='PPNC '+m)
122
+
123
+ # tomapviewer.add_object(which='wmsback',
124
+ # newobj=imagetexture('PPNC','Orthos France','OI.OrthoimageCoverage.HR','',
125
+ # tomapviewer,xmin,xmax,ymin,ymax,-99999,1024,France=True,epsg='EPSG:27563'),
126
+ # ToCheck=False,id='Orthos France')
127
+
128
+ # forelist={'EAU':{'Aqualim':'RES_LIMNI_DGARNE','Alea':'ALEA_INOND','Lidaxes':'LIDAXES','Juillet 2021':'ZONES_INONDEES','Juillet 2021 IDW':'ZONES_INONDEES$IDW'},
129
+ # 'LIMITES':{'Secteurs Statistiques':'LIMITES_QS_STATBEL'},
130
+ # 'INSPIRE':{'Limites administratives':'AU_wms'},
131
+ # 'PLAN_REGLEMENT':{'Plan Percellaire':'CADMAP_2021_PARCELLES'}}
132
+
133
+ # for idx,(k,item) in enumerate(forelist.items()):
134
+ # for kdx,(m,subitem) in enumerate(item.items()):
135
+ # tomapviewer.add_object(which='wmsfore',
136
+ # newobj=imagetexture('PPNC',m,k,subitem,
137
+ # tomapviewer,xmin,xmax,ymin,ymax,-99999,1024),
138
+ # ToCheck=False,id=m)
131
139
 
132
140
  class MapManager(GenMapManager):
133
141
  def __init__(self,*args, **kw):
@@ -294,8 +302,8 @@ class HydrologyModel(GenMapManager):
294
302
  self.mapviewer.add_object(which='other',newobj=self.SPWstations,ToCheck=False,id='SPW-MI stations')
295
303
  self.mapviewer.add_object(which='other',newobj=self.DCENNstations,ToCheck=False,id='SPW-DCENN stations')
296
304
 
297
- self.add_grid()
298
- self.add_WMS()
305
+ self.mapviewer.add_grid()
306
+ self.mapviewer.add_WMS()
299
307
 
300
308
  self.mapviewer.findminmax(True)
301
309
  self.mapviewer.Autoscale(False)
wolfhece/PyPalette.py CHANGED
@@ -480,10 +480,17 @@ class wolfpalette(wx.Frame,LinearSegmentedColormap):
480
480
  myfile.write(str(self.colors[i,1])+'\n')
481
481
  myfile.write(str(self.colors[i,2])+'\n')
482
482
 
483
- def isopop(self,array: ma.masked_array,nbnotnull=99999):
483
+ def isopop(self, array: ma.masked_array, nbnotnull:int=99999):
484
484
  """Remplissage des valeurs de palette sur base d'une équirépartition de valeurs"""
485
485
 
486
486
  sortarray = array.flatten(order='F')
487
+
488
+ idx_nan = np.where(np.isnan(sortarray))
489
+ if idx_nan[0].size > 0:
490
+ sortarray = np.delete(sortarray, idx_nan)
491
+ nbnotnull -= idx_nan[0].size
492
+ logging.warning('NaN values found in array - removed from palette')
493
+
487
494
  sortarray.sort(axis=-1)
488
495
 
489
496
  #valeurs min et max
wolfhece/Results2DGPU.py CHANGED
@@ -18,7 +18,7 @@ try:
18
18
  from wolfgpu.results_store import ResultsStore, ResultType
19
19
  except :
20
20
  logging.error(_("Unable to import wolfgpu.results_store.ResultsStore. Please install wolfgpu package or add a symlink to the wolfgpu package in the wolfhece directory"))
21
- raise ImportError(_("Unable to import wolfgpu.results_store.ResultsStore. Please install wolfgpu package or add a symlink to the wolfgpu package in the wolfhece directory"))
21
+ # raise ImportError(_("Unable to import wolfgpu.results_store.ResultsStore. Please install wolfgpu package or add a symlink to the wolfgpu package in the wolfhece directory"))
22
22
 
23
23
  def _load_res(x) -> tuple[csr_array, csr_array, csr_array]:
24
24
  store:ResultsStore
@@ -721,7 +721,7 @@ class BcManager(wx.Frame):
721
721
  namebc=self._find_EnumName_TypeBC(tbc)
722
722
 
723
723
  if(str(val)!='99999.0'):
724
- text+= "simul.add_boundary_condition(i={}, j={},bc_type=BoundaryConditionsTypes.{}, bc_value={}, border=Direction.{}\n".format(i,j,namebc,val,direction)
724
+ text+= "simul.add_boundary_condition(i={}, j={},bc_type=BoundaryConditionsTypes.{}, bc_value={}, border=Direction.{})\n".format(i,j,namebc,val,direction)
725
725
  return text
726
726
 
727
727
  def parse(self, text:str):
@@ -615,13 +615,14 @@ class Config_Manager_2D_GPU:
615
615
  if (self.workingdir / 'bathymetry.tif').exists():
616
616
  locheader = self.get_header()
617
617
  infilzones = WolfArray(srcheader=locheader, whichtype= WOLF_ARRAY_FULL_INTEGER)
618
- infilzones.array.data[:,:] = -1
619
- infilzones.write_all(str(self.workingdir / 'infiltration_zones.tif'))
618
+ infilzones.array.data[:,:] = 0
619
+ infilzones.nullvalue = -1
620
+ infilzones.write_all(str(self.workingdir / 'infiltration.tif'))
620
621
 
621
- if (self.workingdir / 'infiltration_zones.tif').exists():
622
- logging.info(_('infiltration_zones.tif created and set to -1 ! -- Please edit it !'))
622
+ if (self.workingdir / 'infiltration.tif').exists():
623
+ logging.info(_('infiltration.tif created and set to -1 ! -- Please edit it !'))
623
624
  else:
624
- logging.error(_("infiltration_zones.tif not created ! -- Does 'bathymetry.tif' or any '.tif' file exist in the root directory ?"))
625
+ logging.error(_("infiltration.tif not created ! -- Does 'bathymetry.tif' or any '.tif' file exist in the root directory ?"))
625
626
  else:
626
627
  logging.error(_("No 'bathymetry.tif' file found in the root directory !"))
627
628
 
@@ -1118,6 +1119,10 @@ class UI_Manager_2D_GPU():
1118
1119
 
1119
1120
  self._parent.load_data()
1120
1121
 
1122
+ if allsims is None:
1123
+ logging.error(_('No simulation created !'))
1124
+ return
1125
+
1121
1126
  if len(allsims)>0:
1122
1127
 
1123
1128
  self._txtctrl.write(_('You have created {} simulations\n\n'.format(len(allsims))))
@@ -3,11 +3,15 @@ import ast
3
3
  import importlib.util
4
4
  from pathlib import Path
5
5
  import tempfile
6
+ import logging
6
7
 
7
8
  from wolfhece.wolf_array import WolfArray
8
9
  from wolfhece.PyVertexvectors import Zones, zone, vector, wolfvertex
9
- from wolfgpu.simple_simulation import SimpleSimulation, BoundaryConditionsTypes, Direction
10
10
 
11
+ try:
12
+ from wolfgpu.simple_simulation import SimpleSimulation, BoundaryConditionsTypes, Direction
13
+ except:
14
+ logging.error(_('WOLFGPU not installed !'))
11
15
 
12
16
  class Impose_Boundary_Conditions:
13
17
  """
@@ -0,0 +1,33 @@
1
+ #version 460 core
2
+
3
+ layout (points) in;
4
+ layout (triangle_strip, max_vertices = 4) out;
5
+
6
+ uniform sampler2D texture;
7
+ uniform float zScale;
8
+ uniform float dx;
9
+ uniform float origx;
10
+ uniform float origy;
11
+
12
+ void main() {
13
+
14
+ float halfdx = dx/2.0;
15
+
16
+ vec2 texCoord = (gl_in[0].gl_Position.xy - vec2(origx, origy)) / dx + 0.5;
17
+
18
+ float zValue = texture(texture, texCoord).r * zScale;
19
+
20
+ gl_Position = vec4(gl_in[0].gl_Position.x - halfdx, gl_in[0].gl_Position.y - halfdx, zValue, 1.0);
21
+ EmitVertex();
22
+
23
+ gl_Position = vec4(gl_in[0].gl_Position.x + halfdx, gl_in[0].gl_Position.y - halfdx, zValue, 1.0);
24
+ EmitVertex();
25
+
26
+ gl_Position = vec4(gl_in[0].gl_Position.x + halfdx, gl_in[0].gl_Position.y + halfdx, zValue, 1.0);
27
+ EmitVertex();
28
+
29
+ gl_Position = vec4(gl_in[0].gl_Position.x - halfdx, gl_in[0].gl_Position.y + halfdx, zValue, 1.0);
30
+ EmitVertex();
31
+
32
+ EndPrimitive();
33
+ }
@@ -0,0 +1,7 @@
1
+ #version 460 core
2
+ layout (location = 0) in vec2 aVertex;
3
+
4
+ void main()
5
+ {
6
+ gl_Position = vec4(aVertex, 0.0, 1.0);
7
+ }
wolfhece/wolf_array.py CHANGED
@@ -2443,24 +2443,35 @@ class SelectionData():
2443
2443
  def get_script(self, which:int = None) -> str:
2444
2444
  """ Get script of the current selection or of a stored one """
2445
2445
 
2446
- txt = 'script adapted to a WolfGPU script -- (i,j) are 1-based -- Do not forget to adapt BC type, value and direction\n\n'
2446
+ txt = '# script adapted to a WolfGPU script\n'
2447
+ txt += '# - (i,j) are 1-based for add_boundary_condition -- Do not forget to adapt BC type, value and direction or use BC Manager\n'
2448
+ txt += '# - (i,j) are 0-based for infiltration zones\n\n'
2447
2449
 
2448
2450
  if which is None:
2449
2451
  curlist = self.myselection
2452
+ idx = 0
2450
2453
  else:
2451
2454
  if str(which) in self.selections:
2452
- txt += 'Selection {}\n'.format(which)
2455
+ txt += '# Selection {}\n'.format(which)
2453
2456
  curlist = self.selections[str(which)]['select']
2457
+ idx = which
2454
2458
  else:
2455
2459
  logging.error(_('Selection {} does not exist').format(which))
2456
2460
  return ''
2457
2461
 
2462
+ txt += '# For boundary conditions :\n'
2458
2463
  for cur in curlist:
2459
2464
  i,j = self.parent.get_ij_from_xy(cur[0], cur[1], aswolf=True)
2460
2465
  txt += "simul.add_boundary_condition(i={}, j={}, bc_type=BoundaryConditionsTypes.FROUDE_NORMAL, bc_value=.3, border=Direction.LEFT)".format(i, j) + '\n'
2461
2466
 
2462
- txt += '\n\nIf needed, selection as string :\n'
2467
+ txt += '\n\n# For infiltration zones :\n'
2468
+ for cur in curlist:
2469
+ i,j = self.parent.get_ij_from_xy(cur[0], cur[1], aswolf=True)
2470
+ txt += "infiltration_zones.array[{},{}]={}".format(i-1, j-1, idx) + '\n'
2471
+
2472
+ txt += '\n\n"""If needed, selection as string :\n'
2463
2473
  txt += self.get_string(which)
2474
+ txt += '"""\n'
2464
2475
 
2465
2476
  return txt
2466
2477
 
@@ -2594,7 +2605,8 @@ class SelectionData():
2594
2605
  # le but est de ne conserver que les coordonnées des CG de mailles
2595
2606
  i, j = self.parent.get_ij_from_xy(x, y)
2596
2607
 
2597
- if i>=0 and j>=0 and i<self.parent.nbx and j<self.parent.nby:
2608
+ if self.parent.check_bounds_ij(i, j):
2609
+ # if i>=0 and j>=0 and i<self.parent.nbx and j<self.parent.nby:
2598
2610
  self.add_node_to_selectionij(i, j, verif)
2599
2611
 
2600
2612
  def add_nodes_to_selection(self, xy:list[float], verif:bool=True):
@@ -2688,14 +2700,17 @@ class SelectionData():
2688
2700
  path = mpltPath.Path(myvect.asnparray())
2689
2701
  inside = path.contains_points(mypoints)
2690
2702
 
2691
- if self.parent.myops.selectrestricttomask.IsChecked():
2692
- self.hideselection=True
2703
+ self.hideselection=False
2704
+ if self.parent.myops is not None:
2705
+ if self.parent.myops.selectrestricttomask.IsChecked():
2706
+ self.hideselection=True
2693
2707
 
2694
2708
  self.add_nodes_to_selection(mypoints[np.where(inside)], verif=nbini != 0)
2695
2709
 
2696
- if len(self.myselection) > 0:
2697
- if self.parent.myops.selectrestricttomask.IsChecked():
2698
- self.condition_select('Mask',0)
2710
+ if self.parent.myops is not None:
2711
+ if len(self.myselection) > 0:
2712
+ if self.parent.myops.selectrestricttomask.IsChecked():
2713
+ self.condition_select('Mask',0)
2699
2714
 
2700
2715
  self.hideselection=False
2701
2716
  self.update_nb_nodes_sections()
@@ -2710,8 +2725,9 @@ class SelectionData():
2710
2725
 
2711
2726
  self.add_nodes_to_selectionij(mypoints, verif=nbini != 0)
2712
2727
 
2713
- if self.parent.myops.selectrestricttomask.IsChecked():
2714
- self.condition_select('Mask',0)
2728
+ if self.parent.myops is not None:
2729
+ if self.parent.myops.selectrestricttomask.IsChecked():
2730
+ self.condition_select('Mask',0)
2715
2731
 
2716
2732
  self.update_nb_nodes_sections()
2717
2733
 
@@ -2738,12 +2754,13 @@ class SelectionData():
2738
2754
  else:
2739
2755
  self.update_plot_selection = True
2740
2756
 
2741
- self.parent.myops.nbselect.SetLabelText(str(nb))
2742
- if nb>0:
2743
- self.parent.myops.minx.SetLabelText(str(np.min(np.asarray(self.myselection)[:, 0])))
2744
- self.parent.myops.miny.SetLabelText(str(np.min(np.asarray(self.myselection)[:, 1])))
2745
- self.parent.myops.maxx.SetLabelText(str(np.max(np.asarray(self.myselection)[:, 0])))
2746
- self.parent.myops.maxy.SetLabelText(str(np.max(np.asarray(self.myselection)[:, 1])))
2757
+ if self.parent.myops is not None:
2758
+ self.parent.myops.nbselect.SetLabelText(str(nb))
2759
+ if nb>0:
2760
+ self.parent.myops.minx.SetLabelText(str(np.min(np.asarray(self.myselection)[:, 0])))
2761
+ self.parent.myops.miny.SetLabelText(str(np.min(np.asarray(self.myselection)[:, 1])))
2762
+ self.parent.myops.maxx.SetLabelText(str(np.max(np.asarray(self.myselection)[:, 0])))
2763
+ self.parent.myops.maxy.SetLabelText(str(np.max(np.asarray(self.myselection)[:, 1])))
2747
2764
 
2748
2765
  def condition_select(self, cond, condval, condval2=0, usemask=False):
2749
2766
  array = self.parent.array
@@ -3423,6 +3440,16 @@ class WolfArray(Element_To_Draw, header_wolf):
3423
3440
 
3424
3441
  self.add_ops_sel() # Ajout d'un gestionnaire de sélection et d'opérations
3425
3442
 
3443
+
3444
+ def check_bounds_ij(self, i:int, j:int):
3445
+ """Check if i and j are inside the array bounds"""
3446
+ return i>=0 and j>=0 and i<self.nbx and j<self.nby
3447
+
3448
+ def check_bounds_xy(self, x:float, y:float):
3449
+ """Check if i and j are inside the array bounds"""
3450
+ i,j = self.get_ij_from_xy(x,y)
3451
+ return self.check_bounds_ij(i,j)
3452
+
3426
3453
  def show_properties(self):
3427
3454
  """ Affichage des propriétés de la matrice dans une fenêtre wxPython """
3428
3455
  if self.wx_exists and self.myops is not None:
@@ -3497,6 +3524,15 @@ class WolfArray(Element_To_Draw, header_wolf):
3497
3524
  - mask data outisde linkedvec
3498
3525
  """
3499
3526
  self.array[np.where(self.array<eps)] = 0.
3527
+
3528
+ idx_nan = np.where(np.isnan(self.array))
3529
+ if len(idx_nan[0])>0:
3530
+ self.array[idx_nan] = 0.
3531
+ self.array.mask[idx_nan] = True
3532
+ logging.warning(_('NaN values found in the array'))
3533
+ for i,j in zip(idx_nan[0],idx_nan[1]):
3534
+ logging.warning(f'NaN at {i+1},{j+1} -- 1-based')
3535
+
3500
3536
  if self.linkedvec is not None:
3501
3537
  self.mask_outsidepoly(self.linkedvec)
3502
3538
 
@@ -5666,7 +5702,6 @@ class WolfArray(Element_To_Draw, header_wolf):
5666
5702
 
5667
5703
  self.plotting = False
5668
5704
 
5669
- # glFinish()
5670
5705
  # Plot selected nodes
5671
5706
  if self.mngselection is not None:
5672
5707
  self.mngselection.plot_selection()
@@ -5678,7 +5713,7 @@ class WolfArray(Element_To_Draw, header_wolf):
5678
5713
  def delete_lists(self):
5679
5714
  """ Delete OpenGL lists """
5680
5715
 
5681
- logging.info(_('OpenGL lists - deletion -- array {}'.format(self.idx)))
5716
+ logging.debug(_('OpenGL lists - deletion -- array {}'.format(self.idx)))
5682
5717
  for idx, cursize in enumerate(self.mygrid):
5683
5718
  curlist = self.mygrid[cursize]
5684
5719
  nbx = curlist['nbx']
@@ -6003,6 +6038,18 @@ class WolfArrayMB(WolfArray):
6003
6038
  super().__init__(fname, mold, masknull, crop, whichtype, preload, create, mapviewer, nullvalue, srcheader)
6004
6039
  # self.wolftype = whichtype
6005
6040
 
6041
+ def check_bounds_ij(self, i:int, j:int):
6042
+ """Check if i and j are inside the array bounds"""
6043
+ x,y = self.get_xy_from_ij(i,j)
6044
+ return self.check_bounds_xy(x,y)
6045
+
6046
+ def check_bounds_xy(self, x:float, y:float):
6047
+ """Check if i and j are inside the array bounds"""
6048
+
6049
+ xmin, xmax, ymin, ymax = self.get_bounds()
6050
+
6051
+ return x>=xmin and x<=xmax and y>=ymin and y<=ymax
6052
+
6006
6053
  def __getitem__(self, block_key:Union[int,str]) -> WolfArray:
6007
6054
  """Access a block of this multi-blocks array."""
6008
6055
  if isinstance(block_key,int):
@@ -63,7 +63,7 @@ except Exception as ex:
63
63
 
64
64
  raise Exception(msg)
65
65
 
66
- from .wolf_array import WolfArray, getkeyblock, header_wolf, WolfArrayMB, WolfArrayMNAP, header_wolf
66
+ from .wolf_array import WolfArray, getkeyblock, header_wolf, WolfArrayMB, WolfArrayMNAP, header_wolf, SelectionData
67
67
  from .mesh2d import wolf2dprev
68
68
  from .PyVertexvectors import vector, zone, Zones
69
69
 
@@ -1148,10 +1148,10 @@ class Props_Res_2D(wx.Frame):
1148
1148
 
1149
1149
  # self.myzones.saveas(self.fnsave)
1150
1150
 
1151
- # def select_node_by_node(self):
1152
- # if self._mapviewer is not None:
1153
- # self._mapviewer.action = 'select node by node'
1154
- # self._mapviewer.active_array = self._parent
1151
+ def select_node_by_node(self):
1152
+ if self._mapviewer is not None:
1153
+ self._mapviewer.action = 'select node by node - results'
1154
+ self._mapviewer.active_res2d = self._parent
1155
1155
 
1156
1156
  # def select_zone_inside_manager(self):
1157
1157
 
@@ -2002,6 +2002,36 @@ class Wolfresults_2D(Element_To_Draw):
2002
2002
  self.properties:Props_Res_2D = None
2003
2003
  self.set_properties()
2004
2004
 
2005
+ self.mngselection = SelectionData(self)
2006
+ self.mngselection.dx, self.mngselection.dy = self[0].dx, self[0].dy
2007
+ self.myops = None
2008
+
2009
+ def get_bounds(self, abs=True):
2010
+ """
2011
+ Return bounds in coordinates
2012
+
2013
+ :param abs = if True, add translation to (x, y) (coordinate to global space)
2014
+ :return : tuple of two lists of two floats - ([xmin, xmax],[ymin, ymax])
2015
+ """
2016
+ if abs:
2017
+ return ([self.origx + self.translx, self.origx + self.translx + float(self.nbx) * self.dx],
2018
+ [self.origy + self.transly, self.origy + self.transly + float(self.nby) * self.dy])
2019
+ else:
2020
+ return ([self.origx, self.origx + float(self.nbx) * self.dx],
2021
+ [self.origy, self.origy + float(self.nby) * self.dy])
2022
+
2023
+ def check_bounds_ij(self, i:int, j:int):
2024
+ """Check if i and j are inside the array bounds"""
2025
+ x,y = self.get_xy_from_ij(i,j)
2026
+ return self.check_bounds_xy(x,y)
2027
+
2028
+ def check_bounds_xy(self, x:float, y:float):
2029
+ """Check if i and j are inside the array bounds"""
2030
+
2031
+ (xmin, xmax), (ymin, ymax) = self.get_bounds()
2032
+
2033
+ return x>=xmin and x<=xmax and y>=ymin and y<=ymax
2034
+
2005
2035
  @property
2006
2036
  def nullvalue(self):
2007
2037
  return self.epsilon
@@ -2115,7 +2145,7 @@ class Wolfresults_2D(Element_To_Draw):
2115
2145
 
2116
2146
  def __next__(self):
2117
2147
  self._iter += 1
2118
- return self[self._iter-1]
2148
+ return self[self._iter]
2119
2149
 
2120
2150
  def as_WolfArray(self, copyarray:bool=True) -> Union[WolfArray, WolfArrayMB]:
2121
2151
  """Récupération d'une matrice MB ou Mono sur base du résultat courant"""
@@ -2388,7 +2418,7 @@ class Wolfresults_2D(Element_To_Draw):
2388
2418
  curblock.min_field_size = minsize
2389
2419
 
2390
2420
  if which in views_2D:
2391
- self.delete_lists()
2421
+ # self.delete_lists()
2392
2422
 
2393
2423
  self._which_current_view = which
2394
2424
 
@@ -2419,7 +2449,7 @@ class Wolfresults_2D(Element_To_Draw):
2419
2449
  self.update_zoom_factor()
2420
2450
 
2421
2451
  # self.mypal.automatic = True
2422
- self.reset_plot()
2452
+ # self.reset_plot()
2423
2453
 
2424
2454
  self.plotting=False
2425
2455
  self.mimic_plotdata()
@@ -3292,22 +3322,34 @@ class Wolfresults_2D(Element_To_Draw):
3292
3322
  else:
3293
3323
  return nullvalue
3294
3324
 
3295
- def get_xy_from_ij(self, i, j, which_block, aswolf=False, abs=True):
3325
+ def get_xy_from_ij(self, i:int, j:int, which_block:int=1, aswolf:bool=False, abs:bool=True):
3296
3326
  """
3297
3327
  Retourne les coordonnées (x,y) depuis les indices (i,j) et le numéro de block
3328
+
3329
+ :param i: i index
3330
+ :param j: j index
3331
+ :param which_block: block number; 1-based;
3332
+ :param aswolf: True to add 1 to i and j to match the VB6/Fortran numbering format
3333
+ :param abs: True to return absolute coordinates
3298
3334
  """
3299
3335
 
3300
3336
  x,y = self.myblocks[getkeyblock(which_block,False)].waterdepth.get_xy_from_ij(i, j, aswolf=aswolf, abs=abs)
3301
3337
  return x,y
3302
3338
 
3303
- def get_ij_from_xy(self, x:float, y:float, which_block, aswolf=False, abs=True):
3339
+ def get_ij_from_xy(self, x:float, y:float, which_block:int = 1, aswolf=False, abs=True):
3304
3340
  """
3305
3341
  Retrouve les indices d'un point (x,y) dans un bloc spécifique
3306
3342
 
3307
3343
  Utilise la routine du même nom dans la martrice 'waterdepth'
3344
+
3345
+ :param x: x coordinate
3346
+ :param y: y coordinate
3347
+ :param which_block: block number; 1-based;
3348
+ :param aswolf: True to add 1 to i and j to match the VB6/Fortran numbering format
3349
+ :param abs: True to return absolute coordinates
3308
3350
  """
3309
3351
 
3310
- i,j = self.myblocks[getkeyblock(which_block,False)].waterdepth.get_ij_from_xy(x,y, aswolf=aswolf, abs=abs)
3352
+ i,j = self.myblocks[getkeyblock(which_block, False)].waterdepth.get_ij_from_xy(x,y, aswolf=aswolf, abs=abs)
3311
3353
 
3312
3354
  return i,j # Par défaut en indices Python et non WOLF (VB6/Fortran)
3313
3355
 
@@ -3483,6 +3525,10 @@ class Wolfresults_2D(Element_To_Draw):
3483
3525
  self.myparam.weak_bc_x.myzones.plot()
3484
3526
  self.myparam.weak_bc_y.myzones.plot()
3485
3527
 
3528
+ # Plot selected nodes
3529
+ if self.mngselection is not None:
3530
+ self.mngselection.plot_selection()
3531
+
3486
3532
  self.mimic_plotdata(False)
3487
3533
 
3488
3534
  def fillonecellgrid(self,curscale,loci,locj,force=False):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: wolfhece
3
- Version: 2.0.12
3
+ Version: 2.0.13
4
4
  Author-email: Stéphane Champailler <stephane.champailler@uliege.be>, Pierre Archambeau <pierre.archambeau@uliege.be>
5
5
  Project-URL: Homepage, https://uee.uliege.be/hece
6
6
  Project-URL: Issues, https://uee.uliege.be/hece
@@ -5,11 +5,11 @@ wolfhece/Lidar2002.py,sha256=sXZ6p8_EKI5l8fJswIMAABT6dqHKVexU52Tjl1uuisU,5770
5
5
  wolfhece/ManageParams.py,sha256=Wgt5Zh7QBtyiwTAltPHunSLqt4XuVuRH76GTUrXabS4,219
6
6
  wolfhece/PyConfig.py,sha256=oGSL1WsLM9uinlNP4zGBLK3uHPmBfduUi7R-VtWuRFA,8034
7
7
  wolfhece/PyCrosssections.py,sha256=HtvhSracK8Yz6RCNQCfjzflvend_DtybI9mTb9gnTrs,111048
8
- wolfhece/PyDraw.py,sha256=u9D1rcpiV5Hh_uIfLprP-zYE0JvcScYbFkBCUKRgQiw,297692
9
- wolfhece/PyGui.py,sha256=WWu4CJrmwsih5c6YLoXnxGdtrCi77cefecMaqr_bVzc,52313
8
+ wolfhece/PyDraw.py,sha256=LdJiB4GW-1s-b4VlMge0NYC2XQbb_Q4lIUR3ngYZO9s,298905
9
+ wolfhece/PyGui.py,sha256=mzJCRjMHtebFrxmPnwUK6YpQgMf5iiiCTm0hCOuRsOY,52722
10
10
  wolfhece/PyGuiHydrology.py,sha256=t7EqOMyA1mkVg_aATMaduR-aqs04V-uRCifyHVmPqRs,7133
11
11
  wolfhece/PyHydrographs.py,sha256=2BqsvZSb8WuH22SYxU_BcakfA43yV_qA0ujWQE4uwQo,3407
12
- wolfhece/PyPalette.py,sha256=Y3GHvP-J56IsBeNsgn_bJR3tQwAISMZ9r-tcGIJ55wk,21544
12
+ wolfhece/PyPalette.py,sha256=2nZnI1YlMP658F5A844b9Wnac5QMgaaYAsgpu4_TjP8,21814
13
13
  wolfhece/PyParams.py,sha256=PzGnWzlo7dyw9yaDZ90eS3HrXrPEukN1BOEtTPsthEU,77473
14
14
  wolfhece/PyPictures.py,sha256=wI6t38rmRiNG1pGWTXVW-nWQO2mg8SH7Gf-X2HIi02A,2023
15
15
  wolfhece/PyTranslate.py,sha256=4appkmNeHHZLFmUtaA_k5_5QL-5ymxnbVN4R2OblmtE,622
@@ -20,7 +20,7 @@ wolfhece/RatingCurve.py,sha256=Psw4OknvqVXOjIomJxCW4hGd_q2HZ4DmcwV-wJXehds,21420
20
20
  wolfhece/RatingCurveData.py,sha256=5UvnIm89BwqjnEbLCcY3CA8WoFd_xHJbooNy62fX5iY,57660
21
21
  wolfhece/RatingCurve_xml.py,sha256=iP6hanwG6EzddcWF2zvsuU9JLfrPtq7-AOFwcz2HO8k,24469
22
22
  wolfhece/ReadDataDCENN.py,sha256=4OMDBgkZ_v7OWmVhyQ-reab7MPxGhFEDY2qS8yThhdM,1240
23
- wolfhece/Results2DGPU.py,sha256=JC-bCtBine4i-j9Ab3Hd_xuinuapgxGWRNGU-pchtsI,16016
23
+ wolfhece/Results2DGPU.py,sha256=EeitHU4WsMpHsissLue_w9fxw2JEN2-poNDVnBgeTPg,16018
24
24
  wolfhece/__init__.py,sha256=FRDE8PiJAWxX9PMXsShRMZ8YADAY4WIgKMRh52rmhiw,23
25
25
  wolfhece/_add_path.py,sha256=nudniS-lsgHwXXq5o626XRDzIeYj76GoGKYt6lcu2Nc,616
26
26
  wolfhece/cli.py,sha256=Xj0yfgs7MnvNCk5Td_Qp_oz4DMI66eBHu2bkVrGW3OU,1828
@@ -45,12 +45,12 @@ wolfhece/pywalous.py,sha256=jwp251AzGBc0VmMzOqA0IJiRRa6yQIfccRM8lVGszIY,4474
45
45
  wolfhece/rain_SPWMI.py,sha256=YqsF-yFro3y_a6MfVRFfr-Rxi7NR1gl_i8VX7scmzes,13548
46
46
  wolfhece/textpillow.py,sha256=YJxF4JzPv3G1oqenJgWVYq3OPZx9iFtrmeIfvBwbJVU,8735
47
47
  wolfhece/tools_mpl.py,sha256=q8Yc4aukPPiUcEzREvZRM_em67XqXaahdoaNt0DETfE,266
48
- wolfhece/wolf_array.py,sha256=vJFPzqNPloV_oQrl6Q2UvhaLHxCXnAWu_MqsfzZTzm0,276260
48
+ wolfhece/wolf_array.py,sha256=eMdZcBQIqvBqIjzhYd-zKmsh50xnDpYZSbMt1EzTbZw,278186
49
49
  wolfhece/wolf_hist.py,sha256=JpRXvzJLUP-RkSkvth3DQWglgTMFI2ZEUDb4RYOfeeI,3284
50
50
  wolfhece/wolf_texture.py,sha256=quflEvi32lWSvOPa0aDCDl-8Jv-jGtLHbR2rdx67LsI,14883
51
51
  wolfhece/wolf_tiles.py,sha256=F2JsJHdAP8fIffNJdG_J26bonCIRtIwMmxKFqdSCRDA,10088
52
52
  wolfhece/wolf_vrt.py,sha256=wuMPAXNYTByNGNtvWhwW1fQelPstAPTQZECgXHZ0oTM,5180
53
- wolfhece/wolfresults_2D.py,sha256=wiHpAQ8W6X3lyE3XkJBMEB198Pbp3i96WslCUXZjI2I,142147
53
+ wolfhece/wolfresults_2D.py,sha256=l0E84-4h9AeyGGsrVaUSo5QZB8mjyf7TnKnhTlY7RA0,144087
54
54
  wolfhece/xyz_file.py,sha256=aQOcTHkHRhXHxL_WxTHwzygp6e47San7SHSpxKQU0dw,5457
55
55
  wolfhece/apps/ManageParams.py,sha256=its7JhceQiwzQVl95wA51GZs1zjtbpUNvbqvdvDTeyM,316
56
56
  wolfhece/apps/Optimisation_hydro.py,sha256=25H5PVN_Gh3mkDQ6BWbJjBqsGCNdGapZOqKECcOGJIQ,398
@@ -200,7 +200,7 @@ wolfhece/mar/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
200
200
  wolfhece/mar/commontools.py,sha256=vCmoNI2sMOco6Y4KPpKb7WORq45qFU_lSxbKGV9oZ8A,53824
201
201
  wolfhece/mar/interface_MAR_WOLF.py,sha256=MWeXaHLDT4Eo9jZOAvz013lmpgGYT1v9VUYGAgBgSRU,21454
202
202
  wolfhece/mesh2d/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
203
- wolfhece/mesh2d/bc_manager.py,sha256=8WTKkWX_mwp-AihFkJWrcWxugrUTbTnAO4H867QLOkc,51172
203
+ wolfhece/mesh2d/bc_manager.py,sha256=vSVogXy1x3A6fZKWA6mPZSGX2e3EAUVmEjD9Bgww_hU,51173
204
204
  wolfhece/mesh2d/cell_tracker.py,sha256=AR-Bty-QnrY1ni8Lwak2kU2UWMAJSBCF2ugl2YpfsB4,8660
205
205
  wolfhece/mesh2d/config_manager.py,sha256=0zVoSD4DNsm_180d8ulDLy8EGFBhTUVApBvRpY730Zk,15284
206
206
  wolfhece/mesh2d/cst_2D_boundary_conditions.py,sha256=BaJeKHyJiKEFWBkTQeYsDBW86703ooj65MFVpPMgjLg,2810
@@ -224,19 +224,21 @@ wolfhece/rem/RasterViz.py,sha256=TDhWyMppcYBL71HfhpZuMgYKhz7faZg-MEOQJo_3Ivo,291
224
224
  wolfhece/rem/__init__.py,sha256=S2-J5uEGK_VaMFjRUYFIdSScJjZyuXH4RmMmnG3OG7I,19
225
225
  wolfhece/scenario/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
226
226
  wolfhece/scenario/check_scenario.py,sha256=Q0_jA3PYapcbCT881YojTwKoRi_RjZpevHXhtP9VoqE,4619
227
- wolfhece/scenario/config_manager.py,sha256=mcad9PXsMVYDLCCAYWbun_oercmEpt7pABVW6dfYUCA,55123
228
- wolfhece/scenario/imposebc_void.py,sha256=59MFld_jJq1m0O8f4Dlh_1wtBlHKNTCEjbEK2A1EaUo,5163
227
+ wolfhece/scenario/config_manager.py,sha256=kYN2V82B8nwUUBmhPzoTATAPVncSg1s7pf4Inp_8WcU,55245
228
+ wolfhece/scenario/imposebc_void.py,sha256=rZs_y0-dOeiHEw_hJyiPeEyL2fmOve-sFtrV57SWhe8,5247
229
229
  wolfhece/scenario/update_void.py,sha256=r9ztr9LlJbd6BgOK-KWpYvUAUakZCyze58-olucbVcI,7156
230
+ wolfhece/shaders/quad_geom_shader.glsl,sha256=cHLwA6RfHIbzCB8S0Pu6C2Wi1i-DtGBYJdZWq-YBQ3M,922
230
231
  wolfhece/shaders/simple_fragment_shader.glsl,sha256=rk8uBroc8MX8r8K3S71zCSSMGtU27ChZIna-sTiIS9A,112
231
232
  wolfhece/shaders/simple_vertex_shader.glsl,sha256=crJlvIx-nNcUpKyK4KpJWR789xG-RqSa56yr4DRq4d4,285
233
+ wolfhece/shaders/simple_vertex_shader_wo_mvp.glsl,sha256=CT5dr1s0kdL90MtZi22DelFzFVns-w0XcrVbPan6yOc,122
232
234
  wolfhece/sounds/son12.wav,sha256=iZJYSrKkE4HLXJwWzszVR07w_3d-WLO8npFlUcxQlrc,12664
233
235
  wolfhece/sounds/son6.wav,sha256=v7CFE-PlGvVcRC3oAaWBBGngutCDS_MUiCIhNHkpv2Y,7884
234
236
  wolfhece/sounds/sonsw1.wav,sha256=HhuGeZ3iIyJdDALmM-jvGZDkKw3IZ3JXCuQZkN3Zjtc,212550
235
237
  wolfhece/sounds/sonsw2.wav,sha256=pFLVt6By0_EPQNt_3KfEZ9a1uSuYTgQSX1I_Zurv9Rc,110636
236
238
  wolfhece/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
237
239
  wolfhece/ui/wolf_multiselection_collapsiblepane.py,sha256=yGbU_JsF56jsmms0gh7mxa7tbNQ_SxqhpAZxhm-mTy4,14860
238
- wolfhece-2.0.12.dist-info/METADATA,sha256=3-XSmtZBypcBJa0GTKvUpFQQXO-Qtv_Xd4ctVXrdUxA,2053
239
- wolfhece-2.0.12.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
240
- wolfhece-2.0.12.dist-info/entry_points.txt,sha256=IHhq-i2W9QpyXFHKe2Ld8j1R4hW5DmYqrZsuSsXkdEE,245
241
- wolfhece-2.0.12.dist-info/top_level.txt,sha256=EfqZXMVCn7eILUzx9xsEu2oBbSo9liWPFWjIHik0iCI,9
242
- wolfhece-2.0.12.dist-info/RECORD,,
240
+ wolfhece-2.0.13.dist-info/METADATA,sha256=MzxbbpRv4ctOCVW9othMrQX-JbdBAkSk5BUYX3Fs4rM,2053
241
+ wolfhece-2.0.13.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
242
+ wolfhece-2.0.13.dist-info/entry_points.txt,sha256=IHhq-i2W9QpyXFHKe2Ld8j1R4hW5DmYqrZsuSsXkdEE,245
243
+ wolfhece-2.0.13.dist-info/top_level.txt,sha256=EfqZXMVCn7eILUzx9xsEu2oBbSo9liWPFWjIHik0iCI,9
244
+ wolfhece-2.0.13.dist-info/RECORD,,