Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
motif_utils.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 motif_utils.cc
11 /// @brief Motif helper/conversion/io functions
12 /// @author havranek, sthyme (sthyme@gmail.com)
13 
14 // Unit Headers
16 
17 // Package Headers
22 
23 // Project Headers (protocols)
25 // AUTO-REMOVED #include <protocols/dna/DnaInterfaceFinder.hh>
26 #include <protocols/dna/util.hh>
27 #include <protocols/loops/Loops.hh>
28 
29 // Project Headers
30 // AUTO-REMOVED #include <core/chemical/automorphism.hh>
35 // AUTO-REMOVED #include <core/chemical/VariantType.hh>
39 // AUTO-REMOVED #include <core/conformation/ResidueMatcher.hh>
40 #include <core/graph/Graph.hh>
41 #include <core/id/AtomID.hh>
42 // AUTO-REMOVED #include <core/io/pdb/pose_io.hh>
43 #include <core/kinematics/Jump.hh>
44 #include <core/kinematics/RT.hh>
51 #include <core/pose/Pose.hh>
52 #include <core/pose/PDBInfo.hh>
53 #include <core/pose/PDBPoseMap.hh>
62 #include <core/types.hh>
63 #include <basic/Tracer.hh>
64 
65 // Utility Headers
66 #include <utility/exit.hh>
67 #include <utility/file/file_sys_util.hh>
68 #include <utility/file/FileName.hh>
69 #include <utility/io/izstream.hh>
70 #include <utility/tools/make_map.hh>
71 #include <utility/tools/make_vector1.hh>
72 #include <utility/string_util.hh>
73 #include <utility/vector1.hh>
74 #include <utility/vector0.hh>
75 
76 // Numeric Headers
77 // AUTO-REMOVED #include <numeric/model_quality/rms.hh>
78 #include <numeric/xyzVector.hh>
79 // AUTO-REMOVED #include <numeric/xyz.functions.hh>
80 // AUTO-REMOVED #include <ObjexxFCL/FArray2D.hh>
81 
82 // C++ Headers
83 // AUTO-REMOVED #include <cctype>
84 
85 // Option Key Includes
86 #include <basic/options/option.hh>
87 #include <basic/options/keys/dna.OptionKeys.gen.hh>
88 #include <basic/options/keys/motifs.OptionKeys.gen.hh>
89 
91 
92 namespace protocols {
93 namespace motifs {
94 
95 static basic::Tracer mu_tr( "protocols.motifs.motif_utils", basic::t_info );
96 
97 //this function uses the constructor that accepts two residues, rather than input atoms, because if the constructors that allow you to setup the atoms explicitly are necessary you are likely to have the information setup in a motif_file (or you can simply make another matching function that allows input atoms as well as a pdb, rather than a istream)
100  utility::file::FileName const & motif_filename
101 )
102 {
104  core::import_pose::pose_from_pdb( *pose, motif_filename );
105  core::conformation::Residue res1( pose->residue(1) ); //the motifs in my motif pdbs are setup so that residue #1 is the amino acid and #2 is the base
106  core::conformation::Residue res2( pose->residue(2) ); //this function at some point include some checks to see what residue is base or amino acid or both bases, both amino acids (or something else, like a ligand, etc)
107 
108  SingleMotifOP retval = new SingleMotif( res1, res2 );
109  std::string this_remark( motif_filename.base() ); //I am using the remark to keep track of the pdb name for output purposes (I don't know what Jim is using the remark for, since he made it)
110  std::string this_path( motif_filename.path() ); //I am using the remark to keep track of the pdb name for output purposes (I don't know what Jim is using the remark for, since he made it)
111  retval->store_remark( this_remark );
112  retval->store_path( this_path );
113 
114  return retval;
115 }
116 
119  utility::io::izstream & motif_info
120 )
121 {
122  std::string res1;
123  std::string r1atom1, r1atom2, r1atom3;
124  std::string res2;
125  std::string r2atom1, r2atom2, r2atom3;
126  core::kinematics::Jump motif_jump;
127 
128  core::Size const max_line_len(1024);
129  char first_line[max_line_len];
130  motif_info.getline( first_line, sizeof(first_line) );
131  std::istringstream line_in( first_line );
132 
133  line_in >> res1;
134  line_in >> r1atom1;
135  line_in >> r1atom2;
136  line_in >> r1atom3;
137  line_in >> res2;
138  line_in >> r2atom1;
139  line_in >> r2atom2;
140  line_in >> r2atom3;
141 
142  char rest_of_line[max_line_len];
143  line_in.getline( rest_of_line, sizeof(rest_of_line) );
144  std::string rest( rest_of_line );
145  std::string::size_type index( rest.find("REMARK ") );
146  std::string this_remark;
147  bool has_remark( false );
148  if( index != std::string::npos ) {
149  this_remark = rest.substr( index + 7 );
150  has_remark = true;
151  } else {
152  }
153 
154  // Scan to end of line to skip comments
155  // motif_info.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
156  // motif_info.get( remark_in, max_remark );
157 
158  motif_info >> motif_jump;
159 
160  SingleMotifOP retval = new SingleMotif( res1, r1atom1, r1atom2, r1atom3, res2, r2atom1, r2atom2, r2atom3, motif_jump );
161  if( has_remark ) {
162  retval->store_remark( this_remark );
163  }
164 
165  return retval;
166 }
167 
170  std::istream & motif_info
171 )
172 {
173  std::string res1;
174  std::string r1atom1, r1atom2, r1atom3;
175  std::string res2;
176  std::string r2atom1, r2atom2, r2atom3;
177  core::kinematics::Jump motif_jump;
178 
179  core::Size const max_line_len(1024);
180  char first_line[max_line_len];
181  motif_info.getline( first_line, sizeof(first_line) );
182  std::istringstream line_in( first_line );
183 
184  line_in >> res1;
185  line_in >> r1atom1;
186  line_in >> r1atom2;
187  line_in >> r1atom3;
188  line_in >> res2;
189  line_in >> r2atom1;
190  line_in >> r2atom2;
191  line_in >> r2atom3;
192 
193  char rest_of_line[max_line_len];
194  line_in.getline( rest_of_line, sizeof(rest_of_line) );
195  //std::cout << "Rest of line:" << rest_of_line << std::endl;
196  std::string rest( rest_of_line );
197  std::string::size_type index( rest.find("REMARK ") );
198  std::string this_remark;
199  bool has_remark( false );
200  if( index != std::string::npos ) {
201  this_remark = rest.substr( index + 7 );
202  has_remark = true;
203  // std::cout << "Remark is " << this_remark << std::endl;
204  } else {
205  // std::cout << "No remark in motif" << std::endl;
206  }
207 
208  // Scan to end of line to skip comments
209  // motif_info.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
210  // motif_info.get( remark_in, max_remark );
211 
212  motif_info >> motif_jump;
213 
214  SingleMotifOP retval = new SingleMotif( res1, r1atom1, r1atom2, r1atom3, res2, r2atom1, r2atom2, r2atom3, motif_jump );
215  if( has_remark ) {
216  retval->store_remark( this_remark );
217  }
218 
219  return retval;
220 }
221 
224  std::istream & motif_info
225 )
226 {
227  std::string res1;
228  std::string r1atom1, r1atom2, r1atom3;
229  std::string res2;
230  std::string r2atom1, r2atom2, r2atom3;
231  core::kinematics::Jump motif_jump;
232 
233  core::Size const max_line_len(1024);
234  char first_line[max_line_len];
235  motif_info.getline( first_line, sizeof(first_line) );
236  std::istringstream line_in( first_line );
237 
238  line_in >> res1;
239  line_in >> r1atom1;
240  line_in >> r1atom2;
241  line_in >> r1atom3;
242  line_in >> res2;
243  line_in >> r2atom1;
244  line_in >> r2atom2;
245  line_in >> r2atom3;
246 
247  char rest_of_line[max_line_len];
248  line_in.getline( rest_of_line, sizeof(rest_of_line) );
249  std::string rest( rest_of_line );
250  std::string::size_type index( rest.find("REMARK ") );
251  std::string this_remark;
252  bool has_remark( false );
253  if( index != std::string::npos ) {
254  this_remark = rest.substr( index + 7 );
255  has_remark = true;
256  } else {
257  }
258  motif_info >> motif_jump;
259  SingleMotifOP retval = new SingleMotif( res1, r1atom1, r1atom2, r1atom3, r2atom1, r2atom2, r2atom3, motif_jump );
260  if( has_remark ) {
261  retval->store_remark( this_remark );
262  }
263 
264  return retval;
265 }
266 
269  core::conformation::Residue const & pose_dna,
270  core::conformation::Residue const & motif_dna
271 )
272 {
274  xyzVec p( core::scoring::dna::get_z_axis( motif_dna, core::scoring::dna::get_y_axis( motif_dna, 1 ) ) );
275  // The second argument is the chain and if the value is changed from 1 to 2 the resulting value becomes negative
276  xyzVec q( core::scoring::dna::get_z_axis( pose_dna, core::scoring::dna::get_y_axis( pose_dna, 1 ) ) );
277  core::Real dotproduct( p.dot(q));
278  // The dot product should equal 1.0 if the motif base is parallel to the dna that it will be connected with - a reasonable cutoff is 0.95
279  return dotproduct;
280 }
281 
284  core::conformation::Residue const & r1,
285  core::conformation::Residue const & r2
286 )
287 {
288  core::Real retval( 0.0 );
289 
290  retval += r1.xyz( "N" ).distance_squared( r2.xyz( "N" ) );
291  retval += r1.xyz( "CA" ).distance_squared( r2.xyz( "CA" ) );
292  retval += r1.xyz( "C" ).distance_squared( r2.xyz( "C" ) );
293 
294  // For the fourth atom, if either residue is glycine, you need to use HA, else use CB
295  if( r1.type().aa() == core::chemical::aa_gly || r2.type().aa() == core::chemical::aa_gly ) {
296  core::Size index1( r1.type().aa() == core::chemical::aa_gly ? r1.atom_index( "1HA" ) : r1.atom_index( "HA" ) );
297  core::Size index2( r2.type().aa() == core::chemical::aa_gly ? r2.atom_index( "1HA" ) : r2.atom_index( "HA" ) );
298  retval += r1.xyz( index1 ).distance_squared( r2.xyz( index2 ) );
299  } else {
300  retval += r1.xyz( "CB" ).distance_squared( r2.xyz( "CB" ) );
301  }
302 
303  retval = std::sqrt( 0.25 * retval );
304 
305  return retval;
306 }
307 
308 void
311  core::pose::Pose & pose,
312  core::Size this_pos,
313  core::conformation::Residue const & inv_rotamer
314 )
315 {
316  using namespace core::scoring::constraints;
317 
318  cst_set->add_constraint( new CoordinateConstraint( core::id::AtomID( pose.residue( this_pos ).atom_index( "CA" ), this_pos ),
319  core::id::AtomID( pose.residue( 1 ).atom_index( "CA" ), 1 ),
320  inv_rotamer.xyz( "CA" ),
321  new HarmonicFunc( 0.0, 1.0 ) ) );
322 
323  cst_set->add_constraint( new CoordinateConstraint( core::id::AtomID( pose.residue( this_pos ).atom_index( "C" ), this_pos ),
324  core::id::AtomID( pose.residue( 1 ).atom_index( "CA" ), 1 ),
325  inv_rotamer.xyz( "C" ),
326  new HarmonicFunc( 0.0, 1.0 ) ) );
327 
328  cst_set->add_constraint( new CoordinateConstraint( core::id::AtomID( pose.residue( this_pos ).atom_index( "N" ), this_pos ),
329  core::id::AtomID( pose.residue( 1 ).atom_index( "CA" ), 1 ),
330  inv_rotamer.xyz( "N" ),
331  new HarmonicFunc( 0.0, 1.0 ) ) );
332 
333  // For the fourth atom, if either residue is glycine, you need to use HA, else use CB
334  if( pose.residue( this_pos ).type().aa() == core::chemical::aa_gly || inv_rotamer.type().aa() == core::chemical::aa_gly ) {
335  core::Size index1( pose.residue( this_pos ).type().aa() == core::chemical::aa_gly ?
336  pose.residue( this_pos ).atom_index( "1HA" ) : pose.residue( this_pos ).atom_index( "HA" ) );
337  core::Size index2( inv_rotamer.type().aa() == core::chemical::aa_gly ?
338  inv_rotamer.atom_index( "1HA" ) : inv_rotamer.atom_index( "HA" ) );
339 
340  cst_set->add_constraint( new CoordinateConstraint( core::id::AtomID( index1, this_pos ),
341  core::id::AtomID( pose.residue( 1 ).atom_index( "CA" ), 1 ),
342  inv_rotamer.xyz( index2 ),
343  new HarmonicFunc( 0.0, 1.0 ) ) );
344  } else {
345  cst_set->add_constraint( new CoordinateConstraint( core::id::AtomID( pose.residue( this_pos ).atom_index( "CB" ), this_pos ),
346  core::id::AtomID( pose.residue( 1 ).atom_index( "CA" ), 1 ),
347  inv_rotamer.xyz( "CB" ),
348  new HarmonicFunc( 0.0, 1.0 ) ) );
349  }
350 
351  return;
352 }
353 
354 void
357  core::pose::Pose & pose,
358  core::Size this_pos,
359  core::conformation::Residue const & inv_rotamer,
360  MotifCOP this_motif,
361  bool const is_it_forward
362 )
363 {
364  using namespace core::scoring::constraints;
365 
366  core::Size const index1( pose.residue( this_pos ).atom_index(
367  ( is_it_forward ? this_motif->res2_atom1_name() : this_motif->res1_atom1_name() )
368  ) );
369 
370  core::Size const index2( pose.residue( this_pos ).atom_index(
371  ( is_it_forward ? this_motif->res2_atom2_name() : this_motif->res1_atom2_name() )
372  ) );
373 
374  core::Size const index3( pose.residue( this_pos ).atom_index(
375  ( is_it_forward ? this_motif->res2_atom3_name() : this_motif->res1_atom3_name() )
376  ) );
377 
378  // This section is necessary in case pose.residue(1) is not a protein residue, because a DNA residue would not have a CA atom
379  core::Size first_protein_resi(1);
380  core::Size nres( pose.total_residue() );
381  for ( core::Size i(1); i <= nres; ++i ) {
382  if ( pose.residue_type(i).is_protein() ) {
383  first_protein_resi = i;
384  break;
385  }
386  }
387 
388  cst_set->add_constraint( new CoordinateConstraint( core::id::AtomID( index1, this_pos ),
389  core::id::AtomID( pose.residue( first_protein_resi ).atom_index( "CA" ), 1 ),
390  inv_rotamer.xyz( index1 ),
391  new HarmonicFunc( 0.0, 1.0 ) ) );
392 
393  cst_set->add_constraint( new CoordinateConstraint( core::id::AtomID( index2, this_pos ),
394  core::id::AtomID( pose.residue( first_protein_resi ).atom_index( "CA" ), 1 ),
395  inv_rotamer.xyz( index2 ),
396  new HarmonicFunc( 0.0, 1.0 ) ) );
397 
398  cst_set->add_constraint( new CoordinateConstraint( core::id::AtomID( index3, this_pos ),
399  core::id::AtomID( pose.residue( first_protein_resi ).atom_index( "CA" ), 1 ),
400  inv_rotamer.xyz( index3 ),
401  new HarmonicFunc( 0.0, 1.0 ) ) );
402 
403  return;
404 }
405 
407  core::pose::Pose & pose,
408  protocols::loops::Loops & flex_regions
409 )
410 {
411  // Get a score function
412  std::string weights( "standard" );
414 
415  // Set up the packer task
417 
419  allow_vector[ core::chemical::aa_ala ] = true;
420 
421  for( core::Size ires = 1, end_res = pose.total_residue() ; ires <= end_res ; ++ires ) {
422  if( flex_regions.is_loop_residue( ires ) ) {
423  if( pose.residue( ires ).aa() != core::chemical::aa_pro &&
424  pose.residue( ires ).aa() != core::chemical::aa_gly ) {
425  // Add it to the packer task
426  alanize_task->nonconst_residue_task( ires ).restrict_absent_canonical_aas( allow_vector );
427  } else {
428  // Let prolines and glycines stay
429  alanize_task->temporarily_set_pack_residue( ires, false );
430  }
431  } else {
432  // Leave non-loop residues alone
433  alanize_task->temporarily_set_pack_residue( ires, false );
434  }
435  }
436 
437  // Do the actual packing
438  core::pack::pack_rotamers( pose, *score_fxn, alanize_task );
439 }
440 
441 // The following functions are all related to user input and setup for the MotifSearch
442 MotifLibrary const
444 {
445  using namespace basic::options;
446  // Make MotifLibrary from list of motif pdbs
447  if ( option[ OptionKeys::motifs::list_motifs ].user() ) {
448  utility::vector1< utility::file::FileName > listnames( option[ OptionKeys::motifs::list_motifs ]().vector() );
450  MotifLibrary motifs( motifnames );
451  return motifs;
452  // Make MotifLibrary from a file containing motifs
453  } else if ( option[ OptionKeys::motifs::motif_filename ].user() ) {
454  std::string motif_filename( option[ OptionKeys::motifs::motif_filename ]() );
455  MotifLibrary motifs;
456  motifs.add_from_file( motif_filename );
457  return motifs;
458  } else {
459  // (not anymore) Program terminates if no MotifLibrary is given by the command line options
460  // utility_exit_with_message( "ERROR! User must provide input motifs as either a list of PDBs or as a motif file" );
461  mu_tr << "User did not provide input motifs via cmd line, but could be coming in as BuildPosition specific data" << std::endl;
462  MotifLibrary motifs;
463  return motifs;
464  }
465 }
466 
467 MotifLibrary const
469 {
470  using namespace basic::options;
471  // Make MotifLibrary from list of motif pdbs
472  if ( option[ OptionKeys::motifs::list_motifs ].user() ) {
473  utility::vector1< utility::file::FileName > listnames( option[ OptionKeys::motifs::list_motifs ]().vector() );
474  mu_tr << "In get_LigandMotifLibrary, it's working" << std::endl;
476  mu_tr << "" << std::endl;
477  MotifLibrary motifs( motifnames );
478  mu_tr << "" << std::endl;
479  return motifs;
480  // Make MotifLibrary from a file containing motifs
481  } else if ( option[ OptionKeys::motifs::motif_filename ].user() ) {
482  std::string motif_filename( option[ OptionKeys::motifs::motif_filename ]() );
483  mu_tr << "Got filename" << std::endl;
484  MotifLibrary motifs;
485  mu_tr << "Made motiflibrary" << std::endl;
486  motifs.add_ligand_from_file( motif_filename ); //This is main change to continue on ligand path
487  mu_tr << "added motifs from file" << std::endl;
488  return motifs;
489  //mu_tr << "returned motifs" << std::endl; // This code will never be reached. ~Labonte
490  } else {
491  // (not anymore) Program terminates if no MotifLibrary is given by the command line options
492  // utility_exit_with_message( "ERROR! User must provide input motifs as either a list of PDBs or as a motif file" );
493  mu_tr << "User did not provide input motifs via cmd line, but could be coming in as BuildPosition specific data" << std::endl;
494  MotifLibrary motifs;
495  return motifs;
496  }
497 }
498 
501 {
502  using namespace basic::options;
503  // Load a list of conformer PDBs, DNA in my case
504  // At some point there will be input options other than PDB format
505  // Currently this fxn will add all the conformers to one vector, even
506  // if they are of multiple ResidueTypes, ie all 4 DNA bases
508  if ( option[ OptionKeys::motifs::list_dnaconformers ].user() ) {
509  utility::vector1< utility::file::FileName > listnames( option[ OptionKeys::motifs::list_dnaconformers ]().vector() );
510  utility::vector1< utility::file::FileName > conformernames( get_filenames( listnames ) );
512  filename != conformernames.end(); ++filename ) {
514  continue;
515  }
518  if ( pose->total_residue() > 1 ) {
519  std::cerr << "WARNING!!! Conformer PDB contains more than one residue, loading all residues in PDB as conformers." << std::endl;
520  }
521  for ( core::Size i(1); i <= pose->total_residue(); ++i ) {
522  conformerOPs.push_back( pose->residue(i).clone() );
523  }
524  }
525  } else {
526  }
527  return conformerOPs;
528 }
529 
530 std::map< std::string, utility::vector1< core::conformation::ResidueOP > > const
533 )
534 {
535  using namespace core::conformation;
536  std::map< std::string, ResidueOPs > conformer_map;
537  for ( ResidueOPs::const_iterator itr = conformerOPs.begin(), end_itr = conformerOPs.end();
538  itr != end_itr; ++itr ) {
539  std::string name( (*itr)->name3() );
540  conformer_map[name].push_back( *itr );
541  }
542  return conformer_map;
543 }
544 
545 // This function (and related functions) does not belong in the motifs namespace
546 // It also need to be more general, only uses DnaDefs currently
547 // Make resfile compatible, see what options already exist (JA TARGET strategy)
548 // Defs assume PDB numbering!!
551  core::pose::Pose & pose
552 )
553 {
554  using namespace basic::options;
555  using namespace protocols::dna;
556  utility::vector1< core::Size > target_positions(0);
557  if ( option[ OptionKeys::motifs::target_dna_defs ].user() &&
558  option[ OptionKeys::dna::design::dna_defs ].user() ) {
559  // This situation would only arise if you want to make many
560  // DNA mutations, but only focus motif targeting on a subset
561  // The option target_dna_defs should only be used in this situation
562  // At least as I can see now, I could imagine input mutations in another manner
563  // And use that def input to direct motifs
564  // A second situation that should involve target_dna_defs is the one where
565  // multiple bases are allowed a single position, so the Def is in the form of
566  // 409.X.N or 409.X.V, using the standard code for degeneracy
567  DnaDesignDefOPs mutated_dna;
568  DnaDesignDefOPs targeted_dna;
569  load_dna_design_defs_from_options( mutated_dna );
570  make_dna_mutations( pose, mutated_dna );
571  utility::vector1< std::string > str_def( option[ OptionKeys::motifs::target_dna_defs ]().vector() );
572  load_dna_design_defs_from_strings( targeted_dna, str_def );
573  target_positions = defs2vector( pose, targeted_dna );
574  } else if ( option[ OptionKeys::dna::design::dna_defs ].user() ) {
575  DnaDesignDefOPs mutated_dna;
576  load_dna_design_defs_from_options( mutated_dna );
577  make_dna_mutations( pose, mutated_dna );
578  target_positions = defs2vector( pose, mutated_dna );
579  } else if ( option[ OptionKeys::motifs::target_dna_defs ].user() ) {
580  DnaDesignDefOPs targeted_dna;
581  mu_tr << "DNA is not being mutated, but alternative bases are allowed, so mutation may occur at a later point, use dna::dna_defs to input positions to mutate in the straightforward manner." << std::endl;
582  utility::vector1< std::string > str_def( option[ OptionKeys::motifs::target_dna_defs ]().vector() );
583  load_dna_design_defs_from_strings( targeted_dna, str_def );
584  target_positions = defs2vector( pose, targeted_dna );
585  } else {
586  mu_tr << "No input given for DNA target positions, will identify target positions based on input motif building positions." << std::endl;
587  }
588  return target_positions;
589 }
590 
591 // 12-29-09, this is the updated version that can keep track of allowed types, as well as a build position number
592 // parts of this are sort of ridiculous, like if you are only doing the mutating part, then you don't really need to make a pair vector, since it's really just a vector, same goes for the situation where everything should remain wild-type . . .
593 // ie, the first two if statements are really not worthwhile, since you wouldn't be making the single mutations if you were allowing all possiblities, doesn't make sense
594 // this will be modified later, at least right now it is functional and always produces the vector of pairs
595 // the real problem is that the vector of strings is not useful (and thus the purpose of the pair), and the output should really just be a vector of sizes if you are going to allow for degeneracy at some positions . . . although maybe some positions allow degeneracy, some must be mutated to single position, who knows, there are all sorts of input possibilities, at least I know right now that this should function, even if it isn't perfect . . .
596 //utility::vector1< std::pair< core::Size, utility::vector1< std::string > > >
597 std::map< core::Size, std::set< std::string > >
599  core::pose::Pose & pose
600 )
601 {
602  using namespace basic::options;
603  using namespace protocols::dna;
604  //utility::vector1< std::pair< core::Size, utility::vector1< std::string > > > target_positions(0);
605  std::map< core::Size, std::set< std::string > > target_positions;
606  if ( option[ OptionKeys::motifs::target_dna_defs ].user() &&
607  option[ OptionKeys::dna::design::dna_defs ].user() ) {
608  DnaDesignDefOPs mutated_dna;
609  DnaDesignDefOPs targeted_dna;
610  load_dna_design_defs_from_options( mutated_dna );
611  make_dna_mutations( pose, mutated_dna );
612  utility::vector1< std::string > str_def( option[ OptionKeys::motifs::target_dna_defs ]().vector() );
613  load_dna_design_defs_from_strings( targeted_dna, str_def );
614  //target_positions = defs2allowedtypes( pose, targeted_dna );
615  target_positions = defs2map( pose, targeted_dna );
616  } else if ( option[ OptionKeys::dna::design::dna_defs ].user() ) {
617  DnaDesignDefOPs mutated_dna;
618  load_dna_design_defs_from_options( mutated_dna );
619  make_dna_mutations( pose, mutated_dna );
620  //target_positions = defs2allowedtypes( pose, mutated_dna );
621  target_positions = defs2map( pose, mutated_dna );
622  } else if ( option[ OptionKeys::motifs::target_dna_defs ].user() ) {
623  DnaDesignDefOPs targeted_dna;
624  mu_tr << "DNA is not being mutated, but alternative bases are allowed, so mutation may occur at a later point, use dna::dna_defs to input positions to mutate in the straightforward manner." << std::endl;
625  utility::vector1< std::string > str_def( option[ OptionKeys::motifs::target_dna_defs ]().vector() );
626  load_dna_design_defs_from_strings( targeted_dna, str_def );
627  //target_positions = defs2allowedtypes( pose, targeted_dna );
628  target_positions = defs2map( pose, targeted_dna );
629  } else {
630  mu_tr << "No input given for DNA target positions, will identify target positions based on input motif building positions." << std::endl;
631  }
632  return target_positions;
633 }
634 
635 void
637  core::pose::Pose & pose
638 )
639 {
640  using namespace basic::options;
641  using namespace protocols::dna;
642  if ( option[ OptionKeys::motifs::target_dna_defs ].user() &&
643  option[ OptionKeys::dna::design::dna_defs ].user() ) {
644  DnaDesignDefOPs mutated_dna;
645  DnaDesignDefOPs targeted_dna;
646  load_dna_design_defs_from_options( mutated_dna );
647  make_dna_mutations( pose, mutated_dna );
648  utility::vector1< std::string > str_def( option[ OptionKeys::motifs::target_dna_defs ]().vector() );
649  load_dna_design_defs_from_strings( targeted_dna, str_def );
650  } else if ( option[ OptionKeys::dna::design::dna_defs ].user() ) {
651  DnaDesignDefOPs mutated_dna;
652  load_dna_design_defs_from_options( mutated_dna );
653  make_dna_mutations( pose, mutated_dna );
654  } else if ( option[ OptionKeys::motifs::target_dna_defs ].user() ) {
655  DnaDesignDefOPs targeted_dna;
656  mu_tr << "DNA is not being mutated, but alternative bases are allowed, so mutation may occur at a later point, use dna::dna_defs to input positions to mutate in the straightforward manner." << std::endl;
657  utility::vector1< std::string > str_def( option[ OptionKeys::motifs::target_dna_defs ]().vector() );
658  load_dna_design_defs_from_strings( targeted_dna, str_def );
659  } else {
660  mu_tr << "No input given for DNA target positions, will identify target positions based on input motif building positions." << std::endl;
661  }
662 }
663 
664 void
666  core::pose::Pose & pose,
667  protocols::dna::DnaDesignDefOPs const & target
668 )
669 {
670  using namespace protocols::dna;
671  core::pose::PDBPoseMap const & pdb_pose_map( pose.pdb_info()->pdb2pose() );
673  for ( DnaDesignDefOPs::const_iterator def( target.begin() );
674  def != target.end(); ++def ) {
675  // SHOULD INCLUDE JA checks to ensure that the input is DNA and is the correct strand
676  core::Size index( pdb_pose_map.find( (*def)->chain, (*def)->pdbpos ) );
677  if ( ! (*def)->name3.empty() ) {
678  std::string basepairID( (*def)->name3 );
679  //if ( basepairID.length() == 3 ) {
680  if( protocols::dna::dna_full_name3( pose.residue(index).name3() ) != basepairID ) {
681  make_base_pair_mutation( pose, index, core::chemical::aa_from_name( basepairID ) ); //what if it has an X instead of a name3
682  }
683  // } else {
684  // in the future this will end up checking to make sure that it = N or whatever other one-letter identifier you want
685  // mu_tr << "DNA is set to be mutated to multiple DNA bases during the motif search" << std::endl;
686  // }
687  // Actually, cannot add this functionality to this function, because the input from the dna_defs will affect the later steps with design, so I will need to find a new place to add this functionality, probably have to use target_defs if I want something other than simple one-to-one dna mutations to be made
688  } else {
689  mu_tr << "DNA was not mutated because input Def did not include a type!" << std::endl;
690  // Future: DEF Does not include a type, therefore I should mutate later in protocol to all types of bases for the RMSD comparison
691  }
692  }
693 }
694 
697  core::pose::Pose const & pose,
698  protocols::dna::DnaDesignDefOPs const & targets
699 )
700 {
701  using namespace protocols::dna;
702  core::pose::PDBPoseMap const & pdb_pose_map( pose.pdb_info()->pdb2pose() );
704  for ( DnaDesignDefOPs::const_iterator def( targets.begin() );
705  def != targets.end(); ++def ) {
706  core::Size index( pdb_pose_map.find( (*def)->chain, (*def)->pdbpos ) );
707  positions.push_back( index );
708  }
709  return positions;
710 }
711 
714  core::pose::Pose const & pose,
715  protocols::dna::DnaDesignDefOPs const & targets
716 )
717 {
718  using namespace protocols::dna;
719  core::pose::PDBPoseMap const & pdb_pose_map( pose.pdb_info()->pdb2pose() );
721  for ( DnaDesignDefOPs::const_iterator def( targets.begin() );
722  def != targets.end(); ++def ) {
723  core::Size index( pdb_pose_map.find( (*def)->chain, (*def)->pdbpos ) );
725  std::string name( (*def)->name3 );
726  //if name3 something, then names.push_back();
727  if ( name.length() > 1 ) {
728  positions.push_back( std::make_pair( index, names ) );
729  } else if ( name.length() == 1 ) {
730  // this map should maybe go elsewhere (almost certainly)
731  std::map < std::string, utility::vector1< std::string > > degeneracycodes(
732  utility::tools::make_map(
733  std::string("N"), utility::tools::make_vector1( std::string("ADE"), std::string("CYT"), std::string("CYT"), std::string("THY") )
734  ) );
735  names = degeneracycodes[name];
736  positions.push_back( std::make_pair( index, names ) );
737  } else {
738  mu_tr << "All target positions will remain wild-type." << std::endl; // need to make sure code checks that in motif search and really does use wild-type if no other types are considered
739  }
740  }
741  return positions;
742 }
743 
744 // THIS FUNCTION CURRENTLY ISN'T GREAT, WON'T WORK FOR THE BUILDPOS AND MULTIPLE AAs YET
745 std::map< core::Size, std::set< std::string > >
747  core::pose::Pose const & pose,
748  protocols::dna::DnaDesignDefOPs const & targets
749 )
750 {
751  using namespace protocols::dna;
752  core::pose::PDBPoseMap const & pdb_pose_map( pose.pdb_info()->pdb2pose() );
753  std::map< core::Size, std::set< std::string > > positions;
754  for ( DnaDesignDefOPs::const_iterator def( targets.begin() );
755  def != targets.end(); ++def ) {
756  core::Size index( pdb_pose_map.find( (*def)->chain, (*def)->pdbpos ) );
757  std::set< std::string > names;
758  std::string name( (*def)->name3 );
759  if ( name.length() > 1 ) {
760  //positions.push_back( std::make_pair( index, names ) );
761  names.insert( name );
762  } else if ( name.length() == 1 ) {
763  // THIS NEEDS TO BE FIXED FOR SET VERSUS VECTOR1 IF I WANT TO USE IT
764  // this map should maybe go elsewhere (almost certainly)
765  std::map < std::string, utility::vector1< std::string > > degeneracycodes(
766  utility::tools::make_map(
767  std::string("N"), utility::tools::make_vector1( std::string("ADE"), std::string("CYT"), std::string("CYT"), std::string("THY") )
768  ) );
769  //names = degeneracycodes[name];
770  } else {
771  mu_tr << "All target positions will remain wild-type." << std::endl; // need to make sure code checks that in motif search and really does use wild-type if no other types are considered
772  }
773  positions[index] = names;
774  }
775  return positions;
776 }
777 
778 std::map< core::Size, std::set< std::string > >
780  core::pose::Pose const & pose,
781  protocols::dna::DnaDesignDefOPs const & targets
782 )
783 {
784  using namespace protocols::dna;
785  core::pose::PDBPoseMap const & pdb_pose_map( pose.pdb_info()->pdb2pose() );
786  std::map< core::Size, std::set< std::string > > positions;
787  for ( DnaDesignDefOPs::const_iterator def( targets.begin() );
788  def != targets.end(); ++def ) {
789  core::Size index( pdb_pose_map.find( (*def)->chain, (*def)->pdbpos ) );
790  std::set< std::string > names;
791  std::string name( (*def)->name3 );
792  for ( core::Size c(0); c < name.size(); ++c ) {
793  mu_tr << "Allowing AAtype " << name[c] << " for motif search." << std::endl;
794  // put all canonical AAs in it
795  std::stringstream name1;
796  name1 << name[c];
797  if ( name1.str() == "X" ) {
798  utility::vector1< std::string > allAA(utility::tools::make_vector1(std::string("A"), std::string("C"), std::string("D"), std::string("E"), std::string("F"), std::string("H"), std::string("I"), std::string("K"), std::string("L"), std::string("M"), std::string("N"), std::string("P"), std::string("Q"), std::string("R"), std::string("S"), std::string("T"), std::string("V"), std::string("W"), std::string("Y") ) );
799  for( core::Size x(1); x <= allAA.size(); ++x ) {
800  names.insert( name3_from_oneletter( allAA[x] ) );
801  };
802  };
803  std::string name3( name3_from_oneletter( name1.str() ) );
804  names.insert( name3 );
805  if (name3 == "GLY") {
806  mu_tr << "There are no such thing as glycine motifs, check your build_position_defs and remove G" << std::endl;
807  }
808 
809  // This function could be also potentially be converted to take a 3 letter code for some residue type that is not a canonical aa with a 1-letter
810  }
811  positions[index] = names;
812  }
813  return positions;
814 }
815 
818  std::string const & oneletter
819 )
820 {
821  std::map< std::string, std::string > name3_name1( utility::tools::make_map(
822  std::string("A"), std::string("ALA"),
823  std::string("C"), std::string("CYS"),
824  std::string("D"), std::string("ASP"),
825  std::string("E"), std::string("GLU"),
826  std::string("F"), std::string("PHE"),
827  std::string("G"), std::string("GLY"),
828  std::string("H"), std::string("HIS"),
829  std::string("I"), std::string("ILE"),
830  std::string("K"), std::string("LYS"),
831  std::string("L"), std::string("LEU"),
832  std::string("M"), std::string("MET"),
833  std::string("N"), std::string("ASN"),
834  std::string("P"), std::string("PRO"),
835  std::string("Q"), std::string("GLN"),
836  std::string("R"), std::string("ARG"),
837  std::string("S"), std::string("SER"),
838  std::string("T"), std::string("THR"),
839  std::string("V"), std::string("VAL"),
840  std::string("W"), std::string("TRP"),
841  std::string("Y"), std::string("TYR")
842  ) );
843  return name3_name1[ oneletter ];
844 }
845 
848  core::pose::Pose const & pose
849 )
850 {
851  using namespace basic::options;
852  using namespace protocols::dna;
853  utility::vector1< core::Size > motif_build_positions;
854  if ( option[ OptionKeys::motifs::motif_build_defs ].user() ) {
855  DnaDesignDefOPs build_positions; // it's not a DnaDef anymore, since I'm using it for protein . .
856  utility::vector1< std::string > str_def( option[ OptionKeys::motifs::motif_build_defs ]().vector() );
857  load_dna_design_defs_from_strings( build_positions, str_def );
858  motif_build_positions = defs2vector( pose, build_positions );
859  } else {
860  mu_tr << "No build positions specified by user input, will identify build positions based on proximity to target positions" << std::endl;
861  }
862  return motif_build_positions;
863 }
864 
867 {
868  using namespace basic::options;
870  using namespace protocols::dna;
871  if ( option[ OptionKeys::motifs::motif_build_defs ].user() ) {
872  DnaDesignDefOPs build_positions; // it's not a DnaDef anymore, since I'm using it for protein . .
873  utility::vector1< std::string > str_def( option[ OptionKeys::motifs::motif_build_defs ]().vector() );
874  load_dna_design_defs_from_strings( build_positions, str_def );
875  motif_build_positions = build_positions;
876  } else {
877  mu_tr << "No build positions specified by user input, will identify build positions based on proximity to target positions" << std::endl;
878  }
879  return motif_build_positions;
880 }
881 
882 //Ligand motif load_build_position_data
883 //This is a pretty stupid, hacky way to fix the problem. I should just fix the other load_build_position_data with an _optional_ ligand_marker which allows me to divert ligand motifs into conditional statements.
884 void
886  BuildPosition & bp,
887  std::string const & filename,
888  core::pose::Pose & pose,
889  core::Size const
890 )
891 {
892  bool keep_one_motif( true );
893  std::map< std::string, SingleMotifOP > single_motifs;
894  utility::io::izstream data_file( filename.c_str() );
895  std::string key_in;
896  data_file >> key_in;
897  if( key_in == "POSITION" ) {
898  while( data_file >> key_in ) {
899  std::stringstream bpseqpos;
900  bpseqpos << bp.seqpos();
901  if( key_in == bpseqpos.str() ) {
902  std::string key2_in;
903  while( data_file >> key2_in ) {
904  if( key2_in == "POSITION" ) {
905  std::string key3_in;
906  data_file >> key3_in;
907  break;
908  } else if( key2_in == "SINGLE" ) {
909  SingleMotifOP new_motif = single_ligand_motif_from_stream( data_file );
910  if( ! keep_one_motif ) {
911  bp.keep_motif( *new_motif );//best_motifs()->add_to_library( new_motif );
912  } else {
913  single_motifs[ new_motif->remark() ] = new_motif;
914  }
915  } else if( key2_in == "RESIDUE" ) {
916  // std::cout << "Pos2 id: " << key_in << std::endl;
918  rsd = ( single_residue_from_stream( data_file )->clone() );
919  rsd->seqpos( bp.seqpos() );
920  utility::vector1<core::Real> mainchains( pose.residue(bp.seqpos()).mainchain_torsions() );
921  rsd->mainchain_torsions( mainchains );
923  rsd->copy_residue_connections( pose.residue(bp.seqpos()) );
924  bp.keep_rotamer( *rsd );
925  }
926  }
927  break;
928  } else {
929  continue;
930  }
931  }
932  if( keep_one_motif ) {
933  for( std::map< std::string, SingleMotifOP >::iterator mot( single_motifs.begin() ),
934  end( single_motifs.end()); mot != end; ++mot ) {
935  bp.keep_motif( *(mot->second) );
936  }
937  }
938  } else {
939  mu_tr << "This file doesn't have any positions in it" << std::endl;
940  }
941 }
942 
943 void
945  BuildPosition & bp,
946  std::string const & filename,
947  core::pose::Pose & pose
948 )
949 {
950  bool keep_one_motif( true );
951  std::map< std::string, SingleMotifOP > single_motifs;
952  utility::io::izstream data_file( filename.c_str() );
953  std::string key_in;
954  data_file >> key_in;
955  //std::cout << "Pos id: " << key_in << std::endl;
956  if( key_in == "POSITION" ) {
957  while( data_file >> key_in ) {
958  // std::string seqpos = key_in;
959  //data_file >> seqpos;
960  // std::cout << "ASeqpos: " << seqpos << std::endl;
961  std::stringstream bpseqpos;
962  bpseqpos << bp.seqpos();
963  if( key_in == bpseqpos.str() ) {
964  //std::cout << "SEQPOS: " << bpseqpos.str() << std::endl;
965  //std::cout << "SEQPOS: " << key_in << std::endl;
966  std::string key2_in;
967  while( data_file >> key2_in ) {
968  //std::cout << "Pos2 id: " << key_in << std::endl;
969  if( key2_in == "POSITION" ) {
970  std::string key3_in;
971  data_file >> key3_in;
972  // std::cout << "READY TO BREAK ON: " << key2_in << " " << key3_in << std::endl;
973  break;
974  } else if( key2_in == "SINGLE" ) {
975  SingleMotifOP new_motif = single_motif_from_stream( data_file );
976  if( ! keep_one_motif ) {
977  bp.keep_motif( *new_motif );//best_motifs()->add_to_library( new_motif );
978  } else {
979  single_motifs[ new_motif->remark() ] = new_motif;
980  }
981  } else if( key2_in == "RESIDUE" ) {
982  // std::cout << "Pos2 id: " << key_in << std::endl;
984  rsd = ( single_residue_from_stream( data_file )->clone() );
985  rsd->seqpos( bp.seqpos() );
986  //core::conformation::ResidueOP new_rsd( core::conformation::ResidueFactory::create_residue( rsd->type(), *rsd, pose.conformation() ) );
987  utility::vector1<core::Real> mainchains( pose.residue(bp.seqpos()).mainchain_torsions() );
988  rsd->mainchain_torsions( mainchains );
990  rsd->copy_residue_connections( pose.residue(bp.seqpos()) );
991  bp.keep_rotamer( *rsd );
992  }
993  }
994  break;
995  } else {
996  continue;
997  }
998  }
999  if( keep_one_motif ) {
1000  for( std::map< std::string, SingleMotifOP >::iterator mot( single_motifs.begin() ),
1001  end( single_motifs.end()); mot != end; ++mot ) {
1002  bp.keep_motif( *(mot->second) );
1003  }
1004  }
1005  } else {
1006  mu_tr << "This file doesn't have any positions in it" << std::endl;
1007  }
1008 }
1009 
1013 )
1014 {
1017  filename != listnames.end(); ++filename ) {
1018  utility::io::izstream list( (*filename).name().c_str() );
1019  while ( list ) {
1020  std::string name;
1021  list >> name;
1022  names.push_back( name );
1023  }
1024  }
1025  return names;
1026 }
1027 
1028 
1031  utility::io::izstream & residue_info
1032 )
1033 {
1034  std::string resname;
1035  residue_info >> resname;
1036  //std::cout << "READING IN: " << resname << std::endl;
1037  std::string firstline;
1038  getline( residue_info, firstline );
1040  core::Size nlines( rsd->natoms() );
1041  for( core::Size i(1); i <= nlines; ++i ) {
1042  //std::string atomline;
1043  std::string atomname;
1044  residue_info >> atomname;
1045  //getline( residue_info, atomline );
1046  utility::vector1< std::string > atomwords( utility::string_split( atomname, ':' ) );
1047  std::string atomname2( atomwords.front() );
1048  // std::cout << "atomname: " << atomname << std::endl;
1049  // std::cout << "atomname2: " << atomname2 << std::endl;
1050  std::string skip, x, y, z;
1051  if( atomname == atomname2 ) {
1052  residue_info >> skip;
1053  residue_info >> x;
1054  residue_info >> y;
1055  residue_info >> z;
1056  // std::cout << skip << x << y << z << std::endl;
1057  } else {
1058  residue_info >> x;
1059  residue_info >> y;
1060  residue_info >> z;
1061  }
1062  core::Vector atomxyz( utility::string2float(x), utility::string2float(y), utility::string2float(z) );
1063  //numeric::xyzVector atomxyz;
1064 // residueinfo >> atomxyz;
1065  rsd->set_xyz( atomname2, atomxyz );
1066  }
1067 // std::cout << "TESTING\n" << *rsd << std::endl;
1068  return rsd;
1069 }
1070 
1073  core::Size const nres,
1075 )
1076 {
1077  utility::vector1< bool > b( nres, false );
1078  for ( utility::vector1< core::Size >::const_iterator pos= v.begin(), epos= v.end(); pos != epos; ++pos ) b[ *pos ] = true;
1079  return b;
1080 }
1081 
1082 void
1084  core::pose::Pose & pose,
1085  core::Size const seqpos,
1086  core::chemical::AA const & na
1087 )
1088 {
1089 using namespace core::chemical;
1090 using namespace core::conformation;
1091 using namespace core::scoring::dna;
1092 
1093 ResidueTypeSet const & residue_set( pose.residue(1).residue_type_set() );
1094 BasePartner const & partner( retrieve_base_partner_from_pose( pose ) );
1095 
1096 for ( int r=1; r<= 2; ++r ) {
1097  core::Size const pos( r == 1 ? seqpos : partner[seqpos] );
1098  if ( pos == 0 ) continue; // unpaired
1099  AA const aa( r == 1 ? na : protocols::dna::dna_base_partner( na ) );
1100 
1101  Residue const & existing_residue( pose.residue( pos ) );
1102  assert( existing_residue.is_DNA() );
1103 
1104  // search for the matching residue type
1105  ResidueTypeCOPs rsd_types
1106  ( ResidueSelector().set_aa( aa ).match_variants( existing_residue.type() ).select( residue_set ) );
1107  if ( rsd_types.size() != 1 ) {
1108  utility_exit_with_message("couldnt find residuetype for basepair mutation!");
1109  }
1110 
1111  ResidueOP rsd = ResidueFactory::create_residue( *(rsd_types[1]), existing_residue, pose.conformation() );
1112  rsd->set_chi( 1, existing_residue.chi(1) );
1113 
1114  pose.replace_residue( pos, *rsd, false );
1115 }
1116 }
1117 
1118 core::Real
1120  core::conformation::Residue const & rsd1,
1121  core::conformation::Residue const & rsd2,
1122  utility::vector1< core::Size > const & atoms
1123 )
1124 {
1125  using namespace core;
1126  using namespace core::chemical;
1127  using namespace core::conformation;
1128  // Doesn't do automorphisms like original core/scoring/rms_util.cc functions!!
1129  //if( rsd1.type().name3() != rsd2.type().name3() ) utility_exit_with_message("Residue type name3 mismatch");
1130  //if( rsd1.nheavyatoms() != rsd2.nheavyatoms() ) utility_exit_with_message("Residue number-of-heavy-atoms mismatch");
1131  core::Real best_rms = 1e99;
1132  // Make atom-number translation table
1133  core::Real sum2( 0.0 );
1134  core::Size natoms( 0 );
1135  for( core::Size j = 1; j <= atoms.size(); ++j ) {
1136  core::Vector diff = rsd1.xyz( atoms[j] ) - rsd2.xyz( atoms[j] );
1137  sum2 += diff.length_squared();
1138  natoms +=1;
1139  }
1140  core::Real const curr_rms = std::sqrt(sum2 / natoms);
1141 
1142  // Check vs. minimum rmsd
1143  if( curr_rms < best_rms ) {
1144  best_rms = curr_rms;
1145  }
1146  return best_rms;
1147 }
1148 
1149 core::Real
1151  core::conformation::Residue const & rsd1,
1152  core::conformation::Residue const & rsd2,
1153  utility::vector1< std::string > const & atoms
1154 )
1155 {
1156  using namespace core;
1157  using namespace core::chemical;
1158  using namespace core::conformation;
1159  // Doesn't do automorphisms like original core/scoring/rms_util.cc functions!!
1160  //if( rsd1.type().name3() != rsd2.type().name3() ) utility_exit_with_message("Residue type name3 mismatch");
1161  //if( rsd1.nheavyatoms() != rsd2.nheavyatoms() ) utility_exit_with_message("Residue number-of-heavy-atoms mismatch");
1162  core::Real best_rms = 1e99;
1163  // Make atom-number translation table
1164  core::Real sum2( 0.0 );
1165  core::Size natoms( 0 );
1166  for( core::Size j = 1; j <= atoms.size(); ++j ) {
1167  core::Vector diff = rsd1.xyz( atoms[j] ) - rsd2.xyz( atoms[j] );
1168  sum2 += diff.length_squared();
1169  natoms +=1;
1170  }
1171  core::Real const curr_rms = std::sqrt(sum2 / natoms);
1172 
1173  // Check vs. minimum rmsd
1174  if( curr_rms < best_rms ) {
1175  best_rms = curr_rms;
1176  }
1177  return best_rms;
1178 }
1181  core::pose::Pose & pose,
1182  core::Size const rotamer_build_position,
1183  utility::vector1< bool > aa_info,
1184  core::Size const ex_,
1185  bool bump_check
1186 )
1187 {
1188  using namespace core::pack::rotamer_set;
1189  using namespace core::chemical;
1190  using namespace core::scoring;
1191  using namespace core::pack;
1192  using namespace core::pack::task;
1193 
1194  RotamerSetFactory rsf;
1195  RotamerSetOP rotset = rsf.create_rotamer_set( pose.residue( rotamer_build_position ) );
1196  rotset->set_resid( rotamer_build_position );
1197 
1198  // Gather up the many things needed to build rotamers
1199  ScoreFunction scorefxn;
1200  scorefxn.set_weight( fa_atr, 1.00 );
1201  scorefxn.set_weight( fa_rep, 1.00 );
1202 
1204  task->set_bump_check( bump_check );
1205  task->temporarily_fix_everything();
1206  task->temporarily_set_pack_residue( rotamer_build_position, true );
1207 
1208  task->nonconst_residue_task( rotamer_build_position ).restrict_absent_canonical_aas( aa_info );
1209 
1210  //pose.update_residue_neighbors(); //This was necessary before, but let's see if it is now
1211  //task->nonconst_residue_task( rotamer_build_position ).or_include_current( true );
1212  // You can't "include_current" because there is no current or native residue
1213  //task->nonconst_residue_task( rotamer_build_position).or_exrandom_sample_level(core::pack::task::NO_EXTRA_CHI_SAMPLES);
1214  if( ex_ > 0 ) task->nonconst_residue_task( rotamer_build_position ).or_ex1( true );
1215  if( ex_ > 1 ) task->nonconst_residue_task( rotamer_build_position ).or_ex2( true );
1216  if( ex_ > 2 ) task->nonconst_residue_task( rotamer_build_position ).or_ex3( true );
1217  if( ex_ > 3 ) task->nonconst_residue_task( rotamer_build_position ).or_ex4( true );
1218  if( ex_ > 4 ) task->nonconst_residue_task( rotamer_build_position ).or_ex1_sample_level(core::pack::task::EX_FOUR_HALF_STEP_STDDEVS);
1219  if( ex_ > 5 ) task->nonconst_residue_task( rotamer_build_position ).or_ex2_sample_level(core::pack::task::EX_FOUR_HALF_STEP_STDDEVS);
1220  if( ex_ > 6 ) task->nonconst_residue_task( rotamer_build_position ).or_ex3_sample_level(core::pack::task::EX_FOUR_HALF_STEP_STDDEVS);
1221  if( ex_ > 7 ) task->nonconst_residue_task( rotamer_build_position ).or_ex4_sample_level(core::pack::task::EX_FOUR_HALF_STEP_STDDEVS);
1222 
1223  scorefxn( pose );
1224  core::graph::GraphOP packer_neighbor_graph = create_packer_graph( pose, scorefxn, task );
1225 
1226  rotset->build_rotamers( pose, scorefxn, *task, packer_neighbor_graph, false );
1227 
1228  return rotset;
1229 }
1230 
1231 
1232 } // namespace motifs
1233 } // namespace protocols