30 #include <basic/Tracer.hh>
37 #include <basic/options/option.hh>
38 #include <basic/options/keys/rescore.OptionKeys.gen.hh>
40 #include <numeric/conversions.hh>
41 #include <utility/vector1.hh>
43 #include <ObjexxFCL/FArray2D.hh>
44 #include <ObjexxFCL/format.hh>
46 using ObjexxFCL::fmt::I;
48 static basic::Tracer
tr(
"core.scoring.rna.RNA_Mg_Energy");
76 hbond_options_( new core::scoring::hbonds::HBondOptions ),
77 verbose_( basic::options::option[ basic::options::OptionKeys::rescore::verbose ]() )
169 Vector const a = j_xyz - i_xyz;
170 Vector const b = xyz_base - i_xyz;
172 Real cos_theta = dot( a, b )/( a.length() * b.length() );
192 runtime_assert( rsd1.
is_RNA() );
193 runtime_assert( is_magnesium[ rsd2.
seqpos() ] );
195 Real score( 0.0 ), score_indirect( 0.0 );
199 runtime_assert( rsd2.
atom_name( j ) ==
"MG " );
214 bool const apply_angle_potential_(
true );
217 Distance const direct_interaction_cutoff_( 999.0 ), indirect_interaction_cutoff_( 999.0 );
221 bool is_phosphate_oxygen(
false );
222 for (
Size m = 1; m <= atom_numbers1.size(); ++m ) {
224 Size const i = atom_numbers1[ m ];
228 Distance d = ( i_xyz - j_xyz ).length();
232 Real cos_theta( -999.0 );
233 bool get_angle_form_factor =
false;
236 if ( d < direct_interaction_cutoff_ && mg_potential_gaussian_parameter.center > 0.0 ){
240 if ( get_angle_form_factor ){
244 binding_score *= angle_potential;
247 if (
verbose_ && std::abs(binding_score) > 0.1 )
tr <<
"Mg " << rsd2.
seqpos() <<
" direct to ligand " << pos1 <<
' ' << rsd1.
atom_name(i) <<
" cos_angle " << cos_theta <<
" score: " << binding_score << std::endl;
249 if (is_phosphate_oxygen) {
250 phosphate_scores.push_back( binding_score );
252 score += binding_score;
260 if ( d < indirect_interaction_cutoff_ && mg_potential_indirect_gaussian_parameter.center > 0.0 ){
262 if ( mg_potential_indirect_gaussian_parameter.
center > 0.0 ){
265 if ( get_angle_form_factor ){
267 if ( cos_theta < -1.0 ) cos_theta =
get_cos_theta( rsd1, i, i_xyz, j_xyz );
270 Real const angle_potential_indirect =
get_gaussian_score( mg_potential_costheta_indirect_gaussian_parameter, cos_theta );
271 binding_score_indirect *= angle_potential_indirect;
274 score_indirect += binding_score_indirect;
276 if (
verbose_ && std::abs(binding_score_indirect) > 0.1 )
tr <<
"Mg " << rsd2.
seqpos() <<
" indirect to ligand " << pos1 <<
' ' << rsd1.
atom_name(i) <<
" score: " << binding_score_indirect << std::endl;
285 if ( phosphate_scores.size() == 1 ) phosphate_scores.push_back( 0.0 );
287 if ( phosphate_scores.size() > 1 ){
288 runtime_assert( phosphate_scores.size() == 2 );
289 score += std::min( phosphate_scores[1], phosphate_scores[2] );
305 Vector const & pos2 )
const
308 Distance const d = ( pos1 - pos2 ).length();
321 Real const d0 = mg_potential_gaussian_parameter.
center;
322 Real const sigma = mg_potential_gaussian_parameter.
width;
324 Real const score = a * exp( -0.5 * std::pow( ( d - d0 )/sigma, 2 ) );