48 #include <basic/Tracer.hh>
54 #include <numeric/trig.functions.hh>
55 #include <numeric/deriv/distance_deriv.hh>
56 #include <numeric/deriv/angle_deriv.hh>
59 #include <ObjexxFCL/format.hh>
61 #include <utility/vector1.hh>
64 static basic::Tracer
tr(
"core.scoring.geometric_solvation.OccludedHbondSolEnergy" );
68 namespace geometric_solvation {
70 using namespace ObjexxFCL::fmt;
106 if (
verbose_ )
tr <<
"OccludedHbondSolEnergy constructor" << std::endl;
111 occ_hbond_sol_database_( src.occ_hbond_sol_database_ ),
112 verbose_( src.verbose_ )
114 if (
verbose_ )
tr <<
"OccludedHbondSolEnergy constructor" << std::endl;
146 if (
verbose_ )
tr <<
"jk evaluating residue pair energy" << std::endl;
169 if (
verbose_ )
tr <<
"jk evaluating intrares energy" << std::endl;
181 bool res_moving_wrt_eachother
184 return res_moving_wrt_eachother;
216 Real const atom_pair_cutoff2( atom_pair_cutoff*atom_pair_cutoff );
218 Real d2cut = dcut * dcut;
220 for ( chemical::AtomIndices::const_iterator
223 hnum != hnume; ++hnum ) {
224 Size const don_h_atom( *hnum );
226 if ( rsd1.
xyz( don_h_atom ).distance_squared( r2_nb_xyz ) > d2cut )
continue;
228 if ( rsd1.
xyz( don_h_atom ).distance_squared( rsd2.
xyz(jj) ) > atom_pair_cutoff2 )
continue;
230 r1_atom_derivs[ don_base_atom ].f1(), r1_atom_derivs[ don_base_atom ].f2(),
231 r1_atom_derivs[ don_h_atom ].f1(), r1_atom_derivs[ don_h_atom ].f2(),
232 r2_atom_derivs[ jj ].f1(), r2_atom_derivs[ jj ].f2() );
236 for ( chemical::AtomIndices::const_iterator
239 anum != anume; ++anum ) {
240 Size const acc_atom( *anum );
242 if ( rsd1.
xyz( acc_atom ).distance_squared( r2_nb_xyz ) > d2cut )
continue;
244 if ( rsd1.
xyz( acc_atom ).distance_squared( rsd2.
xyz(jj) ) > atom_pair_cutoff2 )
continue;
246 r1_atom_derivs[ base_atom ].f1(), r1_atom_derivs[ base_atom ].f2(),
247 r1_atom_derivs[ acc_atom ].f1(), r1_atom_derivs[ acc_atom ].f2(),
248 r2_atom_derivs[ jj ].f1(), r2_atom_derivs[ jj ].f2() );
285 Real geo_solE(0.), energy(0.);
288 Real d2cut = dcut * dcut;
292 for ( chemical::AtomIndices::const_iterator hnum = polar_rsd.
Hpos_polar().begin(), hnume = polar_rsd.
Hpos_polar().end(); hnum != hnume; ++hnum ) {
293 Size const don_h_atom( *hnum );
294 Size const don_base_atom( polar_rsd.
atom_base( don_h_atom ) );
295 if ( polar_rsd.
xyz( don_h_atom ).distance_squared( occ_nb_xyz ) > d2cut )
continue;
296 for (
Size occ_atom = 1; occ_atom <= occ_rsd.
natoms(); occ_atom++ ) {
303 for ( chemical::AtomIndices::const_iterator anum = polar_rsd.
accpt_pos().begin(), anume = polar_rsd.
accpt_pos().end(); anum != anume; ++anum ) {
304 Size const acc_atom( *anum );
306 if ( polar_rsd.
xyz( acc_atom ).distance_squared( occ_nb_xyz ) > d2cut )
continue;
307 for (
Size occ_atom = 1; occ_atom <= occ_rsd.
natoms(); occ_atom++ ) {
319 Size const polar_atom,
320 Size const base_atom,
325 bool const update_deriv,
326 Real const occ_sol_fitted_weight,
352 if ( polar_atom == occ_atom )
return;
353 if ( base_atom == occ_atom )
return;
356 bool polar_atom_donates =
false;
359 if ( polar_atom_donates ) {
385 assert( ( polar_atom_donates &&
atom_is_donor_h( polar_rsd, polar_atom ) ) ||
386 ( ( ! polar_atom_donates ) &&
atom_is_acceptor( polar_rsd, polar_atom ) ) );
390 if ( polar_atom_donates ) polar_atom_type_lookup_index = polar_rsd.
atom_type_index( base_atom );
392 Vector const & polar_atom_xyz( polar_rsd.
atom( polar_atom ).
xyz() );
393 Vector const & base_atom_xyz( polar_rsd.
atom( base_atom ).
xyz() );
396 Vector const & occ_atom_xyz( occ_rsd.
atom( occ_atom ).
xyz() );
399 Real const dist_sq = ( occ_atom_xyz - polar_atom_xyz).length_squared();
401 Real const curr_cos_angle =
get_cos_angle( base_atom_xyz, polar_atom_xyz, occ_atom_xyz );
415 Real const dist_diff = sqrt(dist_sq) - dist_mu;
416 Real const cos_angle_diff = cos_angle_mu - curr_cos_angle;
418 Real dist_exp, cos_angle_exp;
419 if ( update_deriv ) {
420 dist_exp = exp( - ( dist_diff * dist_diff / twice_dist_sigma_sq ) );
421 cos_angle_exp = exp( - ( cos_angle_diff * cos_angle_diff / twice_cos_angle_sigma_sq ) );
422 energy = amp * dist_exp * cos_angle_exp;
426 exp( - ( ( dist_diff * dist_diff / twice_dist_sigma_sq ) + ( cos_angle_diff * cos_angle_diff / twice_cos_angle_sigma_sq ) ) );
429 if (
verbose_ && ( energy > 0. ) ) {
430 tr <<
"jk res "<< polar_rsd.
name1() << I(3,polar_rsd.
seqpos()) <<
431 " atom " << polar_rsd.
atom_name( polar_atom ) <<
" is occluded by occ_res " <<
433 " atom " << occ_rsd.
atom_name( occ_atom ) <<
434 " with energy " << F(8,3,energy) << std::endl;
437 if ( ! update_deriv )
return;
441 Real const curr_angle = numeric::arccos(curr_cos_angle);
442 Real const cos_angle_dfunc = -2. * cos_angle_diff * energy / twice_cos_angle_sigma_sq;
443 Real const angle_dfunc = -std::sin(curr_angle) * cos_angle_dfunc * occ_sol_fitted_weight;
445 Vector angle_f1_p1(0.), angle_f2_p1(0.);
446 Vector angle_f1_p2(0.), angle_f2_p2(0.);
447 Vector angle_f1_p3(0.), angle_f2_p3(0.);
449 numeric::deriv::angle_p1_p2_p3_deriv( base_atom_xyz, polar_atom_xyz, occ_atom_xyz, theta,
450 angle_f1_p1, angle_f2_p1, angle_f1_p2, angle_f2_p2, angle_f1_p3, angle_f2_p3 );
452 f1_polar += angle_dfunc * angle_f1_p2;
453 f2_polar += angle_dfunc * angle_f2_p2;
455 f1_base += angle_dfunc * angle_f1_p1;
456 f2_base += angle_dfunc * angle_f2_p1;
458 f1_occ += angle_dfunc * angle_f1_p3;
459 f2_occ += angle_dfunc * angle_f2_p3;
463 Real const dist_dfunc = -2. * dist_diff * energy * occ_sol_fitted_weight / twice_dist_sigma_sq;
465 Vector dist_f1(0.), dist_f2(0.);
467 numeric::deriv::distance_f1_f2_deriv( polar_atom_xyz, occ_atom_xyz, dist, dist_f1, dist_f2 );
468 f1_polar += dist_dfunc * dist_f1;
469 f2_polar += dist_dfunc * dist_f2;
471 f1_occ -= dist_dfunc * dist_f1;
472 f2_occ -= dist_dfunc * dist_f2;
593 Vector const & base_atom_xyz,
594 Vector const & polar_atom_xyz,
595 Vector const & occluding_atom_xyz )
const
597 return dot( (polar_atom_xyz - base_atom_xyz).normalize(), (occluding_atom_xyz - polar_atom_xyz).normalize() );
604 for ( chemical::AtomIndices::const_iterator hnum = rsd.
Hpos_polar().begin(), hnume = rsd.
Hpos_polar().end(); hnum != hnume; ++hnum ) {
605 Size const don_h_atom( *hnum );
606 if ( don_h_atom == atom )
return true;
613 for ( chemical::AtomIndices::const_iterator anum = rsd.
accpt_pos().begin(), anume = rsd.
accpt_pos().end(); anum != anume; ++anum ) {
614 Size const acc_atom( *anum );
615 if ( acc_atom == atom )
return true;
622 for ( chemical::AtomIndices::const_iterator hnum = rsd.
Hpos_polar().begin(), hnume = rsd.
Hpos_polar().end(); hnum != hnume; ++hnum ) {
623 Size const don_h_atom( *hnum );
625 if ( base_atom == atom )
return true;
627 for ( chemical::AtomIndices::const_iterator anum = rsd.
accpt_pos().begin(), anume = rsd.
accpt_pos().end(); anum != anume; ++anum ) {
628 Size const acc_atom( *anum );
630 if ( base_atom == atom )
return true;