Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
NeighborList.cc
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
11 /// @brief
12 /// @author
13 
14 
15 // Unit headers
17 
18 // Package headers
19 // AUTO-REMOVED #include <core/scoring/EnergyGraph.hh> // necessary?
20 //#include <core/scoring/etable/EtableEnergy.hh>
21 // AUTO-REMOVED #include <core/scoring/etable/count_pair/CountPairFunction.hh>
22 #include <basic/options/option.hh>
23 
24 // Project headers
26 #include <core/pose/Pose.hh>
27 // AUTO-REMOVED #include <basic/prof.hh>
28 #include <basic/Tracer.hh>
29 
30 // option key includes
31 
32 #include <basic/options/keys/run.OptionKeys.gen.hh>
33 
34 #include <utility/vector1.hh>
35 
36 
37 
38 
39 
40 namespace core {
41 namespace scoring {
42 
43 static basic::Tracer tr("core.scoring.NeighborList");
44 
46  kinematics::DomainMap const & domain_map_in,
47  Real const XX_cutoff,
48  Real const XH_cutoff,
49  Real const HH_cutoff
50 ) :
51  auto_update_( false ),
52  move_tolerance_sqr_( 0.0 ),
53  // add an extra (2.0 - move_tolerance_) angstroms of fudge
54  wide_nblist_extension_(
55  basic::options::option[basic::options::OptionKeys::run::wide_nblist_extension].user() ?
56  basic::options::option[basic::options::OptionKeys::run::wide_nblist_extension]() :
57  basic::options::option[basic::options::OptionKeys::run::nblist_autoupdate_wide]()
58  ),
59  wide_move_tolerance_sqr_( 0.0 ), // this is updated when move_tolerance is set
60  domain_map_( domain_map_in ), // make a copy of the domain_map
61  XX_cutoff_( XX_cutoff ),
62  XH_cutoff_( XH_cutoff ),
63  HH_cutoff_( HH_cutoff ),
64  sqrt_XX_cutoff_( std::sqrt(XX_cutoff) ),
65  sqrt_XH_cutoff_( std::sqrt(XH_cutoff) ),
66  sqrt_HH_cutoff_( std::sqrt(HH_cutoff) ),
67  XX_cutoff_wide_( std::pow( sqrt_XX_cutoff_ + 2 * wide_nblist_extension_, 2 ) ),
68  XH_cutoff_wide_( std::pow( sqrt_XH_cutoff_ + 2 * wide_nblist_extension_, 2 ) ),
69  HH_cutoff_wide_( std::pow( sqrt_HH_cutoff_ + 2 * wide_nblist_extension_, 2 ) ),
70  n_prepare_for_scorings_( 0 ),
71  n_update_from_wide_( 0 ),
72  n_full_updates_( 0 )
73 {
74  //assert( XX_cutoff_ >= XH_cutoff_ + 1e-3 &&
75  // XH_cutoff_ >= HH_cutoff_ + 1e-3 ); //debug order of arguments
76 }
77 
79 {
80  if ( auto_update_ ) {
81  tr << "Minimization stats: " << n_prepare_for_scorings_ << " score/deriv cals, ";
82  tr << n_update_from_wide_ << " narrow-from-wide updates, ";
83  tr << n_full_updates_ << " full updates." << std::endl;
84  }
85 }
86 
87 
88 ///////////////////////////////////////////////////////////////////////////////
89 void
91  kinematics::DomainMap const & domain_map_in
92 ) const
93 {
94  for ( Size i=1; i<= nblist_.size(); ++i ) {
95  if ( domain_map_in(i) != domain_map_(i) ) {
96  utility_exit_with_message("domain_map mismatch in nblist");
97  }
98  }
99 }
100 
101 void
103 {
104  auto_update_ = true;
105  move_tolerance_sqr_ = move_tolerance * move_tolerance;
106  wide_move_tolerance_sqr_ = std::pow( wide_nblist_extension_ - move_tolerance, 2 );
107 }
108 
109 void
111 {
112  auto_update_ = false;
113 }
114 
115 /// @details instead of doing a full neighbor calculation, we're sure we can
116 /// update the scoring neighborlist from the wide neighborlist
117 ///
118 void
120 {
121  Size const natoms_moved_more_than_move_tolerance( atoms_to_update_.size() );
122 
123  /// Move the reference coordinate for an atom that has moved more than move_tolerance_ from
124  /// its reference coordinate, but do not move the reference coordinate for the other atoms
125  /// that have to have their nblist_s updated. Do this step first so that all of the reference
126  /// coordinates are up-to-date by the time the next loop begins.
127  for ( Size ii = 1; ii <= natoms_moved_more_than_move_tolerance; ++ii ) {
128  id::AtomID const ii_atom( atoms_to_update_[ ii ] ); // weird bug if this is a reference...
129 
130  assert( pose.residue( ii_atom.rsd() ).xyz( ii_atom.atomno()).distance_squared(
131  wide_reference_coords_[ ii_atom.rsd() ][ ii_atom.atomno() ] )
133 
134  reference_coords_[ ii_atom.rsd() ][ ii_atom.atomno() ] = pose.residue( ii_atom.rsd() ).xyz( ii_atom.atomno() );
135  }
136 
137  /// Iterate across the subset of atoms that need to be updated because they, or their
138  /// neighbors have moved far enough to invalidate their nblist_ data.
139  /// Note: atoms_need_updating_ grows over the course of this loop
140  for ( Size ii = 1; ii <= atoms_to_update_.size(); ++ii ) {
141  id::AtomID const ii_atom( atoms_to_update_[ ii ] ); // weird bug on Will's laptop if this is a reference...
142  bool const ii_is_hydrogen = pose.residue( ii_atom.rsd() ).atom_is_hydrogen( ii_atom.atomno() );
143 
144  bool const ii_original_atom_moved( ii <= natoms_moved_more_than_move_tolerance );
145  if ( ii_original_atom_moved ) {
146  AtomNeighbors const & ii_nblist = nblist_[ ii_atom.rsd() ][ ii_atom.atomno() ];
147  for ( Size jj = 1, jje = ii_nblist.size(); jj <= jje; ++jj ) {
148  int const nbr_rsd = ii_nblist[ jj ].rsd();
149  int const nbr_atom = ii_nblist[ jj ].atomno();
150  if ( atom_needs_update_from_wide_[ nbr_rsd ][ nbr_atom ] == 0 ) {
151  // add the neighbor atom to the to-do list
152  atom_needs_update_from_wide_[ nbr_rsd ][ nbr_atom ] = 1;
153  atoms_to_update_.push_back( id::AtomID( nbr_atom, nbr_rsd ) );
154  }
155  }
156  }
157 
158  /// Clear out the stale nblist data
159  //AtomNeighbors & ii_nblist = nblist_[ ii_atom.rsd() ][ ii_atom.atomno() ];
160  //ii_nblist.clear();
161  nblist_[ ii_atom.rsd() ][ ii_atom.atomno() ].clear();
162  upper_nblist_[ ii_atom.rsd() ][ ii_atom.atomno() ].clear();
163  intrares_upper_nblist_[ ii_atom.rsd() ][ ii_atom.atomno() ].clear();
164 
165 
166  Vector const & ii_coord = reference_coords_[ ii_atom.rsd() ][ ii_atom.atomno() ];
167 
168  AtomNeighbors const & ii_wide_nblist = wide_nblist_[ ii_atom.rsd() ][ ii_atom.atomno() ];
169 
170  for ( Size jj = 1, jje = ii_wide_nblist.size(); jj <= jje; ++jj ) {
171  int const nbr_rsd = ii_wide_nblist[ jj ].rsd();
172  int const nbr_atom = ii_wide_nblist[ jj ].atomno();
173  bool const nbr_is_hydrogen = pose.residue( nbr_rsd ).atom_is_hydrogen( nbr_atom );
174 
175  if ( ii_coord.distance_squared( reference_coords_[ nbr_rsd ][ nbr_atom ] ) <=
176  atom_pair_cutoff( ii_is_hydrogen, nbr_is_hydrogen ) ) {
177  //ii_nblist.push_back( ii_wide_nblist[ jj ] ); // copy from wide into narrow
178  declare_atom_neighbor_1sided( ii_atom, id::AtomID( nbr_atom, nbr_rsd ), ii_wide_nblist[ jj ].path_dist(), ii_wide_nblist[ jj ].weight() );
179 
180  /// Neighbors of one of the original atoms to exceed the move_tolerance_sqr_ movement
181  /// limitation need to have their nblist_'s updated.
182  if ( ii_original_atom_moved && atom_needs_update_from_wide_[ nbr_rsd ][ nbr_atom ] == 0 ) {
183  // add the neighbor atom to the to-do list
184  atom_needs_update_from_wide_[ nbr_rsd ][ nbr_atom ] = 1;
185  atoms_to_update_.push_back( id::AtomID( nbr_atom, nbr_rsd ) );
186  }
187 
188  }
189  }
190  }
191  /// Now that we've updated all the atoms that need updating,
192  /// clear out the atom_needs_update_from_wide_ array so that the next
193  /// invocation of this function starts with clean data
194  for ( Size ii = 1; ii <= atoms_to_update_.size(); ++ii ) {
195  id::AtomID const & ii_atom( atoms_to_update_[ ii ] );
196  atom_needs_update_from_wide_[ ii_atom.rsd() ][ ii_atom.atomno() ] = 0;
197  }
198 }
199 
200 void
202 {
203  nblist_[ at1.rsd() ][ at1.atomno() ].push_back( AtomNeighbor( at2.rsd(), at2.atomno(), path_dist, weight, weight_func ));
204  nblist_[ at2.rsd() ][ at2.atomno() ].push_back( AtomNeighbor( at1.rsd(), at1.atomno(), path_dist, weight, weight_func ));
205  if ( at1.rsd() != at2.rsd() ) {
206  if ( at1.rsd() < at2.rsd() ) {
207  upper_nblist_[ at1.rsd() ][ at1.atomno() ].push_back( AtomNeighbor( at2.rsd(), at2.atomno(), path_dist, weight, weight_func ));
208  } else {
209  upper_nblist_[ at2.rsd() ][ at2.atomno() ].push_back( AtomNeighbor( at1.rsd(), at1.atomno(), path_dist, weight, weight_func ));
210  }
211  } else {
212  assert( at1.atomno() != at2.atomno() ); // no atom-self interactions!
213  if ( at1.atomno() < at2.atomno() ) {
214  intrares_upper_nblist_[ at1.rsd() ][ at1.atomno() ].push_back( AtomNeighbor( at2.rsd(), at2.atomno(), path_dist, weight, weight_func ));
215  } else {
216  intrares_upper_nblist_[ at2.rsd() ][ at2.atomno() ].push_back( AtomNeighbor( at1.rsd(), at1.atomno(), path_dist, weight, weight_func ));
217  }
218  }
219 }
220 
221 /// @details Add at2 to atom 1's neighbor lists, but don't touch at2's neighbor lists.
222 void
224 {
225  nblist_[ at1.rsd() ][ at1.atomno() ].push_back( AtomNeighbor( at2.rsd(), at2.atomno(), path_dist, weight, weight_func ));
226  if ( at1.rsd() != at2.rsd() ) {
227  if ( at1.rsd() < at2.rsd() ) {
228  upper_nblist_[ at1.rsd() ][ at1.atomno() ].push_back( AtomNeighbor( at2.rsd(), at2.atomno(), path_dist, weight, weight_func ));
229  }
230  } else {
231  assert( at1.atomno() != at2.atomno() ); // no atom-self interactions!
232  if ( at1.atomno() < at2.atomno() ) {
233  intrares_upper_nblist_[ at1.rsd() ][ at1.atomno() ].push_back( AtomNeighbor( at2.rsd(), at2.atomno(), path_dist, weight, weight_func ));
234  }
235  }
236 }
237 
238 
239 } // namespace scoring
240 } // namespace core