Skip to content

Commit a1afc40

Browse files
committed
2 parents 8bbed4a + 6a1953c commit a1afc40

12 files changed

+1673
-123
lines changed

epidemic_roman/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
# Susceptible-Infected-Recovered Disease Spread Model
22

3-
Yet another Cell-DEVS implementation of the cellular automata model presented by [Hoya White et al.](https://doi.org/10.1016/j.amc.2006.06.126).
3+
Yet another Cell-DEVS implementation of the cellular automata model presented by [Hoya White et al.](https://www.sciencedirect.com/science/article/pii/S0096300306009295).
44
However, rules have been re-interpreted by [Román Cárdenas](mailto:[email protected]).
55

66

77
## How to run the model:
88

99
In the linux terminal, type:
1010
```shell
11-
> ./../cd++ -mSsir_roman.ma -lresults/sir_roman.log
11+
> ./../cd++ -msir_roman.ma -lresults/sir_roman.log
1212
```
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
2+
import argparse
3+
4+
parser = argparse.ArgumentParser(description='Auxiliar script to generate Zhong-based CA models')
5+
6+
parser.add_argument('-f', '--infected_steps', type=int, default=6, help='Number of days for the infected state')
7+
parser.add_argument('-r', '--recovered_steps', type=int, default=7, help='Number of days for the recovered state')
8+
parser.add_argument('-t', '--template_ma', type=str, default="template_sirs_zhong_ma", help='Path to zhong .ma template')
9+
parser.add_argument('-m', '--template_macros', type=str, default="template_sirs_zhong_macros", help='Path to zhong macros template')
10+
parser.add_argument('-o', '--out_ma_file', type=str, default="out.ma", help='Output path of the .ma file')
11+
parser.add_argument('-om', '--out_macros_file', type=str, default="sirs_zhong_macros.inc", help='Output path of the macros file')
12+
parser.add_argument('-ov', '--out_var_file', type=str, default="sirs_zhong.var", help='Output path of the .var file')
13+
parser.add_argument('-v', '--virulences', type=str, default="0.6", help='Default virulence values per infected state')
14+
parser.add_argument('-c', '--cured_rates', type=str, default="0.0", help='Default cured rates values per infected state')
15+
16+
args = parser.parse_args()
17+
18+
i = 1
19+
states = ["sus_0"]
20+
neighbors = ["(1,0)", "(0,-1)", "(0,1)", "(-1,0)"]
21+
steps_per_state = list(map(str, [args.infected_steps, args.recovered_steps]))
22+
23+
while i <= args.infected_steps:
24+
states.append("inf_%d" % i)
25+
i += 1
26+
27+
while i <= args.infected_steps + args.recovered_steps:
28+
states.append("rec_%d" % i)
29+
i += 1
30+
31+
##############################
32+
# GENERATION OF THE .MA FILE
33+
##############################
34+
content = ""
35+
with open(args.template_ma, "r") as f:
36+
content = f.read()
37+
38+
internal_vars = ["i_%s" % s for s in states] + \
39+
["v_%d" % n for n in range(1, args.infected_steps + 1)] + \
40+
["cr_%d" % n for n in range(1, args.infected_steps)]
41+
content = content.replace("[[internal_vars]]", " ".join(internal_vars))
42+
43+
internal_vars_values = " ".join(steps_per_state + ["1.0"] + ["0.0"] * (len(states) - 1))
44+
if "," in args.virulences:
45+
virulences = list(args.virulences.split(","))
46+
else:
47+
virulences = [args.virulences] * args.infected_steps
48+
49+
internal_vars_values += " %s" % " ".join(virulences)
50+
51+
if "," in args.cured_rates:
52+
cured_rates = list(args.cured_rates.split(","))
53+
else:
54+
cured_rates = [args.cured_rates] * (args.infected_steps - 1)
55+
56+
internal_vars_values += " %s" % " ".join(cured_rates)
57+
58+
content = content.replace("[[internal_vars_values]]", internal_vars_values)
59+
update_ports_str = " ".join(["~%s := $i_%s;" % (s, s) for s in states])
60+
content = content.replace("[[initial_ports_set_up]]", update_ports_str)
61+
content = content.replace("[[update_ports_step]]", update_ports_str)
62+
content = content.replace("[[ports]]", " ".join(states))
63+
64+
update_rules = ""
65+
idx_first_rec = len(states)-args.recovered_steps
66+
for i in range(len(states)-1, idx_first_rec, -1):
67+
update_rules += "$i_%s := $i_%s;\n" % (states[i], states[i-1])
68+
update_rules += "$i_%s := $i_%s + #macro(local_cured);\n\n" % (states[idx_first_rec], states[idx_first_rec-1])
69+
70+
for i in range(idx_first_rec-1, 1, -1):
71+
cr = "$cr_%s" % states[i - 1].split("_")[-1]
72+
update_rules += "$i_%s := round(min((1 - %s) * $i_%s, 1)*100)/100;\n" % (states[i], cr, states[i - 1])
73+
update_rules += "$i_%s := #macro(internal_infected) + #macro(external_infected);\n\n" % states[1]
74+
75+
update_rules += "$i_%s := 1 " % states[0]
76+
update_rules += " ".join(["- $i_%s" % s for s in states[1:]])
77+
update_rules += ";\n"
78+
79+
content = content.replace("[[update_vars_step]]", update_rules)
80+
81+
with open(args.out_ma_file, "w") as f:
82+
f.write(content)
83+
84+
#################################
85+
# GENERATION OF THE MACROS FILE
86+
#################################
87+
88+
content = ""
89+
with open(args.template_macros, "r") as f:
90+
content = f.read()
91+
92+
local_cured_rules = []
93+
for i in range(idx_first_rec-2, 0, -1):
94+
cr = "$cr_%s" % states[i].split("_")[-1]
95+
local_cured_rules.append("round(min(%s * $i_%s, 1)*100)" % (cr, states[i]))
96+
97+
content = content.replace("[[local_cured]]", "(( %s ) / 100 )" % " +\n".join(local_cured_rules))
98+
content = content.replace("[[infected_vars]]", " + ".join(["i_%s" % s for s in states[idx_first_rec:0]]))
99+
100+
external_infected_comp = \
101+
"""( round(min((
102+
$connection * $movement * $i_sus_0 * (
103+
[[external_infected]]
104+
)), 1)*100) / 100 )"""
105+
106+
internal_infected_comp = \
107+
"""( round(min((
108+
$i_sus_0 * (
109+
[[internal_infected]]
110+
)), 1)*100) / 100 )"""
111+
112+
external_infected_rules = []
113+
for nei in neighbors:
114+
lines = []
115+
for s in states[args.infected_steps:0:-1]:
116+
v = "$v_%s" % s.split("_")[-1]
117+
line = "(%s~pop / $population) * %s * %s~%s" % (nei, v, nei, s)
118+
lines.append(line)
119+
120+
ext_comp = external_infected_comp.replace("[[external_infected]]", " +\n".join(lines))
121+
external_infected_rules.append(ext_comp)
122+
123+
content = content.replace("[[external_infected]]", " +\n".join(external_infected_rules))
124+
125+
lines = []
126+
for s in states[args.infected_steps:0:-1]:
127+
v = "$v_%s" % s.split("_")[-1]
128+
line = "(%s * $i_%s)" % (v, s)
129+
lines.append(line)
130+
131+
internal_infected_rule = internal_infected_comp.replace("[[internal_infected]]", " +\n".join(lines))
132+
content = content.replace("[[internal_infected]]", internal_infected_rule)
133+
134+
with open(args.out_macros_file, "w") as f:
135+
f.write(content)
136+
137+
138+
#################################
139+
# GENERATION OF THE .VAR FILE
140+
#################################
141+
142+
with open(args.out_var_file, "w") as f:
143+
ivv = internal_vars_values.split()
144+
assert ivv[2] == "1.0" or ivv[2] == "1", "Unexpected vals (original susceptible: %s)" % ivv[2]
145+
ivv[2] = "0.7"
146+
ivv[3] = "0.3"
147+
stimulus = "(25,25) = 100 1 0.6 %s\n" % " ".join(ivv)
148+
f.write(stimulus)
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#include(sirs_zhong_macros.inc)
2+
[top]
3+
components : area
4+
5+
[area]
6+
type : cell
7+
width : 50
8+
height : 50
9+
delay : transport
10+
defaultDelayTime : 1
11+
border : wrapped
12+
neighbors : area(-1,0)
13+
neighbors : area(0,-1) area(0,0) area(0,1)
14+
neighbors : area(1,0)
15+
initialvalue : -1
16+
17+
localtransition : sirs-zhong-rule
18+
19+
statevariables: population connection movement t_i t_r [[internal_vars]]
20+
statevalues: 100 1 0.6 [[internal_vars_values]]
21+
initialvariablesvalue: sirs_zhong.var
22+
23+
neighborports : initial pop [[ports]]
24+
25+
[sirs-zhong-rule]
26+
rule : {~initial := 0; ~pop := $population; [[initial_ports_set_up]]}
27+
1 {(0,0)~initial = -1}
28+
29+
rule : {
30+
~pop := $population; [[update_ports_step]]
31+
}
32+
{
33+
[[update_vars_step]]
34+
}
35+
1 { (0,0)~initial != -1 }
36+
37+
38+
39+
40+
41+
42+
43+
44+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
#BeginMacro(local_cured)
3+
[[local_cured]]
4+
#EndMacro
5+
6+
#BeginMacro(internal_infected)
7+
[[internal_infected]]
8+
#EndMacro
9+
10+
#BeginMacro(external_infected)
11+
[[external_infected]]
12+
#EndMacro
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#include(sirs_zhong_macros.inc)
2+
[top]
3+
components : area
4+
5+
[area]
6+
type : cell
7+
width : 50
8+
height : 50
9+
delay : transport
10+
defaultDelayTime : 1
11+
border : wrapped
12+
neighbors : area(-1,0)
13+
neighbors : area(0,-1) area(0,0) area(0,1)
14+
neighbors : area(1,0)
15+
initialvalue : -1
16+
17+
localtransition : sirs-zhong-rule
18+
19+
statevariables: population connection movement t_i t_r i_sus_0 i_inf_1 i_inf_2 i_inf_3 i_inf_4 i_inf_5 i_inf_6 i_rec_7 i_rec_8 i_rec_9 i_rec_10 i_rec_11 i_rec_12 i_rec_13 i_rec_14 i_rec_15 i_rec_16 i_rec_17 i_rec_18 i_rec_19 i_rec_20 i_rec_21 i_rec_22 v_1 v_2 v_3 v_4 v_5 v_6 cr_1 cr_2 cr_3 cr_4 cr_5
20+
statevalues: 100 1 0.6 6 16 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.15 0.15 0.15 0.15 0.15 0.15 0.07 0.07 0.07 0.07 0.07
21+
initialvariablesvalue: sirs_zhong.var
22+
23+
neighborports : initial pop sus_0 inf_1 inf_2 inf_3 inf_4 inf_5 inf_6 rec_7 rec_8 rec_9 rec_10 rec_11 rec_12 rec_13 rec_14 rec_15 rec_16 rec_17 rec_18 rec_19 rec_20 rec_21 rec_22
24+
25+
[sirs-zhong-rule]
26+
rule : {~initial := 0; ~pop := $population; ~sus_0 := $i_sus_0; ~inf_1 := $i_inf_1; ~inf_2 := $i_inf_2; ~inf_3 := $i_inf_3; ~inf_4 := $i_inf_4; ~inf_5 := $i_inf_5; ~inf_6 := $i_inf_6; ~rec_7 := $i_rec_7; ~rec_8 := $i_rec_8; ~rec_9 := $i_rec_9; ~rec_10 := $i_rec_10; ~rec_11 := $i_rec_11; ~rec_12 := $i_rec_12; ~rec_13 := $i_rec_13; ~rec_14 := $i_rec_14; ~rec_15 := $i_rec_15; ~rec_16 := $i_rec_16; ~rec_17 := $i_rec_17; ~rec_18 := $i_rec_18; ~rec_19 := $i_rec_19; ~rec_20 := $i_rec_20; ~rec_21 := $i_rec_21; ~rec_22 := $i_rec_22;}
27+
1 {(0,0)~initial = -1}
28+
29+
rule : {
30+
~pop := $population; ~sus_0 := $i_sus_0; ~inf_1 := $i_inf_1; ~inf_2 := $i_inf_2; ~inf_3 := $i_inf_3; ~inf_4 := $i_inf_4; ~inf_5 := $i_inf_5; ~inf_6 := $i_inf_6; ~rec_7 := $i_rec_7; ~rec_8 := $i_rec_8; ~rec_9 := $i_rec_9; ~rec_10 := $i_rec_10; ~rec_11 := $i_rec_11; ~rec_12 := $i_rec_12; ~rec_13 := $i_rec_13; ~rec_14 := $i_rec_14; ~rec_15 := $i_rec_15; ~rec_16 := $i_rec_16; ~rec_17 := $i_rec_17; ~rec_18 := $i_rec_18; ~rec_19 := $i_rec_19; ~rec_20 := $i_rec_20; ~rec_21 := $i_rec_21; ~rec_22 := $i_rec_22;
31+
}
32+
{
33+
$i_rec_22 := $i_rec_21;
34+
$i_rec_21 := $i_rec_20;
35+
$i_rec_20 := $i_rec_19;
36+
$i_rec_19 := $i_rec_18;
37+
$i_rec_18 := $i_rec_17;
38+
$i_rec_17 := $i_rec_16;
39+
$i_rec_16 := $i_rec_15;
40+
$i_rec_15 := $i_rec_14;
41+
$i_rec_14 := $i_rec_13;
42+
$i_rec_13 := $i_rec_12;
43+
$i_rec_12 := $i_rec_11;
44+
$i_rec_11 := $i_rec_10;
45+
$i_rec_10 := $i_rec_9;
46+
$i_rec_9 := $i_rec_8;
47+
$i_rec_8 := $i_rec_7;
48+
$i_rec_7 := $i_inf_6 + #macro(local_cured);
49+
50+
$i_inf_6 := round(min((1 - $cr_5) * $i_inf_5, 1)*100)/100;
51+
$i_inf_5 := round(min((1 - $cr_4) * $i_inf_4, 1)*100)/100;
52+
$i_inf_4 := round(min((1 - $cr_3) * $i_inf_3, 1)*100)/100;
53+
$i_inf_3 := round(min((1 - $cr_2) * $i_inf_2, 1)*100)/100;
54+
$i_inf_2 := round(min((1 - $cr_1) * $i_inf_1, 1)*100)/100;
55+
$i_inf_1 := #macro(internal_infected) + #macro(external_infected);
56+
57+
$i_sus_0 := 1 - $i_inf_1 - $i_inf_2 - $i_inf_3 - $i_inf_4 - $i_inf_5 - $i_inf_6 - $i_rec_7 - $i_rec_8 - $i_rec_9 - $i_rec_10 - $i_rec_11 - $i_rec_12 - $i_rec_13 - $i_rec_14 - $i_rec_15 - $i_rec_16 - $i_rec_17 - $i_rec_18 - $i_rec_19 - $i_rec_20 - $i_rec_21 - $i_rec_22;
58+
59+
}
60+
1 { (0,0)~initial != -1 }
61+
62+
63+
64+
65+
66+
67+
68+
69+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[-100; -0.001] 255 0 0
2+
[0; 0.200] 0 0 0
3+
[0.201; 0.400] 50 50 50
4+
[0.401; 0.600] 100 100 100
5+
[0.601; 0.800] 150 150 150
6+
[0.801; 1.00] 200 200 200
7+
[1.001;100] 255 0 0
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
(25,25) = 100 1 0.6 6 16 0.7 0.3 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.15 0.15 0.15 0.15 0.15 0.15 0.07 0.07 0.07 0.07 0.07
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
2+
#BeginMacro(local_cured)
3+
(( round(min($cr_5 * $i_inf_5, 1)*100) +
4+
round(min($cr_4 * $i_inf_4, 1)*100) +
5+
round(min($cr_3 * $i_inf_3, 1)*100) +
6+
round(min($cr_2 * $i_inf_2, 1)*100) +
7+
round(min($cr_1 * $i_inf_1, 1)*100) ) / 100 )
8+
#EndMacro
9+
10+
#BeginMacro(internal_infected)
11+
( round(min((
12+
$i_sus_0 * (
13+
($v_6 * $i_inf_6) +
14+
($v_5 * $i_inf_5) +
15+
($v_4 * $i_inf_4) +
16+
($v_3 * $i_inf_3) +
17+
($v_2 * $i_inf_2) +
18+
($v_1 * $i_inf_1)
19+
)), 1)*100) / 100 )
20+
#EndMacro
21+
22+
#BeginMacro(external_infected)
23+
( round(min((
24+
$connection * $movement * $i_sus_0 * (
25+
((1,0)~pop / $population) * $v_6 * (1,0)~inf_6 +
26+
((1,0)~pop / $population) * $v_5 * (1,0)~inf_5 +
27+
((1,0)~pop / $population) * $v_4 * (1,0)~inf_4 +
28+
((1,0)~pop / $population) * $v_3 * (1,0)~inf_3 +
29+
((1,0)~pop / $population) * $v_2 * (1,0)~inf_2 +
30+
((1,0)~pop / $population) * $v_1 * (1,0)~inf_1
31+
)), 1)*100) / 100 ) +
32+
( round(min((
33+
$connection * $movement * $i_sus_0 * (
34+
((0,-1)~pop / $population) * $v_6 * (0,-1)~inf_6 +
35+
((0,-1)~pop / $population) * $v_5 * (0,-1)~inf_5 +
36+
((0,-1)~pop / $population) * $v_4 * (0,-1)~inf_4 +
37+
((0,-1)~pop / $population) * $v_3 * (0,-1)~inf_3 +
38+
((0,-1)~pop / $population) * $v_2 * (0,-1)~inf_2 +
39+
((0,-1)~pop / $population) * $v_1 * (0,-1)~inf_1
40+
)), 1)*100) / 100 ) +
41+
( round(min((
42+
$connection * $movement * $i_sus_0 * (
43+
((0,1)~pop / $population) * $v_6 * (0,1)~inf_6 +
44+
((0,1)~pop / $population) * $v_5 * (0,1)~inf_5 +
45+
((0,1)~pop / $population) * $v_4 * (0,1)~inf_4 +
46+
((0,1)~pop / $population) * $v_3 * (0,1)~inf_3 +
47+
((0,1)~pop / $population) * $v_2 * (0,1)~inf_2 +
48+
((0,1)~pop / $population) * $v_1 * (0,1)~inf_1
49+
)), 1)*100) / 100 ) +
50+
( round(min((
51+
$connection * $movement * $i_sus_0 * (
52+
((-1,0)~pop / $population) * $v_6 * (-1,0)~inf_6 +
53+
((-1,0)~pop / $population) * $v_5 * (-1,0)~inf_5 +
54+
((-1,0)~pop / $population) * $v_4 * (-1,0)~inf_4 +
55+
((-1,0)~pop / $population) * $v_3 * (-1,0)~inf_3 +
56+
((-1,0)~pop / $population) * $v_2 * (-1,0)~inf_2 +
57+
((-1,0)~pop / $population) * $v_1 * (-1,0)~inf_1
58+
)), 1)*100) / 100 )
59+
#EndMacro

0 commit comments

Comments
 (0)