Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
RNA_FilteredBaseBaseInfo.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/methods/RNA_RawBaseBaseInfo.cc
11 /// @brief Statistically derived rotamer pair potential class implementation
12 /// @author Phil Bradley
13 /// @author Andrew Leaver-Fay
14 /// @author Rhiju Das
15 
16 
17 // Unit headers
23 
24 // Package headers
25 
26 // Project headers
27 #include <core/chemical/AA.hh>
28 
29 // Utility headers
30 #include <ObjexxFCL/FArray3D.hh>
31 #include <ObjexxFCL/FArray2D.hh>
32 
33 #include <utility/vector1.hh>
34 #include <ObjexxFCL/format.hh>
35 
36 #include <basic/options/option.hh>
37 #include <basic/options/keys/score.OptionKeys.gen.hh>
38 
39 
40 // C++
41 
42 ///////////////////////////////////////////////////////
43 // Keep track of some base geometry that is
44 // useful for RNA scoring.
45 ///////////////////////////////////////////////////////
46 
47 namespace core {
48 namespace scoring {
49 namespace rna {
50 
51 using namespace ObjexxFCL::fmt;
52 
54  total_base_pair_score_ ( 0.0 ),
55  total_base_axis_score_ ( 0.0 ),
56  total_base_stagger_score_ ( 0.0 ),
57  total_base_stack_score_ ( 0.0 ),
58  total_base_stack_axis_score_ ( 0.0 ),
59  scale_axis_stagger_( true ),
60  basepair_axis_stagger_scaling_( 0.1 ),
61  basestack_axis_scaling_( 1.0 ),
62  include_neighbor_base_stacks_( basic::options::option[ basic::options::OptionKeys::score::include_neighbor_base_stacks ]() ),
63  calculated_( false ),
64  rna_verbose_( false )
65 {}
66 
67 /// @details Copy constructors must copy all data, not just some...
69  CacheableData(),
70  scale_axis_stagger_( src.scale_axis_stagger_ ),
71  basepair_axis_stagger_scaling_( src.basepair_axis_stagger_scaling_ ),
72  basestack_axis_scaling_( src.basestack_axis_scaling_ ),
73  include_neighbor_base_stacks_( src.include_neighbor_base_stacks_ )
74 {
87 }
88 
89 void
90 RNA_FilteredBaseBaseInfo::resize( Size const & total_residue )
91 {
92  filtered_base_pair_array_.dimension( total_residue, total_residue );
93  filtered_base_stagger_array_.dimension( total_residue, total_residue );
94  filtered_base_axis_array_.dimension( total_residue, total_residue );
95  filtered_base_stack_array_.dimension( total_residue, total_residue );
96  filtered_base_stack_axis_array_.dimension( total_residue, total_residue );
97 }
98 
99 
100 //////////////////////////////////////////////////////////////////////////////////////
101 //////////////////////////////////////////////////////////////////////////////////////
102 //////////////////////////////////////////////////////////////////////////////////////
103 ///////////////////////////////////////////////////////////////////////////////
104 // Sort list of base pairs by energy, and go down list -- don't allow
105 // any base pairs that are mutually exclusive!
106 ///////////////////////////////////////////////////////////////////////////////
107 //////////////////////////////////////////////////////////////////////////////////////
108 void
110 
111  // Actually not a good idea -- sometimes the Monte Carlo
112  // wants a tally of the energy, but no recalculation of pair terms.
113  // assert( raw_base_base_info.calculated() );
114 
115  Size const total_residue = raw_base_base_info.size();
116  resize( total_residue );
117 
118  figure_out_rna_base_pairs_to_score( raw_base_base_info );
119 
120  figure_out_rna_base_stacks_to_score( raw_base_base_info );
121 
122  set_calculated( true );
123 }
124 
125 void
127  RNA_RawBaseBaseInfo const & raw_base_base_info
128 )
129 {
130  ObjexxFCL::FArray3D< Real > raw_base_pair_array( raw_base_base_info.base_pair_array() );
131  ObjexxFCL::FArray3D< Real > raw_base_axis_array( raw_base_base_info.base_axis_array() );
132  ObjexxFCL::FArray3D< Real > raw_base_stagger_array( raw_base_base_info.base_stagger_array() );
133 
134  ObjexxFCL::FArray2D< Real > raw_base_geometry_orientation_array( raw_base_base_info.base_geometry_orientation_array() );
135 
136  //A rigorous list of base pairs, for scoring.
137  Energy_base_pair_list energy_base_pair_list;
138 
139  scored_base_pair_list_.clear();
140 
144 
148 
149  Real const SCORE_CUTOFF = -0.001;
150 
151  Size const total_residue = raw_base_base_info.size();
152  ObjexxFCL::FArray2D_bool edge_is_base_pairing( total_residue, NUM_EDGES, false );
153 
154  for (Size i = 1; i <= total_residue; i++ ){
155  for (Size k = 1; k <= NUM_EDGES; k++ ){
156 
157  for (Size j = i+1; j <= total_residue; j++ ){
158  //A base pair is only real if each partner called the other one a true partner.
159  if (raw_base_pair_array(i,j,k) < SCORE_CUTOFF ){
160 
161  Size found_match( 0 );
162  Real tmp_energy = 0.0;
163  for (Size m = 1; m <= NUM_EDGES; m++){
164  if (raw_base_pair_array(j,i,m) < tmp_energy){
165  found_match = m;
166  tmp_energy = raw_base_pair_array(j, i, m);
167  }
168  }//m
169  if (found_match == 0) continue;
170 
171  Real const total_base_pair_energy =
172  raw_base_pair_array(i,j,k) + raw_base_pair_array(j,i,found_match);
173 
174  Base_pair base_pair;
175  base_pair.res1 = i;
176  base_pair.edge1 = k;
177 
178  base_pair.res2 = j;
179  base_pair.edge2 = found_match;
180 
181  //orientations are cos( theta ) and should be symmetric!
182  assert( std::abs( raw_base_geometry_orientation_array( i, j ) - raw_base_geometry_orientation_array( j, i ) ) < 1.0e-2 );
183  base_pair.orientation = ( raw_base_geometry_orientation_array( i, j ) + raw_base_geometry_orientation_array( j, i ) < 0.0 ? 1 : 2);
184 
185  energy_base_pair_list.push_back( std::make_pair( total_base_pair_energy, base_pair ) );
186 
187  }//is it a basepair?
188  } //j
189 
190  } //k
191  }//i
192 
193  energy_base_pair_list.sort(); //Start with the lowest energy base pairs.
194 
195  // static bool const scale_axis_stagger_by_xy_score = true;
196 
197  for ( Energy_base_pair_list::const_iterator it = energy_base_pair_list.begin();
198  it != energy_base_pair_list.end(); ++it ){
199  Real const energy = it->first;
200  Base_pair const base_pair = it->second;
201 
202  Size const i = base_pair.res1;
203  Size const k = base_pair.edge1;
204 
205  Size const j = base_pair.res2;
206  Size const m = base_pair.edge2;
207 
208  if (edge_is_base_pairing( i, k )) continue;
209  if (edge_is_base_pairing( j, m )) continue;
210 
211  edge_is_base_pairing( i, k ) = true;
212  edge_is_base_pairing( j, m ) = true;
213 
214  Real scalefactor ( 1.0f ) ;
215  if ( scale_axis_stagger_ ) scalefactor = -1.0 * basepair_axis_stagger_scaling_ * energy;
216 
217  Real const scaled_axis_energy = scalefactor * ( raw_base_axis_array(i,j,k) + raw_base_axis_array(j,i,m) );
218  Real const scaled_stagger_energy = scalefactor * ( raw_base_stagger_array(i,j,k) + raw_base_stagger_array(j,i,m) );
219  //rna_axis_score += scaled_axis_energy;
220  //rna_stagger_score += scaled_stagger_energy;
221 
222  if (rna_verbose_) {
223 
224  std::cout << "BASE PAIR: " << I(3,i) << " " << I(3,j) << " "
225  << get_edge_from_num( k ) << " "
226  << get_edge_from_num( m ) << " "
227  << get_orientation_from_num( base_pair.orientation )
228  << " ==> "
229  << F(5,3,raw_base_pair_array(i,j,k)) << " " << F(5,3,raw_base_pair_array(j,i,m)) << " "
230  // << scaled_axis_energy
231  << std::endl;
232 
233  }
234 
235  //if ( user_defined_basepair(i,j,k,m) > 0.1 ) rna_contact_score += -1.0;
236 
237  filtered_base_pair_array_(i,j) = energy;
238  filtered_base_pair_array_(j,i) = energy;
239  total_base_pair_score_ += energy;
240 
241  filtered_base_axis_array_(i,j) = scaled_axis_energy;
242  filtered_base_axis_array_(j,i) = scaled_axis_energy;
243  total_base_axis_score_ += scaled_axis_energy;
244 
245  filtered_base_stagger_array_(i,j) = scaled_stagger_energy;
246  filtered_base_stagger_array_(j,i) = scaled_stagger_energy;
247  total_base_stagger_score_ += scaled_stagger_energy;
248 
249  scored_base_pair_list_.push_back( *it );
250  }
251 
252 }
253 
254 ///////////////////////////////////////////////////////////////////////////////
255 void
257  RNA_RawBaseBaseInfo const & raw_base_base_info )
258 {
259 
260  ObjexxFCL::FArray2D< Real > raw_base_stack_array( raw_base_base_info.base_stack_array() );
261  ObjexxFCL::FArray2D< Real > raw_base_stack_axis_array( raw_base_base_info.base_stack_axis_array() );
262  ObjexxFCL::FArray2D< Real > raw_base_geometry_orientation_array( raw_base_base_info.base_geometry_orientation_array() );
263  ObjexxFCL::FArray2D< Real > raw_base_geometry_height_array( raw_base_base_info.base_geometry_height_array() );
264 
265  // static bool const include_neighbor_base_stacks = false;//truefalseoption("include_neighbor_base_stacks");
266 
267  Size const total_residue = raw_base_base_info.size();
268 
269  scored_base_stack_list_.clear();
270 
273 
276 
277  for (Size i = 1; i <= total_residue; i++ ){
278  for (Size j = i+1; j <= total_residue; j++ ){
279 
280 
281  //Base pairs and base stacks are mutually exclusive!
282  if (filtered_base_pair_array_(i,j) < 0.0) continue;
283 
284  //Both partners should think they are stacked onto each other.
285  if ( raw_base_stack_array( i, j ) < 0.0 &&
286  raw_base_stack_array( j, i ) < 0.0 ){
287  if (rna_verbose_) std::cout << "BASE STACK: " << i << " " << j << std::endl;
288 
289  Base_stack base_stack;
290  base_stack.res1 = i;
291  base_stack.res2 = j;
292 
293  //orientations are cos( theta ) and should be symmetric!
294  assert( std::abs( raw_base_geometry_orientation_array( i, j ) - raw_base_geometry_orientation_array( j, i ) ) < 1.0e-2 );
295  base_stack.orientation = ( raw_base_geometry_orientation_array( i, j ) + raw_base_geometry_orientation_array( j, i ) ) < 0.0 ? 1 : 2;
296 
297  // height is not necessarily (anti)-symmetric if the planes of the two bases aren't co-planar.
298  base_stack.which_side = ( raw_base_geometry_height_array( i, j ) > 0.0 ) ? 1 : 2;
299 
300  Real const total_base_stack_energy = raw_base_stack_array( i, j ) + raw_base_stack_array( j, i);
301  scored_base_stack_list_.push_back( std::make_pair( total_base_stack_energy, base_stack ));
302 
303  //By default, don't count stacks between neighboring nucleotides, since that
304  // interaction is captured by fragments.
305  if (!include_neighbor_base_stacks_ && j == i+1) continue;
306 
307  filtered_base_stack_array_(i,j) = total_base_stack_energy;
308  filtered_base_stack_array_(j,i) = total_base_stack_energy;
309  total_base_stack_score_ += total_base_stack_energy;
310 
311  Real total_base_stack_axis_energy = raw_base_stack_axis_array( i, j ) + raw_base_stack_axis_array( j, i) ;
312 
313  // This scaling is actually unity, unless we're fading near the boundaries:
314  if (scale_axis_stagger_) total_base_stack_axis_energy *= -1 * basestack_axis_scaling_ * total_base_stack_energy;
315 
316  filtered_base_stack_axis_array_(i,j) = total_base_stack_axis_energy;
317  filtered_base_stack_axis_array_(j,i) = total_base_stack_axis_energy;
318  total_base_stack_axis_score_ += total_base_stack_axis_energy;
319 
320  }
321  }
322  }
323 
324 }
325 
326 /////////////////////////////////////////////////////////////////////
328 {
329  Real rna_data_score( 0.0 );
330 
331  utility::vector1< RNA_Datum> const & rna_data( rna_data_info.rna_data() );
332 
333  for (Size n = 1; n <= rna_data.size(); n++ ){
334 
335  Size const seqpos( rna_data[n].position() );
336 
337  // This could be accelerated if needed.
338  for ( Energy_base_pair_list::const_iterator it = scored_base_pair_list_.begin();
339  it != scored_base_pair_list_.end(); ++it ){
340 
341  Base_pair const base_pair = it->second;
342 
343  Size const i = base_pair.res1;
344  Size const j = base_pair.res2;
345 
346  Size k( 0 );
347  if ( i == seqpos ){
348  k = base_pair.edge1;
349  } else if ( j == seqpos ){
350  k = base_pair.edge2;
351  } else {
352  continue;
353  }
354 
355  if ( k == rna_data[ n ].edge() ) {
356  rna_data_score += rna_data[n].weight();
357  }
358 
359  }
360  }
361 
362  return rna_data_score;
363 }
364 
365 }
366 }
367 }