diff --git a/src/penn_chime/charts.py b/src/penn_chime/charts.py index fb239356..c29bd5bc 100644 --- a/src/penn_chime/charts.py +++ b/src/penn_chime/charts.py @@ -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"]) .mark_line(point=True) .encode( x=alt.X(**x_kwargs), diff --git a/src/penn_chime/models.py b/src/penn_chime/models.py index a578ad32..62219b1c 100644 --- a/src/penn_chime/models.py +++ b/src/penn_chime/models.py @@ -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: @@ -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 @@ -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")} ) diff --git a/src/penn_chime/parameters.py b/src/penn_chime/parameters.py index 38438d77..37b3a4c2 100644 --- a/src/penn_chime/parameters.py +++ b/src/penn_chime/parameters.py @@ -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 diff --git a/src/penn_chime/presentation.py b/src/penn_chime/presentation.py index 4d7c8aa4..4b37660f 100644 --- a/src/penn_chime/presentation.py +++ b/src/penn_chime/presentation.py @@ -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 diff --git a/tests/test_app.py b/tests/test_app.py index fc51e6ad..73df291e 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -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 @@ -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()