Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cli #170

Merged
merged 1 commit into from
Mar 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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