prime_py / src /primepy /cli.py
sdilbaz's picture
Add PRIME UI and analysis code with Turkey data
7b1174f
Raw History Blame Contribute Delete
6.08 kB
from __future__ import annotations
import json
from pathlib import Path
from typing import Optional
import typer
from .logging_utils import configure_logging
from .data_registry import DataRegistry
from .download import download_files, DownloadTarget
from .io import export_rda_to_xlsx, read_xlsx_tables, build_xlsx_from_repo
from .country_workbook import build_country_only_workbook
from .data_readers import from_xlsx_tables
from .demo import DemoParams, run_demo_and_export, compare_intermediates
from .psa import LHSSpec, ParameterDist, run_psa
import numpy as np
from scipy.stats import beta as sp_beta
app = typer.Typer(add_completion=False, no_args_is_help=True)
@app.command()
def init_registry(base_dir: str = typer.Argument(..., help="Base repository directory containing data/")) -> None:
logger = configure_logging()
reg = DataRegistry(Path(base_dir))
reg.default_from_repo()
# Print confirmation
logger.info("Initialized data registry from repository data directory")
@app.command()
def register_xlsx(base_dir: str = typer.Argument(...), year: str = typer.Argument(...), xlsx: str = typer.Argument(...)) -> None:
"""Register an xlsx bundle for a given dataset year (2012/2018/2020)."""
from .data_registry import DatasetPaths
reg = DataRegistry(Path(base_dir))
reg.register(year, DatasetPaths(rda_bundle=None, xlsx_bundle=Path(xlsx))) # type: ignore[arg-type]
typer.echo(f"Registered {year} -> {xlsx}")
@app.command()
def show_versions(base_dir: str = typer.Argument(...)) -> None:
reg = DataRegistry(Path(base_dir))
versions = reg.list_versions()
typer.echo(json.dumps(versions, indent=2))
@app.command()
def data_download(config: str = typer.Argument(..., help="JSON mapping names to {url, out}")) -> None:
"""Download current data files using a JSON config.
Example config:
{
"globocan2020_incidence": {"url": "https://.../incidence2020.csv", "out": "data/raw/incidence2020.csv"}
}
"""
logger = configure_logging()
cfg_path = Path(config)
spec = json.loads(cfg_path.read_text())
targets = {
name: DownloadTarget(url=item["url"], out=Path(item["out"])) for name, item in spec.items()
}
download_files(targets)
logger.info("Downloads completed")
@app.command()
def data_convert_rda_to_xlsx(rda_path: str = typer.Argument(...), xlsx_path: str = typer.Argument(...)) -> None:
"""Convert an R .rda bundle to an editable .xlsx workbook with multiple sheets."""
export_rda_to_xlsx(Path(rda_path), Path(xlsx_path))
typer.echo(f"Wrote {xlsx_path}")
@app.command()
def data_validate_xlsx(xlsx_path: str = typer.Argument(...), year: str = typer.Argument(...)) -> None:
"""Validate required sheets exist and show basic shapes for a given dataset year."""
tables = read_xlsx_tables(Path(xlsx_path))
data = from_xlsx_tables(tables, year) # type: ignore[arg-type]
summary = {
"incidence": list(data.incidence.columns),
"mortality": list(data.mortality.columns),
"prevalence5y": list(data.prevalence5y.columns),
"sexual_debut": list(data.sexual_debut.columns),
"hpv_distribution": list(data.hpv_distribution.columns),
"disability_weights": list(data.disability_weights.columns),
"population": list(data.population.columns),
"unwpp_nqx": list(data.unwpp_nqx.columns),
}
typer.echo(json.dumps({k: len(v) for k, v in summary.items()}, indent=2))
@app.command()
def data_build_xlsx_from_repo(base_dir: str = typer.Argument(...), year: str = typer.Argument(...), out: str = typer.Argument(...)) -> None:
"""Build a consolidated .xlsx from the repo's .rda data files for a dataset year."""
build_xlsx_from_repo(Path(base_dir) / "data", year, Path(out))
typer.echo(f"Wrote {out}")
@app.command()
def data_country_xlsx(
base_dir: str = typer.Argument(...),
year: str = typer.Argument(...),
iso3: str = typer.Argument(...),
) -> None:
"""Create a country-only workbook (e.g., TUR) for the given dataset year.
Writes data/globocan_{year}_{iso3}.xlsx and refreshes the registry so it is preferred.
"""
path = build_country_only_workbook(Path(base_dir), year, iso3)
typer.echo(f"Wrote {path}")
@app.command()
def demo_run(
base_dir: str = typer.Argument(...),
country: str = typer.Argument(...),
dataset_year: str = typer.Argument(...),
age_vaccination: int = typer.Argument(...),
current_year: int = typer.Argument(...),
oldest_year: int = typer.Argument(...),
next_n_years: int = typer.Argument(...),
coverage: float = typer.Argument(...),
out_dir: str = typer.Argument(...),
vaccine: str = typer.Option("4vHPV"),
) -> None:
params = DemoParams(
country_iso3=country,
dataset_year=dataset_year,
vaccine=vaccine, # type: ignore[arg-type]
age_vaccination=age_vaccination,
current_year=current_year,
oldest_year=oldest_year,
next_n_years=next_n_years,
coverage_vac=coverage,
)
run_demo_and_export(Path(base_dir), params, Path(out_dir))
typer.echo("Demo intermediates exported (python)")
@app.command()
def demo_compare(r_dir: str = typer.Argument(...), p_dir: str = typer.Argument(...)) -> None:
diffs = compare_intermediates(Path(r_dir), Path(p_dir))
typer.echo(json.dumps(diffs, indent=2))
@app.command()
def psa_run(
size: int = typer.Argument(...),
seed: int = typer.Option(1),
) -> None:
# Example PSA over two parameters with beta distributions
dists = {
"incidence_ratio": ParameterDist(inv_cdf=lambda u: sp_beta(a=2, b=5).ppf(u)),
"mortality_ratio": ParameterDist(inv_cdf=lambda u: sp_beta(a=2, b=5).ppf(u)),
}
def simulate(params: dict) -> dict:
# placeholder output; wire into country simulation later
return {"outcome": float(params["incidence_ratio"] * 1000.0)}
results = run_psa(LHSSpec(size=size, dims=len(dists), seed=seed), dists, simulate)
typer.echo(json.dumps(results[:5], indent=2))