Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
RNA_TorsionPotential.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 /// @file core/scoring/RNA_TorsionPotential.cc
11 /// @brief RNA_TorsionPotential potential class implementation
12 /// @author Rhiju Das
13 
14 // Unit Headers
16 
17 
18 // Package Headers
20 
23 #include <core/chemical/AA.hh>
24 
25 #include <basic/options/option.hh>
26 #include <basic/options/keys/out.OptionKeys.gen.hh>
27 #include <basic/options/keys/in.OptionKeys.gen.hh>
28 #include <utility/file/file_sys_util.hh>
29 
30 // Project Headers
32 #include <basic/database/open.hh>
33 #include <core/pose/Pose.hh>
39 
40 // Numeric Headers
41 #include <numeric/angle.functions.hh>
42 #include <numeric/xyz.functions.hh>
43 #include <numeric/conversions.hh>
44 #include <numeric/deriv/dihedral_deriv.hh>
45 
46 // Utility Headers
47 #include <utility/pointer/ReferenceCount.hh>
48 
49 // ObjexxFCL Headers
50 #include <ObjexxFCL/FArray1D.hh>
51 // AUTO-REMOVED #include <ObjexxFCL/FArray2D.hh>
52 #include <ObjexxFCL/format.hh>
53 
54 #include <basic/Tracer.hh>
55 
56 //Auto Headers
57 #include <utility/vector1.hh>
58 //Auto Headers
59 #include <platform/types.hh>
61 #include <core/id/TorsionID.hh>
64 #include <utility/Bound.hh>
65 #include <utility/vector0_bool.hh>
66 #include <utility/keys/AutoKey.hh>
67 #include <utility/keys/SmallKeyVector.hh>
68 #include <utility/options/BooleanOption.hh>
69 #include <algorithm>
70 #include <cassert>
71 #include <cmath>
72 #include <complex>
73 #include <cstddef>
74 #include <cstdio>
75 #include <cstdlib>
76 #include <iomanip>
77 #include <iosfwd>
78 #include <iostream>
79 #include <istream>
80 #include <limits>
81 #include <list>
82 #include <map>
83 #include <ostream>
84 #include <set>
85 #include <sstream>
86 #include <string>
87 #include <utility>
88 #include <vector>
89 #include <basic/options/keys/score.OptionKeys.gen.hh>
90 #include <basic/options/option.hh>
91 #include <boost/bind.hpp>
92 #include <boost/function.hpp>
93 #include <boost/functional/hash.hpp>
94 
95 //Auto using namespaces
96 namespace std { } using namespace std; // AUTO USING NS
97 namespace ObjexxFCL { } using namespace ObjexxFCL; // AUTO USING NS
98 //Auto using namespaces end
99 
100 ///////////////////////////
101 
102 
103 static basic::Tracer tr( "core.scoring.rna.RNA_TorsionPotential" );
104 
105 using namespace ObjexxFCL::fmt;
106 using numeric::conversions::radians;
107 
108 namespace core {
109 namespace scoring {
110 namespace rna {
111 
112 // @brief Auto-generated virtual destructor
113 RNA_TorsionPotential::~RNA_TorsionPotential() {}
114 
115  RNA_TorsionPotential::RNA_TorsionPotential():
116  rna_tight_torsions_( true ),
117  delta_fade_( 10.0 ),
118  alpha_fade_( 10.0 ),
119  skip_chainbreak_torsions_( basic::options::option[ basic::options::OptionKeys::score::rna_torsion_skip_chainbreak ]() ),
120  verbose_( false ),
121  use_new_potential_( false ),
122  use_2prime_OH_potential_( basic::options::option[ basic::options::OptionKeys::score::use_2prime_OH_potential ]() )
123  {
124  if( basic::options::option[ basic::options::OptionKeys::score::rna_torsion_potential ].user() ){
125 
126  path_to_torsion_files_="scoring/rna/torsion_potentials/" + basic::options::option[ basic::options::OptionKeys::score::rna_torsion_potential ]();
127 
128  std::cout << "-----------------------------------------------------------------------------------" << std::endl;
129  std::cout << "USER INPUTTED path_to_torsion_files_=" << basic::database::full_name(path_to_torsion_files_) << std::endl;
130 
131 
132  //Turn on the new torsional potential if the folder name ends wirh "new"
133  if ( path_to_torsion_files_ .compare(path_to_torsion_files_.size() - 3, 3, "new") == 0 ) {
134  use_new_potential_ = true;
135  std::cout << "Path name ends with 'new'... Turn on the new torsional potential" << std::endl;
136  }
137  std::cout << "-----------------------------------------------------------------------------------" << std::endl;
138  }else{
139  //path_to_torsion_files_( "scoring/rna/torsion_potentials/rd2008/" ),
140  //path_to_torsion_files_( "scoring/rna/torsion_potentials/FINAL_Mar_24_2010_new_delta_zeta_chi/" ),
141  //path_to_torsion_files_( "scoring/rna/torsion_potentials/FINAL_April_28_OLD_syn_chi/" ),
142 
143  path_to_torsion_files_= "scoring/rna/torsion_potentials/ps_04282011/";
144 
145  std::cout << "-----------------------------------------------------------------------------------" << std::endl;
146  std::cout << "DEFAULT path_to_torsion_files_=" << basic::database::full_name(path_to_torsion_files_) << std::endl;
147  std::cout << "-----------------------------------------------------------------------------------" << std::endl;
148  }
149 
150  // init_potentials_from_gaussian_parameters();
152 
154 
155  }
156 
157  //////////////////////////////////////////////////////////////////////////
158  Real
160  {
161  using namespace core::id;
162 
163  if (!rsd.is_RNA() ) return 0.0;
164 
165  if(verbose_){
166  std::cout << std::endl;
167  std::cout << "Intra_res: " << " rsd.seqpos()= " << rsd.seqpos() << std::endl;
168  std::cout << std::endl;
169  }
170  Real score( 0.0 );
171 
172  Real const beta= numeric::principal_angle_degrees( rsd.mainchain_torsion( BETA ) );
173  Real const gamma= numeric::principal_angle_degrees( rsd.mainchain_torsion( GAMMA ) );
174  Real const delta= numeric::principal_angle_degrees( rsd.mainchain_torsion( DELTA ) );
175  Real const chi= numeric::principal_angle_degrees( rsd.chi( CHI - NUM_RNA_MAINCHAIN_TORSIONS ) );
176  Real const nu2= numeric::principal_angle_degrees( rsd.chi( NU2 - NUM_RNA_MAINCHAIN_TORSIONS ) );
177  Real const nu1= numeric::principal_angle_degrees( rsd.chi( NU1 - NUM_RNA_MAINCHAIN_TORSIONS ) );
178  Real const o2h = numeric::principal_angle_degrees( rsd.chi( O2H - NUM_RNA_MAINCHAIN_TORSIONS ) );
179 
180  if(verbose_) std::cout << "Beta torsion" << std::endl;
181 
182  if(Should_score_torsion(pose, TorsionID( rsd.seqpos(), id::BB, BETA ) ) ) {
183  score += beta_potential_->func( beta ); //beta
184  }
185 
186  if(verbose_) std::cout << "Gamma torsion" << std::endl;
187 
188  if(Should_score_torsion(pose, TorsionID( rsd.seqpos(), id::BB, GAMMA ) ) ) {
189  score += gamma_potential_->func( gamma ); //gamma
190  }
191 
192  if(verbose_) std::cout << "Delta torsion" << std::endl;
193 
194 
195  if(Should_score_torsion(pose, TorsionID( rsd.seqpos(), id::BB, DELTA ) ) ) {
196  score += ( fade_delta_north_->func( delta ) * delta_north_potential_->func( delta ) +
197  fade_delta_south_->func( delta ) * delta_south_potential_->func( delta ) ); //delta
198  }
199 
200  if(verbose_) std::cout << "Chi torsion" << std::endl;
201 
203  if (use_new_potential_) {
204  if ( rsd.aa() == core::chemical::na_rgu || rsd.aa() == core::chemical::na_rad ) {
205  score += ( fade_delta_north_->func( delta ) * chi_purine_north_potential_->func( chi ) +
206  fade_delta_south_->func( delta ) * chi_purine_south_potential_->func( chi ) ); //chi
207  }else{
208  score += ( fade_delta_north_->func( delta ) * chi_pyrimidine_north_potential_->func( chi ) +
209  fade_delta_south_->func( delta ) * chi_pyrimidine_south_potential_->func( chi ) ); //chi
210  }
211  } else {
212  if ( rsd.aa() == core::chemical::na_rgu ) {
213  score += ( fade_delta_north_->func( delta ) * chi_north_potential_guanosine_->func( chi ) +
214  fade_delta_south_->func( delta ) * chi_south_potential_guanosine_->func( chi ) ); //chi
215  }else{
216  score += ( fade_delta_north_->func( delta ) * chi_north_potential_others_->func( chi ) +
217  fade_delta_south_->func( delta ) * chi_south_potential_others_->func( chi ) ); //chi
218  }
219  }
220  }
221 
222  if(verbose_) std::cout << "nu2 torsion" << std::endl;
223 
225  score += ( fade_delta_north_->func( delta ) * nu2_north_potential_->func( nu2 ) +
226  fade_delta_south_->func( delta ) * nu2_south_potential_->func( nu2 ) ); //nu2
227  }
228 
229  if(verbose_) std::cout << "nu1 torsion" << std::endl;
230 
232  score += ( fade_delta_north_->func( delta ) * nu1_north_potential_->func( nu1 ) +
233  fade_delta_south_->func( delta ) * nu1_south_potential_->func( nu1 ) ); //nu1
234  }
235 
237  score += ( fade_delta_north_->func( delta ) * o2h_north_potential_->func( o2h ) +
238  fade_delta_south_->func( delta ) * o2h_south_potential_->func( o2h ) ); //o2h
239  }
240 
241  return score;
242 
243  }
244 
245  //////////////////////////////////////////////////////////////////////////
246  Real
248  {
249 
250  using namespace core::id;
251 
252  // CAN WE ASSUME rsd1 < rsd2 ???
253 
254 //THESE ASSERTION FAIL!! TRY RERUN ~/minirosetta/test/Mar_27_torsion_potential_fix/1zih/new_RNA_TorssionPotential/trail_2/output.txt
255 // if((rsd1.seqpos() < rsd2.seqpos())==false){
256 // std::cout << "rsd1.seqpos()= " << rsd1.seqpos() << " rsd2.seqpos()= " << rsd2.seqpos() << std::endl;
257 // utility_exit_with_message( "(rsd1.seqpos() < rsd2.seqpos())==false" );
258 // }
259 
260 // assert( rsd1.seqpos() < rsd2.seqpos() );
261 
262  if ( rsd1.seqpos() != (rsd2.seqpos() - 1) ) return 0.0;
263  if (!rsd1.is_RNA() ) return 0.0;
264  if (!rsd2.is_RNA() ) return 0.0;
265 
266  if(verbose_) {
267  std::cout << std::endl;
268  std::cout << "Between_res= " << " rsd1.seqpos()= " << rsd1.seqpos() << " rsd2.seqpos()= " << rsd2.seqpos() << std::endl;
269  std::cout << std::endl;
270  }
271 
272  Real score( 0.0 );
273 
274  Real const delta= numeric::principal_angle_degrees( rsd1.mainchain_torsion( DELTA ) );
275  Real const epsilon= numeric::principal_angle_degrees( rsd1.mainchain_torsion( EPSILON ) );
276  Real const zeta= numeric::principal_angle_degrees( rsd1.mainchain_torsion( ZETA ) );
277  Real const next_alpha= numeric::principal_angle_degrees( rsd2.mainchain_torsion( ALPHA ) );
278 
279  if(verbose_) std::cout << "epsilon torsion" << std::endl;
280 
281  if(Should_score_torsion(pose, TorsionID( rsd1.seqpos(), id::BB, EPSILON ) ) ) {
282  score += ( fade_delta_north_->func( delta ) * epsilon_north_potential_->func( epsilon ) +
283  fade_delta_south_->func( delta ) * epsilon_south_potential_->func( epsilon ) );
284  }
285 
286  if(verbose_) std::cout << "zeta torsion" << std::endl;
287 
288  if(Should_score_torsion(pose, TorsionID( rsd1.seqpos(), id::BB, ZETA ) ) ) {
289  score += ( fade_alpha_sc_minus_->func( next_alpha ) * zeta_alpha_sc_minus_potential_->func( zeta ) +
290  fade_alpha_sc_plus_->func( next_alpha ) * zeta_alpha_sc_plus_potential_->func( zeta ) +
291  fade_alpha_ap_->func( next_alpha ) * zeta_alpha_ap_potential_->func( zeta ) );
292  }
293 
294  if(verbose_) std::cout << "next alpha torsion" << std::endl;
295 
296  if(Should_score_torsion(pose, TorsionID( rsd2.seqpos(), id::BB, ALPHA ) ) ) {
297  score += alpha_potential_->func( next_alpha );
298  }
299 
300  return score;
301  }
302 
303  ///////////////////////////////////////////////////////////////////////////////////////
304  bool
305  RNA_TorsionPotential::get_f1_f2( core::id::TorsionID const & torsion_id, pose::Pose const & pose, core::id::AtomID const & id, Vector & f1, Vector & f2 ) const
306  {
307 
308  conformation::Conformation const & conformation( pose.conformation() );
309 
310  if ( !pose.residue_type( torsion_id.rsd() ).is_RNA() ) return false;
311 
312  // Check that torsion is intraresidue.
313  id::AtomID id1,id2,id3,id4;
314  if ( conformation.get_torsion_angle_atom_ids( torsion_id, id1, id2, id3, id4 ) ) return false;
315 
316  //Kinda hacky, but most succinct this way
317  if(verbose_) {
318  tr.Info << "In get_f1_f2_function: ";
319  tr.Info << " atom_id: " << id << std::endl;
320  }
321  if(Should_score_torsion(pose, torsion_id)==false) return false;
322 
323  Real theta( 0.0 );
324  // copied from DihedralConstraint. Better work, damnit.
325  if ( id == id1 ) {
326  numeric::deriv::dihedral_p1_cosine_deriv( conformation.xyz( id1 ),conformation.xyz( id2 ),
327  conformation.xyz( id3 ),conformation.xyz( id4 ), theta, f1, f2 );
328  } else if ( id == id2 ) {
329  numeric::deriv::dihedral_p2_cosine_deriv( conformation.xyz( id1 ),conformation.xyz( id2 ),
330  conformation.xyz( id3 ),conformation.xyz( id4 ), theta, f1, f2 );
331  } else if ( id == id3 ) {
332  numeric::deriv::dihedral_p2_cosine_deriv( conformation.xyz( id4 ),conformation.xyz( id3 ),
333  conformation.xyz( id2 ),conformation.xyz( id1 ), theta, f1, f2 );
334  } else if ( id == id4 ) {
335  numeric::deriv::dihedral_p1_cosine_deriv( conformation.xyz( id4 ),conformation.xyz( id3 ),
336  conformation.xyz( id2 ),conformation.xyz( id1 ), theta, f1, f2 );
337  } else {
338  return false;
339  }
340  return true;
341  }
342 
343  //////////////////////////////////////////////////////////////
344  void
346  id::AtomID const & id,
347  pose::Pose const & pose,
348  EnergyMap const & weights,
349  Vector & F1,
350  Vector & F2
351  ) const{
352 
353  Real const radians2degrees = 1.0 / radians( 1.0 );
354 
355  Size const current_seqpos( id.rsd() );
356  Size const nres( pose.total_residue() );
357 
358  // Look for torsions in current, previous, and next residues that might match up with this atom_id.
359  // This isn't totally efficient, but the extra checks should not be rate limiting...
360  for ( int offset = -1; offset <= +1; offset++ ) {
361 
362  Size const seqpos = current_seqpos + offset;
363 
364  if (seqpos < 1 ) continue;
365  if (seqpos > nres ) continue;
366  if ( !pose.residue_type( seqpos ).is_RNA() ) continue;
367 
368  conformation::Residue const & rsd( pose.residue( seqpos ) );
369 
370  Real const alpha= numeric::principal_angle_degrees( rsd.mainchain_torsion( ALPHA ) );
371  Real const beta = numeric::principal_angle_degrees( rsd.mainchain_torsion( BETA ) );
372  Real const gamma= numeric::principal_angle_degrees( rsd.mainchain_torsion( GAMMA ) );
373  Real const delta= numeric::principal_angle_degrees( rsd.mainchain_torsion( DELTA ) );
374  Real const epsilon= numeric::principal_angle_degrees( rsd.mainchain_torsion( EPSILON ) );
375  Real const zeta= numeric::principal_angle_degrees( rsd.mainchain_torsion( ZETA ) );
376  Real const chi = numeric::principal_angle_degrees( rsd.chi( CHI - NUM_RNA_MAINCHAIN_TORSIONS ) );
377  Real const nu2 = numeric::principal_angle_degrees( rsd.chi( NU2 - NUM_RNA_MAINCHAIN_TORSIONS ) );
378  Real const nu1 = numeric::principal_angle_degrees( rsd.chi( NU1 - NUM_RNA_MAINCHAIN_TORSIONS ) );
379  Real const o2h = numeric::principal_angle_degrees( rsd.chi( O2H - NUM_RNA_MAINCHAIN_TORSIONS ) );
380 
381  Vector f1( 0.0 ), f2( 0.0 );
382 
383  ///////////////////////////////ALPHA//////////////////////////////
384  if ( seqpos > 1 && pose.residue( seqpos - 1 ).is_RNA() && get_f1_f2( id::TorsionID( seqpos, id::BB, ALPHA ), pose, id, f1, f2 ) ){
385 
386  Real dE_dtorsion = alpha_potential_->dfunc( alpha );
387 
388  Real const previous_zeta = numeric::principal_angle_degrees( pose.residue( seqpos - 1 ).mainchain_torsion( ZETA ) ); ///NEED TO CHANGE THIS AS WELL
389  dE_dtorsion += ( fade_alpha_sc_minus_->dfunc( alpha ) * zeta_alpha_sc_minus_potential_->func( previous_zeta ) +
390  fade_alpha_sc_plus_->dfunc( alpha ) * zeta_alpha_sc_plus_potential_->func( previous_zeta ) +
391  fade_alpha_ap_->dfunc( alpha ) * zeta_alpha_ap_potential_->func( previous_zeta ) );
392 
393  F1 += radians2degrees * dE_dtorsion * weights[ rna_torsion ] * f1;
394  F2 += radians2degrees * dE_dtorsion * weights[ rna_torsion ] * f2;
395  }
396 
397  /////////////////////////////////Beta/////////////////////////////////////////////////////////
398  if ( get_f1_f2( id::TorsionID( seqpos, id::BB, BETA ), pose, id, f1, f2 ) ){
399  Real const dE_dtorsion = beta_potential_->dfunc( beta );
400 
401  F1 += radians2degrees * dE_dtorsion * weights[ rna_torsion ] * f1;
402  F2 += radians2degrees * dE_dtorsion * weights[ rna_torsion ] * f2;
403  }
404 
405  /////////////////////////////////Gamma/////////////////////////////////////////////////////////
406  if ( get_f1_f2( id::TorsionID( seqpos, id::BB, GAMMA ), pose, id, f1, f2 ) ){
407  Real const dE_dtorsion = gamma_potential_->dfunc( gamma );
408 
409  F1 += radians2degrees * dE_dtorsion * weights[ rna_torsion ] * f1;
410  F2 += radians2degrees * dE_dtorsion * weights[ rna_torsion ] * f2;
411  }
412 
413  /////////////////////////////////Delta////////////////////////////////////////////////////////
414  if ( get_f1_f2( id::TorsionID( seqpos, id::BB, DELTA ), pose, id, f1, f2 ) ){
415  Real dE_dtorsion = ( fade_delta_north_->dfunc( delta ) * delta_north_potential_->func( delta ) +
416  fade_delta_north_->func( delta ) * delta_north_potential_->dfunc( delta ) +
417  fade_delta_south_->dfunc( delta ) * delta_south_potential_->func( delta ) +
418  fade_delta_south_->func( delta ) * delta_south_potential_->dfunc( delta ) );
419 
420  if (use_new_potential_) {
421  if ( rsd.aa() == core::chemical::na_rgu || rsd.aa() == core::chemical::na_rad ) {
422  dE_dtorsion += ( fade_delta_north_->dfunc( delta ) * chi_purine_north_potential_->func( chi ) +
423  fade_delta_south_->dfunc( delta ) * chi_purine_south_potential_->func( chi ) );
424  }else{
425  dE_dtorsion += ( fade_delta_north_->dfunc( delta ) * chi_pyrimidine_north_potential_->func( chi ) +
426  fade_delta_south_->dfunc( delta ) * chi_pyrimidine_south_potential_->func( chi ) );
427  }
428  } else {
429  if ( rsd.aa() == core::chemical::na_rgu ) {
430  dE_dtorsion += ( fade_delta_north_->dfunc( delta ) * chi_north_potential_guanosine_->func( chi ) +
431  fade_delta_south_->dfunc( delta ) * chi_south_potential_guanosine_->func( chi ) );
432  }else{
433  dE_dtorsion += ( fade_delta_north_->dfunc( delta ) * chi_north_potential_others_->func( chi ) +
434  fade_delta_south_->dfunc( delta ) * chi_south_potential_others_->func( chi ) );
435  }
436  }
437 
438  dE_dtorsion += ( fade_delta_north_->dfunc( delta ) * nu2_north_potential_->func( nu2 ) +
439  fade_delta_south_->dfunc( delta ) * nu2_south_potential_->func( nu2 ) );
440 
441  dE_dtorsion += ( fade_delta_north_->dfunc( delta ) * nu1_north_potential_->func( nu1 ) +
442  fade_delta_south_->dfunc( delta ) * nu1_south_potential_->func( nu1 ) );
443 
444  if ( seqpos < nres && pose.residue( seqpos+1 ).is_RNA() ){
445  dE_dtorsion += ( fade_delta_north_->dfunc( delta ) * epsilon_north_potential_->func( epsilon ) +
446  fade_delta_south_->dfunc( delta ) * epsilon_south_potential_->func( epsilon ) );
447  }
448 
449  F1 += radians2degrees * dE_dtorsion * weights[ rna_torsion ] * f1;
450  F2 += radians2degrees * dE_dtorsion * weights[ rna_torsion ] * f2;
451  }
452 
453  ////////////////////////////////////EPSILON////////////////////////////////////////////////
454  if ( seqpos < nres && pose.residue( seqpos+1 ).is_RNA() && get_f1_f2( id::TorsionID( seqpos, id::BB, EPSILON ), pose, id, f1, f2 ) ){
455  Real const dE_dtorsion = ( fade_delta_north_->func( delta ) * epsilon_north_potential_->dfunc( epsilon ) +
456  fade_delta_south_->func( delta ) * epsilon_south_potential_->dfunc( epsilon ) );
457 
458  F1 += radians2degrees * dE_dtorsion * weights[ rna_torsion ] * f1;
459  F2 += radians2degrees * dE_dtorsion * weights[ rna_torsion ] * f2;
460  }
461 
462  ////////////////////////////////////ZETA////////////////////////////////////////////////
463  if ( seqpos < nres && pose.residue( seqpos+1 ).is_RNA() && get_f1_f2( id::TorsionID( seqpos, id::BB, ZETA ), pose, id, f1, f2 ) ){
464 
465  Real const next_alpha = numeric::principal_angle_degrees( pose.residue( seqpos+1 ).mainchain_torsion( ALPHA ) ); ///NEED TO CHANGE THIS AS WELL
466  Real const dE_dtorsion = ( fade_alpha_sc_minus_->func( next_alpha ) * zeta_alpha_sc_minus_potential_->dfunc( zeta ) +
467  fade_alpha_sc_plus_->func( next_alpha ) * zeta_alpha_sc_plus_potential_->dfunc( zeta ) +
468  fade_alpha_ap_->func( next_alpha ) * zeta_alpha_ap_potential_->dfunc( zeta ) );
469 
470  F1 += radians2degrees * dE_dtorsion * weights[ rna_torsion ] * f1;
471  F2 += radians2degrees * dE_dtorsion * weights[ rna_torsion ] * f2;
472  }
473 
474  /////////////////////////////////////CHI///////////////////////////////////////////////////
475  if ( get_f1_f2( id::TorsionID( seqpos, id::CHI, CHI - NUM_RNA_MAINCHAIN_TORSIONS ), pose, id, f1, f2 ) ){
476 
477  Real dE_dtorsion;
478 
479  if (use_new_potential_) {
480  if ( rsd.aa() == core::chemical::na_rgu || rsd.aa() == core::chemical::na_rad ) {
481  dE_dtorsion = ( fade_delta_north_->func( delta ) * chi_purine_north_potential_->dfunc( chi ) +
482  fade_delta_south_->func( delta ) * chi_purine_south_potential_->dfunc( chi ) );
483  } else {
484  dE_dtorsion = ( fade_delta_north_->func( delta ) * chi_pyrimidine_north_potential_->dfunc( chi ) +
485  fade_delta_south_->func( delta ) * chi_pyrimidine_south_potential_->dfunc( chi ) );
486  }
487  } else {
488  if ( rsd.aa() == core::chemical::na_rgu ) {
489  dE_dtorsion = ( fade_delta_north_->func( delta ) * chi_north_potential_guanosine_->dfunc( chi ) +
490  fade_delta_south_->func( delta ) * chi_south_potential_guanosine_->dfunc( chi ) );
491 
492  } else {
493  dE_dtorsion = ( fade_delta_north_->func( delta ) * chi_north_potential_others_->dfunc( chi ) +
494  fade_delta_south_->func( delta ) * chi_south_potential_others_->dfunc( chi ) );
495  }
496  }
497 
498  F1 += radians2degrees * dE_dtorsion * weights[ rna_torsion ] * f1;
499  F2 += radians2degrees * dE_dtorsion * weights[ rna_torsion ] * f2;
500  }
501 
502  /////////////////////////////////////NU2//////////////////////////////////////////////////////
503  if ( get_f1_f2( id::TorsionID( seqpos, id::CHI, NU2 - NUM_RNA_MAINCHAIN_TORSIONS ), pose, id, f1, f2 ) ){
504  Real const dE_dtorsion = ( fade_delta_north_->func( delta ) * nu2_north_potential_->dfunc( nu2 ) +
505  fade_delta_south_->func( delta ) * nu2_south_potential_->dfunc( nu2 ) );
506 
507  F1 += radians2degrees * dE_dtorsion * weights[ rna_torsion ] * f1;
508  F2 += radians2degrees * dE_dtorsion * weights[ rna_torsion ] * f2;
509  }
510 
511  /////////////////////////////////////NU1//////////////////////////////////////////////////////
512  if ( get_f1_f2( id::TorsionID( seqpos, id::CHI, NU1 - NUM_RNA_MAINCHAIN_TORSIONS ), pose, id, f1, f2 ) ){
513  Real const dE_dtorsion = ( fade_delta_north_->func( delta ) * nu1_north_potential_->dfunc( nu1 ) +
514  fade_delta_south_->func( delta ) * nu1_south_potential_->dfunc( nu1 ) );
515 
516  F1 += radians2degrees * dE_dtorsion * weights[ rna_torsion ] * f1;
517  F2 += radians2degrees * dE_dtorsion * weights[ rna_torsion ] * f2;
518  }
519 
520  /////////////////////////////////O2H/////////////////////////////////////////////////////////
522  get_f1_f2( id::TorsionID( seqpos, id::CHI, O2H - NUM_RNA_MAINCHAIN_TORSIONS ), pose, id, f1, f2 ) ){
523  Real const dE_dtorsion = ( fade_delta_north_->func( delta ) * o2h_north_potential_->dfunc( o2h ) +
524  fade_delta_south_->func( delta ) * o2h_south_potential_->dfunc( o2h ) );
525 
526  F1 += radians2degrees * dE_dtorsion * weights[ rna_torsion ] * f1;
527  F2 += radians2degrees * dE_dtorsion * weights[ rna_torsion ] * f2;
528  }
529  }
530  }
531 
532 
533  ////////////////////////////////////////////////////////////////////////////////////////
534  bool
535  RNA_TorsionPotential::check_intra_residue( id::TorsionID const & torsion_id, pose::Pose const & pose, Size const seqpos ) const{
536 
537  // Check that torsion is intraresidue.
538  id::AtomID id1,id2,id3,id4;
539  bool fail = pose.conformation().get_torsion_angle_atom_ids( torsion_id, id1, id2, id3, id4 );
540  if (fail) return false;
541 
542  if ( id1.rsd() != seqpos ) return false;
543  if ( id2.rsd() != seqpos ) return false;
544  if ( id3.rsd() != seqpos ) return false;
545  if ( id4.rsd() != seqpos ) return false;
546 
547  return true;
548  }
549 
550  ///////////////////////////////////////////////////////////////////////////////////////
551  void
553 
554  // Initialize potential functions.
555  initialize_potential_from_file( alpha_potential_, "alpha_potential.txt" );
556  initialize_potential_from_file( beta_potential_, "beta_potential.txt" );
557  initialize_potential_from_file( gamma_potential_, "gamma_potential.txt" );
558  initialize_potential_from_file( delta_north_potential_, "delta_north_potential.txt" );
559  initialize_potential_from_file( delta_south_potential_, "delta_south_potential.txt" );
560  initialize_potential_from_file( epsilon_north_potential_, "epsilon_north_potential.txt" );
561  initialize_potential_from_file( epsilon_south_potential_, "epsilon_south_potential.txt" );
562  initialize_potential_from_file( zeta_alpha_sc_minus_potential_, "zeta_alpha_sc_minus_potential.txt" );
563  initialize_potential_from_file( zeta_alpha_sc_plus_potential_, "zeta_alpha_sc_plus_potential.txt" );
564  initialize_potential_from_file( zeta_alpha_ap_potential_, "zeta_alpha_ap_potential.txt" );
565  initialize_potential_from_file( nu2_north_potential_, "nu2_north_potential.txt" );
566  initialize_potential_from_file( nu2_south_potential_, "nu2_south_potential.txt" );
567  initialize_potential_from_file( nu1_north_potential_, "nu1_north_potential.txt" );
568  initialize_potential_from_file( nu1_south_potential_, "nu1_south_potential.txt" );
569 
570  if (use_new_potential_) {
571  initialize_potential_from_file( chi_purine_north_potential_, "chi_purine_north_potential.txt" );
572  initialize_potential_from_file( chi_purine_south_potential_, "chi_purine_south_potential.txt" );
573  initialize_potential_from_file( chi_pyrimidine_north_potential_, "chi_pyrimidine_north_potential.txt" );
574  initialize_potential_from_file( chi_pyrimidine_south_potential_, "chi_pyrimidine_south_potential.txt" );
575  initialize_potential_from_file( o2h_north_potential_, "o2h_north_potential.txt" );
576  initialize_potential_from_file( o2h_south_potential_, "o2h_south_potential.txt" );
577  } else {
578  initialize_potential_from_file( chi_north_potential_guanosine_, "chi_north_potential_guanosine.txt" );
579  initialize_potential_from_file( chi_south_potential_guanosine_, "chi_south_potential_guanosine.txt" );
580  initialize_potential_from_file( chi_north_potential_others_, "chi_north_potential_others.txt" );
581  initialize_potential_from_file( chi_south_potential_others_, "chi_south_potential_others.txt" );
582  }
583 
584  }
585 
586  ///////////////////////////////////////////////////////////////////////////////////////
587  void
589  std::string const & filename ) {
590 
591  std::string const full_filename = basic::database::full_name( path_to_torsion_files_ + "/"+filename );
592 
593  //std::cout << "full_torsional_potential_filename= " << full_filename << std::endl;
594  if(utility::file::file_exists( full_filename )==false){
595  utility_exit_with_message( "full_torsional_potential_filename " + full_filename + " doesn't exist!" );
596  }
597 
598  func = new core::scoring::constraints::CircularGeneral1D_Func( full_filename );
599 
600  }
601 
602 
603  ///////////////////////////////////////////////////////////////////////////////////////
604  void
606  {
607 
608  using namespace scoring::constraints;
609 
610  RNA_FittedTorsionInfo rna_torsion_fitted_info;
611  Real const DELTA_CUTOFF_ = rna_torsion_fitted_info.delta_cutoff();
612 
613  // FadeFunc initialized with min, max, fade-width, and function value.
615  -180.0 -delta_fade_,
616  DELTA_CUTOFF_ + 0.5*delta_fade_ ,
617  delta_fade_ ,
618  1.0 );
620  DELTA_CUTOFF_ - 0.5*delta_fade_,
621  180.0 +delta_fade_ ,
622  delta_fade_ ,
623  1.0 );
624 
625 
626  // FadeFunc initialized with min, max, fade-width, and function value.
628  -120.0 - 0.5 * alpha_fade_ ,
629  0.0 + 0.5 * alpha_fade_ ,
630  alpha_fade_ ,
631  1.0 );
633  0.0 - 0.5 * alpha_fade_ ,
634  100.0 + 0.5 * alpha_fade_ ,
635  alpha_fade_ ,
636  1.0 );
637 
638  fade_alpha_ap_ = new SumFunc();
639  fade_alpha_ap_->add_func(
640  new FadeFunc(
641  -180.0 - alpha_fade_ ,
642  -120.0 + 0.5 * alpha_fade_ ,
643  alpha_fade_ ,
644  1.0 ) );
645 
646  fade_alpha_ap_->add_func(
647  new FadeFunc(
648  100.0 - 0.5 * alpha_fade_ ,
649  180.0 + alpha_fade_ ,
650  alpha_fade_ ,
651  1.0 ) );
652  }
653 
654  //HACKY /////////////////////////////////////////////////////////////////////////////////////////
655  void
656  RNA_TorsionPotential::Output_boolean(std::string const & tag, bool boolean) const {
657 
658  using namespace ObjexxFCL;
659  using namespace ObjexxFCL::fmt;
660  std::cout << tag;
661 
662  if(boolean==true){
663  std::cout << A(4,"T");
664  } else {
665  std::cout << A(4,"F");
666  }
667  }
668  /////////////////////////////////////////////////////////////////////////////////////////
669  bool
671  std::string const & atom_name=rsd.type().atom_name(id.atomno());
672 
673  if(atom_name=="OVU1" || atom_name=="OVL1" || atom_name=="OVL2"){
674  return true;
675  }else{
676  return false;
677  }
678 
679  }
680  /////////////////////////////////////////////////////////////////////////////////////////
681  bool
683  {
684  using namespace ObjexxFCL;
685 
686  Size torsion_seq_num=torsion_id.rsd();
687  Size lower_seq_num=0;
688  Size upper_seq_num=0;
689 
690 
691  if ( torsion_id.type() != id::BB) return false;
692 
693  if ( torsion_id.torsion() == ALPHA){ //COULD BE A UPPER RESIDUE OF A CHAIN_BREAK_CLOSE
694 
695  lower_seq_num=torsion_seq_num-1;
696  upper_seq_num=torsion_seq_num;
697 
698  }else if(torsion_id.torsion() == EPSILON || torsion_id.torsion() == ZETA){
699  lower_seq_num=torsion_seq_num;
700  upper_seq_num=torsion_seq_num+1;
701  }else{
702  if( torsion_id.torsion()!=DELTA && torsion_id.torsion() != BETA && torsion_id.torsion() != GAMMA){
703  utility_exit_with_message("The torsion should be DELTA(lower), BETA(upper) or GAMMA(upper) !!" );
704  }
705  return false;
706  }
707 
708  if(upper_seq_num==1) return false;
709 
710  if(lower_seq_num==pose.total_residue()) return false;
711 
712  if(pose.residue( lower_seq_num ).has_variant_type( chemical::CUTPOINT_LOWER ) ){
713  if( pose.residue( upper_seq_num ).has_variant_type( chemical::CUTPOINT_UPPER )==false ){
714  utility_exit_with_message("seq_num " + string_of(lower_seq_num) + " is a CUTPOINT_LOWER but seq_num " + string_of(upper_seq_num) + " is not a cutpoint CUTPOINT_UPPER??" );
715  }
716  return true;
717  }
718 
719  return false;
720  }
721 
722 
723  ///////////////////////////////////////////////Dec 26, 2010//////////////////////////////////////////////////////////
724  void
725  RNA_TorsionPotential::print_torsion_info(pose::Pose const & pose, id::TorsionID const & torsion_id) const
726  {
727 
728  id::AtomID id1,id2,id3,id4;
729  pose.conformation().get_torsion_angle_atom_ids( torsion_id, id1, id2, id3, id4 );
730 
731  std::cout << "torsion_id: " << torsion_id << std::endl;
732 
733  bool fail = pose.conformation().get_torsion_angle_atom_ids( torsion_id, id1, id2, id3, id4 );
734  if (fail){
735  std::cout << "fail to get torsion!, perhap this torsion is located at a chain_break " << std::endl;
736  return;
737  }
738 
739  conformation::Residue const & rsd_1=pose.residue(id1.rsd());
740  conformation::Residue const & rsd_2=pose.residue(id2.rsd());
741  conformation::Residue const & rsd_3=pose.residue(id3.rsd());
742  conformation::Residue const & rsd_4=pose.residue(id4.rsd());
743 
744  tr.Info << " Torsion containing one or more virtual atom(s)" << std::endl;
745  tr.Info << " torsion_id: " << torsion_id;
746  tr.Info << " atom_id: " << id1 << " " << id2 << " " << id3 << " " << id4 << std::endl;
747  tr.Info << " name: " << rsd_1.type().atom_name(id1.atomno()) << " " << rsd_2.type().atom_name(id2.atomno()) << " " << rsd_3.type().atom_name(id3.atomno()) << " " << rsd_4.type().atom_name(id4.atomno()) << std::endl;
748  tr.Info << " type: " << rsd_1.atom_type(id1.atomno()).name() << " " << rsd_2.atom_type(id2.atomno()).name() << " " << rsd_3.atom_type(id3.atomno()).name() << " " << rsd_4.atom_type(id4.atomno()).name() << std::endl;
749  tr.Info << " atom_type_index: " << rsd_1.atom_type_index( id1.atomno()) << " " << rsd_2.atom_type_index( id2.atomno()) << " " << rsd_3.atom_type_index( id3.atomno()) << " " << rsd_4.atom_type_index( id4.atomno()) << std::endl;
750  tr.Info << " atomic_charge: " << rsd_1.atomic_charge( id1.atomno()) << " " << rsd_2.atomic_charge( id2.atomno()) << " " << rsd_3.atomic_charge( id3.atomno()) << " " << rsd_4.atomic_charge( id4.atomno()) << std::endl;
751 
752 
753  }
754  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
755 
756  bool
758  {
759 
760  id::AtomID id1,id2,id3,id4;
761  pose.conformation().get_torsion_angle_atom_ids( torsion_id, id1, id2, id3, id4 );
762 
763  if(verbose_) std::cout << "torsion_id: " << torsion_id << std::endl;
764 
765  bool fail = pose.conformation().get_torsion_angle_atom_ids( torsion_id, id1, id2, id3, id4 );
766  if (fail){
767  if(verbose_) std::cout << "fail to get torsion!, perhap this torsion is located at a chain_break " << std::endl;
768  return false;
769  }
770 
771  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
772  conformation::Residue const & rsd_1=pose.residue(id1.rsd());
773  conformation::Residue const & rsd_2=pose.residue(id2.rsd());
774  conformation::Residue const & rsd_3=pose.residue(id3.rsd());
775  conformation::Residue const & rsd_4=pose.residue(id4.rsd());
776 
777  if ( !rsd_1.is_RNA() || !rsd_2.is_RNA() || !rsd_3.is_RNA() || !rsd_4.is_RNA() ) return false; //Rhiju's added this between r47018 and r46616
778  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
779 
780  bool Is_virtual_torsion=( rsd_1.is_virtual(id1.atomno()) || rsd_2.is_virtual(id2.atomno()) || rsd_3.is_virtual(id3.atomno()) || rsd_4.is_virtual(id4.atomno()) );
781 
782  if(Is_virtual_torsion && verbose_) print_torsion_info(pose, torsion_id);
783 
784 
785  /////////////////////Check for cutpoint_closed (Since these torsions will contain virtual atom(s), but want to score these torsions!///////////////////////////////
786  //Method 1:
787  bool const METHOD_ONE_Is_cutpoint_closed_torsion = Is_cutpoint_closed_torsion(pose, torsion_id);
788 
789  //Method 2:
790  bool const METHOD_TWO_Is_cutpoint_closed_torsion = ( Is_cutpoint_closed_atom(rsd_1, id1) || Is_cutpoint_closed_atom(rsd_2, id2) || Is_cutpoint_closed_atom(rsd_3, id3) || Is_cutpoint_closed_atom(rsd_4, id4) );
791 
792 
793  if( METHOD_ONE_Is_cutpoint_closed_torsion != METHOD_TWO_Is_cutpoint_closed_torsion){
794  Output_boolean(" METHOD_ONE_Is_cutpoint_closed_torsion= ", METHOD_ONE_Is_cutpoint_closed_torsion);
795  Output_boolean(" METHOD_TWO_Is_cutpoint_closed_torsion= ", METHOD_TWO_Is_cutpoint_closed_torsion);
796  Output_boolean(" Is_virtual_torsion= ", Is_virtual_torsion); std::cout << std::endl;
797 
798  print_torsion_info(pose, torsion_id);
799 
800  utility_exit_with_message( "METHOD_ONE_Is_cutpoint_closed_torsion != METHOD_TWO_Is_cutpoint_closed_torsion !!" );
801  }
802 
803  if( METHOD_ONE_Is_cutpoint_closed_torsion==true && Is_virtual_torsion==false ){
804 
805  print_torsion_info(pose, torsion_id);
806 
807  utility_exit_with_message( "METHOD_ONE_Is_cutpoint_closed_torsion==true && Is_virtual_torsion==false !!" );
808  }
809 
810 
811  ////////////////////////////////////////////////Jan 19, 2012: New code//////////////////////////////////////////
812  if(rsd_1.seqpos()>rsd_2.seqpos()) utility_exit_with_message("rsd_1.seqpos()>rsd_2.seqpos()");
813  if(rsd_2.seqpos()>rsd_3.seqpos()) utility_exit_with_message("rsd_1.seqpos()>rsd_2.seqpos()");
814  if(rsd_3.seqpos()>rsd_4.seqpos()) utility_exit_with_message("rsd_1.seqpos()>rsd_2.seqpos()");
815 
816  if( (rsd_1.seqpos()!=rsd_4.seqpos()) && (rsd_1.seqpos()!=(rsd_4.seqpos()-1)) ){
817  utility_exit_with_message("(rsd_1.seqpos()!=rsd_4.seqpos()) && (rsd_1.seqpos()!=(rsd_4.seqpos()-1))");
818  }
819 
820  bool const inter_residue_torsion= (rsd_1.seqpos()!=rsd_4.seqpos());
821 
822  bool Is_chain_break_torsion=false;
823 
824  if(inter_residue_torsion){
825 
826  //Note that chain_break_torsion does not neccessarily have to be located at a cutpoint_open. For example, in RNA might contain multiple strands, but the user not have specified them as cutpoint_open
827  //This happen frequently, for example when modeling single-stranded RNA loop (PNAS December 20, 2011 vol. 108 no. 51 20573-20578).
828  //Actually if chain_break is cutpoint_open, pose.conformation().get_torsion_angle_atom_ids() should fail, which leads to the EARLY RETURN FALSE statement at the beginning of this function.
829 
830  bool const violate_max_O3_prime_to_P_bond_dist= is_rna_chainbreak(pose, rsd_1.seqpos());
831 
832  //Note that cutpoint_closed_torsions are NOT considered as chain_break_torsion since we want to score them EVEN when skip_chainbreak_torsions_=true!
833  //Necessary since for cutpoint_closed_torsions, the max O3_prime_to_P_bond_dist might be violated during stages of the Fragment Assembly and Stepwise Assembly where the chain is not yet closed.
834 
835  Is_chain_break_torsion= (violate_max_O3_prime_to_P_bond_dist==true && METHOD_ONE_Is_cutpoint_closed_torsion==false);
836 
837  }
838 
839  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
840  bool should_score_this_torsion= true; //Warning before Jan 20, 2012, this used to be "Size should_score_this_torsion= true;"
841 
842  if( Is_virtual_torsion==true && METHOD_ONE_Is_cutpoint_closed_torsion==false ) should_score_this_torsion=false;
843 
844  if( skip_chainbreak_torsions_ && Is_chain_break_torsion ) should_score_this_torsion=false;
845 
846  if(verbose_){
847  Output_boolean(" should_score_torsion= ", should_score_this_torsion);
848  Output_boolean(" | Is_cutpoint_closed_torsion= ", METHOD_ONE_Is_cutpoint_closed_torsion);
849  Output_boolean(" | Is_virtual_torsion= ", Is_virtual_torsion);
850  Output_boolean(" | skip_chainbreak_torsions_= ", skip_chainbreak_torsions_);
851  Output_boolean(" | Is_chain_break_torsion = ", Is_chain_break_torsion) ;
852  std::cout << std::endl;
853  }
854 
855  return should_score_this_torsion;
856 
857 
858  }
859 
860 
861 
862 }
863 }
864 }