Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Etable.cc
Go to the documentation of this file.
1 // -*- mode:c++;tab-width:2;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t -*-
2 // vi: set ts=2 noet:
3 //
4 // (c) Copyright Rosetta Commons Member Institutions.
5 // (c) This file is part of the Rosetta software suite and is made available under license.
6 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
7 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
8 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
9 //////////////////////////////////////////////////////////////////////
10 /// @begin Etable.cc
11 ///
12 /// @brief
13 /// A class for generating the table for fa_atr/rep and fa_sol
14 ///
15 /// @detailed
16 /// This class is called upon by the ScoringManager. Since actual calculating of the LJ potential
17 /// is time consuming if done multiple times, this class precomputes and discritizes the potential
18 /// (meaning that the potential is broken down into bins). Once the bins have been created, it will
19 /// smooth out the bins, for better interpolation.
20 ///
21 ///
22 /// @authors
23 /// I dont know?
24 /// Steven Combs - comments and skipping of virtual atoms
25 ///
26 /// @last_modified December 6 2010
27 /////////////////////////////////////////////////////////////////////////
28 
29 
30 
31 
32 
33 // Unit Headers
36 
37 // Package headers
41 
42 #include <basic/options/option.hh>
43 #include <utility/exit.hh>
44 
45 #include <utility/vector1.hh>
46 #include <numeric/interpolation/spline/SplineGenerator.hh>
47 #include <numeric/interpolation/spline/SimpleInterpolator.hh>
48 
49 // ObjexxFCL Headers
50 #include <ObjexxFCL/FArray1D.hh>
51 #include <ObjexxFCL/FArray2D.hh>
52 #include <ObjexxFCL/FArray3D.hh>
53 
54 // Utility Headers
55 
56 // C++ Headers
57 #include <iostream>
58 #include <fstream>
59 
60 #include <basic/Tracer.hh>
61 
62 // option key includes
63 
64 #include <basic/options/keys/score.OptionKeys.gen.hh>
65 #include <basic/options/keys/corrections.OptionKeys.gen.hh>
67 
68 
69 
70 using basic::T;
71 using basic::Error;
72 using basic::Warning;
73 
74 using namespace ObjexxFCL;
75 
76 static basic::Tracer TR("core.scoring.etable");
77 
78 namespace core {
79 namespace scoring {
80 namespace etable {
81 
82 /// @details Auto-generated virtual destructor
83 Etable::~Etable() {}
84 
85 using namespace basic::options;
86 using namespace basic::options::OptionKeys;
87 
88 /// constructor
89 Etable::Etable(
90  chemical::AtomTypeSetCAP atom_set_in, // like etable namespace
91  EtableOptions const & options,
92  std::string const alternate_parameter_set // = ""
93 ):
94  // from atop_props_in:
95  atom_set_ ( atom_set_in ),
96  n_atomtypes_ ( atom_set_in->n_atomtypes() ),
97 
98  // from options
99  max_dis_ ( options.max_dis ),
100  bins_per_A2 ( options.bins_per_A2 ),
101  Wradius ( options.Wradius ), // global mod to radii
102  lj_switch_dis2sigma ( options.lj_switch_dis2sigma ),
103  max_dis2 ( max_dis_*max_dis_ ),
104  etable_disbins ( static_cast< int >( max_dis2 * bins_per_A2)+1),
105 
106  // hard-coded for now
107  lj_use_lj_deriv_slope ( true ),
108  lj_slope_intercept ( 0.0 ),
109  lj_use_hbond_radii ( true ),
110  lj_hbond_OH_donor_dis ( options.lj_hbond_OH_donor_dis ),
111  lj_hbond_dis ( 3.0 ),
112  lj_hbond_hdis ( options.lj_hbond_hdis ),
113  lj_hbond_accOch_dis ( 2.80 ), // unused
114  lj_hbond_accOch_hdis ( 1.75 ), // unused
115  lj_use_water_radii ( true ),
116  lj_water_dis ( 3.0 ),
117  lj_water_hdis ( 1.95 ),
118  lk_min_dis2sigma ( 0.89 ),
119  min_dis ( 0.01 ),
120  min_dis2 ( min_dis * min_dis ),
121  add_long_range_damping ( true ),
122  long_range_damping_length ( 0.5 ),
123  epsilon ( 0.0001 ),
124  safe_max_dis2 ( max_dis2 - epsilon ),
125  hydrogen_interaction_cutoff2_( option[ score::fa_Hatr ] ?
126  std::pow( max_dis_ + 2*chemical::MAX_CHEMICAL_BOND_TO_HYDROGEN_LENGTH, 2 ) :
127  std::pow(5.0,2) ),
128  max_non_hydrogen_lj_radius_( 0.0 ),
129  max_hydrogen_lj_radius_( 0.0 )
130 
131 {
132 
134  initialize_from_input_atomset( atom_set_in );
136  read_alternate_parameter_set( atom_set_in, alternate_parameter_set );
140 }
141 
142 void
144 {
145  // size the arrays
146  if ( ! basic::options::option[ basic::options::OptionKeys::score::analytic_etable_evaluation ] )
147  {
156  }
157 
158  lj_radius_.resize( n_atomtypes_, 0.0 );
159  lj_wdepth_.resize( n_atomtypes_, 0.0 );
160  lk_dgfree_.resize( n_atomtypes_, 0.0 );
161  lk_lambda_.resize( n_atomtypes_, 0.0 );
162  lk_volume_.resize( n_atomtypes_, 0.0 );
163 
164  lj_sigma_.dimension( n_atomtypes_ + 1, n_atomtypes_ + 1 );
165  lj_r6_coeff_.dimension( n_atomtypes_ + 1, n_atomtypes_ + 1 );
166  lj_r12_coeff_.dimension( n_atomtypes_ + 1, n_atomtypes_ + 1 );
167  lj_switch_intercept_.dimension( n_atomtypes_ + 1, n_atomtypes_ + 1 );
168  lj_switch_slope_.dimension( n_atomtypes_ + 1, n_atomtypes_ + 1 );
169  lk_inv_lambda2_.dimension( n_atomtypes_ );
170  lk_coeff_.dimension( n_atomtypes_, n_atomtypes_ );
171  lk_min_dis2sigma_value_.dimension( n_atomtypes_ + 1, n_atomtypes_ + 1 );
172 
173  //lj_minima.dimension( n_atomtypes_, n_atomtypes_ );
174  //lj_vals_at_minima.dimension( n_atomtypes_, n_atomtypes_ );
175 
176  //ljatr_spline_xlo_xhi.dimension( n_atomtypes_, n_atomtypes_ );
177  //ljatr_spline_parameters.dimension( n_atomtypes_, n_atomtypes_ );
178 
179  //ljrep_extra_repulsion.dimension( n_atomtypes_, n_atomtypes_ );
180  /// Set up the ExtraQuadraticRepulsion parameters for everything: by default, add in no extra repulsion
181  //ExtraQuadraticRepulsion exrep;
182  //exrep.xlo = 0; exrep.xhi = 0; exrep.slope = 0; exrep.extrapolated_slope = 0; exrep.ylo = 0;
183  //ljrep_extra_repulsion = exrep;
184 
185  //fasol_spline_close_start_end.dimension( n_atomtypes_, n_atomtypes_ );
186  //fasol_spline_close.dimension( n_atomtypes_, n_atomtypes_ );
187  //fasol_spline_far.dimension( n_atomtypes_, n_atomtypes_ );
188 
189  //ljrep_from_negcrossing.dimension( n_atomtypes_, n_atomtypes_ );
190  //ljrep_from_negcrossing = false;
191 
192  //ljatr_final_weight.dimension( n_atomtypes_, n_atomtypes_); ljatr_final_weight = 1.0;
193  //fasol_final_weight.dimension( n_atomtypes_, n_atomtypes_); fasol_final_weight = 1.0;
194 
195  Size n_unique_pair_types = n_atomtypes_ * n_atomtypes_ - ( n_atomtypes_ * (n_atomtypes_ - 1 ) / 2 );
196  analytic_parameters.resize( n_unique_pair_types );
197 
198 }
199 
200 void
202  chemical::AtomTypeSetCAP atom_set_in
203 )
204 {
205  for ( int i=1; i<= n_atomtypes_; ++i ) {
206  lj_radius_[i] = (*atom_set_in)[i].lj_radius();
207  lj_wdepth_[i] = (*atom_set_in)[i].lj_wdepth();
208  lk_dgfree_[i] = (*atom_set_in)[i].lk_dgfree();
209  lk_lambda_[i] = (*atom_set_in)[i].lk_lambda();
210  lk_volume_[i] = (*atom_set_in)[i].lk_volume();
211  if ( (*atom_set_in)[i].is_hydrogen() ) {
213  } else {
215  }
216  }
217 
218  /// APL -- hydrophobic desolvation only; turn off hydrophilic desolvation penalty
219  if ( option[ score::no_lk_polar_desolvation ] ) {
220  for ( int i=1; i<= n_atomtypes_; ++i ) {
221  if ( (*atom_set_)[i].is_acceptor() || (*atom_set_)[i].is_donor() ) {
222  lk_dgfree_[i] = 0.0;
223  }
224  }
225  }
226 
227 }
228 
229 void
231  EtableOptions const & options
232 )
233 {
235  max_hydrogen_hydrogen_cutoff_ = option[ score::fa_Hatr ] ? max_dis_ : 2 * max_hydrogen_lj_radius_;
236  nblist_dis2_cutoff_XX_ = (options.max_dis+1.5) * (options.max_dis+1.5);
238  nblist_dis2_cutoff_HH_ = (max_hydrogen_lj_radius_+0.5) * (max_hydrogen_lj_radius_+0.5);
239 
240  //std::cout << "Etable setup: " << max_non_hydrogen_lj_radius_ << " "
241  //<< max_hydrogen_lj_radius_ << " " << max_heavy_hydrogen_cutoff_ << " "
242  //<< max_hydrogen_hydrogen_cutoff_ << std::endl;
243 
244 }
245 
246 void
248  chemical::AtomTypeSetCAP atom_set_in,
249  std::string const alternate_parameter_set
250 )
251 {
252  if ( alternate_parameter_set.size() ) {
253  /// uses alternate paramers
254  std::string param_name;
255 
256  param_name = "LJ_RADIUS_"+alternate_parameter_set;
257  if ( atom_set_in->has_extra_parameter( param_name ) ) {
258  TR << "Using alternate parameters: " << param_name << " in Etable construction." << std::endl;
259  Size const index( atom_set_in->extra_parameter_index( param_name ) );
260  for ( int i=1; i<= n_atomtypes_; ++i ) lj_radius_[i] = (*atom_set_in)[i].extra_parameter( index );
261  }
262 
263  param_name = "LJ_WDEPTH_"+alternate_parameter_set;
264  if ( atom_set_in->has_extra_parameter( param_name ) ) {
265  TR << "Using alternate parameters: " << param_name << " in Etable construction."<<std::endl;
266  Size const index( atom_set_in->extra_parameter_index( param_name ) );
267  for ( int i=1; i<= n_atomtypes_; ++i ) lj_wdepth_[i] = (*atom_set_in)[i].extra_parameter( index );
268  }
269 
270  param_name = "LK_DGFREE_"+alternate_parameter_set;
271  if ( atom_set_in->has_extra_parameter( param_name ) ) {
272  TR << "Using alternate parameters: " << param_name << " in Etable construction."<<std::endl;
273  Size const index( atom_set_in->extra_parameter_index( param_name ) );
274  for ( int i=1; i<= n_atomtypes_; ++i ) lk_dgfree_[i] = (*atom_set_in)[i].extra_parameter( index );
275  }
276 
277  param_name = "LK_LAMBDA_"+alternate_parameter_set;
278  if ( atom_set_in->has_extra_parameter( param_name ) ) {
279  TR << "Using alternate parameters: " << param_name << " in Etable construction." << std::endl;
280  Size const index( atom_set_in->extra_parameter_index( param_name ) );
281  for ( int i=1; i<= n_atomtypes_; ++i ) lk_lambda_[i] = (*atom_set_in)[i].extra_parameter( index );
282  }
283 
284  param_name = "LK_VOLUME_"+alternate_parameter_set;
285  if ( atom_set_in->has_extra_parameter( param_name ) ) {
286  TR << "Using alternate parameters: " << param_name << " in Etable construction." << std::endl;
287  Size const index( atom_set_in->extra_parameter_index( param_name ) );
288  for ( int i=1; i<= n_atomtypes_; ++i ) lk_volume_[i] = (*atom_set_in)[i].extra_parameter( index );
289  }
290  }
291 }
292 
293 void
295 {
296 
297  Real const MAX_H_HEAVY_DISTANCE = 1.35; // FIX THIS SULFUR to hydrogen bond length.
298 
299  Real max_lj_rep_for_h = std::max(
300  2 * max_hydrogen_lj_radius_ + 2 * MAX_H_HEAVY_DISTANCE,
301  max_hydrogen_lj_radius_ + MAX_H_HEAVY_DISTANCE + max_non_hydrogen_lj_radius_ );
302 
303 
304  hydrogen_interaction_cutoff2_ = basic::options::option[ score::fa_Hatr ] ?
305  std::pow( 2 * MAX_H_HEAVY_DISTANCE + max_dis_, 2 ) : max_lj_rep_for_h * max_lj_rep_for_h;
306 
307 }
308 
309 void
311 {
312  carbon_types.push_back( atom_set_->atom_type_index("CH1") );
313  carbon_types.push_back( atom_set_->atom_type_index("CH2") );
314  carbon_types.push_back( atom_set_->atom_type_index("CH3") );
315  carbon_types.push_back( atom_set_->atom_type_index("aroC") );
316 }
317 
318 ////////////////////////////////////////////////////////////////////////////////
319 /// @begin Etable::make_pairenergy_table
320 ///
321 /// @brief calculate fast lookup arrays for vdw and solvation energy
322 ///
323 /// @detailed
324 ///
325 /// Several energies are precomputed when fullatom mode is initialized and
326 /// stored in lookup tables to speed fullatom calculation. Currently
327 /// pre-computed values are the Lennard-Jones van der Waals approximation
328 /// (lj) and the Lazaridis-Karplus implicit solvation function (lk). For
329 /// each of these energies the derivative w.r.t. atom pair separation distance is
330 /// calculated and stored as well. Note that the lj energy is artificially
331 /// divided into atractive and repulsive components.
332 ///
333 /// @global_read
334 ///
335 /// pdbstatistics_pack.h: several threshold distances
336 /// energy.h: just about everything should be used in the tree of
337 /// etable functions
338 ///
339 /// @global_write
340 ///
341 /// the etable: ljatr,dljatr,ljrep,dljrep,solvE
342 ///
343 /// @remarks
344 ///
345 /// @references
346 ///
347 /// @authors ctsa 10-2003
348 ///
349 /// @last_modified
350 /////////////////////////////////////////////////////////////////////////////////
351 void
353 {
354  using namespace basic::options;
355  using namespace basic::options::OptionKeys;
356 
357  // locals
358 
359  ObjexxFCL::FArray1D< Real > ljatr( etable_disbins );
360  ObjexxFCL::FArray1D< Real > dljatr( etable_disbins);
361  ObjexxFCL::FArray1D< Real > ljrep( etable_disbins );
362  ObjexxFCL::FArray1D< Real > dljrep( etable_disbins );
363  ObjexxFCL::FArray1D< Real > fasol1( etable_disbins );
364  ObjexxFCL::FArray1D< Real > fasol2( etable_disbins );
365  ObjexxFCL::FArray1D< Real > dfasol( etable_disbins );
366  ObjexxFCL::FArray1D< Real > dfasol1( etable_disbins );
367 
368  /// The index defining the range [1..normal_disbins] for which the
369  /// energy function is calculated analytically.
370  int const normal_disbins = calculate_normal_disbins();
371 
372  // etable parameters
373  TR << "Starting energy table calculation" << std::endl;
374 
375  //
376 // std::TR << "Energy table parameter set: " << etable_label << ' ' <<
377 // etable_revision.substr( 1, etable_revision.length() - 3 ) << ' ' <<
378 // etable_date.substr( 1, etable_date.length() - 3 ) << std::endl;
379 
380  // ctsa - values precomputed from etable parameters:
381  // these were all originally constants but need
382  // to be calculated here b/c the switch value:
383  // lj_switch_dis2sigma
384  // is set at runtime
386 
387  // ctsa - value of the lennard-jones potential at the linear
388  // switch point divided by the wdepth (note that this
389  // coefficient is independent of atomtype)
390  lj_switch_value2wdepth = std::pow( lj_switch_sigma2dis, 12 ) -
391  2.0 * std::pow( lj_switch_sigma2dis, 6 );
392 
393  // ctsa - slope of the lennard-jones potential at the linear
394  // switch point times sigma divided by wdepth (note that this
395  // coefficient is independent of atomtype)
396  lj_switch_slope_sigma2wdepth = -12.0 * (
397  std::pow( lj_switch_sigma2dis, 13 ) -
398  std::pow( lj_switch_sigma2dis, 7 ) );
399 
400  // initialize non-distance dependent coefficients
404 
405  // calc distance**2 step per bin
406  Real const dis2_step = 1.0 / bins_per_A2;
407 
408 
409  int const slim( basic::options::option[ basic::options::OptionKeys::score::analytic_etable_evaluation ] );
410 
411  // ctsa - step through distance**2 bins and calculate potential
412  for ( int atype1 = 1, atype_end = n_atomtypes_; atype1 <= atype_end; ++atype1 ) {
413  //check to make sure that atype1 is not virtual. This is important later
414  bool atype1_virtual(atom_type(atype1).is_virtual());
415  for ( int atype2 = slim ? atype1 : 1 ; atype2 <= atype_end; ++atype2 ) {
416  bool atype2_virtual(atom_type(atype2).is_virtual());
417 
418  // ctsa - normal bins have their lj and lk values
419  // calculated analytically
420  for ( int disbin = 1; disbin <= normal_disbins; ++disbin ) {
421  Real const dis2 = ( disbin - 1 ) * dis2_step;
422  if( atype1_virtual || atype2_virtual ) {
423  ljatr( disbin) = 0;
424  dljatr( disbin) = 0;
425  ljrep( disbin) = 0;
426  dljrep( disbin) = 0;
427  fasol1( disbin) = 0;
428  fasol2( disbin) = 0;
429  dfasol( disbin) = 0;
430  dfasol1(disbin) = 0;
431  } else{
432  Real atrE,d_atrE,repE,d_repE,solvE1,solvE2,dsolvE1,dsolvE2;
433  calc_etable_value(dis2,atype1,atype2,atrE,d_atrE,repE,d_repE,solvE1,
434  solvE2,dsolvE1,dsolvE2,lj_sigma_, lj_r6_coeff_,lj_r12_coeff_,
437 
438  ljatr( disbin) = atrE;
439  dljatr( disbin) = d_atrE;
440  ljrep( disbin) = repE;
441  dljrep( disbin) = d_repE;
442  fasol1( disbin) = solvE1;
443  fasol2( disbin) = solvE2;
444  dfasol( disbin) = dsolvE1 + dsolvE2;
445  dfasol1(disbin) = dsolvE1;
446  }
447  }
448  // save these parameters for the analytic evaluation of the etable energy
449  if ( atype1 <= atype2 ) {
450  EtableParamsOnePair & p = analytic_params_for_pair( atype1, atype2 );
451  p.maxd2 = safe_max_dis2;
452  p.ljrep_linear_ramp_d2_cutoff = std::pow( lj_switch_dis2sigma * lj_sigma_( atype1, atype2 ), 2); // ie dis / lj_sigma < lj_switch_d2sigma
453  p.lj_r6_coeff = lj_r6_coeff_( atype1, atype2 );
454  p.lj_r12_coeff = lj_r12_coeff_( atype1, atype2 );
455  p.lj_switch_intercept = lj_switch_intercept_( atype1, atype2 );
456  p.lj_switch_slope = lj_switch_slope_( atype1, atype2 );
457  p.lk_coeff1 = lk_coeff_( atype1, atype2 );
458  p.lk_coeff2 = lk_coeff_( atype2, atype1 );
459  p.lk_min_dis2sigma_value = lk_min_dis2sigma_value_( atype2, atype1 );
460  }
461 
462  if ( add_long_range_damping ) {
463  damp_long_range( normal_disbins,
464  ljatr, dljatr, ljrep, dljrep,
465  fasol1, fasol2, dfasol, dfasol1 );
466  }
467 
468  // ctsa - set last bin of all values to zero
469  ljatr( etable_disbins) = 0.0;
470  ljrep( etable_disbins) = 0.0;
471  fasol1(etable_disbins) = 0.0;
472  fasol2(etable_disbins) = 0.0;
473 
474  // throwing this all into one function
476  atype1,atype2,
477  ljatr, dljatr, ljrep, dljrep,
478  fasol1, fasol2, dfasol, dfasol1 );
479 
480  if( !option[ score::no_smooth_etables ] ) {
482  atype1, atype2,
483  ljatr, dljatr, ljrep, dljrep,
484  fasol1, fasol2, dfasol, dfasol1 );
485  }
486 
487  if ( !option[ score::fa_Hatr ]) {
489  atype1, atype2,
490  ljrep, ljatr, dljatr,
491  fasol1, fasol2, dfasol, dfasol1 );
492  }
493 
494  if ( ! slim ) {
496  atype1, atype2,
497  ljatr, dljatr, ljrep, dljrep,
498  fasol1, fasol2, dfasol, dfasol1 );
499  }
500  }
501  }
502 
503 
504  ////////////////////////////////////////////////////////
505  // etable I/O stuff
506  ////////////////////////////////////////////////////////
507  using namespace std;
508  using namespace ObjexxFCL;
509 
510  // just for convenience in input/output_etables
511  map< string, FArray3D<Real>* > etables;
512  etables[ "ljatr"] = & ljatr_; etables[ "ljrep"] = & ljrep_;
513  etables["dljatr"] = & dljatr_; etables["dljrep"] = & dljrep_;
514  etables[ "solv1"] = & solv1_; etables[ "solv2"] = & solv2_;
515  etables["dsolv"] = & dsolv_; etables["dsolv1"] = & dsolv1_;
516 
517 
518  if ( option[ score::input_etables ].user() ) {
519  string tag = option[ score::input_etables ];
520  TR << "INPUT ETABLES " << tag << std::endl;
521  for (map<string,FArray3D<Real>*>::iterator i = etables.begin(); i != etables.end(); i++) {
522  string ename = i->first;
523  string fname = tag+"."+ename+".etable";
524  std::ifstream input( fname.c_str() ); // TODO sheffler: figure out how to do this the right way
525  input_etable(*(i->second),ename,input);
526  input.close();
527  }
528  }
529 
530  if ( option[ score::output_etables ].user() ) {
531  string header = option[ score::output_etables ];
532  TR << "OUTPUT ETABLES " << header << std::endl;
533  for (map<string,FArray3D<Real>*>::iterator i = etables.begin(); i != etables.end(); i++) {
534  string ename = i->first;
535  string fname = header+"."+ename+".etable";
536  TR << "output_etable: writing etable: " << ename << " to " << fname << std::endl;
537  ofstream out(fname.c_str());
538  output_etable(*(i->second),ename,out);
539  out.close();
540  }
541  }
542 
543  TR << "Finished calculating energy tables." << std::endl;
544 }
545 
546 int
548 {
549  // parameters to calculate the damping at max_dis range
550  Real damping_thresh_dis2;
551  int damping_disbins, normal_disbins;
552 
553  // get the number of damping disbins
554  if ( add_long_range_damping ) {
556  damping_thresh_dis2 = max_dis2 - ( dif * dif );
557  damping_disbins = static_cast< int >( damping_thresh_dis2*bins_per_A2 );
558  normal_disbins = etable_disbins-damping_disbins;
559  } else {
560  normal_disbins = etable_disbins;
561  }
562  return normal_disbins;
563 }
564 
565 void
567  int const normal_disbins,
568  ObjexxFCL::FArray1A< Real > ljatr,
569  ObjexxFCL::FArray1A< Real > dljatr,
570  ObjexxFCL::FArray1A< Real > ljrep,
571  ObjexxFCL::FArray1A< Real > dljrep,
572  ObjexxFCL::FArray1A< Real > fasol1,
573  ObjexxFCL::FArray1A< Real > fasol2,
574  ObjexxFCL::FArray1A< Real > dfasol,
575  ObjexxFCL::FArray1A< Real > dfasol1
576 )
577 {
578  ljatr.dimension( etable_disbins );
579  dljatr.dimension( etable_disbins );
580  ljrep.dimension( etable_disbins );
581  dljrep.dimension( etable_disbins );
582  fasol1.dimension( etable_disbins );
583  fasol2.dimension( etable_disbins );
584  dfasol.dimension( etable_disbins );
585  dfasol1.dimension( etable_disbins );
586 
587  // ctsa - remaining bins damp to 0. on a linear path
588  Real const dljatr_damp = -ljatr( normal_disbins) / long_range_damping_length;
589  Real const dljrep_damp = -ljrep( normal_disbins) / long_range_damping_length;
590  Real const dsolv1_damp = -fasol1(normal_disbins) / long_range_damping_length;
591  Real const dsolv2_damp = -fasol2(normal_disbins) / long_range_damping_length;
592 
593  Real const intercept_ljatr_damp = -dljatr_damp*max_dis_;
594  Real const intercept_ljrep_damp = -dljrep_damp*max_dis_;
595  Real const intercept_solv1_damp = -dsolv1_damp*max_dis_;
596  Real const intercept_solv2_damp = -dsolv2_damp*max_dis_;
597 
598  Real const dis2_step = 1.0 / bins_per_A2;
599 
600  for ( int disbin = normal_disbins+1; disbin <= etable_disbins; ++disbin ) {
601  Real const dis2 = ( disbin - 1 ) * dis2_step;
602  Real const dis = std::sqrt(dis2);
603 
604  ljatr( disbin) = intercept_ljatr_damp + dis *dljatr_damp;
605  ljrep( disbin) = intercept_ljrep_damp + dis *dljrep_damp;
606  fasol1(disbin) = intercept_solv1_damp + dis *dsolv1_damp;
607  fasol2(disbin) = intercept_solv2_damp + dis *dsolv2_damp;
608 
609  dljatr( disbin) = dljatr_damp;
610  dljrep( disbin) = dljrep_damp;
611  dfasol( disbin) = dsolv1_damp + dsolv2_damp;
612  dfasol1(disbin) = dsolv1_damp;
613  }
614 
615 }
616 
617 void
619  Size atype1,
620  Size atype2,
621  ObjexxFCL::FArray1A< Real > ljatr,
622  ObjexxFCL::FArray1A< Real > dljatr,
623  ObjexxFCL::FArray1A< Real > ljrep,
624  ObjexxFCL::FArray1A< Real > dljrep,
625  ObjexxFCL::FArray1A< Real > fasol1,
626  ObjexxFCL::FArray1A< Real > fasol2,
627  ObjexxFCL::FArray1A< Real > dfasol,
628  ObjexxFCL::FArray1A< Real > dfasol1
629 )
630 {
631  assert( ljatr_.size() != 0 );
632 
633  ljatr.dimension( etable_disbins );
634  dljatr.dimension( etable_disbins );
635  ljrep.dimension( etable_disbins );
636  dljrep.dimension( etable_disbins );
637  fasol1.dimension( etable_disbins );
638  fasol2.dimension( etable_disbins );
639  dfasol.dimension( etable_disbins );
640  dfasol1.dimension( etable_disbins );
641 
642  /// Take slices of the large arrays
643  ObjexxFCL::FArray1A< Real > ljatr_full( ljatr_( 1, atype2, atype1 ) );
644  ObjexxFCL::FArray1A< Real > dljatr_full( dljatr_( 1, atype2, atype1 ) );
645  ObjexxFCL::FArray1A< Real > ljrep_full( ljrep_( 1, atype2, atype1 ) );
646  ObjexxFCL::FArray1A< Real > dljrep_full( dljrep_( 1, atype2, atype1 ) );
647  ObjexxFCL::FArray1A< Real > fasol1_full( solv1_( 1, atype2, atype1 ) );
648  ObjexxFCL::FArray1A< Real > fasol2_full( solv2_( 1, atype2, atype1 ) );
649  ObjexxFCL::FArray1A< Real > dfasol_full( dsolv_( 1, atype2, atype1 ) );
650  ObjexxFCL::FArray1A< Real > dfasol1_full( dsolv1_( 1, atype2, atype1 ) );
651 
652  ljatr_full.dimension( etable_disbins );
653  dljatr_full.dimension( etable_disbins );
654  ljrep_full.dimension( etable_disbins );
655  dljrep_full.dimension( etable_disbins );
656  fasol1_full.dimension( etable_disbins );
657  fasol2_full.dimension( etable_disbins );
658  dfasol_full.dimension( etable_disbins );
659  dfasol1_full.dimension( etable_disbins );
660 
661  /// Slice assignment
662  ljatr_full = ljatr;
663  dljatr_full = dljatr;
664  ljrep_full = ljrep;
665  dljrep_full = dljrep;
666  fasol1_full = fasol1;
667  fasol2_full = fasol2;
668  dfasol_full = dfasol;
669  dfasol1_full = dfasol1;
670 
671 
672 }
673 
674 
675 ////////////////////////////////////////////////////////////////////////////////
676 /// @begin modify_pot
677 ///
678 /// @brief modify Etable to better treat 0-0, C-C, and H-H interactions
679 ///
680 /// @detailed
681 ///$$$ the Etables are modified in three ways:
682 ///$$$ (1) the LK solvation energy is set to a constant below 4.2A to avoid shifting the position
683 ///$$$ of the minimum on the LJatr potential. in refined decoys the peak in the C C pair
684 ///$$$ distribution function shifts to around 3.8 A from ~4.0A in native structures; the LJatr
685 ///$$$ potential has a minimum at 4.0A but this shifts towards smaller values because of the LK
686 ///$$$ solvation term, which became increasingly favorable at shorter distances
687 ///$$$ (2) the backbone carbonyl oxygen-carbonyl oxygen LJrep term has been modified to become
688 ///$$$ moderately repulsive at distances less than 3.6A. this is to counteract the favorable
689 ///$$$ LJatr between the atoms (which have radii of ~1.4A and so a minimum at ~2.8A; very few
690 ///$$$ counts are observed in the pdb until around 3.2A) which leads to a significant shift in the
691 ///$$$ O O pair distribution function towards smaller values in refined decoys. the repulsion is
692 ///$$$ a temporary proxy for the lack of explicit electrostatic repulsion in the current force
693 ///$$$ field.
694 ///$$$ (3) a third soft repulsion between non polar hydrogens that was also based on comparison of
695 ///$$$ refined decoy to native pdf's is currently commented out as the effects on packing have not
696 ///$$$ been tested. it was observed that the protons tend to pile up at just beyond the point
697 ///$$$ where the repulsion becomes strong, perhaps due to a general tendency to overcontraction
698 ///$$$ because of long range LJatr interactions not compensated by interactions with solvent
699 ///$$$ (which are of course missing)
700 ///
701 /// Comments from DB:
702 ///db the following function call modifies the potential in three ways:
703 ///db (1) the solvation energy for nonpolar atoms is held constant below
704 ///db 4.2A to avoid shifting the minimum in the LJ potential.
705 ///db (2) a short range repulsion is added between backbone oxygens which are
706 ///db otherwise brought too close together by the LJatr.
707 ///db (3) the range of the repulsive interaction between non polar hydrogens is
708 ///db increased slightly. (this is currently commented out because the effects
709 ///db on design have not been tested)
710 //db all three modifications are based on inspection of the atom pair distributions
711 //db after extensive refinement.
712 
713 ///
714 /// @global_read
715 /// pdbstatistics_pack.h: ljatr,dljatr,ljrep, dljrep, solv1,solv2,dsolv
716 ///
717 /// @global_write
718 /// pdbstatistics_pack.h: ljatr,dljatr,ljrep, dljrep, solv1,solv2,dsolv
719 ///
720 /// @remarks
721 ///
722 /// @references
723 ///
724 /// @authors ctsa 10-2003
725 ///
726 /// @last_modified
727 void
729  Size const atype1,
730  Size const atype2,
731  ObjexxFCL::FArray1A< Real > ljatr,
732  ObjexxFCL::FArray1A< Real > dljatr,
733  ObjexxFCL::FArray1A< Real > ljrep,
734  ObjexxFCL::FArray1A< Real > dljrep,
735  ObjexxFCL::FArray1A< Real > fasol1,
736  ObjexxFCL::FArray1A< Real > fasol2,
737  ObjexxFCL::FArray1A< Real > dfasol,
738  ObjexxFCL::FArray1A< Real > dfasol1
739 )
740 {
741 
742  ljatr.dimension( etable_disbins );
743  dljatr.dimension( etable_disbins );
744  ljrep.dimension( etable_disbins );
745  dljrep.dimension( etable_disbins );
746  fasol1.dimension( etable_disbins );
747  fasol2.dimension( etable_disbins );
748  dfasol.dimension( etable_disbins );
749  dfasol1.dimension( etable_disbins );
750 
751  using namespace std;
752 
753  bool mod_hhrep = false; //truefalseoption("mod_hhrep");
754  Real const h = 0.0;// fullatom_setup_ns::mod_hhrep_height;
755  Real const c = 0.0;// fullatom_setup_ns::mod_hhrep_center;
756  Real const w = 0.0;// fullatom_setup_ns::mod_hhrep_width;
757  Real const e = 0.0;// fullatom_setup_ns::mod_hhrep_exponent;
758 
759 
760  if(mod_hhrep) {
761  TR << "fullatom_setup: modifying h-h repulsion "
762  << " hhrep center " << c
763  << " hhrep height " << h
764  << " hhrep width " << w
765  << " hhrep exponent " << e
766  << std::endl;
767  }
768 
769  {
770 
771  Size const OCbb_idx = atom_set_->atom_type_index("OCbb");
772  if ( atype1 == OCbb_idx && atype2 == OCbb_idx ) {
773  ExtraQuadraticRepulsion OCbb_OCbb_exrep;
774  OCbb_OCbb_exrep.xlo = 2.1; OCbb_OCbb_exrep.xhi = 3.6; OCbb_OCbb_exrep.slope = 2;
775  //OCbb_OCbb_exrep.extrapolated_slope = 0; OCbb_OCbb_exrep.ylo = 4.5; // 2*(1.5)^2;
776  OCbb_OCbb_exrep.extrapolated_slope = -6; /* d/dx 2*( 3.6 - x )^2 at x=2.1 ==> -2*2*1.5 */ OCbb_OCbb_exrep.ylo = 4.5; // 2*(1.5)^2;
777  //ljrep_extra_repulsion( OCbb_idx, OCbb_idx ) = OCbb_OCbb_exrep;
778  EtableParamsOnePair & p = analytic_params_for_pair( atype1, atype2 );
779  p.ljrep_extra_repulsion = OCbb_OCbb_exrep;
780  }
781 
782 
783  Real const bin = ( 4.2 * 4.2 / .05 ) + 1.0; //SGM Off-by-1 bug fix: Add + 1.0: Index 1 is at distance^2==0
784  int const ibin( static_cast< int >( bin ) );
785  for ( int k = 1; k <= etable_disbins; ++k ) {
786  Real const dis = std::sqrt( ( k - 1 ) * .05f ); //SGM Off-by-1 bug fix: k -> ( k - 1 )
787 
788  // if( !SMOOTH_ETABLES ) {
789  if ( dis < 4.2 ) {
790  bool at1iscarbon(false), at2iscarbon(false);
791  for ( Size i = 1; i <= carbon_types.size(); ++i ) { at1iscarbon |= (atype1 == carbon_types[i] ); }
792  for ( Size i = 1; i <= carbon_types.size(); ++i ) { at2iscarbon |= (atype2 == carbon_types[i] ); }
793  if ( at1iscarbon && at2iscarbon ) {
794  fasol1( k ) = fasol1( ibin );
795  fasol2( k ) = fasol2( ibin );
796  dfasol( k ) = 0.0;
797  dfasol1( k ) = 0.0;
798  }
799  }
800  // push carbonyl oxygens (in beta sheets) apart. a proxy for the missing
801  // electrostatic repulsion needed to counteract the LJatr which pulls the oxyens
802  // together
803  if ( dis <= 3.6 ) {
804  if ( atype1 == OCbb_idx && atype2 == OCbb_idx ) {
805  Real const fac = std::max( dis - 3.6, -1.5 );
806  //std::cout << "adding extra repulsion " << dis << " " << 2*fac*fac << " + " << ljrep_(k,OCbb_idx,OCbb_idx) << std::endl;
807  //Real const fac = std::max( dis - 3.6f, -1.5f );
808  ljrep( k ) += 2 * ( fac * fac );
809  dljrep( k ) += 4 * fac;
810  }
811  }
812 
813  // the following gives peak at 2.4 in 22 and 23 interactions. maybe push out a
814  // bit further. (this is commented out because effects on design have not been
815  // tested)
816 
817  // use one half of a single term polynomial
818  // as the repulsive term for apolar hydrogens (types 23 & 24)
819 
820  // if( mod_hhrep ) {
821  // if( dis < c ) {
822  // for ( int j = 23; j <= 24; ++j ) {
823  // for ( int kk = 23; kk <= 24; ++kk ) {
824  // ljrep_(k,j,kk) = h * pow( min(0.0f, (dis-c)/w ), e );// +
825  // dljrep_(k,j,kk) = h * e / w * pow( min(0.0f, dis-c)/w, e-1 ) ;// +
826  // }
827  // }
828  // }
829  // }
830 
831  } // end for ( int k = 1; k <= etable_disbins; ++k ) {
832 
833 
834  } //Objexx:SGM Extra {} scope is a VC++ work-around
835 
836  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
837  // zero out the attractive and solvation energies for the REPLS and HREPS atom types
838  //
839  // TR << "setting up REPLONLY residues to zero" << std::endl;
840  Size repls_idx = atom_set_->atom_type_index( "REPLS" );
841  Size hreps_idx = atom_set_->atom_type_index( "HREPS" );
842  if ( atype1 == repls_idx || atype2 == repls_idx || atype1 == hreps_idx || atype2 == hreps_idx ) {
843  Size last_rep_bin( 0 );
844  for ( int i = 1; i <= etable_disbins; i++ ){
845  ljatr( i ) = 0.0;
846  dljatr( i ) = 0.0;
847  fasol1( i ) = 0.0;
848  fasol2( i ) = 0.0;
849  dfasol( i ) = 0.0;
850  dfasol1( i ) = 0.0;
851  if ( last_rep_bin == 0 && ljrep( i ) == 0.0 ) {
852  last_rep_bin = i;
853  }
854  }
855  //std::cout << "zeroing ljatr_final_weight " << (*atom_set_)[at1].name() << " " << (*atom_set_)[at2].name() << std::endl;
856  //ljrep_from_negcrossing( atype1, atype2 ) = true;
857  //ljatr_final_weight( atype1, atype2 ) = 0.0;
858  //fasol_final_weight( atype1, atype2 ) = 0.0;
859  EtableParamsOnePair & p = analytic_params_for_pair( atype1, atype2 );
860  p.ljrep_from_negcrossing = true;
861  // record the minimum value as the bin after the last value at which the repulsive energy is positive.
862  p.lj_minimum = std::sqrt( ( last_rep_bin - 1 ) * 1.0 / bins_per_A2 );
863  p.maxd2 = p.lj_minimum*p.lj_minimum; // also set this value as the maximum distance for which the energy should be evaluated
864  p.ljatr_final_weight = 0.0;
865  p.fasol_final_weight = 0.0;
866  }
867 }
868 
869 
870 void
872  Size const atype1,
873  Size const atype2,
874  ObjexxFCL::FArray1A< Real > ljatr,
875  ObjexxFCL::FArray1A< Real > dljatr,
876  ObjexxFCL::FArray1A< Real > ljrep,
877  ObjexxFCL::FArray1A< Real > dljrep,
878  ObjexxFCL::FArray1A< Real > fasol1,
879  ObjexxFCL::FArray1A< Real > fasol2,
880  ObjexxFCL::FArray1A< Real > dfasol,
881  ObjexxFCL::FArray1A< Real > dfasol1
882 )
883 {
884  using namespace numeric::interpolation;
885  using namespace basic::options;
886  using namespace basic::options::OptionKeys;
887 
888  ljatr.dimension( etable_disbins );
889  dljatr.dimension( etable_disbins );
890  ljrep.dimension( etable_disbins );
891  dljrep.dimension( etable_disbins );
892  fasol1.dimension( etable_disbins );
893  fasol2.dimension( etable_disbins );
894  dfasol.dimension( etable_disbins );
895  dfasol1.dimension( etable_disbins );
896 
897  FArray1D<Real> dis(etable_disbins);
898  for(int i = 1; i <= etable_disbins; ++i) {
899  dis(i) = sqrt( ( i - 1 ) * 1.0 / bins_per_A2 );
900  }
901  FArray1D<int> bin_of_dis(100);
902  for(int i = 1; i <= 100; ++i) {
903  float d = ((float)i)/10.0;
904  bin_of_dis(i) = (int)( d*d * bins_per_A2 + 1 );
905  }
906  //FArray2D< int > minima_bin_indices( n_atomtypes_, n_atomtypes_ );
907  int minima_bin_index = 0;
908 
909  //////////////////////////////////////////////////////////////////
910  // 1) change ljatr / ljrep split so that scaling is smooth
911  //////////////////////////////////////////////////////////////////
912  if ( atype1 == 1 && atype2 == 1 ) {
913  TR << "smooth_etable: changing atr/rep split to bottom of energy well" << std::endl;
914  }
915 
916  // find ljatr min
917  core::Real min_atr = 0;
918  int which_min = -1;
919  for(int i = 1; i <= etable_disbins; ++i) {
920  if ( ljatr(i) < min_atr ) {
921  min_atr = ljatr(i);
922  which_min = i;
923  }
924  }
925  if ( which_min != -1 ) {
926  minima_bin_index = which_min;
927  //lj_minima(atype1,atype2) = dis( which_min );
928  //lj_vals_at_minima(atype1, atype2) = min_atr;
929  EtableParamsOnePair & p = analytic_params_for_pair( atype1, atype2 );
930  p.lj_minimum = dis( which_min );
931  p.lj_val_at_minimum = min_atr;
932  } else {
933  //lj_minima(atype1,atype2) = max_dis_;
934  //lj_vals_at_minima( atype1,atype2) = 0;
935  EtableParamsOnePair & p = analytic_params_for_pair( atype1, atype2 );
936  p.lj_minimum = max_dis_;
937  p.lj_val_at_minimum = 0;
938  }
939  // for dis below ljatr min, transfer ljatr to ljrep
940  if( min_atr < 0.0 ) {
941  for( int i = 1; i <= which_min; ++i ) {
942  ljrep(i) += ljatr(i) - min_atr;
943  ljatr(i) -= ljatr(i) - min_atr; // = min_atr;
944  dljrep(i) += dljatr(i);
945  dljatr(i) -= dljatr(i); // = 0;
946  }
947  }
948 
949  using namespace numeric::interpolation::spline;
950  ///////////////////////////////////////////////////////////////////
951  // 2) spline smooth ljatr/ljrep at fa_max_dis cut
952  //////////////////////////////////////////////////////////////////
953  if ( atype1 == 1 && atype2 == 1 ) {
954  TR << "smooth_etable: spline smoothing lj etables (maxdis = " << max_dis_ << ")" << std::endl;
955  }
956 
957  /// APL - 2012/6/14 - Take the bin maximum of the LJ-radii sum and (w/famxd=6) 4.5 A. This change
958  /// effects the interaction of Br/Br and Br/I.
959  int start = std::max( bin_of_dis( (int)( (max_dis_-1.5) * 10.0) ), minima_bin_index );
960  Real lbx = dis(start);
961  Real ubx = dis(etable_disbins);
962  Real lby = ljatr(start);
963  Real lbdy = dljatr(start);
964  Real uby = 0.0;
965  Real ubdy = 0.0;
966  //ljatr_spline_xlo_xhi(atype1,atype2) = std::make_pair( lbx, ubx );
967  {
968  EtableParamsOnePair & p = analytic_params_for_pair( atype1, atype2 );
969  p.ljatr_spline_xlo = lbx;
970  p.ljatr_spline_xhi = ubx;
971  }
972  //std::cout << (*atom_set_)[at1].name() << " " << (*atom_set_)[at2].name() << " lj_minima: " << lj_minima(at1,at2) << " lj_vals_at_minima " << lj_vals_at_minima(at1,at2);
973  //std::cout << " lbx " << lbx << " ubx " << ubx << std::endl;
974 
975  SplineGenerator gen( lbx, lby, lbdy, ubx, uby, ubdy );
976 
977  /// APL -- Disabling this behavior since I think it is unused and if it is used, then it would
978  /// Prevent the analytic etable evaluation code I'm working on
979  //if( option[ score::etable_lr ].user() ) {
980  // Real modx = option[ score::etable_lr ]();
981  // Real mody = lbx * 0.5;
982  // gen.add_known_value( modx, mody );
983  //}
984 
985  InterpolatorOP interp( gen.get_interpolator() );
986  for( int i = start; i <= etable_disbins; ++i ) {
987  interp->interpolate( dis(i), ljatr(i), dljatr(i) );
988  }
989 
990  // Save the spline parameters for the analytic evaluation
991  SimpleInterpolatorOP sinterp = dynamic_cast< SimpleInterpolator * > (interp() );
992  if ( ! sinterp ) {
993  utility_exit_with_message( "Etable created non-simple-interpolator in smooth_etables()" );
994  }
995  {
996  SplineParameters sparams;
997  sparams.ylo = sinterp->y()[ 1 ];
998  sparams.yhi = sinterp->y()[ 2 ];
999  sparams.y2lo = sinterp->ddy()[ 1 ];
1000  sparams.y2hi = sinterp->ddy()[ 2 ];
1001  //ljatr_spline_parameters( atype1, atype2 ) = sparams;
1002  EtableParamsOnePair & p = analytic_params_for_pair( atype1, atype2 );
1003  p.ljatr_spline_parameters = sparams;
1004  }
1005 
1006  /////////////////////////////////////////////////////////////////////////////
1007  // 3) spline smooth solv1/solv2 at fa_max_dis cut && and first switchpoint
1008  /////////////////////////////////////////////////////////////////////////////
1009  if ( atype1 == 1 && atype2 == 1 ) {
1010  TR << "smooth_etable: spline smoothing solvation etables (max_dis = " << max_dis_ << ")" << std::endl;
1011  }
1012 
1013  /// These two values do not depend on at1 or at2
1014  int const S2 = bin_of_dis( (int)((max_dis_-1.5)*10.0) ); // start of spline 2
1015  int const E2 = etable_disbins; // end os spline 2
1016 
1017  /// Save these values for the splines
1018  fasol_spline_far_xlo = dis( S2 );
1019  fasol_spline_far_xhi = dis( E2 );
1022 
1023  int SWTCH = 1;
1024  for( SWTCH=1; SWTCH <= etable_disbins; ++SWTCH) {
1025  // std::cerr << SWTCH << "," << at1 << "," << at2 << "," << solv1_(SWTCH,at1,at2) << " ";
1026  if( (fasol1(SWTCH) != fasol1(1)) ||
1027  (fasol2(SWTCH) != fasol2(1)) ) {
1028  break;
1029  }
1030  }
1031  if ( SWTCH > etable_disbins ) {
1032  // treat the range [0,famaxdis] as a constant (of zero) -- everything below
1033  // the distance fasol_spline_close_start_end(at1,at2).first is evaluated as
1034  // the constant fasol_spline_close(at1,at2).ylo.
1035  //fasol_spline_close_start_end( atype1, atype2 ) = std::make_pair( fasol_spline_far_xhi, fasol_spline_far_xhi+1.0 );
1036  SplineParameters sp; sp.ylo=0; sp.yhi=0; sp.y2lo = 0; sp.y2hi = 0;
1037  //fasol_spline_close( atype1, atype2 ) = sp;
1038  EtableParamsOnePair & p = analytic_params_for_pair( atype1, atype2 );
1039  p.fasol_spline_close = sp;
1042  return;
1043  }
1044 
1045  int const S1 = std::max(1,SWTCH - 30);
1046  int const E1 = std::min(SWTCH + 20,406);
1047  //std::cout << (*atom_set_)[atype1].name() << " " << (*atom_set_)[atype2].name() << " smooth solv " << S1 << " " << E1 << " " << S2 << " " << E2 << std::endl;
1048 
1049  Real dsolv1e1 = (fasol1(E1+1)-fasol1(E1 ))/(dis(E1+1)-dis(E1 ));
1050  Real dsolv1s2 = (fasol1(S2 )-fasol1(S2-1))/(dis(S2 )-dis(S2-1));
1051  Real dsolv2e1 = (fasol2(E1+1)-fasol2(E1 ))/(dis(E1+1)-dis(E1 ));
1052  Real dsolv2s2 = (fasol2(S2 )-fasol2(S2-1))/(dis(S2 )-dis(S2-1));
1053 
1054  SplineGenerator gen11( dis(S1), fasol1(S1), 0.0 , dis(E1), fasol1(E1), dsolv1e1 );
1055  SplineGenerator gen21( dis(S1), fasol2(S1), 0.0 , dis(E1), fasol2(E1), dsolv2e1 );
1056  SplineGenerator gen12( dis(S2), fasol1(S2), dsolv1s2, dis(E2), fasol1(E2), 0.0 );
1057  SplineGenerator gen22( dis(S2), fasol2(S2), dsolv2s2, dis(E2), fasol2(E2), 0.0 );
1058 
1059  InterpolatorOP interp11( gen11.get_interpolator() );
1060  InterpolatorOP interp21( gen21.get_interpolator() );
1061  for( int i = S1; i <= E1; ++i ) {
1062  Real d1,d2;
1063  interp11->interpolate( dis(i), fasol1(i), d1 );
1064  interp21->interpolate( dis(i), fasol2(i), d2 );
1065  dfasol(i) = d1+d2;
1066  dfasol1(i) = d1;
1067  }
1068 
1069  InterpolatorOP interp12( gen12.get_interpolator() );
1070  InterpolatorOP interp22( gen22.get_interpolator() );
1071  for( int i = S2; i <= E2; ++i ) {
1072  Real d1,d2;
1073  interp12->interpolate( dis(i), fasol1(i), d1 );
1074  interp22->interpolate( dis(i), fasol2(i), d2 );
1075  dfasol(i) = d1+d2;
1076  dfasol1(i) = d1;
1077  }
1078 
1079  /// Save the spline parameters
1080  /// Represent the energy as simply the sum of the two splines: the polynomials may simply be added together.
1081  {
1082  SplineGenerator genclose( dis(S1), fasol1(S1) + fasol2(S1), 0, dis(E2), fasol1(E1)+fasol2(E1), dfasol(E1) );
1083  InterpolatorOP interp_close( genclose.get_interpolator() );
1084 
1085  SimpleInterpolatorOP sinterp_close = dynamic_cast< SimpleInterpolator * > (interp_close() );
1086 
1087  if ( ! sinterp_close ) {
1088  utility_exit_with_message( "Etable created non-simple-interpolator in smooth_etables()" );
1089  }
1090  SplineParameters sparams;
1091  sparams.ylo = sinterp_close->y()[ 1 ];
1092  sparams.yhi = sinterp_close->y()[ 2 ];
1093  sparams.y2lo = sinterp_close->ddy()[ 1 ];
1094  sparams.y2hi = sinterp_close->ddy()[ 2 ];
1095 
1096  EtableParamsOnePair & p = analytic_params_for_pair( atype1, atype2 );
1097  p.fasol_spline_close = sparams;
1098  p.fasol_spline_close_start = dis(S1);
1099  p.fasol_spline_close_end = dis(E1);
1100  }
1101 
1102  {
1103  // 2. far spline
1104  // APL Smoother derivatives -- create a spline where the derivatives are actually correct
1105  SplineGenerator genfar( dis(S2), fasol1(S2) + fasol2(S2), dfasol(S2), dis(E2), 0.0, 0.0 );
1106  InterpolatorOP interp_far( genfar.get_interpolator() );
1107 
1108  SimpleInterpolatorOP sinterp_far = dynamic_cast< SimpleInterpolator * > (interp_far() );
1109  if ( ! sinterp_far ) {
1110  utility_exit_with_message( "Etable created non-simple-interpolator in smooth_etables()" );
1111  }
1112  SplineParameters sparams;
1113  sparams.ylo = sinterp_far->y()[ 1 ];
1114  sparams.yhi = sinterp_far->y()[ 2 ];
1115  sparams.y2lo = sinterp_far->ddy()[ 1 ];
1116  sparams.y2hi = sinterp_far->ddy()[ 2 ];
1117  EtableParamsOnePair & p = analytic_params_for_pair( atype1, atype2 );
1118  p.fasol_spline_far = sparams;
1119  }
1120 
1121 }
1122 
1123 
1124 ////////////////////////////////////////////////////////////////////////////////
1125 /// @begin output_etable
1126 ///
1127 /// @brief output an etable data file in the same format used in input_etable
1128 ///
1129 /// @detailed
1130 ///$$$ file first line is <etable> <etable_disbins>
1131 ///$$$ other lines are <atom type 1> <atomtype 1> <eval bin 1> <eval bin 2>...
1132 ///
1133 /// @global_read
1134 /// pdbstatistics_pack.h: ljatr, dljatr, ljrep, dljrep, solv1,solv2,dsolv
1135 ///
1136 ///
1137 /// @remarks
1138 ///
1139 /// @references
1140 ///
1141 /// @authors sheffler mar 19 2006
1142 ///
1143 /// @last_modified
1144 /////////////////////////////////////////////////////////////////////////////////
1145 void
1147  ObjexxFCL::FArray3D<Real> & etable,
1148  std::string label,
1149  std::ostream & out
1150 ) {
1151  using namespace std;
1152  using namespace ObjexxFCL;
1153 
1154  out << label << " " << etable_disbins << endl;
1155  for(int at1 = 1; at1 <= n_atomtypes_; at1++) {
1156  for(int at2 = 1; at2 <= n_atomtypes_; at2++) {
1157  out << at1 << " "
1158  << at2 << " ";
1159  for(int bin = 1; bin <= etable_disbins; bin++) {
1160  float evalue = etable(bin,at1,at2);
1161  out << evalue << ' ';
1162  }
1163  out << endl;
1164  }
1165  }
1166 
1167 }
1168 
1169 
1170 ////////////////////////////////////////////////////////////////////////////////
1171 /// @begin input_etable
1172 ///
1173 /// @brief read in etable from a datafile
1174 ///
1175 /// @detailed
1176 ///$$$ file first line is <etable> <etable_disbins>
1177 ///$$$ other lines are <atom type 1> <atomtype 1> <eval bin 1> <eval bin 2>...
1178 ///
1179 /// @global_read
1180 /// pdbstatistics_pack.h: ljatr, dljatr, ljrep, dljrep, solv1,solv2,dsolv
1181 ///
1182 /// @global_write
1183 /// pdbstatistics_pack.h: ljatr, dljatr, ljrep, dljrep, solv1,solv2,dsolv
1184 ///
1185 /// @remarks
1186 ///
1187 /// @references
1188 ///
1189 /// @authors sheffler mar 19 2006
1190 ///
1191 /// @last_modified
1192 /////////////////////////////////////////////////////////////////////////////////
1193 void
1195  ObjexxFCL::FArray3D<Real> & etable,
1196  const std::string label,
1197  std::istream & in
1198 ) {
1199  using namespace std;
1200 
1201  TR << "input_etable: reading etable... " << label << endl;
1202  istringstream intmp;
1203  string lblin;
1204  int numdisbin;
1205  char buf[100000];
1206 
1207  // check header
1208  in.getline(buf,100000);
1209  intmp.str(buf);
1210  if( !(intmp >> lblin >> numdisbin) ) {
1211  TR << "input_etable: WARNING bad etable header " << buf << endl;
1212  return;
1213  }
1214  if( lblin != label || etable_disbins != numdisbin ) {
1215  TR << "input_etable: WARNING etable types don't match! "<< endl;
1216  TR << " expected " << label << "," << etable_disbins
1217  << " got " << lblin << ',' << numdisbin<< endl;
1218  utility_exit_with_message( "input_etable: WARNING etable types don't match! " );
1219  } else {
1220  TR << "input_etable expected etable " << label << " of size " << etable_disbins
1221  << ", got " << lblin << ',' << numdisbin<< endl;
1222 
1223  }
1224 
1225  // read in etable
1226  int at1,at2,count=0,scount=0;
1227  float evalue;
1228  while( in.getline(buf,100000) ) {
1229  //TR << "ASDFF buf " << buf << endl;
1230  count++;
1231  intmp.clear();
1232  intmp.str(buf);
1233  if( ! (intmp >> at1 >> at2 ) ) {
1234  TR << "input_etable: error reading etable line: " << buf << endl;
1235  } else {
1236  for(int bin = 1; bin <=numdisbin; bin++) {
1237  if( !(intmp >> evalue) ) {
1238  TR << "input_etable: not enough bins on etable line: " << buf << endl;
1239  utility_exit_with_message( "input_etable: not enough bins on etable line: " );
1240  }
1241  //TR << "ASDFF read " << lblin << ' ' << at1 << ' ' << at2 << ' ' << bin << ' ' << evalue << endl;
1242  //TR << "ASDFF " << lblin << at1 << at2 << evalue;
1243  etable(bin,at1,at2) = evalue;
1244  etable(bin,at2,at1) = evalue;
1245  }
1246  scount++;
1247  }
1248  }
1249  TR << " read " << scount << " of " << count << " lines" << endl;
1250 }
1251 
1252 
1253 
1254 
1255 ////////////////////////////////////////////////////////////////////////////////
1256 /// @begin precalc_etable_coefficients
1257 ///
1258 /// @brief precalculate non-distance dependent coefficients of energy functions
1259 ///
1260 /// @detailed
1261 ///
1262 /// @param[out] lj_sigma - out - for atomtypes i and j: (radius_i+radius_j)
1263 /// @param[out] lj_r6_coeff - out - precalced coefficient on the (1/dis)**6 term in lj
1264 /// @param[out] lj_r12_coeff - out - precalced coefficient on the (1/dis)**12 term in lj
1265 /// @param[out] lj_switch_intercept - out -
1266 /// for close contacts calculate lj from a line with this intercept
1267 /// @param[out] lj_switch_slope - out -
1268 /// for close contacts calculate lj from a line with this slope
1269 /// @param[out] lk_inv_lambda2 - out -
1270 /// surprise! it's the 1/(lambda)**2 term in the lk equation
1271 /// @param[out] lk_coeff - out - precalculation of all non-distance dependent terms
1272 /// outside of the exponential in the lk equation
1273 /// @param[out] lk_min_dis2sigma_value - out - below the min dis2sigma ratio for lk,
1274 /// this value is assigned to the solvation
1275 ///
1276 /// @global_read
1277 ///
1278 /// @global_write
1279 ///
1280 /// @remarks
1281 ///
1282 /// @references
1283 ///
1284 /// @authors ctsa 10-2003
1285 ///
1286 /// @last_modified
1287 /////////////////////////////////////////////////////////////////////////////////
1288 void
1290  FArray2< Real > & lj_sigma,
1291  FArray2< Real > & lj_r6_coeff,
1292  FArray2< Real > & lj_r12_coeff,
1293  FArray2< Real > & lj_switch_intercept,
1294  FArray2< Real > & lj_switch_slope,
1295  FArray1< Real > & lk_inv_lambda2,
1296  FArray2< Real > & lk_coeff,
1297  FArray2< Real > & lk_min_dis2sigma_value
1298 )
1299 {
1300 
1301 // using namespace etable;
1302 // using namespace param;
1303 // using namespace water;
1304 // using namespace hbonds;
1305 
1306  // locals
1307  Real sigma,sigma6,sigma12,wdepth;
1308  Real inv_lambda;
1309  FArray1D< Real > lk_coeff_tmp( n_atomtypes_ );
1310  Real thresh_dis,inv_thresh_dis2,x_thresh;
1311  //int dstype;
1312  //int const atype_sulfur = { 16 };
1313  Real const inv_neg2_tms_pi_sqrt_pi = { -0.089793561062583294 };
1314  // coefficient for lk solvation
1315 
1316  // include follows locals so that data statements can initialize included arrays
1317  for ( int i = 1, e = n_atomtypes_; i <= e; ++i ) {
1318  inv_lambda = 1.0/lk_lambda(i);
1319  //inv_lambda = 1.0/atom_type(i).lk_lambda();
1320  lk_inv_lambda2(i) = inv_lambda * inv_lambda;
1321  lk_coeff_tmp(i) = inv_neg2_tms_pi_sqrt_pi *
1322  lk_dgfree(i) * inv_lambda;
1323  //atom_type(i).lk_dgfree() * inv_lambda;
1324  }
1325 
1326  for ( int i = 1, e = n_atomtypes_; i <= e; ++i ) {
1327  for ( int j = i; j <= e; ++j ) {
1328 
1329  sigma = Wradius * ( lj_radius(i) + lj_radius(j) );
1330  //sigma = Wradius * ( atom_type(i).lj_radius() + atom_type(j).lj_radius() );
1331 //jjh temporary fix to prevent division by zero below
1332  sigma = ( sigma < 1.0e-9 ? 1.0e-9 : sigma );
1333 
1334  // (bk) modify sigma for hbond donors and acceptors
1335  // ctsa -- should these scale down by Wradius as well?
1336 
1337  // pb specific sigma correction for pairs between charged oxygen acceptors (15)
1338  // pb and hydroxyl oxygen donors (13). sigma correction for all polar H and charged oxygen
1339  // pb acceptor. Combinations of these corrections allow better prediction of both
1340  // pb hydroxyl O donor/charged O acceptor and charged NH donor/charged O acceptor
1341  // pb distances.
1342 
1343  if ( lj_use_hbond_radii ) {
1344  if ( ( atom_type(i).is_acceptor() && atom_type(j).is_donor() ) ||
1345  ( atom_type(i).is_donor() && atom_type(j).is_acceptor() ) ) {
1346  if ( ( atom_type(j).is_donor() && atom_type(j).name() == "OH" ) ||
1347  ( atom_type(i).is_donor() && atom_type(i).name() == "OH" ) ) {
1348  sigma = lj_hbond_OH_donor_dis;
1349  } else {
1350  sigma = lj_hbond_dis;
1351 // if (tight_hb && ((i == 15 && j == 13) || (j == 15 && i == 13)))
1352 // sigma = lj_hbond_accOch_dis;
1353  }
1354  } else if ( ( atom_type(i).is_acceptor() && atom_type(j).is_polar_hydrogen() ) ||
1355  ( atom_type(i).is_polar_hydrogen() && atom_type(j).is_acceptor() ) ) {
1356  sigma = lj_hbond_hdis;
1357 // if (tight_hb && ((i == 15 && j == 22) || (j == 15 && i == 22)))
1358 // sigma = lj_hbond_accOch_hdis;
1359  }
1360  }
1361 
1362 //lin modify sigma for water and hbond donors/acceptors
1363  if ( lj_use_water_radii ) {
1364  if ( ( ( atom_type(i).is_acceptor() ||
1365  atom_type(i).is_donor() ) &&
1366  atom_type(j).is_h2o() ) ||
1367  ( ( atom_type(j).is_acceptor() ||
1368  atom_type(j).is_donor() ) &&
1369  atom_type(i).is_h2o() ) ) {
1370  sigma = lj_water_dis;
1371  } else if ( ( atom_type(i).is_polar_hydrogen() &&
1372  atom_type(j).is_h2o() ) ||
1373  ( atom_type(j).is_polar_hydrogen() &&
1374  atom_type(i).is_h2o() ) ) {
1375  sigma = lj_water_hdis;
1376  }
1377  }
1378 
1379  sigma6 = std::pow( sigma, 6 );
1380  sigma12 = sigma6 * sigma6;
1381  wdepth = std::sqrt(lj_wdepth(i)*lj_wdepth(j));
1382  //wdepth = std::sqrt(atom_type(i).lj_wdepth()*atom_type(j).lj_wdepth());
1383 
1384  lj_sigma(i,j) = sigma;
1385  lj_sigma(j,i) = lj_sigma(i,j);
1386 
1387  lj_r6_coeff(i,j) = -2. * wdepth * sigma6;
1388  lj_r6_coeff(j,i) = lj_r6_coeff(i,j);
1389 
1390  lj_r12_coeff(i,j) = wdepth * sigma12;
1391  lj_r12_coeff(j,i) = lj_r12_coeff(i,j);
1392 
1393  // ctsa - create coefficients for linear projection of lj repulsive used
1394  // for low distance values
1395  if ( lj_use_lj_deriv_slope ) {
1396 
1397  // ctsa - use the slope of the true lj repulsive at the
1398  // linear switch point to create a linear projection of
1399  // lj for low distances
1400 
1401  // slope = wdepth/sigma *
1402  // (slope@switch_point*sigma/wdepth)
1403  lj_switch_slope(i,j) = (wdepth/sigma)*
1405  lj_switch_slope(j,i) = lj_switch_slope(i,j);
1406 
1407  // intercept = wdepth*(lj@switch_point/wdepth)
1408  // - slope*switch_point_distance
1409  lj_switch_intercept(i,j) = wdepth*lj_switch_value2wdepth -
1410  lj_switch_slope(i,j)*sigma*lj_switch_dis2sigma;
1411  lj_switch_intercept(j,i) = lj_switch_intercept(i,j);
1412  } else {
1413 
1414  // ctsa - create a linear projection of lj for low distances which
1415  // is defined by a constant y intercept and the true lj repulsive
1416  // value at the linear switch point
1417  lj_switch_slope(i,j) = -(1./sigma)*lj_switch_sigma2dis*
1419  lj_switch_slope(j,i) = lj_switch_slope(i,j);
1420 
1421  lj_switch_intercept(i,j) = lj_slope_intercept;
1422  lj_switch_intercept(j,i) = lj_switch_intercept(i,j);
1423  }
1424 
1425  // ctsa - precalculated lk solvation coefficients
1426  lk_coeff(i,j) = lk_coeff_tmp(i) * lk_volume(j);
1427  //lk_coeff(i,j) = lk_coeff_tmp(i) * atom_type(j).lk_volume();
1428  lk_coeff(j,i) = lk_coeff_tmp(j) * lk_volume(i);
1429  //lk_coeff(j,i) = lk_coeff_tmp(j) * atom_type(i).lk_volume();
1430 
1431  // ctsa - when dis/sigma drops below lk_min_dis2sigma,
1432  // a constant lk solvation value equal to the value at the
1433  // switchover point is used. That switchover-point value
1434  // is calculated here and stored in lk_min_dis2sigma_value
1435  thresh_dis = lk_min_dis2sigma*sigma;
1436  inv_thresh_dis2 = 1./( thresh_dis * thresh_dis );
1437  Real dis_rad = thresh_dis - lj_radius(i);
1438  //Real dis_rad = thresh_dis - atom_type(i).lj_radius();
1439  x_thresh = ( dis_rad * dis_rad ) * lk_inv_lambda2(i);
1440  lk_min_dis2sigma_value(i,j) = std::exp(-x_thresh) * lk_coeff(i,j) *
1441  inv_thresh_dis2;
1442 
1443  dis_rad = thresh_dis - lj_radius(j);
1444  //dis_rad = thresh_dis - atom_type(j).lj_radius();
1445  x_thresh = ( dis_rad * dis_rad ) * lk_inv_lambda2(j);
1446  lk_min_dis2sigma_value(j,i) = std::exp(-x_thresh) * lk_coeff(j,i) *
1447  inv_thresh_dis2;
1448 
1449  }
1450  }
1451 
1452  // ctsa - calculate disulfide coefficients
1453  // pb -- killed this
1454 
1455 }
1456 
1457 
1458 ////////////////////////////////////////////////////////////////////////////////
1459 /// @begin calc_etable_value
1460 ///
1461 /// @brief calc all etable values given a distance and atom-type pair
1462 ///
1463 /// @detailed
1464 ///
1465 /// given a pair of atom types and the squared inter-atomic separation
1466 /// distance (and a whole bunch of pre-computed coeffecients), this returns
1467 /// the value of the lennard-jones and lk solvation potentials and
1468 /// their derivatives w.r.t. the separation distance
1469 ///
1470 ///
1471 /// @param[in] dis2 - in - atomic separation distance squared
1472 /// @param[in] atype1 - in - chemical type of atom 1
1473 /// @param[in] atype2 - in - chemical type of atom 2
1474 /// @param[out] atrE - out - atractive lj energy
1475 /// @param[out] d_atrE - out - d(atrE)/d(dis)
1476 /// @param[out] repE - out - repulsive lj energy
1477 /// @param[out] d_repE - out - d(repE)/d(dis)
1478 /// @param[out] solvE1 - out - lk solvation energy
1479 /// @param[out] solvE2 - out - lk solvation energy
1480 /// @param[out] dsolvE - out - d(solvE1+solvE2)/d(dis)
1481 /// @param[in] lj_sigma - in - for atomtypes i and j: (radius_i+radius_j)
1482 /// @param[in] lj_r6_coeff - in - precalced coefficient on the (1/dis)**6 term in lj
1483 /// @param[in] lj_r12_coeff - in - precalced coefficient on the (1/dis)**12 term in lj
1484 /// @param[in] lj_switch_intercept - in -
1485 /// for close contacts calculate lj from a line with this intercept
1486 /// @param[in] lj_switch_slope - in -
1487 /// for close contacts calculate lj from a line with this slope
1488 /// @param[in] lk_inv_lambda2 - in -
1489 /// surprise! it's the 1/(lambda)**2 term in the lk equation
1490 /// @param[in] lk_coeff - in - precalculation of all non-distance dependent terms
1491 /// outside of the exponential in the lk equation
1492 /// @param[in] lk_min_dis2sigma_value - in - below the min dis2sigma ratio for lk,
1493 /// this value is assigned to the solvation
1494 ///
1495 /// @global_read
1496 ///
1497 /// pdbstatistics_pack.h
1498 /// etable.h
1499 ///
1500 /// @global_write
1501 ///
1502 /// @remarks
1503 ///
1504 /// @references
1505 ///
1506 /// @authors ctsa 10-2003
1507 ///
1508 /// @last_modified
1509 /////////////////////////////////////////////////////////////////////////////////
1510 void
1512  Real dis2,
1513  int & atype1,
1514  int & atype2,
1515  Real & atrE,
1516  Real & d_atrE,
1517  Real & repE,
1518  Real & d_repE,
1519  Real & solvE1,
1520  Real & solvE2,
1521  Real & dsolvE1,
1522  Real & dsolvE2,
1523  FArray2< Real > & lj_sigma,
1524  FArray2< Real > & lj_r6_coeff,
1525  FArray2< Real > & lj_r12_coeff,
1526  FArray2< Real > & lj_switch_intercept,
1527  FArray2< Real > & lj_switch_slope,
1528  FArray1< Real > & lk_inv_lambda2,
1529  FArray2< Real > & lk_coeff,
1530  FArray2< Real > & lk_min_dis2sigma_value
1531 )
1532 {
1533 // using namespace etable;
1534 // using namespace param;
1535 // using namespace pdbstatistics_pack;
1536 
1537  // locals
1538  Real ljE,d_ljE,x1,x2;
1539  Real dis;
1540  Real inv_dis,inv_dis2,inv_dis6,inv_dis7,inv_dis12,inv_dis13;
1541  Real dis2sigma;
1542  int xtra_atype1,xtra_atype2;
1543  //int const atype_sulfur = { 16 };
1544 
1545  // include after local variables to allow data statements to initialize
1546  atrE = 0.;
1547  d_atrE = 0.;
1548  repE = 0.;
1549  d_repE = 0.;
1550  solvE1 = 0.;
1551  solvE2 = 0.;
1552  dsolvE1 = 0.;
1553  dsolvE2 = 0.;
1554 
1555  // ctsa - epsilon allows final bin value to be calculated
1556  if ( dis2 > max_dis2 + epsilon ) return;
1557 
1558  if ( dis2 < min_dis2 ) dis2 = min_dis2;
1559 
1560  dis = std::sqrt(dis2);
1561  inv_dis = 1.0/dis;
1562  inv_dis2 = inv_dis * inv_dis;
1563 
1564 
1565 
1566  // ctsa - switch to disulfide bonded atom types
1567  // when conditions are met
1568 // if ( ( atype1 == atype_sulfur && atype2 == atype_sulfur ) &&
1569 // dis < disulfide_dis_thresh ) {
1570 // xtra_atype1 = n_atomtypes_ + 1;
1571 // xtra_atype2 = n_atomtypes_ + 1;
1572 // } else {
1573  xtra_atype1 = atype1;
1574  xtra_atype2 = atype2;
1575  //}
1576 
1577 
1578  dis2sigma = dis / lj_sigma(xtra_atype1,xtra_atype2);
1579 
1580 
1581  if ( dis2sigma < lj_switch_dis2sigma ) {
1582  // ctsa - use linear ramp instead of lj when the dis/sigma
1583  // ratio drops below theshold
1584  d_ljE = lj_switch_slope(xtra_atype1,xtra_atype2);
1585  ljE = dis*d_ljE + lj_switch_intercept(xtra_atype1,xtra_atype2);
1586  } else {
1587  // ctsa - calc regular lennard-jones
1588  inv_dis6 = inv_dis2 * inv_dis2 * inv_dis2;
1589  inv_dis7 = inv_dis6 * inv_dis;
1590  inv_dis12 = inv_dis6 * inv_dis6;
1591  inv_dis13 = inv_dis12 * inv_dis;
1592 
1593  ljE = lj_r12_coeff(xtra_atype1,xtra_atype2) * inv_dis12 +
1594  lj_r6_coeff(xtra_atype1,xtra_atype2) * inv_dis6;
1595 
1596  d_ljE = -12.*lj_r12_coeff(xtra_atype1,xtra_atype2) * inv_dis13-6. *
1597  lj_r6_coeff(xtra_atype1,xtra_atype2) * inv_dis7;
1598  }
1599 
1600  if ( ljE < 0. ) {
1601  atrE = ljE;
1602  d_atrE = d_ljE;
1603  } else {
1604  repE = ljE;
1605  d_repE = d_ljE;
1606  }
1607 
1608 
1609  // ctsa - calc lk
1610  if ( dis2sigma < lk_min_dis2sigma ) {
1611  // ctsa - solvation is constant when the dis/sigma ratio
1612  // falls below minimum threshold
1613  solvE1 = lk_min_dis2sigma_value(xtra_atype1,xtra_atype2);
1614  solvE2 = lk_min_dis2sigma_value(xtra_atype2,xtra_atype1);
1615  dsolvE1 = dsolvE2 = 0.0;
1616 
1617  } else {
1618 
1619  Real dis_rad = dis - lj_radius(atype1);
1620  //Real dis_rad = dis - atom_type(atype1).lj_radius();
1621  x1 = ( dis_rad * dis_rad ) * lk_inv_lambda2(atype1);
1622  dis_rad = dis - lj_radius(atype2);
1623  //dis_rad = dis - atom_type(atype2).lj_radius();
1624  x2 = ( dis_rad * dis_rad ) * lk_inv_lambda2(atype2);
1625 
1626  solvE1 = std::exp(-x1) * lk_coeff(atype1,atype2) * inv_dis2;
1627  solvE2 = std::exp(-x2) * lk_coeff(atype2,atype1) * inv_dis2;
1628 
1629  // ctsa - get d(lk_E)/dr
1630  dsolvE1 = -2.0 * solvE1 *
1631  (((dis-lj_radius(atype1))*lk_inv_lambda2(atype1))+inv_dis);
1632  //(((dis-atom_type(atype1).lj_radius())*lk_inv_lambda2(atype1))+inv_dis);
1633  dsolvE2 = -2.0 * solvE2 *
1634  (((dis-lj_radius(atype2))*lk_inv_lambda2(atype2))+inv_dis);
1635  //(((dis-atom_type(atype2).lj_radius())*lk_inv_lambda2(atype2))+inv_dis);
1636 
1637  }
1638 
1639 }
1640 
1641 
1642 void
1644  Size const atype1,
1645  Size const atype2,
1646  ObjexxFCL::FArray1A< Real > ljrep,
1647  ObjexxFCL::FArray1A< Real > ljatr,
1648  ObjexxFCL::FArray1A< Real > dljatr,
1649  ObjexxFCL::FArray1A< Real > fasol1,
1650  ObjexxFCL::FArray1A< Real > fasol2,
1651  ObjexxFCL::FArray1A< Real > dfasol,
1652  ObjexxFCL::FArray1A< Real > dfasol1
1653 )
1654 {
1655  ljrep.dimension( etable_disbins );
1656  ljatr.dimension( etable_disbins );
1657  dljatr.dimension( etable_disbins );
1658  fasol1.dimension( etable_disbins );
1659  fasol2.dimension( etable_disbins );
1660  dfasol.dimension( etable_disbins );
1661  dfasol1.dimension( etable_disbins );
1662 
1663  Size const HOH = atom_set_->atom_type_index("HOH");
1664  if ( atype1 == HOH || atype2 == HOH || atom_type(atype1).is_hydrogen() || atom_type(atype2).is_hydrogen() ) {
1665 
1666  // cbk don't give hydrogens or water attractive lennard-jones
1667  // cbk this is so very short range cut-offs can be used
1668 
1669  Size first_zero_ljrep = 0;
1670  for( int i = 1; i <= etable_disbins; ++i ) {
1671  ljatr(i) = 0.0;
1672  dljatr(i) = 0.0;
1673  fasol1(i) = fasol2(i) = dfasol(i) = dfasol1(i) = 0.0; // APL TEMP. Disable solvation term for hydrogen atoms
1674  if ( first_zero_ljrep == 0 && ljrep(i) == 0.0 ) {
1675  first_zero_ljrep = i;
1676  }
1677  }
1678  //std::cout << "zeroing ljatr_final_weight " << (*atom_set_)[at1].name() << " " << (*atom_set_)[at2].name() << std::endl;
1679  //ljatr_final_weight(atype1,atype2) = 0.0;
1680  EtableParamsOnePair & p = analytic_params_for_pair( atype1, atype2 );
1681  p.ljatr_final_weight = 0.0;
1682  p.fasol_final_weight = 0.0;
1683  p.maxd2 = ( first_zero_ljrep - 1 ) * 1.0 / bins_per_A2;
1684  p.hydrogen_interaction = true;
1685  /// Disable fasol for hydrogens? Technically, fasol doesn't get disabled for hydrogens! fasol_final_weight(at1,at2) = 0.0;
1686  /// This is surely a bug.
1687  }
1688 }
1689 
1690 /// @brief Returns the maximum lj radius for any non-hydrogen
1691 /// atom as defined by the atom-type-set used to create this Etable.
1692 Real
1694 {
1696 }
1697 
1698 /// @brief Returns the maximum lj radius for any hydrogen atom as
1699 /// defined by the input atom-type-set used to create this Etable.
1700 Real
1702 {
1703  return max_hydrogen_lj_radius_;
1704 }
1705 
1707  core::conformation::Atom const & at1,
1708  core::conformation::Atom const & at2,
1709  core::Real & lj_atrE,
1710  core::Real & lj_repE,
1711  core::Real & fa_solE,
1712  Real & dis2
1713 ) const
1714 {
1715  Real ljatrE_lo, ljrepE_lo, fasolE_lo;
1716  Real ljatrE_hi, ljrepE_hi, fasolE_hi;
1717  core::conformation::Atom at2_lo( at2 ), at2_hi( at2 );
1718  dis2 = at1.xyz().distance_squared( at2.xyz() );
1719  Real d2dummy;
1720  int dis2bin = (int) ( dis2 * bins_per_A2 );
1721 
1722  Real dis2lo = Real(dis2bin) / bins_per_A2;
1723  Real dis2hi = Real(dis2bin + 1 )/bins_per_A2;
1724  at2_lo.xyz( Vector( std::sqrt( dis2lo ), 0, 0 ));
1725  at2_hi.xyz( Vector( std::sqrt( dis2hi ), 0, 0 ));
1726 
1727  analytic_etable_evaluation( at1, at2_lo, ljatrE_lo, ljrepE_lo, fasolE_lo, d2dummy );
1728  analytic_etable_evaluation( at1, at2_hi, ljatrE_hi, ljrepE_hi, fasolE_hi, d2dummy );
1729 
1730  Real alpha = (dis2*bins_per_A2 - dis2bin);
1731  //std::cout << "debug " << dis2 << " " << dis2lo << " " << dis2hi << " " << alpha << " " << 1-alpha << " " << ljatrE_lo << " " << ljatrE_hi << std::endl;
1732 
1733  lj_atrE = alpha * ljatrE_hi + (1-alpha) * ljatrE_lo;
1734  lj_repE = alpha * ljrepE_hi + (1-alpha) * ljrepE_lo;
1735  fa_solE = alpha * fasolE_hi + (1-alpha) * fasolE_lo;
1736 }
1737 
1738 
1739 
1740 
1741 } // etable
1742 } // scoring
1743 } // core