23 #include <basic/Tracer.hh>
24 #include <basic/options/option.hh>
25 #include <basic/options/keys/out.OptionKeys.gen.hh>
26 #include <basic/options/keys/pb_potential.OptionKeys.gen.hh>
44 #include <utility/pointer/ReferenceCount.hh>
45 #include <utility/io/izstream.hh>
48 #include <ObjexxFCL/format.hh>
49 #include <ObjexxFCL/FArray3D.hh>
50 #include <numeric/xyz.functions.hh>
51 #include <numeric/xyzMatrix.hh>
52 #include <numeric/xyzVector.hh>
56 #include <utility/vector1.hh>
65 static basic::Tracer
TR(
"core.scoring.PoissonBoltzmannPotential");
81 :config_filename_(
"Unknown.in"),
82 pqr_filename_(
"Unknown.pqr"),
83 dx_filename_(
"Unknown.dx"),
84 apbs_path_(DEFAULT_APBS_PATH),
101 Real & PB_energy_residue,
102 Real & PB_energy_backbone,
103 Real & PB_energy_sidechain,
104 Real const & PB_burial_weight
107 PB_energy_residue = 0.0;
108 PB_energy_backbone = 0.0;
109 PB_energy_sidechain = 0.0;
112 for (
Size iatom=1; iatom<=rsd.
natoms(); ++iatom ) {
119 PB_energy_backbone += atom_energy;
122 PB_energy_sidechain += atom_energy;
124 PB_energy_residue += atom_energy;
130 #ifdef LINK_APBS_LIB // APBS libraries are linked
135 std::map<std::string, bool>
const &charged_residues )
145 int apbs_dbg = basic::options::option[ basic::options::OptionKeys::pb_potential::apbs_debug ];
146 calcenergy_ = basic::options::option[ basic::options::OptionKeys::pb_potential::calcenergy ];
151 result = apbs.exec();
154 TR.Error <<
"APBS failed! Terminating the program..." << std::endl;
156 runtime_assert(
false);
158 TR.Debug <<
"Solved PB. Loading potential..." << std::endl;
159 const double * meta = result->grid_meta;
160 const double * data = &(result->grid_data[0][0]);
161 load_potential(meta, data);
165 TR <<
"PB took " <<
end-begin <<
" seconds" << std::endl;
168 PB::load_potential(
const double grid_meta[],
169 const double pot[]) {
170 int nx = grid_meta[1];
171 int ny = grid_meta[2];
172 int nz = grid_meta[3];
188 0.,grid_spacing_[1],0.,
189 0.,0.,grid_spacing_[2]);
191 1./grid_spacing_[0],0.,0.,
192 0.,1./grid_spacing_[1],0.,
193 0.,0.,1./grid_spacing_[2]);
197 double cap = basic::options::option[ basic::options::OptionKeys::pb_potential::potential_cap ];
207 for (
int i=1; i<=nx; i++) {
208 for (
int j=1; j<=ny; j++) {
209 for (
int k=1; k<=nz; k++) {
210 u = (k-1)*(nx)*(ny)+(j-1)*(nx)+(i-1);
221 else if( pot[u] < -cap ) {
231 TR.Debug <<
"PB potential is successfully loaded." << std::endl;
234 TR <<
"Convertion of PB potential to Certesian coordinates is completed" << std::endl;
237 #else // APBS libraries are not linked. Use system call.
242 std::map<std::string, bool>
const &charged_residues )
248 if (basic::options::option[basic::options::OptionKeys::pb_potential::apbs_path].user()) {
249 apbs_path_ = basic::options::option[basic::options::OptionKeys::pb_potential::apbs_path];
252 calcenergy_ = basic::options::option[ basic::options::OptionKeys::pb_potential::calcenergy ];
262 int ret = system(command_line.c_str());
266 if( ! dxstream.good() ) {
267 TR <<
"APBS failed to generate the result file. Terminating the program." << std::endl;
269 runtime_assert(
false);
278 TR <<
"PB took " <<
end-begin <<
" seconds" << std::endl;
284 runtime_assert(p_stream);
289 char first_char = p_stream.peek();
290 if ( first_char ==
'#' ) {
291 p_stream.getline( line );
297 for (
Size i=0;i<5;++i) p_stream >> buff;
303 p_stream >> lower_bound_[1];
304 p_stream >> lower_bound_[2];
310 p_stream >> buff >> grid_spacing_[0] >> buff >> buff;
311 p_stream >> buff >> buff >> grid_spacing_[1] >> buff;
312 p_stream >> buff >> buff >> buff >> grid_spacing_[2];
314 grid_spacing_[0],0.,0.,
315 0.,grid_spacing_[1],0.,
316 0.,0.,grid_spacing_[2]);
318 1./grid_spacing_[0],0.,0.,
319 0.,1./grid_spacing_[1],0.,
320 0.,0.,1./grid_spacing_[2]);
324 p_stream.getline( line );
325 p_stream.getline( line );
326 p_stream.getline( line );
329 potential_.dimension(n_grid_[0],n_grid_[1],n_grid_[2]);
336 if (
potential_(i,j,k) > basic::options::option[ basic::options::OptionKeys::pb_potential::potential_cap ]) {
337 potential_(i,j,k) = basic::options::option[ basic::options::OptionKeys::pb_potential::potential_cap ];
339 if (
potential_(i,j,k) < -basic::options::option[ basic::options::OptionKeys::pb_potential::potential_cap ]) {
340 potential_(i,j,k) = -basic::options::option[ basic::options::OptionKeys::pb_potential::potential_cap ];
347 TR <<
"PB potential is successfully loaded from: " <<
dx_filename_ << std::endl;
350 TR <<
"Convertion of PB potential to Certesian coordinates is completed" << std::endl;
360 #endif // LINK_APBS_LIB
364 std::map<std::string, bool>
const & is_residue_charged_by_name_)
const {
368 using namespace basic::options::OptionKeys;
370 charged_chains.push_back(1);
376 static std::string const chains(
" ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" );
378 for (
Size i=1; i<= nres; ++i ) {
382 bool residue_charged =
const_cast<std::map<std::string,bool>&
>(is_residue_charged_by_name_)[rsd.type().name()];
383 for (
Size j=1; j<= rsd.natoms(); ++j ) {
390 if ( rsd.atom_type(j).is_virtual() )
continue;
393 runtime_assert( rsd.chain() < chains.size() );
395 char const chain( chains[ rsd.chain() ] );
396 if (residue_charged) {
397 using namespace ObjexxFCL::fmt;
398 pqr_ostr <<
"ATOM " << I(5,number) <<
' ' << rsd.atom_name(j) <<
' ' <<
399 rsd.name3() <<
' ' << chain << I(4,rsd.seqpos() ) <<
" " <<
400 F(8,3,atom.xyz()(1)) <<
401 F(8,3,atom.xyz()(2)) <<
402 F(8,3,atom.xyz()(3)) <<
404 F(8,3,rsd.atom_type(j).lj_radius()) <<
'\n';
407 using namespace ObjexxFCL::fmt;
408 pqr_ostr <<
"ATOM " << I(5,number) <<
' ' << rsd.atom_name(j) <<
' ' <<
409 rsd.name3() <<
' ' << chain << I(4,rsd.seqpos() ) <<
" " <<
410 F(8,3,atom.xyz()(1)) <<
411 F(8,3,atom.xyz()(2)) <<
412 F(8,3,atom.xyz()(3)) <<
414 F(8,3,rsd.atom_type(j).lj_radius()) <<
'\n';
437 if (pose.
residue(ires).
xyz(iatom)[i] < min_r[i]) {
440 if (pose.
residue(ires).
xyz(iatom)[i] > max_r[i]) {
459 using namespace ObjexxFCL::fmt;
460 config_ostr <<
"#" << std::endl;
461 config_ostr <<
"# Note that most of the comments here were taken from sample" << std::endl;
462 config_ostr <<
"# input files that came with APBS. You can find APBS at" << std::endl;
463 config_ostr <<
"# http://agave.wustl.edu/apbs/" << std::endl;
464 config_ostr <<
"# Note that APBS is BSD & MIT'd code." << std::endl;
465 config_ostr <<
"#" << std::endl;
466 config_ostr <<
"read" << std::endl;
467 config_ostr <<
"mol pqr "<<
pqr_filename_ <<
" # read molecule 1" << std::endl;
468 config_ostr <<
"end" << std::endl;
469 config_ostr <<
"elec" << std::endl;
470 config_ostr <<
"mg-auto" << std::endl;
471 config_ostr <<
"dime " << I(5,n_grid.x()) <<
" "<< I(5,n_grid.y()) <<
" "<< I(5,n_grid.z()) <<
" # number of find grid points" << std::endl;
472 config_ostr <<
"# calculated by psize.py" << std::endl;
473 config_ostr <<
"cglen " << F(11,6,dimension_coarse.x()) <<
" " << F(11,6,dimension_coarse.y()) <<
" " << F(11,6,dimension_coarse.z()) <<
" # coarse mesh lengths (A)" << std::endl;
474 config_ostr <<
"fglen " << F(11,6,dimension_fine.x()) <<
" " << F(11,6,dimension_fine.y()) <<
" " << F(11,6,dimension_fine.z()) <<
" # fine mesh lengths (A)" << std::endl;
475 config_ostr <<
"# calculated by psize.py" << std::endl;
476 config_ostr <<
"cgcent " << F(11,6,center.x()) <<
" " << F(11,6,center.y()) <<
" " << F(11,6,center.z()) <<
" # (could also give (x,y,z) form psize.py) #known center" << std::endl;
477 config_ostr <<
"fgcent " << F(11,6,center.x()) <<
" " << F(11,6,center.y()) <<
" " << F(11,6,center.z()) <<
" # (could also give (x,y,z) form psize.py) #known center" << std::endl;
478 config_ostr <<
"npbe # solve the full nonlinear PBE with npbe" << std::endl;
479 config_ostr <<
"#lpbe # solve the linear PBE with lpbe" << std::endl;
480 config_ostr <<
"bcfl sdh # Boundary condition flag" << std::endl;
481 config_ostr <<
"# 0 => Zero" << std::endl;
482 config_ostr <<
"# 1 => Single DH sphere" << std::endl;
483 config_ostr <<
"# 2 => Multiple DH spheres" << std::endl;
484 config_ostr <<
"# 4 => Focusing" << std::endl;
485 config_ostr <<
"#" << std::endl;
486 config_ostr <<
"#ion 1 0.000 2.0 # Counterion declaration:" << std::endl;
487 config_ostr <<
"ion 1 0.150000 2.000000 # Counterion declaration:" << std::endl;
488 config_ostr <<
"ion -1 0.150000 2.000000 # ion <charge> <conc (M)> <radius>" << std::endl;
489 config_ostr <<
"ion 2 0.000000 2.000000 # ion <charge> <conc (M)> <radius>" << std::endl;
490 config_ostr <<
"ion -2 0.000000 2.000000 # ion <charge> <conc (M)> <radius>" << std::endl;
491 config_ostr <<
"pdie 4.000000 # Solute dielectric" << std::endl;
492 config_ostr <<
"sdie 80.000000 # Solvent dielectric" << std::endl;
493 config_ostr <<
"chgm spl2 # Charge disc method" << std::endl;
494 config_ostr <<
"# 0 is linear splines" << std::endl;
495 config_ostr <<
"# 1 is cubic b-splines" << std::endl;
496 config_ostr <<
"mol 1 # which molecule to use" << std::endl;
497 config_ostr <<
"srfm smol # Surface calculation method" << std::endl;
498 config_ostr <<
"# 0 => Mol surface for epsilon;" << std::endl;
499 config_ostr <<
"# inflated VdW for kappa; no" << std::endl;
500 config_ostr <<
"# smoothing" << std::endl;
501 config_ostr <<
"# 1 => As 0 with harmoic average" << std::endl;
502 config_ostr <<
"# smoothing" << std::endl;
503 config_ostr <<
"# 2 => Cubic spline " << std::endl;
504 config_ostr <<
"srad 1.400000 # Solvent radius (1.4 for water)" << std::endl;
505 config_ostr <<
"swin 0.3 # Surface cubic spline window .. default 0.3" << std::endl;
506 config_ostr <<
"temp 310.000000 # System temperature (298.15 default)" << std::endl;
507 config_ostr <<
"sdens 10.000000 # Specify the number of grid points per square-angstrom to use in Vacc object. Ignored when srad is 0.0 (see srad) or srfm is spl2 (see srfm). There is a direct correlation between the value used for the Vacc sphere density, the accuracy of the Vacc object, and the APBS calculation time. APBS default value is 10.0." << std::endl;
508 config_ostr <<
"gamma 0.105 # Surface tension parameter for apolar forces (in kJ/mol/A^2)" << std::endl;
509 config_ostr <<
"# only used for force calculations, so we don't care, but" << std::endl;
510 config_ostr <<
"# it's always required, and 0.105 is the default" << std::endl;
511 config_ostr <<
"calcenergy " << (
calcenergy_?
"yes" :
"no") <<
" # Energy I/O to stdout" << std::endl;
512 config_ostr <<
"# 0 => don't write out energy" << std::endl;
513 config_ostr <<
"# 1 => write out total energy" << std::endl;
514 config_ostr <<
"# 2 => write out total energy and all" << std::endl;
515 config_ostr <<
"# components" << std::endl;
516 config_ostr <<
"calcforce no # Atomic forces I/O (to stdout)" << std::endl;
517 config_ostr <<
"# 0 => don't write out forces" << std::endl;
518 config_ostr <<
"# 1 => write out net forces on molecule" << std::endl;
519 config_ostr <<
"# 2 => write out atom-level forces" << std::endl;
521 config_ostr <<
"# format to a file." << std::endl;
522 config_ostr <<
"end" << std::endl;
523 config_ostr <<
"quit" << std::endl;