Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
BackboneMover.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 docking_initialization_protocols
11 /// @brief initialization protocols for docking
12 /// @detailed
13 /// This contains the functions that create initial positions for docking
14 /// You can either randomize partner 1 or partner 2, spin partner 2, or
15 /// perform a simple perturbation.
16 /// @author Mike Tyka
17 
21 
22 // Rosetta Headers
23 #include <core/pose/Pose.hh>
29 #include <basic/basic.hh>
30 #include <core/id/DOF_ID_Range.hh>
31 #include <numeric/NumericTraits.hh>
32 //symmetry
34 // Random number generator
35 #include <numeric/random/random.hh>
36 #include <utility/tag/Tag.hh>
37 
38 //
39 #include <string>
40 
41 #include <basic/Tracer.hh>
42 
44 #include <utility/vector0.hh>
45 #include <utility/vector1.hh>
46 #include <utility/options/IntegerVectorOption.hh>
47 
48 
49 using basic::T;
50 using basic::Error;
51 using basic::Warning;
52 
53 static basic::Tracer TR("protocols.simple_moves.BackboneMover");
54 
55 namespace protocols {
56 namespace simple_moves {
57 
58 static numeric::random::RandomGenerator RG(90);
59 
60 using namespace core;
61 
62 //constructor
64  protocols::canonical_sampling::ThermodynamicMover(),
65  temperature_( 0.5 ),
66  nmoves_( 1 ),
67  preserve_detailed_balance_(false)
68 {
69  moves::Mover::type( "BackboneMoverBase" );
71  movemap->set_bb( true ); // allow all backbone residues to move
72  movemap_=movemap; // and make this a constant object
73  angle_max( 'H', 0.0 ); // helix
74  angle_max( 'L', 6.0 ); // other
75  angle_max( 'E', 5.0 ); // strand
76 }
77 
79  core::kinematics::MoveMapOP movemap_in,
80  core::Real temperature_in,
81  core::Size nmoves_in
82 ) : protocols::canonical_sampling::ThermodynamicMover(),
83  movemap_( movemap_in ),
84  temperature_( temperature_in),
85  nmoves_( nmoves_in ),
86  preserve_detailed_balance_(false)
87 {
88  moves::Mover::type( "BackboneMoverBase" );
89  // set default values for angle_max since it is not passed in
90  angle_max( 'H', 0.0 ); // helix
91  angle_max( 'L', 6.0 ); // other
92  angle_max( 'E', 5.0 ); // strand
93 }
94 
95 //destructor
97 
98 
99 void BackboneMover::temperature( core::Real const temperature_in ) { temperature_ = temperature_in; }
100 
103  return temperature_;
104 }
105 
106 void BackboneMover::nmoves( core::Size const nmoves_in ) { nmoves_ = nmoves_in; }
107 
110  return nmoves_;
111 }
112 
114 
116 
117 
119 {
120  angle_max( 'H', angle ); // helix
121  angle_max( 'L', angle ); // other
122  angle_max( 'E', angle ); // strand
123 }
124 
125 void BackboneMover::angle_max( char const type, core::Real const angle ) { angle_max_[ type ] = angle; }
126 
127 void BackboneMover::angle_max( std::map< char, core::Real > angle_max_in ) { angle_max_.swap( angle_max_in ); }
128 
130 BackboneMover::get_angle_max(char const type) const
131 {
132  return angle_max_.find(type)->second;
133 }
134 
135 
136 bool
138 {
140 }
141 
142 void
144  bool preserve_detailed_balance
145 )
146 {
148 }
149 
151 
153 
154 void
156  utility::tag::TagPtr const tag,
158  protocols::filters::Filters_map const & /*filters*/,
159  protocols::moves::Movers_map const & /*movers*/,
160  core::pose::Pose const & pose
161 )
162 {
164  protocols::rosetta_scripts::parse_movemap( tag, pose, mm, data );
165  movemap( mm );
166  temperature( tag->getOption<core::Real>( "temperature", temperature_ ) );
167  nmoves( tag->getOption<core::Size>( "nmoves", nmoves_ ) );
168  angle_max( tag->getOption<core::Real>( "angle_max", 6.0 ) );
169  set_preserve_detailed_balance( tag->getOption<bool>( "preserve_detailed_balance", preserve_detailed_balance_ ) );
170 }
171 
173 {
174  // clear everything to start from clean
175  clear();
176 
177  //what if symmetry input
178  // will not run for now, can change this to true if symmetry desired
179  // potential problem with incoming modified symmetric movemaps, this will
180  // reset any changes to the input movemap
181  if(false){
182  if ( core::pose::symmetry::is_symmetric( pose ) ) {
183  //TR << "Pose is symmetric, making backbone movemap symmetric."<< std::endl;
185  }
186  }
187 
188  // currently secstruct is not implemented and returns 'L' for all residues
189  setup_list( pose );
190 
191  if( pos_list_.empty() ) {
192  Warning() << "no movable positions in " << type() << "!" << std::endl;
193  return;
194  }
195 
196  // how many moves to make
197  num_ = std::max( Size(1), std::min( nmoves_, pos_list_.size()/2 ) );
198 
199  // now loop
200  for ( int k=1; k<= num_; ++k ) {
201  while ( true ) {
202  ++tries_;
203 
204  // give up after trying 10000 times
205  if ( tries_ > 10000 ) {
206  break;
207  }
208 
209  //choose a random position from the list of positions previously chose to be candidate positions
210  std::pair< int, Real > const & random_pos( pos_list_[ static_cast< int >( RG.uniform() * pos_list_.size() + 1 ) ] );
211  resnum_ = random_pos.first;
212  set_angles( random_pos.second );
213 
214 // next three lines skip ends of structure !!
215 // fix a logic error here: the closer to the end, the higher the probability
216 // to skip it; and when it is 1 or total_residue, the probability should be
217 // zero; and the probability distribution should be symmetrical for two ends
218 // residue: N- 1 2 3 4 5 6
219 // residue: C- t t-1 t-2 t-3 t-4 t-5
220 // prob to skip: 1 0.8 0.6 0.4 0.2 0.0
221 // -- chu
222 
223  // need to add this back, prob want a pose.distance_to_chain_end(i)
224  // function
225  //
226  //end = total_residue - 5;
227  //if ( resnum <= 5 && static_cast< int >(ran3()*5+1) >= resnum ) goto L401;
228  //if ( resnum > end && static_cast< int >(ran3()*5) + end <= resnum ) goto L401;
229 
230  // maybe we've already moved this position ?
231  if ( std::find( already_moved_.begin(), already_moved_.end(), resnum_ ) !=
232  already_moved_.end() ) continue;
233 
234  if ( !make_move( pose ) ) continue;
235  already_moved_.push_back( resnum_ );
236  break;
237  } // while ( true )
238 
239  } // k=1,num
240 }
241 
244  return "BackboneMover";
245 }
246 
248  tries_=0;
249  pos_list_.erase(pos_list_.begin(), pos_list_.end());
250  already_moved_.erase(already_moved_.begin(), already_moved_.end());
251 }
252 
254  if ( preserve_detailed_balance_ ) return true;
256  Real const boltz_factor = (old_rama_score_-new_rama_score_)/temperature_;
257  Real const probability = std::exp(std::max(Real(-40.0),boltz_factor) );
258  if ( RG.uniform() >= probability ) return( false );
259  }
260  return( true );
261 }
262 
263 
267 }
268 
271  return new SmallMover;
272 }
273 
276  return "Small";
277 }
278 
279 
280 //constructor
282 
284  core::kinematics::MoveMapOP movemap_in,
285  core::Real temperature_in,
286  core::Size nmoves_in
287 )
288  : BackboneMover( movemap_in, temperature_in, nmoves_in )
289 {
290  moves::Mover::type( "Small" );
291 }
292 
293 //destructor
295 
298  return "Small";
299 }
300 
303  return new SmallMover(*this);
304 }
305 
306 
308 {
309  using namespace id;
310  for ( int i=1, i_end = pose.total_residue(); i<= i_end; ++i ) {
311  conformation::Residue const & rsd( pose.residue( i ) );
312  //Checks if the residue is protein and has a free psi and phi angle as determined by the move map
313  if ( rsd.is_protein() && movemap_->get( TorsionID( i, BB, phi_torsion ) ) &&
314  movemap_->get( TorsionID( i, BB, psi_torsion ) ) ) {
315  //Gets the secondary structure nature of the residue
316  char const ss( pose.secstruct( i ) );
317  if ( angle_max_.count( ss ) ) {
318  //Checks the maximum angle deviation for the specific kind of secondary structure and if it is greater than 0 pushes back the residue and
319  //the maximum angle deviation to the list of movable residues.
320  Real const mx( angle_max_.find( ss )->second );
321  if ( mx > 0.0 ) {
322  pos_list_.push_back( std::make_pair( i, mx ) );
323  }
324  }
325  // Check if the residue is a monosaccharide and has a free phi (BB 5) and psi (BB 4).
326  } else if (rsd.is_carbohydrate() && movemap_->get(TorsionID(i, BB, 4)) &&
327  movemap_->get(TorsionID(i, BB, 5))) {
328  // Carbohydrates are always considered loops for now.
329  Real const mx = angle_max_.find('L')->second;
330  if (mx > 0.0) {
331  pos_list_.push_back(std::make_pair(i, mx));
332  }
333  }
334  }
335 }
336 
339  core::pose::Pose & //pose
340 )
341 {
343 }
344 
347  core::pose::Pose & pose
348 )
349 {
350  Real static const pi(numeric::NumericTraits<Real>::pi());
351  clear();
352  setup_list( pose );
353 
355 
356  for (core::Size i = 1; i <= pos_list_.size(); ++i) {
357 
359  core::id::DOF_ID phi_dof(pose.conformation().dof_id_from_torsion_id(phi_torsion));
360  if (phi_dof.valid()) range_vector.push_back(core::id::DOF_ID_Range(phi_dof, -pi, pi));
361 
363  core::id::DOF_ID psi_dof(pose.conformation().dof_id_from_torsion_id(psi_torsion));
364  if (psi_dof.valid()) range_vector.push_back(core::id::DOF_ID_Range(psi_dof, -pi, pi));
365  }
366 
367  return range_vector;
368 }
369 
371  ///< if anyone can think of how to explain this better, please do so!!
372  big_angle_ = angle_in; ///< this number comes from max angle, it is the maximum
373  ///< total deviation
374  small_angle_ = big_angle_/2.0; ///< this is max_angle/2, which is the deviation from the angle input
375 
376 }
377 
379 {
380  scoring::Ramachandran const & rama( scoring::ScoringManager::get_instance()->get_Ramachandran() );
381 
382  conformation::Residue const & current_rsd( pose.residue(resnum_) );
383 
384  old_phi_ = pose.phi(resnum_);
385  new_phi_ = basic::periodic_range( old_phi_ - small_angle_ + RG.uniform() * big_angle_, 360.0 );
386 
387  old_psi_ = pose.psi(resnum_);
388  new_psi_ = basic::periodic_range( old_psi_ - small_angle_ + RG.uniform() * big_angle_, 360.0 );
389 
390  // Always accept carbohydrate moves for now....
391  if (current_rsd.is_protein()) {
392  old_rama_score_ = rama.eval_rama_score_residue( current_rsd.aa(), old_phi_, old_psi_ );
393  new_rama_score_ = rama.eval_rama_score_residue( current_rsd.aa(), new_phi_, new_psi_ );
394 
395  // decide whether to accept the move
396  if ( !check_rama() ) return( false );
397  }
398 
399  // set the new values for residue resnum
400  pose.set_phi( resnum_, new_phi_ );
401  pose.set_psi( resnum_, new_psi_ );
402 
403  return( true );
404 }
405 
407 {
409  mmap->set_chi( true );
410  mmap->set_bb( true );
411 
412  movemap(mmap);
413 
414  apply(pose);
415 }
416 
420 }
421 
425 }
426 
429  return "Shear";
430 }
431 
432 //constructor
433 
435 
437  core::kinematics::MoveMapOP movemap_in,
438  core::Real temperature_in,
439  core::Size nmoves_in
440 )
441  : BackboneMover( movemap_in, temperature_in, nmoves_in )
442 {
444 }
445 
446 //destructor
448 
451  return "Shear";
452 }
453 
456  return new protocols::simple_moves::ShearMover(*this);
457 }
458 
460 {
461  using namespace id;
462 
463  // Compare code below to that for SmallMover above.
464  for ( int i=2, i_end = pose.total_residue(); i<= i_end; ++i ) {
465  conformation::Residue const & rsd( pose.residue( i ) );
466  if ( rsd.is_protein() && movemap_->get( TorsionID( i, BB, phi_torsion ) /*phi of i*/) &&
467  movemap_->get( TorsionID( i-1, BB, psi_torsion ) /*psi of i-1*/)) {
468  char const ss( pose.secstruct( i ) );
469  if ( angle_max_.count( ss ) ) {
470  Real const mx( angle_max_.find( ss )->second );
471  if ( mx > 0.0 ) {
472  pos_list_.push_back( std::make_pair( i, mx ) );
473  }
474  }
475  // Check if the residue is a monosaccharide and has a free phi (BB 5) and psi (BB 4).
476  } else if (rsd.is_carbohydrate() && movemap_->get(TorsionID(i - 1, BB, 4)) &&
477  movemap_->get(TorsionID(i, BB, 5))) {
478  // Carbohydrates are always considered loops for now.
479  Real const mx = angle_max_.find('L')->second;
480  if (mx > 0.0) {
481  pos_list_.push_back(std::make_pair(i, mx));
482  }
483  }
484  }
485 }
486 
489  core::pose::Pose & //pose
490 )
491 {
493 }
494 
497  core::pose::Pose & pose
498 )
499 {
500  Real static const pi(numeric::NumericTraits<Real>::pi());
501 
502  clear();
503  setup_list( pose );
504 
506 
507  for (core::Size i = 1; i <= pos_list_.size(); ++i) {
508 
510  core::id::DOF_ID phi_dof(pose.conformation().dof_id_from_torsion_id(phi_torsion));
511  if (phi_dof.valid()) range_vector.push_back(core::id::DOF_ID_Range(phi_dof, -pi, pi));
512 
514  core::id::DOF_ID psi_dof(pose.conformation().dof_id_from_torsion_id(psi_torsion));
515  if (phi_dof.valid()) range_vector.push_back(core::id::DOF_ID_Range(psi_dof, -pi, pi));
516  }
517 
518  return range_vector;
519 }
520 
521 // db (from rosetta++) set maximum deviation to be twice that of small move since shears are less perturbing
523  ///< if anyone can think of how to explain this, please do so!!
524  big_angle_ = angle_in*2.0;
525  small_angle_ = big_angle_/2.0;
526 }
527 
528 
530 {
531  scoring::Ramachandran const & rama( scoring::ScoringManager::get_instance()->get_Ramachandran() );
532 
533  // grab the residues
534  conformation::Residue const & current_rsd( pose.residue(resnum_) );
535  conformation::Residue const & prev_rsd( pose.residue(resnum_-1) );
536 
537  Real shear_delta = small_angle_ - RG.uniform() * big_angle_;
538  // save current phi and psi
539  old_phi_ = pose.phi(resnum_);
540  new_phi_ = basic::periodic_range( old_phi_ - shear_delta, 360.0 );
541 
542  // Always accept carbohydrate moves for now....
543  if (current_rsd.is_protein()) {
544  // rama for phi of resnum and psi of resnum-1
545  old_rama_score_ = rama.eval_rama_score_residue( current_rsd.aa(), old_phi_, pose.psi(resnum_));
546  new_rama_score_ = rama.eval_rama_score_residue( current_rsd.aa(), new_phi_, pose.psi(resnum_));
547 
548  // decide whether to accept the move
549  if ( !check_rama() ) return( false );
550  }
551 
552  old_psi_ = pose.psi(resnum_-1);
553  new_psi_ = basic::periodic_range( old_psi_ + shear_delta, 360.0 );
554 
555  if (current_rsd.is_protein()) {
556  // rama for residue resnum-1
557  old_rama_score_ = rama.eval_rama_score_residue( prev_rsd.aa(), pose.phi(resnum_-1), old_psi_ );
558  new_rama_score_ = rama.eval_rama_score_residue( prev_rsd.aa(), pose.phi(resnum_-1), new_psi_ );
559 
560  // decide whether to accept the move
561  if ( !check_rama() ) return( false );
562  }
563 
564  // set the new values phi of resnum and psi of resnum-1
565  pose.set_phi( resnum_, new_phi_ );
566  pose.set_psi( resnum_-1, new_psi_ );
567 
568  return( true );
569 }
570 
572 {
574  mmap->set_chi( true );
575  mmap->set_bb( true );
576 
577  movemap(mmap);
578 
579  apply(pose);
580 }
581 
582 
583 std::ostream &operator<< (std::ostream &os, BackboneMover const &mover)
584 {
585  moves::operator<<(os, mover);
586  os << "Max angle for helices (H): " << mover.get_angle_max('H') <<
587  "\nMax angle for strands (E): " << mover.get_angle_max('E') <<
588  "\nMax angle for loops (L): " << mover.get_angle_max('L') <<
589  "\nTemperature factor (kT): " << mover.temperature() <<
590  "\nNumber of moves: " << mover.nmoves() << std::endl;
591  os << "MoveMap:" << std::endl;
592  mover.movemap()->show(os);
593  return os;
594 }
595 
596 
597 } // namespace moves
598 
599 } // namespace protocols