Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
BDR.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/forge/components/BDR.cc
11 /// @brief
12 /// @author Yih-En Andrew Ban (yab@u.washington.edu)
13 
14 // unit headers
16 
17 // package headers
25 
26 // project headers
27 #include <core/chemical/AA.hh>
29 
35 #include <core/pose/Pose.hh>
37 #include <core/scoring/Energies.hh>
40 // AUTO-REMOVED #include <core/scoring/constraints/Constraint.hh>
41 #include <basic/MetricValue.hh>
42 #include <basic/Tracer.hh>
51 // AUTO-REMOVED #include <protocols/forge/remodel/RemodelConstraintGenerator.hh>
52 
53 // C++ headers
54 #include <utility>
55 
56 //Auto Headers
59 #include <utility/vector0.hh>
60 #include <utility/vector1.hh>
61 
62 namespace protocols {
63 namespace forge {
64 namespace components {
65 
66 
67 static basic::Tracer TR( "protocols.forge.components.BDR" );
68 
69 
70 /// @brief default constructor
72  Super( "BDR" ),
73  use_fullmer_( false ),
74  use_sequence_bias_( false ),
75  max_linear_chainbreak_( 0.07 ),
76  centroid_loop_mover_str_( "RemodelLoopMover" ),
77  redesign_loop_neighborhood_( true ),
78  dr_cycles_( 3 ),
79  centroid_sfx_( core::scoring::ScoreFunctionFactory::create_score_function( "remodel_cen" ) ),
80  fullatom_sfx_( core::scoring::ScoreFunctionFactory::create_score_function( core::scoring::STANDARD_WTS, core::scoring::SCORE12_PATCH ) )
81 {}
82 
83 
84 /// @brief copy constructor
85 BDR::BDR( BDR const & rval ) :
86  //utility::pointer::ReferenceCount(),
87  Super( rval ),
88  manager_( rval.manager_ ),
89  design_info_( rval.design_info_ ),
90  use_fullmer_( rval.use_fullmer_ ),
91  use_sequence_bias_( rval.use_sequence_bias_ ),
92  max_linear_chainbreak_( rval.max_linear_chainbreak_ ),
93  centroid_loop_mover_str_( rval.centroid_loop_mover_str_ ),
94  redesign_loop_neighborhood_( rval.redesign_loop_neighborhood_ ),
95  resfile_( rval.resfile_ ),
96  dr_cycles_( rval.dr_cycles_ ),
97  centroid_sfx_( rval.centroid_sfx_->clone() ),
98  fullatom_sfx_( rval.fullatom_sfx_->clone() )
99 {
100  if ( rval.vlb_.get() ) {
101  vlb_ = new VarLengthBuild( *rval.vlb_ );
102  }
103 }
104 
105 
106 /// @brief default destructor
108 
109 
110 /// @brief clone this object
112  return new BDR( *this );
113 }
114 
115 
116 /// @brief create this type of object
118  return new BDR();
119 }
120 
121 
122 /// @brief the centroid level score function, default "remodel_cen"
124  return *centroid_sfx_;
125 }
126 
127 
128 /// @brief the full-atom level score function, default score12
130  return *fullatom_sfx_;
131 }
132 
133 
134 /// @brief add instruction to the manager of this BDR (no copy)
135 /// @param[in] bi BuildInstruction
136 /// @param[in] aa_during_design_refine The allowed amino acid sequence
137 /// during design. Only applicable to BuildInstructions like
138 /// SegmentRebuild and SegmentInsert. Make sure the length of this
139 /// string matches up properly. Default empty string.
142  String const & aa_during_design_refine
143 )
144 {
145  manager_.add( bi );
146  if ( !aa_during_design_refine.empty() ) {
147  design_info_.push_back( std::make_pair( bi->original_interval(), aa_during_design_refine ) );
148  }
149 
150  // additional instruction means we'll need a new re-init the VLB, so
151  // go ahead and drop the existing one
152  vlb_ = 0;
153 }
154 
155 
156 /// @brief create directed dependency between two instructions
160 )
161 {
163 }
164 
165 
166 /// @brief set the centroid level score function
168  centroid_sfx_ = sfx.clone();
169 }
170 
171 
172 /// @brief set the centroid level score function
174  centroid_sfx_ = sfx->clone();
175 }
176 
177 
178 /// @brief set the full-atom level score function
180  fullatom_sfx_ = sfx.clone();
181 }
182 
183 
184 /// @brief set the full-atom level score function
186  fullatom_sfx_ = sfx->clone();
187 }
188 
189 
190 /// @brief apply defined moves to given Pose
191 void BDR::apply( Pose & pose ) {
193  using basic::MetricValue;
200 
201  // assign secondary structure
202  Dssp dssp( pose );
203  dssp.insert_ss_into_pose( pose );
204 
205  // do centroid build
206  if ( !centroid_build( pose ) ) { // build failed
208  return;
209  }
210 
211  // setup calculators
212  CalculatorFactory::Instance().remove_calculator( neighborhood_calc_name() );
213  CalculatorFactory::Instance().register_calculator(
215  new NeighborhoodByDistanceCalculator( manager_.union_of_intervals_containing_undefined_positions() )
216  );
217 
218  // do design-refine iteration
219  if ( dr_cycles_ > 0 ) {
220 
221  if ( !design_refine( pose ) ) { // design-refine failed
223  return;
224  }
225 
226  }
227 
228  // if we've gotten to this point, then the structure has been
229  // built properly
231 
232  // setup the PoseMetricCalculators and add them to the evaluators in the
233  // JobOutputter
234  CalculatorFactory::Instance().remove_calculator( loops_buns_polar_calc_name() );
235  CalculatorFactory::Instance().remove_calculator( neighborhood_buns_polar_calc_name() );
236 
237  CalculatorFactory::Instance().register_calculator(
239  new BuriedUnsatisfiedPolarsCalculator(
240  "default",
241  "default",
243  )
244  );
245 
246  MetricValue< std::set< Size > > loops_neighborhood;
247  pose.metric( neighborhood_calc_name(), "neighbors", loops_neighborhood );
248  CalculatorFactory::Instance().register_calculator(
250  new BuriedUnsatisfiedPolarsCalculator(
251  "default",
252  "default",
253  loops_neighborhood.value()
254  )
255  );
256 }
257 
258 
260 BDR::get_name() const {
261  return "BDR";
262 }
263 
264 /// @brief run the centroid level build stage
265 /// @return true if loop closed, false otherwise
267  Pose & pose
268 ) {
274 
278 
279  // safety, clear the energies object
280  pose.energies().clear();
281 
282  // make backup Pose for transferring sidechains
283  Pose archive_pose = pose;
284  Pose modified_archive_pose = archive_pose;
285  manager_.modify( modified_archive_pose );
286 
287  // ensure modified_archive_pose is completely full-atom, otherwise mismatch
288  // will occur when restoring sidechains at the end of the procedure
289  bool mod_ap_is_full_atom = true;
290  for ( Size i = 1, ie = modified_archive_pose.n_residue(); mod_ap_is_full_atom && i != ie; ++i ) {
291  mod_ap_is_full_atom &= ( modified_archive_pose.residue( i ).residue_type_set().name() == core::chemical::FA_STANDARD );
292  }
293 
294  if ( !mod_ap_is_full_atom ) {
296  }
297 
298  // flip to poly-ala-gly-pro-disulf pose
299  utility::vector1< Size > protein_residues;
300  for ( Size i = 1, ie = pose.n_residue(); i <= ie; ++i ) {
301  if ( pose.residue( i ).is_protein() ) {
302  protein_residues.push_back( i );
303  }
304  }
305 
306  construct_poly_ala_pose( pose, protein_residues, true, true, true );
307 
308  // run VLB to build the new section, if no segments have been added/deleted
309  // we use the same VLB so that fragment caching works properly
310  if ( !vlb_.get() ) {
311  vlb_ = new VarLengthBuild( manager_ );
312  }
313 
314  vlb_->scorefunction( centroid_sfx_ );
316  vlb_->use_fullmer( use_fullmer_ );
317  vlb_->max_linear_chainbreak( max_linear_chainbreak_ );
318  vlb_->loop_mover_str( centroid_loop_mover_str_ );
319 
320  if ( use_sequence_bias_ ) {
321  vlb_->original_sequence( archive_pose.sequence() );
322  }
323 
324  vlb_->apply( pose );
325 
326  if ( vlb_->get_last_move_status() == MS_SUCCESS ) {
327 
328  // record the used manager w/ all mapping info
329  manager_ = vlb_->manager();
330 
331  // safety, clear all the energies before restoring full-atom residues and
332  // scoring
333  pose.energies().clear();
334 
335  // Swap back original sidechains. At the moment this is a two step process
336  // in case any sidechains from SegmentInsert and the like that aren't in the
337  // original archive pose need to be transferred.
338  restore_residues( modified_archive_pose, pose );
339  restore_residues( manager_.original2modified(), archive_pose, pose );
340 
341  // go ahead and score w/ full-atom here; we do this in case there are no
342  // design-refine cycles -- it's useful to have e.g. rama in the output
343  (*fullatom_sfx_)( pose );
344 
345  return true; // loop closed
346 
347  } else {
348 
349  pose = archive_pose;
350 
351  }
352 
353  return false; // false if loop not closed
354 }
355 
356 
357 /// @brief run the design-refine stage
358 /// @return currently always true
360  Pose & pose
361 )
362 {
376 
381 
383 
384  // collect new regions/positions
385  std::set< Interval > loop_intervals = manager_.intervals_containing_undefined_positions();
386  Original2Modified original2modified_interval_endpoints = manager_.original2modified_interval_endpoints();
387 
388  // collect loops
389  loops::LoopsOP loops = new Loops( intervals_to_loops( loop_intervals.begin(), loop_intervals.end() ) );
390 
391  // refine Mover used doesn't setup a fold tree, so do it here
392  FoldTree loop_ft = protocols::forge::methods::fold_tree_from_loops( pose, *loops );
393 
394  // save original fold tree
395  FoldTree original_ft = pose.fold_tree();
396 
397  // define the score function
398  ScoreFunctionOP sfx = fullatom_sfx_->clone();
399 
400  // setup the design TaskFactory
401  TaskFactoryOP design_tf = generic_taskfactory();
402  design_tf->push_back( new RestrictToNeighborhoodOperation( neighborhood_calc_name() ) );
403 
405  // set repack only for non-loop positions
407 
408  Positions new_positions = manager_.new_positions();
409  for ( Size i = 1, ie = pose.n_residue(); i != ie; ++i ) {
410  if ( new_positions.find( i ) == new_positions.end() ) {
411  repack_op->include_residue( i );
412  }
413  }
414 
415  design_tf->push_back( repack_op );
416  }
417 
418  // add explicit residue types to design task factory if requested
419  for ( DesignInfo::const_iterator di = design_info_.begin(), die = design_info_.end(); di != die; ++di ) {
420  if ( !di->second.empty() ) {
421  String const aa = core::pose::annotated_to_oneletter_sequence( di->second );
422 
423  assert( original2modified_interval_endpoints.find( di->first.left ) != original2modified_interval_endpoints.end() );
424 
425  if ( aa.find( SegmentInsert::insertion_char() ) != String::npos ) { // SegmentInsert style
426  process_insert_design_string( di->first, aa, original2modified_interval_endpoints, design_tf );
427  } else { // SegmentRebuild style
428  process_continuous_design_string( di->first, aa, original2modified_interval_endpoints, design_tf );
429  }
430  }
431  }
432 
433  // setup the refine TaskFactory
434  TaskFactoryOP refine_tf = generic_taskfactory();
435  refine_tf->push_back( new RestrictToNeighborhoodOperation( neighborhood_calc_name() ) );
436  refine_tf->push_back( new RestrictToRepacking() );
437 
438  // safety, clear the energies object
439  pose.energies().clear();
440 
441  // run design-refine cycle
442  for ( Size i = 0; i < dr_cycles_; ++i ) {
443 
444  // design the new section
445  PackRotamersMover design( sfx );
446  design.task_factory( design_tf );
447  design.apply( pose );
448 
449  // set loop topology
450  pose.fold_tree( loop_ft );
451 
452  // refine the new section
453  LoopMover_Refine_CCD refine( loops, sfx );
454  refine.false_movemap( manager_.movemap_as_OP() );
455  refine.set_task_factory( refine_tf );
456  refine.apply( pose );
457 
458  // remove cutpoint variants -- shouldn't this happen at the end
459  // of the refine Mover?
460  remove_cutpoint_variants( pose );
461 
462  // set original topology
463  pose.fold_tree( original_ft );
464  }
465 
466  // must score one last time since we've removed variants and set
467  // new topology, otherwise component energies not correct for
468  // e.g. structure output
469  (*sfx)( pose );
470 
471  // evaluate all chainbreaks using linear chainbreak
472  bool cbreaks_pass = true;
473  for ( Loops::const_iterator l = loops->begin(), le = loops->end(); l != le && cbreaks_pass; ++l ) {
474  if ( l->cut() > 0 ) {
475  Real const c = linear_chainbreak( pose, l->cut() );
476  TR << "design_refine: final chainbreak = " << c << std::endl;
477  cbreaks_pass = c <= max_linear_chainbreak_;
478  }
479  }
480 
481  return cbreaks_pass;
482 }
483 
484 
485 /// @brief return a TaskFactory useable as a starting point for either
486 /// design or refinement
494 
495  TaskFactoryOP tf = new TaskFactory();
496 
497  tf->push_back( new InitializeFromCommandline() ); // also inits -ex options
498  tf->push_back( new IncludeCurrent() ); // enforce keeping of input sidechains
499  tf->push_back( new NoRepackDisulfides() );
500 
501  // load resfile op only if requested
502  if ( !resfile_.empty() ) {
503  ReadResfileOP rrf = new ReadResfile();
504  rrf->filename( resfile_ );
505  tf->push_back( rrf );
506  }
507 
508  return tf;
509 }
510 
511 
512 /// @brief process a continuous design string, adding appropriate operations
513 /// to the TaskFactory
515  Interval const & original_interval,
516  String const & design_str,
517  Original2Modified const & original2modified_interval_endpoints,
518  TaskFactoryOP design_tf
519 )
520 {
522 
524 
525  Size const offset = original2modified_interval_endpoints.find( original_interval.left )->second;
526  for ( Size i = 0, ie = design_str.length(); i < ie; ++i ) {
527  utility::vector1< bool > allowed_aa_types( 20, false );
528 
529  switch ( design_str.at( i ) ) {
530  case 's': // surface case, no CFWY
531  allowed_aa_types = allowed_surface_aa();
532  break;
533  case '.': // protocol default design
534  continue;
535  default: // regular case, single aa type
536  allowed_aa_types[ aa_from_oneletter_code( design_str.at( i ) ) ] = true;
537  break;
538  }
539 
540  design_tf->push_back( new RestrictAbsentCanonicalAAS( i + offset, allowed_aa_types ) );
541  }
542 }
543 
544 
545 /// @brief process a design string containing an insert, adding appropriate
546 /// operations to the TaskFactory
548  Interval const & original_interval,
549  String const & design_str,
550  Original2Modified const & original2modified_interval_endpoints,
551  TaskFactoryOP design_tf
552 )
553 {
559 
561 
562  char const insert_char = SegmentInsert::insertion_char();
563 
564  // Figure out the number of residues in each section.
565  Interval const interval(
566  original2modified_interval_endpoints.find( original_interval.left )->second,
567  original2modified_interval_endpoints.find( original_interval.right )->second
568  );
569 
570  Size const insert_char_idx = design_str.find( insert_char );
571  Size const left_nres = insert_char_idx;
572  Size const right_nres = design_str.size() - left_nres - 1;
573  Size const insert_nres = interval.length() - left_nres - right_nres;
574 
575  // Make setup easy by building a new design string to expand the
576  // insertion character into a series of the insertion character
577  // the size of the insert.
578  String aa = design_str;
579  aa.replace( insert_char_idx, 1, insert_nres, insert_char );
580 
581  // setup TaskOperations
583 
584  Size const left_offset = interval.left;
585  for ( Size i = 0, ie = aa.size(); i < ie; ++i ) {
586  utility::vector1< bool > allowed_aa_types( 20, false );
587 
588  if ( aa.at( i ) == insert_char ) { // repack only
589  repack_op->include_residue( i + left_offset );
590  continue;
591  } else if ( aa.at( i ) == 's' ) { // surface case, no CFWY
592  allowed_aa_types = allowed_surface_aa();
593  } else if ( aa.at( i ) == '.' ) { // protocol default design
594  continue;
595  } else { // regular case, single aa type
596  allowed_aa_types[ aa_from_oneletter_code( aa.at( i ) ) ] = true;
597  }
598 
599  design_tf->push_back( new RestrictAbsentCanonicalAAS( i + left_offset, allowed_aa_types ) );
600  }
601 
602  design_tf->push_back( repack_op );
603 }
604 
605 
606 /// @brief return a boolean vector specifying allowed a.a. when designing
607 /// on the surface
610 
611  static String surface_aa = "ADEGHIKLMNPQRSTV";
612  static utility::vector1< bool > v( 20, false );
613 
614  for ( Size i = 0, ie = surface_aa.length(); i < ie; ++i ) {
615  v[ aa_from_oneletter_code( surface_aa.at( i ) ) ] = true;
616  }
617 
618  return v;
619 }
620 
621 
622 } // namespace components
623 } // namespace forge
624 } // namespace protocols