Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SidechainMoverBase.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/sidechain_moves/SidechainMoverBase.cc
11 /// @brief implementation of SidechainMoverBase class and functions
12 /// @author Oliver Lange ( oliver.lange@tum.de )
13 
14 
16 
17 // Procols Headers
19 
20 // Core Headers
25 #include <core/id/DOF_ID_Range.hh>
26 #include <core/id/TorsionID.hh>
30 #include <core/pose/Pose.hh>
35 #include <core/types.hh>
36 
37 #include <basic/options/option.hh>
38 #include <basic/options/keys/packing.OptionKeys.gen.hh>
39 #include <basic/Tracer.hh>
40 #include <basic/basic.hh>
41 #include <basic/prof.hh>
42 
43 // Numeric Headers
44 #include <numeric/angle.functions.hh>
45 #include <numeric/constants.hh>
46 #include <numeric/conversions.hh>
47 #include <numeric/random/random.hh>
48 
49 // Utility
50 #include <utility/string_util.hh>
51 #include <utility/tag/Tag.hh>
52 #include <utility/exit.hh>
53 
54 // for debug ( temporary )
55 #include <ObjexxFCL/string.functions.hh>
56 #include <ObjexxFCL/format.hh>
57 
58 
59 // C++ Headers
60 #include <sstream>
61 #include <fstream>
62 #include <utility/excn/Exceptions.hh>
63 #include <utility/fixedsizearray1.hh>
64 using namespace core;
65 using namespace core::pose;
66 
67 static numeric::random::RandomGenerator RG(38256225);
68 static basic::Tracer tr("protocols.simple_moves.sidechain_moves.SidechainMoverBase");
69 
70 namespace protocols {
71 namespace simple_moves {
72 namespace sidechain_moves {
73 
74 using namespace chemical;
75 using namespace conformation;
76 
77 SidechainMoverBase::SidechainMoverBase():
78  rotamer_library_( pack::dunbrack::RotamerLibrary::get_instance() )
79 {
80  set_defaults();
82 }
83 
85  pack::dunbrack::RotamerLibrary const & rotamer_library
86 ):
87  rotamer_library_(rotamer_library)
88 {
89  set_defaults();
91 }
92 
94  SidechainMoverBase const & mover
95 ) :
96  //utility::pointer::ReferenceCount(),
97  protocols::canonical_sampling::ThermodynamicMover(mover),
98  rotamer_library_(mover.rotamer_library_),
99  packed_residues_(mover.packed_residues_),
100  residue_packed_(mover.residue_packed_),
101  preserve_detailed_balance_(mover.preserve_detailed_balance_),
102  change_chi_without_replacing_residue_(mover.change_chi_without_replacing_residue_),
103  last_chi_angles_(mover.last_chi_angles_),
104  last_nchi_(mover.last_nchi_),
105  last_proposal_density_ratio_(mover.last_proposal_density_ratio_)
106 {
108  if (mover.task_) task_ = mover.task_->clone();
109 }
110 
112 
113 void
115  utility::tag::TagPtr const tag,
117  protocols::filters::Filters_map const & /*filters*/,
118  protocols::moves::Movers_map const & /*movers*/,
119  pose::Pose const & /*pose*/
120 )
121 {
122  pack::task::TaskFactoryOP new_task_factory( new pack::task::TaskFactory );
123 
124  if ( tag->hasOption("task_operations") ) {
125  std::string const t_o_val( tag->getOption<std::string>("task_operations") );
126  typedef utility::vector1< std::string > StringVec;
127  StringVec const t_o_keys( utility::string_split( t_o_val, ',' ) );
128  for ( StringVec::const_iterator t_o_key( t_o_keys.begin() ), end( t_o_keys.end() );
129  t_o_key != end; ++t_o_key ) {
130  if ( data.has( "task_operations", *t_o_key ) ) {
131  new_task_factory->push_back( data.get< pack::task::operation::TaskOperation* >( "task_operations", *t_o_key ) );
132  } else {
133  throw utility::excn::EXCN_RosettaScriptsOption("TaskOperation " + *t_o_key + " not found in protocols::moves::DataMap.");
134  }
135  }
136  } else {
137  new_task_factory->push_back( new pack::task::operation::RestrictToRepacking );
138  }
139 
140  task_factory_ = new_task_factory;
141 
142  set_preserve_detailed_balance( tag->getOption<bool>( "preserve_detailed_balance", preserve_detailed_balance() ) );
143  set_change_chi_without_replacing_residue( tag->getOption<Real>( "change_chi_without_replacing_residue", change_chi_without_replacing_residue() ) );
144 }
145 
146 void
150 }
151 
152 void
154  using namespace basic::options;
157  // design is not supported yet !!!
158  new_task_factory->push_back( new core::pack::task::operation::RestrictToRepacking );
159  if ( option[ OptionKeys::packing::resfile ].user() ) {
160  new_task_factory->push_back( new pack::task::operation::ReadResfile );
161  }
162  set_task_factory( new_task_factory );
163 }
164 
165 
166 /// @detailed
167 /// Check to make sure that a packer task exists and matches the numer of residues in
168 /// the given pose. If that isn't the case, create a new one with the task factory.
169 /// Exits with an error if no task factory exists.
170 void
172  // does a valid task exist ?
173  if ( !task_ || task_->total_residue() != pose.total_residue() ) {
174  if ( task_factory_ ) { //no - create a new one
175  set_task(task_factory_->create_task_and_apply_taskoperations( pose ));
176  } else {
177  utility_exit_with_message("Cannot create task because no task factory is set");
178  }
179  }
180 }
181 
182 void
184  pose::Pose & pose,
185  protocols::canonical_sampling::MetropolisHastingsMover const&, /*metropolis_hastings_mover*/
186  core::Size /*cycle*/
187 ) {
188  idealize_sidechains( pose );
189  init_task( pose );
190 }
191 
193  core::Size resid;
194  do { //pick residue, respecting underlying packer task
195  resid = packed_residues_[ RG.random_range(1, packed_residues_.size()) ];
196  } while ( pose.residue( resid ).name1() == 'P'); //SidechainMover cannot sample proline rotamers? (is this true?)
197  return resid;
198 }
199 
200 /// @detailed
201 void
203  using numeric::conversions::degrees;
204  using numeric::conversions::radians;
205 
206  init_task(pose);
207 
208  //select_resnum
209  Size const resnum( suggest_residue_number( pose ) );
210 
211  ResidueOP newresidue = new Residue( pose.residue( resnum ) );
212  ResidueOP final = make_move( newresidue );
213 
215  pose.replace_residue( resnum, *final, true );
216  } else {
217  Size const nchi( final->nchi() );
218  for ( Size i(1); i<=nchi; ++i ) {
219  pose.set_chi(i, resnum, final->chi(i));
220  } //for
221  } //else
222 } //apply
223 
224 
225 
228 {
229 
230  using numeric::conversions::degrees;
231  using numeric::conversions::radians;
232  using namespace ObjexxFCL;
233  chemical::ResidueType const& old_res_type( old_res->type() );
234  chemical::ResidueTypeCOP new_res_type( &( old_res->type() ) ); //for now until we fix the design stuff back in...
235  utility::vector1<Real> const old_chi( old_res->chi() );
236  Size resnum = old_res->seqpos();
237  Size nchi( old_chi.size() );
238 
239  utility::vector1< Real > new_chi;
240  new_chi.reserve( 4 );
241  new_chi.resize( nchi );
242 
243  make_chi_move( *old_res, old_chi, new_chi );
244  tr << "chi1 (old/new): " << fmt::F(8,4,old_chi[ 1 ]) << " " << fmt::F( 8,4,new_chi[ 1 ]) << std::endl;
245  Real proposal_density_reverse(1);
246  Real proposal_density_forward(1);
247 
249  proposal_density_reverse = compute_proposal_density(*old_res, resnum, *new_res_type, new_chi);
250  }
251  tr << "chi1 (old/new): " << fmt::F(8,4,old_chi[ 1 ]) << " " << fmt::F( 8,4,new_chi[ 1 ]) << std::endl;
252  /// set the chi
253  conformation::ResidueOP new_residue = old_res;
254  conformation::ResidueOP previous_residue = old_res;
255  if ( false ) { /* replace by if (residue_type() != & previous_residue->type() ) */
256  /* do design stuff */
257  /* new_residue = < a new residue > */
258  /* new_residue =
259  conformation::ResidueFactory::create_residue(*residue_type,
260  *old_res,
261  pose_->conformation(),
262  residue_task.preserve_c_beta());
263  for( Size ii = 1; ii <= residue_type->nchi(); ii++ ){
264  new_residue->set_chi( ii, numeric::principal_angle_degrees(last_chi_angles_[ ii ] ));
265  */
266  } else {
267  for (Size i = 1; i <= old_res->nchi(); ++i) {
268  new_residue->set_chi( i, new_chi[ i ] );
269  }
270  }
271  tr << "chi1 (old/new): " << fmt::F(8,4,old_chi[ 1 ]) << " " << fmt::F( 8,4,new_chi[ 1 ]) << std::endl;
273  proposal_density_forward = compute_proposal_density(*new_residue, resnum, old_res_type, old_chi);
274  }
275 
276  tr << "chi1 (old/new): " << fmt::F(8,4,old_chi[ 1 ]) << " " << fmt::F( 8,4,new_chi[ 1 ]) << " reverse/forward" << fmt::E( 10,5, proposal_density_reverse) << " " << fmt::E(10,5,proposal_density_forward ) << std::endl;
277  last_proposal_density_ratio_ = proposal_density_reverse / proposal_density_forward;
278  return new_residue;
279 
280 }
281 
282 
283 
286  return "SidechainMoverBase";
287 }
288 
289 /// @detailed
290 /// all sidechains that might be changed are replaced with ideal coordinates that have
291 /// the original chi angles
292 void
294  pose::Pose & pose
295 )
296 {
298  init_task(pose);
299  for (Size i = 1; i <= packed_residues_.size(); ++i) {
300  Size const resnum(packed_residues_[i]);
301 
302  // get the residue type and residue level task
303  ResidueType const & residue_type(pose.residue_type(resnum));
304  pack::task::ResidueLevelTask const & residue_task(task_->residue_task(resnum));
305 
306  // disable proline idealization for now
307  if (residue_type.aa() == aa_pro) continue;
308 
309  // save original chi angles
310  if (residue_type.nchi() > chi.size()) chi.resize(residue_type.nchi());
311  for (Size chinum = 1; chinum <= residue_type.nchi(); ++chinum) {
312  chi[chinum] = pose.chi(chinum, resnum);
313  }
314 
315  // create a new residue and replace the old one with it
316  ResidueOP new_residue(
317  ResidueFactory::create_residue(residue_type, pose.residue(resnum), pose.conformation(),
318  residue_task.preserve_c_beta())
319  );
320  pose.replace_residue(resnum, *new_residue, false);
321 
322  // put original chi angles back
323  for (Size chinum = 1; chinum <= residue_type.nchi(); ++chinum) {
324  pose.set_chi(chinum, resnum, chi[chinum]);
325  }
326  }
327 }
328 
331  return rotamer_library_;
332 }
333 
336  return task_factory_;
337 }
338 
339 void
342 }
343 
346  return task_;
347 }
348 
349 void
352 
353  task_ = task;
354 
355  // update the list of residues being packed
356  packed_residues_.clear();
357  residue_packed_.resize(task_->total_residue());
358  for (Size i = 1; i <= task_->total_residue(); ++i) {
359 
360  // loop over all possible residue types and check if any have chi angles
361  residue_packed_[i] = false;
362  pack::task::ResidueLevelTask const & residue_task(task->residue_task(i));
363  for (ResidueLevelTask::ResidueTypeCOPListConstIter iter(residue_task.allowed_residue_types_begin());
364  iter != residue_task.allowed_residue_types_end(); ++iter) {
365 
366  // temporarily exclude proline residues from side chain sampling
367  if ((*iter)->nchi() > 0 && (*iter)->aa() != aa_pro) {
368  packed_residues_.push_back(i);
369  residue_packed_[i] = true;
370  break;
371  }
372  }
373  }
374 }
375 
376 bool
379 }
380 
381 void
384 ) {
386 }
387 
388 bool
391 }
392 
393 void
397 }
398 
402 }
403 
406  Real static const pi(numeric::NumericTraits<Real>::pi());
407 
408  init_task(pose);
409 
411 
412  for (Size i = 1; i <= packed_residues_.size(); ++i) {
413 
414  Size const resnum(packed_residues_[i]);
415 
416  bool all_names_match = true;
417 
418  // we only monitor DOFs of residues that won't change primary type
419  // check to see if pose residue type has the same name as all allowed residue types
420  pack::task::ResidueLevelTask const & residueleveltask(task_->residue_task(resnum));
421  for (pack::task::ResidueLevelTask::ResidueTypeCOPListConstIter iter(residueleveltask.allowed_residue_types_begin());
422  iter != residueleveltask.allowed_residue_types_end(); ++iter) {
423 
424  if ((*iter)->name3() != pose.residue_type(resnum).name3()) {
425  all_names_match = false;
426  break;
427  }
428  }
429 
430  if (!all_names_match) break;
431 
432  for (Size j = 1; j <= pose.residue_type(resnum).nchi(); ++j) {
433 
434  id::TorsionID chi_torsion(resnum, id::CHI, j);
435  id::DOF_ID chi_dof(pose.conformation().dof_id_from_torsion_id(chi_torsion));
436  if (chi_dof.valid()) range_vector.push_back(id::DOF_ID_Range(chi_dof, -pi, pi));
437  }
438  }
439 
440  return range_vector;
441 }
442 
445  return packed_residues_;
446 }
447 
450  return residue_packed_;
451 }
452 
455 }
456 
457 
458 } // sidechain_moves
459 } // simple_moves
460 } // protocols