Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
pack_rotamers.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/pack/pack_rotamers.cc
11 /// @brief pack rotamers module
12 /// @author Andrew Leaver-Fay (aleaverfay@gmail.com)
13 
14 // Unit Headers
16 
17 // Package Headers
24 // AUTO-REMOVED #include <core/pack/rotamer_set/symmetry/SymmetricRotamerSet_.hh>
25 // AUTO-REMOVED #include <core/pack/rotamer_set/RotamerCouplings.hh>
27 
32 
35 // AUTO-REMOVED #include <core/conformation/symmetry/util.hh>
36 
37 
38 // Project Headers
40 #include <core/graph/Graph.hh>
41 #include <core/pose/Pose.hh>
43 // AUTO-REMOVED #include <basic/options/util.hh>
44 
45 // util
46 #include <basic/prof.hh>
47 #include <basic/Tracer.hh>
48 #include <ObjexxFCL/format.hh>
49 
50 // option key includes
51 
52 #include <basic/options/keys/packing.OptionKeys.gen.hh>
53 
55 #include <utility/vector0.hh>
56 #include <utility/vector1.hh>
57 
58 
59 
60 
61 using namespace ObjexxFCL;
62 
63 namespace core {
64 namespace pack {
65 
68 
69 static basic::Tracer tt("core.pack.pack_rotamers",basic::t_info );
70 
71 // @begin pack_rotamers
72 // @details Wraps the two very distinct and separate stages of rotamer packing, which are factored so that they may be called asynchronously. Use this wrapper as a base model for higher-level packing routines (such as pack_rotamers_loop)
73 void
75  pose::Pose & pose,
76  scoring::ScoreFunction const & scfxn,
78 )
79 {
80  using namespace interaction_graph;
81  using namespace rotamer_set;
82 
83  //fpd safety check for symmetry
84  if ( core::pose::symmetry::is_symmetric( pose ) ) {
85  symmetric_pack_rotamers( pose, scfxn, task );
86  return;
87  }
88 
89  PROF_START( basic::PACK_ROTAMERS );
90 
91  pack_scorefxn_pose_handshake( pose, scfxn);
92 
93  //replace this with RotSetsFactory
95  InteractionGraphBaseOP ig = NULL;
96 
97  pack_rotamers_setup( pose, scfxn, task, rotsets, ig );
98  pack_rotamers_run( pose, task, rotsets, ig );
99 
100  // rescore here to make the state of the Energies good.
101  scfxn( pose );
102 
103  PROF_STOP ( basic::PACK_ROTAMERS );
104 }
105 
106 // @begin pack_rotamers_loop
107 // @details run the FixbbSimAnnealer multiple times using the same InteractionGraph, storing the results
108 void
110  pose::Pose & pose,
111  scoring::ScoreFunction const & scfxn,
112  task::PackerTaskCOP task,
113  Size const nloop
114 )
115 {
117  pack_rotamers_loop( pose, scfxn, task, nloop, results );
118 }
119 
120 // @begin pack_rotamers_loop
121 // @details run the FixbbSimAnnealer multiple times using the same InteractionGraph, storing the results
122 void
124  pose::Pose & pose,
125  scoring::ScoreFunction const & scfxn,
126  task::PackerTaskCOP task,
127  Size const nloop,
128  utility::vector1< std::pair< Real, std::string > > & results
129 )
130 {
132  pack_rotamers_loop( pose, scfxn, task, nloop, results, pose_list );
133 }
134 
135 // @begin pack_rotamers_loop
136 // @details run the FixbbSimAnnealer multiple times using the same InteractionGraph, storing the results
137 void
139  pose::Pose & pose,
140  scoring::ScoreFunction const & scfxn,
141  task::PackerTaskCOP task,
142  Size const nloop,
143  utility::vector1< std::pair< Real, std::string > > & results,
145 )
146 {
147  using namespace ObjexxFCL::fmt;
148  using namespace interaction_graph;
149  using namespace rotamer_set;
150 
152  InteractionGraphBaseOP ig = NULL;
153  pack_rotamers_setup( pose, scfxn, task, rotsets, ig );
154 
155  setup_IG_res_res_weights( pose, task, rotsets, ig );
156 
157  Real best_bestenergy( 0.0 );
158  pose::Pose best_pose;
159  best_pose = pose;
160 
161  for ( Size run(1); run <= nloop; ++run ) {
162 
163  Real bestenergy( pack_rotamers_run( pose, task, rotsets, ig ) );
164 
165  Real const final_score( scfxn( pose ) );
166  // show the resulting sequence
167  std::string final_seq;
168  for ( Size i=1; i<= pose.total_residue(); ++i ) {
169  if ( task->design_residue(i) ) final_seq+= pose.residue(i).name1();
170  }
171  if ( final_seq.size() == 0 ) final_seq = "-";
172 
173  tt << "packloop: " << I(4,run) << " rescore-deltaE: " << F(9,3,final_score - bestenergy ) <<
174  " seq: " << final_seq << " simannealerE: " << bestenergy << " rescoreE: " << final_score << std::endl;
175 
176  results.push_back( std::make_pair( final_score, pose.sequence() ) );
177  pose_list.push_back( new pose::Pose( pose ) ); //saves a copy.
178  if ( run == 1 || bestenergy < best_bestenergy ) {
179  best_pose = pose;
180  best_bestenergy = bestenergy;
181  }
182  }
183  pose = best_pose;
184 }
185 
186 // @begin pack_rotamers_setup
187 // @details get rotamers, compute energies
188 void
190  pose::Pose & pose,
191  scoring::ScoreFunction const & scfxn,
192  task::PackerTaskCOP task,
195 )
196 {
197  using namespace interaction_graph;
198 
199  pack_scorefxn_pose_handshake( pose, scfxn);
200 
202 
203  scfxn.setup_for_packing( pose, task->repacking_residues(), task->designing_residues() );
204 
205  graph::GraphOP packer_neighbor_graph = create_packer_graph( pose, scfxn, task );
206 
207  rotsets->set_task( task );
208 
209  rotsets->build_rotamers( pose, scfxn, packer_neighbor_graph );
210  rotsets->prepare_sets_for_packing( pose, scfxn );
211 
212  if ( basic::options::option[ basic::options::OptionKeys::packing::dump_rotamer_sets ] ) { // hacking
213  static int counter(0);
214  ++counter;
215  std::string const filename( "rotset"+lead_zero_string_of( counter,4 )+".pdb" );
216  tt << "dump rotsets: " << filename << std::endl;
217  rotsets->dump_pdb( pose, filename );
218  }
219 
220  ig = InteractionGraphFactory::create_interaction_graph( *task, *rotsets, pose, scfxn );
221 
222  tt << "built " << rotsets->nrotamers() << " rotamers at "
223  << rotsets->nmoltenres() << " positions." << std::endl;
224 
225  //for ( Size i=1; i<= pose.total_residue(); ++i ) {
226  // if ( task->design_residue(i) ) tt << "designing at position: " << i << std::endl;
227  //}
228 
229  PROF_START( basic::GET_ENERGIES );
230  rotsets->compute_energies( pose, scfxn, packer_neighbor_graph, ig );
231  PROF_STOP( basic::GET_ENERGIES );
232 
233  tt << "IG: " << ig->getTotalMemoryUsage() << " bytes" << std::endl;
234 
235 }
236 
237 
238 /// @brief upweights certain edges in the interaction graph if this is specified in the task
239 void
241  pose::Pose const & pose,
242  task::PackerTaskCOP task,
245 )
246 {
247  task::IGEdgeReweightContainerCOP edge_reweights = task->IGEdgeReweights();
248 
249  if( edge_reweights ){
250 
251  for( Size ii = 1; ii<= rotsets->nmoltenres(); ++ii){
252  Size const res1id = rotsets->moltenres_2_resid( ii );
253 
254  for( ig->reset_edge_list_iterator_for_node( ii ); !ig->edge_list_iterator_at_end(); ig->increment_edge_list_iterator() ){
255 
256  interaction_graph::EdgeBase const & edge( ig->get_edge() );
257  Size const other_node = edge.get_other_ind( ii );
258  if ( other_node < ii ) continue; // only deal with upper edges
259  Size const res2id = rotsets->moltenres_2_resid( other_node );
260  ig->set_edge_weight( ii, other_node, edge_reweights->res_res_weight( pose, *task, res1id, res2id ) );
261  }
262  }
263  } // if( edge_reweights )
264 
265 }//setup_IG_res_res_weights
266 
267 
268 
269 // @begin pack_rotamers_run
270 // @details as simple as possible -- runs simulated annealing and then places
271 // the optimal rotamers onto the backbone of the input pose.
272 Real
274  pose::Pose & pose,
275  task::PackerTaskCOP task,
278  utility::vector0< int > rot_to_pack // defaults to an empty vector (no effect)
279 )
280 {
281  using namespace ObjexxFCL::fmt;
282 
283  FArray1D_int bestrotamer_at_seqpos( pose.total_residue() );
284  core::PackerEnergy bestenergy( 0.0 );
285 
286  pack_rotamers_run( pose, task, rotsets, ig, rot_to_pack, bestrotamer_at_seqpos, bestenergy );
287 
288  // place new rotamers on input pose
289  for ( uint ii = 1; ii <= rotsets->nmoltenres(); ++ii ) {
290  uint iiresid = rotsets->moltenres_2_resid( ii );
291  uint iibestrot = rotsets->rotid_on_moltenresidue( bestrotamer_at_seqpos( iiresid ) );
292  conformation::ResidueCOP bestrot( rotsets->rotamer_set_for_moltenresidue( ii )->rotamer( iibestrot ) );
293 
294 // for( Size i = 1 ; i <= bestrot->natoms() ; ++i ) {
295 // std::cout << "bestrot " << bestrot->atom_name(i) <<
296 // " x " << bestrot->xyz(i)[0] <<
297 // " y " << bestrot->xyz(i)[1] <<
298 // " z " << bestrot->xyz(i)[2] << std::endl;
299 // }
300 
301  conformation::ResidueOP newresidue( bestrot->create_residue() );
302  pose.replace_residue ( iiresid, *newresidue, false );
303  }
304  return bestenergy;
305 }
306 
307 /// @brief Runs simulated annealing and returns the
308 void
310  pose::Pose const & pose,
311  task::PackerTaskCOP task,
314  utility::vector0< int > rot_to_pack,
315  ObjexxFCL::FArray1D_int & bestrotamer_at_seqpos,
316  core::PackerEnergy & bestenergy
317 )
318 {
319  using namespace annealer;
320 
321  bool start_with_current = false;
322  FArray1D_int current_rot_index( pose.total_residue(), 0 );
323  bool calc_rot_freq = false;
324  FArray1D< core::PackerEnergy > rot_freq( ig->get_num_total_states(), 0.0 );
325 
326  // too many parameters for annealer's constructor! should replace with a task only;
327  // the annealer should then provide read access to the data its collected after
328  // annealing has completed. some data it won't bother collecting because the task
329  // did not instruct it to.
330 
331  /// Parameters passed by reference in task's constructor to which it writes at the
332  /// completion of sim annealing.
333 
334  SimAnnealerBaseOP annealer = AnnealerFactory::create_annealer(
335  task, rot_to_pack, bestrotamer_at_seqpos, bestenergy, start_with_current, ig,
336  rotsets, current_rot_index, calc_rot_freq, rot_freq );
337 
338  // Following additional initialization would be cleaner if above suggestion
339  // regarding the removal of "too many parameters" is implemented properly.
340  if ( task->low_temp() > 0.0 ) annealer->set_lowtemp( task->low_temp() );
341  if ( task->high_temp() > 0.0 ) annealer->set_hightemp( task->high_temp() );
342  annealer->set_disallow_quench( task->disallow_quench() );
343 
344  PROF_START( basic::SIMANNEALING );
345  annealer->run();
346  PROF_STOP( basic::SIMANNEALING );
347 }
348 
349 void
351  pose::Pose & pose,
352  scoring::ScoreFunction const & scfxn,
353  task::PackerTaskCOP non_symmetric_task
354 )
355 {
356  using namespace interaction_graph;
357  using namespace rotamer_set;
358  PROF_START( basic::PACK_ROTAMERS );
359 
361 
362  pack_scorefxn_pose_handshake( pose, scfxn);
363 
364  //replace this with RotSetsFactory
366  InteractionGraphBaseOP ig = NULL;
367 
368  symmetric_pack_rotamers_setup( pose, scfxn, task, rotsets, ig );
369  symmetric_pack_rotamers_run( pose, task, rotsets, ig );
370 
371  // rescore here to make the state of the Energies good.
372  scfxn( pose );
373 
374  PROF_STOP ( basic::PACK_ROTAMERS );
375 }
376 
377 void
379  pose::Pose & pose,
380  scoring::ScoreFunction const & scfxn,
381  task::PackerTaskCOP task,
384 )
385 {
386  using namespace interaction_graph;
387 
388  pack_scorefxn_pose_handshake( pose, scfxn);
389 
391  scfxn.setup_for_packing( pose, task->repacking_residues(), task->designing_residues() );
392 
393  graph::GraphOP packer_neighbor_graph = create_packer_graph( pose, scfxn, task );
394 
395  //rotsets->set_symmetrical_task( task, pose );
396  rotsets->set_task( task );
397  rotsets->build_rotamers( pose, scfxn, packer_neighbor_graph );
398  rotsets->prepare_sets_for_packing( pose, scfxn );
399 
400  if ( basic::options::option[ basic::options::OptionKeys::packing::dump_rotamer_sets ] ) { // hacking
401  static int counter(0);
402  ++counter;
403  std::string const filename( "rotset"+lead_zero_string_of( counter,4 )+".pdb" );
404  tt << "dump rotsets: " << filename << std::endl;
405  rotsets->dump_pdb( pose, filename );
406  }
407 
408  ig = InteractionGraphFactory::create_interaction_graph( *task, *rotsets, pose, scfxn );
409 
410  tt << "built " << rotsets->nrotamers() << " rotamers at "
411  << rotsets->nmoltenres() << " positions." << std::endl;
412 
413  //for ( Size i=1; i<= pose.total_residue(); ++i ) {
414  // if ( task->design_residue(i) ) tt << "designing at position: " << i << std::endl;
415  //}
416 
417  PROF_START( basic::GET_ENERGIES );
418  rotsets->compute_energies( pose, scfxn, packer_neighbor_graph, ig );
419  PROF_STOP( basic::GET_ENERGIES );
420 
421  tt << "IG: " << ig->getTotalMemoryUsage() << " bytes" << std::endl;
422 
423 }
424 
425 // @begin pack_rotamers_run
426 // @details as simple as possible
427 Real
429  pose::Pose & pose,
430  task::PackerTaskCOP task,
433  utility::vector0< int > rot_to_pack // defaults to an empty vector (no effect)
434 )
435 {
436  using namespace ObjexxFCL::fmt;
437  using namespace annealer;
438 
439  // too many parameters for annealer's constructor! should replace with a task only;
440  // the annealer should then provide read access to the data its collected after
441  // annealing has completed. some data it won't bother collecting because the task
442  // did not instruct it to.
443 
444  // Symmetry info
445  SymmetricConformation const & SymmConf (
446  dynamic_cast<SymmetricConformation const &> ( pose.conformation()) );
447  SymmetryInfoCOP symm_info( SymmConf.Symmetry_Info() );
448 
449 
450  /// Parameters passed by reference in task's constructor to which it writes at the
451  /// completion of sim annealing.
452  FArray1D_int bestrotamer_at_seqpos( pose.total_residue() );
453  core::PackerEnergy bestenergy;
454  bool start_with_current = false;
455  FArray1D_int current_rot_index( pose.total_residue(), 0 );
456  bool calc_rot_freq = false;
457  FArray1D< core::PackerEnergy > rot_freq( ig->get_num_total_states(), 0.0 );
458 
459  SimAnnealerBaseOP annealer = AnnealerFactory::create_annealer(
460  task, rot_to_pack, bestrotamer_at_seqpos, bestenergy, start_with_current, ig,
461  rotsets, current_rot_index, calc_rot_freq, rot_freq );
462 
463 // SimAnnealerBaseOP annealer = new annealer::symmetry::SymFixbbSimAnnealer(
464 // rot_to_pack, bestrotamer_at_seqpos, bestenergy, start_with_current, ig,
465 // rotsets, current_rot_index, calc_rot_freq, rot_freq, symm_info );
466 
467  // Following additional initialization would be cleaner if above suggestion
468  // regarding the removal of "too many parameters" is implemented properly.
469  if ( task->low_temp() > 0.0 ) annealer->set_lowtemp( task->low_temp() );
470  if ( task->high_temp() > 0.0 ) annealer->set_hightemp( task->high_temp() );
471  annealer->set_disallow_quench( task->disallow_quench() );
472 
473  PROF_START( basic::SIMANNEALING );
474  annealer->run();
475  PROF_STOP( basic::SIMANNEALING );
476 
477  // place new rotamers on input pose
478  for ( uint ii = 1; ii <= rotsets->nmoltenres(); ++ii ) {
479  uint iiresid = rotsets->moltenres_2_resid( ii );
480  uint iibestrot = rotsets->rotid_on_moltenresidue( bestrotamer_at_seqpos( iiresid ) );
481  conformation::ResidueCOP bestrot( rotsets->rotamer_set_for_moltenresidue( ii )->rotamer( iibestrot ) );
482 
483 // for( Size i = 1 ; i <= bestrot->natoms() ; ++i ) {
484 // std::cout << "bestrot " << bestrot->atom_name(i) <<
485 // " x " << bestrot->xyz(i)[0] <<
486 // " y " << bestrot->xyz(i)[1] <<
487 // " z " << bestrot->xyz(i)[2] << std::endl;
488 // }
489 
490  conformation::ResidueOP newresidue( bestrot->create_residue() );
491  pose.replace_residue ( iiresid, *newresidue, false );
492 
493  //fpd replace residue is symmetric now
494  //for ( std::vector< Size>::const_iterator
495  // clone = symm_info.bb_clones( iiresid ).begin(),
496  // clone_end = symm_info.bb_clones( iiresid ).end();
497  // clone != clone_end; ++clone ){
498  // conformation::ResidueOP sym_rsd = newresidue->clone();
499  // sym_rsd->orient_onto_residue(pose.residue( *clone) );
500  // pose.replace_residue ( *clone, *sym_rsd, false );
501  // }
502  }
503  return bestenergy;
504 }
505 
506 
507 } // namespace pack
508 } // namespace core
509