VinaLC: Parallel Molecular Docking Program

Biochemical and Biophysical Systems Group
VinaLC version: 1.1.2

common.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_COMMON_H
24 #define VINA_COMMON_H
25 
26 #include <cassert>
27 #include <string>
28 #include <limits>
29 #include <utility> // pair
30 #include <algorithm> // too common
31 #include <vector> // used in typedef, and commonly used overall
32 #include <cmath> // commonly used
33 #include <iostream> // various debugging everywhere
34 #include <fstream> // print_coords
35 #include <iomanip> // to_string
36 #include <sstream> // to_string
37 #include <string> // probably included by the above anyway, common anyway
38 
39 #include <boost/serialization/vector.hpp> // can't come before the above two - wart fixed in upcoming Boost versions
40 #include <boost/serialization/base_object.hpp> // movable_atom needs it - (derived from atom)
41 #include <boost/filesystem/path.hpp> // typedef'ed
42 
43 #include "macros.h"
44 
45 typedef double fl;
46 
47 template<typename T>
48 T sqr(T x) {
49  return x*x;
50 }
51 
52 const fl not_a_num = std::sqrt(fl(-1)); // FIXME? check
53 
54 typedef std::size_t sz;
55 typedef std::pair<fl, fl> pr;
56 
57 struct vec {
58  fl data[3];
59  vec() {
60 #ifndef NDEBUG
61  data[0] = data[1] = data[2] = not_a_num;
62 #endif
63  }
64  vec(fl x, fl y, fl z) {
65  data[0] = x;
66  data[1] = y;
67  data[2] = z;
68  }
69  const fl& operator[](sz i) const { assert(i < 3); return data[i]; }
70  fl& operator[](sz i) { assert(i < 3); return data[i]; }
71  fl norm_sqr() const {
72  return sqr(data[0]) + sqr(data[1]) + sqr(data[2]);
73  }
74  fl norm() const {
75  return std::sqrt(norm_sqr());
76  }
77  fl operator*(const vec& v) const {
78  return data[0] * v[0] + data[1] * v[1] + data[2] * v[2];
79  }
80  const vec& operator+=(const vec& v) {
81  data[0] += v[0];
82  data[1] += v[1];
83  data[2] += v[2];
84  return *this;
85  }
86  const vec& operator-=(const vec& v) {
87  data[0] -= v[0];
88  data[1] -= v[1];
89  data[2] -= v[2];
90  return *this;
91  }
92  const vec& operator+=(fl s) {
93  data[0] += s;
94  data[1] += s;
95  data[2] += s;
96  return *this;
97  }
98  const vec& operator-=(fl s) {
99  data[0] -= s;
100  data[1] -= s;
101  data[2] -= s;
102  return *this;
103  }
104  vec operator+(const vec& v) const {
105  return vec(data[0] + v[0],
106  data[1] + v[1],
107  data[2] + v[2]);
108  }
109  vec operator-(const vec& v) const {
110  return vec(data[0] - v[0],
111  data[1] - v[1],
112  data[2] - v[2]);
113  }
114  const vec& operator*=(fl s) {
115  data[0] *= s;
116  data[1] *= s;
117  data[2] *= s;
118  return *this;
119  }
120  void assign(fl s) {
121  data[0] = data[1] = data[2] = s;
122  }
123  sz size() const { return 3; }
124 private:
126  template<class Archive>
127  void serialize(Archive& ar, const unsigned version) {
128  ar & data;
129  }
130 };
131 
132 inline vec operator*(fl s, const vec& v) {
133  return vec(s * v[0], s * v[1], s * v[2]);
134 }
135 
136 inline vec cross_product(const vec& a, const vec& b) {
137  return vec(a[1]*b[2] - a[2]*b[1],
138  a[2]*b[0] - a[0]*b[2],
139  a[0]*b[1] - a[1]*b[0]);
140 }
141 
142 inline vec elementwise_product(const vec& a, const vec& b) {
143  return vec(a[0] * b[0],
144  a[1] * b[1],
145  a[2] * b[2]);
146 }
147 
148 struct mat {
149  fl data[9];
150  mat() {
151 #ifndef NDEBUG
152  data[0] = data[1] = data[2] =
153  data[3] = data[4] = data[5] =
154  data[6] = data[7] = data[8] = not_a_num;
155 #endif
156  }
157  // column-major
158  const fl& operator()(sz i, sz j) const { assert(i < 3); assert(j < 3); return data[i + 3*j]; }
159  fl& operator()(sz i, sz j) { assert(i < 3); assert(j < 3); return data[i + 3*j]; }
160 
161  mat(fl xx, fl xy, fl xz,
162  fl yx, fl yy, fl yz,
163  fl zx, fl zy, fl zz) {
164 
165  data[0] = xx; data[3] = xy; data[6] = xz;
166  data[1] = yx; data[4] = yy; data[7] = yz;
167  data[2] = zx; data[5] = zy; data[8] = zz;
168  }
169  vec operator*(const vec& v) const {
170  return vec(data[0]*v[0] + data[3]*v[1] + data[6]*v[2],
171  data[1]*v[0] + data[4]*v[1] + data[7]*v[2],
172  data[2]*v[0] + data[5]*v[1] + data[8]*v[2]);
173  }
174  const mat& operator*=(fl s) {
175  VINA_FOR(i, 9)
176  data[i] *= s;
177  return *this;
178  }
179 };
180 
181 
182 typedef std::vector<vec> vecv;
183 typedef std::pair<vec, vec> vecp;
184 typedef std::vector<fl> flv;
185 typedef std::vector<pr> prv;
186 typedef std::vector<sz> szv;
188 
190  std::string file;
191  unsigned line;
192  internal_error(const std::string& file_, unsigned line_) : file(file_), line(line_) {}
193 };
194 
195 #ifdef NDEBUG
196  #define VINA_CHECK(P) do { if(!(P)) throw internal_error(__FILE__, __LINE__); } while(false)
197 #else
198  #define VINA_CHECK(P) assert(P)
199 #endif
200 
201 const fl pi = fl(3.1415926535897931);
202 
203 inline sz fl_to_sz(fl x, sz max_sz) { // return a value in [0, max_sz]
204  if(x <= 0) return 0;
205  if(x >= max_sz) return max_sz;
206  sz tmp = static_cast<sz>(x);
207  return (std::min)(tmp, max_sz); // sz -> fl cast loses precision. 'min' is to guard against returning values out of range
208 }
209 
210 const fl fl_tolerance = fl(0.001);
211 
212 inline bool eq(fl a, fl b) {
213  return std::abs(a - b) < fl_tolerance;
214 }
215 
216 const fl fl_tolerance_r2 = fl(0.000001);
217 
218 inline bool eq_r2(fl a, fl b) {
219  return std::abs(a - b) < fl_tolerance_r2;
220 }
221 
222 inline bool eq(const vec& a, const vec& b) {
223  return eq(a[0], b[0]) && eq(a[1], b[1]) && eq(a[2], b[2]);
224 }
225 
226 template<typename T>
227 bool eq(const std::vector<T>& a, const std::vector<T>& b) {
228  if(a.size() != b.size()) return false;
229  VINA_FOR_IN(i, a)
230  if(!eq(a[i], b[i]))
231  return false;
232  return true;
233 }
234 
235 const fl max_fl = (std::numeric_limits<fl>::max)();
236 const sz max_sz = (std::numeric_limits<sz>::max)();
237 const unsigned max_unsigned = (std::numeric_limits<unsigned>::max)();
238 const fl epsilon_fl = std::numeric_limits<fl>::epsilon();
239 
240 const vec zero_vec(0, 0, 0);
241 const vec max_vec(max_fl, max_fl, max_fl);
242 
243 inline bool not_max(fl x) {
244  return (x < 0.1 * max_fl);
245 }
246 
247 inline fl vec_distance_sqr(const vec& a, const vec& b) {
248  return sqr(a[0] - b[0]) + \
249  sqr(a[1] - b[1]) + \
250  sqr(a[2] - b[2]);
251 }
252 
253 inline fl sqr(const vec& v) {
254  return sqr(v[0]) + sqr(v[1]) + sqr(v[2]);
255 }
256 
257 template<typename T>
258 sz vector_append(std::vector<T>& x, const std::vector<T>& y) { // return old size
259  sz old_size = x.size();
260  x.insert(x.end(), y.begin(), y.end());
261  return old_size;
262 }
263 
264 template<typename T>
265 sz find_min(const std::vector<T>& v) { // returns v.size() i.e. 0 for empty vectors; the index of the smallest elt otherwise
266  sz tmp = v.size();
267  VINA_FOR_IN(i, v)
268  if(i == 0 || v[i] < v[tmp])
269  tmp = i;
270  return tmp;
271 }
272 
273 inline void normalize_angle(fl& x) { // subtract or add enough 2*pi's to make x be in [-pi, pi]
274  if (x > 3*pi) { // very large
275  fl n = ( x - pi) / (2*pi); // how many 2*pi's do you want to subtract?
276  x -= 2*pi*std::ceil(n); // ceil can be very slow, but this should not be called often
277  normalize_angle(x);
278  }
279  else if(x < -3*pi) { // very small
280  fl n = (-x - pi) / (2*pi); // how many 2*pi's do you want to add?
281  x += 2*pi*std::ceil(n); // ceil can be very slow, but this should not be called often
282  normalize_angle(x);
283  }
284  else if(x > pi) { // in ( pi, 3*pi]
285  x -= 2*pi;
286  }
287  else if(x < -pi) { // in [-3*pi, -pi)
288  x += 2*pi;
289  }
290  assert(x >= -pi && x <= pi);
291  // in [-pi, pi]
292 }
293 
294 inline fl normalized_angle(fl x) {
295  normalize_angle(x);
296  return x;
297 }
298 
299 template<typename T>
300 std::string to_string(const T& x, std::streamsize width = 0, char fill = ' ') { // default 0 width means no restrictions on width
301  std::ostringstream out;
302  out.fill(fill);
303  if(width > 0)
304  out << std::setw(width);
305  out << x;
306  return out.str();
307 }
308 
309 template<typename T>
310 T sum(const std::vector<T>& v) {
311  T acc = 0;
312  VINA_FOR_IN(i, v)
313  acc += v[i];
314  return acc;
315 }
316 
317 // multiply pK by this to get free energy in kcal/mol:
318  // K = exp(E/RT) -- lower K and lower E == better binder
319  // pK = -log10(K) => K = 10^(-pK)
320  // E = RT ln(K) = RT ln (10^(-pK)) = - RT * ln(10) * pK
321 const fl pK_to_energy_factor = -8.31 /* RT in J/K/mol */ * 0.001 /* kilo */ * 300 /* K */ / 4.184 /* J/cal */ * std::log(10.0); // -0.6 kcal/mol * log(10) = -1.38
322 
323 inline fl pK_to_energy(fl pK) { return pK_to_energy_factor * pK; }
324 
325 inline void print(fl x, std::ostream& out = std::cout) {
326  out << x;
327 }
328 
329 inline void print(sz x, std::ostream& out = std::cout) {
330  out << x;
331 }
332 
333 inline void print(const vec& v, std::ostream& out = std::cout) {
334  out << "(";
335  VINA_FOR_IN(i, v) {
336  if(i != 0)
337  out << ", ";
338  print(v[i], out);
339  }
340  out << ")";
341 }
342 
343 template<typename T>
344 void print(const std::vector<T>& v, std::ostream& out = std::cout) {
345  out << "[";
346  VINA_FOR_IN(i, v) {
347  if(i != 0)
348  out << " ";
349  print(v[i], out);
350  }
351  out << "]";
352 }
353 
354 template<typename T>
355 void printnl(const T& x, std::ostream& out = std::cout) {
356  print(x, out);
357  out << '\n';
358 }
359 
360 inline bool starts_with(const std::string& str, const std::string& start) {
361  return str.size() >= start.size() && str.substr(0, start.size()) == start;
362 }
363 
364 template<typename T>
365 bool has(const std::vector<T>& v, const T& element) {
366  return std::find(v.begin(), v.end(), element) != v.end();
367 }
368 
369 #endif