Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Ramachandran.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/Ramachandran.cc
11 /// @brief Ramachandran potential class implementation
12 /// @author Andrew Leaver-Fay (leaverfa@email.unc.edu)
13 
14 // Unit Headers
16 
17 // Package Headers
19 #include <core/scoring/Energies.hh>
20 
21 // Project Headers
23 #include <core/pose/Pose.hh>
24 #include <basic/database/open.hh>
25 #include <basic/options/option.hh>
26 
27 // Numeric Headers
28 #include <numeric/angle.functions.hh>
29 #include <numeric/interpolation/periodic_range/half/interpolation.hh>
30 #include <numeric/random/random.hh>
31 
32 // Utility Headers
33 #include <utility/pointer/ReferenceCount.hh>
34 #include <utility/io/izstream.hh>
35 
36 // ObjexxFCL Headers
37 #include <ObjexxFCL/FArray1D.hh>
38 #include <ObjexxFCL/FArray2D.hh>
39 #include <ObjexxFCL/FArray2A.hh>
40 #include <ObjexxFCL/FArray4D.hh>
41 #include <ObjexxFCL/string.functions.hh>
42 
43 // AS -- to get access to get_torsion_bin()
45 
46 // option key includes
47 
48 // AUTO-REMOVED #include <basic/options/keys/loops.OptionKeys.gen.hh>
49 // AUTO-REMOVED #include <basic/options/keys/score.OptionKeys.gen.hh>
50 #include <basic/options/keys/corrections.OptionKeys.gen.hh>
51 // AUTO-REMOVED #include <basic/options/keys/in.OptionKeys.gen.hh>
52 #include <basic/options/keys/OptionKeys.hh>
53 
54 #include <utility/vector1.hh>
55 #include <sstream>
56 
57 
58 
59 using namespace ObjexxFCL;
60 
61 namespace core {
62 namespace scoring {
63 
64 // @brief Auto-generated virtual destructor
65 Ramachandran::~Ramachandran() {}
66 
67 typedef Ramachandran R;
68 
69 bool R::rama_initialized_( false );
70 Real const R::binw_( 10.0 );
71 Real const R::rama_sampling_thold_( 0.00075 ); // only sample torsions with Rama prob above this value
72 Real const R::rama_sampling_factor_( 10.0 ); // factor for increased precision of Rama sampling table
73 ObjexxFCL::FArray4D< Real > R::ram_probabil_( R::n_phi_, R::n_psi_, 3, R::n_aa_ );
74 ObjexxFCL::FArray4D_int R::ram_counts_( R::n_phi_, R::n_psi_, 3, R::n_aa_ );
75 ObjexxFCL::FArray4D< Real > R::ram_energ_( R::n_phi_, R::n_psi_, 3, R::n_aa_);
76 ObjexxFCL::FArray2D< Real > R::ram_entropy_( 3, R::n_aa_ );
77 
78 Ramachandran::Ramachandran()
79 {
80  using namespace basic::options;
81  read_rama(
82  option[ OptionKeys::corrections::score::rama_map ]().name(),
83  option[ OptionKeys::corrections::score::use_bicubic_interpolation ]);
84 }
85 
86 
87 Ramachandran::Ramachandran(
88  std::string const & rama_map_filename,
89  bool use_bicubic_interpolation
90 ) {
91  read_rama(rama_map_filename, use_bicubic_interpolation);
92 }
93 
94 
95 ///////////////////////////////////////////////////////////////////////////////
96 
97 /// @brief evaluate rama score for each (protein) residue and store that score
98 /// in the pose.energies() object
99 void
100 Ramachandran::eval_rama_score_all(
101  pose::Pose & pose,
102  ScoreFunction const & scorefxn
103 ) const
104 {
105  if ( scorefxn.has_zero_weight( rama ) ) return; // unnecessary, righ?
106 
107  //double rama_sum = 0.0;
108 
109  // in pose mode, we use fold_tree.cutpoint info to exclude terminus
110  // residues from rama calculation. A cutpoint could be either an artificial
111  // cutpoint such as loop cutpoint or a real physical chain break such as
112  // multiple-chain complex. For the artificial cutpoint, we may need to
113  // calculate rama scores for cutpoint residues, but for the real chain break
114  // cutpoint, we don't want to do that. So here we first loop over all the
115  // residue in the protein and exclude those ones which are the cutpoints.
116  // Then we loop over the cutpoint residues and add rama score for residues
117  // at artificial cutpoints, i.e., cut_weight != 0.0, which means that
118  // jmp_chainbreak_score is also calculated for this cutpoint. Note that the
119  // default value for cut_weight here is dependent on whether
120  // jmp_chainbreak_weight is set. This is to ensure that rama score for
121  // termini residues are not calculated when jmp_chainbreak_weight is 0.0,
122  // e.g normal pose docking.
123 
124  int const total_residue = pose.total_residue();
125 
126  // retrieve cutpoint info // apl do we actually need this data?
127  // if so, Pose must provide it 'cause we're offing all global data
128  //
129  //kinematics::FoldTree const & fold_tree(
130  // pose.fold_tree() );
131  //int const n_cut( fold_tree.num_cutpoint() );
132 
133  //FArray1D< Real > cut_weight( n_cut,
134  // scorefxns::jmp_chainbreak_weight == 0.0 ? 0.0 : 1.0 ); // apl need to handle
135 
136  //if( cut_weight.size1() == scorefxns::cut_weight.size1() )
137  // cut_weight = scorefxns::cut_weight;
138 
139  // exclude chain breaks
140 
141  Energies & pose_energies( pose.energies() );
142 
143  for ( int ii = 1; ii <= total_residue; ++ii )
144  {
145  if ( pose.residue(ii).is_protein() && ! pose.residue(ii).is_terminus() && ! pose.residue(ii).is_virtual_residue() )
146  {
147  Real rama_score,dphi,dpsi;
148  eval_rama_score_residue(pose.residue(ii),rama_score,dphi,dpsi);
149  //std::cout << "Rama: residue " << ii << " = " << rama_score << std::endl;
150  pose_energies.onebody_energies( ii )[rama] = rama_score;
151  }
152  }
153 }
154 
155 
156 ///////////////////////////////////////////////////////////////////////////////
157 void
158 Ramachandran::write_rama_score_all( Pose const & /*pose*/ ) const
159 {}
160 
161  ///////////////////////////////////////////////////////////////////////////////
162  /// Initialize the table holding the sample-able torsion space for each residue
163  /// with each torsion given indices proportionate to its probability
164  void
165  Ramachandran::init_rama_sampling_table(
166  char const torsion_bin) // torsion_bin defaults to 'X' unless specified
167  {
168  //rama_sampling_table_.resize(n_aa_);
169  utility::vector1< utility::vector1< utility::vector1< Real > > > current_rama_sampling_table;
170  current_rama_sampling_table.resize(n_aa_);
171  int ss_type=3;
172  FArray2A< Real >::IR const zero_index( 0, n_phi_ - 1);
173  for (int aa=1; aa<=n_aa_; aa++) { // loop over all residue types
174  FArray2A< Real > const rama_for_res( ram_probabil_(1, 1, ss_type, aa), zero_index, zero_index );
175  Size max_allowed = n_phi_ * n_psi_;
176  Size actual_allowed = 0;
177  Real min_val = 1.0; // minimum probability (above rama_sampling_thold_) observed for this residue
178  Real max_val = 0.0; // maximum probability (above rama_sampling_thold_) observed for this residue
179  utility::vector1< utility::vector1< Real> > res_torsions( max_allowed ); // double vector of allowed torsions for this residue
180  utility::vector1< Real > res_probs( max_allowed ); // rama probs of allowed torsions for this residue (coupled to res_torsions by index)
181  //rama_sampling_table_[aa].resize(max_allowed);
182  for (int i=0; i<n_phi_; i++) {
183  for (int j=0; j<n_psi_; j++) {
184  Real res_prob = rama_for_res(i,j);
185  if ( res_prob > rama_sampling_thold_ ) {
186  //actual_allowed++; // AS: moved down into if statement, otherwise some entries are empty -> segfault
187  if (res_prob < min_val) min_val = res_prob;
188  else if (res_prob > max_val) max_val = res_prob;
189  //std::cout << res_prob << std::endl;
190  //res_probs[actual_allowed] = res_prob;
191 
192  utility::vector1< Real > torsion(2);
193  Real cur_phi, cur_psi;
194  if (i <= n_phi_ / 2) {
195  cur_phi = i;
196  }
197  else {
198  cur_phi = 0 - (n_phi_ - i);
199  }
200  if (j <= n_psi_ / 2) {
201  cur_psi = j;
202  }
203  else {
204  cur_psi = 0 - (n_psi_ - j);
205  }
206  char cur_tb = ' ';
207  if (torsion_bin != 'X')
208  cur_tb = core::conformation::get_torsion_bin(cur_phi * 10, cur_psi * 10); // AS -- how can we get the factor properly / without hard-coding? - also: this takes very long...
209  if (torsion_bin == 'X' || cur_tb == torsion_bin) {
210  actual_allowed++;
211  res_probs[actual_allowed] = res_prob;
212  torsion[1] = static_cast <Real> (/*i*/ cur_phi * binw_); // phi
213  torsion[2] = static_cast <Real> (/*j*/ cur_psi * binw_); // psi
214  res_torsions[actual_allowed] = torsion;
215  //rama_sampling_table_[aa][++actual_allowed] = torsion;
216  //} else {
217  //std::cerr << "warning -- discarding phi/psi " << cur_phi << "/" << cur_psi << " because they're not in torsion bin " << torsion_bin << std::endl;
218  }
219  }
220  }
221  }
222 
223  if( ((int)aa < (int)1) || ((int)aa > (int)current_rama_sampling_table.size()) ){
224  std::cerr << "AA exceeded size of rama_sampling_table_ AA=" + ObjexxFCL::string_of( aa ) + " size()=" + ObjexxFCL::string_of( current_rama_sampling_table.size() );
225  continue; // Avoid death.
226  }
227 
228  //std::cerr << "populating table for torsion bin " << torsion_bin << " and " << AA(aa) << std::endl;
229 
230  // now populate the rama_sampling_table_ so the torsions are given index space proporionate to their probs
231  current_rama_sampling_table[aa].resize(Size(actual_allowed * (max_val / min_val) * rama_sampling_factor_));
232  Size index=0; // to increment the index into the aa's rama_sampling_table_ vector
233  //std::cout << "for aa " << aa << ":" << std::endl;
234  for (Size tor = 1; tor <= actual_allowed; tor++) {
235  Size n_indices = Size(( res_probs[tor] / min_val ) * rama_sampling_factor_);
236  //std::cout << "n_indices for torsion " << tor << ": " << n_indices << std::endl;
237  for (Size ind=1; ind<=n_indices; ind++) {
238  index++;
239  if( (int(index) < 1) || (int(index) > (int)current_rama_sampling_table[aa].size()) ){
240  std::cerr << "index exceeded size of rama_sampling_table_[aa] index=" +
241  ObjexxFCL::string_of( (index) ) +
242  " rama_sampling_table_[aa].size()=" +
243  ObjexxFCL::string_of( current_rama_sampling_table[aa].size() ) +
244  " AA=" + ObjexxFCL::string_of( aa );
245 
246  continue; // avoid certain death - we dont yet understand why its failing here occasionally
247  }
248  if( ((int)tor < 1) || ((int)tor > (int)res_torsions.size()) ){
249  std::cerr << "tor exceeded size of rama_sampling_table_[aa] index=" +
250  ObjexxFCL::string_of( tor ) +
251  " res_torsions.size()=" + ObjexxFCL::string_of( res_torsions.size() ) +
252  " AA=" + ObjexxFCL::string_of( aa );
253  continue; // avoid certain death - we dont yet understand why its failing here occasionally
254  }
255 
256  current_rama_sampling_table[aa][index] = res_torsions[tor];
257  }
258  }
259  current_rama_sampling_table[aa].resize(index);
260  //std::cerr << " table for " << AA(aa) << " has size " << index << std::endl; // ?
261  }
262 
263  if (torsion_bin == 'X') {
264  rama_sampling_table_ = current_rama_sampling_table;
265  }
266  core::Size tb_index = get_torsion_bin_index(torsion_bin);
267  //std::cerr << "storing table for torsion bin " << torsion_bin << " --> " << tb_index << std::endl;
268  if (rama_sampling_table_by_torsion_bin_.size() < tb_index)
269  rama_sampling_table_by_torsion_bin_.resize(tb_index);
270  //std::cerr << "table resized" << std::endl;
271  rama_sampling_table_by_torsion_bin_[tb_index] = current_rama_sampling_table;
272 
273  // DJM: test the rama sampling table
274  //AA test_aa(core::chemical::aa_gly);
275  //for (Size jj = 1; jj <= 500; jj++) {
276  // Real new_phi, new_psi;
277  // random_phipsi_from_rama(test_aa, new_phi, new_psi);
278  // std::cout << new_phi << " " << new_psi << std::endl;
279  //}
280  }
281 
282  ///////////////////////////////////////////////////////////////////////////////
283  /// Sample phi/psi torsions with probabilities proportionate to their
284  /// Ramachandran probabilities
285  /// Note -- this function had previously required that the option
286  /// loops::nonpivot_torsion_sampling be active. This function now
287  /// performs a just-in-time check to initialize these tables the first
288  /// time they are requested -- To properly multi-thread this code, the
289  /// function should nab a mutex so that no two threads try to execute
290  /// the code at once.
291  void
292  Ramachandran::random_phipsi_from_rama(
293  AA const res_aa,
294  Real & phi,
295  Real & psi
296  ) const
297  {
298 
299  if ( rama_sampling_table_.size() == 0 ) {
300  /// Danger -- not threadsafe.
301  const_cast< Ramachandran * > (this)->init_rama_sampling_table('X');
302  }
303 
304  Size n_torsions = rama_sampling_table_[res_aa].size();
305  Size index = numeric::random::random_range(1, n_torsions);
306 
307  // following lines set phi and set to values drawn proportionately from Rama space
308  // plus or minus uniform noise equal to half the bin width.
309  phi = rama_sampling_table_[res_aa][index][1] +
310  (numeric::random::uniform() * binw_ * 0.5 * (numeric::random::uniform() < 0.5 ? -1 : 1));
311  psi = rama_sampling_table_[res_aa][index][2] +
312  (numeric::random::uniform() * binw_ * 0.5 * (numeric::random::uniform() < 0.5 ? -1 : 1));
313  // DJM: debug
314  //std::cout << "res_aa: " << res_aa << std::endl;
315  //std::cout << "phi: " << phi << std::endl;
316  //std::cout << "psi: " << psi << std::endl;
317 
318  /*
319  for (Size i=1; i<= rama_sampling_table_.size(); i++) {
320  std::cout << "number of allowed torsions for " << AA(i) << ": " << rama_sampling_table_[i].size() << std::endl;
321  }
322 
323  for (Size i=1; i <= n_torsions; i++) {
324  std::cout << rama_sampling_table_[res_aa][i][1] << " " << rama_sampling_table_[res_aa][i][2] << std::endl;
325  }
326  */
327  }
328 
329  ///////////////////////////////////////////////////////////////////////////////
330  /// Sample phi/psi torsions with probabilities proportionate to their
331  /// Ramachandran probabilities -- this version performs lookup restricted to specified torsion bins
332  /// based on random_phipsi_from_rama and has the same issue for parallel running
333 
334  /// @author Amelie Stein (amelie.stein@ucsf.edu)
335  /// @date Fri May 11 15:52:01 PDT 2012
336  /// @details returns a random phi/psi combination within the given torsion bin -- WARNING: this will only work for the torsion bins that are currently implemented
337 
338  void
339  Ramachandran::random_phipsi_from_rama_by_torsion_bin(
340  AA const res_aa,
341  Real & phi,
342  Real & psi,
343  char const torsion_bin
344  ) const
345  {
346 
347 
348  //utility::vector1< utility::vector1< utility::vector1< Real > > > current_rama_sampling_table; // depends on the torsion bin
349 
350  //if (rama_sampling_table_by_torsion_bin_.find(torsion_bin) == rama_sampling_table_by_torsion_bin_.end()) {
351  if (rama_sampling_table_by_torsion_bin_.size() == 0) {
352  const_cast< Ramachandran * > (this)->init_rama_sampling_tables_by_torsion_bin();
353  // not threadsafe either
354  // initialize the table for this torsion bin and residue
355  // TODO: store the original sampling table before doing this, and then write it back after storing the result of this function, so that we don't lose or overwrite this information
356  //std::cerr << " generating rama sampling table for torsion bin " << torsion_bin << std::endl; // make sure that all of this is only done once
357 
358  }
359 
360  core::Size tb_index = get_torsion_bin_index(torsion_bin);
361  /*
362  std::map< char, utility::vector1< utility::vector1< utility::vector1< Real > > > >::const_iterator m_iter = rama_sampling_table_by_torsion_bin_.find(torsion_bin);
363  if (m_iter != rama_sampling_table_by_torsion_bin_.end()) {
364  //std::cerr << "trying to fetch the table for torsion bin " << torsion_bin << std::endl;
365  current_rama_sampling_table = m_iter->second;
366  }
367 
368  std::cerr << " rama sampling table size / # torsion bins" << rama_sampling_table_by_torsion_bin_.size() << std::endl;
369  std::cerr << " rama sampling table size " << rama_sampling_table_by_torsion_bin_[tb_index].size() << std::endl;
370  std::cerr << " -- res: " << res_aa << " " << rama_sampling_table_by_torsion_bin_[tb_index][res_aa].size() << std::endl;
371  */
372 
373  Size n_torsions = rama_sampling_table_by_torsion_bin_[tb_index][res_aa].size();
374  Size index = numeric::random::random_range(1, n_torsions);
375 
376  /*
377  // check if for some reason the bins are not populated
378  std::cerr << current_rama_sampling_table[res_aa][index].size() << " index " << index << std::endl;
379  for (int i = 0; i < current_rama_sampling_table[res_aa][index].size(); i++)
380  std::cerr << current_rama_sampling_table[res_aa][index][i] << " - " << i << std::endl;
381 
382  std::cerr << current_rama_sampling_table[res_aa][index][1] << " index " << index << " / 1" << std::endl;
383  std::cerr << current_rama_sampling_table[res_aa][index][2] << " index " << index << " / 2" << std::endl;
384  */
385  // following lines set phi and set to values drawn proportionately from Rama space
386  // plus or minus uniform noise equal to half the bin width.
387  phi = rama_sampling_table_by_torsion_bin_[tb_index][res_aa][index][1] +
388  (numeric::random::uniform() * binw_ * 0.5 * (numeric::random::uniform() < 0.5 ? -1 : 1));
389  psi = rama_sampling_table_by_torsion_bin_[tb_index][res_aa][index][2] +
390  (numeric::random::uniform() * binw_ * 0.5 * (numeric::random::uniform() < 0.5 ? -1 : 1));
391  // DJM: debug
392  //std::cout << "res_aa: " << res_aa << std::endl;
393  //std::cout << "phi: " << phi << std::endl;
394  //std::cout << "psi: " << psi << std::endl;
395 
396 
397  } // random_phipsi_from_rama_by_torsion_bin
398 
399 
400 
401  core::Size Ramachandran::get_torsion_bin_index(char torsion_bin) const
402  {
403  return toupper(torsion_bin) - toupper('A') + 1;
404  }
405 
406 
407  // just to avoid code duplication
408  void
409  Ramachandran::init_rama_sampling_tables_by_torsion_bin()
410  {
411  const_cast< Ramachandran * > (this)->init_rama_sampling_table( 'A' );
412  const_cast< Ramachandran * > (this)->init_rama_sampling_table( 'B' );
413  const_cast< Ramachandran * > (this)->init_rama_sampling_table( 'E' );
414  const_cast< Ramachandran * > (this)->init_rama_sampling_table( 'G' );
415  const_cast< Ramachandran * > (this)->init_rama_sampling_table( 'X' ); // to allow wildcards in the torsion string
416  }
417 
418  void
419  Ramachandran::get_entries_per_torsion_bin( AA const res_aa, std::map< char, core::Size > & tb_frequencies ) const
420  {
421  // check if the tables are initialized, and if not, do so
422  if (rama_sampling_table_by_torsion_bin_.size() == 0)
423  const_cast< Ramachandran * > (this)->init_rama_sampling_tables_by_torsion_bin();
424  tb_frequencies['A'] = rama_sampling_table_by_torsion_bin_[get_torsion_bin_index('A')][res_aa].size();
425  tb_frequencies['B'] = rama_sampling_table_by_torsion_bin_[get_torsion_bin_index('B')][res_aa].size();
426  tb_frequencies['E'] = rama_sampling_table_by_torsion_bin_[get_torsion_bin_index('E')][res_aa].size();
427  tb_frequencies['G'] = rama_sampling_table_by_torsion_bin_[get_torsion_bin_index('G')][res_aa].size();
428  tb_frequencies['X'] = rama_sampling_table_by_torsion_bin_[get_torsion_bin_index('X')][res_aa].size();
429  }
430 
431 
432 ///////////////////////////////////////////////////////////////////////////////
433 void
434 Ramachandran::eval_rama_score_residue(
435  conformation::Residue const & rsd,
436  Real & rama,
437  Real & drama_dphi,
438  Real & drama_dpsi
439 ) const
440 {
441  using namespace numeric;
442 
443  //assert( pose.residue(res).is_protein() );
444  assert( rsd.is_protein() );
445 
446  Real const phi
447  ( nonnegative_principal_angle_degrees( rsd.mainchain_torsion(1)));
448  Real const psi
449  ( nonnegative_principal_angle_degrees( rsd.mainchain_torsion(2)));
450 
451  if ( phi == 0.0 || psi == 0.0 || rsd.is_terminus() || rsd.is_virtual_residue() ) { // begin or end of chain
452  rama = 0.0;
453  drama_dphi = 0.0;
454  drama_dpsi = 0.0;
455  return;
456  }
457 
458  eval_rama_score_residue( rsd.aa(), phi, psi, rama, drama_dphi, drama_dpsi );
459 }
460 
461 
462 ///////////////////////////////////////////////////////////////////////////////
463 ///
464 Real
465 Ramachandran::eval_rama_score_residue(
466  AA const res_aa,
467  Real const phi,
468  Real const psi
469 ) const
470 {
471 
472  Real rama, drama_dphi, drama_dpsi;
473  eval_rama_score_residue( res_aa, phi, psi, rama, drama_dphi, drama_dpsi );
474  return rama;
475 }
476 
477 void
478 Ramachandran::eval_rama_score_residue(
479  AA const res_aa,
480  Real const phi,
481  Real const psi,
482  Real & rama,
483  Real & drama_dphi,
484  Real & drama_dpsi
485 ) const {
486  using namespace basic::options;
487  eval_rama_score_residue(
488  option[ OptionKeys::corrections::score::use_bicubic_interpolation ],
489  option[ OptionKeys::corrections::score::rama_not_squared ],
490  res_aa, phi, psi, rama, drama_dphi, drama_dpsi);
491 }
492 
493 ///////////////////////////////////////////////////////////////////////////////
494 ///
495 void
496 Ramachandran::eval_rama_score_residue(
497  bool use_bicubic_interpolation,
498  bool rama_not_squared,
499  AA const res_aa,
500  Real const phi,
501  Real const psi,
502  Real & rama,
503  Real & drama_dphi,
504  Real & drama_dpsi
505 ) const
506 {
507  using namespace numeric;
508 
509 //db
510 //db secondary structure dependent tables favor helix slightly.
511 //db only use if have predicted all alpha protein
512 //db
513 // rhiju and db: no longer use alpha-specific rama, after
514 // tests on 1yrf and other all alpha proteins. 2-8-07
515 
516 // apl -- removing ss dependence on rama in first implementation of mini
517 // after reading rhiju and david's comment above. We will need a structural annotation
518 // obect (structure.cc, maybe a class SecStruct) at some point. The question
519 // remains whether a pose should hold that object and be responsible for its upkeep,
520 // or whether such an object could be created as needed to sit alongside a pose.
521 //
522 // std::string protein_sstype = get_protein_sstype();
523 // int ss_type;
524 // if ( use_alpha_rama_flag() && get_protein_sstype() == "a" ) {
525 // ss_type = ( ( ss == 'H' ) ? 1 : ( ( ss == 'E' ) ? 2 : 3 ) );
526 // } else {
527  int ss_type = 3;
528 // }
529 
530 // do I (?cems/cj/cdb?) want to interpolate probabilities or log probs???
531 // currently am interpolating probs then logging.
532 
533  //int const res_aa( rsd.aa() );
534  // int const res_aa( pose.residue( res ).aa() );
535  if ( use_bicubic_interpolation ) {
536 
537  rama = rama_energy_splines_[ res_aa ].F(phi,psi);
538  drama_dphi = rama_energy_splines_[ res_aa ].dFdx(phi,psi);
539  drama_dpsi = rama_energy_splines_[ res_aa ].dFdy(phi,psi);
540  return; // temp -- just stop right here
541  } else {
542 
543  FArray2A< Real >::IR const zero_index( 0, n_phi_ - 1);
544  FArray2A< Real > const rama_for_res( ram_probabil_(1, 1, ss_type, res_aa), zero_index, zero_index );
545  Real interp_p,dp_dphi,dp_dpsi;
546 
547  using namespace numeric::interpolation::periodic_range::half;
548  interp_p = bilinearly_interpolated( phi, psi, binw_, n_phi_, rama_for_res, dp_dphi, dp_dpsi );
549 
550  if ( interp_p > 0.0 ) {
551  rama = ram_entropy_(ss_type, res_aa ) - std::log( static_cast< double >( interp_p ) );
552  double const interp_p_inv_neg = -1.0 / interp_p;
553  drama_dphi = interp_p_inv_neg * dp_dphi;
554  drama_dpsi = interp_p_inv_neg * dp_dpsi;
555  } else {
556  //if ( runlevel > silent ) { //apl fix this
557  // std::cout << "rama prob = 0. in eval_rama_score_residue!" << std::endl;
558  // std::cout << "phi" << SS( phi ) << " psi" << SS( psi ) <<
559  // " ss " << SS( ss ) << std::endl;
560  //}
561  drama_dphi = 0.0;
562  drama_dpsi = 0.0;
563  rama = 20.0;
564  }
565 
566  if ( ! rama_not_squared ) {
567  if ( rama > 1.0 ) {
568  Real const rama_squared = rama * rama;
569  if ( rama_squared > 20.0 ) {
570  //// limit the score, but give the true derivative
571  //// as guidance out of the flat section of map
572  drama_dphi = 0.0;
573  drama_dpsi = 0.0;
574  rama = 20.0;
575  } else {
576  drama_dphi = 2 * rama * drama_dphi;
577  drama_dpsi = 2 * rama * drama_dpsi;
578  rama = rama_squared;
579  }
580  }
581  }
582  }
583 }
584 
585 
586 
587 ///////////////////////////////////////////////////////////////////////////////
588 void Ramachandran::eval_procheck_rama(
589  Pose const & /*pose*/,
590  Real & /*favorable*/,
591  Real & /*allowed*/,
592  Real & /*generous*/
593 ) const
594 {}
595 
596 void
597 Ramachandran::read_rama(
598  std::string const & rama_map_filename,
599  bool use_bicubic_interpolation
600 ) {
601 
602  int aa_num,phi_bin,psi_bin,ss_type;
603  Real check,min_prob,max_prob;
604  double entropy;
605  char line[60];
606  int scan_count;
607  float pval, eval; // vars for sscanf float I/O
608 
609  utility::io::izstream iunit;
610 
611  // search in the local directory first
612  iunit.open( rama_map_filename );
613 
614  if ( !iunit.good() ) {
615  iunit.close();
616  if(!basic::database::open( iunit, rama_map_filename )){
617  std::stringstream err_msg;
618  err_msg << "Unable to open Ramachandran map '" << rama_map_filename << "'.";
619  utility_exit_with_message(err_msg.str());
620  }
621  }
622 
623 //cj std::cout << "index" << "aa" << "ramachandran entropy" << std::endl;
624 //KMa add_phospho_ser 2006-01
625  for ( int i = 1; i <= n_aa_ ; ++i ) {
626  for ( int ii = 1; ii <= 3; ++ii ) {
627  entropy = 0.0;
628  check = 0.0;
629  min_prob = 1e36;
630  max_prob = -min_prob;
631  for ( int j = 1; j <= 36; ++j ) {
632  for ( int k = 1; k <= 36; ++k ) {
633  iunit.getline( line, 60 );
634  if ( iunit.eof() ) {
635  goto L100;
636  } else if ( iunit.fail() ) { // Clear and continue: NO ERROR DETECTION
637  iunit.clear();
638  }
639  std::sscanf( line, "%5d", &aa_num );
640  std::sscanf( line+6, "%5d", &ss_type );
641  std::sscanf( line+12, "%5d", &phi_bin );
642  std::sscanf( line+18, "%5d", &psi_bin );
643  std::sscanf( line+24, "%5d", &ram_counts_(j,k,ii,i) );
644  std::sscanf( line+30, "%12f", &pval );
645  ram_probabil_(j,k,ii,i) = pval;
646  scan_count = std::sscanf( line+43, "%12f", &eval );
647  ram_energ_(j,k,ii,i) = eval;
648 
649  if ( scan_count == EOF ) continue; // Read problem: NO ERROR DETECTION
650 
651 // This is the Slick & Slow (S&S) stream-based method that is too slow for large
652 // files like this one, at least under the GCC 3.3.1 stream implementation.
653 // It should be retried on future releases and target compilers because there is
654 // no reason it cannot be competitive with good optimization and inlining.
655 // If this is used the <cstdio> can be removed.
656 //
657 // iunit >> bite( 5, aa_num ) >> skip( 1 ) >>
658 // bite( 5, ss_type ) >> skip( 1 ) >>
659 // bite( 5, phi_bin ) >> skip( 1 ) >>
660 // bite( 5, psi_bin ) >> skip( 1 ) >>
661 // bite( 5, ram_counts(j,k,ii,i) ) >> skip( 1 ) >>
662 // bite( 12, ram_probabil(j,k,ii,i) ) >> skip( 1 ) >>
663 // bite( 12, ram_energ(j,k,ii,i) ) >> skip;
664 // if ( iunit.eof() ) {
665 // goto L100;
666 // } else if ( iunit.fail() ) { // Clear and continue: NO ERROR DETECTION
667 // iunit.clear();
668 // iunit >> skip;
669 // }
670 
671  check += ram_probabil_(j,k,ii,i);
672  entropy += ram_probabil_(j,k,ii,i) *
673  std::log( static_cast< double >( ram_probabil_(j,k,ii,i) ) );
674  min_prob = std::min(ram_probabil_(j,k,ii,i),min_prob);
675  max_prob = std::max(ram_probabil_(j,k,ii,i),max_prob);
676  }
677  }
678  ram_entropy_(ii,i) = entropy;
679  }
680 //cj std::cout << SS( check ) << SS( std::log(min_prob) ) <<
681 //cj SS( std::log(max_prob) ) << SS( entropy ) << std::endl;
682  }
683 L100:
684  iunit.close();
685  iunit.clear();
686 
687  if ( use_bicubic_interpolation ) {
688  using namespace numeric;
689  using namespace numeric::interpolation::spline;
690  rama_energy_splines_.resize( chemical::num_canonical_aas );
691  for ( Size ii = 1; ii <= chemical::num_canonical_aas; ++ii ) {
692  BicubicSpline ramaEspline;
693  MathMatrix< Real > energy_vals( 36, 36 );
694  for ( Size jj = 0; jj < 36; ++jj ) {
695  for ( Size kk = 0; kk < 36; ++kk ) {
696  energy_vals( jj, kk ) = -std::log( ram_probabil_(jj+1,kk+1,3,ii )) + ram_entropy_(3,ii) ;
697  }
698  }
699  BorderFlag periodic_boundary[2] = { e_Periodic, e_Periodic };
700  Real start_vals[2] = {5.0, 5.0}; // grid is shifted by five degrees.
701  Real deltas[2] = {10.0, 10.0}; // grid is 10 degrees wide
702  bool lincont[2] = {false,false}; //meaningless argument for a bicubic spline with periodic boundary conditions
703  std::pair< Real, Real > unused[2];
704  unused[0] = std::make_pair( 0.0, 0.0 );
705  unused[1] = std::make_pair( 0.0, 0.0 );
706  ramaEspline.train( periodic_boundary, start_vals, deltas, energy_vals, lincont, unused );
707  rama_energy_splines_[ ii ] = ramaEspline;
708  }
709  }
710 //cj std::cout << "========================================" << std::endl;
711 }
712 
713 
714 
715 }
716 }