Skip to content

Commit 810a352

Browse files
refactor update
1 parent b1de47d commit 810a352

File tree

8 files changed

+535
-597
lines changed

8 files changed

+535
-597
lines changed

config.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,18 @@
77
class config_error(Exception):
88
pass
99

10-
class configuration():
10+
class Configuration():
1111
def __init__(self, *args, **kwargs):
1212
#simulation variables
1313
self.verbose = False #whether to print infections, recoveries and fatalities to the terminal
1414
self.simulation_steps = 10000 #total simulation steps performed
1515
self.tstep = 0 #current simulation timestep
1616
self.save_data = True #whether to dump data
17+
self.save_timesteps = True #dumps population data every time step
1718

1819
#scenario flags
1920
self.traveling_infects = False
20-
self.self_isolate = False
21+
self.self_isolate = True
2122
self.lockdown = False
2223
self.lockdown_percentage = 0.1 #after this proportion is infected, lock-down begins
2324
self.lockdown_compliance = 0.95 #fraction of the population that will obey the lockdown
File renamed without changes.

infection.py

Lines changed: 116 additions & 116 deletions
Large diffs are not rendered by default.

motion.py

Lines changed: 25 additions & 223 deletions
Original file line numberDiff line numberDiff line change
@@ -45,44 +45,44 @@ def out_of_bounds(population, xbounds, ybounds):
4545
#determine number of elements that need to be updated
4646

4747
shp = population[:,3][(population[:,1] <= xbounds[:,0]) &
48-
(population[:,3] < 0)].shape
48+
(population[:,3] < 0)].shape
4949
population[:,3][(population[:,1] <= xbounds[:,0]) &
5050
(population[:,3] < 0)] = np.clip(np.random.normal(loc = 0.5,
51-
scale = 0.5/3,
52-
size = shp),
53-
a_min = 0.05, a_max = 1)
51+
scale = 0.5/3,
52+
size = shp),
53+
a_min = 0.05, a_max = 1)
5454

5555
shp = population[:,3][(population[:,1] >= xbounds[:,1]) &
56-
(population[:,3] > 0)].shape
56+
(population[:,3] > 0)].shape
5757
population[:,3][(population[:,1] >= xbounds[:,1]) &
5858
(population[:,3] > 0)] = np.clip(-np.random.normal(loc = 0.5,
59-
scale = 0.5/3,
60-
size = shp),
61-
a_min = -1, a_max = -0.05)
59+
scale = 0.5/3,
60+
size = shp),
61+
a_min = -1, a_max = -0.05)
6262

6363
#update y heading
6464
shp = population[:,4][(population[:,2] <= ybounds[:,0]) &
65-
(population[:,4] < 0)].shape
65+
(population[:,4] < 0)].shape
6666
population[:,4][(population[:,2] <= ybounds[:,0]) &
6767
(population[:,4] < 0)] = np.clip(np.random.normal(loc = 0.5,
68-
scale = 0.5/3,
69-
size = shp),
70-
a_min = 0.05, a_max = 1)
68+
scale = 0.5/3,
69+
size = shp),
70+
a_min = 0.05, a_max = 1)
7171

7272
shp = population[:,4][(population[:,2] >= ybounds[:,1]) &
73-
(population[:,4] > 0)].shape
73+
(population[:,4] > 0)].shape
7474
population[:,4][(population[:,2] >= ybounds[:,1]) &
7575
(population[:,4] > 0)] = np.clip(-np.random.normal(loc = 0.5,
76-
scale = 0.5/3,
77-
size = shp),
78-
a_min = -1, a_max = -0.05)
76+
scale = 0.5/3,
77+
size = shp),
78+
a_min = -1, a_max = -0.05)
7979

8080
return population
8181

8282

8383
def update_randoms(population, pop_size, heading_update_chance=0.02,
84-
speed_update_chance=0.02, heading_multiplication=1,
85-
speed_multiplication=1, speed=0.01):
84+
speed_update_chance=0.02, heading_multiplication=1,
85+
speed_multiplication=1, speed=0.01):
8686
'''updates random states such as heading and speed
8787
8888
Function that randomized the headings and speeds for population members
@@ -118,223 +118,25 @@ def update_randoms(population, pop_size, heading_update_chance=0.02,
118118
update = np.random.random(size=(pop_size,))
119119
shp = update[update <= heading_update_chance].shape
120120
population[:,3][update <= heading_update_chance] = np.random.normal(loc = 0,
121-
scale = 1/3,
122-
size = shp) * heading_multiplication
121+
scale = 1/3,
122+
size = shp) * heading_multiplication
123123
#y
124124
update = np.random.random(size=(pop_size,))
125125
shp = update[update <= heading_update_chance].shape
126126
population[:,4][update <= heading_update_chance] = np.random.normal(loc = 0,
127-
scale = 1/3,
128-
size = shp) * heading_multiplication
127+
scale = 1/3,
128+
size = shp) * heading_multiplication
129129
#randomize speeds
130130
update = np.random.random(size=(pop_size,))
131131
shp = update[update <= heading_update_chance].shape
132132
population[:,5][update <= heading_update_chance] = np.random.normal(loc = speed,
133-
scale = speed / 3,
134-
size = shp) * speed_multiplication
133+
scale = speed / 3,
134+
size = shp) * speed_multiplication
135135

136136
population[:,5] = np.clip(population[:,5], a_min=0.0001, a_max=0.05)
137137
return population
138138

139139

140-
#########################
141-
##### PATH PLANNING #####
142-
#########################
143-
144-
def set_destination(population, destinations):
145-
'''sets destination of population
146-
147-
Sets the destination of population if destination marker is not 0.
148-
Updates headings and speeds as well.
149-
150-
Keyword arguments
151-
-----------------
152-
population : ndarray
153-
the array containing all the population information
154-
155-
destinations : ndarray
156-
the array containing all destinations information
157-
'''
158-
159-
#how many destinations are active
160-
active_dests = np.unique(population[:,11][population[:,11] != 0])
161-
162-
#set destination
163-
for d in active_dests:
164-
dest_x = destinations[:,int((d - 1) * 2)]
165-
dest_y = destinations[:,int(((d - 1) * 2) + 1)]
166-
167-
#compute new headings
168-
head_x = dest_x - population[:,1]
169-
head_y = dest_y - population[:,2]
170-
171-
#head_x = head_x / np.sqrt(head_x)
172-
#head_y = head_y / np.sqrt(head_y)
173-
174-
#reinsert headings into population of those not at destination yet
175-
population[:,3][(population[:,11] == d) &
176-
(population[:,12] == 0)] = head_x[(population[:,11] == d) &
177-
(population[:,12] == 0)]
178-
population[:,4][(population[:,11] == d) &
179-
(population[:,12] == 0)] = head_y[(population[:,11] == d) &
180-
(population[:,12] == 0)]
181-
#set speed to 0.01
182-
population[:,5][(population[:,11] == d) &
183-
(population[:,12] == 0)] = 0.02
184-
185-
return population
186-
187-
188-
def check_at_destination(population, destinations, wander_factor=1.5):
189-
'''check who is at their destination already
190-
191-
Takes subset of population with active destination and
192-
tests who is at the required coordinates. Updates at destination
193-
column for people at destination.
194-
195-
Keyword arguments
196-
-----------------
197-
population : ndarray
198-
the array containing all the population information
199-
200-
destinations : ndarray
201-
the array containing all destinations information
202-
203-
wander_factor : int or float
204-
defines how far outside of 'wander range' the destination reached
205-
is triggered
206-
'''
207-
208-
#how many destinations are active
209-
active_dests = np.unique(population[:,11][(population[:,11] != 0)])
210-
211-
#see who is at destination
212-
for d in active_dests:
213-
dest_x = destinations[:,int((d - 1) * 2)]
214-
dest_y = destinations[:,int(((d - 1) * 2) + 1)]
215-
216-
#see who arrived at destination and filter out who already was there
217-
at_dest = population[(np.abs(population[:,1] - dest_x) < (population[:,13] * wander_factor)) &
218-
(np.abs(population[:,2] - dest_y) < (population[:,14] * wander_factor)) &
219-
(population[:,12] == 0)]
220-
221-
if len(at_dest) > 0:
222-
#mark those as arrived
223-
at_dest[:,12] = 1
224-
#insert random headings and speeds for those at destination
225-
at_dest = update_randoms(at_dest, len(at_dest), 1, 1)
226-
227-
#at_dest[:,5] = 0.001
228-
229-
#reinsert into population
230-
population[(np.abs(population[:,1] - dest_x) < (population[:,13] * wander_factor)) &
231-
(np.abs(population[:,2] - dest_y) < (population[:,14] * wander_factor)) &
232-
(population[:,12] == 0)] = at_dest
233-
234-
235-
return population
236-
237-
238-
def keep_at_destination(population, destinations, wander_factor=1):
239-
'''keeps those who have arrived, within wander range
240-
241-
Function that keeps those who have been marked as arrived at their
242-
destination within their respective wander ranges
243-
244-
Keyword arguments
245-
-----------------
246-
population : ndarray
247-
the array containing all the population information
248-
249-
destinations : ndarray
250-
the array containing all destinations information
251-
252-
wander_factor : int or float
253-
defines how far outside of 'wander range' the destination reached
254-
is triggered
255-
'''
256-
257-
#how many destinations are active
258-
active_dests = np.unique(population[:,11][(population[:,11] != 0) &
259-
(population[:,12] == 1)])
260-
261-
for d in active_dests:
262-
dest_x = destinations[:,int((d - 1) * 2)][(population[:,12] == 1) &
263-
(population[:,11] == d)]
264-
dest_y = destinations[:,int(((d - 1) * 2) + 1)][(population[:,12] == 1) &
265-
(population[:,11] == d)]
266-
267-
#see who is marked as arrived
268-
arrived = population[(population[:,12] == 1) &
269-
(population[:,11] == d)]
270-
271-
ids = np.int32(arrived[:,0]) # find unique IDs of arrived persons
272-
273-
#check if there are those out of bounds
274-
#replace x oob
275-
#where x larger than destination + wander, AND heading wrong way, set heading negative
276-
shp = arrived[:,3][arrived[:,1] > (dest_x + (arrived[:,13] * wander_factor))].shape
277-
278-
arrived[:,3][arrived[:,1] > (dest_x + (arrived[:,13] * wander_factor))] = -np.random.normal(loc = 0.5,
279-
scale = 0.5 / 3,
280-
size = shp)
281-
282-
283-
#where x smaller than destination - wander, set heading positive
284-
shp = arrived[:,3][arrived[:,1] < (dest_x - (arrived[:,13] * wander_factor))].shape
285-
arrived[:,3][arrived[:,1] < (dest_x - (arrived[:,13] * wander_factor))] = np.random.normal(loc = 0.5,
286-
scale = 0.5 / 3,
287-
size = shp)
288-
#where y larger than destination + wander, set heading negative
289-
shp = arrived[:,4][arrived[:,2] > (dest_y + (arrived[:,14] * wander_factor))].shape
290-
arrived[:,4][arrived[:,2] > (dest_y + (arrived[:,14] * wander_factor))] = -np.random.normal(loc = 0.5,
291-
scale = 0.5 / 3,
292-
size = shp)
293-
#where y smaller than destination - wander, set heading positive
294-
shp = arrived[:,4][arrived[:,2] < (dest_y - (arrived[:,14] * wander_factor))].shape
295-
arrived[:,4][arrived[:,2] < (dest_y - (arrived[:,14] * wander_factor))] = np.random.normal(loc = 0.5,
296-
scale = 0.5 / 3,
297-
size = shp)
298-
299-
#slow speed
300-
arrived[:,5] = np.random.normal(loc = 0.005,
301-
scale = 0.005 / 3,
302-
size = arrived[:,5].shape)
303-
304-
#reinsert into population
305-
population[(population[:,12] == 1) &
306-
(population[:,11] == d)] = arrived
307-
308-
return population
309-
310-
311-
def reset_destinations(population, ids=[]):
312-
'''clears destination markers
313-
314-
Function that clears all active destination markers from the population
315-
316-
Keyword arguments
317-
-----------------
318-
population : ndarray
319-
the array containing all the population information
320-
321-
ids : ndarray or list
322-
array containing the id's of the population members that need their
323-
destinations reset
324-
'''
325-
326-
327-
if len(ids) == 0:
328-
#if ids empty, reset everyone
329-
population[:,11] = 0
330-
else:
331-
pass
332-
#else, reset id's
333-
334-
335-
pass
336-
337-
338140
def get_motion_parameters(xmin, ymin, xmax, ymax):
339141
'''gets destination center and wander ranges
340142
@@ -354,4 +156,4 @@ def get_motion_parameters(xmin, ymin, xmax, ymax):
354156
x_wander = (xmax - xmin) / 2
355157
y_wander = (ymax - ymin) / 2
356158

357-
return x_center, y_center, x_wander, y_wander
159+
return x_center, y_center, x_wander, y_wander

0 commit comments

Comments
 (0)