17 #include <basic/options/option.hh>
18 #include <utility/exit.hh>
20 #include <utility/vector1.hh>
21 #include <numeric/interpolation/spline/SplineGenerator.hh>
24 #include <ObjexxFCL/FArray1D.hh>
25 #include <ObjexxFCL/FArray2D.hh>
26 #include <ObjexxFCL/FArray3D.hh>
35 #include <basic/Tracer.hh>
39 #include <basic/options/keys/score.OptionKeys.gen.hh>
47 using namespace ObjexxFCL;
49 static basic::Tracer
TR(
"core.scoring.etable");
55 using namespace basic::options;
56 using namespace basic::options::OptionKeys;
59 MembEtable::MembEtable(
61 EtableOptions
const & options,
65 Etable( atom_set_in, options, alternate_parameter_set ),
68 atom_set_ ( atom_set_in ),
69 n_atomtypes ( atom_set_in->n_atomtypes() ),
72 max_dis_ ( options.max_dis ),
73 bins_per_A2 ( options.bins_per_A2 ),
74 Wradius ( options.Wradius ),
75 lj_switch_dis2sigma ( options.lj_switch_dis2sigma ),
76 max_dis2 ( max_dis_*max_dis_ ),
77 etable_disbins ( static_cast<
int >( max_dis2 * bins_per_A2)+1),
80 lj_use_lj_deriv_slope ( true ),
81 lj_slope_intercept ( 0.0 ),
82 lj_use_hbond_radii ( true ),
84 lj_hbond_hdis ( 1.95 ),
85 lj_hbond_accOch_dis ( 2.80 ),
86 lj_hbond_accOch_hdis ( 1.75 ),
87 lj_use_water_radii ( true ),
89 lj_water_hdis ( 1.95 ),
90 lk_min_dis2sigma ( 0.89 ),
92 min_dis2 ( min_dis * min_dis ),
93 add_long_range_damping ( true ),
94 long_range_damping_length ( 0.5 ),
96 safe_max_dis2 ( max_dis2 - epsilon ),
97 hydrogen_interaction_cutoff2_( option[ score::fa_Hatr ] ?
100 nblist_dis2_cutoff_XX_ ((options.max_dis+1.5) * (options.max_dis+1.5) ),
101 nblist_dis2_cutoff_XH_ ( option[ score::fa_Hatr ] ?
102 nblist_dis2_cutoff_XX_ :
103 ((options.max_dis+0.5)/2.0+2.2) * ((options.max_dis+0.5)/2.0+2.2) ),
104 nblist_dis2_cutoff_HH_ ( option[ score::fa_Hatr ] ?
105 nblist_dis2_cutoff_XX_ :
107 max_non_hydrogen_lj_radius_( 0.0 ),
108 max_hydrogen_lj_radius_( 0.0 )
139 lj_radius_[i] = (*atom_set_in)[i].lj_radius();
142 lk_lambda_[i] = (*atom_set_in)[i].lk_lambda();
143 lk_volume_[i] = (*atom_set_in)[i].lk_volume();
151 if ( (*atom_set_in)[i].is_hydrogen() ) {
198 param_name =
"LK_DGFREE";
200 TR <<
"Using alternate parameters: " << param_name <<
" in MembEtable construction." << std::endl;
201 Size const lkfree_index( atom_set_in->extra_parameter_index( param_name ) );
202 for (
int i=1; i<=
n_atomtypes; ++i )
lk_dgfree_[i] = (*atom_set_in)[i].extra_parameter( lkfree_index );
206 param_name =
"MEMB_LK_DGFREE";
208 TR <<
"Using alternate parameters: " << param_name <<
" in MembEtable construction." << std::endl;
209 Size const mb_lkfree_index( atom_set_in->extra_parameter_index( param_name ) );
214 param_name =
"LK_DGREFCE";
216 TR <<
"Using alternate parameters: " << param_name <<
" in MembEtable construction." << std::endl;
217 Size const lkref_index( atom_set_in->extra_parameter_index( param_name ) );
223 param_name =
"MEMB_LK_DGREFCE";
225 TR <<
"Using alternate parameters: " << param_name <<
" in MembEtable construction." << std::endl;
226 Size const mb_lkref_index( atom_set_in->extra_parameter_index( param_name ) );
301 using namespace basic::options;
302 using namespace basic::options::OptionKeys;
305 Real dis2,dis,dis2_step;
307 Real solvE1,solvE2,dsolvE1,dsolvE2;
308 Real memb_solvE1,memb_solvE2,memb_dsolvE1,memb_dsolvE2;
327 Real damping_thresh_dis2;
328 int damping_disbins, normal_disbins;
331 Real dsolv1_damp, dsolv2_damp, intercept_solv1_damp, intercept_solv2_damp;
332 Real memb_dsolv1_damp, memb_dsolv2_damp, intercept_memb_solv1_damp, intercept_memb_solv2_damp;
335 TR <<
"Starting membrane specific energy table calculation" << std::endl;
374 damping_thresh_dis2 =
max_dis2 - ( dif * dif );
375 damping_disbins =
static_cast< int >( damping_thresh_dis2*
bins_per_A2 );
382 for (
int atype1 = 1, atype_end =
n_atomtypes; atype1 <= atype_end; ++atype1 ) {
383 for (
int atype2 = 1; atype2 <= atype_end; ++atype2 ) {
386 for (
int disbin = 1; disbin <= normal_disbins; ++disbin ) {
387 dis2 = ( disbin - 1 ) * dis2_step;
395 calc_etable_value(dis2,atype1,atype2,solvE1,solvE2,dsolvE1,dsolvE2,lj_sigma,lk_inv_lambda2,
396 lk_coeff, lk_min_dis2sigma_value,memb_solvE1, memb_solvE2,
397 memb_lk_coeff, memb_lk_min_dis2sigma_value, memb_dsolvE1, memb_dsolvE2);
403 solv1_(disbin,atype2,atype1) = solvE1;
404 solv2_(disbin,atype2,atype1) = solvE2;
405 dsolv2_(disbin,atype2,atype1) = dsolvE2;
406 dsolv1_(disbin,atype2,atype1) = dsolvE1;
424 dsolv1_damp = -
solv1_(normal_disbins,atype2,atype1) /
426 dsolv2_damp = -
solv2_(normal_disbins,atype2,atype1) /
429 memb_dsolv1_damp = -
memb_solv1_(normal_disbins,atype2,atype1) /
431 memb_dsolv2_damp = -
memb_solv2_(normal_disbins,atype2,atype1) /
436 intercept_solv1_damp = -dsolv1_damp*
max_dis_;
437 intercept_solv2_damp = -dsolv2_damp*
max_dis_;
439 intercept_memb_solv1_damp = -memb_dsolv1_damp*
max_dis_;
440 intercept_memb_solv2_damp = -memb_dsolv2_damp*
max_dis_;
442 for (
int disbin = normal_disbins+1; disbin <=
etable_disbins; ++disbin ) {
443 dis2 = ( disbin - 1 ) * dis2_step;
444 dis = std::sqrt(dis2);
448 solv1_(disbin,atype2,atype1) = intercept_solv1_damp + dis *dsolv1_damp;
449 solv2_(disbin,atype2,atype1) = intercept_solv2_damp + dis *dsolv2_damp;
451 memb_solv1_(disbin,atype2,atype1) = intercept_memb_solv1_damp + dis * memb_dsolv1_damp;
452 memb_solv2_(disbin,atype2,atype1) = intercept_memb_solv2_damp + dis * memb_dsolv2_damp;
456 dsolv1_(disbin,atype2,atype1) = dsolv1_damp;
457 dsolv2_(disbin,atype2,atype1) = dsolv2_damp;
505 using namespace ObjexxFCL;
508 map< string, FArray3D<Real>* > etables;
511 etables[
"solv1"] = &
solv1_; etables[
"solv2"] = &
solv2_;
517 if ( option[ score::input_etables ].user() ) {
518 string tag = option[ score::input_etables ];
519 TR <<
"INPUT ETABLES " << tag << std::endl;
520 for (map<
string,FArray3D<Real>*>::iterator i = etables.begin(); i != etables.end(); i++) {
521 string ename = i->first;
522 string fname = tag+
"."+ename+
".etable";
523 std::ifstream input( fname.c_str() );
529 if ( option[ score::output_etables ].user() ) {
530 string header = option[ score::output_etables ];
531 TR <<
"OUTPUT ETABLES " << header << std::endl;
532 for (map<
string,FArray3D<Real>*>::iterator i = etables.begin(); i != etables.end(); i++) {
533 string ename = i->first;
534 string fname = header+
"."+ename+
".etable";
535 TR <<
"output_etable: writing etable: " << ename <<
" to " << fname << std::endl;
536 ofstream out(fname.c_str());
542 TR <<
"Finished calculating membrane specific energy tables." << std::endl;
592 bool mod_hhrep =
false;
600 TR <<
"fullatom_setup: modifying h-h repulsion "
601 <<
" hhrep center " <<
c
602 <<
" hhrep height " << h
603 <<
" hhrep width " << w
604 <<
" hhrep exponent " << e
610 Real const bin = ( 4.2 * 4.2 / .05 ) + 1.0;
611 int const ibin( static_cast< int >( bin ) );
613 Real const dis = std::sqrt( ( k - 1 ) * .05f );
618 carbon_types.push_back(
atom_set_->atom_type_index(
"CH1") );
619 carbon_types.push_back(
atom_set_->atom_type_index(
"CH2") );
620 carbon_types.push_back(
atom_set_->atom_type_index(
"CH3") );
621 carbon_types.push_back(
atom_set_->atom_type_index(
"aroC") );
623 for (
int i = 1, i_end = carbon_types.size(); i <= i_end; ++i ) {
624 for (
int j = 1, j_end = carbon_types.size(); j <= j_end; ++j ) {
625 int const ii = carbon_types[i];
626 int const jj = carbon_types[j];
689 using namespace numeric::interpolation;
690 using namespace basic::options;
691 using namespace basic::options::OptionKeys;
697 FArray1D<int> bin_of_dis(100);
698 for(
int i = 1; i <= 100; ++i) {
699 float d = ((float)i)/10.0;
704 // 1) change ljatr / ljrep split so that scaling is smooth
706 TR << "smooth_etable: changing atr/rep split to bottom of energy well" << std::endl;
707 for( int at1 = 1; at1 <= n_atomtypes; ++at1 ) {
708 for( int at2 = 1; at2 <= n_atomtypes; ++at2 ) {
711 core::Real min_atr = 0.0;
713 for(int i = 1; i <= etable_disbins; ++i) {
714 if ( ljatr_(i,at1,at2) < min_atr ) {
715 min_atr = ljatr_(i,at1,at2);
719 // for dis below ljatr min, transfer ljatr to ljrep
720 if( min_atr < 0.0 ) {
721 for( int i = 1; i <= which_min; ++i ) {
722 ljrep_(i,at1,at2) += ljatr_(i,at1,at2) - min_atr;
723 ljatr_(i,at1,at2) -= ljatr_(i,at1,at2) - min_atr; // = min_atr;
724 dljrep_(i,at1,at2) += dljatr_(i,at1,at2);
725 dljatr_(i,at1,at2) -= dljatr_(i,at1,at2); // = 0;
732 using namespace numeric::interpolation::spline;
734 // 2) spline smooth ljatr/ljrep at fa_max_dis cut
736 TR << "smooth_etable: spline smoothing lj etables (maxdis = " << max_dis_ << ")" << std::endl;
737 for( int at1 = 1; at1 <= n_atomtypes; ++at1 ) {
738 for( int at2 = 1; at2 <= n_atomtypes; ++at2 ) {
740 int start = bin_of_dis( (int)((max_dis_-1.5)*10.0) );//arg_max_first(dljatr_(1,at1,at2),1,600);
742 Real lbx = dis(start);
743 Real lby = ljatr_(start,at1,at2);
744 Real lbdy = dljatr_(start,at1,at2);
745 Real ubx = dis(etable_disbins);
748 SplineGenerator gen( lbx, lby, lbdy, ubx, uby, ubdy );
750 if( option[ score::etable_lr ].user() ) {
751 Real modx = option[ score::etable_lr ]();
752 Real mody = lbx * 0.5;
753 gen.add_known_value( modx, mody );
756 InterpolatorOP interp( gen.get_interpolator() );
757 for( int i = start; i <= etable_disbins; ++i ) {
758 interp->interpolate( dis(i), ljatr_(i,at1,at2), dljatr_(i,at1,at2) );
767 using namespace numeric::interpolation::spline;
768 TR <<
"smooth_etable: spline smoothing solvation etables (max_dis = " <<
max_dis_ <<
")" << std::endl;
784 int const S1 = std::max(1,SWTCH - 30);
785 int const E1 = std::min(SWTCH + 20,406);
786 int const S2 = bin_of_dis( (
int)((
max_dis_-1.5)*10.0) );
790 Real dsolv1e1 = (
solv1_(E1+1,at1,at2)-
solv1_(E1 ,at1,at2))/(dis(E1+1)-dis(E1 ));
791 Real dsolv1s2 = (
solv1_(S2 ,at1,at2)-
solv1_(S2-1,at1,at2))/(dis(S2 )-dis(S2-1));
792 Real dsolv2e1 = (
solv2_(E1+1,at1,at2)-
solv2_(E1 ,at1,at2))/(dis(E1+1)-dis(E1 ));
793 Real dsolv2s2 = (
solv2_(S2 ,at1,at2)-
solv2_(S2-1,at1,at2))/(dis(S2 )-dis(S2-1));
800 SplineGenerator gen11( dis(S1),
solv1_(S1,at1,at2), 0.0 , dis(E1),
solv1_(E1,at1,at2), dsolv1e1 );
801 SplineGenerator gen21( dis(S1),
solv2_(S1,at1,at2), 0.0 , dis(E1),
solv2_(E1,at1,at2), dsolv2e1 );
802 SplineGenerator gen12( dis(S2),
solv1_(S2,at1,at2), dsolv1s2, dis(E2),
solv1_(E2,at1,at2), 0.0 );
803 SplineGenerator gen22( dis(S2),
solv2_(S2,at1,at2), dsolv2s2, dis(E2),
solv2_(E2,at1,at2), 0.0 );
805 SplineGenerator mgen11( dis(S1),
memb_solv1_(S1,at1,at2), 0.0 , dis(E1),
memb_solv1_(E1,at1,at2), mdsolv1e1 );
806 SplineGenerator mgen21( dis(S1),
memb_solv2_(S1,at1,at2), 0.0 , dis(E1),
memb_solv2_(E1,at1,at2), mdsolv2e1 );
807 SplineGenerator mgen12( dis(S2),
memb_solv1_(S2,at1,at2), mdsolv1s2, dis(E2),
memb_solv1_(E2,at1,at2), 0.0 );
808 SplineGenerator mgen22( dis(S2),
memb_solv2_(S2,at1,at2), mdsolv2s2, dis(E2),
memb_solv2_(E2,at1,at2), 0.0 );
810 InterpolatorOP interp11( gen11.get_interpolator() );
811 InterpolatorOP interp21( gen21.get_interpolator() );
813 InterpolatorOP minterp11( mgen11.get_interpolator() );
814 InterpolatorOP minterp21( mgen21.get_interpolator() );
816 for(
int i = S1; i <= E1; ++i ) {
818 interp11->interpolate( dis(i),
solv1_(i,at1,at2), d1 );
819 interp21->interpolate( dis(i),
solv2_(i,at1,at2), d2 );
822 minterp11->interpolate( dis(i),
memb_solv1_(i,at1,at2), d1 );
823 minterp21->interpolate( dis(i),
memb_solv2_(i,at1,at2), d2 );
828 InterpolatorOP interp12( gen12.get_interpolator() );
829 InterpolatorOP interp22( gen22.get_interpolator() );
831 InterpolatorOP minterp12( mgen12.get_interpolator() );
832 InterpolatorOP minterp22( mgen22.get_interpolator() );
834 for(
int i = S2; i <= E2; ++i ) {
836 interp12->interpolate( dis(i),
solv1_(i,at1,at2), d1 );
837 interp22->interpolate( dis(i),
solv2_(i,at1,at2), d2 );
840 minterp12->interpolate( dis(i),
memb_solv1_(i,at1,at2), d1 );
841 minterp22->interpolate( dis(i),
memb_solv2_(i,at1,at2), d2 );
875 ObjexxFCL::FArray3D<Real> & etable,
880 using namespace ObjexxFCL;
888 float evalue = etable(bin,at1,at2);
889 out << evalue <<
' ';
923 ObjexxFCL::FArray3D<Real> & etable,
929 TR <<
"input_etable: reading etable... " << label << endl;
936 in.getline(buf,100000);
938 if( !(intmp >> lblin >> numdisbin) ) {
939 TR <<
"input_etable: WARNING bad etable header " << buf << endl;
943 TR <<
"input_etable: WARNING etable types don't match! "<< endl;
945 <<
" got " << lblin <<
',' << numdisbin<< endl;
946 utility_exit_with_message(
"input_etable: WARNING etable types don't match! " );
948 TR <<
"input_etable expected etable " << label <<
" of size " <<
etable_disbins
949 <<
", got " << lblin <<
',' << numdisbin<< endl;
954 int at1,at2,count=0,scount=0;
956 while( in.getline(buf,100000) ) {
961 if( ! (intmp >> at1 >> at2 ) ) {
962 TR <<
"input_etable: error reading etable line: " << buf << endl;
964 for(
int bin = 1; bin <=numdisbin; bin++) {
965 if( !(intmp >> evalue) ) {
966 TR <<
"input_etable: not enough bins on etable line: " << buf << endl;
967 utility_exit_with_message(
"input_etable: not enough bins on etable line: " );
971 etable(bin,at1,at2) = evalue;
972 etable(bin,at2,at1) = evalue;
977 TR <<
" read " << scount <<
" of " << count <<
" lines" << endl;
1018 FArray2< Real > & lj_sigma,
1023 FArray1< Real > & lk_inv_lambda2,
1024 FArray2< Real > & lk_coeff,
1025 FArray2< Real > & memb_lk_coeff,
1026 FArray2< Real > & lk_min_dis2sigma_value,
1027 FArray2< Real > & memb_lk_min_dis2sigma_value
1040 FArray1D< Real > memb_lk_coeff_tmp(
n_atomtypes );
1041 Real thresh_dis,inv_thresh_dis2,x_thresh;
1044 Real const inv_neg2_tms_pi_sqrt_pi = { -0.089793561062583294 };
1051 lk_inv_lambda2(i) = inv_lambda * inv_lambda;
1052 lk_coeff_tmp(i) = inv_neg2_tms_pi_sqrt_pi *
lk_dgfree(i) * inv_lambda;
1053 memb_lk_coeff_tmp(i) = inv_neg2_tms_pi_sqrt_pi *
memb_lk_dgfree(i) * inv_lambda;
1057 for (
int j = i; j <= e; ++j ) {
1062 sigma = ( sigma < 1.0e-9 ? 1.0e-9 : sigma );
1109 lj_sigma(i,j) = sigma;
1110 lj_sigma(j,i) = lj_sigma(i,j);
1151 lk_coeff(i,j) = lk_coeff_tmp(i) *
lk_volume(j);
1153 lk_coeff(j,i) = lk_coeff_tmp(j) *
lk_volume(i);
1155 memb_lk_coeff(i,j) = memb_lk_coeff_tmp(i) *
lk_volume(j);
1156 memb_lk_coeff(j,i) = memb_lk_coeff_tmp(j) *
lk_volume(i);
1163 inv_thresh_dis2 = 1./( thresh_dis * thresh_dis );
1166 x_thresh = ( dis_rad * dis_rad ) * lk_inv_lambda2(i);
1167 lk_min_dis2sigma_value(i,j) = std::exp(-x_thresh) * lk_coeff(i,j) *
1169 memb_lk_min_dis2sigma_value(i,j) = std::exp(-x_thresh) * memb_lk_coeff(i,j) *
1174 x_thresh = ( dis_rad * dis_rad ) * lk_inv_lambda2(j);
1175 lk_min_dis2sigma_value(j,i) = std::exp(-x_thresh) * lk_coeff(j,i) *
1177 memb_lk_min_dis2sigma_value(j,i) = std::exp(-x_thresh) * memb_lk_coeff(j,i) *
1257 FArray2< Real > & lj_sigma,
1262 FArray1< Real > & lk_inv_lambda2,
1263 FArray2< Real > & lk_coeff,
1264 FArray2< Real > & lk_min_dis2sigma_value,
1267 FArray2< Real > & memb_lk_coeff,
1268 FArray2< Real > & memb_lk_min_dis2sigma_value,
1269 Real & memb_dsolvE1,
1281 Real inv_dis,inv_dis2;
1283 int xtra_atype1,xtra_atype2;
1305 dis = std::sqrt(dis2);
1307 inv_dis2 = inv_dis * inv_dis;
1318 xtra_atype1 = atype1;
1319 xtra_atype2 = atype2;
1323 dis2sigma = dis / lj_sigma(xtra_atype1,xtra_atype2);
1360 solvE1 = lk_min_dis2sigma_value(xtra_atype1,xtra_atype2);
1361 solvE2 = lk_min_dis2sigma_value(xtra_atype2,xtra_atype1);
1364 memb_solvE1 = memb_lk_min_dis2sigma_value(xtra_atype1,xtra_atype2);
1365 memb_solvE2 = memb_lk_min_dis2sigma_value(xtra_atype2,xtra_atype1);
1366 memb_dsolvE1 = memb_dsolvE2 = 0.0;
1372 x1 = ( dis_rad * dis_rad ) * lk_inv_lambda2(atype1);
1375 x2 = ( dis_rad * dis_rad ) * lk_inv_lambda2(atype2);
1377 solvE1 = std::exp(-x1) * lk_coeff(atype1,atype2) * inv_dis2;
1378 solvE2 = std::exp(-x2) * lk_coeff(atype2,atype1) * inv_dis2;
1379 memb_solvE1 = std::exp(-x1) * memb_lk_coeff(atype1,atype2) * inv_dis2;
1380 memb_solvE2 = std::exp(-x2) * memb_lk_coeff(atype2,atype1) * inv_dis2;
1387 dsolvE1 = -2.0 * solvE1 *
1388 (((dis-
lj_radius(atype1))*lk_inv_lambda2(atype1))+inv_dis);
1390 dsolvE2 = -2.0 * solvE2 *
1391 (((dis-
lj_radius(atype2))*lk_inv_lambda2(atype2))+inv_dis);
1395 memb_dsolvE1 = -2.0 * memb_solvE1 *
1396 (((dis-
lj_radius(atype1))*lk_inv_lambda2(atype1))+inv_dis);
1397 memb_dsolvE2 = -2.0 * memb_solvE2 *
1398 (((dis-
lj_radius(atype2))*lk_inv_lambda2(atype2))+inv_dis);