2
2
3
3
import os
4
4
import operator
5
+ import numpy as np
5
6
from lightdock .pdbutil .PDBIO import create_pdb_from_points
6
7
from lightdock .prep .starting_points import calculate_surface_points
7
8
from lightdock .prep .ftdock import FTDockCoordinatesParser , classify_ftdock_poses
@@ -24,16 +25,40 @@ def get_random_point_within_sphere(number_generator, radius):
24
25
if x ** 2 + y ** 2 + z ** 2 <= r2 :
25
26
return x , y , z
26
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 ])
34
+ c = np .cross (a , b )
35
+ d = np .dot (a , b )
27
36
28
- def populate_poses (to_generate , center , radius , number_generator , rng_nm = None , rec_nm = 0 , lig_nm = 0 ):
37
+ s = np .sqrt ( (1 + d )* 2 )
38
+ invs = 1. / s
39
+ x = c [0 ] * invs
40
+ y = c [1 ] * invs
41
+ z = c [2 ] * invs
42
+ w = s * 0.5
43
+
44
+ return Quaternion (w = w , x = x , y = y , z = z ).normalize ()
45
+
46
+
47
+ def populate_poses (to_generate , center , radius , number_generator , rng_nm = None , rec_nm = 0 , lig_nm = 0 ,
48
+ receptor_restraints = None , ligand_restraints = None ):
29
49
"""Creates new poses around a given center and a given radius"""
30
50
new_poses = []
31
51
for _ in xrange (to_generate ):
32
52
x , y , z = get_random_point_within_sphere (number_generator , radius )
33
53
tx = center [0 ] + x
34
54
ty = center [1 ] + y
35
55
tz = center [2 ] + z
36
- q = Quaternion .random (number_generator )
56
+ if receptor_restraints and ligand_restraints :
57
+ rec_residue = receptor_restraints [number_generator .randint (0 , len (receptor_restraints )- 1 )]
58
+ lig_residue = ligand_restraints [number_generator .randint (0 , len (ligand_restraints )- 1 )]
59
+ q = get_quaternion_for_restraint (rec_residue , lig_residue , center [0 ], center [1 ], center [2 ])
60
+ else :
61
+ q = Quaternion .random (number_generator )
37
62
op_vector = [tx , ty , tz , q .w , q .x , q .y , q .z ]
38
63
if rng_nm :
39
64
if rec_nm > 0 :
@@ -53,7 +78,8 @@ def create_file_from_poses(pos_file_name, poses):
53
78
positions_file .close ()
54
79
55
80
56
- def apply_restraints (swarm_centers , receptor_restraints , distance_cutoff , translation , swarms_per_restraint = 10 ):
81
+ def apply_restraints (swarm_centers , receptor_restraints , distance_cutoff , translation ,
82
+ is_membrane = False , swarms_per_restraint = 10 ):
57
83
58
84
closer_swarms = []
59
85
for i , residue in enumerate (receptor_restraints ):
@@ -72,14 +98,25 @@ def apply_restraints(swarm_centers, receptor_restraints, distance_cutoff, transl
72
98
if swarms_considered == swarms_per_restraint :
73
99
break
74
100
closer_swarms = list (set (closer_swarms ))
75
- return closer_swarms
101
+ if is_membrane :
102
+ # Requieres the receptor to be aligned in the Z axis with the membrane
103
+ min_z = min ([residue .get_calpha ().z for residue in receptor_restraints ]) + translation [2 ]
104
+ compatible = []
105
+ for swarm_id , center in enumerate (swarm_centers ):
106
+ if swarm_id in closer_swarms :
107
+ if center [2 ] >= min_z :
108
+ compatible .append (swarm_id )
109
+ return compatible
110
+ else :
111
+ return closer_swarms
76
112
77
113
78
114
def calculate_initial_poses (receptor , ligand , num_clusters , num_glowworms ,
79
115
seed , receptor_restraints , ligand_restraints ,
80
116
rec_translation , lig_translation ,
81
- dest_folder , ftdock_file = '' , nm_mode = False , nm_seed = 0 , rec_nm = 0 , lig_nm = 0 ):
82
- """Calculates the starting points for each of the glowworms using the center of clusters
117
+ dest_folder , ftdock_file = '' , nm_mode = False , nm_seed = 0 , rec_nm = 0 , lig_nm = 0 ,
118
+ is_membrane = False ):
119
+ """Calculates the starting points for each of the glowworms using the center of swarms
83
120
and FTDock poses.
84
121
"""
85
122
# Random number generator for poses
@@ -91,18 +128,19 @@ def calculate_initial_poses(receptor, ligand, num_clusters, num_glowworms,
91
128
else :
92
129
rng_nm = None
93
130
94
- # Calculate cluster centers
95
- cluster_centers , receptor_diameter , ligand_diameter = calculate_surface_points (receptor ,
131
+ # Calculate swarm centers
132
+ swarm_centers , receptor_diameter , ligand_diameter = calculate_surface_points (receptor ,
96
133
ligand ,
97
134
num_clusters ,
98
135
distance_step = 1.0 )
99
136
# Filter cluster centers far from the restraints
100
137
if receptor_restraints :
101
- filtered_swarms = apply_restraints (cluster_centers , receptor_restraints , ligand_diameter / 2. , rec_translation )
102
- cluster_centers = [cluster_centers [i ] for i in filtered_swarms ]
138
+ filtered_swarms = apply_restraints (swarm_centers , receptor_restraints , ligand_diameter / 2. ,
139
+ rec_translation , is_membrane = is_membrane )
140
+ swarm_centers = [swarm_centers [i ] for i in filtered_swarms ]
103
141
104
142
pdb_file_name = os .path .join (dest_folder , CLUSTERS_CENTERS_FILE )
105
- create_pdb_from_points (pdb_file_name , cluster_centers )
143
+ create_pdb_from_points (pdb_file_name , swarm_centers )
106
144
107
145
ligand_center = ligand .center_of_coordinates ()
108
146
radius = 10. # ligand_diameter / 2.
@@ -114,7 +152,7 @@ def calculate_initial_poses(receptor, ligand, num_clusters, num_glowworms,
114
152
raise NotImplementedError ('Using FTDock poses with NM is not supported' )
115
153
116
154
poses = FTDockCoordinatesParser .get_list_of_poses (ftdock_file , ligand_center )
117
- clusters = classify_ftdock_poses (poses , cluster_centers , radius )
155
+ clusters = classify_ftdock_poses (poses , swarm_centers , radius )
118
156
119
157
for cluster_id , ftdock_poses in clusters .iteritems ():
120
158
# Translate FTDock poses into lightdock poses
@@ -131,7 +169,7 @@ def calculate_initial_poses(receptor, ligand, num_clusters, num_glowworms,
131
169
# Populate new poses if needed
132
170
if len (poses ) < num_glowworms :
133
171
needed = num_glowworms - len (poses )
134
- poses .extend (populate_poses (needed , cluster_centers [cluster_id ], radius , rng ))
172
+ poses .extend (populate_poses (needed , swarm_centers [cluster_id ], radius , rng ))
135
173
136
174
# Save poses as pdb file
137
175
pdb_file_name = os .path .join (dest_folder , '%s_%s.pdb' % (DEFAULT_PDB_STARTING_PREFIX , cluster_id ))
@@ -144,8 +182,9 @@ def calculate_initial_poses(receptor, ligand, num_clusters, num_glowworms,
144
182
positions_files .append (pos_file_name )
145
183
create_bild_file (bild_file_name , poses )
146
184
else :
147
- for cluster_id , cluster_center in enumerate (cluster_centers ):
148
- poses = populate_poses (num_glowworms , cluster_center , radius , rng , rng_nm , rec_nm , lig_nm )
185
+ for cluster_id , cluster_center in enumerate (swarm_centers ):
186
+ poses = populate_poses (num_glowworms , cluster_center , radius , rng , rng_nm , rec_nm , lig_nm ,
187
+ receptor_restraints , ligand_restraints )
149
188
# Save poses as pdb file
150
189
pdb_file_name = os .path .join (dest_folder , '%s_%s.pdb' % (DEFAULT_PDB_STARTING_PREFIX , cluster_id ))
151
190
create_pdb_from_points (pdb_file_name , [[pose [0 ], pose [1 ], pose [2 ]] for pose in poses [:num_glowworms ]])
0 commit comments