Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
MakeRotLib.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 // This file is made available under the Rosetta Commons license.
5 // See http://www.rosettacommons.org/license
6 // (C) 199x-2008 University of Washington
7 // (C) 199x-2008 University of California Santa Cruz
8 // (C) 199x-2008 University of California San Francisco
9 // (C) 199x-2008 Johns Hopkins University
10 // (C) 199x-2008 University of North Carolina, Chapel Hill
11 // (C) 199x-2008 Vanderbilt University
12 
13 // unit headers
16 
17 // core headers
18 #include <core/types.hh>
19 // AUTO-REMOVED #include <core/scoring/ScoreFunctionFactory.hh>
21 #include <core/io/pdb/pose_io.hh>
22 #include <core/pose/Pose.hh>
23 #include <core/scoring/Energies.hh>
29 #include <core/id/TorsionID.hh>
30 #include <core/id/types.hh>
31 
32 // utility headers
33 #include <utility/file/FileName.hh>
34 #include <utility/file/file_sys_util.hh>
35 #include <utility/exit.hh>
36 #include <utility/vector1.functions.hh>
37 
38 // numeric headers
39 #include <numeric/angle.functions.hh>
40 
41 // protocol headers
43 
44 // C++ headers
45 #include <iostream>
46 // AUTO-REMOVED #include <istream>
47 #include <sstream>
48 #include <fstream>
49 #include <string>
50 #include <iomanip>
51 #include <cmath>
52 
53 #include <utility/vector1.hh>
54 
55 
56 namespace protocols {
57 namespace MakeRotLib {
58 
59 using namespace core;
60 using namespace utility;
61 
62 
63 // helper function returns the difference between to angles
64 Real
65 angle_diff( Real a1, Real a2 )
66 {
67  Real t1( fabs(a1 - a2) );
68  Real t2( 360 - t1 );
69  return( t1 <= t2 ? t1 : t2 );
70 }
71 
72 // hack hack hack
73 void
74 asp_corrections( RotVec & rotamers )
75 {
76  for( Size i = 1; i <= rotamers.size(); ++i ) {
77  Real temp_chi( rotamers[i].get_min_chi(2) );
78  if ( temp_chi >= 90 && temp_chi <= 180 ) {
79  rotamers[i].set_min_chi( temp_chi+180, 2 );
80  } else if ( temp_chi > 180 && temp_chi <= 270 ) {
81  rotamers[i].set_min_chi( temp_chi-180, 2 );
82  }
83  }
84 }
85 
86 void
87 glu_corrections( RotVec & rotamers )
88 {
89  for( Size i = 1; i <= rotamers.size(); ++i ) {
90  Real temp_chi( rotamers[i].get_min_chi(3) );
91  if ( temp_chi >= 90 && temp_chi <= 180 ) {
92  rotamers[i].set_min_chi( temp_chi+180, 3 );
93  } else if ( temp_chi > 180 && temp_chi <= 270 ) {
94  rotamers[i].set_min_chi( temp_chi-180, 3 );
95  }
96  }
97 }
98 
99 void
101 {
102  for( Size i = 1; i <= rotamers.size(); ++i ) {
103  Real temp_chi( rotamers[i].get_min_chi(2) );
104  if ( temp_chi >= 135 && temp_chi <= 180 ) {
105  rotamers[i].set_min_chi( temp_chi+180, 2 );
106  } else if ( temp_chi > 180 && temp_chi <= 315 ) {
107  rotamers[i].set_min_chi( temp_chi-180, 2 );
108  }
109  }
110 }
111 
112 void
114 {
115  int count(0);
116  for ( vector1<RotData>::iterator start( rotamers.begin() ), iter( rotamers.end() - 1 ); iter >= start; iter-- ) {
117  Real temp_omg( iter->get_min_omega() );
118  if ( temp_omg >=0 && temp_omg < 90 ) {
119  rotamers.erase( iter );
120  count++;
121  } else if ( temp_omg >= 270 && temp_omg < 360 ) {
122  rotamers.erase( iter );
123  count++;
124  }
125  }
126  std::cout << "Erased " << count << "CIS PEPTOID rotamers" << std::endl;
127 }
128 
129 void
131 {
132  int count(0);
133  for ( vector1<RotData>::iterator start( rotamers.begin() ), iter( rotamers.end() - 1 ); iter >= start; iter-- ) {
134  Real temp_omg( iter->get_min_omega() );
135  if ( temp_omg >= 90 && temp_omg < 270 ) {
136  rotamers.erase( iter );
137  count++;
138  }
139  }
140  std::cout << "Erased " << count << "TRANS PEPTOID rotamers" << std::endl;
141 }
142 
143 void
145 {
146  using namespace core;
147  using namespace pose;
148  using namespace scoring;
149  using namespace chemical;
150  using namespace conformation;
151 
152  std::cout << "In min_rotamers()..." << std::flush << std::endl;
153 
154  // iterate over rotamers array
155  Size const nrot( rotamers.size() );
156  for (Size i = 1; i <= nrot; ++i ) {
157 
158  std::cout << "Working on rotamer " << i << " of " << nrot << std::flush << std::endl;
159 
160  // get number of chi
161  Size const nchi( rotamers[i].get_num_chi() );
162 
163  // create filenames
164  std::stringstream start_name;
165  start_name << "tripeptide_" << rotamers[i].get_phi() << "_" << rotamers[i].get_psi() << "_";
166  for(Size j = 1; j <= nchi; ++j ) {
167  start_name << rotamers[i].get_inp_chi( j ) << "_";
168  }
169  start_name << "start.pdb";
170  std::string start_filename( start_name.str() );
171 
172  std::stringstream end_name;
173  end_name << "tripeptide_" << rotamers[i].get_phi() << "_" << rotamers[i].get_psi() << "_";
174  for(Size j = 1; j <= nchi; ++j ) {
175  end_name << rotamers[i].get_inp_chi( j ) << "_";
176  }
177  end_name << "end.pdb";
178  std::string end_filename( end_name.str() );
179 
180  // make a pose, residue, and append residue to pose
181  Pose pose;
182  ResidueTypeSetCAP RTS( ChemicalManager::get_instance()->residue_type_set( FA_STANDARD ) );
183  ResidueType const & RT( RTS->name_map( aa_name ) );
184  Residue R( RT, true );
185  pose.append_residue_by_jump( R, 1 );
186 
187  // score the pose
188  //Real debug_ener( (*scrfxn)( pose ) );
189  //std::cout << "DEBUG ENER: " << debug_ener << std::endl;
190 
191  // set phi, psi, omega, epsilon and chi(s)
192  id::TorsionID bb1( 1, id::BB, 1 );
193  id::TorsionID bb2( 1, id::BB, 2 );
194  id::TorsionID bb3( 1, id::BB, 3 );
195  id::TorsionID bb4( 1, id::BB, 4 );
196 
197  pose.set_torsion( bb1, rotamers[i].get_omega() );
198  pose.set_torsion( bb2, rotamers[i].get_phi() );
199  pose.set_torsion( bb3, rotamers[i].get_psi() );
200  pose.set_torsion( bb4, rotamers[i].get_epsilon() );
201 
202  for(Size j = 1; j <= nchi; ++j ) {
203  pose.set_chi( j, 1, rotamers[i].get_inp_chi( j ) );
204  }
205 
206  // output starting pose
207  //core::io::pdb::dump_pdb( pose, start_filename );
208 
209  // score the pose
210  Real orig_ener( (*scrfxn)( pose ) );
211 
212  std::cout << "ORIG ENER: " << orig_ener << "\t" << pose.energies().total_energy() << std::endl;
213 
214  // minimize the pose
216  mvmp->set_chi( 1, true );
217  mvmp->set( bb1, true );
218  mvmp->set( bb4, true );
219  protocols::simple_moves::MinMover mnmvr( mvmp, scrfxn, "linmin", 0.0001, true );
220 
221 
222  Real current_ener( orig_ener), previous_ener( orig_ener );
223  Size iter(0);
224  do {
225  previous_ener = current_ener;
226  mnmvr.apply( pose );
227  current_ener = pose.energies().total_energy();
228  iter++;
229  if ( iter > 100 ) break;
230  } while ( current_ener + 0.001 < previous_ener );
231 
232  // score the pose
233  Real min_ener( pose.energies().total_energy() );
234 
235  // output ending pose
236  //core::io::pdb::dump_pdb( pose, end_filename );
237 
238  std::cout << "MIN ENER: " << min_ener << " found in " << iter << " steps" << std::endl;
239 
240  EnergyMap em( pose.energies().residue_total_energies(1) );
241  rotamers[i].set_twist( em[ mm_twist ] );
242  rotamers[i].set_inter_rep( em[ mm_lj_inter_rep ] );
243  rotamers[i].set_inter_atr( em[ mm_lj_inter_atr ] );
244  rotamers[i].set_intra_rep( em[ mm_lj_intra_rep ] );
245  rotamers[i].set_intra_atr( em[ mm_lj_intra_atr ] );
246  rotamers[i].set_solvation( em[ fa_sol ] );
247 
248  // record min chi, energy
249  for(Size j = 1; j <= nchi; ++j ) {
250  rotamers[i].set_min_chi( pose.chi( j, 1 ), j );
251  }
252  rotamers[i].set_energy( min_ener );
253  rotamers[i].set_min_omega( numeric::nonnegative_principal_angle_degrees( pose.torsion( bb1 ) ) );
254  rotamers[i].set_min_epsilon( numeric::nonnegative_principal_angle_degrees( pose.torsion( bb4 ) ) );
255 
256  }
257 
258 }
259 
260 void
262 ( RotVec & rotamers,
263  RotVec & centroids,
264  Size & ncluster,
265  std::string options_filename,
266  std::string & aa_name,
267  bool is_peptoid,
268  Real omega_start_val,
269  Real epsilon_start_val
270 )
271 {
272 
273  //init stuff to hold lines
275  std::string line;
276 
277  // check to see if options file exists
278  if( ! utility::file::file_exists( options_filename.c_str() ) ) {
279  utility_exit_with_message("Cannot find options file"+options_filename);
280  }
281 
282  // open file
283  std::ifstream options( options_filename.c_str() );
284 
285  // read in each line
286  while ( getline( options, line ) ) {
287  std::istringstream l( line );
288  if ( line.size() < 1 || line[0] == '#' ) continue;
289  lines.push_back( line );
290  }
291 
292  // close options file
293  options.close();
294 
295  // get number of lines
296  Size const nlines( lines.size() );
297 
298  // go through file once to get number of chi angles, number of clusters,
299  // and aa name before parsing the rest of the file
300  Size nchi( 0 );
301  std::string base_aa_name;
302  for (Size i=1; i<= nlines; ++i ) {
303  std::string const & line( lines[i] );
304  std::istringstream l( line );
305  std::string tag;
306 
307  l >> tag;
308 
309  // get number of chi
310  if ( tag == "NUM_CHI" ) {
311  l >> nchi;
312  }
313 
314  // get number of clusters
315  else if ( tag == "CENTROID" ) {
316  ++ncluster;
317  }
318 
319  // get amino acid name
320  else if ( tag == "AA_NAME" ) {
321  l >> base_aa_name;
322  }
323  }
324 
325  // create full_aa_name
326  std::string patch;
327  if ( is_peptoid ) { // use this patch if we want peptoids
328  patch = "_p:AcetylatedNtermDimethylatedCtermPeptoidFull";
329  std::cout << "Making a PEPTOID rotamer library..." << std::endl;
330  } else { // use this patch if protein
331  patch = "_p:MethylatedCtermProteinFull_p:AcetylatedNtermProteinFull";
332  std::cout << "Making a PROTEIN rotamer library..." << std::endl;
333  }
334 
335  aa_name = base_aa_name + patch;
336 
337 
338  // parse the rest of the file
339  int phi_lower(0), phi_upper(0), phi_increment(0);
340  int psi_lower(0), psi_upper(0), psi_increment(0);
341  utility::vector1<int> chi_lower, chi_upper, chi_increment;
342  chi_lower.resize(nchi, 0); chi_upper.resize(nchi, 0); chi_increment.resize(nchi, 0);
343 
344  for (Size i=1; i<= nlines; ++i ) {
345  std::string const & line( lines[i] );
346  std::istringstream l( line );
347  std::string tag;
348 
349  l >> tag;
350 
351  // get phi range
352  if ( tag == "PHI_RANGE" ) {
353  l >> phi_lower >> phi_upper >> phi_increment;
354  }
355 
356  // get psi range
357  else if ( tag == "PSI_RANGE" ) {
358  l >> psi_lower >> psi_upper >> psi_increment;
359  }
360 
361  // get chi range(s)
362  else if ( tag == "CHI_RANGE" ) {
363  Size chi_num(0); int temp_lower, temp_upper, temp_increment;
364  l >> chi_num >> temp_lower >> temp_upper >> temp_increment;
365  assert( chi_num <= nchi );
366  chi_lower[chi_num] = temp_lower;
367  chi_upper[chi_num] = temp_upper;
368  chi_increment[chi_num] = temp_increment;
369  }
370 
371  // get centoids
372  else if ( tag == "CENTROID" ) {
373  RotData temp( nchi, ncluster );
374  for(Size i = 1; i<= nchi; ++i ) {
375  Real chi_val(0); int lib_chi_val(0);
376  l >> chi_val >> lib_chi_val;
377  temp.set_inp_chi( chi_val, i );
378  temp.set_min_chi( chi_val, i );
379  temp.set_lib_chi_val( lib_chi_val, i );
380  }
381  centroids.push_back( temp );
382  }
383  }
384 
385  // create intital based on rotamer range data
386  utility::vector1<Size> total_chi_num_bins;
387  total_chi_num_bins.resize(nchi, 0);
388  Size nrotamers(1);
389  for( Size i = 1; i <= nchi; ++i ) {
390  if ( (chi_upper[i] - chi_lower[i])%chi_increment[i] != 0 ) {
391  utility_exit_with_message("Number of chi bins not integer for chi: "+i);
392  }
393  total_chi_num_bins[i] = ((chi_upper[i] - chi_lower[i])/chi_increment[i])+1;
394  nrotamers *= total_chi_num_bins[i];
395  }
396 
397  // init rotamer array
398  RotData temp( nchi, ncluster );
399  rotamers.resize(nrotamers, temp);
400 
401  for (Size i = 1; i <= nchi; ++i ) {
402 
403  // calc all chi(i) valuse based on upper, lower, inc
404  utility::vector1<Real> chi_values;
405  for (int k = chi_lower[i]; k <= chi_upper[i]; k+=chi_increment[i] ){
406  chi_values.push_back( k );
407  }
408 
409  // iterator to keep track of where in rotamers we are
410  Size rot_iter(1);
411 
412  // calc number of rotmater combos for larger chi numbers
413  Size count_up(1);
414  if( i >= nchi ) {
415  count_up = 1;
416  }
417  else {
418  for (Size m = i+1; m <= nchi; ++m ) {
419  count_up *= total_chi_num_bins[m];
420  }
421  }
422  // calc number of rotmater combos for smaller chi numbers
423  Size count_down(1);
424  if( i <= 1) {
425  count_down = 1;
426  }
427  else {
428  for (Size m = 1; m < i; ++m ) {
429  count_down *= total_chi_num_bins[m];
430  }
431  }
432 
433  // assign chi values
434  for (Size n = 1; n <= count_down; ++n ) {
435  for (Size j = 1; j <= chi_values.size(); ++j ) {
436  for (Size l = 1; l <= count_up; ++l ) {
437  rotamers[rot_iter].set_inp_chi(chi_values[j], i);
438  ++rot_iter;
439  }
440  }
441  }
442  }
443 
444  // set phi and psi
445  // ultimatly this will be done higher up in the code to initialize EVERYTHING
446  // but i don't think that we will run that way at first
447  for( Size i = 1; i <= nrotamers; ++i ) {
448  rotamers[i].set_phi( phi_lower );
449  rotamers[i].set_psi( psi_lower );
450  rotamers[i].set_omega( omega_start_val );
451  rotamers[i].set_epsilon( epsilon_start_val );
452  }
453 }
454 
455 bool
457 {
458  // for all rotamers find closest centroid and assign cluster_num
459  // compare pt to its old cluster see if it changed locations
460  bool clust_change = false;
461  for (Size i=1; i<=rotamers.size(); ++i){
462  Size oldclust = rotamers[i].get_cluster_num();
463  Size clust = rotamers[i].get_min_cent_dist(); //to get closest centroid
464  rotamers[i].set_cluster_num(clust);
465  if ( oldclust != clust ){
466  clust_change = true;
467  }
468  }
469 
470  return clust_change;
471 }
472 
473 bool
474 calc_centroids(RotVec & rotamers, RotVec & centroids)
475 {
476  // for cluster i calc_dist divide by # in clust
477  // find mean of all pts in cluster
478  // set centroid to this mean
479 
480  typedef vector1<Real> rvec;
481 
482  Size ncluster( centroids.size() );
483  Size nchi( rotamers[1].get_num_chi() );
484 
485  // init num_rots
486  vector1<Size> num_rots;
487  num_rots.resize(ncluster,0);
488 
489  // init total_chi_angle
490  vector1< rvec > total_chi_angle;
491  total_chi_angle.resize(ncluster);
492  for( Size i = 1; i <= total_chi_angle.size(); ++i ) {
493  total_chi_angle[i].resize(nchi, 0);
494  }
495 
496  // sum up chi angle totals
497  for( Size i = 1; i <= rotamers.size(); ++i ) {
498  Size clusternum = rotamers[i].get_cluster_num();
499  for( Size j = 1; j <= nchi; ++j) {
500  total_chi_angle[clusternum][j] += rotamers[i].get_min_chi(j);
501  }
502  num_rots[clusternum]++;
503  }
504 
505  //get average angles and assign new centroid chi's
506  bool centroid_change(false);
507  for (Size i=1;i <= ncluster; ++i){
508  for (Size j=1; j <= nchi; ++j ){
509  Real old_angle = centroids[i].get_min_chi( j );
510  Real avg_angle = total_chi_angle[i][j] / num_rots[i];
511  centroids[i].set_min_chi( avg_angle, j );
512  if(old_angle != avg_angle) {
513  centroid_change = true;
514  }
515  }
516  }
517 
518  return centroid_change;
519 }
520 
521 Real
522 calc_dist( RotData & point1, RotData & point2 )
523 {
524  Size nchi(point1.get_num_chi());
525  Real sd(0);
526 
527  for( Size i = 1; i <= nchi; ++i ) {
528  sd += pow( angle_diff(point1.get_min_chi(i), point2.get_min_chi(i) ), 2 );
529  }
530 
531  return sqrt( sd/nchi );
532 }
533 
534 Real
535 avg_cluster_cen_dist(RotVec & rotamers, Size & ncluster)
536 {
537  // calc_dist from centroid to rotamers in cluster
538 
539  vector1<Real> total_dist;
540  vector1<Size> num_rots;
541 
542  total_dist.resize(ncluster,0);
543  num_rots.resize(ncluster,0);
544 
545 
546  for( Size i = 1; i <= rotamers.size(); ++i ) {
547  Size clusternum = rotamers[i].get_cluster_num();
548  total_dist[clusternum] += rotamers[i].get_cen_dist(clusternum);
549  num_rots[clusternum]++;
550  }
551 
552  //print out how many rots in each cluster
553  for (Size i=1; i <= ncluster; ++i){
554  std::cout << "Cluster: "<< i << " contains "<< num_rots[i] << " of "<< rotamers.size()<< " or %=" << static_cast<Real>(num_rots[i]) / static_cast<Real>(rotamers.size()) <<std::endl;
555  }
556 
557  std::cout <<"AVG_CLUST_CENT_DST: " <<std::endl;
558  Real avgdist(0);
559  for( Size i = 1; i <= ncluster; ++i ) {
560  std::cout << total_dist[i]/num_rots[i] << "\t";
561  avgdist += (total_dist[i]/num_rots[i]);
562  }
563  std::cout << std::endl;
564  std::cout << "AVG_CENT_DST:" << "\t";
565  return avgdist / total_dist.size();
566 }
567 
568 void
569 calc_all_dist(RotVec & rotamers, RotVec & centroids)
570 {
571  for (Size i=1; i <= rotamers.size(); ++i){
572  for (Size j=1; j<= centroids.size(); ++j){
573  Real dist = calc_dist (rotamers[i], centroids[j]);
574  rotamers[i].set_cen_dist(dist, j);
575  }
576  }
577 }
578 
579 // pull out best rots from rotamers and add them to final_rotamers
580 void
581 get_final_rots(RotVec & rotamers , RotVec & final_rotamers, Size & nclusters ){
582  RotData temp(rotamers[1].get_num_chi(), nclusters);
583  final_rotamers.resize(nclusters, temp);
584 
585  //sets high energies for later minimization (probably better way to do this)
586  for (Size j=1; j<= nclusters ; ++j){
587  final_rotamers[j].set_energy(6000);
588  }
589  //finds lowest E rotamer in each cluster
590  for (Size i=1; i<= rotamers.size(); ++i){
591  Size cluster_num( rotamers[i].get_cluster_num() );
592  if (rotamers[i].get_energy() <= final_rotamers[cluster_num].get_energy()){
593  final_rotamers[cluster_num] = rotamers[i];
594  }
595  }
596 }
597 
598 
599 // calc probabilites for final rots & normilize
600 void
601 get_final_rot_probs( RotVec & final_rotamers)
602 {
603  vector1<Real> prob_temp;
604  prob_temp.resize(final_rotamers.size(),0);
605  vector1<Real> normalized_ener;
606  normalized_ener.resize(final_rotamers.size(),0);
607  Real KbT(0.5961); //constant
608  Real total_prob(0);
609 
610  // get the minimum energy
611  Real min_ener(final_rotamers[1].get_energy()); // seed
612  for (Size i=1; i<=final_rotamers.size(); ++i){
613  if ( final_rotamers[i].get_energy() < min_ener ) {
614  min_ener = final_rotamers[i].get_energy();
615  }
616  }
617 
618  // calc the normalized energies
619  for (Size i=1; i<=final_rotamers.size(); ++i){
620  normalized_ener[i] = final_rotamers[i].get_energy() - min_ener;
621  }
622 
623  // finds probabilities from energy
624  for (Size i=1; i<=final_rotamers.size(); ++i){
625  prob_temp[i] = exp( ( -normalized_ener[i] ) / KbT ) ;
626  total_prob += prob_temp[i];
627  std::cout <<"Cluster: " << i << " Probability=" << prob_temp[i] << std::endl;
628  }
629  std::cout <<"Total Probability= " << total_prob << std::endl;
630  std::cout <<"Kb T value used: " << KbT << std::endl;
631 
632  //normalizes and sets probabilities of final_rotamers
633  for (Size i=1; i<=final_rotamers.size(); ++i){
634  final_rotamers[i].set_probability(prob_temp[i] / total_prob);
635  }
636 }
637 
638 //find standard deviation of chi
639 void
641 {
642  //copy from min_rotamers function
643  using namespace pose;
644  using namespace scoring;
645  using namespace chemical;
646  using namespace conformation;
647 
648  // make a pose, residue, and append residue to pos
649  Pose pose;
650  ResidueTypeSetCAP RTS( ChemicalManager::get_instance()->residue_type_set( FA_STANDARD ) );
651  ResidueType const & RT( RTS->name_map( aa_name ) );
652  Residue R( RT, true );
653  pose.append_residue_by_jump( R, 1 );
654 
655  // itterate over final rotamers
656  for (Size i = 1; i<= final_rotamers.size(); ++i){
657  Size const nchi (final_rotamers[i].get_num_chi() );
658 
659  // set phi, psi, chi
660  id::TorsionID bb1( 1, id::BB, 1 );
661  id::TorsionID bb2( 1, id::BB, 2 );
662  id::TorsionID bb3( 1, id::BB, 3 );
663  id::TorsionID bb4( 1, id::BB, 4 );
664  pose.set_torsion( bb1, final_rotamers[i].get_omega() );
665  pose.set_torsion( bb2, final_rotamers[i].get_phi() );
666  pose.set_torsion( bb3, final_rotamers[i].get_psi() );
667  pose.set_torsion( bb4, final_rotamers[i].get_epsilon() );
668 
669  for(Size l = 1; l <= nchi; ++l ) {
670  pose.set_chi( l, 1, final_rotamers[i].get_inp_chi( l ) );
671  }
672 
673  // minimize the pose
675  mvmp->set_chi( 1, true );
676  mvmp->set( bb1, true );
677  mvmp->set( bb4, true );
678  protocols::simple_moves::MinMover mnmvr( mvmp, scrfxn, "linmin", 0.0001, true );
679  for ( Size j=1; j<= 25; ++j ) {
680  //std::cout << " ----- " << j << " ----- " << std::flush << std::endl;
681  mnmvr.apply( pose );
682  }
683 
684  // dump coords to a file
685  std::stringstream final_name;
686  final_name << pose.residue(1).type().name3() << "_" << final_rotamers[i].get_phi() << "_" << final_rotamers[i].get_psi() << "_";
687  final_name << "INP_CHI_";
688  for(Size j = 1; j <= nchi; ++j ) {
689  final_name << final_rotamers[i].get_inp_chi( j ) << "_";
690  }
691  final_name << "MIN_CHI_";
692  for(Size j = 1; j <= nchi; ++j ) {
693  final_name << final_rotamers[i].get_min_chi( j ) << "_";
694  }
695  final_name << "final.pdb";
696  std::string final_filename( final_name.str() );
697 
698  // Dump a pdb
699  core::io::pdb::dump_pdb( pose, final_filename );
700 
701  //set energy barrier to stop at
702  Real cut_off_ener (final_rotamers[i].get_energy() + 0.5);
703 
704  //test to see if getting right Energy for this rotamer
705  Real test_ener ( (*scrfxn)(pose) );
706  Real found_ener (final_rotamers[i].get_energy());
707  if (test_ener != found_ener){
708  std::cout << "--------WARNING---------"<< std::endl;
709  std::cout << "For Final_Rot: " << i << " Scored E: "<< test_ener << " but Min Rot E: "<< found_ener <<std::endl;
710  }
711 
712  //set step size of chi
713  Real chi_step (0.1);
714 
715  // search around minimized chi's
716  //std::cout <<"pre-for loop" <<std::endl;
717  for(Size j = 1; j <= nchi; ++j ) {
718  Size k(0);
719  Real new_ener (0);
720  //std::cout <<"pre-while loop" <<std::endl;
721  while(new_ener < cut_off_ener && (k * chi_step) <= 30 ){
722  k=k+1;
723  pose.set_chi( j, 1,
724  numeric::nonnegative_principal_angle_degrees( final_rotamers[i].get_min_chi( j ) + k * chi_step ));
725  Real plus_ener( (*scrfxn)( pose ) );
726  pose.set_chi( j, 1,
727  numeric::nonnegative_principal_angle_degrees( final_rotamers[i].get_min_chi( j ) - k * chi_step ));
728  Real neg_ener( (*scrfxn)( pose ) );
729  // set new_ener to highest energy in either direction
730  new_ener = (plus_ener >= neg_ener ? plus_ener : neg_ener);
731 
732  //std::cout << "While Loop run: " << k <<" for chi: "<< j
733  //<<" for final_rot: " << i << " Current E= " << new_ener << " Cutoff E=" << cut_off_ener << std::endl;
734  }
735  final_rotamers[i].set_std_dev(k*chi_step, j);
736 
737  //reset pose
738  pose.set_chi( j, 1, final_rotamers[i].get_min_chi( j ) );
739  }
740  }
741 }
742 
743 
744 void
746 {
747  using namespace std;
748 
749  cout << "PHI: " << setw(4) << setprecision(2) << fixed << rot.get_phi() << " "
750  << "PSI: " << setw(4) << setprecision(2) << fixed << rot.get_psi() << " "
751  << "OMG: " << setw(8) << setprecision(4) << fixed << rot.get_min_omega() << " "
752  << "ESL: " << setw(8) << setprecision(4) << fixed << rot.get_min_epsilon() << " "
753  << "PRB: " << setw(4) << setprecision(4) << fixed << rot.get_probability() << " "
754  << "ENR: " << setw(8) << setprecision(4) << fixed << rot.get_energy() << " "
755  << "TWS: " << setw(8) << setprecision(4) << fixed << rot.get_twist() << " "
756  << "RAR: " << setw(8) << setprecision(4) << fixed << rot.get_intra_rep() << " "
757  << "RAA: " << setw(8) << setprecision(4) << fixed << rot.get_intra_atr() << " "
758  //<< "ERR: " << setw(8) << setprecision(4) << fixed << rot.get_inter_rep() << " "
759  // << "ERA: " << setw(8) << setprecision(4) << fixed << rot.get_inter_atr() << " "
760  // << "SOL: " << setw(8) << setprecision(4) << fixed << rot.get_solvation() << " "
761  << "NCH: " << setw(4) << fixed << rot.get_num_chi() << " "
762  << "CLN: " << setw(4) << fixed << rot.get_cluster_num() << " ";
763 
764  // print inp_chi_ vector
765  cout << "ICHI:";
766  for(Size i=1; i<=rot.get_num_chi(); ++i) {
767  cout << setw(7) << setprecision(2) << fixed << rot.get_inp_chi(i) << " ";
768  }
769  // print min_chi_ vector
770  cout << "MCHI:";
771  for(Size i=1; i<=rot.get_num_chi(); ++i) {
772  cout << setw(7) << setprecision(2) << fixed << rot.get_min_chi(i) << " ";
773  }
774  // print std_dev_ vector
775  cout << "STDD:";
776  for(Size i=1; i<=rot.get_num_chi(); ++i) {
777  cout << setw(7) << setprecision(2) << fixed << rot.get_std_dev(i) << " ";
778  }
779  // print cen_dst_ vector
780  cout << "CDST:";
781  for(Size i=1; i<=rot.get_num_clusters(); ++i) {
782  cout << setw(7) << setprecision(2) << fixed << rot.get_cen_dist(i) << " ";
783  }
784 
785  cout << endl;
786 }
787 
788 /*
789 Dunbrack file format (unfortunatly limited to 4 chi angles) so some of this code is ugly and repetitive
790 PHE -60 -40 2936 2 1 0 0 0.617431 179.7 78.9 0.0 0.0 10.0 12.3 0.0 0.0
791 PHE -60 -40 2936 3 1 0 0 0.222414 -78.1 101.2 0.0 0.0 10.3 19.5 0.0 0.0
792 PHE -60 -40 2936 3 2 0 0 0.117451 -69.2 -15.4 0.0 0.0 9.3 19.5 0.0 0.0
793 PHE -60 -40 2936 2 2 0 0 0.028434 -173.6 23.5 0.0 0.0 9.3 22.3 0.0 0.0
794 PHE -60 -40 2936 1 1 0 0 0.014263 76.9 94.0 0.0 0.0 9.0 8.7 0.0 0.0
795 PHE -60 -40 2936 1 2 0 0 0.000007 61.2 -7.4 0.0 0.0 12.6 29.3 0.0 0.0
796 AAAXXBBBBXCCCCXXDDDDXXXXEEEEEEEXXFFFFFFFFXXGGGGGGXXHHHHHHXXIIIIIIXXJJJJJJXXXXKKKKKKXXLLLLLLXXMMMMMMXXNNNNNN
797 */
798 void
799 dunbrack_print( RotVec & final_rotamers, RotVec & centroids, std::string aa_name_full )
800 {
801  using namespace std;
802 
803  // sanity check
804  assert( final_rotamers.size() >= 1 && centroids.size() >= 1 && final_rotamers.size() == centroids.size() );
805 
806  // get nchi and num rots
807  Size nchi( final_rotamers[1].get_num_chi() );
808  Size nrot( final_rotamers.size() );
809  Real phi( final_rotamers[1].get_phi() );
810  Real psi( final_rotamers[1].get_psi() );
811 
812  // get aa name
813  std::string aa_name3( aa_name_full.substr( 0, 3 ) );
814 
815  //counts (imaginary and I believe unused)
816  Size count(9999);
817 
818  // sort final_rotamers based on probability adjust centroids too
819  for ( Size i = 1; i <= nrot; ++i ) {
820  Size max(i);
821  for ( Size j = i+1; j <= nrot; ++j ) {
822  if( final_rotamers[j].get_probability() > final_rotamers[max].get_probability() ) {
823  max = j;
824  }
825  }
826  RotData temp_rot( final_rotamers[i] );
827  RotData temp_cen( centroids[i] );
828  final_rotamers[i] = final_rotamers[max];
829  centroids[i] = centroids[max];
830  final_rotamers[max] = temp_rot;
831  centroids[max] = temp_cen;
832  }
833 
834  // get "chi bin" number assignments from centroids
835  vector1<Size> chi1_bin_nums; vector1<Size> chi2_bin_nums; vector1<Size> chi3_bin_nums; vector1<Size> chi4_bin_nums;
836  chi1_bin_nums.resize( nrot, 0 ); chi4_bin_nums.resize( nrot, 0 ); chi3_bin_nums.resize( nrot, 0 ); chi2_bin_nums.resize( nrot, 0 );
837 
838  if( nchi >= 1) {
839  for( Size i = 1; i <= nrot; ++i ) {
840  chi1_bin_nums[i] = Size( centroids[i].get_lib_chi_val(1) );
841  }
842  }
843 
844  if( nchi >= 2) {
845  for( Size i = 1; i <= nrot; ++i ) {
846  chi2_bin_nums[i] = Size( centroids[i].get_lib_chi_val(2) );
847  }
848  }
849 
850  if( nchi >= 3) {
851  for( Size i = 1; i <= nrot; ++i ) {
852  chi3_bin_nums[i] = Size( centroids[i].get_lib_chi_val(3) );
853  }
854  }
855 
856  if( nchi >= 4) {
857  for( Size i = 1; i <= nrot; ++i ) {
858  chi4_bin_nums[i] = Size( centroids[i].get_lib_chi_val(4) );
859  }
860  }
861 
862  // create filename with string stream
863  std::stringstream lib_name;
864  lib_name << aa_name3 << "_" << phi << "_" << psi << "_bbdep.rotlib";
865 
866  // open file for writing
867  std::ofstream rotlib;
868  rotlib.open( lib_name.str().c_str() );
869 
870  // now print out lines
871  for( Size i = 1; i <= nrot; ++i ) {
872  rotlib << setw(3) << aa_name3
873  << " "
874  << setw(4) << setprecision(0) << fixed << phi
875  << " "
876  << setw(4) << setprecision(0) << fixed << psi
877  << " "
878  << setw(4) << count
879  << " "
880  << chi1_bin_nums[i] << " " << chi2_bin_nums[i] << " " << chi3_bin_nums[i] << " " << chi4_bin_nums[i]
881  << " "
882  << setw(8) << setprecision(6) << fixed << final_rotamers[i].get_probability()
883  << " ";
884 
885  for( Size j = 1; j <= 4; ++j ){
886  if( j <= nchi ) rotlib << setw(6) << setprecision(1) << fixed << numeric::principal_angle_degrees( final_rotamers[i].get_min_chi(j) );
887  else rotlib << setw(6) << setprecision(1) << fixed << "0.0";
888  rotlib << " ";
889  }
890 
891  rotlib << " ";
892 
893  for( Size j = 1; j <= 4; ++j ){
894  if( j <= nchi ) rotlib << setw(6) << setprecision(1) << fixed << final_rotamers[i].get_std_dev(j);
895  else rotlib << setw(6) << setprecision(1) << fixed << "0.0";
896  rotlib << " ";
897  }
898 
899  rotlib << endl;
900 
901  }
902 
903  rotlib.close();
904 
905 }
906 
907 
908 
909 } // namespace MakeRotLib
910 } // namespace protocols