44 #include <ObjexxFCL/format.hh>
51 #include <ObjexxFCL/FArray2D.hh>
53 #include <utility/vector1.hh>
56 using namespace ObjexxFCL;
61 namespace rotamer_set {
63 RotamerSets::RotamerSets() {}
64 RotamerSets::~RotamerSets() {}
71 using ObjexxFCL::fmt::I;
74 std::ofstream out( filename.c_str() );
77 Size model(0), atom_counter(0);
79 out <<
"MODEL" << I(9,model) <<
'\n';
81 if ( task_->pack_residue(i) )
continue;
87 bool found_a_rotamer(
false );
90 for (
Size ii=1; ii<= nmoltenres_; ++ii ) {
93 if ( rotset->num_rotamers() >= model ) {
94 if ( !found_a_rotamer ) {
95 found_a_rotamer =
true;
96 out <<
"MODEL" << I(9,model) <<
'\n';
101 if ( found_a_rotamer ) {
114 nmoltenres_ = task_->num_to_be_packed();
115 total_residue_ = task_->total_residue();
117 resid_2_moltenres_.resize( total_residue_ );
118 moltenres_2_resid_.resize( nmoltenres_ );
119 set_of_rotamer_sets_.resize( nmoltenres_ );
120 nrotamer_offsets_.resize( nmoltenres_ );
121 nrotamers_for_moltenres_.resize( nmoltenres_ );
123 uint count_moltenres = 0;
124 for (
uint ii = 1; ii <= total_residue_; ++ii )
126 if ( task_->pack_residue( ii ) ) {
128 resid_2_moltenres_[ ii ] = count_moltenres;
129 moltenres_2_resid_[ count_moltenres ] = ii;
133 resid_2_moltenres_[ ii ] = 0;
136 assert( count_moltenres == nmoltenres_ );
141 RotamerSets::build_rotamers(
148 for (
uint ii = 1; ii <= nmoltenres_; ++ii )
150 uint ii_resid = moltenres_2_resid_[ ii ];
152 rotset->set_resid( ii_resid );
153 rotset->build_rotamers( pose, sfxn, *task_, packer_neighbor_graph );
155 set_of_rotamer_sets_[ ii ] = rotset;
160 if ( set_of_rotamer_sets_.size() > 0 )
161 runtime_assert ( dynamic_cast< core::pack::rotamer_set::symmetry::SymmetricRotamerSet_ const * >( set_of_rotamer_sets_[ 1 ].
get() ) );
165 for (
uint ii = 1; ii <= nmoltenres_; ++ii )
167 set_of_rotamer_sets_[ ii ]->build_dependent_rotamers( *
this, pose, sfxn, *task_, packer_neighbor_graph );
170 update_offset_data();
172 if (task_->rotamer_links_exist()){
177 int expected_rot_count = 0;
179 for (
uint ii = 1; ii <= nmoltenres_; ++ii){
183 if ( visited[ moltenres_2_resid_[ii] ]){
187 int num_rot = 1000000;
188 int smallest_res = 0;
189 for (
uint jj = 1; jj <= copies.size(); ++jj){
190 visited[ copies[jj] ] =
true;
192 buffer = set_of_rotamer_sets_[ resid_2_moltenres_[ copies[jj] ] ]->num_rotamers();
193 if (buffer <= num_rot){
195 smallest_res = copies[jj];
198 expected_rot_count += num_rot;
201 RotamerSetCOP bufferset = rotamer_set_for_moltenresidue( resid_2_moltenres_[ smallest_res ]);
203 for (
uint jj = 1; jj <= copies.size(); ++jj){
205 if (copies[jj] == smallest_res){
212 for (Rotamers::const_iterator itr = bufferset->begin(), ite = bufferset->end(); itr!=ite; itr++){
216 cloneRes->seqpos(copies[jj]);
221 if ((*itr)->seqpos() == 1 && copies[jj] != 1 ){
223 cloneRes->residue_connection_partner(1, copies[jj]-1, 2);
224 cloneRes->residue_connection_partner(2, copies[jj]+1, 1);
226 else if ((*itr)->seqpos() == 1 && copies[jj] == 1 ){
227 cloneRes->copy_residue_connections( pose.
residue(copies[jj]));
231 cloneRes->residue_connection_partner(1, copies[jj]-1, 2);
232 cloneRes->residue_connection_partner(2, copies[jj]+1, 1);
235 cloneRes->copy_residue_connections( pose.
residue(copies[jj]));
238 cloneRes->copy_residue_connections( pose.
residue(copies[jj]));
248 using namespace core::chemical;
263 smallset->add_rotamer(*cloneRes);
267 smallset->set_resid(copies[jj]);
268 set_of_rotamer_sets_[ resid_2_moltenres_[ copies[jj] ]] = smallset;
280 std::cout <<
"expected rotamer count is " << expected_rot_count << std::endl;
283 update_offset_data();
302 RotamerSets::update_offset_data()
306 for (
uint ii = 1; ii <= nmoltenres_; ++ii )
308 nrotamers_for_moltenres_[ ii ] = set_of_rotamer_sets_[ii]->num_rotamers();
309 nrotamers_ += set_of_rotamer_sets_[ii]->num_rotamers();
310 if ( ii > 1 ) { nrotamer_offsets_[ ii ] = nrotamer_offsets_[ii - 1] + set_of_rotamer_sets_[ii - 1]->num_rotamers(); }
311 else { nrotamer_offsets_[ ii ] = 0; }
314 moltenres_for_rotamer_.resize( nrotamers_ );
315 uint count_rots_for_moltenres = 1;
316 uint count_moltenres = 1;
317 for (
uint ii = 1; ii <= nrotamers_; ++ii )
319 moltenres_for_rotamer_[ ii ] = count_moltenres;
320 if ( count_rots_for_moltenres == nrotamers_for_moltenres_[ count_moltenres ] )
322 count_rots_for_moltenres = 1;
327 ++count_rots_for_moltenres;
336 RotamerSets::compute_energies(
343 using namespace interaction_graph;
344 using namespace scoring;
348 ig->initialize( *
this );
349 compute_one_body_energies( pose, scfxn, packer_neighbor_graph, ig );
352 dynamic_cast< PrecomputedPairEnergiesInteractionGraph *
> ( ig.get() );
354 precompute_two_body_energies( pose, scfxn, packer_neighbor_graph, pig );
359 prepare_otf_graph( pose, scfxn, packer_neighbor_graph, otfig );
360 compute_proline_correction_energies_for_otf_graph( pose, scfxn, packer_neighbor_graph, otfig);
362 utility_exit_with_message(
"Unknown interaction graph type encountered in RotamerSets::compute_energies()");
369 RotamerSets::compute_one_body_energies(
377 for (
uint ii = 1; ii <= nmoltenres_; ++ii )
380 set_of_rotamer_sets_[ ii ]->compute_one_body_energies(
381 pose, scfxn, *task_, packer_neighbor_graph, one_body_energies );
382 ig->add_to_nodes_one_body_energy( ii, one_body_energies );
387 RotamerSets::precompute_two_body_energies(
392 bool const finalize_edges
395 using namespace interaction_graph;
396 using namespace scoring;
402 for (
uint ii = 1; ii <= nmoltenres_; ++ ii )
405 uint const ii_resid = moltenres_2_resid_[ ii ];
409 uli = packer_neighbor_graph->get_node( ii_resid )->const_upper_edge_list_begin(),
410 ulie = packer_neighbor_graph->get_node( ii_resid )->const_upper_edge_list_end();
413 uint const jj_resid = (*uli)->get_second_node_ind();
414 uint const jj = resid_2_moltenres_[ jj_resid ];
415 if ( jj == 0 )
continue;
417 FArray2D< core::PackerEnergy > pair_energy_table(
418 nrotamers_for_moltenres_[ jj ],
419 nrotamers_for_moltenres_[ ii ], 0.0 );
425 *ii_rotset, *jj_rotset, pose, pair_energy_table );
427 pig->add_edge( ii, jj );
428 pig->add_to_two_body_energies_for_edge( ii, jj, pair_energy_table );
431 pig->declare_edge_energies_final( ii, jj );
442 lr_iter != lr_end; ++lr_iter ) {
444 if ( !lrec || lrec->empty() )
continue;
447 for (
uint ii = 1; ii <= nmoltenres_; ++ ii ) {
448 uint const ii_resid = moltenres_2_resid_[ ii ];
451 rni = lrec->const_upper_neighbor_iterator_begin( ii_resid ),
452 rniend = lrec->const_upper_neighbor_iterator_end( ii_resid );
453 (*rni) != (*rniend); ++(*rni) ) {
454 Size const jj_resid = rni->upper_neighbor_id();
456 uint const jj = resid_2_moltenres_[ jj_resid ];
457 if ( jj == 0 )
continue;
459 FArray2D< core::PackerEnergy > pair_energy_table(
460 nrotamers_for_moltenres_[ jj ],
461 nrotamers_for_moltenres_[ ii ], 0.0 );
466 (*lr_iter)->evaluate_rotamer_pair_energies(
467 *ii_rotset, *jj_rotset, pose, scfxn, scfxn.
weights(), pair_energy_table );
469 if ( ! pig->get_edge_exists( ii, jj ) ) { pig->add_edge( ii, jj ); }
470 pig->add_to_two_body_energies_for_edge( ii, jj, pair_energy_table );
471 if ( finalize_edges ) pig->declare_edge_energies_final( ii, jj );
481 RotamerSets::prepare_otf_graph(
488 using namespace conformation;
489 using namespace interaction_graph;
490 using namespace scoring;
492 FArray2D_bool sparse_conn_info( otfig->get_num_aatypes(), otfig->get_num_aatypes(), false );
495 for (
Size ii = 1; ii <= nmoltenres_; ++ii ) {
497 bool all_canonical_aas(
true );
498 for (
Size jj = 1, jje = ii_rotset->get_n_residue_types(); jj <= jje; ++jj ) {
499 ResidueCOP jj_rotamer = ii_rotset->rotamer( ii_rotset->get_residue_type_begin( jj ) );
501 all_canonical_aas =
false;
504 if ( all_canonical_aas ) {
505 otfig->distinguish_backbone_and_sidechain_for_node( ii,
true );
509 for (
Size ii = 1; ii <= nmoltenres_; ++ii ) {
511 uint const ii_resid = moltenres_2_resid_[ ii ];
513 uli = packer_neighbor_graph->get_node( ii_resid )->const_upper_edge_list_begin(),
514 ulie = packer_neighbor_graph->get_node( ii_resid )->const_upper_edge_list_end();
515 uli != ulie; ++uli ) {
516 uint const jj_resid = (*uli)->get_second_node_ind();
517 uint const jj = resid_2_moltenres_[ jj_resid ];
518 if ( jj == 0 )
continue;
520 bool any_neighbors =
false;
523 otfig->note_long_range_interactions_exist_for_edge( ii, jj );
526 any_neighbors =
true;
527 sparse_conn_info =
true;
534 sparse_conn_info =
false;
535 Distance const sfxn_reach = scfxn.
info()->max_atomic_interaction_distance();
536 for (
Size kk = 1, kk_end = ii_rotset->get_n_residue_types(); kk <= kk_end; ++kk ) {
537 Size kk_example_rotamer_index = ii_rotset->get_residue_type_begin( kk );
541 Vector const kk_nbratom( kk_rotamer.xyz( kk_rotamer.nbr_atom() ) );
543 for (
Size ll = 1, ll_end = jj_rotset->get_n_residue_types(); ll <= ll_end; ++ll ) {
544 Size ll_example_rotamer_index = jj_rotset->get_residue_type_begin( ll );
547 Distance const ll_reach( ll_rotamer.nbr_radius() );
548 Vector const ll_nbratom( ll_rotamer.xyz( ll_rotamer.nbr_atom() ) );
550 DistanceSquared const nbrdist2 = kk_nbratom.distance_squared( ll_nbratom );
551 Distance const intxn_cutoff = sfxn_reach + kk_reach + ll_reach;
553 if ( nbrdist2 <= intxn_cutoff * intxn_cutoff ) {
554 any_neighbors =
true;
555 sparse_conn_info( ll, kk ) =
true;
561 if ( any_neighbors ) {
562 otfig->add_edge( ii, jj );
563 otfig->note_short_range_interactions_exist_for_edge( ii, jj );
564 otfig->set_sparse_aa_info_for_edge( ii, jj, sparse_conn_info );
569 sparse_conn_info =
true;
575 lr_iter != lr_end; ++lr_iter ) {
577 if ( !lrec || lrec->empty() )
continue;
580 for (
uint ii = 1; ii <= nmoltenres_; ++ ii ) {
581 uint const ii_resid = moltenres_2_resid_[ ii ];
584 rni = lrec->const_upper_neighbor_iterator_begin( ii_resid ),
585 rniend = lrec->const_upper_neighbor_iterator_end( ii_resid );
586 (*rni) != (*rniend); ++(*rni) ) {
587 Size const jj_resid = rni->upper_neighbor_id();
589 uint const jj = resid_2_moltenres_[ jj_resid ];
590 if ( jj == 0 )
continue;
599 if ( ! otfig->get_edge_exists( ii, jj ) ) {
600 otfig->add_edge( ii, jj );
602 otfig->note_long_range_interactions_exist_for_edge( ii, jj );
603 otfig->set_sparse_aa_info_for_edge( ii, jj, sparse_conn_info );
616 RotamerSets::compute_proline_correction_energies_for_otf_graph(
623 using namespace conformation;
629 for (
Size ii = 1; ii <= nmoltenres_; ++ii ) {
631 Size potential_gly_replacement( 0 );
632 for (
Size jj = 1, jje = ii_rotset->get_n_residue_types(); jj <= jje; ++jj ) {
633 ResidueCOP jj_rotamer = ii_rotset->rotamer( ii_rotset->get_residue_type_begin( jj ) );
635 example_gly_rotamers[ ii ] = ii_rotset->get_residue_type_begin( jj );
637 example_pro_rotamers[ ii ] = ii_rotset->get_residue_type_begin( jj );
638 }
else if ( jj_rotamer->is_protein() ) {
639 potential_gly_replacement = ii_rotset->get_residue_type_begin( jj );
644 if ( example_gly_rotamers[ ii ] == 0 ) {
645 example_gly_rotamers[ ii ] = potential_gly_replacement;
650 for (
Size ii = 1; ii <= nmoltenres_; ++ ii ) {
651 Size const ii_resid = moltenres_2_resid_[ ii ];
652 if ( ! otfig->distinguish_backbone_and_sidechain_for_node( ii ) )
continue;
654 uli = packer_neighbor_graph->get_node( ii_resid )->const_upper_edge_list_begin(),
655 ulie = packer_neighbor_graph->get_node( ii_resid )->const_upper_edge_list_end();
656 uli != ulie; ++uli ) {
657 Size const jj_resid = (*uli)->get_second_node_ind();
658 Size const jj = resid_2_moltenres_[ jj_resid ];
659 if ( jj == 0 )
continue;
660 if ( ! otfig->distinguish_backbone_and_sidechain_for_node( jj ) )
continue;
666 for (
Size kk = 1; kk <= ii_rotset->num_rotamers(); ++kk ) {
670 if ( example_gly_rotamers[ jj ] != 0 ) {
671 bb_bbnonproE = get_bb_bbE( pose, scfxn, *ii_rotset->rotamer( kk ), *jj_rotset->rotamer( example_gly_rotamers[ jj ] ) );
672 sc_npbb_energy = get_sc_bbE( pose, scfxn, *ii_rotset->rotamer( kk ), *jj_rotset->rotamer( example_gly_rotamers[ jj ] ) );
675 if ( example_pro_rotamers[ jj ] != 0 ) {
676 bb_bbproE = get_bb_bbE( pose, scfxn, *ii_rotset->rotamer( kk ), *jj_rotset->rotamer( example_pro_rotamers[ jj ] ) );
677 sc_probb_energy = get_sc_bbE( pose, scfxn, *ii_rotset->rotamer( kk ), *jj_rotset->rotamer( example_pro_rotamers[ jj ] ) );
679 otfig->add_to_one_body_energy_for_node_state( ii, kk, sc_npbb_energy + 0.5 * bb_bbnonproE );
680 otfig->set_ProCorrection_values_for_edge( ii, jj, ii, kk,
681 bb_bbnonproE, bb_bbproE, sc_npbb_energy, sc_probb_energy );
684 for (
Size kk = 1; kk <= jj_rotset->num_rotamers(); ++kk ) {
688 if ( example_gly_rotamers[ ii ] != 0 ) {
689 bb_bbnonproE = get_bb_bbE( pose, scfxn, *jj_rotset->rotamer( kk ), *ii_rotset->rotamer( example_gly_rotamers[ ii ] ) );
690 sc_npbb_energy = get_sc_bbE( pose, scfxn, *jj_rotset->rotamer( kk ), *ii_rotset->rotamer( example_gly_rotamers[ ii ] ) );
693 if ( example_pro_rotamers[ ii ] != 0 ) {
694 bb_bbproE = get_bb_bbE( pose, scfxn, *jj_rotset->rotamer( kk ), *ii_rotset->rotamer( example_pro_rotamers[ ii ] ) );
695 sc_probb_energy = get_sc_bbE( pose, scfxn, *jj_rotset->rotamer( kk ), *ii_rotset->rotamer( example_pro_rotamers[ ii ] ) );
697 otfig->add_to_one_body_energy_for_node_state( jj, kk, sc_npbb_energy + 0.5 * bb_bbnonproE );
699 otfig->set_ProCorrection_values_for_edge( ii, jj, jj, kk,
700 bb_bbnonproE, bb_bbproE, sc_npbb_energy, sc_probb_energy );
708 for ( Size ii = 1; ii <= (Size) nmoltenres_; ++ii ) {
709 RotamerSetCOP ii_rotset = set_of_rotamer_sets_[ ii ];
711 Size const ii_nrots = ii_rotset->num_rotamers();
712 Size const ii_resid = moltenres_2_resid_[ ii ];
714 utility::vector1< core::PackerEnergy > energies( ii_nrots, 0.0 );
715 for ( Size jj = 1; jj <= ii_nrots; ++jj ) {
717 sfxn.eval_ci_1b( *ii_rotset->rotamers( jj ), pose, emap );
718 sfxn.eval_cd_1b( *ii_rotset->rotamers( jj ), pose, emap );
719 energies[ jj ] += static_cast< core::PackerEnergy > ( sfxn.weights().dot( emap ) ); // precision loss here.
722 sfxn.evaluate_rotamer_intrares_energies( *ii_rotset, pose, energies );
725 for ( graph::Graph::EdgeListConstIter
726 uli = packer_neighbor_graph->get_node( ii_resid )->const_upper_edge_list_begin(),
727 ulie = packer_neighbor_graph->get_node( ii_resid )->const_upper_edge_list_end();
728 uli != ulie; ++uli ) {
729 Size const jj_resid = (*uli)->get_second_node_ind();
730 Size const jj = resid_2_moltenres_[ jj_resid ]; //pretend we're iterating over jj >= ii
731 if ( jj != 0 ) continue;
733 Residue const & neighbor( pose.residue( jj_resid ) );
734 sfxn.evaluate_rotamer_background_energies( ii_rotset, neighbor, pose, energies );
738 for ( ScoreFunction::LR_2B_MethodIterator
739 lr_iter = sf.long_range_energies_begin(),
740 lr_end = sf.long_range_energies_end();
741 lr_iter != lr_end; ++lr_iter ) {
742 LREnergyContainerCOP lrec = pose.energies().long_range_container( (*lr_iter)->long_range_type() );
743 if ( !lrec || lrec->empty() ) continue; // only score non-emtpy energies.
745 // Potentially O(N) operation...
746 for ( ResidueNeighborConstIteratorOP
747 rni = lrec->const_neighbor_iterator_begin( ii_resid ),
748 rniend = lrec->const_neighbor_iterator_end( ii_resid );
749 (*rni) != (*rniend); ++(*rni) ) {
750 Size const neighbor_id = rni->neighbor_id();
751 assert( neighbor_id != theresid );
752 if ( resid_2_moltenres_[ neighbor_id ] != 0 ) continue;
754 (*lr_iter)->evaluate_rotamer_background_energies(
755 *ii_rotset, pose.residue( neighbor_id ), pose, sfxn,
756 sfxn.weights(), energies );
758 } // (potentially) long-range neighbors of ii
759 } // long-range energy functions
761 for ( Size jj = 1; jj <= ii_nrots; ++jj ) {
762 otfig->add_to_one_body_energy_for_node_state( ii, jj, energies[ jj ] );
770 uint RotamerSets::nrotamers()
const {
return nrotamers_;}
771 uint RotamerSets::nrotamers_for_moltenres(
uint mresid )
const
773 return rotamer_set_for_moltenresidue( mresid )->num_rotamers();
776 uint RotamerSets::nmoltenres()
const {
return nmoltenres_;}
778 uint RotamerSets::total_residue()
const {
return total_residue_;}
781 RotamerSets::moltenres_2_resid(
uint mresid )
const {
return moltenres_2_resid_[ mresid ]; }
784 RotamerSets::resid_2_moltenres(
uint resid )
const {
return resid_2_moltenres_[ resid ]; }
787 RotamerSets::moltenres_for_rotamer(
uint rotid )
const {
return moltenres_for_rotamer_[ rotid ]; }
790 RotamerSets::res_for_rotamer(
uint rotid )
const {
return moltenres_2_resid( moltenres_for_rotamer( rotid ) ); }
793 RotamerSets::rotamer(
uint rotid )
const
795 return rotamer_set_for_residue( res_for_rotamer( rotid ) )->rotamer( rotid_on_moltenresidue( rotid ) );
799 RotamerSets::rotamer_for_moltenres(
uint moltenres_id,
uint rotamerid )
const
801 return rotamer_set_for_moltenresidue( moltenres_id )->rotamer( rotamerid );
806 RotamerSets::nrotamer_offset_for_moltenres(
uint mresid )
const {
return nrotamer_offsets_[ mresid ]; }
809 RotamerSets::rotamer_set_for_residue(
uint resid )
const {
return set_of_rotamer_sets_[ resid_2_moltenres( resid ) ]; }
812 RotamerSets::rotamer_set_for_residue(
uint resid ) {
return set_of_rotamer_sets_[ resid_2_moltenres( resid ) ]; }
815 RotamerSets::rotamer_set_for_moltenresidue(
uint moltenresid )
const {
return set_of_rotamer_sets_[ moltenresid ]; }
819 RotamerSets::rotamer_set_for_moltenresidue(
uint moltenresid ) {
return set_of_rotamer_sets_[ moltenresid ]; }
823 RotamerSets::rotid_on_moltenresidue(
uint rotid )
const
825 return rotid - nrotamer_offsets_[ moltenres_for_rotamer_[ rotid ] ];
830 RotamerSets::moltenres_rotid_2_rotid(
uint moltenres,
uint moltenresrotid )
const
832 return moltenresrotid + nrotamer_offsets_[ moltenres ];
837 RotamerSets::task()
const
843 RotamerSets::prepare_sets_for_packing(
847 for (
Size ii = 1; ii <= nmoltenres(); ++ii )
854 RotamerSets::get_bb_bbE(
868 RotamerSets::get_sc_bbE(