VinaLC: Parallel Molecular Docking Program

Biochemical and Biophysical Systems Group
VinaLC version: 1.1.2

conf.h
Go to the documentation of this file.
1 /*
2 
3  Copyright (c) 2006-2010, The Scripps Research Institute
4 
5  Licensed under the Apache License, Version 2.0 (the "License");
6  you may not use this file except in compliance with the License.
7  You may obtain a copy of the License at
8 
9  http://www.apache.org/licenses/LICENSE-2.0
10 
11  Unless required by applicable law or agreed to in writing, software
12  distributed under the License is distributed on an "AS IS" BASIS,
13  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  See the License for the specific language governing permissions and
15  limitations under the License.
16 
17  Author: Dr. Oleg Trott <ot14@columbia.edu>,
18  The Olson Lab,
19  The Scripps Research Institute
20 
21 */
22 
23 #ifndef VINA_CONF_H
24 #define VINA_CONF_H
25 
26 #include <boost/ptr_container/ptr_vector.hpp> // typedef output_container
27 
28 #include "quaternion.h"
29 #include "random.h"
30 
31 struct scale {
35  scale(fl position_, fl orientation_, fl torsion_) : position(position_), orientation(orientation_), torsion(torsion_) {}
36 };
37 
38 struct conf_size {
42  return sum(ligands) + sum(flex) + 6 * ligands.size();
43  }
44 };
45 
46 inline void torsions_set_to_null(flv& torsions) {
47  VINA_FOR_IN(i, torsions)
48  torsions[i] = 0;
49 }
50 
51 inline void torsions_increment(flv& torsions, const flv& c, fl factor) { // new torsions are normalized
52  VINA_FOR_IN(i, torsions) {
53  torsions[i] += normalized_angle(factor * c[i]);
54  normalize_angle(torsions[i]);
55  }
56 }
57 
58 inline void torsions_randomize(flv& torsions, rng& generator) {
59  VINA_FOR_IN(i, torsions)
60  torsions[i] = random_fl(-pi, pi, generator);
61 }
62 
63 inline bool torsions_too_close(const flv& torsions1, const flv& torsions2, fl cutoff) {
64  assert(torsions1.size() == torsions2.size());
65  VINA_FOR_IN(i, torsions1)
66  if(std::abs(normalized_angle(torsions1[i] - torsions2[i])) > cutoff)
67  return false;
68  return true;
69 }
70 
71 inline void torsions_generate(flv& torsions, fl spread, fl rp, const flv* rs, rng& generator) {
72  assert(!rs || rs->size() == torsions.size()); // if present, rs should be the same size as torsions
73  VINA_FOR_IN(i, torsions)
74  if(rs && random_fl(0, 1, generator) < rp)
75  torsions[i] = (*rs)[i];
76  else
77  torsions[i] += random_fl(-spread, spread, generator);
78 }
79 
80 struct rigid_change {
83  rigid_change() : position(0, 0, 0), orientation(0, 0, 0) {}
84  void print() const {
87  }
88 };
89 
90 struct rigid_conf {
94  void set_to_null() {
97  }
98  void increment(const rigid_change& c, fl factor) {
99  position += factor * c.position;
100  vec rotation; rotation = factor * c.orientation;
101  quaternion_increment(orientation, rotation); // orientation does not get normalized; tests show rounding errors growing very slowly
102  }
103  void randomize(const vec& corner1, const vec& corner2, rng& generator) {
104  position = random_in_box(corner1, corner2, generator);
105  orientation = random_orientation(generator);
106  }
107  bool too_close(const rigid_conf& c, fl position_cutoff, fl orientation_cutoff) const {
108  if(vec_distance_sqr(position, c.position) > sqr(position_cutoff)) return false;
109  if(sqr(quaternion_difference(orientation, c.orientation)) > sqr(orientation_cutoff)) return false;
110  return true;
111  }
112  void mutate_position(fl spread, rng& generator) {
113  position += spread * random_inside_sphere(generator);
114  }
115  void mutate_orientation(fl spread, rng& generator) {
116  vec tmp; tmp = spread * random_inside_sphere(generator);
118  }
119  void generate(fl position_spread, fl orientation_spread, fl rp, const rigid_conf* rs, rng& generator) {
120  if(rs && random_fl(0, 1, generator) < rp)
121  position = rs->position;
122  else
123  mutate_position(position_spread, generator);
124  if(rs && random_fl(0, 1, generator) < rp)
125  orientation = rs->orientation;
126  else
127  mutate_orientation(orientation_spread, generator);
128  }
129  void apply(const vecv& in, vecv& out, sz begin, sz end) const {
130  assert(in.size() == out.size());
131  const mat m = quaternion_to_r3(orientation);
132  VINA_RANGE(i, begin, end)
133  out[i] = m * in[i] + position;
134  }
135  void print() const {
136  ::print(position);
138  }
139 private:
141  template<class Archive>
142  void serialize(Archive & ar, const unsigned version) {
143  ar & position;
144  ar & orientation;
145  }
146 };
147 
151  void print() const {
152  rigid.print();
153  printnl(torsions);
154  }
155 };
156 
157 struct ligand_conf {
160  void set_to_null() {
161  rigid.set_to_null();
163  }
164  void increment(const ligand_change& c, fl factor) {
165  rigid.increment(c.rigid, factor);
167  }
168  void randomize(const vec& corner1, const vec& corner2, rng& generator) {
169  rigid.randomize(corner1, corner2, generator);
170  torsions_randomize(torsions, generator);
171  }
172  void print() const {
173  rigid.print();
174  printnl(torsions);
175  }
176 private:
178  template<class Archive>
179  void serialize(Archive & ar, const unsigned version) {
180  ar & rigid;
181  ar & torsions;
182  }
183 };
184 
187  void print() const {
188  printnl(torsions);
189  }
190 };
191 
192 struct residue_conf {
194  void set_to_null() {
196  }
197  void increment(const residue_change& c, fl factor) {
199  }
200  void randomize(rng& generator) {
201  torsions_randomize(torsions, generator);
202  }
203  void print() const {
204  printnl(torsions);
205  }
206 private:
208  template<class Archive>
209  void serialize(Archive & ar, const unsigned version) {
210  ar & torsions;
211  }
212 };
213 
214 struct change {
215  std::vector<ligand_change> ligands;
216  std::vector<residue_change> flex;
217  change(const conf_size& s) : ligands(s.ligands.size()), flex(s.flex.size()) {
218  VINA_FOR_IN(i, ligands)
219  ligands[i].torsions.resize(s.ligands[i], 0);
220  VINA_FOR_IN(i, flex)
221  flex[i].torsions.resize(s.flex[i], 0);
222  }
223  fl operator()(sz index) const { // returns by value
224  VINA_FOR_IN(i, ligands) {
225  const ligand_change& lig = ligands[i];
226  if(index < 3) return lig.rigid.position[index];
227  index -= 3;
228  if(index < 3) return lig.rigid.orientation[index];
229  index -= 3;
230  if(index < lig.torsions.size()) return lig.torsions[index];
231  index -= lig.torsions.size();
232  }
233  VINA_FOR_IN(i, flex) {
234  const residue_change& res = flex[i];
235  if(index < res.torsions.size()) return res.torsions[index];
236  index -= res.torsions.size();
237  }
238  VINA_CHECK(false);
239  return 0; // shouldn't happen, placating the compiler
240  }
241  fl& operator()(sz index) {
242  VINA_FOR_IN(i, ligands) {
243  ligand_change& lig = ligands[i];
244  if(index < 3) return lig.rigid.position[index];
245  index -= 3;
246  if(index < 3) return lig.rigid.orientation[index];
247  index -= 3;
248  if(index < lig.torsions.size()) return lig.torsions[index];
249  index -= lig.torsions.size();
250  }
251  VINA_FOR_IN(i, flex) {
252  residue_change& res = flex[i];
253  if(index < res.torsions.size()) return res.torsions[index];
254  index -= res.torsions.size();
255  }
256  VINA_CHECK(false);
257  return ligands[0].rigid.position[0]; // shouldn't happen, placating the compiler
258  }
259  sz num_floats() const {
260  sz tmp = 0;
261  VINA_FOR_IN(i, ligands)
262  tmp += 6 + ligands[i].torsions.size();
263  VINA_FOR_IN(i, flex)
264  tmp += flex[i].torsions.size();
265  return tmp;
266  }
267  void print() const {
268  VINA_FOR_IN(i, ligands)
269  ligands[i].print();
270  VINA_FOR_IN(i, flex)
271  flex[i].print();
272  }
273 };
274 
275 struct conf {
276  std::vector<ligand_conf> ligands;
277  std::vector<residue_conf> flex;
278  conf() {}
279  conf(const conf_size& s) : ligands(s.ligands.size()), flex(s.flex.size()) {
280  VINA_FOR_IN(i, ligands)
281  ligands[i].torsions.resize(s.ligands[i], 0); // FIXME?
282  VINA_FOR_IN(i, flex)
283  flex[i].torsions.resize(s.flex[i], 0); // FIXME?
284  }
285  void set_to_null() {
286  VINA_FOR_IN(i, ligands)
287  ligands[i].set_to_null();
288  VINA_FOR_IN(i, flex)
289  flex[i].set_to_null();
290  }
291  void increment(const change& c, fl factor) { // torsions get normalized, orientations do not
292  VINA_FOR_IN(i, ligands)
293  ligands[i].increment(c.ligands[i], factor);
294  VINA_FOR_IN(i, flex)
295  flex[i] .increment(c.flex[i], factor);
296  }
297  bool internal_too_close(const conf& c, fl torsions_cutoff) const {
298  assert(ligands.size() == c.ligands.size());
299  VINA_FOR_IN(i, ligands)
300  if(!torsions_too_close(ligands[i].torsions, c.ligands[i].torsions, torsions_cutoff))
301  return false;
302  return true;
303  }
304  bool external_too_close(const conf& c, const scale& cutoff) const {
305  assert(ligands.size() == c.ligands.size());
306  VINA_FOR_IN(i, ligands)
307  if(!ligands[i].rigid.too_close(c.ligands[i].rigid, cutoff.position, cutoff.orientation))
308  return false;
309  assert(flex.size() == c.flex.size());
310  VINA_FOR_IN(i, flex)
311  if(!torsions_too_close(flex[i].torsions, c.flex[i].torsions, cutoff.torsion))
312  return false;
313  return true;
314  }
315  bool too_close(const conf& c, const scale& cutoff) const {
316  return internal_too_close(c, cutoff.torsion) &&
317  external_too_close(c, cutoff); // a more efficient implementation is possible, probably
318  }
319  void generate_internal(fl torsion_spread, fl rp, const conf* rs, rng& generator) { // torsions are not normalized after this
320  VINA_FOR_IN(i, ligands) {
321  ligands[i].rigid.position.assign(0);
322  ligands[i].rigid.orientation = qt_identity;
323  const flv* torsions_rs = rs ? (&rs->ligands[i].torsions) : NULL;
324  torsions_generate(ligands[i].torsions, torsion_spread, rp, torsions_rs, generator);
325  }
326  }
327  void generate_external(const scale& spread, fl rp, const conf* rs, rng& generator) { // torsions are not normalized after this
328  VINA_FOR_IN(i, ligands) {
329  const rigid_conf* rigid_conf_rs = rs ? (&rs->ligands[i].rigid) : NULL;
330  ligands[i].rigid.generate(spread.position, spread.orientation, rp, rigid_conf_rs, generator);
331  }
332  VINA_FOR_IN(i, flex) {
333  const flv* torsions_rs = rs ? (&rs->flex[i].torsions) : NULL;
334  torsions_generate(flex[i].torsions, spread.torsion, rp, torsions_rs, generator);
335  }
336  }
337  void randomize(const vec& corner1, const vec& corner2, rng& generator) {
338  VINA_FOR_IN(i, ligands)
339  ligands[i].randomize(corner1, corner2, generator);
340  VINA_FOR_IN(i, flex)
341  flex[i].randomize(generator);
342  }
343  void print() const {
344  VINA_FOR_IN(i, ligands)
345  ligands[i].print();
346  VINA_FOR_IN(i, flex)
347  flex[i].print();
348  }
349 private:
351  template<class Archive>
352  void serialize(Archive & ar, const unsigned version) {
353  ar & ligands;
354  ar & flex;
355  }
356 };
357 
358 struct output_type {
360  fl e;
362  output_type(const conf& c_, fl e_) : c(c_), e(e_) {}
363 };
364 
365 typedef boost::ptr_vector<output_type> output_container;
366 
367 inline bool operator<(const output_type& a, const output_type& b) { // for sorting output_container
368  return a.e < b.e;
369 }
370 
371 #endif