Esempio n. 1
0
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])
Esempio n. 2
0
def collect_inputs(parent_region="BR", where=st.sidebar):
    """
    Collect input parameters for the app to run.

    Returns:
        Dictionary with the following keys:
            parent_region, regions, columns, targets, days
    """
    st = where
    kind = st.selectbox(_("Select scenario"), list(REGIONS_TYPES[parent_region]))
    query = REGIONS_TYPES[parent_region][kind]

    regions = get_regions(**query)

    msg = _("Columns")
    columns = st.multiselect(msg, COLUMNS, default=COLUMNS_DEFAULT)

    msg = _("Isolation scores")
    kwargs = {"default": TARGETS_DEFAULT, "format_func": lambda x: f"{x}%"}
    targets = st.multiselect(msg, TARGETS, **kwargs)

    msg = _("Show values for the given days")
    days = st.multiselect(msg, DAYS, default=DAYS_DEFAULT)

    return {
        "parent_region": parent_region,
        "regions": regions,
        "columns": columns,
        "targets": targets,
        "days": days,
    }
Esempio n. 3
0
def explore_object(name, obj, where=st):
    """
    Explore methods of object.
    """

    fn = select_method(name, obj, where=where)
    args, kwargs = select_arguments(fn, where=where)

    t0 = time.time()
    msg = st.empty()
    result = fn(*args, **kwargs)
    msg.info(_("Method executed in {} seconds.").format(fmt(time.time() - t0)))

    st.line()
    st.subheader(_("Method help and signature"))
    st.help(fn)

    if result is not None:
        st.line()
        st.subheader(_("Function output"))

        if isinstance(result, plt.Axes):
            st.markdown(_("Function returned a matplotlib **ax** object. Showing it..."))
            st.pyplot(result.get_figure())
        else:
            st.write(result)
Esempio n. 4
0
def show_results(
    parent_region,
    regions,
    columns,
    targets,
    days,
    scenario,
    disease=covid19,
    transpose=False,
):
    """
    Show results from user input.
    """

    parent_region = mundi.region(parent_region)
    parent_region.ui.cases_and_deaths(disease=disease, grid=True, logy=True)

    if days and targets and columns:
        info = scenario["info"]
        info_cols = tuple(info)
        df = get_dataframe(
            regions, tuple(days), tuple(targets), tuple(columns), info_cols=info_cols
        )
        get = {**COL_NAMES, **info}.get
        df.columns = pd.MultiIndex.from_tuples(
            [tuple(_(get(x, x) for x in t)) for t in df.columns.to_list()]
        )
        if transpose:
            df = df.T

        st.subheader(_("Download results"))
        st.dataframe_download(df, name="report-brazil.{ext}")
    def ask(self, parent_region="BR", where=st.sidebar):

        st = where
        scenario_kind = st.selectbox(_("Select scenario"), list(REGIONS_TYPES[parent_region]))
        query = REGIONS_TYPES[parent_region][scenario_kind]

        regions = self.__datahandler.get_regions(**query)

        message = _("Columns")
        columns = st.multiselect(message, COLUMNS, default=COLUMNS_DEFAULT)

        message = _("Isolation scores")
        kwargs = {"default": TARGETS_DEFAULT, "format_func": lambda x: f"{x}%"}
        targets = st.multiselect(message, TARGETS, **kwargs)

        message = _("Show values for the given days")
        days = st.multiselect(message, DAYS, default=DAYS_DEFAULT)

        self.__datahandler.user_inputs = {
            "parent_region": parent_region,
            "regions": regions,
            "columns": columns,
            "targets": targets,
            "days": days,
            "disease": "covid-19"
        }
Esempio n. 6
0
 def run(self):
     super().run()
     models = ["crude", "delay", "overflow"]
     kind = st.sidebar.selectbox(_("Clinical model"), models)
     m = SEAIR(region="BR", disease=covid19)
     cm = m.clinical(kind)
     cm.ui.summary_table(subheader=_("Parameters table"))
Esempio n. 7
0
    def show(self):
        """
        Show results from user input.
        """
        parent_region = self.user_inputs["parent_region"]
        regions = self.user_inputs["regions"]
        columns = self.user_inputs["columns"]
        targets = self.user_inputs["targets"]
        days = self.user_inputs["days"]
        scenario = self.user_inputs["scenario"]
        transpose = self.user_inputs["transpose"]
        disease = self.user_inputs["disease"]

        parent_region = mundi.region(parent_region)
        parent_region.ui.cases_and_deaths(disease=disease, grid=True, logy=True)

        if days and targets and columns:
            info = scenario["info"]
            info_cols = tuple(info)
            df = self.get_dataframe(
                regions, tuple(days), tuple(targets), tuple(columns), info_cols=info_cols
            )
            get = {**COL_NAMES, **info}.get
            df.columns = pd.MultiIndex.from_tuples(
                [tuple(_(get(x, x) for x in t)) for t in df.columns.to_list()]
            )
            if transpose:
                df = df.T

            st.subheader(_("Download results"))
            st.dataframe_download(df, name="report-brazil.{ext}")
    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])
Esempio n. 9
0
    def report_intro(self, region):
        name = _(region.name)
        return _(
            """{name} is in a **(good|bad|ugly)** state, yadda, yadda, yadda.

            The plot bellow shows the progression of cases and deaths.
            """).format(**locals())
Esempio n. 10
0
    def ask(self):
        """
        Ask for user input and save values as properties in the app.
        """
        self.where.header(("Options"))

        self.region = self.where.text_input(_("Mundi region code"), value="BR")
        try:
            self.region = mundi.region(self.region)
        except LookupError:
            self.where.error("Invalid mundi region code.")
            return

        options = {
            "model": _("A Pydemic Model"),
            "region": _("A Mundi Region"),
            "components": _("Input components"),
        }
        message = _("What do you want to explore?")
        option = self.where.radio(message,
                                  list(options),
                                  format_func=options.get)

        self.option = option
        self.object = self.handle_explore_option(option)
Esempio n. 11
0
def sidebar(where=st.sidebar):
    st = where

    st.subheader(_("Section"))
    msg = _("Which section do you want to see?")
    key = st.radio(msg, list(APPS), format_func=lambda x: APPS[x].DISPLAY_NAME)
    app = APPS[key]
    opts = app.options(where=where)
    return app.show, opts
Esempio n. 12
0
    def ask(self, parent_region="BR", where=st.sidebar):
        st = where
        scenario_kind = st.selectbox(_("Select scenario"), list(REGIONS_TYPES[parent_region]))
        scenario = REGIONS_TYPES[parent_region][scenario_kind]
        regions = self.__datahandler.get_regions(**scenario["query"])

        if "filter" in scenario:
            filtering = scenario["filter"]
            format_func = filtering.pop("format_func", None)
            if format_func is not None:
                function = format_func

                def format_func(x):
                    if x == "all":
                        return _("All")
                    return function(x)

            field, message = filtering.popitem()
            groups = sk.group_by(lambda x: getattr(x, field), regions)

            key = st.selectbox(message, ["all", *groups], format_func=format_func)
            if key != "all":
                regions = groups[key]

        message = _("Columns")
        columns = st.multiselect(message, COLUMNS, default=COLUMNS_DEFAULT)

        message = _("Isolation scores")
        kwargs = {"default": TARGETS_DEFAULT, "format_func": lambda x: f"{x}%"}
        targets = st.multiselect(message, TARGETS, **kwargs)

        message = _("Show values for the given days")
        days = st.multiselect(message, DAYS, default=DAYS_DEFAULT)
        if any(not isinstance(d, int) for d in days):
            day_max = sk.pipe(
                days,
                sk.remove(lambda d: isinstance(d, int)),
                sk.map(lambda d: int(NUMBER.search(d).groups()[0])),
                max,
            )
            days = list(range(1, day_max + 1))

        message = _("Transpose data")
        transpose = st.checkbox(message, value=False)

        self.__datahandler.user_inputs = {
            "parent_region": parent_region,
            "regions": regions,
            "columns": columns,
            "targets": targets,
            "days": days,
            "scenario": scenario,
            "transpose": transpose,
            "disease": "covid-19"
        }
Esempio n. 13
0
def main(embed=False):
    if not embed:
        st.css(keep_menu=True)
        st.sidebar.logo()

    models = ["crude", "delay", "overflow"]
    kind = st.sidebar.selectbox(_("Clinical model"), models)
    m = SEAIR(region="BR", disease=covid19)

    cm = m.clinical(kind)
    cm.ui.summary_table(subheader=_("Parameters table"))
Esempio n. 14
0
    def show(self):
        by_region, by_state = self.tables
        self.st.markdown(self.message.format(self=self))

        self.st.subheader(_("Epidemic situation, by region"))
        self.st.markdown(_("Cases and deaths by 100k people."))
        self.show_table(by_region)

        self.st.subheader(_("Epidemic situation, by state"))
        self.st.markdown(_("Cases and deaths by 100k people."))
        self.show_table(by_state)
Esempio n. 15
0
def progression_cards(deaths, color="st-blue"):
    deaths = deaths.values[-60:]
    st.cards(
        {
            _("7 days"): fmt(deaths[6]),
            _("15 days"): fmt(deaths[14]),
            _("30 days"): fmt(deaths[29]),
            _("60 days"): fmt(deaths[59]),
        },
        color=color,
    )
Esempio n. 16
0
def collect_inputs(region="BR", where=st.sidebar):
    states = mundi.regions(region, type="state")
    highlight = where.selectbox(_("Select a state to highlight"), states.index)

    msg = _("Which kind of curve to you want to analyze?")
    which = where.selectbox(msg, ["cases", "deaths"])

    return {
        "loc": highlight,
        "idx": int(which == "deaths"),
        "states": states,
        "which": which,
    }
Esempio n. 17
0
    def explore_function_output(self, result):
        if result is not None:
            self.where = st
            self.where.line()
            self.where.subheader(_("Function output"))

            if isinstance(result, plt.Axes):
                self.where.markdown(
                    _("Function returned a matplotlib **ax** object. Showing it..."
                      ))
                self.where.pyplot(result.get_figure())
            else:
                self.where.write(result)
Esempio n. 18
0
def select_arguments(fn, where=st):
    """
    Select arguments from a callable object.

    This method only works if we are able to introspect the object signature.
    """

    st = where
    sig = inspect.Signature.from_callable(fn)
    args = []
    kwargs = {}
    show_title = True

    for k, v in sig.parameters.items():
        if k == "where":
            continue
        if show_title:
            st.subheader(_("Arguments"))
            show_title = False
        if v.annotation == str:
            kwargs[k] = st.text_input(k)
        elif v.annotation == bool:
            kwargs[k] = st.checkbox(k)
        elif v.annotation == float:
            kwargs[k] = st.number_input(k)
        elif v.annotation == int:
            kwargs[k] = st.number_input(k)
        else:
            st.text(k)

    return args, kwargs
Esempio n. 19
0
    def show(self, model, title=_("Hospital pressure calculator")):
        """
        Create default output from model.
        """
        if title:
            st.title(title)

        model.ui.summary_cards()

        st.pause()
        model.ui.hospitalizations_chart()

        st.pause()
        model.ui.available_beds_chart()

        st.line()
        ui.population_info_chart(model.age_pyramid)

        st.pause()
        model.ui.deaths_chart()

        st.line()
        model.ui.healthcare_parameters()

        st.pause()
        model.ui.ppe_demand_table()

        st.pause()
        model.ui.epidemiological_parameters()

        st.pause()
        st.footnotes()
Esempio n. 20
0
def get_models(regions, targets, duration) -> dict:
    models = {}
    for region in regions:
        with st.spinner(_("Processing {name}").format(name=region.name)):
            result = process_region(region, targets, duration)
            models.update({(region, k): v for k, v in result.items()})
    return models
Esempio n. 21
0
def sidebar(
    region="BR", disease=covid19, where=st.sidebar, secret_date=None, secret_function=None
):
    """
    Calculator sidebar element.

    It receives a region and a disease (defaults to Covid-19) and return a
    dictionary of parameters that might be useful to configure a simulation.
    """
    st = where
    st.logo()
    region = st.region_input(region, sus_regions=True, arbitrary=True)

    try:
        params = st.simulation_params(region, disease, secret_date=secret_date)
    except RuntimeError:
        st = globals()["st"]
        st.title(_("Secret area for beta testers"))
        secret_function()
        return

    return {
        "region": region,
        **params,
        **st.healthcare_params(region),
        **st.epidemiological_params(region, disease),
        **{"runner": st.intervention_runner_input(params["period"])},
    }
Esempio n. 22
0
    def get_dataframe(self, days, columns, info_cols=()):
        regions = self.user_inputs["regions"]
        steps = len(self.user_inputs["regions"])
        duration = max(days)
        days_ranges = np.array([0, *days])
        columns = list(columns)

        progress_bar = st.progress(0)
        with st.spinner(_("Running simulations")):

            rows = {}
            for i, region in enumerate(regions):
                base, group = self.__run_simulations(region, duration)
                progress_bar.progress(int(100 * i / steps))

                cols = {}
                for a, b in sk.window(2, days_ranges):
                    day = b
                    a += base.time + 1
                    b += a - 1
                    renames = dict(zip(itertools.count(), columns))

                    name = _("{} days").format(day)
                    cols[name] = (
                        pd.DataFrame(group[columns, a:b].max(0))
                        .T.rename(columns=renames)
                        .rename(index={0: region.id})
                        .astype(int)
                    )

                keys = [*cols]
                cols_data = [*cols.values()]
                rows[region.id] = pd.concat(cols_data, axis=1, names=[_("days")], keys=keys)

        progress_bar.empty()
        cols_data = pd.concat(list(rows.values()))
        cols_data.index = rows.keys()

        if info_cols:
            extra_info = cols_data.mundi[info_cols]
            extra_info = extra_info.astype(object)  # streamlit bug?
            extra_info.columns = pd.MultiIndex.from_tuples(("", "info", x) for x in extra_info.columns)
            data = pd.concat([extra_info, cols_data], axis=1)
            return cols_data.sort_values(cols_data.columns[0])
        else:
            return cols_data.sort_index()
Esempio n. 23
0
 def list_top(data: pd.Series):
     *head, last = sk.pipe(
         data.sort_values(ascending=False).index[:top],
         sk.map(mundi.region),
         sk.map("{0.name}".format),
     )
     head = ", ".join(head)
     return _(" and ").join([head, last])
Esempio n. 24
0
 def _other_regions(self, col):
     data, _ = self.tables
     names = data.sort_values(col).mundi["name"]
     *other, last = names.iloc[1:]
     other = ", ".join(other)
     if other:
         return _(" and ").join([other, last])
     return last
Esempio n. 25
0
def hospitalization_chart(model, shift=0):
    df = model[["severe", "critical"]]
    df.index = df.index - shift
    df.plot(grid=grid)
    plt.mark_y(model.hospital_surge_capacity,
               "--",
               color=plt.color(2),
               label=_("Hospital beds"))
    plt.mark_y(model.icu_surge_capacity,
               "--",
               color=plt.color(2),
               label=_("ICU"))
    if shift:
        plt.mark_x(0, "k--")
    plt.legend()
    plt.tight_layout("x")
    st.pyplot()
Esempio n. 26
0
    def __get_models(self) -> dict:
        models = {}
        regions = self.user_inputs["regions"]

        for region in regions:
            with st.spinner(_("Processing {name}").format(name=region.name)):
                result = self.__process_region(region)
                models.update({(region, k): v for k, v in result.items()})
        return models
Esempio n. 27
0
def main(embed=False, disease=covid19):
    if not embed:
        ui.css(keep_menu=True)

    if not embed:
        ui.logo(where=st.sidebar)

    st.title(_("Projections for COVID-19 evolution in Brazil"))
    inputs = collect_inputs(where=st if embed else st.sidebar)
    show_results(disease=disease, **inputs)
Esempio n. 28
0
    def explore_object(self, name, obj):
        """
        Explore methods of object.
        """

        self.where = st.sidebar
        method = self.select_method(name, obj)
        args, kwargs = self.select_arguments(method)

        start = time.time()
        message = st.empty()
        result = method(*args, **kwargs)
        message.info(
            _("Method executed in {} seconds.").format(fmt(time.time() -
                                                           start)))

        self.where.line()
        self.where.subheader(_("Method help and signature"))
        self.where.help(method)

        self.explore_function_output(result)
Esempio n. 29
0
def natural_date(x):
    """
    Friendly representation of dates.

    String inputs are returned as-is.
    """
    if isinstance(x, str):
        return x
    elif x is None:
        return _("Not soon...")
    else:
        return format_date(x, format="short")
Esempio n. 30
0
    def information_message(self, results, params, epidemiology, clinical,
                            model, clinical_model):
        if results:
            self.st.html('<div style="height: 15rem"></div>')
        self.st.html('<h2 id="debug">{}</h2>'.format(_("Debug information")))

        self.st.subheader(_("Generic parameters"))
        self.st.write(params)

        self.st.subheader(_("Epidemiological parameters"))
        self.st.write(epidemiology)

        self.st.subheader(_("Clinical parameters"))
        self.st.write(clinical)

        self.st.subheader(_("Output"))
        self.st.write(results)

        if model:
            self.st.line_chart(model.data)

        if clinical_model:
            self.st.line_chart(
                clinical_model[["infectious", "severe", "critical"]])

            self.st.subheader(_("Distribution of deaths"))
            df = clinical_model[DEATH_DISTRIBUTION_COLUMNS]
            df.columns = [DEATH_DISTRIBUTION_COL_NAMES[k] for k in df.columns]
            self.st.area_chart(df)