99from math import cos
1010import numpy as np
1111from numpy .random import random
12- from tqdm import tqdm
12+ from numpy import maximum , nansum
1313
1414
1515def random_pick_seed (choices , probs = None ):
@@ -39,76 +39,63 @@ def random_pick_seed(choices, probs=None):
3939 return choices [idx ]
4040
4141
42- def make_weight (Particles ):
43- """Make an array with the routing weights."""
44- # local namespace function imports
45- from numpy import maximum
46- from numpy import nansum
47- # init the weight array
48- L , W = np .shape (Particles .stage )
49- Particles .weight = np .zeros ((L , W , 9 ))
50- # do weighting calculation for each cell
51- print ('Calculating routing weights ...' )
52- for i in tqdm (list (range (1 , L - 1 )), ascii = True ):
53- for j in list (range (1 , W - 1 )):
54- # weights for each location in domain
55- # get stage values for neighboring cells
56- stage_ind = Particles .stage [i - 1 :i + 2 , j - 1 :j + 2 ]
42+ def make_weight (Particles , ind ):
43+ """Update weighting array with weights at this index"""
44+ # get stage values for neighboring cells
45+ stage_ind = Particles .stage [ind [0 ]- 1 :ind [0 ]+ 2 , ind [1 ]- 1 :ind [1 ]+ 2 ]
5746
58- # calculate surface slope weights
59- weight_sfc = maximum (0 ,
60- (Particles .stage [i , j ] - stage_ind ) /
61- Particles .distances )
47+ # calculate surface slope weights
48+ weight_sfc = maximum (0 ,
49+ (Particles .stage [ind ] - stage_ind ) /
50+ Particles .distances )
6251
63- # calculate inertial component weights
64- weight_int = maximum (0 , ((Particles .qx [i , j ] * Particles .jvec +
65- Particles .qy [i , j ] * Particles .ivec ) /
66- Particles .distances ))
52+ # calculate inertial component weights
53+ weight_int = maximum (0 , ((Particles .qx [ind ] * Particles .jvec +
54+ Particles .qy [ind ] * Particles .ivec ) /
55+ Particles .distances ))
6756
68- # get depth and cell types for neighboring cells
69- depth_ind = Particles .depth [i - 1 :i + 2 , j - 1 :j + 2 ]
70- ct_ind = Particles .cell_type [i - 1 :i + 2 , j - 1 :j + 2 ]
57+ # get depth and cell types for neighboring cells
58+ depth_ind = Particles .depth [ind [ 0 ] - 1 :ind [ 0 ] + 2 , ind [ 1 ] - 1 :ind [ 1 ] + 2 ]
59+ ct_ind = Particles .cell_type [ind [ 0 ] - 1 :ind [ 0 ] + 2 , ind [ 1 ] - 1 :ind [ 1 ] + 2 ]
7160
72- # set weights for cells that are too shallow, or invalid 0
73- weight_sfc [(depth_ind <= Particles .dry_depth ) | (ct_ind == 2 )] = 0
74- weight_int [(depth_ind <= Particles .dry_depth ) | (ct_ind == 2 )] = 0
61+ # set weights for cells that are too shallow, or invalid 0
62+ weight_sfc [(depth_ind <= Particles .dry_depth ) | (ct_ind == 2 )] = 0
63+ weight_int [(depth_ind <= Particles .dry_depth ) | (ct_ind == 2 )] = 0
7564
76- # if sum of weights is above 0 normalize by sum of weights
77- if nansum (weight_sfc ) > 0 :
78- weight_sfc = weight_sfc / nansum (weight_sfc )
65+ # if sum of weights is above 0 normalize by sum of weights
66+ if nansum (weight_sfc ) > 0 :
67+ weight_sfc = weight_sfc / nansum (weight_sfc )
7968
80- # if sum of weight is above 0 normalize by sum of weights
81- if nansum (weight_int ) > 0 :
82- weight_int = weight_int / nansum (weight_int )
69+ # if sum of weight is above 0 normalize by sum of weights
70+ if nansum (weight_int ) > 0 :
71+ weight_int = weight_int / nansum (weight_int )
8372
84- # define actual weight by using gamma, and weight components
85- weight = Particles .gamma * weight_sfc + \
86- (1 - Particles .gamma ) * weight_int
73+ # define actual weight by using gamma, and weight components
74+ weight = Particles .gamma * weight_sfc + \
75+ (1 - Particles .gamma ) * weight_int
8776
88- # modify the weight by the depth and theta weighting parameter
89- weight = depth_ind ** Particles .theta * weight
77+ # modify the weight by the depth and theta weighting parameter
78+ weight = depth_ind ** Particles .theta * weight
9079
91- # if the depth is below the minimum depth then location is not
92- # considered therefore set the associated weight to nan
93- weight [(depth_ind <= Particles .dry_depth ) | (ct_ind == 2 )] \
94- = np .nan
80+ # if the depth is below the minimum depth then location is not
81+ # considered therefore set the associated weight to nan
82+ weight [(depth_ind <= Particles .dry_depth ) | (ct_ind == 2 )] \
83+ = np .nan
9584
96- # if it's a dead end with only nans and 0's, choose deepest cell
97- if nansum (weight ) <= 0 :
98- weight = np .zeros_like (weight )
99- weight [depth_ind == np .max (depth_ind )] = 1.0
85+ # if it's a dead end with only nans and 0's, choose deepest cell
86+ if nansum (weight ) <= 0 :
87+ weight = np .zeros_like (weight )
88+ weight [depth_ind == np .max (depth_ind )] = 1.0
10089
101- # set weight in the true weight array
102- Particles .weight [i , j , :] = weight .ravel ()
103-
104- print ('Finished routing weight calculation.' )
90+ # set weight in the true weight array
91+ Particles .weight [ind [0 ], ind [1 ], :] = weight .ravel ()
10592
10693
10794def get_weight (Particles , ind ):
10895 """Choose new cell location given an initial location.
10996
11097 Function to randomly choose 1 of the surrounding 8 cells around the
111- current index using the pre-calculated routing weights.
98+ current index using the routing weights from make_weight .
11299
113100 **Inputs** :
114101
@@ -124,6 +111,9 @@ def get_weight(Particles, ind):
124111 New location given as a value between 1 and 8 (inclusive)
125112
126113 """
114+ # Check if weights have been computed for this location:
115+ if nansum (Particles .weight [ind [0 ], ind [1 ], :]) <= 0 :
116+ make_weight (Particles , ind )
127117 # randomly pick the new cell for the particle to move to using the
128118 # random_pick function and the set of weights
129119 if Particles .steepest_descent is not True :
0 commit comments