Skip to content

Commit 03753c6

Browse files
Merge pull request #170 from CodeForPhilly/add_cli
Add cli
2 parents 9587c25 + 733020d commit 03753c6

File tree

3 files changed

+127
-5
lines changed

3 files changed

+127
-5
lines changed

cli.py

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
"""CLI for CHIME."""
2+
3+
from argparse import (
4+
Action,
5+
ArgumentParser,
6+
)
7+
from datetime import datetime
8+
9+
from pandas import DataFrame
10+
11+
from penn_chime.defaults import RateLos
12+
from penn_chime.models import Parameters
13+
from penn_chime.utils import build_admissions_df, build_census_df
14+
15+
16+
class FromFile(Action):
17+
"""From File."""
18+
19+
def __call__(self, parser, namespace, values, option_string=None):
20+
with values as f:
21+
parser.parse_args(f.read().split(), namespace)
22+
23+
24+
def validator(cast, min_value, max_value):
25+
"""Validator."""
26+
27+
def validate(string):
28+
"""Validate."""
29+
value = cast(string)
30+
if min_value is not None:
31+
assert value >= min_value
32+
if max_value is not None:
33+
assert value <= max_value
34+
return value
35+
36+
return validate
37+
38+
39+
def parse_args():
40+
"""Parse args."""
41+
parser = ArgumentParser(description='CHIME')
42+
43+
parser.add_argument('--file', type=open, action=FromFile)
44+
parser.add_argument(
45+
'--prefix',
46+
type=str,
47+
default=datetime.now().strftime("%Y.%m.%d.%H.%M."),
48+
)
49+
50+
for arg, cast, min_value, max_value, help in (
51+
('--current-hospitalized', int, 0, None, "Currently Hospitalized COVID-19 Patients (>= 0)"),
52+
('--doubling-time', float, 0.0, None, "Doubling time before social distancing (days)"),
53+
('--hospitalized-los', int, 0, None, "Hospitalized Length of Stay (days)"),
54+
('--hospitalized-rate', float, 0.00001, 1.0, "Hospitalized Rate: 0.00001 - 1.0"),
55+
('--icu-los', int, 0, None, "ICU Length of Stay (days)"),
56+
('--icu-rate', float, 0.0, 1.0, "ICU Rate: 0.0 - 1.0"),
57+
('--known-infected', int, 0, None,
58+
"Currently Known Regional Infections (>=0) (only used to compute detection rate - does not change projections)"),
59+
('--market_share', float, 0.00001, 1.0, "Hospital Market Share (0.00001 - 1.0)"),
60+
('--n-days', int, 0, None, "Nuber of days to project >= 0"),
61+
('--relative-contact-rate', float, 0.0, 1.0, "Social Distancing Reduction Rate: 0.0 - 1.0"),
62+
('--susceptible', int, 1, None, "Regional Population >= 1"),
63+
('--ventilated-los', int, 0, None, "Hospitalized Length of Stay (days)"),
64+
('--ventilated-rate', float, 0.0, 1.0, "Ventilated Rate: 0.0 - 1.0"),
65+
):
66+
parser.add_argument(arg, type=validator(cast, min_value, max_value))
67+
return parser.parse_args()
68+
69+
70+
def main():
71+
"""Main."""
72+
a = parse_args()
73+
74+
p = Parameters(
75+
current_hospitalized=a.current_hospitalized,
76+
doubling_time=a.doubling_time,
77+
known_infected=a.known_infected,
78+
market_share=a.market_share,
79+
relative_contact_rate=a.relative_contact_rate,
80+
susceptible=a.susceptible,
81+
n_days=a.n_days,
82+
hospitalized=RateLos(a.hospitalized_rate, a.hospitalized_los),
83+
icu=RateLos(a.icu_rate, a.icu_los),
84+
ventilated=RateLos(a.ventilated_rate, a.ventilated_los),
85+
)
86+
87+
raw_df = DataFrame({
88+
"Susceptible": p.susceptible_v,
89+
"Infected": p.infected_v,
90+
"Recovered": p.recovered_v,
91+
})
92+
admits_df = build_admissions_df(p.n_days, *p.dispositions)
93+
census_df = build_census_df(admits_df, *p.lengths_of_stay)
94+
95+
prefix = a.prefix
96+
for df, name in (
97+
(raw_df, 'raw'),
98+
(admits_df, 'admits'),
99+
(census_df, 'census'),
100+
):
101+
df.to_csv(prefix + name + '.csv')
102+
103+
104+
if __name__ == '__main__':
105+
main()

penn_chime/models.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ def __init__(
2222
icu: RateLos,
2323
ventilated: RateLos,
2424

25-
max_y_axis: int
25+
max_y_axis: int = None,
26+
n_days: int = None
2627
):
2728
self.current_hospitalized = current_hospitalized
2829
self.doubling_time = doubling_time
@@ -84,6 +85,13 @@ def __init__(
8485
# TODO constrain values np.log2(...) > 0.0
8586
self.doubling_time_t = 1.0 / np.log2(beta * susceptible - gamma + 1)
8687

88+
self.dispositions = None
89+
self.susceptible_v = self.infected_v = self.recovered_v = None
90+
self.hospitalized_v = self.icu_v = self.ventilated_v = None
91+
92+
if n_days is not None:
93+
self.n_days = n_days
94+
8795
@property
8896
def n_days(self):
8997
return self._n_days
@@ -92,10 +100,6 @@ def n_days(self):
92100
def n_days(self, n_days: int):
93101
self._n_days = n_days
94102

95-
# s := Susceptible, able to be infected
96-
# i := Infected, currently infected with the virus
97-
# r := Recovered, no longer infected with the virus
98-
99103
s_v, i_v, r_v = sim_sir(
100104
self.susceptible,
101105
self.infected,

settings.cfg

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
--current-hospitalized 6
2+
--doubling-time 6.0
3+
--known-infected 157
4+
--relative-contact-rate 0.0
5+
--hospitalized-los 7
6+
--hospitalized-rate 0.05
7+
--icu-los 9
8+
--icu-rate 0.02
9+
--market_share 0.15
10+
--n-days 60
11+
--susceptible 4119405
12+
--ventilated-los 10
13+
--ventilated-rate 0.01

0 commit comments

Comments
 (0)