Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
util.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/methods/util.cc
11 /// @brief miscellaneous utility functions for forge
12 /// @author Yih-En Andrew Ban (yab@u.washington.edu)
13 /// @author Possu Huang (possu@u.washington.edu)
14 
15 // unit headers
17 
18 // package headers
21 
22 // project headers
26 #include <core/chemical/AA.hh>
31 #include <core/id/types.hh>
32 #include <core/types.hh>
35 #include <core/pose/Pose.hh>
36 #include <core/pose/util.hh>
37 #include <core/pose/PDBInfo.hh>
38 #include <basic/Tracer.hh>
44 #include <basic/options/keys/remodel.OptionKeys.gen.hh>
45 #include <basic/options/option.hh>
47 #include <protocols/loops/Loops.hh>
48 
49 #include <core/pose/PDBPoseMap.hh>
50 
51 // numeric headers
52 #include <numeric/random/random.hh>
53 
54 // C++ headers
55 #include <set>
56 
57 #include <utility/vector1.hh>
58 
59 
60 // REQUIRED FOR WINDOWS
61 #ifdef _WIN32
62 #include <cstdio>
63 #include <ctype.h>
64 #endif
65 
66 using basic::T;
67 
68 namespace protocols {
69 namespace forge {
70 namespace methods {
71 
72 
73 // static
74 static basic::Tracer TR( "protocols.forge.methods.util" );
75 static numeric::random::RandomGenerator RG( 2211990 ); // magic number, don't change
76 
77 
78 /// @brief perform union( root, i ) for all 'i' within the closed interval
79 /// [left, right]
80 /// @param[in] root position to union with; can be any number, does not have
81 /// to be a true root of a set
82 /// @param[in] left start of the interval
83 /// @param[in] right end of the interval
84 /// @param[in,out] uf
85 void
87  core::Size const root,
88  core::Size const left,
89  core::Size const right,
91 )
92 {
93  using core::Size;
94 
95  assert( left <= right );
96  assert( root <= uf.n_nodes() );
97  assert( left <= uf.n_nodes() );
98  assert( right <= uf.n_nodes() );
99 
100  for ( Size i = left; i <= right; ++i ) {
101  uf.ds_union( root, i );
102  }
103 }
104 
105 /// @brief moving left to right, find the first true cutpoint within specified
106 /// extent
107 /// @return the cutpoint position, otherwise 0 if not found
108 /// @details 0, pose.n_residue(), and any cutpoint with lower/upper terminus
109 /// are not counted as cutpoints
112  core::pose::Pose const & pose,
114  core::Size right
115 )
116 {
117  using core::Size;
119 
120  FoldTree const & ft = pose.fold_tree();
121 
122  for ( Size i = left; i <= right; ++i ) {
123  if ( ft.is_cutpoint( i ) && i < pose.n_residue() &&
124  !pose.residue( i ).is_lower_terminus() &&
125  !pose.residue( i ).is_upper_terminus()
126  ) {
127  return i;
128  }
129  }
130 
131  return 0;
132 }
133 
134 
135 /// @brief moving left to right, count the number of true cutpoints within the
136 /// specified extent
137 /// @details 0, pose.n_residue(), and any cutpoint with lower/upper terminus
138 /// are not counted as cutpoints
141  core::pose::Pose const & pose,
143  core::Size right
144 )
145 {
146  using core::Size;
148 
149  Size n = 0;
150  FoldTree const & ft = pose.fold_tree();
151 
152  for ( Size i = left; i <= right; ++i ) {
153  if ( ft.is_cutpoint( i ) && i < pose.n_residue() &&
154  !pose.residue( i ).is_lower_terminus() &&
155  !pose.residue( i ).is_upper_terminus()
156  ) {
157  ++n;
158  }
159  }
160 
161  return n;
162 }
163 
164 
165 /// @brief set omega to 180 for a range of residues [left, right]
166 void
168  core::Size const left,
169  core::Size const right,
170  core::pose::Pose & pose
171 )
172 {
173  using core::Size;
174 
175  for ( Size i = left; i <= right; ++i ) {
176  pose.set_omega( i, 180.0 );
177  }
178 }
179 
180 
181 /// @brief create Loop object w/ random cutpoint from an Interval
184  using core::Size;
186 
187  // pick a cutpoint fully inside the loop so that there is always
188  // at least one moveable residue on each side
189  Size const cut = RG.random_range( interval.left, interval.right - 1 );
190 
191  return Loop( interval.left, interval.right, cut );
192 }
193 
194 
195 /// @brief create fold tree from loops
196 /// @remarks This is a generic replacement function for the one in protocols::loops
197 /// and will be moved there in the near future.
200  core::pose::Pose const & pose,
201  protocols::loops::Loops const & loops
202 )
203 {
204  using core::Size;
209 
211 
212  // setup movemap, mark only loops moveable, everything else fixed
213  MoveMap mm;
214  loops.switch_movemap( mm, core::id::BB , true );
215  loops.switch_movemap( mm, core::id::CHI , true );
216 
217  // Generate initial fold tree from pose. If existing root is a virtual
218  // residue use it, otherwise use the existing root if non-moveable,
219  // otherwise use a random non-moveable residue.
220  Size root;
221  if ( pose.residue( pose.fold_tree().root() ).aa() == core::chemical::aa_vrt ) {
222  root = pose.fold_tree().root();
223  } else if ( !mm.get_bb( pose.fold_tree().root() ) ) {
224  root = pose.fold_tree().root();
225  } else { // need to pick a random non-moveable residue
226 
227  utility::vector1< Size > fixed_bb;
228  for ( Size i = 1, ie = pose.n_residue(); i <= ie; ++i ) {
229  if ( !mm.get_bb( i ) ) {
230  fixed_bb.push_back( i );
231  }
232  }
233 
234  if ( fixed_bb.size() == 0 ) {
235  root = 1;
236  } else {
237  root = fixed_bb[ RG.random_range( 1, fixed_bb.size() ) ];
238  }
239  }
240 
241  FoldTree ft = fold_tree_from_pose( pose, root, mm );
242 
243  // track chain termini to distinguish internal vs terminal loops
244  std::set< Size > lower_termini;
245  std::set< Size > upper_termini;
246  for ( Size i = 1, ie = pose.conformation().num_chains(); i <= ie; ++i ) {
247  lower_termini.insert( pose.conformation().chain_begin( i ) );
248  upper_termini.insert( pose.conformation().chain_end( i ) );
249  }
250 
251  // post-modify tree with new loop jump/cuts for internal loop modeling
252  for ( Loops::const_iterator i = loops.begin(), ie = loops.end(); i != ie; ++i ) {
253  Loop const & loop = *i;
254 
255  if ( lower_termini.find( loop.start() ) == lower_termini.end() && upper_termini.find( loop.stop() ) == upper_termini.end() ) {
256  ft.new_jump( loop.start() - 1, loop.stop() + 1, loop.cut() );
257  }
258  }
259 
260  return ft;
261 }
262 
263 
264 /// @brief set a single loop fold tree
265 /// @remarks This is a generic replacement function for the one in protocols::loops
266 /// and will be moved there in the near future.
267 void
269  core::pose::Pose & pose,
270  protocols::loops::Loop const & loop
271 )
272 {
275 
276  Loops loops;
277  loops.add_loop( loop );
278 
279  FoldTree ft = fold_tree_from_loops( pose, loops );
280  pose.fold_tree( ft );
281 }
282 
283  // duplicated code from resfile reader... unfortunately there's no easy way around.
284  // question: if no chain is supplied should it be accepted?
285  // yes just pass ' ' for the chain
286  // how if a symbol is a chain or not?
287  // all commands begin with something in the command map, if it's not a command treat it as a chain
288 
290 parse_resfile_string_with_no_lockdown( core::pose::Pose const & pose, core::pack::task::PackerTask & the_task, std::string const & resfile_string )// throw(ResfileReaderException)
291 {
292  using namespace std;
293  using namespace core::pack::task;
294  using namespace core;
295  istringstream resfile(resfile_string);
296 
297  bool have_read_start_token = false;
298 
299  utility::vector1< bool > non_default_lines( the_task.total_residue(), false );
300  utility::vector1< std::string > default_tokens;
301  utility::vector1< Size > origin_lines_of_default_tokens;
302 
303  core::uint lineno = 0;
304  while ( resfile ) {
305  map< string, ResfileCommandOP > command_map = create_command_map();
306  utility::vector1< string > tokens( tokenize_line( resfile ));
307  ++lineno;
308 
309  // for debug
310  //std::cout << "line->";
311  //for( Size i=1; i <= tokens.size(); i++){
312  // std::cout << tokens[ i ] << ", ";
313  //}
314  //std::cout << std::endl;
315 
316  Size ntokens( tokens.size() );
317  if ( ntokens == 0 ) continue;
318  if ( comment_begin( tokens, 1 ) ) continue; // ignore the rest of this line
319 
320  if ( have_read_start_token ) {
321  Size which_token = 1;
322 
323  // expected format: <residue identifier> <chain identifier> <commands*>
324  //( the res/chain combo is used to get the pose's resid)
325 
326  // PDB numbering can be negative
327  std::string const PDBnum_token = get_token( which_token, tokens );
328  int PDBnum;
329  char icode = ' ';
330 #ifdef _WIN32
331  if ( isalpha( *PDBnum_token.rbegin() ) ) { // REQUIRED FOR WINDOWS
332 #else
333  if ( std::isalpha( *PDBnum_token.rbegin() ) ) {
334 #endif
335  PDBnum = atoi( PDBnum_token.substr( 0, PDBnum_token.length() - 1 ).c_str() );
336  icode = *PDBnum_token.rbegin();
337  } else { // no insertion code
338  PDBnum = atoi( PDBnum_token.c_str() );
339  }
340  ++which_token;
341  char chain;
342  chain = get_token( which_token, tokens )[ 0 ];
343  if (chain == '_') chain = ' ';
344  ++which_token;
345 
346  Size resid(0);
347  if(pose.pdb_info()){
348  resid = pose.pdb_info()->pdb2pose().find( chain, PDBnum, icode );
349  } else {
350  if((1 <= PDBnum) && (PDBnum <= (int)pose.total_residue())) {
351  resid = PDBnum;
352  }
353  }
354  if (resid == 0){
355  std::stringstream err_msg;
356  err_msg << "On line " << lineno << ", the pose does not have residue (" << chain << ", " << PDBnum << ").";
357  onError( err_msg.str());
358  }
359  non_default_lines[ resid ] = true;
360 
361  while ( which_token <= ntokens ) {
362  if ( comment_begin( tokens, which_token ) ) break; // ignore the rest of this line
363  if ( command_map.find( get_token( which_token, tokens ) ) == command_map.end() ) {
364  std::stringstream err_msg;
365  err_msg << "On line " << lineno << " command '" << get_token( which_token, tokens) <<"' is not recognized.";
366  onError(err_msg.str());
367  which_token++;
368  continue;
369  }
370 
371  ResfileCommandOP command = command_map[ get_token( which_token, tokens ) ];
372 
373  try{
374  command->initialize_from_tokens( tokens, which_token, resid );
375  command->residue_action( the_task, resid );
376  } catch ( ResfileReaderException() ){
377  // there was a problem with this command. If we're doing error recovery skip to next command.
378  while( which_token <= ntokens && command_map.find( get_token(which_token, tokens ) ) == command_map.end() )
379  which_token++;
380  continue;
381  }
382  }
383 
384  } else { // the start token has not been read
385  // read in default behaviors, store them, process them later
386  if ( get_token( 1, tokens) == "START" ) {
387  have_read_start_token = true;
388  } else {
389  for ( Size ii = 1; ii <= ntokens; ++ii ) {
390  if ( comment_begin( tokens, ii ) ) break; // ignore the rest of this line
391  default_tokens.push_back( get_token( ii, tokens ) );
392  origin_lines_of_default_tokens.push_back( lineno );
393  }
394  }
395 
396  }
397  }
398 
399  if ( ! have_read_start_token ) {
400  T("core.pack.task.ResfileReader") << "RESFILE WARNING: reached the end of resfile without finding a 'start' token." << std::endl;
401  T("core.pack.task.ResfileReader") << "RESFILE WARNING: No residue-specific behavior specified in resfile" << std::endl;
402  }
403 
404  return non_default_lines;
405 
406  // now process default behaviors
407 /*
408  for ( Size ii = 1; ii <= non_default_lines.size(); ++ii ) {
409  if ( ! non_default_lines[ ii ] ) {
410  Size which_token = 1, ntokens = default_tokens.size();
411 
412  while( which_token <= ntokens ){
413  if ( command_map.find( get_token( which_token, default_tokens ) ) == command_map.end() ) {
414  std::stringstream err_msg;
415  err_msg << "The default command '" << get_token( which_token, default_tokens) <<"' is not recognized.";
416  onError(err_msg.str());
417  which_token++;
418  continue;
419  }
420 
421  ResfileCommandOP command = command_map[ get_token( which_token, default_tokens ) ];
422 
423  try{
424  command->residue_action( default_tokens, which_token, the_task, ii );
425  } catch ( ResfileReaderException() ){
426  // there was a problem with this command. If we're doing error recovery skip to next command.
427  while( which_token <= ntokens && command_map.find( get_token(which_token, default_tokens ) ) == command_map.end() )
428  which_token++;
429  continue;
430  }
431  }
432  }
433  }
434 */
435 }
436 
443 
445 
446  TF->push_back( new InitializeFromCommandline() ); // also inits -ex options
447  TF->push_back( new IncludeCurrent() ); // enforce keeping of input sidechains
448  TF->push_back( new NoRepackDisulfides() );
449  if (!basic::options::option[basic::options::OptionKeys::remodel::design::allow_rare_aro_chi].user()){
450  TF->push_back( new LimitAromaChi2Operation() );
451  }
452 
453  return TF;
454 }
455 
456 void
458  core::pose::Pose & pose,
460 {
461  using namespace core::id;
462  using namespace core::conformation;
463  using namespace core::scoring::constraints;
464 
465  core::Real const coord_sdev( 2.0 );
466  core::Size const my_anchor(1);
467 
468  ConstraintSetOP cst_set = pose.constraint_set()->clone();
469 
470  std::set<core::Size> loopRange;
471 
472  for ( protocols::loops::Loops::const_iterator it = loops.begin(), ite = loops.end(); it != ite; ++it ) {
473  protocols::loops::Loop const & loop = *it;
474  for (core::Size i = loop.start(); i<= loop.stop(); i++){
475 
476  loopRange.insert(i);
477 
478  }
479  }
480  core::Size const nres( pose.total_residue());
481  for (core::Size i =1 ; i<=nres ; ++i){
482  if (loopRange.find(i) != loopRange.end()){ //value exist(check!)
483  continue;
484  }
485  else {
486  Residue const & i_rsd( pose.residue(i));
487 
488  for (core::Size ii = 1; ii <= i_rsd.nheavyatoms(); ++ii) {
489  cst_set->add_constraint( new CoordinateConstraint(AtomID(ii,i), AtomID(1, my_anchor), i_rsd.xyz(ii), new HarmonicFunc(0.0, coord_sdev)));
490  }
491  }
492  }
493 
494  pose.constraint_set( cst_set );
495 }
496  void fixH(core::pose::Pose & pose) {
497  using namespace core;
498  using core::id::AtomID;
499  for(Size i = 1; i <= pose.n_residue(); ++i) {
500  numeric::xyzVector<Real> n = pose.residue(i).xyz("N");
501  numeric::xyzVector<Real> ca = pose.residue(i).xyz("CA");
502  Size in = i-1;
503  if(in == 0) in = pose.n_residue();
504  numeric::xyzVector<Real> c = pose.residue(in).xyz("C");
505  numeric::xyzVector<Real> h = n + (n-(ca+c)/2.0).normalized()*1.01;
506  if (pose.residue(i).name3() != "PRO"){
507  pose.set_xyz(AtomID(pose.residue(i).atom_index("H"),i), h );
508  }
509  }
510  }
511 
512 
514  using namespace core;
515  using namespace core::pose;
516  using namespace core::scoring::constraints;
517  using namespace chemical;
518  using core::id::AtomID;
519  //pose.conformation().show_residue_connections();
520  Size N = pose.n_residue();
521  for(Size i = 1; i <= N; ++i) {
526  }
527  if(!pose.residue(1).has_variant_type(CUTPOINT_UPPER)) {
529  /*
530  //make connection
531  conformation::ResidueOP cloneRes = new conformation::Residue(*pose.residue(1).clone());
532 
533  cloneRes->residue_connection_partner(1, N, 2);
534  cloneRes->residue_connection_partner(2, 2, 1);
535 
536  pose.replace_residue(1, *cloneRes, false);
537  */
538 
539  }
542  /*
543  //make connection
544  conformation::ResidueOP cloneRes = new conformation::Residue(*pose.residue(N).clone());
545 
546  cloneRes->residue_connection_partner(1, N-1, 2);
547  cloneRes->residue_connection_partner(2, 1, 1);
548 
549  pose.replace_residue(N, *cloneRes, false);
550  */
551  }
552  pose.conformation().declare_chemical_bond( 1, "N", N, "C" );
553  fixH(pose);
554 
556 
557 // conformation::ResidueOP cloneRes2 = new conformation::Residue(*pose.residue(2).clone());
558 // cloneRes2->residue_connection_partner(1, 1, 2);
559 // cloneRes2->residue_connection_partner(2, 3, 1);
560 //std::cout << "resconn1CR2: " << cloneRes2->connected_residue_at_resconn( 1 ) << " ";
561 // std::cout << cloneRes2->residue_connection_conn_id(1);
562 // std::cout << " resconn2: " << cloneRes2->connected_residue_at_resconn( 2 ) << " ";
563 // std::cout << cloneRes2->residue_connection_conn_id(2);
564 // std::cout << " seqpos: " << cloneRes2->seqpos() << std::endl;
565 //
566 // pose.replace_residue(2, *cloneRes2, false);
567 // pose.conformation().update_polymeric_connection(2);
568 //std::cout << "resconn1PR2: " << pose.residue(2).connected_residue_at_resconn( 1 ) << " ";
569 // std::cout << pose.residue(2).residue_connection_conn_id(1);
570 // std::cout << " resconn2: " << pose.residue(2).connected_residue_at_resconn( 2 ) << " ";
571 // std::cout << pose.residue(2).residue_connection_conn_id(2);
572 // std::cout << " seqpos: " << pose.residue(2).seqpos() << std::endl;
573 
574  /*
575  //make connection
576  conformation::ResidueOP cloneRes1 = new conformation::Residue(*pose.residue(1).clone());
577 // conformation::ResidueOP cloneResN = new conformation::Residue(*pose.residue(N).clone());
578 
579  cloneRes1->residue_connection_partner(1, N, 2);
580  cloneRes1->residue_connection_partner(2, 2, 1);
581 // cloneRes1->residue_connection_partner(2, N, 2);
582  cloneRes2->residue_connection_partner(1, 1, 2);
583  cloneRes2->residue_connection_partner(2, 3, 1);
584 // cloneResN->residue_connection_partner(1, N-1, 2);
585 // cloneResN->residue_connection_partner(2, 1, 1);
586 
587  pose.replace_residue(1, *cloneRes1, false);
588  pose.replace_residue(2, *cloneRes2, false);
589 // pose.replace_residue(N, *cloneResN, false);
590 */
591 
592 // pose.conformation().show_residue_connections();
593 
594  using namespace core::scoring::constraints;
595  AtomID a1( pose.residue(1).atom_index( "N"), 1 ), a2( pose.residue(pose.n_residue()).atom_index("OVL1"), pose.n_residue() );
596  AtomID b1( pose.residue(1).atom_index( "CA"), 1 ), b2( pose.residue(pose.n_residue()).atom_index("OVL2"), pose.n_residue() );
597  AtomID c1( pose.residue(1).atom_index("OVU1"), 1 ), c2( pose.residue(pose.n_residue()).atom_index( "C"), pose.n_residue() );
598 // pose.remove_constraints();
599  pose.add_constraint(new AtomPairConstraint(a1,a2,new HarmonicFunc(0.0,0.1)));
600  pose.add_constraint(new AtomPairConstraint(b1,b2,new HarmonicFunc(0.0,0.1)));
601  pose.add_constraint(new AtomPairConstraint(c1,c2,new HarmonicFunc(0.0,0.1)));
602 }
603 
604 
605 
606 
607 //void lockdown_task_with_default_behaviors(){
608 //}
609 
610 
611 
612 } // namespace methods
613 } // namespace forge
614 } // namespace protocols