Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
rtmin.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/rtmin.cc
11 /// @brief rotamer trials with minimization module header. Originally concieved of and implemented in Rosetta++ by Chu Wang.
12 /// @author Ian W. Davis (ian.w.davis@gmail.com)
13 /// @author Andrew Leaver-Fay (aleaverfay@gmail.com) -- reimplemented 8/2010
14 
15 // Unit headers
16 #include <core/pack/rtmin.hh>
17 
18 // Package headers
19 
30 
31 // Project headers
32 #include <core/types.hh>
33 
35 // AUTO-REMOVED #include <core/conformation/signals/GeneralEvent.hh>
36 #include <core/id/AtomID.hh>
37 // AUTO-REMOVED #include <core/id/AtomID_Mask.hh>
38 // AUTO-REMOVED #include <core/id/AtomID_Map.Pose.hh>
39 // AUTO-REMOVED #include <core/kinematics/MoveMap.hh>
40 // AUTO-REMOVED #include <core/kinematics/FoldTree.hh>
44 // AUTO-REMOVED #include <core/optimization/MinimizerMap.hh>
45 // AUTO-REMOVED #include <core/optimization/AtomTreeMultifunc.hh>
46 // AUTO-REMOVED #include <core/optimization/SingleResidueMultifunc.hh>
47 
48 #include <core/pose/Pose.hh>
50 #include <core/scoring/Energies.hh>
51 // AUTO-REMOVED #include <core/scoring/EnergyGraph.hh>
54 // AUTO-REMOVED #include <core/scoring/ScoreFunctionFactory.hh>
55 // AUTO-REMOVED #include <core/scoring/ScoringManager.hh>
56 // AUTO-REMOVED #include <core/scoring/hbonds/HBondOptions.hh>
57 // AUTO-REMOVED #include <core/scoring/methods/EnergyMethodOptions.hh>
59 // AUTO-REMOVED #include <core/scoring/ScoreFunctionInfo.hh>
60 // AUTO-REMOVED #include <core/scoring/hbonds/hbonds.hh>
61 // AUTO-REMOVED #include <core/scoring/hbonds/HBondSet.hh>
63 
64 // AUTO-REMOVED #include <basic/prof.hh>
65 #include <basic/Tracer.hh>
66 
67 #include <utility/vector1.hh>
68 // AUTO-REMOVED #include <utility/vector1.functions.hh>
69 
70 #include <numeric/random/random.hh>
71 #include <numeric/random/random_permutation.hh>
72 
73 // AUTO-REMOVED #include <ObjexxFCL/format.hh>
74 #include <basic/options/option.hh>
75 #include <basic/options/keys/optimization.OptionKeys.gen.hh>
76 
77 // STL headers
78 // AUTO-REMOVED #include <ctime>
79 
80 #include <core/kinematics/Jump.hh>
81 #include <utility/vector0.hh>
82 
83 //Auto using namespaces
84 namespace ObjexxFCL { namespace fmt { } } using namespace ObjexxFCL::fmt; // AUTO USING NS
85 //Auto using namespaces end
86 
87 
88 namespace core {
89 namespace pack {
90 
91 using namespace ObjexxFCL::fmt;
92 
93 static numeric::random::RandomGenerator rtmin_RG(206025); // <- Magic number, do not change it!!!
94 
95 static basic::Tracer TR( "core.pack.rtmin" );
96 
97 //forward dec
99 repackable_residues_dup( task::PackerTask const & the_task );
100 
102  pose::Pose & pose,
103  scoring::ScoreFunction const & scorefxn,
105  pack::scmin::SCMinMinimizerMap const & scminmap,
106  conformation::Residue const & rsd,
107  scoring::MinimizationGraph & mingraph
108 );
109 
110 
111 RTMin::RTMin()
112  : minimize_ligand_chis_(true),
113  minimize_ligand_jumps_(false),
114  nonideal_(false),
115  cartesian_(false)
116 {}
117 
119  bool minimize_ligand_chis,
120  bool minimize_ligand_jumps
121 ) :
122  minimize_ligand_chis_(minimize_ligand_chis),
123  minimize_ligand_jumps_(minimize_ligand_jumps)
124 {}
125 
127 
128 /// @details Don't look, it's not pretty!
129 void
131  pose::Pose & pose,
132  scoring::ScoreFunction const & scfxn,
133  task::PackerTaskOP input_task
134 ) const
135 {
136  using namespace conformation;
137  using namespace chemical;
138  using namespace pack::rotamer_set;
139  using namespace pack::scmin;
140  using namespace pose;
141  using namespace scoring;
142  using namespace scoring::methods;
143  using namespace optimization;
144  using namespace graph;
145  using namespace basic::options;
147 
148  /// 1st verify that all energy methods are compatible with rtmin.
149  /// No energy method that requires whole-structure context to calculate derivatives
150  /// can be used within rtmin, unless it is a whole-structure energy, in which
151  /// case, RTMin will not complain, BUT the energy will not be minimized.
152  bool bad( false );
153  for ( ScoreFunction::AllMethodsIterator iter = scfxn.all_methods().begin(),
154  iter_end = scfxn.all_methods().end(); iter != iter_end; ++iter ) {
155  /// Allow whole-structure energy methods to be present. They will not be minized!
156  /// When would this be good? If RG or chainbreak were on.
157  if ( (*iter)->method_type() != ws && (*iter)->minimize_in_whole_structure_context( pose ) ) {
158  std::cerr << "Scoring term responsible for score types:";
159  for ( Size ii = 1; ii <= (*iter)->score_types().size(); ++ii ) {
160  std::cerr << " " << (*iter)->score_types()[ ii ];
161  }
162  std::cerr << " states that it requires whole-structure context to perform minimization, and thus" <<
163  " cannot be used in RTMin." << std::endl;
164  bad = true;
165  }
166  }
167  if ( bad ) {
168  utility_exit_with_message( "Incompatible scoring terms requested in invocation of RTMin" );
169  }
170 
171  utility::vector1< Size > inactive_neighbors;
172  inactive_neighbors.reserve( pose.total_residue() );
173  utility::vector1< bool > residue_is_inactive_neighbor( pose.total_residue(), false );
174  utility::vector1< bool > active_residue_has_been_visited( pose.total_residue(), false );
175 
176  utility::vector1< Size > active_residues = pack::repackable_residues_dup( *input_task );
177  numeric::random::random_permutation( active_residues, rtmin_RG );
178 
180  graph::GraphOP packer_neighbor_graph = pack::create_packer_graph( pose, scfxn, input_task );
181  scoring::MinimizationGraph mingraph( pose.total_residue() );
182 
183  SCMinMinimizerMapOP scminmap;
184  if (cartesian_) {
185  scminmap = new CartSCMinMinimizerMap();
186  } else {
187  scminmap = new AtomTreeSCMinMinimizerMap();
188  }
189  scminmap->set_nonideal( nonideal_ );
190  scminmap->set_total_residue( pose.total_residue() );
191 
192  EnergyMap emap_dummy;
193 
194  // true -- nblist, false -- deriv_check, false -- deriv_verbose
195  //optimization::MinimizerOptions min_options( "dfpmin", 0.1, true, false, false );
196  std::string minimizer = "dfpmin";
197  Size max_iter=200;
198  if (cartesian_) {
199  minimizer = "lbfgs_armijo";
200  max_iter = 25;
201  }
202 
203  optimization::MinimizerOptions min_options( minimizer, 0.1, true, false, false );
204  min_options.max_iter(max_iter);
205  min_options.silent(true);
206 
207 
208  for ( Size ii = 1; ii <= input_task->num_to_be_packed(); ++ii ) {
209  Size iires = active_residues[ ii ];
211  eiter = packer_neighbor_graph->get_node( iires )->const_edge_list_begin(),
212  eiter_end = packer_neighbor_graph->get_node( iires )->const_edge_list_end();
213  eiter != eiter_end; ++eiter ) {
214  Size jjres = (*eiter)->get_other_ind( iires );
215  if ( ! bgres[ jjres ] && ! input_task->being_packed( jjres )) {
216  inactive_neighbors.push_back( jjres );
217  residue_is_inactive_neighbor[ jjres ] = true;
218  bgres[ jjres ] = new Residue( pose.residue( jjres ) );
219  scminmap->set_natoms_for_residue( jjres, bgres[ jjres ]->natoms() );
220  /// Do setup_for_minimizing for background nodes once and leave them alone for
221  /// the rest of the trajectory
223  * mingraph.get_minimization_node( jjres ), pose.residue( jjres ),
224  *scminmap, pose, false, emap_dummy );
225  }
226  if ( ! input_task->being_packed( jjres ) || iires < jjres ) {
227  mingraph.add_edge( iires, jjres ); // add edges, but don't bother calling setup_for_minimization yet
228  }
229  }
230 
231  // LR2B neighbor graphs may not coincide with the
232  // packer_neighbor_graph. Make the background nodes the union of
233  // the background nodes from the packer_neighbor_graph and the
234  // background nodes for each LR2B neighbor graph
236  iter = scfxn.long_range_energies_begin(),
237  iter_end = scfxn.long_range_energies_end();
238  iter != iter_end; ++iter ) {
239 
240  if ( (*iter)->minimize_in_whole_structure_context( pose ) ) continue;
241 
242  LREnergyContainerCOP lrec = pose.energies().long_range_container( (*iter)->long_range_type() );
243  if ( !lrec || lrec->empty() ) continue;
244 
245  EnergyMap dummy_emap;
246 
247  // Potentially O(N) operation...
249  rni = lrec->const_neighbor_iterator_begin( iires ), // traverse both upper and lower neighbors
250  rniend = lrec->const_neighbor_iterator_end( iires );
251  (*rni) != (*rniend); ++(*rni) ) {
252  Size const r1 = rni->lower_neighbor_id();
253  Size const r2 = rni->upper_neighbor_id();
254  Size const jjres = ( r1 == iires ? r2 : r1 );
255  bool const res_moving_wrt_eachother( true );
256 
257  if ( ! bgres[ jjres ] && ! input_task->being_packed( jjres )) {
258  inactive_neighbors.push_back( jjres );
259  residue_is_inactive_neighbor[ jjres ] = true;
260  bgres[ jjres ] = new Residue( pose.residue( jjres ) );
261  scminmap->set_natoms_for_residue( jjres, bgres[ jjres ]->natoms() );
262  /// Do setup_for_minimizing for background nodes once and leave them alone for
263  /// the rest of the trajectory
265  * mingraph.get_minimization_node( jjres ), pose.residue( jjres ),
266  *scminmap, pose, false, emap_dummy );
267  }
268  if ( ! input_task->being_packed( jjres ) || iires < jjres ) {
269  if(!mingraph.get_edge_exists(iires, jjres)){
270  mingraph.add_edge( iires, jjres ); // add edges, but don't bother calling setup_for_minimization yet
271  }
272  }
273  }
274  }
275 
276  }
277 
278 
279  input_task->set_bump_check( false );
280  input_task->or_include_current( true );
281  input_task->temporarily_fix_everything();
282 
283  /// in real rtmin, the active residues will be examined in a random order;
284  /// random__shuffle( active_residues );
285 
286  Size ndofs = 4;
287  if (nonideal_) ndofs=14;
288  if (cartesian_) ndofs=75;
289 
290  optimization::Multivec chi(ndofs); // guess -- resized smaller
291 
292  for ( Size ii = 1; ii <= active_residues.size(); ++ii ) {
293  /// Now, build rotamers, prep the nodes and edges of the minimization graph
294  /// and build the AtomTreeCollection for this residue;
295  Size iiresid = active_residues[ ii ];
296  conformation::Residue const & trial_res = pose.residue( iiresid );
297  scminmap->activate_residue_dofs( iiresid );
298 
299  //pretend this is a repacking and only this residue is being repacked
300  //while all other residues are being held fixed.
301  input_task->temporarily_set_pack_residue( iiresid, true );
302 
303  RotamerSetFactory rsf;
304  rotamer_set::RotamerSetOP iirotset = rsf.create_rotamer_set( trial_res );
305  iirotset->set_resid( iiresid );
306  iirotset->build_rotamers( pose, scfxn, *input_task, packer_neighbor_graph );
307  assert( iirotset->id_for_current_rotamer() != 0 );
308 
309  AtomTreeCollectionOP ii_atc = new AtomTreeCollection( pose, *iirotset, iiresid );
310  ii_atc->residue_atomtree_collection( iiresid ).set_active_restype_index( 1 ); // start at the beginning.
311  ii_atc->residue_atomtree_collection( iiresid ).set_rescoords( * iirotset->rotamer( 1 ) );
312  ii_atc->residue_atomtree_collection( iiresid ).update_atom_tree();
313  scminmap->setup( ii_atc );
314 
315  {/// SCOPE -- make sure the minimization graph is ready to optimize this residue
316  Residue const & iirsd( ii_atc->residue_atomtree_collection( iiresid ).active_residue() );
317  if ( ! bgres[ iiresid ] ) {
318  // we have not ever done setup for scoring for this residue
320  * mingraph.get_minimization_node( iiresid ), iirsd,
321  *scminmap, pose, false, emap_dummy );
322  } else {
324  * mingraph.get_minimization_node( iiresid ), iirsd,
325  *scminmap, pose );
326  }
328  eiter = mingraph.get_node( iiresid )->edge_list_begin(),
329  eiter_end = mingraph.get_node( iiresid )->edge_list_end();
330  eiter != eiter_end; ++eiter ) {
331 
332  Size jjresid = (*eiter)->get_other_ind( iiresid );
333  if ( ! bgres[ jjresid ] ) {
334  /// we have an active residue which we have not yet visited in the rtmin traversal
335  bgres[ jjresid ] = new Residue( pose.residue( jjresid ) );
337  * mingraph.get_minimization_node( jjresid ),
338  * bgres[ jjresid ],
339  *scminmap, pose, false, emap_dummy );
340  scminmap->set_natoms_for_residue( jjresid, bgres[ jjresid ]->natoms() );
341  }
342  Residue const & jjrsd( * bgres[ jjresid ] );
343  MinimizationEdge & min_edge( static_cast< MinimizationEdge & > ( **eiter ));
344  //std::cout << "Minedge " << iiresid << " " << jjresid << std::endl;
345  if ( jjresid < iiresid ) {
346  if ( residue_is_inactive_neighbor[ jjresid ] || ! active_residue_has_been_visited[ jjresid ] ) {
348  jjrsd, iirsd, min_edge, *scminmap, pose, true, false, ( EnergyEdge * ) 0, emap_dummy );
349  } else {
350  min_edge.reinitialize_active_energy_methods( iirsd, jjrsd, pose, true);
351  }
352  /// hold off on the setup_for_minimizing until we know we're done with this edge (no long-range additions)
353  ///min_edge.setup_for_minimizing( jjrsd, iirsd, pose, scfxn, scminmap );
354 
355  } else {
356  if ( residue_is_inactive_neighbor[ jjresid ] || ! active_residue_has_been_visited[ jjresid ] ) {
358  iirsd, jjrsd, min_edge, *scminmap, pose, true, false, ( EnergyEdge * ) 0, emap_dummy );
359  } else {
360  min_edge.reinitialize_active_energy_methods( jjrsd, iirsd, pose, true);
361  }
362  /// hold off on the setup_for_minimizing until we know we're done with this edge (no long-range additions)
363  ///min_edge.setup_for_minimizing( iirsd, jjrsd, pose, scfxn, scminmap );
364  }
365  }
366  //// LONG RANGE SETUP
368  iter = scfxn.long_range_energies_begin(),
369  iter_end = scfxn.long_range_energies_end();
370  iter != iter_end; ++iter ) {
371 
372  if ( (*iter)->minimize_in_whole_structure_context( pose ) ) continue;
373 
374  LREnergyContainerCOP lrec = pose.energies().long_range_container( (*iter)->long_range_type() );
375  if ( !lrec || lrec->empty() ) continue;
376 
377  EnergyMap dummy_emap;
378 
379  // Potentially O(N) operation...
381  rni = lrec->const_neighbor_iterator_begin( iiresid ), // traverse both upper and lower neighbors
382  rniend = lrec->const_neighbor_iterator_end( iiresid );
383  (*rni) != (*rniend); ++(*rni) ) {
384  Size const r1 = rni->lower_neighbor_id();
385  Size const r2 = rni->upper_neighbor_id();
386  Size const jjresid = ( r1 == iiresid ? r2 : r1 );
387  bool const res_moving_wrt_eachother( true );
388 
389  /// We've already set up the long-range energy methods for this edge if
390  /// jjresid is an active residue that has already had its conformation optimized
391  if ( active_residue_has_been_visited[ jjresid ] ) continue;
392  conformation::Residue const & lower_res( r1 == iiresid ? iirsd : *bgres[ jjresid ] );
393  conformation::Residue const & upper_res( r1 == iiresid ? *bgres[ jjresid ] : iirsd );
395  lower_res, upper_res, *iter, mingraph, *scminmap, pose,
396  res_moving_wrt_eachother, false, rni, dummy_emap );
397  }
398  }
399 
400  } /// END MinimizationGraph initialization SCOPE
401 
402  /// OK: now start iterating across rotamers, setting up for minimization when the residue type changes,
403  /// initializing the scminmultifunc
404  Size next_restype_index( 2 );
405 
406  Real best_score( 0.0 ); bool first_pass( true );
407 #ifdef APL_FULL_DEBUG
408  Real best_real_score( 0.0 );
409 #endif
410  ResidueAtomTreeCollectionMomento momento;
411  scminmap->set_natoms_for_residue( iiresid, ii_atc->residue_atomtree_collection( iiresid ).active_residue().natoms() );
412  for ( Size jj = 1, jj_end = iirotset->num_rotamers(); jj <= jj_end; ++jj ) {
413  if (next_restype_index <= iirotset->get_n_residue_types() &&
414  iirotset->get_residue_type_begin( next_restype_index ) == jj ) {
415  ii_atc->residue_atomtree_collection( iiresid ).set_active_restype_index( next_restype_index );
416  ++next_restype_index;
417 
418  ii_atc->residue_atomtree_collection( iiresid ).set_rescoords( * iirotset->rotamer( jj ));
419  ii_atc->residue_atomtree_collection( iiresid ).update_atom_tree();
420  scminmap->set_natoms_for_residue( iiresid, iirotset->rotamer( jj )->natoms() );
421 
422  scminmap->setup( ii_atc ); // traverse the atom tree and identify dofs
423  }
424 
425  ii_atc->residue_atomtree_collection( iiresid ).set_rescoords( * iirotset->rotamer( jj ));
426  ii_atc->residue_atomtree_collection( iiresid ).update_atom_tree();
427  //chi = iirotset->rotamer( jj )->chi();
428  scminmap->starting_dofs( chi );
429 
430  reinitialize_mingraph_neighborhood_for_residue( pose, scfxn, bgres, *scminmap, scminmap->residue( iiresid ), mingraph );
431 
432 #ifdef APL_FULL_DEBUG
433  pose.replace_residue( iiresid, ii_atc->residue_atomtree_collection( iiresid ).active_residue(), false );
434  Real const real_start_score( scfxn( pose ) );
435 #endif
436  //pose.dump_pdb( "rtmin_before_" + utility::to_string( iiresid ) + "_" + utility::to_string( jj ) + ".pdb" );
437  /// OK: Minimization graph is initialized. Now setup the SCMinMultifunc
438  //SCMinMultifunc scmin_multifunc( pose, bgres, scfxn, mingraph, *scminmap );
439  MultifuncOP scmin_multifunc = scminmap->make_multifunc( pose, bgres, scfxn, mingraph );
440  //Real const start_score( scmin_multifunc( chi ) );
441 
442  //std::cout << "Starting comparison: " << iiresid << " " << start_score << " " << iirotset->rotamer( jj )->name() << std::endl;
443 #ifdef APL_FULL_DEBUG
444  deriv_check_for_residue( iiresid, jj, *scmin_multifunc, chi );
445  compare_mingraph_and_energy_graph( iiresid, pose, scfxn, mingraph );
446 #endif
447 
448  Minimizer minimizer( *scmin_multifunc, min_options );
449  //Real const start_func = (*scmin_multifunc)( chi );
450  //Real const end_func =
451  minimizer.run( chi );
452  /// Note: our neighborlist may have gone out-of-date. Update now to make sure the best rotamer is placed in the pose
453  reinitialize_mingraph_neighborhood_for_residue( pose, scfxn, bgres, *scminmap, scminmap->residue( iiresid ), mingraph );
454  Real const end_score = (*scmin_multifunc)( chi );
455  //for ( Size kk = 1; kk <= chi.size(); ++kk ) {
456  // std::cout << "chi " << kk << " " << chi[ kk ] << " vs "
457  // << ii_atc->residue_atomtree_collection( iiresid ).active_residue().chi()[ kk ]
458  // << " ";
459  //}
460  //std::cout << std::endl;
461 
462 #ifdef APL_FULL_DEBUG
463  pose.replace_residue( iiresid, ii_atc->residue_atomtree_collection( iiresid ).active_residue(), false );
464  Real const real_end_score( scfxn( pose ) );
465  //std::cout << "Ending comparison: " << iiresid << " " << end_score << " " << real_end_score << " " << iirotset->rotamer( jj )->name() << std::endl;
466  deriv_check_for_residue( iiresid, jj, *scmin_multifunc, chi );
467  compare_mingraph_and_energy_graph( iiresid, pose, scfxn, mingraph );
468  //if ( iiresid == 14 && jj == 7 ) {
469  // atom_tree_multifunc_dump( pose, scfxn, chi, ii );
470  //}
471 #endif
472 
473  if ( first_pass || end_score <= best_score ) {
474  best_score = end_score;
475 #ifdef APL_FULL_DEBUG
476  best_real_score = real_end_score;
477 #endif
478  first_pass = false;
479  ii_atc->residue_atomtree_collection( iiresid ).save_momento( momento );
480  }
481 
482  // ok -- lets get here
483  //std::cout << "iiresid " << iiresid << " rot: " << jj << " start score: "
484  // << start_score << " end score: " << end_score << " real start: " << real_start_score
485  // << " real end:" << real_end_score << " ddScore " << ( end_score - start_score ) - ( real_end_score - real_start_score )
486  // << std::endl;
487 
488  //pose.dump_pdb( "rtmin_after_" + utility::to_string( iiresid ) + "_" + utility::to_string( jj ) + ".pdb" );
489 
490  }
491  ii_atc->residue_atomtree_collection( iiresid ).update_from_momento( momento );
492  bgres[ iiresid ] = new Residue( ii_atc->residue_atomtree_collection( iiresid ).active_residue() );
493 
494  /// NOW, we must call setup_for_scoring_for_residue for this residue we've just replaced, and
495  /// for the edges adjacent to this residue and to other non-background residues so that the guarantee
496  /// that setup_for_scoring_for_residue has been called on a residue before the next time its score is
497  /// evaluated as a two-body energy
498 
499  //scfxn.reinitialize_minnode_for_residue( * mingraph.get_minimization_node( iiresid ),
500  // *bgres[ iiresid ], scminmap, pose );
501  reinitialize_mingraph_neighborhood_for_residue( pose, scfxn, bgres, *scminmap, *bgres[ iiresid ], mingraph );
502 
503  /*for ( graph::Graph::EdgeListIter
504  edgeit = mingraph.get_node( iiresid )->edge_list_begin(),
505  edgeit_end = mingraph.get_node( iiresid )->edge_list_end();
506  edgeit != edgeit_end; ++edgeit ) {
507  Size const jjresid = (*edgeit)->get_other_ind( iiresid );
508  if ( residue_is_inactive_neighbor[ jjresid ] ) continue;
509 
510  MinimizationEdge & min_edge = static_cast< MinimizationEdge & > ( (**edgeit) );
511  if ( iiresid < jjresid ) {
512  min_edge.reinitialize_active_energy_methods( *bgres[ iiresid ], *bgres[ jjresid ], pose, true);
513  min_edge.setup_for_minimizing( *bgres[ iiresid ], *bgres[ jjresid ], pose, scfxn, scminmap );
514  } else {
515  min_edge.reinitialize_active_energy_methods( *bgres[ jjresid ], *bgres[ iiresid ], pose, true);
516  min_edge.setup_for_minimizing( *bgres[ jjresid ], *bgres[ iiresid ], pose, scfxn, scminmap );
517  }
518 
519  }*/
520  active_residue_has_been_visited[ iiresid ] = true;
521  scminmap->clear_active_dofs();
522  pose.replace_residue( iiresid, *bgres[ iiresid ], false );
523 
524 #ifdef APL_FULL_DEBUG
525  for ( Size jj = 1; jj <= bgres[ iiresid ]->natoms(); ++jj ) {
526  assert( bgres[ iiresid ]->xyz( jj ).distance( pose.residue( iiresid ).xyz( jj ) ) < 1e-5 );
527  }
528  Real const ii_final_score( scfxn( pose ) );
529  assert( std::abs( best_real_score - ii_final_score ) < 1e-13 );
530 #endif
531  //pose.dump_pdb( "rtmin_selected_" + utility::to_string( iiresid ) + ".pdb" );
532  //std::cout << "Round " << ii << " final score: " << scfxn(pose) << std::endl;
533  }
534 
535 }
536 
537 /*{
538  using namespace numeric::random;
539  using namespace core::optimization;
540 
541  PROF_START( basic::ROTAMER_TRIALS );
542  pack_scorefxn_pose_handshake( pose, scfxn);
543  pose.update_residue_neighbors();
544 
545  utility::vector1< uint > residues_for_trials( repackable_residues_dup( *input_task ));
546  random_permutation( residues_for_trials, rtmin_RG );
547 
548  task::PackerTaskOP rottrial_task( input_task->clone() );
549  rottrial_task->set_bump_check( false );
550  rottrial_task->or_include_current( true );
551  rottrial_task->temporarily_fix_everything();
552 
553  // this will call setup fxns for each scoring method, eg HBondEnergy will
554  // compute backbone hbonds to prepare for hbchecking,
555  // PairEnergy will update actcoords...
556  scfxn.setup_for_packing( pose, rottrial_task->repacking_residues(),rottrial_task->designing_residues() );
557 
558  rotamer_set::RotamerSetFactory rsf;
559  graph::GraphOP packer_neighbor_graph = create_packer_graph( pose, scfxn, input_task );
560 
561  Size const num_in_trials = residues_for_trials.size();
562  for (Size ii = 1; ii <= num_in_trials; ++ii)
563  {
564  pose.update_residue_neighbors(); // will return if uptodate
565 
566  int const resid = residues_for_trials[ ii ];
567  conformation::Residue const & trial_res = pose.residue( resid );
568 
569  //pretend this is a repacking and only this residue is being repacked
570  //while all other residues are being held fixed.
571  rottrial_task->temporarily_set_pack_residue( resid, true );
572 
573  rotamer_set::RotamerSetOP rotset = rsf.create_rotamer_set( trial_res );
574  rotset->set_resid( resid );
575  rotset->build_rotamers( pose, scfxn, *rottrial_task, packer_neighbor_graph );
576  scfxn.prepare_rotamers_for_packing( pose, *rotset );
577  TR.Debug << "working on " << resid << " with " << rotset->num_rotamers() << " rotamers" << std::endl;
578 
579  // All DOF start false (frozen)
580  kinematics::MoveMap movemap;
581  if( !pose.residue_type( resid ).is_ligand() ) movemap.set_chi(resid, true);
582  else{
583  if( minimize_ligand_chis_ ) movemap.set_chi(resid, true);
584  if( minimize_ligand_jumps_ ){
585  movemap.set_jump( pose.fold_tree().get_jump_that_builds_residue( resid ), true );
586  }
587  }
588  optimization::MinimizerOptions min_options("dfpmin", 0.1, true , false, false);
589 
590  Size best_jj = 0;
591  Real best_score = 1e99;
592  conformation::ResidueOP best_rsd;
593  for ( Size jj = 1; jj <= rotset->num_rotamers(); ++jj ) {
594  conformation::ResidueOP newresidue( rotset->rotamer( jj )->clone() );
595 
596  // Assume that protein residues' conformation is fully specified by chi angles.
597  // This is NOT true for e.g. ligands, which may have e.g. various ring puckers.
598  if( newresidue->is_protein() && newresidue->type().name() == pose.residue_type(resid).name() ) {
599  //TR << "Setting chi angles..." << std::endl;
600  for( Size kk = 1; kk <= newresidue->nchi(); ++kk ) {
601  pose.set_chi(kk, resid, newresidue->chi(kk));
602  }
603  } else {
604  pose.replace_residue( resid, *newresidue, false );
605  scfxn.update_residue_for_packing( pose, resid );
606  }
607 
608  // Code copied from AtomTreeMinimizer::run()
609  // This has to be repeated for each residue because the ResidueType may change if we're doing design.
610  // Even if not, we get a fatal error if we try to do it outside the loop,
611  // which I think is related to replace_residue() modifying the structure of the atom tree.
612  // It's important that the structure be scored prior to nblist setup -- why?
613  // A: required for graph state == GOOD; triggers assert in debug mode.
614  //Real const start_score = scfxn( pose );
615  // Actually, this appears to be sufficient, and is much cheaper (no twobody energy calc)
616  pose.scoring_begin( scfxn );
617  pose.scoring_end( scfxn );
618  // setup the map of the degrees of freedom
619  MinimizerMap min_map;
620  min_map.setup( pose, movemap );
621  // if we are using the nblist, set it up
622  if ( min_options.use_nblist() ) {
623  // setup a mask of the moving dofs
624  pose.energies().set_use_nblist( pose, min_map.domain_map(), min_options.nblist_auto_update() );
625  }
626  scfxn.setup_for_minimizing( pose, min_map );
627  // setup the function that we will pass to the low-level minimizer
628  //AtomTreeMultifunc f( pose, min_map, scfxn, min_options.deriv_check(), min_options.deriv_check_verbose() );
629  SingleResidueMultifunc f( pose, resid, min_map, scfxn, packer_neighbor_graph, min_options.deriv_check(), min_options.deriv_check_verbose() );
630  // starting position -- "dofs" = Degrees Of Freedom
631  Multivec dofs( min_map.nangles() );
632 
633  // Code copied from AtomTreeMinimizer::run()
634  min_map.copy_dofs_from_pose( pose, dofs );
635  //Real const start_func = f( dofs );
636 
637  // This actually caches the hbonds, etc.
638  for ( scoring::ScoreFunction::AllMethodsIterator it=scfxn.all_energies_begin(),
639  it_end = scfxn.all_energies_end(); it != it_end; ++it ) {
640  (*it)->setup_for_scoring( pose, scfxn );
641  }
642 
643  // now do the optimization with the low-level minimizer function
644  Minimizer minimizer( f, min_options );
645  Real const score = minimizer.run( dofs );
646  //Real const end_func = f( dofs );
647  TR.Trace << "Rotamer " << jj << " " << newresidue->name3() <<
648  " nangles= " << min_map.nangles() <<
649  //" start_score: " << F(12,3,start_score) <<
650  //" start_func: " << F(12,3,start_func) <<
651  " score: " << F(12,3,score ) <<
652  //" end_func: " << F(12,3,end_func ) <<
653  std::endl;
654 
655  if ( min_options.use_nblist() ) pose.energies().reset_nblist();
656 
657  if(score < best_score) {
658  best_jj = jj;
659  best_score = score;
660  best_rsd = pose.residue(resid).clone();
661  }
662  }
663 
664  if ( best_jj > 0 ) {
665  pose.replace_residue ( resid, *best_rsd, false );
666  scfxn.update_residue_for_packing( pose, resid );
667  }
668 
669  rottrial_task->temporarily_set_pack_residue( resid, false );
670  }
671  PROF_STOP ( basic::ROTAMER_TRIALS );
672 }*/
673 
675  pose::Pose & pose,
676  scoring::ScoreFunction const & scorefxn,
678  pack::scmin::SCMinMinimizerMap const & scminmap,
679  conformation::Residue const & rsd,
680  scoring::MinimizationGraph & mingraph
681 )
682 {
683  //Residue const & iires( ii_atc->residue_atomtree_collection( iiresid ).active_residue() );
684  Size const resid = rsd.seqpos();
685  //std::cout << "reinitialize_mingraph_neighborhood_for_residue: " << resid << std::endl;
686 
687  /// Setup the minimization graph for this new restype
689  * mingraph.get_minimization_node( resid ),
690  rsd, scminmap, pose );
691  /// Now, iterate across all the edges and set them up
693  eiter = mingraph.get_node( resid )->edge_list_begin(),
694  eiter_end = mingraph.get_node( resid )->edge_list_end();
695  eiter != eiter_end; ++eiter ) {
696  Size iiresid = (*eiter)->get_other_ind( resid );
697  scoring::MinimizationEdge & min_edge( static_cast< scoring::MinimizationEdge & > ( **eiter ));
698  if ( resid <= iiresid ) {
699  min_edge.reinitialize_active_energy_methods( rsd, *bgres[ iiresid ], pose, true);
700  min_edge.setup_for_minimizing( rsd, *bgres[ iiresid ], pose, scorefxn, scminmap );
701  } else {
702  min_edge.reinitialize_active_energy_methods( *bgres[ iiresid ], rsd, pose, true);
703  min_edge.setup_for_minimizing( *bgres[ iiresid ], rsd, pose, scorefxn, scminmap );
704  }
705  }
706 
707 }
708 
709 
712 {
713  utility::vector1< int > to_be_packed( the_task.num_to_be_packed() );
714  uint count = 0;
715  for (uint ii = 1; ii <= the_task.total_residue(); ++ii )
716  {
717  if ( the_task.pack_residue( ii ) )
718  {
719  ++count;
720  to_be_packed[ count ] = ii;
721  }
722  }
723  return to_be_packed;
724 }
725 
726 
727 } //end namespace core
728 } //end namespace pack