|
| 1 | +# Vitals |
| 2 | + |
| 3 | +[![PyPI Version][pypi-image]][pypi-url] |
| 4 | +[![Build Status][build-image]][build-url] |
| 5 | + |
| 6 | +<!-- Badges --> |
| 7 | + |
| 8 | +[pypi-image]: https://img.shields.io/pypi/v/python-phenoage |
| 9 | +[pypi-url]: https://pypi.org/project/python-phenoage/ |
| 10 | +[build-image]: https://github.com/fbraza/vitals/actions/workflows/ci.yml/badge.svg |
| 11 | +[build-url]: https://github.com/fbraza/vitals/blob/master/.github/workflows/ci.yml |
| 12 | + |
| 13 | +## Functionality |
| 14 | + |
| 15 | +`Vitals` is a Python library that implements biomarker algorithms for health assessment, including biological age calculation and cardiovascular disease risk prediction. The library provides robust implementations of scientifically validated algorithms with comprehensive data validation and error handling. |
| 16 | + |
| 17 | +## Setup |
| 18 | + |
| 19 | +To install the package run the following command: |
| 20 | + |
| 21 | +```bash |
| 22 | +pip install python-phenoage |
| 23 | +``` |
| 24 | + |
| 25 | +For development, this project uses UV for dependency management: |
| 26 | + |
| 27 | +```bash |
| 28 | +# Clone the repository |
| 29 | +git clone https://github.com/fbraza/vitals.git |
| 30 | +cd vitals |
| 31 | + |
| 32 | +# Install dependencies |
| 33 | +uv sync |
| 34 | +``` |
| 35 | + |
| 36 | +Once installed, import the algorithms you need: |
| 37 | + |
| 38 | +```python |
| 39 | +from vitals.models.phenoage import compute |
| 40 | +from vitals.models.score2 import compute |
| 41 | +from vitals.models.score2_diabetes import compute |
| 42 | +``` |
| 43 | + |
| 44 | +## Usage |
| 45 | + |
| 46 | +### PhenoAge |
| 47 | + |
| 48 | +Biological age calculation using Levine's PhenoAge algorithm. This algorithm estimates biological aging based on 10 biomarkers and chronological age. |
| 49 | + |
| 50 | +**Required biomarkers:** |
| 51 | +- Albumin (g/dL or g/L) |
| 52 | +- Creatinine (mg/dL or ¼mol/L) |
| 53 | +- Glucose (mg/dL or mmol/L) |
| 54 | +- C-reactive protein (mg/L or mg/dL) |
| 55 | +- Lymphocyte percentage (%) |
| 56 | +- Mean cell volume (fL) |
| 57 | +- Red cell distribution width (%) |
| 58 | +- Alkaline phosphatase (U/L) |
| 59 | +- White blood cell count (10³/¼L or 10y/L) |
| 60 | +- Age (years) |
| 61 | + |
| 62 | +```python |
| 63 | +from vitals.models.phenoage import compute |
| 64 | + |
| 65 | +# Example biomarker data |
| 66 | +biomarkers = { |
| 67 | + "albumin": 4.2, |
| 68 | + "creatinine": 0.9, |
| 69 | + "glucose": 95, |
| 70 | + "c_reactive_protein": 1.5, |
| 71 | + "lymphocyte_percent": 25, |
| 72 | + "mean_cell_volume": 88, |
| 73 | + "red_cell_distribution_width": 13.2, |
| 74 | + "alkaline_phosphatase": 75, |
| 75 | + "white_blood_cell_count": 6.5, |
| 76 | + "age": 45 |
| 77 | +} |
| 78 | + |
| 79 | +result = compute(biomarkers) |
| 80 | +print(f"Chronological Age: {result.age}") |
| 81 | +print(f"Predicted Age: {result.predicted_age:.1f}") |
| 82 | +print(f"Accelerated Aging: {result.accelerated_aging:.1f}") |
| 83 | +``` |
| 84 | + |
| 85 | +### SCORE2 |
| 86 | + |
| 87 | +10-year cardiovascular disease risk assessment for non-diabetic European patients aged 40-69 years. |
| 88 | + |
| 89 | +**Required parameters:** |
| 90 | +- Age (40-69 years) |
| 91 | +- Sex (male/female) |
| 92 | +- Systolic blood pressure (mmHg) |
| 93 | +- Total cholesterol (mg/dL or mmol/L) |
| 94 | +- HDL cholesterol (mg/dL or mmol/L) |
| 95 | +- Smoking status (boolean) |
| 96 | + |
| 97 | +```python |
| 98 | +from vitals.models.score2 import compute |
| 99 | + |
| 100 | +# Example patient data |
| 101 | +biomarkers = { |
| 102 | + "age": 55, |
| 103 | + "sex": "male", |
| 104 | + "systolic_bp": 140, |
| 105 | + "total_cholesterol": 220, |
| 106 | + "hdl_cholesterol": 45, |
| 107 | + "smoking": True |
| 108 | +} |
| 109 | + |
| 110 | +result = compute(biomarkers) |
| 111 | +print(f"Age: {result.age}") |
| 112 | +print(f"CVD Risk: {result.risk_percentage:.1f}%") |
| 113 | +print(f"Risk Category: {result.risk_category}") |
| 114 | +``` |
| 115 | + |
| 116 | +### SCORE2-Diabetes |
| 117 | + |
| 118 | +CVD risk assessment for diabetic patients, including diabetes-specific risk factors. |
| 119 | + |
| 120 | +**Additional parameters for diabetic patients:** |
| 121 | +- Diabetes status (boolean) |
| 122 | +- Age at diabetes diagnosis (years) |
| 123 | +- HbA1c (% or mmol/mol) |
| 124 | +- Estimated glomerular filtration rate (mL/min/1.73m²) |
| 125 | + |
| 126 | +```python |
| 127 | +from vitals.models.score2_diabetes import compute |
| 128 | + |
| 129 | +# Example diabetic patient data |
| 130 | +biomarkers = { |
| 131 | + "age": 60, |
| 132 | + "sex": "female", |
| 133 | + "systolic_bp": 135, |
| 134 | + "total_cholesterol": 200, |
| 135 | + "hdl_cholesterol": 50, |
| 136 | + "smoking": False, |
| 137 | + "diabetes": True, |
| 138 | + "age_diagnosis_diabetes": 45, |
| 139 | + "hba1c": 7.2, |
| 140 | + "egfr": 75 |
| 141 | +} |
| 142 | + |
| 143 | +result = compute(biomarkers) |
| 144 | +print(f"Age: {result.age}") |
| 145 | +print(f"CVD Risk: {result.risk_percentage:.1f}%") |
| 146 | +print(f"Risk Category: {result.risk_category}") |
| 147 | +``` |
| 148 | + |
| 149 | +### Working with JSON Data |
| 150 | + |
| 151 | +The library can extract biomarkers from structured JSON files: |
| 152 | + |
| 153 | +```python |
| 154 | +from vitals.biomarkers.helpers import extract_biomarkers_from_json |
| 155 | +from vitals.models.phenoage import compute |
| 156 | + |
| 157 | +# Load biomarkers from JSON file |
| 158 | +with open("patient_data.json", "r") as f: |
| 159 | + json_data = json.load(f) |
| 160 | + |
| 161 | +biomarkers = extract_biomarkers_from_json(json_data, target_biomarkers=[ |
| 162 | + "albumin", "creatinine", "glucose", "c_reactive_protein", |
| 163 | + "lymphocyte_percent", "mean_cell_volume", "red_cell_distribution_width", |
| 164 | + "alkaline_phosphatase", "white_blood_cell_count", "age" |
| 165 | +]) |
| 166 | + |
| 167 | +result = compute(biomarkers) |
| 168 | +``` |
| 169 | + |
| 170 | +## Features |
| 171 | + |
| 172 | +- **Robust Data Validation**: Uses Pydantic for comprehensive input validation |
| 173 | +- **Automatic Unit Conversion**: Handles multiple unit formats automatically |
| 174 | +- **Scientific Accuracy**: Implements peer-reviewed algorithms with proper calibrations |
| 175 | +- **Type Safety**: Full type hints and mypy compliance |
| 176 | +- **Comprehensive Testing**: Extensive test suite with known reference values |
| 177 | +- **Error Handling**: Clear error messages for invalid inputs or missing biomarkers |
| 178 | + |
| 179 | +## Algorithms Implemented |
| 180 | + |
| 181 | +### PhenoAge (Levine et al., 2018) |
| 182 | +Biological age estimation based on 10 clinical biomarkers. The algorithm was developed using NHANES data and validated across multiple cohorts. |
| 183 | + |
| 184 | +**Reference:** Levine, M.E. et al. An epigenetic biomarker of aging for lifespan and healthspan. Aging (2018). |
| 185 | + |
| 186 | +### SCORE2 (European Society of Cardiology, 2021) |
| 187 | +Updated cardiovascular risk prediction algorithm for European populations, calibrated for different risk regions. |
| 188 | + |
| 189 | +**Reference:** SCORE2 working group. SCORE2 risk prediction algorithms. European Heart Journal (2021). |
| 190 | + |
| 191 | +### SCORE2-Diabetes (European Society of Cardiology, 2023) |
| 192 | +Diabetes-specific cardiovascular risk assessment incorporating diabetes duration, glycemic control, and kidney function. |
| 193 | + |
| 194 | +**Reference:** SCORE2-Diabetes working group. European Heart Journal (2023). |
| 195 | + |
| 196 | +## For Developers |
| 197 | + |
| 198 | +Clone the repository and set up the development environment: |
| 199 | + |
| 200 | +```bash |
| 201 | +git clone https://github.com/fbraza/vitals.git |
| 202 | +cd vitals |
| 203 | + |
| 204 | +# Install dependencies and pre-commit hooks |
| 205 | +make install |
| 206 | + |
| 207 | +# Run tests |
| 208 | +make test |
| 209 | + |
| 210 | +# Run linting |
| 211 | +make lint |
| 212 | +``` |
| 213 | + |
| 214 | +The project uses: |
| 215 | +- **UV** for dependency management |
| 216 | +- **pytest** for testing with coverage reporting |
| 217 | +- **pre-commit** hooks for code quality |
| 218 | +- **black** for code formatting |
| 219 | +- **mypy** for type checking |
| 220 | + |
| 221 | +All contributions are welcome! Please ensure tests pass and follow the coding guidelines in `specs/coding_style.md`. |
| 222 | + |
| 223 | +## Author |
| 224 | + |
| 225 | +Faouzi Braza |
0 commit comments