Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
AtomTree.hh
Go to the documentation of this file.
1 // -*- mode:c++;tab-width:2;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t -*-
2 // vi: set ts=2 noet:
3 //
4 // (c) Copyright Rosetta Commons Member Institutions.
5 // (c) This file is part of the Rosetta software suite and is made available under license.
6 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
7 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
8 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
9 
10 /// @file core/kinematics/AtomTree.hh
11 /// @brief Atom tree class
12 /// @author Phil Bradley
13 
14 
15 #ifndef INCLUDED_core_kinematics_AtomTree_hh
16 #define INCLUDED_core_kinematics_AtomTree_hh
17 
18 
19 // Unit headers
21 
22 // Package headers
23 #ifdef WIN32
25 #endif
26 // AUTO-REMOVED #include <core/kinematics/AtomPointer.hh>
27 // AUTO-REMOVED #include <core/kinematics/Edge.fwd.hh>
28 #include <core/kinematics/Jump.hh>
30 #include <core/kinematics/Stub.hh>
31 #include <core/kinematics/tree/Atom.hh> // apl temp, until all of AtomTree's methods are moved into its .cc file
32 #ifdef WIN32
34 #endif
35 #include <core/id/AtomID.hh>
36 #include <core/id/DOF_ID.hh>
40 
41 // ObjexxFCL headers
42 // AUTO-REMOVED #include <ObjexxFCL/FArray1D.hh>
43 
44 // Numeric headers
45 // AUTO-REMOVED #include <numeric/all.fwd.hh>
46 // AUTO-REMOVED #include <numeric/conversions.hh>
47 #include <numeric/xyzMatrix.hh>
48 #include <numeric/xyzVector.hh>
49 
50 // Utility headers
51 #include <utility/pointer/ReferenceCount.hh>
52 
53 // C++ headers
54 #include <algorithm>
55 #include <cmath>
56 #include <cstdlib>
57 //#include <iostream>
58 //#include <iosfwd>
59 #include <cassert>
60 // AUTO-REMOVED #include <vector>
61 //#include <string>
62 #include <map>
63 // AUTO-REMOVED #include <list>
64 
65 #include <core/id/AtomID_Map.hh>
69 #include <utility/vector1.hh>
70 
71 
72 
73 namespace core {
74 namespace kinematics {
75 
76 
77 /// @brief The AtomTree class is a wrapper for a tree of kinematic Atoms.
78 ///
79 ///the responsibilities of the class are:
80 ///
81 ///@li 1. maintain a map from AtomID's to Atom's for fast lookup
82 ///
83 ///@li 2. keep the internal and xyz coords of the Atoms in sync.
84 /// Note that this sync'ing is handled
85 /// in a lazy fashion, analogous to the way the current pose handles
86 /// refolding. As a result geting and setting of coords can trigger
87 /// coordinate updates.
88 ///
89 ///@li 3. gatekeep modification of internal or xyz coords for the Atoms
90 /// (necessary for #2)
91 ///
92 ///@li 4. serve out the xyz coords for updating a pose/conformation object
93 ///
94 ///@li 5. identify DOF_ID's that correspond to torsion angles (eg phi,psi,chi)
95 /// specified by 4 AtomID's. Do this in a way that enables fast
96 /// lookup, eg cacheing the results of previous calls (?)
97 /// Note that some torsions will not correspond exactly to a DOF of
98 /// an Atom, eg chi1 when we are folding c->n, necessitating
99 /// calculation of an offset. We should be able to handle getting/setting
100 /// of these torsion angles as well as handing back the DOF_ID
101 /// (the last one is necessary when setting up the DOF_IDMask for
102 /// minimization given a MoveMap object).
103 ///
104 /// See @ref atomtree_overview "AtomTree overview and concepts" for details.
105 ///
107 {
108 
109 public: // Types
110  // ids
112  //typedef id::AtomID_Map AtomID_Map;
118 
119  typedef std::vector< AtomID > AtomIDs;
120 
121  // for fragment insertions
122  typedef std::map< AtomID, Vector > FragXYZ;
123  typedef std::map< StubID, RT > FragRT;
124 
125  typedef tree::Atom Atom;
128 
129 public: // Creation
130 
131 
132  ////////////////////////////
133  /// @brief construction: from a tree of atoms;
134  ///
135  // note that we steal the atoms, ie it's incorporated into the AtomTree,
136  // not cloned
137  AtomTree( AtomPointer2D const & new_atom_pointer, bool const from_xyz = true );
138 
139  /// @brief default constructor
140  AtomTree();
141 
142  /// @brief Destructor
143  virtual
144  ~AtomTree();
145 
146  /// @brief copy ctor
147  AtomTree( AtomTree const & src );
148 
149 public: // Assignment
150 
151 
152  /// @brief Copy assignment, makes complete copy of another AtomTree
153  AtomTree &
154  operator=( AtomTree const & src );
155 
156 public:
157  /// @brief Weak-pointer setter. The object that instantiates an owning pointer to an AtomTree object
158  /// must hand that AtomTree a weak pointer to itself so that the AtomTree may share that weak pointer
159  /// with other AtomTrees. Such sharing allows for crucial speedups when copying between AtomTrees.
160  /// If the object that instantiates this AtomTree does not provide it with a pointer-to-self, the
161  /// AtomTree will still function, but it will not share its pointers properly.
162  void set_weak_pointer_to_self( AtomTreeCAP self_pointer );
163 
164 public: // Methods
165 
166  /// @brief number of residues
167  Size
168  size() const
169  {
170  return atom_pointer_.size();
171  }
172 
173  /// the atom with this AtomID in the current AtomID_Map?
174  /// @brief true only if AtomID is in the range of the map and its Atom pointer has value
175  bool
176  has( AtomID const & id ) const
177  {
178  return ( atom_pointer_.has( id ) && ( atom_pointer_[ id ] != 0 ) );
179  }
180 
181  /**
182  /// @brief add an atom id1 to the AtomTree whose parent is id2
183  void
184  add_atom(
185  AtomID const & id1,
186  AtomID const & id2,
187  bool const add_bonded_atom,
188  bool const from_xyz
189  );
190  **/
191 
192  /**
193  void
194  setup_backrub_segment(
195  utility::vector1< AtomID > const & mainchain,
196  AtomID const & downstream_id, // mainchain child of last atom in mainchain vector
197  utility::vector1< std::pair< Size, Size > > const & edges,
198  Size const first_new_pseudo_residue
199  );
200  **/
201 
202  /**
203  ///////////////////////////////////////////////////////////////////////////////////
204  /// @brief modification of topology: atoms are incorporated into tree, not cloned
205  void
206  insert_subtree(
207  Atom * const subtree_root,
208  AtomID const & anchor_id,
209  bool const insert_at_front
210  );
211 
212  void
213  insert_subtree_into_bond(
214  Atom * const subtree_root,
215  AtomID const & old_child_id,
216  AtomID const & new_parent_id
217  );
218  **/
219 
220  // replaces the subtree defined by the list of AtomIDs old_atoms
221  // with the tree of atoms in src;
222  //
223  // the "root" of the old tree is identified and is replaced by
224  // src.root()
225  //
226  // outgoing connections (links from the old_tree to atoms in the
227  // current tree that are not being
228  // deleted) are rewired using the mapping defined by the "atom_map"
229  // argument. IE, atom_map must define a mapping from each atom_id
230  // in the old_tree which has children that are not in the old_tree,
231  //
232  /// @brief replace any subtree of atoms in the atom tree by a new tree of atoms
233  /**
234  void
235  replace_subtree(
236  Atom * const subtree_root,
237  AtomIDs const & old_atoms,
238  id::AtomID_Map< AtomID > const & atom_map
239  );
240  **/
241 
242  void
244  id::BondID const & incoming,
245  utility::vector1< id::BondID > const & outgoing,
246  AtomPointer1D const & new_atoms // this will be the new slice of our atom_pointer
247  );
248 
249 
250  /// @brief Useful for guaranteeing that a stub remains within a single residue
251  void
252  promote_sameresidue_nonjump_child( AtomID const & parent_atom_id );
253 
254  /// @brief Deletes atoms for seqpos.
255  /// Does not renumber other atoms -- need to call update_sequence_numbering for that
256  /// designed for the simple case of 1 incoming connecting and 0 or 1 outgoing connection,
257  /// where the desired behavior is to rewire the outgoing connection in place of seqpos' tree
258  void
259  delete_seqpos( Size const seqpos );
260 
261  /// @brief updates the Atom's AtomID's and the atom_pointer array
262  void
264  Size const new_size,
265  utility::vector1< int > const & old2new
266  );
267 
268  /// @brief replaces the entire tree
269  void
270  replace_tree( AtomPointer2D const & new_atom_pointer, bool const from_xyz = true );
271 
272 
273  /// @brief copy the internal and xyz coords from src tree, which should have the same topology as me
274  void
275  copy_coords(
276  AtomTree const & src
277  );
278 
279 
280  /// @brief setters
281  void
282  set_dof( DOF_ID const & id, Real const setting );
283 
284  /// @brief set a specific atom xyz position
285  void
286  set_xyz( AtomID const & id, PointPosition const & xyz );
287 
288  /// @brief simultaniously set several atom xyz positions
289  void
291 
292  /// @brief set a specific jump transform
293  void
294  set_jump( AtomID const & id, Jump const & jump );
295 
296  /// @brief set a specific jump transform and immediately refold downstream atoms
297  void
298  set_jump_now( AtomID const & id, Jump const & jump );
299 
300  /// @brief Set the transform between two stubs, returns the atomid of the jump atom which moved (for book-keeping)
301  AtomID
303  StubID const & stub_id1,
304  StubID const & stub_id2,
305  RT const & target_rt
306  );
307 
308  /// @brief get the transform between two stubs
309  RT
311  StubID const & stub_id1,
312  StubID const & stub_id2
313  ) const;
314 
315  /// @brief set a torsion angle "setting" to a specifc DOF derived by the four atoms
316  DOF_ID
318  AtomID const & atom1,
319  AtomID const & atom2,
320  AtomID const & atom3,
321  AtomID const & atom4,
322  Real const setting
323  );
324 
325  DOF_ID
327  AtomID const & atom1,
328  AtomID const & atom2,
329  AtomID const & atom3,
330  Real const setting
331  );
332 
333  DOF_ID
335  AtomID const & atom1,
336  AtomID const & atom2,
337  Real const setting
338  );
339 
340 
341 // id::AtomID
342 // make_stub_transform(
343 // id::StubID const & stub1_id, // triplet of atomids
344 // id::StubID const & stub2_id, // triplet of atomids
345 // RT const & target_rt,
346 // utility::vector1< id::BondID > const & preferred_bonds
347 // );
348 
349  /// @brief generates a "domain_map" defining the rigid body regions
350  /// whose internal coords have not changed, according to the
351  /// informaiton in the two bool Mask's
352  /// update domain map from dof_moved and xyz_moved
353  void
355  DomainMap & domain_map,
356  AtomID_Mask const & dof_moved,
357  AtomID_Mask const & xyz_moved
358  ) const;
359 
360 
361  /// @brief clear the content of an AtomTree object, delete root atom and all pointers
362  void
363  clear();
364 
365  void
367  StubID const & instub_id,
368  FragRT const & outstub_transforms,
369  FragXYZ const & frag_xyz,
370  utility::vector1< AtomID > & moving_atoms
371  );
372 
373 
374  /// @brief The AtomTree provides to the Conformation object a list of residues
375  /// whose xyz coordinates have changed. When the Conformation has finished reading off
376  /// residues that have changed from the AtomTree, and has copied the coordinates of
377  /// those residues into its conformation::Residue objects, it informs the AtomTree
378  /// to reset this list by a call to mark_changed_residues_registered
381 
384 
385  /// @brief The AtomTree provides a list of residues who's xyz coordinates have changed
386  /// to the Conformation object. When the Conformation has finished reading off residues
387  /// that have changed from the AtomTree, and has copied the coordinates of those residues
388  /// into its conformation::Residue objects, it informs the AtomTree to reset this list
389  /// by a call to mark_changed_residues_registered
390  void
392 
393 public: // Properties
394 
395 
396  /// @brief is there any atom in the tree yet?
397  bool
398  empty() const
399  {
400  return ( root_ == 0 );
401  }
402 
403  /// @brief const-access to the root of the tree
404  AtomCOP
405  root() const
406  {
407  return root_;
408  }
409 
410 
411  // accessors -- which may trigger coordinate updates
412  /// @brief get value of DOF( PHI, THETA, D, RB1, ....) given its DOF_ID
413  Real
414  dof( DOF_ID const & id ) const;
415 
416  /// @brief get xyz position of an atom given its AtomID
417  PointPosition const &
418  xyz( AtomID const & id ) const;
419 
420 
421  Atom const &
422  atom( AtomID const & id ) const;
423 
424  Atom const &
425  atom_dont_do_update( AtomID const & id ) const;
426 
427 
428  Jump const &
429  jump( AtomID const & id ) const;
430 
431  /// @brief a wrapper function to get the DOF_ID of a torsion angle given those four atoms which define this torsion
432  /** another version of this functino also calculates an offset value, which is not needed here*/
433  DOF_ID
435  AtomID const & atom1,
436  AtomID const & atom2,
437  AtomID const & atom3,
438  AtomID const & atom4
439  ) const
440  {
441  Real offset;
442  return torsion_angle_dof_id( atom1, atom2, atom3, atom4, offset );
443  }
444 
445  /// @brief get the DOF_ID of a torsion angle given those four atoms which define this torsion
446  DOF_ID
448  AtomID const & atom1_in_id,
449  AtomID const & atom2_in_id,
450  AtomID const & atom3_in_id,
451  AtomID const & atom4_in_id,
452  Real & offset
453  ) const;
454 
455 
456  /// @brief get the DOF_ID of a bond angle given those 3 atoms which define this torsion
457  DOF_ID
459  AtomID const & atom1_in_id,
460  AtomID const & atom2_in_id,
461  AtomID const & atom3_in_id,
462  Real & offset
463  ) const;
464 
465 
466  /// @brief get the DOF_ID of a bond length given those 2 atoms which define this torsion
467  DOF_ID
469  AtomID const & atom1_in_id,
470  AtomID const & atom2_in_id
471  ) const;
472 
473  /// @brief calculate torsion angle defined by four atoms in the atom tree
474  Real
476  AtomID const & atom1,
477  AtomID const & atom2,
478  AtomID const & atom3,
479  AtomID const & atom4
480  ) const;
481 
482  Real
483  bond_angle(
484  AtomID const & atom1,
485  AtomID const & atom2,
486  AtomID const & atom3
487  ) const;
488 
489  Real
490  bond_length(
491  AtomID const & atom1,
492  AtomID const & atom2
493  ) const;
494 
495 
496  void
497  set_jump_atom_stub_id( StubID const & id );
498 
499  Stub
500  stub_from_id( StubID const & id ) const
501  {
502  if ( id.center().valid() ) {
503  return Stub( xyz( id.center() ), xyz( id.atom1 ), xyz( id.atom2 ), xyz( id.atom3 ) );
504  } else {
505  return Stub( xyz( id.atom1 ), xyz( id.atom2 ), xyz( id.atom3 ) );
506  }
507  }
508 
509 private:
510 
511  /// @brief When an atom tree copies the topology of another atom tree, it must
512  /// register itself as a topological observer of that other tree. When the other
513  /// tree changes its topology, then the tree being observed must notify its
514  /// observers that they are no longer a topological copy of this tree. An atom
515  /// tree may only be the topological copy of a single other atom tree, though several
516  /// atom trees may be copies of a single atom tree.
517  void attach_topological_observer( AtomTreeCAP observer ) const;
518 
519  /// @brief When an atom tree changes its topology, it must inform all of its
520  /// observers that they are no longer the same topology as this tree.
521  void notify_topological_change( AtomTreeCAP observee ) const;
522 
523  /// @brief When an atom tree observing this tree decides it wants to become an observer
524  /// of another tree, it must notify the tree that it formerly observed of this change.
525  void detatch_topological_observer( AtomTreeCAP observer ) const;
526 
527 public:
528  /// Functions only necessary for unit tests
529 
530  /// @brief For testing purposes only: report the address of the AtomTree this tree
531  /// is a topological copy of. The fact that AtomTrees keep track of other atom trees
532  /// is "private" in the sense that no other class needs to worry about it. However,
533  /// to *test* that the topological match algorithm is working properly, this private
534  /// data needs to be readable. Do not use this function outside of the unit tests.
537  return topological_match_to_;
538  }
539 
540  /// @brief For testing purposes only: report the list of observer AtomTrees that
541  /// are topological copies of this tree. The fact that AtomTrees keep track of
542  /// other atom trees is "private" in the sense that no other class needs to worry
543  /// about it. However, to *test* that the topological match algorithm is working
544  /// properly, this private data needs to be readable. Do not use this function
545  /// outside of the unit tests.
548  return topological_observers_;
549  }
550 
551 
552 private: // Helper Methods for fragment insertion
553 
554  /// @brief Deduce root_ from atom_pointer_ -- look for atom with atom->parent() == 0
555  void
557 
558  void
560  StubID const & id,
561  FragXYZ const & frag_xyz,
562  AtomCOP & frag_atom,
563  AtomCOP & nonfrag_atom
564  ) const;
565 
566 
567  StubID
569  AtomID const & id,
570  FragXYZ const & frag_xyz,
571  bool & fail
572  ) const;
573 
574 
575  Stub
577  StubID const & stubid,
578  FragXYZ const & frag_xyz,
579  bool & fail
580  ) const;
581 
582  Vector
584  AtomID const & id,
585  FragXYZ const & frag_xyz,
586  bool & fail
587  ) const;
588 
589 
590  Vector
592  AtomCOP atom,
593  FragXYZ const & frag_xyz,
594  bool & fail
595  ) const;
596 
597 
598  Vector
600  AtomCOP child,
601  FragXYZ const & frag_xyz,
602  bool & fail
603  ) const;
604 
605 
606  void
608  StubID const & instub_id,
609  FragRT const & outstub_transforms,
610  FragXYZ const & frag_xyz,
611  utility::vector1< AtomID > & moving_atoms
612  );
613 
614 private: // Methods
615 
616  /// @brief bookkeeping -- set the Atoms' atomIDs from the atom_pointer_ array
617  void
619 
620 
621  /// @brief Convenience when we want an Atom*
622  AtomOP
623  atom_pointer( AtomID const & id )
624  {
625  return atom_pointer_[ id ]();
626  }
627 
628  /// @brief Convenience when we want an Atom*
629  AtomCOP
630  atom_pointer( AtomID const & id ) const
631  {
632  return atom_pointer_[ id ]();
633  }
634 
635  /// @brief Update the internal coordinates using the xyz (cartesian) coords
636  /// these two private functions are for maintaining synchrony between the
637  /// internal and xyz coords
638  ///
639 
640  void
641  update_internal_coords() const;
642 
643  /// @brief Update the xyz coordinates using the internal coords
644  void
645  update_xyz_coords() const;
646 
647 
648  /// @brief Notify self of new tree topology
649  /// Useful if we move to caching some things that depend on the tree
650  /// @note Probably need to go through and put more calls of this guy
651  void
653 
654 private: // Fields
655 
656  /// @brief A weak pointer to self (this). The weak pointer must be provided to the AtomTree immediately after creation.
657  /// The weak pointer
659 
660  /// @brief Root Atom
662 
663  /// @brief Atom pointers map (map[AtomID] = AtomPointer)
665 
666  /// @brief List of the jump atom ID's, excluding the root. Order matters (for movemap indexing)
667  //utility::vector1< AtomID > jump_atoms_; // NOT HERE YET
668 
669  /// @brief Internal coords out of date?
671 
672  /// @brief XYZ coords out of date?
674 
675  /// @brief pointer to the atom tree this tree has an exact topological match to
676  /// since that tree was the last tree copied from without subsequence topological
677  /// modifications -- or at most one modification when that tree copied this
678  /// tree's topology
680 
681  /// @brief pointers to all atom trees that are observing this tree's topology.
682  /// On topological changes (including the destruction of this tree!),
683  /// each of these trees have their topological_match_to_
684  /// pointers set to null and this list is cleared.
686 
687  /// @brief A list of the atoms that have had changed DOFs since the last refold.
689  /// @brief A list of residues that have had xyz coordinate changes since the last
690  /// time the owning Conformation object has asked for an update.
692 
693  /// @ (SOON) A list of residues that have had DOF changes since the last
694  /// time the owning Conformation object has asked for an update.
695  //ResidueCoordinateChangeListOP internal_coordinate_residues_changed_;
696 
697 
698 }; // AtomTree
699 
700 
701 } // namespace kinematics
702 } // namespace core
703 
704 
705 #endif // INCLUDED_core_kinematics_AtomTree_HH