Metadata-Version: 2.4
Name: agingclockbench
Version: 0.2.1
Summary: Benchmark biological aging clocks on your data — PhenoAge, KDM, DunedinPACE proxy
License: MIT
License-File: LICENSE
Keywords: aging,biomarkers,aging-clocks,longevity,biological-age,phenoage,kdm,nhanes,mortality
Author: Aaditya Geddam
Author-email: aaditya.geddam@gmail.com
Requires-Python: >=3.11,<4.0
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
Requires-Dist: altair (>=5.0.0)
Requires-Dist: click (>=8.1.0)
Requires-Dist: lifelines (>=0.28.0)
Requires-Dist: matplotlib (>=3.8.0)
Requires-Dist: numpy (>=1.26.0)
Requires-Dist: pandas (>=2.2.0)
Requires-Dist: plotly (>=5.17.0)
Requires-Dist: pyarrow (>=13.0.0)
Requires-Dist: pydantic (>=2.3.0)
Requires-Dist: scipy (>=1.13.0)
Requires-Dist: seaborn (>=0.13.0)
Project-URL: Documentation, https://github.com/aadityageddam-ux/aging_clock_bench#quick-start
Project-URL: Homepage, https://github.com/aadityageddam-ux/aging_clock_bench
Project-URL: Repository, https://github.com/aadityageddam-ux/aging_clock_bench
Description-Content-Type: text/markdown

# AgingClockBench

[![PyPI version](https://badge.fury.io/py/agingclockbench.svg)](https://badge.fury.io/py/agingclockbench)
[![Tests](https://github.com/aadityageddam-ux/aging_clock_bench/actions/workflows/test.yml/badge.svg)](https://github.com/aadityageddam-ux/aging_clock_bench/actions/workflows/test.yml)
[![Coverage](https://img.shields.io/badge/coverage-89%25-brightgreen)](https://github.com/aadityageddam-ux/aging_clock_bench)
[![Docs](https://img.shields.io/badge/docs-README-blue)](https://github.com/aadityageddam-ux/aging_clock_bench#quick-start)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue)](https://www.python.org/downloads/)

**Benchmark biological aging clocks on your data in minutes.**

Multiple biological aging clocks exist — PhenoAge, KDM, DunedinPACE — but no standard tool lets researchers compare them side-by-side. AgingClockBench is the **first open-source Python package** implementing multiple clocks with a unified interface and reproducible mortality-validated benchmarking.

📖 **[Documentation & Examples](#quick-start)**

---

## Install

```bash
pip install agingclockbench
```

Requires Python 3.11+.

---

## Quick Start

```python
from agingclockbench import PhenoAge, KDM, BenchmarkSuite
from agingclockbench.datasets import load_nhanes_sample

# Load bundled NHANES 1999-2000 (N=4,086, 20-year mortality follow-up)
df = load_nhanes_sample()

# Compute biological ages
results = {
    "PhenoAge": PhenoAge().transform(df),
    "KDM":      KDM().transform(df),
}

# Benchmark against mortality
suite = BenchmarkSuite(mortality_col="mortstat", followup_col="permth_exm")
report = suite.run(df, results)

print(report.to_dataframe())
```

```
Clock     Pearson r  Mort HR (per SD accel)  Mort p-value
PhenoAge      0.930                    1.83      0.000001
KDM           0.677                    1.41      0.000001
```

```python
report.plot_km_survival()      # Kaplan-Meier by acceleration quartile
report.plot_comparison()       # biological age vs chronological age
report.to_html("report.html")  # interactive Plotly report
```

---

## CLI

```bash
# Benchmark on bundled NHANES with HTML report
agingclockbench benchmark --data bundled --clocks all --report

# Your own data
agingclockbench benchmark \
  --data my_cohort.csv \
  --clocks PhenoAge KDM \
  --mortality-col vital_status \
  --followup-col followup_months \
  --output ./results/
```

---

## Implemented Clocks

| Clock | Reference | Biomarkers | Key metric (NHANES) |
|-------|-----------|-----------|---------------------|
| **PhenoAge** | Levine et al. 2018 *Aging Cell* | 9 blood | Pearson r=0.93, HR=1.83 |
| **KDM** | Klemera & Doubal 2006 *Mech Ageing Dev* | 8 blood | Pearson r=0.68, HR=1.41 |
| **DunedinPACEProxy** | Proxy (NOT Belsky 2022) | 7 blood | pace corr w/ PhenoAge accel r=0.84 |

> **Note:** DunedinPACEProxy is a blood-biomarker approximation. The real DunedinPACE requires DNA methylation data (Illumina EPIC array).

---

## Features

- ✅ **Unified interface** — all clocks share the same `transform()` API
- ✅ **Validated** — PhenoAge implementation cross-validated against reference; zero numerical difference on N=4,086 NHANES participants  
- ✅ **Mortality benchmarking** — Cox PH hazard ratios, Kaplan-Meier curves
- ✅ **Bundled data** — NHANES 1999-2000 with 20-year mortality follow-up, ready to use
- ✅ **Interactive reports** — Plotly HTML with comparison plots and benchmark table
- ✅ **CLI tool** — `agingclockbench benchmark` works out of the box
- ✅ **89% test coverage** — 91 tests, CI/CD on every push

---

## FAQ

**How do I add a new clock?**

Implement the `BaseClock` interface in a new file under `src/agingclockbench/clocks/`. See [CONTRIBUTING.md](https://github.com/aadityageddam-ux/aging_clock_bench/blob/main/CONTRIBUTING.md) for step-by-step instructions and [BaseClock source](https://github.com/aadityageddam-ux/aging_clock_bench/blob/main/src/agingclockbench/clocks/base.py).

**What's the difference between PhenoAge, KDM, and DunedinPACEProxy?**

| Clock | Biomarkers | Key Metric | Use Case |
|-------|-----------|-----------|----------|
| **PhenoAge** | 9 blood | HR=1.83 per 10yr accel | Best mortality prediction; recommended for research |
| **KDM** | 8 blood | HR=1.41 per 10yr accel | Classical approach; simpler model |
| **DunedinPACEProxy** | 7 blood | r=0.84 w/ PhenoAge | Blood-based proxy (real DunedinPACE requires DNA methylation) |

**Can I use my own data?**

Yes! Pass any pandas DataFrame with the required biomarker columns:

```python
import pandas as pd
from agingclockbench import PhenoAge

df = pd.read_csv("my_cohort.csv")
result = PhenoAge().transform(df)
print(result.biological_ages)
```

**How do I interpret the HTML report?**

The report generated by `report.to_html("report.html")` contains three sections:

1. **Benchmark Table** — Pearson r (correlation), Spearman r, Mortality HR (hazard ratio per 10-year acceleration), and p-value
2. **Bland-Altman Plot** — Shows mean bias and ±95% limits of agreement; tight limits indicate consistent predictions
3. **Kaplan-Meier Survival Curves** — Stratified by clock acceleration quartile; steeper curves indicate stronger mortality association

**What if I get a "missing biomarker" error?**

All 9 biomarkers are required for PhenoAge; 8 for KDM. Check that your DataFrame contains:
- For PhenoAge: `albumin_g_l`, `creatinine_umol_l`, `glucose_mmol_l`, `crp_mg_l`, `lymphocyte_pct`, `mcv_fl`, `rdw_pct`, `alkaline_phosphatase_u_l`, `wbc_10k_ul`
- For KDM: All of the above except `crp_mg_l`

Drop rows with missing values before calling `.transform()`.

---

## Documentation & Learning

**Getting started:** See [Quick Start](#quick-start) above for a minimal working example.

**API reference:**
```python
from agingclockbench import PhenoAge, KDM, BenchmarkSuite
help(PhenoAge)        # View docstring and parameters
help(BenchmarkSuite)  # View benchmarking options
```

**Adding a new clock:** See [CONTRIBUTING.md](https://github.com/aadityageddam-ux/aging_clock_bench/blob/main/CONTRIBUTING.md) for step-by-step instructions.

**Example notebooks:** See [examples/](https://github.com/aadityageddam-ux/aging_clock_bench/tree/main/examples) for Jupyter notebooks.

---

## Citation

If you use AgingClockBench in your research, please cite:

```bibtex
@software{geddam2026agingclockbench,
  author = {Geddam, Aaditya},
  title  = {AgingClockBench: Benchmarking biological aging clocks},
  url    = {https://github.com/aadityageddam-ux/aging_clock_bench},
  year   = {2026}
}
```

**Also cite the underlying clock papers:**

- Levine ME, et al. *Aging Cell.* 2018. (PhenoAge)
- Klemera P, Doubal S. *Mech Ageing Dev.* 2006. (KDM)

---

## Contributing

Contributions welcome! See [CONTRIBUTING.md](https://github.com/aadityageddam-ux/aging_clock_bench/blob/main/CONTRIBUTING.md).

To add a new clock, implement the `BaseClock` interface — see the [FAQ](#faq) section above.

---

## License

MIT © Aaditya Geddam

