Skip to content

Commit

Permalink
Merge pull request #170 from CodeForPhilly/add_cli
Browse files Browse the repository at this point in the history
Add cli
  • Loading branch information
quinn-dougherty authored Mar 21, 2020
2 parents 9587c25 + 733020d commit 03753c6
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 5 deletions.
105 changes: 105 additions & 0 deletions cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
"""CLI for CHIME."""

from argparse import (
Action,
ArgumentParser,
)
from datetime import datetime

from pandas import DataFrame

from penn_chime.defaults import RateLos
from penn_chime.models import Parameters
from penn_chime.utils import build_admissions_df, build_census_df


class FromFile(Action):
"""From File."""

def __call__(self, parser, namespace, values, option_string=None):
with values as f:
parser.parse_args(f.read().split(), namespace)


def validator(cast, min_value, max_value):
"""Validator."""

def validate(string):
"""Validate."""
value = cast(string)
if min_value is not None:
assert value >= min_value
if max_value is not None:
assert value <= max_value
return value

return validate


def parse_args():
"""Parse args."""
parser = ArgumentParser(description='CHIME')

parser.add_argument('--file', type=open, action=FromFile)
parser.add_argument(
'--prefix',
type=str,
default=datetime.now().strftime("%Y.%m.%d.%H.%M."),
)

for arg, cast, min_value, max_value, help in (
('--current-hospitalized', int, 0, None, "Currently Hospitalized COVID-19 Patients (>= 0)"),
('--doubling-time', float, 0.0, None, "Doubling time before social distancing (days)"),
('--hospitalized-los', int, 0, None, "Hospitalized Length of Stay (days)"),
('--hospitalized-rate', float, 0.00001, 1.0, "Hospitalized Rate: 0.00001 - 1.0"),
('--icu-los', int, 0, None, "ICU Length of Stay (days)"),
('--icu-rate', float, 0.0, 1.0, "ICU Rate: 0.0 - 1.0"),
('--known-infected', int, 0, None,
"Currently Known Regional Infections (>=0) (only used to compute detection rate - does not change projections)"),
('--market_share', float, 0.00001, 1.0, "Hospital Market Share (0.00001 - 1.0)"),
('--n-days', int, 0, None, "Nuber of days to project >= 0"),
('--relative-contact-rate', float, 0.0, 1.0, "Social Distancing Reduction Rate: 0.0 - 1.0"),
('--susceptible', int, 1, None, "Regional Population >= 1"),
('--ventilated-los', int, 0, None, "Hospitalized Length of Stay (days)"),
('--ventilated-rate', float, 0.0, 1.0, "Ventilated Rate: 0.0 - 1.0"),
):
parser.add_argument(arg, type=validator(cast, min_value, max_value))
return parser.parse_args()


def main():
"""Main."""
a = parse_args()

p = Parameters(
current_hospitalized=a.current_hospitalized,
doubling_time=a.doubling_time,
known_infected=a.known_infected,
market_share=a.market_share,
relative_contact_rate=a.relative_contact_rate,
susceptible=a.susceptible,
n_days=a.n_days,
hospitalized=RateLos(a.hospitalized_rate, a.hospitalized_los),
icu=RateLos(a.icu_rate, a.icu_los),
ventilated=RateLos(a.ventilated_rate, a.ventilated_los),
)

raw_df = DataFrame({
"Susceptible": p.susceptible_v,
"Infected": p.infected_v,
"Recovered": p.recovered_v,
})
admits_df = build_admissions_df(p.n_days, *p.dispositions)
census_df = build_census_df(admits_df, *p.lengths_of_stay)

prefix = a.prefix
for df, name in (
(raw_df, 'raw'),
(admits_df, 'admits'),
(census_df, 'census'),
):
df.to_csv(prefix + name + '.csv')


if __name__ == '__main__':
main()
14 changes: 9 additions & 5 deletions penn_chime/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ def __init__(
icu: RateLos,
ventilated: RateLos,

max_y_axis: int
max_y_axis: int = None,
n_days: int = None
):
self.current_hospitalized = current_hospitalized
self.doubling_time = doubling_time
Expand Down Expand Up @@ -84,6 +85,13 @@ def __init__(
# TODO constrain values np.log2(...) > 0.0
self.doubling_time_t = 1.0 / np.log2(beta * susceptible - gamma + 1)

self.dispositions = None
self.susceptible_v = self.infected_v = self.recovered_v = None
self.hospitalized_v = self.icu_v = self.ventilated_v = None

if n_days is not None:
self.n_days = n_days

@property
def n_days(self):
return self._n_days
Expand All @@ -92,10 +100,6 @@ def n_days(self):
def n_days(self, n_days: int):
self._n_days = n_days

# s := Susceptible, able to be infected
# i := Infected, currently infected with the virus
# r := Recovered, no longer infected with the virus

s_v, i_v, r_v = sim_sir(
self.susceptible,
self.infected,
Expand Down
13 changes: 13 additions & 0 deletions settings.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
--current-hospitalized 6
--doubling-time 6.0
--known-infected 157
--relative-contact-rate 0.0
--hospitalized-los 7
--hospitalized-rate 0.05
--icu-los 9
--icu-rate 0.02
--market_share 0.15
--n-days 60
--susceptible 4119405
--ventilated-los 10
--ventilated-rate 0.01

0 comments on commit 03753c6

Please sign in to comment.