File size: 6,089 Bytes
40e5504 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | import string, os
import numpy as np
MAX_INPUT_SEQ = 1000
MAX_SEQ_LEN = 2000
nn_config = {
'node_input_dim': 1024 + 9 + 184,
'edge_input_dim': 450,
'hidden_dim': 128,
'layer': 4,
'augment_eps': 0.1,
'dropout': 0.2
}
# deal with IDs with different formats: e.g. "sp|P05067|A4_HUMAN Amyloid-beta precursor protein" (UniProt), "7PRW_1|Chains A, B|Glucocorticoid receptor|Homo sapiens" (PDB)
def get_ID(name):
name = name.split("|")
ID = "_".join(name[0:min(2, len(name))])
ID = ID.replace(" ", "_")
return ID
def remove_non_standard_aa(seq):
standard_aa = "ACDEFGHIKLMNPQRSTVWY"
new_seq = ""
for aa in seq:
if aa in standard_aa:
new_seq += aa
return new_seq
def process_fasta(fasta_file, outpath):
ID_list = []
seq_list = []
with open(fasta_file, "r") as f:
lines = f.readlines()
for line in lines:
if line[0] == ">":
ID_list.append(get_ID(line[1:-1]))
elif line[0] in string.ascii_letters:
seq = line.strip().upper()
seq = remove_non_standard_aa(seq)
seq_list.append(seq[0:min(MAX_SEQ_LEN, len(seq))]) # trim long sequence
if len(ID_list) == len(seq_list):
if len(ID_list) > MAX_INPUT_SEQ:
return 1
else:
new_fasta = "" # with processed IDs and seqs
for i in range(len(ID_list)):
new_fasta += (">" + ID_list[i] + "\n" + seq_list[i] + "\n")
with open(outpath + "test_seq.fa", "w") as f:
f.write(new_fasta)
return [ID_list, seq_list]
else:
return -1
def export_predictions(predictions, seq_list, outpath):
# original order: ["PRO", "PEP", "DNA", "RNA", "ZN", "CA", "MG", "MN", "ATP", "HEME"]
thresholds = [0.35, 0.47, 0.41, 0.46, 0.73, 0.57, 0.44, 0.65, 0.51, 0.61] # select by maximizing MCC on the cross validation
index = [2, 3, 1, 0, 8, 9, 4, 5, 6, 7] # switch order to ["DNA", "RNA", "PEP", "PRO", "ATP", "HEME", "ZN", "CA", "MG", "MN"]
GPSite_binding_scores = {}
for i, ID in enumerate(predictions):
seq = seq_list[i]
preds = predictions[ID]
norm_preds = []
binding_scores = [] # protein-level binding scores
for lig_idx, pred in enumerate(preds):
threshold = thresholds[lig_idx]
norm_pred = []
for score in pred:
if score > threshold:
norm_score = (score - threshold) / (1 - threshold) * 0.5 + 0.5
else:
norm_score = (score / threshold) * 0.5
norm_pred.append(norm_score)
norm_preds.append(norm_pred)
if lig_idx in [4, 5, 6, 7]: # metal ions
k = 5
else:
k = 10
k = min(k, len(seq))
idx = np.argpartition(norm_pred, -k)[-k:]
topk_norm_sores = np.array(norm_pred)[idx]
binding_scores.append(topk_norm_sores.mean())
GPSite_binding_scores[ID] = binding_scores
pred_txt = "No.\tAA\tDNA_binding\tRNA_binding\tPeptide_binding\tProtein_binding\tATP_binding\tHEM_binding\tZN_binding\tCA_binding\tMG_binding\tMN_binding\n"
for j in range(len(seq)):
pred_txt += "{}\t{}".format(j+1, seq[j]) # 1-based
for idx in index:
norm_score = norm_preds[idx][j]
pred_txt += "\t{:.3f}".format(norm_score)
pred_txt += "\n"
with open("{}/pred/{}.txt".format(outpath, ID), "w") as f:
f.write(pred_txt)
# export the predictions to a pdb file (for the visualization in the server)
'''
score_lines = []
for j in range(len(seq)):
score_line = ""
for idx in index:
score = norm_preds[idx][j]
score = "{:.2f}".format(score * 100)
score = " " * (6 - len(score)) + score
score_line += score
score_lines.append(score_line)
with open("{}/pdb/{}.pdb".format(outpath, ID), "r") as f:
lines = f.readlines()
current_pos = -1
new_pdb = ""
for line in lines:
if line[0:4] != "ATOM":
continue
if int(line[22:26].strip()) != current_pos:
current_pos = int(line[22:26].strip())
score_line = score_lines.pop(0)
new_line = line[0:60] + score_line + " " + line.strip()[-1] + " \n"
new_pdb += new_line
new_pdb += "TER\n"
with open("{}/pred/{}.pdb".format(outpath, ID), "w") as f:
f.write(new_pdb)
'''
with open(outpath + "esmfold_pred.log", "r") as f:
lines = f.readlines()
info_dict = {}
for line in lines:
if "pLDDT" in line:
ID_len, pLDDT, pTM = line.strip().split("|")[-1].strip().split(",")[0:3]
ID = ID_len.strip().split()[3]
length = ID_len.strip().split()[6]
pLDDT = float(pLDDT.strip().split()[1])
pTM = float(pTM.strip().split()[1])
info_dict[ID] = [length, pLDDT, pTM]
entry_info = "ID\tLength\tpLDDT\tpTM\tDNA_Binding\tRNA_Binding\tPeptide_Binding\tProtein_Binding\tATP_Binding\tHEM_Binding\tZN_Binding\tCA_Binding\tMG_Binding\tMN_Binding\n"
for ID in predictions:
Length, pLDDT, pTM = info_dict[ID]
binding_scores = GPSite_binding_scores[ID]
binding_scores = np.array(binding_scores)[index] # switch order to DNA, RNA, PEP ...
entry = "{}\t{}\t{}\t{:.3f}".format(ID, Length, pLDDT, pTM)
for score in binding_scores:
entry += "\t{:.3f}".format(score)
entry_info += (entry + "\n")
with open("{}/pred/overview.txt".format(outpath), "w") as f:
f.write(entry_info)
os.system("rm {}/esmfold_pred.log".format(outpath))
|