Skip to content

Commit d98e7c1

Browse files
committed
Support for different number of ANM modes
1 parent 6051d82 commit d98e7c1

File tree

11 files changed

+102
-47
lines changed

11 files changed

+102
-47
lines changed

bin/post/lgd_generate_conformations.py

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from lightdock.structure.complex import Complex
1414
from lightdock.mathutil.cython.quaternion import Quaternion
1515
from lightdock.structure.nm import read_nmodes
16+
from lightdock.prep.simulation import get_setup_from_file
1617

1718

1819
log = LoggingManager.get_logger('generate_conformations')
@@ -59,7 +60,7 @@ def get_lightdock_structures(input_file):
5960
return file_names
6061

6162

62-
def parse_output_file(lightdock_output):
63+
def parse_output_file(lightdock_output, num_anm_rec, num_anm_lig):
6364
translations = []
6465
rotations = []
6566
receptor_ids = []
@@ -79,9 +80,9 @@ def parse_output_file(lightdock_output):
7980
coord = line[1:last].split(',')
8081
translations.append([float(coord[0]), float(coord[1]), float(coord[2])])
8182
rotations.append(Quaternion(float(coord[3]), float(coord[4]), float(coord[5]), float(coord[6])))
82-
if len(coord) == (7 + DEFAULT_NMODES_REC + DEFAULT_NMODES_LIG):
83-
rec_extents.append(np.array([float(x) for x in coord[7:7+DEFAULT_NMODES_REC]]))
84-
lig_extents.append(np.array([float(x) for x in coord[-DEFAULT_NMODES_LIG:]]))
83+
if len(coord) > 7:
84+
rec_extents.append(np.array([float(x) for x in coord[7:7+num_anm_rec]]))
85+
lig_extents.append(np.array([float(x) for x in coord[-num_anm_lig:]]))
8586
raw_data = line[last+1:].split()
8687
receptor_id = int(raw_data[0])
8788
ligand_id = int(raw_data[1])
@@ -105,9 +106,21 @@ def parse_output_file(lightdock_output):
105106
type=valid_file, metavar="lightdock_output")
106107
# Number of glowworms
107108
parser.add_argument("glowworms", help="number of glowworms", type=valid_integer_number)
109+
# Optional, setup file
110+
parser.add_argument("--setup", "-setup", "-s", help="Simulation setup file",
111+
dest="setup_file", metavar="setup_file", type=valid_file, default=None)
108112

109113
args = parser.parse_args()
110114

115+
# Load setup configuration if provided
116+
setup = get_setup_from_file(args.setup_file) if args.setup_file else None
117+
118+
num_anm_rec = DEFAULT_NMODES_REC
119+
num_anm_lig = DEFAULT_NMODES_LIG
120+
if setup and setup['use_anm']:
121+
num_anm_rec = setup['anm_rec']
122+
num_anm_lig = setup['anm_lig']
123+
111124
# Receptor
112125
structures = []
113126
for structure in get_lightdock_structures(args.receptor_structures):
@@ -128,7 +141,7 @@ def parse_output_file(lightdock_output):
128141

129142
# Output file
130143
translations, rotations, receptor_ids, ligand_ids, \
131-
rec_extents, lig_extents = parse_output_file(args.lightdock_output)
144+
rec_extents, lig_extents = parse_output_file(args.lightdock_output, num_anm_rec, num_anm_lig)
132145

133146
found_conformations = len(translations)
134147
num_conformations = args.glowworms
@@ -157,22 +170,30 @@ def parse_output_file(lightdock_output):
157170
# Use normal modes if provided:
158171
if len(rec_extents):
159172
try:
160-
for nm in range(DEFAULT_NMODES_REC):
173+
for nm in range(num_anm_rec):
161174
receptor_pose.coordinates += nmodes_rec[nm] * rec_extents[i][nm]
162-
except ValueError, e:
175+
except ValueError:
163176
log.error("Problem found on calculating ANM for receptor:")
164177
log.error("Number of atom coordinates is: %s" % str(receptor_pose.coordinates.shape))
165178
log.error("Number of ANM is: %s" % str(nmodes_rec.shape))
166179
raise SystemExit
180+
except IndexError:
181+
log.error("Problem found on calculating ANM for receptor:")
182+
log.error("If you have used anm_rec different than default, please use --setup")
183+
raise SystemExit
167184
if len(lig_extents):
168185
try:
169-
for nm in range(DEFAULT_NMODES_LIG):
186+
for nm in range(num_anm_lig):
170187
ligand_pose.coordinates += nmodes_lig[nm] * lig_extents[i][nm]
171-
except ValueError, e:
188+
except ValueError:
172189
log.error("Problem found on calculating ANM for ligand:")
173190
log.error("Number of atom coordinates is: %s" % str(receptor_pose.coordinates.shape))
174191
log.error("Number of ANM is: %s" % str(nmodes_rec.shape))
175192
raise SystemExit
193+
except IndexError:
194+
log.error("Problem found on calculating ANM for ligand:")
195+
log.error("If you have used anm_lig different than default, please use --setup")
196+
raise SystemExit
176197

177198
# We rotate first, ligand it's at initial position
178199
ligand_pose.rotate(rotations[i])

bin/simulation/docking_mpi.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ def set_gso(number_of_glowworms, adapters, scoring_functions, initial_positions,
3838
else:
3939
gso_parameters = GSOParameters()
4040
builder = LightdockGSOBuilder()
41+
if not use_anm:
42+
anm_rec = anm_lig = 0
4143
gso = builder.create_from_file(number_of_glowworms, random_number_generator, gso_parameters,
4244
adapters, scoring_functions, bounding_box, initial_positions,
4345
step_translation, step_rotation, nmodes_step, local_minimization)
@@ -112,8 +114,16 @@ def run_simulation(parser):
112114
ligand.move_to_origin()
113115

114116
if args.use_anm:
115-
receptor.n_modes = read_nmodes("%s%s" % (DEFAULT_REC_NM_FILE, NUMPY_FILE_SAVE_EXTENSION) )
116-
ligand.n_modes = read_nmodes("%s%s" % (DEFAULT_LIG_NM_FILE, NUMPY_FILE_SAVE_EXTENSION) )
117+
try:
118+
receptor.n_modes = read_nmodes("%s%s" % (DEFAULT_REC_NM_FILE, NUMPY_FILE_SAVE_EXTENSION) )
119+
except:
120+
log.warning("No ANM found for receptor molecule")
121+
receptor.n_modes = None
122+
try:
123+
ligand.n_modes = read_nmodes("%s%s" % (DEFAULT_LIG_NM_FILE, NUMPY_FILE_SAVE_EXTENSION) )
124+
except:
125+
log.warning("No ANM found for ligand molecule")
126+
ligand.n_modes = None
117127

118128
starting_points_files = load_starting_positions(args.swarms, args.glowworms, args.use_anm,
119129
args.anm_rec, args.anm_lig)

bin/simulation/docking_multiprocessing.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,12 @@ def set_gso(number_of_glowworms, adapters, scoring_functions, initial_positions,
3737
else:
3838
gso_parameters = GSOParameters()
3939
builder = LightdockGSOBuilder()
40+
if not use_anm:
41+
anm_rec = anm_lig = 0
4042
gso = builder.create_from_file(number_of_glowworms, random_number_generator, gso_parameters,
4143
adapters, scoring_functions, bounding_box, initial_positions,
42-
step_translation, step_rotation, nmodes_step, local_minimization)
44+
step_translation, step_rotation, nmodes_step, local_minimization,
45+
anm_rec, anm_lig)
4346
return gso
4447

4548

@@ -121,8 +124,16 @@ def run_simulation(parser):
121124
ligand.move_to_origin()
122125

123126
if args.use_anm:
124-
receptor.n_modes = read_nmodes("%s%s" % (DEFAULT_REC_NM_FILE, NUMPY_FILE_SAVE_EXTENSION) )
125-
ligand.n_modes = read_nmodes("%s%s" % (DEFAULT_LIG_NM_FILE, NUMPY_FILE_SAVE_EXTENSION) )
127+
try:
128+
receptor.n_modes = read_nmodes("%s%s" % (DEFAULT_REC_NM_FILE, NUMPY_FILE_SAVE_EXTENSION) )
129+
except:
130+
log.warning("No ANM found for receptor molecule")
131+
receptor.n_modes = None
132+
try:
133+
ligand.n_modes = read_nmodes("%s%s" % (DEFAULT_LIG_NM_FILE, NUMPY_FILE_SAVE_EXTENSION) )
134+
except:
135+
log.warning("No ANM found for ligand molecule")
136+
ligand.n_modes = None
126137

127138
starting_points_files = load_starting_positions(args.swarms, args.glowworms, args.use_anm,
128139
args.anm_rec, args.anm_lig)

bin/simulation/lightdock_setup.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,12 @@
6161

6262
# Calculate and save ANM if required
6363
if args.use_anm:
64-
calculate_anm(receptor, args.anm_rec, DEFAULT_REC_NM_FILE)
65-
calculate_anm(ligand, args.anm_lig, DEFAULT_LIG_NM_FILE)
64+
if args.anm_rec > 0:
65+
log.info("Calculating ANM for receptor molecule...")
66+
calculate_anm(receptor, args.anm_rec, DEFAULT_REC_NM_FILE)
67+
if args.anm_lig > 0:
68+
log.info("Calculating ANM for ligand molecule...")
69+
calculate_anm(ligand, args.anm_lig, DEFAULT_LIG_NM_FILE)
6670

6771
# Parse restraints if any:
6872
receptor_restraints = ligand_restraints = None

lightdock/gso/algorithm.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,14 @@ class LightdockGSOBuilder(object):
107107
"""Creates a GSO simulation object for the LightDock framework"""
108108
def create_from_file(self, number_of_glowworms, random_number_generator, gso_parameters,
109109
adapters, scoring_functions, bounding_box, initial_population_file,
110-
step_translation, step_rotation, step_nmodes, local_minimization):
110+
step_translation, step_rotation, step_nmodes, local_minimization,
111+
anm_rec, anm_lig):
111112
"""Creates a new GSO instance of the algorithm reading the initial position of the glowworms
112113
agents from initial_population_file and using the scoring function adapter.
113114
"""
114115
self._initializer = LightdockFromFileInitializer(adapters, scoring_functions, number_of_glowworms,
115116
gso_parameters, bounding_box.dimension,
116117
initial_population_file, step_translation, step_rotation,
117-
random_number_generator, step_nmodes)
118+
random_number_generator, step_nmodes, anm_rec, anm_lig)
118119
return GSO(self._initializer.generate_glowworms(), gso_parameters, random_number_generator,
119120
local_minimization=local_minimization)

lightdock/gso/initializer.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ class LightdockFromFileInitializer(Initializer):
8888
"""This initializer takes into account the complex provided by the adapter"""
8989
def __init__(self, adapters, scoring_functions, number_of_glowworms, gso_parameters,
9090
dimensions, initial_population_file, step_translation, step_rotation,
91-
random_number_generator, step_nmodes):
91+
random_number_generator, step_nmodes, anm_rec, anm_lig):
9292
super(LightdockFromFileInitializer, self).__init__(scoring_functions, number_of_glowworms, gso_parameters)
9393
self.dimensions = dimensions
9494
self.initial_population_file = initial_population_file
@@ -98,6 +98,8 @@ def __init__(self, adapters, scoring_functions, number_of_glowworms, gso_paramet
9898
self.step_nmodes = step_nmodes
9999
# Patch to not mess with old simulations
100100
self.random_number_generator = MTGenerator(random_number_generator.seed)
101+
self.anm_rec = anm_rec
102+
self.anm_lig = anm_lig
101103

102104
def generate_landscape_positions(self):
103105
"""Generates a list of landscape positions that have been read
@@ -122,6 +124,5 @@ def generate_landscape_positions(self):
122124
adapter.receptor_model, adapter.ligand_model,
123125
receptor_index, ligand_index,
124126
self.step_translation, self.step_rotation,
125-
self.step_nmodes))
126-
127+
self.step_nmodes, self.anm_rec, self.anm_lig))
127128
return positions

lightdock/gso/searchspace/landscape.py

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -97,24 +97,22 @@ class DockingLandscapePosition(LandscapePosition):
9797
"""
9898
def __init__(self, scoring_function, coordinates, receptor, ligand, receptor_id=0, ligand_id=0,
9999
step_translation=DEFAULT_TRANSLATION_STEP, step_rotation=DEFAULT_ROTATION_STEP,
100-
step_nmodes=DEFAULT_NMODES_STEP):
100+
step_nmodes=0, num_rec_nmodes=0, num_lig_nmodes=0):
101101
self.objective_function = scoring_function
102102
self.translation = np.array(coordinates[:3])
103103
self.rotation = Quaternion(coordinates[3], coordinates[4], coordinates[5], coordinates[6])
104-
# Copy ANM information if required
105-
if len(coordinates) > 7 and len(coordinates) == (7 + DEFAULT_NMODES_REC + DEFAULT_NMODES_LIG):
106-
self.rec_extent = np.array(coordinates[7:7+DEFAULT_NMODES_REC])
107-
self.lig_extent = np.array(coordinates[-DEFAULT_NMODES_LIG:])
108-
else:
109-
self.rec_extent = np.array([])
110-
self.lig_extent = np.array([])
111104
self.receptor = receptor
112105
self.ligand = ligand
113106
self.receptor_id = receptor_id
114107
self.ligand_id = ligand_id
115108
self.step_translation = step_translation
116109
self.step_rotation = step_rotation
117110
self.step_nmodes = step_nmodes
111+
self.num_rec_nmodes = num_rec_nmodes
112+
self.num_lig_nmodes = num_lig_nmodes
113+
# Copy ANM information if required
114+
self.rec_extent = np.array(coordinates[7:7+self.num_rec_nmodes]) if self.num_rec_nmodes > 0 else np.array([])
115+
self.lig_extent = np.array(coordinates[-self.num_lig_nmodes:]) if self.num_lig_nmodes > 0 else np.array([])
118116
# This part is important, each position needs to retain its own pose coordinates
119117
self.receptor_pose = self.receptor.coordinates[self.receptor_id].clone()
120118
self.ligand_pose = self.ligand.coordinates[self.ligand_id].clone()
@@ -129,7 +127,8 @@ def clone(self):
129127
return DockingLandscapePosition(self.objective_function, coordinates,
130128
self.receptor, self.ligand,
131129
self.receptor_id, self.ligand_id,
132-
self.step_translation, self.step_rotation, self.step_nmodes)
130+
self.step_translation, self.step_rotation, self.step_nmodes,
131+
self.num_rec_nmodes, self.num_lig_nmodes)
133132

134133
def evaluate_objective_function(self, receptor_structure_id=None, ligand_structure_id=None):
135134
"""Evaluates the objective function at the given coordinates"""
@@ -147,13 +146,11 @@ def evaluate_objective_function(self, receptor_structure_id=None, ligand_structu
147146
self.ligand_reference_points = self.ligand.reference_points.clone()
148147

149148
# Use normal modes if provided:
150-
num_rec_nmodes = len(self.rec_extent)
151-
if num_rec_nmodes:
152-
for i in range(num_rec_nmodes):
149+
if self.num_rec_nmodes > 0:
150+
for i in range(self.num_rec_nmodes):
153151
self.receptor_pose.coordinates += self.receptor.n_modes[i] * self.rec_extent[i]
154-
num_lig_nmodes = len(self.lig_extent)
155-
if num_lig_nmodes:
156-
for i in range(num_lig_nmodes):
152+
if self.num_lig_nmodes > 0:
153+
for i in range(self.num_lig_nmodes):
157154
self.ligand_pose.coordinates += self.ligand.n_modes[i] * self.lig_extent[i]
158155

159156
# We rotate first, ligand it's at initial position
@@ -198,14 +195,14 @@ def move(self, other):
198195
# Rotation (Quaternion SLERP)
199196
self.rotation = self.rotation.slerp(other.rotation, self.step_rotation)
200197
# NModes
201-
if len(self.rec_extent):
198+
if self.num_rec_nmodes > 0:
202199
delta_x = other.rec_extent - self.rec_extent
203200
n = np.linalg.norm(delta_x)
204201
# Only move if required
205202
if not np.allclose([0.0], [n]):
206203
delta_x *= (self.step_nmodes / n)
207204
self.rec_extent += delta_x
208-
if len(self.lig_extent):
205+
if self.num_lig_nmodes > 0:
209206
delta_x = other.lig_extent - self.lig_extent
210207
n = np.linalg.norm(delta_x)
211208
# Only move if required
@@ -238,8 +235,8 @@ def update_landscape_position(self, optimized_vector):
238235
"""Updates the current pose"""
239236
self.translation = optimized_vector[:3]
240237
self.rotation = Quaternion(optimized_vector[3], optimized_vector[4], optimized_vector[5], optimized_vector[6])
241-
self.rec_extent = optimized_vector[7:7+DEFAULT_NMODES_REC]
242-
self.lig_extent = optimized_vector[-DEFAULT_NMODES_LIG:]
238+
self.rec_extent = optimized_vector[7:7+self.num_rec_nmodes] if self.num_rec_nmodes > 0 else np.array([])
239+
self.lig_extent = optimized_vector[-self.num_lig_nmodes:] if self.num_lig_nmodes > 0 else np.array([])
243240

244241
def minimize(self):
245242
"""Returns the new scoring after minimizing this landscape position using a local non-grandient

lightdock/test/gso/test_initializer.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ def test_create_swarm(self):
109109
initializer = LightdockFromFileInitializer([self.adapter], [self.scoring_function],
110110
number_of_glowworms, gso_parameters,
111111
7, self.golden_data_path+'initial_positions_1PPE.txt',
112-
0.5, 0.5, random_number_generator, 0.5)
112+
0.5, 0.5, random_number_generator, 0.5, 10, 10)
113113
swarm = initializer.generate_glowworms()
114114

115115
assert number_of_glowworms == swarm.get_size()
@@ -123,7 +123,7 @@ def test_generate_landscape_positions_without_coordinates(self):
123123
initializer = LightdockFromFileInitializer(self.adapter, self.scoring_function,
124124
number_of_glowworms, gso_parameters,
125125
7, self.golden_data_path+'initial_positions_empty.txt',
126-
0.5, 0.5, random_number_generator, 0.5)
126+
0.5, 0.5, random_number_generator, 0.5, 10, 10)
127127
swarm = initializer.generate_glowworms()
128128

129129
assert swarm.get_size() > 0
@@ -137,7 +137,7 @@ def test_generate_landscape_positions_num_glowworms_different(self):
137137
initializer = LightdockFromFileInitializer(self.adapter, self.scoring_function,
138138
number_of_glowworms, gso_parameters,
139139
7, self.golden_data_path+'initial_positions_1PPE.txt',
140-
0.5, 0.5, random_number_generator, 0.5)
140+
0.5, 0.5, random_number_generator, 0.5, 10, 10)
141141
swarm = initializer.generate_glowworms()
142142

143143
assert swarm.get_size() > 0

lightdock/test/gso/test_lightdockbuilder.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def test_LightDockGSOBuilder_using_FromFileInitializer(self):
5353
gso = builder.create_from_file(number_of_glowworms, self.random_number_generator,
5454
self.gso_parameters, [adapter], [scoring_function], self.bounding_box,
5555
self.golden_data_path+'initial_positions_1PPE.txt',
56-
0.5, 0.5, 0.5, local_minimization=False)
56+
0.5, 0.5, 0.5, False, 10, 10)
5757

5858
assert 5 == gso.swarm.get_size()
5959

0 commit comments

Comments
 (0)