EnsembleAgeStaticTop#
Index#
Let’s first import some packages:
[16]:
import os
import inspect
import shutil
import json
import torch
import pandas as pd
import pyaging as pya
Instantiate model class#
[17]:
def print_entire_class(cls):
source = inspect.getsource(cls)
print(source)
print_entire_class(pya.models.EnsembleAgeStaticTop)
class EnsembleAgeStaticTop(pyagingModel):
def __init__(self):
super().__init__()
def preprocess(self, x):
return x
def postprocess(self, x):
return x
[18]:
model = pya.models.EnsembleAgeStaticTop()
Define clock metadata#
[19]:
model.metadata["clock_name"] = 'ensembleagestatictop'
model.metadata["data_type"] = 'methylation'
model.metadata["species"] = 'Mus musculus'
model.metadata["year"] = 2025
model.metadata["approved_by_author"] = '⌛'
model.metadata["citation"] = "Haghani, A., Lu, A.T., Yan, Q. et al. EnsembleAge: enhancing epigenetic age assessment with a multi-clock framework. GeroScience (2025)"
model.metadata["doi"] = 'https://doi.org/10.1007/s11357-025-01808-1'
model.metadata["research_only"] = None
model.metadata["notes"] = None
Download clock dependencies#
Download directly with curl#
[20]:
supplementary_url = "https://static-content.springer.com/esm/art%3A10.1007%2Fs11357-025-01808-1/MediaObjects/11357_2025_1808_MOESM1_ESM.xlsx"
supplementary_file_name = "coefficients.xlsx"
os.system(f"curl -o {supplementary_file_name} {supplementary_url}")
[20]:
0
Load features#
From Excel file#
[21]:
df = pd.read_excel('coefficients.xlsx', sheet_name='Table S3. Ensemble.Static')
df = df[df['EnsembleAge.Static.Top_ElasticNoAgeTraf'] != 0]
model.features = df['CGid'][1:].tolist()
Load weights into base model#
[22]:
weights = torch.tensor(df['EnsembleAge.Static.Top_ElasticNoAgeTraf'][1:].tolist()).unsqueeze(0).float()
intercept = torch.tensor([df['EnsembleAge.Static.Top_ElasticNoAgeTraf'][0]]).float()
Linear model#
[23]:
base_model = pya.models.LinearModel(input_dim=len(model.features))
base_model.linear.weight.data = weights.float()
base_model.linear.bias.data = intercept.float()
model.base_model = base_model
Load reference values#
[24]:
model.reference_values = None
Load preprocess and postprocess objects#
[25]:
model.preprocess_name = None
model.preprocess_dependencies = None
[26]:
model.postprocess_name = None
model.postprocess_dependencies = None
Check all clock parameters#
[27]:
pya.utils.print_model_details(model)
%==================================== Model Details ====================================%
Model Attributes:
training: True
metadata: {'approved_by_author': '⌛',
'citation': 'Haghani, A., Lu, A.T., Yan, Q. et al. EnsembleAge: enhancing '
'epigenetic age assessment with a multi-clock framework. '
'GeroScience (2025)',
'clock_name': 'ensembleagestatictop',
'data_type': 'methylation',
'doi': 'https://doi.org/10.1007/s11357-025-01808-1',
'notes': None,
'research_only': None,
'species': 'Mus musculus',
'version': None,
'year': 2025}
reference_values: None
preprocess_name: None
preprocess_dependencies: None
postprocess_name: None
postprocess_dependencies: None
features: ['cg00045149', 'cg00091964', 'cg00117955', 'cg00158333', 'cg00181698', 'cg00243488', 'cg00258262', 'cg00259292', 'cg00407148', 'cg00409684', 'cg00493887', 'cg00553880', 'cg00578937', 'cg00659065', 'cg00896209', 'cg00929113', 'cg00946032', 'cg00957561', 'cg01024113', 'cg01039540', 'cg01061575', 'cg01099625', 'cg01134518', 'cg01149078', 'cg01294450', 'cg01473155', 'cg01486146', 'cg01553138', 'cg01621100', 'cg01657263']... [Total elements: 431]
base_model_features: None
%==================================== Model Details ====================================%
Model Structure:
base_model: LinearModel(
(linear): Linear(in_features=431, out_features=1, bias=True)
)
%==================================== Model Details ====================================%
Model Parameters and Weights:
base_model.linear.weight: [0.1743975728750229, -0.04364413395524025, 0.22944891452789307, 0.2686740756034851, 0.01912594959139824, -0.09232170134782791, 0.11978655308485031, -0.0801130011677742, 0.5056779384613037, 0.1736055165529251, -0.473909854888916, -0.20611447095870972, 1.324728012084961, -0.05422835797071457, -0.2410501092672348, -0.42427003383636475, -0.39920952916145325, -0.20043838024139404, -0.008536707609891891, -0.09825412929058075, 0.16520655155181885, 0.012782384641468525, 0.01064230501651764, -0.1301790326833725, -0.6252124309539795, -0.0008419872610829771, 0.10042154788970947, -0.013664733618497849, 0.16023848950862885, 0.023345399647951126]... [Tensor of shape torch.Size([1, 431])]
base_model.linear.bias: tensor([5.7927])
%==================================== Model Details ====================================%
Basic test#
[28]:
torch.manual_seed(42)
input = torch.randn(10, len(model.features), dtype=float)
model.eval()
model.to(float)
pred = model(input)
pred
[28]:
tensor([[ -9.4919],
[ -4.8999],
[-11.6078],
[ 5.9647],
[ 23.9748],
[ 3.0499],
[-12.5388],
[ 4.6096],
[ 5.1646],
[-10.7823]], dtype=torch.float64, grad_fn=<AddmmBackward0>)
Save torch model#
[29]:
torch.save(model, f"../weights/{model.metadata['clock_name']}.pt")
Clear directory#
[30]:
# Function to remove a folder and all its contents
def remove_folder(path):
try:
shutil.rmtree(path)
print(f"Deleted folder: {path}")
except Exception as e:
print(f"Error deleting folder {path}: {e}")
# Get a list of all files and folders in the current directory
all_items = os.listdir('.')
# Loop through the items
for item in all_items:
# Check if it's a file and does not end with .ipynb
if os.path.isfile(item) and not item.endswith('.ipynb'):
os.remove(item)
print(f"Deleted file: {item}")
# Check if it's a folder
elif os.path.isdir(item):
remove_folder(item)
Deleted file: coefficients.xlsx