Episia Package#

Episia - Epidemiology Toolbox for Python Based on OpenEpi algorithms, extended for the African public health context.

Quick start:

from episia import epi

# SEIR model
model  = epi.seir(N=1_000_000, I0=10, E0=50, beta=0.35,
                  sigma=1/5.2, gamma=1/14)
result = model.run()
result.plot().show()

# Biostatistics
rr = epi.risk_ratio(a=40, b=10, c=20, d=30)
print(rr)

# Report
report = epi.report(result, title="SEIR — Burkina Faso 2024")
report.save_html("report.html")

Advanced usage (direct imports):

# Models
from episia.models import SIRModel, SEIRModel, SEIRDModel
from episia.models import SensitivityAnalysis, ModelCalibrator

# Stats
from episia.stats import risk_ratio, odds_ratio, diagnostic_test_2x2
from episia.stats import roc_analysis, sample_size_risk_ratio

# Reporting
from episia import EpiReport
report = EpiReport(title="My report", author="Dr. Ouedraogo")
report.add_metrics({"R0": 3.2, "Peak": "42,500"})
report.save_html("report.html")

# Visualization
from episia.viz import plot_epicurve, plot_roc, plot_forest, set_theme
set_theme("dark")

# Surveillance data
from episia.data import SurveillanceDataset, AlertEngine
class episia.AlertEngine(dataset)[source]#

Bases: object

Threshold-based and statistical alert detection for surveillance data.

Example:

engine = AlertEngine(dataset)
alerts = engine.run(
    threshold=10,
    zscore_threshold=2.0,
    use_endemic_channel=True,
)
for a in alerts:
    print(a.period, a.severity, a.message)
Parameters:

dataset (SurveillanceDataset)

__init__(dataset)[source]#
Parameters:

dataset (SurveillanceDataset)

alert_summary(alerts)[source]#

Summarise a list of alerts.

Parameters:

alerts (List[Alert])

Return type:

Dict[str, Any]

run(threshold=None, zscore_threshold=2.0, use_endemic_channel=False, historical_years=None, freq='W')[source]#

Run all enabled alert detectors.

Parameters:
  • threshold (float | None) – Absolute case count threshold.

  • zscore_threshold (float) – Z-score threshold for statistical alert.

  • use_endemic_channel (bool) – Use endemic channel (requires ≥3 historical years).

  • historical_years (List[int] | None) – Years to use for endemic channel baseline.

  • freq (str) – Aggregation frequency (‘D’, ‘W’, ‘ME’).

Returns:

List of Alert objects, sorted by period.

Return type:

List[Alert]

class episia.EpiReport(title='Epidemiological report', author=None, institution=None, date=None, description=None)[source]#

Bases: object

Structured epidemiological report builder.

Example:

report = EpiReport(title="Analyse SEIR", author="Dr. Ouedraogo")
report.add_text("Introduction...", title="Introduction")
report.add_metrics({"R0": 3.2, "Peak": 42500})
report.add_table(df, title="Results")
report.save_html("rapport.html")
report.save_markdown("rapport.md")
Parameters:
  • title (str)

  • author (Optional[str])

  • institution (Optional[str])

  • date (Optional[str])

  • description (Optional[str])

__init__(title='Epidemiological report', author=None, institution=None, date=None, description=None)[source]#
Parameters:
  • title (str)

  • author (str | None)

  • institution (str | None)

  • date (str | None)

  • description (str | None)

add_divider()[source]#
Return type:

EpiReport

add_figure(figure, title=None, caption=None, width='100%')[source]#
Parameters:
  • figure (Any)

  • title (str | None)

  • caption (str | None)

  • width (str)

Return type:

EpiReport

add_metrics(metrics, title='Key indicators')[source]#
Parameters:
Return type:

EpiReport

add_result(result, title=None)[source]#
Parameters:
  • result (Any)

  • title (str | None)

Return type:

EpiReport

add_table(data, title=None, caption=None, max_rows=100)[source]#
Parameters:
  • data (Any)

  • title (str | None)

  • caption (str | None)

  • max_rows (int)

Return type:

EpiReport

add_text(text, title=None, level=2)[source]#
Parameters:
Return type:

EpiReport

save_html(path)[source]#
Parameters:

path (str | Path)

Return type:

Path

save_json(path)[source]#
Parameters:

path (str | Path)

Return type:

Path

save_markdown(path)[source]#
Parameters:

path (str | Path)

Return type:

Path

to_html()[source]#
Return type:

str

to_json(indent=2)[source]#
Parameters:

indent (int)

Return type:

str

to_markdown()[source]#
Return type:

str

class episia.EpisiaAPI[source]#

Bases: object

Unified Episia API single entry point for all functionality. Instantiated as the module-level epi singleton.

static cumulative_incidence(*args, **kwargs)[source]#
static diagnostic(*args, **kwargs)[source]#
static get_available_themes()[source]#
static incidence_rate(*args, **kwargs)[source]#
static mean_ci(*args, **kwargs)[source]#
static odds_ratio(*args, **kwargs)[source]#
static plot_epicurve(*args, **kwargs)[source]#
static plot_forest(*args, **kwargs)[source]#
static plot_roc(*args, **kwargs)[source]#
static prevalence(*args, **kwargs)[source]#
static proportion_ci(*args, **kwargs)[source]#
static read_csv(path, **kwargs)[source]#
static report(result, title=None, **kwargs)[source]#

Build a report from any EpiResult or ModelResult.

Parameters:
  • result (Any)

  • title (str | None)

static risk_ratio(*args, **kwargs)[source]#
static sample_size(*args, **kwargs)[source]#
static seir(N, I0, E0, beta, sigma, gamma, t_end=365, **kwargs)[source]#

Convenience factory for SEIRModel.

Parameters:
static seird(N, I0, E0, beta, sigma, gamma, mu, t_end=365, **kwargs)[source]#

Convenience factory for SEIRDModel.

Parameters:
static set_theme(theme)[source]#
Parameters:

theme (str)

Return type:

None

static sir(N, I0, beta, gamma, t_end=160, **kwargs)[source]#

Convenience factory for SIRModel.

Parameters:
static surveillance_from_csv(path, **kwargs)[source]#
class episia.SurveillanceDataset(df, *, date_col='date', cases_col='cases', deaths_col=None, district_col=None, disease_col=None, population_col=None)[source]#

Bases: object

Structured surveillance case count dataset.

Wraps a pandas DataFrame with columns:

date / week / period time axis district / site spatial unit (optional) disease disease or syndrome name cases integer case count deaths integer death count (optional) population population at risk (optional)

Built from CSV, DHIS2 exports, or a plain DataFrame.

Example:

from episia.data.surveillance import SurveillanceDataset

ds = SurveillanceDataset.from_csv("meningite_2024.csv",
                                   date_col="semaine",
                                   cases_col="cas")
print(ds.summary())
ds.epicurve().plot().show()
alerts = ds.alert_engine().run()
Parameters:
  • date_col (str)

  • cases_col (str)

  • deaths_col (Optional[str])

  • district_col (Optional[str])

  • disease_col (Optional[str])

  • population_col (Optional[str])

__init__(df, *, date_col='date', cases_col='cases', deaths_col=None, district_col=None, disease_col=None, population_col=None)[source]#
Parameters:
  • date_col (str)

  • cases_col (str)

  • deaths_col (str | None)

  • district_col (str | None)

  • disease_col (str | None)

  • population_col (str | None)

aggregate(freq='W', group_by=None)[source]#

Aggregate cases by time frequency and optional grouping columns.

Parameters:
  • freq (str) – Pandas offset alias (‘D’=daily, ‘W’=weekly, ‘ME’=monthly).

  • group_by (List[str] | None) – Additional columns to group by (district, disease…).

Returns:

pandas DataFrame with aggregated counts.

attack_rate(population=None, per=100000)[source]#

Compute overall attack rate.

Parameters:
  • population (int | None) – Population denominator (uses population_col if None).

  • per (int) – Rate denominator (default 100,000).

Returns:

Attack rate per per population.

Return type:

float

property cfr: float | None#

Case fatality rate = total_deaths / total_cases.

completeness(freq='auto', period_col=None)[source]#

Compute reporting completeness over the observed date range.

Identifies expected periods (inferred from freq) versus periods actually present in the dataset, and returns the missing ones.

This is especially relevant when loading data from DHIS2 instances in sub-Saharan Africa where silent gaps are common: a district that did not submit its weekly report will simply be absent from the export, distorting endemic-channel baselines without any warning.

Parameters:
  • freq (str) –

    Expected reporting frequency. One of:

    • "auto" – inferred from median gap between dates (default).

    • "W" – weekly (ISO weeks).

    • "ME" – monthly (pandas >= 2.2).

    • "QE" – quarterly.

    • "D" – daily.

  • period_col (str | None) – Column that contains DHIS2 period strings such as "2024W01" or "202401" (optional). When provided, completeness is calculated against these string labels rather than inferred datetime periods, and the period_range() helper is used internally to build the expected sequence.

Returns:

  • expected_periods (int)

  • reported_periods (int)

  • completeness_rate (float, 0.0 – 1.0)

  • missing_periods (list[str])

  • freq (str, the frequency used)

Return type:

dict with keys

Raises:

ValueError – if the dataset has fewer than 2 records.

Example:

ds = client.to_dataset(
    data_element="FTRrcoaog83",
    period="LAST_52_WEEKS",
    org_unit="ImspTQPwCqd",
)
result = ds.completeness()
# {
#   "expected_periods": 52,
#   "reported_periods": 49,
#   "completeness_rate": 0.942,
#   "missing_periods": ["2024W15", "2024W16", "2024W31"],
#   "freq": "W",
# }
property date_range: Tuple[Any, Any]#
property df#
property diseases: List[str]#
property districts: List[str]#
endemic_channel(historical_years=None, percentiles=(25, 50, 75))[source]#

Compute the endemic channel (historical percentile envelope).

Groups by ISO week number across historical years. Returns the percentile bands used for alert zone classification.

Parameters:
  • historical_years (List[int] | None) – Years to include (all years if None).

  • percentiles (Tuple[float, float, float]) – (low, median, high) percentiles.

Returns:

‘weeks’, ‘p_low’, ‘p_mid’, ‘p_high’.

Return type:

Dict with keys

filter_date(start=None, end=None)[source]#

Filter to a date range (inclusive).

Parameters:
  • start (Any | None)

  • end (Any | None)

Return type:

SurveillanceDataset

filter_disease(disease)[source]#

Return a new dataset filtered to a single disease.

Parameters:

disease (str)

Return type:

SurveillanceDataset

filter_district(district)[source]#

Return a new dataset filtered to a single district.

Parameters:

district (str)

Return type:

SurveillanceDataset

classmethod from_csv(path, date_col='date', cases_col='cases', deaths_col=None, district_col=None, disease_col=None, population_col=None, **read_kwargs)[source]#

Load from CSV file.

Parameters:
  • path (str | Path) – Path to CSV file.

  • date_col (str) – Column name for date / week.

  • cases_col (str) – Column name for case counts.

  • deaths_col (str | None) – Column name for deaths (optional).

  • district_col (str | None) – Column name for district / site (optional).

  • disease_col (str | None) – Column name for disease / syndrome (optional).

  • population_col (str | None) – Column for population at risk (optional).

  • **read_kwargs – Passed to pd.read_csv.

Returns:

SurveillanceDataset.

Return type:

SurveillanceDataset

classmethod from_dataframe(df, **kwargs)[source]#

Wrap an existing DataFrame.

Return type:

SurveillanceDataset

classmethod from_dict(data, **kwargs)[source]#

Create from a plain dict of lists.

Parameters:

data (Dict[str, List])

Return type:

SurveillanceDataset

property n_records: int#
summary()[source]#

Return a summary statistics dict.

Return type:

Dict[str, Any]

to_timeseries_result()[source]#

Convert to api.results.TimeSeriesResult for viz integration.

Returns:

TimeSeriesResult ready for plot_epicurve().

property total_cases: int#
property total_deaths: int | None#
weekly_attack_rates(population, per=100000)[source]#

Compute weekly attack rates.

Parameters:
  • population (int) – Population at risk.

  • per (int) – Rate denominator.

Returns:

period, cases, attack_rate.

Return type:

pandas DataFrame with columns

episia.report_from_model(model_result, title=None, author=None, institution=None, sensitivity_result=None, backend='plotly', theme='scientific')[source]#

Full model simulation report (SIR / SEIR / SEIRD).

Parameters:
  • model_result (Any)

  • title (str | None)

  • author (str | None)

  • institution (str | None)

  • sensitivity_result (Any | None)

  • backend (str)

  • theme (str)

Return type:

EpiReport

episia.report_from_result(result, title=None, author=None, backend='plotly', theme='scientific')[source]#

One-line report from any EpiResult.

Parameters:
  • result (Any)

  • title (str | None)

  • author (str | None)

  • backend (str)

  • theme (str)

Return type:

EpiReport

Package Overview#

The episia package provides a comprehensive toolbox for epidemiological analysis. The recommended entry point is the unified epi interface:

from episia import epi

# Unified API
model = epi.seir(N=1_000_000, I0=10, E0=50, beta=0.35, sigma=1/5.2, gamma=1/14)
rr = epi.risk_ratio(a=40, b=10, c=20, d=30)
report = epi.report(result)

For advanced usage, individual modules can be imported directly.

Version Information#

episia.__version__: str = "0.1.3"#

Current version of Episia.

episia.__author__: str = "Fidlouindé Ariel Shadrac Ouedraogo"#

Package author.

episia.__email__: str = "arielshadrac@gmail.com"#

Author’s email address.

episia.__organization__: str = "Xcept-Health"#

Organization name.

episia.__license__: str = "MIT"#

License type.

Lazy Loading#

Episia uses lazy loading to improve startup performance. Heavy modules (scipy, sklearn, plotly, matplotlib) are only imported when first used. This means:

  • from episia import epi is fast

  • from episia import risk_ratio triggers the import of required dependencies

The lazy loading is implemented via PEP 562 (__getattr__).

Plotly Renderer Configuration#

Episia automatically configures the Plotly renderer based on the environment:

  • In Jupyter notebooks: Renderer is left unchanged (inline display works normally)

  • In scripts/terminals: Renderer is set to "browser" to open figures in your web browser

This prevents raw JSON from being dumped in the terminal when calling fig.show().

Unified Interface#

episia.epi = EpisiaAPI()#

Unified Episia API single entry point for all functionality. Instantiated as the module-level epi singleton.

The main entry point for Episia functionality. Provides a unified interface to all modules through a single object.

class episia.api.unified.EpisiaAPI[source]

Bases: object

Unified Episia API single entry point for all functionality. Instantiated as the module-level epi singleton.

static cumulative_incidence(*args, **kwargs)[source]
static diagnostic(*args, **kwargs)[source]
static get_available_themes()[source]
static incidence_rate(*args, **kwargs)[source]
static mean_ci(*args, **kwargs)[source]
static odds_ratio(*args, **kwargs)[source]
static plot_epicurve(*args, **kwargs)[source]
static plot_forest(*args, **kwargs)[source]
static plot_roc(*args, **kwargs)[source]
static prevalence(*args, **kwargs)[source]
static proportion_ci(*args, **kwargs)[source]
static read_csv(path, **kwargs)[source]
static report(result, title=None, **kwargs)[source]

Build a report from any EpiResult or ModelResult.

Parameters:
  • result (Any)

  • title (str | None)

static risk_ratio(*args, **kwargs)[source]
static sample_size(*args, **kwargs)[source]
static seir(N, I0, E0, beta, sigma, gamma, t_end=365, **kwargs)[source]

Convenience factory for SEIRModel.

Parameters:
static seird(N, I0, E0, beta, sigma, gamma, mu, t_end=365, **kwargs)[source]

Convenience factory for SEIRDModel.

Parameters:
static set_theme(theme)[source]
Parameters:

theme (str)

Return type:

None

static sir(N, I0, beta, gamma, t_end=160, **kwargs)[source]

Convenience factory for SIRModel.

Parameters:
static surveillance_from_csv(path, **kwargs)[source]

Reporting#

class episia.api.reporting.EpiReport(title='Epidemiological report', author=None, institution=None, date=None, description=None)[source]

Bases: object

Structured epidemiological report builder.

Example:

report = EpiReport(title="Analyse SEIR", author="Dr. Ouedraogo")
report.add_text("Introduction...", title="Introduction")
report.add_metrics({"R0": 3.2, "Peak": 42500})
report.add_table(df, title="Results")
report.save_html("rapport.html")
report.save_markdown("rapport.md")
Parameters:
  • title (str)

  • author (Optional[str])

  • institution (Optional[str])

  • date (Optional[str])

  • description (Optional[str])

__init__(title='Epidemiological report', author=None, institution=None, date=None, description=None)[source]
Parameters:
  • title (str)

  • author (str | None)

  • institution (str | None)

  • date (str | None)

  • description (str | None)

add_divider()[source]
Return type:

EpiReport

add_figure(figure, title=None, caption=None, width='100%')[source]
Parameters:
  • figure (Any)

  • title (str | None)

  • caption (str | None)

  • width (str)

Return type:

EpiReport

add_metrics(metrics, title='Key indicators')[source]
Parameters:
Return type:

EpiReport

add_result(result, title=None)[source]
Parameters:
  • result (Any)

  • title (str | None)

Return type:

EpiReport

add_table(data, title=None, caption=None, max_rows=100)[source]
Parameters:
  • data (Any)

  • title (str | None)

  • caption (str | None)

  • max_rows (int)

Return type:

EpiReport

add_text(text, title=None, level=2)[source]
Parameters:
Return type:

EpiReport

save_html(path)[source]
Parameters:

path (str | Path)

Return type:

Path

save_json(path)[source]
Parameters:

path (str | Path)

Return type:

Path

save_markdown(path)[source]
Parameters:

path (str | Path)

Return type:

Path

to_html()[source]
Return type:

str

to_json(indent=2)[source]
Parameters:

indent (int)

Return type:

str

to_markdown()[source]
Return type:

str

episia.api.reporting.report_from_result(result, title=None, author=None, backend='plotly', theme='scientific')[source]

One-line report from any EpiResult.

Parameters:
  • result (Any)

  • title (str | None)

  • author (str | None)

  • backend (str)

  • theme (str)

Return type:

EpiReport

episia.api.reporting.report_from_model(model_result, title=None, author=None, institution=None, sensitivity_result=None, backend='plotly', theme='scientific')[source]

Full model simulation report (SIR / SEIR / SEIRD).

Parameters:
  • model_result (Any)

  • title (str | None)

  • author (str | None)

  • institution (str | None)

  • sensitivity_result (Any | None)

  • backend (str)

  • theme (str)

Return type:

EpiReport

Surveillance Data#

class episia.data.surveillance.SurveillanceDataset(df, *, date_col='date', cases_col='cases', deaths_col=None, district_col=None, disease_col=None, population_col=None)[source]

Bases: object

Structured surveillance case count dataset.

Wraps a pandas DataFrame with columns:

date / week / period time axis district / site spatial unit (optional) disease disease or syndrome name cases integer case count deaths integer death count (optional) population population at risk (optional)

Built from CSV, DHIS2 exports, or a plain DataFrame.

Example:

from episia.data.surveillance import SurveillanceDataset

ds = SurveillanceDataset.from_csv("meningite_2024.csv",
                                   date_col="semaine",
                                   cases_col="cas")
print(ds.summary())
ds.epicurve().plot().show()
alerts = ds.alert_engine().run()
Parameters:
  • date_col (str)

  • cases_col (str)

  • deaths_col (Optional[str])

  • district_col (Optional[str])

  • disease_col (Optional[str])

  • population_col (Optional[str])

__init__(df, *, date_col='date', cases_col='cases', deaths_col=None, district_col=None, disease_col=None, population_col=None)[source]
Parameters:
  • date_col (str)

  • cases_col (str)

  • deaths_col (str | None)

  • district_col (str | None)

  • disease_col (str | None)

  • population_col (str | None)

aggregate(freq='W', group_by=None)[source]

Aggregate cases by time frequency and optional grouping columns.

Parameters:
  • freq (str) – Pandas offset alias (‘D’=daily, ‘W’=weekly, ‘ME’=monthly).

  • group_by (List[str] | None) – Additional columns to group by (district, disease…).

Returns:

pandas DataFrame with aggregated counts.

attack_rate(population=None, per=100000)[source]

Compute overall attack rate.

Parameters:
  • population (int | None) – Population denominator (uses population_col if None).

  • per (int) – Rate denominator (default 100,000).

Returns:

Attack rate per per population.

Return type:

float

property cfr: float | None

Case fatality rate = total_deaths / total_cases.

completeness(freq='auto', period_col=None)[source]

Compute reporting completeness over the observed date range.

Identifies expected periods (inferred from freq) versus periods actually present in the dataset, and returns the missing ones.

This is especially relevant when loading data from DHIS2 instances in sub-Saharan Africa where silent gaps are common: a district that did not submit its weekly report will simply be absent from the export, distorting endemic-channel baselines without any warning.

Parameters:
  • freq (str) –

    Expected reporting frequency. One of:

    • "auto" – inferred from median gap between dates (default).

    • "W" – weekly (ISO weeks).

    • "ME" – monthly (pandas >= 2.2).

    • "QE" – quarterly.

    • "D" – daily.

  • period_col (str | None) – Column that contains DHIS2 period strings such as "2024W01" or "202401" (optional). When provided, completeness is calculated against these string labels rather than inferred datetime periods, and the period_range() helper is used internally to build the expected sequence.

Returns:

  • expected_periods (int)

  • reported_periods (int)

  • completeness_rate (float, 0.0 – 1.0)

  • missing_periods (list[str])

  • freq (str, the frequency used)

Return type:

dict with keys

Raises:

ValueError – if the dataset has fewer than 2 records.

Example:

ds = client.to_dataset(
    data_element="FTRrcoaog83",
    period="LAST_52_WEEKS",
    org_unit="ImspTQPwCqd",
)
result = ds.completeness()
# {
#   "expected_periods": 52,
#   "reported_periods": 49,
#   "completeness_rate": 0.942,
#   "missing_periods": ["2024W15", "2024W16", "2024W31"],
#   "freq": "W",
# }
property date_range: Tuple[Any, Any]
property df
property diseases: List[str]
property districts: List[str]
endemic_channel(historical_years=None, percentiles=(25, 50, 75))[source]

Compute the endemic channel (historical percentile envelope).

Groups by ISO week number across historical years. Returns the percentile bands used for alert zone classification.

Parameters:
  • historical_years (List[int] | None) – Years to include (all years if None).

  • percentiles (Tuple[float, float, float]) – (low, median, high) percentiles.

Returns:

‘weeks’, ‘p_low’, ‘p_mid’, ‘p_high’.

Return type:

Dict with keys

filter_date(start=None, end=None)[source]

Filter to a date range (inclusive).

Parameters:
  • start (Any | None)

  • end (Any | None)

Return type:

SurveillanceDataset

filter_disease(disease)[source]

Return a new dataset filtered to a single disease.

Parameters:

disease (str)

Return type:

SurveillanceDataset

filter_district(district)[source]

Return a new dataset filtered to a single district.

Parameters:

district (str)

Return type:

SurveillanceDataset

classmethod from_csv(path, date_col='date', cases_col='cases', deaths_col=None, district_col=None, disease_col=None, population_col=None, **read_kwargs)[source]

Load from CSV file.

Parameters:
  • path (str | Path) – Path to CSV file.

  • date_col (str) – Column name for date / week.

  • cases_col (str) – Column name for case counts.

  • deaths_col (str | None) – Column name for deaths (optional).

  • district_col (str | None) – Column name for district / site (optional).

  • disease_col (str | None) – Column name for disease / syndrome (optional).

  • population_col (str | None) – Column for population at risk (optional).

  • **read_kwargs – Passed to pd.read_csv.

Returns:

SurveillanceDataset.

Return type:

SurveillanceDataset

classmethod from_dataframe(df, **kwargs)[source]

Wrap an existing DataFrame.

Return type:

SurveillanceDataset

classmethod from_dict(data, **kwargs)[source]

Create from a plain dict of lists.

Parameters:

data (Dict[str, List])

Return type:

SurveillanceDataset

property n_records: int
summary()[source]

Return a summary statistics dict.

Return type:

Dict[str, Any]

to_timeseries_result()[source]

Convert to api.results.TimeSeriesResult for viz integration.

Returns:

TimeSeriesResult ready for plot_epicurve().

property total_cases: int
property total_deaths: int | None
weekly_attack_rates(population, per=100000)[source]

Compute weekly attack rates.

Parameters:
  • population (int) – Population at risk.

  • per (int) – Rate denominator.

Returns:

period, cases, attack_rate.

Return type:

pandas DataFrame with columns

class episia.data.surveillance.AlertEngine(dataset)[source]

Bases: object

Threshold-based and statistical alert detection for surveillance data.

Example:

engine = AlertEngine(dataset)
alerts = engine.run(
    threshold=10,
    zscore_threshold=2.0,
    use_endemic_channel=True,
)
for a in alerts:
    print(a.period, a.severity, a.message)
Parameters:

dataset (SurveillanceDataset)

__init__(dataset)[source]
Parameters:

dataset (SurveillanceDataset)

alert_summary(alerts)[source]

Summarise a list of alerts.

Parameters:

alerts (List[Alert])

Return type:

Dict[str, Any]

run(threshold=None, zscore_threshold=2.0, use_endemic_channel=False, historical_years=None, freq='W')[source]

Run all enabled alert detectors.

Parameters:
  • threshold (float | None) – Absolute case count threshold.

  • zscore_threshold (float) – Z-score threshold for statistical alert.

  • use_endemic_channel (bool) – Use endemic channel (requires ≥3 historical years).

  • historical_years (List[int] | None) – Years to use for endemic channel baseline.

  • freq (str) – Aggregation frequency (‘D’, ‘W’, ‘ME’).

Returns:

List of Alert objects, sorted by period.

Return type:

List[Alert]

Available Lazy Imports#

The following names are lazily loaded from their respective modules:

Statistics: - risk_ratio - odds_ratio - proportion_ci - mean_ci - diagnostic_test_2x2 - roc_analysis - sample_size_risk_ratio - sample_size_single_proportion

Visualization: - set_theme - get_available_themes - plot_epicurve - plot_roc - plot_forest

Examples#

Basic usage with unified interface:

from episia import epi

# SEIR model
model = epi.seir(
    N=1_000_000,
    I0=10,
    E0=50,
    beta=0.35,
    sigma=1/5.2,
    gamma=1/14
)
result = model.run()
result.plot().show()

# Risk ratio
rr = epi.risk_ratio(a=40, b=10, c=20, d=30)
print(rr)  # Risk Ratio: 2.667 (1.514-4.696)

# Generate report
report = epi.report(result, title="SEIR Analysis")
report.save_html("report.html")

Direct imports for advanced usage:

from episia.models import SEIRModel, SensitivityAnalysis
from episia.stats import roc_analysis, sample_size_risk_ratio
from episia.viz import plot_epicurve, set_theme
from episia.data import SurveillanceDataset

# Set theme globally
set_theme("dark")

# Load surveillance data
ds = SurveillanceDataset.from_csv("cases.csv")

# ROC analysis
roc_result = roc_analysis(y_true, y_scores)

Version check:

import episia
print(f"Episia version: {episia.__version__}")