Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
RNA_BasePairClassifier.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 relax_protocols
11 /// @brief Implementation of Leontis/Westhof nucleic acid base-pair classification
12 /// @detailed
13 /// @author Rhiju Das
14 
15 
16 // Unit headers
18 
19 // Package headers
20 #include <core/chemical/AA.hh>
22 #include <core/pose/Pose.hh>
32 
33 // ObjexxFCL Headers
34 #include <ObjexxFCL/FArray1D.hh>
35 
36 // Utility headers
37 // AUTO-REMOVED #include <utility/vector1.hh>
38 #include <utility/pointer/owning_ptr.hh>
39 
40 #include <numeric/xyzMatrix.hh>
41 // AUTO-REMOVED #include <numeric/conversions.hh>
42 
43 // External library headers
44 
45 //C++ headers
46 #include <vector>
47 #include <string>
48 
49 #include <basic/Tracer.hh>
50 
51 #include <utility/vector1.hh>
52 
53 
54 using namespace core;
55 using basic::T;
56 
57 static basic::Tracer TR( "protocols.rna.rna_base_pair_classifier" ) ;
58 
59 namespace protocols {
60 namespace rna {
61 
62 ///////////////////////////////////////////////////////////////////////////////
63 ///////////////////////////////////////////////////////////////////////////////
64 // Implementation of Leontis/Westhof base pair classifier (RNA, 2001)
65 //
66 // Partly follows RNAVIEW algorithm, though no use of CH..O bonds, and
67 // all base pairs get a Watson-Crick,Hoogsteen,Sugar classification.
68 //
69 // This should probably be made into an object.
70 //
71 ///////////////////////////////////////////////////////////////////////////////
72 ///////////////////////////////////////////////////////////////////////////////
73 ///////////////////////////////////////////////////////////////////////////////
74 
75 
76 ///////////////////////////////////////////////////////////////////
77 void
79  conformation::Residue const & rsd,
80  Size const & atm,
81  Size & N_W,
82  Size & N_H,
83  Size & N_S )
84 {
85  using namespace core::chemical;
86 
87  //std::cout << atm << std::endl;
88  std::string atom_name = rsd.atom_name( atm );
89  // std::cout << atom_name << std::endl;
90 
91  if ( rsd.aa() == na_rad ) {
92 
93  if ( atom_name == " N1 " ||
94  atom_name == " C2 " ||
95  atom_name == " N6 " ) N_W++;
96 
97  if ( atom_name == " N6 " ||
98  atom_name == " C5 " ||
99  atom_name == " C8 " ||
100  atom_name == " N7 " ) N_H++;
101 
102  if ( atom_name == " N3 " ||
103  atom_name == " C2 " ||
104  atom_name == " C4 " ||
105  atom_name == " C1 " ||
106  atom_name == " C2 " ||
107  atom_name == " C3*" ||
108  atom_name == " O3*" ||
109  atom_name == " O2*" ) N_S++;
110 
111  } else if ( rsd.aa() == na_rcy ) {
112 
113  if ( atom_name == " O2 " ||
114  atom_name == " N3 " ||
115  atom_name == " N4 " ) N_W++;
116 
117  if ( atom_name == " N4 " ||
118  atom_name == " C5 " ||
119  atom_name == " C6 " ) N_H++;
120 
121  if ( atom_name == " O2 " ||
122  atom_name == " N1 " ||
123  atom_name == " C1*" ||
124  atom_name == " C2*" ||
125  atom_name == " C3*" ||
126  atom_name == " O3*" ||
127  atom_name == " O2*" ) N_S++;
128 
129  } else if ( rsd.aa() == na_rgu ) {
130 
131  if ( atom_name == " N1 " ||
132  atom_name == " N2 " ||
133  atom_name == " O6 " ) N_W++;
134 
135  if ( atom_name == " O6 " ||
136  atom_name == " C5 " ||
137  atom_name == " C8 " ||
138  atom_name == " N7 " ) N_H++;
139 
140  if ( atom_name == " N3 " ||
141  atom_name == " N2 " ||
142  atom_name == " C4 " ||
143  atom_name == " N9 " ||
144  atom_name == " C1*" ||
145  atom_name == " C2*" ||
146  atom_name == " O2*" ) N_S++;
147 
148  } else if ( rsd.aa() == na_ura ) {
149 
150  if ( atom_name == " O2 " ||
151  atom_name == " N3 " ||
152  atom_name == " O4 " ) N_W++;
153 
154  if ( atom_name == " O4 " ||
155  atom_name == " C5 " ||
156  atom_name == " C6 " ) N_H++;
157 
158  if ( atom_name == " O2 " ||
159  atom_name == " N1 " ||
160  atom_name == " C1*" ||
161  atom_name == " C2*" ||
162  atom_name == " C3*" ||
163  atom_name == " O3*" ||
164  atom_name == " O2*" ) N_S++;
165 
166  } else {
167  std::cout << "PROBLEM !!!! " << rsd.aa() << std::endl;
168  utility_exit_with_message( "Problem with base classification, residue " );
169  }
170 }
171 
172 ///////////////////////////////////
173 void
175  conformation::Residue const & rsd,
176  Size const & atm,
177  conformation::Residue const & other_rsd,
178  Size const & other_atm,
179  Size & N_W,
180  Size & N_H,
181  Size & N_S )
182 {
183  using namespace core::chemical;
184 
185  std::string atom_name = rsd.atom_name( atm );
186 
187  if (rsd.aa() == na_rad && atom_name == " N6 ") {
188  //std::cout << "CHECKING " << rsd.seqpos() << std::endl;
189  if ( (rsd.xyz( rsd.atom_index("1H6 ") ) - other_rsd.xyz( other_atm )).length() <
190  (rsd.xyz( rsd.atom_index("2H6 ") ) - other_rsd.xyz( other_atm )).length() ) {
191  N_W++;
192  } else {
193  N_H++;
194  }
195  }
196 
197  if (rsd.aa() == na_rcy && atom_name == " N4 ") {
198  if ( (rsd.xyz( rsd.atom_index("1H4 ") ) - other_rsd.xyz( other_atm )).length() <
199  (rsd.xyz( rsd.atom_index("2H4 ") ) - other_rsd.xyz( other_atm )).length() ) {
200  N_H++;
201  } else {
202  N_W++;
203  }
204  }
205 
206  if (rsd.aa() == na_rgu && atom_name == " N2 ") {
207  if ( (rsd.xyz( rsd.atom_index("1H2 ") ) - other_rsd.xyz( other_atm )).length() <
208  (rsd.xyz( rsd.atom_index("2H2 ") ) - other_rsd.xyz( other_atm )).length() ) {
209  N_S++;
210  } else {
211  N_W++;
212  }
213  }
214 
215 }
216 
217 //////////////////////////////////
218 bool
219 atom_is_polar( core::conformation::Residue const & rsd, Size const & atm )
220 {
221  for ( chemical::AtomIndices::const_iterator
222  anum = rsd.Hpos_polar().begin(),
223  anume = rsd.Hpos_polar().end(); anum != anume; ++anum ) {
224  Size const H_atm( *anum );
225  if ( H_atm == atm ) return true;
226  }
227  return false;
228 
229 }
230 
231 //////////////////////////////////
232 bool
234 {
235  for ( chemical::AtomIndices::const_iterator
236  anum = rsd.Hpos_polar().begin(),
237  anume = rsd.Hpos_polar().end(); anum != anume; ++anum ) {
238  Size const H_atm( *anum );
239  if ( rsd.atom_base( H_atm ) == atm ) return true;
240  }
241  return false;
242 
243 }
244 
245 //////////////////////////////////
246 bool
248 {
249  for ( chemical::AtomIndices::const_iterator
250  anum = rsd.accpt_pos().begin(),
251  anume = rsd.accpt_pos().end(); anum != anume; ++anum ) {
252  Size const H_atm( *anum );
253  if ( H_atm == atm ) return true;
254  }
255  return false;
256 
257 }
258 
259 
260 ////////////////////////////////////////////////////////
261 // Look at contacts made by i to base on residue j
262 // Tabulate any contacts (not just H-bonds and possible CH-bonds)
263 ////////////////////////////////////////////////////////
264 void
266  conformation::Residue const & rsd_i,
267  conformation::Residue const & rsd_j,
268  Size & edge_classification )
269 {
270  using namespace core::scoring::rna;
271 
272  static Real const DIST_CUTOFF( 4.2 );
273  // static Real const ANGLE_CUTOFF( numeric::conversions::radians( 100.0 ) );
274  //Size n_hbonds( 0 );
275  Size N_W( 0 ), N_H( 0 ), N_S( 0 );
276 
277  // Size const i = rsd_i.seqpos();
278  // Size const j = rsd_j.seqpos();
279 
280  //std::cout << i << " <--> " << j << std::endl;
281  // heavy atom on base j; heavy atom on i.
282  for ( Size k = rsd_j.first_sidechain_atom()+1 ; k <= rsd_j.nheavyatoms(); k++ ) {
283 
284  // if ( k <= rsd_j.first_sidechain_atom() ) continue;
285 
286  for ( Size m = 1; m <= rsd_i.nheavyatoms(); m++ ) {
287 
288  Real const dist_ij = ( rsd_i.xyz( m ) - rsd_j.xyz( k ) ).length();
289 
290  // Real const angle_ij = angle_radians( rsd_i.xyz( acc_atm ),
291  // rsd_j.xyz( don_h_atm ),
292  // rsd_j.xyz( don_atm ) );
293  if ( dist_ij < DIST_CUTOFF /*&& angle_ij > ANGLE_CUTOFF*/ ) {
294  update_edge_hbond_numbers( rsd_i, m, N_W, N_H, N_S );
295 
296  if ( atom_is_acceptor( rsd_j, k ) && heavy_atom_is_polar( rsd_i, m) ) {
297  update_edge_hbond_numbers_careful_hydrogen( rsd_i, m, rsd_j, k, N_W, N_H, N_S ); //helps resolve confusion for A, C, and G bifurcated
298  }
299 
300  }
301 
302  }
303 
304  }
305 
306 
307  //std::cout << i << " <--> " << j << std::endl;
308 
309  // acceptor on base j; donor on i.
310  // for ( Size acc_atm = 1; acc_atm <= rsd_j.nheavyatoms(); acc_atm++ ) {
311  //
312  // if ( acc_atm <= rsd_j.first_sidechain_atom() ) continue;
313  //
314  // for ( Size k = rsd_i.nheavyatoms() + 1; k <= rsd_i.natoms(); k++ ) {
315  //
316  // Size const & don_h_atm = k;
317  // Size const & don_atm = rsd_i.atom_base( k );
318  //
319  // if ( ( rsd_j.xyz( acc_atm ) - rsd_i.xyz( don_h_atm ) ).length() < DIST_CUTOFF /*&&
320  // angle_radians( rsd_j.xyz( acc_atm ),
321  // rsd_i.xyz( don_h_atm ),
322  // rsd_i.xyz( don_atm ) ) > ANGLE_CUTOFF*/ ) {
323  // update_edge_hbond_numbers( rsd_i, don_atm, N_W, N_H, N_S );
324  // //if ( atom_is_polar( rsd_i, k ) && atom_is_acceptor( rsd_j, acc_atm) &&
325  // // don_atm > rsd_i.first_sidechain_atom() ) {
326  // // if( (i == 4 && j ==9) || (i == 9 && j ==4) )std::cout << "2. FOUND H-BOND " << i << " " << j << " " << rsd_i.atom_name( k ) << " " << rsd_j.atom_name( acc_atm ) << std::endl;
327  // // n_hbonds++;
328  // // }
329  // }
330  //
331  // }
332  // }
333 
334  if ( N_W >= N_H && N_W >= N_S ) {
335  edge_classification = WATSON_CRICK;
336  } else if (N_H >= N_S ) {
337  edge_classification = HOOGSTEEN;
338  } else {
339  edge_classification = SUGAR;
340  }
341 
342  // return n_hbonds;
343 
344 }
345 
346 
347 
348 /////////////////////////////////////////////////////////////////////////////
350 
351 /////////////////////////////////////////////////////////////////////////////
352 Size
354  core::pose::Pose & pose,
355  Size const & i,
356  Size const & j )
357 {
358  using namespace core::scoring::rna;
359 
360  RNA_ScoringInfo & rna_scoring_info( nonconst_rna_scoring_info_from_pose( pose ) );
361  RNA_CentroidInfo & rna_centroid_info( rna_scoring_info.rna_centroid_info() );
362  rna_centroid_info.update( pose );
363 
364  //utility::vector1< Vector > const & base_centroids( rna_centroid_info.base_centroids() );
365  utility::vector1< kinematics::Stub > const & base_stubs( rna_centroid_info.base_stubs() );
366 
367  kinematics::Stub const & stub_i( base_stubs[i] );
368  Matrix const & M_i( stub_i.M );
369  Vector const & z_i = M_i.col_z();
370 
371  kinematics::Stub const & stub_j( base_stubs[j] );
372  Matrix const & M_j( stub_j.M );
373  Vector const & z_j = M_j.col_z();
374  Real const cos_theta = dot_product( z_i, z_j );
375 
376  Size const theta_bin = (cos_theta < 0) ? 1 : 2;
377  return theta_bin;
378 
379 }
380 
381 ////////////////////////////////////////////////////////////////
382 bool
383 residue_is_bulge( pose::Pose const & pose, Size const i )
384 {
385 
386  conformation::Residue const & rsd_i ( pose.residue( i ) ) ;
387  static Real const DIST_CUTOFF( 4.0 );
388 
389  for ( Size k = rsd_i.first_sidechain_atom()+1; k <= rsd_i.nheavyatoms(); k++ ) {
390  for ( Size j = 1 ; j <= pose.total_residue(); j++ ) {
391  if ( i == j ) continue;
392  for ( Size m = 1; m <= pose.residue( j ).nheavyatoms(); m++ ) {
393  if ( ( rsd_i.xyz( k ) - pose.residue( j ).xyz( m ) ).length() < DIST_CUTOFF ) {
394  // std::cout << "Residue " << i << " --> " << j << " " << pose.residue(j).atom_name( m ) << std::endl;
395  return false;
396  }
397  }
398  }
399  }
400 
401  return true;
402 
403 }
404 
405 /////////////////////////////////////////////////////////////////////////////
406 Size
408  core::pose::Pose & pose,
409  Size const & i,
410  Size const & j )
411 {
412 
413  Size num_hbonds = 0;
414 
415  static Real const HBOND_CUTOFF( -0.1 );
416  for (Size n = 1; n <= hbond_set->nhbonds(); n++ ) {
417  core::scoring::hbonds::HBond const & hbond( hbond_set->hbond( n ) );
418 
419  Size const & don_res_num = hbond.don_res();
420  Size const & don_hatm = hbond.don_hatm();
421 
422  Size const & acc_res_num = hbond.acc_res();
423  Size const & acc_atm = hbond.acc_atm();
424 
425  if ( don_res_num == i && acc_res_num == j ) {
426  if ( pose.residue( i ).atom_base( don_hatm ) > pose.residue( i ).first_sidechain_atom() &&
427  acc_atm > pose.residue( j ).first_sidechain_atom() ) {
428 
429  //if ( ( i == 4 && j == 10 ) || ( i==10 && j==4) ) std::cout << i << "--" << j << " -> " << pose.residue( i ).atom_name( don_hatm) << " " << pose.residue( j ).atom_name( acc_atm ) << hbond.energy() << std::endl;
430  if ( hbond.energy() <= HBOND_CUTOFF ) num_hbonds++;
431 
432  }
433  }
434 
435  if ( don_res_num == j && acc_res_num == i ) {
436  if ( pose.residue( j ).atom_base( don_hatm ) > pose.residue( j ).first_sidechain_atom() &&
437  acc_atm > pose.residue( i ).first_sidechain_atom() ) {
438 
439  //if ( ( i == 4 && j == 10 ) || ( i==10 && j==4) ) std::cout << j << "--" << i << " -> " << pose.residue( j ).atom_name( don_hatm) << " " << pose.residue( i ).atom_name( acc_atm ) << hbond.energy() << std::endl;
440  if ( hbond.energy() <= HBOND_CUTOFF ) num_hbonds++;
441 
442  }
443  }
444 
445  }
446 
447  if (num_hbonds > 0 ) return num_hbonds;
448 
449  // Last check -- there may be unusually *close* contacts in lo-res structures that don't get good hbond scores.
450  static Real const DIST_CUTOFF( 3.0 );
451  conformation::Residue const & rsd_i( pose.residue( i ) ) ;
452  conformation::Residue const & rsd_j( pose.residue( j ) ) ;
453 
454  for ( chemical::AtomIndices::const_iterator
455  anum = rsd_i.accpt_pos().begin(),
456  anume = rsd_i.accpt_pos().end(); anum != anume; ++anum ) {
457 
458  Size const aatm( *anum ) ;
459  if ( aatm <= rsd_i.first_sidechain_atom() ) continue;
460 
461  for ( chemical::AtomIndices::const_iterator
462  hnum = rsd_j.Hpos_polar().begin(),
463  hnume = rsd_j.Hpos_polar().end(); hnum != hnume; ++hnum ) {
464  Size const hatm( *hnum );
465 
466  if ( rsd_j.atom_base( hatm ) <= rsd_j.first_sidechain_atom() ) continue;
467 
468  if ( ( rsd_i.xyz( aatm ) - rsd_j.xyz( hatm ) ).length() < DIST_CUTOFF ) {
469  // if ( ( i == 4 && j == 10 ) || ( i==10 && j==4) ) std::cout << j << "--" << i << " -> " << pose.residue( j ).atom_name( hatm) << " " << pose.residue( i ).atom_name( aatm ) << " blah" << std::endl;
470  return 1;
471  }
472  }
473  }
474 
475 
476  for ( chemical::AtomIndices::const_iterator
477  anum = rsd_j.accpt_pos().begin(),
478  anume = rsd_j.accpt_pos().end(); anum != anume; ++anum ) {
479 
480  Size const aatm( *anum ) ;
481  if ( aatm <= rsd_j.first_sidechain_atom() ) continue;
482 
483  for ( chemical::AtomIndices::const_iterator
484  hnum = rsd_i.Hpos_polar().begin(),
485  hnume = rsd_i.Hpos_polar().end(); hnum != hnume; ++hnum ) {
486  Size const hatm( *hnum );
487 
488  if ( rsd_i.atom_base( hatm ) <= rsd_i.first_sidechain_atom() ) continue;
489 
490  if ( ( rsd_j.xyz( aatm ) - rsd_i.xyz( hatm ) ).length() < DIST_CUTOFF ) {
491  // if ( ( i == 4 && j == 10 ) || ( i==10 && j==4) ) std::cout << i << "--" << j << " -> " << pose.residue( i ).atom_name( hatm) << " " << pose.residue( j ).atom_name( aatm ) << " blah " << dist << std::endl;
492  return 1;
493  }
494  }
495  }
496 
497 
498  return false;
499 }
500 
501 //////////////////////////////////////////////////
502 bool
504  core::pose::Pose & pose,
505  Size const & i,
506  Size const & j )
507 {
508 
509  using namespace core::scoring::rna;
510 
511  RNA_ScoringInfo & rna_scoring_info( nonconst_rna_scoring_info_from_pose( pose ) );
512  RNA_CentroidInfo & rna_centroid_info( rna_scoring_info.rna_centroid_info() );
513  rna_centroid_info.update( pose );
514 
515  utility::vector1< Vector > const & base_centroids( rna_centroid_info.base_centroids() );
516  utility::vector1< kinematics::Stub > const & base_stubs( rna_centroid_info.base_stubs() );
517 
518  Vector const & centroid_i( base_centroids[i] );
519  kinematics::Stub const & stub_i( base_stubs[i] );
520  Matrix const & M_i( stub_i.M );
521  //Vector const & x_i = M_i.col_x();
522  //Vector const & y_i = M_i.col_y();
523  Vector const & z_i = M_i.col_z();
524 
525  Vector const & centroid_j( base_centroids[j] );
526  kinematics::Stub const & stub_j( base_stubs[j] );
527 
528  Vector d_ij = centroid_j - centroid_i;
529  //Real const dist_x = dot_product( d_ij, x_i );
530  // Real const dist_y = dot_product( d_ij, y_i );
531  Real const dist_z = dot_product( d_ij, z_i );
532 
533  Matrix const & M_j( stub_j.M );
534  Vector const & z_j = M_j.col_z();
535  Real const cos_theta = dot_product( z_i, z_j );
536 
537  // if ( i == 8 && j == 11 ) std::cout << "DIST_Z COS_THETA " << dist_z << " " << cos_theta << std::endl;
538  // if ( i == 5 && j == 8 ) std::cout << "DIST_Z COS_THETA " << dist_z << " " << cos_theta << std::endl;
539  // if ( j == 5 && i == 8 ) std::cout << "DIST_Z COS_THETA " << dist_z << " " << cos_theta << std::endl;
540 
541 
542  static Real const rna_basepair_stagger_cutoff_( 2.8 );
543  static Real const COS_THETA_CUTOFF( 0.6 );
544  if ( std::abs(dist_z) < rna_basepair_stagger_cutoff_ && std::abs( cos_theta ) > COS_THETA_CUTOFF ) return true;
545 
546  //
547  // static Real const rna_basepair_stagger_cutoff_loose_( 3.5 );
548  // static Real const COS_THETA_CUTOFF_STRICT( 0.65 );
549  // if ( std::abs(dist_z) < rna_basepair_stagger_cutoff_loose_ && std::abs( cos_theta ) > COS_THETA_CUTOFF_STRICT ) return true;
550 
551  return false;
552 }
553 
554 
555 
556 /////////////////////////////////////////////////////////////////////////////
557 /////////////////////////////////////////////////////////////////////////////
558 /////////////////////////////////////////////////////////////////////////////
559 void
561  core::pose::Pose const & pose_input,
563  utility::vector1< bool > & is_bulged
564 )
565 {
566  using namespace core::scoring;
567  using namespace core::scoring::rna;
568  using namespace core::chemical;
569 
570  base_pair_list.clear();
571 
572  pose::Pose pose = pose_input;
573 
574  //////////////////////////////////////////////////////////////
575  ObjexxFCL::FArray1D < bool > is_base_paired( pose.total_residue(), false );
576 
577  // Get hydrogen bond list.
578  //ScoreFunctionOP score_fxn( ScoreFunctionFactory::create_score_function( core::scoring::RNA_HIRES_WTS ) );
579  ScoreFunctionOP score_fxn = new ScoreFunction;
580  score_fxn->set_weight( hbond_sc, 1.0);
581  (*score_fxn)(pose);
582 
583  hbonds::HBondOptionsOP hbond_options( new hbonds::HBondOptions() );
584  hbond_options->use_hb_env_dep( false );
585  hbonds::HBondSetOP hbond_set( new hbonds::HBondSet( hbond_options ));
586 
587  hbonds::fill_hbond_set( pose, false /*calc deriv*/, *hbond_set );
588 
589  // std::cout << "---------" << std::endl;
590 
591  //////////////////////////////////////////////////////////////
592  for (Size i = 1; i <= pose.total_residue(); i++ ) {
593  if ( ! pose.residue(i).is_RNA() ) continue;
594  for (Size j = i+1; j <= pose.total_residue(); j++ ) {
595  if ( ! pose.residue(j).is_RNA() ) continue;
596 
597  Size const num_hbonds = bases_form_a_hydrogen_bond( hbond_set, pose, i, j );
598  if ( num_hbonds == 0 ) continue;
599  if ( ! bases_are_coplanar( pose, i, j ) || ! bases_are_coplanar( pose, j, i ) ) continue;
600 
601  Size edge_classification_i( 0 ), edge_classification_j( 0 );
602 
603  figure_out_number_base_contacts( pose.residue( i ), pose.residue( j ), edge_classification_i );
604  figure_out_number_base_contacts( pose.residue( j ), pose.residue( i ), edge_classification_j );
605 
606  Size const orientation = figure_out_base_pair_orientation( pose, i, j );
607 
608  //These pernicious bifurcated hydrogen bonds.
609  // if ( num_hbonds == 1 &&
610  // ( pose.residue(i).aa() == na_rad || pose.residue(i).aa() == na_rgu ) &&
611  // ( pose.residue(j).aa() == na_rad || pose.residue(j).aa() == na_rgu ) ) {
612  // edge_classification_i = WATSON_CRICK;
613  // edge_classification_j = WATSON_CRICK;
614  // }
615 
616 
617  // if ( n_i > 0 && n_j > 0 ) {
618  base_pair_list.push_back( core::scoring::rna::Base_pair( i, j, edge_classification_i, edge_classification_j , orientation ) );
619  if ( false ) std::cout << pose.residue( i ).name1() << i << " " << pose.residue(j).name1() << j << " " << get_edge_from_num( edge_classification_i ) << " " << get_edge_from_num( edge_classification_j ) << " " << orientation << std::endl;
620 
621  // }
622 
623  }
624  }
625 
626  //////////////////////////////////////////////////////////////
627  is_bulged.clear();
628  for ( Size i = 1; i <= pose.total_residue(); i++ ) {
629  bool const check_bulge = residue_is_bulge( pose, i );
630  is_bulged.push_back( check_bulge );
631  if ( check_bulge && false ) {
632  std::cout << " BULGE " << i << std::endl;
633  }
634  }
635 
636 }
637 
638 //////////////////////////////////////////////////////////////////////
639 Size
641  core::pose::Pose const & pose_input
642 )
643 {
644  using namespace core::scoring;
645  using namespace core::scoring::rna;
646 
648 
649  pose::Pose pose = pose_input;
650 
651  (*denovo_scorefxn)( pose );
652 
653  RNA_ScoringInfo const & rna_scoring_info( rna_scoring_info_from_pose( pose ) );
654  RNA_FilteredBaseBaseInfo const & rna_filtered_base_base_info( rna_scoring_info.rna_filtered_base_base_info() );
655  Energy_base_stack_list const & scored_base_stack_list( rna_filtered_base_base_info.scored_base_stack_list() );
656 
657  return scored_base_stack_list.size();
658 
659 }
660 
661 } // namespace rna
662 } // namespace protocols