wolfhece 1.8.7__py3-none-any.whl → 1.8.9__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/PyWatershed.py DELETED
@@ -1,1686 +0,0 @@
1
- import os
2
- from scipy.interpolate import interpolate
3
- from matplotlib import figure as mplfig
4
- import matplotlib.pyplot as plt
5
-
6
- from .PyTranslate import _
7
- from .PyVertex import wolfvertex
8
- from .wolf_array import *
9
- from .PyCrosssections import crosssections
10
- from .GraphNotebook import PlotNotebook
11
-
12
- listdem=['dem1','dem2','dem10m','dem20m','cs']
13
- #listdem=['dem2']
14
-
15
- class node_watershed:
16
- """Noeud du modèle hydrologique maillé"""
17
- i:int
18
- j:int
19
- index:int
20
-
21
- dem:dict
22
- demdelta:float
23
-
24
- mycs:list = None
25
-
26
- time:float
27
- slope:float
28
- sloped8:float
29
-
30
- slopecorr:dict
31
- demcorr:dict
32
-
33
- river:bool
34
- reach:int
35
- sub:int
36
- forced:bool
37
- uparea:float
38
-
39
- strahler:int
40
- reachlevel:int
41
-
42
- cums:float
43
- incrs:float
44
-
45
- down=None
46
- up:list
47
- upriver:list
48
-
49
- flatindex:int = -1
50
-
51
- def incr_curvi(self):
52
- if self.down is None:
53
- self.cums=0.
54
- else:
55
- self.cums = self.down.cums+self.incrs
56
-
57
- #for curup in self.upriver:
58
- # curup.incr_curvi()
59
- for curup in self.up:
60
- curup.incr_curvi()
61
-
62
- def mean_slope_up(self,threshold):
63
- curnode: node_watershed
64
- meanslope=0.
65
- nbmean=0
66
- for curnode in self.up:
67
- if curnode.slope>threshold:
68
- nbmean+=1.
69
- meanslope+=curnode.slope
70
- if nbmean>0:
71
- meanslope=meanslope/nbmean
72
-
73
- return meanslope
74
-
75
- def slope_down(self,threshold):
76
- slopedown=0.
77
- curnode=self
78
- while curnode.slope < threshold:
79
- if curnode.down is None:
80
- break
81
- curnode=curnode.down
82
-
83
- slopedown = curnode.slope
84
- return slopedown
85
-
86
- def slope_upriver(self,threshold):
87
- slopeup=0.
88
-
89
- if self.slope<threshold:
90
- if len(self.upriver)>0:
91
- slopeup=self.upriver[0].slope_upriver(threshold)
92
- else:
93
- slopeup=-1.
94
- else:
95
- slopeup = self.slope
96
-
97
- return slopeup
98
-
99
- class riversystem:
100
- """Classe du réseau de rivières d'un modèle hydrologique WOLF"""
101
- nbreaches:int
102
- myreaches:dict
103
-
104
- myupmin:dict
105
-
106
- parent=None
107
- myupstreams:dict
108
-
109
- maxlevels:int
110
- maxstrahler:int
111
-
112
- tslopemin:float =None
113
- tslopemax:float =None
114
-
115
- myplotter:PlotNotebook = None
116
- savedir:str=''
117
-
118
- def __init__(self,rivers:list,parent,thslopemin,
119
- thslopemax, *args, **kwargs):
120
- curnode:node_watershed
121
-
122
- self.parent=parent
123
- self.nbreaches = max([x.reach for x in rivers])
124
- self.myreaches={}
125
- self.myreaches['reaches']={}
126
- self.myupstreams={}
127
- self.myupstreams['list']=[]
128
-
129
- for curreach in range(1,self.nbreaches+1):
130
- curup:node_watershed
131
- listreach,curup=parent.find_rivers(whichreach=curreach)
132
-
133
- if len(curup.upriver)==0:
134
- self.myupstreams['list'].append(curup)
135
-
136
- self.myreaches['reaches'][curreach]={}
137
- curdict=self.myreaches['reaches'][curreach]
138
- curdict['upstream']=curup
139
- curdict['baselist']=listreach
140
-
141
- self.create_index()
142
-
143
- self.tslopemin=thslopemin
144
- self.tslopemax=thslopemax
145
- self.slope_correctionmin()
146
- self.slope_correctionmax()
147
-
148
- return super().__init__(*args, **kwargs)
149
-
150
- def get_x(self,whichreach=None,whichup=None):
151
- if not whichreach is None:
152
- nodeslist=self.myreaches['reaches'][whichreach]['baselist']
153
- x=list(curnode.cums for curnode in nodeslist)
154
- elif not whichup is None:
155
- curnode:node_watershed
156
- x=[]
157
- curnode=self.myupstreams['list'][whichup]
158
- while not curnode is None:
159
- x.append(curnode.cums)
160
- curnode=curnode.down
161
- else:
162
- x=[]
163
-
164
- return x
165
-
166
- def get_dem(self,whichdem,whichreach=None,whichup=None):
167
- if not whichreach is None:
168
- nodeslist=self.myreaches['reaches'][whichreach]['baselist']
169
- dem=list(curnode.dem[whichdem] for curnode in nodeslist)
170
- elif not whichup is None:
171
- curnode:node_watershed
172
- dem=[]
173
- curnode=self.myupstreams['list'][whichup]
174
- while not curnode is None:
175
- dem.append(curnode.dem[whichdem])
176
- curnode=curnode.down
177
- return dem
178
-
179
- def get_dem_corr(self,whichdem,whichreach=None,whichup=None):
180
- if not whichreach is None:
181
- nodeslist=self.myreaches['reaches'][whichreach]['baselist']
182
- dem=list(curnode.demcorr[whichdem] for curnode in nodeslist)
183
- elif not whichup is None:
184
- curnode:node_watershed
185
- dem=[]
186
- curnode=self.myupstreams['list'][whichup]
187
- while not curnode is None:
188
- dem.append(curnode.dem[whichdem])
189
- curnode=curnode.down
190
- return dem
191
-
192
- def get_slope(self,whichslope=None,whichreach=None,whichup=None):
193
- if whichslope is None:
194
- if not whichreach is None:
195
- nodeslist=self.myreaches['reaches'][whichreach]['baselist']
196
- slope=list(curnode.slope for curnode in nodeslist)
197
- elif not whichup is None:
198
- curnode:node_watershed
199
- slope=[]
200
- curnode=self.myupstreams['list'][whichup]
201
- while not curnode is None:
202
- slope.append(curnode.slope)
203
- curnode=curnode.down
204
- else:
205
- if not whichreach is None:
206
- nodeslist=self.myreaches['reaches'][whichreach]['baselist']
207
- slope=list(curnode.slopecorr[whichslope]['value'] for curnode in nodeslist)
208
- elif not whichup is None:
209
- curnode:node_watershed
210
- slope=[]
211
- curnode=self.myupstreams['list'][whichup]
212
- while not curnode is None:
213
- slope.append(curnode.slopecorr[whichslope]['value'])
214
- curnode=curnode.down
215
-
216
- return slope
217
-
218
- def create_index(self):
219
- #incrément d'index depuis l'amont jusque l'exutoire final
220
- for curup in self.myupstreams['list']:
221
- curnode:node_watershed
222
- curnode=curup
223
- while not curnode is None:
224
- curnode.reachlevel +=1
225
- curnode=curnode.down
226
-
227
- #recherche de l'index max --> à l'exutoire
228
- self.maxlevels = self.parent.myoutlet.reachlevel
229
- self.maxstrahler=0
230
- self.myreaches['indexed']={}
231
- for i in range(1,self.maxlevels+1):
232
- self.myreaches['indexed'][i]=[]
233
-
234
- #création de listes pour chaque niveau
235
- for curreach in self.myreaches['reaches']:
236
- curdict=self.myreaches['reaches'][curreach]
237
- listreach=curdict['baselist']
238
- curlevel=listreach[0].reachlevel
239
- self.myreaches['indexed'][curlevel].append(curreach)
240
-
241
- #création de listes pour chaque amont
242
- # on parcourt toutes les mailles depuis chaque amont et on ajoute les index de biefs qui sont différents
243
- for idx,curup in enumerate(self.myupstreams['list']):
244
- curdict=self.myupstreams[idx]={}
245
- curdict['up']=curup
246
- curdict['fromuptodown']=[]
247
- curdict['fromuptodown'].append(curup.reach)
248
- curnode=curup.down
249
- while not curnode is None:
250
- if curnode.reach!=curdict['fromuptodown'][-1]:
251
- curdict['fromuptodown'].append(curnode.reach)
252
- curnode=curnode.down
253
-
254
- #création de l'indice de strahler
255
- self.myreaches['strahler']={}
256
- #on commence par ajouter les biefs de 1er niveau qui sont à coup sûr d'indice 1
257
- self.myreaches['strahler'][1]=self.myreaches['indexed'][1]
258
- for curreach in self.myreaches['strahler'][1]:
259
- self.set_strahler_in_nodes(curreach,1)
260
-
261
- #on parcourt les différents niveaux
262
- for i in range(2,self.maxlevels+1):
263
- listlevel=self.myreaches['indexed'][i]
264
- for curreach in listlevel:
265
- curup:node_watershed
266
- curup=self.myreaches['reaches'][curreach]['upstream']
267
- upidx=list(x.strahler for x in curup.upriver)
268
- sameidx=upidx[0]==upidx[-1]
269
- maxidx=max(upidx)
270
-
271
- curidx=maxidx
272
- if sameidx:
273
- curidx+=1
274
- if not curidx in self.myreaches['strahler'].keys():
275
- #création de la liste du niveau supérieur
276
- self.myreaches['strahler'][curidx]=[]
277
- self.maxstrahler=curidx
278
-
279
- self.myreaches['strahler'][curidx].append(curreach)
280
- self.set_strahler_in_nodes(curreach,curidx)
281
-
282
-
283
- myarray=WolfArray(mold=self.parent.subs)
284
- myarray.reset()
285
- curnode:node_watershed
286
- for curreach in self.myreaches['reaches']:
287
- curdict=self.myreaches['reaches'][curreach]
288
- listreach=curdict['baselist']
289
- for curnode in listreach:
290
- i=curnode.i
291
- j=curnode.j
292
- myarray.array[i,j]=curnode.strahler
293
- myarray.filename = self.parent.mydir+'\\Characteristic_maps\\Drainage_basin.strahler'
294
- myarray.write_all()
295
- myarray.reset()
296
- for curreach in self.myreaches['reaches']:
297
- curdict=self.myreaches['reaches'][curreach]
298
- listreach=curdict['baselist']
299
- for curnode in listreach:
300
- i=curnode.i
301
- j=curnode.j
302
- myarray.array[i,j]=curnode.reachlevel
303
- myarray.filename = self.parent.mydir+'\\Characteristic_maps\\Drainage_basin.reachlevel'
304
- myarray.write_all()
305
-
306
- def set_strahler_in_nodes(self,whichreach,strahler):
307
- listnodes = self.myreaches['reaches'][whichreach]['baselist']
308
- curnode:node_watershed
309
- for curnode in listnodes:
310
- curnode.strahler = strahler
311
-
312
- def plot_dem(self,which=-1):
313
- mymarkers=['x','+','1','2','3','4']
314
- if which==-1:
315
- if not self.myplotter is None:
316
- fig=self.myplotter.add('All Reaches')
317
- else:
318
- fig=plt.figure()
319
-
320
- ax=fig.add_subplot(111)
321
-
322
- for curreach in self.myreaches['reaches']:
323
- x=np.array(self.get_x(whichreach=curreach))
324
- for idx,curdem in enumerate(listdem):
325
- y=np.array(self.get_dem(curdem,whichreach=curreach))
326
-
327
- xmask=np.ma.masked_where(y==99999.,x)
328
- ymask=np.ma.masked_where(y==99999.,y)
329
-
330
- ax.scatter(xmask,ymask,marker=mymarkers[idx],label=curdem)
331
- ax.legend()
332
- fig.canvas.draw()
333
-
334
- elif which==-99:
335
- size=int(np.ceil(np.sqrt(self.nbreaches)))
336
-
337
- if not self.myplotter is None:
338
- fig=self.myplotter.add('reaches')
339
- else:
340
- fig=plt.figure()
341
-
342
- for index,curreach in enumerate(self.myreaches['reaches']):
343
- #curax=ax[int(np.floor(index/size)),int(np.mod(index,size))]
344
- curax=fig.add_subplot(size,size,index+1)
345
-
346
- curdict=self.myreaches['reaches'][curreach]
347
- x=np.array(self.get_x(whichreach=curreach))
348
-
349
- for idx,curdem in enumerate(listdem):
350
- y=np.array(self.get_dem(curdem,whichreach=curreach))
351
-
352
- xmask=np.ma.masked_where(y==99999.,x)
353
- ymask=np.ma.masked_where(y==99999.,y)
354
-
355
- curax.scatter(xmask,ymask,marker=mymarkers[idx],label=curdem)
356
- curax.legend()
357
- fig.canvas.draw()
358
-
359
- elif which==-98:
360
- size=int(np.ceil(np.sqrt(len(self.myupstreams['list']))))
361
-
362
- if not self.myplotter is None:
363
- fig=self.myplotter.add('reaches')
364
- else:
365
- fig=plt.figure()
366
-
367
- for idxup,curup in enumerate(self.myupstreams['list']):
368
- curax=fig.add_subplot(size,size,idxup+1)
369
-
370
- x=np.array(self.get_x(whichup=idxup))
371
-
372
- for idx,curdem in enumerate(listdem):
373
- y=np.array(self.get_dem(curdem,whichup=idxup))
374
-
375
- xmask=np.ma.masked_where(y==99999.,x)
376
- ymask=np.ma.masked_where(y==99999.,y)
377
- curax.scatter(xmask,ymask,marker=mymarkers[idx],label=curdem)
378
-
379
- curax.legend()
380
- fig.canvas.draw()
381
-
382
- elif which>-1:
383
- if which<len(self.myupstreams['list']):
384
- if not self.myplotter is None:
385
- fig=self.myplotter.add('Upstream n°'+str(which))
386
- else:
387
- fig=plt.figure()
388
-
389
- ax=fig.add_subplot(111)
390
-
391
- x=np.array(self.get_x(whichup=which))
392
- for idx,curdem in enumerate(listdem):
393
- y=np.array(self.get_dem(curdem,whichup=which))
394
-
395
- xmask=np.ma.masked_where(y==99999.,x)
396
- ymask=np.ma.masked_where(y==99999.,y)
397
- ax.scatter(xmask,ymask,marker=mymarkers[idx],label=curdem)
398
-
399
- ax.legend()
400
- fig.canvas.draw()
401
-
402
-
403
- def plot_dem_and_corr(self,which=-1,whichdem='dem2'):
404
-
405
- if which<len(self.myupstreams['list']):
406
- if not self.myplotter is None:
407
- fig=self.myplotter.add('Upstream n°'+str(which))
408
- else:
409
- fig=plt.figure()
410
- fig.suptitle('Upstream n°'+str(which))
411
-
412
- ax=fig.add_subplot(111)
413
-
414
- x=np.array(self.get_x(whichup=which))
415
- y=np.array(self.get_dem(whichdem,whichup=which))
416
-
417
- xcorr=self.myupmin[which][whichdem][0]
418
- ycorr=self.myupmin[which][whichdem][1]
419
-
420
- xmask=np.ma.masked_where(y==99999.,x)
421
- ymask=np.ma.masked_where(y==99999.,y)
422
-
423
- ax.scatter(xmask,ymask,marker='x',label=whichdem)
424
- ax.scatter(xcorr,ycorr,marker='+',label='selected points')
425
-
426
- ax.legend()
427
- fig.canvas.draw()
428
-
429
- if not self.savedir=='':
430
- plt.savefig(self.savedir+'\\Up'+str(which)+'_'+whichdem+'.png')
431
-
432
- def plot_slope(self,which=-1):
433
- mymarkers=['x','+','1','2','3','4']
434
- if which==-1:
435
- if not self.myplotter is None:
436
- fig=self.myplotter.add('reaches')
437
- else:
438
- fig=plt.figure()
439
-
440
- ax=fig.add_subplot(111)
441
-
442
- for curreach in self.myreaches['reaches']:
443
- x=self.get_x(whichreach=curreach)
444
- for idx,curdem in enumerate(listdem):
445
- y=self.get_slope(curdem,whichreach=curreach)
446
- ax.scatter(x,y,marker=mymarkers[idx],label=curdem)
447
- fig.canvas.draw()
448
-
449
- elif which==-99:
450
- size=int(np.ceil(np.sqrt(self.nbreaches)))
451
- if not self.myplotter is None:
452
- fig=self.myplotter.add('reaches')
453
- else:
454
- fig=plt.figure()
455
-
456
- for index,curreach in enumerate(self.myreaches['reaches']):
457
- curax=fig.add_subplot(size,size,index+1)
458
-
459
- x=self.get_x(whichreach=curreach)
460
-
461
- for idx,curdem in enumerate(listdem):
462
- y=self.get_slope(curdem,whichreach=curreach)
463
- curax.scatter(x,y,marker=mymarkers[idx],label=curdem)
464
- curax.legend()
465
- fig.canvas.draw()
466
-
467
- elif which==-98:
468
- size=int(np.ceil(np.sqrt(len(self.myupstreams['list']))))
469
-
470
- if not self.myplotter is None:
471
- fig=self.myplotter.add('reaches')
472
- else:
473
- fig=plt.figure()
474
-
475
- for idxup,curup in enumerate(self.myupstreams['list']):
476
- curax=fig.add_subplot(size,size,idxup+1)
477
- x=self.get_x(whichup=idxup)
478
-
479
- for idx,curdem in enumerate(listdem):
480
- y=self.get_slope(curdem,whichup=idxup)
481
- curax.scatter(x,y,marker=mymarkers[idx],label=curdem)
482
- curax.legend()
483
- fig.canvas.draw()
484
-
485
- def write_slopes(self):
486
- #Uniquement les pentes rivières
487
- for curlist in listdem:
488
- slopes= WolfArray(self.parent.mydir+'\\Characteristic_maps\\Drainage_basin.slope')
489
- slopes.reset()
490
- for curreach in self.myreaches['reaches']:
491
- curdict=self.myreaches['reaches'][curreach]
492
- listreach=curdict['baselist']
493
-
494
- curnode:node_watershed
495
- for curnode in listreach:
496
- i=curnode.i
497
- j=curnode.j
498
- slopes.array[i,j]=curnode.slopecorr[curlist]['value']
499
-
500
- slopes.filename = self.parent.mydir+'\\Characteristic_maps\\Drainage_basin.slope_corr_riv_'+curlist
501
- slopes.write_all()
502
-
503
- def slope_correctionmin(self):
504
- if not self.tslopemin is None:
505
- print(_('select min - river'))
506
- self.selectmin()
507
- print(_('slope correction min - river'))
508
- self.compute_slopescorr(self.myupmin)
509
-
510
- def slope_correctionmax(self):
511
- if not self.tslopemax is None:
512
- print(_('select max - river'))
513
- self.selectmax()
514
- print(_('slope correction max - river'))
515
- self.compute_slopescorr(self.myupmax)
516
-
517
- def selectmin(self):
518
- #Sélection des valeurs minimales afin de conserver une topo décroissante vers l'aval --> une pente positive
519
- self.myupmin={}
520
-
521
- #on initialise le dictionnaire de topo min pour chaque amont
522
- for idx,curup in enumerate(self.myupstreams['list']):
523
- self.myupmin[idx]={}
524
-
525
- curnode:node_watershed
526
- for curdem in listdem:
527
- print(_(curdem))
528
- for idx,curup in enumerate(self.myupstreams['list']):
529
- #on part de l'amont
530
- curnode=curup
531
- x=[]
532
- y=[]
533
-
534
- x.append(curnode.cums)
535
-
536
- if curdem=='cs':
537
- basey=min(curnode.dem[curdem],curnode.dem['dem2'])
538
- else:
539
- basey=curnode.dem[curdem]
540
-
541
- y.append(basey)
542
- curnode=curnode.down
543
-
544
- locs= self.parent.myresolution
545
- while not curnode is None:
546
- if curdem=='cs':
547
- yloc=min(curnode.dem[curdem],curnode.dem['dem2'])
548
- else:
549
- yloc=curnode.dem[curdem]
550
-
551
- #on ajoute la maille si la pente est suffisante, sinon cekla créera un trou dans le parcours
552
- if (basey-yloc)/locs>self.tslopemin:
553
- x.append(curnode.cums)
554
- y.append(yloc)
555
- basey=yloc
556
- locs= self.parent.myresolution
557
- else:
558
- locs+= self.parent.myresolution
559
-
560
- #if curnode.i==232 and curnode.j==226:
561
- # a=1
562
-
563
- curnode=curnode.down
564
-
565
- #on stocke les vecteurs de coordonnées curvi et d'altitudes pour les zones respectant les critères
566
- self.myupmin[idx][curdem]=[x,y]
567
-
568
- def selectmax(self):
569
- #Sélection des valeurs maximales afin de conserver une topo décroissante vers l'aval --> une pente positive
570
- # on travaille sur base de la topo corrigée min
571
- self.myupmax={}
572
-
573
- #on initialise le dictionnaire de topo max pour chaque amont
574
- for idx,curup in enumerate(self.myupstreams['list']):
575
- self.myupmax[idx]={}
576
-
577
- ds=self.parent.myresolution
578
- curnode:node_watershed
579
- for curdem in listdem:
580
- print(_(curdem))
581
- for idx,curup in enumerate(self.myupstreams['list']):
582
- curnode=curup
583
- x=[]
584
- y=[]
585
-
586
- basey=curnode.demcorr[curdem]['value']
587
-
588
- x.append(curnode.cums)
589
- y.append(basey)
590
- curnode=curnode.down
591
-
592
- locs= ds
593
- while not curnode is None:
594
- yloc=curnode.demcorr[curdem]['value']
595
-
596
- if (basey-yloc)/locs>self.tslopemax:
597
- while len(x)>1 and (basey-yloc)/locs>self.tslopemax:
598
- x.pop()
599
- y.pop()
600
- basey=y[-1]
601
- locs+=ds
602
-
603
- if yloc<y[-1]:
604
- x.append(curnode.cums)
605
- y.append(yloc)
606
- basey=yloc
607
- locs=ds
608
-
609
- curnode=curnode.down
610
-
611
- self.myupmax[idx][curdem]=[x,y]
612
-
613
- def compute_slopescorr(self,whichdict:dict):
614
- curnode:node_watershed
615
- for curdem in listdem:
616
- print(_(curdem))
617
- for idx,curup in enumerate(self.myupstreams['list']):
618
- curdict=whichdict[idx][curdem]
619
- xmin=curdict[0]
620
- if len(xmin)>1:
621
- ymin=curdict[1]
622
- x=self.get_x(whichup=idx)
623
-
624
- #on cale une fonction d'interpolation sur la sélection dans lequalle on a oublié les pentes faibles --> à trou
625
- f=interpolate.interp1d(xmin,ymin, fill_value='extrapolate')
626
- #on interpole sur tous les x --> on remplit les trous
627
- y=f(x)
628
- #calcul des pentes sur base des noeuds aval
629
- slopes=self.compute_slope_down(x,y)
630
-
631
- #on remplit le dictionnaire de résultat
632
- curnode=curup
633
- i=0
634
- while not curnode is None:
635
- #if curnode.i==232 and curnode.j==226:
636
- # a=1
637
- curnode.demcorr[curdem]['parts'].append(y[i])
638
- curnode.slopecorr[curdem]['parts'].append(slopes[i])
639
- i+=1
640
- curnode=curnode.down
641
-
642
- #calcul de la moyenne sur base des valeurs partielles
643
- for curdem in listdem:
644
- for curreach in self.myreaches['reaches']:
645
- nodeslist=self.myreaches['reaches'][curreach]['baselist']
646
- for curnode in nodeslist:
647
- #if curnode.i==232 and curnode.j==226:
648
- # a=1
649
- if len(nodeslist)<2:
650
- if not self.tslopemin is None:
651
- curnode.slopecorr[curdem]['value']=max(self.tslopemin,curnode.slope)
652
- else:
653
- curnode.slopecorr[curdem]['value']=self.tslopemin=1.e-4
654
-
655
- if not self.tslopemax is None:
656
- curnode.slopecorr[curdem]['value']=min(self.tslopemax,curnode.slope)
657
- else:
658
- curnode.demcorr[curdem]['value']=np.mean(curnode.demcorr[curdem]['parts'])
659
- curnode.slopecorr[curdem]['value']=np.mean(curnode.slopecorr[curdem]['parts'])
660
-
661
- #on vide les parts
662
- curnode.demcorr[curdem]['parts']=[]
663
- curnode.slopecorr[curdem]['parts']=[]
664
-
665
- def compute_slope_down(self,x,y):
666
- slope=[]
667
- for i in range(len(x)-1):
668
- slope.append((y[i+1]-y[i])/(x[i+1]-x[i]))
669
- slope.append(slope[-1])
670
- return slope
671
-
672
- def plot_all_in_notebook(self):
673
-
674
- self.myplotter = PlotNotebook()
675
-
676
- for i in range(self.nbreaches):
677
- self.plot_dem_and_corr(i,whichdem='cs')
678
- self.plot_dem()
679
- self.plot_slope(-98)
680
- self.plot_dem(-98)
681
-
682
- class runoffsystem:
683
- """Classe de l'ensemble des mailles de ruissellement d'un modèle
684
- hydrologique WOLF"""
685
- myupmin:dict
686
- mynodes:list
687
-
688
- parent=None
689
- myupstreams:dict
690
-
691
- maxlevels:int
692
- maxstrahler:int
693
-
694
- tslopemin:float =None
695
- tslopemax:float =None
696
-
697
- def __init__(self,runoff:list,parent,thslopemin,
698
- thslopemax,*args, **kwargs):
699
- curnode:node_watershed
700
-
701
- self.parent=parent
702
- self.mynodes=runoff
703
- self.myupstreams={}
704
- #sélection des mailles qui ont une surface unitaire comme surface drainée
705
- areaup = pow(parent.myresolution,2)/1.e6
706
- self.myupstreams['list']=list(filter(lambda x: (x.uparea-areaup)<1.e-6 ,runoff))
707
-
708
- self.tslopemin=thslopemin
709
- self.tslopemax=thslopemax
710
-
711
- self.slope_correctionmin()
712
- self.slope_correctionmax()
713
-
714
- return super().__init__(*args, **kwargs)
715
-
716
- def get_x(self,whichup=None):
717
- if not whichup is None:
718
- curnode:node_watershed
719
- x=[]
720
- curnode=self.myupstreams['list'][whichup]
721
- while not curnode.river:
722
- x.append(curnode.cums)
723
- curnode=curnode.down
724
- if len(x)==1:
725
- x.append(curnode.cums)
726
- else:
727
- x=[]
728
-
729
- return x
730
-
731
- def get_dem(self,whichdem,whichup=None):
732
- if not whichup is None:
733
- curnode:node_watershed
734
- dem=[]
735
- curnode=self.myupstreams['list'][whichup]
736
- while not curnode.river:
737
- dem.append(curnode.dem[whichdem])
738
- curnode=curnode.down
739
- return dem
740
-
741
- def get_dem_corr(self,whichdem,whichup=None):
742
- if not whichup is None:
743
- curnode:node_watershed
744
- dem=[]
745
- curnode=self.myupstreams['list'][whichup]
746
- while not curnode.river:
747
- dem.append(curnode.dem[whichdem])
748
- curnode=curnode.down
749
- return dem
750
-
751
- def get_slope(self,whichslope=None,whichup=None):
752
- if whichslope is None:
753
- if not whichup is None:
754
- curnode:node_watershed
755
- slope=[]
756
- curnode=self.myupstreams['list'][whichup]
757
- while not curnode.river:
758
- slope.append(curnode.slope)
759
- curnode=curnode.down
760
- else:
761
- if not whichup is None:
762
- curnode:node_watershed
763
- slope=[]
764
- curnode=self.myupstreams['list'][whichup]
765
- while not curnode.river:
766
- slope.append(curnode.slopecorr[whichslope]['value'])
767
- curnode=curnode.down
768
-
769
- return slope
770
-
771
- def plot_dem(self,which=-1):
772
- mymarkers=['x','+','1','2','3','4']
773
- if which>-1:
774
- if which<len(self.myupstreams['list']):
775
- fig=plt.figure()
776
- fig.suptitle('Upstream n°'+str(which))
777
-
778
- x=np.array(self.get_x(whichup=which))
779
- for idx,curdem in enumerate(listdem):
780
- y=np.array(self.get_dem(curdem,whichup=which))
781
-
782
- xmask=np.ma.masked_where(y==99999.,x)
783
- ymask=np.ma.masked_where(y==99999.,y)
784
- plt.scatter(xmask,ymask,marker=mymarkers[idx],label=curdem)
785
-
786
- plt.legend()
787
- plt.show()
788
-
789
- def plot_dem_and_corr(self,which=-1,whichdem='dem2'):
790
- if which<len(self.myupstreams['list']):
791
- fig=plt.figure()
792
- fig.suptitle('Upstream n°'+str(which))
793
-
794
- x=np.array(self.get_x(whichup=which))
795
- y=np.array(self.get_dem(whichdem,whichup=which))
796
-
797
- xcorr=self.myupmin[which][whichdem][0]
798
- ycorr=self.myupmin[which][whichdem][1]
799
-
800
- xmask=np.ma.masked_where(y==99999.,x)
801
- ymask=np.ma.masked_where(y==99999.,y)
802
-
803
- plt.scatter(xmask,ymask,marker='x',label=whichdem)
804
- plt.scatter(xcorr,ycorr,marker='+',label='selected points')
805
-
806
- plt.legend()
807
- plt.savefig(r'D:\OneDrive\OneDrive - Universite de Liege\Crues\2021-07 Vesdre\Simulations\Hydrologie\Up'+str(which)+'_'+whichdem+'.png')
808
- #plt.show()
809
-
810
- def write_slopes(self):
811
- #Uniquement les pentes runoff
812
- for curlist in listdem:
813
- slopes= WolfArray(self.parent.mydir+'\\Characteristic_maps\\Drainage_basin.slope')
814
- slopes.reset()
815
- curnode:node_watershed
816
- for curnode in self.mynodes:
817
- i=curnode.i
818
- j=curnode.j
819
- slopes.array[i,j]=curnode.slopecorr[curlist]['value']
820
-
821
- slopes.filename = self.parent.mydir+'\\Characteristic_maps\\Drainage_basin.slope_corr_run_'+curlist
822
- slopes.write_all()
823
-
824
- def slope_correctionmin(self):
825
- if not self.tslopemin is None:
826
- print(_('select min - runoff'))
827
- self.selectmin()
828
- print(_('slope correction min - runoff'))
829
- self.compute_slopescorr(self.myupmin)
830
-
831
- def slope_correctionmax(self):
832
- if not self.tslopemax is None:
833
- print(_('select max - runoff'))
834
- self.selectmax()
835
- print(_('slope correction max - runoff'))
836
- self.compute_slopescorr(self.myupmax)
837
-
838
- def selectmin(self):
839
- #Sélection des valeurs minimales afin de conserver une topo décroissante vers l'aval --> une pente positive
840
- self.myupmin={}
841
-
842
- #on initialise le dictionnaire de topo min pour chaque amont
843
- for idx,curup in enumerate(self.myupstreams['list']):
844
- self.myupmin[idx]={}
845
-
846
- ds=self.parent.myresolution
847
- curnode:node_watershed
848
- for curdem in listdem:
849
- print(_(curdem))
850
- for idx,curup in enumerate(self.myupstreams['list']):
851
- curnode=curup
852
- x=[]
853
- y=[]
854
-
855
- if curdem=='cs':
856
- basey=min(curnode.dem[curdem],curnode.dem['dem2'])
857
- else:
858
- basey=curnode.dem[curdem]
859
-
860
- x.append(curnode.cums)
861
- y.append(basey)
862
- curnode=curnode.down
863
-
864
- locs=ds
865
- while not curnode is None:
866
- if curdem=='cs':
867
- yloc=min(curnode.dem[curdem],curnode.dem['dem2'])
868
- else:
869
- yloc=curnode.dem[curdem]
870
-
871
- if (basey-yloc)/locs>self.tslopemin:
872
- x.append(curnode.cums)
873
- y.append(yloc)
874
- basey=yloc
875
- locs=ds
876
- if curnode.river:
877
- break
878
- else:
879
- locs+=ds
880
- curnode=curnode.down
881
-
882
- self.myupmin[idx][curdem]=[x,y]
883
-
884
- def selectmax(self):
885
- #Sélection des valeurs minimales afin de conserver une topo décroissante vers l'aval --> une pente positive
886
- self.myupmax={}
887
-
888
- #on initialise le dictionnaire de topo min pour chaque amont
889
- for idx,curup in enumerate(self.myupstreams['list']):
890
- self.myupmax[idx]={}
891
-
892
- ds=self.parent.myresolution
893
- curnode:node_watershed
894
- for curdem in listdem:
895
- print(_(curdem))
896
- for idx,curup in enumerate(self.myupstreams['list']):
897
- curnode=curup
898
- x=[]
899
- y=[]
900
-
901
- """
902
- if curdem=='cs':
903
- basey=min(curnode.demcorr[curdem]['value'],curnode.demcorr['dem2']['value'])
904
- else:
905
- basey=curnode.demcorr[curdem]['value']
906
- """
907
- basey=curnode.demcorr[curdem]['value']
908
-
909
- x.append(curnode.cums)
910
- y.append(basey)
911
- curnode=curnode.down
912
-
913
- locs= ds
914
- while not curnode is None:
915
- """
916
- if curdem=='cs':
917
- yloc=min(curnode.demcorr[curdem]['value'],curnode.demcorr['dem2']['value'])
918
- else:
919
- yloc=curnode.demcorr[curdem]['value']
920
- """
921
- yloc=curnode.demcorr[curdem]['value']
922
-
923
- if (basey-yloc)/locs>self.tslopemax:
924
- while len(x)>1 and (basey-yloc)/locs>self.tslopemax:
925
- x.pop()
926
- y.pop()
927
- basey=y[-1]
928
- locs+=ds
929
-
930
- if yloc<y[-1]:
931
- x.append(curnode.cums)
932
- y.append(yloc)
933
- basey=yloc
934
- locs=ds
935
- if curnode.river:
936
- break
937
-
938
- curnode=curnode.down
939
- #if curnode.i==187 and curnode.j==207:
940
- # a=1
941
-
942
- self.myupmax[idx][curdem]=[x,y]
943
-
944
- def compute_slopescorr(self,whichdict:dict):
945
- curnode:node_watershed
946
- for curdem in listdem:
947
- print(_(curdem))
948
- for idx,curup in enumerate(self.myupstreams['list']):
949
- curdict=whichdict[idx][curdem]
950
- xmin=curdict[0]
951
- if len(xmin)>1:
952
- ymin=curdict[1]
953
- x=self.get_x(whichup=idx)
954
-
955
- f=interpolate.interp1d(xmin,ymin, fill_value='extrapolate')
956
- y=f(x)
957
- slopes=self.compute_slope_down(x,y)
958
-
959
- curnode=curup
960
- i=0
961
- while not curnode.river:
962
- #if curnode.i==187 and curnode.j==207:
963
- # a=1
964
- curnode.demcorr[curdem]['parts'].append(y[i])
965
- curnode.slopecorr[curdem]['parts'].append(slopes[i])
966
- i+=1
967
- curnode=curnode.down
968
- #calcul de la moyenne sur base des valeurs partielles
969
- for curdem in listdem:
970
- for curnode in self.mynodes:
971
- #if curnode.i==187 and curnode.j==207:
972
- # a=1
973
- if len(curnode.slopecorr[curdem]['parts'])<2:
974
- #Ce cas particulier peut arriver si des mailles BV sont remplies par une zone plate qui s'étend en rivière
975
- # Comme on ne recherche de mailles plus basses que dans la partie BV, il n'est pas possible de corriger les pentes
976
- if not self.tslopemin is None:
977
- curnode.slopecorr[curdem]['value']=max(self.tslopemin,curnode.slope)
978
- else:
979
- curnode.slopecorr[curdem]['value']=1.e-4
980
-
981
- if not self.tslopemax is None:
982
- curnode.slopecorr[curdem]['value']=min(self.tslopemax,curnode.slope)
983
- else:
984
- curnode.demcorr[curdem]['value']=np.mean(curnode.demcorr[curdem]['parts'])
985
- curnode.slopecorr[curdem]['value']=np.mean(curnode.slopecorr[curdem]['parts'])
986
-
987
- curnode.demcorr[curdem]['parts']=[]
988
- curnode.slopecorr[curdem]['parts']=[]
989
-
990
- def compute_slope_down(self,x,y):
991
- slope=[]
992
- for i in range(len(x)-1):
993
- slope.append((y[i+1]-y[i])/(x[i+1]-x[i]))
994
- slope.append(slope[-1])
995
- return slope
996
-
997
- class watershed:
998
- """Classe bassin versant"""
999
-
1000
- mydir: str
1001
- myresolution: float
1002
-
1003
- myoutlet=None
1004
-
1005
- subs: WolfArray
1006
-
1007
- mynodes:list
1008
- mynodesindex:np.array
1009
- myrivers:list
1010
- myrunoff:list
1011
- up=None
1012
-
1013
- mycoupled:list
1014
-
1015
- mysubs: dict
1016
- nbsubs: int
1017
- mystats: dict
1018
-
1019
- mycouplednodesxy:list
1020
- mycouplednodesij:list
1021
- myriversystem:riversystem
1022
- myrunoffsystem:runoffsystem
1023
- mycs:crosssections = None
1024
-
1025
- def __init__(self,dir,thzmin=None,thslopemin=None,
1026
- thzmax=None,thslopemax=None,
1027
- mycs=None,
1028
- computestats=False,plotstats=False,
1029
- *args, **kwargs):
1030
-
1031
- print(_('Read files...'))
1032
- self.mydir=os.path.normpath(dir)
1033
-
1034
- self.subs= WolfArray(self.mydir+'\\Characteristic_maps\\Drainage_basin.sub')
1035
- self.nbsubs = ma.max(self.subs.array)
1036
- self.myresolution = self.subs.dx
1037
-
1038
- f = open(self.mydir+'\\Coupled_pairs.txt', 'r')
1039
- lines = f.read().splitlines()
1040
- f.close()
1041
-
1042
- self.mycouplednodesxy=[]
1043
- self.mycouplednodesij=[]
1044
-
1045
- if lines[0]=='COORDINATES':
1046
- for xy in enumerate(lines[1:]):
1047
- xup,yup,xdown,ydown=xy[1].split('\t')
1048
- self.mycouplednodesxy.append([float(xup),float(yup),float(xdown),float(ydown)])
1049
- self.mycouplednodesij.append([self.subs.get_ij_from_xy(float(xup),float(yup)),self.subs.get_ij_from_xy(float(xdown),float(ydown))])
1050
-
1051
- self.mynodesindex = np.zeros([self.subs.nbx,self.subs.nby],dtype=int)
1052
-
1053
- print(_('Initialization of nodes...'))
1054
- self.init_nodes()
1055
-
1056
- if not mycs is None:
1057
- print(_('Cross sections...'))
1058
- self.set_crossSections(mycs)
1059
- self.attrib_cs_to_nodes()
1060
-
1061
- print(_('Slopes corrections...'))
1062
- self.myriversystem = riversystem(self.myrivers,self,thslopemin=thslopemin,thslopemax=thslopemax)
1063
- self.myrunoffsystem = runoffsystem(self.myrunoff,self,thslopemin=thslopemin,thslopemax=thslopemax)
1064
-
1065
- if computestats or plotstats:
1066
- print(_('Statistics...'))
1067
- self.compute_stats(plotstats)
1068
-
1069
- print(_('Done!'))
1070
-
1071
- #Ecriture des résultats de correction des pentes
1072
- self.write_dem()
1073
- self.write_slopes()
1074
- self.myriversystem.plot_all_in_notebook()
1075
-
1076
- def write_slopes(self):
1077
-
1078
- for curlist in listdem:
1079
- curpath=self.mydir+'\\Characteristic_maps\\corrslopes\\'+curlist
1080
- os.makedirs(curpath,exist_ok=True)
1081
- slopes= WolfArray(self.mydir+'\\Characteristic_maps\\Drainage_basin.slope')
1082
-
1083
- curnode:node_watershed
1084
- for curnode in self.mynodes:
1085
- i=curnode.i
1086
- j=curnode.j
1087
- slopes.array[i,j]=curnode.slopecorr[curlist]['value']
1088
-
1089
- slopes.filename = curpath +'\\Drainage_basin.slope_corr'
1090
- slopes.write_all()
1091
-
1092
- def write_dem(self):
1093
-
1094
- for curlist in listdem:
1095
- curpath=self.mydir+'\\Characteristic_maps\\corrdem\\'+curlist
1096
- os.makedirs(curpath,exist_ok=True)
1097
- dem= WolfArray(self.mydir+'\\Characteristic_maps\\Drainage_basincorr.b')
1098
-
1099
- curnode:node_watershed
1100
- for curnode in self.mynodes:
1101
- i=curnode.i
1102
- j=curnode.j
1103
- dem.array[i,j]=curnode.demcorr[curlist]['value']
1104
-
1105
- dem.filename = curpath +'\\Drainage_basincorr.b'
1106
- dem.write_all()
1107
-
1108
- def set_crossSections(self,cs):
1109
- self.mycs=cs
1110
-
1111
- def attrib_cs_to_nodes(self):
1112
- if not self.mycs is None:
1113
- for curlist in self.mycs:
1114
- for namecs in curlist.myprofiles:
1115
- curvert:wolfvertex
1116
- curcs=curlist.myprofiles[namecs]
1117
-
1118
- try:
1119
- curvert=curcs['bed']
1120
- except:
1121
- curvert=curlist.get_min(whichprofile=curcs)
1122
-
1123
- i,j=self.subs.get_ij_from_xy(curvert.x,curvert.y)
1124
- curnode:node_watershed
1125
- curnode =self.mynodes[self.mynodesindex[i,j]]
1126
-
1127
- if curnode.river:
1128
- if curnode.mycs is None:
1129
- curnode.mycs=[]
1130
- curnode.mycs.append(curcs)
1131
- curnode.dem['cs']=min(curnode.dem['cs'],curvert.z)
1132
-
1133
- def init_nodes(self):
1134
- self.mynodes=[node_watershed() for i in range(self.subs.nbnotnull)]
1135
-
1136
- dem1= WolfArray(self.mydir+'\\Characteristic_maps\\Drainage_basin.b')
1137
- dem2= WolfArray(self.mydir+'\\Characteristic_maps\\Drainage_basincorr.b')
1138
- demdelta= WolfArray(self.mydir+'\\Characteristic_maps\\Drainage_basindiff.b')
1139
- slopes= WolfArray(self.mydir+'\\Characteristic_maps\\Drainage_basin.slope',masknull=False)
1140
- reaches= WolfArray(self.mydir+'\\Characteristic_maps\\Drainage_basin.reachs')
1141
- cnv= WolfArray(self.mydir+'\\Characteristic_maps\\Drainage_basin.cnv')
1142
- times= WolfArray(self.mydir+'\\Characteristic_maps\\Drainage_basin.time')
1143
-
1144
- dem2.array.mask = self.subs.array.mask
1145
-
1146
- nb=0
1147
- for index,x in np.ndenumerate(self.subs.array):
1148
- if(x>0):
1149
- i=int(index[0])
1150
- j=int(index[1])
1151
- self.mynodesindex[i,j]=nb
1152
- nb+=1
1153
-
1154
- curnode:node_watershed
1155
- nb=0
1156
- for index,x in np.ndenumerate(self.subs.array):
1157
- if(x>0):
1158
- i=int(index[0])
1159
- j=int(index[1])
1160
- curnode =self.mynodes[self.mynodesindex[i,j]]
1161
-
1162
- curnode.i = i
1163
- curnode.j = j
1164
- curnode.index=nb
1165
- curnode.dem={}
1166
- curnode.dem['dem1']=dem1.array[i,j]
1167
- curnode.dem['dem2']=dem2.array[i,j]
1168
- curnode.dem['cs']=99999.
1169
- curnode.demdelta=demdelta.array[i,j]
1170
- curnode.slope=slopes.array[i,j]
1171
-
1172
- curnode.slopecorr={}
1173
- for curlist in listdem:
1174
- curnode.slopecorr[curlist]={}
1175
- curnode.slopecorr[curlist]['parts']=[]
1176
- curnode.slopecorr[curlist]['value']=curnode.slope
1177
-
1178
- curnode.demcorr={}
1179
- for curlist in listdem:
1180
- curnode.demcorr[curlist]={}
1181
- curnode.demcorr[curlist]['parts']=[]
1182
- curnode.demcorr[curlist]['value']=curnode.dem['dem2']
1183
-
1184
- curnode.sub=int(x)
1185
- curnode.time=times.array[i,j]
1186
- curnode.uparea=cnv.array[i,j]
1187
- curnode.river=not reaches.array.mask[i,j]
1188
- if curnode.river:
1189
- curnode.reach=int(reaches.array[i,j])
1190
- curnode.forced=False
1191
- curnode.up=[]
1192
- curnode.upriver=[]
1193
- curnode.strahler=0
1194
- curnode.reachlevel=0
1195
- nb+=1
1196
-
1197
- #Liaison échanges forcés
1198
- incr=slopes.dx
1199
- for curexch in self.mycouplednodesij:
1200
- i=int(curexch[0][0])
1201
- j=int(curexch[0][1])
1202
- curnode=self.mynodes[self.mynodesindex[i,j]]
1203
- curnode.forced=True
1204
- idown = int(curexch[1][0])
1205
- jdown = int(curexch[1][1])
1206
- curdown = self.mynodes[self.mynodesindex[idown,jdown]]
1207
- curnode.down = curdown
1208
- curdown.up.append(curnode)
1209
- if curnode.river:
1210
- curdown.upriver.append(curnode)
1211
- curnode.incrs = incr * np.sqrt(pow(curdown.i-i,2)+pow(curdown.j-j,2))
1212
-
1213
- #Liaison hors échanges forcés
1214
- for curnode in self.mynodes:
1215
- if not curnode.forced:
1216
- i=curnode.i
1217
- j=curnode.j
1218
-
1219
- curtop=curnode.dem['dem2']
1220
- diff=[dem2.array[i-1,j] - curtop,dem2.array[i+1,j] - curtop,dem2.array[i,j-1] - curtop,dem2.array[i,j+1] - curtop]
1221
- mindiff = ma.min(diff)
1222
- if mindiff<0:
1223
- index = diff.index(mindiff)
1224
- if index==0:
1225
- curdown = self.mynodes[self.mynodesindex[i-1,j]]
1226
- elif index==1:
1227
- curdown = self.mynodes[self.mynodesindex[i+1,j]]
1228
- elif index==2:
1229
- curdown = self.mynodes[self.mynodesindex[i,j-1]]
1230
- else:
1231
- curdown = self.mynodes[self.mynodesindex[i,j+1]]
1232
-
1233
- curnode.down = curdown
1234
- curdown.up.append(curnode)
1235
- if curnode.river:
1236
- curdown.upriver.append(curnode)
1237
- curnode.incrs=incr
1238
- else:
1239
- self.myoutlet = curnode
1240
-
1241
- #Rechreche de la pente dans les voisins en croix dans la topo non remaniée
1242
- for curnode in self.mynodes:
1243
- if not curnode.forced:
1244
- i=curnode.i
1245
- j=curnode.j
1246
-
1247
- curtop = curnode.dem['dem1']
1248
- diff=[dem1.array[i-1,j] - curtop,dem1.array[i+1,j] - curtop,dem1.array[i,j-1] - curtop,dem1.array[i,j+1] - curtop,
1249
- dem1.array[i-1,j-1] - curtop,dem1.array[i+1,j+1] - curtop,dem1.array[i+1,j-1] - curtop,dem1.array[i-1,j+1] - curtop]
1250
- mindiff = ma.min(diff)
1251
-
1252
- fact=1.
1253
- if mindiff<0:
1254
- index = diff.index(mindiff)
1255
- if index>3:
1256
- fact=np.sqrt(2)
1257
-
1258
- curnode.sloped8 = -mindiff/(self.myresolution*fact)
1259
-
1260
- self.myrivers=list(filter(lambda x: x.river,self.mynodes))
1261
- self.myrivers.sort(key=lambda x: x.dem['dem2'])
1262
- self.myoutlet.incr_curvi()
1263
-
1264
- self.find_dem_subpixels()
1265
-
1266
- self.myrunoff=self.find_runoffnodes()
1267
-
1268
- def find_rivers(self,whichsub=0,whichreach=0):
1269
- """
1270
- Recherche des mailles rivières
1271
- @param whichsub : numéro du sous-bassin à traiter
1272
- @param whicreach : numéro du tronçon à identifier
1273
- """
1274
- if whichsub>0 and whichsub<=self.nbsubs:
1275
- if whichreach>0:
1276
- myrivers=list(filter(lambda x: x.river and x.sub==whichsub and x.reach==whichreach,self.myrivers))
1277
- else:
1278
- myrivers=list(filter(lambda x: x.river and x.sub==whichsub,self.myrivers))
1279
- else:
1280
- if whichreach>0:
1281
- myrivers=list(filter(lambda x: x.river and x.reach==whichreach,self.myrivers))
1282
- else:
1283
- myrivers=list(filter(lambda x: x.river,self.myrivers))
1284
-
1285
- myrivers.sort(key=lambda x: x.dem['dem2'])
1286
-
1287
- up=None
1288
- if len(myrivers)>0:
1289
- up=myrivers[-1]
1290
-
1291
- return myrivers,up
1292
-
1293
- def find_sub(self,whichsub=0):
1294
- """
1295
- Recherche des mailles du sou-bassin versant
1296
- @param whichsub : numéro du sous-bassin à traiter
1297
- """
1298
- if whichsub>0 and whichsub<=self.nbsubs:
1299
- mysub=list(filter(lambda x: x.sub==whichsub,self.mynodes))
1300
- else:
1301
- mysub=self.mynodes.copy
1302
-
1303
- mysub.sort(key=lambda x: x.dem['dem2'])
1304
-
1305
- return mysub
1306
-
1307
- def find_runoffnodes(self,whichsub=0):
1308
- """
1309
- Recherche des mailles du bassin versant seul (sans les rivières)
1310
- @param whichsub : numéro du sous-bassin à traiter
1311
- """
1312
- if whichsub>0 and whichsub<=self.nbsubs:
1313
- myrunoff=list(filter(lambda x: not x.river and x.sub==whichsub,self.mynodes))
1314
- else:
1315
- myrunoff=list(filter(lambda x: not x.river,self.mynodes))
1316
-
1317
- myrunoff.sort(key=lambda x: x.dem['dem2'])
1318
-
1319
- return myrunoff
1320
-
1321
- def index_flatzone(self,listofsortednodes,threshold):
1322
- curnode:node_watershed
1323
- curflat:node_watershed
1324
-
1325
- curindex=0
1326
- for curnode in listofsortednodes[-1:1:-1]:
1327
- addone=False
1328
- while curnode.slope<threshold and curnode.flatindex==-1:
1329
- addone=True
1330
- curnode.flatindex=curindex
1331
- if curnode.down is None:
1332
- break
1333
- curnode=curnode.down
1334
- if addone:
1335
- curindex+=1
1336
-
1337
- return curindex
1338
-
1339
- def find_flatnodes(self,listofsortednodes):
1340
- """
1341
- Recherche des mailles dans des zones de faibles pentes
1342
- @param listofsortednodes : liste triée de mailles
1343
- """
1344
- myflatnodes=list(filter(lambda x: x.flatindex>-1,listofsortednodes))
1345
-
1346
- return myflatnodes
1347
-
1348
- def find_flatzones(self,listofsortednodes,maxindex):
1349
- """
1350
- Recherche des mailles dans des zones de faibles pentes
1351
- @param listofsortednodes : liste triée de mailles
1352
- """
1353
- myflatzones=[[]] * maxindex
1354
- for i in range(maxindex):
1355
- myflatzones[i]=list(filter(lambda x: x.flatindex==i,listofsortednodes))
1356
-
1357
- return myflatzones
1358
-
1359
- def find_dem_subpixels(self):
1360
- """
1361
- Recherche des altitudes dans un mnt plus dense
1362
- """
1363
- dem10m=WolfArray(self.mydir+'\\mnt10m.bin')
1364
- dem20m=WolfArray(self.mydir+'\\mnt20m.bin')
1365
-
1366
- demsubs={'dem10m':dem10m,'dem20m':dem20m}
1367
-
1368
- curnode:node_watershed
1369
- for curdem in demsubs:
1370
- locdem=demsubs[curdem]
1371
- dx=locdem.dx
1372
- dy=locdem.dy
1373
-
1374
- for curnode in self.mynodes:
1375
- curi=curnode.i
1376
- curj=curnode.j
1377
-
1378
- curx,cury=self.subs.get_xy_from_ij(curi,curj)
1379
-
1380
- decalx=(self.myresolution-dx)/2.
1381
- decaly=(self.myresolution-dy)/2.
1382
- x1=curx-decalx
1383
- y1=cury-decaly
1384
- x2=curx+decalx
1385
- y2=cury+decaly
1386
-
1387
- i1,j1=locdem.get_ij_from_xy(x1,y1)
1388
- i2,j2=locdem.get_ij_from_xy(x2,y2)
1389
-
1390
- curnode.dem[curdem]=np.min(locdem.array[i1:i2+1,j1:j2+1])
1391
-
1392
- def compute_stats(self,plot=False):
1393
-
1394
- self.mystats={}
1395
-
1396
- slopes=np.array(list(x.slope for x in self.mynodes))
1397
- slopesrunoff=np.array(list(x.slope for x in list(filter(lambda x: not x.river,self.mynodes))))
1398
- slopesriver=np.array(list(x.slope for x in list(filter(lambda x: x.river,self.mynodes))))
1399
-
1400
- curdict=self.mystats
1401
- curdict['slopemin'] = np.min(slopes)
1402
- curdict['slopemax'] = np.max(slopes)
1403
- curdict['slopemedian'] = np.median(slopes)
1404
- curdict['slopemean'] = np.mean(slopes)
1405
- curdict['hist'] = slopes
1406
- curdict['hist_watershed'] = slopesrunoff
1407
- curdict['hist_reaches'] = slopesriver
1408
- curdict['count_neg'] = np.count_nonzero(slopes < 0.)
1409
-
1410
- print(_('Min : '),curdict['slopemin'])
1411
- print(_('Max : '),curdict['slopemax'])
1412
- print(_('Median : '),curdict['slopemedian'])
1413
- print(_('Mean : '),curdict['slopemean'])
1414
- print(_('Non Zero : '),curdict['count_neg'])
1415
-
1416
-
1417
- for curlist in listdem:
1418
- curdict=self.mystats[curlist]={}
1419
-
1420
- slopes=np.array(list(x.slopecorr[curlist]['value'] for x in self.mynodes))
1421
- slopesrunoff=np.array(list(x.slopecorr[curlist]['value'] for x in list(filter(lambda x: not x.river,self.mynodes))))
1422
- slopesriver=np.array(list(x.slopecorr[curlist]['value'] for x in list(filter(lambda x: x.river,self.mynodes))))
1423
-
1424
- curdict['slopemin'] = np.min(slopes)
1425
- curdict['slopemax'] = np.max(slopes)
1426
- curdict['slopemedian'] = np.median(slopes)
1427
- curdict['slopemean'] = np.mean(slopes)
1428
- curdict['hist'] = slopes
1429
- curdict['hist_watershed'] = slopesrunoff
1430
- curdict['hist_reaches'] = slopesriver
1431
- curdict['count_neg'] = np.count_nonzero(slopes < 0.)
1432
-
1433
- print(_(curlist))
1434
- print(_('Min : '),curdict['slopemin'])
1435
- print(_('Max : '),curdict['slopemax'])
1436
- print(_('Median : '),curdict['slopemedian'])
1437
- print(_('Mean : '),curdict['slopemean'])
1438
- print(_('Non Zero : '),curdict['count_neg'])
1439
-
1440
- if plot:
1441
- self.plot_stats()
1442
-
1443
- def plot_stats(self):
1444
-
1445
- self.myplotterstats = PlotNotebook()
1446
-
1447
- bin1=np.array([1.e-8,1.e-7,1.e-6,5.e-6])
1448
- bin2=np.linspace(1.e-5,1e-3,num=20)
1449
- bin3=np.linspace(2.e-3,1e-1,num=20)
1450
- bin4=np.linspace(.11,1,num=100)
1451
- bins=np.concatenate((bin1,bin2,bin3,bin4))
1452
-
1453
- fig=self.myplotterstats.add(_('Slope distribution - log'))
1454
- ax:plt.axis
1455
-
1456
- ax = fig.add_subplot(311)
1457
- ax.hist(self.mystats['hist'],bins,cumulative=True,density=True,histtype=u'step',label='base')
1458
- ax.set_xscale('log')
1459
- ax.set_xlabel(_('All meshes'))
1460
-
1461
- for curlist in listdem:
1462
- curdict=self.mystats[curlist]
1463
- ax.hist(curdict['hist'],bins,cumulative=True,density=True,histtype=u'step',label=curlist)
1464
-
1465
- ax = fig.add_subplot(312)
1466
- ax.hist(self.mystats['hist_watershed'],bins,cumulative=True,density=True,histtype=u'step',label='base')
1467
- ax.set_xscale('log')
1468
- ax.set_xlabel(_('Watershed'))
1469
-
1470
- for curlist in listdem:
1471
- curdict=self.mystats[curlist]
1472
- ax.hist(curdict['hist_watershed'],bins,cumulative=True,density=True,histtype=u'step',label=curlist)
1473
-
1474
- ax = fig.add_subplot(313)
1475
- ax.hist(self.mystats['hist_reaches'],bins,cumulative=True,density=True,histtype=u'step',label='base')
1476
- ax.set_xscale('log')
1477
- ax.set_xlabel(_('River'))
1478
-
1479
- for curlist in listdem:
1480
- curdict=self.mystats[curlist]
1481
- ax.hist(curdict['hist_reaches'],bins,cumulative=True,density=True,histtype=u'step',label=curlist)
1482
-
1483
- ax.legend()
1484
- fig.canvas.draw()
1485
-
1486
- fig=self.myplotterstats.add(_('Slope distribution'))
1487
- ax:plt.axis
1488
-
1489
- ax = fig.add_subplot(311)
1490
- ax.hist(self.mystats['hist'],bins,cumulative=True,density=True,histtype=u'step',label='base')
1491
- ax.set_xlabel(_('All meshes'))
1492
-
1493
- for curlist in listdem:
1494
- curdict=self.mystats[curlist]
1495
- ax.hist(curdict['hist'],bins,cumulative=True,density=True,histtype=u'step',label=curlist)
1496
-
1497
- ax = fig.add_subplot(312)
1498
- ax.hist(self.mystats['hist_watershed'],bins,cumulative=True,density=True,histtype=u'step',label='base')
1499
- ax.set_xlabel(_('Watershed'))
1500
-
1501
- for curlist in listdem:
1502
- curdict=self.mystats[curlist]
1503
- ax.hist(curdict['hist_watershed'],bins,cumulative=True,density=True,histtype=u'step',label=curlist)
1504
-
1505
- ax = fig.add_subplot(313)
1506
- ax.hist(self.mystats['hist_reaches'],bins,cumulative=True,density=True,histtype=u'step',label='base')
1507
- ax.set_xlabel(_('River'))
1508
-
1509
- for curlist in listdem:
1510
- curdict=self.mystats[curlist]
1511
- ax.hist(curdict['hist_reaches'],bins,cumulative=True,density=True,histtype=u'step',label=curlist)
1512
-
1513
- ax.legend()
1514
- fig.canvas.draw()
1515
-
1516
-
1517
- def analyze_flatzones(self):
1518
-
1519
- self.myplotterflat = PlotNotebook()
1520
-
1521
- ### Flat zones
1522
- eps=1e-7
1523
- #indexation des zones "indépendantes" de plats - ruissellement
1524
- maxindex=self.index_flatzone(self.myrunoff,eps)
1525
- #identification des mailles dans les zones
1526
- myflatnodes=self.find_flatnodes(self.myrunoff)
1527
- #création de listes avec les noeuds dans chaque zone
1528
- myflats=self.find_flatzones(myflatnodes,maxindex)
1529
-
1530
- #calcul de la longueur de la zone de plat --> sommation du nombre de mailles
1531
- lenflats=np.zeros((maxindex),dtype=np.int32)
1532
- for i in range(maxindex):
1533
- lenflats[i]=len(myflats[i])
1534
-
1535
- #indexation des zones "indépendantes" de plats - rivières
1536
- maxindexrivers=self.index_flatzone(self.myrivers,eps)
1537
- #création de listes avec les noeuds dans chaque zone - rivières
1538
- myflatsrivers=self.find_flatzones(self.myrivers,maxindexrivers)
1539
-
1540
- #calcul de la longueur de la zone de plat --> sommation du nombre de mailles
1541
- lenflatsrivers=np.zeros((maxindexrivers),dtype=np.int32)
1542
- for i in range(maxindexrivers):
1543
- lenflatsrivers[i]=len(myflatsrivers[i])
1544
-
1545
- fig:mplfig.Figure
1546
- fig=self.myplotterflat.add("Nb nodes in flat area")
1547
- ax=fig.add_subplot(211)
1548
- mybins=np.arange(0.5,np.max(lenflats),1.)
1549
- myticks=np.arange(1,np.ceil(np.max(lenflats)),1)
1550
- ax.hist(lenflats,bins=mybins)
1551
- ax.set_xlabel(_('Nb nodes in flat area - runoff'))
1552
- ax.set_xticks(myticks)
1553
- ax.set_xbound(.5,np.max(lenflats))
1554
- ax.set_ylabel('Nb flat areas')
1555
- ax.set_yscale('log')
1556
-
1557
- ax=fig.add_subplot(212)
1558
- mybinsrivers=np.arange(0.5,np.max(lenflatsrivers),1.)
1559
- myticksrivers=np.arange(1,np.ceil(np.max(lenflatsrivers)),1)
1560
- ax.hist(lenflatsrivers,bins=mybinsrivers)
1561
- ax.set_xlabel(_('Nb nodes in flat area - rivers'))
1562
- ax.set_xticks(myticksrivers)
1563
- ax.set_xbound(.5,np.max(lenflatsrivers))
1564
- ax.set_ylabel('Nb flat areas')
1565
- ax.set_yscale('log')
1566
-
1567
- fig=self.myplotterflat.add("Nb nodes in flat area")
1568
- ax=fig.add_subplot(211)
1569
- ax.hist(lenflats,bins=mybins,cumulative=True,density=True)
1570
- ax.set_xlabel(_('Nb nodes in flat area - runoff'))
1571
- ax.set_xticks(myticks)
1572
- ax.set_xbound(.5,np.max(lenflats))
1573
- ax.set_ylabel('Cumulative flat areas')
1574
- #ax.set_yscale('log')
1575
-
1576
- ax=fig.add_subplot(212)
1577
- ax.hist(lenflatsrivers,bins=mybinsrivers,cumulative=True,density=True)
1578
- ax.set_xlabel(_('Nb nodes in flat area - rivers'))
1579
- ax.set_xticks(myticksrivers)
1580
- ax.set_xbound(.5,np.max(lenflatsrivers))
1581
- ax.set_ylabel('Cumulative flat areas')
1582
- #ax.set_yscale('log')
1583
- fig.canvas.draw()
1584
-
1585
- #Tri des pentes dans différentes listes
1586
-
1587
- #toutes les mailles
1588
- sdown=[]
1589
- sup=[]
1590
- for curflat in myflats:
1591
- for curnode in curflat:
1592
- #recherche de la pente aval plus grande que le seuil
1593
- sdown.append(curnode.slope_down(eps))
1594
- #recherche de la pente amont moyenne - uniquement pour les mailles qui ont une pente supérieure au seuil
1595
- sup.append(curnode.mean_slope_up(eps))
1596
-
1597
- sflat=[]
1598
- sdownraw=[]
1599
- for curflat in myflats:
1600
- for curnode in curflat:
1601
- #pente de la maille aval
1602
- sdownraw.append(curnode.down.slope)
1603
- #pente courante
1604
- sflat.append(curnode.slope)
1605
-
1606
- #mailles rivières
1607
- sdownriv=[]
1608
- supriv=[]
1609
- suponlyriv=[]
1610
- for curflat in myflatsrivers:
1611
- for curnode in curflat:
1612
- #recherche de la pente aval plus grande que le seuil
1613
- sdownriv.append(curnode.slope_down(eps))
1614
- #recherche de la pente amont moyenne - uniquement pour les mailles qui ont une pente supérieure au seuil
1615
- supriv.append(curnode.mean_slope_up(eps))
1616
- #recherche de la pente amont > seuil
1617
- suponlyriv.append(curnode.slope_upriver(eps))
1618
-
1619
- sdownd8=[]
1620
- suponlyriv1=[]
1621
- for curflat in myflatsrivers:
1622
- for curnode in curflat:
1623
- #pente aval selon voisines D8
1624
- sdownd8.append(curnode.sloped8)
1625
- #recherche de la pente amont > seuil
1626
- suponlyriv1.append(curnode.slope_upriver(eps))
1627
-
1628
- sflatriver=[]
1629
- sdownrawriver=[]
1630
- sd8rawriver=[]
1631
- for curflat in myflatsrivers:
1632
- if len(curflat)==1:
1633
- for curnode in curflat:
1634
- if not curnode.down is None:
1635
- sd8rawriver.append(curnode.sloped8)
1636
- sdownrawriver.append(curnode.down.slope)
1637
- sflatriver.append(curnode.slope)
1638
-
1639
-
1640
- #tracage des graphiques
1641
- fig=self.myplotterflat.add("Scatter plots")
1642
- ax=fig.add_subplot(211)
1643
- ax.scatter(sdownrawriver,sflatriver,marker='o',label='slope down vs flat slope')
1644
- ax.scatter(sdownriv,suponlyriv,marker='+',label='slope down vs slope d8')
1645
- ax=fig.add_subplot(212)
1646
- ax.scatter(sdownraw,sflat,marker='0',label='slope down vs flat slope')
1647
- ax.scatter(sdown,sup,marker='+',label='slope down vs slope up')
1648
- fig.canvas.draw()
1649
-
1650
- fig=self.myplotterflat.add("Scatter plots 2")
1651
- curax=fig.add_subplot(221)
1652
- curax.scatter(sdown,sup,marker='+')
1653
- curax.set_xlabel(_('Slope down [-]'))
1654
- curax.set_ylabel(_('Mean slope up [-]'))
1655
- curax.set_aspect('equal','box')
1656
- curax.set_xbound(0,.55)
1657
- curax.set_ybound(0,.55)
1658
- curax.set_title('Runoff')
1659
-
1660
- curax=fig.add_subplot(222)
1661
- curax.scatter(sdownriv,supriv,marker='+')
1662
- curax.set_xlabel(_('Slope down [-]'))
1663
- curax.set_ylabel(_('Mean slope up [-]'))
1664
- curax.set_aspect('equal','box')
1665
- curax.set_xbound(0,.55)
1666
- curax.set_ybound(0,.55)
1667
- curax.set_title('River')
1668
-
1669
- curax=fig.add_subplot(223)
1670
- curax.scatter(sdownriv,suponlyriv,marker='+')
1671
- curax.set_xlabel(_('Slope down [-]'))
1672
- curax.set_ylabel(_('Slope up only river [-]'))
1673
- curax.set_aspect('equal','box')
1674
- curax.set_xbound(0,.55)
1675
- curax.set_ybound(0,.55)
1676
- curax.set_title('River')
1677
-
1678
- curax=fig.add_subplot(224)
1679
- curax.scatter(sdownd8,suponlyriv1,marker='+')
1680
- curax.set_xlabel(_('Slope D8 [-]'))
1681
- curax.set_ylabel(_('Slope up only river [-]'))
1682
- curax.set_aspect('equal','box')
1683
- curax.set_xbound(0,.3)
1684
- curax.set_ybound(0,.3)
1685
- curax.set_title('River')
1686
- fig.canvas.draw()