Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
StepWisePoseSetup.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 StepWisePoseSetup
11 /// @brief Sets up pose and job parameters for protein or RNA stepwise building.
12 /// @detailed
13 /// @author Rhiju Das
14 /// @author Parin Sripakdeevong
15 
16 
17 //////////////////////////////////
25 
26 //////////////////////////////////
27 // AUTO-REMOVED #include <core/chemical/util.hh>
30 //////////////////////////////////////////////
40 #include <core/types.hh>
41 #include <core/pose/Pose.hh>
44 
46 #include <core/pose/util.hh>
47 // AUTO-REMOVED #include <core/import_pose/pose_stream/PoseInputStream.hh>
48 // AUTO-REMOVED #include <core/import_pose/pose_stream/PDBPoseInputStream.hh>
49 // AUTO-REMOVED #include <core/import_pose/pose_stream/SilentFilePoseInputStream.hh>
50 #include <basic/Tracer.hh>
51 // AUTO-REMOVED #include <core/io/pdb/pose_io.hh>
52 // AUTO-REMOVED #include <basic/database/open.hh>
53 #include <core/id/TorsionID.hh>
55 // AUTO-REMOVED #include <core/scoring/rms_util.tmpl.hh>
56 
57 // RNA stuff
61 
62 #include <ObjexxFCL/FArray1D.hh>
63 
64 
65 #include <ObjexxFCL/string.functions.hh>
66 #include <ObjexxFCL/FArray2D.hh>
67 
68 
69 #include <utility/exit.hh>
70 
71 // AUTO-REMOVED #include <time.h>
72 #include <string>
73 
74 //Auto Headers
75 #include <core/scoring/rms_util.hh>
76 #include <utility/vector1.hh>
77 using namespace core;
78 using core::Real;
79 using protocols::rna::possible_root; /*not the best place for this...*/
80 
81 //////////////////////////////////////////////////////////////////////////
82 //////////////////////////////////////////////////////////////////////////
83 // Core routine for stepwise sampling of proteins (and probably other
84 // biopolymers soon). Take a starting pose and a list of residues to sample,
85 // and comprehensively sample all backbone torsion angles by recursion.
86 //////////////////////////////////////////////////////////////////////////
87 //////////////////////////////////////////////////////////////////////////
88 //////////////////////////////////////////////////////////////////////////
89 
90 static basic::Tracer TR( "protocols.swa.stepwise_pose_setup" ) ;
91 
92 //typedef std::map< core::Size, core::Size > ResMap;
93 
94 namespace protocols {
95 namespace swa {
96 
97  //////////////////////////////////////////////////////////////////////////
98  //constructor!
99  StepWisePoseSetup::StepWisePoseSetup( utility::vector1< core::Size > const & moving_res_list,
100  std::string const & desired_sequence,
101  utility::vector1< InputStreamWithResidueInfoOP > & input_streams_with_residue_info,
102  utility::vector1< core::Size > const & cutpoint_open,
103  utility::vector1< core::Size > const & cutpoint_closed ):
104  // do we still need this variable, moving_res_, since we have moving_res_list? --- Rhiju, feb. 2010
105  moving_res_list_( moving_res_list ),
106  desired_sequence_( desired_sequence ), //This is the full/global sequence Jan 2, 2009 Parin S.
107  rsd_set_( core::chemical::ChemicalManager::get_instance()->residue_type_set( core::chemical::FA_STANDARD ) ),
108  input_streams_with_residue_info_( input_streams_with_residue_info ),
109  cutpoint_open_( cutpoint_open ),
110  cutpoint_closed_( cutpoint_closed ),
111  is_cutpoint_( desired_sequence_.size(), false ),
112  secstruct_( "" ),
113  job_parameters_( new StepWiseJobParameters ),
114  virtualize_5prime_phosphates_( true ),
115  add_peptide_plane_variants_( false ),
116  remove_nterminus_variant_( false ),
117  remove_cterminus_variant_( false ),
118  cst_file_( "" ),
119  BRIDGE_RES_( 123 ),
120  ready_to_align_( false ),
121  dump_( false )
122  {
123  ///////////////////////////////////////////////////////
124  // Cutpoint setup
125  for ( Size n = 1; n <= cutpoint_closed_.size(); n++ ) {
126  is_cutpoint_( cutpoint_closed_[ n ] ) = true;
127  }
128 
129  for ( Size n = 1; n <= cutpoint_open_.size(); n++ ) {
130  is_cutpoint_( cutpoint_open_[ n ] ) = true;
131  for ( Size m = 1; m <= cutpoint_closed_.size(); m++ ) {
132  if ( cutpoint_open_[ n ] == cutpoint_closed_[ m ] ) utility_exit_with_message( "Position cannot be both cutpoint_open and cutpoint_closed" );
133  }
134  }
135 
136  }
137 
138  //////////////////////////////////////////////////////////////////////////
139  //destructor
141  {}
142 /////////////////////
145 return "StepWisePoseSetup";
146 }
147 
148 
149  //////////////////////////////////////////////////////////////////////////
150  void
152 
153  using namespace core::pose;
154  using namespace core::kinematics;
155  using namespace core::chemical;
156 
157  // Define chain boundaries, mapping to working pose, etc.
160  figure_out_cuts();
161 
162  // actually make the pose, set fold tree, copy in starting
163  // templates from disk.
164  make_pose( pose ); //Create pose with random torsions + setup the fold_tree
165 
166  initialize_pose_from_streams( pose ); //Grab info from input poses/silent-files. Also initializes full_to_sub in the streams.
167 
168  /////////////////////////////////////////////////
169  // useful in job definition. Need to carry out
170  // following in exactly the right order!
172  figure_out_partition_definition( pose ); // this DOES NOT re-roots the fold tree. Parin S. Jan 30, 2010
174 
175  ////////////////////////////////
176  //Misc. parameters for job --
177  // fixed res, terminal res will be useful in finalizing fold tree.
178  // superimpose_res, rmsd_res will be necessary for clustering across subset of residues, and rmsds to native.
179  job_parameters_->set_working_fixed_res( apply_full_to_sub_mapping( fixed_res_ ) );
180  job_parameters_->set_working_terminal_res( apply_full_to_sub_mapping( terminal_res_ ) );
181  job_parameters_->set_working_superimpose_res( apply_full_to_sub_mapping( superimpose_res_ ) );
182  job_parameters_->set_working_calc_rms_res( apply_full_to_sub_mapping( calc_rms_res_ ) );
183  job_parameters_->set_working_bridge_res( apply_full_to_sub_mapping( bridge_res_ ) );
184 
185 
186  /////////////////////////////////
187  // More fold tree stuff.
188  reroot_fold_tree( pose );
189  apply_cutpoint_variants( pose );
190  check_close_chain_break( pose );
191 
192  /////////////////////////////////
193  // Residue variants.
196  apply_bulge_variants( pose );
198 
199  setup_constraints( pose );
200  setup_disulfides( pose );
201 
202  //////////////////////////////////////////////////
203  // Final cleanup. This is manual and quite silly, but the pose machinery currently
204  // does a poor job with phi/psi's at the ends of chains.
205  // ACTUALLY IMPROVEMENTS TO COPY_DOFS() SEEMS TO FIX THIS ISSUE -- AND
206  // NOW FIX_PHI_PSI_OFFSETS() IS ACTUALLY CAUSING A PROBLEM!!
207  // if ( dump_ ) pose.dump_pdb( "before_fix_phi_psi.pdb" );
208  // fix_phi_psi_offsets( pose );
209  // if ( dump_ ) pose.dump_pdb( "after_fix_phi_psi.pdb" );
210 
211  //Would it be possible to setup the fold_tree, chain_break terminus and virtual phosphate of the native_pose as well so that it can be minimized? Parin Jan 29, 2010
212  //This will be easy to do it we create a new class to create job_parameters_ independent of pose_setup
213  // check_superimpose_res( pose );
214 
215  setup_working_native_pose(); //slice up native pose
216  align_poses( pose ); // read in align pose, then align pose and native_pose to it.
217  job_parameters_->set_working_native_pose( working_native_pose );
218 
220 
221  setup_secstruct( pose );
222 
223  // pose.dump_pdb( "start.pdb" );
224  // std::cout << "FOLD_TREE " << pose.fold_tree() << std::endl;
225  // if ( pose.fold_tree().num_jump() > 0 ) std::cout << "RT " << pose.jump( 1 ).rt() << std::endl;
226 
227  }
228 
229  /////////////////////////////////////////////////////////////////////
230  void
232 
234  //core::Size num_chains;
235  std::map< core::Size, core::Size > full_to_sub;
236  std::string working_sequence;
237 
238  // There are up to two input poses. Need to merge their input residues,
239  // and figure out chain boundaries.
240  Size const nres( desired_sequence_.size() );
241  ObjexxFCL::FArray1D< Size > is_working_res( nres );
242  ObjexxFCL::FArray1D< Size > is_moving_res( nres );
243  is_working_res = 0;
244  is_moving_res = 0;
245 
246  // Then input residues. Note that this can overwrite domain definitions in loop
247  for ( Size i = 1; i <= input_streams_with_residue_info_.size(); i++ ) {
248  utility::vector1< Size > const & input_res_vector = input_streams_with_residue_info_[i]->input_res();
249  for ( Size n = 1; n <= input_res_vector.size(); n++ ) {
250  is_working_res( input_res_vector[ n ] ) = i; //indicate whether belong to pose 1 or 2, what about the case where there are overlap residues between pose1 and pose2? Jan 29 2010, Parin S.
251  }
252  }
253 
254  //First any residues in a loop to be closed.
255  for ( Size i = 1; i <= bridge_res_.size(); i++ ) {
256  is_working_res( bridge_res_[ i ] ) = BRIDGE_RES_; /*Some number*/
257  }
258 
259 
260  for( Size i = 1; i <= moving_res_list_.size(); i++){
261  if (!is_working_res( moving_res_list_[ i ] ) ) is_working_res( moving_res_list_[i] )= 999;
262  is_moving_res( moving_res_list_[i] ) = 999;
263  }
264 
265 
266  Size start_chain( 0 );
267  Size end_chain( 0 );
268 
269  Size n( 0 );
270  for ( Size pos = 1; pos <= nres; pos++ ) {
271 
272  if ( !is_working_res( pos ) ) continue;
273  n++;
274 
275  if ( n == 1 ) start_chain = pos;
276 
277  if (n > 1 &&
278  ( pos > end_chain + 1 || //In what situation does pos > end_chain + 1??
279  is_cutpoint_( end_chain ) ) ) {
280 
281  chain_boundaries.push_back( std::make_pair( start_chain, end_chain ) ); //The last chain...
282  // std::cout << "FOUND CHAIN " << start_chain << " " << end_chain << std::endl;
283  //check_moving_res_in_chain( start_chain, end_chain, chain_boundaries.size(), which_chain_has_moving_res );
284 
285  start_chain = pos;
286  }
287 
288  end_chain = pos;
289  }
290 
291  // For now, need to have at least one chain defined in the input!
292  assert( start_chain > 0 );
293  chain_boundaries.push_back( std::make_pair( start_chain, end_chain ) );
294  // std::cout << "FOUND CHAIN " << start_chain << " " << end_chain << std::endl;
295  // check_moving_res_in_chain( start_chain, end_chain, chain_boundaries.size(), which_chain_has_moving_res );
296 
297  //num_chains = chain_boundaries.size(); // set but never used ~Labonte
298 
299  // if ( which_chain_has_moving_res== 0 ) {
300  // utility_exit_with_message( "Could not figure out which chain to attach moving_res to!" );
301  // }
302 
303  working_sequence= "";
304  full_to_sub.clear();
305  Size count( 0 );
306  utility::vector1< core::Size > working_res_list;
307  for ( Size i = 1; i <= desired_sequence_.size(); i++ ) {
308  if ( is_working_res( i ) ) {
309  working_sequence += desired_sequence_[ i-1 ]; //i-1 because std::string elements starts at 0...
310  count++;
311  full_to_sub[ i ] = count;
312  working_res_list.push_back( i );
313  }
314  }
315 
316  std::cout << "desired_sequence= " << desired_sequence_ << std::endl;
317  std::cout << "working_sequence= " << working_sequence << std::endl;
318 
319  utility::vector1< core::Size > working_moving_res_list;
320  for(Size i=1; i <= desired_sequence_.size(); i++){
321  if ( is_working_res( i ) && is_moving_res( i ) ){
322  working_moving_res_list.push_back(full_to_sub[ i ]);
323  }
324  }
325 
326  job_parameters_->set_sequence( desired_sequence_ ); //full_sequence
327  job_parameters_->set_working_sequence( working_sequence ); //partial_sequence
328  job_parameters_->set_working_res_list( working_res_list );
329  job_parameters_->set_working_moving_res_list( working_moving_res_list );
330  job_parameters_->set_is_working_res( is_working_res ); //A vector to indicate if res exist in the working pose and if it belong to input_pose 1 or input_pose 2 or working_res_list.
331  job_parameters_->set_is_moving_res( is_moving_res );
332  job_parameters_->set_full_to_sub( full_to_sub ); //res_map
333  job_parameters_->set_chain_boundaries( chain_boundaries );
334  //job_parameters_->set_which_chain_has_moving_res( which_chain_has_moving_res );
335 
336  }
337 
338 
339  ///////////////////////////////////////////////////////////////////////////////////
340  // Changed this to match Parin's favorite convention --
341  // jumps far away from rebuilt residue.
342  void
344 
345  jump_partners_.clear();
346 
347  utility::vector1< std::pair< core::Size, core::Size > > const & chain_boundaries( job_parameters_->chain_boundaries() );
348  std::map< core::Size, core::Size > & full_to_sub( job_parameters_->full_to_sub() );
349  ObjexxFCL::FArray1D< Size > const & is_working_res = job_parameters_->is_working_res();
350 
351  Size const num_chains( chain_boundaries.size() );
352 
353  // std::cout << "NUM_CHAINS: " << num_chains << std::endl;
354 
355  ////////////////////////////////////////////////
356  // Make a list of potential jumps.
357  utility::vector1< std::pair< Size, Size > > potential_jump_partners, potential_jump_partners_low_priority;
358 
359  // start with user-defined jumps (top priority list)
360  utility::vector1< Size > working_jump_res = job_parameters_->apply_full_to_sub_mapping( jump_res_ );
361  for ( Size n = 1; n <= working_jump_res.size() /2; n++ ){
362  Size const i = working_jump_res[ 2*(n-1) + 1 ];
363  Size const j = working_jump_res[ 2*(n-1) + 2 ];
364  potential_jump_partners.push_back( std::make_pair( i, j) );
365  }
366 
367  // Then, jumps that go from the end of one chain to the beginning of the next --
368  // note that we don't like this if moving residues are involved, so those go
369  // to a third priority list.
370  for ( Size n = 1 ; n <= num_chains; n++ ) {
371 
372  Size const i = chain_boundaries[n].second;
373  Size const j = n < num_chains ? chain_boundaries[n+1].first : chain_boundaries[1].first;
374 
375  // If there are two input poses, make sure their
376  // rigid body arrangment is sampled --> no jumps between these
377  // different regions!
378  std::cout << "CHAIN " << n << ". Considering jump: " << i << " to " << j << ". WORKING_RES: " << is_working_res(i) << " " << is_working_res(j) << std::endl;
379  if ( is_working_res( i ) == 1 &&
380  is_working_res( j ) == 2 ) continue;
381  if ( is_working_res( j ) == 1 &&
382  is_working_res( i ) == 2 ) continue;
383  if ( is_working_res( i ) == BRIDGE_RES_ ) continue;
384  if ( is_working_res( j ) == BRIDGE_RES_ ) continue;
385 
386  std::cout << "Adding potential jump! " << std::endl;
387 
388  std::pair< Size, Size > jump_pair = std::make_pair( full_to_sub[ i ], full_to_sub[ j ] );
390  potential_jump_partners.push_back( jump_pair );
391  } else {
392  potential_jump_partners_low_priority.push_back( jump_pair );
393  }
394  }
395 
396  // Tack on the low priority jump pairs at the end.
397  for ( Size n = 1; n <= potential_jump_partners_low_priority.size(); n++ ) {
398  potential_jump_partners.push_back( potential_jump_partners_low_priority[ n ] );
399  }
400 
401  // Might as well figure out (ahead of time) the chain assignments.
402  utility::vector1< std::pair< Size, Size > > potential_chain_partners;
403  for ( Size n = 1; n <= potential_jump_partners.size(); n++ ) {
404  potential_chain_partners.push_back( std::make_pair( which_chain( potential_jump_partners[n].first ),
405  which_chain( potential_jump_partners[n].second ) ) );
406  std::cout << "POTENTIAL JUMPS: " << potential_jump_partners[n].first << " "
407  << potential_jump_partners[n].second << " chain: "
408  << which_chain( potential_jump_partners[n].first ) << ' '
409  << which_chain( potential_jump_partners[n].second ) << std::endl;
410  }
411 
412 
413  ////////////////////////////////////////////////
414  // Then grab enough jumps so that we have all the chains
415  // somehow connected to each other.
416  jump_partners_.clear();
418  Size ntries( 0 );
419 
420  while ( chain_partners.size() < (num_chains-1) && ntries++ < 10000 ){
421  for ( Size n = 1; n <= potential_jump_partners.size(); n++ ){
422  std::cout << "Going to test jump: " << potential_jump_partners[ n ].first << " "
423  << potential_jump_partners[ n ].second << "? " << already_connected( potential_chain_partners[ n ], chain_partners ) << std::endl;
424 
425  if ( already_connected( potential_chain_partners[ n ], chain_partners ) ) continue;
426  chain_partners.push_back( potential_chain_partners[ n ] );
427  jump_partners_.push_back( potential_jump_partners[ n ] );
428  std::cout << "ADDING JUMP: " << potential_jump_partners[n].first << ' ' << potential_jump_partners[n].second << std::endl;
429  break;
430  }
431  }
432 
433  if ( chain_partners.size() != (num_chains-1) ) utility_exit_with_message( "Problem setting up jump partners!" );
434 
435  }
436 
437  ////////////////////////////////////////////////////////////////////////////////////////////////////
438  Size
440 
441  utility::vector1< std::pair< core::Size, core::Size > > const & chain_boundaries( job_parameters_->chain_boundaries() );
442  std::map< core::Size, core::Size > & full_to_sub( job_parameters_->full_to_sub() );
443 
444  for ( Size n = 1; n <= chain_boundaries.size(); n++ ){
445  if ( full_to_sub[ chain_boundaries[n].first ] <= i &&
446  full_to_sub[ chain_boundaries[n].second ] >= i ) return n;
447  }
448  return 0;
449  }
450 
451  ////////////////////////////////////////////////////////////////////////////////////////////////////
452  bool
453  StepWisePoseSetup::already_connected( std::pair< Size, Size > const & potential_chain_partner,
454  utility::vector1< std::pair< Size, Size > > const & chain_partners ) const {
455  utility::vector1< bool > already_checked( chain_partners.size(), false );
456  // traverse our way from chain to chain until we get from the first partner to the second partner -- or to the end of the list.
457  return already_connected( potential_chain_partner.first, potential_chain_partner.second, chain_partners, already_checked );
458  }
459 
460  ////////////////////////////////////////////////////////////////////////////////////////////////////
461  bool
463  Size const stop_chain,
464  utility::vector1< std::pair< Size, Size > > const & chain_partners,
465  utility::vector1< bool > already_checked ) const {
466 
467  bool made_the_connection( false );
468  for ( Size n = 1; n <= chain_partners.size(); n++ ) {
469 
470  if ( already_checked[ n ] ) continue;
471 
472  Size other_chain( 0 );
473  if ( chain_partners[n].first == start_chain ){
474  other_chain = chain_partners[ n ].second;
475  }
476  if ( chain_partners[n].second == start_chain ){
477  other_chain = chain_partners[ n ].first;
478  }
479  if ( other_chain < 1 ) continue;
480 
481  if ( other_chain == stop_chain ){
482  made_the_connection = true;
483  } else {
484  utility::vector1< bool > already_checked_new = already_checked;
485  already_checked_new[ n ] = true;
486  made_the_connection = already_connected( other_chain, stop_chain, chain_partners, already_checked_new );
487  }
488 
489  if ( made_the_connection ) return true;
490  }
491 
492  // end of the road
493  return false;
494 
495  }
496 
497  ///////////////////////////////////////////////////////////////////////////////////
498  void
500 
501  cuts_.clear();
502 
503  utility::vector1< std::pair< core::Size, core::Size > > const & chain_boundaries( job_parameters_->chain_boundaries() );
504  std::map< core::Size, core::Size > & full_to_sub( job_parameters_->full_to_sub() );
505  Size const num_chains = chain_boundaries.size();
506 
507  for ( Size n = 1; n < num_chains; n++ ) {
508  cuts_.push_back( full_to_sub[ chain_boundaries[n].second ] );
509  }
510 
511  }
512 
513  ///////////////////////////////////////////////////////////////////////////////////
514  void
516 
517  make_pose_from_sequence( pose, desired_sequence_, *rsd_set_); //, false /*auto_termini*/);
518 
521 
522  std::cout << remove_nterminus_variant_ << ' ' << remove_cterminus_variant_ << " FULL POSE ANNOTATED SEQUENCE: " << pose.annotated_sequence( true ) << std::endl;
523 
524  }
525 
526  ///////////////////////////////////////////////////////////////////////////////////
527  void
529 
530  using namespace core::conformation;
531  using namespace core::scoring::constraints;
532 
533  //std::string const working_sequence = job_parameters_->working_sequence();
534  // std::map< core::Size, core::Size > & full_to_sub( job_parameters_->full_to_sub() );
535 
536  make_full_pose( pose );
537 
538  // Extend pose. (protein)
539  for ( Size n = 1; n <= pose.total_residue();n++ ) {
540  if ( !pose.residue( n ).is_protein() ) continue;
541  pose.set_phi( n, -150 );
542  pose.set_psi( n, 150);
543  pose.set_omega( n, 180 );
544  }
545 
546  // slice it down.
547  ObjexxFCL::FArray1D< Size > const & is_working_res = job_parameters_->is_working_res();
548  utility::vector1< Size > working_res_list;
549  for ( Size n = 1; n <= pose.total_residue(); n++ ) if ( is_working_res( n ) ) working_res_list.push_back( n );
550  pdbslice( pose, working_res_list );
551 
552 
553  Size const nres( pose.total_residue() );
554  core::kinematics::FoldTree f( nres );
555  assert( cuts_.size() == jump_partners_.size() );
556  Size const num_cuts( cuts_.size() );
557 
558  ObjexxFCL::FArray2D< int > jump_point( 2, num_cuts, 0 );
559  ObjexxFCL::FArray1D< int > cuts( num_cuts, 0 );
560 
561  for ( Size i = 1; i <= num_cuts; i++ ) {
562  std::cout << "Upstream jump_point= " << jump_partners_[i].first;
563  std::cout << " Downstream jump_point= " << jump_partners_[i].second;
564  std::cout << " cut_point= " << cuts_[ i ] << std::endl;
565 
566  jump_point( 1, i ) = jump_partners_[i].first;
567  jump_point( 2, i ) = jump_partners_[i].second;
568  cuts( i ) = cuts_[ i ];
569  // std::cout << " HELLO: " << jump_point( 1, i ) << " " << jump_point( 2, i ) << " " << cuts( i ) << std::endl;
570  }
571 
572  // if ( moving_res_list_.size() < 1 ) return;
573  // Size const root_res = ( full_to_sub[ moving_res_list_[1] ] == 1 ) ? nres : 1;
574 
575  f.tree_from_jumps_and_cuts( nres, num_cuts, jump_point, cuts ); //order of element in jump_point and cuts does not have to match. Jan 29, 2010 Parin S.
576 
577  for ( Size i = 1; i <= num_cuts; i++ ) {
578  Size const k = f.upstream_jump_residue( i );
579  Size const m = f.downstream_jump_residue( i );
580 
581  Residue const & rsd1( pose.residue( k ) );
582  Residue const & rsd2( pose.residue( m ) );
583 
584  bool const KeepStubInResidue( true ); //rsd1.is_protein() & rsd2.is_protein() );
585  f.set_jump_atoms( i, get_swa_jump_atom( rsd1 ), get_swa_jump_atom( rsd2 ), KeepStubInResidue );
586 
587  }
588 
589  f.reassign_atoms_for_intra_residue_stubs(); // it seems silly that we need to do this separately.
590 
591  pose.fold_tree( f );
592 
593  }
594 
595 
596  ////////////////////////////////////////////////////////////////////////////////////
597  void
599 
600  if ( disulfide_file_.size() == 0 ) return;
601 
602  Pose full_pose;
603  make_full_pose( full_pose );
604 
605  // move to its own function?
608  ds_file.disulfides(disulf_bonds, full_pose);
609 
610  std::map< core::Size, core::Size > & full_to_sub( job_parameters_->full_to_sub() );
611  ObjexxFCL::FArray1D< Size > const & is_working_res = job_parameters_->is_working_res();
612 
613  utility::vector1< std::pair<Size,Size> > working_disulf_bonds;
614 
615  for ( Size n = 1; n <= disulf_bonds.size(); n++ ){
616  // std::cout << disulf_bonds[n].first << " " << is_working_res( disulf_bonds[n].first ) << " " << disulf_bonds[n].second << " " << is_working_res( disulf_bonds[n].second ) << std::endl;
617  if ( is_working_res( disulf_bonds[n].first )>0 &&
618  is_working_res( disulf_bonds[n].second )>0 ){
619 
620  std::cout << "FOUND PAIR: " << disulf_bonds[n].first << "--" << disulf_bonds[n].second << "[in subpose: " << full_to_sub[ disulf_bonds[n].first ] << "--" << full_to_sub[ disulf_bonds[n].second ] << "]" << std::endl;
621 
622  working_disulf_bonds.push_back( std::make_pair( full_to_sub[ disulf_bonds[n].first ], full_to_sub[ disulf_bonds[n].second ] ) );
623  }
624  }
625 
626  pose.conformation().fix_disulfides( working_disulf_bonds );
627  for ( Size n = 1; n<= pose.total_residue();n++ ) std::cout << pose.residue_type( n ).has_variant_type( chemical::DISULFIDE );
628  std::cout << std::endl;
629 
630  // this is not showing up right...
631  std::cout << "AFTER DISULF: " << pose.annotated_sequence( true ) << std::endl;
632 
633  }
634 
635  ////////////////////////////////////////////////////////////////////////////////////
638 
639  //if (rsd.is_RNA() ) return rsd.atom_name( rsd.chi_atoms(1)[4] );
640  if (rsd.is_RNA() ) return " C4*";
641 
642  if (rsd.is_protein() ) return " CA ";
643 
644  utility_exit_with_message( "Cannot deal with pose that is not RNA or protein yet." );
645  return "";
646  }
647 
648  ////////////////////////////////////////////////////////////////////////////////////
649  void
651 
652  using namespace core::scoring::constraints;
653 
654  if ( cst_file_.size() == 0 ) return;
655 
656  utility::vector1< Size > const & working_res_list = job_parameters_->working_res_list();
657 
658  Pose full_pose;
659  make_full_pose( full_pose );
660 
661  // Constraints!
662  // To read in constraints, need to use full desired_sequence pose,
663  // since there's a careful check of atom names...
664  // Hey, this has to happen after the variants are figured out!!!
668  scorefxn->set_weight( core::scoring::coordinate_constraint, 1.0 );
669  full_pose.constraint_set( cst_set_ );
670  (*scorefxn)( full_pose );
671 
672  cst_set_ = constraint_set_slice( cst_set_, working_res_list, pose, full_pose );
673  pose.constraint_set( cst_set_ );
674 
675  //(*scorefxn)( pose );
676  }
677 
678  ///////////////////////////////////////////////////////////////////////////////////
679  void
681 
682  Size const & nres = pose.total_residue();
683 
684  phi_offsets_.dimension( nres, 0.0 );
685  psi_offsets_.dimension( nres, 0.0 );
686 
687  for ( Size n = 1; n <= nres; n++ ) {
688  if (!pose.residue( n ).is_protein()) continue;
689  // The "pretend" phi and psi are torsion angles based on:
690  // C-CA-N-H (rather than C-CA-N-C) for phi, and
691  // CA-N-C-O (rather than CA-N-C-CA) for psi.
694  // std::cout << " HELLO! " << protocols::swa::protein::get_pretend_phi_explicit( pose, n )<< " " << phi_offsets_( n ) << " " << psi_offsets_( n ) << std::endl;
695  }
696  }
697 
698 
699  ///////////////////////////////////////////////////////////////////////////////////
700  void
702  pose::Pose const & start_pose,
703  utility::vector1< core::Size > const & input_res,
704  utility::vector1< core::Size > const & slice_res ){
705 
706  assert( slice_res.size() == input_res.size() );
707  std::map< core::Size, core::Size > & full_to_sub( job_parameters_->full_to_sub() );
708 
709  for ( Size n = 1; n <= input_res.size(); n++ ) {
710  if (!start_pose.residue( slice_res[ n ] ).is_protein()) continue;
711  phi_offsets_( full_to_sub[ input_res[ n ] ] ) = protocols::swa::protein::get_pretend_phi_explicit( start_pose, slice_res[ n ] ) ;
712  psi_offsets_( full_to_sub[ input_res[ n ] ] ) = protocols::swa::protein::get_pretend_psi_explicit( start_pose, slice_res[ n ] ) ;
713  }
714 
715  }
716 
717  ///////////////////////////////////////////////////////////////////////////////////
718  void
720 
721  for ( Size n = 1; n <= pose.total_residue(); n++ ) {
722 
723  if (!pose.residue( n ).is_protein()) continue;
724  Real const phi_current = protocols::swa::protein::get_pretend_phi_explicit( pose, n );
725  Real const psi_current = protocols::swa::protein::get_pretend_psi_explicit( pose, n );
726 
727  pose.set_phi( n, pose.phi( n ) - phi_current + phi_offsets_( n ) ) ;
728  pose.set_psi( n, pose.psi( n ) - psi_current + psi_offsets_( n ) ) ;
729  }
730 
731  }
732 
733  ///////////////////////////////////////////////////////////////////////////////////
734  void
736  pose::Pose const import_pose,
737  utility::vector1< core::Size > const & input_res,
738  utility::vector1< core::Size > const & slice_res ){
739 
740  std::map< core::Size, core::Size > & full_to_sub( job_parameters_->full_to_sub() );
741 
742  for ( Size n = 1; n <= input_res.size(); n++ ) {
743  if (!import_pose.residue( slice_res[ n ] ).is_RNA()) continue;
744  pose.set_chi( 1, full_to_sub[ input_res[ n ] ], import_pose.chi( 1, slice_res[n] ) );
745  }
746 
747  }
748 
749  ///////////////////////////////////////////////////////////////////////////////////
750  void
752  {
753 
754  using namespace core::chemical;
755 
757 
758  Pose import_pose;
759 
760  if (dump_) pose.dump_pdb( "before_copy_dofs.pdb" );
761 
762  // go ahead and align pose to this first input. If native or align_pose is specified, we will realign again later...
763  bool align_pose_to_import_pose( true );
764  if (get_native_pose() || align_file_.size() > 0 ) align_pose_to_import_pose = false; // will happen later in align_poses()
765 
766  for ( Size i = 1; i <= input_streams_with_residue_info_.size(); i++ ){
767 
768  if ( i > 1) align_pose_to_import_pose = false;
769 
771  stream->set_full_to_sub( job_parameters_->full_to_sub() );
772  stream->set_rsd_set( rsd_set_ );
773 
774  stream->copy_next_pose_segment( pose, import_pose, true /*check_sequence_matches*/, align_pose_to_import_pose );
775 
776  save_phi_psi_offsets( import_pose, stream->input_res(), stream->slice_res() );
777  copy_rna_chi( pose, import_pose, stream->input_res(), stream->slice_res() ); //hope this is OK.
778 
779  if (dump_) pose.dump_pdb( "after_copy_dofs"+ObjexxFCL::string_of(i)+".pdb" );
780  if (dump_) import_pose.dump_pdb( "import"+ObjexxFCL::string_of(i)+".pdb" );
781 
782  }
783 
784  // protocols::rna::print_internal_coords( pose );
785 
786  }
787 
788  ///////////////////////////////////////////////////////////////////////////////////
789  void
791 
792  ObjexxFCL::FArray1D_bool partition_definition( pose.total_residue(), false );
793 
794  utility::vector1< Size > const & moving_suite_list( job_parameters_->working_moving_suite_list() );
795  utility::vector1< Size > const & moving_res_list( job_parameters_->working_moving_res_list() );
796 
797  // THIS SUCKS! SHOULD GET RID OF IT AND SPECIFY FROM COMMAND LINE MOVING_SUITE!!!
798 
799  if ( moving_res_list.size() > 0 ){ //may not be filled if we are setting up for a "prepack"
800  // trick to figure out which residues are upstream vs. downstream of the moving suite --
801  Size partition_res( 0 );
802  if ( (moving_suite_list.size() > 0 &&
803  moving_suite_list[ 1 ] == (moving_res_list[ 1 ]-1) ) /*append*/ ||
804  ( moving_res_list[1] > 1 &&
805  moving_res_list[ moving_res_list.size() ] == pose.total_residue() ) ){
806  partition_res = moving_res_list[ 1 ] - 1;
807  } else {
808  partition_res = moving_res_list[ moving_res_list.size() ];
809  }
810  std::cout << "PARTITION_RES ==> " << partition_res << std::endl;
811  pose.fold_tree().partition_by_residue( partition_res, partition_definition );
812  }
813 
814  std::cout << "PARTITION_DEFINITION ==> ";
815  for ( Size i = 1; i <= pose.total_residue(); i++ ) std::cout << partition_definition( i );
816  std::cout << std::endl;
817  std::cout << "FOLD_TREE " << pose.fold_tree() << std::endl;
818  // std::cout << "NUM_JUMPS " << pose.fold_tree().num_jump() << std::endl;
819 
820  job_parameters_->set_partition_definition( partition_definition ); //this is a useful decomposition.
821 
822  if ( moving_res_list.size() == 0 ) return;
823 
824  bool const start_partition = partition_definition( moving_res_list[ 1 ] );
825 // for ( Size i = 1; i <= moving_res_list.size(); i++ ){
826 // if ( partition_definition( moving_res_list[ i ] ) != start_partition ){
827 // utility_exit_with_message( "Moving res list is split across two partitions -- cannot handle this case now!" );
828 // }
829 // }
830 
831  ObjexxFCL::FArray1D< Size > const & is_moving_res( job_parameters_->is_moving_res() );
832  std::map< core::Size, core::Size > & sub_to_full( job_parameters_->sub_to_full() );
833  for ( Size i = 1; i <= pose.total_residue(); i++ ){
834  if ( is_moving_res( sub_to_full[ i ] ) ) continue;
835  if ( partition_definition( i ) == start_partition ){
836  job_parameters_->set_Is_internal( true );
837  break;
838  }
839  }
840 
841 
842  }
843 
844  ////////////////////////////////////////////////////////////////////////////////////////////////////
845  ////////////////////////////////////////////////////////////////////////////////////////////////////
846  ////////////////////////////////////////////////////////////////////////////////////////////////////
847  // Figure out a good root residue -- which partition of the pose has the fewest residues to move around?
848  void
850 
851  utility::vector1< Size > const & moving_res_list = job_parameters_->working_moving_res_list();
852  if ( moving_res_list.size() < 1 ) return; // might be setting up for a prepack -- root is irrelevant.
853 
854  ObjexxFCL::FArray1D< bool > const & partition_definition = job_parameters_->partition_definition();
855  // std::map< core::Size, core::Size > & full_to_sub( job_parameters_->full_to_sub() );
856  Size const nres = pose.total_residue();
857 
858  Size num_partition_0( 0 ), num_partition_1( 0 );
859  Size possible_new_root_residue_in_partition_0( 0 ), possible_new_root_residue_in_partition_1( 0 ), root_res( 0 );
860 
861  for ( Size n = 1; n <= nres; n++ ) {
862  if( partition_definition( n ) ) {
863  num_partition_1 += 1;
864  if ( possible_root( pose.fold_tree(), n ) ) possible_new_root_residue_in_partition_1 = n;
865  } else {
866  num_partition_0 += 1;
867  if ( possible_root( pose.fold_tree(), n ) ) possible_new_root_residue_in_partition_0 = n;
868  }
869  }
870 
871  //If moving_res=1 or nres, then it is best to put root_res at one of the fixed residue in the correct partition. Parin Jan 18, 2010
872  //CHANGE FROM fix_res to terminal_res!!! Parin Feb 7, 2010
873  utility::vector1< core::Size > working_fixed_res( job_parameters_->working_fixed_res() );
874  for(Size i=1; i<=working_fixed_res.size(); i++){
875  Size const seq_num = working_fixed_res[i];
876  if(partition_definition( seq_num ) && possible_root( pose.fold_tree(), seq_num ) ){
877  possible_new_root_residue_in_partition_1= seq_num;
878  break;
879  }
880  }
881 
882  for(Size i=1; i<=working_fixed_res.size(); i++){
883  Size const seq_num = working_fixed_res[i];
884  if( !partition_definition( seq_num ) && possible_root( pose.fold_tree(), seq_num ) ){
885  possible_new_root_residue_in_partition_0= seq_num;
886  break;
887  }
888  }
889 
890  //assert( num_partition_0 > 0 );
891  //assert( num_partition_1 > 0 );
892 
893  //Made some changes here .... Parin Jan 18, 2009
894  Size const moving_res( moving_res_list[1] );
895  if ( job_parameters_->Is_internal() ){
896  // std::cout << "Is_internal" << std::endl;
897  if ( num_partition_1 >= num_partition_0 ){
898  // best to put the root in partition 1 -- it is bigger, and will stay anchored.
899  if ( partition_definition( 1 ) && partition_definition( nres ) ) {
900  root_res = 1;
901  } else {
902  root_res = possible_new_root_residue_in_partition_1;
903  }
904  } else {
905  if ( !partition_definition( 1 ) && !partition_definition( nres )) {
906  root_res = 1;
907  } else {
908  root_res = possible_new_root_residue_in_partition_0;
909  }
910  }
911  } else {
912  // std::cout << "Is not internal" << std::endl;
913  // Put root in the partition that does *not* contain the moving residue.
914  if ( partition_definition( moving_res ) ){
915  root_res = possible_new_root_residue_in_partition_0;
916  // std::cout << "part1 " << root_res << std::endl;
917  } else {
918  root_res = possible_new_root_residue_in_partition_1;
919  // std::cout << "part0 " << root_res << std::endl;
920  }
921  }
922 
923  if ( root_res == 0 ) root_res = 1; // happens if all the residues are moving.
924 
925  std::cout << "Num. res in partition 0: " << num_partition_0 << ". Num. res in partition 1: " << num_partition_1 <<
926  ". Moving_res is in partition " << partition_definition( moving_res ) <<
927  ". New root residue " << root_res << std::endl;
928 
929  assert( root_res > 0 );
931  bool reorder_went_OK = f.reorder( root_res );
932  runtime_assert( reorder_went_OK );
933  pose.fold_tree( f );
934 
935 
936  // moving positions
937  utility::vector1< Size > moving_positions;
938  bool const root_partition = partition_definition( pose.fold_tree().root() );
939  for (Size seq_num=1; seq_num<=pose.total_residue(); seq_num++){
940  if ( partition_definition( seq_num ) != root_partition ) moving_positions.push_back( seq_num );
941  }
942  job_parameters_->set_moving_pos( moving_positions );
943 
944  //////////////////////////////////////////////////////////////////////////////////////////////////
945  // For "internal" suites, we can also better define whether we are prepending or appending.
946  // This actually does not affect very much -- only how we *cluster* (suite_rmsd
947  // needs to pick a side_chain to calculate rmsds over!). This way the suite_rmsd is calculated over the base in the smaller/moving paritition.
948 
949  utility::vector1< Size > working_moving_suite_list( job_parameters_->working_moving_suite_list() );
950  if ( working_moving_suite_list.size() < 1 ) return;
951  Size const first_moving_suite = working_moving_suite_list[ 1 ];
952 
953  if ( job_parameters_->Is_internal() ){
954  if ( partition_definition( first_moving_suite ) == partition_definition( root_res ) ){
955  job_parameters_->set_Is_prepend( false );
956  } else {
957  job_parameters_->set_Is_prepend( true );
958  }
959  } else {
960  /// consistency check!
961  bool const should_be_prepend = ( partition_definition( first_moving_suite ) != partition_definition( root_res ) );
962  if ( should_be_prepend != job_parameters_->Is_prepend() ) {
963 
964  // Wait there's one way the root res is a moving res -- if we're building from scratch.
965  ObjexxFCL::FArray1D< Size > const & is_working_res( job_parameters_->is_working_res() );
966  ObjexxFCL::FArray1D< Size > const & is_moving_res( job_parameters_->is_moving_res() );
967  bool ok( true );
968  for ( Size i = 1; i <= desired_sequence_.size(); i++ ) {
969  if ( is_working_res( i ) && !is_moving_res( i ) ) {
970  ok = false; break;
971  }
972  }
973 
974  if (!ok) {
975  std::cout << " Is_prepend: " << job_parameters_->Is_prepend() << std::endl;
976  std::cout << " should_be_prepend: " << should_be_prepend << std::endl;
977  std::cout << " first_moving_suite: " << first_moving_suite << " partition: " << partition_definition( first_moving_suite ) << std::endl;
978  std::cout << " root_res: " << root_res << " partition: " << partition_definition( root_res ) << std::endl;
979  utility_exit_with_message( "Possible problem with prepend/append assignment!!" );
980  }
981 
982  }
983  }
984 
985  }
986 
987 
988  ///////////////////////////////////////////////////////////////////////////////////
989  void
991 
992  utility::vector1< std::pair< core::Size, core::Size > > const & chain_boundaries( job_parameters_->chain_boundaries() );
993 
994  Size gap_size = 999; // junk value... totally "free" end.
995  job_parameters_->set_gap_size( gap_size /*DUMMY*/ );
996  job_parameters_->set_first_chain_break_res( 0 );
997 
998  /////////////////////////////////////////////////////////////////////////////////////////////
999  // Need to look for a chainbreak whose ends actually will move relative to each other if
1000  // we change degrees of freedom in the "moving residues".
1001  ObjexxFCL::FArray1D< bool > const & partition_definition = job_parameters_->partition_definition();
1002  ObjexxFCL::FArray1D< Size > const & is_working_res = job_parameters_->is_working_res();
1003 
1004  /////////////////////////////////////////////////////////////////////////////////////////////
1005  std::map< core::Size, core::Size > & full_to_sub( job_parameters_->full_to_sub() );
1006  Size found_moving_gap( 0 );
1007  Size const num_chains = chain_boundaries.size();
1008  for ( Size n = 1; n < num_chains; n++ ) {
1009  Size chain_end = chain_boundaries[ n ].second;
1010  Size next_chain_start = chain_boundaries[ n+1 ].first;
1011 
1012  std::cout << "CHECK_CHAIN --> " << chain_end << ' ' << partition_definition( full_to_sub[ chain_end ] ) << ' ' << next_chain_start << ' ' << partition_definition( full_to_sub[ next_chain_start ] ) << std::endl;
1013 
1014  if ( partition_definition( full_to_sub[ chain_end ] ) !=
1015  partition_definition( full_to_sub[ next_chain_start ] ) ||
1016  ( is_working_res( chain_end ) == BRIDGE_RES_ ) ||
1017  ( is_working_res( next_chain_start ) == BRIDGE_RES_ ) ){
1018 
1019  bool found_cutpoint_open( false );
1020  for (Size i = 1; i <= cutpoint_open_.size(); i++ ){
1021  if ( cutpoint_open_[i] >= chain_end && cutpoint_open_[i] < next_chain_start ) {
1022  found_cutpoint_open = true;
1023  break;
1024  }
1025  }
1026  if ( found_cutpoint_open ) continue;
1027 
1028  std::cout << "CUTPOINT CLOSED --> " << chain_end << ' ' << next_chain_start << std::endl;
1029  job_parameters_->set_gap_size( next_chain_start - chain_end - 1 );
1030  job_parameters_->set_first_chain_break_res( full_to_sub[ chain_end ] );
1031  found_moving_gap++;
1032 
1033  }
1034  }
1035 
1036  if ( found_moving_gap > 1 ){
1037  std::cout << "WARNING: Had trouble figure out which gap might be the one to close! Try to renumber input poses sequentially." << std::endl;
1038  }
1039 
1040  }
1041 
1042  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1043  void
1045 
1046  using namespace core::id;
1047 
1048  pose::Pose pose_copy = pose;
1049  kinematics::FoldTree f_simple( pose.total_residue() );
1050  pose_copy.fold_tree( f_simple );
1051 
1052  std::map< core::Size, core::Size > & full_to_sub( job_parameters_->full_to_sub() );
1053 
1054  for ( Size n = 1; n <= cutpoint_closed_.size(); n++ ){
1055 
1056  Size const cutpoint = cutpoint_closed_[ n ];
1057 
1058  if ( full_to_sub.find( cutpoint ) != full_to_sub.end() &&
1059  full_to_sub.find( cutpoint+1 ) != full_to_sub.end() ) {
1060 
1061  Size const cutpos = full_to_sub[ cutpoint ];
1062 
1063  // Taken from Parin's code. Need to make sure virtual atoms are correctly positioned
1064  // next to O1P, O2P.
1065  if ( pose.residue( cutpos ).is_RNA() ) protocols::swa::rna::Correctly_position_cutpoint_phosphate_torsions( pose, cutpos, false /*verbose*/ );
1066 
1069 
1070  std::cout << "Applied cutpoint variants to " << cutpoint << std::endl;
1071 
1072  for (Size i = cutpos; i <= cutpos + 1; i++ ){
1073  utility::vector1< Real > const mainchain_torsions = pose_copy.residue( i ).mainchain_torsions();
1074  for (Size j = 1; j <= mainchain_torsions.size(); j++ ) {
1075  id::TorsionID torsion_id( i, id::BB, j );
1076  //std::cout << "TORSION AT CHAINBREAK: " << torsion_id << mainchain_torsions[ j ] << std::endl;
1077  pose.set_torsion( torsion_id, mainchain_torsions[ j ] ); //This makes sure that the chain_break torsions have the correct value
1078  } // j
1079  } // i
1080 
1081  }
1082  }
1083 
1084  // pose.dump_pdb( "AFTER_CUTPOINTS.pdb" );
1085 
1086  }
1087 
1088 
1089  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1090  void
1092  using namespace core::conformation;
1093  using namespace core::pose;
1094 
1095  ObjexxFCL::FArray1D< Size > const & is_working_res( job_parameters_->is_working_res() );
1096  std::map< core::Size, core::Size > & full_to_sub( job_parameters_->full_to_sub() );
1097 
1098  for ( Size n = 1; n <= bulge_res_.size(); n++ ) {
1099  if ( !is_working_res( bulge_res_[ n ] ) ) continue;
1100  pose::add_variant_type_to_pose_residue( pose, "BULGE", full_to_sub[ bulge_res_[ n ] ] );
1101  }
1102 
1103 
1104  }
1105 
1106 
1107  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1108  //applies terminus variants to any internal residues. Note that
1109  void
1111  using namespace core::conformation;
1112  using namespace core::pose;
1113 
1114  for ( Size n = 1; n <= pose.total_residue()-1; n++ ) {
1115  if ( (pose.residue( n ).is_RNA() && pose.residue( n+1).is_protein()) ||
1116  (pose.residue( n ).is_protein() && pose.residue( n+1).is_RNA()) ){
1117  pose::add_variant_type_to_pose_residue( pose, "UPPER_TERMINUS", n );
1118  pose::add_variant_type_to_pose_residue( pose, "LOWER_TERMINUS", n+1 );
1119  }
1120  }
1121 
1122  }
1123 
1124  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1125  void
1127 
1128  if ( !Is_close_chain_break( pose ) && job_parameters_->gap_size() == 0 ) {
1129  utility_exit_with_message( "mismatch --> gap_size = 0, but no cutpoint variants defined?" );
1130  }
1131  // if ( Is_close_chain_break( pose ) && job_parameters_->gap_size() != 0 ) {
1132  //utility_exit_with_message( "mismatch --> gap_size != 0, but cutpoint variants defined?" );
1133  // }
1134 
1135  }
1136 
1137 
1138  ////////////////////////////////////////////////////////
1139  void
1141 
1142  utility::vector1< core::Size > const & working_superimpose_res( job_parameters_->working_superimpose_res() );
1143  utility::vector1< core::Size > const & working_fixed_res( job_parameters_->working_fixed_res() );
1144  ObjexxFCL::FArray1D< bool > const & partition_definition = job_parameters_->partition_definition();
1145 
1146  bool const root_partition = partition_definition( pose.fold_tree().root() );
1147 
1148  for ( Size i = 1; i <= working_superimpose_res.size(); i++ ) {
1149  if ( !Contain_seq_num( working_superimpose_res[ i ], working_fixed_res ) ){
1150  std::cout << "working superimpose_res " << working_superimpose_res[ i] << " not in fixed_res? " << std::endl;
1151  utility_exit_with_message( "You will get weird results if superimpose_res residues are allowed to move!" );
1152  }
1153  if ( !partition_definition( working_superimpose_res[ i ] ) == root_partition ) {
1154  std::cout << "working_superimpose_res " << working_superimpose_res[ i ] << std::endl;
1155  utility_exit_with_message( "Superimpose_res residues need to end up in root paritition and stay fixed!" );
1156  }
1157  }
1158  }
1159 
1160 
1161  ////////////////////////////////////////////////////////
1162  void
1164 
1165  using namespace core::pose;
1166  using namespace core::conformation;
1167 
1168  working_pose = Pose(); //clear this out.
1169 
1170  ObjexxFCL::FArray1D< Size > const & is_working_res( job_parameters_->is_working_res() );
1171 
1172  // Need a simple fold tree for following to work...
1173  Pose full_pose_copy = pose;
1174  full_pose_copy.fold_tree( core::kinematics::FoldTree( full_pose_copy.total_residue() ) );
1175 
1176  for ( Size i = 1; i <= full_pose_copy.total_residue(); i++ ) {
1177  if ( !is_working_res( i ) ) continue;
1178  //std::cout << "About to append: " << i << std::endl;
1179  ResidueOP residue_to_add = full_pose_copy.residue( i ).clone() ;
1180 
1181  if ( i > 1 && residue_to_add->is_lower_terminus() ) {
1182  working_pose.append_residue_by_jump( *residue_to_add, working_pose.total_residue() ) ;
1183  } else {
1184  working_pose.append_residue_by_bond( *residue_to_add ) ;
1185  }
1186  }
1187 
1188  assert( working_pose.sequence() == job_parameters_->working_sequence() );
1189 
1190  // RNA thing.
1192 
1193 
1194  //also carry over disulfides?
1195 
1196 
1197  }
1198 
1199  ////////////////////////////////////////////////////////
1200  void
1202  using namespace core::conformation;
1203  using namespace core::pose;
1204  using namespace protocols::rna;
1205 
1206  if ( get_native_pose() == 0 ) return;
1207 
1208  std::cout << "NATIVE sequence: " << get_native_pose()->annotated_sequence( true ) << std::endl;
1209 
1210  working_native_pose = new Pose;
1212 
1213  }
1214 
1215  //////////////////////////////////////////////////////////////////////////////////////
1216  void
1218 
1219 
1220  if ( align_file_.size() > 0 ){
1221  Pose full_align_pose;
1222  import_pose::pose_from_pdb( full_align_pose, *rsd_set_, align_file_ );
1223 
1225  get_working_pose( full_align_pose, *working_align_pose_ );
1226 
1227  std::cout << "PoseSetup: Align to file: " << align_file_ << std::endl;
1228  } else {
1229  if ( get_native_pose() ) {
1230 
1233 
1234  std::cout << "PoseSetup: Align to NATIVE" << std::endl;
1235 
1236  } else {
1237 
1238  std::cout << "PoseSetup: Do not do any alignment." << std::endl;
1239  return;
1240 
1241  }
1242  }
1243 
1244 
1245  ////////////////////////////////////////////////////////////////////////////////////////////////
1246  // Following is needed to help calculate rmsds to native... there are some runs,
1247  // for example where we just model a little loop. We only want to calculate rmsd over that loop, with
1248  // the rest of the structure pre-aligned. User can specify "-superimpose_res" from the command line.
1249  utility::vector1< core::Size > superimpose_res( job_parameters_->working_superimpose_res() );
1250 
1251  if ( superimpose_res.size() == 0 ){
1252  for ( Size i = 1; i <= pose.total_residue(); i++ ) superimpose_res.push_back( i );
1253  }
1254 
1255  // std::cout << "WORKING_SUPERIMPOSE_RES SIZE " << superimpose_res.size() << std::endl;
1256 
1258  ready_to_align_ = true;
1259  align_pose( pose );
1260 
1261  if ( get_native_pose() ) {
1262  id::AtomID_Map< id::AtomID > const & alignment_atom_id_map_native =
1264  core::scoring::superimpose_pose( *working_native_pose, *working_align_pose_, alignment_atom_id_map_native );
1265  }
1266 
1267  // working_native_pose->dump_pdb( "WORKING_NATIVE.pdb" );
1268  // working_align_pose_->dump_pdb( "WORKING_ALIGN.pdb" );
1269  // pose.dump_pdb( "WORKING_POSE.pdb" );
1270 
1271 
1272  }
1273 
1274  //////////////////////////////////////////////////////////////////////////////////////
1275  void
1278  utility_exit_with_message( "Called align pose, but PoseSetup wasn't ready to do it..." );
1279  }
1281  }
1282 
1283  //////////////////////////////////////////////////////////////////////////////////////
1286  return job_parameters_->apply_full_to_sub_mapping( res_vector );
1287  }
1288 
1289  ///////////////////////////////////////////////////////////////////////////////////////////////////
1291  return job_parameters_;
1292  }
1293 
1294  /////////////////////////////////////////////////////////////////
1296 
1297  utility::vector1< core::Size > const & working_moving_res_list( job_parameters_->working_moving_res_list() );
1298  if ( working_moving_res_list.size() < 1 ) return; //happens if we are just setting up the pose to, e.g., prepack.
1299 
1300  Size const first_working_moving_res = working_moving_res_list[ 1 ];
1301  Size const last_working_moving_res = working_moving_res_list[ working_moving_res_list.size() ];
1302 
1303  // Size moving_suite( 0 );
1304  utility::vector1< core::Size > working_moving_suite_list;
1305 
1306  bool moving_res_attached_at_start = true;
1307  bool moving_res_attached_at_end = true;
1308 
1309  //////////////////////////////////////////////////////
1310  if ( first_working_moving_res == 1 ||
1311  pose.fold_tree().is_cutpoint( first_working_moving_res - 1 ) ) {
1312  moving_res_attached_at_start = false;
1313  }
1314 
1315  if ( last_working_moving_res == pose.total_residue() ||
1316  pose.fold_tree().is_cutpoint( last_working_moving_res ) ){
1317  moving_res_attached_at_end = false;
1318  }
1319 
1320  // It might actually make more sense to replace Is_prepend and Is_internal
1321  // with moving_res_attached_at_start and moving_res_attached_at_end...
1322  //
1323  // Or perhaps we should just get rid of these booleans -- what about the more complex
1324  // case in which the N-terminus and C-terminus are being sampled?
1325  //
1326  // bool const Is_prepend = moving_res_attached_at_end;
1327  bool const Is_internal = ( moving_res_attached_at_end && moving_res_attached_at_start );
1328 
1329  //////////////////////////////////////////////////////
1330  // Fill out working_moving_suite.
1331  if ( moving_res_attached_at_start && !Is_internal ){
1332  working_moving_suite_list.push_back( first_working_moving_res - 1 );
1333  }
1334 
1335  for ( Size n = 1; n < working_moving_res_list.size(); n++ ){
1336  working_moving_suite_list.push_back( working_moving_res_list[ n ] );
1337  }
1338 
1339  if ( moving_res_attached_at_end ){
1340  working_moving_suite_list.push_back( last_working_moving_res );
1341  }
1342 
1343  // std::cout << "WORKING_MOVING_SUITE_LIST: " << std::endl;
1344  // for ( Size i = 1; i <= working_moving_suite_list.size(); i++ ) std::cout << ' ' << working_moving_suite_list[ i ];
1345  // std::cout << std::endl;
1346 
1347  //job_parameters_->set_moving_res_attached_at_start( moving_res_attached_start );
1348  //job_parameters_->set_moving_res_attached_at_end( moving_res_attached_at_end );
1349 
1350  // std::cout << "ATTACH AT START: " << moving_res_attached_at_start << std::endl;
1351  // std::cout << "ATTACH AT END: " << moving_res_attached_at_end << std::endl;
1352 
1353  job_parameters_->set_Is_prepend( moving_res_attached_at_end );
1354 
1355  // Watch out! Is_internal gets replaced later based on "partition_definition" --
1356  // occurs in complex fold_trees.
1357  job_parameters_->set_Is_internal( moving_res_attached_at_end && moving_res_attached_at_start );
1358 
1359 
1360  job_parameters_->set_working_moving_suite_list( working_moving_suite_list );
1361 
1362  }
1363 
1364  //////////////////////////////////////////////////////////////////////////////
1365  bool
1366  StepWisePoseSetup::is_working_cutpoint_closed( Size const res, std::map< Size, Size > & full_to_sub ) const {
1367 
1368  for ( Size m = 1; m <= cutpoint_closed_.size(); m++ ) {
1369  if ( res > 0 &&
1370  res == full_to_sub[ cutpoint_closed_[m] ] &&
1371  (res+1) == full_to_sub[ cutpoint_closed_[m]+1 ] ) return true;
1372  }
1373  return false;
1374  }
1375 
1376  //////////////////////////////////////////////////////////////////////////////
1377  // Assume we have done a crappy job of placing 5' phosphates.
1378  // this would be true if, for example, the 5' phosphate was built
1379  // by prepending in a previous rebuild-from-scratch effort.
1380  // The only exception is if the 5'-phosphate is involved in *chain closure*.
1381  //(5' phosphate actually refer to the phosphate group of the residue 3' of the chain_break!!! Jan 29, 2010 Parin S.)
1382  void
1384 
1385  utility::vector1< std::pair< core::Size, core::Size > > const & chain_boundaries( job_parameters_->chain_boundaries() );
1386  std::map< core::Size, core::Size > & full_to_sub( job_parameters_->full_to_sub() );
1387 
1388  Size const num_chains = chain_boundaries.size();
1389 
1390  for ( Size n = 1; n <= num_chains; n++ ) {
1391  Size const chain_start = chain_boundaries[ n ].first;
1392  Size const potential_five_prime_res = full_to_sub[ chain_start ];
1393 
1394  if (is_working_cutpoint_closed( potential_five_prime_res-1, full_to_sub ) ) continue;
1395 
1396  if ( !pose.residue( potential_five_prime_res ).is_RNA() ) continue;
1397 
1398  if ( pose.residue( potential_five_prime_res ).type().has_variant_type( core::chemical::CUTPOINT_UPPER ) ) {
1399  utility_exit_with_message( "Should not be trying to virtualize phosphate on close cutpoint residue!" );
1400  }
1401 
1402  pose::add_variant_type_to_pose_residue( pose, "VIRTUAL_PHOSPHATE", full_to_sub[ chain_start ] );
1403  }
1404  }
1405 
1406  ////////////////////////////////////////////////////////////////////////////////////////////////
1407  // remove?
1408  void
1410 
1411  if ( !add_peptide_plane_variants_ ) return;
1412 
1413 // std::map< core::Size, core::Size > & full_to_sub( job_parameters_->full_to_sub() );
1414 // utility::vector1< core::Size > working_moving_res_list = job_parameters_->working_moving_res_list();
1415 
1416 // for ( Size n = 1; n <= working_moving_res_list.size(); n++ ) {
1417 
1418 // Size const moving_res( working_moving_res_list[ n ] );
1419 
1420 // if (!pose.residue_type( moving_res ).is_protein() ) continue;
1421 
1422 // if ( ( moving_res == pose.total_residue() || pose.fold_tree().is_cutpoint( moving_res ) ) &&
1423 // ( moving_res != full_to_sub[ cutpoint_closed_ ] ) &&
1424 // !pose.residue_type( moving_res ).has_variant_type( "UPPER_TERMINUS" ) ) {
1425 // pose::add_variant_type_to_pose_residue( pose, "C_METHYLAMIDATION", moving_res );
1426 // }
1427 
1428 // if ( ( moving_res == 1 || pose.fold_tree().is_cutpoint( moving_res-1 ) ) &&
1429 // ( moving_res != full_to_sub[ cutpoint_closed_ ] + 1) &&
1430 // !pose.residue_type( moving_res ).has_variant_type( "LOWER_TERMINUS" ) ) {
1431 // pose::add_variant_type_to_pose_residue( pose, "N_ACETYLATION", moving_res );
1432 // }
1433 
1434 // }
1435  }
1436 
1437  //////////////////////////////////////////////////////////////////////////////
1438  // Add peptide plane "caps" to moving ends of protein... lets phi/psi be sampled
1439  // and moves around hydrogen bond donor (NH) or acceptor (backbone C=O).
1440  void
1442 
1443  if ( !add_peptide_plane_variants_ ) return;
1444 
1445  utility::vector1< std::pair< core::Size, core::Size > > const & chain_boundaries( job_parameters_->chain_boundaries() );
1446  std::map< core::Size, core::Size > & full_to_sub( job_parameters_->full_to_sub() );
1447 
1448  Size const num_chains = chain_boundaries.size();
1449 
1450  for ( Size n = 1; n <= num_chains; n++ ) {
1451 
1452  Size const chain_start = chain_boundaries[ n ].first;
1453  Size const potential_Nterm_res = full_to_sub[ chain_start ];
1454  if ( !is_working_cutpoint_closed( potential_Nterm_res-1, full_to_sub ) &&
1455  pose.residue( potential_Nterm_res ).is_protein() &&
1456  !pose.residue( potential_Nterm_res ).has_variant_type( "LOWER_TERMINUS") ) {
1457  pose::add_variant_type_to_pose_residue( pose, "N_ACETYLATION", potential_Nterm_res );
1458  }
1459 
1460  Size const chain_end = chain_boundaries[ n ].second;
1461  Size const potential_Cterm_res = full_to_sub[ chain_end ];
1462  if ( !is_working_cutpoint_closed( potential_Cterm_res, full_to_sub ) &&
1463  pose.residue( potential_Cterm_res ).is_protein() &&
1464  !pose.residue( potential_Cterm_res ).has_variant_type( "UPPER_TERMINUS") ) {
1465  pose::add_variant_type_to_pose_residue( pose, "C_METHYLAMIDATION", potential_Cterm_res );
1466  }
1467 
1468 
1469  }
1470 
1471  }
1472 
1473 
1474  ////////////////////////////////////////////////////////////////////////////////////////
1475  void
1477  //Parin Jan 17, 2010
1478  // For RNA only, for now.
1479  // Rhiju added proteins May 5, 2010
1480  using namespace core::id;
1481 
1482  pose::Pose pose_copy = pose;
1483 
1484  std::map< core::Size, core::Size > & full_to_sub( job_parameters_->full_to_sub() );
1485 
1486  for(Size i=1; i<=virtual_res_list_.size(); i++){
1487  Size const seq_num=virtual_res_list_[i];
1488  if (full_to_sub.find( seq_num ) != full_to_sub.end() ) {
1489  pose::add_variant_type_to_pose_residue( pose, "VIRTUAL_RESIDUE", full_to_sub[ seq_num] );
1490  }
1491  }
1492  }
1493 
1494  //////////////////////////////////////////////////////////////////////////
1495  void
1497  {
1498  using namespace core::conformation;
1499  using namespace core::id;
1500  using namespace core::scoring::constraints;
1501  using namespace core::scoring::rna;
1502 
1503  ConstraintSetOP cst_set( pose.constraint_set()->clone() );
1504  assert( cst_set );
1505 
1506  utility::vector1< core::Size > const & working_terminal_res = job_parameters_->working_terminal_res();
1507 
1508  /////////////////////////////////////////////////
1509  Size const nres( pose.total_residue() );
1510 
1511  ObjexxFCL::FArray1D<bool> is_moving_res( nres, false );
1512  ObjexxFCL::FArray1D<bool> is_fixed_res( nres, false );
1513 
1514  ObjexxFCL::FArray1D< bool > const & partition_definition = job_parameters_->partition_definition();
1515  bool const root_partition = partition_definition( pose.fold_tree().root() );
1516 
1517  for (Size seq_num=1; seq_num <= nres; seq_num++){
1518  if ( partition_definition( seq_num ) == root_partition ) {
1519  is_fixed_res( seq_num ) = true;
1520  } else {
1521  is_moving_res( seq_num ) = true;
1522  }
1523  }
1524 
1525 
1526  /////////////////////////////////////////////////
1527  Distance const DIST_CUTOFF = 8.0;
1528  FuncOP const repulsion_func( new FadeFunc( -2.0 /*min*/, DIST_CUTOFF /*max*/, 1.0 /*fade zone width*/, 100.0 /*penalty*/ ) );
1529 
1530  for ( Size i = 1; i <= working_terminal_res.size(); i++ ) {
1531 
1532  Size const k = working_terminal_res[ i ];
1533 
1534  for ( Size m = 1; m <= nres; m++ ) {
1535 
1536  Residue const & rsd1( pose.residue( k ) );
1537  Residue const & rsd2( pose.residue( m ) );
1538 
1539  AtomID const atom_id1( first_base_atom_index( rsd1 ), rsd1.seqpos() );
1540  AtomID const atom_id2( first_base_atom_index( rsd2 ), rsd2.seqpos() );
1541 
1542  // the one exception -- close contacts WITHIN a partition
1543  if ( ( ( is_moving_res( k ) && is_moving_res( m ) ) ||
1544  ( is_fixed_res( k ) && is_fixed_res( m ) ) ) &&
1545  ( pose.xyz( atom_id1 ) - pose.xyz( atom_id2 ) ).length() < DIST_CUTOFF ) {
1546  //std::cout << "Not adding repulsive constraint between " << k << " and " << m << " already closeby in same partition" << std::endl;
1547  continue;
1548  }
1549 
1550  // distance from O3* to P
1551  cst_set->add_constraint( new AtomPairConstraint( atom_id1, atom_id2, repulsion_func ) );
1552 
1553  }
1554  }
1555 
1556  pose.constraint_set( cst_set );
1557 
1558  /////////////////////////////////////////////////////////////
1559  // New virtualize terminal res.
1560  // keep the hydrogens in there though -- they supply sterics.
1561  // for ( Size i = 1; i <= working_terminal_res.size(); i++ ) {
1562  // pose::add_variant_type_to_pose_residue( pose, "VIRTUAL_BASE_HEAVY_ATOM", working_terminal_res[ i ] );
1563  // }
1564 
1565 
1566  }
1567 
1568  //////////////////////////////////////////////////////////////////////////
1569  void
1571 
1572  ObjexxFCL::FArray1D< Size > const & is_working_res( job_parameters_->is_working_res() );
1573 
1574  if ( secstruct_.size() > 0 ){
1575 
1576  if ( secstruct_.size() != desired_sequence_.size() ) utility_exit_with_message( "Input secstruct does not have same size as full length sequence" );
1577 
1578  Size count = 0;
1579  for( Size n = 1; n <= desired_sequence_.size(); n++ ){
1580  if( !is_working_res[ n ] ) continue;
1581  count++;
1582  pose.set_secstruct( count, secstruct_[n-1] );
1583  }
1584 
1585  } else {
1586 
1587  for( Size n = 1; n <= pose.total_residue(); n++ ) {
1588  pose.set_secstruct( n, 'L' );
1589  }
1590 
1591  }
1592 
1593 
1594  }
1595 
1596  //////////////////////////////////////////////////////////////////////////
1597  void
1599  fixed_res_ = fixed_res;
1600  }
1601 
1602  //////////////////////////////////////////////////////////////////////////
1603  void
1605  jump_res_ = jump_res;
1606  }
1607 
1608  //////////////////////////////////////////////////////////////////////////
1609  void
1611  virtual_res_list_ = set_virtual_res_list;
1612  }
1613  //////////////////////////////////////////////////////////////////////////
1614  void
1616  terminal_res_ = terminal_res;
1617  }
1618 
1619  //////////////////////////////////////////////////////////////////////////
1620  void
1622  bulge_res_ = bulge_res;
1623  }
1624 
1625  //////////////////////////////////////////////////////////////////////////
1626  void
1628  bridge_res_ = bridge_res;
1629  }
1630 
1631  //////////////////////////////////////////////////////////////////////////
1632  void
1634  rsd_set_ = rsd_set;
1635  }
1636 
1637  //////////////////////////////////////////////////////////////////////////
1638  void
1640  cst_file_ = cst_file;
1641  }
1642 
1643 
1644  //////////////////////////////////////////////////////////////////////////
1645  void
1647  disulfide_file_ = disulfide_file;
1648  }
1649 
1650  //////////////////////////////////////////////////////////////////////////
1651  void
1653  align_file_ = align_file;
1654  }
1655 
1656  //////////////////////////////////////////////////////////////////////////
1657  void
1659  add_peptide_plane_variants_ = setting;
1660  }
1661 
1662  //////////////////////////////////////////////////////////////////////////
1663  void
1665  calc_rms_res_ = calc_rms_res;
1666  }
1667 
1668  //////////////////////////////////////////////////////////////////////////
1669  void
1671  superimpose_res_ = superimpose_res;
1672  }
1673 
1674  //////////////////////////////////////////////////////////////////////////
1675  void
1676  StepWisePoseSetup::set_dump( bool const dump ){
1677  dump_ = dump;
1678  }
1679 
1680  //////////////////////////////////////////////////////////////////////////
1681  bool
1683  return ready_to_align_;
1684  }
1685 
1686 
1687  //////////////////////////////////////////////////////////////////////////
1688  void
1690  secstruct_ = secstruct;
1691  }
1692 
1693 
1694 }
1695 }