"""Cached data loaders for the RHTP dashboard. Every loader reads from /data//. Replace the file with a real-data file of the same schema to switch from synthetic to live data. """ from __future__ import annotations from pathlib import Path from typing import Optional import pandas as pd import streamlit as st # /app at runtime in Docker, project root locally ROOT_CANDIDATES = [Path("/app"), Path(__file__).resolve().parents[2]] for _root in ROOT_CANDIDATES: if (_root / "data").exists(): ROOT = _root break else: # pragma: no cover ROOT = ROOT_CANDIDATES[-1] DATA = ROOT / "data" def _read(rel: str) -> pd.DataFrame: """Read a CSV (or its parquet sibling if present and newer). `fips` and `county_fips` are kept as zero-padded strings so they merge cleanly across files. Use object dtype rather than pandas string[python] -- the latter trips patsy when used as a categorical fixed effect. """ csv = DATA / rel parquet = csv.with_suffix(".parquet") if parquet.exists() and parquet.stat().st_mtime >= csv.stat().st_mtime: df = pd.read_parquet(parquet) else: df = pd.read_csv(csv, dtype={"fips": str, "county_fips": str}) for c in ("fips", "county_fips"): if c in df.columns: df[c] = df[c].astype(str).str.zfill(5) return df # -------------------------------------------------------------------------- # Geography # -------------------------------------------------------------------------- @st.cache_data(show_spinner=False) def counties() -> pd.DataFrame: return _read("geography/montana_counties.csv") @st.cache_data(show_spinner=False) def population_panel() -> pd.DataFrame: return _read("geography/county_population_panel.csv") @st.cache_data(show_spinner=False) def hospitals() -> pd.DataFrame: return _read("geography/montana_hospitals.csv") # -------------------------------------------------------------------------- # Facilities # -------------------------------------------------------------------------- @st.cache_data(show_spinner=False) def facility_quarter_ops() -> pd.DataFrame: df = _read("facilities/facility_quarter_ops.csv") df["period"] = df["year"].astype(str) + "Q" + df["quarter"].astype(str) df["period_index"] = df["year"] * 4 + (df["quarter"] - 1) return df @st.cache_data(show_spinner=False) def facility_quarter_treatment() -> pd.DataFrame: df = _read("facilities/facility_quarter_treatment_status.csv") df["period"] = df["year"].astype(str) + "Q" + df["quarter"].astype(str) df["period_index"] = df["year"] * 4 + (df["quarter"] - 1) return df @st.cache_data(show_spinner=False) def coe_implementation() -> pd.DataFrame: return _read("facilities/coe_implementation.csv") @st.cache_data(show_spinner=False) def telehealth_activation() -> pd.DataFrame: return _read("facilities/telehealth_activation.csv") @st.cache_data(show_spinner=False) def shared_services() -> pd.DataFrame: return _read("facilities/shared_services.csv") # -------------------------------------------------------------------------- # Workforce # -------------------------------------------------------------------------- @st.cache_data(show_spinner=False) def workforce_panel() -> pd.DataFrame: return _read("workforce/workforce_county_year.csv") @st.cache_data(show_spinner=False) def service_commitment_awards() -> pd.DataFrame: return _read("workforce/service_commitment_awards.csv") @st.cache_data(show_spinner=False) def residency_slots() -> pd.DataFrame: return _read("workforce/residency_slots.csv") @st.cache_data(show_spinner=False) def training_participants() -> pd.DataFrame: return _read("workforce/training_participants.csv") @st.cache_data(show_spinner=False) def workforce_supports() -> pd.DataFrame: return _read("workforce/workforce_supports.csv") # -------------------------------------------------------------------------- # Claims # -------------------------------------------------------------------------- @st.cache_data(show_spinner=False) def member_month_pmpm() -> pd.DataFrame: return _read("claims/member_month_pmpm.csv") @st.cache_data(show_spinner=False) def county_quarter_treatment_status() -> pd.DataFrame: return _read("claims/county_quarter_treatment_status.csv") @st.cache_data(show_spinner=False) def ed_high_utilizers() -> pd.DataFrame: return _read("claims/ed_high_utilizers.csv") @st.cache_data(show_spinner=False) def tnt_cpt_usage() -> pd.DataFrame: return _read("claims/tnt_cpt_usage.csv") @st.cache_data(show_spinner=False) def pharmacy_prescribing() -> pd.DataFrame: return _read("claims/pharmacy_prescribing.csv") @st.cache_data(show_spinner=False) def outpatient_share() -> pd.DataFrame: return _read("claims/outpatient_share.csv") @st.cache_data(show_spinner=False) def ems_modernization() -> pd.DataFrame: return _read("claims/ems_modernization.csv") @st.cache_data(show_spinner=False) def vbc_attribution() -> pd.DataFrame: return _read("claims/vbc_attribution.csv") # -------------------------------------------------------------------------- # Prevention # -------------------------------------------------------------------------- @st.cache_data(show_spinner=False) def prevention_panel() -> pd.DataFrame: return _read("prevention/prevention_county_year.csv") @st.cache_data(show_spinner=False) def school_sites() -> pd.DataFrame: return _read("prevention/school_sites.csv") @st.cache_data(show_spinner=False) def mobile_care_runs() -> pd.DataFrame: return _read("prevention/mobile_care_runs.csv") @st.cache_data(show_spinner=False) def chap_rollout() -> pd.DataFrame: return _read("prevention/chap_rollout.csv") @st.cache_data(show_spinner=False) def crisis_infrastructure() -> pd.DataFrame: return _read("prevention/crisis_infrastructure.csv") # -------------------------------------------------------------------------- # Technology # -------------------------------------------------------------------------- @st.cache_data(show_spinner=False) def hie_participation() -> pd.DataFrame: return _read("technology/hie_participation.csv") @st.cache_data(show_spinner=False) def ehr_modernization() -> pd.DataFrame: return _read("technology/ehr_modernization.csv") @st.cache_data(show_spinner=False) def bed_registry() -> pd.DataFrame: return _read("technology/bed_registry.csv") @st.cache_data(show_spinner=False) def bh_bed_wait_time() -> pd.DataFrame: return _read("technology/bh_bed_wait_time.csv") @st.cache_data(show_spinner=False) def dashboard_usage() -> pd.DataFrame: return _read("technology/dashboard_usage.csv")