Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
LinearChainbreakEnergy.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 core/scoring/ScoreFunction.cc
11 /// @brief Atom pair energy functions
12 /// @author Stuart G. Mentzer (Stuart_Mentzer@objexx.com)
13 /// @author Kevin P. Hinshaw (KevinHinshaw@gmail.com)
14 /// @author Christopher Miles (cmiles@uw.edu)
15 
16 
20 // AUTO-REMOVED #include <boost/unordered/unordered_set.hpp>
21 
22 // AUTO-REMOVED #include <basic/options/option.hh>
23 #include <basic/options/keys/OptionKeys.hh>
24 // AUTO-REMOVED #include <basic/options/keys/score.OptionKeys.gen.hh>
25 
26 #include <core/types.hh>
27 #include <core/pose/Pose.hh>
34 // AUTO-REMOVED #include <core/id/NamedAtomID.hh>
35 
36 #include <basic/Tracer.hh>
37 
38 #include <algorithm>
39 #include <iostream>
40 // AUTO-REMOVED #include <iterator>
41 
42 #include <utility/vector1.hh>
43 
44 //Auto Headers
47 
48 
49 
50 
51 namespace core {
52 namespace scoring {
53 namespace methods {
54 
55 using core::Size;
56 static basic::Tracer tr("core.scoring.LinearChainbreak", basic::t_info);
57 
61  }
62 
65  initialize(allowable_sequence_sep);
66  }
67 
69  : parent(o) {
70  // assignment to non-cache-related variables
72 
73  // assign cache-related variables to their default values. this will trigger
74  // a cache miss on their first use, but greatly simplifies the design and
75  // improves reasoning about code paths in the event of copying/cloning
76  shortest_paths_.reset();
78  }
79 
81  if (this != &o) {
82  // base class assignments
83  parent::operator=(o);
84 
85  // assignment to non-cache-related variables
87 
88  // assign cache-related variables to their default values. this will trigger
89  // a cache miss on their first use, but greatly simplifies the design and
90  // improves reasoning about code paths in the event of copying/cloning
91  shortest_paths_.reset();
93  }
94  return *this;
95  }
96 
98 
99  void LinearChainbreakEnergy::initialize(Size allowable_sequence_sep) {
100  allowable_sequence_sep_ = allowable_sequence_sep;
102  shortest_paths_.reset();
103  }
104 
106  const core::conformation::Residue& upper_rsd,
107  const core::Size nbb) const {
108  // virtual N and CA on lower_rsd (OVL1 and OVL2) and a virtual C on upper_rsd "OVU1"
109  return (upper_rsd.atom(upper_rsd.mainchain_atoms()[1]).xyz().distance(lower_rsd.atom("OVL1").xyz()) +
110  upper_rsd.atom(upper_rsd.mainchain_atoms()[2]).xyz().distance(lower_rsd.atom("OVL2").xyz()) +
111  lower_rsd.atom(lower_rsd.mainchain_atoms()[nbb]).xyz().distance(upper_rsd.atom("OVU1").xyz()));
112 }
113 
115  const core::conformation::Residue& upper_rsd,
116  const core::Size nbb,
117  const core::Size cutpoint,
118  const core::pose::Pose& pose) const {
119  using core::id::AtomID;
121 
122  // now compute the overlap score: this is done by comparing the stub (lower side ) C, | N, CA (upper side)
123  // the stub for the lower_rsd is already in the atom-tree at atom "OVL2 == CA*"
124  Stub lower_stub(pose.conformation().atom_tree().atom(AtomID(pose.residue(cutpoint).atom_index("OVL2"), cutpoint)).get_stub());
125 
126  // the upper stub... let's just compute it for now...
127  // could be gained from AtomID( NamedAtomID( "OVU1", cutpoint+1 ).get_stub()
128  // and then the correct reversal...
129  Stub upper_stub(upper_rsd.atom(upper_rsd.mainchain_atoms()[2]).xyz(), // CA
130  upper_rsd.atom(upper_rsd.mainchain_atoms()[1]).xyz(), // N
131  upper_rsd.atom("OVU1" ).xyz()); // virtual C
132 
133  //for double-checking... ( debug )
134  Stub manual_lower_stub(lower_rsd.atom("OVL2").xyz(), // virtual CA
135  lower_rsd.atom("OVL1").xyz(), // virtual N
136  lower_rsd.atom(lower_rsd.mainchain_atoms()[nbb]).xyz()); // C
137 
138  if (distance(lower_stub, manual_lower_stub) > 0.01)
139  tr.Warning << "WARNING: mismatch between manual computed and atom-tree stub: "
140  << lower_stub << " " << manual_lower_stub << std::endl;
141 
142  return
143  manual_lower_stub.M.col_x().distance(upper_stub.M.col_x()) +
144  manual_lower_stub.M.col_y().distance(upper_stub.M.col_y()) +
145  manual_lower_stub.M.col_z().distance(upper_stub.M.col_z());
146 }
147 
148  /// called at the end of energy evaluation
149  /// In this case (LinearChainbreakEnergy), all the calculation is done here
151  ScoreFunction const &,
152  EnergyMap& totals) const {
153  using core::Size;
154  using conformation::Residue;
157  using utility::vector1;
158 
159  Real total_dev = 0.0;
160  Real total_ovp = 0.0;
161 
162  // Cached ShortestPathInFoldTree instance is invalid and must be recomputed
163  const FoldTree& tree = pose.fold_tree();
164  size_t hash_value = tree.hash_value();
166  shortest_paths_.reset(new ShortestPathInFoldTree(tree));
168  }
169 
170  // Identify all cutpoint variants defined by the caller
171  vector1<int> cutpoints;
172  find_cutpoint_variants(pose, tree, &cutpoints);
173 
174  for (Size i = 1; i <= cutpoints.size(); ++i) {
175  const int cutpoint = cutpoints[i];
176  const Residue& lower_rsd = pose.residue(cutpoint);
177  const Residue& upper_rsd = pose.residue(cutpoint + 1);
178  const Size nbb = lower_rsd.mainchain_atoms().size();
179 
182  continue;
183  }
184 
185  // Determine whether the separation between <lowed_rsd> and <upper_rsd>,
186  // as computed by ShortestPathInFoldTree, exceeds the current allowable
187  // sequence separation
188  const Size separation = shortest_paths_->dist(cutpoint, cutpoint + 1);
189  if (separation > allowable_sequence_sep_) {
190  tr.Trace << "Chainbreak skipped-- "
191  << separation << " > " << allowable_sequence_sep_
192  << std::endl;
193  continue;
194  }
195 
196  // Scoring
197  total_dev += do_score_dev(lower_rsd, upper_rsd, nbb);
198  total_ovp += do_score_ovp(lower_rsd, upper_rsd, nbb, cutpoint, pose);
199  }
200 
201  assert(std::abs(totals[linear_chainbreak]) < 1e-3 );
202  totals[linear_chainbreak] = total_dev / 3.0; // average over 3 distances
203  totals[overlap_chainbreak] = total_ovp;
204  }
205 
206 
207 /// called during gradient-based minimization inside dfunc
208 /**
209  F1 and F2 are not zeroed -- contributions from this atom are
210  just summed in
211 **/
213  id::AtomID const & id,
214  pose::Pose const & pose,
215  kinematics::DomainMap const &, // domain_map,
216  ScoreFunction const &, // sfxn,
217  EnergyMap const & weights,
218  Vector & F1,
219  Vector & F2
220 ) const {
221  using namespace basic::options;
222  using namespace basic::options::OptionKeys;
223  using core::Size;
224  using conformation::Residue;
225 
226  // This method is called on a per-residue basis, which means that we could
227  // be looking at a residue with no cutpoint variants, a lower cutpoint
228  // variant, or an upper cutpoint variant. This method must address both
229  // possibilities.
230 
231  // CASE 1: left-hand side of chainbreak (CUTPOINT_LOWER)
232  Size const residue = id.rsd();
233  if ( is_lower_cutpoint(residue,pose) ) {
234  Residue const & lower_rsd( pose.residue(residue));
235  Residue const & upper_rsd( pose.residue(residue + 1));
236  Vector const & xyz_moving( pose.xyz( id ) );
237 
238  bool match( true );
239  Vector xyz_fixed;
240  Size const nbb( lower_rsd.mainchain_atoms().size() );
241  if ( id.atomno() == lower_rsd.mainchain_atoms()[nbb] ) {
242  xyz_fixed = upper_rsd.atom( "OVU1" ).xyz();
243  } else if ( lower_rsd.atom_name( id.atomno() ) == "OVL1" ) {
244  xyz_fixed = upper_rsd.atom( upper_rsd.mainchain_atoms()[1] ).xyz();
245  } else if ( lower_rsd.atom_name( id.atomno() ) == "OVL2" ) {
246  xyz_fixed = upper_rsd.atom( upper_rsd.mainchain_atoms()[2] ).xyz();
247  } else {
248  match = false;
249  }
250 
251  if ( match ) {
252  Vector const f2 ( xyz_moving - xyz_fixed );
253  Real const dist ( f2.length() );
254  if ( dist >= 0.01 ) { // avoid getting too close to singularity...
255  Real const invdist( 1.0 / dist );
256  F1 += weights[ linear_chainbreak ] * invdist * cross( xyz_moving, xyz_fixed ) / 3;
257  F2 += weights[ linear_chainbreak ] * invdist * ( xyz_moving - xyz_fixed ) / 3;
258  }
259  }
260  }
261 
262  // CASE 2: right-hand side of chainbreak (CUTPOINT_UPPER)
263  if (is_upper_cutpoint(residue,pose)) {
264  Residue const & lower_rsd( pose.residue(residue - 1));
265  Residue const & upper_rsd( pose.residue(residue));
266  Vector const & xyz_moving( pose.xyz( id ) );
267 
268  bool match( true );
269  Vector xyz_fixed;
270  Size const nbb( lower_rsd.mainchain_atoms().size() );
271  if ( id.atomno() == upper_rsd.mainchain_atoms()[1] ) {
272  xyz_fixed = lower_rsd.atom( "OVL1" ).xyz();
273  } else if ( id.atomno() == upper_rsd.mainchain_atoms()[2] ) {
274  xyz_fixed = lower_rsd.atom( "OVL2" ).xyz();
275  } else if ( upper_rsd.atom_name( id.atomno() ) == "OVU1" ) {
276  xyz_fixed = lower_rsd.atom( lower_rsd.mainchain_atoms()[nbb] ).xyz();
277  } else {
278  match = false;
279  }
280 
281  if ( match ) {
282  Vector const f2 ( xyz_moving - xyz_fixed );
283  Real const dist ( f2.length() );
284  if ( dist >= 0.01 ) { // avoid getting too close to singularity...
285  Real const invdist( 1.0 / dist );
286  F1 += weights[ linear_chainbreak ] * invdist * cross( xyz_moving, xyz_fixed ) / 3;
287  F2 += weights[ linear_chainbreak ] * invdist * ( xyz_moving - xyz_fixed ) / 3;
288  }
289  }
290  }
291  }
292 
293 /// @brief LinearChainbreak Energy is context independent and thus indicates that no context graphs need to
294 /// be maintained by class Energies
295 void
297 
299  return 2;
300 }
301 
302 } // namespace methods
303 } // namespace scoring
304 } // namespace core