Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ResidueTypeSet.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 ResidueTypeSet.cc
11 ///
12 /// @brief
13 /// ResidueTypeSet class
14 ///
15 /// @details
16 /// This class is responsible for iterating through the sets of residue types, including, but not limited to, amino
17 /// acids, nucleic acids, peptoid residues, and monosaccharides. It first reads through a file that contains the
18 /// location of residue types in the database. At the beginning of that file are the atom types, mm atom types,
19 /// element sets, and orbital types that will be used. The sets are all for fa_standard. If a new type of atom are
20 /// added for residues, this is where they would be added. Once it assigns the types, it then reads in extra residue
21 /// params that are passed through the command line. Finally, patches are applied to all residues added.
22 ///
23 ///
24 /// @author
25 /// Phil Bradley
26 /// Steven Combs - these comments
27 /////////////////////////////////////////////////////////////////////////
28 
29 
30 // Rosetta headers
32 #include <core/chemical/Patch.hh>
34 
35 //XRW_B_T1
36 /*
37 // Commented by inclean daemon #include <core/coarse/Translator.hh>
38 #include <core/coarse/TranslatorSet.hh>
39 #include <core/coarse/Rules.hh>
40 */
41 //XRW_E_T1
42 
45 
46 // Basic headers
47 #include <basic/database/open.hh>
48 #include <basic/options/option.hh>
49 #include <utility/io/izstream.hh>
50 #include <basic/Tracer.hh>
51 
52 // Utility headers
53 #include <utility/file/FileName.hh>
54 
55 
56 // C++ headers
57 #include <fstream>
58 #include <string>
59 #include <sstream>
60 #include <set>
61 #include <algorithm>
62 
63 // option key includes
64 #include <basic/options/keys/packing.OptionKeys.gen.hh>
65 #include <basic/options/keys/pH.OptionKeys.gen.hh>
66 #include <basic/options/keys/chemical.OptionKeys.gen.hh>
67 #include <basic/options/keys/in.OptionKeys.gen.hh>
69 
70 // Boost Headers
71 #include <boost/foreach.hpp>
72 
73 #include <utility/vector1.hh>
74 #define foreach BOOST_FOREACH
75 
76 
77 namespace core {
78 namespace chemical {
79 
80 static basic::Tracer tr("core.chemical.ResidueTypeSet");
81 
82 ///////////////////////////////////////////////////////////////////////////////
83 /// @brief c-tor from directory
85  std::string const & name,
86  std::string const & directory,
87  std::vector< std::string > const & extra_res_param_files, // defaults to empty
88  std::vector< std::string > const & extra_patch_files // defaults to empty
89 ) :
90  name_( name ),
91  database_directory_(directory)
92 {
93  using namespace basic::options;
94 
95  //XRW_B_T1
96  //coarse::RuleSetOP coarsify_rule_set;
97  //XRW_E_T1
98  ResidueTypeSetCAP fine_res_set;
99  // read ResidueTypes
100  {
101  AtomTypeSetCAP atom_types;
102  ElementSetCAP elements;
103  MMAtomTypeSetCAP mm_atom_types;
104  orbitals::OrbitalTypeSetCAP orbital_types;
105  //CSDAtomTypeSetCAP csd_atom_types; kwk commenting out until there are fully implemented
106 
107  std::string const list_filename( directory + "residue_types.txt" );
108  utility::io::izstream data( list_filename.c_str() );
109  if ( !data.good() ) {
110  utility_exit_with_message( "Unable to open file: " + list_filename + '\n' );
111  }
112  std::string line,tag;
113  while ( getline( data,line) ) {
114  // Skip empty lines and comments.
115  if ( line.size() < 1 || line[0] == '#' ) continue;
116 
117  // kp don't consider files for protonation versions of the residues if flag pH_mode is not used
118  // to make sure even applications that use ResidueTypeSet directly never run into problems
119  bool no_proton_states = false;
120  if ( line.size() > 20 ){
121  if ( ( !basic::options::option[ basic::options::OptionKeys::pH::pH_mode ].user() ) &&
122  ( line.substr (14,6) == "proton" ) ) {
123  no_proton_states = true;
124  }
125  }
126  if ( no_proton_states ) continue;
127 
128  // Skip carbohydrate ResidueTypes unless included with include_sugars flag.
129  if ((!option[OptionKeys::in::include_sugars]) &&
130  (line.substr(0, 27) == "residue_types/carbohydrates")) {
131  continue;
132  }
133 
134  // Parse lines.
135  std::istringstream l( line );
136  l >> tag;
137  if ( tag == "ATOM_TYPE_SET" ) {
138  l >> tag;
139  atom_types = ChemicalManager::get_instance()->atom_type_set( tag );
140  } else if ( tag == "ELEMENT_SET" ) {
141  l >> tag;
142  elements = ChemicalManager::get_instance()->element_set( tag );
143  } else if ( tag == "MM_ATOM_TYPE_SET" ) {
144  l >> tag;
145  mm_atom_types = ChemicalManager::get_instance()->mm_atom_type_set( tag );
146  } else if(tag == "ORBITAL_TYPE_SET"){
147  l >> tag;
148  orbital_types = ChemicalManager::get_instance()->orbital_type_set(tag);
149  // kwk commenting out until the CSD_ATOM_TYPE_SET has been fully implemented
150  //} else if ( tag == "CSD_ATOM_TYPE_SET" ) {
151  // l >> tag;
152  // csd_atom_types = ChemicalManager::get_instance()->csd_atom_type_set( tag );
153  //XRW_B_T1
154  /*
155  } else if ( tag == "COARSE_RULE" ) {
156  l >> tag; // the ruleset
157  coarsify_rule_set = new coarse::RuleSet(tag);
158  l >> tag; // the fine residue set
159  fine_res_set = ChemicalManager::get_instance()->residue_type_set( tag );
160  */
161  //XRW_E_T1
162  } else {
163  std::string const filename( directory + line );
164 
165  ResidueTypeOP rsd_type( read_topology_file( filename, atom_types, elements, mm_atom_types, orbital_types, this ) ); //, csd_atom_types ) );
166 
167  //kwk commenting out csd_atom_types until they have been fully implemented
168  residue_types_.push_back( rsd_type );
169  }
170  }
171 
172  foreach(std::string filename, extra_res_param_files){
173  ResidueTypeOP rsd_type( read_topology_file( filename, atom_types, elements, mm_atom_types, orbital_types, this ) ); //, csd_atom_types ) );
174  // kwk commenting out csd atom types until they have been fully implemented
175  if(basic::options::option[ basic::options::OptionKeys::in::add_orbitals]){
176  orbitals::AssignOrbitals add_orbitals_to_residue(rsd_type);
177  add_orbitals_to_residue.assign_orbitals();
178  }
179  residue_types_.push_back( rsd_type );
180  }
181 
183  }
184 
185  // now apply patches
186  {
187  std::string const list_filename( directory+"/patches.txt" );
188  utility::io::izstream data( list_filename.c_str() );
189 
190  if ( !data.good() ) {
191  utility_exit_with_message( "Unable to open patch list file: "+list_filename );
192  }
193 
194  // Read the command line and avoid applying patches that the user has requested be
195  // skipped. The flag allows the user to specify a patch by its name or by its file.
196  // E.g. "SpecialRotamer" or "SpecialRotamer.txt". Directory names will be ignored if given.
197  std::set< std::string > patches_to_avoid;
198  if ( basic::options::option[ basic::options::OptionKeys::chemical::exclude_patches ].user() ) {
199  utility::vector1< std::string > avoidlist = basic::options::option[ basic::options::OptionKeys::chemical::exclude_patches ];
200  for ( Size ii = 1; ii <= avoidlist.size(); ++ii ) {
201  utility::file::FileName fname( avoidlist[ ii ] );
202  patches_to_avoid.insert( fname.base() );
203  }
204  }
205 
206  utility::vector1< std::string > patch_filenames(extra_patch_files);
207  // Unconditional loading of listed patches is deliberate - if you specified it explicitly, you probably want it to load.
208  std::string line;
209  while ( getline( data,line) ) {
210  if ( line.size() < 1 || line[0] == '#' ) continue;
211 
212  // Skip this patch if the "patches_to_avoid" set contains the named patch.
213  utility::file::FileName fname( line );
214  if ( patches_to_avoid.find( fname.base() ) != patches_to_avoid.end() ) {
215  tr << "While generating ResidueTypeSet " << name << ": Skipping patch " << fname.base() << " as requested" << std::endl;
216  continue;
217  }
218  patch_filenames.push_back( directory + line );
219  }
220 
221  //kdrew: include list allows patches to be included while being commented out in patches.txt, useful for testing non-canonical patches.
222  //tr << "include_patches activated? " << basic::options::option[ basic::options::OptionKeys::chemical::include_patches ].active() << std::endl;
223  if ( basic::options::option[ basic::options::OptionKeys::chemical::include_patches ].active() ) {
224  utility::vector1< std::string > includelist = basic::options::option[ basic::options::OptionKeys::chemical::include_patches ];
225  for ( Size ii = 1; ii <= includelist.size(); ++ii ) {
226  utility::file::FileName fname( includelist[ ii ] );
227  patch_filenames.push_back( directory + includelist[ ii ]);
228  tr << "While generating ResidueTypeSet " << name << ": Including patch " << fname << " as requested" << std::endl;
229  }
230  }
231 
232 
233  apply_patches( patch_filenames );
234  }
235 
236  // Generate combinations of adducts as specified by the user
237  place_adducts();
238 
239  if(basic::options::option[ basic::options::OptionKeys::in::add_orbitals]){
240  for( Size ii = 1 ; ii <= residue_types_.size() ; ++ii ) {
241  orbitals::AssignOrbitals add_orbitals_to_residue(residue_types_[ii]);
242  add_orbitals_to_residue.assign_orbitals();
243  }
244  }
245 
246 
247 // for( Size ii = 1 ; ii <= residue_types_.size() ; ++ii ) {
248 // residue_types_[ii]->debug_dump_icoor();
249 // }
250 
251 //XRW_B_T1
252 /*
253  if ( coarsify_rule_set ) {
254  coarsifier_ = new coarse::TranslatorSet(*coarsify_rule_set, fine_res_set, this);
255  }
256 */
257 //XRW_E_T1
258 
259  tr << "Finished initializing " << name << " residue type set. Created " << residue_types_.size() << " residue types" << std::endl;
260 }
261 
262 
264 
265 
267 
268 ///////////////////////////////////////////////////////////////////////////////
269 /// @details the file contains a list of names of residue type parameter files
270 /// stored in the database path
271 ///
272 void
274  std::string const & list_filename,
275  AtomTypeSetCAP atom_types,
276  ElementSetCAP elements,
277  MMAtomTypeSetCAP mm_atom_types,
278  orbitals::OrbitalTypeSetCAP orbital_types//,
279 // CSDAtomTypeSetCAP csd_atom_types //kwk commented out until they hae been fully implemented
280 )
281 {
282 
283  // read the files
285  {
286  utility::io::izstream data( list_filename.c_str() );
287  std::string line;
288  while ( getline( data, line ) ) {
289  // add full database path to the AA.params filename
290  filenames.push_back( basic::database::full_name( line ) );
291  }
292  data.close();
293  }
294 
295  read_files( filenames, atom_types, elements, mm_atom_types, orbital_types ); // , csd_atom_types ); //kwk commented out csd atom types until they have been fully implemented
296 }
297 
298 ///////////////////////////////////////////////////////////////////////////////
299 void
301  utility::vector1< std::string > const & filenames,
302  AtomTypeSetCAP atom_types,
303  ElementSetCAP elements,
304  MMAtomTypeSetCAP mm_atom_types,
305  orbitals::OrbitalTypeSetCAP orbital_types//,
306 // CSDAtomTypeSetCAP csd_atom_types //kwk commented out csd atomtypes until they have been fully implemented
307 )
308 {
309  for ( Size ii=1; ii<= filenames.size(); ++ii ) {
310  ResidueTypeOP rsd_type( read_topology_file( filenames[ii], atom_types, elements, mm_atom_types,orbital_types, this ) ); //, csd_atom_types ) );
311  //Commented out csd_atom_types until they have been fully implemented
312  residue_types_.push_back( rsd_type );
313  }
314 
316 }
317 
318 /* Old code - doesn't respect various command line options. See constructor for current patch-loading functionality
319 
320 ///////////////////////////////////////////////////////////////////////////////
321 /// @brief apply patches to base ResidueType to generate variant ResidueTyes
322 ///
323 /// @details loop through all the existing ResidueTypes and apply patch files
324 /// given certain selector rules to each of the ResidueTypes to create new variant
325 /// types. Patches can be applied combinatorially to create more variant types, e.g.,
326 /// a residue with both N-terminus and C-terminus patches.
327 ///
328 void
329 ResidueTypeSet::apply_patches(
330  std::string const & list_filename
331 )
332 {
333 
334  // read the files
335  utility::vector1< std::string > filenames;
336  {
337  utility::io::izstream data( list_filename.c_str() );
338  if( !data.good() ) { utility_exit_with_message("Unable to open patch list file " + list_filename); }
339  std::string line;
340  while ( getline( data, line ) ) {
341  // add full database path to the patch filename
342  filenames.push_back( basic::database::full_name( line ) );
343  }
344  data.close();
345  }
346 
347  apply_patches( filenames );
348 }
349 */
350 
351  //XRW_B_T1
352  /*
353 ///////////////////////////////////////////////////////////////////////////////
354 bool
355 ResidueTypeSet::coarsify(
356  pose::Pose &coarse_pose, pose::Pose const &fine_pose
357 ) const
358 {
359  if (coarsifier_) {
360  coarsifier_->coarsify(coarse_pose,fine_pose);
361  return true;
362  } else
363  return false;
364 }
365  */
366  //XRW_E_T1
367 
368 ///////////////////////////////////////////////////////////////////////////////
369 void
371  utility::vector1< std::string > const & filenames
372 )
373 {
374  for ( Size ii=1; ii<= filenames.size(); ++ii ) {
375  Patch p;
376  p.read_file( filenames[ii] );
377  Size const current_n_residue( residue_types_.size() );
378  for ( Size i=1; i<= current_n_residue; ++i ) {
379  ResidueType const & rsd_type( *residue_types_[ i ] );
380  if ( p.applies_to( rsd_type ) ) {
381  if ( p.replaces( rsd_type ) ) {
382  residue_types_[ i ] = p.apply( rsd_type );
383  } else {
384  ResidueTypeOP new_rsd_type( p.apply( rsd_type ) );
385  if ( new_rsd_type ) {
386  residue_types_.push_back( new_rsd_type );
387  }
388  }
389  }
390  }
391  }
392 
394 
395 
396 }
397 
398 ///////////////////////////////////////////////////////////////////////////////
399 //private
400 /// @brief clear residue maps
401 void
403 {
404  aa_map_.clear();
405  name3_map_.clear();
406  name_map_.clear();
407  nonconst_name_map_.clear();
408  aas_defined_.clear();
409  residue_types_const_.clear();
410 }
411 
412 
413 ///////////////////////////////////////////////////////////////////////////////
414 //private
415 /// @details check that residue id map should be unique,
416 /// sort the aas_defined list and make its membe unique
417 ///
418 void
420 {
421 
423 
424  assert( residue_types_const_.empty() );
425 
426  for ( ResidueTypeOPs::iterator rsdtype_it(residue_types_.begin() ), rsdtype_end( residue_types_.end() );
427  rsdtype_it != rsdtype_end; ++rsdtype_it ) {
428  ResidueTypeOP rsd( *rsdtype_it );
430  }
431  aas_defined_.sort();
432  aas_defined_.unique();
433 }
434 
435 void
437 {
438 
439  residue_types_const_.push_back( rsd_ptr() );
440 
441  // name should be unique!
442  if ( name_map_.count( rsd_ptr->name() ) ) {
443  std::stringstream err_msg;
444  err_msg << "Attempting to add a residue type with name '" + rsd_ptr->name() + "' ";
445  err_msg << "but this name is already taken." << std::endl;
446  err_msg << "Please check your residue parameter files." << std::endl;
447  utility_exit_with_message(err_msg.str());
448  }
449  name_map_[ rsd_ptr->name() ] = rsd_ptr();
450  nonconst_name_map_[ rsd_ptr->name() ] = rsd_ptr;
451 
452  // map by AA
453  if ( rsd_ptr->aa() != aa_unk ) {
454  aa_map_[ rsd_ptr->aa() ].push_back( rsd_ptr() );
455  }
456 
457  // add aa type
458  aas_defined_.push_back( rsd_ptr->aa() );
459 
460  // map by pdb string
461  name3_map_[ rsd_ptr->name3() ].push_back( rsd_ptr() );
462 
463  // For specialty amino acids, add them to the name three maps both with their PDB strings and
464  // with their specialty string -- the first three letters of the residue name.
465  // E.g., CYD will appear in both lists for name3_map_[ "CYS" ] and name3_map_[ "CYD" ]
466  if ( rsd_ptr->name3() != rsd_ptr->name().substr(0,3) ) {
467  name3_map_[ rsd_ptr->name().substr(0,3) ].push_back( rsd_ptr() );
468  }
469 
470 }
471 
472 void
474 {
475  //Assert rather than utility exit, because this should have been called by remove residue, which utility exits
476  assert(has_name(rsd->name()));
477  ResidueTypeCOPs::iterator const_res_it(std::find(residue_types_const_.begin(),residue_types_const_.end(),rsd));
478  residue_types_const_.erase(const_res_it);
479 
480  name_map_.erase(rsd->name());
481  nonconst_name_map_.erase(rsd->name());
482  if(rsd->aa() != aa_unk)
483  {
484  ResidueTypeCOPs::iterator aa_it(std::find(aa_map_[rsd->aa()].begin(),aa_map_[rsd->aa()].end(),rsd));
485  aa_map_[rsd->aa()].erase(aa_it);
486  if(aa_map_[rsd->aa()].size() == 0)
487  {
488  aa_map_.erase(rsd->aa());
489  }
490  }
491 
492  std::list<AA>::iterator aa_it(std::find(aas_defined_.begin(),aas_defined_.end(),rsd->aa()));
493  aas_defined_.erase(aa_it);
494 
495  ResidueTypeCOPs::iterator name3_it(std::find(name3_map_[rsd->name3()].begin(),name3_map_[rsd->name3()].end(),rsd));
496  name3_map_[rsd->name3()].erase(name3_it);
497  if(name3_map_[rsd->name3()].size() == 0)
498  {
499  name3_map_.erase(rsd->name3());
500  }
501 
502  if(rsd->name3() != rsd->name().substr(0,3))
503  {
504  name3_it = std::find(name3_map_[rsd->name3().substr(0,3)].begin(),name3_map_[rsd->name3().substr(0,3)].end(),rsd);
505  name3_map_[rsd->name3().substr(0,3)].erase(name3_it);
506  if(name3_map_[rsd->name3().substr(0,3)].size() == 0)
507  {
508  name3_map_.erase(rsd->name3().substr(0,3));
509  }
510  }
511 
512 }
513 
514  ///@brief beginning of aas_defined_ list
515 std::list< AA >::const_iterator
517 {
518  return aas_defined_.begin();
519 }
520  ///@brief end of aas_defined_ list
521 std::list< AA >::const_iterator
523 {
524  return aas_defined_.end();
525 }
526 
527 ///////////////////////////////////////////////////////////////////////////////
528 /// @details selection done by ResidueSelector class
529 ///
530 void
532  ResidueSelector const & selector,
533  ResidueTypeCOPs & matches
534 ) const
535 {
536  for ( ResidueTypeOPs::const_iterator iter=residue_types_.begin(), iter_end = residue_types_.end(); iter!= iter_end; ++iter ) {
537  if ( selector[ **iter ] ) {
538  matches.push_back( (*iter)() );
539  }
540  }
541 }
542 
543 ///////////////////////////////////////////////////////////////////////////////
544 /// @details return the first match with both base ResidueType id and variant_type
545 /// name. Abort if there is no match
546 ///
547 /// @note currently, this will not work for variant types defined as alternate
548 /// base residues (ie different params files)
549 ResidueType const &
551 {
552  if ( init_rsd.has_variant_type( new_type ) ) return init_rsd;
553 
554  // find all residues with the same base name as init_rsd
555  std::string const base_name( residue_type_base_name( init_rsd ) );
556 
557  // the desired set of variant types:
558  utility::vector1< VariantType > target_variants( init_rsd.variant_types() );
559  if ( !init_rsd.has_variant_type(new_type) ) target_variants.push_back( new_type );
560 
561  Size const nvar( target_variants.size() );
562 
563  // now look for residue_type with same base_name and the desired set of variants
564  for ( ResidueTypeOPs::const_iterator iter= residue_types_.begin(), iter_end = residue_types_.end();
565  iter != iter_end; ++iter ) {
566  ResidueType const & rsd( **iter );
567  if ( residue_type_base_name( rsd ) == base_name && rsd.variant_types().size() == nvar ) {
568  bool match( true );
569  for ( Size i=1; i<= nvar; ++i ) {
570  if ( !rsd.has_variant_type( target_variants[i] ) ) {
571  match = false;
572  break;
573  }
574  }
575  if ( match == true ) {
576  return rsd;
577  }
578  }
579  }
580  utility_exit_with_message( "unable to find desired variant residue: "+init_rsd.name()+" "+base_name+" "+new_type);
581  // wont get here:
582  return *( name_map_.begin()->second );
583 }
584 
585 ///////////////////////////////////////////////////////////////////////////////
586 ResidueType const &
588 {
589  if ( !init_rsd.has_variant_type( old_type ) ) return init_rsd; // already done
590 
591  // find all residues with the same base name as init_rsd
592  std::string const base_name( residue_type_base_name( init_rsd ) );
593 
594  // the desired set of variant types:
595  utility::vector1< VariantType > target_variants( init_rsd.variant_types() );
596  target_variants.erase( std::find( target_variants.begin(), target_variants.end(), old_type ) );
597 
598  Size const nvar( target_variants.size() );
599 
600  // now look for residue_type with same base_name and the desired set of variants
601  for ( ResidueTypeOPs::const_iterator iter= residue_types_.begin(), iter_end = residue_types_.end();
602  iter != iter_end; ++iter ) {
603  ResidueType const & rsd( **iter );
604  if ( residue_type_base_name( rsd ) == base_name && rsd.variant_types().size() == nvar ) {
605  bool match( true );
606  for ( Size i=1; i<= nvar; ++i ) {
607  if ( !rsd.has_variant_type( target_variants[i] ) ) {
608  match = false;
609  break;
610  }
611  }
612  if ( match == true ) {
613  return rsd;
614  }
615  }
616  }
617  utility_exit_with_message( "unable to find desired non-variant residue: "+init_rsd.name()+" "+base_name+" "+old_type);
618  // wont get here:
619  return *( name_map_.begin()->second );
620 }
621 
622 ///////////////////////////////////////////////////////////////////////////////
623 /// @details Generation of new residue types augmented by adduct atoms
624 ///
625 void
627 {
628  // First parse the command line for requested adducts
629  utility::options::StringVectorOption & add_set
630  = basic::options::option[ basic::options::OptionKeys::packing::adducts ];
631 
632  // No adducts, skip out
633  if( add_set.size() == 0 ) return;
634 
635  // Convert to a map that takes a string descriptor of an adduct and
636  // gives the max number of adducts of that class to apply, so
637  // a command line option of -adducts <adduct_type> 2 for a type that has
638  // 5 entries in the rsd param file will create all combinations with up to
639  // 2 total adducts.
640 
641  AdductMap add_map = parse_adduct_string( add_set );
642 
643  // Error check each requested adduct from the command line, and
644  // complain if there are no examples in any residues. This function
645  // will not return if
647 
648  // Set up a starting point map where the int value is the number
649  // of adducts of a given type placed
650  AdductMap blank_map( add_map );
651  for( AdductMap::iterator add_iter = blank_map.begin(),
652  end_iter = blank_map.end() ;
653  add_iter != end_iter ; ++add_iter ) {
654  add_iter->second = 0;
655  }
656 
657  // Process the residues in turn
658  for ( ResidueTypeOPs::const_iterator iter= residue_types_.begin(), iter_end = residue_types_.end();
659  iter != iter_end; ++iter ) {
660  ResidueType const & rsd( **iter );
661  AdductMap count_map( blank_map );
662  utility::vector1< bool > add_mask( rsd.defined_adducts().size(), false );
663  create_adduct_combinations( rsd, add_map, count_map, add_mask, rsd.defined_adducts().begin() );
664  }
665 
666 // utility_exit_with_message( "Debug stop point \n" );
667 
669 
670 }
671 
672 void
674 {
675  if(basic::options::option[ basic::options::OptionKeys::in::add_orbitals]){
676  orbitals::AssignOrbitals add_orbitals_to_residue(new_type);
677  add_orbitals_to_residue.assign_orbitals();
678  }
679  residue_types_.push_back( new_type );
680  add_residue_type_to_maps( new_type );
681  aas_defined_.sort();
682  aas_defined_.unique();
683 }
684 
686 {
687 
688  if(!has_name(name))
689  {
690  utility_exit_with_message("ResidueTypeSet does not have a residue called "+name+ " so it cannot be deleted.");
691  }
692 
693  //See, this is why using vectors everywhere is annoying
694  ResidueTypeOP type_to_remove(nonconst_name_map(name));
695 
696  ResidueTypeOPs::iterator res_it(std::find(residue_types_.begin(),residue_types_.end(),type_to_remove));
697  residue_types_.erase(res_it);
698  remove_residue_type_from_maps(type_to_remove);
699 }
700 
701 /// @brief Create correct combinations of adducts for a residue type
703  ResidueType const & rsd,
704  AdductMap ref_map,
705  AdductMap count_map,
706  utility::vector1< bool > add_mask,
708 )
709 {
710 
711  if( work_iter == rsd.defined_adducts().end() ) {
712  // Skip the 'no adduct' case - that has already been
713  // made when reading in files
714  if( std::find( add_mask.begin(), add_mask.end(), true ) == add_mask.end() ) {
715  return;
716  }
717  // Make this combo and return;
718 // std::cout << "Making an adduct" << std::endl;
719 
721  foreach(bool make, add_mask){
722  std::cout << "Adduct " << add_iter->adduct_name() << " make is " << make << std::endl;
723  ++add_iter;
724  }
725 
726  // Farm this out to a helper function
727  residue_types_.push_back( apply_adducts_to_residue( rsd, add_mask ) );
728 
729  return;
730  }
731 
732  // Traverse the 'make' branch for this adduct if:
733  // 1. The adduct is in the map of requested adducts
734  // 2. we haven't exceeded the count limit for this adduct
735  AdductMap::iterator test_iter =
736  ref_map.find( work_iter->adduct_name() );
737 
738  if ( test_iter != ref_map.end() &&
739  count_map[ test_iter->first ] < ref_map[ test_iter->first ] ) {
740  AdductMap new_count_map( count_map );
741  new_count_map[ work_iter->adduct_name() ]++;
742  utility::vector1< bool > new_add_mask( add_mask );
743  // This following line may not work if the Adducts are no longer
744  // stored in a vector
745  new_add_mask[ work_iter - rsd.defined_adducts().begin() + 1 ] = true;
746  create_adduct_combinations( rsd, ref_map, new_count_map, new_add_mask, work_iter+1 );
747  }
748 
749  // Always traverse the 'do not make' for this adduct
750  // The count is not incremented, and the mask is left at the default (false)
751  AdductMap new_count_map( count_map );
752  utility::vector1< bool > new_add_mask( add_mask );
753  create_adduct_combinations( rsd, ref_map, new_count_map, new_add_mask, work_iter+1 );
754 
755 }
756 
757 
758 
759 ///////////////////////////////////////////////////////////////////////////////
760 
761 } // pose
762 } // core