Skip to content

Commit 36ef5d7

Browse files
committed
Only restraints in ligand and compatible with membrane
1 parent c6257db commit 36ef5d7

File tree

4 files changed

+40
-10
lines changed

4 files changed

+40
-10
lines changed

bin/simulation/lightdock_setup.py

+1-4
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,7 @@
8080
num_lig_active = len(restraints['ligand']['active'])
8181
num_lig_passive = len(restraints['ligand']['passive'])
8282

83-
# Check if restraints have been defined for the ligand, but not to the receptor
84-
if not num_rec_active and not num_rec_passive and (num_lig_active or num_lig_passive):
85-
raise LightDockError("Restraints defined for ligand, but not receptor. Try switching structures.")
86-
83+
# Complain if not a single restraint has been defined, but restraints are enabled
8784
if not num_rec_active and not num_rec_passive and not num_lig_active and not num_lig_passive:
8885
raise LightDockError("Restraints file specified, but not a single restraint found")
8986

lightdock/prep/poses.py

+29-3
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@
99
from lightdock.mathutil.lrandom import MTGenerator, NormalGenerator
1010
from lightdock.mathutil.cython.quaternion import Quaternion
1111
from lightdock.mathutil.cython.cutil import distance as cdistance
12+
from lightdock.mathutil.cython.cutil import norm
1213
from lightdock.constants import CLUSTERS_CENTERS_FILE,\
1314
DEFAULT_PDB_STARTING_PREFIX, DEFAULT_STARTING_PREFIX, DEFAULT_BILD_STARTING_PREFIX, DEFAULT_EXTENT_MU, \
1415
DEFAULT_EXTENT_SIGMA
1516
from lightdock.prep.geometry import create_bild_file
17+
from lightdock.structure.residue import Residue
1618

1719

1820
def get_random_point_within_sphere(number_generator, radius):
@@ -100,11 +102,12 @@ def get_quaternion_for_restraint(rec_residue, lig_residue, tx, ty, tz, rt, lt):
100102

101103

102104
def populate_poses(to_generate, center, radius, number_generator, rec_translation, lig_translation,
103-
rng_nm=None, rec_nm=0, lig_nm=0, receptor_restraints=None, ligand_restraints=None):
105+
rng_nm=None, rec_nm=0, lig_nm=0, receptor_restraints=None, ligand_restraints=None,
106+
ligand_diameter=1.):
104107
"""Creates new poses around a given center and a given radius"""
105108
new_poses = []
106109

107-
# Calculate closer residue restraints
110+
# Calculate closest residue restraints
108111
closest_residues = []
109112
if receptor_restraints:
110113
distances = []
@@ -118,24 +121,47 @@ def populate_poses(to_generate, center, radius, number_generator, rec_translatio
118121
closest_residues = [x[0] for x in distances[:10]]
119122

120123
for _ in xrange(to_generate):
124+
# First calculate a random translation within the swarm sphere
121125
x, y, z = get_random_point_within_sphere(number_generator, radius)
122126
tx = center[0] + x
123127
ty = center[1] + y
124128
tz = center[2] + z
129+
130+
# Restraints in both partners
125131
if receptor_restraints and ligand_restraints:
132+
# We select one of the closest residue restraints to point the quaternion
126133
rec_residue = receptor_restraints[closest_residues[number_generator.randint(0, len(closest_residues)-1)]]
134+
# Random restraint on the ligand to use for pre-orientation
127135
lig_residue = ligand_restraints[number_generator.randint(0, len(ligand_restraints)-1)]
136+
# Calculate the quaternion which rotates the ligand to point to the given receptor restraint
128137
q = get_quaternion_for_restraint(rec_residue, lig_residue, tx, ty, tz,
129138
rec_translation, lig_translation)
139+
140+
# Only restraints in the ligand partner
141+
elif ligand_restraints and not receptor_restraints:
142+
# The strategy is similar to previous but for the receptor side we will use a simulated point
143+
# over the receptor surface to point out the quaternion
144+
coef = norm(center) / ligand_diameter
145+
rec_residue = Residue.dummy(center[0]*coef, center[1]*coef, center[2]*coef)
146+
lig_residue = ligand_restraints[number_generator.randint(0, len(ligand_restraints)-1)]
147+
q = get_quaternion_for_restraint(rec_residue, lig_residue, 0, 0, 0,
148+
[0,0,0], lig_translation)
149+
# No restraints at all
130150
else:
131151
q = Quaternion.random(number_generator)
152+
153+
# Glowworm's optimization vector
132154
op_vector = [tx, ty, tz, q.w, q.x, q.y, q.z]
155+
156+
# If ANM is enabled, we need to create random components for the extents
133157
if rng_nm:
134158
if rec_nm > 0:
135159
op_vector.extend([rng_nm() for _ in xrange(rec_nm)])
136160
if lig_nm > 0:
137161
op_vector.extend([rng_nm() for _ in xrange(lig_nm)])
162+
138163
new_poses.append(op_vector)
164+
139165
return new_poses
140166

141167

@@ -295,7 +321,7 @@ def calculate_initial_poses(receptor, ligand, num_clusters, num_glowworms,
295321
else:
296322
for swarm_id, swarm_center in enumerate(swarm_centers):
297323
poses = populate_poses(num_glowworms, swarm_center, radius, rng, rec_translation, lig_translation,
298-
rng_nm, rec_nm, lig_nm, receptor_restraints, ligand_restraints)
324+
rng_nm, rec_nm, lig_nm, receptor_restraints, ligand_restraints, ligand_diameter)
299325
# Save poses as pdb file
300326
pdb_file_name = os.path.join(dest_folder, '%s_%s.pdb' % (DEFAULT_PDB_STARTING_PREFIX, swarm_id))
301327
create_pdb_from_points(pdb_file_name, [[pose[0], pose[1], pose[2]] for pose in poses[:num_glowworms]])

lightdock/structure/residue.py

+9-2
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ class Residue(object):
4040
'SER': 'S', 'THR': 'T', 'TRP': 'W', 'TYR': 'Y', 'VAL': 'V'}
4141

4242
MODIFIED_TYPES = {'CYX': 'C', 'HIP': 'H', 'HID': 'H', 'HIE': 'H'}
43+
44+
DUMMY_TYPES = ['MMB', 'DUM']
4345

4446
def __init__(self, residue_name, residue_number, atoms=None, residue_index=0):
4547
"""Creates a new residue"""
@@ -65,6 +67,10 @@ def is_standard(self):
6567
"""Checks if residue is standard"""
6668
return self.name in Residue.STANDARD_TYPES.keys()
6769

70+
def is_dummy(self):
71+
"""Checks if residue is a dummy bead"""
72+
return self.name in Residue.DUMMY_TYPES
73+
6874
def set_backbone_and_sidechain(self):
6975
"""Classifies the atoms in backbone or side-chain"""
7076
if self.is_standard():
@@ -75,7 +81,7 @@ def set_backbone_and_sidechain(self):
7581
self.sidechain = []
7682

7783
def check(self):
78-
"""Check if the residue has all the backbone and sidechain atoms"""
84+
"""Check if the residue has all the backbone and sidechain atoms, ignore dummy beads"""
7985
if self.is_standard():
8086
backbone_correct = sorted([a.name for a in self.backbone]) == sorted(backbone)
8187
if not backbone_correct:
@@ -87,7 +93,8 @@ def check(self):
8793

8894
return True
8995
else:
90-
raise ResidueNonStandardError("Can not check non-standard residue %s.%s" % (self.name, self.number))
96+
if not self.is_dummy():
97+
raise ResidueNonStandardError("Can not check non-standard residue %s.%s" % (self.name, self.number))
9198

9299
def __eq__(self, other):
93100
"""Compares two residues for equality."""

lightdock/version.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
"""Framework version"""
22

3-
CURRENT_VERSION = "0.7.0"
3+
CURRENT_VERSION = "0.7.1"

0 commit comments

Comments
 (0)