def epidemiological_parameters(model, where=st): """ Basic report with epidemiological parameters. """ st = where days = model.iter mortality = model["deaths:final:pp"] fatality = model["empirical-CFR:final"] infected = model["infected:final:pp"] mortality *= 100_000 mortality = fmt(mortality) fatality = pc(fatality) infected = pc(infected) symptomatic = pc(model.prob_symptoms) st.md_description( { _("Number of cases generated by a single case"): fmt(model.R0), _("Mortality (deaths per 100k population)"): mortality, _("Letality ({pc} of deaths among the ill)").format(pc="%"): fatality.rstrip( "%" ), } ) lang = os.environ.get("LANGUAGE", "en_US") namespace = locals() del namespace["st"], namespace["model"], namespace["where"] st.footnote_disclaimer(**namespace)
def get_dataframe(regions, days, targets, columns, duration): models = get_models(regions, targets, duration) frames = [] prev_day = 0 for day in days: delta = (day, prev_day) for target in targets: frame = pd.DataFrame( { col: get_column(models, regions, target, col, delta, duration) for col in columns } ).astype(int) names = ("days", "isolation", "data") prepend = ( _("{n} days").format(n=day), _("isolation {pc}").format(pc=pc(target / 100)), ) cols = ((*prepend, c) for c in frame.columns) frame.columns = pd.MultiIndex.from_tuples(cols, names=names) frames.append(frame) prev_day = day df = pd.concat(frames, axis=1) extra = df.mundi["numeric_code", "short_code", "name"] extra = extra.astype(str) # streamlit bug? extra.columns = pd.MultiIndex.from_tuples(("info", x, "") for x in extra.columns) df = pd.concat([extra, df], axis=1) return df.sort_values(df.columns[0])
def get_dataframe(self, days, targets, columns): regions = self.user_inputs["regions"] frames = [] prev_day = 0 for day in days: delta = (day, prev_day) for target in targets: frame = pd.DataFrame( { column: self.__get_column(regions, target, column, delta) for column in columns } ).astype(int) columns_names = ("days", "isolation", "data") prepend = ( _("{n} days").format(n=day), _("isolation {pc}").format(pc=pc(target / 100)), ) cols = ((*prepend, col) for col in frame.columns) frame.columns = pd.MultiIndex.from_tuples(cols, names=columns_names) frames.append(frame) prev_day = day df = pd.concat(frames, axis=1) extra_info = df.mundi["numeric_code", "short_code", "name"] extra_info = extra_info.astype(str) # streamlit bug? extra_info.columns = pd.MultiIndex.from_tuples(("info", extra_col, "") for extra_col in extra.columns) df = pd.concat([extra_info, df], axis=1) return df.sort_values(df.columns[0])
def test_other_formats(self): assert utils.pc(0.5) == "50%" assert utils.pm(0.05) == "50‰" assert utils.p10k(0.005) == "50‱" assert utils.p100k(0.0005) == "50/100k" assert utils.safe_int(3.14) == 3 assert utils.safe_int(float("nan")) == 0
def get(title, capacity, rate, key=None): where.subheader(title) total = where.number_input(_("Total capacity"), min_value=0, value=int(capacity), key=key + "_total") occupied = where.number_input(_("Occupied"), min_value=0, value=int(capacity * rate), key=key + "_used") if occupied > total: where.warning(_("Using more beds than total capacity")) msg = markdown( OCCUPANCY_MSG.format(n=fmt(total - occupied), rate=pc(occupied / total), globalrate=pc(rate))) html(f'<span style="font-size: smaller;">{msg}</span>', where=where) return max(total - occupied, 0)
def process_region(region, targets, duration): data = info.get_seair_curves_for_region(region, use_deaths=True) m = models.SEAIR(region=region, disease=covid19) m.set_data(data) m.initial_cases = info.get_cases_for_region(region)["cases"].iloc[0] out = {} for level in targets: new = m.copy(name=_("Isolation {}").format(pc(level / 100))) new.R0 *= 1 - level / 100 new.run(duration) out[level] = new.clinical.overflow_model() return MappingProxyType(out)
def __run_simulations(self, region, duration) -> Tuple[Model, ModelGroup]: targets = self.user_inputs["targets"] disease = get_disease("covid-19") base = models.SEAIR(region=region, disease=disease, name=region.id) base.set_cases(self.__get_cases_information(region, disease), save_observed=True) column_names = [] R0s = [] for target in targets: column_names.append(_("Isolation {}").format(pc(target / 100))) R0s.append(base.R0 * (1 - target / 100)) info_group = base.split(name=column_names, R0=R0s) info_group.run(duration) return base, info_group.clinical.overflow_model()
def simulations( region, targets: Sequence[int], duration, disease ) -> Tuple[Model, ModelGroup]: disease = get_disease(disease) base = models.SEAIR(region=region, disease=disease, name=region.id) base.set_cases(cases(region, disease), save_observed=True) names = [] R0s = [] for target in targets: names.append(_("Isolation {}").format(pc(target / 100))) R0s.append(base.R0 * (1 - target / 100)) group = base.split(name=names, R0=R0s) group.run(duration) return base, group.clinical.overflow_model()
def __process_region(self, region): targets = self.user_inputs["targets"] data = info.get_seair_curves_for_region(region, use_deaths=True) model = models.SEAIR(region=region, disease=covid19) model.set_data(data) model.initial_cases = info.get_cases_for_region(region)["cases"].iloc[0] out = {} for level in targets: new_model = model.copy(name=_("Isolation {}").format(pc(level / 100))) new_model.R0 *= 1 - level / 100 new_model.run(DURATION) out[level] = new_model.clinical.overflow_model() return MappingProxyType(out)
def show_outputs(base, group, region: RegionT, plot_opts, clinical_opts, **kwargs): """ Show results from user input. """ cmodels = group.clinical.overflow_model(**clinical_opts) cforecast = cmodels[0] start = base.info["event.simulation_start"] # # Introduction # st.header(_("Introduction")) st.markdown(report_intro(region)) st.cards( { _("Basic reproduction number"): fmt(base.R0), _("Ascertainment rate"): pc( base.info["observed.notification_rate"]), }, color="st-gray-900", ) # # Forecast # st.header(_("Forecasts")) st.markdown(forecast_intro(region)) # Infectious curve group["infectious:dates"].plot(**plot_opts) mark_x(start.date, "k--") plt.legend() plt.title(_("Active cases")) plt.tight_layout() st.pyplot() st.markdown("#### " + _("Download data")) opts = ["critical", "severe", "infectious", "cases", "deaths"] default_columns = ["critical", "severe", "cases", "deaths"] columns = st.multiselect(_("Select columns"), opts, default=default_columns) rename = dict(zip(range(len(columns)), columns)) columns = [c + ":dates" for c in columns] data = pd.concat([cm[columns].rename(rename, axis=1) for cm in cmodels], axis=1, keys=cmodels.names) st.data_anchor(data.astype(int), f"data-{region.id}.csv") # # Reopening # st.header(_("When can we reopen?")) st.markdown(reopening_intro(region)) st.subheader(_("Step 1: Controlling the curve")) st.markdown(rt_intro(region)) st.subheader(_("Step 2: Testing")) st.markdown(rt_intro(region)) if kwargs.get("show_weekday_rate"): region.ui.weekday_rate() st.subheader(_("Step 3: Hospital capacity")) st.markdown(rt_intro(region)) # Hospitalization cmodels["critical:dates"].plot(**plot_opts) mark_x(start.date, "k--") mark_y(cforecast.icu_surge_capacity, "k:") plt.legend() plt.title(_("Critical cases")) plt.tight_layout() st.pyplot()
def summary_cards(model, where=st): """ Show list of summary cards for the results of simulation. """ def datum(x): return f"{fmt(int(x))} ({pc(x / population)})" st = where region = model.region disease = model.disease results = model.results deaths = results["data.deaths"] hospitalizations = results["data.hospitalized_cases"] extra_icu = model["icu_overflow:max"] extra_hospitals = model["hospital_overflow:max"] recovered = results["data.recovered"] population = model.population # Print friendlier messages if region has no ICU or hospital beds if model.icu_capacity > 0: icu_overflow = model.info["event.icu_overflow"].date else: icu_overflow = _("No ICU beds!") if model.hospital_capacity > 0: hospital_overflow = model.info["event.hospital_overflow"].date else: hospital_overflow = _("No hospital beds!") # A peak of cases in the final date is bogus: it probably corresponds # to a simulation that simply did not run long enough to see the peak peak_cases = model["infectious:peak-date"] if peak_cases == model.date: peak_cases = _("Still coming...") # Do not reference Brasil.io as a data source :( brasil_io = '<a href="http://brasil.io" target="_blank">Brasil.io</a>' cases_title = _("Confirmed cases*").format(link=brasil_io) deaths_title = _("Confirmed deaths*").format(link=brasil_io) st.cards( { cases_title: fmt(info.get_confirmed_cases_for_region(region, disease)), deaths_title: fmt(info.get_confirmed_deaths_for_region(region, disease)), }, escape=False, color="st-red", ) st.html('<div style="height: 0.5rem;"></div>') st.cards( { _("Deaths"): datum(deaths), _("Hospitalizations"): datum(hospitalizations), _("Required extra ICU beds"): fmt(extra_icu), _("Required extra hospital beds"): fmt(extra_hospitals), _("No more ICU beds available by"): natural_date(icu_overflow), _("No more hospital beds available by"): natural_date(hospital_overflow), _("Estimated date for the peak"): natural_date(peak_cases), _("Cumulative attack rate"): pc(recovered / population), } ) st.markdown(_("* Compiled from local Healthcare Secretaries"))