48 #include <ObjexxFCL/format.hh>
49 #include <ObjexxFCL/FArray2D.hh>
59 #include <basic/prof.hh>
60 #include <basic/datacache/BasicDataCache.hh>
61 #include <basic/Tracer.hh>
63 #include <numeric/constants.hh>
64 #include <numeric/xyz.functions.hh>
66 #include <utility/vector1.functions.hh>
99 static basic::Tracer
TR(
"core.scoring.methods.LK_BallEnergy");
115 assert( seqpos && seqpos <= ( static_cast< LKB_PoseInfo const & >
117 return ( static_cast< LKB_PoseInfo const & >
124 assert( seqpos && seqpos <= ( static_cast< LKB_PoseInfo const & >
126 return ( static_cast< LKB_PoseInfo & >
173 etable_ ( *
ScoringManager::get_instance()->etable( options.etable_type() ) ),
174 solv1_ (
ScoringManager::get_instance()->etable( options.etable_type() )->solv1()),
175 solv2_ (
ScoringManager::get_instance()->etable( options.etable_type() )->solv2()),
176 dsolv1_ (
ScoringManager::get_instance()->etable( options.etable_type() )->dsolv1()),
177 safe_max_dis2_ (
ScoringManager::get_instance()->etable( options.etable_type() )->get_safe_max_dis2() ),
178 etable_bins_per_A2_(
ScoringManager::get_instance()->etable( options.etable_type() )->get_bins_per_A2() ),
179 use_intra_dna_cp_crossover_4_( true )
220 etable_(src.etable_),
221 solv1_( src.solv1_ ),
222 solv2_( src.solv2_ ),
223 dsolv1_( src.dsolv1_ ),
224 safe_max_dis2_( src.safe_max_dis2_ ),
225 etable_bins_per_A2_( src.etable_bins_per_A2_ ),
226 use_intra_dna_cp_crossover_4_( src.use_intra_dna_cp_crossover_4_ )
310 Real const h2o_radius( 1.4 );
312 d2_low_.resize( atom_set.n_atomtypes() );
313 for (
Size i=1; i<= atom_set.n_atomtypes(); ++i ) {
317 TR.Trace <<
"d2_low_high: " << atype.
name() <<
' ' <<
318 std::sqrt(
d2_low_[i] ) <<
' ' << std::sqrt( d2_high ) << std::endl;
324 for (
Size i=1; i<= atom_set.n_atomtypes(); ++i ) {
326 assert(
Size( atom_set.atom_type_index( name ) ) == i );
355 assert( d2_delta >= -0.001 && d2_delta <=
ramp_width_A2_ + 0.001 );
357 Real const xprime( inv_range * d2_delta );
358 return ( 1 - xprime*xprime ) * ( 1 - xprime*xprime );
364 assert( d2_delta >= -0.001 && d2_delta <=
ramp_width_A2_ + 0.001 );
366 Real const xprime( inv_range * d2_delta );
367 return -8.0 * inv_range * ( 1 - xprime * xprime ) * xprime;
378 Size const atom2_type,
380 Size & closest_water,
381 Real & closest_water_d2_delta
389 closest_water_d2_delta = 100.0;
391 for ( Vectors::const_iterator water= atom1_waters.begin(), water_end= atom1_waters.end();
392 water != water_end; ++water ) {
393 d2_delta = atom2_xyz.distance_squared( *water ) - d2_low;
395 else if ( d2_delta < closest_water_d2_delta ) {
396 closest_water_d2_delta = d2_delta;
397 closest_water = water - atom1_waters.begin() + 1;
398 if ( d2_delta < 0.0 )
break;
404 if ( closest_water ) {
405 frac = ( closest_water_d2_delta < 0.0 ?
Real( 1.0 ) :
eval_lk_fraction( closest_water_d2_delta ) );
414 Size const atom2_type,
415 Vector const & atom1_water
422 Real const d2_delta = atom2_xyz.distance_squared( atom1_water ) - d2_low;
424 else if ( d2_delta < 0.0 )
return 1.0;
432 Size const atom2_type,
436 Size closest_water(0);
437 Real closest_water_d2_delta(0.0);
468 using namespace etable::count_pair;
470 CountPairFactory::create_count_pair_function( rsd1, rsd2,
CP_CROSSOVER_4 );
473 Vector const & atom1_xyz( rsd1.
xyz( atom1 ) );
474 Size const atom1_type_index( rsd1.
atom( atom1 ).
type() );
476 Real total_desolvation( 0.0 );
478 Vector const & atom2_xyz( rsd2.
xyz( atom2 ) );
480 Real cp_weight = 1.0;
482 if ( cpfxn->count( atom1, atom2, cp_weight, pathdist ) ) {
483 Real const d2( atom1_xyz.distance_squared( atom2_xyz ) );
488 Size const atom2_type_index( rsd2.
atom( atom2 ).
type() );
490 int disbin =
static_cast< int >( d2_bin ) + 1;
491 Real frac = d2_bin - ( disbin - 1 );
492 int const l1 =
solv1_.index( disbin, atom2_type_index, atom1_type_index );
494 Real const lk_desolvation_of_atom1_by_atom2
495 ( cp_weight * ( ( 1. - frac ) *
solv1_[ l1 ] + frac *
solv1_[ l1+1 ] ) );
497 total_desolvation += lk_desolvation_of_atom1_by_atom2;
500 return total_desolvation;
512 Real & lk_desolvation_of_atom1_by_atom2,
513 Real & lk_ball_desolvation_of_atom1_by_atom2
516 using namespace etable::count_pair;
519 lk_desolvation_of_atom1_by_atom2 = 0.0;
520 lk_ball_desolvation_of_atom1_by_atom2 = 0.0;
523 CountPairFactory::create_count_pair_function( rsd1, rsd2,
CP_CROSSOVER_4 );
525 Real cp_weight = 1.0;
Size pathdist;
526 if ( !cpfxn->count( atom1, atom2, cp_weight, pathdist ) )
return;
528 Vector const & atom1_xyz( rsd1.
xyz( atom1 ) );
529 Vector const & atom2_xyz( rsd2.
xyz( atom2 ) );
531 Real const d2( atom1_xyz.distance_squared( atom2_xyz ) );
536 Size const atom1_type_index( rsd1.
atom( atom1 ).
type() );
537 Size const atom2_type_index( rsd2.
atom( atom2 ).
type() );
540 int disbin =
static_cast< int >( d2_bin ) + 1;
541 Real frac = d2_bin - ( disbin - 1 );
542 int const l1 =
solv1_.index( disbin, atom2_type_index, atom1_type_index );
544 lk_desolvation_of_atom1_by_atom2 = ( cp_weight * ( ( 1. - frac ) *
solv1_[
l1 ] + frac *
solv1_[
l1+1 ] ) );
548 lk_ball_desolvation_of_atom1_by_atom2 = lk_desolvation_of_atom1_by_atom2 *
564 Vector const & atom1_xyz( rsd1.
xyz( atom1 ) );
565 Size const atom1_type_index( rsd1.
atom( atom1 ).
type() );
567 Real total_desolvation( 0.0 );
569 Vector const & atom2_xyz( rsd2.
xyz( atom2 ) );
571 Real const d2( atom1_xyz.distance_squared( atom2_xyz ) );
576 Size const atom2_type_index( rsd2.
atom( atom2 ).
type() );
578 int disbin =
static_cast< int >( d2_bin ) + 1;
579 Real frac = d2_bin - ( disbin - 1 );
580 int const l1 =
solv1_.index( disbin, atom2_type_index, atom1_type_index );
582 Real const lk_desolvation_of_atom1_by_atom2
583 ( ( ( 1. - frac ) *
solv1_[ l1 ] + frac *
solv1_[ l1+1 ] ) );
585 total_desolvation += lk_desolvation_of_atom1_by_atom2;
588 return total_desolvation;
598 Real & atom1_lk_desolvation_by_atom2_deriv,
599 Real & atom2_lk_desolvation_by_atom1_deriv
603 atom1_lk_desolvation_by_atom2_deriv = 0.0;
604 atom2_lk_desolvation_by_atom1_deriv = 0.0;
609 Size const disbin( static_cast< int >( d2_bin ) + 1 );
610 Real const frac( d2_bin - ( disbin - 1 ) );
617 atom1_lk_desolvation_by_atom2_deriv =
dsolv1_[ linear_index12 ] * ( 1-frac ) +
dsolv1_[ linear_index12 + 1 ] * frac;
618 atom2_lk_desolvation_by_atom1_deriv =
dsolv1_[ linear_index21 ] * ( 1-frac ) +
dsolv1_[ linear_index21 + 1 ] * frac;
629 bool const use_intra_dna_cp_crossover_4
634 using namespace scoring::etable::count_pair;
639 ( !( use_intra_dna_cp_crossover_4 && res1.
is_DNA() && res2.
is_DNA() ) ) &&
659 Size const atom2_type_index,
661 Real const lk_desolvation_of_atom1_by_atom2,
667 if ( !atom1_waters.empty() ) {
668 emap[
lk_ball_iso ] += lk_desolvation_of_atom1_by_atom2;
671 emap[
lk_ball ] += lk_desolvation_of_atom1_by_atom2 *
689 using namespace etable::count_pair;
700 CountPairFunctionOP cpfxn = CountPairFactory::create_count_pair_function( rsd1, rsd2, crossover );
704 Vectors const & atom1_waters( rsd1_waters[ atom1 ] );
705 Vector const & atom1_xyz( rsd1.
xyz( atom1 ) );
706 Size const atom1_type_index( rsd1.
atom( atom1 ).
type() );
710 Vectors const & atom2_waters( rsd2_waters[ atom2 ] );
711 Vector const & atom2_xyz( rsd2.
xyz( atom2 ) );
714 if ( atom1_waters.empty() && atom2_waters.empty() )
continue;
716 Real cp_weight = 1.0;
Size pathdist;
717 if ( cpfxn->count( atom1, atom2, cp_weight, pathdist ) ) {
718 Real const d2( atom1_xyz.distance_squared( atom2_xyz ) );
723 Size const atom2_type_index( rsd2.
atom( atom2 ).
type() );
725 int disbin =
static_cast< int >( d2_bin ) + 1;
726 Real frac = d2_bin - ( disbin - 1 );
727 int const l1 =
solv1_.index( disbin, atom2_type_index, atom1_type_index );
729 Real lk_desolvation_of_atom1_by_atom2
730 ( cp_weight * ( ( 1. - frac ) *
solv1_[ l1 ] + frac *
solv1_[ l1+1 ] ) );
732 Real lk_desolvation_of_atom2_by_atom1
733 ( cp_weight * ( ( 1. - frac ) *
solv2_[ l1 ] + frac *
solv2_[ l1+1 ] ) );
736 rsd1, atom2_type_index, atom2_xyz,
737 lk_desolvation_of_atom1_by_atom2, emap );
740 rsd2, atom1_type_index, atom1_xyz,
741 lk_desolvation_of_atom2_by_atom1, emap );
799 Size const atom2_type,
801 bool const evaluate_deriv,
807 Size closest_water(0);
808 Real closest_water_d2_delta( 100.0);
810 closest_water, closest_water_d2_delta ) );
812 if ( evaluate_deriv ) {
813 f1.clear(); f2.clear();
817 if ( closest_water_d2_delta < ramp_width_A2_ && closest_water_d2_delta > 0.0 ) {
818 Vector const & atom1_water_xyz( atom1_waters[ closest_water ] );
821 f1 = dE_dr_over_r * ( atom1_water_xyz.cross( atom2_xyz ) );
822 f2 = dE_dr_over_r * ( atom1_water_xyz - atom2_xyz );
843 Real const weight_factor,
850 if ( atom1_waters.empty() )
return;
856 Size const disbin( static_cast< int >( d2_bin ) + 1 );
857 Real const frac( d2_bin - ( disbin - 1 ) );
860 Size const atom1_type_index( rsd1.
atom( atom1 ).
type() );
861 int const linear_index(
dsolv1_.index( disbin, rsd2.
atom( atom2 ).
type(), atom1_type_index ) );
863 Real const lk_deriv(
dsolv1_[ linear_index ] * ( 1-frac ) +
dsolv1_[ linear_index+1 ] * frac );
864 Real const lk_score(
solv1_[ linear_index ] * ( 1-frac ) +
solv1_[ linear_index+1 ] * frac );
869 Vector const & atom1_xyz( rsd1.
xyz( atom1 ) );
870 Vector const & atom2_xyz( rsd2.
xyz( atom2 ) );
871 Vector f1( atom1_xyz.cross( atom2_xyz ) ), f2( atom1_xyz - atom2_xyz );
873 Real const inv_dis( 1.0 / std::sqrt( d2 ) );
878 Real const dE_dr_over_r( weight_factor * lk_ball_iso_weight * lk_deriv * inv_dis );
879 F1 += dE_dr_over_r * f1;
880 F2 += dE_dr_over_r * f2;
889 Size closest_water(0);
890 Real closest_water_d2_delta( 100.0);
892 closest_water, closest_water_d2_delta ) );
896 Real const dE_dr_over_r( weight_factor * lk_ball_weight * lk_fraction * lk_deriv * inv_dis );
897 F1 += dE_dr_over_r * f1;
898 F2 += dE_dr_over_r * f2;
903 if ( closest_water_d2_delta < ramp_width_A2_ && closest_water_d2_delta > 0.0 ) {
904 Vector const & atom1_water_xyz( atom1_waters[ closest_water ] );
906 f1 = atom1_water_xyz.cross( atom2_xyz );
907 f2 = atom1_water_xyz - atom2_xyz;
909 Real const dE_dr_over_r
911 F1 += dE_dr_over_r * f1;
912 F2 += dE_dr_over_r * f2;
929 Real const cp_weight,
935 Real const d2( rsd1.
xyz( atom1 ).distance_squared( rsd2.
xyz( atom2 ) ) );
1012 ObjexxFCL::FArray2D< core::PackerEnergy > & energy_table
1015 using namespace conformation;
1016 using namespace numeric;
1030 if ( !info1[ ii_offset ].has_waters() && !info2[ jj_offset ].has_waters() )
continue;
1033 Size const kk_rot_id = ii_offset + kk - 1;
1035 Size const ll_rot_id = jj_offset + ll - 1;
1038 *set2.
rotamer( ll_rot_id ), info2[ ll_rot_id ], emap );
1069 if ( !set_info[ ii_offset ].has_waters() && !rsd_info.
has_waters() )
continue;
1072 Size const kk_rot_id = ii_offset + kk - 1;
1112 assert( r1_at_derivs.size() >= rsd1.
natoms() );
1113 assert( r2_at_derivs.size() >= rsd2.
natoms() );
1124 for (
Size ii = 1, iiend = neighbs.size(); ii <= iiend; ++ii ) {
1125 Size const atom1( neighbs[ ii ].atomno1() ), atom2( neighbs[ ii ].atomno2() );
1127 Real const cp_weight( neighbs[ ii ].weight() );
1129 Vector f1(0,0,0),f2(0,0,0);
1131 cp_weight, f1, f2 );
1133 r1_at_derivs[ neighbs[ ii ].atomno1() ].f1() += f1;
1134 r1_at_derivs[ neighbs[ ii ].atomno1() ].f2() += f2;
1135 r2_at_derivs[ neighbs[ ii ].atomno2() ].f1() += -1*f1;
1136 r2_at_derivs[ neighbs[ ii ].atomno2() ].f2() += -1*f2;
1147 using namespace chemical;
1149 typedef std::map< ResidueTypeCOP, utility::vector1< Size > > H_Map;
1152 H_Map::const_iterator iter = hmap.find( rsd_type_ptr );
1153 if ( iter == hmap.end() ) {
1160 hmap.insert( std::make_pair( rsd_type_ptr, parallel_h ) );
1161 iter = hmap.find( rsd_type_ptr );
1163 return iter->second[ hatm ];
1184 Real & unweighted_energy,
1185 bool const evaluate_derivative,
1187 Real & don_fraction,
1193 bool const no_lk_ball_for_SP2(
false );
1194 bool const exclude_arg_double_parallel_hbonds(
true );
1204 static Real const optimal_acceptor_water_distance( 2.85 );
1205 static Real const optimal_donor_water_distance ( 2.85 );
1206 static Real const optimal_acceptor_angle_SP2( numeric::conversions::radians( 120.0 ) );
1207 static Real const n1_coeff_SP2( -1.0 * optimal_acceptor_water_distance * std::cos( optimal_acceptor_angle_SP2 ) );
1208 static Real const n2_coeff_SP2( optimal_acceptor_water_distance * std::sin( optimal_acceptor_angle_SP2 ) );
1212 Vector f1_don( 0.0 ), f2_don( 0.0 ), f1_acc( 0.0 ), f2_acc( 0.0 );
1213 don_fraction = acc_fraction = 1.0;
1218 waters.push_back( datm_xyz + optimal_donor_water_distance * ( hatm_xyz - datm_xyz ).normalized_any() );
1223 & other_hatm_xyz( don_rsd.
xyz( other_hatm ) ), & aatm_xyz( acc_rsd.
xyz( aatm ) );
1224 Vector const other_water( other_datm_xyz + optimal_donor_water_distance *
1225 ( other_hatm_xyz - other_datm_xyz ).normalized_any() );
1226 if ( aatm_xyz.distance_squared( other_water ) < aatm_xyz.distance_squared( waters.front() ) ) {
1231 don_fraction = acc_fraction = 0.0;
1233 if ( evaluate_derivative ) {
1240 if ( !waters.empty() ) {
1243 waters, evaluate_derivative, f1_don, f2_don );
1251 using namespace chemical;
1257 Vector const & aatm_xyz( acc_rsd.
xyz( aatm ) );
1263 Vector const n1( ( aatm_xyz - abase_xyz ).normalized_any() );
1264 Vector n2( ( abase2_xyz - abase_xyz ) );
1265 n2 = ( n2 - n1.dot( n2 ) * n1 ).normalized_any();
1266 assert( std::abs( n1.dot( n2 ) ) < 1e-3 );
1267 waters.push_back( aatm_xyz + n1_coeff_SP2 * n1 + n2_coeff_SP2 * n2 );
1268 waters.push_back( aatm_xyz + n1_coeff_SP2 * n1 - n2_coeff_SP2 * n2 );
1272 Vector const n1( ( aatm_xyz - 0.5 * abase_xyz - 0.5 * abase2_xyz ).normalized_any() );
1273 waters.push_back( aatm_xyz + optimal_acceptor_water_distance * n1 );
1277 utility_exit_with_message(
"dont do this hybridization state!");
1282 evaluate_derivative, f1_acc, f2_acc );
1286 if ( acc_fraction < 0.99 || don_fraction < 0.99 ) {
1288 using namespace ObjexxFCL::fmt;
1300 if ( evaluate_derivative ) {
1305 unweighted_energy * f1_don * acc_fraction +
1306 unweighted_energy * don_fraction * -1 * f1_acc );
1309 unweighted_energy * f2_don * acc_fraction +
1310 unweighted_energy * don_fraction * -1 * f2_acc );
1313 unweighted_energy * -1 * f1_don * acc_fraction +
1314 unweighted_energy * don_fraction * f1_acc );
1317 unweighted_energy * -1 * f2_don * acc_fraction +
1318 unweighted_energy * don_fraction * f2_acc );
1342 unweighted_energy = unweighted_energy * don_fraction * acc_fraction;