| |
| """Bootstrap confidence intervals on all key metrics.""" |
| from _common import * |
|
|
| OUT = output_dir("02_bootstrap_ci") |
|
|
|
|
| def bootstrap_halflife(adata, hl_df, n_boot=1000, seed=42): |
| g, h, _ = match_halflife(adata, hl_df) |
| if len(g) < 10: |
| return {"r": np.nan, "ci_lo": np.nan, "ci_hi": np.nan, "se": np.nan, "n": len(g)} |
|
|
| r_point, _ = stats.spearmanr(g, h) |
| rng = np.random.RandomState(seed) |
| rs = np.zeros(n_boot) |
| for i in range(n_boot): |
| idx = rng.choice(len(g), size=len(g), replace=True) |
| rs[i], _ = stats.spearmanr(g[idx], h[idx]) |
|
|
| return { |
| "r": float(r_point), |
| "ci_lo": float(np.percentile(rs, 2.5)), |
| "ci_hi": float(np.percentile(rs, 97.5)), |
| "se": float(np.std(rs)), |
| "n": len(g), |
| } |
|
|
|
|
| def main(): |
| set_figure_style() |
| hl_mouse, hl_human = load_halflife_refs() |
| all_results = {} |
|
|
| for name, loader, _ in DATASETS: |
| print(f"\n{'=' * 60}\n{name.upper()}\n{'=' * 60}") |
| adata_an = run_analytical(loader) |
| results = {} |
| for ref_name, hl_df in [("mouse", hl_mouse), ("human", hl_human)]: |
| r = bootstrap_halflife(adata_an, hl_df) |
| results[ref_name] = r |
| print(f" {ref_name}: r={r['r']:.4f} [{r['ci_lo']:.4f}, {r['ci_hi']:.4f}] (n={r['n']})") |
| all_results[name] = results |
|
|
| save_json(all_results, "bootstrap_ci", OUT) |
|
|
| |
| fig, ax = plt.subplots(figsize=(8, 5)) |
| labels, rs, los, his = [], [], [], [] |
| for name in all_results: |
| for ref in ("mouse", "human"): |
| d = all_results[name][ref] |
| labels.append(f"{name}\n{ref}") |
| rs.append(d["r"]) |
| los.append(d["r"] - d["ci_lo"]) |
| his.append(d["ci_hi"] - d["r"]) |
| ax.barh(range(len(labels)), [-r for r in rs], xerr=[[lo for lo in los], [hi for hi in his]], |
| color="steelblue", alpha=0.7, capsize=4) |
| ax.set_yticks(range(len(labels))) |
| ax.set_yticklabels(labels) |
| ax.set_xlabel("|Spearman r| with half-life (95% CI)") |
| ax.set_title("Half-life correlation with bootstrap CIs") |
| fig.tight_layout() |
| save_fig(fig, "bootstrap_ci", OUT) |
|
|
|
|
| if __name__ == "__main__": |
| main() |
|
|