kcat-km-model / predict.py
RohanSaha2006's picture
ProtT5 + SMILES-T + MACCS + Morgan + GroupKFold ET
5a4fcb6 verified
Raw History Blame Contribute Delete
3.28 kB
import numpy as np
import pandas as pd
import joblib
import argparse
import os
import sys
import torch
from rdkit import Chem
from rdkit.Chem import AllChem, MACCSkeys
BASE = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, BASE)
from build_vocab import WordVocab
from pretrain_trfm import TrfmSeq2seq
from utils import split
cache_data = np.load(os.path.join(BASE, "prott5_cache.npz"), allow_pickle=True)
prott5_cache = cache_data["cache"].item()
scaler = joblib.load(os.path.join(BASE, "scaler.pkl"))
smiles_cache = joblib.load(os.path.join(BASE, "smiles_cache.pkl"))
N_FOLDS = 5
et_kcat_models = [joblib.load(os.path.join(BASE, f"et_kcat_fold{i}.pkl")) for i in range(N_FOLDS)]
et_km_models = [joblib.load(os.path.join(BASE, f"et_km_fold{i}.pkl")) for i in range(N_FOLDS)]
vocab = WordVocab.load_vocab(os.path.join(BASE, "vocab.pkl"))
pad_index = 0; unk_index = 1; eos_index = 2; sos_index = 3
trfm = TrfmSeq2seq(len(vocab), 256, len(vocab), 4)
trfm.load_state_dict(torch.load(os.path.join(BASE, "trfm_12_23000.pkl"), map_location="cpu"))
trfm.eval()
def smiles_to_vec(smiles):
x_split = [split(smiles)]
xid = []
for tokens in x_split:
seq_len = 220
if len(tokens) > 218:
tokens = tokens[:109] + tokens[-109:]
ids = [vocab.stoi.get(t, unk_index) for t in tokens]
ids = [sos_index] + ids + [eos_index]
pad_len = seq_len - len(ids)
ids += [pad_index] * pad_len
xid.append(ids)
xid = torch.tensor(xid).T
with torch.no_grad():
out = trfm.encode(xid)
return np.array(out, dtype=np.float32).squeeze(0)
def get_maccs(smiles):
mol = Chem.MolFromSmiles(smiles)
if mol is None: return np.zeros(167, dtype=np.float32)
return np.array(MACCSkeys.GenMACCSKeys(mol), dtype=np.float32)
def get_morgan_fp(smiles, radius=2, nbits=2048):
mol = Chem.MolFromSmiles(smiles)
if mol is None: return np.zeros(nbits, dtype=np.float32)
fp = AllChem.GetMorganFingerprintAsBitVect(mol, radius, nBits=nbits)
return np.array(fp, dtype=np.float32)
def predict(input_path, output_path):
df = pd.read_parquet(input_path)
rows = []
for _, row in df.iterrows():
prot_emb = prott5_cache.get(row["sequence"], np.zeros(1024, dtype=np.float32))
smiles_emb = smiles_cache.get(row["smiles"])
if smiles_emb is None:
smiles_emb = smiles_to_vec(row["smiles"])
maccs = get_maccs(row["smiles"])
morgan = get_morgan_fp(row["smiles"])
rows.append(np.concatenate([prot_emb, smiles_emb, maccs, morgan]))
X = np.array(rows, dtype=np.float32)
X = scaler.transform(X)
pred_kcat = np.mean([m.predict(X) for m in et_kcat_models], axis=0)
pred_km = np.mean([m.predict(X) for m in et_km_models], axis=0)
out = pd.DataFrame({
"id" : df["id"].values,
"log10_kcat" : pred_kcat,
"log10_km" : pred_km,
})
out.to_csv(output_path, index=False)
print(f"Saved {len(out)} predictions to {output_path}")
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--input", required=True)
parser.add_argument("--output", required=True)
args = parser.parse_args()
predict(args.input, args.output)