Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
LigandMotifSearch.cc
Go to the documentation of this file.
1 // -*- mode:c++;tab-width:2;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t -*-
2 // vi: set ts=2 noet:
3 //
4 // (c) Copyright Rosetta Commons Member Institutions.
5 // (c) This file is part of the Rosetta software suite and is made available under license.
6 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
7 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
8 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu
9 
10 /// @file protocols/motifs/LigandMotifSearch.cc
11 /// @brief Ligand motif searching protocol
12 /// @author sthyme (sthyme@gmail.com); mdsmith (mdwsmith@u.washington.edu)
13 
14 // Unit Headers
16 
17 // Package Headers
23 
24 // Project Headers (protocols)
27 // AUTO-REMOVED #include <protocols/dna/RestrictDesignToProteinDNAInterface.hh>
28 #include <protocols/dna/util.hh>
30 
31 // Project Headers
34 #include <core/chemical/AtomType.hh> //Need this to prevent the compiling error: invalid use of incomplete type 'const struct core::chemical::AtomType
35 #include <core/chemical/AtomTypeSet.hh> //Need this to get AtomType integers
37 // AUTO-REMOVED #include <core/chemical/util.hh>
43 // AUTO-REMOVED #include <core/pack/task/TaskFactory.hh>
44 #include <core/io/pdb/pose_io.hh>
46 // AUTO-REMOVED #include <core/kinematics/FoldTree.hh>
47 #include <core/pose/PDBInfo.hh>
48 #include <core/pose/Pose.hh>
49 // AUTO-REMOVED #include <core/scoring/constraints/CoordinateConstraint.hh>
51 // AUTO-REMOVED #include <core/scoring/dna/setup.hh>
52 #include <core/scoring/Energies.hh>
54 // AUTO-REMOVED #include <core/scoring/rms_util.hh>
58 #include <basic/Tracer.hh>
60 
62 // AUTO-REMOVED #include <core/pack/rotamer_set/RotamerSets.hh>
63 #include <core/pose/util.hh>
64 
65 // Utility Headers
66 #include <utility/io/ozstream.hh>
67 // AUTO-REMOVED #include <utility/string_util.hh>
68 #include <utility/file/file_sys_util.hh>
69 
70 #include <numeric/xyzVector.hh>
71 
72 // C++ Headers
73 #include <iostream>
74 
75 // Option Key Includes
76 #include <basic/options/option.hh>
77 // AUTO-REMOVED #include <basic/options/util.hh>
78 // AUTO-REMOVED #include <basic/options/keys/dna.OptionKeys.gen.hh>
79 #include <basic/options/keys/motifs.OptionKeys.gen.hh>
80 
81 #include <utility/vector1.hh>
82 
83 
84 namespace protocols {
85 namespace motifs {
86 
87 static basic::Tracer ms_tr( "protocols.motifs.LigandMotifSearch", basic::t_info );
88 
90 {}
91 
93  : motif_library_(),
94  target_positions_(),
95  build_positionOPs_(0),
96  target_conformers_map_(),
97  // Option flags/parameters: default to command line options
98  ztest_cutoff_1_( basic::options::option[ basic::options::OptionKeys::motifs::z1 ]() ),
99  ztest_cutoff_2_( basic::options::option[ basic::options::OptionKeys::motifs::z2 ]() ),
100  rmsd_cutoff_1_( basic::options::option[ basic::options::OptionKeys::motifs::r1 ]() ),
101  rmsd_cutoff_2_( basic::options::option[ basic::options::OptionKeys::motifs::r2 ]() ),
102  dtest_cutoff_( basic::options::option[ basic::options::OptionKeys::motifs::dtest ]() ),
103  rot_level_( basic::options::option[ basic::options::OptionKeys::motifs::rotlevel ]() ),
104  minimize_( basic::options::option[ basic::options::OptionKeys::motifs::minimize ]() )
105 {
106  init_options();
107 }
108 
110  utility::pointer::ReferenceCount( src )
111 {
112  (*this) = src;
113 }
114 
115 LigandMotifSearch const &
117 {
118  if( this != &src ) {
128  rot_level_ = src.rot_level_ ;
129  minimize_ = src.minimize_;
130  bpdata_ = src.bpdata_;
132  output_ = src.output_;
134  data_ = src.data_;
139  rots2add_ = src.rots2add_;
140  }
141  return *this;
142 }
143 
144 void
146  Pose const & pose,
147  utility::vector1< Size > & input_BPs
148 )
149 {
150  for ( utility::vector1< Size >::const_iterator position( input_BPs.begin() );
151  position != input_BPs.end(); ++position ) {
152  ms_tr << "In run, Design position: " << *position << std::endl;
153  }
154  initialize( pose, input_BPs );
155  incorporate_motifs( pose );
156 }
157 
158 void
160  Pose const & pose,
161  core::Real & ligand_motif_sphere
162 )
163 {
165 
166  utility::io::ozstream motif_output_file;
167 
168  utility::vector1< Size > target_positions_sphere ;
169  target_positions_sphere = get_sphere_aa( pose, ligand_motif_sphere ) ;
170  initialize( pose, target_positions_sphere );
171 
172 //Move functions back down to after open_append if we have problems
173 
174  if( output_ ) {
175  if ( file_exists( output_filename_ ) ) {
176  Pose & pose2 = const_cast< Pose & >( pose );
177  Size const ligand_marker = 0;
178  ms_tr << "Motif search has already run, we will get rotamers from output file" << std::endl;
179  //We already have the output file, let's just take the rotamers from there rather than searching again.
180  for( BuildPositionOPs::const_iterator ir( build_positionOPs_.begin() ), end_ir( build_positionOPs_.end() );
181  ir != end_ir; ++ir ) {
182  load_build_position_data( **ir, output_filename_, pose2, ligand_marker );
183  if( clear_bprots_ ) {
184  // I could avoid adding them in the first place, but that loading function is more complicated than just clearing and I might want them later
185  (*ir)->clear_rots();
186  }
187  }
188  if( ! motif_library_.empty() ) {
189  ms_tr << "Loading BPData, but also loaded a MotifLibrary of all motifs. Probably not a problem for ligand motifs (we will always hit this condition)" << std::endl;
190  }
191 
192  } //If the output file already exists
193  else { //If the output file doesn't already exist, let's find some motifs!
194  ms_tr << "Starting motif search" << std::endl;
195  motif_output_file.open_append( output_filename_ );
196 
197 
198 
199  incorporate_motifs( pose );
200  }
201 
202  } else {
203  //User gave no output file, this is a problem!
204  ms_tr << "You didn't give a -motifs:output filename, but we need that for storage! Please specify a filename." << std::endl;
205 
206  }
207  //This is run for Enzdes, we have no input_BPs
208 }
209 
210 
211 //run as task operation
212 void
214  Pose const & pose,
215  PackerTask & task
216 )
217 {
219 
220  utility::io::ozstream motif_output_file;
221 
223 
224  for(core::Size i=1; i<=pose.total_residue(); ++i) {
225  if (pose.residue(i).is_protein() && task.being_designed(i) ) {
226  target_positions.push_back(i);
227  }
228  }
229 
230  initialize( pose, target_positions );
231 
232  if( output_ ) {
233  if ( file_exists( output_filename_ ) ) {
234  Pose & pose2 = const_cast< Pose & >( pose );
235  Size const ligand_marker = 0;
236  ms_tr << "Motif search has already run, we will get rotamers from output file" << std::endl;
237  //We already have the output file, let's just take the rotamers from there rather than searching again.
238  for( BuildPositionOPs::const_iterator ir( build_positionOPs_.begin() ), end_ir( build_positionOPs_.end() );
239  ir != end_ir; ++ir ) {
240  load_build_position_data( **ir, output_filename_, pose2, ligand_marker );
241  if( clear_bprots_ ) {
242  // I could avoid adding them in the first place, but that loading function is more complicated than just clearing and I might want them later
243  (*ir)->clear_rots();
244  }
245  }
246  if( ! motif_library_.empty() ) {
247  ms_tr << "Loading BPData, but also loaded a MotifLibrary of all motifs. Probably not a problem for ligand motifs (we will always hit this condition)" << std::endl;
248  }
249 
250  } //If the output file already exists
251  else { //If the output file doesn't already exist, let's find some motifs!
252  ms_tr << "Starting motif search" << std::endl;
253  motif_output_file.open_append( output_filename_ );
254 
255 
256 
257  incorporate_motifs( pose );
258  }
259  //OK, we have either loaded motifs from file or we have found them. Now we will add rotamers to task.
260 
261 
262  std::set< core::Size > src_pos;
263 
264 
265  for(core::Size i=1; i<=pose.total_residue(); ++i) {
266  if (pose.residue(i).is_protein() && task.being_designed(i) ) {
267 
268  std::set< std::string > name3set;
269  core::pack::rotamer_set::Rotamers motif_rotamers( bp_rotamers( i ) );
270  src_pos.insert( i );
271  core::pack::rotamer_set::Rotamers variant_rotamers;
272 
273  if ( ! motif_rotamers.empty() ) {
274  ms_tr << "yes, we have motif rotamers for this position!" << std::endl;
275  for( core::Size rot(1); rot <= motif_rotamers.size(); ++rot ) {
276  core::conformation::ResidueOP variant_rot( core::pose::add_variant_type_to_residue( *(motif_rotamers[rot]), core::chemical::SPECIAL_ROT, pose ) ); //This is where we're crashing (original 546)
277  variant_rotamers.push_back( variant_rot );
278 
279  name3set.insert( (motif_rotamers[rot])->name3() );
280  }
281  //rotamer_map[i] = variant_rotamers;
283  ms_rsoop->set_new_rots( variant_rotamers );
284  // taskfactory->push_back( new AppendRotamerSet( ms_rsoop ) );
285  //task.nonconst_residue_task( lig_it->first ).append_rotamerset_operation( rb_rotsetop );
287  } else {
288  ms_tr << "no motif rotamers for this position" << std::endl;
289  } //end else
290  } //end if position is protein and designed
291  } //end protein position loop
292 ///////////////////////////////// END ENZDES TASK OPERATION ///////////////////////////////////////////////
293 
294  } else {
295  //User gave no output file, this is a problem!
296  ms_tr << "You didn't give a -motifs:output filename, but we need that for storage! Please specify a filename." << std::endl;
297 
298  }
299 }
300 
301 void
303  Pose const & pose
304 )
305 {
306 //This is initialize for solo app (not from Enzdes)
307  // Obtain all necessary user input
308  if( motif_library_.empty() ) {
310  MotifCOPs motifcops = motifs.library();
311  motif_library_ = motifcops;
312  } // if it's not empty that means that the app must have filled the motif_library_
315 
316  DnaDesignDefOPs build_position_defs;
317  position_vector_setup( pose );
318 }
319 void
321  Pose const & pose,
322  utility::vector1< Size > & input_BPs
323 )
324 {
325 //This is initialize for solo app (not from Enzdes)
326  // Obtain all necessary user input
327  for ( utility::vector1< Size >::const_iterator position( input_BPs.begin() );
328  position != input_BPs.end(); ++position ) {
329  ms_tr << "In init, Design position: " << *position << std::endl;
330  }
331  if( motif_library_.empty() ) {
333  MotifCOPs motifcops = motifs.library();
334  motif_library_ = motifcops;
335  } // if it's not empty that means that the app must have filled the motif_library_
338 
339  DnaDesignDefOPs build_position_defs;
340  position_vector_setup( pose );
341 
342  if ( ! input_BPs.empty() ) {
343  for( Size i(1); i <= input_BPs.size(); ++i ) {
344  BuildPosition_from_Size( pose, input_BPs[i] );
345  }
346  } else {
347  ms_tr << "Didn't give any BPs, so I'm gonna quit." << std::endl;
348  }
349 }
350 
351 void
353  Pose const & pose
354 )
355 {
356  core::pose::Pose posecopy( pose );
357  core::pose::Pose posecopy2( pose );
358 
359  // Setup output files for motifs and rotamers
360  utility::io::ozstream motif_output_file;
361  utility::io::ozstream data_output_file;
362  utility::io::ozstream qd_output_file;
363  if( output_ ) {
364  motif_output_file.open_append( output_filename_ );
365  }
366  if( data_ ) {
367  data_output_file.open_append( data_filename_ );
368  }
369  if( quick_and_dirty_ ) {
370  std::string motif_filename( pose.pdb_info()->name() );
371  motif_filename.erase( motif_filename.end()-4, motif_filename.end() );
372  std::string qd_output_filename = motif_filename + ".qd_motifs";
373  qd_output_file.open_append( qd_output_filename );
374  }
375 
376  //Here we're going to get triplets from the ligand in the protein which is being searched
377  using namespace core;
378  using namespace ObjexxFCL;
379  using namespace pose;
380  using namespace chemical;
381  using namespace scoring;
382  using namespace optimization;
383 
384  using utility::vector1;
385  int ligand_resi_number = 0;
386  utility::vector1< utility::vector1< Size > > search_lig_triplets;
387 // utility::vector1< utility::vector1< Size > > motif_indices_list;
388  utility::vector1< utility::vector1< utility::vector1< Size > > > motif_indices_list; //Now, instead of having a vector of triplet vectors containing a size for the atom number, change size to vector of size to contain atom number and atomtype size
389  //motif_indices_list[all triplets][atom i/j/k][1 is atom number, 2 is AtomType integer]
391 
392  int nres( pose.total_residue() );
393  for( int lig_pos = 1 ; lig_pos <= nres ; ++lig_pos ) {
394  ResidueType const & lig_type( pose.residue_type( lig_pos ) );
395 
396  if( !lig_type.is_ligand() ) continue;
397  ms_tr << "in ligand splitter block, found my ligand, lig_pos is " << lig_pos << std::endl;
398  ligand_resi_number = lig_pos;
399 // This is to make a ligres object once we find our ligand
400  core::conformation::ResidueOP ligres = new core::conformation::Residue (pose.residue( lig_pos ) );
401 
402 // This is to make an atomtypeset to get atomtype integers
404 
405  for(core::Size atom_i = 1; atom_i <= ligres->natoms(); ++atom_i) {
406 
407  //std::cout << "in atom iterate block, atom num is" << atom_i << std::endl;
408  std::string const atom_name = ligres->atom_name(atom_i);
409  if( ligres->atom_is_hydrogen(atom_i) ) { continue; }
410  //std::cout << "atom name is " << atom_name << std::endl;
411 
412  // This is a for loop to iterate over each atom's connected atoms:
413  core::conformation::Residue::AtomIndices atom_i_connects( ligres->bonded_neighbor( atom_i ) );
414  for(core::Size atom_j = 1; atom_j <= atom_i_connects.size(); ++ atom_j ) {
415  if( ligres->atom_is_hydrogen(atom_i_connects[atom_j]) ) { continue; }
416  // std::cout << "ATOM j: " << atom_i_connects[atom_j] << " Name: " << ligres.atom_name(atom_i_connects[atom_j]) << std::endl;
417 
418  // This is the next for loop to find connects for the second atom, giving us the final atom number (atom k)
419  core::conformation::Residue::AtomIndices atom_j_connects( ligres->bonded_neighbor( atom_i_connects[atom_j] ) );
420  for(core::Size atom_k = 1; atom_k <= atom_j_connects.size(); ++ atom_k ) {
421  if( ligres->atom_is_hydrogen(atom_j_connects[atom_k]) ) { continue; }
422  //std::cout << "ATOM k: " << atom_j_connects[atom_k] << " Name: " << ligres.atom_name(atom_j_connects[atom_k]) << std::endl;
423 
424  chemical::AtomType atom_i_type(ligres->atom_type(atom_i));
425  std::string atom_i_name = atom_i_type.atom_type_name();
426  //Size atom_i_int = atset->atom_type_index(atom_i_name);
427  // std::cout << "ATOM j: " << atom_i << " Name: " << atom_i_name << " Int: " << atom_i_int << std::endl;
428  //
429 
430  //std::cout << "Connected triplet is: " << atom_i << ", type is " << atom_i_name << ", ";
431  //std::cout << atom_i_connects[atom_j] << ", type is " << ligres.atom_type(atom_i_connects[atom_j]).atom_type_name() << ", " ;
432  //std::cout << atom_j_connects[atom_k] << ", type is " << ligres.atom_type(atom_j_connects[atom_k]).atom_type_name() << " " << std::endl;
433  if ( atom_i != atom_j_connects[atom_k] ) {
434 
435  //make the 3 atom vector
436  utility::vector1< utility::vector1< Size > > cur_motif_indices;
437 
438  utility::vector1< Size > atom_i_vector;
439  atom_i_vector.push_back( atom_i );
440  atom_i_vector.push_back( atset->atom_type_index( ligres->atom_type(atom_i).atom_type_name() ) );
441 
442  utility::vector1< Size > atom_j_vector;
443  atom_j_vector.push_back( atom_i_connects[atom_j] );
444  atom_j_vector.push_back( atset->atom_type_index( ligres->atom_type(atom_i_connects[atom_j]).atom_type_name() ) );
445 
446  utility::vector1< Size > atom_k_vector;
447  atom_k_vector.push_back( atom_j_connects[atom_k] );
448  atom_k_vector.push_back( atset->atom_type_index( ligres->atom_type(atom_j_connects[atom_k]).atom_type_name() ) );
449 
450  cur_motif_indices.push_back( atom_i_vector);
451  cur_motif_indices.push_back( atom_j_vector);
452  cur_motif_indices.push_back( atom_k_vector);
453 
454  //check if current index is a duplicate
455  //don't need to do that here, but I forget what code I can delete. I'm just going to change bool assignment.
456 
457  bool current_is_duplicate ( false );
458  if ( !motif_indices_list.empty() ) {
459  for(core::Size cur_motif_check = 1; cur_motif_check <= motif_indices_list.size(); ++ cur_motif_check) {
460  // run a test to see if vectors are identical
461  utility::vector1< utility::vector1< Size > > cur_mainlist_parent ( motif_indices_list[cur_motif_check] );
462  utility::vector1< Size > cur_mainlist;
463  utility::vector1< Size > cur_index;
464  for(core::Size slice_parent = 1; slice_parent <= 3; ++ slice_parent) {
465  cur_mainlist.push_back( cur_mainlist_parent[slice_parent][1] ); }
466  for(core::Size slice_cur = 1; slice_cur <= 3; ++ slice_cur) {
467  cur_index.push_back( cur_motif_indices[slice_cur][1] ); }
468  utility::vector1< Size > sort_from_curindex (cur_index) ;
469  utility::vector1< Size > sort_from_mainlist (cur_mainlist) ;
470  std::sort( sort_from_mainlist.begin(), sort_from_mainlist.end() );
471  std::sort( sort_from_curindex.begin(), sort_from_curindex.end() );
472  if ( sort_from_mainlist[1] == sort_from_curindex[1] && sort_from_mainlist[2] == sort_from_curindex[2] && sort_from_mainlist[3] == sort_from_curindex[3] ) {
473  current_is_duplicate = false;
474  }
475  }
476  }
477  //Making master list to see what's getting pruned with my check
478  all_motif_indices.push_back( cur_motif_indices );
479  //if current index isn't a duplicate, add it to the vector
480  if ( !current_is_duplicate ) {
481  motif_indices_list.push_back( cur_motif_indices );
482  }
483  }
484  }
485  }
486  }
487  std::cout << "Total 3 atoms in unpruned indices list is: " << all_motif_indices.size() << std::endl;
488  for( int prot_pos = 1 ; prot_pos <= nres ; ++prot_pos ) {
489  ResidueType const & prot_type( pose.residue_type( prot_pos ) );
490  if( !prot_type.is_protein() ) continue;
491  if( pose.residue( prot_pos ).name3() == "GLY" ) continue;
492 
493  // map will automatically sort the "contacts" with the lowest total_score at the front of map
494  std::map< Real, Size > contacts;
495  std::map< Real, Size > distance_sorter;
496 
497  // Loop over positions, skipping non-ligand
498  for( int lig_pos = 1 ; lig_pos <= nres ; ++lig_pos ) {
499  ResidueType const & lig_type( pose.residue_type( lig_pos ) );
500 
501  if( !lig_type.is_ligand() ) continue;
502  }
503  }
504  }
505 
506 //////////////////////////////////////////////////////////////////////////////////////////
507 ////////////// end of triplet search for current ligand //////////////////////////////////
508 //////////////////////////////////////////////////////////////////////////////////////////
509 
510 //Now we want to prune the motif library as well as the triplet list.
511 //Few reasons: first, test to see if we have motifs for the current ligand. This is not a given.
512 //Also pruning will speed up considerably. Don't look for motifs from orphan triplets, don't search through unrepresented motifs.
513 
515  // If the BP has motifs in it at this point then they came from an input file from the cmd line
517 
518 //Make new motif library
519  MotifCOPs pruned_motif_library;
520 
521 //Make new triplet list
522 // utility::vector1< utility::vector1< Size > > pruned_indices_list;
523 // std::map< Real, Size > contacts;
524 
525 //For each motif in library
526 
527  for( protocols::motifs::MotifCOPs::iterator motifcop_itr = motif_library.begin(), end_itr = motif_library.end();
528  motifcop_itr != end_itr; ++motifcop_itr ) {
529 
530  protocols::motifs::MotifCOP motifcop( *motifcop_itr );
531  int motif_atom1_int(motifcop->res2_atom1_int());
532  int motif_atom2_int(motifcop->res2_atom2_int());
533  int motif_atom3_int(motifcop->res2_atom3_int());
534 // ms_tr << "Motif atom 1 type: " << motif_atom1_name << "; Motif atom 2 type: " << motif_atom2_name << "; Motif atom 3 type: " << motif_atom3_name << std::endl;
535  //For each triplet in ligand
536  for(core::Size cur_lig_trip = 1; cur_lig_trip <= motif_indices_list.size(); ++ cur_lig_trip) {
537  int ligand_atom1_int(motif_indices_list[cur_lig_trip][1][2]);
538  int ligand_atom2_int(motif_indices_list[cur_lig_trip][2][2]);
539  int ligand_atom3_int(motif_indices_list[cur_lig_trip][3][2]);
540  // ms_tr << "Motif types: " << motif_atom1_int << " " << motif_atom2_int << " " << motif_atom3_int << ", Ligand types: " << ligand_atom1_int << " " << ligand_atom2_int << " " << ligand_atom3_int << " " << std::endl;
541  //Check to see if match
542 // ms_tr << "Checking if match..." << std::endl;
543  if (
544  motif_atom1_int == ligand_atom1_int && motif_atom2_int == ligand_atom2_int && motif_atom3_int == ligand_atom3_int ) {
545 //also OK if it's reversed
546  // ms_tr << "It's a match!" << std::endl;
547  //also add motif to new motif library
548  pruned_motif_library.push_back(motifcop);
549  break;
550  }
551 
552  //If match, add motif to new library, and also add triplet to new triplet list
553  } // end ligand triplet iteration
554  } // end library iteration
555  ms_tr << "Unpruned motifs: " << motif_library.size() << std::endl;
556  Size motif_library_size = pruned_motif_library.size();
557  Size motif_percent_chunk;
558  double double_chunk = std::floor( (double) motif_library_size / 10 ) ; // REQUIRED FOR WINDOWS
559  motif_percent_chunk = Size ( double_chunk );
560  //Size next_motif_percent = motif_percent_chunk;
561  ms_tr << "Pruned motifs: " << motif_library_size << std::endl;
562 
563 ///////////////////////////////////////////////////////////////////////////
564 /////////////////// done with pruning, ready to search! ///////////////////
565 ///////////////////////////////////////////////////////////////////////////
566 
567  // for every protein backbone position (motif build position)
568  for( BuildPositionOPs::const_iterator ir( build_positionOPs_.begin() ), end_ir( build_positionOPs_.end() );
569  ir != end_ir; ++ir ) {
570  Size motif_counter=0;
571  Size motif_percent=0;
572  Size next_motif_percent = motif_percent_chunk;
573 
574  Size trip_atom_1;
575  Size trip_atom_2;
576  Size trip_atom_3;
577  // Map of all of the very best residues for each amino acid type, to make sure I don't add 2,000 Args and only 2 Tyrs
578  std::map< std::string, std::map< Real, MotifHitOP > > best_mhits_all;
579 
580  // If we have rotamers coming in from files and they weren't cleared in initialization, then the search won't happen on this BuildPosition
581  if ( ! ((*ir)->best_rotamers()).empty() ) continue;
582  ms_tr << "WORKING ON PROTEIN POSITION " << (*ir)->seqpos() << std::endl;
583  ms_tr << "NATIVE AA IS " << pose.residue( (*ir)->seqpos() ).name3() << std::endl;
584 
585 //Setting up rmsd list
586  std::map< Real, std::string > rmsd_list;
587 
588 
589  MotifCOPs bp_best_motifs( (*ir)->best_motifs() );
590  core::pack::rotamer_set::Rotamers bp_best_rotamers( (*ir)->best_rotamers() );
591  // Need to clear the best_rotamers and best_motifs before I collect new ones
592  (*ir)->clear_data();
593 
594  Size seqpos( (*ir)->seqpos() );
595  std::stringstream firstline;
596  firstline << "POSITION " << seqpos;
597  if( output_ ) {
598  motif_output_file << firstline.str() << "\n";
599  }
600  if( data_ ) {
601  data_output_file << firstline.str() << "\n";
602  }
603  if( quick_and_dirty_ ) {
604  qd_output_file << firstline.str() << "\n";
605  }
606 
607 
608  std::map< core::Size, core::pack::rotamer_set::RotamerSetOP > rotamer_sets;
609  if( bp_best_rotamers.empty() ) {
610  for( Size i(1); i <= core::chemical::num_canonical_aas; ++i ) {
612  aa_info[i] = true;
613  bool bump_yes( true );
614  //need to make this an option
615  core::pack::rotamer_set::RotamerSetOP rotset = build_rotamers_lite( posecopy, seqpos, aa_info, rot_level_, bump_yes );
616  rotamer_sets[i] = rotset;
617  }
618  } else {
619  Size bp_rots( bp_best_rotamers.size() );
620  for( Size i(1); i <= core::chemical::num_canonical_aas; ++i ) {
622  core::pack::rotamer_set::RotamerSetOP rotset = rsf.create_rotamer_set( posecopy.residue((*ir)->seqpos()) );
623  for( Size r(1); r <= bp_rots; ++r ) {
624  if( bp_best_rotamers[r]->name3() == core::chemical::name_from_aa(core::chemical::AA(i)) ) {
625  rotset->add_rotamer( *((bp_best_rotamers)[r]) );
626  }
627  }
628  rotamer_sets[i] = rotset;
629  }
630  }
631 
632  // For every motif in the motif_library_
633  for( protocols::motifs::MotifCOPs::const_iterator motifcop_itr = pruned_motif_library.begin(), end_itr = pruned_motif_library.end();
634  motifcop_itr != end_itr; ++motifcop_itr ) {
635  ++motif_counter;
636  if ( motif_counter == next_motif_percent ) {
637  next_motif_percent = motif_percent_chunk + next_motif_percent ;
638  motif_percent = 10 + motif_percent;
639  ms_tr << "On motif number: " << motif_counter << " and we are " << motif_percent << "% through library" << std::endl;
640 
641 
642  }
643  // WARNING: everything in this code assumes that residue 1 in the motif is the protein position and residue 2 is the dna
644  bool passed_quick_and_dirty(false);
645  protocols::motifs::MotifCOP motifcop( *motifcop_itr );
646  //ms_tr << "WORKING ON MOTIF: " << motifcop->remark() << std::endl;
647 
648  // The BuildPosition may at some point have the ability to restrict ahead of time
649  // currently I am not sure how to get restrictions from resfiles and so on . . .
650  // it may not be an issue because there are ways other than resfiles, such as the defs for protein positions
651  // and the main reason I would want this functionality is for homology models and theoretically the input pose
652  // should already have all of the position types set as wild-type and be relaxed and minimized
653  std::set< std::string > allowedtypes( (*ir)->allowed_types() );
654 
655  // Tighter cutoffs for residues with 3 and 4 chi angles
659  if( (motifcop->restype_name1() == "ARG") && ( ! quick_and_dirty_ ) ) {
660  rmsd_cutoff_1 = (rmsd_cutoff_1 / 2.0 );
661  rmsd_cutoff_2 = (rmsd_cutoff_2 / 2.0 );
662  dtest_cutoff = (dtest_cutoff / 2.0 );
663  }
664  if( ( (motifcop->restype_name1() == "MET") || (motifcop->restype_name1() == "LYS") || (motifcop->restype_name1() == "GLU") || (motifcop->restype_name1() == "GLN") ) && ( ! quick_and_dirty_ ) ) {
665  rmsd_cutoff_1 = (rmsd_cutoff_1 / 1.33 );
666  rmsd_cutoff_2 = (rmsd_cutoff_2 / 1.33 );
667  dtest_cutoff = (dtest_cutoff / 1.33 );
668  }
669  //utility::vector1< std::string > atoms;
670  /*
671  // Atoms required for the parallel base test
672  // maybe these vectors should be stored as a part of this class?
673  // for non-DNA motif searches I won't be using the z-test at all
674  if( protocols::dna::dna_full_name3( motifcop->restype_name2() ) == "GUA" || protocols::dna::dna_full_name3( motifcop->restype_name2() ) == "ADE" ) {
675  atoms.push_back("C5");
676  atoms.push_back("C6");
677  atoms.push_back("N3");
678  atoms.push_back("C2");
679  atoms.push_back("N1");
680  atoms.push_back("C4");
681  } else if( protocols::dna::dna_full_name3( motifcop->restype_name2() ) == "CYT" || protocols::dna::dna_full_name3( motifcop->restype_name2() ) == "THY" ) {
682  atoms.push_back("C5");
683  atoms.push_back("C4");
684  atoms.push_back("N1");
685  atoms.push_back("C2");
686  atoms.push_back("N3");
687  atoms.push_back("C6");
688  } else {
689  ms_tr << "Residue you are planning to do parallel base test with is not a DNA base!" << std::endl;
690  }
691  */ //commented out parallel base test--doesn't work for ligands
692  bool automorphism(false);
693  bool passed_automorphism(false);
694  if(
695  motifcop->restype_name1() == "ASP" ||
696  motifcop->restype_name1() == "GLU" ||
697  motifcop->restype_name1() == "PHE" ||
698  motifcop->restype_name1() == "LEU" ||
699  motifcop->restype_name1() == "ARG" ||
700  motifcop->restype_name1() == "TYR" ||
701  motifcop->restype_name1() == "VAL"
702  ) {
703  automorphism = true;
704  }
705 
706  // Related to only using motifs that include an allowed amino acid at the BuildPosition
707  // At this point the allowedtypes is always going to be empty
708  bool allowed(false);
709  if( allowedtypes.empty() ) {
710  allowed = true;
711  }
712  for( std::set< std::string >::const_iterator ir2(allowedtypes.begin() ), end_ir2( allowedtypes.end() );
713  ir2 != end_ir2; ++ir2 ) {
714  if( (*ir2) == motifcop->restype_name1() ) {
715  allowed = true;
716  }
717  }
718  if( ! allowed ) continue;
719 
720  // Create a standard dna base of type in motif
721  // For ligand motifs we will need to create a residue of the type we are trying to target
722  // Since there won't be a second residue in the motif
723  // restype_name2() will need to be set to something in the motif?
724  std::string basetype( motifcop->restype_name2() );
725  // If there are conformers
726  core::conformation::ResidueOPs DNAResidueOPs( target_conformers_map_[basetype] );
727  //core::conformation::ResidueOPs LigandResidueOPs( target_conformers_map_[basetype]);
728  bool noconformers( false );
729  if( DNAResidueOPs.empty() ) {
730  noconformers = true;
731  }
733  // Get the rotamer set with type matching motif at the motif build position
734  core::pack::rotamer_set::RotamerSetOP rotset = rotamer_sets[ core::chemical::aa_from_name(motifcop->restype_name1()) ];
735 
736  Real final(100);
737  std::pair< core::conformation::ResidueOP, core::conformation::ResidueOP > bestpair;
738  bool b_bestpair( false );
739  Size rs1( rotset->num_rotamers() );
740 
741  Real rmsdtest_ir2(100.0);
742 
743  // This atom type is only C1* because that atom is common
744  // to all DNA bases and it is basically in the plane of the base
745  // Right now we're looking at a motif -- we don't have triplet yet. Don't place because maybe nothing in common (need to do test once we're in triplet loop).
746 
747  // Important in case of the very strange situation where more than one
748  // target_position is close enough to pass the tests
749  bool tftest(false);
751  Real test(1000);
752 // Used to iterate over target_positions, now we will iterate over triplets in current ligand
753  Sizes target_positions( (*ir)->target_positions() );
754 
755 
756  //utility::vector1< utility::vector1< utility::vector1< Size > > > motif_indices_list; //Now, instead of having a vector of triplet vectors containing a size for the atom number, change size to vector of size to contain atom number and atomtype size
757  //motif_indices_list[all triplets][atom i/j/k][1 is atom number, 2 is AtomType integer]
758  for( utility::vector1< utility::vector1< utility::vector1< Size > > >::const_iterator curtrip( motif_indices_list.begin() ), end( motif_indices_list.end() ); //prof II
759  curtrip != end; ++curtrip ) {
760 
761  //before: bpos now: curtrip
762  //bpos was DNA build position
763  // std::set< std::string > allowed_types( target_positions_[*bpos] ); nonsensical now
764  // Should have a test to ensure that it has the atom types I'll be using?
765  // At this point, I know what my triplet is, and I know what my motif is--let's se if they match. Otherwise, we'll continue to the next triplet.
766  utility::vector1< utility::vector1< Size > > deref_trip( *curtrip );
767  core::conformation::ResidueOP check_ligand = ligres;
768  int motif_atom1_int(motifcop->res2_atom1_int());
769  int motif_atom2_int(motifcop->res2_atom2_int());
770  int motif_atom3_int(motifcop->res2_atom3_int());
771  //For each triplet in ligand
772  int ligand_atom1_int( deref_trip[1][2]);
773  int ligand_atom2_int( deref_trip[2][2]);
774  int ligand_atom3_int( deref_trip[3][2]);
775  //Check to see if match
776  if (
777  motif_atom1_int == ligand_atom1_int && motif_atom2_int == ligand_atom2_int && motif_atom3_int == ligand_atom3_int )
778  //not OK if it's reversed--we'll find it because we don't prune ligand triplets
779  {
780  //std::cout << "Motif atom 1 type: " << motif_atom1_name << "; Motif atom 2 type: " << motif_atom2_name << "; Motif atom 3 type: " << motif_atom3_name << std::endl;
781  //std::cout << "Lig atom 1 type: " << ligand_atom1_name << "; Lig atom 2 type: " << ligand_atom2_name << "; Lig atom 3 type: " << ligand_atom3_name << std::endl;
782  // ms_tr << "It's a match! (INSIDE LOOPS NOW)" << std::endl;
783  } else {
784  continue;
785  }
786 
787 
788  //Instead of parallel base test, let's check the similarity of the motifs. A1-A2-A3, B1-B2-B3. Compare D(A1,A2)~=D(B1,B2); D(A2,A3)~=D(B2,B3); Angle(A1-A2-A3)~=Angle(B1-B2-B3)
789  //These tests will uniquely specify the three atoms on either side, and so they will show us if the motif and triplet are a match.
790  //Want 0.3 A agreement between distances
791  //Want 30 degree agreement between angles
792  //Can tighten later if needed
793  //Turns out this is a real bitch to code, not going to do it until later -Matt
794  /* numeric::xyzVector motif_vector();
795  numeric::xyzVector ligand_vector();
796  //For each atom in motif triplet
797  // Vector const res2_C = res2.xyz( "C" );
798  // Vector const motif_atom1_xyz( motifcop->forward_jump() );
799 
800  //For each atom in ligand triplet
801  // Vector const ligand_atom1_xyz( check_ligand.atom_type(deref_trip[1]).atom_type_name() );
802 
803  ligand_vector += check_ligand.xyz( deref_trip[1]) ;
804  ligand_vector += check_ligand.xyz( deref_trip[2]) ;
805  ligand_vector += check_ligand.xyz( deref_trip[3]) ;
806 
807  Real ligand_distance_AB( check_ligand.xyz( deref_trip[1] ).distance( check_ligand.xyz( deref_trip[2] ) ) );
808  Real ligand_distance_BC( check_ligand.xyz( deref_trip[2] ).distance( check_ligand.xyz( deref_trip[3] ) ) );
809  // src/numeric/xyzTriple.hh: angle_of( xyzTriple const & a, xyzTriple const & b )
810 
811  */
812 
813  //We are looping over the rotamer set here. Matt put the rotamer loop here so that we wouldn't be checking motif/triplet matching for every rotamer--that would take forever!
814  for( Size ir2(1); ir2 <= rs1; ++ir2 ) { //rotamer loop
815 
816  //Used to be before this loop, now put it here because we didn't know which atom to place yet
817  core::conformation::Atom atm( check_ligand->atom( deref_trip[2][1] ) );
818  core::conformation::Atom auto_atm( check_ligand->atom( deref_trip[2][1] ) );
819 
820  Size trip_atom_1(deref_trip[1][1]);
821  Size trip_atom_2(deref_trip[2][1]);
822  Size trip_atom_3(deref_trip[3][1]);
823  //utility::vector1< Size > atoms = new utility::vector1< Size >( {trip_atom_1, trip_atom_2, trip_atom_3} );
824  //Size myatoms[] = {trip_atom_1, trip_atom_2, trip_atom_3};
826  atoms.push_back(trip_atom_1);
827  atoms.push_back(trip_atom_2);
828  atoms.push_back(trip_atom_3);
829 
830 // motifcop->place_atom( *(rotset->nonconst_rotamer(ir2)), *check_ligand, atm, trip_atom_1, trip_atom_2, trip_atom_3, atm_str ); //prof II
831  motifcop->place_atom( *(rotset->nonconst_rotamer(ir2)), *check_ligand, atm, trip_atom_1, trip_atom_2, trip_atom_3, trip_atom_2 );
832  if( automorphism ) {
833  motifcop->place_atom( *(rotset->nonconst_rotamer(ir2)), *check_ligand, auto_atm, trip_atom_1, trip_atom_2, trip_atom_3, trip_atom_2, false ); //the false just flips the placement
834  }
835 
836 
837  Real dtest1( atm.xyz().distance( posecopy.residue( ligand_resi_number ).xyz( deref_trip[2][1] ) ) );
838 // For dtest1, we are getting the distance from the motif base which has already been placed to the DNA base in the build. This is very similar to what we're going
839  Real dtest1_auto(100);
840  if( automorphism ) {
841  dtest1_auto = ( auto_atm.xyz().distance( posecopy.residue( ligand_resi_number ).xyz( deref_trip[2][1] ) ) );
842 
843 
844  //ms_tr << "RMSD between ligand resi (rosetta #) " << ligand_resi_number << " and motif ligand = " << dtest1 << " dtestauto is " << dtest1_auto << " for residue type " << motifcop->restype_name1() << ", rotamer # " << ir2 << ", motif named " << motifcop->remark() << std::endl;
845  }
846 
847  if( ! automorphism ) {
848  if( dtest1 > dtest_cutoff ) continue;
849  } else {
850  if( dtest1 > dtest_cutoff && dtest1_auto > dtest_cutoff ) continue;
851  if( dtest1 < dtest_cutoff && dtest1_auto < dtest_cutoff ) {
852  if( dtest1_auto < dtest1 ) {
853  passed_automorphism = true;
854  } else {
855  passed_automorphism = false;
856  }
857  } else if( dtest1_auto < dtest_cutoff ) {
858  passed_automorphism = true;
859  } else {
860  passed_automorphism = false;
861  }
862  } //All of these tests are good, we'll keep for ligand motifs
863 
864  // ms_tr << "Passed first round tests on 712: RMSD between ligand resi (rosetta #) " << ligand_resi_number << " and motif ligand = " << dtest1 << " dtestauto is " << dtest1_auto << " for residue type " << motifcop->restype_name1() << ", rotamer # " << ir2 << ", motif named " << motifcop->remark() << std::endl;
865 
866  core::conformation::ResidueOP posebase = new core::conformation::Residue( posecopy.residue( ligand_resi_number ) );
867  if( passed_automorphism ) {
868 // rmsd_list[dtest1_auto] = motifcop->restype_name1() ; //(ADD TO THE MAP)
869  motifcop->place_atoms( *(rotset->nonconst_rotamer(ir2)), *posebase, atoms, trip_atom_1, trip_atom_2, trip_atom_3, false );
870  } else {
871 // rmsd_list[dtest1] = motifcop->restype_name1() ; //(ADD TO THE MAP)
872  motifcop->place_atoms( *(rotset->nonconst_rotamer(ir2)), *posebase, atoms, trip_atom_1, trip_atom_2, trip_atom_3 );
873  }
874 
875  if( quick_and_dirty_ ) {
876  qd_output_file << *motifcop;
877  passed_quick_and_dirty = true;
878  break;
879  }
880  Real rmsdtest = atom_specific_rms( *posebase, posecopy.residue(ligand_resi_number), atoms );
881  if( rmsdtest > rmsd_cutoff_1 ) continue;
882  // ms_tr << "at 779, RMSD cutoff is " << rmsd_cutoff_1 << " and rmsd is " << rmsdtest << std::endl;
883  //ms_tr << "Passed 728! " << std::endl;
884 
885  rmsdtest_ir2 = rmsdtest;
886  if( rmsdtest < test ) {
887  test = rmsdtest;
888  bestpos = deref_trip;
889  posecopy2 = posecopy;
890  tftest = true;
891  } // if( rmsdtest < test )
892  if( passed_quick_and_dirty ) break;
893 
894  if( passed_quick_and_dirty ) break;
895  if( ! tftest ) continue;
896  //ms_tr << "Passed 741! " << std::endl;
897 
898  MotifHitOP motifhit = new MotifHit( *motifcop, ligand_resi_number, passed_automorphism );
899 
900  // If there are no conformers will use the base from the pose, so rmsd can be 0 theoretically
901  if( noconformers ) {
902  core::conformation::ResidueOP posebase2 = new core::conformation::Residue( posecopy2.residue( ligand_resi_number ) );
903  if( passed_automorphism ) {
904  motifcop->place_residue(*(rotset->nonconst_rotamer(ir2)), *posebase2,trip_atom_1, trip_atom_2, trip_atom_3 , false );
905  } else {
906  motifcop->place_residue(*(rotset->nonconst_rotamer(ir2)), *posebase2,trip_atom_1, trip_atom_2, trip_atom_3 );
907  }
908  Real rmsdtest2 = rmsdtest;
909  //Real rmsdtest2 = core::scoring::automorphic_rmsd( *posebase2, posecopy2.residue(ligand_resi_number), false );
910  Real finaltest = ( ( rmsdtest2) );
911  //std::cout << "FINAL: " << finaltest << std::endl;
912  //std::cout << "cutoff: " << rmsd_cutoff_2 << " ir2 " << rmsdtest_ir2 << std::endl;
913  //NOTE: Do I want to keep any statistics about percentages of passing certain cutoffs??
914  //ms_tr << "Passed 755! " << std::endl;
915  if( (rmsdtest_ir2 < rmsd_cutoff_2) ) {
916  //ms_tr << "adding to map, RMSD cutoff is " << rmsd_cutoff_2 << " and rmsdtest is " << rmsdtest_ir2 << std::endl;
917  rmsd_list[rmsdtest_ir2] = motifcop->restype_name1() ; //(ADD TO THE MAP)
918  //ms_tr << "Passed 757! RMSD between DNA resi (rosetta #), no conformers " << ligand_resi_number << " and motif DNA = " << rmsdtest_ir2 << " and combined score = " << finaltest << " for residue type " << motifcop->restype_name1() << ", rotamer # " << ir2 << ", motif named " << motifcop->remark() << std::endl;
919  if( data_ ) {
920  data_output_file << "Passed 759! RMSD between DNA resi (rosetta #), no conformers " << ligand_resi_number << " and motif DNA = " << rmsdtest_ir2 << " and combined score = " << finaltest << " for residue type " << motifcop->restype_name1() << ", rotamer # " << ir2 << ", motif named " << motifcop->remark() << std::endl;
921  }
922  motifhit->final_test( finaltest );
923  motifhit->build_rotamer( *(rotset->nonconst_rotamer(ir2) ) );
924  motifhit->target_conformer( *posebase2 );
925  best_mhits_all[motifcop->restype_name1()][finaltest] = motifhit->clone();
926  if ( finaltest < final ) {
927  b_bestpair = true;
928  bestpair = std::make_pair( (rotset->nonconst_rotamer(ir2))->clone(), posebase2->clone() );
929  final = finaltest;
930  }
931  } // if passed the second round of tests
932  } else {
933  for( core::conformation::ResidueOPs::const_iterator resop( DNAResidueOPs.begin() ), end( DNAResidueOPs.end() );
934  resop != end; ++resop ) {
935  if( passed_automorphism ) {
936  motifcop->place_residue(*(rotset->nonconst_rotamer(ir2)), **resop, trip_atom_1, trip_atom_2, trip_atom_3 , false );
937  } else {
938  motifcop->place_residue(*(rotset->nonconst_rotamer(ir2)), **resop,trip_atom_1, trip_atom_2, trip_atom_3 );
939  }
940  Real rmsdtest2 = rmsdtest;
941  //Real rmsdtest2 = core::scoring::automorphic_rmsd( **resop, posecopy2.residue(ligand_resi_number), false );
942  if( rmsdtest2 > rmsd_cutoff_2 ) continue;
943  Real finaltest = ( ( rmsdtest2 * 100 ) );
944  Real finaltestc = ( ( rmsdtest_ir2 * 100 ) );
945  //NOTE: Do I want to keep any statistics about percentages of passing certain cutoffs??
946  //ms_tr << "Passed 784! " << std::endl;
947  if( (rmsdtest2 < rmsd_cutoff_2) ) {
948  rmsd_list[rmsdtest2] = motifcop->restype_name1() ; //(ADD TO THE MAP)
949  // ms_tr << "at 843, adding to map, RMSD cutoff is " << rmsd_cutoff_2 << " and rmsdtest is " << rmsdtest_ir2 << std::endl;
950  //ms_tr << "Passed 781! RMSD between DNA resi (rosetta #) " << ligand_resi_number << " and motif DNA = " << rmsdtest2 << " and combined score = " << finaltest << " for residue type " << motifcop->restype_name1() << ", rotamer # " << ir2 << ", motif named " << motifcop->remark() << std::endl;
951  if( data_ ) {
952  data_output_file << "Passed 783! RMSD between DNA resi (rosetta #) " << ligand_resi_number << " and motif DNA = " << rmsdtest2 << " and combined score = " << finaltest << " for residue type " << motifcop->restype_name1() << ", rotamer # " << ir2 << ", motif named " << motifcop->remark() << std::endl;
953  }
954  motifhit->final_test( finaltest );
955  motifhit->build_rotamer( *(rotset->nonconst_rotamer(ir2) ) );
956  motifhit->target_conformer( **resop );
957  best_mhits_all[motifcop->restype_name1()][finaltestc] = motifhit->clone();
958  if ( finaltest < final ) {
959  b_bestpair = true;
960  bestpair = std::make_pair( (rotset->nonconst_rotamer(ir2))->clone(), (*resop)->clone() );
961  final = finaltest;
962  }
963  } // if conformer passed the second round of tests
964  } // loop over conformers
965  } // if not noconfomers
966  } // loop over first rotamer set
967  } // loop over triplets in current ligand
968 
969  // Dump the best rotamer and conformer pair for each motif, mainly for debugging purposes
970  if( dump_motifs_ ) {
971  if( b_bestpair ) {
972  core::pose::Pose pose_dump2;
973  pose_dump2.append_residue_by_jump( *(bestpair.second), 1);
974  pose_dump2.append_residue_by_jump( *(bestpair.first), 1);
975  std::stringstream pose2_name_full;
976  if( passed_automorphism ) {
977  pose2_name_full << "Test_auto_" << motifcop->restype_name2()[0] << "_" << (*ir)->seqpos() << motifcop->restype_name1() << "_" << motifcop->remark() << ".pdb";
978  } else {
979  pose2_name_full << "Test_" << motifcop->restype_name2()[0] << "_" << (*ir)->seqpos() << motifcop->restype_name1() << "_" << motifcop->remark() << ".pdb";
980  }
981  core::io::pdb::dump_pdb( pose_dump2, pose2_name_full.str() );
982  }
983  }
984  }
985  if( ! best_mhits_all.empty() ) {
986  core::pose::Pose pose_dump( pose );
987  for( std::map< std::string, std::map< Real, MotifHitOP > >::const_iterator bh( best_mhits_all.begin() ),
988  end( best_mhits_all.end() ); bh != end; ++bh ) {
989  Size hits = 0;
990  for( std::map< Real, MotifHitOP >::const_iterator bh2( (bh->second).begin() ),
991  end2( (bh->second).end() ); bh2 != end2; ++bh2 ) {
992  MotifHitOP motifhitop( bh2->second );
993  if( ! minimize_ ) {
994  (*ir)->keep_rotamer( *(motifhitop->build_rotamer()) );
995  ++hits;
996  if( hits > rots2add_ ) break;
997  } else {
998  using namespace core::scoring;
999  // Need a copy of the pose to generate the constraints
1000  // Maybe there's a way to rewrite the constraint making code to avoid this?
1001  // No, because the minimize itself needs the residues to be a part of the pose?
1002  // Or maybe instead of copying the pose you could save the residue you are replacing and replace it back?
1003  //core::pose::Pose pose_dump( pose );
1004  core::conformation::ResidueOP build_rotamer = new core::conformation::Residue( *(motifhitop->build_rotamer()) );
1005  pose_dump.replace_residue( (*ir)->seqpos(), *build_rotamer, false );
1006  // The residue is probably already placed . . .
1007  // if( passed_automorphism ) {
1008  // motifcop->place_residue( motifhitop->build_rotamer(), motifhitop->target_conformer(), false );
1009  // } else {
1010  // motifcop->place_residue( motifhitop->build_rotamer(), motifhitop->target_conformer() );
1011  // }
1012  if ( protocols::dna::dna_full_name3( pose_dump.residue(motifhitop->vbpos()).name3() ) != protocols::dna::dna_full_name3( (motifhitop->target_conformer())->name3() ) ) {
1013  make_base_pair_mutation( pose_dump, motifhitop->vbpos(), core::chemical::aa_from_name( protocols::dna::dna_full_name3( motifhitop->target_conformer()->name3() ) ) );
1014  }
1015  if( motifhitop->passed_automorphism() ) {
1016  (motifhitop->motifcop())->place_residue( pose_dump.residue( motifhitop->vbpos() ), *build_rotamer, trip_atom_1, trip_atom_2, trip_atom_3 , false );
1017  } else {
1018  (motifhitop->motifcop())->place_residue( pose_dump.residue( motifhitop->vbpos() ), *build_rotamer, trip_atom_1, trip_atom_2, trip_atom_3 );
1019  //Place_residue wants (fixed, mobile, ...)
1020  }
1021  /*core::pose::Pose pose_dump2( pose );
1022  pose_dump2.replace_residue( (*ir)->seqpos(), *build_rotamer, false );
1023  std::stringstream pose2_name_full;
1024  std::stringstream pose_name_full;
1025  std::stringstream pose3_name_full;
1026  pose2_name_full << "AfterReplace_" << bh2->first << ".pdb";
1027  pose_name_full << "BeforeReplace_" << bh2->first << ".pdb";
1028  pose3_name_full << "AfterMinBeforeReplace_" << bh2->first << ".pdb";
1029  core::io::pdb::dump_pdb( pose_dump2, pose2_name_full.str() );
1030  core::io::pdb::dump_pdb( pose_dump, pose_name_full.str() );*/
1031 
1033  add_motif_sc_constraints( sc_cst_set, pose_dump, (*ir)->seqpos(), *build_rotamer, motifhitop->motifcop(), false );
1034  //add_motif_sc_constraints( sc_cst_set, pose_dump2, (*ir)->seqpos(), *build_rotamer, motifhitop->motifcop(), false );
1036  methods::EnergyMethodOptions options( score_fxn->energy_method_options() );
1037  score_fxn->set_energy_method_options( options );
1038  score_fxn->set_weight( coordinate_constraint, 10.0 );
1039  pose_dump.constraint_set( sc_cst_set );
1040  //pose_dump2.constraint_set( sc_cst_set );
1041  //core::Real pre_sc_constraint_check( pose_dump.energies().total_energies()[ coordinate_constraint ] );
1042  //core::Real pre_sc_constraint_check2( pose_dump2.energies().total_energies()[ coordinate_constraint ] );
1043  //ms_tr << "Before sidechain refinement constraints score is " << pre_sc_constraint_check << std::endl;
1044  //ms_tr << "2Before sidechain refinement constraints score is " << pre_sc_constraint_check2 << std::endl;
1045  /*if( data_ ) {
1046  data_output_file << "Before sidechain refinement constraints score is " << pre_sc_constraint_check << std::endl;
1047  }*/
1049  movemap->set_chi( (*ir)->seqpos(), true );
1050  protocols::simple_moves::MinMoverOP minmover = new protocols::simple_moves::MinMover( movemap, score_fxn, "dfpmin_armijo_nonmonotone_atol", 0.000001, true );
1051  minmover->apply( pose_dump );
1052  //core::io::pdb::dump_pdb( pose_dump, pose3_name_full.str() );
1053  core::Real sc_constraint_check( pose_dump.energies().total_energies()[ coordinate_constraint ] );
1054  ms_tr << "After sidechain refinement constraints score is " << sc_constraint_check << std::endl;
1055  /*if( data_ ) {
1056  data_output_file << "After sidechain refinement constraints score is " << sc_constraint_check << std::endl;
1057  }*/
1058  /*if( sc_constraint_check < 10.0 && sc_constraint_check < pre_sc_constraint_check ) {
1059  (*ir)->keep_rotamer( (pose_dump.residue((*ir)->seqpos())) );
1060  ++hits;
1061  if( output_ ) {
1062  motif_output_file << *(motifhitop->motifcop());
1063  motif_output_file << "RESIDUE " << (pose_dump.residue((*ir)->seqpos()));
1064  }
1065  } else if( pre_sc_constraint_check < 10.0 && sc_constraint_check > pre_sc_constraint_check ) {
1066  pose_dump.replace_residue( (*ir)->seqpos(), *(motifhitop->build_rotamer()), true );
1067  (*ir)->keep_rotamer( (pose_dump.residue((*ir)->seqpos())) );
1068  ++hits;
1069  if( output_ ) {
1070  motif_output_file << *(motifhitop->motifcop());
1071  motif_output_file << "RESIDUE " << (pose_dump.residue((*ir)->seqpos()));
1072  }
1073  }*/
1074 
1075  } //Here is end of minimize code block, get rid of it eventually
1076 
1077  pose_dump.replace_residue( (*ir)->seqpos(), *(motifhitop->build_rotamer()), true );
1078  (*ir)->keep_rotamer( (pose_dump.residue((*ir)->seqpos())) );
1079  if( output_ ) {
1080 
1081  motif_output_file << *(motifhitop->motifcop());
1082  motif_output_file << "RESIDUE " << (pose_dump.residue((*ir)->seqpos()));
1083  }
1084  if( hits > rots2add_ ) break;
1085  }
1086  }
1087  }
1088 
1089 
1090 //print out placed motifs by RMSD
1091 
1092  ms_tr << "RMSD, amino acid" << std::endl;
1093  for( std::map< Real, std::string >::const_iterator rmsd_it( rmsd_list.begin() ), end( rmsd_list.end() ); rmsd_it != end; ++rmsd_it ) {
1094  ms_tr << rmsd_it->first << ", " << rmsd_it->second << std::endl;
1095 
1096  }
1097  }
1098  if( output_ ) {
1099  motif_output_file.close();
1100  }
1101  if( data_ ) {
1102  data_output_file.close();
1103  }
1104  if( quick_and_dirty_ ) {
1105  qd_output_file.close();
1106  }
1107 }
1108 
1111 {
1112  core::pack::rotamer_set::Rotamers best_rotamers;
1113  for ( BuildPositionOPs::const_iterator ir( build_positionOPs_.begin() ), end_ir( build_positionOPs_.end() );
1114  ir != end_ir; ++ir ) {
1115  if ( ! ((*ir)->best_rotamers()).empty() ) {
1116  best_rotamers = (*ir)->best_rotamers();
1117  }
1118  }
1119  return best_rotamers;
1120 }
1123  Size const seqpos
1124 )
1125 {
1126  core::pack::rotamer_set::Rotamers best_rotamers;
1127  for ( BuildPositionOPs::const_iterator ir( build_positionOPs_.begin() ), end_ir( build_positionOPs_.end() );
1128  ir != end_ir; ++ir ) {
1129  if( (*ir)->seqpos() != seqpos ) continue;
1130  if ( ! ((*ir)->best_rotamers()).empty() ) {
1131  best_rotamers = (*ir)->best_rotamers();
1132  } else {
1133  ms_tr << "There were no rotamers to be included for position " << seqpos << std::endl;
1134  }
1135  }
1136  return best_rotamers;
1137 }
1138 
1139 // Maybe this belongs with Motif.cc or MotifLibrary.cc, or both, but not here
1140 bool
1142 {
1143  using namespace core::chemical;
1144  // This function only works for a motif that is made up of only two residues
1145  bool protein_dna( false );
1146  // motif_library_ has to be filled with the input MotifLibrary before you can call this fxn
1147  if ( ! motif_library_.empty() ) {
1148  // Check to see if motif has a protein component and a dna component
1149  //THIS IS RIDICULOUS, DON'T MAKE RESIDUES, MAKE RESIDUE TYPE FROM NAME3
1152  if ( ( res1->is_protein() && res2->is_DNA() ) || ( res2->is_protein() && res1->is_DNA() ) ) {
1153  protein_dna = true;
1154  }
1155  } else {
1156  ms_tr << "MotifLibrary has not been initialized yet, cannot yet identify the type of motifs being used, assuming protein-DNA with possible disastrous consequences." << std::endl;
1157  protein_dna = true;
1158  }
1159  return protein_dna;
1160 }
1161 
1162 // Will make this more general! Should keep the chains separate
1163 // Maybe make a map of vectors, keeping track of the different chains
1164 void
1166  Pose const & pose
1167 )
1168 {
1169  for ( Size i(1), end( pose.total_residue() ); i <= end; ++i ) {
1170  if ( pose.residue_type(i).is_protein() ) {
1171  protein_positions_.push_back(i);
1172  }
1173  if ( pose.residue_type(i).is_DNA() ) {
1174  dna_positions_.push_back(i);
1175  }
1176  }
1177 }
1178 
1179 void
1181  Pose const & pose,
1182  utility::vector1< Size > & build_positions
1183 )
1184 {
1185  if ( protein_dna_motif() ) {
1186  protein_DNA_motif_build_positions_JA( pose, build_positions, dna_positions_ ); //could easily change this line to take one of Phil's DNA interface fxns that also fills a vector
1187  } else {
1188  ms_tr << "ERROR! These motifs are not protein-DNA, need to add another else if statement that allows for a different type of interface finding function." << std::endl;
1189  }
1190 }
1191 
1192 
1195  Pose const & pose,
1196  core::Real cut1
1197 )
1198 {
1199 //This is where Matt will put enzdes sphere finding function to make build_position list
1200  using namespace core;
1201  using namespace ObjexxFCL;
1202  using namespace pose;
1203  using namespace chemical;
1204  using namespace scoring;
1205  using namespace optimization;
1206  int nres( pose.total_residue() );
1207  // std::cout << "In get_sphere_aa, about to find ligand " << std::endl;
1208  std::set< core::Size > interface_target_res;
1209  for( int lig_pos = 1 ; lig_pos <= nres ; ++lig_pos ) {
1210  ResidueType const & lig_type( pose.residue_type( lig_pos ) );
1211  // std::cout << "In get_sphere_aa, made res type, aa number is " << lig_pos << std::endl;
1212 
1213  if( lig_type.is_ligand() ) {
1214  ms_tr << "in get_sphere_aa, found my ligand, lig_pos is " << lig_pos << std::endl;
1215  interface_target_res.insert( lig_pos) ;
1216  }
1217  }
1218  utility::vector1< core::Size > sphere_resi;
1219 
1220  {
1221 
1222  core::Real cut2 = cut1 + 1;
1223  core::Real cut3 = cut2 + 1;
1224  core::Real cut4 = cut3 + 1;
1225  core::Real cut1_sq = cut1 * cut1;
1226  core::Real cut2_sq = cut2 * cut2;
1227  core::Real cut3_sq = cut3 * cut3;
1228  core::Real cut4_sq = cut4 * cut4;
1229 
1230  for( std::set< core::Size >::const_iterator targ_it( interface_target_res.begin()),targ_end(interface_target_res.end());
1231  targ_it != targ_end; ++targ_it ) {
1232 
1233  // on protein side, have to do distance check
1234  core::conformation::Residue const & targ_rsd = pose.residue( *targ_it );
1235  core::Size targ_res_atom_start = 1;
1236  if( targ_rsd.is_protein() ) {
1237  targ_res_atom_start = targ_rsd.first_sidechain_atom();
1238  }
1239 
1240  for(core::Size i = 1, i_end = pose.total_residue(); i <= i_end; ++i) {
1241  core::conformation::Residue const & prot_rsd = pose.residue(i);
1242  for(core::Size k = targ_res_atom_start, k_end = targ_rsd.nheavyatoms(); k <= k_end; ++k) {
1243  core::Vector prot_cb, prot_ca;
1244  if( prot_rsd.has("CB") ) prot_cb = prot_rsd.xyz("CB");
1245  if( prot_rsd.has("CA") ) prot_ca = prot_rsd.xyz("CA"); // GLY
1246  core::Real ca_dist2 = targ_rsd.xyz(k).distance_squared( prot_ca );
1247  if( ca_dist2 <= cut4_sq ) {
1248  if( ca_dist2 <= cut3_sq ) {
1249  if( ca_dist2 <= cut2_sq ) {
1250  if( ca_dist2 <= cut1_sq) {
1251  sphere_resi.push_back(i);
1252  break;
1253  } // cut1
1254  else if( prot_rsd.has("CB") ) {
1255  core::Real cb_dist2 = targ_rsd.xyz(k).distance_squared( prot_cb );
1256  // tr.Info << "cb_dist2 is " << cb_dist2 << "; ";
1257  if( cb_dist2 < ca_dist2 ) {
1258  sphere_resi.push_back(i);
1259  break;
1260  }
1261  } // end of non-gly residues
1262  else if ( prot_rsd.has("2HA") ) { //glycine doesn't have a CB, so use 2HA to get position where CB would be
1263  // use the name "cb" to describe the 2HA atom; design if 2HA < CA
1264  prot_cb = prot_rsd.xyz("2HA");
1265  core::Real cb_dist2 = targ_rsd.xyz(k).distance_squared( prot_cb );
1266  if( cb_dist2 < ca_dist2 ) { // 2HA is closer than CA
1267  sphere_resi.push_back(i);
1268  break;
1269  }
1270  } // end of gly residues
1271  else { // Exception handling case for residue without CB or 2HA
1272  ms_tr << "Weird residue without CB or 2HA. Watch out! Residue: " << i << std::endl;
1273  break;
1274  } // end of exception catching for neither CB nor 2HA
1275  } //cut2
1276  } //cut3
1277  } //cut4
1278  } //loop over target res atoms
1279  } //loop over protein residues
1280  } //loop over target residues
1281 
1282  ms_tr << "Finished sphere check ok" << std::endl;
1283 
1284  } //find_design_interface
1285 
1286  return sphere_resi;
1287 } // get_sphere_aa function
1288 
1289 /*
1290 void
1291 LigandMotifSearch::fill_bp_allowed_types(
1292  Pose const & pose,
1293  Size const seqpos,
1294  std::set< std::string > & allowed_types
1295 )
1296 {
1297  // This doesn't work for some reason . . .
1298  // Not quite sure how to do it, so that it knows about resfile restrictions
1299  core::pack::task::TaskFactoryOP tf = new core::pack::task::TaskFactory;
1300  tf->push_back( new core::pack::task::ReadResfileOperation );//new protocols::dna::RestrictDesignToProteinDNAInterface );
1301  core::pack::task::PackerTaskOP task( tf->create_task_and_apply_taskoperations( pose ) );
1302  for( core::pack::task::ResidueLevelTask::ResidueTypeCOPListConstIter
1303  allowed_iter = task->residue_task( seqpos ).allowed_residue_types_begin(),
1304  allowed_end = task->residue_task( seqpos ).allowed_residue_types_end();
1305  allowed_iter != allowed_end; ++allowed_iter ) {
1306  std::cout << ' ' << (*allowed_iter)->name3();
1307  }
1308  std::cout << std::endl;
1309 }
1310 */
1311 
1312 void
1314  Pose const & pose
1315 )
1316 {
1317  Sizes positions(0);
1318  if ( protein_dna_motif() ) {
1320  protein_DNA_motif_build_positions_JA( pose, positions, target_positions );
1321  for ( Sizes::const_iterator pos( positions.begin() ), end( positions.end() );
1322  pos != end; ++pos ) {
1323  Size seqpos(*pos);
1324  Sizes short_target_positions( shorten_target_list( pose, seqpos, target_positions ) );
1325  std::set< std::string > allowed_types; // this vector will remain empty in this sitatuation since there is no input Def to limit the types of amino acids allowed
1326  //fill_bp_allowed_types( pose, seqpos, allowed_types );
1327  BuildPositionOP build_position = new BuildPosition( seqpos, short_target_positions, allowed_types );
1328  build_positionOPs_.push_back( build_position );
1329  }
1330  } else {
1331  ms_tr << "ERROR! These motifs are not protein-DNA, need to add another else if statement that allows for a different type of interface finding function." << std::endl;
1332  }
1333 }
1334 
1335 void
1337  Pose const & pose,
1338  Size const input_BP
1339 )
1340 {
1342  Sizes short_target_positions( shorten_target_list( pose, input_BP, target_positions ) );
1343  std::set< std::string > allowed_types; // this set will remain empty in this sitatuation since there is no input Def to limit the types of amino acids allowed
1344  // MAKE ANOTHER FUNCTION THAT FILLS ALLOWED_TYPES VIA CHECKING WHAT IS ALLOWED
1345  //fill_bp_allowed_types( pose, input_BP, allowed_types );
1346  BuildPositionOP build_position = new BuildPosition( input_BP, short_target_positions, allowed_types );
1347  build_positionOPs_.push_back( build_position );
1348 }
1349 
1350 void
1352  Pose const & pose,
1353  DnaDesignDefOPs const & defs
1354 )
1355 {
1356  if ( protein_dna_motif() ) {
1357  Sizes full_tl( map2keyvector( target_positions_ ) );
1358  std::map< Size, std::set< std::string > > mappositions( defs2map( pose, defs ) );
1359  for ( std::map<Size, std::set< std::string > >::const_iterator it( mappositions.begin() ),
1360  end( mappositions.end() ); it != end; ++it ) {
1361  BuildPositionOP build_position = new BuildPosition( it->first, full_tl, it->second );
1362  build_positionOPs_.push_back( build_position );
1363  }
1364  } else {
1365  ms_tr << "ERROR! These motifs are not protein-DNA, need to add another else if statement that allows for a different type of interface finding function." << std::endl;
1366  }
1367 }
1368 
1369 void
1371  Pose const & pose,
1372  DnaDesignDefOPs const & defs
1373 )
1374 {
1375  if ( protein_dna_motif() ) {
1376  Sizes full_tl( map2keyvector( target_positions_ ) );
1377  std::map< Size, std::set< std::string > > mappositions( defs2map( pose, defs ) );
1378  for ( std::map<Size, std::set< std::string > >::const_iterator it( mappositions.begin() ),
1379  end( mappositions.end() ); it != end; ++it ) {
1380  Size test(it->first);
1381  Sizes short_tl( shorten_target_list( pose, test, full_tl ) );
1382  BuildPositionOP build_position = new BuildPosition( it->first, short_tl, it->second );
1383  build_positionOPs_.push_back( build_position );
1384  }
1385  } else {
1386  ms_tr << "ERROR! These motifs are not protein-DNA, need to add another else if statement that allows for a different type of interface finding function." << std::endl;
1387  }
1388 }
1389 
1392  std::map< Size, std::set< std::string > > mappositions
1393 )
1394 {
1395  Sizes positions(0);
1396  for ( std::map<Size, std::set< std::string > >::const_iterator it( mappositions.begin() ),
1397  end( mappositions.end() ); it != end; ++it ) {
1398  positions.push_back( it->first );
1399  }
1400  return positions;
1401 }
1402 
1405  Pose const & pose,
1406  Size const bp,
1407  Sizes & full_tl
1408 )
1409 {
1410  Sizes short_tl(0);
1411  Sizes bps(0);
1412  bps.push_back( bp );
1413  protein_DNA_motif_target_positions_JA( pose, bps, full_tl, short_tl );
1414  return short_tl;
1415 }
1416 
1417 void
1419  Pose const & pose,
1420  Sizes & build_positions,
1422 )
1423 {
1424  protocols::dna::DnaInterfaceFinderOP interface = new protocols::dna::DnaInterfaceFinder( 10*10, 3.9*3.9, 6., true ); //how does the z_axis cutoff work here that JA uses, I looked up once, but need ot read again
1425  if ( ! target_positions.empty() ) { // again, this won't work well if there are multiple target positions in vector
1426  interface->determine_protein_interface( pose, protein_positions_, target_positions ); // unless target_positions_ is empty - will actually deal with that later, will fill with all DNA in initialize if no protein pos or dna pos are given
1427  protocols::dna::DnaNeighbors protein_neighbors = interface->protein_neighbors();
1428  for ( protocols::dna::DnaNeighbors::const_iterator itr( protein_neighbors.begin() ),
1429  end( protein_neighbors.end() ); itr != end; ++itr ) {
1430  if ( (*itr).second.contact() ) {
1431  build_positions.push_back( itr->first );
1432  ms_tr << "Positions being targeted for motif design " << itr->first << std::endl;
1433  }
1434  }
1435 // ms_tr << "Attempting to identify build positions when there are no target positions." << std::endl;
1436  }
1437 }
1438 
1439 void
1441  Pose const & pose,
1442  Sizes & build_positions,
1444  Sizes & short_tl
1445 )
1446 {
1447  // JA used 3.7, I picked 3.9 to access a position I knew was important
1448  protocols::dna::DnaInterfaceFinderOP interface = new protocols::dna::DnaInterfaceFinder( 10*10, 3.9*3.9, 10., true ); //how does the z_axis cutoff work here that JA uses, I looked up once, but need ot read again
1449  if ( ! build_positions.empty() ) {
1450  interface->determine_dna_interface( pose, build_positions, target_positions );
1451  protocols::dna::DnaNeighbors dna_neighbors = interface->dna_neighbors();
1452  for ( protocols::dna::DnaNeighbors::const_iterator itr( dna_neighbors.begin() ),
1453  end( dna_neighbors.end() ); itr != end; ++itr ) {
1454  if ( (*itr).second.contact() ) {
1455  short_tl.push_back( itr->first );
1456  ms_tr << "Positions (DNA) being targeted for motif design " << itr->first << std::endl;
1457  }
1458  }
1459 // ms_tr << "Attempting to identify build positions when there are no target positions." << std::endl;
1460  }
1461 }
1462 
1463 void
1465  Real const & r1,
1466  Real const & z1,
1467  Real const & r2,
1468  Real const & z2,
1469  Real const & d1,
1470  Size const & rlevel
1471 )
1472 {
1473  ztest_cutoff_1_ = z1;
1474  ztest_cutoff_2_ = z2;
1475  rmsd_cutoff_1_ = r1;
1476  rmsd_cutoff_2_ = r2;
1477  dtest_cutoff_ = d1;
1478  rot_level_ = rlevel;
1479 }
1480 
1481 void
1483 {
1484  ztest_cutoff_1_ = basic::options::option[ basic::options::OptionKeys::motifs::z1 ]();
1485  ztest_cutoff_2_ = basic::options::option[ basic::options::OptionKeys::motifs::z2 ]();
1486  rmsd_cutoff_1_ = basic::options::option[ basic::options::OptionKeys::motifs::r1 ]();
1487  rmsd_cutoff_2_ = basic::options::option[ basic::options::OptionKeys::motifs::r2 ]();
1488  dtest_cutoff_ = basic::options::option[ basic::options::OptionKeys::motifs::dtest ]();
1489  rot_level_ = basic::options::option[ basic::options::OptionKeys::motifs::rotlevel ]();
1490 }
1491 
1492 void
1494  MotifLibrary & motiflibrary
1495 )
1496 {
1497  for( protocols::motifs::MotifCOPs::const_iterator motifcop_itr = motiflibrary.begin(), end_itr = motiflibrary.end();
1498  motifcop_itr != end_itr; ++motifcop_itr ) {
1499  protocols::motifs::MotifCOP motifcop( *motifcop_itr );
1500  motif_library_.push_back( motifcop );
1501  }
1502 }
1503 
1504 // should probably be a private fxn, so should other ones . . . need to organize code
1505 void
1507 {
1508  if( basic::options::option[ basic::options::OptionKeys::motifs::BPData ].user() ) {
1509  bpdata_ = true;
1510  bpdata_filename_ = basic::options::option[ basic::options::OptionKeys::motifs::BPData ]();
1511  } else {
1512  bpdata_ = false;
1513  }
1514  if( basic::options::option[ basic::options::OptionKeys::motifs::output_file ].user() ) {
1515  output_filename_ = basic::options::option[ basic::options::OptionKeys::motifs::output_file ]();
1516  output_ = true;
1517  } else {
1518  output_ = false;
1519  }
1520  if( basic::options::option[ basic::options::OptionKeys::motifs::data_file ].user() ) {
1521  data_filename_ = basic::options::option[ basic::options::OptionKeys::motifs::data_file ]();
1522  data_ = true;
1523  } else {
1524  data_ = false;
1525  }
1526  if( (basic::options::option[ basic::options::OptionKeys::motifs::quick_and_dirty ]).user() ) {
1527  quick_and_dirty_ = true;
1528  } else {
1529  quick_and_dirty_ = false;
1530  }
1531  if( (basic::options::option[ basic::options::OptionKeys::motifs::dump_motifs ]).user() ) {
1532  dump_motifs_ = true;
1533  } else {
1534  dump_motifs_ = false;
1535  }
1536  if( basic::options::option[ basic::options::OptionKeys::motifs::clear_bprots ].user() ) {
1537  clear_bprots_ = true;
1538  } else {
1539  clear_bprots_ = false;
1540  }
1541  if( basic::options::option[ basic::options::OptionKeys::motifs::rots2add ].user() ) {
1542  rots2add_ = basic::options::option[ basic::options::OptionKeys::motifs::rots2add ]();
1543  } else {
1544  rots2add_ = 100;
1545  }
1546 }
1547 
1548 } // motifs
1549 } // protocols