Пример #1
0
    def test_initialization_options(self):
        br = mundi.region("BR")
        it = mundi.region("IT")

        # Initialize with no region
        m = SIR()
        assert m.population == 1_000_000
        assert m.region is None
        assert m.age_distribution is None
        assert m.age_pyramid is None

        # Use a region
        m = SIR(region="BR")
        assert m.population == br.population
        assert_series_equal(m.age_distribution, br.age_distribution, check_names=False)
        assert_frame_equal(m.age_pyramid, br.age_pyramid)

        # Mix parameters a region
        tol = 1e-6
        m = SIR(region="BR", population=1000)
        assert m.population == 1000
        assert abs(m.age_distribution.sum() - 1000) < tol
        assert abs(m.age_pyramid.sum().sum() - 1000) < tol

        ratio = br.age_distribution / m.age_distribution
        assert ((ratio - br.population / 1000).dropna().abs() < tol).all()

        # Mixed values: brazilian population with the age_distribution proportions
        # from Italy
        m = SIR(region="BR", age_distribution="IT")
        assert m.population == br.population
        assert m.age_distribution.sum() == approx(br.population)
        assert list(m.age_distribution / m.population) == approx(
            it.age_distribution / it.population
        )
Пример #2
0
    def from_children(
            cls,
            region: Union[Region, str],
            model_cls: Type[Model],
            options=MappingProxyType({}),
            **kwargs,
    ) -> "ModelGroup":
        """
        Create a group from children of the given Region.
        """
        region: Region = mundi.region(region)
        children = region.children(
            **extract_keys(("deep", "type", "subtype", "which"), kwargs))

        name = kwargs.pop("name", "{region.name}")
        group = []
        if options:
            options = {mundi.region(k): v for k, v in options.items()}

        for child in children:
            opts = options.get(child, {})
            if isinstance(name, str):
                opts["name"] = name.format(region=child, **kwargs, **opts)
            group.append(model_cls(region=child, **kwargs, **opts))

        return ModelGroup(group)
Пример #3
0
def region_input(default: str,
                 *,
                 advanced=False,
                 text=False,
                 where=st,
                 **kwargs) -> Region:
    """
    Select region or sub-region based on mundi code.
    """
    st = where
    kwargs["where"] = where
    default = mundi.code(default)
    if text or advanced and st.checkbox(_("Advanced selection"), value=False):
        try:
            code = st.text_input(_("Select mundi region"), value=default)
            return mundi.region(code)
        except LookupError:
            st.error(_("Region not found!"))
            return mundi.region(default)
    region = mundi.region(default)

    if region.id == "BR":
        return _br_region_input(**kwargs)
    elif len(default) == 2:
        return _from_sub_regions(region, _("Location"), where=where)
    else:
        raise NotImplementedError(f"Cannot select {default!r}")
Пример #4
0
    def test_arbitrary_composite_region(self):
        bsb = region("BR-5300108")
        sp = region("BR-3550308")
        reg = CompositeRegion([bsb, sp])

        assert reg.population == bsb.population + sp.population
        assert_series_equal(reg.age_distribution, bsb.age_distribution + sp.age_distribution)
Пример #5
0
def ibge_city(code):
    if code.isdigit():
        if len(code) == 7:
            code = code[:-1]
        elif len(code) != 6:
            raise ValueError(_("invalid city code: {code}").format(code=code))
        return mundi.region(country_code="BR", type="city", short_code=code)
    return mundi.region(code)
Пример #6
0
def _from_template(code, template, where=st) -> Region:
    """
    Select a Brazilian region from country up to municipality.
    """
    code = mundi.region(code)
    for label, type_, subtype in template:
        kwargs = {"type": type_}
        if subtype:
            kwargs["subtype"] = subtype
        new_code = _from_sub_regions(code, label, where=where, **kwargs)
        if new_code == code:
            return mundi.region(code)
        code = new_code
    return mundi.region(code)
Пример #7
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)
Пример #8
0
def get_confirmed_daily_cases_for_region(region, disease=covid19) -> int:
    """
    Return the number of newly confirmed cases per day.
    """
    region = mundi.region(region)
    df = region.pydemic.epidemic_curve(disease)
    return safe_int(df["cases"].diff().iloc[-7:].mean())
Пример #9
0
 def test_epidemiological_params_advanced(self, en):
     br = mundi.region("BR")
     st = Driver([
         out.header("Epidemiology"),
         ask.selectbox["custom"](...),
         out.subheader(...),
         ask.slider[2.0](...),  # R0
         ask.slider[3.0](...),  # incubation period
         ask.slider[3.0](...),  # infectious period
         ask.slider[50](...),  # symptomatic cases
         out.subheader(...),
         ask.slider[5](...),  # prob_severe
         ask.slider[25](...),  # prob_critical
         ask.slider[10](...),  # hospitalization_period
         ask.slider[7](...),  # icu_period
     ])
     assert input.epidemiological_params(br, where=st) == {
         "R0": 2.0,
         "severe_period": 10,
         "critical_period": 7,
         "incubation_period": 3.0,
         "infectious_period": 3.0,
         "prob_critical": 0.0125,
         "prob_severe": 0.05,
         "prob_symptoms": 0.5,
     }
     assert st.is_empty()
Пример #10
0
    def __init(self, region=None, population=None, age_distribution=None, age_pyramid=None):

        if age_distribution is not None and age_pyramid is not None:
            msg = "cannot set age_pyramid and age_distribution simultaneously"
            raise ValueError(msg)

        # Set region
        if region is not None:
            self.region = mundi.region(region)
            population = population or self.region.population
        elif not hasattr(self, "region"):
            self.region = None

        # Set age_pyramid
        if age_pyramid is not None:
            self.age_pyramid = fallback_to_region(age_pyramid, "age_pyramid")
        elif hasattr(self, "age_pyramid"):
            pass
        elif self.region is not None:
            self.age_pyramid = fallback_to_region(self.region, "age_pyramid")
        else:
            self.age_pyramid = None

        # Set age_distribution
        if age_distribution is not None:
            value = fallback_to_region(age_distribution, "age_distribution")
            self.age_distribution = value
        elif hasattr(self, "age_distribution"):
            pass
        elif self.age_pyramid is not None:
            self.age_distribution = self.age_pyramid.sum(1)
            self.age_distribution.name = "age_distribution"
            self.age_distribution.index.names = ["age"]
        elif self.region is not None:
            self.age_distribution = fallback_to_region(self.region, "age_distribution")
        else:
            self.age_distribution = None

        # Set population and fix age_distribution and age_pyramid, if necessary
        if hasattr(self, "population"):
            pass
        elif population is not None:
            population = fallback_to_region(population, "population")
            self.population = population

            if self.age_distribution is not None:
                ratio = population / self.age_distribution.sum()
                if ratio != 1:
                    self.age_distribution *= ratio

            if self.age_pyramid is not None:
                ratio = population / self.age_pyramid.sum().sum()
                if ratio != 1:
                    self.age_pyramid *= ratio
        elif self.age_distribution is not None:
            self.population = self.age_distribution.sum()
        elif self.region is not None:
            self.population = self.region.population
        else:
            self.population = 1_000_000
Пример #11
0
    def get_regions(self, **query):
        """
        Get all children in region that have the same values of the parameters passed
        as keyword arguments.
        """

        return [mundi.region(id_) for id_ in mundi.regions(**query).index]
Пример #12
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}")
Пример #13
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}")
Пример #14
0
def region_name(code):
    """Region name from Mundi code."""

    if code.startswith("*"):
        return _("{name} (everything)").format(name=region_name(code[1:]))

    reg = mundi.region(code)
    return _(reg["name"])
Пример #15
0
def _from_sub_regions(code,
                      label,
                      fastrack=False,
                      where=st,
                      **kwargs) -> Region:
    """
    Select a region from a list that starts with the parent region and its
    children.
    """
    region = mundi.region(code)
    regions = sub_regions(region.id, **kwargs)
    if len(regions) == 1 and fastrack:
        return regions[0]
    regions = ("*" + region.id, *regions)
    return mundi.region(
        where.selectbox(str(label), regions,
                        format_func=region_name).lstrip("*"))
Пример #16
0
def sari_br_state_content(region: str) -> bytes:
    region = mundi.region(region)
    ref = region.short_code.lower()
    url = f"https://s3-sa-east-1.amazonaws.com/ckan.saude.gov.br/dados-{ref}.csv"
    log.info(f"[sari-br] Downloading data for {region}")
    response = requests.get(url)
    log.info(f"[sari-br] Download complete!")
    return response.content
Пример #17
0
 def test_select_region(self, en):
     st = Driver([
         out.header("Location"),
         ask.selectbox["BR-1"](...),
         ask.selectbox["*BR-1"](...),
     ])
     assert input.region_input("BR", where=st) == mundi.region("BR-1")
     assert st.is_empty()
Пример #18
0
 def _test_regional_model_to_json(self):
     m = SIR(region="BR")
     br = mundi.region("BR")
     assert m.info.to_dict() == {
         "demography.population": br.population,
         "demography.age_distribution": br.age_distribution,
         "demography.age_pyramid": br.age_pyramid,
     }
     assert m.info.to_dict(flat=True) == flatten_dict(m.info.to_dict())
Пример #19
0
def from_region(cls, transform, region, params=None, disease=None, **kwargs):
    """
    Initialize data extracting curve from region.
    """
    region = mundi.region(region)
    disease = diseases.disease(disease)
    data = disease.epidemic_curve(region)
    kwargs.setdefault("population", region.population)
    return cls(transform(data), params, **kwargs)
Пример #20
0
 def from_region(cls, region, *, model_cls=None, init_cases=True, **kwargs):
     """
     Initialize report from cases reported in region.
     """
     region = mundi.region(region)
     init_kwargs = extract_keys(INIT_KEYS, kwargs)
     model = (model_cls or cls.model_cls)(region=region, **kwargs)
     if init_cases:
         model.set_cases()
     return cls(model, **init_kwargs)
Пример #21
0
    def _fatality_ratio(self, col, age_distribution=None, source=None, region=None):
        table = self.mortality_table(source=source)

        if age_distribution is None and region:
            ages = mundi.region(region).age_distribution
        elif age_distribution is None:
            ages = world_age_distribution()
        else:
            ages = age_distribution
        return age_adjusted_average(ages, table[col])
Пример #22
0
def get_model(region):
    region = mundi.region(region)
    data = region.pydemic.epidemic_curve()
    empirical_CFR = (data["deaths"] / data["cases"]).mean()
    notification_rate = min(0.5, covid19.CFR(region=region) / empirical_CFR)

    m = SEAIR(region=region, R0=R0[region.id])
    real_data = data.copy()
    real_data["cases"] /= notification_rate
    m.set_cases(real_data, save_observed=True)
    m.run(60)
    return m.clinical.overflow_model()
Пример #23
0
    def test_info(self):
        approx = lambda x: _approx(x, rel=0.005)
        disease = get_disease("covid-19")
        m = SIR(disease="covid-19", region="BR")
        m.set_ic(cases=1e6)
        m.run(60)

        # Disease
        infectious_period = disease.infectious_period(region="BR")
        assert m.info["disease.CFR"] == approx(disease.CFR(region="BR"))
        assert m.info["disease.IFR"] == approx(disease.IFR(region="BR"))
        assert m.info["disease.infectious_period"] == approx(infectious_period)
        assert set(m.info["disease"]) == {
            "R0",
            "case_fatality_ratio",
            "critical_delay",
            "critical_period",
            "death_delay",
            "hospital_fatality_ratio",
            "hospitalization_overflow_bias",
            "hospitalization_period",
            "hospitalization_table",
            "icu_fatality_ratio",
            "icu_period",
            "incubation_period",
            "infection_fatality_ratio",
            "infectious_period",
            "mortality_table",
            "prob_aggravate_to_icu",
            "prob_critical",
            "prob_severe",
            "prob_symptoms",
            "rho",
            "serial_period",
            "severe_delay",
            "severe_period",
            "symptom_delay",
        }

        # Region
        br = mundi.region("BR")
        keys = {
            "population",
            "age_distribution",
            "age_pyramid",
            "hospital_capacity",
            "icu_capacity",
        }

        assert m.info["region.population"] == br.population
        assert all(m.info["region.age_distribution"] == br.age_distribution)
        assert all(m.info["region.age_pyramid"] == br.age_pyramid)
        assert set(m.info["region"]) == keys
Пример #24
0
    def test_load_country(self):
        br = mundi.region("BR")
        assert isinstance(br, Region)
        assert br.id == "BR"
        assert br["name"] == "Brazil"
        assert br["type"] == "country"
        assert br["short_code"] == "BR"
        assert br["numeric_code"] == "076"
        assert br["long_code"] == "BRA"
        assert br["country_code"] is None
        assert br["parent_id"] == "XSA"

        ar = mundi.region("ar")
        assert isinstance(ar, Region)
        assert ar["name"] == "Argentina"
        assert ar["type"] == "country"
        assert ar["short_code"] == "AR"
        assert ar["numeric_code"] == "032"
        assert ar["long_code"] == "ARG"
        assert ar["country_code"] is None
        assert br["parent_id"] == "XSA"
Пример #25
0
def sari_br_state_dataframe(region: Region) -> pd.DataFrame:
    """
    Return the full table of SARI hospital vigilance for the given region.
    """

    region = mundi.region(region)
    content = sari_br_state_content(region.id)
    lines = content.splitlines()
    content = lines[0] + b"\n" + b"\n".join(lines[-1000:])
    fd = io.BytesIO(content)

    with st.spinner(f"Converting to CSV ({region.name})"):
        chunks = []
        date_columns = [
            "dataNotificacao",
            "dataInicioSintomas",
            "dataNascimento",
            "dataEncerramento",
            "dataTeste",
        ]
        for df in pd.read_csv(
                fd,
                index_col=0,
                sep=";",
                parse_dates=date_columns,
                dtype=DTYPES,
                converters=CONVERTERS,
                engine="c",
                chunksize=1000,
                encoding="latin1",
        ):
            df: pd.DataFrame = (df.astype(DTYPES).rename(
                columns=RENAME).astype({
                    "status": Status.categories,
                    "gender": Gender.categories,
                    "evolution": Evolution.categories,
                    "test_status": Test.categories,
                }))

            def localtime(x):
                if pd.isna(x):
                    return x
                return x.time()

            df["notification_time"] = df["notification_date"].apply(localtime)
            df["notification_date"] = df["notification_date"].apply(
                lambda x: x if pd.isna(x) else x.date())
            df.index.name = "id"
            chunks.append(df)

    df = pd.concat(chunks)
    return df
Пример #26
0
def show_results(parent_region, regions, columns, targets, days, disease=covid19):
    """
    Show results from user input.
    """

    parent_region = mundi.region(parent_region)
    ax = parent_region.plot.cases_and_deaths(disease=disease, logy=True, grid=True)
    st.pyplot(ax.get_figure())
    if days and targets and columns:
        df = get_dataframe(regions, tuple(days), tuple(targets), tuple(columns), 61)

        st.subheader(_("Download results"))
        st.dataframe_download(df, name="report-brazil.{ext}")
Пример #27
0
def healthcare_params(region,
                      title=__("Hospital capacity"),
                      occupancy=0.75,
                      where=st):
    """
    Return a dictionary with hospital and icu capacities from user input.

    Returns:
        icu_capacity (float): surge system capacity of ICUs
        icu_full_capacity (float): total system capacity of ICUs
        hospital_capacity (float): surge system capacity of regular beds
        hospital_full_capacity (float): total system capacity of regular beds
    """

    region = mundi.region(region)
    where.header(str(title))

    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)

    h_cap = safe_int(region.hospital_capacity)
    icu_cap = safe_int(region.icu_capacity)

    return {
        "icu_full_capacity":
        icu_cap,
        "hospital_full_capacity":
        h_cap,
        "icu_capacity":
        get(_("ICU beds"), icu_cap, occupancy, key="icu"),
        "hospital_capacity":
        get(_("Clinical beds"), h_cap, occupancy, key="hospital"),
    }
Пример #28
0
    def test_clinical_model_uses_region_IFR(self, region="BR"):
        m = SEIR(region=region, disease=covid19)
        br = mundi.region("BR")
        m1 = m.clinical.crude_model()
        m2 = m.clinical.delay_model()
        m3 = m.clinical.overflow_model()

        IFR = covid19.IFR(region=region)
        CFR = covid19.CFR(region=region)

        for m in [m1, m2, m3]:
            assert m.region == br
            assert m.IFR == m.infection_fatality_ratio == IFR
            assert m.CFR == m.case_fatality_ratio == CFR
Пример #29
0
 def test_simulation_params(self, en):
     br = mundi.region("BR")
     st = Driver([
         out.header("Simulation options"),
         ask.slider[10](...),
         ask.date_input[today(10)](...),
         out.subheader("Cases"),
         ask.number_input[10](...),
         ask.slider[10](...),
     ])
     assert input.simulation_params(br, where=st) == {
         "period": 70,
         "date": today(10),
         "daily_cases": 100,
     }
     assert st.is_empty()
Пример #30
0
    def show(self):

        parent_region = self.__datahandler.user_inputs["parent_region"]
        columns = self.__datahandler.user_inputs["columns"]
        targets = self.__datahandler.user_inputs["targets"]
        days = self.__datahandler.user_inputs["days"]
        disease = self.__datahandler.user_inputs["disease"]

        parent_region = mundi.region(parent_region)
        axes = parent_region.plot.cases_and_deaths(disease=disease, logy=True, grid=True)
        st.pyplot(axes.get_figure())
        if days and targets and columns:
            df = self.__datahandler.get_dataframe(tuple(days), tuple(targets), tuple(columns))

            st.subheader(_("Download results"))
            st.dataframe_download(df, name="report-brazil.{ext}")