Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
FixbbSimAnnealer.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/pack/annealer/FixbbSimAnnealer.cc
11 /// @brief Packer's standard simulated annealing class implementation
12 /// @author Andrew Leaver-Fay (aleaverfay@gmail.com)
13 
14 // Unit Headers
16 
17 // Package Headers
22 #include <basic/Tracer.hh>
23 
24 //#include "after_opts.h"
25 //#include "FixbbSimAnnealer.h"
26 //#include "RotamerAssigningAnnealer.h"
27 //#include "random_numbers.h"
28 //#include "param.h"
29 //#include "RotamerSet.h"
30 
31 #include <utility/exit.hh>
32 
33 // AUTO-REMOVED #include <ObjexxFCL/Fmath.hh>
34 
35 #include <iostream>
36 
38 #include <utility/vector0.hh>
39 #include <utility/vector1.hh>
40 
41 
42 using namespace ObjexxFCL;
43 
44 #ifndef NDEBUG
45 static basic::Tracer TR("core.pack.annealer.FixbbSimAnnealer");
46 #endif
47 
48 namespace core {
49 namespace pack {
50 namespace annealer {
51 
52 ////////////////////////////////////////////////////////////////////////////////
53 /// @begin FixbbSimAnnealer::FixbbSimAnnealer()
54 ///
55 /// @brief
56 /// constructor
57 ///
58 /// @detailed
59 ///
60 /// @global_read
61 ///
62 /// @global_write
63 ///
64 /// @remarks
65 ///
66 /// @references
67 ///
68 /// @authors
69 ///
70 /// @last_modified
71 
72 ////////////////////////////////////////////////////////////////////////////////
73 FixbbSimAnnealer::FixbbSimAnnealer(
74  utility::vector0< int > & rot_to_pack,
75  FArray1D_int & bestrotamer_at_seqpos,
76  float & bestenergy,
77  bool start_with_current, // start simulation with current rotamers
79  FixbbRotamerSetsCOP rotamer_sets,
80  FArray1_int & current_rot_index,
81  bool calc_rot_freq,
82  FArray1D_float & rot_freq
83 ):
84  RotamerAssigningAnnealer(
85  rot_to_pack,
86  (int) rot_to_pack.size(),
87  bestrotamer_at_seqpos,
88  bestenergy,
89  start_with_current, // start simulation with current rotamers
90  rotamer_sets,
91  current_rot_index,
92  calc_rot_freq,
93  rot_freq
94  ), ig_(ig)
95 {
96 }
97 
99  FArray1D_int & bestrotamer_at_seqpos,
100  float & bestenergy,
101  bool start_with_current, // start simulation with current rotamers
103  FixbbRotamerSetsCOP rotamer_set,
104  FArray1_int & current_rot_index,
105  bool calc_rot_freq,
106  FArray1D_float & rot_freq
107 ):
108  RotamerAssigningAnnealer(
109  (ig->get_num_total_states()),
110  bestrotamer_at_seqpos,
111  bestenergy,
112  start_with_current, // start simulation with current rotamers
113  rotamer_set,
114  current_rot_index,
115  calc_rot_freq,
116  rot_freq
117  ), ig_(ig)
118 {
119 }
120 
121 /// @brief virtual destructor
123 {}
124 
125 /// @brief sim_annealing for fixed backbone design mode
127 {
128 
129  int const nmoltenres = ig_->get_num_nodes();
130 
131  FArray1D_int state_on_node( nmoltenres,0 ); // parallel representation of interaction graph's state
132  FArray1D_int best_state_on_node( nmoltenres,0 );
133  FArray1D_float loopenergy(maxouteriterations,0.0);
134 
135  //bk variables for calculating rotamer frequencies during simulation
136  int nsteps = 0;
137  FArray1D_int nsteps_for_rot( ig_->get_num_total_states(), 0 );
138 
139  //--------------------------------------------------------------------
140  //initialize variables
141 
142  core::PackerEnergy currentenergy = 0.0;
143 
144  ig_->prepare_for_simulated_annealing();
145  ig_->blanket_assign_state_0();
146 
147  //--------------------------------------------------------------------
148  if ( num_rots_to_pack() == 0 ) return;
149 
151 
152  FArray1D_float previous_nsteps_for_rot( rotamer_sets()->nrotamers(), 0.0);
153 
154  int outeriterations = get_outeriterations();
155 
156 
157  //std::ofstream annealer_trajectory;
158  //static bool const record_annealer_trajectory( truefalseoption("record_annealer_trajectory") ); //look up once
159  //if ( record_annealer_trajectory )
160  //{
161  // std::string trajectory_file_name( stringafteroption("record_annealer_trajectory" ) );
162  // annealer_trajectory.open(trajectory_file_name.c_str() );
163  //}
164 
165  //std::cout << "Annealing begins" << std::endl;
166 
167  //outer loop
168  for (int nn = 1; nn <= outeriterations; ++nn ){
169  setup_temperature(loopenergy,nn);
170  if ( quench() ){
171  currentenergy = bestenergy();
172  state_on_node = best_state_on_node;
173  ig_->set_network_state( state_on_node );
174  }
175  //rh std::cout << "Sim Annealer Temperature: " << get_temperature() << std::endl;
176 
177  int inneriterations = get_inneriterations();
178 
179  float treshold_for_deltaE_inaccuracy = std::sqrt( get_temperature() );
180  ig_->set_errorfull_deltaE_threshold( treshold_for_deltaE_inaccuracy );
181 
182  //inner loop
183  for (int n = 1; n <= inneriterations; ++n ){
184  int const ranrotamer = pick_a_rotamer( n );
185  if (ranrotamer == -1) continue;
186 
187  int const moltenres_id = rotamer_sets()->moltenres_for_rotamer( ranrotamer );
188  int const rotamer_state_on_moltenres = rotamer_sets()->rotid_on_moltenresidue( ranrotamer );
189  int const prevrotamer_state = state_on_node(moltenres_id);
190 
191  if (rotamer_state_on_moltenres == prevrotamer_state ) continue; //skip iteration
192 
193  core::PackerEnergy previous_energy_for_node, delta_energy;
194 
195  ig_->consider_substitution( moltenres_id, rotamer_state_on_moltenres,
196  delta_energy, previous_energy_for_node);
197  //std::cout << "mres: " << moltenres_id << ", state: ";
198  //std::cout << rotamer_state_on_moltenres << ", deltaE: " << delta_energy;
199 
200  //bk keep new rotamer if it is lower in energy or accept it at some
201  //bk probability if it is higher in energy, if it is the first
202  //bk rotamer to be tried at this position automatically accept it.
203  if ( (prevrotamer_state == 0) || pass_metropolis(previous_energy_for_node,delta_energy) )
204  {
205  //std::cout << " accepted\n";
206  currentenergy = ig_->commit_considered_substitution();
207  state_on_node(moltenres_id) = rotamer_state_on_moltenres;
208  if ((prevrotamer_state == 0)||(currentenergy < bestenergy() ))
209  {
210  best_state_on_node = state_on_node;
211 
212  /*
213  //ronj - debugging output useful for seeing how the energy changes during the course of the simulation
214  for ( Size ii=0; ii < best_state_on_node.size(); ii++ ) {
215  if ( best_state_on_node[ii] != 0 )
216  TR << rotamer_sets()->rotamer_set_for_moltenresidue( ii+1 )->rotamer( best_state_on_node[ii] )->name1();
217  else
218  TR << '-';
219  }
220  TR << ", current_energy: " << currentenergy << ", best_energy: " << bestenergy() << std::endl;
221  */
222 
223  bestenergy() = currentenergy;
224  }
225 
226  //if ( record_annealer_trajectory )
227  //{
228  // annealer_trajectory << moltenres_id << " " << rotamer_state_on_moltenres << " A\n";
229  //}
230 
231  } // end Metropolis criteria
232  //else if ( record_annealer_trajectory )
233  //{
234  // annealer_trajectory << moltenres_id << " " << rotamer_state_on_moltenres << " R\n";
235  //}
236  //else {
237  // std::cout << " rejected\n";
238  //}
239 
240 
241  loopenergy(nn) = currentenergy;
242  float const temperature = get_temperature();
243 
244  if ( calc_rot_freq() && ( temperature <= calc_freq_temp ) )
245  {
246  ++nsteps;
247  for (int ii = 1; ii <= nmoltenres; ++ii )
248  {
249  int iistate = state_on_node(ii);
250  if (iistate != 0)
251  {
252  ++nsteps_for_rot( rotamer_sets()->moltenres_rotid_2_rotid(ii, iistate) );
253  }
254  }
255  }
256 
257  } // end of inneriteration loop
258  } //end of outeriteration loop
259 
260 #ifndef NDEBUG
261  TR << "pack_rotamers run final: ";
262  for ( Size ii=0; ii < best_state_on_node.size(); ii++ ) {
263  if ( best_state_on_node[ii] != 0 )
264  TR << rotamer_sets()->rotamer_set_for_moltenresidue( ii+1 )->rotamer( best_state_on_node[ii] )->name1();
265  else
266  TR << '-';
267  }
268  TR << ", best_energy: " << bestenergy() << std::endl;
269 #endif
270 
271  if ( ig_->any_vertex_state_unassigned() ) {
272  std::cerr << "Critical error -- In FixbbSimAnnealer, one or more vertex states unassigned at annealing's completion." << std::endl;
273  std::cerr << "Critical error -- assignment and energy of assignment meaningless" << std::endl;
274 
275  FArray1D_int nstates_for_moltenres( rotamer_sets()->nmoltenres(), 0 );
276  for ( uint ii = 0; ii < num_rots_to_pack(); ++ii)
277  {
278  ++nstates_for_moltenres( rotamer_sets()->res_for_rotamer( rot_to_pack()[ ii ] ) );
279  }
280 
281  for ( uint ii = 1; ii <= rotamer_sets()->nmoltenres(); ++ii)
282  {
283  if ( best_state_on_node( ii ) == 0 )
284  {
285  std::cout << "Molten res " << ii << " (residue " << rotamer_sets()->moltenres_2_resid( ii );
286  std::cout << " ) assigned state 0 despite having " << nstates_for_moltenres( ii ) << " states to choose from" << std::endl;
287  }
288  }
289  assert( ! ig_->any_vertex_state_unassigned() );
290  utility_exit();
291 
292 
293  }
294 
295  //convert best_state_on_node into best_rotamer_at_seqpos
296  for (int ii = 1; ii <= nmoltenres; ++ii){
297  int const iiresid = rotamer_sets()->moltenres_2_resid( ii );
298  bestrotamer_at_seqpos()( iiresid ) = rotamer_sets()->moltenres_rotid_2_rotid( ii, best_state_on_node(ii));
299  }
300 
301  //std::cout << "Annealing ends" << std::endl;
302 }
303 
304 }//end namespace annealer
305 }//end namespace pack
306 }//end namespace core