PCSkinAndBlood#
Index#
Let’s first import some packages:
[1]:
import os
import inspect
import shutil
import json
import torch
import pandas as pd
import pyaging as pya
Instantiate model class#
[2]:
def print_entire_class(cls):
source = inspect.getsource(cls)
print(source)
print_entire_class(pya.models.PCSkinAndBlood)
class PCSkinAndBlood(pyagingModel):
def __init__(self):
super().__init__()
def preprocess(self, x):
return x
def postprocess(self, x):
"""
Applies an anti-logarithmic linear transformation to a PyTorch tensor.
"""
adult_age = 20
# Create a mask for negative and non-negative values
mask_negative = x < 0
mask_non_negative = ~mask_negative
# Initialize the result tensor
age_tensor = torch.empty_like(x)
# Exponential transformation for negative values
age_tensor[mask_negative] = (1 + adult_age) * torch.exp(x[mask_negative]) - 1
# Linear transformation for non-negative values
age_tensor[mask_non_negative] = (1 + adult_age) * x[
mask_non_negative
] + adult_age
return age_tensor
[3]:
model = pya.models.PCSkinAndBlood()
Define clock metadata#
[4]:
model.metadata["clock_name"] = 'pcskinandblood'
model.metadata["data_type"] = 'methylation'
model.metadata["species"] = 'Homo sapiens'
model.metadata["year"] = 2022
model.metadata["approved_by_author"] = '⌛'
model.metadata["citation"] = "Higgins-Chen, Albert T., et al. \"A computational solution for bolstering reliability of epigenetic clocks: Implications for clinical trials and longitudinal tracking.\" Nature aging 2.7 (2022): 644-661."
model.metadata["doi"] = "https://doi.org/10.1038/s43587-022-00248-2"
model.metadata["research_only"] = None
model.metadata["notes"] = None
Download clock dependencies#
[5]:
#download PCClock Rdata file from https://yale.app.box.com/s/kq0b0a7lxckxjvaz7x5n4keaug7tewry
logger = pya.logger.Logger()
url = "https://pyaging.s3.amazonaws.com/supporting_files/CalcAllPCClocks.RData"
dir = "."
pya.utils.download(url, dir, logger, indent_level=1)
|-----------> Downloading data to ./CalcAllPCClocks.RData
|-----------> in progress: 100.0000%
Download from R package#
[6]:
%%writefile download.r
library(dplyr)
library(tibble)
library(tidyr)
library(jsonlite)
load(file = "CalcAllPCClocks.RData")
print(ls(all.names = TRUE))
write_json(CalcPCHorvath2, "CalcPCHorvath2.json", digits = 10)
write_json(CpGs, "PCHorvath2CpGs.json")
write_json(imputeMissingCpGs, "PCHorvath2ReferenceCpGBetas.json", digits = 10)
Writing download.r
[7]:
os.system("Rscript download.r")
[7]:
0
Load features#
From JSON file#
[8]:
with open('PCHorvath2CpGs.json', 'r') as f:
model.features = json.load(f)
Load weights into base model#
From JSON file#
[9]:
with open('CalcPCHorvath2.json', 'r') as f:
weights_dict = json.load(f)
weights = torch.tensor(weights_dict['model']).unsqueeze(0).float()
intercept = torch.tensor(weights_dict['intercept']).float()
center = torch.tensor(weights_dict['center']).float()
rotation = torch.tensor(weights_dict['rotation']).float()
PC linear model#
[10]:
base_model = pya.models.PCLinearModel(input_dim=len(model.features), pc_dim=rotation.shape[1])
base_model.center.data = center.float()
base_model.rotation.data = rotation.float()
base_model.linear.weight.data = weights.float()
base_model.linear.bias.data = intercept.float()
model.base_model = base_model
Load reference values#
From JSON file#
[11]:
with open('PCHorvath2ReferenceCpGBetas.json', 'r') as f:
reference_feature_values = json.load(f)
model.reference_values = reference_feature_values
Load preprocess and postprocess objects#
[12]:
model.preprocess_name = None
model.preprocess_dependencies = None
[13]:
model.postprocess_name = 'anti_log_linear'
model.postprocess_dependencies = None
Check all clock parameters#
[14]:
pya.utils.print_model_details(model)
%==================================== Model Details ====================================%
Model Attributes:
training: True
metadata: {'approved_by_author': '⌛',
'citation': 'Higgins-Chen, Albert T., et al. "A computational solution for '
'bolstering reliability of epigenetic clocks: Implications for '
'clinical trials and longitudinal tracking." Nature aging 2.7 '
'(2022): 644-661.',
'clock_name': 'pcskinandblood',
'data_type': 'methylation',
'doi': 'https://doi.org/10.1038/s43587-022-00248-2',
'notes': None,
'research_only': None,
'species': 'Homo sapiens',
'version': None,
'year': 2022}
reference_values: [0.82635363384, 0.18898814441, 0.72938889209, 0.8680421375, 0.090353927561, 0.0066895021761, 0.48924643338, 0.87262052546, 0.87955373232, 0.04847264273, 0.0093070979947, 0.16393676218, 0.058440936082, 0.18857484916, 0.58239394253, 0.86564960457, 0.58457176982, 0.82903550669, 0.065646928047, 0.8500055061, 0.79155429878, 0.83499889314, 0.7754384128, 0.0039641831799, 0.50570339787, 0.60547040884, 0.29093154314, 0.88154845595, 0.46844171936, 0.79205361021]... [Total elements: 78464]
preprocess_name: None
preprocess_dependencies: None
postprocess_name: 'anti_log_linear'
postprocess_dependencies: None
features: ['cg00000292', 'cg00000714', 'cg00001099', 'cg00001446', 'cg00001747', 'cg00002116', 'cg00002224', 'cg00002426', 'cg00002646', 'cg00002660', 'cg00002719', 'cg00002810', 'cg00003091', 'cg00003287', 'cg00003345', 'cg00003529', 'cg00003578', 'cg00003625', 'cg00003994', 'cg00004429', 'cg00004608', 'cg00004806', 'cg00005072', 'cg00005306', 'cg00005619', 'cg00005849', 'cg00006081', 'cg00006459', 'cg00007076', 'cg00007221']... [Total elements: 78464]
base_model_features: None
%==================================== Model Details ====================================%
Model Structure:
base_model: PCLinearModel(
(linear): Linear(in_features=139, out_features=1, bias=True)
)
%==================================== Model Details ====================================%
Model Parameters and Weights:
base_model.center: [0.6989603042602539, 0.15956708788871765, 0.6852545738220215, 0.8436605334281921, 0.06963495165109634, 0.022423643618822098, 0.3099723756313324, 0.5627376437187195, 0.8343909382820129, 0.08058885484933853, 0.039684172719717026, 0.1338687390089035, 0.07226327806711197, 0.17344607412815094, 0.4125054180622101, 0.6524730920791626, 0.6432204246520996, 0.7295728921890259, 0.08485441654920578, 0.8147767782211304, 0.7249654531478882, 0.8113170266151428, 0.8138924241065979, 0.02371947653591633, 0.6228847503662109, 0.5994234085083008, 0.27681541442871094, 0.6650522947311401, 0.3386619985103607, 0.47046491503715515]... [Tensor of shape torch.Size([78464])]
base_model.rotation: [-0.004212469328194857, -0.0018427305622026324, -0.00342817441560328, -0.0019621967803686857, -0.0038084788247942924, -0.001714007230475545, 0.0009071855456568301, 0.0009312129113823175, 0.0005078349495306611, 0.0013207424199208617, 0.004016305319964886, -0.0008206570637412369, 0.002955526579171419, 0.0009135246509686112, -0.003197634592652321, 0.00868172850459814, -0.011338912881910801, 0.006802823860198259, -0.006287768483161926, -0.00478862039744854, 0.001487976755015552, -0.008474800735712051, 0.005175075959414244, -0.002744645345956087, -0.006363819353282452, 0.0027778574731200933, -0.007200028281658888, 0.003951014950871468, 0.0025292737409472466, -0.0006783857243135571]... [Tensor of shape torch.Size([78464, 139])]
base_model.linear.weight: [-0.008271735161542892, 0.026615887880325317, 0.06532493233680725, 0.03855971246957779, 0.10452642291784286, -0.24639244377613068, 0.0814928412437439, -0.06538811326026917, 0.029210954904556274, -0.001272108987905085, 0.016053402796387672, 0.08029855042695999, -0.012919272296130657, -0.06098422035574913, 0.028758035972714424, -0.12004351615905762, -0.020917272195219994, -0.04205343499779701, 0.029078252613544464, -0.01387680321931839, 0.06542300432920456, -0.03968583419919014, 0.002720639808103442, -0.0522029809653759, 0.002719870302826166, 0.013684911653399467, 0.014434539712965488, -0.0017883781110867858, -0.07386524230241776, -0.02207360416650772]... [Tensor of shape torch.Size([1, 139])]
base_model.linear.bias: tensor([0.4743])
%==================================== Model Details ====================================%
Basic test#
[15]:
torch.manual_seed(42)
input = torch.randn(10, len(model.features), dtype=float)
model.eval()
model.to(float)
pred = model(input)
pred
[15]:
tensor([[8.7096],
[4.7385],
[4.5074],
[1.4422],
[2.7803],
[0.5132],
[0.3571],
[1.6538],
[9.6653],
[3.8396]], dtype=torch.float64, grad_fn=<IndexPutBackward0>)
Save torch model#
[16]:
torch.save(model, f"../weights/{model.metadata['clock_name']}.pt")
Clear directory#
[17]:
# 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: PCHorvath2ReferenceCpGBetas.json
Deleted file: CalcAllPCClocks.RData
Deleted file: PCHorvath2CpGs.json
Deleted file: download.r
Deleted file: CalcPCHorvath2.json