Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
RotamerDots.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/pack/interaction_graph/RotamerDots.hh
11 /// @brief RotamerDots classes header files - ported from rosetta++
12 /// @author Andrew Leaver-Fay
13 /// @author Ron Jacak
14 
15 #ifndef INCLUDED_core_pack_interaction_graph_RotamerDots_hh
16 #define INCLUDED_core_pack_interaction_graph_RotamerDots_hh
17 
18 // Unit Headers
19 // AUTO-REMOVED #include <core/chemical/AtomType.hh>
23 #include <core/types.hh>
24 
25 // Objexx Headers
26 // AUTO-REMOVED #include <ObjexxFCL/FArray2D.hh>
27 #include <ObjexxFCL/ubyte.hh>
28 
29 // Numeric headers
30 // AUTO-REMOVED #include <numeric/xyzVector.hh>
31 
32 //Utilitiy Headers
33 #include <utility/pointer/ReferenceCount.hh>
34 #include <utility/pointer/owning_ptr.hh>
35 #include <utility/vector1.hh>
36 
37 //C++ Headers
38 #include <vector>
39 
40 #include <ObjexxFCL/FArray2D.fwd.hh>
41 
42 
43 
44 namespace core {
45 namespace pack {
46 namespace interaction_graph {
47 
48 ///
49 /// @begin DotSphere
50 ///
51 /// @brief
52 /// Represents the sphere of dots on the vdW surface of an atom, for use in the LeGrand and Merz method of calculating SASA.
53 ///
54 /// @detailed
55 /// For every atom in a protein, the vdW surface is patterned with dots. Each dot has to keep track of how many other
56 /// residues are "covering" this dot. So, that's 1 character for each dot. Each character is the count of the number of
57 /// residues overlapping with this dot. An assumption we're making here is that a single atom (or really, dot) will never
58 /// be covered by more than 255 residues.
59 ///
60 /// In this implementation of the LeGrand and Merz algorithm, we're going to be using 162 dots per atom. Turns out that
61 /// you can distribute 162 dots evenly on the surface of a sphere.
62 ///
63 /// This class is extremely simple. The RotamerDots class below does all the work of tying a particular residues atoms to
64 /// DotSpheres. As a matter of fact, DotSphere doesn't even know what atom it's representing. It just has the one C-style
65 /// array for the coverage count and that's it.
66 ///
67 class DotSphere {
68 
69 public:
70  DotSphere();
71  ~DotSphere();
72  DotSphere( DotSphere const & rhs );
73  DotSphere const & operator= ( DotSphere const & rhs );
74  bool operator!= ( DotSphere const & rhs );
75 
76  void zero();
77 
78  inline core::Size get_total_dots() const { return NUM_DOTS_TOTAL; }
80 
81  void count_num_covered() const;
84 
85  DotSphere const & operator -= ( DotSphere const & rhs );
86  DotSphere const & operator += ( DotSphere const & rhs );
87 
88  void print( std::ostream & os) const;
89 
90  bool get_dot_covered( core::Size dot_index ) const;
91 
94 
95  static core::Size const NUM_DOTS_TOTAL = 162;
96 
97 private:
98 
101 
102  unsigned char dots_coverage_count_[ NUM_COUNTS_TO_ALLOCATE ]; // sized to 168
104  mutable bool num_covered_current_;
105 
106 };
107 
108 std::ostream & operator<< ( std::ostream & os, DotSphere const & ds );
109 
110 
111 
112 ///
113 /// @begin RotamerDots
114 ///
115 /// @brief
116 /// Handles sphere-sphere overlap calculations for the HPatchInteractionGraph.
117 ///
118 /// @detailed
119 /// One big change from the r++ version of this class is that this class now includes all of the information that was
120 /// previously stored in the RotamerCoords class. Since I'm not storing atoms in trie ordering (perhaps I'll add this
121 /// later), there is no need to have a separate class for the rotamer coordinates.
122 ///
123 /// RotamerDots hold DotSphere objects for the atoms of a given Residue (or really, of the current state on some interaction
124 /// graph Node). Default use of the class will result in RotamerDots objects keeping DotSpheres for every atom of a residue.
125 /// For the hpatch interaction graph, though, we only care about the SASA of the heavy atoms. No need to include the
126 /// hydrogens when looking for hydrophobic patches. By not keeping track of the hydrogens, we save a huge amount of time
127 /// on computing updates to the SASA score because hydrogen atoms generally make up half of a protein. So I'm adding a
128 /// boolean flag to the non-default constructor which toggles whether we're tracking SASA of all atoms, or just the heavy
129 /// atoms.
130 ///
131 /// Two other big changes being made to this class are that 1) the class will now keep track of two kinds of SASA and
132 /// 2) it will no longer keep score or score_is_current variables. The two kinds of SASA the class will keep track of
133 /// are the standard SASA, and a SASA with polar atom radii extended. The expanded polar SASA will only be kept if a
134 /// boolean flag is set at construct time. If not, it will just calculate standard SASA and that's it. The second
135 /// change is that this class is now only keeping track of SASA. RotamerDots objects will not be responsible for calculating
136 /// a score.
137 ///
139 
140 public:
141  RotamerDots();
142  RotamerDots( conformation::ResidueCOP rotamer, bool exclude_hydrogen_atoms = false, bool use_expanded_polar_atom_radii = false );
143  virtual ~RotamerDots();
144  RotamerDots( RotamerDots const & rhs );
145 
146  void copy(RotamerDots const & rhs);
147  RotamerDots const & operator= ( RotamerDots const & rhs );
148  bool operator!= ( RotamerDots const & rhs );
149  // zeros out the dot coverage counts on all atoms. only used to reinit IG's for multiple packing runs.
150  void zero();
151 
152  // do two rotamers have any sphere overlaps? doesn't actually determine which dots are covered if there is overlap.
153  bool overlaps( RotamerDots const & other ) const;
154 
156  rotamer() const;
157 
158  bool state_unassigned() const;
159  core::Size get_num_atoms() const;
161  core::Real get_atom_radius( Size atom_index ) const;
162  core::Real radius_for_attype( Size const attype_index );
165 
166  // add rotamer coverage counts produced by self overlap.
167  void increment_self_overlap();
168 
169  // increments the atom counts on this only, and saves the overlap into the passed in rotamerdotscache
170  void increment_this_and_cache( RotamerDots const & other, RotamerDotsCache & this_overlap_on_other,
171  utility::vector1< utility::vector1< bool > > & atom_atom_overlaps_cache );
172 
173  // rotamerdots frequently have to calculate how they overlap with another rotamerdots object. this method figures it all out.
174  void get_res_res_overlap( RotamerDots const & other_res,
175  utility::vector1< utility::vector1< ObjexxFCL::ubyte > > & res1_covered_by_res2,
176  utility::vector1< utility::vector1< ObjexxFCL::ubyte > > & res2_covered_by_res1,
177  utility::vector1< utility::vector1< bool > > & atom_atom_overlaps_cache ) const;
178 
179  // given two atoms, figures out which dots are covered on both atoms and sets the appropriate bits in the passed in vectors
180  bool get_atom_atom_coverage( Vector const & at1_xyz, Real at1_base_radius, Vector const & at2_xyz, Real at2_base_radius,
181  utility::vector1< ObjexxFCL::ubyte > & at1_sphere_covered, utility::vector1< ObjexxFCL::ubyte > & at2_sphere_covered, Real dist_sq ) const;
182 
183  void increment_from_cached( RotamerDotsCache const & cached_dot_overlap );
184  void decrement_from_cached( RotamerDotsCache const & cached_dot_overlap );
185 
186  // add rotamer coverage counts for dots on both this and other.
187  void increment_both( RotamerDots & other );
188 
189  void increment_both_and_cache( RotamerDots & other_rotamer, RotamerDotsCache & others_dots_covered_by_this,
190  RotamerDotsCache & this_dots_covered_by_other, utility::vector1< utility::vector1< bool > > & atom_atom_overlaps_cache );
191 
192  core::Real get_sasa() const;
193  core::Real get_atom_sasa( Size atom_index ) const;
194 
197 
198  //void write_dot_kinemage( std::ofstream & kinfile );
199 
200  void print( std::ostream & os ) const;
201  std::string name3() const;
202  core::Size seqpos() const;
203 
204  // used by the unit tests only
206 
208 
209  void invert_to_boolmasks(
211  utility::vector1< Size > const & ats_to_update
212  ) const;
213 
214  static core::Vector dot_coord( Size index );
215 
216 private:
217  static void initialize_sasa_arrays();
218 
219  void get_overlap_cache(
220  RotamerDots const & other,
221  RotamerDotsCache & others_dots_covered_by_this,
222  RotamerDotsCache & this_dots_covered_by_other,
223  utility::vector1< utility::vector1< bool > > & atom_atom_overlaps_cache
224  ) const;
225 
226  //void write_dotlist_header( std::ofstream & kinfile, std::string master_name, std::string color );
227  //void write_dot( std::ofstream & kinfile, core::Size atom, core::Size dot, core::Real radius );
228  //void write_dot( std::ofstream & kinfile, numeric::xyzVector< core::Real > const & coord, std::string atname );
229 
230  //numeric::xyzVector< core::Real > const & get_dot_coord( core::Size dot_id );
231  //void initialize_dot_sphere_coordinates_from_file();
232 
233 public:
234  static core::Size const num_bytes_;
237 
238 private:
242 
244  mutable core::Real sasa_;
245  mutable bool sasa_is_current_;
247 
250 
251  static void initialize_dot_coords( utility::vector1< core::Vector > & dot_coords );
252 
253 public: /// TEMP!
254  static ObjexxFCL::FArray2D_int const * lg_angles_;
255  static ObjexxFCL::FArray2D_ubyte const * lg_masks_;
256 
257 };
258 
259 std::ostream & operator<< ( std::ostream & os, RotamerDots const & rd );
260 
261 
262 ///
263 /// @begin RotamerDotsRadiusData
264 ///
265 /// @brief
266 /// A singleton class which reads in database SASA radii files and provides accessors for those values to the RotamerDots class.
267 ///
268 /// @detailed
269 /// The RotamerDots class keeps track of the SASA of some rotamer using DotSphere objects and lots of get overlap calls
270 /// on atoms. The SASA of a given atom (or residue) depends on what radii are used for the atoms. Different program use
271 /// different sets of radii, and for the hpatch score, the polar atom radii are expanded. Previously RotamerDots objects
272 /// would have a static vector member variable that represented the particular set of radii being used. It would also have
273 /// a second static vector member variable that represented the expanded polar version of the radii. So, no matter how
274 /// many instances of RotamerDots objects we created, we only maintained two vectors for the radii.
275 /// Now, we want to make the RotamerDots class only use one set of radii for the hpatch score: the expanded polar radii.
276 /// The super easy solution would be to remove all the logic that keeps track of SASA when using the standard radii and
277 /// make the RotamerDots class only calculate that kind of SASA. But, there will probably be more uses in the future
278 /// for a RotamerDots class that can calculate SASA with a standard set of radii than with the expanded polar ones. So, that's
279 /// where this class comes in. It will read in database files, depending on which set of radii are requested and provide
280 /// access to that data in some way.
281 ///
282 /// Let's say we have to create RotamerDots objects for two different sets of SASA radii. When those objects are constructed
283 /// a pointer to the right set of radii will have to be set. Definitely don't want to copy/store the radii to each instance.
284 /// If I make it a pointer to this class, then it would only work for one set of radii. So at RotamerDots construct time
285 /// we have to ask this class to give us a pointer to the set of radii that are requested. Then only one instance of this
286 /// class exists, and all RotamerDots objects have pointers set to the radii they care about. What would this change in
287 /// the RotamerDots API? The get_radius() function would dereference the pointer and index into the vector to get the
288 /// right radius. This structure is similar to how the ChemicalManager works. But, in that class, the functions return
289 /// AtomTypeSet objects.
290 ///
292 
293 public:
295 
296  /// @brief return a pointer to the standard Rosetta SASA radii
298 
299  /// @brief return a pointer to the SASA radii used by NACCESS
301 
302  /// @brief return a pointer to the SASA radii used by NACCESS, with polar atom radii expanded
304 
305 private:
306  /// @brief private constructor
308 
309  /// @brief static data member holding pointer to the singleton class itself
311 
315 
316 };
317 
318 
319 ///
320 /// @begin RotamerDotsCache
321 ///
322 /// @brief
323 /// A lightweight version of the RotamerDots class. Used to cache overlap between interaction graph Nodes and BGNodes.
324 ///
325 /// @detailed
326 /// During packing, when a first class node has to respond to another Node changing state, it's faster to decrement the
327 /// coverage the previous state produced and increment the coverage the new state produces than to completely recalculate
328 /// how the new state overlaps the node. But instead of holding that coverage information in a RotamerDots object (which
329 /// does alot of other things), hold it in this cache class instead.
330 ///
332 
333 public:
334  friend class RotamerDots;
335 
338  RotamerDotsCache( RotamerDotsCache const & rhs );
339  RotamerDotsCache const & operator= ( RotamerDotsCache const & rhs );
341 
342  void resize( core::Size num_atoms );
343  void zero();
344 
347 
349  void print( std::ostream & os ) const;
350 
351  // for unit tests only
352  inline utility::vector1< DotSphere > const & get_atom_counts() const { return atom_counts_; }
353 
354 private:
356 
357 };
358 
359 
360 ///
361 /// @begin InvRotamerDots
362 ///
363 /// @brief
364 /// Used to determine whether the overlap between two atoms is buried or exposed.
365 ///
367 
368 public:
369  InvRotamerDots();
370  InvRotamerDots( InvRotamerDots const & src );
371  virtual ~InvRotamerDots();
372 
373  InvRotamerDots const & operator = ( InvRotamerDots const & rhs );
374 
375  void setup_from_rotamer_dots( RotamerDots const & rdots );
377  RotamerDots const & rdots,
378  utility::vector1< Size > const & ats_to_update
379  );
380 
382  rotamer() const;
383 
384  /// @brief Is the intersection between two atoms on this inv-rotamer-dots object exposed?
385  bool atom_overlap_is_exposed( Size at1, Size at2 ) const;
386 
387  /// @brief Is the intersection between one atom on this inv-rotamer-dots object,
388  /// and one atom on another inv-rotamer-dots object exposed?
389  bool atom_overlap_is_exposed( Size at_this, InvRotamerDots const & other, Size at_other ) const;
390 
391  bool dot_exposed( Size atomid, Size dot_index ) const;
392 
393  void write_exposed_dots_to_kinemage( std::ostream & ostr, bool group = false ) const;
394 
396  std::ostream & ostr,
397  Size const atom_this,
398  InvRotamerDots const & invdots_other,
399  Size const atom_other,
400  bool group = false
401  ) const;
402 
403 private:
404 
405  bool
407  core::conformation::Atom const & at1,
408  utility::vector1< ObjexxFCL::ubyte > const & at1exposed_dots,
409  core::conformation::Atom const & at2,
410  utility::vector1< ObjexxFCL::ubyte > const & at2exposed_dots
411  ) const;
412 
414 
415 private:
420 
421 };
422 
423 
424 } // interaction_graph
425 } // pack
426 } // core
427 
428 
429 #endif // INCLUDED_core_pack_interaction_graph_RotamerDots_HH