@@ -25,19 +25,43 @@ def get_random_point_within_sphere(number_generator, radius):
25
25
if x ** 2 + y ** 2 + z ** 2 <= r2 :
26
26
return x , y , z
27
27
28
- def get_quaternion_for_restraint (rec_residue , lig_residue , cx , cy , cz ):
29
- """Calculates the quaternion required for orienting the ligand towards the restraint"""
30
- r_ca = rec_residue .get_calpha ()
31
- l_ca = lig_residue .get_calpha ()
32
- a = np .array ([r_ca .x , r_ca .y , r_ca .z ])
33
- b = np .array ([l_ca .x - cx , l_ca .y - cy , l_ca .z - cz ])
28
+
29
+ def normalize_vector (v ):
30
+ norm = np .linalg .norm (v )
31
+ if norm < 0.00001 :
32
+ return v
33
+ return v / norm
34
+
35
+
36
+ def orthogonal (v ):
37
+ """Returns the orthogonal vector to v"""
38
+ x = abs (v [0 ])
39
+ y = abs (v [1 ])
40
+ z = abs (v [2 ])
41
+ if x < y :
42
+ if x < z :
43
+ other = np .array ([1.0 , 0.0 , 0.0 ])
44
+ else :
45
+ other = np .array ([0.0 , 0.0 , 1.0 ])
46
+ else :
47
+ if y < z :
48
+ other = np .array ([0.0 , 1.0 , 0.0 ])
49
+ else :
50
+ other = np .array ([0.0 , 0.0 , 1.0 ])
51
+ return np .cross (v , other )
52
+
53
+
54
+ def quaternion_from_vectors (a , b ):
55
+ """Calculate quaternion between two vectors a and b."""
56
+ a = normalize_vector (a )
57
+ b = normalize_vector (b )
58
+ # Check for scenario where vectors are in the same direction
59
+ if np .allclose (a , - b ):
60
+ o = orthogonal (a )
61
+ return Quaternion (w = 0. , x = o [0 ], y = o [1 ], z = o [2 ])
34
62
c = np .cross (a , b )
35
63
d = np .dot (a , b )
36
-
37
- try :
38
- s = np .sqrt ( (1 + d )* 2 )
39
- except FloatingPointError :
40
- return Quaternion ()
64
+ s = np .sqrt ( (1 + abs (d ))* 2 )
41
65
invs = 1. / s
42
66
x = c [0 ] * invs
43
67
y = c [1 ] * invs
@@ -47,19 +71,57 @@ def get_quaternion_for_restraint(rec_residue, lig_residue, cx, cy, cz):
47
71
return Quaternion (w = w , x = x , y = y , z = z ).normalize ()
48
72
49
73
50
- def populate_poses (to_generate , center , radius , number_generator , rng_nm = None , rec_nm = 0 , lig_nm = 0 ,
51
- receptor_restraints = None , ligand_restraints = None ):
74
+ def get_quaternion_for_restraint (rec_residue , lig_residue , tx , ty , tz , rt , lt ):
75
+ """Calculates the quaternion required for orienting the ligand towards the restraint"""
76
+ r_ca = rec_residue .get_calpha ()
77
+ l_ca = lig_residue .get_calpha ()
78
+
79
+ rx = r_ca .x + rt [0 ]
80
+ ry = r_ca .y + rt [1 ]
81
+ rz = r_ca .z + rt [2 ]
82
+ print rx , ry , rz
83
+
84
+ lx = l_ca .x + lt [0 ]
85
+ ly = l_ca .y + lt [1 ]
86
+ lz = l_ca .z + lt [2 ]
87
+ print lx , ly , lz
88
+
89
+ # Define restraints vectors
90
+ a = np .array ([lx , ly , lz ])
91
+ b = np .array ([rx - tx , ry - ty , rz - tz ])
92
+
93
+ q = quaternion_from_vectors (a , b )
94
+ #print q
95
+ #print "***************"
96
+ return q
97
+
98
+
99
+ def populate_poses (to_generate , center , radius , number_generator , rec_translation , lig_translation ,
100
+ rng_nm = None , rec_nm = 0 , lig_nm = 0 , receptor_restraints = None , ligand_restraints = None ):
52
101
"""Creates new poses around a given center and a given radius"""
53
102
new_poses = []
103
+
104
+ # Calculate closer residue restraints
105
+ closest_residues = []
106
+ if receptor_restraints :
107
+ distances = []
108
+ for i , residue in enumerate (receptor_restraints ):
109
+ ca = residue .get_calpha ()
110
+ distances .append ((i , cdistance (ca .x , ca .y , ca .z ,
111
+ center [0 ], center [1 ], center [2 ])))
112
+ distances .sort (key = lambda tup : tup [1 ])
113
+ closest_residues = [x [0 ] for x in distances [:10 ]]
114
+
54
115
for _ in xrange (to_generate ):
55
116
x , y , z = get_random_point_within_sphere (number_generator , radius )
56
117
tx = center [0 ] + x
57
118
ty = center [1 ] + y
58
119
tz = center [2 ] + z
59
120
if receptor_restraints and ligand_restraints :
60
- rec_residue = receptor_restraints [number_generator .randint (0 , len (receptor_restraints )- 1 )]
121
+ rec_residue = receptor_restraints [closest_residues [ number_generator .randint (0 , len (closest_residues )- 1 )] ]
61
122
lig_residue = ligand_restraints [number_generator .randint (0 , len (ligand_restraints )- 1 )]
62
- q = get_quaternion_for_restraint (rec_residue , lig_residue , center [0 ], center [1 ], center [2 ])
123
+ q = get_quaternion_for_restraint (rec_residue , lig_residue , tx , ty , tz ,
124
+ rec_translation , lig_translation )
63
125
else :
64
126
q = Quaternion .random (number_generator )
65
127
op_vector = [tx , ty , tz , q .w , q .x , q .y , q .z ]
@@ -172,7 +234,7 @@ def calculate_initial_poses(receptor, ligand, num_clusters, num_glowworms,
172
234
# Populate new poses if needed
173
235
if len (poses ) < num_glowworms :
174
236
needed = num_glowworms - len (poses )
175
- poses .extend (populate_poses (needed , swarm_centers [cluster_id ], radius , rng ))
237
+ poses .extend (populate_poses (needed , swarm_centers [cluster_id ], radius , rng , rec_translation , lig_translation ))
176
238
177
239
# Save poses as pdb file
178
240
pdb_file_name = os .path .join (dest_folder , '%s_%s.pdb' % (DEFAULT_PDB_STARTING_PREFIX , cluster_id ))
@@ -186,8 +248,8 @@ def calculate_initial_poses(receptor, ligand, num_clusters, num_glowworms,
186
248
create_bild_file (bild_file_name , poses )
187
249
else :
188
250
for cluster_id , cluster_center in enumerate (swarm_centers ):
189
- poses = populate_poses (num_glowworms , cluster_center , radius , rng , rng_nm , rec_nm , lig_nm ,
190
- receptor_restraints , ligand_restraints )
251
+ poses = populate_poses (num_glowworms , cluster_center , radius , rng , rec_translation , lig_translation ,
252
+ rng_nm , rec_nm , lig_nm , receptor_restraints , ligand_restraints )
191
253
# Save poses as pdb file
192
254
pdb_file_name = os .path .join (dest_folder , '%s_%s.pdb' % (DEFAULT_PDB_STARTING_PREFIX , cluster_id ))
193
255
create_pdb_from_points (pdb_file_name , [[pose [0 ], pose [1 ], pose [2 ]] for pose in poses [:num_glowworms ]])
0 commit comments