Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
RotamerTrie.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/trie/trie_vs_trie.hh
11 /// @brief
12 /// @author Andrew Leaver-Fay (aleaverfay@gmail.com)
13 
14 #ifndef INCLUDED_core_scoring_trie_RotamerTrie_hh
15 #define INCLUDED_core_scoring_trie_RotamerTrie_hh
16 
17 // Unit Headers
19 
20 // Package Headers
29 
30 #ifdef WIN32 //VC++ needs full class declaration
31  #include <core/scoring/etable/etrie/EtableAtom.hh> // WIN32 INCLUDE
32  #include <core/scoring/hbonds/hbtrie/HBAtom.hh> // WIN32 INCLUDE
33  #include <core/scoring/mm/mmtrie/MMEnergyTableAtom.hh> // WIN32 INCLUDE
34  #include <core/scoring/etable/etrie/CountPairData_1_1.hh> // WIN32 INCLUDE
35  #include <core/scoring/etable/etrie/CountPairData_1_2.hh> // WIN32 INCLUDE
36  #include <core/scoring/etable/etrie/CountPairData_1_3.hh> // WIN32 INCLUDE
37  #include <core/scoring/etable/etrie/CountPairDataGeneric.hh> // WIN32 INCLUDE
38  #include <core/scoring/hackelec/ElecAtom.hh> // WIN32 INCLUDE
39  #include <core/scoring/hbonds/hbtrie/HBCPData.hh> // WIN32 INCLUDE
40 #endif
41 // Project Headers
43 #include <core/types.hh>
44 
45 // Utility Headers
46 // AUTO-REMOVED #include <utility/vector1.hh>
47 #include <utility/exit.hh>
48 
49 // Numeric Headers
50 #include <numeric/xyzVector.hh>
51 
52 // ObjexxFCL Headers
53 #include <ObjexxFCL/FArray2D.fwd.hh>
54 
55 #include <utility/vector1_bool.hh>
56 
57 
58 // STL Headers
59 //#include <cmath>
60 
61 namespace core {
62 namespace scoring {
63 namespace trie {
64 
65 template < class AT, class CPDATA >
66 class TrieNode
67 {
68 public:
69  // CTOR
72  first_atom_in_branch_( false ),
73  is_hydrogen_( false ),
74  is_term_( false ),
75  sibling_( 0 ),
77  {}
78 
79  TrieNode( AT atom, CPDATA cp_data ) :
80  atom_( atom ),
81  cp_data_( cp_data ),
83  first_atom_in_branch_( false ),
85  is_term_( false ),
86  sibling_( 0 ),
88  {}
89 
90  TrieNode( TrieNode< AT, CPDATA > const & other ) :
91  atom_( other.atom_ ),
92  cp_data_( other.cp_data_ ),
95  is_hydrogen_( other.is_hydrogen_ ),
96  is_term_( other.is_term_ ),
97  sibling_( other.sibling_ ),
99  {}
100 
101  //DSTOR
103 
104  /// Properties
106  bool has_sibling() const { return sibling_ != 0; }
107  bool is_hydrogen() const { return is_hydrogen_; }
108  bool is_rotamer_terminal() const { return is_term_; }
109 
110  /// Accessors
112  CPDATA const & cp_data() const { return cp_data_; }
113  AT const & atom() const { return atom_; }
114  Size sibling() const { return sibling_; }
117  }
118 
119  ///Setters
120  void first_atom_in_branch( bool setting ) { first_atom_in_branch_ = setting; }
121  void sibling( Size setting ) { sibling_ = setting; }
122  void is_hydrogen( bool setting ) { is_hydrogen_ = setting; }
123  void is_rotamer_terminal( bool setting ) { is_term_ = setting; }
125  {
127  }
128  void num_rotamers_in_subtree( Size setting ) { rotamers_in_subtree_ = setting; }
129 
130  void print() const
131  {
132  std::cout << atom_ << "; " << cp_data_ << " : sqrad: " << subtree_intxn_sphere_radius_sqr_;
133  std::cout << " faib: " << first_atom_in_branch_;
134  std::cout << " H: " << is_hydrogen_;
135  std::cout << " term: " << is_term_;
136  std::cout << " sib: " << sibling_;
137  std::cout << " ris: " << rotamers_in_subtree_ << std::endl;
138  }
139 
140 private:
141  AT atom_;
142  CPDATA cp_data_;
146  bool is_term_;
149 
150 };
151 
152 template < class AT, class CPDATA >
153 class RotamerTrie : public RotamerTrieBase
154 {
155 public:
156 
158  typename utility::vector1< RotamerDescriptor< AT, CPDATA> > & rotamers,
159  Distance const atomic_interaction_cutoff_distance
160  )
161  {
162  construct_rotamer_trie( rotamers, atomic_interaction_cutoff_distance );
163  }
164 
165  virtual ~RotamerTrie() {}
166 
167 public: /// Type Resolution Functions
168  /// Four trie-vs-trie type resolution functions
169  virtual
170  void
172  RotamerTrieBase const & other,
173  TrieCountPairBase & cp,
174  etable::TableLookupEvaluator const & sfxn,
175  ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
176  ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
177  ) const
178  {
179  other.resolve_trie_vs_trie( *this, cp, sfxn, pair_energy_table, temp_table );
180  }
181 
182  virtual
183  void
186  TrieCountPairBase & cp,
187  etable::TableLookupEvaluator const & sfxn,
188  ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
189  ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
190  ) const
191  {
192  cp.resolve_trie_vs_trie( other, *this, sfxn, pair_energy_table, temp_table );
193  }
194 
195  virtual
196  void
199  TrieCountPairBase & cp,
200  etable::TableLookupEvaluator const & sfxn,
201  ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
202  ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
203  ) const
204  {
205  cp.resolve_trie_vs_trie( other, *this, sfxn, pair_energy_table, temp_table );
206  }
207 
208 
209  virtual
210  void
213  TrieCountPairBase & cp,
214  etable::TableLookupEvaluator const & sfxn,
215  ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
216  ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
217  ) const
218  {
219  cp.resolve_trie_vs_trie( other, *this, sfxn, pair_energy_table, temp_table );
220  }
221 
222  virtual
223  void
226  TrieCountPairBase & cp,
227  etable::TableLookupEvaluator const & sfxn,
228  ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
229  ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
230  ) const
231  {
232  cp.resolve_trie_vs_trie( other, *this, sfxn, pair_energy_table, temp_table );
233  }
234 
235  /// This function is called when the etable energy function get mixed up with non-etable tries.
236  /// It produces a utility_exit call.
237  virtual
238  void
240  RotamerTrieBase const &,
243  ObjexxFCL::FArray2D< core::PackerEnergy > &,
244  ObjexxFCL::FArray2D< core::PackerEnergy > &
245  ) const
246  {
247  utility_exit();
248  }
249 
250 
251  /// Four trie-vs-path type resolution functions
252  virtual
253  void
255  RotamerTrieBase const & other,
256  TrieCountPairBase & cp,
257  etable::TableLookupEvaluator const & sfxn,
258  utility::vector1< core::PackerEnergy > & pair_energy_vector,
260  ) const
261  {
262  other.resolve_trie_vs_path( *this, cp, sfxn, pair_energy_vector, temp_vector );
263  }
264 
265  virtual
266  void
269  TrieCountPairBase & cp,
270  etable::TableLookupEvaluator const & sfxn,
271  utility::vector1< core::PackerEnergy > & pair_energy_vector,
273  ) const
274  {
275  cp.resolve_trie_vs_path( other, *this, sfxn, pair_energy_vector, temp_vector );
276  }
277 
278  virtual
279  void
282  TrieCountPairBase & cp,
283  etable::TableLookupEvaluator const & sfxn,
284  utility::vector1< core::PackerEnergy > & pair_energy_vector,
286  ) const
287  {
288  cp.resolve_trie_vs_path( other, *this, sfxn, pair_energy_vector, temp_vector );
289  }
290 
291 
292  virtual
293  void
296  TrieCountPairBase & cp,
297  etable::TableLookupEvaluator const & sfxn,
298  utility::vector1< core::PackerEnergy > & pair_energy_vector,
300  ) const
301  {
302  cp.resolve_trie_vs_path( other, *this, sfxn, pair_energy_vector, temp_vector );
303  }
304 
305  virtual
306  void
309  TrieCountPairBase & cp,
310  etable::TableLookupEvaluator const & sfxn,
311  utility::vector1< core::PackerEnergy > & pair_energy_vector,
313  ) const
314  {
315  cp.resolve_trie_vs_path( other, *this, sfxn, pair_energy_vector, temp_vector );
316  }
317 
318  /// This function is called when the etable energy function get mixed up with non-etable tries.
319  /// It produces a utility_exit call.
320  virtual
321  void
323  RotamerTrieBase const &,
328  ) const
329  {
330  utility_exit_with_message("blah2");
331  }
332 
333  //////////////////////////////////////// CoarseEtableEnergy//////////////////////////////
334  virtual
335  void
337  RotamerTrieBase const & other,
338  TrieCountPairBase & cp,
339  etable::AnalyticEtableEvaluator const & sfxn,
340  ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
341  ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
342  ) const
343  {
344  other.resolve_trie_vs_trie( *this, cp, sfxn, pair_energy_table, temp_table );
345  }
346 
347  virtual
348  void
351  TrieCountPairBase & cp,
352  etable::AnalyticEtableEvaluator const & sfxn,
353  ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
354  ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
355  ) const
356  {
357  cp.resolve_trie_vs_trie( other, *this, sfxn, pair_energy_table, temp_table );
358  }
359 
360  virtual
361  void
364  TrieCountPairBase & cp,
365  etable::AnalyticEtableEvaluator const & sfxn,
366  ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
367  ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
368  ) const
369  {
370  cp.resolve_trie_vs_trie( other, *this, sfxn, pair_energy_table, temp_table );
371  }
372 
373 
374  virtual
375  void
378  TrieCountPairBase & cp,
379  etable::AnalyticEtableEvaluator const & sfxn,
380  ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
381  ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
382  ) const
383  {
384  cp.resolve_trie_vs_trie( other, *this, sfxn, pair_energy_table, temp_table );
385  }
386 
387  virtual
388  void
391  TrieCountPairBase & cp,
392  etable::AnalyticEtableEvaluator const & sfxn,
393  ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
394  ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
395  ) const
396  {
397  cp.resolve_trie_vs_trie( other, *this, sfxn, pair_energy_table, temp_table );
398  }
399 
400 
401  /// This function is called when the coarse etable energy function get mixed up with non-etable tries.
402  /// It produces a utility_exit call.
403  virtual
404  void
406  RotamerTrieBase const & ,
409  ObjexxFCL::FArray2D< core::PackerEnergy > & ,
410  ObjexxFCL::FArray2D< core::PackerEnergy > &
411  ) const
412  {
413  utility_exit();
414  }
415 
416  /// Four trie-vs-path type resolution functions
417  virtual
418  void
420  RotamerTrieBase const & other,
421  TrieCountPairBase & cp,
422  etable::AnalyticEtableEvaluator const & sfxn,
423  utility::vector1< core::PackerEnergy > & pair_energy_vector,
425  ) const
426  {
427  other.resolve_trie_vs_path( *this, cp, sfxn, pair_energy_vector, temp_vector );
428  }
429 
430  virtual
431  void
434  TrieCountPairBase & cp,
435  etable::AnalyticEtableEvaluator const & sfxn,
436  utility::vector1< core::PackerEnergy > & pair_energy_vector,
438  ) const
439  {
440  cp.resolve_trie_vs_path( other, *this, sfxn, pair_energy_vector, temp_vector );
441  }
442 
443  virtual
444  void
447  TrieCountPairBase & cp,
448  etable::AnalyticEtableEvaluator const & sfxn,
449  utility::vector1< core::PackerEnergy > & pair_energy_vector,
451  ) const
452  {
453  cp.resolve_trie_vs_path( other, *this, sfxn, pair_energy_vector, temp_vector );
454  }
455 
456 
457  virtual
458  void
461  TrieCountPairBase & cp,
462  etable::AnalyticEtableEvaluator const & sfxn,
463  utility::vector1< core::PackerEnergy > & pair_energy_vector,
465  ) const
466  {
467  cp.resolve_trie_vs_path( other, *this, sfxn, pair_energy_vector, temp_vector );
468  }
469 
470  virtual
471  void
474  TrieCountPairBase & cp,
475  etable::AnalyticEtableEvaluator const & sfxn,
476  utility::vector1< core::PackerEnergy > & pair_energy_vector,
478  ) const
479  {
480  cp.resolve_trie_vs_path( other, *this, sfxn, pair_energy_vector, temp_vector );
481  }
482 
483 
484  /// This function is called when the coarse etable energy function get mixed up with non-etable tries.
485  /// It produces a utility_exit call.
486  virtual
487  void
489  RotamerTrieBase const & ,
494  ) const
495  {
496  utility_exit();
497  }
498 
499  // HBond Type Resolution Functions
500  virtual
501  void
503  RotamerTrieBase const & other,
504  TrieCountPairBase & cp,
505  hbonds::HBondEnergy const & sfxn,
506  ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
507  ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
508  ) const
509  {
510  other.resolve_trie_vs_trie( *this, cp, sfxn, pair_energy_table, temp_table );
511  }
512 
513  virtual
514  void
517  TrieCountPairBase & cp,
518  hbonds::HBondEnergy const & sfxn,
519  ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
520  ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
521  ) const
522  {
523  cp.resolve_trie_vs_trie( other, *this, sfxn, pair_energy_table, temp_table );
524  }
525 
526  /// This function is called when hbond energy function get mixed up with non-hbond tries.
527  /// It produces a utility_exit call.
528  virtual
529  void
531  RotamerTrieBase const & ,
533  hbonds::HBondEnergy const & ,
534  ObjexxFCL::FArray2D< core::PackerEnergy > & ,
535  ObjexxFCL::FArray2D< core::PackerEnergy > &
536  ) const
537  {
538  utility_exit_with_message( "Type resolution error in trie vs trie. Unsupported mixing of HBondEnergy function with non-hbond trie.");
539  }
540 
541  virtual
542  void
544  RotamerTrieBase const & other,
545  TrieCountPairBase & cp,
546  hbonds::HBondEnergy const & sfxn,
547  utility::vector1< core::PackerEnergy > & pair_energy_vector,
549  ) const
550  {
551  other.resolve_trie_vs_path( *this, cp, sfxn, pair_energy_vector, temp_vector );
552  }
553 
554  virtual
555  void
558  TrieCountPairBase & cp,
559  hbonds::HBondEnergy const & sfxn,
560  utility::vector1< core::PackerEnergy > & pair_energy_vector,
562  ) const
563  {
564  cp.resolve_trie_vs_path( other, *this, sfxn, pair_energy_vector, temp_vector );
565  }
566 
567  /// This function is called when hbond energy function get mixed up with non-hbond tries.
568  /// It produces a utility_exit call.
569  virtual
570  void
572  RotamerTrieBase const & ,
574  hbonds::HBondEnergy const & ,
577  ) const
578  {
579  utility_exit_with_message("Type resolution error in trie-vs-path. Unsupported mixing of HBondEnergy function with non-hbond trie.");
580  }
581 
582  //////////////// Hack Elec E //////////////////////
583  /// Four trie-vs-trie type resolution functions
584  virtual
585  void
587  RotamerTrieBase const & other,
588  TrieCountPairBase & cp,
589  hackelec::HackElecEnergy const & sfxn,
590  ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
591  ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
592  ) const
593  {
594  other.resolve_trie_vs_trie( *this, cp, sfxn, pair_energy_table, temp_table );
595  }
596 
597  virtual
598  void
601  TrieCountPairBase & cp,
602  hackelec::HackElecEnergy const & sfxn,
603  ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
604  ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
605  ) const
606  {
607  cp.resolve_trie_vs_trie( other, *this, sfxn, pair_energy_table, temp_table );
608  }
609 
610  virtual
611  void
614  TrieCountPairBase & cp,
615  hackelec::HackElecEnergy const & sfxn,
616  ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
617  ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
618  ) const
619  {
620  cp.resolve_trie_vs_trie( other, *this, sfxn, pair_energy_table, temp_table );
621  }
622 
623 
624  virtual
625  void
628  TrieCountPairBase & cp,
629  hackelec::HackElecEnergy const & sfxn,
630  ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
631  ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
632  ) const
633  {
634  cp.resolve_trie_vs_trie( other, *this, sfxn, pair_energy_table, temp_table );
635  }
636 
637  virtual
638  void
641  TrieCountPairBase & cp,
642  hackelec::HackElecEnergy const & sfxn,
643  ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
644  ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
645  ) const
646  {
647  cp.resolve_trie_vs_trie( other, *this, sfxn, pair_energy_table, temp_table );
648  }
649 
650 
651  /// This function is called when the etable energy function get mixed up with non-etable tries.
652  /// It produces a utility_exit call.
653  virtual
654  void
656  RotamerTrieBase const &,
658  hackelec::HackElecEnergy const &,
659  ObjexxFCL::FArray2D< core::PackerEnergy > &,
660  ObjexxFCL::FArray2D< core::PackerEnergy > &
661  ) const
662  {
663  utility_exit();
664  }
665 
666 
667  /// Four trie-vs-path type resolution functions
668  virtual
669  void
671  RotamerTrieBase const & other,
672  TrieCountPairBase & cp,
673  hackelec::HackElecEnergy const & sfxn,
674  utility::vector1< core::PackerEnergy > & pair_energy_vector,
676  ) const
677  {
678  other.resolve_trie_vs_path( *this, cp, sfxn, pair_energy_vector, temp_vector );
679  }
680 
681  virtual
682  void
685  TrieCountPairBase & cp,
686  hackelec::HackElecEnergy const & sfxn,
687  utility::vector1< core::PackerEnergy > & pair_energy_vector,
689  ) const
690  {
691  cp.resolve_trie_vs_path( other, *this, sfxn, pair_energy_vector, temp_vector );
692  }
693 
694  virtual
695  void
698  TrieCountPairBase & cp,
699  hackelec::HackElecEnergy const & sfxn,
700  utility::vector1< core::PackerEnergy > & pair_energy_vector,
702  ) const
703  {
704  cp.resolve_trie_vs_path( other, *this, sfxn, pair_energy_vector, temp_vector );
705  }
706 
707 
708  virtual
709  void
712  TrieCountPairBase & cp,
713  hackelec::HackElecEnergy const & sfxn,
714  utility::vector1< core::PackerEnergy > & pair_energy_vector,
716  ) const
717  {
718  cp.resolve_trie_vs_path( other, *this, sfxn, pair_energy_vector, temp_vector );
719  }
720 
721  virtual
722  void
725  TrieCountPairBase & cp,
726  hackelec::HackElecEnergy const & sfxn,
727  utility::vector1< core::PackerEnergy > & pair_energy_vector,
729  ) const
730  {
731  cp.resolve_trie_vs_path( other, *this, sfxn, pair_energy_vector, temp_vector );
732  }
733 
734 
735  /// This function is called when the etable energy function get mixed up with non-etable tries.
736  /// It produces a utility_exit call.
737  virtual
738  void
740  RotamerTrieBase const &,
742  hackelec::HackElecEnergy const & ,
745  ) const
746  {
747  utility_exit_with_message("blah2");
748  }
749 
750  /// mm lj inter type resolution functions
751  virtual
752  void
754  RotamerTrieBase const & other,
755  TrieCountPairBase & cp,
756  methods::MMLJEnergyInter const & sfxn,
757  ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
758  ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
759  ) const
760  {
761  other.resolve_trie_vs_trie( *this, cp, sfxn, pair_energy_table, temp_table );
762  }
763 
764  virtual
765  void
768  TrieCountPairBase & cp,
769  methods::MMLJEnergyInter const & sfxn,
770  ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
771  ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
772  ) const
773  {
774  cp.resolve_trie_vs_trie( other, *this, sfxn, pair_energy_table, temp_table );
775  }
776 
777  virtual
778  void
781  TrieCountPairBase & cp,
782  methods::MMLJEnergyInter const & sfxn,
783  ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
784  ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
785  ) const
786  {
787  cp.resolve_trie_vs_trie( other, *this, sfxn, pair_energy_table, temp_table );
788  }
789 
790 
791  virtual
792  void
795  TrieCountPairBase & cp,
796  methods::MMLJEnergyInter const & sfxn,
797  ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
798  ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
799  ) const
800  {
801  cp.resolve_trie_vs_trie( other, *this, sfxn, pair_energy_table, temp_table );
802  }
803 
804  /// This function is called when the etable energy function get mixed up with non-etable tries.
805  /// It produces a utility_exit call.
806  virtual
807  void
809  RotamerTrieBase const &,
811  methods::MMLJEnergyInter const &,
812  ObjexxFCL::FArray2D< core::PackerEnergy > &,
813  ObjexxFCL::FArray2D< core::PackerEnergy > &
814  ) const
815  {
816  utility_exit();
817  }
818 
819 
820  /// Four trie-vs-path type resolution functions
821  virtual
822  void
824  RotamerTrieBase const & other,
825  TrieCountPairBase & cp,
826  methods::MMLJEnergyInter const & sfxn,
827  utility::vector1< core::PackerEnergy > & pair_energy_vector,
829  ) const
830  {
831  other.resolve_trie_vs_path( *this, cp, sfxn, pair_energy_vector, temp_vector );
832  }
833 
834  virtual
835  void
838  TrieCountPairBase & cp,
839  methods::MMLJEnergyInter const & sfxn,
840  utility::vector1< core::PackerEnergy > & pair_energy_vector,
842  ) const
843  {
844  cp.resolve_trie_vs_path( other, *this, sfxn, pair_energy_vector, temp_vector );
845  }
846 
847  virtual
848  void
851  TrieCountPairBase & cp,
852  methods::MMLJEnergyInter const & sfxn,
853  utility::vector1< core::PackerEnergy > & pair_energy_vector,
855  ) const
856  {
857  cp.resolve_trie_vs_path( other, *this, sfxn, pair_energy_vector, temp_vector );
858  }
859 
860 
861  virtual
862  void
865  TrieCountPairBase & cp,
866  methods::MMLJEnergyInter const & sfxn,
867  utility::vector1< core::PackerEnergy > & pair_energy_vector,
869  ) const
870  {
871  cp.resolve_trie_vs_path( other, *this, sfxn, pair_energy_vector, temp_vector );
872  }
873 
874  /// This function is called when the etable energy function get mixed up with non-etable tries.
875  /// It produces a utility_exit call.
876  virtual
877  void
879  RotamerTrieBase const &,
881  methods::MMLJEnergyInter const & ,
884  ) const
885  {
886  utility_exit_with_message("blah2");
887  }
888 
889 
890  /// END Type Resolution Functions
891 
892 
893 public:
894  /// Useful Functions
895  virtual
896  void print() const
897  {
898  std::cout << "RotamerTrie with parameters:" << std::endl;
899  for ( Size ii = 1; ii <= num_total_atoms_; ++ii )
900  {
901  trie_[ ii ].print();
902  }
903  }
904 
905  /// Accessors
910  Size max_atom_depth() const { return max_atom_depth_; }
911 
913  atoms() const
914  {
915  return trie_;
916  }
917 
920  {
922  }
923 
924 private: // Functions
925 
926  void
928  typename utility::vector1< RotamerDescriptor< AT, CPDATA > > & rotamers,
929  Distance const interaction_distance
930  )
931  {
932  using namespace numeric;
933 
934  num_total_rotamers_ = rotamers.size();
936  num_total_atoms_ = 0;
937  num_heavyatoms_ = 0;
938 
940  for ( Size ii = 1; ii <= num_total_rotamers_; ++ii ) {
941  if ( max_atoms_per_rotamer_ < rotamers[ ii ].natoms() ) {
942  max_atoms_per_rotamer_ = rotamers[ ii ].natoms();
943  }
944  }
945  max_atom_depth_ = max_atoms_per_rotamer_; // max_atom_depth_ is redundant!
946  std::sort( rotamers.begin(), rotamers.end() );
947 
949  // index ii represents the number of atoms rotamer ii has with ii-1
950  utility::vector1< Size > num_shared_atoms( num_total_rotamers_, 1);
951  for ( Size jj = 2; jj <= num_total_rotamers_; ++jj )
952  {
953  num_shared_atoms[jj] = rotamers[jj].count_atoms_in_common(rotamers[jj-1]);
954  //std::cout << "num_shared_atoms[" << jj << "]: " << num_shared_atoms[jj] << ", natoms[ " << jj-1 << "]: " << rotamers[ jj -1 ].natoms() << std::endl;
955  }
956 
957  Size count_num_shared_atoms = 0;
958  Size num_atoms_in_trie = rotamers[1].natoms();
959  for ( Size jj = 2; jj <= num_total_rotamers_; ++jj )
960  {
961  num_atoms_in_trie += rotamers[jj].natoms() - num_shared_atoms[jj];
962  count_num_shared_atoms += num_shared_atoms[jj];
963  }
964  trie_.resize( num_atoms_in_trie );
965  num_total_atoms_ = num_atoms_in_trie;
966 
967  //add the first rotamer
968  //cerr << "add the first rotamer" << endl;
970  utility::vector1< Size > heavyatoms_at_depth( max_atoms_per_rotamer_ );
971  heavyatoms_at_depth[1] = 0;
972 
973  Size first_rotamer = 1;
974  add_atom_to_trie( 1, rotamers[1].atom(1) );
975 
976  trie_[1].first_atom_in_branch( true );
977  if (! trie_[1].is_hydrogen()) ++num_heavyatoms_;
978  node_stack[1] = 1;
979 
980  for ( Size jj = 2; jj <= rotamers[first_rotamer].natoms(); ++jj ) {
981  //cerr << "atom : " << ii << endl;
982  add_atom_to_trie( jj, rotamers[first_rotamer].atom(jj));
983  if (! trie_[jj].is_hydrogen()) ++num_heavyatoms_;
984  node_stack[jj] = jj;
985  }
986  trie_[ rotamers[first_rotamer].natoms() ].is_rotamer_terminal( true );
987 
988  Size count_unique_rotamers( 1 ), count_atoms_placed( rotamers[1].natoms() );
989  total_rotamers_2_unique_rotamers_[rotamers[1].rotamer_id()] = count_unique_rotamers;
990  for ( Size jj = 2; jj <= num_total_rotamers_; ++jj ) {
991  //int jj_offset_for_bb = total_rotamer_offset_for_bb_(ii) + jj;
992  Size jj_num_shared_with_prev = num_shared_atoms[jj];
993  Size jj_num_atoms = rotamers[jj].natoms();
994  Size jj_first_distinguished = jj_num_shared_with_prev + 1;
995  //cerr << "rotamer : " << jj << endl;
996 
997  if (jj_num_shared_with_prev == jj_num_atoms)
998  {
999  //duplicate rotamer
1000 
1001  total_rotamers_2_unique_rotamers_[rotamers[jj].rotamer_id()] = count_unique_rotamers;
1002  continue;
1003  }
1004 
1005  ++count_atoms_placed;
1006  add_atom_to_trie( count_atoms_placed, rotamers[ jj ].atom( jj_first_distinguished ) );
1007 
1008  // Only mark as the first atom in a brach if there was a genuine branch point
1009  if ( jj_num_shared_with_prev < rotamers[ jj-1].natoms() ) {
1010  trie_[count_atoms_placed].first_atom_in_branch( true );
1011  }
1012 
1013  if (! trie_[count_atoms_placed].is_hydrogen() ) ++num_heavyatoms_;
1014 
1015  assert( node_stack[jj_first_distinguished] <= num_atoms_in_trie
1016  && (node_stack[jj_first_distinguished] > 0 || num_shared_atoms[jj] == rotamers[ jj - 1 ].natoms()) );
1017 
1018  if ( node_stack[ jj_first_distinguished] != 0 ) {
1019  trie_[ node_stack[jj_first_distinguished] ].sibling(count_atoms_placed);
1020  }
1021  node_stack[jj_first_distinguished] = count_atoms_placed;
1022 
1023  for ( Size kk = jj_num_shared_with_prev + 2; kk <= jj_num_atoms; ++kk )
1024  { //cerr << "atom : " << kk << endl;
1025  ++count_atoms_placed;
1026  add_atom_to_trie( count_atoms_placed, rotamers[jj].atom(kk) );
1027 
1028  if (! trie_[count_atoms_placed].is_hydrogen()) ++num_heavyatoms_;
1029  node_stack[ kk ] = count_atoms_placed;
1030  }
1031 
1032  ++count_unique_rotamers;
1033  total_rotamers_2_unique_rotamers_[rotamers[jj].rotamer_id() ] = count_unique_rotamers;
1034 
1035  trie_[ count_atoms_placed ].is_rotamer_terminal( true );
1036  }
1037  num_unique_rotamers_ = count_unique_rotamers;
1040  calculate_subtree_containing_radii( interaction_distance );
1041 
1042  }
1043 
1044  ///wow, this function used to be 100 lines long... count pair was such a beast!
1045  void
1047  Size trie_atom_id,
1049  )
1050  {
1051  trie_[ trie_atom_id ] = TrieNode< AT, CPDATA >( rdatom.atom(), rdatom.cp_data() );
1052  return;
1053  }
1054 
1055 
1056 
1058  {
1059  //cerr << "begin RotamerTrie::compute_max_stack_height()" << endl;
1061  max_branch_depth_ = 2;
1062  utility::vector1< Size > heavy_depth_stack( max_atoms_per_rotamer_ + 1 ); //safe upper bound on size
1063  heavy_depth_stack[1] = 0;
1064 
1065  Size stack_top = 2;
1066  for ( Size ii = 1; ii <= num_total_atoms_; ++ii ) {
1067  if ( trie_[ii].first_atom_in_branch() ) {
1068  --stack_top;
1069  //std::cout << "trie_[ " << ii << "].first_atom_in_branch; stack_top: " << stack_top << std::endl;
1070  }
1071 
1072  if ( trie_[ii].has_sibling() ) {
1073  //std::cout << "trie_[ " << ii << "].has_sibling: " << trie_[ii].sibling() << " stack_top: " << stack_top + 1 << std::endl;
1074  ++stack_top;
1075  heavy_depth_stack[stack_top] = heavy_depth_stack[stack_top-1];
1076  }
1077 
1078  if ( ! trie_[ii].is_hydrogen() ) ++heavy_depth_stack[stack_top];
1079 
1080  if ( max_branch_depth_ < stack_top ) max_branch_depth_ = stack_top;
1081  if ( max_heavyatom_depth_ < heavy_depth_stack[stack_top] ) {
1082  max_heavyatom_depth_ = heavy_depth_stack[stack_top];
1083  }
1084 
1085  }
1086  //assert( max_branch_depth_ <= max_atoms_per_rotamer_ );
1088  utility_exit_with_message("max_branch_depth_ should have triggered index-out-of-bounds assertion!");
1089  }
1090 
1091  //cerr << "max_branch_depth_: " << max_branch_depth_ << endl;
1092  return;
1093  }
1094 
1095  // prerequisit: max_branch_depth_ must have been computed
1097  {
1098 
1099  //cerr << "calculate_subtree_heavyatoms_and_rotamers()" << endl;
1100  utility::vector1< Size > heavyatom_stack( max_atoms_per_rotamer_, 0 );
1101  utility::vector1< Size > rotamers_in_subtree_stack( max_atoms_per_rotamer_, 0 );
1102 
1103  utility::vector1< Size > heavy_depth_stack( max_branch_depth_ );
1104  heavy_depth_stack[2] = 0; // why did I set this to -1 before?
1105  heavy_depth_stack[1] = 0;
1106  Size stack_top = 2;
1107 
1108  for ( Size ii = 1; ii <= num_total_atoms_; ++ii )
1109  {
1110  if ( trie_[ii].first_atom_in_branch() )
1111  { for ( Size jj = heavy_depth_stack[stack_top-1] + 1;
1112  jj <= heavy_depth_stack[stack_top]; ++jj )
1113  {
1114  //apl test
1115  assert ( heavyatom_stack[jj] <= num_total_atoms_ && heavyatom_stack[jj] > 0 );
1116 
1117  trie_[ heavyatom_stack[ jj ]].num_rotamers_in_subtree(
1118  rotamers_in_subtree_stack[jj]);
1119  rotamers_in_subtree_stack[jj] = 0;
1120  }
1121  --stack_top;
1122  }
1123 
1124  if ( trie_[ii].has_sibling() ) {
1125  ++stack_top;
1126  heavy_depth_stack[ stack_top ] = heavy_depth_stack[ stack_top - 1 ];
1127  }
1128 
1129  if (! trie_[ii].is_hydrogen() ) {
1130  ++heavy_depth_stack[stack_top];
1131  heavyatom_stack[ heavy_depth_stack[stack_top] ] = ii;
1132  }
1133 
1134  if ( trie_[ii].is_rotamer_terminal() ) {
1135  for ( Size jj = 1; jj <= heavy_depth_stack[stack_top]; ++jj ) {
1136  ++rotamers_in_subtree_stack[jj];
1137  }
1138  }
1139  }
1140  for ( Size ii = 1; ii <= heavy_depth_stack[ stack_top]; ++ii ) {
1141  assert ( heavyatom_stack[ii] <= num_total_atoms_ && heavyatom_stack[ii] > 0 );
1142  trie_[ heavyatom_stack[ii] ].num_rotamers_in_subtree( rotamers_in_subtree_stack[ii] );
1143  }
1144 
1145  //cerr << "done..." << endl;
1146  return;
1147  }
1148 
1149  void
1151  Distance const interaction_distance
1152  )
1153  {
1154  using namespace numeric;
1155 
1156  //cerr << "calculate_subtree_containing_radii()" << endl;
1157  utility::vector1< Size > heavyatom_stack( max_atoms_per_rotamer_, 0 );
1158 
1160 
1161  utility::vector1< Size > heavy_depth_stack( max_branch_depth_ + 1 );
1162  if ( max_branch_depth_ > 0 ) heavy_depth_stack[2] = 0;
1163  heavy_depth_stack[1] = 0;
1164  Size stack_top = 2;
1165 
1166 
1167  utility::vector1< core::Real > maxd2_in_subtree_stack( max_atoms_per_rotamer_, 0.0 );
1168 
1169  for ( Size ii = 1; ii <= num_total_atoms_; ++ii )
1170  {
1171  if ( trie_[ii].first_atom_in_branch() ) {
1172  for ( Size jj = heavy_depth_stack[stack_top-1] + 1;
1173  jj <= heavy_depth_stack[stack_top]; ++jj ) {
1174  core::Real subtree_plus_interaction_diameter =
1175  std::sqrt(maxd2_in_subtree_stack[ jj ]) + interaction_distance;
1176 
1177  trie_[ heavyatom_stack[ jj ]].subtree_interaction_sphere_square_radius(
1178  subtree_plus_interaction_diameter * subtree_plus_interaction_diameter );
1179  maxd2_in_subtree_stack[jj] = 0;
1180  }
1181  --stack_top;
1182  }
1183 
1184  if ( trie_[ii].has_sibling() ) {
1185  ++stack_top;
1186  heavy_depth_stack[ stack_top ] = heavy_depth_stack[ stack_top - 1 ];
1187  }
1188 
1189  if ( ! trie_[ii].is_hydrogen() ) {
1190  ++heavy_depth_stack[stack_top];
1191  heavyatom_stack[ heavy_depth_stack[stack_top] ] = ii;
1192  heavyatom_centers[ heavy_depth_stack[stack_top]] = trie_[ii].atom().xyz();
1193 
1194  for ( Size jj = 1; jj <= heavy_depth_stack[stack_top] - 1; ++jj ) {
1195  core::Real const d2 =
1196  heavyatom_centers[jj].distance_squared(
1197  heavyatom_centers[heavy_depth_stack[stack_top]] );
1198  if (d2 > maxd2_in_subtree_stack[jj]) {
1199  maxd2_in_subtree_stack[jj] = d2;
1200  }
1201  }
1202  }
1203 
1204  }
1205  for ( Size ii = 1; ii <= heavy_depth_stack[ stack_top]; ++ii ) {
1206  core::Real subtree_plus_interaction_diameter =
1207  std::sqrt(maxd2_in_subtree_stack[ ii ]) + interaction_distance;
1208 
1209  trie_[ heavyatom_stack[ii] ].subtree_interaction_sphere_square_radius(
1210  subtree_plus_interaction_diameter * subtree_plus_interaction_diameter );
1211  }
1212 
1213  return;
1214  }
1215 
1216 
1217 private: // DATA
1222 
1226 
1227  Size max_branch_depth_; //rename this max branch depth
1230 
1231 };
1232 
1233 
1234 } // namespace trie
1235 } // namespace scoring
1236 } // namespace core
1237 
1238 #endif