VinaLC: Parallel Molecular Docking Program

Biochemical and Biophysical Systems Group
VinaLC version: 1.1.2

tree.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_TREE_H
24 #define VINA_TREE_H
25 
26 #include "conf.h"
27 #include "atom.h"
28 
29 struct frame {
31  vec local_to_lab(const vec& local_coords) const {
32  vec tmp;
33  tmp = origin + orientation_m*local_coords;
34  return tmp;
35  }
36  vec local_to_lab_direction(const vec& local_direction) const {
37  vec tmp;
38  tmp = orientation_m * local_direction;
39  return tmp;
40  }
41  const qt& orientation() const { return orientation_q; }
42  const vec& get_origin() const { return origin; }
43 protected:
45  void set_orientation(const qt& q) { // does not normalize the orientation
46  orientation_q = q;
48  }
51 };
52 
53 struct atom_range {
56  atom_range(sz begin_, sz end_) : begin(begin_), end(end_) {}
57  template<typename F>
58  void transform(const F& f) {
59  sz diff = end - begin;
60  begin = f(begin);
61  end = begin + diff;
62  }
63 };
64 
65 struct atom_frame : public frame, public atom_range {
66  atom_frame(const vec& origin_, sz begin_, sz end_) : frame(origin_), atom_range(begin_, end_) {}
67  void set_coords(const atomv& atoms, vecv& coords) const {
68  VINA_RANGE(i, begin, end)
69  coords[i] = local_to_lab(atoms[i].coords);
70  }
71  vecp sum_force_and_torque(const vecv& coords, const vecv& forces) const {
72  vecp tmp;
73  tmp.first.assign(0);
74  tmp.second.assign(0);
75  VINA_RANGE(i, begin, end) {
76  tmp.first += forces[i];
77  tmp.second += cross_product(coords[i] - origin, forces[i]);
78  }
79  return tmp;
80  }
81 };
82 
83 struct rigid_body : public atom_frame {
84  rigid_body(const vec& origin_, sz begin_, sz end_) : atom_frame(origin_, begin_, end_) {}
85  void set_conf(const atomv& atoms, vecv& coords, const rigid_conf& c) {
86  origin = c.position;
88  set_coords(atoms, coords);
89  }
90  void count_torsions(sz& s) const {} // do nothing
91  void set_derivative(const vecp& force_torque, rigid_change& c) const {
92  c.position = force_torque.first;
93  c.orientation = force_torque.second;
94  }
95 };
96 
97 struct axis_frame : public atom_frame {
98  axis_frame(const vec& origin_, sz begin_, sz end_, const vec& axis_root) : atom_frame(origin_, begin_, end_) {
99  vec diff; diff = origin - axis_root;
100  fl nrm = diff.norm();
101  VINA_CHECK(nrm >= epsilon_fl);
102  axis = (1/nrm) * diff;
103  }
104  void set_derivative(const vecp& force_torque, fl& c) const {
105  c = force_torque.second * axis;
106  }
107 protected:
109 };
110 
111 struct segment : public axis_frame {
112  segment(const vec& origin_, sz begin_, sz end_, const vec& axis_root, const frame& parent) : axis_frame(origin_, begin_, end_, axis_root) {
113  VINA_CHECK(eq(parent.orientation(), qt_identity)); // the only initial parent orientation this c'tor supports
115  relative_origin = origin - parent.get_origin();
116  }
117  void set_conf(const frame& parent, const atomv& atoms, vecv& coords, flv::const_iterator& c) {
118  const fl torsion = *c;
119  ++c;
122  qt tmp = angle_to_quaternion(axis, torsion) * parent.orientation();
123  quaternion_normalize_approx(tmp); // normalization added in 1.1.2
124  //quaternion_normalize(tmp); // normalization added in 1.1.2
125  set_orientation(tmp);
126  set_coords(atoms, coords);
127  }
128  void count_torsions(sz& s) const {
129  ++s;
130  }
131 private:
134 };
135 
136 struct first_segment : public axis_frame {
137  first_segment(const segment& s) : axis_frame(s) {}
138  first_segment(const vec& origin_, sz begin_, sz end_, const vec& axis_root) : axis_frame(origin_, begin_, end_, axis_root) {}
139  void set_conf(const atomv& atoms, vecv& coords, fl torsion) {
141  set_coords(atoms, coords);
142  }
143  void count_torsions(sz& s) const {
144  ++s;
145  }
146 };
147 
148 template<typename T> // T == branch
149 void branches_set_conf(std::vector<T>& b, const frame& parent, const atomv& atoms, vecv& coords, flv::const_iterator& c) {
150  VINA_FOR_IN(i, b)
151  b[i].set_conf(parent, atoms, coords, c);
152 }
153 
154 template<typename T> // T == branch
155 void branches_derivative(const std::vector<T>& b, const vec& origin, const vecv& coords, const vecv& forces, vecp& out, flv::iterator& d) { // adds to out
156  VINA_FOR_IN(i, b) {
157  vecp force_torque = b[i].derivative(coords, forces, d);
158  out.first += force_torque.first;
159  vec r; r = b[i].node.get_origin() - origin;
160  out.second += cross_product(r, force_torque.first) + force_torque.second;
161  }
162 }
163 
164 template<typename T> // T == segment
165 struct tree {
166  T node;
167  std::vector< tree<T> > children;
168  tree(const T& node_) : node(node_) {}
169  void set_conf(const frame& parent, const atomv& atoms, vecv& coords, flv::const_iterator& c) {
170  node.set_conf(parent, atoms, coords, c);
171  branches_set_conf(children, node, atoms, coords, c);
172  }
173  vecp derivative(const vecv& coords, const vecv& forces, flv::iterator& p) const {
174  vecp force_torque = node.sum_force_and_torque(coords, forces);
175  fl& d = *p; // reference
176  ++p;
177  branches_derivative(children, node.get_origin(), coords, forces, force_torque, p);
178  node.set_derivative(force_torque, d);
179  return force_torque;
180  }
181 };
182 
184 typedef std::vector<branch> branches;
185 
186 template<typename Node> // Node == first_segment || rigid_body
187 struct heterotree {
188  Node node;
190  heterotree(const Node& node_) : node(node_) {}
191  void set_conf(const atomv& atoms, vecv& coords, const ligand_conf& c) {
192  node.set_conf(atoms, coords, c.rigid);
193  flv::const_iterator p = c.torsions.begin();
194  branches_set_conf(children, node, atoms, coords, p);
195  assert(p == c.torsions.end());
196  }
197  void set_conf(const atomv& atoms, vecv& coords, const residue_conf& c) {
198  flv::const_iterator p = c.torsions.begin();
199  node.set_conf(atoms, coords, *p);
200  ++p;
201  branches_set_conf(children, node, atoms, coords, p);
202  assert(p == c.torsions.end());
203  }
204  void derivative(const vecv& coords, const vecv& forces, ligand_change& c) const {
205  vecp force_torque = node.sum_force_and_torque(coords, forces);
206  flv::iterator p = c.torsions.begin();
207  branches_derivative(children, node.get_origin(), coords, forces, force_torque, p);
208  node.set_derivative(force_torque, c.rigid);
209  assert(p == c.torsions.end());
210  }
211  void derivative(const vecv& coords, const vecv& forces, residue_change& c) const {
212  vecp force_torque = node.sum_force_and_torque(coords, forces);
213  flv::iterator p = c.torsions.begin();
214  fl& d = *p; // reference
215  ++p;
216  branches_derivative(children, node.get_origin(), coords, forces, force_torque, p);
217  node.set_derivative(force_torque, d);
218  assert(p == c.torsions.end());
219  }
220 };
221 
222 template<typename T> // T = main_branch, branch, flexible_body
223 void count_torsions(const T& t, sz& s) {
224  t.node.count_torsions(s);
225  VINA_FOR_IN(i, t.children)
226  count_torsions(t.children[i], s);
227 }
228 
231 
232 template<typename T> // T == flexible_body || main_branch
233 struct vector_mutable : public std::vector<T> {
234  template<typename C>
235  void set_conf(const atomv& atoms, vecv& coords, const std::vector<C>& c) { // C == ligand_conf || residue_conf
236  VINA_FOR_IN(i, (*this))
237  (*this)[i].set_conf(atoms, coords, c[i]);
238  }
239  szv count_torsions() const {
240  szv tmp(this->size(), 0);
241  VINA_FOR_IN(i, (*this))
242  ::count_torsions((*this)[i], tmp[i]);
243  return tmp;
244  }
245  template<typename C>
246  void derivative(const vecv& coords, const vecv& forces, std::vector<C>& c) const { // C == ligand_change || residue_change
247  VINA_FOR_IN(i, (*this))
248  (*this)[i].derivative(coords, forces, c[i]);
249  }
250 };
251 
252 template<typename T, typename F> // tree or heterotree - like structure
253 void transform_ranges(T& t, const F& f) {
254  t.node.transform(f);
255  VINA_FOR_IN(i, t.children)
256  transform_ranges(t.children[i], f);
257 }
258 
259 #endif