wolfhece 2.0.51__py3-none-any.whl → 2.0.53__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/PyGui.py +3 -3
- wolfhece/PyParams.py +13 -7
- wolfhece/apps/version.py +1 -1
- wolfhece/mesh2d/wolf2dprev.py +260 -8
- wolfhece/wolf_array.py +140 -0
- wolfhece/wolf_vrt.py +130 -2
- {wolfhece-2.0.51.dist-info → wolfhece-2.0.53.dist-info}/METADATA +1 -1
- {wolfhece-2.0.51.dist-info → wolfhece-2.0.53.dist-info}/RECORD +11 -11
- {wolfhece-2.0.51.dist-info → wolfhece-2.0.53.dist-info}/WHEEL +0 -0
- {wolfhece-2.0.51.dist-info → wolfhece-2.0.53.dist-info}/entry_points.txt +0 -0
- {wolfhece-2.0.51.dist-info → wolfhece-2.0.53.dist-info}/top_level.txt +0 -0
wolfhece/PyGui.py
CHANGED
@@ -615,7 +615,7 @@ class Wolf2DModel(GenMapManager):
|
|
615
615
|
self.files_others={'Generic file':[
|
616
616
|
('','First parametric file - historical'),
|
617
617
|
('.par','Parametric file - multiblocks')],
|
618
|
-
'
|
618
|
+
'Characteristics':[
|
619
619
|
('.fil','Infiltration hydrographs [m³/s]'),
|
620
620
|
('.mnap','Resulting mesh [-]'),
|
621
621
|
('.trl','Translation to real world [m]')
|
@@ -1147,7 +1147,7 @@ class Wolf2DModel(GenMapManager):
|
|
1147
1147
|
self.myblocfile.write_file()
|
1148
1148
|
|
1149
1149
|
def get_header_MB(self, abs=False):
|
1150
|
-
"""
|
1150
|
+
"""Renvoi d'un header avec les infos multi-blocs"""
|
1151
1151
|
myheader:header_wolf
|
1152
1152
|
myheader = self.mymnap.get_header(abs=abs)
|
1153
1153
|
for curblock in self.mymnap.myblocks.values():
|
@@ -1298,7 +1298,7 @@ class Wolf2DModel(GenMapManager):
|
|
1298
1298
|
ret= _('Text files\n')
|
1299
1299
|
ret+= ('----------\n')
|
1300
1300
|
|
1301
|
-
for key, val in self.files_others['
|
1301
|
+
for key, val in self.files_others['Characteristics']:
|
1302
1302
|
ret += f"{val} : {key}\n"
|
1303
1303
|
|
1304
1304
|
ret +='\n\n'
|
wolfhece/PyParams.py
CHANGED
@@ -640,7 +640,7 @@ class Wolf_Param(wx.Frame):
|
|
640
640
|
if(genGroup != ""):
|
641
641
|
dict_param_def = self.myIncParam[genGroup][genParam]["Dict"][genParam]
|
642
642
|
else:
|
643
|
-
dict_param_def = self.myIncParam[group][genParam]["Dict"]
|
643
|
+
dict_param_def = self.myIncParam[group][genParam]["Dict"][genParam]
|
644
644
|
|
645
645
|
elif(genGroup != ""):
|
646
646
|
dict_param_def = self.myIncGroup[genGroup]["Dict"][param_name]
|
@@ -1239,7 +1239,7 @@ class Wolf_Param(wx.Frame):
|
|
1239
1239
|
curdict["Saved"] = {}
|
1240
1240
|
|
1241
1241
|
#pointage du param courant dans le dict de référence
|
1242
|
-
curparam=curdict["Dict"]
|
1242
|
+
curparam = curdict["Dict"][paramloc[0]] = {}
|
1243
1243
|
else:
|
1244
1244
|
#création d'un dict sur base du nom de paramètre
|
1245
1245
|
curparam=groupdict[paramloc[0]]={}
|
@@ -1916,6 +1916,12 @@ class Wolf_Param(wx.Frame):
|
|
1916
1916
|
savedDict[curGroup] = {}
|
1917
1917
|
|
1918
1918
|
templateDict = self.myIncParam[genGroup][curIncParam]["Dict"]
|
1919
|
+
|
1920
|
+
if curIncParam in templateDict.keys():
|
1921
|
+
templateDict = templateDict[curIncParam]
|
1922
|
+
else:
|
1923
|
+
logging.error(_("ERROR : the template of the incrementable parameter does not exist!"))
|
1924
|
+
|
1919
1925
|
if(nbElements is None):
|
1920
1926
|
if self.wx_exists:
|
1921
1927
|
wx.MessageBox(_('The reference of the incrementable group does not exist!'), _('Error'), wx.OK|wx.ICON_ERROR)
|
@@ -1943,11 +1949,11 @@ class Wolf_Param(wx.Frame):
|
|
1943
1949
|
else:
|
1944
1950
|
self.myparams[curGroup][curParam] = {}
|
1945
1951
|
self.myparams[curGroup][curParam][key_Param.NAME] = curParam
|
1946
|
-
self.myparams[curGroup][curParam][key_Param.VALUE] = templateDict[
|
1947
|
-
self.myparams[curGroup][curParam][key_Param.COMMENT] = templateDict[
|
1948
|
-
self.myparams[curGroup][curParam][key_Param.TYPE] = templateDict[
|
1949
|
-
if key_Param.ADDED_JSON in templateDict
|
1950
|
-
self.myparams[curGroup][curParam][key_Param.ADDED_JSON] = templateDict[
|
1952
|
+
self.myparams[curGroup][curParam][key_Param.VALUE] = templateDict[key_Param.VALUE]
|
1953
|
+
self.myparams[curGroup][curParam][key_Param.COMMENT] = templateDict[key_Param.COMMENT]
|
1954
|
+
self.myparams[curGroup][curParam][key_Param.TYPE] = templateDict[key_Param.TYPE]
|
1955
|
+
if key_Param.ADDED_JSON in templateDict:
|
1956
|
+
self.myparams[curGroup][curParam][key_Param.ADDED_JSON] = templateDict[key_Param.ADDED_JSON]
|
1951
1957
|
|
1952
1958
|
# transfert des paramètres en surplus dans le dictionnaire savedDict
|
1953
1959
|
for i in range(nbElements+1, iterMax+1):
|
wolfhece/apps/version.py
CHANGED
wolfhece/mesh2d/wolf2dprev.py
CHANGED
@@ -12,6 +12,7 @@ except:
|
|
12
12
|
import numpy as np
|
13
13
|
import shutil
|
14
14
|
from os.path import exists
|
15
|
+
from os import makedirs
|
15
16
|
import matplotlib.pyplot as plt
|
16
17
|
import matplotlib.path as mpltPath
|
17
18
|
import wx
|
@@ -19,7 +20,7 @@ import logging
|
|
19
20
|
from enum import Enum
|
20
21
|
|
21
22
|
from ..wolf_array import WOLF_ARRAY_FULL_INTEGER, WOLF_ARRAY_FULL_SINGLE, WolfArray, WolfArrayMB, WolfArrayMNAP, \
|
22
|
-
header_wolf, WolfArray_Sim2D, WolfArrayMNAP, WOLF_ARRAY_MB_SINGLE, WOLF_ARRAY_FULL_LOGICAL, WOLF_ARRAY_FULL_SINGLE, getkeyblock
|
23
|
+
header_wolf, WolfArray_Sim2D, WolfArrayMNAP, WOLF_ARRAY_MB_SINGLE, WOLF_ARRAY_FULL_LOGICAL, WOLF_ARRAY_FULL_SINGLE, getkeyblock, WOLF_ARRAY_MB_INTEGER
|
23
24
|
|
24
25
|
from ..PyVertexvectors import *
|
25
26
|
from ..PyVertex import getIfromRGB
|
@@ -2998,11 +2999,27 @@ class xy_file():
|
|
2998
2999
|
|
2999
3000
|
|
3000
3001
|
class prev_sim2D():
|
3002
|
+
"""
|
3003
|
+
Modélisation 2D CPU -- version 2D originale non OO
|
3004
|
+
|
3005
|
+
Cette classe est en construction et ne contient pas encore toutes les fonctionnalités.
|
3006
|
+
|
3007
|
+
Elle devrait à terme être utilisée dans l'objet Wolf2DModel de PyGui afin de séparer
|
3008
|
+
le stockage des données de la visualisation et interface WX.
|
3009
|
+
|
3010
|
+
"""
|
3001
3011
|
|
3002
3012
|
def __init__(self, fname:str) -> None:
|
3013
|
+
"""
|
3014
|
+
Initialisation de la classe
|
3015
|
+
|
3016
|
+
:param fname: nom du fichier générique de simulation - sans extension
|
3017
|
+
"""
|
3003
3018
|
|
3004
3019
|
from pathlib import Path
|
3005
3020
|
|
3021
|
+
fname = str(fname)
|
3022
|
+
|
3006
3023
|
self.filename = fname
|
3007
3024
|
self.mydir = Path(fname).parent.as_posix()
|
3008
3025
|
self.filenamegen = self.filename
|
@@ -3032,7 +3049,7 @@ class prev_sim2D():
|
|
3032
3049
|
self.files_others={'Generic file':[
|
3033
3050
|
('','First parametric file - historical'),
|
3034
3051
|
('.par','Parametric file - multiblocks')],
|
3035
|
-
'
|
3052
|
+
'Characteristics':[
|
3036
3053
|
('.fil','Infiltration hydrographs [m³/s]'),
|
3037
3054
|
('.mnap','Resulting mesh [-]'),
|
3038
3055
|
('.trl','Translation to real world [m]')
|
@@ -3048,7 +3065,16 @@ class prev_sim2D():
|
|
3048
3065
|
]}
|
3049
3066
|
|
3050
3067
|
|
3051
|
-
def get_header(self):
|
3068
|
+
def get_header(self,abs=False):
|
3069
|
+
"""
|
3070
|
+
Renvoi d'un header avec les infos géométriques de la simulation
|
3071
|
+
|
3072
|
+
Version monobloc et résolution fine
|
3073
|
+
|
3074
|
+
:param abs: si True, les origines sont décalées des translations et les translations sont mises à 0
|
3075
|
+
:type abs: bool
|
3076
|
+
"""
|
3077
|
+
|
3052
3078
|
curhead = header_wolf()
|
3053
3079
|
|
3054
3080
|
curhead.nbx = self.myparam.nxfin
|
@@ -3063,10 +3089,22 @@ class prev_sim2D():
|
|
3063
3089
|
curhead.translx = self.myparam.translx
|
3064
3090
|
curhead.transly = self.myparam.transly
|
3065
3091
|
|
3092
|
+
if abs:
|
3093
|
+
curhead.origx += curhead.translx
|
3094
|
+
curhead.origy += curhead.transly
|
3095
|
+
curhead.translx = 0.
|
3096
|
+
curhead.transly = 0.
|
3097
|
+
|
3066
3098
|
return curhead
|
3067
3099
|
|
3068
3100
|
def get_header_MB(self,abs=False):
|
3069
|
-
"""
|
3101
|
+
"""
|
3102
|
+
Renvoi d'un header avec les infos multi-blocs
|
3103
|
+
|
3104
|
+
:param abs: si True, les origines sont décalées des translations et les translations sont mises à 0
|
3105
|
+
:type abs: bool
|
3106
|
+
"""
|
3107
|
+
|
3070
3108
|
myheader:header_wolf
|
3071
3109
|
myheader = self.mymnap.get_header(abs=abs)
|
3072
3110
|
for curblock in self.mymnap.myblocks.values():
|
@@ -3075,7 +3113,12 @@ class prev_sim2D():
|
|
3075
3113
|
|
3076
3114
|
def verify_files(self):
|
3077
3115
|
"""
|
3078
|
-
Vérification de la présence des en-têtes dans les différents fichiers
|
3116
|
+
Vérification de la présence des en-têtes dans les différents fichiers présents sur disque.
|
3117
|
+
|
3118
|
+
Cette routine est nécessaire pour s'assurer de la cohérence des headers. Certaines versions de l'interface VB6
|
3119
|
+
présentaient un bug lors de la sauvegarde des fichiers ce qui peut avoir comme conséquence de décaler les données
|
3120
|
+
(double application des translations vers le monde réel).
|
3121
|
+
|
3079
3122
|
"""
|
3080
3123
|
|
3081
3124
|
fhead = self.get_header()
|
@@ -3087,7 +3130,7 @@ class prev_sim2D():
|
|
3087
3130
|
if exists(fname):
|
3088
3131
|
logging.info(f'Verifying header for {fname}')
|
3089
3132
|
fname += '.txt'
|
3090
|
-
fhead.write_txt_header(fname,wolftype)
|
3133
|
+
fhead.write_txt_header(fname, wolftype, forceupdate=True)
|
3091
3134
|
|
3092
3135
|
mb = self.files_MB_array['Initial Conditions']
|
3093
3136
|
for curextent,text,wolftype in mb:
|
@@ -3095,10 +3138,219 @@ class prev_sim2D():
|
|
3095
3138
|
if exists(fname):
|
3096
3139
|
logging.info(f'Verifying header for {fname}')
|
3097
3140
|
fname += '.txt'
|
3098
|
-
mbhead.write_txt_header(fname,wolftype)
|
3141
|
+
mbhead.write_txt_header(fname, wolftype, forceupdate=True)
|
3099
3142
|
|
3100
3143
|
fname = self.filenamegen + '.lst'
|
3101
3144
|
if not exists(fname):
|
3102
3145
|
logging.warning(f'File {fname} does not exist -- Creating it')
|
3103
3146
|
with open(fname,'w') as f:
|
3104
|
-
f.write('0\n')
|
3147
|
+
f.write('0\n')
|
3148
|
+
|
3149
|
+
@property
|
3150
|
+
def is_multiblock(self):
|
3151
|
+
return self.mymnap.nb_blocks>1
|
3152
|
+
|
3153
|
+
@property
|
3154
|
+
def nb_blocks(self):
|
3155
|
+
return self.mymnap.nb_blocks
|
3156
|
+
|
3157
|
+
def read_fine_array(self, which:Literal['.top', '.hbin', '.qxbin', '.qybin', '.napbin', '.topini_fine', '.frot', '.inf']=''):
|
3158
|
+
"""
|
3159
|
+
Lecture d'une matrice fine
|
3160
|
+
|
3161
|
+
@param which: suffixe du fichier
|
3162
|
+
@type which: str -- extension with point (e.g. '.hbin')
|
3163
|
+
"""
|
3164
|
+
|
3165
|
+
if Path(self.filenamegen + which).exists():
|
3166
|
+
myarray = WolfArray(fname = self.filenamegen + which)
|
3167
|
+
myarray.mask_reset()
|
3168
|
+
|
3169
|
+
else:
|
3170
|
+
logging.error(f"File {self.filenamegen + which} does not exist")
|
3171
|
+
myarray = None
|
3172
|
+
|
3173
|
+
return myarray
|
3174
|
+
|
3175
|
+
def read_MB_array(self, which:Literal['.hbinb', '.qxbinb', '.qybinb', '.frotini', '.topini']=''):
|
3176
|
+
"""
|
3177
|
+
Lecture d'une matrice MB
|
3178
|
+
|
3179
|
+
@param which: suffixe du fichier
|
3180
|
+
@type which: str -- extension with point (e.g. '.hbinb')
|
3181
|
+
"""
|
3182
|
+
|
3183
|
+
if Path(self.filenamegen + which).exists():
|
3184
|
+
myarray =WolfArrayMB()
|
3185
|
+
myarray.set_header(self.get_header_MB())
|
3186
|
+
myarray.filename = self.filenamegen+which
|
3187
|
+
myarray.read_data()
|
3188
|
+
myarray.mask_reset()
|
3189
|
+
else:
|
3190
|
+
logging.error(f"File {self.filenamegen + which} does not exist")
|
3191
|
+
myarray = None
|
3192
|
+
|
3193
|
+
return myarray
|
3194
|
+
|
3195
|
+
def help_files(self) -> str:
|
3196
|
+
"""
|
3197
|
+
Informations sur les fichiers et les types de données qu'ils contiennent.
|
3198
|
+
"""
|
3199
|
+
|
3200
|
+
ret= _('Text files\n')
|
3201
|
+
ret+= ('----------\n')
|
3202
|
+
|
3203
|
+
for key, val in self.files_others['Characteristics']:
|
3204
|
+
ret += f"{val} : {key}\n"
|
3205
|
+
|
3206
|
+
ret +='\n\n'
|
3207
|
+
|
3208
|
+
ret += _('Fine array - monoblock\n')
|
3209
|
+
ret += ('----------------------\n')
|
3210
|
+
|
3211
|
+
for key, val, dtype in self.files_fine_array['Characteristics']:
|
3212
|
+
|
3213
|
+
if dtype == WOLF_ARRAY_FULL_LOGICAL:
|
3214
|
+
ret += f"{val} : {key} [int16]\n"
|
3215
|
+
elif dtype == WOLF_ARRAY_FULL_INTEGER:
|
3216
|
+
ret += f"{val} : {key} [int32]\n"
|
3217
|
+
elif dtype == WOLF_ARRAY_FULL_SINGLE:
|
3218
|
+
ret += f"{val} : {key} [float32]\n"
|
3219
|
+
else:
|
3220
|
+
ret += f"{val} : {key} error - check code\n"
|
3221
|
+
|
3222
|
+
ret +='\n\n'
|
3223
|
+
|
3224
|
+
ret += _('Multiblock arrays\n')
|
3225
|
+
ret += ('-----------------\n')
|
3226
|
+
|
3227
|
+
for key, val, dtype in self.files_MB_array['Initial Conditions']:
|
3228
|
+
|
3229
|
+
if dtype == WOLF_ARRAY_MB_INTEGER:
|
3230
|
+
ret += f"{val} : {key} [int32]\n"
|
3231
|
+
elif dtype == WOLF_ARRAY_MB_SINGLE:
|
3232
|
+
ret += f"{val} : {key} [float32]\n"
|
3233
|
+
else:
|
3234
|
+
ret += f"{val} : {key} error - check code\n"
|
3235
|
+
|
3236
|
+
return ret
|
3237
|
+
|
3238
|
+
def check_infiltration(self) -> str:
|
3239
|
+
"""
|
3240
|
+
Informations sur les zones d'infiltration :
|
3241
|
+
- nombre de zones dans le fichier .inf et .fil
|
3242
|
+
- nombre de cellules de chaque zone
|
3243
|
+
- première maille de chaque zone
|
3244
|
+
- nombre de temps énumérés dans le fichier .fil
|
3245
|
+
- Warning si le nombre de zones est différent entre les fichiers .inf et .fil
|
3246
|
+
|
3247
|
+
"""
|
3248
|
+
|
3249
|
+
ret = _('inside .inf binary file') + '\n'
|
3250
|
+
ret += ('-----------------------') + '\n'
|
3251
|
+
|
3252
|
+
inf = self.read_fine_array('.inf')
|
3253
|
+
|
3254
|
+
maxinf = inf.array.data.max()
|
3255
|
+
ret += _('Maximum infiltration zone : ') + str(maxinf) + '\n'
|
3256
|
+
for i in range(1,maxinf+1):
|
3257
|
+
|
3258
|
+
nb = np.sum(inf.array.data == i)
|
3259
|
+
if nb>0:
|
3260
|
+
indices = np.where(inf.array.data == i)
|
3261
|
+
ret += f"Zone {i} : {nb} cells -- Indices (i,j) of the zone's first cell ({indices[0][0]+1} ; {indices[1][0]+1}) (1-based)\n"
|
3262
|
+
else:
|
3263
|
+
ret += f"Zone {i} : 0 cells\n"
|
3264
|
+
|
3265
|
+
ret += '\n'
|
3266
|
+
|
3267
|
+
ret += _('inside .fil text file') + '\n'
|
3268
|
+
ret += ('----------------------') + '\n'
|
3269
|
+
|
3270
|
+
ret += f"Zones {self.myinfil.nb_zones}" + '\n'
|
3271
|
+
ret += f"Time steps {self.myinfil.nb_steps}" + '\n'
|
3272
|
+
|
3273
|
+
if maxinf != self.myinfil.nb_zones:
|
3274
|
+
ret += _('Warning : number of zones in .inf and .fil files are different') + '\n'
|
3275
|
+
|
3276
|
+
return ret
|
3277
|
+
|
3278
|
+
|
3279
|
+
def copy2gpu(self, dirout:str='') -> str:
|
3280
|
+
"""
|
3281
|
+
Copie des matrices d'une simulation CPU pour le code GPU
|
3282
|
+
|
3283
|
+
:param dirout: répertoire de sortie
|
3284
|
+
:type dirout: str
|
3285
|
+
"""
|
3286
|
+
|
3287
|
+
def to_absolute(array:WolfArray):
|
3288
|
+
array.origx += array.translx
|
3289
|
+
array.origy += array.transly
|
3290
|
+
array.translx = 0.
|
3291
|
+
array.transly = 0.
|
3292
|
+
|
3293
|
+
ret = ''
|
3294
|
+
|
3295
|
+
dirout = Path(dirout)
|
3296
|
+
makedirs(dirout, exist_ok=True)
|
3297
|
+
|
3298
|
+
inf = self.read_fine_array('.inf')
|
3299
|
+
to_absolute(inf)
|
3300
|
+
inf.write_all(dirout / 'infiltration_zones.npy')
|
3301
|
+
del(inf)
|
3302
|
+
|
3303
|
+
ret += '.inf --> infiltration_zones.npy [np.int32]\n'
|
3304
|
+
|
3305
|
+
frot = self.read_fine_array('.frot')
|
3306
|
+
to_absolute(frot)
|
3307
|
+
frot.write_all(dirout / 'manning.npy')
|
3308
|
+
del(frot)
|
3309
|
+
|
3310
|
+
ret += '.frot --> manning.npy [np.float32]\n'
|
3311
|
+
|
3312
|
+
hbin = self.read_fine_array('.hbin')
|
3313
|
+
to_absolute(hbin)
|
3314
|
+
hbin.write_all(dirout / 'h.npy')
|
3315
|
+
del(hbin)
|
3316
|
+
|
3317
|
+
ret += '.hbin --> h.npy [np.float32]\n'
|
3318
|
+
|
3319
|
+
qxbin = self.read_fine_array('.qxbin')
|
3320
|
+
to_absolute(qxbin)
|
3321
|
+
qxbin.write_all(dirout / 'qx.npy')
|
3322
|
+
del(qxbin)
|
3323
|
+
|
3324
|
+
ret += '.qxbin --> qx.npy [np.float32]\n'
|
3325
|
+
|
3326
|
+
qybin = self.read_fine_array('.qybin')
|
3327
|
+
to_absolute(qybin)
|
3328
|
+
qybin.write_all(dirout / 'qy.npy')
|
3329
|
+
del(qybin)
|
3330
|
+
|
3331
|
+
ret += '.qybin --> qy.npy [np.float32]\n'
|
3332
|
+
|
3333
|
+
nap = self.read_fine_array('.napbin')
|
3334
|
+
napgpu = np.zeros_like(nap.array.data, dtype = np.uint8)
|
3335
|
+
napgpu[np.where(nap.array.data != 0)] = 1
|
3336
|
+
np.save(dirout / 'nap.npy', napgpu)
|
3337
|
+
|
3338
|
+
ret += '.napbin --> nap.npy [np.uint8]\n'
|
3339
|
+
|
3340
|
+
top = self.read_fine_array('.top')
|
3341
|
+
to_absolute(top)
|
3342
|
+
top.array.data[np.where(napgpu != 1)] = 99999.
|
3343
|
+
top.nullvalue = 99999.
|
3344
|
+
top.write_all(dirout / 'bathymetry.npy')
|
3345
|
+
|
3346
|
+
ret += '.top --> bathymetry.npy [np.float32]\n'
|
3347
|
+
ret += _('Force a value 99999. outside nap')
|
3348
|
+
|
3349
|
+
nb = np.sum(top.array.data != 99999.)
|
3350
|
+
assert nb == np.sum(napgpu == 1), 'Error in couting active cells'
|
3351
|
+
|
3352
|
+
ret += f'\n{nb} active cells in bathymetry.npy'
|
3353
|
+
|
3354
|
+
del(top)
|
3355
|
+
|
3356
|
+
return ret
|
wolfhece/wolf_array.py
CHANGED
@@ -5306,6 +5306,8 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
5306
5306
|
"""
|
5307
5307
|
Change resolution - in place
|
5308
5308
|
|
5309
|
+
:param factor: factor of resolution change -- > 1.0 : decrease resolution, < 1.0 : increase resolution
|
5310
|
+
|
5309
5311
|
If you want to keep current data, copy the WolfArray into a new variable -> newWA = Wolfarray(mold=curWA)
|
5310
5312
|
"""
|
5311
5313
|
operation = operation.lower()
|
@@ -5345,6 +5347,8 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
5345
5347
|
else:
|
5346
5348
|
self.array = np.kron(self.array, np.ones((int(1/factor), int(1/factor)), dtype=self.array.dtype))
|
5347
5349
|
|
5350
|
+
self.mask_reset()
|
5351
|
+
|
5348
5352
|
self.count()
|
5349
5353
|
|
5350
5354
|
def read_txt_header(self):
|
@@ -7035,6 +7039,142 @@ class WolfArrayMB(WolfArray):
|
|
7035
7039
|
self.myblocks[key].isblock = True
|
7036
7040
|
self.myblocks[key].blockindex = id
|
7037
7041
|
self.myblocks[key].idx = key
|
7042
|
+
|
7043
|
+
def set_header_from_added_blocks(self):
|
7044
|
+
""" Set header from blocks """
|
7045
|
+
|
7046
|
+
if len(self.myblocks) > 0:
|
7047
|
+
|
7048
|
+
origx = min([curblock.origx + curblock.translx for curblock in self.myblocks.values()])
|
7049
|
+
origy = min([curblock.origy + curblock.transly for curblock in self.myblocks.values()])
|
7050
|
+
endx = max([curblock.origx + curblock.translx + curblock.nbx*curblock.dx for curblock in self.myblocks.values()])
|
7051
|
+
endy = max([curblock.origy + curblock.transly + curblock.nby*curblock.dy for curblock in self.myblocks.values()])
|
7052
|
+
|
7053
|
+
self.dx = endx - origx
|
7054
|
+
self.dy = endy - origy
|
7055
|
+
|
7056
|
+
self.nbx = 1
|
7057
|
+
self.nby = 1
|
7058
|
+
|
7059
|
+
self.origx = origx
|
7060
|
+
self.origy = origy
|
7061
|
+
|
7062
|
+
self.translx = 0.
|
7063
|
+
self.transly = 0.
|
7064
|
+
|
7065
|
+
def as_WolfArray(self, abs:bool=True, forced_header:header_wolf = None) -> WolfArray:
|
7066
|
+
"""
|
7067
|
+
Convert to WolfArray
|
7068
|
+
|
7069
|
+
Rebin blocks if necessary
|
7070
|
+
"""
|
7071
|
+
|
7072
|
+
newArray = WolfArray()
|
7073
|
+
|
7074
|
+
if forced_header is None:
|
7075
|
+
myhead = self.get_header(abs=abs)
|
7076
|
+
else:
|
7077
|
+
myhead = forced_header
|
7078
|
+
myhead.wolftype = self.wolftype
|
7079
|
+
|
7080
|
+
dx = set([curblock.get_header().dx for curblock in iter(self.myblocks.values())])
|
7081
|
+
dy = set([curblock.get_header().dy for curblock in iter(self.myblocks.values())])
|
7082
|
+
|
7083
|
+
if len(dx) == 1 and len(dy) == 1:
|
7084
|
+
# only one resolution
|
7085
|
+
|
7086
|
+
newArray.dx = list(dx)[0]
|
7087
|
+
newArray.dy = list(dy)[0]
|
7088
|
+
|
7089
|
+
newArray.origx = myhead.origx
|
7090
|
+
newArray.origy = myhead.origy
|
7091
|
+
newArray.nbx = int((myhead.nbx*myhead.dx)//newArray.dx)
|
7092
|
+
newArray.nby = int((myhead.nby*myhead.dy)//newArray.dy)
|
7093
|
+
newArray.translx = myhead.translx
|
7094
|
+
newArray.transly = myhead.transly
|
7095
|
+
|
7096
|
+
newArray.wolftype = WOLF_ARRAY_FULL_SINGLE if myhead.wolftype == WOLF_ARRAY_MB_SINGLE else WOLF_ARRAY_FULL_INTEGER
|
7097
|
+
|
7098
|
+
newArray.allocate_ressources()
|
7099
|
+
newArray.array[:,:] = 0
|
7100
|
+
|
7101
|
+
for curblock in self.myblocks.values():
|
7102
|
+
|
7103
|
+
ij = np.where(~curblock.array.mask)
|
7104
|
+
if len(ij[0]) > 0:
|
7105
|
+
if len(ij[0])>0:
|
7106
|
+
i = ij[0]
|
7107
|
+
j = ij[1]
|
7108
|
+
|
7109
|
+
x0, y0 = curblock.get_xy_from_ij(0,0, abs=True)
|
7110
|
+
i0, j0 = newArray.get_ij_from_xy(x0, y0, abs=True)
|
7111
|
+
|
7112
|
+
i_dest = i + i0
|
7113
|
+
j_dest = j + j0
|
7114
|
+
|
7115
|
+
newArray.array[i_dest,j_dest] = curblock.array[i,j]
|
7116
|
+
newArray.array.mask[i_dest,j_dest] = False
|
7117
|
+
else:
|
7118
|
+
logging.debug(f"Block {curblock.idx} is empty or totally masked.")
|
7119
|
+
else:
|
7120
|
+
logging.debug(f"Block {curblock.idx} is empty or totally masked.")
|
7121
|
+
|
7122
|
+
else:
|
7123
|
+
# multiple resolutions
|
7124
|
+
|
7125
|
+
dx = list(dx)
|
7126
|
+
dy = list(dy)
|
7127
|
+
|
7128
|
+
dx.sort()
|
7129
|
+
dy.sort()
|
7130
|
+
|
7131
|
+
newArray.dx = dx[0]
|
7132
|
+
newArray.dy = dy[0]
|
7133
|
+
newArray.origx = myhead.origx
|
7134
|
+
newArray.origy = myhead.origy
|
7135
|
+
newArray.nbx = int((myhead.nbx*myhead.dx)//newArray.dx)
|
7136
|
+
newArray.nby = int((myhead.nby*myhead.dy)//newArray.dy)
|
7137
|
+
newArray.translx = myhead.translx
|
7138
|
+
newArray.transly = myhead.transly
|
7139
|
+
|
7140
|
+
newArray.wolftype = WOLF_ARRAY_FULL_SINGLE if myhead.wolftype == WOLF_ARRAY_MB_SINGLE else WOLF_ARRAY_FULL_INTEGER
|
7141
|
+
|
7142
|
+
newArray.allocate_ressources()
|
7143
|
+
newArray.array[:,:] = 0
|
7144
|
+
|
7145
|
+
for curblock in self.myblocks.values():
|
7146
|
+
|
7147
|
+
if curblock.dx == dx[0] and curblock.dy == dy[0]:
|
7148
|
+
# same resolution
|
7149
|
+
blockArray = curblock
|
7150
|
+
else:
|
7151
|
+
# rebin
|
7152
|
+
|
7153
|
+
factor = dx[0]/curblock.dx
|
7154
|
+
blockArray = WolfArray(mold=curblock)
|
7155
|
+
blockArray.rebin(factor)
|
7156
|
+
|
7157
|
+
|
7158
|
+
ij = np.where(~blockArray.array.mask)
|
7159
|
+
if len(ij[0]) > 0:
|
7160
|
+
if len(ij[0])>0:
|
7161
|
+
i = ij[0]
|
7162
|
+
j = ij[1]
|
7163
|
+
|
7164
|
+
x0, y0 = blockArray.get_xy_from_ij(0,0, abs=True)
|
7165
|
+
i0, j0 = newArray.get_ij_from_xy(x0, y0, abs=True)
|
7166
|
+
|
7167
|
+
i_dest = i + i0
|
7168
|
+
j_dest = j + j0
|
7169
|
+
|
7170
|
+
newArray.array[i_dest,j_dest] = blockArray.array[i,j]
|
7171
|
+
newArray.array.mask[i_dest,j_dest] = False
|
7172
|
+
else:
|
7173
|
+
logging.debug(f"Block {curblock.idx} is empty or totally masked.")
|
7174
|
+
else:
|
7175
|
+
logging.debug(f"Block {curblock.idx} is empty or totally masked.")
|
7176
|
+
|
7177
|
+
return newArray
|
7038
7178
|
class WolfArrayMNAP(WolfArrayMB):
|
7039
7179
|
"""
|
7040
7180
|
Matrice MNAP d'une modélisation WOLF2D
|
wolfhece/wolf_vrt.py
CHANGED
@@ -4,6 +4,8 @@ from osgeo import osr, gdal
|
|
4
4
|
import logging
|
5
5
|
from pathlib import Path
|
6
6
|
|
7
|
+
from .PyVertexvectors import Zones
|
8
|
+
|
7
9
|
def create_vrt(wdir:str, fout:str='out.vrt', format:str='tif'):
|
8
10
|
"""
|
9
11
|
Agglomération de tous les fichiers .tif dans un layer virtuel .vrt
|
@@ -38,6 +40,9 @@ def create_vrt_from_files(files:list[Path]=[], fout:Path='assembly.vrt'):
|
|
38
40
|
if isinstance(fout, str):
|
39
41
|
fout = Path(fout)
|
40
42
|
|
43
|
+
if isinstance(files[0], str):
|
44
|
+
files = [Path(file) for file in files]
|
45
|
+
|
41
46
|
# retain current working directory
|
42
47
|
oldcwd = os.getcwd()
|
43
48
|
# change working directory to the parent of the output file
|
@@ -49,7 +54,7 @@ def create_vrt_from_files(files:list[Path]=[], fout:Path='assembly.vrt'):
|
|
49
54
|
# restore working directory
|
50
55
|
os.chdir(oldcwd)
|
51
56
|
|
52
|
-
def create_vrt_from_files_first_based(files:list[Path]=[], fout:Path='assembly.vrt'):
|
57
|
+
def create_vrt_from_files_first_based(files:list[Path]=[], fout:Path='assembly.vrt', Nodata:float=99999.):
|
53
58
|
"""
|
54
59
|
Agglomération de tous les fichiers énumérés dans files dans un layer virtuel .vrt
|
55
60
|
|
@@ -58,6 +63,9 @@ def create_vrt_from_files_first_based(files:list[Path]=[], fout:Path='assembly.v
|
|
58
63
|
if isinstance(fout, str):
|
59
64
|
fout = Path(fout)
|
60
65
|
|
66
|
+
if isinstance(files[0], str):
|
67
|
+
files = [Path(file) for file in files]
|
68
|
+
|
61
69
|
first = files[0]
|
62
70
|
raster:gdal.Dataset
|
63
71
|
raster = gdal.Open(str(first))
|
@@ -82,7 +90,7 @@ def create_vrt_from_files_first_based(files:list[Path]=[], fout:Path='assembly.v
|
|
82
90
|
yRes=abs(geotr[5]),
|
83
91
|
outputBounds=[xmin,ymin,xmax,ymax],
|
84
92
|
resampleAlg='bilinear',
|
85
|
-
srcNodata=
|
93
|
+
srcNodata=Nodata)
|
86
94
|
|
87
95
|
# retain current working directory
|
88
96
|
oldcwd = os.getcwd()
|
@@ -155,6 +163,126 @@ def crop_vrt(fn:str, crop:list, fout:str=None):
|
|
155
163
|
else:
|
156
164
|
logging.warning('The file does not exist !')
|
157
165
|
|
166
|
+
def create_contours(files:list[Path]=[],
|
167
|
+
fout:Path = 'assembly.vec',
|
168
|
+
color_exterior:tuple=(255,0,0),
|
169
|
+
color_interior:tuple=(0,0,255),
|
170
|
+
width:int=3,
|
171
|
+
ignore_first:bool=True,
|
172
|
+
create_extern:bool = True,
|
173
|
+
create_intern:bool = True,
|
174
|
+
force_mask_border:bool = True) -> Zones:
|
175
|
+
"""
|
176
|
+
Create contour from files
|
177
|
+
|
178
|
+
:param files: list of files to process
|
179
|
+
:type files: list[Path]
|
180
|
+
:param fout: output file
|
181
|
+
:type fout: Path - if None, no output file
|
182
|
+
:param color_exterior: RGB color for exterior contour
|
183
|
+
:type color_exterior: tuple
|
184
|
+
:param color_interior: RGB color for interior contour
|
185
|
+
:type color_interior: tuple
|
186
|
+
:param width: width of the contour
|
187
|
+
:type width: int
|
188
|
+
:param ignore_first: ignore the first file in the list
|
189
|
+
:type ignore_first: bool
|
190
|
+
:param create_extern: create exterior contour
|
191
|
+
:type create_extern: bool
|
192
|
+
:param create_intern: create interior contour
|
193
|
+
:type create_intern: bool
|
194
|
+
:param force_mask_border: force masked data along borders -- [0,:], [-1,:], [:,0], [:,-1
|
195
|
+
:type force_mask_border: bool
|
196
|
+
|
197
|
+
"""
|
198
|
+
|
199
|
+
from tqdm import tqdm
|
200
|
+
from .wolf_array import WolfArray
|
201
|
+
from .PyVertexvectors import Zones, zone, vector, wolfvertex, getIfromRGB
|
202
|
+
|
203
|
+
if isinstance(fout, str):
|
204
|
+
fout = Path(fout)
|
205
|
+
|
206
|
+
if not(create_extern or create_intern):
|
207
|
+
logging.warning('No contour to create !')
|
208
|
+
return None
|
209
|
+
|
210
|
+
emprises = Zones()
|
211
|
+
|
212
|
+
start = 1 if ignore_first else 0
|
213
|
+
|
214
|
+
for file in tqdm(files[start:]):
|
215
|
+
|
216
|
+
curzone = zone(name = str(file.name))
|
217
|
+
emprises.add_zone(curzone, forceparent=True)
|
218
|
+
|
219
|
+
curarray = WolfArray(str(file))
|
220
|
+
|
221
|
+
if force_mask_border:
|
222
|
+
curarray.array.mask[0,:] = True
|
223
|
+
curarray.array.mask[-1,:] = True
|
224
|
+
curarray.array.mask[:,0] = True
|
225
|
+
curarray.array.mask[:,-1] = True
|
226
|
+
else:
|
227
|
+
print_name = False
|
228
|
+
if (~curarray.array.mask[0,:]).any():
|
229
|
+
logging.warning('\nNon masked data along border -- [0,:]\n')
|
230
|
+
print_name = True
|
231
|
+
|
232
|
+
if (~curarray.array.mask[-1,:]).any():
|
233
|
+
pre = '' if print_name else '\n'
|
234
|
+
logging.warning(pre+'Non masked data along border -- [-1,:]\n')
|
235
|
+
print_name = True
|
236
|
+
|
237
|
+
if (~curarray.array.mask[:,0]).any():
|
238
|
+
pre = '' if print_name else '\n'
|
239
|
+
logging.warning(pre+'Non masked data along border -- [:,0]\n')
|
240
|
+
print_name = True
|
241
|
+
|
242
|
+
if (~curarray.array.mask[:,-1]).any():
|
243
|
+
pre = '' if print_name else '\n'
|
244
|
+
logging.warning(pre+'Non masked data along border -- [:,-1]\n')
|
245
|
+
print_name = True
|
246
|
+
|
247
|
+
if print_name:
|
248
|
+
logging.warning(f'File: {file}\n')
|
249
|
+
|
250
|
+
if create_intern:
|
251
|
+
ret = curarray.suxsuy_contour(abs = True)
|
252
|
+
|
253
|
+
curvec = ret[2]
|
254
|
+
curvec.myname = 'contour_utile'
|
255
|
+
curzone.add_vector(curvec, forceparent=True)
|
256
|
+
|
257
|
+
curvec.myprop.color = getIfromRGB(color_interior)
|
258
|
+
curvec.myprop.width = width
|
259
|
+
|
260
|
+
if create_extern:
|
261
|
+
|
262
|
+
bounds = curarray.get_bounds(True)
|
263
|
+
vecrect = vector(name = 'contour_externe')
|
264
|
+
|
265
|
+
curzone.add_vector(vecrect, forceparent=True)
|
266
|
+
|
267
|
+
vecrect.add_vertex((wolfvertex(bounds[0][0], bounds[1][0])))
|
268
|
+
vecrect.add_vertex((wolfvertex(bounds[0][1], bounds[1][0])))
|
269
|
+
vecrect.add_vertex((wolfvertex(bounds[0][1], bounds[1][1])))
|
270
|
+
vecrect.add_vertex((wolfvertex(bounds[0][0], bounds[1][1])))
|
271
|
+
vecrect.close_force()
|
272
|
+
|
273
|
+
vecrect.myprop.color = getIfromRGB(color_exterior)
|
274
|
+
vecrect.myprop.width = width
|
275
|
+
vecrect.myprop.legendvisible = True
|
276
|
+
vecrect.myprop.legendtext = file.name
|
277
|
+
|
278
|
+
sh = vecrect.asshapely_ls()
|
279
|
+
vecrect.myprop.legendx = sh.centroid.x
|
280
|
+
vecrect.myprop.legendy = sh.centroid.y
|
281
|
+
|
282
|
+
if fout is not None:
|
283
|
+
emprises.saveas(str(fout))
|
284
|
+
|
285
|
+
return emprises
|
158
286
|
|
159
287
|
if __name__=='__main__':
|
160
288
|
|
@@ -7,11 +7,11 @@ wolfhece/Model1D.py,sha256=-cMz-ePSYzrKVVDidiDOz6cojEZ3y6u9gIb7RPwT6Y8,476593
|
|
7
7
|
wolfhece/PyConfig.py,sha256=oGSL1WsLM9uinlNP4zGBLK3uHPmBfduUi7R-VtWuRFA,8034
|
8
8
|
wolfhece/PyCrosssections.py,sha256=f4dNYRUGZKePruaaBiTcn5vlrw8TFTj9XwTDrdiF_uU,112450
|
9
9
|
wolfhece/PyDraw.py,sha256=nUHEMpTG0zJvBJYOnreTvAISeP7cLsx14Qyrv-y32OY,344956
|
10
|
-
wolfhece/PyGui.py,sha256
|
10
|
+
wolfhece/PyGui.py,sha256=fx66rJ6vw2m7fw_vElqO8AVDUGlaHG0FgAVwgsbH8NU,59829
|
11
11
|
wolfhece/PyGuiHydrology.py,sha256=wKhR-KthPRyzJ887NmsozmUpm2CIQIwO3IbYORCYjrE,7290
|
12
12
|
wolfhece/PyHydrographs.py,sha256=GKK8U0byI45H9O_e4LAOOi7Aw0Tg7Q0Lx322stPg5IQ,3453
|
13
13
|
wolfhece/PyPalette.py,sha256=SYKYx_vxF_FVuceLhcIqFQsivGD6EoO_Xu-EGN9Ivko,22252
|
14
|
-
wolfhece/PyParams.py,sha256
|
14
|
+
wolfhece/PyParams.py,sha256=SMmITkuZ4JYgF7ng3sj7TLUyDbD78mX7Am9ceCkCowg,84945
|
15
15
|
wolfhece/PyPictures.py,sha256=-mJB0JL2YYiEK3D7_ssDkvYiMWK4ve9kXhozQXNeSx8,2216
|
16
16
|
wolfhece/PyTranslate.py,sha256=4appkmNeHHZLFmUtaA_k5_5QL-5ymxnbVN4R2OblmtE,622
|
17
17
|
wolfhece/PyVertex.py,sha256=OFo8VFxTSViWSTzv2paHeJ9O5BkFUyamXrRPFamlWoU,39630
|
@@ -48,11 +48,11 @@ wolfhece/rain_SPWMI.py,sha256=YqsF-yFro3y_a6MfVRFfr-Rxi7NR1gl_i8VX7scmzes,13548
|
|
48
48
|
wolfhece/test_Results2DGPU.py,sha256=NOJ_hFXrcLSQXS1dtsqXRQltqIZtDSHMz_EgAJ2_FHU,307
|
49
49
|
wolfhece/textpillow.py,sha256=zEfLrKhfCDyMaVuQOUjHqz6MGKeQ4aewMxOsWi5-wKI,13832
|
50
50
|
wolfhece/tools_mpl.py,sha256=q8Yc4aukPPiUcEzREvZRM_em67XqXaahdoaNt0DETfE,266
|
51
|
-
wolfhece/wolf_array.py,sha256=
|
51
|
+
wolfhece/wolf_array.py,sha256=GW5XxM-oHgyP-4jRvWEBM4Lw3-_V5jQv7SeLlZ_2rM4,294309
|
52
52
|
wolfhece/wolf_hist.py,sha256=JpRXvzJLUP-RkSkvth3DQWglgTMFI2ZEUDb4RYOfeeI,3284
|
53
53
|
wolfhece/wolf_texture.py,sha256=llQ7aV8scWXIkhpri9XjaPejzoBJsGfsln2ZnlRbFkU,16270
|
54
54
|
wolfhece/wolf_tiles.py,sha256=F2JsJHdAP8fIffNJdG_J26bonCIRtIwMmxKFqdSCRDA,10088
|
55
|
-
wolfhece/wolf_vrt.py,sha256=
|
55
|
+
wolfhece/wolf_vrt.py,sha256=5z6astjCCg2-6BgR6qlNpk043kxOZCClcqNPAMowljk,9707
|
56
56
|
wolfhece/wolf_zi_db.py,sha256=Ok0MxQYZMMLRJN1QY-HSplLhUzzb6gkXgBQ3ihhLQHk,12669
|
57
57
|
wolfhece/wolfresults_2D.py,sha256=5IlGh8MGXKiuzs0de_B73rDC0C9tdAsgXQWhcSMmH8M,155823
|
58
58
|
wolfhece/xyz_file.py,sha256=aQOcTHkHRhXHxL_WxTHwzygp6e47San7SHSpxKQU0dw,5457
|
@@ -66,7 +66,7 @@ wolfhece/apps/check_install.py,sha256=jrKR-njqnpIh6ZJqvP6KbDUPVCfwTNQj4glQhcyzs9
|
|
66
66
|
wolfhece/apps/curvedigitizer.py,sha256=avWERHuVxPnJBOD_ibczwW_XG4vAenqWS8W1zjhBox8,4898
|
67
67
|
wolfhece/apps/isocurrent.py,sha256=4XnNWPa8mYUK7V4zdDRFrHFIXNG2AN2og3TqWKKcqjY,3811
|
68
68
|
wolfhece/apps/splashscreen.py,sha256=m9hMTqzhSUcTudApyNNjoAK9e2u5vgEkJVV79xmfM1s,2118
|
69
|
-
wolfhece/apps/version.py,sha256=
|
69
|
+
wolfhece/apps/version.py,sha256=tMaJUj2jbKD0yIe4bYrNyC4HSMxcSkmAJChhWsP4nSQ,388
|
70
70
|
wolfhece/apps/wolf.py,sha256=gqfm-ZaUJqNsfCzmdtemSeqLw-GVdSVix-evg5WArJI,293
|
71
71
|
wolfhece/apps/wolf2D.py,sha256=gWD9ee2-1pw_nUxjgRaJMuSe4kUT-RWhOeoTt_Lh1mM,267
|
72
72
|
wolfhece/apps/wolf_logo.bmp,sha256=ruJ4MA51CpGO_AYUp_dB4SWKHelvhOvd7Q8NrVOjDJk,3126
|
@@ -211,7 +211,7 @@ wolfhece/mesh2d/bc_manager.py,sha256=vSVogXy1x3A6fZKWA6mPZSGX2e3EAUVmEjD9Bgww_hU
|
|
211
211
|
wolfhece/mesh2d/cell_tracker.py,sha256=AR-Bty-QnrY1ni8Lwak2kU2UWMAJSBCF2ugl2YpfsB4,8660
|
212
212
|
wolfhece/mesh2d/config_manager.py,sha256=vrxLku4isZJTxbHOACEEIEEjQB9pkLpaVPteJz9GhnE,14417
|
213
213
|
wolfhece/mesh2d/cst_2D_boundary_conditions.py,sha256=BaJeKHyJiKEFWBkTQeYsDBW86703ooj65MFVpPMgjLg,2810
|
214
|
-
wolfhece/mesh2d/wolf2dprev.py,sha256=
|
214
|
+
wolfhece/mesh2d/wolf2dprev.py,sha256=_MnOSYn0OHZav7ikkp-40oIe7LglhKLvwwTBZK0pqow,145333
|
215
215
|
wolfhece/models/HECE_169.pptx,sha256=OWJtsWz504A-REFaaxw8lwStHyQU2l7KEeiE7IZvtbk,3396930
|
216
216
|
wolfhece/models/blue.pal,sha256=NnjJnjnYVdQkG54RyPXvo4Tl9ytB0cN7zpiHtj1N6bw,33
|
217
217
|
wolfhece/models/diff16.pal,sha256=Pkp9kQ1GvmAKz3lgwohsw8eQySjVVKHbjhoWw-gZ6Nc,303
|
@@ -256,8 +256,8 @@ wolfhece/sounds/sonsw2.wav,sha256=pFLVt6By0_EPQNt_3KfEZ9a1uSuYTgQSX1I_Zurv9Rc,11
|
|
256
256
|
wolfhece/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
257
257
|
wolfhece/ui/wolf_multiselection_collapsiblepane.py,sha256=yGbU_JsF56jsmms0gh7mxa7tbNQ_SxqhpAZxhm-mTy4,14860
|
258
258
|
wolfhece/ui/wolf_times_selection_comparison_models.py,sha256=wCxGRnE3kzEkWlWA6-3X8ADOFux_B0a5QWJ2GnXTgJw,4709
|
259
|
-
wolfhece-2.0.
|
260
|
-
wolfhece-2.0.
|
261
|
-
wolfhece-2.0.
|
262
|
-
wolfhece-2.0.
|
263
|
-
wolfhece-2.0.
|
259
|
+
wolfhece-2.0.53.dist-info/METADATA,sha256=CQcXOZCu0QZgwPzlep15lih8X1EL970VHL1ur80ouZM,2233
|
260
|
+
wolfhece-2.0.53.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
261
|
+
wolfhece-2.0.53.dist-info/entry_points.txt,sha256=AIu1KMswrdsqNq_2jPtrRIU4tLjuTnj2dCY-pxIlshw,276
|
262
|
+
wolfhece-2.0.53.dist-info/top_level.txt,sha256=EfqZXMVCn7eILUzx9xsEu2oBbSo9liWPFWjIHik0iCI,9
|
263
|
+
wolfhece-2.0.53.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|