29 #include <basic/Tracer.hh>
32 #include <numeric/constants.hh>
33 #include <numeric/conversions.hh>
34 #include <numeric/deriv/distance_deriv.hh>
35 #include <numeric/deriv/angle_deriv.hh>
36 #include <numeric/deriv/dihedral_deriv.hh>
39 #include <ObjexxFCL/format.hh>
47 #include <basic/options/option.hh>
48 #include <basic/options/keys/OptionKeys.hh>
49 #include <basic/options/keys/in.OptionKeys.gen.hh>
51 #include <basic/options/keys/corrections.OptionKeys.gen.hh>
54 #include <numeric/numeric.functions.hh>
55 #include <numeric/xyz.functions.hh>
58 #include <utility/excn/Exceptions.hh>
61 #include <utility/basic_sys_util.hh>
62 #include <utility/PyAssert.hh>
68 #include <utility/vector1.hh>
69 #include <ObjexxFCL/FArray3D.hh>
71 namespace ObjexxFCL {
namespace fmt { } }
using namespace ObjexxFCL::fmt;
77 static basic::Tracer
tr(
"core.scoring.hbonds");
93 using namespace chemical;
111 switch(don_rsd.
aa()){
114 if (aname ==
" ND1"){
117 assert( aname ==
" NE2");
125 if (aname ==
" NE "){
128 assert(aname ==
" NH1" || aname ==
" NH2");
140 if (aname ==
" N6 ") {
144 }
else if (aname ==
"WN6" || aname ==
"WN7" || aname ==
"WN3") {
148 if (aname ==
" N4 ") {
154 }
else if ( aname ==
"WN4" || aname ==
"WO2" ) {
158 if (aname ==
" N1 ") {
162 }
else if (aname ==
" N2 ") {
166 }
else if ( aname ==
"WO6" || aname ==
"WN7" || aname ==
"WN3" ){
170 if (aname ==
" N3 ") {
174 }
else if ( aname ==
"WO4" || aname ==
"WO2" ) {
178 if (aname ==
" N6 ") {
182 }
else if ( aname ==
"WN6" || aname ==
"WN7" ){
184 }
else if ( aname ==
" O2*" ){
188 }
else if ( aname ==
" N1 " && don_rsd.
has_variant_type(
"PROTONATED_H1_ADENOSINE") ) {
192 if (aname ==
" N1 ") {
196 }
else if (aname ==
" N2 ") {
200 }
else if ( aname ==
" O2*" ){
204 }
else if ( aname ==
"WO6" || aname ==
"WN7"){
208 if (aname ==
" N4 ") {
212 }
else if ( aname ==
" O2*" ){
216 }
else if ( aname ==
"WN4" ){
220 if (aname ==
" N3 ") {
224 }
else if ( aname ==
" O2*" ){
228 }
else if ( aname ==
"WO4" ){
237 utility_exit_with_message(
"ERROR: Unknown Hydrogen Bond donor type for: " + don_rsd.
name1() + I(3, don_rsd.
seqpos()) +
" " + don_rsd.
atom_name( datm) +
". Using hbdon_GENERIC_SC.");
248 using namespace chemical;
261 }
else if (acc_rsd.
is_DNA()){
262 if (aname ==
" O1P" || aname ==
" O2P" ){
264 }
else if (aname ==
" O5*" || aname ==
" O3*"){
266 }
else if (aname ==
" O4*"){
269 }
else if ( acc_rsd.
is_RNA() ){
270 if (aname ==
" O1P" || aname ==
" O2P" || aname ==
" O3P"){
272 }
else if (aname ==
" O5*" || aname ==
" O3*"){
274 }
else if (aname ==
" O4*"){
295 switch(acc_rsd.
aa()){
299 if (aname ==
" ND1"){
310 if (aname ==
" N1 " || aname ==
" N3 " || aname ==
" N7 "){
314 }
else if (aname ==
"WN6" || aname ==
"WN7" || aname ==
"WN3") {
318 if (aname ==
" N3 " || aname ==
" N7 "){
322 }
else if ( aname ==
" O6 "){
324 }
else if ( aname ==
"WO6" || aname ==
"WN7" || aname ==
"WN3" ) {
328 if (aname ==
" O2 "){
332 }
else if (aname ==
" N3 "){
336 }
else if ( aname ==
"WN4" || aname ==
"WO2" ) {
340 if (aname ==
" O2 " || aname ==
" O4 "){
344 }
else if ( aname ==
"WO4" || aname ==
"WO2" ) {
348 if (aname ==
" N1 " || aname ==
" N3 " || aname ==
" N7 "){
350 if(acc_rsd.
has_variant_type(
"PROTONATED_H1_ADENOSINE")) utility_exit_with_message(
"acc_rsd.aa()==na_rad, aname == \" N1 \" and acc_rsd.has_variant_type(\"PROTONATED_H1_ADENOSINE\")!");
355 }
else if (aname ==
" O2*") {
361 if (aname ==
" N3 " || aname ==
" N7 "){
365 }
else if (aname ==
" O6 "){
369 }
else if (aname ==
" O2*") {
375 if (aname ==
" O2 "){
379 }
else if (aname ==
" N3 "){
383 }
else if (aname ==
" O2*") {
389 if (aname ==
" O2 " || aname ==
" O4 "){
393 }
else if (aname ==
" O2*") {
413 utility_exit_with_message(
"unknown Hydrogen Bond acceptor type for: " + acc_rsd.
name1() + I(3,acc_rsd.
seqpos()) +
" " + acc_rsd.
atom_name( aatm) );
445 switch(don_chem_type){
450 switch(acc_chem_type){
480 switch(acc_chem_type){
518 return HBEvalTuple( don_chem_type, acc_chem_type, seq_sep );
532 return HBEvalTuple( don_chem_type, acc_chem_type, seq_sep );
546 bool & apply_chi_torsion_penalty,
557 apply_chi_torsion_penalty =
false;
558 dE_dr = dE_dxD = dE_dxH = dE_dBAH = dE_dchi = 0.0;
561 if ( std::abs(xD) > 1.0 || std::abs(xH) > 1.0 ) {
563 tr <<
"WARNING:: invalid angle value in hbond_compute_energy:"
564 <<
" xH = " << ObjexxFCL::fmt::SS( xH ) <<
" xD = " << ObjexxFCL::fmt::SS( xD ) << std::endl;
575 double const dAHdis =
static_cast<double>(AHdis);
576 double const dxD =
static_cast<double>(xD);
577 double const dxH =
static_cast<double>(xH);
578 double Pr(0.0), PSxD(0.0), PSxH(0.0), PLxD(0.0), PLxH(0.0);
579 double dPr(0.0), dPSxD(0.0), dPSxH(0.0), dPLxD(0.0), dPLxH(0.0);
580 double FSr(0.0), FLr(0.0), FxD(0.0), FxH(0.0);
581 double dFSr(0.0), dFLr(0.0), dFxD(0.0), dFxH(0.0);
588 if ( FSr ==
Real(0.0) && FLr ==
Real(0.0) ) {
597 if ( FxH ==
Real(0.0) ) {
613 if ( ! use_cosAHD ) {
614 AHD = numeric::constants::d::pi-acos(dxD);
617 if ( FxD ==
Real(0.0) ) {
646 energy = Pr*FxD*FxH + FSr*(PSxD*FxH + FxD*PSxH) + FLr*(PLxD*FxH + FxD*PLxH);
664 bool apply_chi_torsion_penalty_sp2 =
false;
665 bool apply_chi_torsion_penalty_sp3 =
false;
668 apply_chi_torsion_penalty =
true;
669 apply_chi_torsion_penalty_sp2 =
true;
719 Real h = (std::cos(2*chi)+1) * 0.5;
720 Real const acos_xH = acos( xH );
721 angleBAH = numeric::constants::d::pi - acos_xH;
722 if ( angleBAH >= numeric::constants::d::pi * 2/3 ) {
723 f = bah180_rise/2*std::cos( 3 * acos_xH ) + (bah180_rise / 2 - 0.5 );
724 g = -0.5 + bah180_rise;
725 }
else if ( angleBAH >= numeric::constants::d::pi * 1/3 ) {
726 f = std::cos(3*acos_xH)*0.75 + 0.25;
727 g = (1.5-bah180_rise)*0.5*std::cos(3*acos_xH) + (0.25 + bah180_rise/2 );
733 energy += h*f + (1-h)*g;
737 apply_chi_torsion_penalty =
true;
738 apply_chi_torsion_penalty_sp3 =
true;
742 Real const max_penalty = 0.25;
743 Real cos2ChiShifted = max_penalty * ( 1 + std::cos(chi)) / 2;
745 energy += cos2ChiShifted;
750 Real const bond_strength(sqrt(don_strength*acc_strength));
752 energy *= bond_strength;
760 dE_dr = dPr*FxD*FxH + dFSr*(PSxD*FxH + FxD*PSxH) + dFLr*(PLxD*FxH + FxD*PLxH);
761 dE_dr *= bond_strength;
764 dE_dxD = dFxD*(Pr*FxH + FLr*PLxH + FSr*PSxH) + FxH*(FSr*dPSxD + FLr*dPLxD);
769 dE_dxD = dFxD*(Pr*FxH + FLr*PLxH + FSr*PSxH)*sin(AHD) + FxH*(FSr*dPSxD + FLr*dPLxD);
771 dE_dxH = dFxH*(Pr*FxD + FLr*PLxD + FSr*PSxD) + FxD*(FSr*dPSxH + FLr*dPLxH);
773 if ( apply_chi_torsion_penalty_sp2 ) {
817 Real g(0), f(0), dfdBAH(0), dgdBAH(0);
818 Real h = (std::cos(2*chi)+1) * 0.5;
819 Real dhdchi = -std::sin(2*chi);
820 Real const acos_xH = numeric::constants::d::pi - angleBAH;
821 if ( angleBAH >= numeric::constants::d::pi * 2/3 ) {
822 f = bah180_rise/2*std::cos( 3 * acos_xH ) + (bah180_rise / 2 - 0.5 );
823 g = -0.5 + bah180_rise;
824 dfdBAH = 3*bah180_rise/2*sin(3*acos_xH);
825 }
else if ( angleBAH >= numeric::constants::d::pi * 1/3 ) {
826 f = 0.75*cos(3*acos_xH) + 0.25;
827 g = (1.5-bah180_rise)*0.5*cos(3*acos_xH) + (0.25 + bah180_rise/2 );
828 dfdBAH = 9.0/4.0*sin(3*acos_xH);
829 dgdBAH = 3*(1.5-bah180_rise)/2*sin(3*acos_xH);
834 dE_dchi = f*dhdchi - g*dhdchi;
835 dE_dBAH = h*dfdBAH + (1-h)*dgdBAH;
838 }
else if ( apply_chi_torsion_penalty_sp3 ) {
839 Real const max_penalty = 0.25;
841 Real minussin2ChiShifted = -1 * max_penalty * std::sin(chi)/2;
842 dE_dchi = minussin2ChiShifted;
903 bool const evaluate_deriv,
907 hb_energy_deriv_u2( database, hbondoptions, hbt, deriv_type, Hxyz, Dxyz, HDunit, Axyz, Bxyz, BAunit, B2xyz, energy, deriv );
933 using namespace hbonds;
954 Real const AHdis2( AH.length_squared() );
956 if ( AHdis2 >
MAX_R2 )
return;
957 if ( AHdis2 <
MIN_R2 )
return;
958 Real const AHdis = std::sqrt(AHdis2);
959 Real const inv_AHdis = 1.0f / AHdis;
961 AHunit = AH * inv_AHdis;
966 dot( AHunit, HDunit );
968 if ( xD <
MIN_xD )
return;
969 if ( xD >
MAX_xD )
return;
972 dot( BAunit, AHunit );
974 if ( xH <
MIN_xH )
return;
975 if ( xH >
MAX_xH )
return;
980 B2xyz !=
Vector(-1.0, -1.0, -1.0) ) {
981 chi = numeric::dihedral_radians( Hxyz, Axyz, Bxyz, B2xyz );
986 chi = numeric::dihedral_radians( Hxyz, Axyz, Bxyz, B2xyz );
1003 Real dE_dxH, dE_dxD, dE_dr, dE_dBAH, dE_dchi;
1004 bool apply_chi_torsion_penalty(
false );
1016 apply_chi_torsion_penalty,
1017 AHD_geometric_dimension,
1048 using namespace numeric::deriv;
1054 distance_f1_f2_deriv(Hxyz, Axyz, temp_AHdis, f1, f2);
1063 angle_p1_deriv( Axyz, Hxyz, Dxyz, theta, f1, f2);
1064 Real const dE_dxD_sin_theta = dE_dxD*sin( theta );
1068 angle_p1_deriv( Dxyz, Hxyz, Axyz, theta, f1, f2);
1072 angle_p2_deriv( Dxyz, Hxyz, Axyz, theta, f1, f2);
1073 deriv.
h_deriv.
f1() += dE_dxD_sin_theta * f1;
1074 deriv.
h_deriv.
f2() += dE_dxD_sin_theta * f2;
1075 }
else if (AHD_geometric_dimension ==
hbgd_AHD){
1077 angle_p1_deriv( Axyz, Hxyz, Dxyz, theta, f1, f2);
1081 angle_p1_deriv( Dxyz, Hxyz, Axyz, theta, f1, f2);
1085 angle_p2_deriv( Dxyz, Hxyz, Axyz, theta, f1, f2);
1094 Vector f1h(0.0),f2h(0.0);
1095 angle_p1_deriv( Hxyz, Axyz, Bxyz, phi, f1h, f2h);
1096 Real const dE_dxH_sin_phi = dE_dxH *sin( phi );
1097 deriv.
h_deriv.
f1() += dE_dxH_sin_phi * f1h;
1098 deriv.
h_deriv.
f2() += dE_dxH_sin_phi * f2h;
1100 Vector f1b(0.0),f2b(0.0);
1101 angle_p1_deriv( Bxyz, Axyz, Hxyz, phi, f1b, f2b);
1105 Vector f1a(0.0),f2a(0.0);
1106 angle_p2_deriv( Bxyz, Axyz, Hxyz, phi, f1a, f2a);
1109 if ( apply_chi_torsion_penalty ) {
1124 if ( apply_chi_torsion_penalty ) {
1125 Vector chi_h_f1(0), chi_h_f2(0);
1126 Vector chi_a_f1(0), chi_a_f2(0);
1127 Vector chi_ab_f1(0), chi_ab_f2(0);
1128 Vector chi_ab2_f1(0), chi_ab2_f2(0);
1130 dihedral_p1_cosine_deriv( Hxyz, Axyz, Bxyz, B2xyz, chi, chi_h_f1, chi_h_f2 );
1131 dihedral_p2_cosine_deriv( Hxyz, Axyz, Bxyz, B2xyz, chi, chi_a_f1, chi_a_f2 );
1132 dihedral_p2_cosine_deriv( B2xyz, Bxyz, Axyz, Hxyz, chi, chi_ab_f1, chi_ab_f2 );
1133 dihedral_p1_cosine_deriv( B2xyz, Bxyz, Axyz, Hxyz, chi, chi_ab2_f1, chi_ab2_f2 );
1135 deriv.
h_deriv.
f1() += dE_dchi * chi_h_f1;
1136 deriv.
h_deriv.
f2() += dE_dchi * chi_h_f2;
1181 HxA = cross( Hxyz, Axyz );
1184 Real prefactor = inv_AHdis * dE_dr;
1185 f1 = prefactor * HxA;
1186 f2 = prefactor * AH;
1192 prefactor = inv_AHdis * dE_dxD;
1193 BD = prefactor * ( HDunit - xD * AHunit );
1196 BDxA = cross( BD, Axyz );
1233 prefactor = inv_AHdis * dE_dxH;
1234 BH = prefactor * ( BAunit - xH * AHunit );
1237 BHxH = cross( BH, Hxyz );
1271 bool const evaluate_deriv,
1275 hb_energy_deriv(database, hbondoptions, hbt, Dxyz, Hxyz, Axyz, Bxyz, B2xyz, energy, deriv_type, deriv );
1293 using namespace hbonds;
1310 HDunit = Dxyz - Hxyz;
1311 Real const HDdis2( HDunit.length_squared() );
1314 if ( ! numeric::is_a_finitenumber( HDdis2, 1.0, 0.0 ) ) {
1315 std::string const warning(
"NAN occurred in H-bonding calculations!" );
1316 PyAssert(
false, warning);
1317 tr.Error << warning << std::endl;
1320 bool fail_on_bad_hbond = basic::options::option[ basic::options::OptionKeys::in::file::fail_on_bad_hbond ]();
1321 if ( fail_on_bad_hbond ) {
1322 throw( utility::excn::EXCN_Msg_Exception( warning ) );
1328 if ( HDdis2 < 0.64 || HDdis2 > 1.5625 ) {
1332 tr.Debug <<
"Warning: hb_energy_deriv has H(" << Hxyz(1) <<
","
1333 << Hxyz(2)<<
"," << Hxyz(3) <<
") D(" << Dxyz(1) <<
"," << Dxyz(2)
1334 <<
"," << Dxyz(3) <<
") distance out of range " << std::sqrt( HDdis2 ) << std::endl;
1343 Real const inv_HDdis = 1.0f / std::sqrt( HDdis2 );
1344 HDunit *= inv_HDdis;
1352 hb_energy_deriv_u2(database, hbondoptions, hbt, deriv_type, Hxyz, Dxyz, HDunit, Axyz, PBxyz, BAunit, B2xyz, energy, deriv );
1369 residue.
atom( atom_id ).
xyz(),
1395 using namespace chemical;
1411 tr <<
"Unrecognized Hybridization: " << acc_hybrid << std::endl;
1414 BAunit = Axyz - PBxyz;
1430 Real weighted_energy,
1434 using namespace chemical;
1436 switch( acc_hybrid ){
1438 acc_atom_derivs[ acc_rsd.
atom_base( acc_atom ) ].f1() += weighted_energy * abase_deriv.
f1();
1439 acc_atom_derivs[ acc_rsd.
atom_base( acc_atom ) ].f2() += weighted_energy * abase_deriv.
f2();
break;
1443 acc_atom_derivs[ acc_rsd.
abase2( acc_atom ) ].f1() += weighted_energy * abase_deriv.
f1();
1444 acc_atom_derivs[ acc_rsd.
abase2( acc_atom ) ].f2() += weighted_energy * abase_deriv.
f2();
1446 acc_atom_derivs[ acc_rsd.
atom_base( acc_atom ) ].f1() += weighted_energy * abase_deriv.
f1();
1447 acc_atom_derivs[ acc_rsd.
atom_base( acc_atom ) ].f2() += weighted_energy * abase_deriv.
f2();
1452 acc_atom_derivs[ acc_rsd.
atom_base( acc_atom ) ].f1() += 0.5 * weighted_energy * abase_deriv.
f1();
1453 acc_atom_derivs[ acc_rsd.
atom_base( acc_atom ) ].f2() += 0.5 * weighted_energy * abase_deriv.
f2();
1454 acc_atom_derivs[ acc_rsd.
abase2( acc_atom ) ].f1() += 0.5 * weighted_energy * abase_deriv.
f1();
1455 acc_atom_derivs[ acc_rsd.
abase2( acc_atom ) ].f2() += 0.5 * weighted_energy * abase_deriv.
f2();
break;
1458 tr <<
"Unrecognized Hybridization: " << acc_hybrid << std::endl;
1477 Real const HDdis2( HDunit.length_squared() );
1478 Real const inv_HDdis = 1.0f / std::sqrt( HDdis2 );
1479 HDunit *= inv_HDdis;