35 #include <basic/Tracer.hh>
43 #include <numeric/xyzVector.hh>
44 #include <numeric/xyzMatrix.hh>
52 #include <utility/vector1.hh>
64 #include <numeric/xyz.functions.hh>
71 static basic::Tracer
TR(
"core.scoring.geometric_solvation.exact_model" );
75 namespace geometric_solvation {
78 using namespace core::scoring;
79 using namespace core::scoring::hbonds;
94 std::vector < std::vector < std::vector <core::Real> > >
const & water_weights,
95 std::vector < std::vector < std::vector <bool> > > & occluded_sites,
96 bool const hydrogens_can_occlude,
97 bool const pairwise_additive,
98 bool const pairwise_additive_output,
103 if ( pairwise_additive_output && ! pairwise_additive ) {
104 TR <<
"Error - pairwise additive output doesn't make sense when calculations are not pairwise additive!!" << std::endl;
112 occluded_sites[tx][ty][tz] =
false;
122 core::Vector translation_vector = -1.0 * orig_polar_atom_xyz;
123 core::Vector translated_base_atom = orig_base_atom_xyz + translation_vector;
131 core::Vector desired_z = -1. * translated_base_atom.normalized();
134 core::Real arbitrary_x, arbitrary_y, arbitrary_z;
135 if ( std::abs( desired_z.z() ) > 0.01 ) {
138 arbitrary_z = -1. * ((arbitrary_x * desired_z.x()) + (arbitrary_y * desired_z.y())) / desired_z.z();
142 arbitrary_y = -1. * ((arbitrary_x * desired_z.x()) + (arbitrary_z * desired_z.z())) / desired_z.y();
144 core::Vector desired_x(arbitrary_x,arbitrary_y,arbitrary_z);
145 desired_x.normalize();
146 core::Vector desired_y = cross_product( desired_x, desired_z );
152 transformation_matrix.xx( desired_x.dot(cartesian_x) );
153 transformation_matrix.xy( desired_x.dot(cartesian_y) );
154 transformation_matrix.xz( desired_x.dot(cartesian_z) );
155 transformation_matrix.yx( desired_y.dot(cartesian_x) );
156 transformation_matrix.yy( desired_y.dot(cartesian_y) );
157 transformation_matrix.yz( desired_y.dot(cartesian_z) );
158 transformation_matrix.zx( desired_z.dot(cartesian_x) );
159 transformation_matrix.zy( desired_z.dot(cartesian_y) );
160 transformation_matrix.zz( desired_z.dot(cartesian_z) );
163 core::Vector new_base_atom_location = transformation_matrix * translated_base_atom;
164 assert( std::abs(new_base_atom_location.normalized().x()) < 0.001 );
165 assert( std::abs(new_base_atom_location.normalized().y()) < 0.001 );
166 assert( std::abs(new_base_atom_location.normalized().z() + 1.) < 0.001 );
171 neighborlist.push_back( polar_resnum);
173 neighbor_iter = graph.get_node( polar_resnum )->const_edge_list_begin(),
175 neighbor_iter != neighbor_iter_end; ++neighbor_iter ) {
176 neighborlist.push_back( (*neighbor_iter)->get_other_ind( polar_resnum ) );
179 for (
Size occ_inx = 1; occ_inx <= neighborlist.size(); ++occ_inx ) {
180 core::Size const occ_resnum( neighborlist[occ_inx] );
184 for (
Size occ_atomno = 1; occ_atomno <= occ_rsd.
natoms(); ++occ_atomno ) {
187 if ( occ_atom_is_hydrogen && ! hydrogens_can_occlude )
continue;
190 if ( polar_resnum == occ_resnum ) {
191 if ( polar_atomno == occ_atomno )
continue;
192 if ( base_atomno == occ_atomno )
continue;
196 if ( pairwise_additive ) {
200 occluded_sites[tx][ty][tz] =
false;
208 core::Vector const translated_occ_atom_xyz = orig_occ_atom_xyz + translation_vector;
209 core::Vector const transformed_occ_atom_xyz = transformation_matrix * ( orig_occ_atom_xyz + translation_vector );
212 assert( std::abs(orig_polar_atom_xyz.distance( orig_occ_atom_xyz ) - transformed_occ_atom_xyz.magnitude()) < 0.001 );
213 assert( std::abs(orig_base_atom_xyz.distance( orig_occ_atom_xyz ) - new_base_atom_location.distance( transformed_occ_atom_xyz )) < 0.001 );
216 core::Real const sq_dist_cut = ( occ_radius + water_radius ) * ( occ_radius + water_radius );
221 water_position.x() += grid_info.
xstep();
222 core::Real sq_xdist = ( water_position.x() - transformed_occ_atom_xyz.x() ) * ( water_position.x() - transformed_occ_atom_xyz.x() );
223 if ( sq_xdist > sq_dist_cut )
continue;
224 water_position.y() = grid_info.
yorigin();
226 water_position.y() += grid_info.
ystep();
227 core::Real sq_ydist = ( water_position.y() - transformed_occ_atom_xyz.y() ) * ( water_position.y() - transformed_occ_atom_xyz.y() );
228 if ( sq_ydist > sq_dist_cut )
continue;
229 water_position.z() = grid_info.
zorigin();
231 water_position.z() += grid_info.
zstep();
232 core::Real sq_zdist = ( water_position.z() - transformed_occ_atom_xyz.z() ) * ( water_position.z() - transformed_occ_atom_xyz.z() );
233 if ( sq_zdist > sq_dist_cut )
continue;
234 core::Real sq_curr_dist = sq_xdist + sq_ydist + sq_zdist;
235 if ( sq_curr_dist < sq_dist_cut ) {
237 occluded_sites[wx][wy][wz] =
true;
243 if ( pairwise_additive ) {
249 if ( occluded_sites[tx][ty][tz] ) {
250 core::Real const curr_water_weight = water_weights[tx][ty][tz];
251 sum_occluded_weights += curr_water_weight;
256 core::Real const geometric_solvation_energy = -
geosol_kT * log( 1 - ( sum_occluded_weights / grid_constant ) );
257 if ( pairwise_additive_output ) {
259 residue_energies[ polar_resnum ] += geometric_solvation_energy / 2.;
260 residue_energies[ occ_resnum ] += geometric_solvation_energy / 2.;
263 residue_energies[ polar_resnum ] += geometric_solvation_energy;
270 if ( ! pairwise_additive ) {
277 if ( occluded_sites[tx][ty][tz] ) {
278 core::Real const curr_water_weight = water_weights[tx][ty][tz];
279 sum_occluded_weights += curr_water_weight;
285 core::Real const geometric_solvation_energy = -
geosol_kT * log( 1 - ( sum_occluded_weights / grid_constant ) );
286 residue_energies[ polar_resnum ] += geometric_solvation_energy;
295 bool const hydrogens_can_occlude,
296 bool const pairwise_additive,
297 bool const pairwise_additive_output,
300 TR <<
"jk geometric solvation exact scoring" << std::endl;
302 residue_energies.clear();
309 std::vector < std::vector < std::vector <bool> > > occluded_sites;
310 occluded_sites.clear();
320 TR <<
"jk computing exact solvation scores" << std::endl;
321 for (
Size polar_resnum = 1; polar_resnum <= input_pose.
total_residue(); polar_resnum++ ) {
326 for ( chemical::AtomIndices::const_iterator
328 hnume = polar_rsd.
Hpos_polar().end(); hnum != hnume; ++hnum ) {
329 Size const polar_atom( *hnum );
338 if ( ( base_atom_name ==
" N " ) && polar_rsd.
is_lower_terminus() ) max_possible_LK /= 3;
339 if ( base_atom_name ==
" NZ " ) max_possible_LK /= 3;
340 if ( base_atom_name ==
" ND2" ) max_possible_LK /= 2;
341 if ( base_atom_name ==
" NE2" ) max_possible_LK /= 2;
342 if ( base_atom_name ==
" NH1" ) max_possible_LK /= 2;
343 if ( base_atom_name ==
" NH2" ) max_possible_LK /= 2;
351 core::Real const Ebulk_weight = ( sum_water_weights * Emax_weight ) / ( 1. - Emax_weight);
354 core::Real const grid_constant = sum_water_weights + Ebulk_weight;
358 pairwise_additive, pairwise_additive_output, residue_energies );
362 for ( chemical::AtomIndices::const_iterator
364 anume = polar_rsd.
accpt_pos().end(); anum != anume; ++anum ) {
365 Size const polar_atom( *anum );
376 core::Real const Ebulk_weight = ( sum_water_weights * Emax_weight ) / ( 1. - Emax_weight);
379 core::Real const grid_constant = sum_water_weights + Ebulk_weight;
383 pairwise_additive, pairwise_additive_output, residue_energies );
388 TR <<
"jk finished computing exact geometric solvation scores" << std::endl;
393 total_solvation_energy += residue_energies[i];
396 return total_solvation_energy;