forked from stemylonas/DeepSurf
-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.py
122 lines (95 loc) · 3.42 KB
/
utils.py
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
"""
Created on Tue Jul 30 13:39:49 2019
@author: smylonas
"""
import warnings
import numpy as np
from scipy.spatial.distance import euclidean
from sklearn.cluster import KMeans
def mol2_reader(mol_file): # does not handle H2
if mol_file[-4:] != 'mol2':
raise Exception("File's extension is not .mol2")
with open(mol_file,'r') as f:
lines = f.readlines()
for i,line in enumerate(lines):
if '@<TRIPOS>ATOM' in line:
first_atom_idx = i+1
if '@<TRIPOS>BOND' in line:
last_atom_idx = i-1
return lines[first_atom_idx:last_atom_idx+1]
def readSurfPoints(surf_file):
with open(surf_file,'r') as f:
lines = f.readlines()
lines = [l for l in lines if len(l.split())>7]
if len(lines)>100000:
warnings.warn('{} has too many points'.format(surf_file))
return
if len(lines)==0:
warnings.warn('{} is empty'.format(surf_file))
return
coords = np.zeros((len(lines),3))
normals = np.zeros((len(lines),3))
for i,l in enumerate(lines):
parts = l.split()
try:
coords[i,0] = float(parts[3])
coords[i,1] = float(parts[4])
coords[i,2] = float(parts[5])
normals[i,0] = float(parts[8])
normals[i,1] = float(parts[9])
normals[i,2] = float(parts[10])
except:
coords[i,0] = float(parts[2][-8:])
coords[i,1] = float(parts[3])
coords[i,2] = float(parts[4])
normals[i,0] = float(parts[7])
normals[i,1] = float(parts[8])
normals[i,2] = float(parts[9])
return coords, normals
def simplify_dms(init_surf_file, factor, seed=None):
coords, normals = readSurfPoints(init_surf_file)
if factor == 1:
return coords, normals
nPoints = len(coords)
nCl = nPoints//factor
kmeans = KMeans(n_clusters=nCl, max_iter=300, n_init=1, random_state=seed).fit(coords)
point_labels = kmeans.labels_
centers = kmeans.cluster_centers_
cluster_idx,freq = np.unique(point_labels,return_counts=True)
if len(cluster_idx)!=nCl:
raise Exception('Number of created clusters should be equal to nCl')
idxs = []
for cl in cluster_idx:
cluster_points_idxs = np.where(point_labels==cl)[0]
closest_idx_to_center = np.argmin([euclidean(centers[cl],coords[idx]) for idx in cluster_points_idxs])
idxs.append(cluster_points_idxs[closest_idx_to_center])
return coords[idxs], normals[idxs]
def rotation(n):
if n[0]==0.0 and n[1]==0.0:
if n[2]==1.0:
return np.identity(3)
elif n[2]==-1.0:
Q = np.identity(3)
Q[0,0] = -1
return Q
else:
print('not possible')
rx = -n[1]/np.sqrt(n[0]*n[0]+n[1]*n[1])
ry = n[0]/np.sqrt(n[0]*n[0]+n[1]*n[1])
rz = 0
th = np.arccos(n[2])
q0 = np.cos(th/2)
q1 = np.sin(th/2)*rx
q2 = np.sin(th/2)*ry
q3 = np.sin(th/2)*rz
Q = np.zeros((3,3))
Q[0,0] = q0*q0+q1*q1-q2*q2-q3*q3
Q[0,1] = 2*(q1*q2-q0*q3)
Q[0,2] = 2*(q1*q3+q0*q2)
Q[1,0] = 2*(q1*q2+q0*q3)
Q[1,1] = q0*q0-q1*q1+q2*q2-q3*q3
Q[1,2] = 2*(q3*q2-q0*q1)
Q[2,0] = 2*(q1*q3-q0*q2)
Q[2,1] = 2*(q3*q2+q0*q1)
Q[2,2] = q0*q0-q1*q1-q2*q2+q3*q3
return Q