22 #include <basic/Tracer.hh>
23 #include <basic/options/option.hh>
24 #include <basic/options/keys/flexpack.OptionKeys.gen.hh>
30 #include <utility/exit.hh>
33 #include <numeric/numeric.functions.hh>
34 #include <numeric/random/random.hh>
35 #include <numeric/random/random_permutation.hh>
40 #include <utility/vector0.hh>
41 #include <utility/vector1.hh>
48 static numeric::random::RandomGenerator
RG(62458);
50 basic::Tracer
TR(
"protocols.flexpack.annealer.FlexbbSimAnnealer");
53 ObjexxFCL::FArray1D_int & bestrotamer_at_seqpos,
55 bool start_with_current,
58 ObjexxFCL::FArray1D_int & current_rot_index,
60 ObjexxFCL::FArray1D< PackerEnergy > & rot_freq
63 ig->get_num_total_states(),
64 bestrotamer_at_seqpos,
85 using namespace interaction_graph;
88 TR <<
"Beginning flexible backbone simulated annealing" << std::endl;
92 Size ranrotamer,ranbbfrag;
93 Size nmoltenres =
ig_->get_num_nodes();
95 Size moltenres_id, rotamer_state_on_moltenres, prevrotamer_state;
97 Size cycle1, cycle2, cycle3;
99 PackerEnergy currentenergy, previous_energy_for_node, delta_energy;
109 ObjexxFCL::FArray1D_int nsteps_for_rot( nrotamers, 0 );
111 ObjexxFCL::FArray1D_int state_on_node( nmoltenres, 0);
112 ObjexxFCL::FArray1D_int best_state_on_node( nmoltenres, 0);
114 for (
Size ii = 1; ii <= nmoltenres; ++ii ) { moltenres_rotoffsets[ ii ] =
rotsets_->nrotamer_offset_for_moltenres( ii ); }
127 accessible_state_list[ i ] = i;
128 nsteps_for_rot(i) = 0;
131 ig_->prepare_for_simulated_annealing();
136 for (
Size ii = 1; ii <= nmoltenres; ++ii) {
139 ig_->set_network_state( state_on_node );
140 currentenergy =
ig_->get_energy_current_state_assignment();
142 best_state_on_node = state_on_node;
144 ig_->blanket_assign_state_0();
160 using namespace basic::options;
161 using namespace basic::options::OptionKeys::flexpack::annealer;
163 if ( option[ inner_iteration_scale ].user() ) {
164 inneriterations_usual *=
static_cast< Size > (inneriterations_usual * option[ inner_iteration_scale ]);
166 if ( option[ outer_iteration_scale ].user() ) {
167 outeriterations =
static_cast< Size > (outeriterations * option[ outer_iteration_scale ]);
169 if ( option[ fixbb_substitutions_scale ].user() ) {
170 cycle1 =
static_cast< Size > ( cycle1 * option[ fixbb_substitutions_scale ]);
172 if ( option[ pure_movebb_substitutions_scale ].user() ) {
173 cycle2 =
static_cast< Size > ( cycle2 * option[ pure_movebb_substitutions_scale ]);
175 if ( option[ rotsub_movebb_substitutions_scale ].user() ) {
176 cycle3 =
static_cast< Size > ( cycle3 * option[ rotsub_movebb_substitutions_scale ]);
185 ig_->get_accessible_states(
186 FlexbbInteractionGraph::BOTH_SC_AND_BB,
191 bool sconly_move_accessible_state_list_current(
false );
195 for (
Size nn = 1; nn <= outeriterations; ++nn ) {
197 Size num_fixbb_move_accepts = 0;
198 Size num_fixbb_move_valid = 0;
199 Size num_bb_move_accepts = 0;
200 Size num_bb_move_valid = 0;
201 Size num_bb_sub_accepts = 0;
202 Size num_bb_sub_valid = 0;
206 Size inneriterations = inneriterations_usual;
218 inneriterations /= 2;
220 inneriterations *= 6;
225 state_on_node = best_state_on_node;
226 ig_->set_network_state( state_on_node );
232 for (
Size j = 1; j <= inneriterations; ++j) {
234 if ( ! sconly_move_accessible_state_list_current ) {
235 ig_->get_accessible_states( FlexbbInteractionGraph::SC_ONLY, accessible_state_list );
236 sconly_move_accessible_state_list_current =
true;
240 for (
Size n = 1; n <= cycle1; ++n ) {
245 ranrotamer =
pick_a_rotamer( j, n, cycle1, accessible_state_list);
252 moltenres_id =
rotsets_->moltenres_for_rotamer( ranrotamer );
254 rotamer_state_on_moltenres =
rotsets_->local_rotid_for_rotamer_on_moltenres( moltenres_id, ranrotamer );
255 prevrotamer_state = state_on_node( moltenres_id );
257 if (rotamer_state_on_moltenres == prevrotamer_state )
continue;
259 ++num_fixbb_move_valid;
264 ig_->consider_substitution( moltenres_id, rotamer_state_on_moltenres,
265 delta_energy, previous_energy_for_node);
267 if ((prevrotamer_state == 0)||
pass_metropolis(previous_energy_for_node,delta_energy)) {
269 ++num_fixbb_move_accepts;
270 currentenergy =
ig_->commit_considered_substitution();
271 state_on_node( moltenres_id ) = rotamer_state_on_moltenres;
272 if ((prevrotamer_state == 0)||(currentenergy <
bestenergy() )) {
274 best_state_on_node = state_on_node;
279 for (
Size ii = 1; ii <= nmoltenres; ++ii ) {
280 Size iistate = state_on_node(ii);
281 if ( iistate != 0 ) {
282 ++nsteps_for_rot( iistate + moltenres_rotoffsets[ii] );
290 ig_->get_backbone_list( accessible_state_list_bbfrag );
291 for (
Size n = 1; n <= cycle2; ++n ) {
295 ranbbfrag =
pick_a_rotamer(j,n,cycle2,accessible_state_list_bbfrag);
301 if (
ig_->get_backbone_currently_assigned( ranbbfrag ) )
continue;
302 int num_changing_nodes = 0;
310 ig_->consider_backbone_move( ranbbfrag, delta_energy,
311 previous_energy_for_bbfrag, valid_bb_move, num_changing_nodes);
313 if (! valid_bb_move )
continue;
317 previous_energy_for_bbfrag,delta_energy, num_changing_nodes)) {
318 ++num_bb_move_accepts;
319 sconly_move_accessible_state_list_current =
false;
323 currentenergy =
ig_->commit_considered_backbone_move(state_on_node);
328 best_state_on_node = state_on_node;
334 for (
Size ii = 1; ii <= nmoltenres; ++ii ) {
335 Size iistate = state_on_node(ii);
336 if ( iistate != 0 ) {
337 ++nsteps_for_rot( iistate + moltenres_rotoffsets[ii] );
347 for (
Size n = 1; n <= cycle3; ++n ) {
355 moltenres_id =
rotsets_->moltenres_for_rotamer( ranrotamer );
357 rotamer_state_on_moltenres =
rotsets_->local_rotid_for_rotamer_on_moltenres( moltenres_id, ranrotamer );
358 prevrotamer_state = state_on_node( moltenres_id );
360 if (prevrotamer_state == rotamer_state_on_moltenres )
continue;
362 int num_changing_nodes = 0;
370 ig_->consider_bbmove_w_state_substitution(
371 moltenres_id, rotamer_state_on_moltenres,
372 delta_energy, previous_energy_for_bbfrag,
373 valid_bb_move, num_changing_nodes );
375 if (! valid_bb_move )
continue;
378 if ( (prevrotamer_state == 0) ||
380 previous_energy_for_bbfrag, delta_energy, num_changing_nodes) ) {
381 ++num_bb_sub_accepts;
384 if ( !
rotsets_->rotamers_on_same_bbconf( moltenres_id, rotamer_state_on_moltenres, prevrotamer_state )) {
385 sconly_move_accessible_state_list_current =
false;
389 currentenergy =
ig_->commit_considered_backbone_move(state_on_node);
390 if ((prevrotamer_state == 0)||(currentenergy <
bestenergy())) {
392 best_state_on_node = state_on_node;
398 for (
Size ii = 1; ii <= nmoltenres; ++ii ) {
399 Size iistate = state_on_node(ii);
400 if ( iistate != 0 ) {
401 ++nsteps_for_rot( iistate + moltenres_rotoffsets[ii] );
406 loopenergy(nn) = currentenergy;
426 for (
Size ii = 1; ii <= nmoltenres; ++ii) {
441 Size inner_loop_iteration_limit,
449 num = numeric::mod( (outercycle - 1) * inner_loop_iteration_limit + innercycle - 1, accessible_state_list.size() ) + 1;
451 numeric::random::random_permutation( accessible_state_list, RG );
454 num =
static_cast< Size > ( RG.uniform() * accessible_state_list.size() ) + 1;
456 return accessible_state_list[ num ];
463 Size num_changing_nodes
466 assert( num_changing_nodes > 0 );
468 return pass_metropolis( previous_fragmentE / num_changing_nodes , deltaE / ( num_changing_nodes > 4 ? 4 : num_changing_nodes) );