Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
TorsionDOFMover.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 protocols/simple_moves/TorsionDOFMover.cc
11 /// @brief TorsionDOFMover methods implemented
12 /// @author Steven Lewis
13 
14 // Unit Headers
16 
17 // Project Headers
19 #include <core/pose/Pose.hh>
20 
21 //#include <core/scoring/methods/MMTorsionEnergy.hh>
24 
25 // Numeric Headers
26 #include <numeric/conversions.hh> //degrees-radians
27 #include <numeric/random/random.hh>
28 
29 // Utility Headers
30 #include <basic/Tracer.hh>
31 #include <core/types.hh>
32 
33 // C++ Headers
34 #include <string>
35 
36 #include <utility/vector1.hh>
37 
38 //Auto Headers
40 
41 using basic::Error;
42 using basic::Warning;
43 
44 static numeric::random::RandomGenerator RG(14331701);
45 static basic::Tracer TR( "protocols.simple_moves.TorsionDOFMover" );
46 
47 namespace protocols {
48 namespace simple_moves {
49 
51  protocols::moves::Mover(),
52  atom1_(core::id::BOGUS_ATOM_ID),
53  atom2_(core::id::BOGUS_ATOM_ID),
54  atom3_(core::id::BOGUS_ATOM_ID),
55  atom4_(core::id::BOGUS_ATOM_ID),
56  upper_angle_(0),
57  lower_angle_(0),
58  check_MMT_(false),
59  mmt_(NULL),
60  temp_(0),
61  tries_(0)
62 { protocols::moves::Mover::type( "TorsionDOFMover" ); }
63 
64 ///@details random angle constructor. Magic numbers 180 and -179.9999999... maintain the uniform range. I'm sure there's a better way to get [180, -180) but I can't figure out what it is.
66  core::id::AtomID const & atom1,
67  core::id::AtomID const & atom2,
68  core::id::AtomID const & atom3,
69  core::id::AtomID const & atom4
70 ) :
71  protocols::moves::Mover(),
72  atom1_(atom1),
73  atom2_(atom2),
74  atom3_(atom3),
75  atom4_(atom4),
76  upper_angle_(180.0),
77  lower_angle_(-179.9999999999999999999999999999999999999999999999),
78  check_MMT_(false),
79  mmt_(NULL),
80  temp_(0.8),
81  tries_(1)
82 { protocols::moves::Mover::type( "TorsionDOFMover" ); }
83 
84 ///@details range of angles constructor - takes DEGREES not RADIANS.
86  core::id::AtomID const & atom1,
87  core::id::AtomID const & atom2,
88  core::id::AtomID const & atom3,
89  core::id::AtomID const & atom4,
90  core::Angle const upper,
91  core::Angle const lower
92 ) :
93  protocols::moves::Mover(),
94  atom1_(atom1),
95  atom2_(atom2),
96  atom3_(atom3),
97  atom4_(atom4),
98  upper_angle_(upper),
99  lower_angle_(lower),
100  check_MMT_(false),
101  mmt_(NULL),
102  temp_(0.8),
103  tries_(1)
104 { protocols::moves::Mover::type( "TorsionDOFMover" ); }
105 
106 ///@details particular angle constructor - takes DEGREES not RADIANS.
107 TorsionDOFMover::TorsionDOFMover( core::id::AtomID const & atom1, core::id::AtomID const & atom2, core::id::AtomID const & atom3, core::id::AtomID const & atom4, core::Angle const angle )
108 : protocols::moves::Mover(),
109  atom1_(atom1),
110  atom2_(atom2),
111  atom3_(atom3),
112  atom4_(atom4),
113  upper_angle_(angle),
114  lower_angle_(angle),
115  check_MMT_(false),
116  mmt_(NULL),
117  temp_(0.8),
118  tries_(1)
119 { protocols::moves::Mover::type( "TorsionDOFMover" ); }
120 
122 
124 
126 
127  Warning() << "In TorsionDOFMover, atoms not valid against pose; atoms:"
128  << " atom1 " << atom1_
129  << " atom2 " << atom2_
130  << " atom3 " << atom3_
131  << " atom4 " << atom4_ << std::endl;
132  return;
133  }
134 
135  //TR << "atoms:" << " atom1 " << atom1_ << " atom2 " << atom2_ << " atom3 " << atom3_ << " atom4 " << atom4_ << std::endl;
136 
137  //if we want this score, fill the pointer!
138  if(check_MMT_ && !mmt_){
140  mmt_->set_weight(core::scoring::mm_twist, 1.0);
141  }
142 
143  //if scoring, pre-score
144  core::Energy pre_score(0), post_score(0);
145  if(check_MMT_) pre_score = score_torsion(pose);
146 
147  //n_tries loop: continue rotating until a good angle is found
148  core::Size ntries(1);
149  for(; ntries <= tries_; ++ntries){
150 
151  //make a move
152  core::Angle const pre_torsion(pose.atom_tree().torsion_angle(atom1_, atom2_, atom3_, atom4_));
153  pose.conformation().set_torsion_angle( atom1_, atom2_, atom3_, atom4_, pre_torsion+calc_angle() );
154 
155  //if scoring, post-score and boltzmann
156  if(check_MMT_){
157  post_score = score_torsion(pose);
158 
159  //if scoring, decide if try again
160  if( boltzmann( pre_score, post_score ) ) break;
161  else pose.conformation().set_torsion_angle( atom1_, atom2_, atom3_, atom4_, pre_torsion );
162  }
163 
164  }
165 
166  if (ntries > tries_)
167  Error() << "TorsionDOFMover gave up after " << tries_ << " attempts, no move made" << std::endl;
168 
169  //TR << pre_score << " " << post_score << " " << pose.atom_tree().torsion_angle(atom1_, atom2_, atom3_, atom4_) << std::endl;
170 
171  //TR << pose.atom_tree().torsion_angle(atom1_, atom2_, atom3_, atom4_) << std::endl;
172  return;
173 }//apply
174 
177  return "TorsionDOFMover";
178 }
179 
180 ///@brief calculate angle for perturbation - call to RNG
182 { return numeric::conversions::radians(lower_angle_ + ((upper_angle_ - lower_angle_) * RG.uniform())); }
183 
184 ///@brief calculate mmt score for the moving bond
185 ///This is the stupidest possible method - score the whole pose. It would be much better if this could directly use MMTorsionEnergy to calculate about just the one bond in question, but I can't figure out how to reliably look up exactly the set of residues modified by this torsion (remember that changing this 4-body torsion affects other 4-bodies with a shared central bond).
187 
188 ///@brief boltzmann calculation - is the new score acceptable?
189 bool TorsionDOFMover::boltzmann( core::Energy const pre_score, core::Energy const post_score ){
190 
191  //TR << pre_score << " " << post_score << std::endl;
192 
193  //borrowed from BackboneMover check_rama
194  if ( post_score > pre_score ) {
195  core::Real const boltz_factor = ((pre_score - post_score)/temp_);
196  core::Real const probability = std::exp(std::max(core::Real(-40.0),boltz_factor) );
197  if ( RG.uniform() >= probability ) return false;
198  }
199 
200  //TR << "accepting" << std::endl;
201 
202  return true;
203 }
204 
205 }//moves
206 }//protocols