Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
automorphism.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/chemical/automorphism.hh
11 ///
12 /// @brief
13 /// @author Ian W. Davis
14 
15 
16 #ifndef INCLUDED_core_chemical_automorphism_hh
17 #define INCLUDED_core_chemical_automorphism_hh
18 
20 
21 #include <utility/vector1.hh>
22 
23 
24 // Commented by inclean daemon #include <utility/vector1.hh>
25 // Commented by inclean daemon #include <utility/pointer/ReferenceCount.hh>
26 
27 namespace core {
28 namespace chemical {
29 
30 
31 class AutomorphismIterator; // fwd declaration
34 
35 ///@brief Enumerates the automorphisms of a residue, which are basically
36 /// chemical symmetries that affect RMSD calculations.
37 ///
38 ///@details Common automorphisms include flipping a phenyl ring (think Phe chi2)
39 /// or rotating a methyl group (or CF3, if you don't care about H).
40 /// However, they can be much more complicated than that,
41 /// and some cannot be imitated by rotation about a bond.
42 /// Examples include labeling a -CF3 clockwise vs. counterclockwise,
43 /// or swapping the -CF3 branches of -C(CF3)2R.
44 /// See the ligand of PDB 1PQC for a reasonably complex example.
45 ///
46 /// Formally, a graph automorphism is an isomorphism of that graph with itself:
47 /// given a graph G(V,E) and a mapping M that relabels the vertices
48 /// according to M(v) -> v', then M is an automorphism iff
49 /// (M(u),M(v)) is an edge if and only if (u,v) is an edge.
50 /// If the vertices are "colored" (in our case, have atom types), it must also
51 /// be true that M(v) and v have the same color, for all v in V.
52 ///
53 /// Thus you can re-label a phenyl ring
54 ///
55 /// 2 3 6 5 6 3
56 /// 1 4 or 1 4 but not 1 4
57 /// 6 5 2 3 2 5
58 ///
59 /// because in the last case, there are new bonds 6-3 and 2-5,
60 /// and missing bonds 6-5 and 2-3.
61 ///
62 /// See also: OpenEye's OEChem library and its OERMSD() function.
63 ///
65 {
66 public:
67 
68  /// @brief Including H will lead to many, many more automorphisms!
69  AutomorphismIterator(ResidueTypeCOP restype, bool includeH = false):
70  restype_(restype),
71  empty_list_()
72  {
73  natoms_ = (includeH ? restype_->natoms() : restype_->nheavyatoms());
74  curr_.assign(natoms_, 1); // = [1, 1, 1, ..., 1]
75  }
76  virtual ~AutomorphismIterator() {}
77 
78  /// @brief Returns the next automorphism for this residue type
79  /// as a vector that maps "old" atom indices to "new" atom indices.
80  /// Returns an empty vector when no more automorphisms remain.
82  next();
83 
84 private:
85  /// @brief Are atoms i and j potentially interchangeable?
86  /// @details We want this check to be fast but also to eliminate
87  /// as many potential pairings as possible.
88  /// We currently check (1) atom types and (2) number of neighbors.
89  /// We could potentially also check atom types of neighbors,
90  /// but that costs a set comparison or two array sorts, so we don't right now.
91  inline
92  bool
93  can_pair(Size i, Size j);
94 
95  /// @brief Does the current mapping preserve all edges?
96  /// @details That is, if (i,j) is an edge, is (curr_[i],curr_[j]) also an edge?
97  /// Checks all edges (i,j) where j < i, for the supplied i.
98  /// (Edges with j > i can't be checked becaues curr_[j] isn't valid yet.)
99  inline
100  bool
102  AtomIndices const & nbrs = restype_->nbrs(i);
103  for( Size idx = 1, end = nbrs.size(); idx <= end; ++idx ) {
104  Size const j = nbrs[idx];
105  if( j > i ) continue;
106  if( !bonded( curr_[i], curr_[j] ) ) return false;
107  }
108  return true;
109  }
110 
111  /// @brief Are atoms i and j bonded to each other?
112  inline
113  bool
114  bonded(Size i, Size j) {
115  return restype_->path_distance(i,j) == 1;
116  }
117 
118 
119 private:
122  /// curr_[i] = current partner for atom i
125 
126 }; // AutomorphismIterator
127 
128 
129 } // namespace chemical
130 } // namespace core
131 
132 #endif // INCLUDED_core_chemical_automorphism_HH