IMP logo
IMP Reference Guide  2.6.1
The Integrative Modeling Platform
ProteinKinematics.h
Go to the documentation of this file.
1 /**
2  * \file IMP/kinematics/ProteinKinematics.h
3  * \brief functionality for defining a kinematic forest for proteins
4  *
5  * Copyright 2007-2016 IMP Inventors. All rights reserved.
6  * \authors Dina Schneidman, Barak Raveh
7  *
8  */
9 
10 #ifndef IMPKINEMATICS_PROTEIN_KINEMATICS_H
11 #define IMPKINEMATICS_PROTEIN_KINEMATICS_H
12 
13 #include "kinematics_config.h"
14 
17 
18 #include <IMP/core/rigid_bodies.h>
19 #include <IMP/atom/Atom.h>
20 
21 #include <boost/unordered_map.hpp>
22 #include <IMP/Vector.h>
23 #include <vector>
24 #include <iostream>
25 
26 #include <boost/graph/adjacency_list.hpp>
27 #include <boost/graph/undirected_dfs.hpp>
28 
29 IMPKINEMATICS_BEGIN_NAMESPACE
30 
31 typedef boost::adjacency_list<
32  boost::vecS, boost::vecS, boost::undirectedS > Graph;
33 
34 class MyDFSVisitor : public boost::default_dfs_visitor {
35 public:
36  MyDFSVisitor(std::vector<int>& dfs_order, std::vector<int>& parents) :
37  dfs_order_(dfs_order), parents_(parents), counter_(0) {}
38 
39  template < typename Vertex, typename Graph >
40  void discover_vertex(Vertex v, const Graph& ) {
41  dfs_order_[v] = counter_;
42  counter_++;
43  }
44 
45  template < typename Edge, typename Graph >
46  void tree_edge(Edge e, const Graph& g) {
47  std::cerr << "tree_edge " << source(e, g) << " -- " << target(e, g)
48  << " dfs_order " << dfs_order_[source(e, g)] << " -- " << dfs_order_[target(e, g)] << std::endl;
49  parents_[target(e,g)] = source(e, g);
50  }
51 
52  std::vector<int>& dfs_order_;
53  std::vector<int>& parents_;
54  int counter_;
55 };
56 
57 /**
58  Defines a kinematic structure over a protein, with backbone
59  and side chain dihedrals
60  */
61 class IMPKINEMATICSEXPORT ProteinKinematics {
62  public:
63  /* Constructors */
64 
65  // all phi/psi rotatable
66  ProteinKinematics(atom::Hierarchy mhd, bool flexible_backbone = true,
67  bool flexible_side_chains = false);
68 
69  // only torsions from dihedral_angles list are rotatable
71  const atom::Residues& flexible_residues,
72  const std::vector<atom::Atoms>& dihedral_angles,
73  atom::Atoms open_loop_bond_atoms = atom::Atoms(),
74  bool flexible_backbone = true,
75  bool flexible_side_chains = false);
76 
77  private:
78  //! the actual construction is done here,
79  //! see constructors for documentation
80  void init( const atom::Residues& flexible_residues,
81  const std::vector<atom::Atoms>& dihedral_angles,
82  atom::Atoms open_loop_bond_atoms,
83  bool flexible_backbone,
84  bool flexible_side_chains);
85 
86  void add_edges_to_rb_graph(const std::vector<atom::Atoms>& dihedral_angles);
87 
88  public:
89  /* Access methods */
90 
91  double get_phi(const atom::Residue r) const {
92  return get_phi_joint(r)->get_angle();
93  }
94 
95  double get_psi(const atom::Residue r) const {
96  return get_psi_joint(r)->get_angle();
97  }
98 
99  DihedralAngleRevoluteJoints get_joints() { return joints_; }
100 
101  DihedralAngleRevoluteJoints get_loop_joints() { return loop_joints_; }
102 
103  DihedralAngleRevoluteJoints get_ordered_joints() {
105  IMP_FOREACH(Joint *j, kf_->get_ordered_joints() ){
106  ret.push_back(dynamic_cast<DihedralAngleRevoluteJoint*>(j));
107  }
108  return ret;
109  }
110 
111  KinematicForest* get_kinematic_forest() { return kf_; }
112  // TODO: not sure if we have to return Pointer or just raw pointer
113 
114  core::RigidBodies get_rigid_bodies() { return rbs_; }
115 
116  // TODO: add chi
117 
118  /* Modifier methods */
119 
120  void set_phi(const atom::Residue r, double angle) {
121  get_phi_joint(r)->set_angle(angle);
122  kf_->update_all_external_coordinates();
123  }
124 
125  void set_psi(const atom::Residue r, double angle) {
126  get_psi_joint(r)->set_angle(angle);
127  kf_->update_all_external_coordinates();
128  }
129 
130  // TODO: add chi
131 
132  private:
133  enum ProteinAngleType {
134  PHI,
135  PSI,
136  CHI1,
137  CHI2,
138  CHI3,
139  CHI4,
140  OTHER,
141  TOTAL
142  };
143 
144  void build_topology_graph();
145 
146  void order_rigid_bodies(const std::vector<atom::Atoms>& dihedral_angles,
147  const std::vector<atom::Atoms>& phi_angles,
148  const std::vector<atom::Atoms>& psi_angles,
149  atom::Atoms open_loop_bond_atoms);
150 
151  void mark_rotatable_angles(const std::vector<atom::Atoms>& dihedral_angles);
152 
153  void build_rigid_bodies();
154 
155  void add_dihedral_joints(const std::vector<atom::Atoms>& dihedral_angles);
156 
157  void add_dihedral_joints(const std::vector<atom::Residue>& residues,
158  ProteinAngleType angle_type,
159  const std::vector<atom::Atoms>& dihedral_angles);
160 
161  void add_dihedral_joint(const atom::Residue r,
162  ProteinAngleType angle_type,
163  const atom::Atoms& atoms);
164 
165  void open_loop(atom::Atoms open_loop_bond_atoms);
166 
167  /* Joint access methods */
168  DihedralAngleRevoluteJoint* get_phi_joint(const atom::Residue r) const {
169  return (DihedralAngleRevoluteJoint*)joint_map_.get_joint(r, PHI);
170  }
171 
172  DihedralAngleRevoluteJoint* get_psi_joint(const atom::Residue r) const {
173  return (DihedralAngleRevoluteJoint*)joint_map_.get_joint(r, PSI);
174  }
175 
176  DihedralAngleRevoluteJoint* get_other_joint(const atom::Residue r) const {
177  return (DihedralAngleRevoluteJoint*)joint_map_.get_joint(r, OTHER);
178  }
179 
180  //DihedralAngleRevoluteJoints get_joints(const atom::Residue r) const;
181 
182 #ifndef IMP_DOXYGEN
183  // A map between residue phi/psi and joints
184  class AngleToJointMap {
185  public:
186  // Joint access
187  Joint* get_joint(const atom::Residue r,
188  ProteinAngleType angle_type) const;
189 
190  // store Joint
191  void add_joint(const atom::Residue r, ProteinAngleType angle_type,
192  Joint* joint);
193 
194  private:
195  /* mapping to phi/psi/chi for a specific residue.
196  the joints are stored using ProteinAngleType as an index */
197  typedef std::vector<Joint*> ResidueJoints;
198  /* mapping between residue and its joints */
199  boost::unordered_map<ParticleIndex, ResidueJoints>
200  residue_to_joints_;
201  };
202 #endif // IMP_DOXYGEN
203 
204  private:
205  // protein hierarchy
206  atom::Hierarchy mhd_;
207 
208  // atom particles
209  ParticlesTemp atom_particles_;
210 
211  // topology graph: nodes = atoms, edges = bonds
212  Graph graph_;
213 
214  // rigid bodies topology graph: node = atoms, edges = joints
215  Graph rb_graph_;
216 
217  // dfs order of rigid bodies
218  std::vector<int> rb_order_, parents_;
219 
220  int largest_rb_;
221 
222  // mapping between atom ParticleIndex and node number in the graph
223  boost::unordered_map<ParticleIndex, int> particle_index_to_node_map_, rb_particle_index_to_node_map_;
224 
225  Vector<ParticleIndex> node_to_particle_index_map_;
226 
227  // rigid bodies
228  core::RigidBodies rbs_;
229 
230  // joints
232 
234 
235  // map between residue phi/psi/chis and joints
236  AngleToJointMap joint_map_;
237 
238  boost::unordered_map<int, boost::unordered_map<int, Pointer<DihedralAngleRevoluteJoint> > > rigid_bodies_2_joint_map_;
239 
240  DihedralAngleRevoluteJoints loop_joints_;
241 };
242 
243 IMPKINEMATICS_END_NAMESPACE
244 
245 #endif /* IMPKINEMATICS_PROTEIN_KINEMATICS_H */
Simple atom decorator.
A smart pointer to a reference counted object.
Definition: Pointer.h:87
The standard decorator for manipulating molecular structures.
functionality for defining rigid bodies
A class for storing lists of IMP items.
A decorator for a residue.
Definition: Residue.h:134
Wrapper class for a kinematic forest (collection of trees) made of KinematicNode objects, interconnected by joints. This data structure allows for kinematic control of the tree and interconversion between internal and external coordinates.
functionality for defining various revolute kinematic joints between rigid bodies as part of a kinema...