-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathutils.py
More file actions
225 lines (195 loc) · 7.6 KB
/
utils.py
File metadata and controls
225 lines (195 loc) · 7.6 KB
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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import os
import seaborn as sns
import pandas as pd
import bcolz
from shutil import copyfile
from PIL import Image
import Bio.PDB as bio
import scipy
import torch
from keras.utils.np_utils import to_categorical
residue_letter_codes = {'GLY': 'G','PRO': 'P','ALA': 'A','VAL': 'V','LEU': 'L',
'ILE': 'I','MET': 'M','CYS': 'C','PHE': 'F','TYR': 'Y',
'TRP': 'W','HIS': 'H','LYS': 'K','ARG': 'R','GLN': 'Q',
'ASN': 'N','GLU': 'E','ASP': 'D','SER': 'S','THR': 'T'}
aa2ix= {'G': 0,'P': 1,'A': 2,'V': 3,'L': 4,
'I': 5,'M': 6,'C': 7,'F': 8,'Y': 9,
'W': 10,'H': 11,'K': 12,'R': 13,'Q': 14,
'N': 15,'E': 16,'D': 17,'S': 18,'T': 19}
#get sequences and corresponding chain ids
def gather_sequence(pdb_id, seq_file):
seqs=[]
#chains=[]
#get line numbers of pdb_id
for ix, line in enumerate(seq_file):
pos = np.core.defchararray.find(line, pdb_id)
if pos > 0:
seqs.append(seq_file[ix+1][:-1]) #cut off newline character
#chains.append(line[pos+5]) #gives the chain letter from the line
return seqs
def create_targets(pdb_file_path):
p = bio.PDBParser()
s = p.get_structure('X', pdb_file_path)
#first = []
#last = []
#coords = []
#chains=[]
chain_coords=[]
#randomly select one model from the pdb file
gen = s.get_models()
l = list(gen)
mod = l[np.random.randint(0, len(l))]
#for model in s:
for chain in mod:
for ix,residue in enumerate(chain):
coords = []
#if ix == 0:
# first.append(residue.get_id()[1])
if residue.get_id()[0] == ' ':
#l = residue.get_id()[1]
for atom in residue:
if atom.get_name() == "N":
n = atom.get_coord()
elif atom.get_name() == "CA":
ca = atom.get_coord()
elif atom.get_name() == "C":
cp = atom.get_coord()
try: #in some cases N is missing on the first residue, so we append zeros instead
coords.append(np.stack([n,ca,cp], axis=0))
del n, ca, cp
except:
#first[-1] += 1 move past the first residue and ignore it
pass
#coords.append(np.zeros(3,3))
chain_coords.append(coords)
#coords = []
#chains.append(chain.get_id())
#last.append(l)
#final array is size 5x(no of residues)*3
return chain_coords #, chains, first, last
def encode_sequence(sequence, onehot=True):
vec=[]
for chain in sequence:
for c in chain:
for aa, val in aa2ix.iteritems():
if c == aa:
vec.append(val)
if onehot:
encoding = to_categorical(vec, 20)
return np.uint8(encoding)
return np.uint8(vec)
def parse_pdb(pdb_file):
#pdb_file = 'pdb5l6t.ent' #np.random.choice(pdb_list)
p = bio.PDBParser()
s = p.get_structure('X', pdb_path+pdb_file)
gen = s.get_models()
l = list(gen)
mod = l[np.random.randint(0, len(l))] #choose random model when more than 1 exists
seq_strs = []
seq_locs = []
for chain in mod:
seq_str = ''
seq_loc = []
for residue in chain:
if residue.get_id()[0] == ' ':
letter_code = residue_letter_codes[residue.get_resname()]
seq_str += letter_code
for atom in residue:
seq_loc.append(atom.get_full_id()[3][1])
seq_strs.append(seq_str)
seq_locs.append(np.unique(seq_loc))
return seq_strs, seq_locs
def align_indices(seq_strs, seq_locs, gt_seq, start_match_length=5):
fill_indices = []
for ix, pdb_seq in enumerate(seq_strs):
search_seq = gt_seq[ix]
pos = np.core.defchararray.find(search_seq, pdb_seq[:start_match_length])
if pos < 0:
raise ValueError('First 5 residues in pdb file have no match!')
locs = seq_locs[ix] + (pos - seq_locs[ix][0])
fill_indices.append(np.intersect1d(range(len(search_seq)), locs))
return fill_indices
def calc_dist(atom1_coord, atom2_coord):
return scipy.spatial.distance.euclidean(atom1_coord, atom2_coord)
def gt_dihedral_angles(pdb_file_path):
p = bio.PDBParser()
s = p.get_structure('X', pdb_file_path)
calc_di = bio.vectors.calc_dihedral
calc_ba = bio.vectors.calc_angle
#torsional angles
phi = []
psi = []
omega = []
#bond angles
ca_c_n = []
c_n_ca = []
n_ca_c = []
#bond_lengths
c_n = []
n_ca = []
ca_c = []
for model in s:
for chain in model:
for ix, residue in enumerate(chain):
for atom in residue:
if atom.get_name() == "N":
n = atom.get_vector()
n_coord = atom.get_coord()
if ix != 0:
psi.append(calc_di(np, cap, cp, n))
ca_c_n.append(calc_ba(cap, cp, n))
c_n.append(calc_dist(cp_coord, n_coord))
if atom.get_name() == "CA":
ca = atom.get_vector()
ca_coord = atom.get_coord()
if ix != 0:
omega.append(calc_di(cap, cp, n, ca))
c_n_ca.append(calc_ba(cp, n, ca))
n_ca.append(calc_dist(n_coord, ca_coord))
if atom.get_name() == "C":
c = atom.get_vector()
c_coord = atom.get_coord()
if ix != 0:
phi.append(calc_di(cp, n, ca, c))
n_ca_c.append(calc_ba(n, ca, c))
ca_c.append(calc_dist(ca_coord, c_coord))
#store previous vectors
np, cap, cp = n, ca, c
cp_coord = c_coord
torsional_angles = torch.stack([torch.tensor(psi),
torch.tensor(omega),
torch.tensor(phi)], dim=1)
bond_angles = torch.stack([torch.tensor(ca_c_n),
torch.tensor(c_n_ca),
torch.tensor(n_ca_c)], dim=1)
bond_lengths = torch.stack([torch.tensor(c_n),
torch.tensor(n_ca),
torch.tensor(ca_c)], dim=1)
return torsional_angles, bond_angles, bond_lengths
def subset(array_path, max_len, min_len=0, save_path=None):
"""Return a subset of a bcolz array based on max and min lengths of sequences
array_path: path to the bcolz array
max_len: maximum length of sequences to include in subset
min_len: Default 0, minimum length of sequences to include in subset
save_path: Default None, path to save subset array
"""
a = bcolz.carray(rootdir=array_path)
shix = []
for ix in range(len(a)):
name, sequence, coords = a[ix]
length = len(sequence[0])
if (length >= min_len) and (length <= max_len):
shix.append(ix)
if save_path:
subset = bcolz.carray(a[shix], rootdir=save_path, mode='w')
subset.flush()
return subset
return a[shix]
def save_array(fname, arr):
c=bcolz.carray(arr, rootdir=fname, mode='w')
c.flush()
def load_array(fname):
return bcolz.open(fname)[:]