Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SemiRotamericSingleResidueDunbrackLibrary.tmpl.hh
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 core/scoring/dunbrack/SemiRotamericSingleResidueDunbrackLibrary.tmpl.hh
11 /// @brief Implementation of semi-rotameric rotamer libraries from Jun08
12 /// @author Andrew Leaver-Fay
13 
14 #ifndef INCLUDED_core_pack_dunbrack_SemiRotamericSingleResidueDunbrackLibrary_tmpl_hh
15 #define INCLUDED_core_pack_dunbrack_SemiRotamericSingleResidueDunbrackLibrary_tmpl_hh
16 
17 #if (defined WIN32) && (!defined WIN_PYROSETTA)
18  #define ZLIB_WINAPI // REQUIRED FOR WINDOWS
19 #endif
20 
21 // Unit Headers
23 
24 // Project Headers
27 #include <basic/basic.hh>
28 
29 // Package Headers
32 
33 // ObjexxFCL Headers
34 #include <ObjexxFCL/FArray2D.hh>
35 #include <ObjexxFCL/FArray3D.hh>
36 
37 // Utility Headers
38 #include <utility/exit.hh>
39 #include <utility/vector1.functions.hh>
40 
41 // Numeric Headers
42 #include <numeric/random/random.hh>
43 #include <numeric/MathTensor.hh>
44 #include <numeric/interpolation/spline/TricubicSpline.hh>
45 
46 // Boost Headers
47 #include <boost/cstdint.hpp>
48 
49 //Auto Headers
50 #include <platform/types.hh>
51 #include <core/types.hh>
52 #include <core/chemical/AA.hh>
54 #include <core/chemical/Adduct.hh>
71 #include <core/chemical/types.hh>
85 #include <core/graph/Graph.fwd.hh>
86 #include <core/graph/Graph.hh>
88 #include <core/id/AtomID.fwd.hh>
89 #include <core/id/DOF_ID.fwd.hh>
93 #include <core/id/TorsionID.fwd.hh>
117 #include <core/pose/PDBInfo.fwd.hh>
119 #include <core/pose/Pose.fwd.hh>
120 #include <core/pose/Pose.hh>
131 #include <utility/Bound.fwd.hh>
132 #include <utility/Bound.hh>
133 #include <utility/LexicographicalIterator.fwd.hh>
134 #include <utility/LexicographicalIterator.hh>
135 #include <utility/assert.hh>
136 #include <utility/down_cast.hh>
137 #include <utility/fixedsizearray1.fwd.hh>
138 #include <utility/fixedsizearray1.hh>
139 #include <utility/stream_util.hh>
140 #include <utility/string_util.hh>
141 #include <utility/vector1.fwd.hh>
142 #include <utility/vector1.hh>
143 #include <utility/vector1_bool.hh>
144 #include <utility/vectorL.fwd.hh>
145 #include <utility/vectorL.hh>
146 #include <utility/vectorL_Selector.hh>
147 #include <utility/vectorL_bool.hh>
148 #include <utility/file/FileName.fwd.hh>
149 #include <utility/file/FileName.hh>
150 #include <utility/file/PathName.fwd.hh>
151 #include <utility/file/PathName.hh>
152 #include <utility/file/gzip_util.hh>
153 #include <utility/io/irstream.fwd.hh>
154 #include <utility/io/irstream.hh>
155 #include <utility/io/izstream.fwd.hh>
156 #include <utility/io/izstream.hh>
157 #include <utility/io/mpistream.hh>
158 #include <utility/io/mpistream.ipp>
159 #include <utility/io/orstream.fwd.hh>
160 #include <utility/io/orstream.hh>
161 #include <utility/io/ozstream.fwd.hh>
162 #include <utility/io/ozstream.hh>
163 #include <utility/io/zipstream.hpp>
164 #include <utility/io/zipstream.ipp>
165 #include <utility/keys/AutoKey.fwd.hh>
166 #include <utility/keys/AutoKey.hh>
167 #include <utility/keys/Key.fwd.hh>
168 #include <utility/keys/Key.hh>
169 #include <utility/keys/Key2Tuple.fwd.hh>
170 #include <utility/keys/Key2Tuple.hh>
171 #include <utility/keys/Key3Tuple.fwd.hh>
172 #include <utility/keys/Key3Tuple.hh>
173 #include <utility/keys/Key4Tuple.fwd.hh>
174 #include <utility/keys/Key4Tuple.hh>
175 #include <utility/keys/KeyLess.fwd.hh>
176 #include <utility/keys/KeyLookup.fwd.hh>
177 #include <utility/keys/KeyLookup.hh>
178 #include <utility/keys/NoClient.fwd.hh>
179 #include <utility/keys/NoClient.hh>
180 #include <utility/keys/SmallKeyVector.fwd.hh>
181 #include <utility/keys/SmallKeyVector.hh>
182 #include <utility/keys/UserKey.fwd.hh>
183 #include <utility/keys/VariantKey.fwd.hh>
184 #include <utility/keys/VariantKey.hh>
185 #include <utility/options/AnyOption.fwd.hh>
186 #include <utility/options/AnyOption.hh>
187 #include <utility/options/AnyVectorOption.fwd.hh>
188 #include <utility/options/AnyVectorOption.hh>
189 #include <utility/options/BooleanOption.fwd.hh>
190 #include <utility/options/BooleanOption.hh>
191 #include <utility/options/BooleanVectorOption.fwd.hh>
192 #include <utility/options/BooleanVectorOption.hh>
193 #include <utility/options/FileOption.fwd.hh>
194 #include <utility/options/FileOption.hh>
195 #include <utility/options/FileVectorOption.fwd.hh>
196 #include <utility/options/FileVectorOption.hh>
197 #include <utility/options/IntegerOption.fwd.hh>
198 #include <utility/options/IntegerOption.hh>
199 #include <utility/options/IntegerVectorOption.fwd.hh>
200 #include <utility/options/IntegerVectorOption.hh>
201 #include <utility/options/Option.fwd.hh>
202 #include <utility/options/Option.hh>
203 #include <utility/options/OptionCollection.fwd.hh>
204 #include <utility/options/OptionCollection.hh>
205 #include <utility/options/PathOption.fwd.hh>
206 #include <utility/options/PathOption.hh>
207 #include <utility/options/PathVectorOption.fwd.hh>
208 #include <utility/options/PathVectorOption.hh>
209 #include <utility/options/RealOption.fwd.hh>
210 #include <utility/options/RealOption.hh>
211 #include <utility/options/RealVectorOption.fwd.hh>
212 #include <utility/options/RealVectorOption.hh>
213 #include <utility/options/ScalarOption.fwd.hh>
214 #include <utility/options/ScalarOption.hh>
215 #include <utility/options/ScalarOption_T_.fwd.hh>
216 #include <utility/options/ScalarOption_T_.hh>
217 #include <utility/options/StringOption.fwd.hh>
218 #include <utility/options/StringOption.hh>
219 #include <utility/options/StringVectorOption.fwd.hh>
220 #include <utility/options/StringVectorOption.hh>
221 #include <utility/options/VariantOption.fwd.hh>
222 #include <utility/options/VariantOption.hh>
223 #include <utility/options/VectorOption.fwd.hh>
224 #include <utility/options/VectorOption.hh>
225 #include <utility/options/VectorOption_T_.fwd.hh>
226 #include <utility/options/VectorOption_T_.hh>
227 #include <utility/options/mpi_stderr.hh>
228 #include <utility/options/keys/AnyOptionKey.fwd.hh>
229 #include <utility/options/keys/AnyOptionKey.hh>
230 #include <utility/options/keys/AnyVectorOptionKey.fwd.hh>
231 #include <utility/options/keys/AnyVectorOptionKey.hh>
232 #include <utility/options/keys/BooleanOptionKey.fwd.hh>
233 #include <utility/options/keys/BooleanOptionKey.hh>
234 #include <utility/options/keys/BooleanVectorOptionKey.fwd.hh>
235 #include <utility/options/keys/BooleanVectorOptionKey.hh>
236 #include <utility/options/keys/FileOptionKey.fwd.hh>
237 #include <utility/options/keys/FileOptionKey.hh>
238 #include <utility/options/keys/FileVectorOptionKey.fwd.hh>
239 #include <utility/options/keys/FileVectorOptionKey.hh>
240 #include <utility/options/keys/IntegerOptionKey.fwd.hh>
241 #include <utility/options/keys/IntegerOptionKey.hh>
242 #include <utility/options/keys/IntegerVectorOptionKey.fwd.hh>
243 #include <utility/options/keys/IntegerVectorOptionKey.hh>
244 #include <utility/options/keys/OptionKey.fwd.hh>
245 #include <utility/options/keys/OptionKey.hh>
246 #include <utility/options/keys/OptionKeys.hh>
247 #include <utility/options/keys/PathOptionKey.fwd.hh>
248 #include <utility/options/keys/PathOptionKey.hh>
249 #include <utility/options/keys/PathVectorOptionKey.fwd.hh>
250 #include <utility/options/keys/PathVectorOptionKey.hh>
251 #include <utility/options/keys/RealOptionKey.fwd.hh>
252 #include <utility/options/keys/RealOptionKey.hh>
253 #include <utility/options/keys/RealVectorOptionKey.fwd.hh>
254 #include <utility/options/keys/RealVectorOptionKey.hh>
255 #include <utility/options/keys/ScalarOptionKey.fwd.hh>
256 #include <utility/options/keys/ScalarOptionKey.hh>
257 #include <utility/options/keys/StringOptionKey.fwd.hh>
258 #include <utility/options/keys/StringOptionKey.hh>
259 #include <utility/options/keys/StringVectorOptionKey.fwd.hh>
260 #include <utility/options/keys/StringVectorOptionKey.hh>
261 #include <utility/options/keys/VectorOptionKey.fwd.hh>
262 #include <utility/options/keys/VectorOptionKey.hh>
263 #include <utility/options/keys/all.hh>
264 #include <utility/pointer/ReferenceCount.fwd.hh>
265 #include <utility/pointer/ReferenceCount.hh>
266 #include <utility/pointer/access_ptr.fwd.hh>
267 #include <utility/pointer/access_ptr.hh>
268 #include <utility/pointer/owning_ptr.functions.hh>
269 #include <utility/pointer/owning_ptr.fwd.hh>
270 #include <utility/pointer/owning_ptr.hh>
271 #include <utility/signals/BufferedSignalHub.fwd.hh>
272 #include <utility/signals/BufferedSignalHub.hh>
273 #include <utility/signals/Link.fwd.hh>
274 #include <utility/signals/Link.hh>
275 #include <utility/signals/LinkUnit.fwd.hh>
276 #include <utility/signals/LinkUnit.hh>
277 #include <utility/signals/SignalHub.fwd.hh>
278 #include <utility/signals/SignalHub.hh>
279 #include <numeric/NumericTraits.hh>
280 #include <numeric/constants.hh>
281 #include <numeric/conversions.hh>
282 #include <numeric/numeric.functions.hh>
283 #include <numeric/sphericalVector.fwd.hh>
284 #include <numeric/sphericalVector.hh>
285 #include <numeric/trig.functions.hh>
286 #include <numeric/types.hh>
287 #include <numeric/xyz.functions.fwd.hh>
288 #include <numeric/xyz.functions.hh>
289 #include <numeric/xyzMatrix.fwd.hh>
290 #include <numeric/xyzMatrix.hh>
291 #include <numeric/xyzVector.fwd.hh>
292 #include <numeric/xyzVector.hh>
293 #include <numeric/internal/ColPointers.hh>
294 #include <numeric/internal/ColVectors.hh>
295 #include <numeric/internal/ColsPointer.hh>
296 #include <numeric/internal/RowPointers.hh>
297 #include <numeric/internal/RowVectors.hh>
298 #include <numeric/internal/RowsPointer.hh>
299 #include <numeric/random/random.fwd.hh>
300 #include <numeric/random/uniform.fwd.hh>
301 #include <numeric/random/uniform.hh>
302 #include <ObjexxFCL/Dimension.fwd.hh>
303 #include <ObjexxFCL/Dimension.hh>
304 #include <ObjexxFCL/DimensionExpression.hh>
305 #include <ObjexxFCL/DynamicIndexRange.fwd.hh>
306 #include <ObjexxFCL/DynamicIndexRange.hh>
307 #include <ObjexxFCL/FArray.all.fwd.hh>
308 #include <ObjexxFCL/FArray.fwd.hh>
309 #include <ObjexxFCL/FArray.hh>
310 #include <ObjexxFCL/FArray1.all.fwd.hh>
311 #include <ObjexxFCL/FArray1.fwd.hh>
312 #include <ObjexxFCL/FArray1A.fwd.hh>
313 #include <ObjexxFCL/FArray1D.fwd.hh>
314 #include <ObjexxFCL/FArray1P.fwd.hh>
315 #include <ObjexxFCL/FArray2.all.fwd.hh>
316 #include <ObjexxFCL/FArray2.fwd.hh>
317 #include <ObjexxFCL/FArray2.hh>
318 #include <ObjexxFCL/FArray2A.fwd.hh>
319 #include <ObjexxFCL/FArray2A.hh>
320 #include <ObjexxFCL/FArray2D.fwd.hh>
321 #include <ObjexxFCL/FArray2P.fwd.hh>
322 #include <ObjexxFCL/FArray2P.hh>
323 #include <ObjexxFCL/FArray3.all.fwd.hh>
324 #include <ObjexxFCL/FArray3.fwd.hh>
325 #include <ObjexxFCL/FArray3.hh>
326 #include <ObjexxFCL/FArray3A.fwd.hh>
327 #include <ObjexxFCL/FArray3D.fwd.hh>
328 #include <ObjexxFCL/FArray3P.fwd.hh>
329 #include <ObjexxFCL/FArray4.all.fwd.hh>
330 #include <ObjexxFCL/FArray4.fwd.hh>
331 #include <ObjexxFCL/FArray4.hh>
332 #include <ObjexxFCL/FArray4A.fwd.hh>
333 #include <ObjexxFCL/FArray4D.fwd.hh>
334 #include <ObjexxFCL/FArray4D.hh>
335 #include <ObjexxFCL/FArray4P.fwd.hh>
336 #include <ObjexxFCL/FArray5.all.fwd.hh>
337 #include <ObjexxFCL/FArray5.fwd.hh>
338 #include <ObjexxFCL/FArray5A.fwd.hh>
339 #include <ObjexxFCL/FArray5D.fwd.hh>
340 #include <ObjexxFCL/FArray5P.fwd.hh>
341 #include <ObjexxFCL/FArray6.all.fwd.hh>
342 #include <ObjexxFCL/FArray6.fwd.hh>
343 #include <ObjexxFCL/FArray6A.fwd.hh>
344 #include <ObjexxFCL/FArray6D.fwd.hh>
345 #include <ObjexxFCL/FArray6P.fwd.hh>
346 #include <ObjexxFCL/FArrayInitializer.fwd.hh>
347 #include <ObjexxFCL/FArrayInitializer.hh>
348 #include <ObjexxFCL/FArraySection.fwd.hh>
349 #include <ObjexxFCL/FArraySection.hh>
350 #include <ObjexxFCL/FArrayTraits.fwd.hh>
351 #include <ObjexxFCL/FArrayTraits.hh>
352 #include <ObjexxFCL/Fmath.hh>
353 #include <ObjexxFCL/IndexRange.fwd.hh>
354 #include <ObjexxFCL/IndexRange.hh>
355 #include <ObjexxFCL/InitializerSentinel.hh>
356 #include <ObjexxFCL/KeyFArray1D.fwd.hh>
357 #include <ObjexxFCL/KeyFArray2D.fwd.hh>
358 #include <ObjexxFCL/KeyFArray3D.fwd.hh>
359 #include <ObjexxFCL/KeyFArray4D.fwd.hh>
360 #include <ObjexxFCL/KeyFArray5D.fwd.hh>
361 #include <ObjexxFCL/KeyFArray6D.fwd.hh>
362 #include <ObjexxFCL/Observer.fwd.hh>
363 #include <ObjexxFCL/Observer.hh>
364 #include <ObjexxFCL/ObserverMulti.hh>
365 #include <ObjexxFCL/ObserverSingle.hh>
366 #include <ObjexxFCL/ProxySentinel.hh>
367 #include <ObjexxFCL/SetWrapper.fwd.hh>
368 #include <ObjexxFCL/Star.fwd.hh>
369 #include <ObjexxFCL/Star.hh>
370 #include <ObjexxFCL/StaticIndexRange.fwd.hh>
371 #include <ObjexxFCL/StaticIndexRange.hh>
372 #include <ObjexxFCL/TypeTraits.hh>
373 #include <ObjexxFCL/char.functions.hh>
374 #include <ObjexxFCL/proxy_const_assert.hh>
375 #include <ObjexxFCL/string.functions.hh>
376 #include <algorithm>
377 #include <cassert>
378 #include <cmath>
379 #include <cstddef>
380 #include <cstdio>
381 #include <cstdlib>
382 #include <fstream>
383 #include <iomanip>
384 #include <ios>
385 #include <iosfwd>
386 #include <iostream>
387 #include <istream>
388 #include <iterator>
389 #include <limits>
390 #include <list>
391 #include <map>
392 #include <ostream>
393 #include <set>
394 #include <sstream>
395 #include <string>
396 #include <typeinfo>
397 #include <utility>
398 #include <vector>
399 #include <basic/MetricValue.fwd.hh>
400 #include <basic/datacache/BasicDataCache.fwd.hh>
401 #include <basic/interpolate.hh>
402 #include <basic/options/keys/OptionKeys.hh>
403 #include <basic/options/option.hh>
404 #include <boost/algorithm/string/erase.hpp>
405 #include <boost/bind.hpp>
406 #include <boost/config.hpp>
407 #include <boost/function.hpp>
408 #include <boost/pool/detail/mutex.hpp>
409 #include <boost/pool/poolfwd.hpp>
410 #include <zlib/zlib.h>
411 #include <zlib/zutil.h>
412 
413 namespace core {
414 namespace pack {
415 namespace dunbrack {
416 
417 using namespace ObjexxFCL;
418 
419 template < Size T >
421  chemical::AA const aa_in,
422  bool const backbone_independent_scoring, // true uses less memory
423  bool const backbone_independent_rotamer_sampling // true uses less memory
424 ) :
425  parent( aa_in, false /*dun02*/ ), // false, since the semi rotameric library is new in 2008
426  bbind_nrchi_scoring_( backbone_independent_scoring ),
427  bbind_nrchi_sampling_( backbone_independent_rotamer_sampling ),
428  nrchi_periodicity_( 0.0 ),
429  nrchi_lower_angle_( 0.0 ),
430  bbdep_nrchi_nbins_( 0 ),
431  bbdep_nrchi_binsize_( 0 ),
432  bbind_nrchi_nbins_( 0 ),
433  bbind_nrchi_binsize_( 0 ),
434  n_nrchi_sample_bins_( 0 )
435 {
436 
437 }
438 
439 template < Size T >
441 
442 template < Size T >
443 Real
445  conformation::Residue const & rsd,
447 ) const
448 {
449  if ( bbind_nrchi_scoring_ ) {
450  return rotamer_energy_deriv_bbind( rsd, scratch, false );
451  } else {
452  return rotamer_energy_deriv_bbdep( rsd, scratch, false );
453  }
454 }
455 
456 
457 template < Size T >
458 Real
460  conformation::Residue const & rsd,
462 ) const
463 {
464  if ( bbind_nrchi_scoring_ ) {
465  return rotamer_energy_deriv_bbind( rsd, scratch, true );
466  } else {
467  return rotamer_energy_deriv_bbdep( rsd, scratch, true );
468  }
469 }
470 
471 template < Size T >
472 Real
474  conformation::Residue const & rsd,
475  RotamerLibraryScratchSpace & scratch,
476  bool eval_deriv
477 ) const
478 {
479  assert( ! bbind_nrchi_scoring_ );
480 
481  parent::eval_rotameric_energy_deriv( rsd, scratch, eval_deriv );
482 
483  Real chidevpen_score( 0.0 );
484  for ( Size ii = 1; ii <= T; ++ii ) {
485  chidevpen_score += scratch.chidevpen()[ ii ];
486  }
487 
488  Real nrchi_score, dnrchiscore_dchi, dnrchiscore_dphi, dnrchiscore_dpsi;
489  nrchi_score = bbdep_nrchi_score( rsd, scratch,
490  dnrchiscore_dchi, dnrchiscore_dphi, dnrchiscore_dpsi );
491 
492  if ( nrchi_score != nrchi_score ) { //NaN check
493  nrchi_score = 0;
494  std::cerr << "NaN in SemiRot: " << rsd.seqpos() << " " << rsd.name() << std::endl;
495  }
496 
497  scratch.fa_dun_tot() = chidevpen_score + nrchi_score;
498  scratch.fa_dun_rot() = 0;
499  scratch.fa_dun_semi() = nrchi_score;
500  //scratch.fa_dun_dev() = chidevpensum; // keep original chidev score...
501 
502  //std::cout << "SRSRDL bbdep score: " << rsd.name() << " " <<
503  // rsd.mainchain_torsion( 1 ) << " " << rsd.mainchain_torsion( 2 ) <<
504  // " " << rsd.chi()[ T + 1 ] << ": " << nrchi_score << " " << chidevpen_score << " " << std::endl;
505 
506  if ( ! eval_deriv ) return chidevpen_score + nrchi_score;
507 
508  /// sum derivatives.
509  Real3 & dE_dbb( scratch.dE_dbb() );
510  Real3 & dE_dbb_dev( scratch.dE_dbb_dev() );
511  Real3 & dE_dbb_rot( scratch.dE_dbb_rot() );
512  Real3 & dE_dbb_semi( scratch.dE_dbb_semi() );
513  Real4 & dE_dchi( scratch.dE_dchi() );
514  Real4 & dE_dchi_dev( scratch.dE_dchi_dev() );
515  Real4 & dE_dchi_semi( scratch.dE_dchi_semi() );
516 
517  std::fill( dE_dchi.begin(), dE_dchi.end(), 0.0 );
518  std::fill( dE_dchi_dev.begin(), dE_dchi_dev.end(), 0.0 );
519  std::fill( dE_dchi_semi.begin(), dE_dchi_semi.end(), 0.0 );
520  std::fill( dE_dbb.begin(), dE_dbb.end(), 0.0 );
521  std::fill( dE_dbb_dev.begin(), dE_dbb_dev.end(), 0.0 );
522  std::fill( dE_dbb_rot.begin(), dE_dbb_rot.end(), 0.0 );
523  std::fill( dE_dbb_semi.begin(), dE_dbb_semi.end(), 0.0 );
524 
525  for ( Size i=1; i<= DUNBRACK_MAX_BBTOR; ++i ) {
526  dE_dbb[ i ] = scratch.dchidevpen_dbb()[ i ];
527  dE_dbb_dev[ i ] = scratch.dchidevpen_dbb()[ i ];
528  //dE_dbb_rot[ i ] = scratch.dneglnrotprob_dbb()[ i ];
529  }
530  dE_dbb[ RotamerLibraryScratchSpace::AA_PHI_INDEX ] += dnrchiscore_dphi;
531  dE_dbb[ RotamerLibraryScratchSpace::AA_PSI_INDEX ] += dnrchiscore_dpsi;
532  dE_dbb_semi[ RotamerLibraryScratchSpace::AA_PHI_INDEX ] = dnrchiscore_dphi;
533  dE_dbb_semi[ RotamerLibraryScratchSpace::AA_PSI_INDEX ] = dnrchiscore_dpsi;
534 
535 
536  for ( Size i=1; i <= T; ++i ) {
537  dE_dchi[ i ] = scratch.dchidevpen_dchi()[ i ];
538  dE_dchi_dev[ i ] = scratch.dchidevpen_dchi()[ i ];
539  }
540  dE_dchi[ T + 1 ] = dnrchiscore_dchi;
541  dE_dchi_semi[ T + 1 ] = dnrchiscore_dchi;
542 
543  parent::correct_termini_derivatives( rsd, scratch );
544 
545  return chidevpen_score + nrchi_score;
546 
547 }
548 
549 template < Size T >
550 Real
552  conformation::Residue const & rsd,
553  RotamerLibraryScratchSpace & scratch,
554  bool eval_deriv
555 ) const
556 {
557  assert( bbind_nrchi_scoring_ );
558 
559  Real rotameric_score = parent::eval_rotameric_energy_deriv( rsd, scratch, eval_deriv );
560 
561  /// The true score is -ln ( p0 ) + nrchi_score + chidev_penalty.
562  Real nrchi_score, dnrchiscore_dnrchi;
563  nrchi_score = bbind_nrchi_score( rsd, scratch, dnrchiscore_dnrchi );
564 
565  scratch.fa_dun_tot() = rotameric_score + nrchi_score;
566  //scratch.fa_dun_rot() = 0; // keep original rot score...
567  scratch.fa_dun_semi() = nrchi_score;
568  //scratch.fa_dun_dev() = chidevpensum; // keep original chidevpen score...
569 
570  if ( ! eval_deriv ) return rotameric_score + nrchi_score;
571 
572  /// sum derivatives.
573  Real3 & dE_dbb( scratch.dE_dbb() );
574  Real3 & dE_dbb_dev( scratch.dE_dbb_dev() );
575  Real3 & dE_dbb_rot( scratch.dE_dbb_rot() );
576  //Real3 & dE_dbb_semi( scratch.dE_dbb_semi() );
577  Real4 & dE_dchi( scratch.dE_dchi() );
578  Real4 & dE_dchi_dev( scratch.dE_dchi_dev() );
579  Real4 & dE_dchi_semi( scratch.dE_dchi_semi() );
580  std::fill( dE_dchi.begin(), dE_dchi.end(), 0.0 );
581  std::fill( dE_dchi_dev.begin(), dE_dchi_dev.end(), 0.0 );
582  std::fill( dE_dchi_semi.begin(), dE_dchi_semi.end(), 0.0 );
583 
584  // p0 - the base probability -- not modified by the chi-dev penalty
585  Real const rotprob( scratch.rotprob() );
586 
587  /*Size const nbb ( rsd.mainchain_torsions().size() );
588  Size const nchi( rsd.nchi() );
589 
590  dE_dbb.resize ( nbb );
591  dE_dchi.resize( nchi );*/
592 
593  Real const invp( ( rotprob == Real( 0.0 ) ) ? 0.0 : -1.0 / rotprob );
594 
595  for ( Size i=1; i<= DUNBRACK_MAX_BBTOR; ++i ) {
596  dE_dbb[ i ] = invp * scratch.drotprob_dbb()[ i ] + scratch.dchidevpen_dbb()[ i ];
597  dE_dbb_dev[ i ] = scratch.dchidevpen_dbb()[ i ];
598  dE_dbb_rot[ i ] = invp * scratch.drotprob_dbb()[ i ];
599  }
600 
601  for ( Size i=1; i<= T; ++i ) {
602  dE_dchi[ i ] = scratch.dchidevpen_dchi()[ i ];
603  dE_dchi_dev[ i ] = scratch.dchidevpen_dchi()[ i ];
604  }
605  dE_dchi[ T + 1 ] = dnrchiscore_dnrchi;
606  dE_dchi_semi[ T + 1 ] = dnrchiscore_dnrchi;
607 
608  parent::correct_termini_derivatives( rsd, scratch );
609 
610  return rotameric_score + nrchi_score;
611 }
612 
613 /// @details simple interpolation; derivatives discontinuous at grid points
614 template < Size T >
615 Real
617  conformation::Residue const & rsd,
618  RotamerLibraryScratchSpace & scratch,
619  Real & dnrchi_score_dnrchi
620 ) const
621 {
622  assert( bbind_nrchi_scoring_ );
623 
624  Size const packed_rotno( grandparent::rotwell_2_packed_rotno( scratch.rotwell() ));
625 
626  Real nrchi = rsd.chi( T + 1 );
627  Size nrchi_bin, nrchi_bin_next;
628  Real nrchi_alpha;
629 
630  get_bbind_nrchi_bin( nrchi, nrchi_bin, nrchi_bin_next, nrchi_alpha );
631 
632  Real const nrchi_beta = 1 - nrchi_alpha;
633  Real const score_lower_bin = bbind_non_rotameric_chi_scores_( nrchi_bin, packed_rotno );
634  Real const score_upper_bin = bbind_non_rotameric_chi_scores_( nrchi_bin_next, packed_rotno );
635 
636  dnrchi_score_dnrchi = ( score_upper_bin - score_lower_bin ) / bbind_nrchi_binsize_;
637  return nrchi_beta * score_lower_bin + nrchi_alpha * score_upper_bin;
638 }
639 
640 
641 /// @brief Trilinear interpolation. Derivatives discontinuous at edge planes.
642 template < Size T >
643 Real
645  conformation::Residue const & rsd,
646  RotamerLibraryScratchSpace & scratch,
647  Real & dnrchi_score_dnrchi,
648  Real & dnrchi_score_dphi,
649  Real & dnrchi_score_dpsi
650 ) const
651 {
652  assert( ! bbind_nrchi_scoring_ );
653 
654  Size const packed_rotno( parent::rotwell_2_packed_rotno( scratch.rotwell() ));
655 
656  Real nrchi = rsd.chi( T + 1 );
657  Size nrchi_bin, nrchi_bin_next;
658  Real nrchi_alpha;
659  get_bbdep_nrchi_bin( nrchi, nrchi_bin, nrchi_bin_next, nrchi_alpha );
660 
661  Real phi( parent::get_phi_from_rsd( rsd ) );
662  Real psi( parent::get_psi_from_rsd( rsd ) );
663 
664  // get phi/psi bins
665  Size phibin, phibin_next, psibin, psibin_next;
666  Real phi_alpha, psi_alpha;
667  // the alpha fraction being the fraction ( range [0,1)) of the way from the
668  // lower grid point to the upper grid point
669  parent::get_phipsi_bins(
670  phi, psi, phibin, psibin,
671  phibin_next, psibin_next,
672  phi_alpha, psi_alpha );
673 
674  assert( phibin >= 1 && phibin <= parent::N_PHIPSI_BINS );
675  assert( psibin >= 1 && psibin <= parent::N_PHIPSI_BINS );
676 
677  BBDepScoreInterpData const & d000( bbdep_nrc_interpdata_[ packed_rotno ]( phibin , psibin , nrchi_bin ));
678  BBDepScoreInterpData const & d001( bbdep_nrc_interpdata_[ packed_rotno ]( phibin , psibin , nrchi_bin_next ));
679  BBDepScoreInterpData const & d010( bbdep_nrc_interpdata_[ packed_rotno ]( phibin , psibin_next, nrchi_bin ));
680  BBDepScoreInterpData const & d011( bbdep_nrc_interpdata_[ packed_rotno ]( phibin , psibin_next, nrchi_bin_next ));
681  BBDepScoreInterpData const & d100( bbdep_nrc_interpdata_[ packed_rotno ]( phibin_next, psibin , nrchi_bin ));
682  BBDepScoreInterpData const & d101( bbdep_nrc_interpdata_[ packed_rotno ]( phibin_next, psibin , nrchi_bin_next ));
683  BBDepScoreInterpData const & d110( bbdep_nrc_interpdata_[ packed_rotno ]( phibin_next, psibin_next, nrchi_bin ));
684  BBDepScoreInterpData const & d111( bbdep_nrc_interpdata_[ packed_rotno ]( phibin_next, psibin_next, nrchi_bin_next ));
685 
686  Real interpolated_energy(0.0);
687 
689  d000.value_, d000.dsecox_, d000.dsecoy_, d000.dsecoz_, d000.dsecoxy_, d000.dsecoxz_, d000.dsecoyz_, d000.dsecoxyz_,
690  d001.value_, d001.dsecox_, d001.dsecoy_, d001.dsecoz_, d001.dsecoxy_, d001.dsecoxz_, d001.dsecoyz_, d001.dsecoxyz_,
691  d010.value_, d010.dsecox_, d010.dsecoy_, d010.dsecoz_, d010.dsecoxy_, d010.dsecoxz_, d010.dsecoyz_, d010.dsecoxyz_,
692  d011.value_, d011.dsecox_, d011.dsecoy_, d011.dsecoz_, d011.dsecoxy_, d011.dsecoxz_, d011.dsecoyz_, d011.dsecoxyz_,
693  d100.value_, d100.dsecox_, d100.dsecoy_, d100.dsecoz_, d100.dsecoxy_, d100.dsecoxz_, d100.dsecoyz_, d100.dsecoxyz_,
694  d101.value_, d101.dsecox_, d101.dsecoy_, d101.dsecoz_, d101.dsecoxy_, d101.dsecoxz_, d101.dsecoyz_, d101.dsecoxyz_,
695  d110.value_, d110.dsecox_, d110.dsecoy_, d110.dsecoz_, d110.dsecoxy_, d110.dsecoxz_, d110.dsecoyz_, d110.dsecoxyz_,
696  d111.value_, d111.dsecox_, d111.dsecoy_, d111.dsecoz_, d111.dsecoxy_, d111.dsecoxz_, d111.dsecoyz_, d111.dsecoxyz_,
697  phi_alpha, psi_alpha, nrchi_alpha,
698  10, 10, bbdep_nrchi_binsize_,
699  interpolated_energy,
700  dnrchi_score_dphi,
701  dnrchi_score_dpsi,
702  dnrchi_score_dnrchi );
703 
704  return interpolated_energy;
705 
706  /* Trilinear interpolation scheme below
707  /// I would have defined this trilinear interpolation in the numeric library but for
708  /// two problems: the bin width is not uniform for all three dimensions, and the
709  /// data structure "F" that the interpolation library wants to read from must be indexed
710  /// from 0, which, while possible with FArrays is distinctly not fun. Indices that work
711  /// for the other 1-based tables will not work for a 0-based table; code to compute indices
712  /// needs to be nearly duplicated. The better solution would be to adapt the numeric
713  /// libraries to use 1-based indexing, since nothing in Rosetta uses 0-based indexing.
714 
715  Real const
716  flll( bbdep_non_rotameric_chi_scores_[ packed_rotno ]( phibin , psibin , nrchi_bin )),
717  fllu( bbdep_non_rotameric_chi_scores_[ packed_rotno ]( phibin , psibin , nrchi_bin_next )),
718  flul( bbdep_non_rotameric_chi_scores_[ packed_rotno ]( phibin , psibin_next, nrchi_bin )),
719  fluu( bbdep_non_rotameric_chi_scores_[ packed_rotno ]( phibin , psibin_next, nrchi_bin_next )),
720  full( bbdep_non_rotameric_chi_scores_[ packed_rotno ]( phibin_next, psibin , nrchi_bin )),
721  fulu( bbdep_non_rotameric_chi_scores_[ packed_rotno ]( phibin_next, psibin , nrchi_bin_next )),
722  fuul( bbdep_non_rotameric_chi_scores_[ packed_rotno ]( phibin_next, psibin_next, nrchi_bin )),
723  fuuu( bbdep_non_rotameric_chi_scores_[ packed_rotno ]( phibin_next, psibin_next, nrchi_bin_next ));
724 
725  //if ( flll > 1e16 ) {std::cout << "inf: flll " << phibin << " " << psibin << " " << phibin_next << " " << psibin_next << " " << nrchi_bin << " " << nrchi_bin_next << std::endl; }
726  //if ( fllu > 1e16 ) {std::cout << "inf: fllu " << phibin << " " << psibin << " " << phibin_next << " " << psibin_next << " " << nrchi_bin << " " << nrchi_bin_next << std::endl; }
727  //if ( flul > 1e16 ) {std::cout << "inf: flul " << phibin << " " << psibin << " " << phibin_next << " " << psibin_next << " " << nrchi_bin << " " << nrchi_bin_next << std::endl; }
728  //if ( fluu > 1e16 ) {std::cout << "inf: fluu " << phibin << " " << psibin << " " << phibin_next << " " << psibin_next << " " << nrchi_bin << " " << nrchi_bin_next << std::endl; }
729  //if ( full > 1e16 ) {std::cout << "inf: full " << phibin << " " << psibin << " " << phibin_next << " " << psibin_next << " " << nrchi_bin << " " << nrchi_bin_next << std::endl; }
730  //if ( fulu > 1e16 ) {std::cout << "inf: fulu " << phibin << " " << psibin << " " << phibin_next << " " << psibin_next << " " << nrchi_bin << " " << nrchi_bin_next << std::endl; }
731  //if ( fuul > 1e16 ) {std::cout << "inf: fuul " << phibin << " " << psibin << " " << phibin_next << " " << psibin_next << " " << nrchi_bin << " " << nrchi_bin_next << std::endl; }
732  //if ( fuuu > 1e16 ) {std::cout << "inf: fuuu " << phibin << " " << psibin << " " << phibin_next << " " << psibin_next << " " << nrchi_bin << " " << nrchi_bin_next << std::endl; }
733 
734 
735  Real const a1 = phi_alpha, a2 = psi_alpha, a3 = nrchi_alpha;
736  Real const b1 = 1 - a1, b2 = 1 - a2, b3 = 1 - a3;
737 
738  dnrchi_score_dphi = (
739  ( b2 * b3 * ( full - flll ) ) + ( a2 * b3 * ( fuul - flul ) ) +
740  ( b2 * a3 * ( fulu - fllu ) ) + ( a2 * a3 * ( fuuu - fluu ) ) ) / parent::PHIPSI_BINRANGE;
741  dnrchi_score_dpsi = (
742  ( b1 * b3 * ( flul - flll ) ) + ( a1 * b3 * ( fuul - full ) ) +
743  ( b1 * a3 * ( fluu - fllu ) ) + ( a1 * a3 * ( fuuu - fulu ) ) ) / parent::PHIPSI_BINRANGE;
744  dnrchi_score_dnrchi = (
745  ( b1 * b2 * ( fllu - flll ) ) + ( a1 * b2 * ( fulu - full ) ) +
746  ( b1 * a2 * ( fluu - flul ) ) + ( a1 * a2 * ( fuuu - fuul ) ) ) / bbdep_nrchi_binsize_;
747 
748  return
749  ( b1 * b2 * b3 * flll ) +
750  ( a1 * b2 * b3 * full ) +
751  ( b1 * a2 * b3 * flul ) +
752  ( a1 * a2 * b3 * fuul ) +
753  ( b1 * b2 * a3 * fllu ) +
754  ( a1 * b2 * a3 * fulu ) +
755  ( b1 * a2 * a3 * fluu ) +
756  ( a1 * a2 * a3 * fuuu ); */
757 
758 }
759 
760 /// @brief Returns the energy of the lowest-energy rotamer accessible to the given residue
761 /// (based on e.g. its current phi and psi values).
762 /// If curr_rotamer_only is true, then consider only the idealized version of the
763 /// residue's current rotamer (local optimum); otherwise, consider all rotamers (global optimum).
764 template < Size T >
765 Real
767  conformation::Residue const & rsd,
768  bool curr_rotamer_only,
770 ) const
771 {
772  assert( rsd.nchi() == T+1 );
773  Real nrchi_score( 0 );
774  if ( curr_rotamer_only ) {
775  Real dnrchiscore_dchi, dnrchiscore_dphi, dnrchiscore_dpsi;
776  // Unused variable, but since thescratch is a non-const reference, it seems wise to continue calling the method
777  //Real rotameric_score =
778  parent::eval_rotameric_energy_deriv( rsd, scratch, false);
779 
780  nrchi_score = bbdep_nrchi_score( rsd, scratch, dnrchiscore_dchi, dnrchiscore_dphi, dnrchiscore_dpsi );
781  core::conformation::Residue rsd_copy (rsd);
782  utility::vector1< Real > rsd_chi=rsd.chi();
783 
784  for ( Size jj = 0; jj <= bbdep_nrchi_nbins_; ++jj ) {
785  rsd_chi[rsd_copy.nchi()]=nrchi_lower_angle_+bbdep_nrchi_binsize_*jj;
786  rsd_copy.chi(rsd_chi);
787  parent::eval_rotameric_energy_deriv( rsd_copy, scratch, false);
788  Real tmp_nrchi_score=bbdep_nrchi_score( rsd_copy, scratch, dnrchiscore_dchi, dnrchiscore_dphi, dnrchiscore_dpsi );
789  if ( tmp_nrchi_score < nrchi_score)
790  nrchi_score=tmp_nrchi_score;
791  }
792 
793  } else {
795  core::pack::dunbrack::SingleResidueDunbrackLibraryCAP dunlib( static_cast< SingleResidueDunbrackLibrary const * > ( rotlib() ));
796 
797  Real const phi( parent::get_phi_from_rsd( rsd ) );
798  Real const psi( parent::get_psi_from_rsd( rsd ) );
799 
800  utility::vector1< DunbrackRotamerSampleData > rotamer_samples=dunlib->get_all_rotamer_samples( phi, psi);
801  //this could be smarter since the T+1 position of the sc_torsions are not used
802 
803  Real dnrchiscore_dchi, dnrchiscore_dphi, dnrchiscore_dpsi;
804  parent::eval_rotameric_energy_deriv( rsd, scratch, false);
805  nrchi_score = bbdep_nrchi_score( rsd, scratch, dnrchiscore_dchi, dnrchiscore_dphi, dnrchiscore_dpsi );
806  Real tmp_nrchi_score;
807  //search the space of terminal chiT
808  core::conformation::Residue rsd_copy (rsd);
809  utility::vector1< Real > rsd_chi=rsd.chi();
810 
811  for ( Size jj = 1; jj <= rotamer_samples.size(); ++jj ) {
812 
813  for ( Size ii = 1; ii <= T; ++ii ) {
814  rsd_chi[ii]=rotamer_samples[jj].chi_mean()[ii];
815  }
816 
817  for ( Size kk = 0; kk <= bbdep_nrchi_nbins_; ++kk ) {
818  rsd_chi[rsd_copy.nchi()]=nrchi_lower_angle_+bbdep_nrchi_binsize_*kk;
819  rsd_copy.chi(rsd_chi);
820  parent::eval_rotameric_energy_deriv( rsd_copy, scratch, false);
821  tmp_nrchi_score=bbdep_nrchi_score( rsd_copy, scratch, dnrchiscore_dchi, dnrchiscore_dphi, dnrchiscore_dpsi );
822  if ( tmp_nrchi_score < nrchi_score)
823  nrchi_score=tmp_nrchi_score;
824  }
825 
826  }
827  }
828 
829  return nrchi_score;
830 }
831 
832 
833 template < Size T >
834 void
836  conformation::Residue const & rsd,
837  RotamerLibraryScratchSpace & scratch,
838  numeric::random::RandomGenerator & RG,
839  ChiVector & new_chi_angles,
840  bool perturb_from_rotamer_center
841 ) const
842 {
843  if ( bbind_nrchi_sampling_ ) {
844  assign_random_rotamer_with_bias_bbind( rsd, scratch, RG, new_chi_angles, perturb_from_rotamer_center );
845  } else {
846  assign_random_rotamer_with_bias_bbdep( rsd, scratch, RG, new_chi_angles, perturb_from_rotamer_center );
847  }
848 
849 }
850 
851 template < Size T >
852 void
854  conformation::Residue const & rsd,
855  RotamerLibraryScratchSpace & scratch,
856  numeric::random::RandomGenerator & RG,
857  ChiVector & new_chi_angles,
858  bool perturb_from_rotamer_center
859 ) const
860 {
861  // Parent will pick a rotwell for the rotameric chi.
862  Size packed_rotno( 0 );
863  parent::assign_random_rotamer( rsd, scratch, RG, new_chi_angles, perturb_from_rotamer_center, packed_rotno );
864 
865  /// Now, given the packed_rotno for the rotameric chi, pick a non-rotameric chi sample.
866  Real random_prob = RG.uniform();
867  Size count( 0 ), nrchi_bin( 0 );
868  while ( random_prob > 0 ) {
869  nrchi_bin = bbind_rotamers_sorted_by_probability_( ++count, packed_rotno );
870  random_prob -= bbind_rotamers_to_sample_( nrchi_bin, packed_rotno ).prob_;
871  if ( count == n_nrchi_sample_bins_ ) break;
872  }
873 
874  if ( perturb_from_rotamer_center ) {
875  /// Could be a lot of work to bias the sample in this well by the continuous energy distribution.
876  /// why not just sample uniformly in this well?
877 
878  Real nrchi_prob = RG.uniform();
879  Real left( bbind_rotamers_to_sample_( nrchi_bin, packed_rotno ).left_ );
880  Real right( bbind_rotamers_to_sample_( nrchi_bin, packed_rotno ).right_ );
881  assert( left < right ); // I'm 99% this is true, that bins don't wrap around the center divide.
882 
883  new_chi_angles[ T + 1 ] = left + (left-right) * nrchi_prob;
884  } else {
885  new_chi_angles[ T + 1 ] = bbind_rotamers_to_sample_( nrchi_bin, packed_rotno ).median_;
886  }
887 }
888 
889 
890 template < Size T >
891 void
893  conformation::Residue const & rsd,
894  RotamerLibraryScratchSpace & scratch,
895  numeric::random::RandomGenerator & RG,
896  ChiVector & new_chi_angles,
897  bool perturb_from_rotamer_center
898 ) const
899 {
900  Real random_prob = RG.uniform();
901 
902  Real const phi( parent::get_phi_from_rsd( rsd ) );
903  Real const psi( parent::get_psi_from_rsd( rsd ) );
904 
905  Size phibin, psibin, phibin_next, psibin_next;
906  Real phi_alpha, psi_alpha;
907  parent::get_phipsi_bins( phi, psi, phibin, psibin, phibin_next, psibin_next,phi_alpha, psi_alpha );
908 
909  BBDepNRChiSample< Real > interpolated_nrchi_sample;
910  Size count( 0 );
911  while ( random_prob > 0 ) {
912  BBDepNRChiSample<> const & nrchi_sample_00(
913  bbdep_rotamers_to_sample_( phibin, psibin, ++count ));
914 
915  interpolated_nrchi_sample = interpolate_bbdep_nrchi_sample(
916  nrchi_sample_00.packed_rotno_, nrchi_sample_00.nrchi_bin_,
917  phibin, psibin, phibin_next, psibin_next,
918  phi_alpha, psi_alpha
919  );
920 
921  random_prob -= interpolated_nrchi_sample.prob_;
922  if ( count == bbdep_rotamers_to_sample_.size3() ) break;
923  }
924 
925  /// Get chimean and chisdves for rotameric chi
926  Size packed_rotno = interpolated_nrchi_sample.packed_rotno_;
927  PackedDunbrackRotamer< T, Real > interpolated_rotamer;
928  parent::interpolate_rotamers( scratch, packed_rotno,
929  phibin, psibin, phibin_next, psibin_next, phi_alpha, psi_alpha,
930  interpolated_rotamer );
931 
932  this->assign_chi_for_interpolated_rotamer( interpolated_rotamer, rsd, RG, new_chi_angles, perturb_from_rotamer_center );
933 
934  if ( ! perturb_from_rotamer_center ) {
935  new_chi_angles[ T + 1 ] = interpolated_nrchi_sample.nrchi_mean_;
936  } else {
937  new_chi_angles[ T + 1 ] = interpolated_nrchi_sample.nrchi_mean_ +
938  RG.gaussian() * interpolated_nrchi_sample.nrchi_sd_;
939  }
940 }
941 
942 
943 template < Size T >
944 void
946  pose::Pose const & pose,
947  scoring::ScoreFunction const & scorefxn,
948  pack::task::PackerTask const & task,
949  graph::GraphCOP packer_neighbor_graph,
950  chemical::ResidueTypeCOP concrete_residue,
951  conformation::Residue const& existing_residue,
952  utility::vector1< utility::vector1< Real > > const & extra_chi_steps,
953  bool buried,
954  RotamerVector & rotamers
955 ) const
956 {
957  if ( bbind_nrchi_sampling_ ) {
958  fill_rotamer_vector_bbind( pose, scorefxn, task, packer_neighbor_graph,
959  concrete_residue, existing_residue, extra_chi_steps, buried, rotamers );
960  } else {
961  fill_rotamer_vector_bbdep( pose, scorefxn, task, packer_neighbor_graph,
962  concrete_residue, existing_residue, extra_chi_steps, buried, rotamers );
963  }
964 }
965 
966 template < Size T >
967 void
969  pose::Pose const & pose,
970  scoring::ScoreFunction const & scorefxn,
971  pack::task::PackerTask const & task,
972  graph::GraphCOP packer_neighbor_graph,
973  chemical::ResidueTypeCOP concrete_residue,
974  conformation::Residue const & existing_residue,
975  utility::vector1< utility::vector1< Real > > const & extra_chi_steps,
976  bool buried,
977  RotamerVector & rotamers
978 ) const
979 {
981 
982  /// Save backbone interpolation data for reuse
983  Real phi( parent::get_phi_from_rsd( existing_residue ) );
984  Real psi( parent::get_psi_from_rsd( existing_residue ) );
985  Size phibin, psibin, phibin_next, psibin_next;
986  Real phi_alpha, psi_alpha;
987  parent::get_phipsi_bins( phi, psi, phibin, psibin, phibin_next, psibin_next, phi_alpha, psi_alpha );
988 
989  utility::vector1< Real > probs_of_next_rotamers( grandparent::n_packed_rots() );
990  utility::vector1< Size > next_nrchi_rotamer_to_take( grandparent::n_packed_rots(), 1 );
991  typename utility::vector1< PackedDunbrackRotamer< T, Real > > interpolated_rotamers( grandparent::n_packed_rots() );
992 
993  for ( Size ii = 1; ii <= grandparent::n_packed_rots(); ++ii ) {
995  scratch, ii,
996  phibin, psibin,
997  phibin_next, psibin_next,phi_alpha, psi_alpha,
998  interpolated_rotamers[ ii ] );
999 
1000  probs_of_next_rotamers[ ii ] = interpolated_rotamers[ ii ].rotamer_probability() *
1001  bbind_rotamers_to_sample_( bbind_rotamers_sorted_by_probability_( 1, ii ), ii ).prob_;
1002  }
1003 
1004  Size const max_rots_that_can_be_built = grandparent::n_packed_rots() * n_nrchi_sample_bins_;
1005 
1006  Real const requisit_probability = buried ? 0.87 : 0.95;
1007  //grandparent::probability_to_accumulate_while_building_rotamers( buried ); -- 98/95 split generates too many samples
1008  Real accumulated_probability( 0.0 );
1009 
1010  Size count_rotamers_built = 0;
1011  while ( accumulated_probability < requisit_probability ) {
1012  /// Build the most probable rotamer of those remaining
1013  Size const which_packedrotno_to_build = utility::arg_max( probs_of_next_rotamers );
1014 
1015  Size const count = next_nrchi_rotamer_to_take[ which_packedrotno_to_build ];
1016  Size const next_count = ++next_nrchi_rotamer_to_take[ which_packedrotno_to_build ];
1017 
1018  Size const nrchi_rotno = bbind_rotamers_sorted_by_probability_( count, which_packedrotno_to_build );
1019  Size const next_nrchi_rotno = count < n_nrchi_sample_bins_ ?
1020  bbind_rotamers_sorted_by_probability_( next_count, which_packedrotno_to_build ) : 0 ;
1021 
1022  accumulated_probability += probs_of_next_rotamers[ which_packedrotno_to_build ];
1023  ++count_rotamers_built;
1024 
1025  if ( probs_of_next_rotamers[ which_packedrotno_to_build ] <= 0 ) break; // this should never happen.
1026 
1027  if ( next_nrchi_rotno == 0 ) {
1028  probs_of_next_rotamers[ which_packedrotno_to_build ] = 0;
1029  } else {
1030  probs_of_next_rotamers[ which_packedrotno_to_build ] =
1031  interpolated_rotamers[ which_packedrotno_to_build ].rotamer_probability() *
1032  bbind_rotamers_to_sample_(
1033  next_nrchi_rotno,
1034  which_packedrotno_to_build ).prob_;
1035  }
1036 
1037  build_bbind_rotamers(
1038  pose, scorefxn, task, packer_neighbor_graph,
1039  concrete_residue, existing_residue, extra_chi_steps, buried,
1040  interpolated_rotamers[ which_packedrotno_to_build ], nrchi_rotno,
1041  bbind_rotamers_to_sample_( nrchi_rotno, which_packedrotno_to_build ),
1042  rotamers);
1043 
1044  if ( count_rotamers_built == max_rots_that_can_be_built ) break;
1045  }
1046 }
1047 
1048 
1049 template < Size T >
1050 void
1052  pose::Pose const & pose,
1053  scoring::ScoreFunction const & scorefxn,
1054  pack::task::PackerTask const & task,
1055  graph::GraphCOP packer_neighbor_graph,
1056  chemical::ResidueTypeCOP concrete_residue,
1057  conformation::Residue const & existing_residue,
1058  utility::vector1< utility::vector1< Real > > const & extra_chi_steps,
1059  bool buried,
1060  RotamerVector & rotamers
1061 ) const
1062 {
1064  utility::vector1< Size > rotamer_has_been_interpolated( grandparent::n_packed_rots(), 0 );
1065  typename utility::vector1< PackedDunbrackRotamer< T, Real > > interpolated_rotamers( grandparent::n_packed_rots() );
1066 
1067  /// Save backbone interpolation data for reuse
1068  Real phi( parent::get_phi_from_rsd( existing_residue ) );
1069  Real psi( parent::get_psi_from_rsd( existing_residue ) );
1070  Size phibin, psibin, phibin_next, psibin_next;
1071  Real phi_alpha, psi_alpha;
1072  parent::get_phipsi_bins( phi, psi, phibin, psibin, phibin_next, psibin_next, phi_alpha, psi_alpha );
1073 
1074  Real const requisit_probability = buried ? 0.95 : 0.87;
1075  //grandparent::probability_to_accumulate_while_building_rotamers( buried ); -- 98/95 split generates too many samples
1076  Real accumulated_probability( 0.0 );
1077 
1078  Size const max_rots_that_can_be_built = grandparent::n_packed_rots() * n_nrchi_sample_bins_;
1079  Size count_rotamers_built = 0;
1080  while ( accumulated_probability < requisit_probability ) {
1081  ++count_rotamers_built;
1082 
1083  BBDepNRChiSample<> const & nrchi_sample_00(
1084  bbdep_rotamers_to_sample_( phibin, psibin, count_rotamers_built ));
1085 
1086  Size const packed_rotno00 = nrchi_sample_00.packed_rotno_;
1087  Size const nrchi_bin = nrchi_sample_00.nrchi_bin_;
1088 
1089  Size const
1090  ind01( bbdep_rotsample_sorted_order_( phibin , psibin_next, packed_rotno00, nrchi_bin )),
1091  ind10( bbdep_rotsample_sorted_order_( phibin_next, psibin , packed_rotno00, nrchi_bin )),
1092  ind11( bbdep_rotsample_sorted_order_( phibin_next, psibin_next, packed_rotno00, nrchi_bin ));
1093 
1094  BBDepNRChiSample<> const & nrchi_sample_01( bbdep_rotamers_to_sample_( phibin , psibin_next, ind01 ));
1095  BBDepNRChiSample<> const & nrchi_sample_10( bbdep_rotamers_to_sample_( phibin_next, psibin , ind10 ));
1096  BBDepNRChiSample<> const & nrchi_sample_11( bbdep_rotamers_to_sample_( phibin_next, psibin_next, ind11 ));
1097 
1098  BBDepNRChiSample< Real > const interpolated_nrchi_sample =
1099  interpolate_bbdep_nrchi_sample(
1100  nrchi_sample_00, nrchi_sample_01,
1101  nrchi_sample_10, nrchi_sample_11,
1102  phi_alpha, psi_alpha
1103  );
1104 
1105  if ( rotamer_has_been_interpolated[ packed_rotno00 ] == 0 ) {
1106  /// interpolate the rotameric chi at most once
1107  rotamer_has_been_interpolated[ packed_rotno00 ] = 1;
1109  scratch, packed_rotno00,
1110  phibin, psibin,
1111  phibin_next, psibin_next,phi_alpha, psi_alpha,
1112  interpolated_rotamers[ packed_rotno00 ] );
1113  }
1114 
1115  build_bbdep_rotamers(
1116  pose, scorefxn, task, packer_neighbor_graph,
1117  concrete_residue, existing_residue, extra_chi_steps, buried,
1118  interpolated_rotamers[ packed_rotno00 ], interpolated_nrchi_sample,
1119  rotamers );
1120 
1121  accumulated_probability += interpolated_nrchi_sample.prob_;
1122 
1123  if ( count_rotamers_built == max_rots_that_can_be_built ) break;
1124 
1125  }
1126 }
1127 
1128 template < Size T >
1131  Real phi,
1132  Real psi
1133 ) const
1134 {
1135  if ( bbind_nrchi_sampling_ ) {
1136  return get_all_rotamer_samples_bbind( phi, psi );
1137  } else {
1138  return get_all_rotamer_samples_bbdep( phi, psi );
1139  }
1140 
1141 }
1142 
1143 template < Size T >
1144 Real
1146  Real phi,
1147  Real psi,
1148  Size rot_ind
1149 ) const
1150 {
1151  if ( bbind_nrchi_sampling_ ) {
1152  return get_probability_for_rotamer_bbind( phi, psi, rot_ind );
1153  } else {
1154  return get_probability_for_rotamer_bbdep( phi, psi, rot_ind );
1155  }
1156 }
1157 
1158 template < Size T >
1161  Real phi,
1162  Real psi,
1163  Size rot_ind
1164 ) const
1165 {
1166  if ( bbind_nrchi_sampling_ ) {
1167  return get_rotamer_bbind( phi, psi, rot_ind );
1168  } else {
1169  return get_rotamer_bbdep( phi, psi, rot_ind );
1170  }
1171 }
1172 
1173 
1174 template < Size T >
1175 Size
1177 {
1178  return T + 1;
1179 }
1180 
1181 template < Size T >
1182 Size
1184 {
1185  return grandparent::n_possible_rots() * n_nrchi_sample_bins_;
1186 }
1187 
1188 
1189 template < Size T >
1192  Real phi,
1193  Real psi
1194 ) const
1195 {
1197 
1198  Size phibin, psibin, phibin_next, psibin_next;
1199  Real phi_alpha, psi_alpha;
1200  parent::get_phipsi_bins( phi, psi, phibin, psibin, phibin_next, psibin_next, phi_alpha, psi_alpha );
1201 
1202  utility::vector1< Real > probs_of_next_rotamers( grandparent::n_packed_rots() );
1203  utility::vector1< Size > next_nrchi_rotamer_to_take( grandparent::n_packed_rots(), 1 );
1204  typename utility::vector1< PackedDunbrackRotamer< T, Real > > interpolated_rotamers( grandparent::n_packed_rots() );
1205 
1206  for ( Size ii = 1; ii <= grandparent::n_packed_rots(); ++ii ) {
1208  scratch, ii,
1209  phibin, psibin,
1210  phibin_next, psibin_next,phi_alpha, psi_alpha,
1211  interpolated_rotamers[ ii ] );
1212 
1213  probs_of_next_rotamers[ ii ] = interpolated_rotamers[ ii ].rotamer_probability() *
1214  bbind_rotamers_to_sample_( bbind_rotamers_sorted_by_probability_( 1, ii ), ii ).prob_;
1215  }
1216 
1217  //Size const max_rots_that_can_be_built = grandparent::n_packed_rots() * n_nrchi_sample_bins_;
1218  Size const n_rots = grandparent::n_packed_rots() * n_nrchi_sample_bins_;
1220  all_rots.reserve( n_rots );
1221 
1222  for ( Size ii = 1; ii <= n_rots; ++ii ) {
1223  /// Build the most probable rotamer of those remaining
1224  Size const which_packedrotno_to_build = utility::arg_max( probs_of_next_rotamers );
1225 
1226  PackedDunbrackRotamer< T, Real > nextrot( interpolated_rotamers[ which_packedrotno_to_build ] );
1227 
1228  Size const count = next_nrchi_rotamer_to_take[ which_packedrotno_to_build ];
1229  Size const next_count = ++next_nrchi_rotamer_to_take[ which_packedrotno_to_build ];
1230 
1231  Size const nrchi_rotno = bbind_rotamers_sorted_by_probability_( count, which_packedrotno_to_build );
1232  Size const next_nrchi_rotno = count < n_nrchi_sample_bins_ ?
1233  bbind_rotamers_sorted_by_probability_( next_count, which_packedrotno_to_build ) : 0 ;
1234 
1235  DunbrackRotamerSampleData sample( true );
1236  sample.set_nchi( T + 1 );
1237  sample.set_rotwell( parent::packed_rotno_2_rotwell(nextrot.packed_rotno()) );
1238  for ( Size jj = 1; jj <= T; ++jj ) sample.set_chi_mean( jj, nextrot.chi_mean( jj ) );
1239  for ( Size jj = 1; jj <= T; ++jj ) sample.set_chi_sd( jj, nextrot.chi_sd( jj ) );
1240  sample.set_rotwell( T + 1, nrchi_rotno );
1241  sample.set_chi_mean( T + 1, bbind_rotamers_to_sample_( nrchi_rotno, which_packedrotno_to_build ).median_ );
1242  sample.set_chi_sd( T + 1, 0.0 ); // bogus value
1243  sample.set_prob( probs_of_next_rotamers[ which_packedrotno_to_build ] );
1244  sample.set_nrchi_lower_boundary( bbind_rotamers_to_sample_( nrchi_rotno, which_packedrotno_to_build ).left_ );
1245  sample.set_nrchi_upper_boundary( bbind_rotamers_to_sample_( nrchi_rotno, which_packedrotno_to_build ).right_ );
1246  sample.set_nrchi_probability( bbind_rotamers_to_sample_( nrchi_rotno, which_packedrotno_to_build ).prob_ );
1247 
1248 
1249  if ( probs_of_next_rotamers[ which_packedrotno_to_build ] <= 0 ) break; // this should never happen.
1250 
1251  if ( next_nrchi_rotno == 0 ) {
1252  probs_of_next_rotamers[ which_packedrotno_to_build ] = 0;
1253  } else {
1254  probs_of_next_rotamers[ which_packedrotno_to_build ] =
1255  interpolated_rotamers[ which_packedrotno_to_build ].rotamer_probability() *
1256  bbind_rotamers_to_sample_( next_nrchi_rotno, which_packedrotno_to_build ).prob_;
1257  }
1258  all_rots.push_back( sample );
1259 
1260  }
1261  return all_rots;
1262 }
1263 
1264 
1265 template < Size T >
1268  Real phi,
1269  Real psi
1270 ) const
1271 {
1273  utility::vector1< Size > rotamer_has_been_interpolated( grandparent::n_packed_rots(), 0 );
1274  typename utility::vector1< PackedDunbrackRotamer< T, Real > > interpolated_rotamers( grandparent::n_packed_rots() );
1275 
1276  Size phibin, psibin, phibin_next, psibin_next;
1277  Real phi_alpha, psi_alpha;
1278  parent::get_phipsi_bins( phi, psi, phibin, psibin, phibin_next, psibin_next, phi_alpha, psi_alpha );
1279 
1280  Size const n_rots = grandparent::n_packed_rots() * n_nrchi_sample_bins_;
1282  all_rots.reserve( n_rots );
1283 
1284  for ( Size ii = 1; ii <= n_rots; ++ii ) {
1285  BBDepNRChiSample<> const & nrchi_sample_00(
1286  bbdep_rotamers_to_sample_( phibin, psibin, ii ));
1287 
1288  Size const packed_rotno00 = nrchi_sample_00.packed_rotno_;
1289  Size const nrchi_bin = nrchi_sample_00.nrchi_bin_;
1290 
1291  Size const
1292  ind01( bbdep_rotsample_sorted_order_( phibin , psibin_next, packed_rotno00, nrchi_bin )),
1293  ind10( bbdep_rotsample_sorted_order_( phibin_next, psibin , packed_rotno00, nrchi_bin )),
1294  ind11( bbdep_rotsample_sorted_order_( phibin_next, psibin_next, packed_rotno00, nrchi_bin ));
1295 
1296  BBDepNRChiSample<> const & nrchi_sample_01( bbdep_rotamers_to_sample_( phibin , psibin_next, ind01 ));
1297  BBDepNRChiSample<> const & nrchi_sample_10( bbdep_rotamers_to_sample_( phibin_next, psibin , ind10 ));
1298  BBDepNRChiSample<> const & nrchi_sample_11( bbdep_rotamers_to_sample_( phibin_next, psibin_next, ind11 ));
1299 
1300  BBDepNRChiSample< Real > const interpolated_nrchi_sample =
1301  interpolate_bbdep_nrchi_sample(
1302  nrchi_sample_00, nrchi_sample_01,
1303  nrchi_sample_10, nrchi_sample_11,
1304  phi_alpha, psi_alpha
1305  );
1306 
1307  if ( rotamer_has_been_interpolated[ packed_rotno00 ] == 0 ) {
1308  /// interpolate the rotameric chi at most once
1309  rotamer_has_been_interpolated[ packed_rotno00 ] = 1;
1311  scratch, packed_rotno00,
1312  phibin, psibin,
1313  phibin_next, psibin_next,phi_alpha, psi_alpha,
1314  interpolated_rotamers[ packed_rotno00 ] );
1315  }
1316 
1317  PackedDunbrackRotamer< T, Real > nextrot( interpolated_rotamers[ packed_rotno00 ] );
1318 
1319  DunbrackRotamerSampleData sample( true );
1320  sample.set_nchi( T + 1 );
1321  sample.set_rotwell( parent::packed_rotno_2_rotwell( packed_rotno00 ));
1322  for ( Size jj = 1; jj <= T; ++jj ) sample.set_chi_mean( jj, nextrot.chi_mean( jj ) );
1323  for ( Size jj = 1; jj <= T; ++jj ) sample.set_chi_sd( jj, nextrot.chi_sd( jj ) );
1324  sample.set_rotwell( T + 1, nrchi_bin );
1325  sample.set_chi_mean( T + 1, interpolated_nrchi_sample.nrchi_mean_ );
1326  sample.set_chi_sd( T + 1, interpolated_nrchi_sample.nrchi_sd_ ); // bogus value
1327  sample.set_prob( interpolated_nrchi_sample.prob_ );
1328  sample.set_nrchi_lower_boundary( bbind_rotamers_to_sample_( nrchi_bin, packed_rotno00 ).left_ );
1329  sample.set_nrchi_upper_boundary( bbind_rotamers_to_sample_( nrchi_bin, packed_rotno00 ).right_ );
1330  // trick: the interpolated rotamer has the sum of the probabilities for each of the nrchi rotamers
1331  // so that the probability of getting this nrchi bin given that you're in this bin for the rotameric
1332  // residues is the quotient of the unconditioned probability for this rotamer and the unconditioned
1333  // probability of the rotameric chi being in this bin.
1334  sample.set_nrchi_probability( interpolated_nrchi_sample.prob_ / nextrot.rotamer_probability() );
1335 
1336  all_rots.push_back( sample );
1337  }
1338  return all_rots;
1339 }
1340 
1341 
1342 /// @details Lookup for bbind is significantly slower than for bbdep
1343 template < Size T >
1344 Real
1346  Real phi,
1347  Real psi,
1348  Size rot_ind
1349 ) const
1350 {
1351  Size phibin, psibin, phibin_next, psibin_next;
1352  Real phi_alpha, psi_alpha;
1353  parent::get_phipsi_bins( phi, psi, phibin, psibin, phibin_next, psibin_next, phi_alpha, psi_alpha );
1354 
1355  utility::vector1< Real > probs_of_next_rotamers( grandparent::n_packed_rots() );
1356  utility::vector1< Size > next_nrchi_rotamer_to_take( grandparent::n_packed_rots(), 1 );
1357  utility::vector1< Real > probability_of_rotameric_chi( grandparent::n_packed_rots() );
1358  for ( Size ii = 1; ii <= grandparent::n_packed_rots(); ++ii ) {
1359 
1360  PackedDunbrackRotamer< T > const & rot00( parent::rotamers()( phibin, psibin, ii ) );
1361  Size const packed_rotno = rot00.packed_rotno();
1362 
1363  Size const
1364  sorted_rotno_01( parent::packed_rotno_2_sorted_rotno()( phibin , psibin_next, packed_rotno )),
1365  sorted_rotno_10( parent::packed_rotno_2_sorted_rotno()( phibin_next, psibin , packed_rotno )),
1366  sorted_rotno_11( parent::packed_rotno_2_sorted_rotno()( phibin_next, psibin_next, packed_rotno ));
1367 
1369  rot01( parent::rotamers()( phibin , psibin_next, sorted_rotno_01 ) ),
1370  rot10( parent::rotamers()( phibin_next, psibin , sorted_rotno_10 ) ),
1371  rot11( parent::rotamers()( phibin_next, psibin_next, sorted_rotno_11 ) );
1372 
1373  Real interpolated_probability, dummy1, dummy2;
1374  basic::interpolate_bilinear_by_value(
1375  static_cast< Real > ( rot00.rotamer_probability()),
1376  static_cast< Real > ( rot10.rotamer_probability()),
1377  static_cast< Real > ( rot01.rotamer_probability()),
1378  static_cast< Real > ( rot11.rotamer_probability()),
1379  phi_alpha, psi_alpha, parent::PHIPSI_BINRANGE, false /*treat_as_angles*/,
1380  interpolated_probability,
1381  dummy1, dummy2
1382  );
1383 
1384  probability_of_rotameric_chi[ ii ] = interpolated_probability;
1385  probs_of_next_rotamers[ ii ] = probability_of_rotameric_chi[ ii ] *
1386  bbind_rotamers_to_sample_( bbind_rotamers_sorted_by_probability_( 1, ii ), ii ).prob_;
1387  }
1388 
1389  //Size const max_rots_that_can_be_built = grandparent::n_packed_rots() * n_nrchi_sample_bins_;
1390  Size const n_rots = grandparent::n_packed_rots() * n_nrchi_sample_bins_;
1392  all_rots.reserve( n_rots );
1393 
1394  Real last_prob( 0 );
1395  /// Recover the rotamers in order, stop at the rot_ind rotamer.
1396  for ( Size ii = 1; ii <= rot_ind; ++ii ) {
1397  /// Build the most probable rotamer of those remaining
1398  Size const which_packedrotno_to_build = utility::arg_max( probs_of_next_rotamers );
1399 
1400  Size const count = next_nrchi_rotamer_to_take[ which_packedrotno_to_build ];
1401  Size const next_count = ++next_nrchi_rotamer_to_take[ which_packedrotno_to_build ];
1402 
1403  //Size const nrchi_rotno = bbind_rotamers_sorted_by_probability_( count, which_packedrotno_to_build );
1404  Size const next_nrchi_rotno = count < n_nrchi_sample_bins_ ?
1405  bbind_rotamers_sorted_by_probability_( next_count, which_packedrotno_to_build ) : 0 ;
1406 
1407  last_prob = probs_of_next_rotamers[ which_packedrotno_to_build ];
1408 
1409  if ( probs_of_next_rotamers[ which_packedrotno_to_build ] <= 0 ) break; // this should never happen.
1410 
1411  if ( next_nrchi_rotno == 0 ) {
1412  probs_of_next_rotamers[ which_packedrotno_to_build ] = 0;
1413  } else {
1414  probs_of_next_rotamers[ which_packedrotno_to_build ] =
1415  probability_of_rotameric_chi[ which_packedrotno_to_build ] *
1416  bbind_rotamers_to_sample_( next_nrchi_rotno, which_packedrotno_to_build ).prob_;
1417  }
1418 
1419  }
1420  return last_prob;
1421 
1422 }
1423 
1424 template < Size T >
1425 Real
1427  Real phi,
1428  Real psi,
1429  Size rot_ind
1430 ) const
1431 {
1432 
1433  Size phibin, psibin, phibin_next, psibin_next;
1434  Real phi_alpha, psi_alpha;
1435  parent::get_phipsi_bins( phi, psi, phibin, psibin, phibin_next, psibin_next, phi_alpha, psi_alpha );
1436 
1437  BBDepNRChiSample<> const & nrchi_sample_00(
1438  bbdep_rotamers_to_sample_( phibin, psibin, rot_ind ));
1439 
1440  Size const packed_rotno00 = nrchi_sample_00.packed_rotno_;
1441  Size const nrchi_bin = nrchi_sample_00.nrchi_bin_;
1442 
1443  Size const
1444  ind01( bbdep_rotsample_sorted_order_( phibin , psibin_next, packed_rotno00, nrchi_bin )),
1445  ind10( bbdep_rotsample_sorted_order_( phibin_next, psibin , packed_rotno00, nrchi_bin )),
1446  ind11( bbdep_rotsample_sorted_order_( phibin_next, psibin_next, packed_rotno00, nrchi_bin ));
1447 
1448  BBDepNRChiSample<> const & nrchi_sample_01( bbdep_rotamers_to_sample_( phibin , psibin_next, ind01 ));
1449  BBDepNRChiSample<> const & nrchi_sample_10( bbdep_rotamers_to_sample_( phibin_next, psibin , ind10 ));
1450  BBDepNRChiSample<> const & nrchi_sample_11( bbdep_rotamers_to_sample_( phibin_next, psibin_next, ind11 ));
1451 
1452  Real nrchi_prob, dummy_dprob_1, dummy_dprob_2;
1453 
1454  basic::interpolate_bilinear_by_value(
1455  static_cast< Real > ( nrchi_sample_00.prob_),
1456  static_cast< Real > ( nrchi_sample_10.prob_),
1457  static_cast< Real > ( nrchi_sample_01.prob_),
1458  static_cast< Real > ( nrchi_sample_11.prob_),
1459  phi_alpha, psi_alpha, parent::PHIPSI_BINRANGE, false /*treat_as_angles*/,
1460  nrchi_prob,
1461  dummy_dprob_1, dummy_dprob_2
1462  );
1463 
1464  return nrchi_prob;
1465 }
1466 
1467 template < Size T >
1470  Real phi,
1471  Real psi,
1472  Size rot_ind
1473 ) const
1474 {
1475  Size phibin, psibin, phibin_next, psibin_next;
1476  Real phi_alpha, psi_alpha;
1477  parent::get_phipsi_bins( phi, psi, phibin, psibin, phibin_next, psibin_next, phi_alpha, psi_alpha );
1478 
1479  utility::vector1< Real > probs_of_next_rotamers( grandparent::n_packed_rots() );
1480  utility::vector1< Size > next_nrchi_rotamer_to_take( grandparent::n_packed_rots(), 1 );
1481  utility::vector1< Real > probability_of_rotameric_chi( grandparent::n_packed_rots() );
1482  for ( Size ii = 1; ii <= grandparent::n_packed_rots(); ++ii ) {
1483 
1484  PackedDunbrackRotamer< T > const & rot00( parent::rotamers()( phibin, psibin, ii ) );
1485  Size const packed_rotno = rot00.packed_rotno();
1486 
1487  Size const
1488  sorted_rotno_01( parent::packed_rotno_2_sorted_rotno()( phibin , psibin_next, packed_rotno )),
1489  sorted_rotno_10( parent::packed_rotno_2_sorted_rotno()( phibin_next, psibin , packed_rotno )),
1490  sorted_rotno_11( parent::packed_rotno_2_sorted_rotno()( phibin_next, psibin_next, packed_rotno ));
1491 
1493  rot01( parent::rotamers()( phibin , psibin_next, sorted_rotno_01 ) ),
1494  rot10( parent::rotamers()( phibin_next, psibin , sorted_rotno_10 ) ),
1495  rot11( parent::rotamers()( phibin_next, psibin_next, sorted_rotno_11 ) );
1496 
1497  Real interpolated_probability, dummy1, dummy2;
1498  basic::interpolate_bilinear_by_value(
1499  static_cast< Real > ( rot00.rotamer_probability()),
1500  static_cast< Real > ( rot10.rotamer_probability()),
1501  static_cast< Real > ( rot01.rotamer_probability()),
1502  static_cast< Real > ( rot11.rotamer_probability()),
1503  phi_alpha, psi_alpha, parent::PHIPSI_BINRANGE, false /*treat_as_angles*/,
1504  interpolated_probability,
1505  dummy1, dummy2
1506  );
1507 
1508  probability_of_rotameric_chi[ ii ] = interpolated_probability;
1509  probs_of_next_rotamers[ ii ] = probability_of_rotameric_chi[ ii ] *
1510  bbind_rotamers_to_sample_( bbind_rotamers_sorted_by_probability_( 1, ii ), ii ).prob_;
1511  }
1512 
1513  //Size const max_rots_that_can_be_built = grandparent::n_packed_rots() * n_nrchi_sample_bins_;
1514  Size const n_rots = grandparent::n_packed_rots() * n_nrchi_sample_bins_;
1516  all_rots.reserve( n_rots );
1517 
1518  Real last_prob( 0 );
1519  Size last_nrchi_rotno( 0 );
1520  Size last_rchi_rotno( 0 );
1521  /// Recover the rotamers in order, stop at the rot_ind rotamer.
1522  for ( Size ii = 1; ii <= rot_ind; ++ii ) {
1523  /// Build the most probable rotamer of those remaining
1524  Size const which_packedrotno_to_build = utility::arg_max( probs_of_next_rotamers );
1525  last_prob = probs_of_next_rotamers[ which_packedrotno_to_build ];
1526  last_rchi_rotno = which_packedrotno_to_build;
1527 
1528  Size const count = next_nrchi_rotamer_to_take[ which_packedrotno_to_build ];
1529  Size const next_count = ++next_nrchi_rotamer_to_take[ which_packedrotno_to_build ];
1530 
1531  Size const nrchi_rotno = bbind_rotamers_sorted_by_probability_( count, which_packedrotno_to_build );
1532  last_nrchi_rotno = nrchi_rotno;
1533  Size const next_nrchi_rotno = count < n_nrchi_sample_bins_ ?
1534  bbind_rotamers_sorted_by_probability_( next_count, which_packedrotno_to_build ) : 0 ;
1535 
1536  last_prob = probs_of_next_rotamers[ which_packedrotno_to_build ];
1537 
1538  if ( probs_of_next_rotamers[ which_packedrotno_to_build ] <= 0 ) break; // this should never happen.
1539 
1540  if ( next_nrchi_rotno == 0 ) {
1541  probs_of_next_rotamers[ which_packedrotno_to_build ] = 0;
1542  } else {
1543  probs_of_next_rotamers[ which_packedrotno_to_build ] =
1544  probability_of_rotameric_chi[ which_packedrotno_to_build ] *
1545  bbind_rotamers_to_sample_( next_nrchi_rotno, which_packedrotno_to_build ).prob_;
1546  }
1547 
1548  }
1549 
1551 
1552  PackedDunbrackRotamer< T, Real > rchi_rotamer;
1554  scratch, last_rchi_rotno,
1555  phibin, psibin,
1556  phibin_next, psibin_next,phi_alpha, psi_alpha,
1557  rchi_rotamer );
1558 
1559  DunbrackRotamerSampleData sample( true );
1560  sample.set_nchi( T + 1 );
1561  sample.set_rotwell( parent::packed_rotno_2_rotwell(rchi_rotamer.packed_rotno()) );
1562  for ( Size jj = 1; jj <= T; ++jj ) sample.set_chi_mean( jj, rchi_rotamer.chi_mean( jj ) );
1563  for ( Size jj = 1; jj <= T; ++jj ) sample.set_chi_sd( jj, rchi_rotamer.chi_sd( jj ) );
1564  sample.set_rotwell( T + 1, last_nrchi_rotno );
1565  sample.set_chi_mean( T + 1, bbind_rotamers_to_sample_( last_nrchi_rotno, last_rchi_rotno ).median_ );
1566  sample.set_chi_sd( T + 1, 0.0 ); // bogus value
1567  sample.set_prob( last_prob );
1568  sample.set_nrchi_lower_boundary( bbind_rotamers_to_sample_( last_nrchi_rotno, last_rchi_rotno ).left_ );
1569  sample.set_nrchi_upper_boundary( bbind_rotamers_to_sample_( last_nrchi_rotno, last_rchi_rotno ).right_ );
1570  sample.set_nrchi_probability( bbind_rotamers_to_sample_( last_nrchi_rotno, last_rchi_rotno ).prob_ );
1571 
1572  return sample;
1573 }
1574 
1575 template < Size T >
1578  Real phi,
1579  Real psi,
1580  Size rot_ind
1581 ) const
1582 {
1584 
1585  Size phibin, psibin, phibin_next, psibin_next;
1586  Real phi_alpha, psi_alpha;
1587  parent::get_phipsi_bins( phi, psi, phibin, psibin, phibin_next, psibin_next, phi_alpha, psi_alpha );
1588 
1589  BBDepNRChiSample<> const & nrchi_sample_00(
1590  bbdep_rotamers_to_sample_( phibin, psibin, rot_ind ));
1591 
1592  Size const packed_rotno00 = nrchi_sample_00.packed_rotno_;
1593  Size const nrchi_bin = nrchi_sample_00.nrchi_bin_;
1594 
1595  Size const
1596  ind01( bbdep_rotsample_sorted_order_( phibin , psibin_next, packed_rotno00, nrchi_bin )),
1597  ind10( bbdep_rotsample_sorted_order_( phibin_next, psibin , packed_rotno00, nrchi_bin )),
1598  ind11( bbdep_rotsample_sorted_order_( phibin_next, psibin_next, packed_rotno00, nrchi_bin ));
1599 
1600  BBDepNRChiSample<> const & nrchi_sample_01( bbdep_rotamers_to_sample_( phibin , psibin_next, ind01 ));
1601  BBDepNRChiSample<> const & nrchi_sample_10( bbdep_rotamers_to_sample_( phibin_next, psibin , ind10 ));
1602  BBDepNRChiSample<> const & nrchi_sample_11( bbdep_rotamers_to_sample_( phibin_next, psibin_next, ind11 ));
1603 
1604  BBDepNRChiSample< Real > const interpolated_nrchi_sample =
1605  interpolate_bbdep_nrchi_sample(
1606  nrchi_sample_00, nrchi_sample_01,
1607  nrchi_sample_10, nrchi_sample_11,
1608  phi_alpha, psi_alpha
1609  );
1610 
1613  scratch, packed_rotno00,
1614  phibin, psibin,
1615  phibin_next, psibin_next,phi_alpha, psi_alpha,
1616  rot );
1617 
1618  DunbrackRotamerSampleData sample( true );
1619  sample.set_nchi( T + 1 );
1620  sample.set_rotwell( parent::packed_rotno_2_rotwell( packed_rotno00 ));
1621  for ( Size jj = 1; jj <= T; ++jj ) sample.set_chi_mean( jj, rot.chi_mean( jj ) );
1622  for ( Size jj = 1; jj <= T; ++jj ) sample.set_chi_sd( jj, rot.chi_sd( jj ) );
1623  sample.set_rotwell( T + 1, nrchi_bin );
1624  sample.set_chi_mean( T + 1, interpolated_nrchi_sample.nrchi_mean_ );
1625  sample.set_chi_sd( T + 1, interpolated_nrchi_sample.nrchi_sd_ ); // bogus value
1626  sample.set_prob( interpolated_nrchi_sample.prob_ );
1627  sample.set_nrchi_lower_boundary( bbind_rotamers_to_sample_( nrchi_bin, packed_rotno00 ).left_ );
1628  sample.set_nrchi_upper_boundary( bbind_rotamers_to_sample_( nrchi_bin, packed_rotno00 ).right_ );
1629  // trick: the interpolated rotamer has the sum of the probabilities for each of the nrchi rotamers
1630  // so that the probability of getting this nrchi bin given that you're in this bin for the rotameric
1631  // residues is the quotient of the unconditioned probability for this rotamer and the unconditioned
1632  // probability of the rotameric chi being in this bin.
1633  sample.set_nrchi_probability( interpolated_nrchi_sample.prob_ / rot.rotamer_probability() );
1634 
1635  return sample;
1636 }
1637 
1638 
1639 template < Size T >
1640 void
1642  pose::Pose const & pose,
1643  scoring::ScoreFunction const & scorefxn,
1644  pack::task::PackerTask const & task,
1645  graph::GraphCOP packer_neighbor_graph,
1646  chemical::ResidueTypeCOP concrete_residue,
1647  conformation::Residue const& existing_residue,
1648  utility::vector1< utility::vector1< Real > > const & extra_chi_steps,
1649  bool buried,
1650  PackedDunbrackRotamer< T, Real > const & interpolated_rotamer,
1651  BBDepNRChiSample< Real > const interpolated_sample,
1652  RotamerVector & rotamers
1653 ) const
1654 {
1655  DunbrackRotamer< T, Real > interpolated_rot( parent::packed_rotamer_2_regular_rotamer( interpolated_rotamer ));
1656  BBDepSemiRotamericData< T > bbdep_rotamer_building_data( interpolated_rot, interpolated_sample );
1657 
1658  // now build the chi sets derived from this base rotamer
1659  utility::vector1< ChiSetOP > chi_set_vector;
1660  parent::enumerate_chi_sets(
1661  *concrete_residue, task, existing_residue.seqpos(), buried,
1662  bbdep_rotamer_building_data,
1663  extra_chi_steps, chi_set_vector );
1664 
1665  parent::create_rotamers_from_chisets(
1666  pose, scorefxn, task,
1667  packer_neighbor_graph, concrete_residue, existing_residue,
1668  chi_set_vector, rotamers );
1669 }
1670 
1671 template < Size T >
1672 void
1674  pose::Pose const & pose,
1675  scoring::ScoreFunction const & scorefxn,
1676  pack::task::PackerTask const & task,
1677  graph::GraphCOP packer_neighbor_graph,
1678  chemical::ResidueTypeCOP concrete_residue,
1679  conformation::Residue const& existing_residue,
1680  utility::vector1< utility::vector1< Real > > const & extra_chi_steps,
1681  bool buried,
1682  PackedDunbrackRotamer< T, Real > const & interpolated_rotamer,
1683  Size const nrchi_rotno,
1684  BBIndNRChiSample<> const & interpolated_sample,
1685  RotamerVector & rotamers
1686 ) const
1687 {
1688  DunbrackRotamer< T, Real > interpolated_rot( parent::packed_rotamer_2_regular_rotamer( interpolated_rotamer ));
1689  BBIndSemiRotamericData< T > bbind_rotamer_building_data( interpolated_rot, interpolated_sample, nrchi_rotno );
1690 
1691  // now build the chi sets derived from this base rotamer
1692  utility::vector1< ChiSetOP > chi_set_vector;
1693  parent::enumerate_chi_sets(
1694  *concrete_residue, task, existing_residue.seqpos(), buried,
1695  bbind_rotamer_building_data,
1696  extra_chi_steps, chi_set_vector );
1697 
1698  parent::create_rotamers_from_chisets(
1699  pose, scorefxn, task,
1700  packer_neighbor_graph, concrete_residue, existing_residue,
1701  chi_set_vector, rotamers );
1702 
1703 }
1704 
1705 
1706 template < Size T >
1707 void
1709  chemical::ResidueType const & rsd_type,
1710  pack::task::ResidueLevelTask const & rtask,
1711  bool buried,
1712  Size const chi_index,
1713  RotamericData< T > const & rotamer_data,
1714  utility::vector1< Real > const & extra_steps,
1715  utility::vector1< Real > & total_chi,
1716  utility::vector1< int > & total_rot,
1717  utility::vector1< Real > & total_ex_steps,
1718  utility::vector1< Real > & rotsample_prob
1719 ) const
1720 {
1721  if ( chi_index != T + 1 ) {
1722  parent::chisamples_for_rotamer_and_chi( rsd_type, rtask, buried, chi_index, rotamer_data, extra_steps,
1723  total_chi, total_rot, total_ex_steps, rotsample_prob );
1724  } else if ( bbind_nrchi_sampling_ ) {
1725  bbind_chisamples_for_rotamer_chi( rsd_type, rtask, buried, chi_index, rotamer_data, extra_steps,
1726  total_chi, total_rot, total_ex_steps, rotsample_prob );
1727  } else {
1728  bbdep_chisamples_for_rotamer_chi( rsd_type, rtask, buried, chi_index, rotamer_data, extra_steps,
1729  total_chi, total_rot, total_ex_steps, rotsample_prob );
1730  }
1731 }
1732 
1733 template < Size T >
1734 void
1736  chemical::ResidueType const & rsd_type,
1737  pack::task::ResidueLevelTask const & rtask,
1738  bool buried,
1739  Size const chi_index,
1740  RotamericData< T > const & rotamer_data,
1741  utility::vector1< Real > const & /*extra_steps*/,
1742  utility::vector1< Real > & total_chi,
1743  utility::vector1< int > & total_rot,
1744  utility::vector1< Real > & total_ex_steps,
1745  utility::vector1< Real > & chisample_prob
1746 ) const
1747 {
1748  using namespace pack::task;
1749  assert( chi_index == T + 1 );
1750 
1751  assert( dynamic_cast< BBIndSemiRotamericData< T > const * > ( & rotamer_data ) );
1752  BBIndSemiRotamericData< T > const & bbind_rotameric_data(
1753  static_cast< BBIndSemiRotamericData< T > const & > ( rotamer_data ) );
1754 
1755  BBIndNRChiSample<> const & nrsample = bbind_rotameric_data.bbind_nrchi_sample();
1756 
1757  Real const minimum_angular_distance_for_extra_bbind_rotamer_sample( 10.0 );
1758 
1759  total_chi.push_back( nrsample.median_ );
1760  total_ex_steps.push_back( 0.0 );
1761  total_rot.push_back( bbind_rotameric_data.nrchi_bin_id() );
1762  chisample_prob.push_back( nrsample.prob_ );
1763  //Real const min_extrachi_sd = 0.0; // ???
1764 
1765  ExtraRotSample ex_samp_level = rtask.extrachi_sample_level( buried, chi_index, &rsd_type );
1766 
1767  if ( ex_samp_level == NO_EXTRA_CHI_SAMPLES ) return;
1768 
1769 
1770  if ( std::abs( basic::periodic_range( nrsample.median_ - nrsample.left_, nrchi_periodicity_ )) >
1771  minimum_angular_distance_for_extra_bbind_rotamer_sample ) {
1772 
1773  /// halfway between the median and the left boundary
1774  total_chi.push_back( nrsample.median_ - 0.5 * ( nrsample.median_ - nrsample.left_ ) );
1775  total_ex_steps.push_back( 1.0 ); // not a measure of # stdevs...
1776  total_rot.push_back( bbind_rotameric_data.nrchi_bin_id() );
1777  chisample_prob.push_back( nrsample.prob_ );
1778  }
1779 
1780  if ( std::abs( basic::periodic_range( nrsample.median_ - nrsample.right_, nrchi_periodicity_ )) >
1781  minimum_angular_distance_for_extra_bbind_rotamer_sample ) {
1782 
1783  /// halfway between the median and the right boundary
1784  total_chi.push_back( nrsample.median_ + 0.5 * ( nrsample.right_ - nrsample.median_ ) );
1785  total_ex_steps.push_back( 1.0 ); // not a measure of # stdevs...
1786  total_rot.push_back( bbind_rotameric_data.nrchi_bin_id() );
1787  chisample_prob.push_back( nrsample.prob_ );
1788  }
1789 }
1790 
1791 
1792 template < Size T >
1793 void
1795  chemical::ResidueType const & rsd_type,
1796  pack::task::ResidueLevelTask const & rtask,
1797  bool buried,
1798  Size const chi_index,
1799  RotamericData< T > const & rotamer_data,
1800  utility::vector1< Real > const & extra_steps,
1801  utility::vector1< Real > & total_chi,
1802  utility::vector1< int > & total_rot,
1803  utility::vector1< Real > & total_ex_steps,
1804  utility::vector1< Real > & chisample_prob
1805 ) const
1806 {
1807  using namespace pack::task;
1808  assert( chi_index == T + 1 );
1809 
1810  assert( dynamic_cast< BBDepSemiRotamericData< T > const * > ( & rotamer_data ) );
1811  BBDepSemiRotamericData< T > const & bbdep_rotameric_data(
1812  static_cast< BBDepSemiRotamericData< T > const & > ( rotamer_data ) );
1813 
1814  BBDepNRChiSample< Real > const & nrsample = bbdep_rotameric_data.bbdep_nrchi_sample();
1815 
1816  total_chi.push_back( nrsample.nrchi_mean_ );
1817  total_ex_steps.push_back( 0. );
1818  total_rot.push_back( nrsample.nrchi_bin_ );
1819  chisample_prob.push_back( nrsample.prob_ );
1820 
1821  ExtraRotSample ex_samp_level = rtask.extrachi_sample_level( buried, chi_index, &rsd_type );
1822 
1823  if ( ex_samp_level == NO_EXTRA_CHI_SAMPLES ) return;
1824 
1825  Real const min_extrachi_sd = 0.0; // What's an appropriate value here?
1826  if ( nrsample.nrchi_sd_ <= min_extrachi_sd ) return;
1827 
1828  for ( Size k=1; k<= extra_steps.size(); ++k ) {
1829  total_chi.push_back( nrsample.nrchi_mean_ + extra_steps[k] * nrsample.nrchi_sd_ );
1830  total_ex_steps.push_back( extra_steps[k] );
1831  total_rot.push_back( nrsample.nrchi_bin_ );
1832  chisample_prob.push_back( nrsample.prob_ ); // no "penalty" for off-mean samples.
1833  }
1834 
1835 }
1836 
1837 //XRW_B_T1
1838 /*
1839 template < Size T >
1840 SingleResidueRotamerLibraryOP
1841 SemiRotamericSingleResidueDunbrackLibrary< T >::coarsify(coarse::Translator const & map ) const
1842 {
1843  return 0;
1844 }
1845 */
1846 //XRW_E_T1
1847 
1848 template < Size T >
1849 void
1851 {
1852  utility_exit_with_message("Unimplemented!");
1853 }
1854 
1855 template < Size T >
1856 void
1858 {
1859  using namespace boost;
1860  parent::write_to_binary( out );
1861  // For safety, write out const data so that when reading in const data later, we can verify we
1862  // have a valid input.
1863 
1864  // 1. bbind_nrchi_scoring_
1865  {
1866  boost::int32_t bbind_nrchi_scoring = bbind_nrchi_scoring_;
1867  out.write( (char*) &bbind_nrchi_scoring, sizeof( boost::int32_t ));
1868  }
1869  // 2. bbind_nrchi_sampling_
1870  {
1871  boost::int32_t bbind_nrchi_sampling = bbind_nrchi_sampling_;
1872  out.write( (char*) &bbind_nrchi_sampling, sizeof( boost::int32_t ));
1873  }
1874 
1875  if ( ! bbind_nrchi_scoring_ ) {
1876  // 3a. bbdep_non_rotameric_chi_scores_
1877  Size const n_bbdep_scores = grandparent::n_packed_rots() * parent::N_PHIPSI_BINS * parent::N_PHIPSI_BINS * bbdep_nrchi_nbins_;
1878  BBDepScoreInterpData * bbdep_nrc_interpdata = new BBDepScoreInterpData[ n_bbdep_scores ];
1879  Size count( 0 );
1880  for ( Size ii = 1; ii <= grandparent::n_packed_rots(); ++ii ) {
1881  for ( Size jj = 1; jj <= bbdep_nrchi_nbins_; ++jj ) {
1882  for ( Size kk = 1; kk <= parent::N_PHIPSI_BINS; ++kk ) {
1883  for ( Size ll = 1; ll <= parent::N_PHIPSI_BINS; ++ll ) {
1884  bbdep_nrc_interpdata[ count ] = bbdep_nrc_interpdata_[ ii ]( ll, kk, jj );
1885  ++count;
1886  }
1887  }
1888  }
1889  }
1890  out.write( (char*) bbdep_nrc_interpdata, n_bbdep_scores * sizeof( BBDepScoreInterpData ) );
1891  delete [] bbdep_nrc_interpdata;
1892  } else {
1893  // 3b. bbind_non_rotameric_chi_scores_
1894  Size const n_bbind_scores = bbind_non_rotameric_chi_scores_.size();
1895  Real * bbind_non_rotameric_chi_scores = new Real[ n_bbind_scores ];
1896  Size count( 0 );
1897  for ( Size ii = 1; ii <= grandparent::n_packed_rots(); ++ii ) {
1898  for ( Size jj = 1; jj <= bbind_nrchi_nbins_; ++jj ) {
1899  bbind_non_rotameric_chi_scores[ count ] = bbind_non_rotameric_chi_scores_( jj, ii );
1900  ++count;
1901  }
1902  }
1903  out.write( (char*) bbind_non_rotameric_chi_scores, n_bbind_scores * sizeof( Real ));
1904  delete [] bbind_non_rotameric_chi_scores;
1905  }
1906 
1907  /// 4.n_nrchi_sample_bins_
1908  {
1909  boost::int32_t n_nrchi_sample_bins = n_nrchi_sample_bins_;
1910  out.write( (char*) & n_nrchi_sample_bins, sizeof( boost::int32_t ) );
1911  }
1912 
1913  if ( ! bbind_nrchi_sampling_ ) {
1914  // 5. bbdep_rotamers_to_sample_, bbdep_rotsample_sorted_order_
1915  Size const n_bbdep_nrchi_samples =
1916  grandparent::n_packed_rots() * parent::N_PHIPSI_BINS * parent::N_PHIPSI_BINS * n_nrchi_sample_bins_;
1917 
1918  boost::int32_t * bbdep_nrchi_packed_rotnos = new boost::int32_t[ n_bbdep_nrchi_samples ];
1919  boost::int32_t * bbdep_nrchi_bin = new boost::int32_t[ n_bbdep_nrchi_samples ];
1920  DunbrackReal * bbdep_nrchi_means = new DunbrackReal[ n_bbdep_nrchi_samples ];
1921  DunbrackReal * bbdep_nrchi_sdevs = new DunbrackReal[ n_bbdep_nrchi_samples ];
1922  DunbrackReal * bbdep_nrchi_probs = new DunbrackReal[ n_bbdep_nrchi_samples ];
1923 
1924  boost::int32_t * bbdep_rotsample_sorted_order = new boost::int32_t[ n_bbdep_nrchi_samples ];
1925 
1926  Size count( 0 );
1927  Size count_iijj( 1 ); // 3d array sorted by frequency instead of 4d array divided first by rotameric rotno.
1928  for ( Size ii = 1; ii <= n_nrchi_sample_bins_; ++ii ) {
1929  for ( Size jj = 1; jj <= grandparent::n_packed_rots(); ++jj ) {
1930  for ( Size kk = 1; kk <= parent::N_PHIPSI_BINS; ++kk ) {
1931  for ( Size ll = 1; ll <= parent::N_PHIPSI_BINS; ++ll ) {
1932  bbdep_nrchi_packed_rotnos[ count ] = bbdep_rotamers_to_sample_( ll, kk, count_iijj ).packed_rotno_;
1933  bbdep_nrchi_bin[ count ] = bbdep_rotamers_to_sample_( ll, kk, count_iijj ).nrchi_bin_;
1934  bbdep_nrchi_means[ count ] = bbdep_rotamers_to_sample_( ll, kk, count_iijj ).nrchi_mean_;
1935  bbdep_nrchi_sdevs[ count ] = bbdep_rotamers_to_sample_( ll, kk, count_iijj ).nrchi_sd_;
1936  bbdep_nrchi_probs[ count ] = bbdep_rotamers_to_sample_( ll, kk, count_iijj ).prob_;
1937  bbdep_rotsample_sorted_order[count]= bbdep_rotsample_sorted_order_( ll, kk, jj, ii );
1938  ++count;
1939  }
1940  }
1941  ++count_iijj;
1942  }
1943  }
1944  out.write( (char*) bbdep_nrchi_packed_rotnos, n_bbdep_nrchi_samples * sizeof( boost::int32_t ) );
1945  out.write( (char*) bbdep_nrchi_bin, n_bbdep_nrchi_samples * sizeof( boost::int32_t ) );
1946  out.write( (char*) bbdep_nrchi_means, n_bbdep_nrchi_samples * sizeof( DunbrackReal ) );
1947  out.write( (char*) bbdep_nrchi_sdevs, n_bbdep_nrchi_samples * sizeof( DunbrackReal ) );
1948  out.write( (char*) bbdep_nrchi_probs, n_bbdep_nrchi_samples * sizeof( DunbrackReal ) );
1949  out.write( (char*) bbdep_rotsample_sorted_order, n_bbdep_nrchi_samples * sizeof( boost::int32_t ) );
1950 
1951  delete [] bbdep_nrchi_packed_rotnos; bbdep_nrchi_packed_rotnos = 0;
1952  delete [] bbdep_nrchi_bin; bbdep_nrchi_bin = 0;
1953  delete [] bbdep_nrchi_means; bbdep_nrchi_means = 0;
1954  delete [] bbdep_nrchi_sdevs; bbdep_nrchi_sdevs = 0;
1955  delete [] bbdep_nrchi_probs; bbdep_nrchi_probs = 0;
1956  delete [] bbdep_rotsample_sorted_order; bbdep_rotsample_sorted_order = 0;
1957 
1958  }
1959 
1960  { // Save the bbind rotamer definitions reguardless of bbind_nrchi_sampling_'s status.
1961 
1962  // 6. bbind_rotamers_to_sample_, bbind_rotamers_sorted_by_probability_
1963  Size const n_bbind_nrchi_samples = n_nrchi_sample_bins_ * grandparent::n_packed_rots();
1964 
1965  DunbrackReal * bbind_nrchi_lefts = new DunbrackReal[ n_bbind_nrchi_samples ];
1966  DunbrackReal * bbind_nrchi_medians = new DunbrackReal[ n_bbind_nrchi_samples ];
1967  DunbrackReal * bbind_nrchi_rights = new DunbrackReal[ n_bbind_nrchi_samples ];
1968  DunbrackReal * bbind_nrchi_probs = new DunbrackReal[ n_bbind_nrchi_samples ];
1969 
1970  boost::int32_t * bbind_rotsample_sorted_order( 0 );
1971  if ( bbind_nrchi_sampling_ ) {
1972  bbind_rotsample_sorted_order = new boost::int32_t[ n_bbind_nrchi_samples ];
1973  }
1974 
1975  Size count( 0 );
1976  for ( Size ii = 1; ii <= grandparent::n_packed_rots(); ++ii ) {
1977  for ( Size jj = 1; jj <= n_nrchi_sample_bins_; ++jj ) {
1978  bbind_nrchi_lefts[ count ] = bbind_rotamers_to_sample_( jj, ii ).left_;
1979  bbind_nrchi_medians[ count ] = bbind_rotamers_to_sample_( jj, ii ).median_;
1980  bbind_nrchi_rights[ count ] = bbind_rotamers_to_sample_( jj, ii ).right_;
1981  bbind_nrchi_probs[ count ] = bbind_rotamers_to_sample_( jj, ii ).prob_;
1982 
1983  if ( bbind_nrchi_sampling_ ) {
1984  bbind_rotsample_sorted_order[ count ] = bbind_rotamers_sorted_by_probability_( jj, ii );
1985  }
1986  ++count;
1987  }
1988  }
1989  out.write( (char*) bbind_nrchi_lefts, n_bbind_nrchi_samples * sizeof( DunbrackReal ) );
1990  out.write( (char*) bbind_nrchi_medians, n_bbind_nrchi_samples * sizeof( DunbrackReal ) );
1991  out.write( (char*) bbind_nrchi_rights, n_bbind_nrchi_samples * sizeof( DunbrackReal ) );
1992  out.write( (char*) bbind_nrchi_probs, n_bbind_nrchi_samples * sizeof( DunbrackReal ) );
1993 
1994  if ( bbind_nrchi_sampling_ ) {
1995  out.write( (char*) bbind_rotsample_sorted_order, n_bbind_nrchi_samples * sizeof( boost::int32_t ) );
1996  }
1997 
1998  delete [] bbind_nrchi_lefts;
1999  delete [] bbind_nrchi_medians;
2000  delete [] bbind_nrchi_rights;
2001  delete [] bbind_nrchi_probs;
2002  delete [] bbind_rotsample_sorted_order;
2003  }
2004 
2005 }
2006 
2007 template < Size T >
2008 void
2010 {
2011  using namespace boost;
2012  parent::read_from_binary( in );
2013 
2014  // Check that constant member data initialized in the ctor is consistent with this input file
2015  // 1. bbind_nrchi_scoring_
2016  {
2017  boost::int32_t bbind_nrchi_scoring( 0 );
2018  in.read( (char*) &bbind_nrchi_scoring, sizeof( boost::int32_t ));
2019  if ( bbind_nrchi_scoring_ != static_cast< bool > ( bbind_nrchi_scoring ) ) {
2020  if ( bbind_nrchi_scoring ) {
2021  std::cerr << "ERROR: binary file description for " << grandparent::aa() << " contains data for"
2022  << " backbone independent non-rotameric chi scoring,\nbut the instantiated Semirotamer library"
2023  << " was created with backbone dependent non-rotameric chi scoring.\nCheck"
2024  << " semirotameric parameter definitions in RotamerLibrary::initialize_dun10_aa_parameters.";
2025  } else {
2026  std::cerr << "ERROR: binary file description for " << grandparent::aa() << " contains data for"
2027  << " backbone dependent non-rotameric chi scoring,\nbut the instantiated Semirotamer library"
2028  << " was created with backbone independent non-rotameric chi scoring.\nCheck"
2029  << " semirotameric parameter definitions in RotamerLibrary::initialize_dun10_aa_parameters.";
2030  }
2031  utility_exit();
2032  }
2033  }
2034 
2035  // 2. bbind_nrchi_sampling_
2036  {
2037  boost::int32_t bbind_nrchi_sampling( 0 );
2038  in.read( (char*) &bbind_nrchi_sampling, sizeof( boost::int32_t ));
2039  if ( bbind_nrchi_sampling_ != static_cast< bool > ( bbind_nrchi_sampling ) ) {
2040  if ( bbind_nrchi_sampling ) {
2041  std::cerr << "ERROR: binary file description for " << grandparent::aa() << " contains data for"
2042  << " backbone independent non-rotameric chi sampling,\nbut the instantiated Semirotamer library"
2043  << " was created with backbone dependent non-rotameric chi sampling.\nCheck"
2044  << " semirotameric parameter definitions in RotamerLibrary::initialize_dun10_aa_parameters.";
2045  } else {
2046  std::cerr << "ERROR: binary file description for " << grandparent::aa() << " contains data for"
2047  << " backbone dependent non-rotameric chi sampling,\nbut the instantiated Semirotamer library"
2048  << " was created with backbone independent non-rotameric chi sampling.\nCheck"
2049  << " semirotameric parameter definitions in RotamerLibrary::initialize_dun10_aa_parameters.";
2050  }
2051  utility_exit();
2052  }
2053  }
2054 
2055  if ( ! bbind_nrchi_scoring_ ) {
2056  // 3a. bbdep_non_rotameric_chi_scores_
2057  Size const n_bbdep_scores = grandparent::n_packed_rots() * parent::N_PHIPSI_BINS * parent::N_PHIPSI_BINS * bbdep_nrchi_nbins_;
2058  BBDepScoreInterpData * bbdep_nrc_interpdata = new BBDepScoreInterpData[ n_bbdep_scores ];
2059  in.read( (char*) bbdep_nrc_interpdata, n_bbdep_scores * sizeof( BBDepScoreInterpData ) );
2060 
2061  Size count( 0 );
2062  bbdep_nrc_interpdata_.resize( grandparent::n_packed_rots() );
2063  for ( Size ii = 1; ii <= grandparent::n_packed_rots(); ++ii ) {
2064  bbdep_nrc_interpdata_[ ii ].dimension( parent::N_PHIPSI_BINS, parent::N_PHIPSI_BINS, bbdep_nrchi_nbins_ );
2065  for ( Size jj = 1; jj <= bbdep_nrchi_nbins_; ++jj ) {
2066  for ( Size kk = 1; kk <= parent::N_PHIPSI_BINS; ++kk ) {
2067  for ( Size ll = 1; ll <= parent::N_PHIPSI_BINS; ++ll ) {
2068  bbdep_nrc_interpdata_[ ii ]( ll, kk, jj ) = bbdep_nrc_interpdata[ count ];
2069  ++count;
2070  }
2071  }
2072  }
2073  }
2074  delete [] bbdep_nrc_interpdata;
2075  } else {
2076  // 3b. bbind_non_rotameric_chi_scores_
2077  Size const n_bbind_scores = grandparent::n_packed_rots() * bbind_nrchi_nbins_;
2078  Real * bbind_non_rotameric_chi_scores = new Real[ n_bbind_scores ];
2079  in.read( (char*) bbind_non_rotameric_chi_scores, n_bbind_scores * sizeof( Real ));
2080  bbind_non_rotameric_chi_scores_.dimension( bbind_nrchi_nbins_, grandparent::n_packed_rots() );
2081 
2082  Size count( 0 );
2083  for ( Size ii = 1; ii <= grandparent::n_packed_rots(); ++ii ) {
2084  for ( Size jj = 1; jj <= bbind_nrchi_nbins_; ++jj ) {
2085  bbind_non_rotameric_chi_scores_( jj, ii ) = bbind_non_rotameric_chi_scores[ count ];
2086  ++count;
2087  }
2088  }
2089  delete [] bbind_non_rotameric_chi_scores;
2090  }
2091 
2092  /// 4.n_nrchi_sample_bins_
2093  {
2094  boost::int32_t n_nrchi_sample_bins( 0 );
2095  in.read( (char*) & n_nrchi_sample_bins, sizeof( boost::int32_t ) );
2096  n_nrchi_sample_bins_ = n_nrchi_sample_bins;
2097  }
2098 
2099 
2100  if ( ! bbind_nrchi_sampling_ ) {
2101  // 5. bbdep_rotamers_to_sample_, bbdep_rotsample_sorted_order_
2102  Size const n_bbdep_nrchi_samples =
2103  grandparent::n_packed_rots() * parent::N_PHIPSI_BINS * parent::N_PHIPSI_BINS * n_nrchi_sample_bins_;
2104 
2105  boost::int32_t * bbdep_nrchi_packed_rotnos = new boost::int32_t[ n_bbdep_nrchi_samples ];
2106  boost::int32_t * bbdep_nrchi_bin = new boost::int32_t[ n_bbdep_nrchi_samples ];
2107  DunbrackReal * bbdep_nrchi_means = new DunbrackReal[ n_bbdep_nrchi_samples ];
2108  DunbrackReal * bbdep_nrchi_sdevs = new DunbrackReal[ n_bbdep_nrchi_samples ];
2109  DunbrackReal * bbdep_nrchi_probs = new DunbrackReal[ n_bbdep_nrchi_samples ];
2110 
2111  boost::int32_t * bbdep_rotsample_sorted_order = new boost::int32_t[ n_bbdep_nrchi_samples ];
2112 
2113  in.read( (char*) bbdep_nrchi_packed_rotnos, n_bbdep_nrchi_samples * sizeof( boost::int32_t ) );
2114  in.read( (char*) bbdep_nrchi_bin, n_bbdep_nrchi_samples * sizeof( boost::int32_t ) );
2115  in.read( (char*) bbdep_nrchi_means, n_bbdep_nrchi_samples * sizeof( DunbrackReal ) );
2116  in.read( (char*) bbdep_nrchi_sdevs, n_bbdep_nrchi_samples * sizeof( DunbrackReal ) );
2117  in.read( (char*) bbdep_nrchi_probs, n_bbdep_nrchi_samples * sizeof( DunbrackReal ) );
2118  in.read( (char*) bbdep_rotsample_sorted_order, n_bbdep_nrchi_samples * sizeof( boost::int32_t ) );
2119 
2120  bbdep_rotamers_to_sample_.dimension( parent::N_PHIPSI_BINS, parent::N_PHIPSI_BINS, grandparent::n_packed_rots()*n_nrchi_sample_bins_ );
2121  bbdep_rotsample_sorted_order_.dimension( parent::N_PHIPSI_BINS, parent::N_PHIPSI_BINS, grandparent::n_packed_rots(), n_nrchi_sample_bins_ );
2122 
2123  Size count( 0 );
2124  Size count_iijj( 1 ); // 3d array sorted by frequency instead of 4d array divided first by rotameric rotno.
2125  for ( Size ii = 1; ii <= n_nrchi_sample_bins_; ++ii ) {
2126  for ( Size jj = 1; jj <= grandparent::n_packed_rots(); ++jj ) {
2127  for ( Size kk = 1; kk <= parent::N_PHIPSI_BINS; ++kk ) {
2128  for ( Size ll = 1; ll <= parent::N_PHIPSI_BINS; ++ll ) {
2129  bbdep_rotamers_to_sample_( ll, kk, count_iijj ).packed_rotno_ = bbdep_nrchi_packed_rotnos[ count ];
2130  bbdep_rotamers_to_sample_( ll, kk, count_iijj ).nrchi_bin_ = bbdep_nrchi_bin[ count ];
2131  bbdep_rotamers_to_sample_( ll, kk, count_iijj ).nrchi_mean_ = bbdep_nrchi_means[ count ];
2132  bbdep_rotamers_to_sample_( ll, kk, count_iijj ).nrchi_sd_ = bbdep_nrchi_sdevs[ count ];
2133  bbdep_rotamers_to_sample_( ll, kk, count_iijj ).prob_ = bbdep_nrchi_probs[ count ];
2134  bbdep_rotsample_sorted_order_( ll, kk, jj, ii ) = bbdep_rotsample_sorted_order[count];
2135  ++count;
2136  }
2137  }
2138  ++count_iijj;
2139  }
2140  }
2141 
2142  delete [] bbdep_nrchi_packed_rotnos; bbdep_nrchi_packed_rotnos = 0;
2143  delete [] bbdep_nrchi_bin; bbdep_nrchi_bin = 0;
2144  delete [] bbdep_nrchi_means; bbdep_nrchi_means = 0;
2145  delete [] bbdep_nrchi_sdevs; bbdep_nrchi_sdevs = 0;
2146  delete [] bbdep_nrchi_probs; bbdep_nrchi_probs = 0;
2147  delete [] bbdep_rotsample_sorted_order; bbdep_rotsample_sorted_order = 0;
2148 
2149  }
2150 
2151  { // Save the bbind rotamer definitions reguardless of bbind_nrchi_sampling_'s status.
2152 
2153  // 6. bbind_rotamers_to_sample_, bbind_rotamers_sorted_by_probability_
2154  Size const n_bbind_nrchi_samples = n_nrchi_sample_bins_ * grandparent::n_packed_rots();
2155 
2156  DunbrackReal * bbind_nrchi_lefts = new DunbrackReal[ n_bbind_nrchi_samples ];
2157  DunbrackReal * bbind_nrchi_medians = new DunbrackReal[ n_bbind_nrchi_samples ];
2158  DunbrackReal * bbind_nrchi_rights = new DunbrackReal[ n_bbind_nrchi_samples ];
2159  DunbrackReal * bbind_nrchi_probs = new DunbrackReal[ n_bbind_nrchi_samples ];
2160  boost::int32_t * bbind_rotsample_sorted_order = new boost::int32_t[ n_bbind_nrchi_samples ];
2161 
2162  in.read( (char*) bbind_nrchi_lefts, n_bbind_nrchi_samples * sizeof( DunbrackReal ) );
2163  in.read( (char*) bbind_nrchi_medians, n_bbind_nrchi_samples * sizeof( DunbrackReal ) );
2164  in.read( (char*) bbind_nrchi_rights, n_bbind_nrchi_samples * sizeof( DunbrackReal ) );
2165  in.read( (char*) bbind_nrchi_probs, n_bbind_nrchi_samples * sizeof( DunbrackReal ) );
2166  if ( bbind_nrchi_sampling_ ) {
2167  in.read( (char*) bbind_rotsample_sorted_order, n_bbind_nrchi_samples * sizeof( boost::int32_t ) );
2168  }
2169 
2170  bbind_rotamers_to_sample_.dimension( n_nrchi_sample_bins_, grandparent::n_packed_rots() );
2171  if ( bbind_nrchi_sampling_ ) {
2172  bbind_rotamers_sorted_by_probability_.dimension( n_nrchi_sample_bins_, grandparent::n_packed_rots() );
2173  }
2174 
2175  Size count( 0 );
2176  for ( Size ii = 1; ii <= grandparent::n_packed_rots(); ++ii ) {
2177  for ( Size jj = 1; jj <= n_nrchi_sample_bins_; ++jj ) {
2178  bbind_rotamers_to_sample_( jj, ii ).left_ = bbind_nrchi_lefts[ count ];
2179  bbind_rotamers_to_sample_( jj, ii ).median_ = bbind_nrchi_medians[ count ];
2180  bbind_rotamers_to_sample_( jj, ii ).right_ = bbind_nrchi_rights[ count ];
2181  bbind_rotamers_to_sample_( jj, ii ).prob_ = bbind_nrchi_probs[ count ];
2182 
2183  if ( bbind_nrchi_sampling_ ) {
2184  bbind_rotamers_sorted_by_probability_( jj, ii ) = bbind_rotsample_sorted_order[ count ];
2185  }
2186  ++count;
2187  }
2188  }
2189 
2190  delete [] bbind_nrchi_lefts;
2191  delete [] bbind_nrchi_medians;
2192  delete [] bbind_nrchi_rights;
2193  delete [] bbind_nrchi_probs;
2194  delete [] bbind_rotsample_sorted_order;
2195  }
2196 
2197 }
2198 
2199 
2200 template < Size T >
2201 void
2203  ChiVector const & chi,
2204  RotVector & rot
2205 ) const
2206 {
2207  parent::get_rotamer_from_chi( chi, rot );
2208  Size const packed_rotno( grandparent::rotwell_2_packed_rotno( rot ) );
2209  Real const nrchi = clip_to_nrchi_range( chi[ T + 1 ] );
2210  /// find bracketting chi's as defined in the bbind rotamer definitions file.
2211  for ( Size ii = 1; ii <= n_nrchi_sample_bins_; ++ii ) {
2212  Real const left = bbind_rotamers_to_sample_( ii, packed_rotno ).left_;
2213  Real const right = bbind_rotamers_to_sample_( ii, packed_rotno ).right_;
2214  if ( left < nrchi_lower_angle_ ) {
2215  /// nrchi bin spans periodicity gap...
2216  if (
2217  ! ( left <= nrchi && nrchi <= right ) &&
2218  ! ( left + nrchi_periodicity_ <= nrchi && nrchi <= right + nrchi_periodicity_ ) ) {
2219  continue;
2220  }
2221  } else if ( right > nrchi_lower_angle_ + nrchi_periodicity_ ) {
2222  if (
2223  ! ( left <= nrchi && nrchi <= right ) &&
2224  ! ( left - nrchi_periodicity_ <= nrchi && nrchi <= right - nrchi_periodicity_ ) ) {
2225  continue;
2226  }
2227  } else if ( left > nrchi ) {
2228  continue;
2229  } else if ( nrchi > right ) {
2230  continue;
2231  }
2232 
2233  rot[ T + 1 ] = ii;
2234  break;
2235  }
2236 
2237  if ( rot[ T + 1 ] == 0 ) {
2238  std::cerr << "Failed to find bracketing bin for : " << nrchi << T;
2239  for ( Size ii = 1; ii <= n_nrchi_sample_bins_; ++ii ) {
2240  std::cerr << "( " << ii << " : " << bbind_rotamers_to_sample_( ii, packed_rotno ).left_ << ", " << bbind_rotamers_to_sample_(ii, packed_rotno ).right_ << ") ";
2241  }
2242  std::cerr << std::endl;
2243  utility_exit();
2244  }
2245 }
2246 
2247 /// @brief For the non rotameric chi, how many asymmetric degrees are there? (e.g. 360 for asn, 180 for asp)
2248 template < Size T >
2249 void
2251  Real angle_in_degrees
2252 )
2253 {
2254  nrchi_periodicity_ = angle_in_degrees;
2255 }
2256 
2257 /// @brief What angle do the interpolation data start from?
2258 template < Size T >
2259 void
2261  Real angle_in_degrees
2262 )
2263 {
2264  nrchi_lower_angle_ = angle_in_degrees;
2265 }
2266 
2267 /// @brief What is the angular step size of the bbdep score?
2268 template < Size T >
2269 void
2271  Real step_size_in_degrees
2272 )
2273 {
2274  assert( nrchi_periodicity_ != 0.0 );
2275  assert( step_size_in_degrees != 0.0 );
2276  bbdep_nrchi_binsize_ = step_size_in_degrees;
2277  bbdep_nrchi_nbins_ = static_cast< Size > (nrchi_periodicity_ / step_size_in_degrees);
2278 }
2279 
2280 /// @brief What is the angular step size of the bbind score?
2281 template < Size T >
2282 void
2284  Real step_size_in_degrees
2285 )
2286 {
2287  assert( nrchi_periodicity_ != 0.0 );
2288  assert( step_size_in_degrees != 0.0 );
2289  bbind_nrchi_binsize_ = step_size_in_degrees;
2290  bbind_nrchi_nbins_ = static_cast< Size > (nrchi_periodicity_ / step_size_in_degrees);
2291 }
2292 
2293 
2294 template < Size T >
2295 Size
2297 {
2298  Size total_memory = parent::memory_usage_dynamic();
2299 
2300  /// for bbdep nrchi scoring
2301  for ( Size ii = 1; ii <= bbdep_nrc_interpdata_.size(); ++ii ) {
2302  total_memory += bbdep_nrc_interpdata_[ ii ].size() * sizeof( BBDepScoreInterpData );
2303  }
2304  total_memory += bbdep_nrc_interpdata_.size() * sizeof( FArray3D< BBDepScoreInterpData > );
2305 
2306  /// for bbind nrchi scoring
2307  total_memory += bbind_non_rotameric_chi_scores_.size() * sizeof( Real );
2308 
2309  /// for bbind nrchi sampling
2310  total_memory += bbind_rotamers_to_sample_.size() * sizeof( BBIndNRChiSample<> );
2311  total_memory += bbind_rotamers_sorted_by_probability_.size() * sizeof( Size );
2312 
2313  /// for bbdep nrchi sampling
2314  total_memory += bbdep_rotamers_to_sample_.size() * sizeof( BBDepNRChiSample<> );
2315  total_memory += bbdep_rotsample_sorted_order_.size() * sizeof( Size );
2316  /// parental cost
2317  total_memory += parent::memory_usage_dynamic();
2318 
2319  return total_memory;
2320 }
2321 
2322 
2323 template < Size T >
2325 {
2327 }
2328 
2329 
2330 template < Size T >
2331 void
2333  utility::io::izstream & in_rotdef,
2334  utility::io::izstream & in_rotameric,
2335  utility::io::izstream & in_continmin_bbdep,
2336  utility::io::izstream & in_continmin_bbind
2337 )
2338 {
2339  read_rotamer_definitions( in_rotdef );
2340  read_rotameric_data( in_rotameric );
2341  read_bbdep_continuous_minimization_data( in_continmin_bbdep );
2342  read_bbind_continuous_minimization_data( in_continmin_bbind );
2343 }
2344 
2345 /// @breif read-from-files that does not require the in_continmin_bbind file
2346 template < Size T >
2347 void
2349  utility::io::izstream & in_rotdef,
2350  utility::io::izstream & in_rotameric,
2351  utility::io::izstream & in_continmin_bbdep
2352 )
2353 {
2354  assert( ! bbind_nrchi_scoring_ ); // make sure you're not actually trying to use backbone-independent scoring.
2355 
2356  read_rotamer_definitions( in_rotdef );
2357  read_rotameric_data( in_rotameric );
2358  read_bbdep_continuous_minimization_data( in_continmin_bbdep );
2359 }
2360 
2361 
2362 
2363 
2364 /// @details The rotamer definition file has already been read before this
2365 /// function is called, so all of the rotameric rotamer wells have been encountered
2366 /// and the packed_rotno enumeration may be used instead of the regular rotno.
2367 template < Size T >
2368 void
2370  utility::io::izstream & in_rotameric
2371 )
2372 {
2373  std::string three_letter_code;
2374  Real phi, psi;
2375  Size count;
2377  DunbrackReal prob;
2380 
2381  FArray2D< Size > rotameric_count( parent::N_PHIPSI_BINS, parent::N_PHIPSI_BINS, Size( 0 ) );
2382  FArray2D< Size > semi_rotameric_count( parent::N_PHIPSI_BINS, parent::N_PHIPSI_BINS, Size( 0 ));
2383 
2384  while ( in_rotameric ) {
2385  /// 1. peek at the line; if it starts with #, skip to the next line.
2386  char first_char = in_rotameric.peek();
2387  if ( first_char == '#' ) {
2388  std::string line;
2389  in_rotameric.getline( line );
2390  continue;
2391  }
2392 
2393  /// 2. Line contains:
2394  /// a. AA three-letter code
2395  /// b. phi (degrees)
2396  /// c. psi (degrees)
2397  /// d. observed count
2398  /// e-h. chi-(1-4) wells (integers)
2399  /// i. rotamer probability
2400  /// j-m. chi-(1-4) mean (degrees)
2401  /// n-o. chi-(1-4) stdev (degrees );
2402 
2403  in_rotameric >> three_letter_code >> phi >> psi >> count;
2404  in_rotameric >> rotwell[ 1 ] >> rotwell[ 2 ] >> rotwell[ 3 ] >> rotwell[ 4 ];
2405  in_rotameric >> prob;
2406  in_rotameric >> mean[ 1 ] >> mean[ 2 ] >> mean[ 3 ] >> mean[ 4 ];
2407  in_rotameric >> stdev[ 1 ] >> stdev[ 2 ] >> stdev[ 3 ] >> stdev[ 4 ];
2408 
2409  if ( ! in_rotameric ) break; // we've read past the end of the file...
2410 
2411  if ( phi == 180 || psi == 180 ) continue; // duplicated data...
2412 
2413  /// AVOID inf and NaN by correcting the database
2414  for ( Size ii = 1; ii <= T; ++ii ) {
2415  if ( stdev[ ii ] == 0.0 ) {
2416  stdev[ ii ] = 5; // bogus!
2417  }
2418  }
2419  if ( prob == 0.0 ) {
2420  prob = 1e-4;
2421  /// APL -- On the advice of Roland Dunbrack, modifying the minimum probability to the
2422  /// resolution of the library. This helps avoid overwhelmingly unfavorable energies
2423  /// (5 log-units difference between 1e-4 and 1e-9) for rare rotamers.
2424  }
2425 
2426  Size phibin, psibin;
2427  parent::get_phipsi_bins( phi, psi, phibin, psibin );
2428 
2429  ++semi_rotameric_count( phibin, psibin );
2430 
2431  /// Store first T elements in rotamers_, and, if we're going to build bbdep
2432  /// rotamers during packing, store data for the last chi in the bbdep_rotamers_to_sample_
2433  /// array. If this rotamer has already been encountered, increment its probability.
2434  /// Because the probabilities of the rotameric chi are accumulated over all the
2435  /// non-rotameric chi samples, but the rotamers do not change order once they're found, they will not be
2436  /// in guaranteed sorted order at the end of reading this file. The "sorted" index
2437  /// is somewhat of a misnomer -- it simply means the sorted order in which the rotamer
2438  /// was first encountered. Fortunately, none of the rotamer building subroutines
2439  /// require that the rotamers_ tables be sorted by probability.
2440 
2441  Size const packed_rotno( grandparent::rotwell_2_packed_rotno( rotwell ) );
2442  if ( parent::packed_rotno_2_sorted_rotno()( phibin, psibin, packed_rotno ) == 0 ) {
2443  // first time this rotwell has been encountered.
2444  Size nencountered = ++rotameric_count( phibin, psibin );
2445  parent::packed_rotno_2_sorted_rotno()( phibin, psibin, packed_rotno ) = nencountered;
2446  for ( Size ii = 1; ii <= T; ++ii ) {
2447  parent::rotamers()( phibin, psibin, nencountered ).chi_mean( ii, mean[ ii ] );
2448  parent::rotamers()( phibin, psibin, nencountered ).chi_sd( ii, stdev[ ii ] );
2449  }
2450  parent::rotamers()( phibin, psibin, nencountered ).rotamer_probability() = prob;
2451  parent::rotamers()( phibin, psibin, nencountered ).rotE() = 0; // temp -- fill in sentinel values for unused variables
2452  parent::rotamers()( phibin, psibin, nencountered ).rotE_dsecophi() = 0;
2453  parent::rotamers()( phibin, psibin, nencountered ).rotE_dsecopsi() = 0;
2454  parent::rotamers()( phibin, psibin, nencountered ).rotE_dsecophipsi() = 0;
2455  } else {
2456  Size const sorted_rotno = parent::packed_rotno_2_sorted_rotno()( phibin, psibin, packed_rotno );
2457  parent::rotamers()( phibin, psibin, sorted_rotno ).rotamer_probability() += prob;
2458  // verify that the data file is as expected: chimean and chisd do not change for
2459  // rotameric chi across different entries of the nrchi.
2460  for ( Size ii = 1; ii <= T; ++ii ) {
2461  if ( std::abs( basic::periodic_range( parent::rotamers()( phibin, psibin, sorted_rotno ).chi_mean( ii ) - mean[ ii ], 360 )) > 1e-5 ) {
2462  std::cerr << "ERROR: semi-rotameric input invalid -- chi means differ." << std::endl;
2463  std::cerr << "Phi: " << phi << " Psi: " << psi << " original chi_" << ii << ": ";
2464  std::cerr << parent::rotamers()( phibin, psibin, sorted_rotno ).chi_mean( ii );
2465  std::cerr << " later chi_" << ii << ": "<< mean[ ii ] << std::endl;
2466  utility_exit();
2467  }
2468  if ( std::abs( parent::rotamers()( phibin, psibin, sorted_rotno ).chi_sd( ii ) - stdev[ ii ]) > 1e-5 ) {
2469  std::cerr << "ERROR: semi-rotameric input invalid -- chi stdevs differ." << std::endl;
2470  std::cerr << "Phi: " << phi << " Psi: " << psi << " original chi_" << ii << ": ";
2471  std::cerr << parent::rotamers()( phibin, psibin, sorted_rotno ).chi_sd( ii );
2472  std::cerr << " later chi_" << ii << ": "<< stdev[ ii ] << std::endl;
2473  utility_exit();
2474  }
2475  }
2476  }
2477 
2478  if ( ! bbind_nrchi_sampling_ ) {
2479  Size const which_rotamer = semi_rotameric_count( phibin, psibin );
2480  BBDepNRChiSample<> & sample( bbdep_rotamers_to_sample_( phibin, psibin, which_rotamer ) );
2481  sample.packed_rotno_ = packed_rotno;
2482  sample.nrchi_bin_ = rotwell[ T + 1 ];
2483  sample.nrchi_mean_ = mean[ T + 1 ];
2484  sample.nrchi_sd_ = stdev[ T + 1 ];
2485  sample.prob_ = prob;
2486  bbdep_rotsample_sorted_order_( phibin, psibin, packed_rotno, rotwell[ T + 1 ]) = which_rotamer;
2487  }
2488 
2489  }
2490  parent::initialize_bicubic_splines();
2491 
2492 
2493 }
2494 
2495 template < Size T >
2496 void
2498  utility::io::izstream & in_continmin
2499 )
2500 {
2501 
2502  if ( bbind_nrchi_scoring_ ) return;
2503 
2504  std::string three_letter_code;
2505  Real phi, psi, base_prob;
2506  Size count;
2507  utility::vector1< Size > rotwell( T );
2508  utility::vector1< Real > chimean( T );
2509  utility::vector1< Real > chisd( T );
2510  utility::vector1< Real > nrchi_probs( bbdep_nrchi_nbins_, 0.0 );
2511 
2512  utility::vector1< ObjexxFCL::FArray3D< Real > > bbdep_non_rotameric_chi_scores;
2513  bbdep_non_rotameric_chi_scores.resize( grandparent::n_packed_rots() );
2514  for ( Size ii = 1; ii <= grandparent::n_packed_rots(); ++ii ) {
2515  bbdep_non_rotameric_chi_scores[ ii ].dimension( parent::N_PHIPSI_BINS, parent::N_PHIPSI_BINS, bbdep_nrchi_nbins_ );
2516  bbdep_non_rotameric_chi_scores[ ii ] = 0;
2517  }
2518 
2519  while ( in_continmin ) {
2520  char first_char = in_continmin.peek();
2521  if ( first_char == '#' ) {
2522  std::string line; in_continmin.getline( line );
2523  continue;
2524  }
2525 
2526  // The structure of an input line is:
2527  // a. Three-letter code
2528  // b. phi
2529  // c. psi
2530  // d. observation count
2531  // e... rotamer well indices for rotameric residues (1 or 2)
2532  // f. probability of this well being occupied
2533  // g... rotameric chi means
2534  // h... rotameric chi sdevs
2535  // i... non-rotameric chi probabilities binned -- sum to 1.
2536  in_continmin >> three_letter_code >> phi >> psi >> count;
2537  for ( Size ii = 1; ii <= T; ++ii ) {
2538  in_continmin >> rotwell[ ii ];
2539  }
2540  in_continmin >> base_prob;
2541  for ( Size ii = 1; ii <= T; ++ii ) {
2542  in_continmin >> chimean[ ii ];
2543  }
2544  for ( Size ii = 1; ii <= T; ++ii ) {
2545  in_continmin >> chisd[ ii ];
2546  }
2547  for ( Size ii = 1; ii <= bbdep_nrchi_nbins_; ++ii ) {
2548  in_continmin >> nrchi_probs[ ii ];
2549  }
2550 
2551  if ( ! in_continmin ) break; // we've read past the end of the file...
2552  if ( phi == 180 || psi == 180 ) continue; // duplicated data...
2553 
2554  /// APL -- On the advice of Roland Dunbrack, modifying the minimum probability to the
2555  /// resolution of the library. This helps avoid overwhelmingly unfavorable energies
2556  /// (5 log-units difference between 1e-4 and 1e-9) for rare rotamers.
2557  if (base_prob == 0.0 ) { base_prob = 1e-4; } // correct probability 0 events.
2558 
2559  /// Now, convert the probabilities into scores
2560  Size phibin, psibin;
2561  parent::get_phipsi_bins( phi, psi, phibin, psibin );
2562  Size const rotno = grandparent::rotwell_2_rotno( rotwell );
2563  for ( Size ii = 1; ii <= bbdep_nrchi_nbins_; ++ii ) {
2564  /// input data has probability 0 events; assign a tiny probability for these cases.
2565 
2566  /// APL -- On the advice of Roland Dunbrack, modifying the minimum probability to the
2567  /// resolution of the library. This helps avoid overwhelmingly unfavorable energies
2568  /// (5 log-units difference between 1e-4 and 1e-9) for rare rotamers.
2569  Real const prob = base_prob * ( nrchi_probs[ ii ] == 0.0 ? 1e-4 : nrchi_probs[ ii ] );
2570  bbdep_non_rotameric_chi_scores[ rotno ]( phibin, psibin, ii ) = -std::log( prob );
2571  }
2572  }
2573 
2574  /// Now create the tricubic interpolation data and store that data in the
2575  if ( true ) {
2576  std::cout << "Creating tricubic splines for the backbone-dependent non-rotameric chi scores" << std::endl;
2577  using namespace numeric;
2578  using namespace numeric::interpolation::spline;
2579  BorderFlag border[3] = { e_Periodic, e_Periodic, e_Periodic};
2580  Real const start[3] = { -180.0, -180.0, nrchi_lower_angle_};
2581  Real const delta[3] = { 10.0, 10.0, bbdep_nrchi_binsize_ };
2582  bool const lin_cont[3] = { true, true, true}; // not used since we're imposing periodic boundary conditions
2583  std::pair< double, double> const first_be[3] = // also not used since we're imposing periodic boundary conditions
2584  {
2585  std::pair< double, double>( 10, 10),
2586  std::pair< double, double>( 10, 10),
2587  std::pair< double, double>( 10, 10)
2588  };
2589 
2590  for ( Size ii = 1; ii <= grandparent::n_packed_rots(); ++ii ) {
2591  MathTensor< Real > data( parent::N_PHIPSI_BINS, parent::N_PHIPSI_BINS, bbdep_nrchi_nbins_ );
2592  for ( Size jj = 1; jj <= parent::N_PHIPSI_BINS; ++jj ) {
2593  for ( Size kk = 1; kk <= parent::N_PHIPSI_BINS; ++kk ) {
2594  for ( Size ll = 1; ll <= bbdep_nrchi_nbins_; ++ll ) {
2595  data( jj-1, kk-1, ll-1 ) = bbdep_non_rotameric_chi_scores[ ii ]( jj, kk, ll );
2596  }
2597  }
2598  }
2599  TricubicSpline spline;
2600  spline.train( border, start, delta, data, lin_cont, first_be );
2601  for ( Size jj = 1; jj <= parent::N_PHIPSI_BINS; ++jj ) {
2602  for ( Size kk = 1; kk <= parent::N_PHIPSI_BINS; ++kk ) {
2603  for ( Size ll = 1; ll <= bbdep_nrchi_nbins_; ++ll ) {
2604  bbdep_nrc_interpdata_[ ii ]( jj, kk, ll ).value_ = (DunbrackReal) data( jj-1, kk-1, ll-1 );
2605  bbdep_nrc_interpdata_[ ii ]( jj, kk, ll ).dsecox_ = (DunbrackReal) spline.get_dsecox()( jj-1, kk-1, ll-1 );
2606  bbdep_nrc_interpdata_[ ii ]( jj, kk, ll ).dsecoy_ = (DunbrackReal) spline.get_dsecoy()( jj-1, kk-1, ll-1 );
2607  bbdep_nrc_interpdata_[ ii ]( jj, kk, ll ).dsecoz_ = (DunbrackReal) spline.get_dsecoz()( jj-1, kk-1, ll-1 );
2608  bbdep_nrc_interpdata_[ ii ]( jj, kk, ll ).dsecoxy_ = (DunbrackReal) spline.get_dsecoxy()( jj-1, kk-1, ll-1 );
2609  bbdep_nrc_interpdata_[ ii ]( jj, kk, ll ).dsecoxz_ = (DunbrackReal) spline.get_dsecoxz()( jj-1, kk-1, ll-1 );
2610  bbdep_nrc_interpdata_[ ii ]( jj, kk, ll ).dsecoyz_ = (DunbrackReal) spline.get_dsecoyz()( jj-1, kk-1, ll-1 );
2611  bbdep_nrc_interpdata_[ ii ]( jj, kk, ll ).dsecoxyz_ = (DunbrackReal) spline.get_dsecoxyz()( jj-1, kk-1, ll-1 );
2612  }
2613  }
2614  }
2615 
2616  }
2617  std::cout << "Finished creating tricubic splines" << std::endl;
2618  }
2619 }
2620 
2621 template < Size T >
2622 void
2624  utility::io::izstream & in_continmin
2625 )
2626 {
2627 
2628  if ( ! bbind_nrchi_scoring_ ) return;
2629 
2630  std::string three_letter_code;
2631  utility::vector1< Size > rotwell( 4, 0 );
2632  Real nrchi_val, rho, prob, neglnprob;
2633 
2634  while ( in_continmin ) {
2635  char first_char = in_continmin.peek();
2636  if ( first_char == '#' ) {
2637  std::string line; in_continmin.getline( line );
2638  continue;
2639  }
2640 
2641  /// Input line format is
2642  /// a. Three letter code
2643  /// b.c.d.e r1, r2, r3, r4
2644  /// f. nrchi grid point
2645  /// g. rho
2646  /// h. prob
2647  /// i. -lnprob
2648  in_continmin >> three_letter_code >> rotwell[ 1 ] >> rotwell[ 2 ] >> rotwell[ 3 ] >> rotwell[ 4 ];
2649  in_continmin >> nrchi_val >> rho >> prob >> neglnprob;
2650 
2651  if ( ! in_continmin ) break; // we've read past the end of the file...
2652 
2653  Size const packed_rotno( grandparent::rotwell_2_packed_rotno( rotwell ) );
2654  Size bbind_nrchi_bin, dummy; Real dummy_alpha;
2655  get_bbind_nrchi_bin( nrchi_val, bbind_nrchi_bin, dummy, dummy_alpha );
2656  bbind_non_rotameric_chi_scores_( bbind_nrchi_bin, packed_rotno ) = neglnprob;
2657  }
2658 }
2659 
2660 /// @details the rotamer definition file must be the first file read.
2661 /// Reading this file gives the number of pseudorotamers used for
2662 /// both the bbdep and bbind rotamer building. The bbind rotamer data
2663 /// is saved iff the bbind_rotamer_building_ flag is true.
2664 template < Size T >
2665 void
2667  utility::io::izstream & in_rotdef
2668 )
2669 {
2670  utility::vector1< Size > rotwell( 4, 0 );
2671  Real prob, lnprob, left, median, right;
2672 
2673  utility::vector1< utility::vector1< Real > > lefts( grandparent::n_possible_rots() );
2674  utility::vector1< utility::vector1< Real > > medians( grandparent::n_possible_rots() );
2675  utility::vector1< utility::vector1< Real > > rights( grandparent::n_possible_rots() );
2676  utility::vector1< utility::vector1< Real > > probs( grandparent::n_possible_rots() );
2677 
2678  while ( in_rotdef ) {
2679  char first_char = in_rotdef.peek();
2680  if ( first_char == '#' ) {
2681  std::string line; in_rotdef.getline( line );
2682  continue;
2683  }
2684 
2685  /// Input line is formatted:
2686  /// a.b.c.d. r1, r2, r3, r4
2687  /// e. prob
2688  /// f. lnprob
2689  /// g. non-rotameric chi pseudorotamer left range
2690  /// h. non-rotameric chi pseudorotamer median (mode?)
2691  /// i. non-rotameric chi pseudorotamer right range
2692  in_rotdef >> rotwell[ 1 ] >> rotwell[ 2 ] >> rotwell[ 3 ] >> rotwell[ 4 ];
2693  in_rotdef >> prob >> lnprob >> left >> median >> right;
2694 
2695  if ( ! in_rotdef ) break; // we've read past the end of the file...
2696 
2697  Size const rotno( grandparent::rotwell_2_rotno( rotwell ) );
2698  if ( rotwell[ T + 1 ] == 1 ) {
2699  grandparent::mark_rotwell_exists( rotwell );
2700  }
2701  lefts[ rotno ].push_back( left );
2702  medians[ rotno ].push_back( median );
2703  rights[ rotno ].push_back( right );
2704  probs[ rotno ].push_back( prob );
2705  }
2706 
2707  for ( Size ii = 1; ii <= grandparent::n_possible_rots(); ++ii ) {
2708  /// Verify that there are the same number of nrchi rotamers for each rotno.
2709  if ( lefts[ ii ].size() != 0 ) {
2710  /// find the first rotno with data.
2711  for ( Size jj = ii+1; jj <= grandparent::n_possible_rots(); ++jj ) {
2712  if ( lefts[ jj ].size() != 0 && lefts[ jj ].size() != lefts[ ii ].size() ) {
2713  std::cerr << "ERROR: Error in reading rotamer definition file" << std::endl;
2714  std::cerr << "ERROR: rotno's " << ii << " and " << jj;
2715  std::cerr << " have each defined a different number of pseudorots: ";
2716  std::cerr << lefts[ ii ].size() << " != " << lefts[ jj ].size();
2717  std::cerr << std::endl;
2718  utility_exit();
2719  }
2720  }
2721 
2722  n_nrchi_sample_bins_ = lefts[ ii ].size();
2723 
2724  /// DONE -- quit this loop
2725  break;
2726  }
2727  }
2728 
2729 
2730  /// After reading this file, we have seen all the rotameric chi that we are going to.
2731  /// Tell the base class that the rotno to packedrotno conversion is now appropriate.
2732  /// This triggers a call to convert rotno indices to packedrotno indices
2733  grandparent::declare_all_existing_rotwells_encountered();
2734 
2735  /// Allocate space for rotamers and rotamer-sorted-order mapping
2736  parent::rotamers().dimension( parent::N_PHIPSI_BINS, parent::N_PHIPSI_BINS, grandparent::n_packed_rots() );
2737  parent::packed_rotno_2_sorted_rotno().dimension( parent::N_PHIPSI_BINS, parent::N_PHIPSI_BINS, grandparent::n_packed_rots() );
2738  parent::packed_rotno_2_sorted_rotno() = 0;
2739 
2740  /// save this data for rotamer creation and for binning nrchi values regardless of whether
2741  /// we're using bbind rotamer sampling.
2742  bbind_rotamers_to_sample_.dimension( n_nrchi_sample_bins_, grandparent::n_packed_rots() );
2743  // demension this mapping array iff bbind_nrchi_sampling_.
2744  //bbind_rotamers_sorted_by_probability_.dimension( n_nrchi_sample_bins_, grandparent::n_packed_rots() );
2745  Size count_packed_rots( 0 );
2746  for ( Size ii = 1; ii <= grandparent::n_possible_rots(); ++ii ) {
2747  if ( lefts[ ii ].size() == 0 ) continue;
2748  ++count_packed_rots;
2749  for ( Size jj = 1; jj <= n_nrchi_sample_bins_; ++jj ) {
2750  bbind_rotamers_to_sample_( jj, count_packed_rots ).left_ = lefts[ ii ][ jj ];
2751  bbind_rotamers_to_sample_( jj, count_packed_rots ).median_ = medians[ ii ][ jj ];
2752  bbind_rotamers_to_sample_( jj, count_packed_rots ).right_ = rights[ ii ][ jj ];
2753  bbind_rotamers_to_sample_( jj, count_packed_rots ).prob_ = probs[ ii ][ jj ];
2754  }
2755  }
2756  if ( ! bbind_nrchi_sampling_ ) {
2757  /// Allocate space for bbdep rotamer sampling for the nrchi.
2758  bbdep_rotamers_to_sample_.dimension(
2759  parent::N_PHIPSI_BINS,
2760  parent::N_PHIPSI_BINS,
2761  grandparent::n_packed_rots() * n_nrchi_sample_bins_ );
2762  bbdep_rotsample_sorted_order_.dimension(
2763  parent::N_PHIPSI_BINS,
2764  parent::N_PHIPSI_BINS,
2765  grandparent::n_packed_rots(),
2766  n_nrchi_sample_bins_ );
2767  bbdep_rotsample_sorted_order_ = 0;
2768  }
2769 
2770  if ( bbind_nrchi_scoring_ ) {
2771  assert( bbind_nrchi_nbins_ != 0 );
2772  bbind_non_rotameric_chi_scores_.dimension( bbind_nrchi_nbins_, grandparent::n_packed_rots() );
2773  bbind_non_rotameric_chi_scores_ = 0;
2774  } else {
2775  assert( bbdep_nrchi_nbins_ != 0 );
2776  bbdep_nrc_interpdata_.resize( grandparent::n_packed_rots() );
2777  for ( Size ii = 1; ii <= grandparent::n_packed_rots(); ++ii ) {
2778  bbdep_nrc_interpdata_[ ii ].dimension( parent::N_PHIPSI_BINS, parent::N_PHIPSI_BINS, bbdep_nrchi_nbins_ );
2779  }
2780  }
2781 
2782  if ( bbind_nrchi_sampling_ ) {
2783  bbind_rotamers_sorted_by_probability_.dimension( n_nrchi_sample_bins_, grandparent::n_packed_rots() );
2784  utility::vector1< ProbSortClass > rot_probs_and_inds( n_nrchi_sample_bins_ );
2785  for ( Size ii = 1; ii <= grandparent::n_packed_rots(); ++ii ) {
2786  for ( Size jj = 1; jj <= n_nrchi_sample_bins_; ++jj ) {
2787  rot_probs_and_inds[ jj ].probability_ = bbind_rotamers_to_sample_( jj, ii ).prob_;
2788  rot_probs_and_inds[ jj ].index_ = jj;
2789  }
2790  /// sort into ascending order by probability
2791  std::sort( rot_probs_and_inds.begin(), rot_probs_and_inds.end(), psc_compare );
2792  for ( Size jj = 1, jj_down = n_nrchi_sample_bins_; jj_down >= 1; --jj_down, ++jj ) {
2793  /// store in descending order; most likely to least likely
2794  bbind_rotamers_sorted_by_probability_( jj, ii ) = rot_probs_and_inds[ jj_down ].index_;
2795  }
2796  }
2797 
2798  }
2799 }
2800 
2801 /// @details Clips to range [ nrchi_lower_angle_, nrchi_lower_angle_ + nrchi_periodicity )
2802 template < Size T >
2803 Real
2805 {
2806  Real chip = basic::periodic_range( chi, nrchi_periodicity_ );
2807 
2808  if ( chip >= nrchi_lower_angle_ + nrchi_periodicity_ ) {
2809  while ( chip >= nrchi_lower_angle_ + nrchi_periodicity_ ) {
2810  chip -= nrchi_periodicity_;
2811  }
2812  } else if ( chip < nrchi_lower_angle_ ) {
2813  while ( chip < nrchi_lower_angle_ ) {
2814  chip += nrchi_periodicity_;
2815  }
2816  }
2817  return chip;
2818 }
2819 
2820 template < Size T >
2821 void
2823  Real nrchi,
2824  Size & bin_lower,
2825  Size & bin_upper,
2826  Real & nrchi_alpha
2827 ) const
2828 {
2829  Real clipped_nrchi( clip_to_nrchi_range( nrchi ));
2830  grandparent::bin_angle(
2831  nrchi_lower_angle_, bbdep_nrchi_binsize_, nrchi_periodicity_, bbdep_nrchi_nbins_,
2832  clipped_nrchi, bin_lower, bin_upper, nrchi_alpha
2833  );
2834 }
2835 
2836 template < Size T >
2837 void
2839  Real nrchi,
2840  Size & bin_lower,
2841  Size & bin_upper,
2842  Real & nrchi_alpha
2843 ) const
2844 {
2845  Real clipped_nrchi( clip_to_nrchi_range( nrchi ));
2846  grandparent::bin_angle(
2847  nrchi_lower_angle_, bbind_nrchi_binsize_, nrchi_periodicity_, bbind_nrchi_nbins_,
2848  clipped_nrchi, bin_lower, bin_upper, nrchi_alpha
2849  );
2850 }
2851 
2852 
2853 template < Size T >
2856  Size const packed_rotno,
2857  Size const nrchi_bin,
2858  Size const phibin,
2859  Size const psibin,
2860  Size const phibin_next,
2861  Size const psibin_next,
2862  Real const phi_alpha,
2863  Real const psi_alpha
2864 ) const
2865 {
2866  Size const
2867  ind00( bbdep_rotsample_sorted_order_( phibin , psibin , packed_rotno, nrchi_bin )),
2868  ind01( bbdep_rotsample_sorted_order_( phibin , psibin_next, packed_rotno, nrchi_bin )),
2869  ind10( bbdep_rotsample_sorted_order_( phibin_next, psibin , packed_rotno, nrchi_bin )),
2870  ind11( bbdep_rotsample_sorted_order_( phibin_next, psibin_next, packed_rotno, nrchi_bin ));
2871 
2872  BBDepNRChiSample<> const & nrchi_sample_00( bbdep_rotamers_to_sample_( phibin , psibin , ind00 ));
2873  BBDepNRChiSample<> const & nrchi_sample_01( bbdep_rotamers_to_sample_( phibin , psibin_next, ind01 ));
2874  BBDepNRChiSample<> const & nrchi_sample_10( bbdep_rotamers_to_sample_( phibin_next, psibin , ind10 ));
2875  BBDepNRChiSample<> const & nrchi_sample_11( bbdep_rotamers_to_sample_( phibin_next, psibin_next, ind11 ));
2876 
2877  return interpolate_bbdep_nrchi_sample(
2878  nrchi_sample_00, nrchi_sample_01,
2879  nrchi_sample_10, nrchi_sample_11,
2880  phi_alpha, psi_alpha
2881  );
2882 }
2883 
2884 template < Size T >
2887  BBDepNRChiSample<> const & nrchi_sample_00,
2888  BBDepNRChiSample<> const & nrchi_sample_01,
2889  BBDepNRChiSample<> const & nrchi_sample_10,
2890  BBDepNRChiSample<> const & nrchi_sample_11,
2891  Real const phi_alpha,
2892  Real const psi_alpha
2893 ) const
2894 {
2895  BBDepNRChiSample< Real > interpolated_sample;
2896  interpolated_sample.packed_rotno_ = nrchi_sample_00.packed_rotno_;
2897  interpolated_sample.nrchi_bin_ = nrchi_sample_00.nrchi_bin_;
2898 
2899  Real dummy_dprob_1, dummy_dprob_2;
2900  basic::interpolate_bilinear_by_value(
2901  static_cast< Real > ( nrchi_sample_00.prob_),
2902  static_cast< Real > ( nrchi_sample_10.prob_),
2903  static_cast< Real > ( nrchi_sample_01.prob_),
2904  static_cast< Real > ( nrchi_sample_11.prob_),
2905  phi_alpha, psi_alpha, parent::PHIPSI_BINRANGE, false /*treat_as_angles*/,
2906  interpolated_sample.prob_,
2907  dummy_dprob_1, dummy_dprob_2
2908  );
2909  Real dummy_dmean_1, dummy_dmean_2;
2910  basic::interpolate_bilinear_by_value(
2911  static_cast< Real > ( nrchi_sample_00.nrchi_mean_),
2912  static_cast< Real > ( nrchi_sample_10.nrchi_mean_),
2913  static_cast< Real > ( nrchi_sample_01.nrchi_mean_),
2914  static_cast< Real > ( nrchi_sample_11.nrchi_mean_),
2915  phi_alpha, psi_alpha, parent::PHIPSI_BINRANGE, true /*treat_as_angles*/,
2916  interpolated_sample.nrchi_mean_,
2917  dummy_dmean_1, dummy_dmean_2
2918  );
2919  Real dummy_dsd_1, dummy_dsd_2;
2920  basic::interpolate_bilinear_by_value(
2921  static_cast< Real > ( nrchi_sample_00.nrchi_sd_),
2922  static_cast< Real > ( nrchi_sample_10.nrchi_sd_),
2923  static_cast< Real > ( nrchi_sample_01.nrchi_sd_),
2924  static_cast< Real > ( nrchi_sample_11.nrchi_sd_),
2925  phi_alpha, psi_alpha, parent::PHIPSI_BINRANGE, false /*treat_as_angles*/,
2926  interpolated_sample.nrchi_sd_,
2927  dummy_dsd_1, dummy_dsd_2
2928  );
2929  return interpolated_sample;
2930 }
2931 
2932 /// @details never call this ctor!
2933 //template < Size T >
2934 //SemiRotamericSingleResidueDunbrackLibrary< T >::SemiRotamericSingleResidueDunbrackLibrary()
2935 // :
2936 //{
2937 // utility_exit();
2938 //}
2939 
2940 
2941 
2942 } // namespace dunbrack
2943 } // namespace scoring
2944 } // namespace core
2945 
2946 #endif // INCLUDED_core_pack_dunbrack_SemiRotamericSingleResidueDunbrackLibrary_TMPL_HH
2947