Skip to main content

AgingClockBench

PyPI version Tests Coverage Docs License: MIT Python 3.11+

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


Install

pip install agingclockbench

Requires Python 3.11+.


Quick Start

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
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

# 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 for step-by-step instructions and BaseClock source.

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:

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 above for a minimal working example.

API reference:

from agingclockbench import PhenoAge, KDM, BenchmarkSuite
help(PhenoAge)        # View docstring and parameters
help(BenchmarkSuite)  # View benchmarking options

Adding a new clock: See CONTRIBUTING.md for step-by-step instructions.

Example notebooks: See examples/ for Jupyter notebooks.


Citation

If you use AgingClockBench in your research, please cite:

@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.

To add a new clock, implement the BaseClock interface — see the FAQ section above.


License

MIT © Aaditya Geddam

Metadata

Release files for agingclockbench 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for agingclockbench 0.2.1
File Size Uploaded Provenance
agingclockbench-0.2.1.tar.gz 90.5 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for agingclockbench 0.2.1
File Interpreter ABI Platform
agingclockbench-0.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 186.4 kB

Release files / agingclockbench-0.2.1.tar.gz

Download URL agingclockbench-0.2.1.tar.gz
Size 90.5 kB
Tags Source
SHA-256 checksum
How to use checksums
44cbbd50aea00e1579b7d8e4a5345f6fcc9cf76f1981ea990c9171660ff560bd
BLAKE2b-256 checksum
How to use checksums
6c509ac5822666c762987f15ff8015d1325724fb1ac78945efb60b941a46d935
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.4.1 CPython/3.11.15 Linux/6.17.0-1018-azure

Release files / agingclockbench-0.2.1-py3-none-any.whl

Download URL agingclockbench-0.2.1-py3-none-any.whl
Size 95.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e8151e27091bf6278e0e7e63598b1fd15261526cce4226c8d7d5bada6d544681
BLAKE2b-256 checksum
How to use checksums
6a4736e2e5f0542ea6e088839a1aa3151fa6035f36e62f9544bef9cfe9d19bd5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.4.1 CPython/3.11.15 Linux/6.17.0-1018-azure

Security for agingclockbench 0.2.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page