36 #include <ObjexxFCL/format.hh>
43 #include <utility/vector1.hh>
50 using namespace ObjexxFCL::fmt;
77 solv1_(etable_in.solv1()),
78 solv2_(etable_in.solv2()),
79 dsolv1_( etable_in.dsolv1() ),
80 safe_max_dis2_( etable_in.get_safe_max_dis2() ),
81 get_bins_per_A2_( etable_in.get_bins_per_A2()),
106 if(rsd.
is_RNA()==
false)
return;
108 Real lk_polar_intra_RNA_score, lk_nonpolar_intra_RNA_score, lk_costheta_intra_RNA_score;
134 etable_(src.etable_),
135 solv1_( src.solv1_ ),
136 solv2_( src.solv2_ ),
137 dsolv1_( src.dsolv1_ ),
138 safe_max_dis2_( src.safe_max_dis2_ ),
139 get_bins_per_A2_( src.get_bins_per_A2_ ),
140 verbose_( src.verbose_ ),
141 lk_costheta_weight_()
159 Real lk_polar_score, lk_nonpolar_score, lk_costheta_score;
179 Size non_H_neighbors = 0;
180 Vector base_pseudo_atom(0);
184 base_pseudo_atom += rsd1.
xyz(neighbor_id);
195 Size const neighbor_res_id( ii_conn.
resid() );
196 if (neighbor_res_id < 1 )
continue;
197 Size const nieghbor_atom_id( pose.
residue( ii_conn.
resid() ).residue_connection( ii_conn.
connid() ).atomno() );
199 base_pseudo_atom += pose.
residue( neighbor_res_id ).
xyz( nieghbor_atom_id );
205 if (non_H_neighbors > 0 ) base_pseudo_atom /= non_H_neighbors;
211 Vector res1_base_vector = rsd1.
xyz(i) - base_pseudo_atom;
212 Vector res1_base_vector_norm = (res1_base_vector).normalized();
213 return res1_base_vector_norm;
221 Real & lk_polar_intra_RNA_score,
222 Real & lk_nonpolar_intra_RNA_score,
223 Real & lk_costheta_intra_RNA_score
227 using namespace etable::count_pair;
229 lk_polar_intra_RNA_score = 0.0;
230 lk_nonpolar_intra_RNA_score = 0.0;
231 lk_costheta_intra_RNA_score = 0.0;
242 for ( Size i = 1, i_end = rsd1.nheavyatoms(); i <= i_end; ++i ) {
244 for ( Size j = 1, j_end = rsd2.nheavyatoms(); j <= j_end; ++j ) {
245 Real cp_weight = 1.0;
247 std::cout << "cpfxn->count(" << i << " [" << rsd1.atom_name( i) << "] " << ", " << j << " [" << rsd2.atom_name( j ) << "] " << ")= " << cpfxn->count( i, j, cp_weight, path_dist );
248 std::cout << " cp_weight= " << cp_weight << " path_dist= " << path_dist << std::endl;
253 for ( Size i = 1, i_end = rsd1.nheavyatoms(); i <= i_end; ++i ) {
255 Vector const heavy_atom_i( rsd1.xyz( i ) );
257 //Just compute cos(theta) for polars.
258 bool is_polar( false );
259 if ( rsd1.atom_type(i).is_acceptor() || rsd1.atom_type(i).is_donor()) is_polar = true;
261 //Need to figure out "direction"...
262 Vector const res1_base_vector_norm = is_polar ? get_base_vector( rsd1, i, pose ) : Vector( 0.0 );
264 for ( Size j = 1, j_end = rsd2.nheavyatoms(); j <= j_end; ++j ) {
266 Real cp_weight = 1.0;
268 if ( cpfxn->count( i, j, cp_weight, path_dist ) ) {
270 if(core::scoring::rna::Is_base_phosphate_atom_pair(rsd1, rsd2, i, j)==false) continue;
272 Vector const heavy_atom_j( rsd2.xyz( j ) );
274 Vector const d_ij = heavy_atom_j - heavy_atom_i;
275 Real const d2 = d_ij.length_squared();
277 if ( ( d2 >= safe_max_dis2_) || ( d2 == Real(0.0) ) ) continue;
280 Real dummy_deriv( 0.0 );
281 Real temp_score = cp_weight * eval_lk( rsd1.atom( i ), rsd2.atom( j ), d2, dummy_deriv);
283 Real const START_lk_polar_intra_RNA_score=lk_polar_intra_RNA_score;
284 Real const START_lk_costheta_intra_RNA_score=lk_costheta_intra_RNA_score;
285 Real const START_lk_nonpolar_intra_RNA_score=lk_nonpolar_intra_RNA_score;
289 lk_polar_intra_RNA_score += temp_score;
291 Vector const d_ij = heavy_atom_j - heavy_atom_i;
292 Vector const d_ij_norm = d_ij.normalized();
293 dotprod = dot( res1_base_vector_norm, d_ij_norm );
294 temp_score *= dotprod;
295 lk_costheta_intra_RNA_score += temp_score;
297 if ( verbose_ && std::abs( temp_score ) > 0.1 ){
298 std::cout << "Occlusion penalty: " << rsd1.name1() << rsd1.seqpos() << " " << rsd1.atom_name( i ) << " covered by " <<
299 rsd2.name1() << rsd2.seqpos() << " " << rsd2.atom_name(j) << " ==> " << F(8,3,temp_score) << ' ' << F(8,3,dotprod) << std::endl;
303 lk_nonpolar_intra_RNA_score += temp_score;
308 if(rsd.is_virtual(i) || rsd.is_virtual(j)){
310 Real const diff_polar =lk_polar_intra_RNA_score-START_lk_polar_intra_RNA_score;
311 Real const diff_costheta =lk_costheta_intra_RNA_score-START_lk_costheta_intra_RNA_score;
312 Real const diff_non_polar =lk_nonpolar_intra_RNA_score-START_lk_nonpolar_intra_RNA_score;
314 if(diff_polar>0.001 || diff_polar<-0.001){
315 std::cout << "At least one of the atoms in the pair " << i << "," << j << " | res= " << rsd.seqpos() << " is virtual";
316 std::cout << " but diff_polar= " << diff_polar << " is non-zero!" <<std::endl;
317 utility_exit_with_message("diff_polar>0.001 || diff_polar<-0.001");
320 if(diff_costheta>0.001 || diff_costheta<-0.001){
321 std::cout << "At least one of the atoms in the pair " << i << "," << j << " | res= " << rsd.seqpos() << " is virtual";
322 std::cout << " but diff_costheta= " << diff_costheta << " is non-zero!" <<std::endl;
323 utility_exit_with_message("diff_costheta>0.001 || diff_costheta<-0.001");
326 if(diff_non_polar>0.001 || diff_non_polar<-0.001){
327 std::cout << "At least one of the atoms in the pair " << i << "," << j << " | res= " << rsd.seqpos() << " is virtual";
328 std::cout << " but diff_non_polar= " << diff_non_polar << " is non-zero!" <<std::endl;
329 utility_exit_with_message("diff_non_polar>0.001 || diff_non_polar<-0.001");
343 LK_CosThetaEnergy::get_residue_pair_energy_one_way(
344 conformation::Residue const & rsd1,
345 conformation::Residue const & rsd2,
346 pose::Pose const & pose,
347 Real & lk_polar_score,
348 Real & lk_nonpolar_score,
349 Real & lk_costheta_score
352 using namespace etable::count_pair;
353 CountPairFunctionOP cpfxn =
354 CountPairFactory::create_count_pair_function( rsd1, rsd2, CP_CROSSOVER_4 );
356 lk_polar_score = 0.0;
357 lk_nonpolar_score = 0.0;
358 lk_costheta_score = 0.0;
360 //Assume rsd1 contributes polar atoms.
361 //Assume rsd2 contributes occluding atoms.
362 for ( Size i = 1, i_end = rsd1.nheavyatoms(); i <= i_end; ++i ) {
364 Vector const heavy_atom_i( rsd1.xyz( i ) );
366 //Just compute cos(theta) for polars.
367 bool is_polar( false );
368 if ( rsd1.atom_type(i).is_acceptor() || rsd1.atom_type(i).is_donor()) is_polar = true;
370 //Need to figure out "direction"...
371 Vector const res1_base_vector_norm = is_polar ? get_base_vector( rsd1, i, pose ) : Vector( 0.0 );
373 for ( Size j = 1, j_end = rsd2.nheavyatoms(); j <= j_end; ++j ) {
375 Real cp_weight = 1.0;
377 if ( cpfxn->count( i, j, cp_weight, path_dist ) ) {
379 Vector const heavy_atom_j( rsd2.xyz( j ) );
381 Vector const d_ij = heavy_atom_j - heavy_atom_i;
382 Real const d2 = d_ij.length_squared();
384 if ( ( d2 >= safe_max_dis2_) || ( d2 == Real(0.0) ) ) continue;
387 Real dummy_deriv( 0.0 );
388 Real temp_score = cp_weight * eval_lk( rsd1.atom( i ), rsd2.atom( j ), d2, dummy_deriv);
391 lk_polar_score += temp_score;
393 Vector const d_ij = heavy_atom_j - heavy_atom_i;
394 Vector const d_ij_norm = d_ij.normalized();
395 dotprod = dot( res1_base_vector_norm, d_ij_norm );
396 temp_score *= dotprod;
397 lk_costheta_score += temp_score;
399 if ( verbose_ && std::abs( temp_score ) > 0.1 ){
400 std::cout << "Occlusion penalty: " << rsd1.name1() << rsd1.seqpos() << " " << rsd1.atom_name( i ) << " covered by " <<
401 rsd2.name1() << rsd2.seqpos() << " " << rsd2.atom_name(j) << " ==> " << F(8,3,temp_score) << ' ' << F(8,3,dotprod) << std::endl;
405 lk_nonpolar_score += temp_score;
420 LK_CosThetaEnergy::setup_for_derivatives(
422 ScoreFunction const &
425 pose.update_residue_neighbors();
431 LK_CosThetaEnergy::eval_lk(
432 conformation::Atom const & atom1,
433 conformation::Atom const & atom2,
438 Real temp_score( 0.0 );
440 //Make this an input option for efficiency
441 bool const eval_deriv( true );
443 if ( ( d2 < safe_max_dis2_) && ( d2 != Real(0.0) ) ) {
445 Real const d2_bin = d2 * get_bins_per_A2_;
446 int disbin = static_cast< int >( d2_bin ) + 1;
447 Real frac = d2_bin - ( disbin - 1 );
449 // l1 and l2 are FArray LINEAR INDICES for fast lookup:
450 // [ l1 ] == (disbin ,attype2,attype1)
451 // [ l2 ] == (disbin+1,attype2,attype1)
453 int const l1 = solv1_.index( disbin, atom2.type(), atom1.type() );
454 int const l2 = l1 + 1;
455 temp_score = ( (1.-frac)* solv1_[ l1 ] + frac * solv1_[ l2 ]);
459 // int const l1 = dsolv1_.index( disbin, atom2.type(), atom1.type() ),
461 // Real e1 = dsolv1_[ l1 ];
462 // deriv = ( e1 + frac * ( dsolv1_[ l2 ] - e1 ) );
463 deriv = ( solv1_[ l2 ] - solv1_[ l1 ] ) * get_bins_per_A2_ * std::sqrt( d2 ) * 2;
474 LK_CosThetaEnergy::eval_atom_derivative_intra_RNA(
475 id::AtomID const & atom_id,
476 pose::Pose const & pose,
477 kinematics::DomainMap const & /*domain_map*/,
487 if(do_eval_intra_RNA==
false)
return;
489 Size const i( atom_id.rsd() );
490 Size const j( atom_id.rsd() );
495 if(rsd1.is_RNA()==
false)
return;
496 if(rsd2.is_RNA()==
false)
return;
498 Size const m( atom_id.atomno() );
500 if ( m > rsd1.nheavyatoms() )
return;
503 std::cout <<
"Start LK_CosThetaEnergy::eval_atom_derivative, intra_res case, res= " << i <<
" atomno= " << m <<
"[" << rsd1.
atom_name(m) <<
"]" << std::endl;
513 Vector const heavy_atom_i( rsd1.xyz( m ) );
524 using namespace etable::count_pair;
528 bool atom1_is_polar(
false );
529 if (rsd1.atom_type(m).is_acceptor() || rsd1.atom_type(m).is_donor() ) atom1_is_polar =
true;
531 for (
Size n = 1; n <= rsd2.nheavyatoms(); ++n ) {
533 Real cp_weight = 1.0;
535 if ( cpfxn->count(m, n, cp_weight, path_dist ) ) {
539 Vector const heavy_atom_j( rsd2.xyz( n ) );
540 Vector const d_ij = heavy_atom_j - heavy_atom_i;
541 Real const d2 = d_ij.length_squared();
542 Real const d = std::sqrt( d2 );
543 Vector const d_ij_norm = d_ij.normalized();
547 bool atom2_is_polar(
false );
548 if (rsd2.atom_type(n).is_acceptor() || rsd2.atom_type(n).is_donor() ) atom2_is_polar =
true;
554 Vector f1_fwd( 0.0 ), f2_fwd( 0.0 ), f1_bkd( 0.0 ), f2_bkd( 0.0 );
555 Real lk_score1( 0.0 ), lk_score2( 0.0 );
556 Real dotprod_fwd( 1.0 ), dotprod_bkd( 1.0 );
559 lk_score1 = cp_weight *
eval_lk( rsd1.atom(m), rsd2.atom(n), d2, deriv );
561 f2_fwd = -1.0 * cp_weight * deriv * d_ij_norm;
562 f1_fwd = 1.0 * cross( f2_fwd, heavy_atom_j );
564 if ( atom1_is_polar ) {
569 dotprod_fwd = dot( res1_base_vector_norm, d_ij_norm );
571 f2_fwd *= dotprod_fwd;
572 f2_fwd -= lk_score1 * ( 1/d ) * (res1_base_vector_norm - dotprod_fwd * d_ij_norm );
574 f1_fwd = 1.0 * cross( f2_fwd, heavy_atom_j );
579 lk_score1 *= dotprod_fwd;
589 Vector d_ji_norm = -d_ij_norm;
591 lk_score2 = cp_weight *
eval_lk( rsd2.atom(n), rsd1.atom(m), d2, deriv );
593 f2_bkd = -1.0 * deriv * cp_weight * d_ji_norm;
594 f1_bkd = 1.0 * cross( f2_bkd, heavy_atom_i );
597 if ( atom2_is_polar ){
602 dotprod_bkd = dot( res2_base_vector_norm, d_ji_norm );
604 f2_bkd *= dotprod_bkd;
605 f2_bkd -= lk_score2 * ( 1/d ) * (res2_base_vector_norm - dotprod_bkd * d_ji_norm );
607 f1_bkd = 1.0 * cross( f2_bkd, heavy_atom_i );
612 lk_score2 *= dotprod_bkd;
620 if (
verbose_ && (std::abs( lk_score1 ) > 0.1 || std::abs( lk_score2 ) > 0.1 ) ) {
621 std::cout <<
"Occlusion penalty: " << rsd1.name1() << rsd1.seqpos() <<
" " << rsd1.atom_name( m ) <<
" covered by " <<
622 rsd2.name1() << rsd2.seqpos() <<
" " << rsd2.atom_name(n) <<
623 " " << F(8,3,lk_score1) <<
" " << F(8,3,lk_score2) <<
624 " ==> " <<
" DERIV " <<
625 F(8,6,f2_fwd( 1 ) ) <<
' ' << F(8,6,f2_bkd(1) ) <<
626 ' ' << std::sqrt( d2 ) <<
" " << cp_weight <<
" " <<
627 F(8,3,dotprod_fwd) <<
" " << F(8,3,dotprod_bkd) << std::endl;
637 std::cout <<
"LK_CosThetaEnergy::eval_atom_derivative, intra_res :";
638 std::cout <<
" F1= " << F1[0] <<
" " << F1[1] <<
" " << F1[2];
639 std::cout <<
" F2= " << F2[0] <<
" " << F2[1] <<
" " << F2[2] << std::endl;
640 std::cout <<
"Finish LK_CosThetaEnergy::eval_atom_derivative, intra_res case, res= " << i <<
" atomno= " << m <<
"[" << rsd1.atom_name(m) <<
"]" << std::endl;
664 if ( m > rsd1.nheavyatoms() )
return;
666 Vector const heavy_atom_i( rsd1.xyz( m ) );
668 bool const pos1_fixed( domain_map( i ) != 0 );
674 EnergyGraph const & energy_graph( energies.energy_graph() );
680 iter = energy_graph.get_node( i )->const_edge_list_begin(),
682 iter != itere; ++iter ) {
684 Size const j( (*iter)->get_other_ind( i ) );
686 if ( pos1_fixed && domain_map(i) == domain_map(j) )
continue;
690 using namespace etable::count_pair;
692 CountPairFactory::create_count_pair_function( rsd1, rsd2,
CP_CROSSOVER_4 );
694 bool atom1_is_polar(
false );
695 if (rsd1.atom_type(m).is_acceptor() || rsd1.atom_type(m).is_donor() ) atom1_is_polar =
true;
697 for (
Size n = 1; n <= rsd2.nheavyatoms(); ++n ) {
699 Real cp_weight = 1.0;
701 if ( cpfxn->count(m, n, cp_weight, path_dist ) ) {
703 Vector const heavy_atom_j( rsd2.xyz( n ) );
704 Vector const d_ij = heavy_atom_j - heavy_atom_i;
705 Real const d2 = d_ij.length_squared();
706 Real const d = std::sqrt( d2 );
707 Vector const d_ij_norm = d_ij.normalized();
711 bool atom2_is_polar(
false );
712 if (rsd2.atom_type(n).is_acceptor() || rsd2.atom_type(n).is_donor() ) atom2_is_polar =
true;
718 Vector f1_fwd( 0.0 ), f2_fwd( 0.0 ), f1_bkd( 0.0 ), f2_bkd( 0.0 );
719 Real lk_score1( 0.0 ), lk_score2( 0.0 );
720 Real dotprod_fwd( 1.0 ), dotprod_bkd( 1.0 );
723 lk_score1 = cp_weight *
eval_lk( rsd1.atom(m), rsd2.atom(n), d2, deriv );
725 f2_fwd = -1.0 * cp_weight * deriv * d_ij_norm;
726 f1_fwd = 1.0 * cross( f2_fwd, heavy_atom_j );
728 if ( atom1_is_polar ) {
733 dotprod_fwd = dot( res1_base_vector_norm, d_ij_norm );
735 f2_fwd *= dotprod_fwd;
736 f2_fwd -= lk_score1 * ( 1/d ) * (res1_base_vector_norm - dotprod_fwd * d_ij_norm );
738 f1_fwd = 1.0 * cross( f2_fwd, heavy_atom_j );
743 lk_score1 *= dotprod_fwd;
753 Vector d_ji_norm = -d_ij_norm;
755 lk_score2 = cp_weight *
eval_lk( rsd2.atom(n), rsd1.atom(m), d2, deriv );
757 f2_bkd = -1.0 * deriv * cp_weight * d_ji_norm;
758 f1_bkd = 1.0 * cross( f2_bkd, heavy_atom_i );
761 if ( atom2_is_polar ){
766 dotprod_bkd = dot( res2_base_vector_norm, d_ji_norm );
768 f2_bkd *= dotprod_bkd;
769 f2_bkd -= lk_score2 * ( 1/d ) * (res2_base_vector_norm - dotprod_bkd * d_ji_norm );
771 f1_bkd = 1.0 * cross( f2_bkd, heavy_atom_i );
776 lk_score2 *= dotprod_bkd;
784 if (
verbose_ && (std::abs( lk_score1 ) > 0.1 || std::abs( lk_score2 ) > 0.1 ) ) {
785 std::cout <<
"Occlusion penalty: " << rsd1.name1() << rsd1.seqpos() <<
" " << rsd1.atom_name( m ) <<
" covered by " <<
786 rsd2.name1() << rsd2.seqpos() <<
" " << rsd2.atom_name(n) <<
787 " " << F(8,3,lk_score1) <<
" " << F(8,3,lk_score2) <<
788 " ==> " <<
" DERIV " <<
789 F(8,6,f2_fwd( 1 ) ) <<
' ' << F(8,6,f2_bkd(1) ) <<
790 ' ' << std::sqrt( d2 ) <<
" " << cp_weight <<
" " <<
791 F(8,3,dotprod_fwd) <<
" " << F(8,3,dotprod_bkd) << std::endl;
818 if (
verbose_) std::cout <<
"DONE SCORING" << std::endl;