Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
RotamerLibrary.cc
Go to the documentation of this file.
1 
2 // -*- mode:c++;tab-width:2;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t -*-
3 // vi: set ts=2 noet:
4 //
5 // (c) Copyright Rosetta Commons Member Institutions.
6 // (c) This file is part of the Rosetta software suite and is made available under license.
7 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
8 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
9 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
10 
11 /// @file
12 /// @brief
13 /// @author
14 
15 
16 // Unit headers
18 
19 // Package headers
29 // AUTO-REMOVED #include <core/scoring/ScoringManager.hh>
30 
31 // Project headers
32 // AUTO-REMOVED #include <core/chemical/ChemicalManager.hh>
34 #include <core/graph/Graph.hh>
35 
36 #include <basic/database/open.hh>
37 #include <basic/options/option.hh>
38 
39 #include <basic/basic.hh>
40 #include <basic/interpolate.hh>
41 //XRW_B_T1
42 //#include <core/coarse/Translator.hh>
43 //#include <core/coarse/TranslatorSet.hh>
44 //XRW_E_T1
45 #include <core/pose/Pose.hh>
47 //#include <core/scoring/TenANeighborGraph.hh>
48 
49 // Numeric headers
50 #include <numeric/xyz.functions.hh>
51 // AUTO-REMOVED #include <numeric/constants.hh>
52 // AUTO-REMOVED #include <numeric/angle.functions.hh>
53 
54 #include <utility/string_util.hh>
55 #include <utility/io/izstream.hh>
56 #include <utility/io/ozstream.hh>
57 
58 // ObjexxFCL headers
59 // AUTO-REMOVED #include <ObjexxFCL/FArray1D.hh>
60 // AUTO-REMOVED #include <ObjexxFCL/format.hh>
61 
62 // C++ Headers
63 #include <string>
64 #include <iostream>
65 #include <fstream>
66 #if defined(WIN32) || defined(__CYGWIN__)
67 // AUTO-REMOVED #include <ctime>
68 #endif
69 
70 // Boost Headers
71 #include <boost/cstdint.hpp>
72 
73 // C Headers
74 // AUTO-REMOVED #include <sys/stat.h>
75 // AUTO-REMOVED #include <stdio.h>
76 // AUTO-REMOVED #include <stdlib.h>
77 
78 #include <basic/Tracer.hh>
79 using basic::T;
80 
81 // option key includes
82 
83 #include <basic/options/keys/out.OptionKeys.gen.hh>
84 // AUTO-REMOVED #include <basic/options/keys/score.OptionKeys.gen.hh>
85 #include <basic/options/keys/corrections.OptionKeys.gen.hh>
86 #include <basic/options/keys/in.OptionKeys.gen.hh>
87 
89 #include <utility/vector1.hh>
90 
91 
92 
93 using basic::Error;
94 using basic::Warning;
95 
96 static basic::Tracer TR("core.pack.dunbrack");
97 
98 /**
99  rearrange the dunbrack arrays:
100 
101  mapping from aa to single-residue-rotamer-library
102 
103  to preserve current interpolation scheme, need ability to (quickly)
104  lookup the probability/chi-means/chi-sdevs for a given rotamer in
105  several torsion-angle bins.
106 
107  so how to store prob/mean/sd for alt rotamers at different pp bins
108 
109  quick conversion from rotno-tuple to index?
110 
111  rotamer_data: probability, chi-mean, chi-sd
112 
113 **/
114 namespace core {
115 namespace pack {
116 namespace dunbrack {
117 
118 /// @brief helper that'll determine the rotamer bins for a residue by asking its associated
119 /// rotamer library for that information.
120 void
122  conformation::Residue const & rsd,
123  RotVector & rot
124 )
125 {
126  assert( rsd.aa() <= chemical::num_canonical_aas );
127 
129  if ( rotlib ) {
130  SingleResidueDunbrackLibraryCAP dunlib( static_cast< SingleResidueDunbrackLibrary const * > ( rotlib() ));
131  dunlib->get_rotamer_from_chi( rsd.chi(), rot );
132  } else { rot.resize( 0 ); }
133 }
134 
135 /// @brief helper that'll determine the rotamer bins for a residue_type by asking its associated
136 /// rotamer library for that information. Takes chi vector as input parameter.
137 void
139  chemical::ResidueType const & rsd_type,
140  ChiVector const & chi,
141  RotVector & rot
142 )
143 {
145  if ( rotlib ) {
146  SingleResidueDunbrackLibraryCAP dunlib( static_cast< SingleResidueDunbrackLibrary const * > ( rotlib() ));
147  dunlib->get_rotamer_from_chi( chi, rot );
148  } else { rot.resize( 0 ); }
149 }
150 
151 
152 void
154  ChiVector const & chi, // pass by reference for speed
155  chemical::AA const res,
156  RotVector & rot
157 )
158 {
159  rot.resize( chi.size() );
160 
161  Size4 rot4; Real4 chi4;
162  Size nchi( std::min( chi.size(), DUNBRACK_MAX_SCTOR ) );
163  for ( Size ii = 1; ii <= nchi; ++ii ) chi4[ ii ] = chi[ ii ];
164 
165  rotamer_from_chi_02( chi4, res, nchi, rot4 );
166 
167  for ( Size ii = 1; ii <= nchi; ++ii ) rot[ ii ] = rot4[ ii ];
168  for ( Size ii = nchi+1; ii <= rot.size(); ++ii ) rot[ ii ] = 0;
169 }
170 
171 /// @brief DEPRICATED
172 /// convert between the real-valued chi dihedrals and the rotamer well indices.
173 ///
174 /// @details This code comes directly from Roland Dunbrack. In certain rare edge cases,
175 /// floating point comparison breaks down (e.g. ! x >= 120.0 && ! x < 120.0 ) and
176 /// Dunbrack's code leaves the rotamer well unassigned -- a value of zero. I'm modifying
177 /// the code to guarantee that the rotamer well is assigned, but so that
178 /// Dunbrack's original form is still recognizable.
179 /// e.g.
180 /// if (x) a; if (y) b; if (z) c; now reads as:
181 /// if (x) a; else if ( y ) b; else /*if (z)*/ c;
182 void
184  Real4 const & chi,
185  chemical::AA const res,
186  Size nchi,
187  Size4 & rot
188 )
189 {
190  using namespace chemical;
191 
192  // This code assumes that we're dealing with a canonical aa - fail if not the case.
193  assert( res <= num_canonical_aas );
194 
195  // default to 0
196  // right now this means 0 for rot numbers larger than dunbrack's nchi
197  // eg for H-chi or extra chi's
198 
199  for ( Size i = 1; i <= nchi; ++i ) {
200  rot[i] = 0;
201  Real chi_i = basic::periodic_range( chi[ i ], 360.0 ); // this saves us a vector construction/destruction
202  if ( i == 1 ) { // chi 1 //KMa phospho_ser
203  if ( res != aa_pro && res != aa_gly && res != aa_ala ) {
204  // chi1 of all residues except P,G,A,RNA
205  if ( ( chi_i >= 0.0 ) && ( chi_i <= 120.0 ) ) { rot[i] = 1; }
206  else if ( std::abs(chi_i) >= 120.0 ) { rot[i] = 2; }
207  else /*if ( ( chi_i >= -120.0 ) && ( chi_i <= 0.0 ) )*/{ rot[i] = 3; }
208  } else if ( res == aa_pro ) {
209  // chi1 of pro
210  if ( chi_i >= 0.0 ) { rot[i] = 1; }
211  else /*if ( chi_i <= 0.0 )*/ { rot[i] = 2; }
212  }
213 
214  } else if ( i == 2 ) { // chi 2
215  if ( res == aa_arg ) {
216  if ( ( chi_i >= 0.0 ) && ( chi_i <= 120.0 ) ) { rot[i] = 1; }
217  else if ( std::abs(chi_i) >= 120.0 ) { rot[i] = 2; }
218  else /*if ( ( chi_i >= -120.0 ) && ( chi_i <= 0.0 ) )*/ { rot[i] = 3; }
219 
220  } else if ( res == aa_glu || res == aa_his || res == aa_ile ||
221  res == aa_lys || res == aa_leu || res == aa_met ||
222  res == aa_gln ) {
223  if ( ( chi_i >= 0.0 ) && ( chi_i <= 120.0 ) ) { rot[i] = 1; }
224  else if ( std::abs(chi_i) >= 120.0 ) { rot[i] = 2; }
225  else /*if ( ( chi_i >= -120.0 ) && ( chi_i <= 0.0 ) )*/ { rot[i] = 3; }
226 
227  } else if ( res == aa_asp ) {
228  if ( ( ( chi_i >= 30.0 ) && ( chi_i <= 90.0 ) ) ||
229  ( ( chi_i <= -90.0 ) && ( chi_i >= -150.0 ) ) ) {
230  rot[i] = 1;
231  } else if ( ( ( chi_i >= -30.0 ) && ( chi_i <= 30.0 ) ) ||
232  ( std::abs(chi_i) >= 150.0 ) ) {
233  rot[i] = 2;
234  } else {
235  /*if ( ( ( chi_i >= -90.0 ) && ( chi_i <= -30.0 ) ) ||
236  ( ( chi_i >= 90.0 ) && ( chi_i <= 150.0 ) ) ) */
237  rot[i] = 3;
238  }
239 
240  } else if ( ( res == aa_phe ) || ( res == aa_tyr ) ) {
241  if ( ( ( chi_i >= 30.0 ) && ( chi_i <= 150.0 ) ) ||
242  ( ( chi_i <= -30.0 ) && ( chi_i >= -150.0 ) ) ) {
243  rot[i] = 1;
244  } else { /*if ( ( ( chi_i >= -30.0 ) && ( chi_i <= 30.0 ) ) ||
245  ( std::abs(chi_i) >= 150.0 ) ) */
246  rot[i] = 2;
247  }
248 
249  } else if ( res == aa_trp ) {
250  if ( ( chi_i >= -180.0 ) && ( chi_i <= -60.0 ) ) { rot[i] = 1; }
251  else if ( ( chi_i >= -60.0 ) && ( chi_i <= 60.0 ) ) { rot[i] = 2; }
252  else /*if ( ( chi_i >= 60.0 ) && ( chi_i <= 180.0 ) ) */ { rot[i] = 3; }
253 
254  } else if ( res == aa_asn ) { // chi2 of asn
255  // ctsa - note this is a special case of the new dunbrack rotamer set
256  if ( rot[1] == 1 ) {
257  if ( chi_i >= -150.0 && chi_i < -90.0 ) { rot[i] = 1; }
258  else if ( chi_i >= -90.0 && chi_i < -30.0 ) { rot[i] = 2; }
259  else if ( chi_i >= -30.0 && chi_i < 30.0 ) { rot[i] = 3; }
260  else if ( chi_i >= 30.0 && chi_i < 90.0 ) { rot[i] = 4; }
261  else if ( chi_i >= 90.0 && chi_i < 150.0 ) { rot[i] = 5; }
262  else /*if ( std::abs(chi_i) >= 150.0 )*/ { rot[i] = 6; }
263  } else if ( rot[1] == 2 ) {
264  if ( chi_i >= -180.0 && chi_i < -90.0 ) { rot[i] = 1; }
265  else if ( chi_i >= -90.0 && chi_i < -45.0 ) { rot[i] = 2; }
266  else if ( chi_i >= -45.0 && chi_i < 0.0 ) { rot[i] = 3; }
267  else if ( chi_i >= 0.0 && chi_i < 45.0 ) { rot[i] = 4; }
268  else if ( chi_i >= 45.0 && chi_i < 90.0 ) { rot[i] = 5; }
269  else /*if ( chi_i >= 90.0 && chi_i <= 180.0 )*/ { rot[i] = 6; }
270  } else {
271  if ( chi_i >= -180.0 && chi_i < -105.0 ) { rot[i] = 1; }
272  else if ( chi_i >= -105.0 && chi_i < -45.0 ) { rot[i] = 2; }
273  else if ( chi_i >= -45.0 && chi_i < 15.0 ) { rot[i] = 3; }
274  else if ( chi_i >= 15.0 && chi_i < 60.0 ) { rot[i] = 4; }
275  else if ( chi_i >= 60.0 && chi_i < 120.0 ) { rot[i] = 5; }
276  else /*if ( chi_i >= 120.0 && chi_i <= 180.0 )*/ { rot[i] = 6; }
277  }
278  } else if ( res == aa_pro ) {
279  // apl proline has only two rotamers, distinguishable by chi1. Chi2 is always 1.
280  rot[i]=1;
281  }
282 
283 
284  } else if ( i == 3 ) { // chi 3
285  if ( res == aa_glu ) {
286  if ( ( ( chi_i >= 30.0 ) && ( chi_i <= 90.0 ) ) ||
287  ( ( chi_i <= -90.0 ) && ( chi_i >= -150.0 ) ) ) { rot[i] = 1; }
288  else if ( ( ( chi_i >= -30.0 ) && ( chi_i <= 30.0 ) ) ||
289  ( std::abs(chi_i) >= 150.0 ) ) { rot[i] = 2; }
290  else /*if ( ( ( chi_i >= -90.0 ) && ( chi_i <= -30.0 ) ) ||
291  ( ( chi_i >= 90.0 ) && ( chi_i <= 150.0 ) ) )*/ { rot[i] = 3; }
292 
293  } else if ( res == aa_arg || res == aa_lys || res == aa_met ) {
294  if ( ( chi_i >= 0.0 ) && ( chi_i <= 120.0 ) ) { rot[i] = 1; }
295  else if ( std::abs(chi_i) > 120.0 ) { rot[i] = 2; }
296  else /*if ( ( chi_i >= -120.0 ) && ( chi_i <= 0.0 ) )*/ { rot[i] = 3; }
297 
298  } else if ( res == aa_gln ) { // chi3 of gln
299  // ctsa - note this is a special case of the new dunbrack rotamer set
300  if ( rot[2] == 2 ) {
301  if ( chi_i >= 135.0 || chi_i < -135.0 ) { rot[i] = 1; }
302  else if ( chi_i >= -135.0 && chi_i < -45.0 ) { rot[i] = 2; }
303  else if ( chi_i >= -45.0 && chi_i < 45.0 ) { rot[i] = 3; }
304  else /*if ( chi_i >= 45.0 && chi_i < 135.0 )*/ { rot[i] = 4; }
305  } else {
306  if ( chi_i >= -180.0 && chi_i < -90.0 ) { rot[i] = 1; }
307  else if ( chi_i >= -90.0 && chi_i < 0.0 ) { rot[i] = 2; }
308  else if ( chi_i >= 0.0 && chi_i < 90.0 ) { rot[i] = 3; }
309  else /*if ( chi_i >= 90.0 && chi_i <= 180.0 )*/ { rot[i] = 4; }
310  }
311  } else if ( res == aa_pro ) {
312  // apl
313  rot[i]=1;
314  }
315  } else if ( i == 4 ) { // chi 4
316  if ( res == aa_arg || res == aa_lys ) {
317  if ( ( chi_i >= 0.0 ) && ( chi_i <= 120.0 ) ) { rot[i] = 1; }
318  else if ( std::abs(chi_i) > 120.0 ) { rot[i] = 2; }
319  else /*if ( ( chi_i >= -120.0 ) && ( chi_i <= 0.0 ) )*/ { rot[i] = 3; }
320  }
321  }
322  } // i=1, i<= nchi
323 
324  //std::cout << "Rotamer from chi02: " << res << " ";
325  //for ( Size ii = 1; ii <= nchi; ++ii ) std::cout << chi[ii] << " ";
326  //std::cout << " : ";
327  //for ( Size ii = 1; ii <= nchi; ++ii ) std::cout << rot[ii] << " ";
328  //std::cout << std::endl;
329 
330 
331 }
332 
333 ///////////////////////////////////////////////////////////////////////////////
334 // taken from rotamer_functions -- total temporary hack
335 //
336 // removed pser and rna
337 //
338 
339 
341 {}
342 
343 
344 //// RotamerLibrary
346 
348  reslibraries_(),
349  libraries_(),
350  aa_libraries_( chemical::num_canonical_aas, 0 ), // for the canonical aa's, fast access
351  libraries_ops_()
352 {}
353 
355 {}
356 
357 Real
359  Residue const & rsd,
361 ) const
362 {
363  SingleResidueRotamerLibraryCAP const library( get_rsd_library( rsd.type() ) );
364 
365  if ( library ) {
366  return library->rotamer_energy( rsd, scratch );
367  }
368  return 0.0;
369 }
370 
371 Real
373  Residue const & rsd,
374  bool curr_rotamer_only,
376 ) const
377 {
378  SingleResidueRotamerLibraryCAP const library( get_rsd_library( rsd.type() ) );
379 
380  if ( library ) {
381  if ( curr_rotamer_only )
382  return library->best_rotamer_energy( rsd, true,scratch );
383  else
384  return library->best_rotamer_energy( rsd, false,scratch );
385  } else {
386  return 0.0;
387  }
388 }
389 
390 Real
392  Residue const & rsd,
394 ) const
395 {
396  SingleResidueRotamerLibraryCAP const library( get_rsd_library( rsd.type() ) );
397 
398  if ( library ) {
399  return library->rotamer_energy_deriv( rsd, scratch );
400  }
401 
402  Real3 & dE_dbb( scratch.dE_dbb() );
403  Real4 & dE_dchi( scratch.dE_dchi() );
404 
405  // ensure that these guys are dimensioned
406  //dE_dbb.resize ( rsd.mainchain_torsions().size() );
407  //dE_dchi.resize( rsd.nchi() );
408  std::fill( dE_dbb.begin(), dE_dbb.end(), 0 );
409  std::fill( dE_dchi.begin(), dE_dchi.end(), 0 );
410  return 0.0;
411 
412 }
413 
414 
415 //XRW_B_T1
416 /*
417 RotamerLibraryOP RotamerLibrary::coarsify(
418  coarse::TranslatorSet const & map_set
419 ) const
420 {
421  RotamerLibraryOP coarse_lib = new RotamerLibrary();
422  for (library_iterator it=libraries_.begin(), eit=libraries_.end(); it!=eit; ++it) {
423  chemical::AA aa = it->first;
424  coarse::TranslatorCOP map=map_set.default_for_aa(aa);
425  coarse_lib->add_residue_library(aa,it->second->coarsify(*map));
426  }
427  return coarse_lib;
428 }
429 */
430 //XRW_E_T1
431 
432 ///
433 void
435  AA const & aa,
437 ) const
438 {
439  if ( libraries_.find(aa) != libraries_.end() ) {
440  utility_exit_with_message("cant add rsd library twice");
441  }
442  libraries_.insert( std::make_pair( aa, rot_lib() ) );
443  if ( aa <= chemical::num_canonical_aas ) {
444  aa_libraries_[ aa ] = rot_lib(); // ASSUMPTION -- only fullatom rotamer libraries are added; centroid restypes don't have rotlibs.
445  }
446  libraries_ops_.push_back( rot_lib );
447 }
448 
449 void
451  ResidueType const & rsd_type,
453 ) const
454 {
455  // May want to change the library for a specific residue type during the run...
456  // This will not be threadsafe, though.
457  //if ( reslibraries_.find(aa) != reslibraries_.end() ) {
458  // utility_exit_with_message("cant add rsd library twice");
459  //}
460  std::string const key( rsd_type.name()+"@"+rsd_type.residue_type_set().name() );
461  reslibraries_.insert( std::make_pair( key, rot_lib() ) );
462  reslibraries_.insert( std::make_pair( rsd_type.name(), rot_lib() ) );
463  libraries_ops_.push_back( rot_lib );
464 }
465 
466 /// @brief Returns true if the singleton has already loaded a library for a given residue type.
467 bool
469 {
470  if ( ncaa_rotlibs_.find( rsd_type.name3() ) != ncaa_rotlibs_.end() ) {
471  return true;
472  }
473 
474  if ( rsd_type.residue_type_set().name() == chemical::FA_STANDARD &&
475  rsd_type.rotamer_aa() <= chemical::num_canonical_aas ) {
476  return aa_libraries_[ rsd_type.rotamer_aa() ] != 0;
477  }
478 
479  std::string const key( rsd_type.name()+"@"+rsd_type.residue_type_set().name() );
480  if ( reslibraries_.find( key ) != reslibraries_.end() ) {
481  return true;
482  } else if ( reslibraries_.find( rsd_type.name() ) != reslibraries_.end() ) {
483  return true;
484  // Dunbrack library only applies to fullatom residue types, right?
485  } else if ( rsd_type.residue_type_set().name() != chemical::CENTROID
486  && libraries_.find( rsd_type.rotamer_aa() ) != libraries_.end() ) {
487  return true;
488  }
489 
490  return false;
491 }
492 
493 /// @details returns NULL if no library is available for the given residue type
494 /// and no pdb rotamers have been defined for the given residue; if PDB rotamers HAVE
495 /// been defined, then
498 {
499  /// intercept, in case the residue type would prefer using the NCAARotamerLibrary
500  if ( rsd_type.get_use_ncaa_rotlib() ) {
501  return get_NCAARotamerLibrary( rsd_type );
502  }
503 
504  if ( rsd_type.residue_type_set().name() == chemical::FA_STANDARD &&
505  rsd_type.rotamer_aa() <= chemical::num_canonical_aas ) {
506  return aa_libraries_[ rsd_type.rotamer_aa() ];
507  }
508 
509  std::string const key( rsd_type.name()+"@"+rsd_type.residue_type_set().name() );
510  if ( reslibraries_.find( key ) != reslibraries_.end() ) {
511  return reslibraries_.find( key )->second;
512  } else if ( reslibraries_.find( rsd_type.name() ) != reslibraries_.end() ) {
513  return reslibraries_.find( rsd_type.name() )->second;
514  // Dunbrack library only applies to fullatom residue types, right?
515  } else if ( rsd_type.residue_type_set().name() != chemical::CENTROID
516  && libraries_.find( rsd_type.rotamer_aa() ) != libraries_.end() ) {
517  return libraries_.find( rsd_type.rotamer_aa() )->second;
518  }
519 
520  if ( rsd_type.get_RotamerLibraryName() != "" ) {
521  if ( !rsd_type.is_ligand() ) {
522  TR.Debug << "Warning: using PDB_ROTAMERS for non-ligand ResidueType!" << std::endl;
523  }
524 
525  TR.Debug << "Initializing conformer library for " << rsd_type.get_RotamerLibraryName() << std::endl;
527  pdb_rotamers->init_from_file( rsd_type.get_RotamerLibraryName(), &rsd_type );
528  add_residue_library( rsd_type, pdb_rotamers );
529  return pdb_rotamers();
530  }
531  return 0;
532 }
533 
536 {
537  if ( (Size) aa <= aa_libraries_.size() ) {
538  return aa_libraries_[ aa ];
539  }
540  return 0;
541 }
542 
543 
544 /// @details Generic decision tree for both 02 and 2010 libraries. Requires
545 /// that low-level subroutines dispatch to 02 and 2010 versions based on
546 /// the dun10 flag.
547 void
549 {
550 
551  if ( decide_read_from_binary() ) {
553  } else {
556  }
557 }
558 
559 bool
561 {
562  using namespace basic::options;
563  using namespace basic::options::OptionKeys;
564 
565  if ( option[ in::file::no_binary_dunlib ] ) return false;
566 
567  std::string binary_filename = get_binary_name();
568  utility::io::izstream binlib( binary_filename.c_str(), std::ios::in | std::ios::binary );
569 
570  if ( ! binlib ) {
571  return false;
572  }
573 
574  if ( ! binary_is_up_to_date( binlib ) ) return false;
575 
576  /// Look for specific objections for the 02 or 08 libraries (if any exist!)
577  if ( option[ corrections::score::dun10 ] ) {
578  if ( ! decide_read_from_binary_10() ) return false;
579  } else {
580  if ( ! decide_read_from_binary_02() ) return false;
581  }
582 
583  return true;
584 }
585 
586 /// @details Put specific objections to reading the 02 library from binary here.
587 /// This function alone will not answer whether the binary file should be read;
588 /// rather, it is called by the more generic "decide_read_from_binary" function.
589 bool
591 {
592  /// TO DO: check time stamp of ascii file vs time stamp of binary file
593  return true;
594 }
595 
596 
597 /// @details Put specific objections to reading the 10 library from binary here.
598 /// This function alone will not answer whether the binary file should be read;
599 /// rather, it is called by the more generic "decide_read_from_binary" function.
600 bool
602 {
603  /// TO DO: check time stamp of ascii files vs time stamp of binary file
604  return true;
605 }
606 
607 /// @details Dispatches binary file is up-to-date to appropriate library given
608 /// flag status (dun10 or dun08 yes/no).
609 bool
610 RotamerLibrary::binary_is_up_to_date( utility::io::izstream & binlib ) const
611 {
612  using namespace basic::options;
613  using namespace basic::options::OptionKeys;
614 
615  if ( option[ corrections::score::dun10 ] ) {
616  return binary_is_up_to_date_10( binlib );
617  } else {
618  return binary_is_up_to_date_02( binlib );
619  }
620 }
621 
622 bool
623 RotamerLibrary::binary_is_up_to_date_02( utility::io::izstream & binlib ) const
624 {
625  boost::int32_t version( 0 );
626  binlib.read( (char*) & version, sizeof( boost::int32_t ));
627  return static_cast< Size > (version) == current_binary_format_version_id_02();
628 }
629 
630 /// @details Binary file is up-to-date if all the following are true:
631 /// 1. Version # for binary file is equal to the current version #
632 /// 2. All the hard coded constants for the rotameric and semirotameric libraries
633 /// are the same from the previous hard coded values.
634 ///
635 /// DANGER DANGER DANGER - True for dun10 as well? -JAB
636 /// When we reopen the binary file in create_fa_dunbrack_libraries_08_from_binary
637 /// we will want to skip past all this data; the code in that section assumes that
638 /// it will read 8 arrays: 2 representing the rotameric amino acids, and 6
639 /// representing the semirotameric amino acids. The arithmetic it performs depends
640 /// on this basic structure not changing, therefore, if you change this structure,
641 /// you must also change the seekg arithmetic in the create...08_from_binary function.
642 
643 bool
644 RotamerLibrary::binary_is_up_to_date_10( utility::io::izstream & binlib ) const
645 {
646  /// 1.
647  boost::int32_t version( 0 );
648  binlib.read( (char*) & version, sizeof( boost::int32_t ));
649  if ( static_cast< Size > (version) != current_binary_format_version_id_10() ) return false;
650 
651  boost::int32_t nrotameric( 0 );
652  binlib.read( (char*) & nrotameric, sizeof( boost::int32_t ) );
653  boost::int32_t nsemirotameric( 0 );
654  binlib.read( (char*) & nsemirotameric, sizeof( boost::int32_t ) );
655 
656  utility::vector1< chemical::AA > rotameric_amino_acids;
657  utility::vector1< Size > rotameric_n_chi;
658 
662  utility::vector1< bool > sampind;
665 
667  rotameric_amino_acids, rotameric_n_chi,
668  sraa, srnchi, scind, sampind, sym, astr );
669 
670  /// 2.
671  if ( static_cast< Size > (nrotameric) != rotameric_amino_acids.size() ) return false;
672  if ( static_cast< Size > (nsemirotameric) != sraa.size() ) return false;
673 
674  boost::int32_t * rotaa_bin = new boost::int32_t[ nrotameric ];
675  boost::int32_t * rot_nchi_bin= new boost::int32_t[ nrotameric ];
676 
677  boost::int32_t * sraa_bin = new boost::int32_t[ nsemirotameric ];
678  boost::int32_t * srnchi_bin = new boost::int32_t[ nsemirotameric ];
679  boost::int32_t * scind_bin = new boost::int32_t[ nsemirotameric ];
680  boost::int32_t * sampind_bin = new boost::int32_t[ nsemirotameric ];
681  boost::int32_t * sym_bin = new boost::int32_t[ nsemirotameric ];
682  Real * astr_bin = new Real[ nsemirotameric ];
683 
684  binlib.read( (char*) rotaa_bin, nrotameric * sizeof( boost::int32_t ));
685  binlib.read( (char*) rot_nchi_bin, nrotameric * sizeof( boost::int32_t ));
686 
687  binlib.read( (char*) sraa_bin, nsemirotameric * sizeof( boost::int32_t ));
688  binlib.read( (char*) srnchi_bin, nsemirotameric * sizeof( boost::int32_t ));
689  binlib.read( (char*) scind_bin, nsemirotameric * sizeof( boost::int32_t ));
690  binlib.read( (char*) sampind_bin, nsemirotameric * sizeof( boost::int32_t ));
691  binlib.read( (char*) sym_bin, nsemirotameric * sizeof( boost::int32_t ));
692  binlib.read( (char*) astr_bin, nsemirotameric * sizeof( Real ));
693 
694  bool good( true );
695  for ( Size ii = 1; ii <= rotameric_amino_acids.size(); ++ii ) {
696  if ( rotaa_bin[ ii - 1 ] != static_cast< boost::int32_t > ( rotameric_amino_acids[ ii ] ) ) good = false;
697  if ( rot_nchi_bin[ ii - 1 ] != static_cast< boost::int32_t > ( rotameric_n_chi[ ii ] ) ) good = false;
698  }
699  for ( Size ii = 1; ii <= sraa.size(); ++ii ) {
700  if ( sraa_bin[ ii - 1 ] != static_cast< boost::int32_t > ( sraa[ ii ] ) ) good = false;
701  if ( srnchi_bin[ ii - 1 ] != static_cast< boost::int32_t > ( srnchi[ ii ] ) ) good = false;
702  if ( scind_bin[ ii - 1 ] != static_cast< boost::int32_t > ( scind[ ii ] ) ) good = false;
703  if ( sampind_bin[ ii - 1 ] != static_cast< boost::int32_t > ( sampind[ ii ] ) ) good = false;
704  if ( sym_bin[ ii - 1 ] != static_cast< boost::int32_t > ( sym[ ii ] ) ) good = false;
705  if ( astr_bin[ ii - 1 ] != astr[ ii ] ) good = false;
706  }
707 
708  delete [] rotaa_bin;
709  delete [] rot_nchi_bin;
710  delete [] sraa_bin;
711  delete [] srnchi_bin;
712  delete [] scind_bin;
713  delete [] sampind_bin;
714  delete [] sym_bin;
715  delete [] astr_bin;
716 
717  return good;
718 }
719 
720 
721 /// @details First checks general conditions under which a binary library file should
722 /// not be writen. It relies on get_binary_name() and binary_is_up_to_date() to
723 /// dispatch to the 02 and 08 data. If the binary file doesn't exist or isn't up-to-date
724 /// it then checks if there are any specific 02 or 08 objections to writing the
725 /// binary file. If no one objects, then this function gives a green light.
726 bool
728 {
729  using namespace basic::options;
730  using namespace basic::options::OptionKeys;
731 
732  if ( option[ in::file::no_binary_dunlib ] ) return false;
733  if ( option[ out::file::dont_rewrite_dunbrack_database ] ) return false;
734 
735  /// place other objections here, e.g. if we're running from a (genuine) database or on BOINC
736 
737 #ifdef BOINC
738  return false;
739 #endif
740 
741 #ifdef WIN32 // binary file handling doesnt appear to work properly on windows 64 bit machines.
742  return false;
743 #endif
744 
745 
746  std::string binary_filename = get_binary_name();
747  utility::io::izstream binlib( binary_filename.c_str(), std::ios::in | std::ios::binary );
748 
749 
750  if ( binlib && binary_is_up_to_date( binlib ) ) {
751  /// Do not overwrite a binary if it already exists and is up-to-date.
752  return false;
753  }
754  /// if we get this far, then the binary file either doesn't exist or isn't up-to-date.
755 
756  /// check if there are any objections to writing the library
757  if ( option[ corrections::score::dun10 ] ) {
758  if ( ! decide_write_binary_10() ) return false;
759  } else {
760  if ( ! decide_write_binary_02() ) return false;
761  }
762 
763  // otherwise, write it.
764  return true;
765 
766 }
767 
768 /// @details Add specific objections to the writing of the 02 library here.
769 bool
771 {
772  return true;
773 }
774 
775 
776 /// @details Add specific objections to the writing of the 10 library here.
777 bool
779 {
780  return true;
781 }
782 
783 
786 {
787  using namespace basic::options;
788  using namespace basic::options::OptionKeys;
789  return basic::database::full_name( option[ corrections::score::dun02_file ]);
790 }
791 
794 {
795  using namespace basic::options;
796  using namespace basic::options::OptionKeys;
797 
798  if ( option[ corrections::score::dun10 ] ) {
799  return get_binary_name_10();
800  } else {
801  return get_binary_name_02();
802  }
803 }
804 
807 {
808  // Keep the binaries for multiple dun02 libraries seperate.
809  return get_library_name_02() + ".Dunbrack02.lib.bin";
810 }
811 
812 
815 {
816  using namespace basic::options;
817  using namespace basic::options::OptionKeys;
818 
819  return basic::database::full_name( option[ corrections::score::dun10_dir ] + "/" + "Dunbrack10.lib.bin" );
820 }
821 
822 
823 /// @details The older binary formats did not have a version number, instead,
824 /// a somewhat stupid time-stamp was hard coded and compared against the time
825 /// stamp of the binary file that existed... e.g. if a new binary format was
826 /// committed to trunk on 1/1/08 12:00 pm, and the time stamp on a particular binary
827 /// was from 12/1/07, then the old binary file would be overwritten. However,
828 /// if the time stamp on some other binary file was from 2/1/08, the code assumed
829 /// that the binary file was up to date. This is a poor assumption, since the
830 /// code from 12/1/07 might have been run on 2/1/08 to generate a binary file.
831 /// The time stamp would have falsely indicated that the 2/1/08 generated file
832 /// was of the same binary format imposed on 1/1/08.
833 ///
834 /// Version numbering avoids this issue. If the 12/1/07 code wrote version # 3,
835 /// the 1/1/08 code could look for version # 4 in a file generated on 2/1/08
836 /// and use the mismatch as an indication of an out-of-date binary format.
837 ///
838 /// The challenge is to come up with a versioning scheme that handles the fact that
839 /// until now, there haven't been version #'s in the binary files. How can a
840 /// binary file generated by a pre-versioning piece of code be detected? The trick
841 /// is to look at the data in the older binary file at the position which will in
842 /// the future be used to hold a version number. The first piece of data in the
843 /// old binary files was a count of the number of libraries in the binary file:
844 /// 18. Therefore, any starting version number beyond 18 would distinguish the
845 /// pre-versioned files from the versioned files.
846 ///
847 /// When changing the binary format, document the date of the change in the comment
848 /// section below and increment the version number in the function. Do not delete
849 /// old comments from the comment block below.
850 ///
851 /// Version 19: start vesion number. 8/9/08. Andrew Leaver-Fay
852 /// Version 20: Limit zero-probability rotamers to the resolution of the library (1e-4).
853 /// 6/16/2009. Andrew Leaver-Fay
854 /// Version 21: Write out bicubic spline parameters for -log(p(rot|phi,psi)). 3/28/2012. Andrew Leaver-Fay
855 /// Version 22: Bicubic spline bugfix 3/29/2012. Andrew Leaver-Fay
856 Size
858 {
859  return 22;
860 }
861 
862 
863 /// @details Version number for binary format. See comments for 02 version.
864 ///
865 /// When changing the binary format, document the date of the change in the comment
866 /// section below and increment the version number in the function. Do not delete
867 /// old comments from the comment block below.
868 ///
869 /// Version 1: start vesion number. 6/3/11. Andrew Leaver-Fay
870 /// Version 2: Rotameric residues write out bicubic spline parameters for -log(p(rot|phi,psi)). 3/28/2012. Andrew Leaver-Fay
871 /// Version 3: Tricubic interpolation data for semi-rotameric residues. 3/29/2012. Andrew Leaver-Fay
872 /// Version 4: Generate and write out bicubic spline data for the rotameric portion of the semi-rotameric residues . 3/29/2012. Andrew Leaver-Fay
873 Size
875 {
876  return 4;
877 }
878 
879 void
881 {
882  using namespace basic::options;
883  using namespace basic::options::OptionKeys;
884 
885  if ( option[ corrections::score::dun10 ] ) {
887  } else {
889  }
890 }
891 
892 void
894 {
895  using namespace basic::options;
896  using namespace basic::options::OptionKeys;
897 
898  if ( option[ corrections::score::dun10 ] ) {
900  } else {
902  }
903 }
904 
905 void
907 {
908  using namespace chemical;
909 
910  ////////////////////////////////////////////
911  //// DATA FOR THE ROTAMERIC AMINO ACIDS
912  ////////////////////////////////////////////
914  Size nrot_aas;
915 
916  utility::vector1< Size > memory_use_rotameric( num_canonical_aas, 0 );
917 
918  initialize_dun02_aa_parameters( nchi_for_aa, nrot_aas );
919 
920 
921  /// Now read in the 02 library.
922  clock_t starttime = clock();
923  utility::io::izstream libstream( get_library_name_02() );
924 
926  std::string nextaa;
927  libstream >> nextaa;
928 
929  //std::cout << "first aa: " << nextaa << std::endl;
930 
932  Size count_libraries_read( 0 );
933  while ( nextaa != "" ) {
934 
935  aan = chemical::aa_from_name( nextaa );
937  aan, nchi_for_aa[ aan ], libstream, true /*dun02*/, nextaa, true /*first aa string already read*/ );
938  ++count_libraries_read;
939 
940  libraries_[ aan ] = newlib();
941  aa_libraries_[ aan ] = newlib();
942  libraries_ops_.push_back( newlib );
943  memory_use_rotameric[ aan ] = newlib->memory_usage_in_bytes();
944 
945  //std::cout << "next aa: " << nextaa << " #" << count_libraries_read + 1 << std::endl;
946 
947  }
948  libstream.close();
949 
950  if ( count_libraries_read != nrot_aas ) {
951  std::cerr << "ERROR: expected to read " << nrot_aas << " libraries from Dun02, but read " << count_libraries_read << std::endl;
952  utility_exit();
953  }
954 
955  clock_t stoptime = clock();
956  TR << "Dunbrack library took " << ((double)stoptime-starttime)/CLOCKS_PER_SEC << " seconds to load from ASCII" << std::endl;
957 
958  //TR << "Memory usage: " << std::endl;
959  //Size total( 0 );
960  //for ( Size ii = 1; ii <= num_canonical_aas; ++ii ) {
961  // total += memory_use_rotameric[ ii ];
962  //if ( memory_use_rotameric[ii] != 0 ) {
963  //TR << chemical::name_from_aa( AA( ii ) ) << " with " << memory_use_rotameric[ ii ] << " bytes" << std::endl;
964  //}
965  //}
966  //TR << "Total memory on Dunbrack Libraries: " << total << " bytes." << std::endl;
967 
968 }
969 
970 
971 void
973 {
974  clock_t starttime = clock();
975 
976  std::string binary_filename = get_binary_name_02();
977  utility::io::izstream binlib( binary_filename.c_str(), std::ios::in | std::ios::binary );
978 
979  if ( ! binlib ) {
980  utility_exit_with_message( "Could not open binary Dunbrack02 file from database -- how did this happen?");
981  }
982 
983  /// READ PREABMLE
984  /// Even if binary file should change its structure in the future, version number should always be
985  /// the first piece of data in the file.
986  boost::int32_t version( 0 );
987  binlib.read( (char*) & version, sizeof( boost::int32_t ));
988  /// END PREABMLE
989 
990 
991  assert( static_cast< Size > (version) == current_binary_format_version_id_02() );
992 
993  read_from_binary( binlib );
994 
995  clock_t stoptime = clock();
996  TR << "Dunbrack library took " << ((double)stoptime-starttime)/CLOCKS_PER_SEC << " seconds to load from binary" << std::endl;
997 
998 }
999 
1000 
1001 void
1003 {
1004  using namespace chemical;
1005  using namespace utility;
1006 
1007  TR << "Reading Dunbrack Libraries" << std::endl;
1008 
1009  clock_t starttime = clock();
1010 
1011  /// Hard code some stuff.
1012  /// Rotameric library file names are of the form
1013  /// <3lc>.Jun9.bbdep.regular.lib
1014  /// Semi-Rotameric library files names are of the form
1015  /// 1. <3lc>.Jun9.bbdep.regular.lib
1016  /// 2. <3lc>.Jun9.bbdep.contMin.lib
1017  /// 3. <3lc>.Jun9.bbind.chi<#>.Definitions.lib
1018  /// 4. <3lc>.Jun9.bbind.chi<#>.Probabities.lib
1019 
1020  //std::string const db_subdir = "dun10/";
1021  std::string const regular_lib_suffix = ".bbdep.rotamers.lib";
1022  std::string const bbdep_contmin = ".bbdep.densities.lib";
1023  std::string const bbind_midfix = ".bbind.chi";
1024  std::string const bbind_defs = ".Definitions.lib";
1025  // Note: No Backbone-Independent NRCHI representation in '10 library
1026  // std::string const bbind_probs = ".Probabilities.lib";
1027 
1028  ////////////////////////////////////////////
1029  //// DATA FOR THE ROTAMERIC AMINO ACIDS
1030  ////////////////////////////////////////////
1031  utility::vector1< chemical::AA > rotameric_amino_acids;
1032  utility::vector1< Size > rotameric_n_chi;
1033  utility::vector1< Size > memory_use_rotameric;
1034 
1035  ////////////////////////////////////////////
1036  //// DATA FOR THE SEMI-ROTAMERIC AMINO ACIDS
1037  ////////////////////////////////////////////
1038 
1039  /// AA code for entry i
1041  /// Number of rotameric chi for entry i; the index of the non-rotameric chi is +1 of the value stored.
1042  utility::vector1< Size > srnchi;
1043  /// Decision: SCore the nonrotameric chi in a backbone INDependent manner?
1045  /// Decision: SAMPle the nonrotameric chi in a backbone INDependent manner?
1046  utility::vector1< bool > sampind;
1047  /// Is there symmetry about the rotameric chi? If so, periodicity is 180 degrees, else, 360.
1048  /// Furthermore, if it's symmetric, then the bbdep sampling is at 5 degree intervals and
1049  /// the bbind is at 0.5 degree intervals; otherwise, bbdep is at 10 degrees, and bbind is at 1.
1051  /// At what starting angle does the chi data come from?
1053 
1054  utility::vector1< Size > memory_use_semirotameric;
1055 
1056  /// Initialize the data.
1057 
1059  rotameric_amino_acids, rotameric_n_chi,
1060  sraa, srnchi, scind, sampind, sym, astr
1061  ); // use the same parameters as dun08 used to.
1062 
1063  for ( Size ii = 1; ii <= rotameric_amino_acids.size(); ++ii ) {
1064  std::string next_aa_in_library;
1065 
1066  chemical::AA ii_aa( rotameric_amino_acids[ ii ] );
1067  std::string ii_lc_3lc( chemical::name_from_aa( ii_aa ) );
1068  std::transform(ii_lc_3lc.begin(), ii_lc_3lc.end(), ii_lc_3lc.begin(), tolower);
1069  std::string library_name = basic::options::option[basic::options::OptionKeys::corrections::score::dun10_dir]() + "/" + ii_lc_3lc + regular_lib_suffix ;
1070  utility::io::izstream lib( library_name.c_str() );
1071  if ( !lib.good() ) {
1072  lib.close();
1073  library_name = basic::database::full_name( basic::options::option[basic::options::OptionKeys::corrections::score::dun10_dir]() + "/" + ii_lc_3lc + regular_lib_suffix );
1074  lib.open( library_name );
1075  }
1076  if ( !lib.good() ) {
1077  utility_exit_with_message( "Unable to open database file for Dun10 rotamer library: " + library_name );
1078  }
1079  TR << "Reading " << library_name << std::endl;
1080 
1082  ii_aa, rotameric_n_chi[ ii ], lib, false, next_aa_in_library, false );
1083  if ( next_aa_in_library != "" ) {
1084  std::cerr << "ERROR: Inappropriate read from dun10 input while reading " << ii_aa
1085  << ": \"" << next_aa_in_library << "\"" << std::endl;
1086  utility_exit();
1087  }
1088 
1089  memory_use_rotameric.push_back( newlib->memory_usage_in_bytes() );
1090 
1091  libraries_[ ii_aa ] = newlib();
1092  aa_libraries_[ ii_aa ] = newlib();
1093  libraries_ops_.push_back( newlib );
1094  }
1095 
1096  for ( Size ii = 1; ii <= sraa.size(); ++ii ) {
1097  chemical::AA ii_aa( sraa[ ii ] );
1098  std::string ii_lc_3lc( chemical::name_from_aa( ii_aa ) );
1099  std::transform(ii_lc_3lc.begin(), ii_lc_3lc.end(), ii_lc_3lc.begin(), tolower);
1100  Size const nrchi = srnchi[ ii ] + 1;
1101 
1102  std::string reg_lib_name = basic::options::option[basic::options::OptionKeys::corrections::score::dun10_dir]() + "/" + ii_lc_3lc + regular_lib_suffix ;
1103  std::string conmin_name = basic::options::option[basic::options::OptionKeys::corrections::score::dun10_dir]() + "/" + ii_lc_3lc + bbdep_contmin ;
1104  std::string rotdef_name = basic::options::option[basic::options::OptionKeys::corrections::score::dun10_dir]() + "/" + ii_lc_3lc + bbind_midfix + to_string(nrchi) + bbind_defs ;
1105  //std::string probs_name = basic::options::option[basic::options::OptionKeys::corrections::score::dun10_dir]() + "/" + ii_lc_3lc + bbind_midfix + to_string(nrchi) + bbind_probs ;
1106 
1107  utility::io::izstream lib( reg_lib_name.c_str() );
1108  utility::io::izstream contmin( conmin_name.c_str() );
1109  utility::io::izstream defs( rotdef_name.c_str() );
1110  //utility::io::izstream probs( probs_name.c_str() );
1111 
1112  if ( !lib.good() ) {
1113  defs.close();
1114  lib.close();
1115  contmin.close();
1116  //probs.close();
1117 
1118  reg_lib_name = basic::database::full_name( basic::options::option[basic::options::OptionKeys::corrections::score::dun10_dir]() + "/" + ii_lc_3lc + regular_lib_suffix );
1119  conmin_name = basic::database::full_name( basic::options::option[basic::options::OptionKeys::corrections::score::dun10_dir]() + "/" + ii_lc_3lc + bbdep_contmin );
1120  rotdef_name = basic::database::full_name( basic::options::option[basic::options::OptionKeys::corrections::score::dun10_dir]() + "/" + ii_lc_3lc + bbind_midfix + to_string(nrchi) + bbind_defs );
1121  //probs_name = basic::database::full_name( basic::options::option[basic::options::OptionKeys::corrections::score::dun10_dir]() + "/" + ii_lc_3lc + bbind_midfix + to_string(nrchi) + bbind_probs );
1122 
1123  lib.open(reg_lib_name);
1124  contmin.open(conmin_name);
1125  defs.open(rotdef_name);
1126  //probs.open(probs_name);
1127  }
1128 
1129  if ( !lib.good() ) {
1130  utility_exit_with_message( "Unable to open database file for Dun10 rotamer library: " + reg_lib_name );
1131  }
1132  if ( !contmin.good() ) {
1133  utility_exit_with_message( "Unable to open database file for Dun10 rotamer library: " + conmin_name );
1134  }
1135  if ( !defs.good() ) {
1136  utility_exit_with_message( "Unable to open database file for Dun10 rotamer library: " + rotdef_name );
1137  }
1138 
1139  TR << "Reading " << reg_lib_name << std::endl;
1140  TR << "Reading " << conmin_name << std::endl;
1141  TR << "Reading " << rotdef_name << std::endl;
1142  //TR << "Reading " << probs_name << std::endl;
1143 
1145  ii_aa, srnchi[ ii ],
1146  scind[ ii ], sampind[ ii ],
1147  sym[ ii ], astr[ ii ],
1148  defs, lib, contmin );
1149 
1150  memory_use_semirotameric.push_back( newlib->memory_usage_in_bytes() );
1151 
1152  libraries_[ ii_aa ] = newlib();
1153  aa_libraries_[ ii_aa ] = newlib();
1154  libraries_ops_.push_back( newlib );
1155  }
1156  TR << "Finished reading Dunbrack Libraries" << std::endl;
1157 
1158  clock_t stoptime = clock();
1159  TR << "Dunbrack 2010 library took " << ((double)stoptime-starttime)/CLOCKS_PER_SEC << " seconds to load from ASCII" << std::endl;
1160 
1161 
1162  TR << "Memory usage: " << std::endl;
1163  Size total( 0 );
1164  for ( Size ii = 1; ii <= memory_use_rotameric.size(); ++ii ) {
1165  total += memory_use_rotameric[ ii ];
1166  TR << chemical::name_from_aa(rotameric_amino_acids[ ii ]) << " with " << memory_use_rotameric[ ii ] << " bytes" << std::endl;
1167  }
1168 
1169  for ( Size ii = 1; ii <= memory_use_semirotameric.size(); ++ii ) {
1170  total += memory_use_semirotameric[ ii ];
1171  TR << chemical::name_from_aa(sraa[ ii ]) << " with " << memory_use_semirotameric[ ii ] << " bytes" << std::endl;
1172  }
1173  TR << "Total memory on Dunbrack Libraries: " << total << " bytes." << std::endl;
1174 
1175 }
1176 
1177 void
1179 {
1180  clock_t starttime = clock();
1181 
1182  std::string binary_filename = get_binary_name_10();
1183  utility::io::izstream binlib( binary_filename.c_str(), std::ios::in | std::ios::binary );
1184 
1185  if ( ! binlib ) {
1186  utility_exit_with_message( "Could not open binary Dunbrack10 file from database -- how did this happen?");
1187  }
1188 
1189  /// READ PREABMLE
1190  /// Even if binary file should change its structure in the future, version number should always be
1191  /// the first piece of data in the file.
1192  boost::int32_t version( 0 );
1193  binlib.read( (char*) & version, sizeof( boost::int32_t ));
1194 
1195  /// Version 1: write out hard coded parameters for 08 library. Verify when reading in
1196  /// the binary file that the parameters have not changed.
1197  /// DANGER DANGER DANGER
1198  /// If you change the binary format and adjust the preamble to the binary file,
1199  /// change the arithmetic in this function so that the correct number of bytes
1200  /// are jumped past.
1201 
1202  boost::int32_t n_rotameric_aas( 0 );
1203  binlib.read( (char*) & n_rotameric_aas, sizeof( boost::int32_t ) );
1204 
1205  boost::int32_t n_semirotameric_aas( 0 );
1206  binlib.read( (char*) & n_semirotameric_aas, sizeof( boost::int32_t ) );
1207 
1208  Size const n_rotameric_arrays_read_of_int32s = 2;
1209  Size const n_semirot_arrays_read_of_int32s = 5;
1210  Size const n_semirot_arrays_read_of_Reals = 1;
1211  Size const bytes_to_skip =
1212  ( n_rotameric_arrays_read_of_int32s * n_rotameric_aas +
1213  n_semirot_arrays_read_of_int32s * n_semirotameric_aas ) * sizeof( boost::int32_t ) +
1214  n_semirot_arrays_read_of_Reals * n_semirotameric_aas * sizeof( Real );
1215 
1216  //binlib.seekg( bytes_to_skip, std::ios::cur ); //seekg not available for izstream...
1217 
1218  char * temp_buffer = new char[ bytes_to_skip ];
1219  binlib.read( temp_buffer, bytes_to_skip );
1220  delete [] temp_buffer;
1221  /// END PREABMLE
1222 
1223 
1224  read_from_binary( binlib );
1225 
1226  clock_t stoptime = clock();
1227  TR << "Dunbrack 2010 library took " << ((double)stoptime-starttime)/CLOCKS_PER_SEC << " seconds to load from binary" << std::endl;
1228 }
1229 
1230 void
1232 {
1233  using namespace basic::options;
1234  using namespace basic::options::OptionKeys;
1235 
1236  if ( option[ corrections::score::dun10 ] ) {
1238  } else {
1240  }
1241 }
1242 
1243 void
1245 {
1246  std::string binary_filename = get_binary_name_02();
1247  std::string tempfilename = random_tempname( "dun02_binary" );
1248 
1249  TR << "Opening file " << tempfilename << " for output." << std::endl;
1250 
1251  utility::io::ozstream binlib( tempfilename.c_str(), std::ios::out | std::ios::binary );
1252  if ( binlib ) {
1253 
1254  /// WRITE PREABMLE
1255  /// Even if binary file should change its structure in the future, version number should always be
1256  /// the first piece of data in the file.
1257  boost::int32_t version( current_binary_format_version_id_02() );
1258  binlib.write( (char*) & version, sizeof( boost::int32_t ));
1259  /// END PREABMLE
1260 
1261  write_to_binary( binlib );
1262  binlib.close();
1263 
1264  // Move the temporary file to its permanent location
1265  TR << "Moving temporary file to " << binary_filename.c_str() << std::endl;
1266  rename( tempfilename.c_str(), binary_filename.c_str() );
1267  } else {
1268  TR << "Unable to open temporary file in rosetta database for writing the binary version of the Dunbrack02 library." << std::endl;
1269  }
1270 
1271 }
1272 
1273 
1274 void
1276 {
1277  std::string binary_filename = get_binary_name_10();
1278  std::string tempfilename = random_tempname( "dun10_binary" );
1279 
1280  TR << "Opening file " << tempfilename << " for output." << std::endl;
1281 
1282  utility::io::ozstream binlib( tempfilename.c_str(), std::ios::out | std::ios::binary );
1283  if ( binlib ) {
1284 
1285  /// WRITE PREABMLE
1286  /// Even if binary file should change its structure in the future, version number should always be
1287  /// the first piece of data in the file.
1288  boost::int32_t version( current_binary_format_version_id_10() );
1289  binlib.write( (char*) & version, sizeof( boost::int32_t ));
1290 
1291  utility::vector1< chemical::AA > rotameric_amino_acids;
1292  utility::vector1< Size > rotameric_n_chi;
1293 
1295  utility::vector1< Size > srnchi;
1297  utility::vector1< bool > sampind;
1300 
1302  rotameric_amino_acids, rotameric_n_chi,
1303  sraa, srnchi, scind, sampind, sym, astr );
1304 
1305  boost::int32_t nrotameric( static_cast< boost::int32_t > (rotameric_amino_acids.size() ));
1306  boost::int32_t nsemirotameric( static_cast< boost::int32_t > (sraa.size()) );
1307 
1308  binlib.write( (char*) & nrotameric, sizeof( boost::int32_t ) );
1309  binlib.write( (char*) & nsemirotameric, sizeof( boost::int32_t ) );
1310 
1311  /// 2.
1312  boost::int32_t * rotaa_bin = new boost::int32_t[ nrotameric ];
1313  boost::int32_t * rot_nchi_bin= new boost::int32_t[ nrotameric ];
1314 
1315  boost::int32_t * sraa_bin = new boost::int32_t[ nsemirotameric ];
1316  boost::int32_t * srnchi_bin = new boost::int32_t[ nsemirotameric ];
1317  boost::int32_t * scind_bin = new boost::int32_t[ nsemirotameric ];
1318  boost::int32_t * sampind_bin = new boost::int32_t[ nsemirotameric ];
1319  boost::int32_t * sym_bin = new boost::int32_t[ nsemirotameric ];
1320  Real * astr_bin = new Real[ nsemirotameric ];
1321 
1322  for ( Size ii = 1; ii <= rotameric_amino_acids.size(); ++ii ) {
1323  rotaa_bin[ ii - 1 ] = static_cast< boost::int32_t > ( rotameric_amino_acids[ ii ] );
1324  rot_nchi_bin[ ii - 1 ] = static_cast< boost::int32_t > ( rotameric_n_chi[ ii ] );
1325  }
1326  for ( Size ii = 1; ii <= sraa.size(); ++ii ) {
1327  sraa_bin[ ii - 1 ] = static_cast< boost::int32_t > ( sraa[ ii ] );
1328  srnchi_bin[ ii - 1 ] = static_cast< boost::int32_t > ( srnchi[ ii ] );
1329  scind_bin[ ii - 1 ] = static_cast< boost::int32_t > ( scind[ ii ] );
1330  sampind_bin[ ii - 1 ] = static_cast< boost::int32_t > ( sampind[ ii ] );
1331  sym_bin[ ii - 1 ] = static_cast< boost::int32_t > ( sym[ ii ] );
1332  astr_bin[ ii - 1 ] = astr[ ii ];
1333  }
1334 
1335 
1336  binlib.write( (char*) rotaa_bin, nrotameric * sizeof( boost::int32_t ));
1337  binlib.write( (char*) rot_nchi_bin, nrotameric * sizeof( boost::int32_t ));
1338 
1339  binlib.write( (char*) sraa_bin, nsemirotameric * sizeof( boost::int32_t ));
1340  binlib.write( (char*) srnchi_bin, nsemirotameric * sizeof( boost::int32_t ));
1341  binlib.write( (char*) scind_bin, nsemirotameric * sizeof( boost::int32_t ));
1342  binlib.write( (char*) sampind_bin, nsemirotameric * sizeof( boost::int32_t ));
1343  binlib.write( (char*) sym_bin, nsemirotameric * sizeof( boost::int32_t ));
1344  binlib.write( (char*) astr_bin, nsemirotameric * sizeof( Real ));
1345 
1346  delete [] rotaa_bin;
1347  delete [] rot_nchi_bin;
1348  delete [] sraa_bin;
1349  delete [] srnchi_bin;
1350  delete [] scind_bin;
1351  delete [] sampind_bin;
1352  delete [] sym_bin;
1353  delete [] astr_bin;
1354 
1355  /// END PREABMLE
1356 
1357  write_to_binary( binlib );
1358  binlib.close();
1359 
1360  // Move the temporary file to its permanent location
1361  //std::cerr << "Moving temporary file to " << binary_filename.c_str() << std::endl;
1362  rename( tempfilename.c_str(), binary_filename.c_str() );
1363  } else {
1364  TR << "Unable to open temporary file in rosetta database for writing the binary version of the Dunbrack '10 library." << std::endl;
1365  }
1366 }
1367 
1368 
1371 {
1372  using namespace basic::options;
1373  using namespace basic::options::OptionKeys;
1374 
1375  // Ugly C stuff...
1376 #ifdef WIN32
1377  char * tmpname_output = _tempnam( option[ in::path::database ](1).name().c_str(), prefix.c_str() );
1378 #elif __CYGWIN__
1379  char * tmpname_output = tempnam( option[ in::path::database ](1).name().c_str(), prefix.c_str() );
1380 #elif USEMPI
1381  // jk change this to mkstemp to prevent race condition
1382  // apl -- any reason mkstemp can't become the standard?
1383  std::string str_name = option[ in::path::database ](1).name() + "/" + prefix + "XXXXXX";
1384  char *tmpname_output = new char [str_name.size()+20]; // Why + 20? Apparently mkstemp can overflow.
1385  strcpy(tmpname_output, str_name.c_str()); // use strcpy to get char* instead of const char*
1386  int fid = mkstemp( tmpname_output );
1387  if ( fid == -1 ) { // error condition of mkstemp.
1388  utility_exit_with_message("Failed to open temporary file with mkstemp" );
1389  }
1390  close( fid ); // have to close the file in order to open it again.
1391  /// On the web, it says the file descriptor alone returned by mkstemp and not the file name is hacker safe.
1392  /// http://lists.virus.org/vulnwatch-0212/msg00023.html
1393  /// I suppose this is a security flaw with mini... just as soon as someone figures out
1394  /// how to open a stream with a file descriptor, this code should be replaced.
1395 #else
1396  char * tmpname_output = tempnam( option[ in::path::database ](1).name().c_str(), prefix.c_str() );
1397 #endif
1398 
1399  /// Copy c-style string to std::string.
1400  std::string tempfilename = tmpname_output;
1401 
1402 #ifdef USEMPI
1403  delete [] tmpname_output;
1404 #else
1405  free( tmpname_output );
1406 #endif
1407 
1408  return tempfilename;
1409 }
1410 
1413  chemical::AA aa,
1414  Size const n_chi,
1415  utility::io::izstream & library,
1416  bool dun02,
1417  std::string & next_aa_in_library,
1418  bool first_three_letter_code_already_read
1419 ) const
1420 {
1422  /// scope the case statements
1423  switch ( n_chi ) {
1424  case 1: {
1427  next_aa_in_library = r1->read_from_file( library, first_three_letter_code_already_read );
1428  rotlib = r1;
1429  break;
1430  }
1431  case 2: {
1434  next_aa_in_library = r2->read_from_file( library, first_three_letter_code_already_read );
1435  rotlib = r2;
1436  break;
1437  }
1438  case 3: {
1441  next_aa_in_library = r3->read_from_file( library, first_three_letter_code_already_read );
1442  rotlib = r3;
1443  break;
1444  }
1445  case 4: {
1448  next_aa_in_library = r4->read_from_file( library, first_three_letter_code_already_read );
1449  rotlib = r4;
1450  break;
1451  }
1452  default:
1453  utility_exit_with_message( "ERROR: too many chi angles desired for dunbrack library: " + n_chi );
1454  break;
1455  }
1456  return rotlib;
1457 
1458 }
1459 
1462  chemical::AA aa,
1463  Size const n_chi,
1464  bool dun02
1465 ) const
1466 {
1468  switch ( n_chi ) {
1469  case 1:
1470  rotlib = new RotamericSingleResidueDunbrackLibrary< ONE >( aa, dun02 );
1471  break;
1472  case 2:
1473  rotlib = new RotamericSingleResidueDunbrackLibrary< TWO >( aa, dun02 );
1474  break;
1475  case 3:
1476  rotlib = new RotamericSingleResidueDunbrackLibrary< THREE >( aa, dun02 );
1477  break;
1478  case 4:
1479  rotlib = new RotamericSingleResidueDunbrackLibrary< FOUR >( aa, dun02 );
1480  break;
1481  default:
1482  utility_exit_with_message( "ERROR: too many chi angles desired for dunbrack library: " + n_chi );
1483  break;
1484  }
1485  return rotlib;
1486 
1487 }
1488 
1489 
1492  chemical::AA aa,
1493  Size const nchi,
1494  bool const use_bbind_rnchi_scoring,
1495  bool const use_bbind_rnchi_sampling,
1496  bool const nrchi_is_symmetric,
1497  Real const nrchi_start_angle,
1498  utility::io::izstream & rotamer_definitions,
1499  utility::io::izstream & regular_library,
1500  utility::io::izstream & continuous_minimization_bbdep
1501  // phasing out bbind sampling -- utility::io::izstream & rnchi_bbind_probabilities
1502 ) const
1503 {
1505  /// scope the case statements
1506  switch ( nchi ) {
1507  case 1: {
1509  new SemiRotamericSingleResidueDunbrackLibrary< ONE >( aa, use_bbind_rnchi_scoring, use_bbind_rnchi_sampling );
1510  initialize_and_read_srsrdl( *r1, nrchi_is_symmetric, nrchi_start_angle,
1511  rotamer_definitions, regular_library, continuous_minimization_bbdep );
1512  rotlib = r1;
1513  break;
1514  }
1515  case 2: {
1517  new SemiRotamericSingleResidueDunbrackLibrary< TWO >( aa, use_bbind_rnchi_scoring, use_bbind_rnchi_sampling );
1518  initialize_and_read_srsrdl( *r2, nrchi_is_symmetric, nrchi_start_angle,
1519  rotamer_definitions, regular_library, continuous_minimization_bbdep );
1520  rotlib = r2;
1521  break;
1522  }
1523 
1524  default:
1525  utility_exit_with_message( "ERROR: too many chi angles desired for semi-rotameric dunbrack library: " + nchi );
1526  break;
1527  }
1528  return rotlib;
1529 
1530 }
1531 
1532 
1535  chemical::AA aa,
1536  Size const nchi,
1537  bool const use_bbind_rnchi_scoring,
1538  bool const use_bbind_rnchi_sampling,
1539  bool const nrchi_is_symmetric,
1540  Real const nrchi_start_angle
1541 ) const
1542 {
1544  switch ( nchi ) {
1545  case 1: {
1547  new SemiRotamericSingleResidueDunbrackLibrary< ONE >( aa, use_bbind_rnchi_scoring, use_bbind_rnchi_sampling );
1548  initialize_srsrdl( *r1, nrchi_is_symmetric, nrchi_start_angle );
1549  rotlib = r1;
1550  break;
1551  }
1552  case 2: {
1554  new SemiRotamericSingleResidueDunbrackLibrary< TWO >( aa, use_bbind_rnchi_scoring, use_bbind_rnchi_sampling );
1555  initialize_srsrdl( *r2, nrchi_is_symmetric, nrchi_start_angle );
1556  rotlib = r2;
1557  break;
1558  }
1559 
1560  default:
1561  utility_exit_with_message( "ERROR: too many chi angles desired for semi-rotameric dunbrack library: " + nchi );
1562  break;
1563  }
1564  return rotlib;
1565 
1566 }
1567 
1568 /// @details Build and initialize some of the data in an SRDL in preparation for
1569 /// binary file input -- that is, the SRDL does not have "read_from_file(s)" called
1570 /// before it is returned to the calling function. ATM not threadsafe.
1573  chemical::AA aa_in
1574 ) const
1575 {
1576  using namespace basic::options;
1577  using namespace basic::options::OptionKeys;
1578 
1579  static bool initialized( false );
1580 
1581  static utility::vector1< chemical::AA > rotameric_amino_acids;
1582  static utility::vector1< Size > rotameric_n_chi;
1583 
1585  static utility::vector1< Size > srnchi;
1586  static utility::vector1< bool > scind;
1587  static utility::vector1< bool > sampind;
1588  static utility::vector1< bool > sym;
1589  static utility::vector1< Real > astr;
1590 
1591  if ( ! initialized ) {
1592  /// put a mutex here...
1593  if ( option[ corrections::score::dun10 ] ) {
1595  rotameric_amino_acids, rotameric_n_chi,
1596  sraa, srnchi, scind, sampind, sym, astr );
1597  } else {
1599  rotameric_amino_acids, rotameric_n_chi );
1600  }
1601  initialized = true;
1602  }
1603 
1604  Size find_rot_aa = 1;
1605  while ( find_rot_aa <= rotameric_amino_acids.size() ) {
1606  if ( rotameric_amino_acids[ find_rot_aa ] == aa_in ) {
1607  return create_rotameric_dunlib( aa_in, rotameric_n_chi[ find_rot_aa ], ! (option[ corrections::score::dun10 ] ) );
1608  }
1609  ++find_rot_aa;
1610  }
1611 
1612  Size find_semirot_aa = 1;
1613  while ( find_semirot_aa <= sraa.size() ) {
1614  if ( sraa[ find_semirot_aa ] == aa_in ) {
1615  Size i = find_semirot_aa;
1616  return create_semi_rotameric_dunlib( aa_in, srnchi[i], scind[i], sampind[i], sym[i], astr[i] );
1617  }
1618  ++find_semirot_aa;
1619  }
1620  return 0;
1621 }
1622 
1623 
1624 
1625 /// @details Hard code this data in a single place; adjust the booleans for the backbone
1626 /// independent
1627 void
1629  utility::vector1< chemical::AA > & rotameric_amino_acids,
1630  utility::vector1< Size > & rotameric_n_chi,
1632  utility::vector1< Size > & srnchi,
1633  utility::vector1< bool > & scind,
1634  utility::vector1< bool > & sampind,
1637 )
1638 {
1639  using namespace chemical;
1640 
1641  /// Rotameric specifics
1642  rotameric_amino_acids.reserve( 10 ); rotameric_n_chi.reserve( 10 );
1643  rotameric_amino_acids.push_back( aa_cys ); rotameric_n_chi.push_back( 1 );
1644  rotameric_amino_acids.push_back( aa_ile ); rotameric_n_chi.push_back( 2 );
1645  rotameric_amino_acids.push_back( aa_lys ); rotameric_n_chi.push_back( 4 );
1646  rotameric_amino_acids.push_back( aa_leu ); rotameric_n_chi.push_back( 2 );
1647  rotameric_amino_acids.push_back( aa_met ); rotameric_n_chi.push_back( 3 );
1648  rotameric_amino_acids.push_back( aa_pro ); rotameric_n_chi.push_back( 3 );
1649  rotameric_amino_acids.push_back( aa_arg ); rotameric_n_chi.push_back( 4 );
1650  rotameric_amino_acids.push_back( aa_ser ); rotameric_n_chi.push_back( 1 );
1651  rotameric_amino_acids.push_back( aa_thr ); rotameric_n_chi.push_back( 1 );
1652  rotameric_amino_acids.push_back( aa_val ); rotameric_n_chi.push_back( 1 );
1653 
1654 
1655  /// Semi rotameric specifics
1656  Size const n_semi_rotameric_aas = 8;
1657  sraa.resize( n_semi_rotameric_aas );
1658  srnchi.resize( n_semi_rotameric_aas );
1659  scind.resize( n_semi_rotameric_aas );
1660  sampind.resize( n_semi_rotameric_aas );
1661  sym.resize( n_semi_rotameric_aas );
1662  astr.resize( n_semi_rotameric_aas );
1663 
1664 
1665  Size i = 0;
1666  sraa[++i] = aa_asp; srnchi[i] = 1; scind[i] = 0; sampind[i] = 0; sym[i]=1; astr[i] = -90;
1667  sraa[++i] = aa_glu; srnchi[i] = 2; scind[i] = 0; sampind[i] = 0; sym[i]=1; astr[i] = -90;
1668  sraa[++i] = aa_phe; srnchi[i] = 1; scind[i] = 0; sampind[i] = 0; sym[i]=1; astr[i] = -30;
1669  sraa[++i] = aa_his; srnchi[i] = 1; scind[i] = 0; sampind[i] = 0; sym[i]=0; astr[i] = -180;
1670  sraa[++i] = aa_asn; srnchi[i] = 1; scind[i] = 0; sampind[i] = 0; sym[i]=0; astr[i] = -180;
1671  sraa[++i] = aa_gln; srnchi[i] = 2; scind[i] = 0; sampind[i] = 0; sym[i]=0; astr[i] = -180;
1672  sraa[++i] = aa_trp; srnchi[i] = 1; scind[i] = 0; sampind[i] = 0; sym[i]=0; astr[i] = -180;
1673  sraa[++i] = aa_tyr; srnchi[i] = 1; scind[i] = 0; sampind[i] = 0; sym[i]=1; astr[i] = -30;
1674 
1675 }
1676 
1677 void
1679  utility::vector1< chemical::AA > & rotameric_amino_acids,
1680  utility::vector1< Size > & rotameric_n_chi
1681 )
1682 {
1683  using namespace chemical;
1684 
1685  utility::vector1< Size > nchi_for_aa;
1686  Size n_rotameric_aas;
1687  initialize_dun02_aa_parameters( nchi_for_aa, n_rotameric_aas );
1688  rotameric_amino_acids.resize( 0 ); rotameric_amino_acids.reserve( n_rotameric_aas );
1689  rotameric_n_chi.resize( 0 ); rotameric_n_chi.reserve( n_rotameric_aas );
1690 
1691  for ( Size ii = 1; ii <= num_canonical_aas; ++ii ) {
1692  if ( nchi_for_aa[ ii ] != 0 ) {
1693  rotameric_amino_acids.push_back( AA(ii) );
1694  rotameric_n_chi.push_back( nchi_for_aa[ ii ] );
1695  }
1696  }
1697 
1698 }
1699 
1700 void
1702  utility::vector1< Size > & nchi_for_aa,
1703  Size & n_rotameric_aas
1704 )
1705 {
1706  using namespace chemical;
1707  nchi_for_aa.resize( num_canonical_aas );
1708  std::fill( nchi_for_aa.begin(), nchi_for_aa.end(), 0 ); // overkill! ala, gly = 0...
1709  n_rotameric_aas = 0;
1710 
1711  nchi_for_aa[ aa_cys ] = 1; ++n_rotameric_aas;
1712  nchi_for_aa[ aa_asp ] = 2; ++n_rotameric_aas;
1713  nchi_for_aa[ aa_glu ] = 3; ++n_rotameric_aas;
1714  nchi_for_aa[ aa_phe ] = 2; ++n_rotameric_aas;
1715  nchi_for_aa[ aa_his ] = 2; ++n_rotameric_aas;
1716  nchi_for_aa[ aa_ile ] = 2; ++n_rotameric_aas;
1717  nchi_for_aa[ aa_lys ] = 4; ++n_rotameric_aas;
1718  nchi_for_aa[ aa_leu ] = 2; ++n_rotameric_aas;
1719  nchi_for_aa[ aa_met ] = 3; ++n_rotameric_aas;
1720  nchi_for_aa[ aa_asn ] = 2; ++n_rotameric_aas;
1721  nchi_for_aa[ aa_pro ] = 3; ++n_rotameric_aas;
1722  nchi_for_aa[ aa_gln ] = 3; ++n_rotameric_aas;
1723  nchi_for_aa[ aa_arg ] = 4; ++n_rotameric_aas;
1724  nchi_for_aa[ aa_ser ] = 1; ++n_rotameric_aas;
1725  nchi_for_aa[ aa_thr ] = 1; ++n_rotameric_aas;
1726  nchi_for_aa[ aa_val ] = 1; ++n_rotameric_aas;
1727  nchi_for_aa[ aa_trp ] = 2; ++n_rotameric_aas;
1728  nchi_for_aa[ aa_tyr ] = 2; ++n_rotameric_aas;
1729 
1730 }
1731 
1732 
1733 template < Size T >
1734 void
1737  bool const nrchi_is_symmetric,
1738  Real const nrchi_start_angle,
1739  utility::io::izstream & rotamer_definitions,
1740  utility::io::izstream & regular_library,
1741  utility::io::izstream & continuous_minimization_bbdep
1742  // phasing out bbind sampling -- utility::io::izstream & rnchi_bbind_probabilities
1743 ) const
1744 {
1745  initialize_srsrdl( srsrdl, nrchi_is_symmetric, nrchi_start_angle );
1746 
1747  srsrdl.read_from_files( rotamer_definitions, regular_library, continuous_minimization_bbdep );
1748 }
1749 
1750 template < Size T >
1751 void
1754  bool const nrchi_is_symmetric,
1755  Real const nrchi_start_angle
1756 ) const
1757 {
1758  Real const nrchi_periodicity = nrchi_is_symmetric ? 180.0 : 360.0;
1759  Real const nrchi_bbdep_step_size = nrchi_is_symmetric ? 5.0 : 10.0;
1760  Real const nrchi_bbind_step_size = nrchi_is_symmetric ? 0.5 : 1.0;
1761 
1762  srsrdl.set_nrchi_periodicity( nrchi_periodicity );
1763  srsrdl.set_nonrotameric_chi_start_angle( nrchi_start_angle );
1764  srsrdl.set_nonrotameric_chi_bbdep_scoring_step_size( nrchi_bbdep_step_size );
1765  srsrdl.set_nonrotameric_chi_bbind_scoring_step_size( nrchi_bbind_step_size );
1766 }
1767 
1768 ///////////////////////////////////////////////////////////////////////////////
1769 //
1770 // this is going to be wicked slow!!!
1771 // apl -- I love Phil's comment above, and though it no longer makes sense to
1772 // keep around, I have trouble deleting it. Input is pretty fast now.
1773 // This function seems unneccessary...
1774 void
1776  RotamerLibrary & rotamer_library
1777 )
1778 {
1779  rotamer_library.create_fa_dunbrack_libraries();
1780 }
1781 
1782 
1783 void
1785 {
1786  utility::io::ozstream out( filename );
1787  for ( library_iterator it=libraries_.begin(), eit=libraries_.end(); it!=eit; ++it ) {
1788  //it->second->write_to_file( out );
1789  }
1790 }
1791 
1792 /// @brief Generic "write out a library to binary" which has a straightforward
1793 /// nlibraries (aa, aa_data)* format. Works for both 02 and 08 libraries. The
1794 /// kind of aa_data written is left to the discression of the SinResDunLib
1795 /// derived classes.
1796 void
1797 RotamerLibrary::write_to_binary( utility::io::ozstream & out ) const
1798 {
1799 
1800  using namespace boost;
1801 
1802  Size count_libraries( 0 );
1803  for ( library_iterator it=libraries_.begin(), eit=libraries_.end(); it!=eit; ++it ) {
1805  dynamic_cast< SingleResidueDunbrackLibrary const * > ( it->second() );
1806 
1807  if ( srdl ) ++count_libraries; /// write out only the dunbrack libraries.
1808 
1809  }
1810 
1811  /// 1. How many libraries?
1812  boost::int32_t const nlibraries = count_libraries;
1813  out.write( (char*) & nlibraries, sizeof( boost::int32_t ) );
1814 
1815  for ( library_iterator it=libraries_.begin(), eit=libraries_.end(); it!=eit; ++it ) {
1817  dynamic_cast< SingleResidueDunbrackLibrary const * > ( it->second() );
1818 
1819  if ( ! srdl ) continue; /// write out only the dunbrack libraries.
1820 
1821  /// 2. Amino acid type of next library
1822  boost::int32_t const which_aa( it->first );
1823  out.write( (char*) &which_aa, sizeof( boost::int32_t ) );
1824 
1825  /// 3. Data for this amino acid type.
1826  srdl->write_to_binary( out );
1827  }
1828 
1829 }
1830 
1831 /// @details Generic binary file reader. Intended to work for both 02 and 08 Libraries.
1832 /// If a "preamble" starts the binary format, the input stream to this function must have already
1833 /// been walked past it. Somewhat circularly, the preamble is anything in the binary file that
1834 /// leads the "nlibraries (aa, aa_data)*" format perscribed in this function.
1835 void
1836 RotamerLibrary::read_from_binary( utility::io::izstream & in )
1837 {
1838 
1839  using namespace boost;
1840 
1841  /// 1. How many libraries?
1842  boost::int32_t nlibraries( 0 );
1843  in.read( (char*) &nlibraries, sizeof( boost::int32_t ) );
1844  for ( Size ii = 1; ii <= Size( nlibraries ); ++ii ) {
1845 
1846  /// 2. Which amino acid is next in the binary file?
1847  boost::int32_t which_aa32( chemical::aa_unk );
1848  in.read( (char*) &which_aa32, sizeof( boost::int32_t ) );
1849  AA which_aa( static_cast< AA >( which_aa32 ) );
1850 
1851  /// 3. Read the data associated with that amino acid.
1852  SingleResidueDunbrackLibraryOP single_lib = create_srdl( which_aa );
1853  if( !single_lib ){
1854  utility_exit_with_message( "Error reading single residue rotamer library for " + name_from_aa( which_aa ) );
1855  }
1856  single_lib->read_from_binary( in );
1857  add_residue_library( which_aa, single_lib );
1858  }
1859 }
1860 
1863 {
1864  if ( rotamer_library_ == 0 ) {
1867  }
1868  return *rotamer_library_;
1869 }
1870 
1871 
1874 {
1875  // get some info about amino acid type
1876  std::string aa_name3( rsd_type.name3() );
1877  Size n_rotlib_chi( rsd_type.nchi() - rsd_type.n_proton_chi() );
1878  chemical::AA aan( rsd_type.aa() );
1879  bool dun02( true );
1880 
1881  if ( ncaa_rotlibs_.find( aa_name3 ) == ncaa_rotlibs_.end() ) {
1882 
1883  // create izstream from path
1884  std::string dir_name = basic::database::full_name( "/rotamer/ncaa_rotlibs/" );
1885  std::string file_name = rsd_type.get_ncaa_rotlib_path();
1886  utility::io::izstream rotlib_in( dir_name + file_name );
1887  std::cout << "Reading in rot lib " << dir_name + file_name << "...";
1888 
1889  // get an instance of RotamericSingleResidueDunbrackLibrary, but need a RotamerLibrary to do it
1890  // this means that when ever you read in the NCAA libraries you will also read in the Dunbrack libraries
1891  // this may need to be a pointer to the full type and not just a SRRLOP
1893 
1894  // this comes almost directally from RotmerLibrary.cc::create_rotameric_dunlib()
1895  SingleResidueRotamerLibraryOP ncaa_rotlib;
1900 
1901  switch ( n_rotlib_chi ) {
1902  case 1:
1903  r1 = new RotamericSingleResidueDunbrackLibrary< ONE >( aan, dun02 );
1905  r1->read_from_file( rotlib_in, false );
1906  ncaa_rotlib = r1; break;
1907  case 2:
1908  r2 = new RotamericSingleResidueDunbrackLibrary< TWO >( aan, dun02 );
1910  r2->read_from_file( rotlib_in, false );
1911  ncaa_rotlib = r2; break;
1912  case 3:
1913  r3 = new RotamericSingleResidueDunbrackLibrary< THREE >( aan, dun02 );
1915  r3->read_from_file( rotlib_in, false );
1916  ncaa_rotlib = r3; break;
1917  case 4:
1918  r4 = new RotamericSingleResidueDunbrackLibrary< FOUR >( aan, dun02 );
1920  r4->read_from_file( rotlib_in, false );
1921  ncaa_rotlib = r4; break;
1922  default:
1923  utility_exit_with_message( "ERROR: too many chi angles desired for ncaa library: " + n_rotlib_chi );
1924  break;
1925  }
1926 
1927  // add new rotamer library to map
1928  ncaa_rotlibs_[ aa_name3 ] = ncaa_rotlib;
1929  std::cout << "done!" << std::endl;
1930  }
1931  return ( ncaa_rotlibs_.find( aa_name3 )->second)();
1932 }
1933 
1934 
1935 } // dunbrack
1936 } // namespace scoring
1937 } // namespace core