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

Fix calculation of new infected cases #190

Merged
merged 4 commits into from
Mar 23, 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
2 changes: 1 addition & 1 deletion src/penn_chime/charts.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def admitted_patients_chart(

return (
alt.Chart(census.head(plot_projection_days))
.transform_fold(fold=["Hospitalized Census", "ICU Census", "Ventilated Census"])
.transform_fold(fold=["Hospitalized", "ICU", "Ventilated"])
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just to get the graphs' x-axes to line up vertically. Label redundant to plot title and y-label.

.mark_line(point=True)
.encode(
x=alt.X(**x_kwargs),
Expand Down
8 changes: 3 additions & 5 deletions src/penn_chime/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,10 @@ def sim_sir_df(p) -> pd.DataFrame:


def get_dispositions(
infected: np.ndarray, rates: Tuple[float, ...], market_share: float = 1.0
patient_state: np.ndarray, rates: Tuple[float, ...], market_share: float = 1.0
) -> Tuple[np.ndarray, ...]:
"""Get dispositions of infected adjusted by rate and market_share."""
return (*(infected * rate * market_share for rate in rates),)

return (*(patient_state * rate * market_share for rate in rates),)


def build_admissions_df(p) -> pd.DataFrame:
Expand All @@ -86,7 +85,6 @@ def build_admissions_df(p) -> pd.DataFrame:
projection = pd.DataFrame.from_dict(data_dict)
# New cases
projection_admits = projection.iloc[:-1, :] - projection.shift(1)
projection_admits[projection_admits < 0] = 0
projection_admits["day"] = range(projection_admits.shape[0])
return projection_admits

Expand Down Expand Up @@ -117,7 +115,7 @@ def build_census_df(
census_df = census_df[["day", "Hospitalized", "ICU", "Ventilated"]]
census_df = census_df.head(n_days)
census_df = census_df.rename(
columns={disposition: f"{disposition} Census"
columns={disposition: f"{disposition}"
for disposition
in ("Hospitalized", "ICU", "Ventilated")}
)
Expand Down
10 changes: 8 additions & 2 deletions src/penn_chime/parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,13 @@ def n_days(self, n_days: int):
)
self.susceptible_v, self.infected_v, self.recovered_v = s_v, i_v, r_v

self.dispositions = hospitalized_v, icu_v, ventilated_v = \
i_hospitalized_v, i_icu_v, i_ventilated_v = \
get_dispositions(i_v, self.rates, self.market_share)
r_hospitalized_v, r_icu_v, r_ventilated_v = \
get_dispositions(r_v, self.rates, self.market_share)

self.dispositions = (i_hospitalized_v+r_hospitalized_v,
i_icu_v+r_icu_v, i_ventilated_v+r_ventilated_v)

self.hospitalized_v, self.icu_v, self.ventilated_v = \
hospitalized_v, icu_v, ventilated_v
i_hospitalized_v, i_icu_v, i_ventilated_v
1 change: 1 addition & 0 deletions src/penn_chime/presentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ def display_header(st, p):
""",
unsafe_allow_html=True,
)
st.markdown("""**IMPORTANT NOTICE**: Admissions and Census calculations were previously **undercounting**. Please update your reports. See more about this issue [here](https://github.com/CodeForPhilly/chime/pull/190).""")
st.markdown(
"""*This tool was developed by the [Predictive Healthcare team](http://predictivehealthcare.pennmedicine.org/) at
Penn Medicine. For questions on how to use this tool see the [User docs](https://code-for-philly.gitbook.io/chime/). For questions and comments please see our
Expand Down
10 changes: 8 additions & 2 deletions tests/test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import altair as alt # type: ignore

from src.penn_chime.charts import new_admissions_chart, admitted_patients_chart
from src.penn_chime.models import sir, sim_sir
from src.penn_chime.models import sir, sim_sir, build_admissions_df
from src.penn_chime.parameters import Parameters
from src.penn_chime.presentation import display_header
from src.penn_chime.settings import DEFAULTS
Expand Down Expand Up @@ -228,8 +228,14 @@ def test_parameters():
assert round(param.infected_v[1], 0) == 43735
assert round(param.recovered_v[30], 0) == 224048
assert [d[0] for d in param.dispositions] == [100.0, 40.0, 20.0]
assert [round(d[-1], 0) for d in param.dispositions] == [115.0, 46.0, 23.0]
assert [round(d[-1], 0) for d in param.dispositions] == [1182.0, 473.0, 236.0]

# change n_days, make sure it cascades
param.n_days = 2
assert len(param.susceptible_v) == len(param.infected_v) == len(param.recovered_v) == param.n_days + 1 == 3

# test that admissions are being properly calculated (thanks @PhilMiller)
admissions = build_admissions_df(param)
cumulative_admissions = admissions.cumsum()
diff = cumulative_admissions["Hospitalized"][1:-1] - (0.05*0.05 * (param.infected_v[1:-1] + param.recovered_v[1:-1]) - 100)
assert (diff.abs() < 0.1).all()