MVGNN-PPIS / scripts /process_feature /get_SC_position.py
wuxing0105's picture
Upload folder using huggingface_hub
ad9fbbf verified
Raw
History Blame Contribute Delete
7.83 kB
import numpy as np
import torch
import torch.nn.functional as F
import joblib
import pandas as pd
import os
import subprocess
from pad_feature import parse_fasta_file
def def_atom_features():
A = {'N':[0,1,0], 'CA':[0,1,0], 'C':[0,0,0], 'O':[0,0,0], 'CB':[0,3,0]}
V = {'N':[0,1,0], 'CA':[0,1,0], 'C':[0,0,0], 'O':[0,0,0], 'CB':[0,1,0], 'CG1':[0,3,0], 'CG2':[0,3,0]}
F = {'N': [0, 1, 0], 'CA': [0, 1, 0], 'C': [0, 0, 0], 'O': [0, 0, 0],'CB':[0,2,0],
'CG':[0,0,1], 'CD1':[0,1,1], 'CD2':[0,1,1], 'CE1':[0,1,1], 'CE2':[0,1,1], 'CZ':[0,1,1] }
P = {'N': [0, 0, 1], 'CA': [0, 1, 1], 'C': [0, 0, 0], 'O': [0, 0, 0],'CB':[0,2,1], 'CG':[0,2,1], 'CD':[0,2,1]}
L = {'N': [0, 1, 0], 'CA': [0, 1, 0], 'C': [0, 0, 0], 'O': [0, 0, 0], 'CB':[0,2,0], 'CG':[0,1,0], 'CD1':[0,3,0], 'CD2':[0,3,0]}
I = {'N': [0, 1, 0], 'CA': [0, 1, 0], 'C': [0, 0, 0], 'O': [0, 0, 0], 'CB':[0,1,0], 'CG1':[0,2,0], 'CG2':[0,3,0], 'CD1':[0,3,0]}
R = {'N': [0, 1, 0], 'CA': [0, 1, 0], 'C': [0, 0, 0], 'O': [0, 0, 0], 'CB':[0,2,0],
'CG':[0,2,0], 'CD':[0,2,0], 'NE':[0,1,0], 'CZ':[1,0,0], 'NH1':[0,2,0], 'NH2':[0,2,0] }
D = {'N': [0, 1, 0], 'CA': [0, 1, 0], 'C': [0, 0, 0], 'O': [0, 0, 0], 'CB':[0,2,0], 'CG':[-1,0,0], 'OD1':[-1,0,0], 'OD2':[-1,0,0]}
E = {'N': [0, 1, 0], 'CA': [0, 1, 0], 'C': [0, 0, 0], 'O': [0, 0, 0], 'CB':[0,2,0], 'CG':[0,2,0], 'CD':[-1,0,0], 'OE1':[-1,0,0], 'OE2':[-1,0,0]}
S = {'N': [0, 1, 0], 'CA': [0, 1, 0], 'C': [0, 0, 0], 'O': [0, 0, 0], 'CB':[0,2,0], 'OG':[0,1,0]}
T = {'N': [0, 1, 0], 'CA': [0, 1, 0], 'C': [0, 0, 0], 'O': [0, 0, 0], 'CB':[0,1,0], 'OG1':[0,1,0], 'CG2':[0,3,0]}
C = {'N': [0, 1, 0], 'CA': [0, 1, 0], 'C': [0, 0, 0], 'O': [0, 0, 0], 'CB':[0,2,0], 'SG':[-1,1,0]}
N = {'N': [0, 1, 0], 'CA': [0, 1, 0], 'C': [0, 0, 0], 'O': [0, 0, 0], 'CB':[0,2,0], 'CG':[0,0,0], 'OD1':[0,0,0], 'ND2':[0,2,0]}
Q = {'N': [0, 1, 0], 'CA': [0, 1, 0], 'C': [0, 0, 0], 'O': [0, 0, 0], 'CB':[0,2,0], 'CG':[0,2,0], 'CD':[0,0,0], 'OE1':[0,0,0], 'NE2':[0,2,0]}
H = {'N': [0, 1, 0], 'CA': [0, 1, 0], 'C': [0, 0, 0], 'O': [0, 0, 0], 'CB':[0,2,0],
'CG':[0,0,1], 'ND1':[-1,1,1], 'CD2':[0,1,1], 'CE1':[0,1,1], 'NE2':[-1,1,1]}
K = {'N': [0, 1, 0], 'CA': [0, 1, 0], 'C': [0, 0, 0], 'O': [0, 0, 0], 'CB':[0,2,0], 'CG':[0,2,0], 'CD':[0,2,0], 'CE':[0,2,0], 'NZ':[0,3,1]}
Y = {'N': [0, 1, 0], 'CA': [0, 1, 0], 'C': [0, 0, 0], 'O': [0, 0, 0], 'CB':[0,2,0],
'CG':[0,0,1], 'CD1':[0,1,1], 'CD2':[0,1,1], 'CE1':[0,1,1], 'CE2':[0,1,1], 'CZ':[0,0,1], 'OH':[-1,1,0]}
M = {'N': [0, 1, 0], 'CA': [0, 1, 0], 'C': [0, 0, 0], 'O': [0, 0, 0], 'CB':[0,2,0], 'CG':[0,2,0], 'SD':[0,0,0], 'CE':[0,3,0]}
W = {'N': [0, 1, 0], 'CA': [0, 1, 0], 'C': [0, 0, 0], 'O': [0, 0, 0], 'CB':[0,2,0],
'CG':[0,0,1], 'CD1':[0,1,1], 'CD2':[0,0,1], 'NE1':[0,1,1], 'CE2':[0,0,1], 'CE3':[0,1,1], 'CZ2':[0,1,1], 'CZ3':[0,1,1], 'CH2':[0,1,1]}
G = {'N': [0, 1, 0], 'CA': [0, 2, 0], 'C': [0, 0, 0], 'O': [0, 0, 0]}
atom_features = {'A': A, 'V': V, 'F': F, 'P': P, 'L': L, 'I': I, 'R': R, 'D': D, 'E': E, 'S': S,
'T': T, 'C': C, 'N': N, 'Q': Q, 'H': H, 'K': K, 'Y': Y, 'M': M, 'W': W, 'G': G}
for atom_fea in atom_features.values():
for i in atom_fea.keys():
i_fea = atom_fea[i]
atom_fea[i] = [i_fea[0]/2+0.5,i_fea[1]/3,i_fea[2]]
return atom_features
def get_pdb_DF(file_path):
atom_fea_dict = def_atom_features()
res_dict = {'GLY': 'G', 'ALA': 'A', 'VAL': 'V', 'ILE': 'I', 'LEU': 'L', 'PHE': 'F', 'PRO': 'P', 'MET': 'M',
'TRP': 'W', 'CYS': 'C', 'SER': 'S', 'THR': 'T', 'ASN': 'N', 'GLN': 'Q', 'TYR': 'Y', 'HIS': 'H',
'ASP': 'D', 'GLU': 'E', 'LYS': 'K', 'ARG': 'R'}
Relative_atomic_mass = {'H': 1, 'C': 12, 'O': 16, 'N': 14, 'S': 32, 'FE': 56, 'P': 31, 'BR': 80, 'F': 19,
'CO': 59, 'V': 51, 'I': 127, 'CL': 35.5, 'CA': 40, 'B': 10.8, 'ZN': 65.5, 'MG': 24.3,
'NA': 23, 'HG': 200.6, 'MN': 55, 'K': 39.1, 'AP': 31, 'AC': 227, 'AL': 27, 'W': 183.9,
'SE': 79, 'NI': 58.7}
atom_count = -1
res_count = -1
res_id_list = []
before_res_pdb_id = None
atoms = [] # List to store atom data
with open(file_path, 'r') as pdb_file:
for line in pdb_file:
if line.startswith('ATOM'):
atom_type = line[76:78].strip()
if atom_type not in Relative_atomic_mass:
continue
atom_count += 1
res_pdb_id = int(line[22:26].strip())
if res_pdb_id != before_res_pdb_id:
res_count += 1
before_res_pdb_id = res_pdb_id
atom_name = line[12:16].strip()
is_sidechain = 0 if atom_name in ['N', 'CA', 'C', 'O', 'H'] else 1
res = res_dict.get(line[17:20].strip(), 'X') # Default to 'X' if unknown
xyz = [float(line[30:38]), float(line[38:46]), float(line[46:54])]
try:
atom_fea = atom_fea_dict[res][atom_name]
except KeyError:
atom_fea = [0.5, 0.5, 0.5]
try:
bfactor = float(line[60:66])
except ValueError:
bfactor = 0.5
atoms.append({
'ID': atom_count,
'atom': atom_name,
'atom_type': atom_type,
'res': res,
'res_id': res_pdb_id,
'xyz': xyz,
'B_factor': bfactor,
'mass': Relative_atomic_mass[atom_type],
'is_sidechain': is_sidechain,
'charge': atom_fea[0],
'num_H': atom_fea[1],
'ring': atom_fea[2]
})
if len(res_id_list) == 0 or res_id_list[-1] != res_pdb_id:
res_id_list.append(res_pdb_id)
elif line.startswith('TER'):
break
return atoms, res_id_list
def PDBFeature(query_id, PDB_chain_dir, results_dir):
pdb_path = f"{PDB_chain_dir}/{query_id}.pdb"
atoms, res_id_list = get_pdb_DF(pdb_path)
# with open(f"{results_dir}/{query_id}.df", 'wb') as f:
# joblib.dump({'atoms': atoms, 'res_id_list': res_id_list}, f)
res_sidechain_centroid = []
res_types = []
for res_id in res_id_list:
res_atoms = [atom for atom in atoms if atom['res_id'] == res_id]
if not res_atoms:
continue
res_type = res_atoms[0]['res']
res_types.append(res_type)
xyz = np.array([atom['xyz'] for atom in res_atoms])
masses = np.array([atom['mass'] for atom in res_atoms]).reshape(-1, 1)
centroid = np.sum(masses * xyz, axis=0) / np.sum(masses)
sidechain_atoms = [atom for atom in res_atoms if atom['is_sidechain'] == 1]
if not sidechain_atoms:
res_sidechain_centroid.append(centroid)
else:
xyz = np.array([atom['xyz'] for atom in sidechain_atoms])
masses = np.array([atom['mass'] for atom in sidechain_atoms]).reshape(-1, 1)
sidechain_centroid = np.sum(masses * xyz, axis=0) / np.sum(masses)
res_sidechain_centroid.append(sidechain_centroid)
res_sidechain_centroid = np.array(res_sidechain_centroid)
with open(f"{results_dir}/{query_id}_psepos_SC.pkl", 'wb') as f:
joblib.dump(res_sidechain_centroid, f)
sequence = ''.join(res_types)
with open(f"{results_dir}/{query_id}.seq", 'w') as f:
f.write(f">{query_id}\n")
f.write(sequence)