IMP logo
IMP Reference Guide  develop.63b38c487d,2024/12/21
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-2022 IMP Inventors. All rights reserved.
6  * \authors Dina Schneidman, Barak Raveh
7  *
8  */
9 
10 #ifndef IMPKINEMATICS_PROTEINKINEMATICS_H
11 #define IMPKINEMATICS_PROTEINKINEMATICS_H
12 
13 #include <IMP/kinematics/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 
28 IMPKINEMATICS_BEGIN_NAMESPACE
29 
30 // public:
31 enum ProteinAngleType {
32  PHI,
33  PSI,
34  CHI,
35  CHI1,
36  CHI2,
37  CHI3,
38  CHI4,
39  CHI5,
40  OTHER,
41  OTHER2,
42  OTHER3,
43  OTHER4,
44  OTHER5,
45  TOTAL
46 };
47 
48 
49 //! Kinematic structure over a protein, with backbone and side chain dihedrals.
50 //! Should only be applied one over a given set of particles.
51 //!
52 //! Note: Particles that are handled by this class should never be decorated
53 //! with IMP::core::RigidBody externally, as this could lead to unexpected behavior
54 //! (e.g., wrong coordinates) and it cannot be detected by IMP at the current time.
55 class IMPKINEMATICSEXPORT ProteinKinematics : public IMP::Object {
56 
57 
58 
59  public:
60 
61  //! Constructor with all phi/psi rotatable
62  /**
63  @param mhd hierarchy of a protein, obtained by e.g. reading a Pdb using IMP::Atom::read_pdb()
64  @param flexible_backbone whether all phi/psi angles are flexible
65  @param flexible_side_chains whether all chi angles are flexible
66  (currently not implemented)
67  */
68  ProteinKinematics(atom::Hierarchy mhd, bool flexible_backbone = true,
69  bool flexible_side_chains = false);
70 
71  // Constructor; torsions from custom_dihedral_angles list are rotatable
72  /**
73  @param mhd hierarchy of a protein, obtained by e.g. reading a Pdb using IMP::Atom::read_pdb()
74  @param flexible_residues all residues for which non-custom backbone of side-chain dihedrals may
75  be flexible (side-chains are not implemented as of May 2017)
76  @param custom_dihedral_angles IMP::ParticleIndexQuads - list of four particles that define a
77  custom dihedral angle
78  @param flexible_backbone whether all phi/psi angles in flexible_residues are flexible
79  @param flexible_side_chains whether all chi angles in flexible_residues are flexible
80  (currently not implemented)
81  */
83  const atom::Residues& flexible_residues,
84  const ParticleIndexQuads custom_dihedral_angles,
85  atom::Atoms open_loop_bond_atoms = atom::Atoms(),
86  bool flexible_backbone = true,
87  bool flexible_side_chains = false);
88 
89  // Constructor; torsions from custom_dihedral_angles list are rotatable
90  /**
91  @param mhd hierarchy of a protein, obtained by e.g. reading a Pdb using IMP::Atom::read_pdb()
92  @param flexible_residues all residues for which non-custom backbone of side-chain dihedrals may
93  be flexible (side-chains are not implemented as of May 2017)
94  @param custom_dihedral_atoms lists of four atoms that define a custom dihedral angle !!Only accessible from C++
95  use custom_dihedral_angles if constructingi n python.
96  @param open_loop_bond_atoms TODO: document
97  @param flexible_backbone whether all phi/psi angles in flexible_residues are flexible
98  @param flexible_side_chains whether all chi angles in flexible_residues are flexible
99  (currently not implemented)
100  */
101 
103  const atom::Residues& flexible_residues,
104  const std::vector<atom::Atoms>& custom_dihedral_atoms,
105  atom::Atoms open_loop_bond_atoms = atom::Atoms(),
106  bool flexible_backbone = true,
107  bool flexible_side_chains = false);
108 
109  // Constructor; torsions from custom_dihedral_angles list are rotatable
110  /**
111  @param mhd hierarchy of a protein, obtained by e.g. reading a Pdb using IMP::Atom::read_pdb()
112  @param flexible_residues all residues for which non-custom backbone of side-chain dihedrals may
113  be flexible (side-chains are not implemented as of May 2017)
114  @param custom_dihedral_angles IMP::ParticleIndexQuads - list of four particles that define a
115  custom dihedral angle
116  @param custom_dihedral_angle_types the types of all custom dihedral angles (a list of the same size)
117  @param open_loop_bond_atoms TODO: document
118  @param flexible_backbone whether all phi/psi angles in flexible_residues are flexible
119  @param flexible_side_chains whether all chi angles in flexible_residues are flexible
120  (currently not implemented)
121  */
122 
124  const atom::Residues& flexible_residues,
125  const ParticleIndexQuads custom_dihedral_angles,
126  const std::vector<ProteinAngleType>& custom_dihedral_angle_types,
127  atom::Atoms open_loop_bond_atoms = atom::Atoms(),
128  bool flexible_backbone = true,
129  bool flexible_side_chains = false);
130 
131  private:
132  //! the actual construction is done here,
133  //! see constructors for documentation
134  /**
135  initialize the protein kinematics object
136  @param flexible_residues all reidues whose phi/psi angles are activated
137  @param custom_dihedral_angles IMP::ParticleIndexQuads - list of four particles that define a
138  custom dihedral angle
139  @param custom_dihedral_atoms lists of four atoms that define a custom dihedral angle !!Only accessible from C++
140  use custom_dihedral_angles if constructingi n python.
141  @param custom_dihedral_angle_types the types of all custom dihedral angles (a list of the same size)
142  @param open_loop_bond_atoms TODO: document
143  @param flexible_backbone are dihedral joints defined for the backbone
144  @param flexible_side_chains are dihedral joints defined for the side chains
145  */
146  void init( const atom::Residues& flexible_residues,
147  const ParticleIndexQuads custom_dihedral_angles,
148  const std::vector<atom::Atoms>& custom_dihedral_atoms,
149  const std::vector<ProteinAngleType>& custom_dihedral_angle_types,
150  atom::Atoms open_loop_bond_atoms,
151  bool flexible_backbone,
152  bool flexible_side_chains);
153 
154  void add_edges_to_rb_graph(const std::vector<atom::Atoms>& dihedral_angles);
155 
156  std::vector<atom::Atoms> quick_hack_converter(Model* m, const ParticleIndexQuads piqs);
157 
158  public:
159  /* Access methods */
160 
161  //! get phi angle associated with residue r
162  double get_phi(const atom::Residue r) const {
163  // TODO: what happens if user queries N' residue?
164  return get_phi_joint(r)->get_angle();
165  }
166 
167  //! get psi angle associated with residue r
168  double get_psi(const atom::Residue r) const {
169  // TODO: what happens if user queries C' residue?
170  return get_psi_joint(r)->get_angle();
171  }
172 
173  //! returns a list of all joints associated with the ProteinKinematics structure
175 
176  DihedralAngleRevoluteJoints get_loop_joints() { return loop_joints_;
177  // TODO: what are loop joints?
178  }
179 
180  //! return joints sorted by BFS traversal from the
181  //! root(s) of the kinematic structure
184  for(Joint *j : kf_->get_ordered_joints() ){
185  ret.push_back(dynamic_cast<DihedralAngleRevoluteJoint*>(j));
186  }
187  return ret;
188  }
189 
190  //! returns the kinematic forest associated with this ProteinKinematics
191  //! object
193 
194  //! get all rigid bodies that were automatically
195  //! generated in the tree
197 
198  // TODO: add chi
199 
200  /* Modifier methods */
201 
202  void set_phi(const atom::Residue r, double angle) {
203  get_phi_joint(r)->set_angle(angle);
204  kf_->update_all_external_coordinates();
205  }
206 
207  void set_psi(const atom::Residue r, double angle) {
208  get_psi_joint(r)->set_angle(angle);
209  kf_->update_all_external_coordinates();
210  }
211 
212  // TODO: add chi
213 
215 
216  void build_topology_graph();
217 
218  void order_rigid_bodies(const std::vector<atom::Atoms>& dihedral_angles,
219  const std::vector<atom::Atoms>& phi_angles,
220  const std::vector<atom::Atoms>& psi_angles,
221  const std::vector<atom::Atoms>& chi1_angles,
222  const std::vector<atom::Atoms>& chi2_angles,
223  const std::vector<atom::Atoms>& chi3_angles,
224  const std::vector<atom::Atoms>& chi4_angles,
225  const std::vector<atom::Atoms>& chi5_angles,
226  atom::Atoms open_loop_bond_atoms);
227 
228  //! mark specified dihedral angles as rotatable - remove the edges of the
229  //! rotatable bonds from graph_, and add them to rb_graph
230  void mark_rotatable_angles(const std::vector<atom::Atoms>& dihedral_angles);
231 
232  //! mark a single dihedral angle as rotatable - remove the edge of the
233  //! rotatable bond from graph_, and add it to rb_graph
234  void mark_rotatable_angle(const std::vector<atom::Atom>& dihedral_angle);
235 
236  //! automatically build rigid bodies for the protein kinematics structure
237  void build_rigid_bodies();
238 
239  //void add_dihedral_joints(const std::vector<atom::Atoms>& dihedral_angles,
240  // const std::vector<ProteinAngleType>);
241 
242  void add_dihedral_joints(const std::vector<atom::Residue>& residues,
243  ProteinAngleType angle_type,
244  const std::vector<atom::Atoms>& dihedral_angles);
245 
246  void add_dihedral_joint(const atom::Residue r,
247  ProteinAngleType angle_type,
248  const atom::Atoms& atoms);
249 
250  void open_loop(atom::Atoms open_loop_bond_atoms);
251 
252  public:
253  /* Joint access methods */
254  DihedralAngleRevoluteJoint* get_phi_joint(const atom::Residue r) const {
255  return (DihedralAngleRevoluteJoint*)joint_map_.get_joint(r, PHI);
256  }
257 
258  DihedralAngleRevoluteJoint* get_psi_joint(const atom::Residue r) const {
259  return (DihedralAngleRevoluteJoint*)joint_map_.get_joint(r, PSI);
260  }
261 
262  DihedralAngleRevoluteJoint* get_other_joint(const atom::Residue r) const {
263  return (DihedralAngleRevoluteJoint*)joint_map_.get_joint(r, OTHER);
264  }
265 
266  DihedralAngleRevoluteJoint* get_chi1_joint(const atom::Residue r) const {
267  return (DihedralAngleRevoluteJoint*)joint_map_.get_joint(r, CHI1);
268  }
269  DihedralAngleRevoluteJoint* get_chi2_joint(const atom::Residue r) const {
270  return (DihedralAngleRevoluteJoint*)joint_map_.get_joint(r, CHI2);
271  }
272  DihedralAngleRevoluteJoint* get_chi3_joint(const atom::Residue r) const {
273  return (DihedralAngleRevoluteJoint*)joint_map_.get_joint(r, CHI3);
274  }
275  DihedralAngleRevoluteJoint* get_chi4_joint(const atom::Residue r) const {
276  return (DihedralAngleRevoluteJoint*)joint_map_.get_joint(r, CHI4);
277  }
278  DihedralAngleRevoluteJoint* get_chi5_joint(const atom::Residue r) const {
279  return (DihedralAngleRevoluteJoint*)joint_map_.get_joint(r, CHI5);
280  }
281 
282  DihedralAngleRevoluteJoint* get_joint(const atom::Residue r, ProteinAngleType angle) const {
283  return (DihedralAngleRevoluteJoint*)joint_map_.get_joint(r, angle);
284  }
285 
286 
287  //DihedralAngleRevoluteJoints get_joints(const atom::Residue r) const;
288 
289 #ifndef IMP_DOXYGEN
290  // A map between residue phi/psi and joints
291  class AngleToJointMap {
292  public:
293  // Joint access
294  Joint* get_joint(const atom::Residue r,
295  ProteinAngleType angle_type) const;
296 
297  // store Joint
298  void add_joint(const atom::Residue r, ProteinAngleType angle_type,
299  Joint* joint);
300 
301  private:
302  /* mapping to phi/psi/chi for a specific residue.
303  the joints are stored using ProteinAngleType as an index */
304  typedef std::vector<Joint*> ResidueJoints;
305  /* mapping between residue and its joints */
306  boost::unordered_map<ParticleIndex, ResidueJoints>
307  residue_to_joints_;
308  };
309 #endif // IMP_DOXYGEN
310 
311 
312  private:
313 
314  typedef boost::adjacency_list<
315  boost::vecS, boost::vecS, boost::undirectedS > Graph;
316 
317  // protein hierarchy
318  atom::Hierarchy mhd_;
319 
320 
321  //! all atom particles in the protein
322  ParticlesTemp atom_particles_;
323 
324  // topology graph: nodes = atoms, edges = bonds - includes all the atoms and non-rotatable bonds from the input protein hierarchy
325  Graph graph_;
326 
327  // rigid bodies topology graph: node = rigid bodies, edges = joints -
328  Graph rb_graph_;
329 
330  // dfs order of rigid bodies
331  std::vector<int> rb_order_, parents_;
332 
333  int largest_rb_;
334 
335  // mapping between atom ParticleIndex and node number in graph_ and rb_graph_
336  boost::unordered_map<ParticleIndex, int> particle_index_to_node_map_, rb_particle_index_to_node_map_;
337 
338  Vector<ParticleIndex> node_to_particle_index_map_;
339 
340  // rigid bodies
341  core::RigidBodies rbs_;
342 
343  // joints
345 
346  PointerMember<kinematics::KinematicForest> kf_;
347 
348  // map between residue phi/psi/chis and joints
349  AngleToJointMap joint_map_;
350 
351  boost::unordered_map<int, boost::unordered_map<int, Pointer<DihedralAngleRevoluteJoint> > > rigid_bodies_2_joint_map_;
352 
353  DihedralAngleRevoluteJoints loop_joints_;
354 };
355 
357 
358 IMPKINEMATICS_END_NAMESPACE
359 
360 #endif /* IMPKINEMATICS_PROTEINKINEMATICS_H */
DihedralAngleRevoluteJoints get_ordered_joints()
double get_phi(const atom::Residue r) const
get phi angle associated with residue r
#define IMP_OBJECT_METHODS(Name)
Define the basic things needed by any Object.
Definition: object_macros.h:25
Simple atom decorator.
A more IMP-like version of the std::vector.
Definition: Vector.h:50
Class for storing model, its restraints, constraints, and particles.
Definition: Model.h:86
The standard decorator for manipulating molecular structures.
Common base class for heavy weight IMP objects.
Definition: Object.h:111
double get_psi(const atom::Residue r) const
get psi angle associated with residue r
functionality for defining rigid bodies
IMP::Vector< IMP::Pointer< DihedralAngleRevoluteJoint > > DihedralAngleRevoluteJoints
DihedralAngleRevoluteJoints get_joints()
returns a list of all joints associated with the ProteinKinematics structure
A class for storing lists of IMP items.
Joint that is parameterized as a dihedral angle between two planes.
#define IMP_OBJECTS(Name, PluralName)
Define the types for storing lists of object pointers.
Definition: object_macros.h:44
A decorator for a residue.
Definition: Residue.h:137
Base class for joints between rigid bodies in a kinematic tree.
Definition: Joint.h:29
Define and manipulate a kinematic structure over a model.
Define and manipulate a kinematic structure over a model.
functionality for defining various revolute kinematic joints between rigid bodies as part of a kinema...