14 #ifndef INCLUDED_core_scoring_trie_RotamerTrie_hh
15 #define INCLUDED_core_scoring_trie_RotamerTrie_hh
30 #ifdef WIN32 //VC++ needs full class declaration
47 #include <utility/exit.hh>
50 #include <numeric/xyzVector.hh>
53 #include <ObjexxFCL/FArray2D.fwd.hh>
55 #include <utility/vector1_bool.hh>
65 template <
class AT,
class CPDATA >
152 template <
class AT,
class CPDATA >
159 Distance const atomic_interaction_cutoff_distance
175 ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
176 ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
188 ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
189 ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
201 ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
202 ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
215 ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
216 ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
228 ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
229 ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
243 ObjexxFCL::FArray2D< core::PackerEnergy > &,
244 ObjexxFCL::FArray2D< core::PackerEnergy > &
330 utility_exit_with_message(
"blah2");
340 ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
341 ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
353 ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
354 ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
366 ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
367 ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
380 ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
381 ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
393 ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
394 ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
409 ObjexxFCL::FArray2D< core::PackerEnergy > & ,
410 ObjexxFCL::FArray2D< core::PackerEnergy > &
506 ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
507 ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
519 ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
520 ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
534 ObjexxFCL::FArray2D< core::PackerEnergy > & ,
535 ObjexxFCL::FArray2D< core::PackerEnergy > &
538 utility_exit_with_message(
"Type resolution error in trie vs trie. Unsupported mixing of HBondEnergy function with non-hbond trie.");
579 utility_exit_with_message(
"Type resolution error in trie-vs-path. Unsupported mixing of HBondEnergy function with non-hbond trie.");
590 ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
591 ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
603 ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
604 ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
616 ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
617 ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
630 ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
631 ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
643 ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
644 ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
659 ObjexxFCL::FArray2D< core::PackerEnergy > &,
660 ObjexxFCL::FArray2D< core::PackerEnergy > &
747 utility_exit_with_message(
"blah2");
757 ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
758 ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
770 ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
771 ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
783 ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
784 ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
797 ObjexxFCL::FArray2D< core::PackerEnergy > & pair_energy_table,
798 ObjexxFCL::FArray2D< core::PackerEnergy > & temp_table
812 ObjexxFCL::FArray2D< core::PackerEnergy > &,
813 ObjexxFCL::FArray2D< core::PackerEnergy > &
886 utility_exit_with_message(
"blah2");
898 std::cout <<
"RotamerTrie with parameters:" << std::endl;
932 using namespace numeric;
946 std::sort( rotamers.begin(), rotamers.end() );
953 num_shared_atoms[jj] = rotamers[jj].count_atoms_in_common(rotamers[jj-1]);
957 Size count_num_shared_atoms = 0;
958 Size num_atoms_in_trie = rotamers[1].natoms();
961 num_atoms_in_trie += rotamers[jj].natoms() - num_shared_atoms[jj];
962 count_num_shared_atoms += num_shared_atoms[jj];
964 trie_.resize( num_atoms_in_trie );
971 heavyatoms_at_depth[1] = 0;
973 Size first_rotamer = 1;
976 trie_[1].first_atom_in_branch(
true );
980 for (
Size jj = 2; jj <= rotamers[first_rotamer].natoms(); ++jj ) {
986 trie_[ rotamers[first_rotamer].natoms() ].is_rotamer_terminal(
true );
988 Size count_unique_rotamers( 1 ), count_atoms_placed( rotamers[1].natoms() );
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;
997 if (jj_num_shared_with_prev == jj_num_atoms)
1005 ++count_atoms_placed;
1006 add_atom_to_trie( count_atoms_placed, rotamers[ jj ].atom( jj_first_distinguished ) );
1009 if ( jj_num_shared_with_prev < rotamers[ jj-1].natoms() ) {
1010 trie_[count_atoms_placed].first_atom_in_branch(
true );
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()) );
1018 if ( node_stack[ jj_first_distinguished] != 0 ) {
1019 trie_[ node_stack[jj_first_distinguished] ].sibling(count_atoms_placed);
1021 node_stack[jj_first_distinguished] = count_atoms_placed;
1023 for (
Size kk = jj_num_shared_with_prev + 2; kk <= jj_num_atoms; ++kk )
1025 ++count_atoms_placed;
1029 node_stack[ kk ] = count_atoms_placed;
1032 ++count_unique_rotamers;
1035 trie_[ count_atoms_placed ].is_rotamer_terminal(
true );
1063 heavy_depth_stack[1] = 0;
1067 if (
trie_[ii].first_atom_in_branch() ) {
1072 if (
trie_[ii].has_sibling() ) {
1075 heavy_depth_stack[stack_top] = heavy_depth_stack[stack_top-1];
1078 if ( !
trie_[ii].is_hydrogen() ) ++heavy_depth_stack[stack_top];
1088 utility_exit_with_message(
"max_branch_depth_ should have triggered index-out-of-bounds assertion!");
1104 heavy_depth_stack[2] = 0;
1105 heavy_depth_stack[1] = 0;
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 )
1115 assert ( heavyatom_stack[jj] <=
num_total_atoms_ && heavyatom_stack[jj] > 0 );
1117 trie_[ heavyatom_stack[ jj ]].num_rotamers_in_subtree(
1118 rotamers_in_subtree_stack[jj]);
1119 rotamers_in_subtree_stack[jj] = 0;
1124 if (
trie_[ii].has_sibling() ) {
1126 heavy_depth_stack[ stack_top ] = heavy_depth_stack[ stack_top - 1 ];
1129 if (!
trie_[ii].is_hydrogen() ) {
1130 ++heavy_depth_stack[stack_top];
1131 heavyatom_stack[ heavy_depth_stack[stack_top] ] = ii;
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];
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] );
1151 Distance const interaction_distance
1154 using namespace numeric;
1163 heavy_depth_stack[1] = 0;
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;
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;
1184 if (
trie_[ii].has_sibling() ) {
1186 heavy_depth_stack[ stack_top ] = heavy_depth_stack[ stack_top - 1 ];
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();
1194 for (
Size jj = 1; jj <= heavy_depth_stack[stack_top] - 1; ++jj ) {
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;
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;
1209 trie_[ heavyatom_stack[ii] ].subtree_interaction_sphere_square_radius(
1210 subtree_plus_interaction_diameter * subtree_plus_interaction_diameter );