Skip to content

Commit

Permalink
Revise ceil to floor
Browse files Browse the repository at this point in the history
  • Loading branch information
jlubken committed Apr 1, 2020
1 parent 0b50c90 commit 0987275
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 38 deletions.
12 changes: 6 additions & 6 deletions src/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@

st.subheader("New Admissions")
st.markdown("Projected number of **daily** COVID-19 admissions. \n\n _NOTE: Now including estimates of prior admissions for comparison._")
admits_chart = build_admits_chart(alt=alt, admits_df=m.admits_df, max_y_axis=p.max_y_axis)
admits_chart = build_admits_chart(alt=alt, admits_floor_df=m.admits_floor_df, max_y_axis=p.max_y_axis)
st.altair_chart(admits_chart, use_container_width=True)
st.markdown(build_descriptions(chart=admits_chart, labels=p.labels, suffix=" Admissions"))
display_download_link(
Expand All @@ -54,15 +54,15 @@
if not st.checkbox("Show Daily Counts"):
admits_modulo = 7
table_df = build_table(
df=m.admits_df,
df=m.admits_floor_df,
labels=p.labels,
modulo=admits_modulo)
st.table(table_df)


st.subheader("Admitted Patients (Census)")
st.markdown("Projected **census** of COVID-19 patients, accounting for arrivals and discharges \n\n _NOTE: Now including estimates of prior census for comparison._")
census_chart = build_census_chart(alt=alt, census_df=m.census_df, max_y_axis=p.max_y_axis)
census_chart = build_census_chart(alt=alt, census_floor_df=m.census_floor_df, max_y_axis=p.max_y_axis)
st.altair_chart(census_chart, use_container_width=True)
st.markdown(build_descriptions(chart=census_chart, labels=p.labels, suffix=" Census"))
display_download_link(
Expand All @@ -76,15 +76,15 @@
if not st.checkbox("Show Daily Census Counts"):
census_modulo = 7
table_df = build_table(
df=m.census_df,
df=m.census_floor_df,
labels=p.labels,
modulo=census_modulo)
st.table(table_df)


st.subheader("Susceptible, Infected, and Recovered")
st.markdown("The number of susceptible, infected, and recovered individuals in the hospital catchment region at any given moment")
sim_sir_w_date_chart = build_sim_sir_w_date_chart(alt=alt, sim_sir_w_date_df=m.sim_sir_w_date_df)
sim_sir_w_date_chart = build_sim_sir_w_date_chart(alt=alt, sim_sir_w_date_floor_df=m.sim_sir_w_date_floor_df)
st.altair_chart(sim_sir_w_date_chart, use_container_width=True)
display_download_link(
st,
Expand All @@ -94,7 +94,7 @@

if st.checkbox("Show SIR Simulation in tabular form"):
table_df = build_table(
df=m.sim_sir_w_date_df,
df=m.sim_sir_w_date_floor_df,
labels=p.labels)
st.table(table_df)

Expand Down
17 changes: 6 additions & 11 deletions src/penn_chime/charts.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,14 @@
def build_admits_chart(
*,
alt,
admits_df: pd.DataFrame,
admits_floor_df: pd.DataFrame,
max_y_axis: Optional[int] = None,
) -> Chart:
"""Build admits chart."""
y_scale = alt.Scale()
if max_y_axis is not None:
y_scale.domain = (0, max_y_axis)

ceil_df = admits_df.copy()
ceil_df.hospitalized = np.ceil(ceil_df.hospitalized)
ceil_df.icu = np.ceil(ceil_df.icu)
ceil_df.ventilated = np.ceil(ceil_df.ventilated)

x = dict(shorthand="date:T", title="Date", axis=alt.Axis(format=(DATE_FORMAT)))
y = dict(shorthand="value:Q", title="Daily admissions", scale=y_scale)
color = "key:N"
Expand All @@ -45,14 +40,14 @@ def build_admits_chart(
.transform_filter(alt.datum.day == 0)
.mark_rule(color="black", opacity=0.35, size=2)
)
return alt.layer(points, bar, data=ceil_df)
return alt.layer(points, bar, data=admits_floor_df)



def build_census_chart(
*,
alt,
census_df: pd.DataFrame,
census_floor_df: pd.DataFrame,
max_y_axis: Optional[int] = None,
) -> Chart:
"""Build census chart."""
Expand All @@ -78,13 +73,13 @@ def build_census_chart(
.transform_filter(alt.datum.day == 0)
.mark_rule(color="black", opacity=0.35, size=2)
)
return alt.layer(points, bar, data=census_df)
return alt.layer(points, bar, data=census_floor_df)


def build_sim_sir_w_date_chart(
*,
alt,
sim_sir_w_date_df: pd.DataFrame,
sim_sir_w_date_floor_df: pd.DataFrame,
max_y_axis: Optional[int] = None,
) -> Chart:
"""Build sim sir w date chart."""
Expand All @@ -110,7 +105,7 @@ def build_sim_sir_w_date_chart(
.transform_filter(alt.datum.day == 0)
.mark_rule(color="black", opacity=0.35, size=2)
)
return alt.layer(points, bar, data=sim_sir_w_date_df)
return alt.layer(points, bar, data=sim_sir_w_date_floor_df)


def build_descriptions(
Expand Down
2 changes: 1 addition & 1 deletion src/penn_chime/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
longer match current results, indicating when users should
re-run their reports
"""
CHANGE_DATE = date(year=2020, month=3, day=30)
CHANGE_DATE = date(year=2020, month=4, day=1)

DATE_FORMAT = "%b, %d" # see https://strftime.org
DOCS_URL = "https://code-for-philly.gitbook.io/chime"
Expand Down
33 changes: 27 additions & 6 deletions src/penn_chime/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ def __init__(self, p: Parameters):
for key, d in p.dispositions.items()
}

self.keys = ("susceptible", "infected", "recovered")

# Note: this should not be an integer.
# We're appoximating infected from what we do know.
# TODO market_share > 0, hosp_rate > 0
Expand Down Expand Up @@ -153,7 +155,11 @@ def __init__(self, p: Parameters):
self.beta_t * susceptible - gamma + 1)
self.doubling_time_t = doubling_time_t

self.sim_sir_w_date_df = build_sim_sir_w_date_df(self.raw_df, p.current_date)
self.sim_sir_w_date_df = build_sim_sir_w_date_df(self.raw_df, p.current_date, self.keys)

self.sim_sir_w_date_floor_df = build_floor_df(self.sim_sir_w_date_df, self.keys)
self.admits_floor_df = build_floor_df(self.admits_df, p.dispositions.keys())
self.census_floor_df = build_floor_df(self.census_df, p.dispositions.keys())

self.daily_growth_rate = get_growth_rate(p.doubling_time)
self.daily_growth_rate_t = get_growth_rate(self.doubling_time_t)
Expand Down Expand Up @@ -252,7 +258,8 @@ def gen_sir(


def sim_sir_df(
s: float, i: float, r: float, gamma: float, i_day: int, *args
s: float, i: float, r: float,
gamma: float, i_day: int, *args
) -> pd.DataFrame:
"""Simulate the SIR model forward in time."""
return pd.DataFrame(
Expand All @@ -264,14 +271,28 @@ def sim_sir_df(
def build_sim_sir_w_date_df(
raw_df: pd.DataFrame,
current_date: datetime,
keys: Sequence[str],
) -> pd.DataFrame:
day = raw_df.day
return pd.DataFrame({
"day": day,
"date": day.astype('timedelta64[D]') + np.datetime64(current_date),
"susceptible": raw_df.susceptible,
"infected": raw_df.infected,
"recovered": raw_df.recovered,
**{
key: raw_df[key]
for key in keys
}
})


def build_floor_df(df, keys):
"""Build floor sim sir w date."""
return pd.DataFrame({
"day": df.day,
"date": df.date,
**{
key: np.floor(df[key])
for key in keys
}
})


Expand Down Expand Up @@ -314,7 +335,7 @@ def build_census_df(
key: (
admits_df[key].cumsum()
- admits_df[key].cumsum().shift(los).fillna(0)
).apply(np.ceil)
)
for key, los in lengths_of_stay.items()
}
})
4 changes: 3 additions & 1 deletion src/penn_chime/presentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,9 @@ def display_sidebar(st, d: Parameters) -> Parameters:

# Build in desired order
st.sidebar.markdown(
"""**CHIME [v1.1.1](https://github.com/CodeForPhilly/chime/releases/tag/v1.1.1) (2020/03/30)**"""
"""**CHIME [v1.1.1](https://github.com/CodeForPhilly/chime/releases/tag/v1.1.1) ({change_date})**""".format(
change_date=CHANGE_DATE
)
)

st.sidebar.markdown(
Expand Down
12 changes: 11 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
Disposition,
Regions,
)
from src.penn_chime.models import SimSirModel
from src.penn_chime.models import SimSirModel, build_floor_df


class MockStreamlit:
Expand Down Expand Up @@ -107,8 +107,18 @@ def admits_df():
)


@pytest.fixture
def admits_floor_df(param, admits_df):
return build_floor_df(admits_df, param.dispositions.keys())


@pytest.fixture
def census_df():
return pd.read_csv(
"tests/by_doubling_time/2020-03-28_projected_census.csv", parse_dates=["date"]
)

@pytest.fixture
def census_floor_df(param, census_df):
return build_floor_df(census_df, param.dispositions.keys())

27 changes: 15 additions & 12 deletions tests/penn_chime/test_charts.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,21 @@
# TODO add test for asterisk


def test_admits_chart(admits_df):
chart = build_admits_chart(alt=alt, admits_df=admits_df)
DISPOSITION_KEYS = ("hospitalized", "icu", "ventilated")


def test_admits_chart(admits_floor_df):
chart = build_admits_chart(alt=alt, admits_floor_df=admits_floor_df)
assert isinstance(chart, (alt.Chart, alt.LayerChart))
assert round(chart.data.iloc[40].icu, 0) == 39
assert round(chart.data.iloc[40].icu, 0) == 38

# test fx call with no params
with pytest.raises(TypeError):
build_admits_chart()


def test_build_descriptions(admits_df, param):
chart = build_admits_chart(alt=alt, admits_df=admits_df)
def test_build_descriptions(admits_floor_df, param):
chart = build_admits_chart(alt=alt, admits_floor_df=admits_floor_df)
description = build_descriptions(chart=chart, labels=param.labels)

hosp, icu, vent = description.split("\n\n") # break out the description into lines
Expand All @@ -33,16 +36,16 @@ def test_build_descriptions(admits_df, param):
assert str(ceil(max_hosp)) in hosp


def test_no_asterisk(admits_df, param):
def test_no_asterisk(admits_floor_df, param):
param.n_days = 600

chart = build_admits_chart(alt=alt, admits_df=admits_df)
chart = build_admits_chart(alt=alt, admits_floor_df=admits_floor_df)
description = build_descriptions(chart=chart, labels=param.labels)
assert "*" not in description


def test_census(census_df, param):
chart = build_census_chart(alt=alt, census_df=census_df)
def test_census(census_floor_df, param):
chart = build_census_chart(alt=alt, census_floor_df=census_floor_df)
description = build_descriptions(chart=chart, labels=param.labels)

assert str(ceil(chart.data["ventilated"].max())) in description
Expand All @@ -53,12 +56,12 @@ def test_census(census_df, param):
)


def test_census_chart(census_df):
chart = build_census_chart(alt=alt, census_df=census_df)
def test_census_chart(census_floor_df):
chart = build_census_chart(alt=alt, census_floor_df=census_floor_df)
assert isinstance(chart, (alt.Chart, alt.LayerChart))
assert chart.data.iloc[1].hospitalized == 3
assert chart.data.iloc[49].ventilated == 365

# test fx call with no params
with pytest.raises(TypeError):
build_census_chart()
build_census_chart()

0 comments on commit 0987275

Please sign in to comment.