Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
CanonicalSamplingMover.cc
Go to the documentation of this file.
2 #include <protocols/moves/SidechainMover.hh>
3 #include <protocols/moves/SidechainMover.fwd.hh>
4 #include <protocols/jd2/util.hh>
5 
7 #include <core/pose/Pose.hh>
8 #include <core/pose/PDBInfo.hh>
12 
13 #include <protocols/loops/Loop.hh>
14 #include <protocols/loops/Loops.hh>
15 
18 #include <protocols/moves/mc_convergence_checks/Pool_ConvergenceCheck.hh>
19 #include <protocols/moves/mc_convergence_checks/MPIBPool_ConvergenceCheck.hh>
20 #include <protocols/moves/mc_convergence_checks/MPIHPool_ConvergenceCheck.hh>
21 #include <protocols/moves/mc_convergence_checks/MPIPool_ConvergenceCheck.hh>
22 #include <protocols/moves/mc_convergence_checks/HPool.hh>
23 #include <protocols/moves/mc_convergence_checks/HierarchicalLevel.hh>
24 
27 
28 #include <basic/options/option.hh>
29 #include <basic/options/after_opts.hh>
30 #include <basic/options/option_macros.hh>
31 #include <basic/options/keys/mc.OptionKeys.gen.hh>
32 #include <basic/options/keys/out.OptionKeys.gen.hh>
33 #include <basic/options/keys/in.OptionKeys.gen.hh>
34 #include <basic/options/keys/loops.OptionKeys.gen.hh>
35 #include <basic/options/keys/constraints.OptionKeys.gen.hh>
36 #include <utility/file/file_sys_util.hh>
37 #include <utility/file/PathName.hh>
38 
42 #include <core/scoring/rms_util.hh>
47 
48 #include <basic/Tracer.hh>
49 #include <basic/prof.hh>
50 
51 #include <fstream>
52 #include <ObjexxFCL/format.hh>
53 #include <ObjexxFCL/Fmath.hh>
54 #ifdef USEMPI
55 #include <mpi.h>
56 #endif
57 
58 OPT_1GRP_KEY(Boolean, sampling, no_detailed_balance) //option moved to test_canonical_mover, need to access this value in setup
59 OPT_1GRP_KEY(Integer,sampling,ntrials)
60 OPT_1GRP_KEY(Real,sampling,mc_kt)
61 OPT_1GRP_KEY(Integer, sampling, interval_pose_dump)
62 OPT_1GRP_KEY(Integer, sampling, interval_data_dump)
63 OPT_1GRP_KEY(Boolean, sampling,output_only_cluster_transitions)
64 OPT_1GRP_KEY(Real, sampling, transition_threshold )
65 OPT_2GRP_KEY(File, sampling, out, new_structures )
66 OPT_1GRP_KEY(Integer, sampling, max_files_per_dir )
67 
68 //debug ramping up temperature to equilibrate structure?
69 OPT_1GRP_KEY(Boolean, sampling, ramp_temperature)
70 OPT_1GRP_KEY(Integer, sampling, interval_increment_temp)
71 OPT_1GRP_KEY(Real, sampling, starting_temp)
72 OPT_1GRP_KEY(Boolean, sampling, add_constraints)
73 
74 //dump or save part of the structure?
75 OPT_1GRP_KEY(Boolean, sampling, save_loops_only )
76 OPT_1GRP_KEY(Boolean, sampling, dump_loops_only )
77 
78 namespace protocols{
79 namespace moves {
80 
81 static basic::Tracer tr("protocols.moves.CanonicalSamplingMover");
82 
84 
86  using namespace protocols::moves;
87  using namespace basic::options;
88  using namespace basic::options::OptionKeys;
89  using namespace core::pack::task;
90  if ( !options_registered_ ) {
91  OPT( mc::known_structures);
92  OPT( out::path::path );
93  NEW_OPT( sampling::ntrials, "number of Monte Carlo trials to run", 1000);
94  NEW_OPT( sampling::no_detailed_balance, "preserve detailed balance", false );
95  NEW_OPT( sampling::mc_kt,"value of kT for Monte Carlo",0.6);
96  NEW_OPT( sampling::interval_pose_dump,"dump a pose out every x steps",1000);
97  NEW_OPT( sampling::interval_data_dump,"dump data out every x steps",100);
98  NEW_OPT( sampling::output_only_cluster_transitions, "output only cluster transitions", false);
99  NEW_OPT( sampling::transition_threshold, "if rmsd to known_structures larger than X, add a new structure to pool", 0.5 );
100  NEW_OPT( sampling::out::new_structures, "write structures above transition_threshold to this file", "discovered_decoys.out" );
101  NEW_OPT( sampling::max_files_per_dir, "distribute traj and transition files into subdirectories with max N entries", 1000 );
102 
103  //
104  //debug ramping up temperature to equilibrate structure?
105  NEW_OPT( sampling::ramp_temperature, "ramp up the temperature and use constraints to equilibrate structure", false);
106  NEW_OPT( sampling::interval_increment_temp, "increment the temperature by 0.1 every x steps", 100000 );
107  NEW_OPT( sampling::starting_temp, "increment the temperature by 0.1 every x steps", 0.1 );
108  NEW_OPT( sampling::add_constraints, "add constraints during equilibration?", false);
109 
110  //dump or save part of the structure?
111  NEW_OPT( sampling::save_loops_only, "save only loop conformation to pool", false );
112  NEW_OPT( sampling::dump_loops_only, "dump only loop conformation in silent-files" , false );
113 
114  options_registered_ = true;
115  }
116 
117 
118 
119 }
120 
121 CanonicalSamplingMover::CanonicalSamplingMover():
122  Mover("CanonicalSamplingMover"),
123  mc_(),
124  sfxn_(),
125  randmove_(new RandomMover()),
126  pool_rms_(),
127  interval_posedump_(100),
128  interval_transitiondump_(100),
129  ntrials_(1000),
130  detailed_balance_(true),
131  MPI_synchronize_pools_(false),
132  use_hierarchical_clustering_(false),
133  save_loops_only_(false),
134  dump_loops_only_(false),
135  output_only_cluster_transition_(false)
136 {
137  set_defaults_from_cmdline();
138 }
139 
140 CanonicalSamplingMover::CanonicalSamplingMover(
143  int ntrial
144 ):
145  Mover("CanonicalSamplingMover"),
146  mc_(new MonteCarlo( *sfxn, basic::options::option[ basic::options::OptionKeys::sampling::mc_kt ]() ) ),
147  sfxn_(sfxn),
148  randmove_(new RandomMover()),
149  pool_rms_(ptr),
150  interval_posedump_(1000),
151  interval_transitiondump_(100),
152  ntrials_(ntrial),
153  detailed_balance_(true),
154  MPI_synchronize_pools_(false),
155  use_hierarchical_clustering_(false),
156  save_loops_only_(false),
157  dump_loops_only_(false),
158  output_only_cluster_transition_(false)
159 {
160  set_defaults_from_cmdline();
161  runtime_assert( sfxn );
162 }
163 
164 void CanonicalSamplingMover::set_defaults_from_cmdline() {
165  using namespace basic::options;
166  using namespace basic::options::OptionKeys;
167 
168  runtime_assert( options_registered_ );
169 
170  ntrials( option[ sampling::ntrials ] );
171  detailed_balance( !option[ sampling::no_detailed_balance ] );
172  output_only_cluster_transitions( option[ sampling::output_only_cluster_transitions ] );
173  set_interval_pose_dump( option[ sampling::interval_pose_dump ] );
174  set_interval_data_dump( option[ sampling::interval_data_dump ] );
175  transition_threshold_ = option[ sampling::transition_threshold ]();
176  ramp_temperature_ = option[ sampling::ramp_temperature ]();
177  save_loops_only_ = option[ sampling::save_loops_only ]();
178  dump_loops_only_ = option[ sampling::dump_loops_only ]();
179 
180 }
181 
182 void
183 CanonicalSamplingMover::add_mover(
184  MoverOP m,
185  core::Real probability
186 ) {
187  randmove_->add_mover( m, probability);
188 }
189 
190 //copied from src/apps/pilot/dekim/bbin.cc
192 CanonicalSamplingMover::periodic_range(
193  core::Real a,
194  core::Real x
195  )
196 {
197  using namespace ObjexxFCL;
198  core::Real const halfx = 0.5f * x;
199  return ( ( a >= halfx || a < -halfx ) ? mod( mod( a, x ) + ( x + halfx ), x ) - halfx : a );
200 }
201 
202 
203 
204  std::string CanonicalSamplingMover::get_ABGEO_string( core::pose::Pose & pose, protocols::loops::Loops & loop ) {
205 
206  std::string ABGEO_assignment = "";
207  for( protocols::loops::Loops::const_iterator itr = loop.begin(); itr != loop.end(); itr++ ) {
208  for( core::Size ii = itr->start(); ii <= itr->stop(); ii++ ){
209  core::Real phi = pose.phi(ii);
210  core::Real psi = pose.psi(ii);
211  core::Real omega = pose.omega(ii);
212  periodic_range( phi , 360.0 ); //does this get applied to phi??
213  periodic_range( psi , 360.0 );
214  periodic_range( omega, 360.0 );
215  std::string position_assignment="";
216  if ( std::abs( omega ) < 90 ) {
217  position_assignment= "O";
218  } else if ( phi >= 0.0 ) {
219  if ( -100 < psi && psi <= 100 ) {
220  position_assignment= "G"; // alpha-L
221  } else {
222  position_assignment= "E"; // E
223  }
224  } else {
225  if ( -125 < psi && psi <= 50 ) {
226  position_assignment= "A"; // helical
227  } else {
228  position_assignment= "B"; // extended
229  }
230  }
231  ABGEO_assignment = ABGEO_assignment + position_assignment;
232  }
233  ABGEO_assignment = ABGEO_assignment + ",";
234  }
235  return ABGEO_assignment;
236 }
237 
238 void CanonicalSamplingMover::ntrials(int ntrials) {ntrials_ = ntrials;}
239 
240 void CanonicalSamplingMover::set_temp(core::Real temperature) {
241  mc_ = new MonteCarlo(*sfxn_, temperature);
242  temperature_ = temperature;
243 }
244 
245 void CanonicalSamplingMover::set_interval_pose_dump(int p_interval){ interval_posedump_=p_interval;}
246 
247 void CanonicalSamplingMover::set_interval_data_dump(int d_interval){ interval_transitiondump_=d_interval;}
248 
249 void CanonicalSamplingMover::set_scorefunction(core::scoring::ScoreFunctionOP sfxn) {sfxn_ = sfxn;}
250 
251 void CanonicalSamplingMover::detailed_balance(bool truefalse) {detailed_balance_ = truefalse;}
252 
253 
254 void CanonicalSamplingMover::use_MPI_sync_pools(bool truefalse) {MPI_synchronize_pools_ = truefalse;}
255 
256 void CanonicalSamplingMover::use_MPI_bcast(bool truefalse) {MPI_bcast_ = truefalse;}
257 
258 void CanonicalSamplingMover::use_hierarchical_clustering(bool truefalse) {use_hierarchical_clustering_ = truefalse;}
259 
260 
261 void CanonicalSamplingMover::set_poolrmsd(mc_convergence_checks::Pool_RMSD_OP ptr){
262  pool_rms_ = ptr;
263 }
264 
265 void CanonicalSamplingMover::output_only_cluster_transitions(bool truefalse){
266  output_only_cluster_transition_ = truefalse;
267 }
268 
270  pose.remove_constraints();
271  core::Real const CA_cutoff(9.0);
272  core::Real const cst_tol(0.5);
273  for(unsigned int itr_res_i = 1; itr_res_i <= pose.total_residue(); itr_res_i++){
274  for(unsigned int itr_res_j = 1; itr_res_j <= pose.total_residue(); itr_res_j++){
275  Vector const CA_i( pose.residue( itr_res_i ).xyz(" CA "));
276  Vector const CA_j( pose.residue( itr_res_j ).xyz(" CA "));
277  core::Real const CA_dist = ( CA_i - CA_j ).length();
278  if( CA_dist < CA_cutoff ){
279  pose.add_constraint(
281  core::id::AtomID(pose.residue(itr_res_i).atom_index(" CA "),itr_res_i),
282  core::id::AtomID(pose.residue(itr_res_j).atom_index(" CA "),itr_res_j),
283  new core::scoring::constraints::HarmonicFunc( CA_dist, cst_tol )
284  )
285  );
286  }
287  }
288  }
289 }
290 
291 std::string jobname_dirhash( std::string const& dir_prefix, core::Size nr_dirs ) {
292  //this should split all files over <nr_dirs> directories:
293  // to do this I simply remove the last 5 chars from jobname (which are probably the nstruct _0001)
294  // then I add all ascii values of each character and take it modulo nr_dirs
295 // core::Size sum( 0 );
296 // const char* str = jobname.c_str();
297 // for ( core::Size i=1; i<=jobname.size()-5; i++ ) {
298 // sum+=(int) *(str++);
299 // }
301  utility::file::PathName output_path = basic::options::option[ basic::options::OptionKeys::out::path::path ];
302  std::string dir_name(
303  output_path.name() +"/" +
304  dir_prefix +"/" +
305  ObjexxFCL::lead_zero_string_of( job_id % nr_dirs, 4 ) +"/"
306  );
307  utility::file::create_directory_recursive( dir_name );
308  return dir_name;
309 }
310 
311 void CanonicalSamplingMover::dump_decoy_or_score(
312  std::ostream& os,
313  core::pose::Pose const& pose,
314  core::Size i_trial,
315  std::string const& jobname,
316  loops::Loops const& loop_to_dump,
317  bool score_only /*default fasle*/
318 ) {
319 
320  //write to silent-struct
321  PROF_START( basic::CANONICALMOVER_WRITE_TO_FILE );
323  if ( score_only ) {
325  } else {
327  }
328 
329  using namespace ObjexxFCL;
330  //allow two easy obtainable skip intervals: 10 and 100
331  core::Size itrial_100 = i_trial / interval_posedump_ / 100;
332  core::Size rest100 = ( i_trial / interval_posedump_ ) % 100;
333  core::Size rest100_10 = rest100 / 10;
334  core::Size rest100_rest10 = rest100 % 10;
335  core::Size score_dump100 = ( i_trial / interval_transitiondump_ ) % interval_posedump_;
336  std::string score_dump_str("");
337  if ( score_only ) {
338  score_dump_str="."+lead_zero_string_of( score_dump100, 3 );
339  }
340 
341  ///construct NAME_00001.0.0
342  /// NAME_00001.0.1
343  // ...
344  /// NAME_00001.1.0
345  /// for easy extraction of 10th and 100th parts of structures from silent-file
346  /// 10th grep '\..\.0'
347  /// 100th grep '\.0\.0'
348 
349  std::string decoy_tag = jobname + "_"
350  + lead_zero_string_of( itrial_100, 8 ) + "."
351  + lead_zero_string_of( rest100_10, 1 ) + "."
352  + lead_zero_string_of( rest100_rest10, 1)
353  + score_dump_str;
354 
355  if( dump_loops_only_ /* save only loop conformations */
356  && loop_to_dump.num_loop() > 0 ) {
357  // make pose with just loop coordinates
358 
359  for( loops::Loops::const_iterator itr = loop_to_dump.begin(); itr != loop_to_dump.end(); itr++ ) {
360  core::pose::Pose looponly( pose, itr->start(), itr->stop() );
361  ss->fill_struct(looponly, decoy_tag);
362  //looponly.copy_segment(itr->size(),pose,looponly.total_residue()+1,itr->start());
363  }
364 
365  } else {
366  ss->fill_struct(pose, decoy_tag);
367  }
368  ss->add_energy( "itrial", i_trial );
369  if ( i_trial == 0 ) { //first time ?
370  ss->print_header( os );
371  }
373  tr.Debug << "about to write to silent file" << std::endl;
374  sfd.write_silent_struct(*ss, os, score_only );
375  PROF_STOP( basic::CANONICALMOVER_WRITE_TO_FILE );
376 }
377 
378 void
379 CanonicalSamplingMover::apply(Pose & pose){
380  using namespace ObjexxFCL::fmt;
381  using namespace basic::options;
382  using namespace basic::options::OptionKeys;
383 
384  tr.Debug << "starting on pose with name: " << (pose.pdb_info())->name() << std::endl;
385 
386  if ( pose.total_residue() == 0 ) {
387  utility_exit_with_message( "did you forget -in:file:silent ? Need to start CanonicalSamplingMover with a valid pose" );
388  }
389 
390  runtime_assert( pose.total_residue() > 0 );
391 
392  PROF_START( basic::MPICANONICALSAMPLING );
394 
395  runtime_assert( pool_rms_ );
396 
397  // set up loop definition if we're only sampling loop conformations.
398  // even if we're not sampling loop defs, make empty loop definition
399  loops::Loops loops;
400  if( option[basic::options::OptionKeys::loops::loop_file].user() ) {
401  std::string loopfile = option[basic::options::OptionKeys::loops::loop_file]()[1];
402  loops.read_loop_file( loopfile );
403  }
404  //add constraints if specified
405  if( option[ constraints::cst_file ].user() ) {
407  }
408 
409 
410 #ifdef USEMPI
411  int n_nodes;
412  MPI_Comm_size( MPI_COMM_WORLD, ( int* )( &n_nodes ) );
413 
414  if( MPI_synchronize_pools_ && MPI_bcast_ ){
415  mc_convergence_checks::MPIBPool_RMSD* mpi_pool_rms = dynamic_cast <mc_convergence_checks::MPIBPool_RMSD *> (&(*pool_rms_));
416  mpi_pool_rms->set_discovered_out( (option[ sampling::out::new_structures ]()).name() );
417  if( mpi_pool_rms ){
418  mpi_pool_rms->set_transition_threshold( transition_threshold_ );
419  //tr.Debug << " set transition threshold to " << transition_threshold_ << std::endl;
420  mpi_pool_rms->set_reserve_size( n_nodes );
421  pool_rms_ = mpi_pool_rms;
422  }else{
423  utility_exit_with_message("cast to MPIBPool_RMSD failed! fatal error!");
424  }
425  }else if( MPI_synchronize_pools_ ){
426  if( !use_hierarchical_clustering_ ) {
427  mc_convergence_checks::MPIPool_RMSD* mpi_pool_rms = dynamic_cast <mc_convergence_checks::MPIPool_RMSD *> (&(*pool_rms_));
428  mpi_pool_rms->set_discovered_out( (option[ sampling::out::new_structures ]()).name() );
429  if( mpi_pool_rms ){
430  mpi_pool_rms->set_transition_threshold( transition_threshold_ );
431  mpi_pool_rms->set_reserve_size( n_nodes );
432  mpi_pool_rms->set_reserve_size( n_nodes );
433  //tr.Debug << " set transition threshold to " << transition_threshold_ << std::endl;
434  pool_rms_ = mpi_pool_rms;
435  }else{
436  utility_exit_with_message("cast to MPIPool_RMSD failed! fatal error!");
437  }
438  } else {
439  mc_convergence_checks::MPIHPool_RMSD* mpi_pool_rms = dynamic_cast <mc_convergence_checks::MPIHPool_RMSD *> (&(*pool_rms_));
440  mpi_pool_rms->set_discovered_out( (option[ sampling::out::new_structures ]()).name() );
441  if( mpi_pool_rms ){
442  mpi_pool_rms->set_transition_threshold( transition_threshold_ );
443  mpi_pool_rms->set_reserve_size( n_nodes );
444  mpi_pool_rms->set_reserve_size( n_nodes );
445  tr.Debug << "MPIHPool: set transition threshold to " << transition_threshold_ << std::endl;
446  pool_rms_ = mpi_pool_rms;
447  tr.Debug << "about to begin sampling with MPIHPool " << std::endl;
448  }else{
449  utility_exit_with_message("cast to MPIPool_RMSD failed! fatal error!");
450  }
451  }
452 
453  }
454 #endif
455 
456 
457  //output params
458  int width(10); int precision(6);
459  ///make sure that this job is not repeated again in case of restart --> output to general output file
460  if ( protocols::jd2::JobDistributor::get_instance()->job_outputter() ) {
463  jd->job_outputter()->final_pose( jd->current_job(), pose );
464  }
465 
466  core::Size nr_jobs( protocols::jd2::JobDistributor::get_instance()->total_nr_jobs() );
467  core::Size nr_dirs( nr_jobs / option[ sampling::max_files_per_dir ]() + 1 );
468 
469  //exceptional use of ofstream to write directly to directory in MPI mode -- short-cutting the MPI-Filebuffer
470  std::ofstream transition_file;
471  std::string transition_filename( jobname_dirhash( "transitions",nr_dirs ) + jobname + ".transition.dat");
472  transition_file.open( transition_filename.c_str() );
473 
474  ///taking care that output stream is std::ofstream so that we write directly to File instead of rerouting via MPIFileBuf.
475  /// this would overload MPIFilebuffer since we open a different file for each process...
476  /// keep file open... parallel open/closing is hard on the file-system
477  std::string traj_filename( jobname_dirhash( "trajectories", nr_dirs ) + jobname + ".traj.out" );
478  std::string traj_scorefile( jobname_dirhash( "trajectories", nr_dirs ) + jobname + ".traj.sc" );
479  std::ofstream traj_file( traj_filename.c_str() );
480  std::ofstream traj_sc( traj_scorefile.c_str() );
482  sfd.set_filename( traj_filename );
483 
484  //test-- add ramp up temperature in order to equilibrate structure?
485  core::Size interval_inc_temp = option[ sampling::interval_increment_temp ];
486  core::Real starting_temp = option[ sampling::starting_temp ];
487  core::Real ending_temp = option[ basic::options::OptionKeys::sampling::mc_kt ];
488  bool constrain_structure = option[ sampling::add_constraints ];
489 
490  if( ramp_temperature_ ){
491  mc_ = new MonteCarlo( *sfxn_, starting_temp );
492  }else{
493  mc_ = new MonteCarlo( *sfxn_, ending_temp );
494  }
495 
496  /**
497  if( MPI_synchronize_pools_ && use_hierarchical_clustering ) {
498  core::io::silent::SilentStructOP ss = core::io::silent::SilentStructFactory::get_silent_struct_out();
499  #ifdef USEMPI
500  mc_convergence_checks::MPIHPool_RMSD* hpool_ptr = dynamic_cast<mc_convergence_checks::MPIHPool_RMSD * > (&(*pool_rms_));
501  if( hpool_ptr ) {
502  hpool_ptr->write_headers_to_hierarchy( ss );
503  }
504  #endif
505  }
506  **/
507 
508  if ( !output_only_cluster_transition_ ) {
509  transition_file << "I_TRIAL SCORE RG CLUSTER RMS_TO_CLUSTER RMS_TO_START" << std::endl;
510  } else {
511  transition_file << "I_TRIAL STEPS_SINCE_TRANSITON SCORE RG CLUSTER RMS_TO_CLUSTER RMS_TO_START" << std::endl;
512  }
513 
514  runtime_assert( mc_ ); //are we initialized ?
515  mc_->reset( pose );
516 
517  //setup Rg score calculator
519 
520  //keep a copy of current pose for rms calculations
521  core::pose::Pose init( pose );
522  core::Real rms_to_start;
523 
524  std::string current_cluster_center="";
525  Size current_cluster_first_seen( 0 );
526 
527  if( constrain_structure ){
528  setup_constraints( pose );
529  sfxn_->set_weight( core::scoring::atom_pair_constraint, 1.0 );
530  }
531 
532  //main loop
533  for ( Size i_trial=0; i_trial < ntrials_; i_trial++ ) {
534  tr.Debug << "now on trial " << i_trial << " score is " << ( *sfxn_ )( pose ) << std::endl;
535  core::Real proposal_density_ratio( 1 );
536  randmove_->apply( pose );
537  tr.Debug << "finished applying move" << std::endl;
538  //(*sfxn_)(pose);
539  //all just to get last_proposal_density_ratio
540  if ( detailed_balance_ ) {
541  proposal_density_ratio = randmove_->last_proposal_density_ratio();
542  }
543  tr.Debug << "got proposal density ratio: " << proposal_density_ratio << std::endl;
544 
545  mc_->boltzmann( pose, randmove_->type(), proposal_density_ratio );
546  tr.Debug << "applied boltzmann criterion" << std::endl;
547 
548  //mc_->show_counters(); //debug output
549 
550  //test-- add ramp up temperature in order to equilibrate structure?
551  if( ramp_temperature_ &&
552  mc_->temperature() < ending_temp &&
553  ( i_trial % interval_inc_temp ) == 0 ){
554 
555  if( constrain_structure ){
556  setup_constraints( pose );
557  sfxn_->set_weight( core::scoring::atom_pair_constraint, 1.0 );
558  }
559  mc_->set_temperature( mc_->temperature() + 0.1 );
560  }
561  if( ramp_temperature_ &&
562  constrain_structure &&
563  sfxn_->has_nonzero_weight( core::scoring::atom_pair_constraint ) &&
564  (i_trial % (interval_inc_temp/10) == 0)
565  ){
566  sfxn_->set_weight(
568  ( sfxn_->get_weight(core::scoring::atom_pair_constraint) - 0.1 )
569  ); //reduce constraints as simulation progresses
570  if(sfxn_->get_weight( core::scoring::atom_pair_constraint ) < 0.1){
571  sfxn_->set_weight( core::scoring::atom_pair_constraint, 0.0); //because of numeric instability
572  pose.remove_constraints();
573  }
574  }
575  if ( (i_trial % interval_posedump_) == 0 ) {
576  tr.Debug << "about to call dump_decoy_or_score" << std::endl;
577  dump_decoy_or_score( traj_file, pose, i_trial, jobname, loops, false /*not just score*/);
578  }
579 
580  if ( (i_trial % interval_transitiondump_) == 0 ) { //output current next cluster
581  std::string cluster_center; core::Real rms_to_cluster;
582  core::pose::Pose looponly;
583  core::Size new_level_start = 0;
584  tr.Debug << "slave on " << i_trial << std::endl;
585  if( use_hierarchical_clustering_ ) {
586  if( !MPI_synchronize_pools_ ) {
587  mc_convergence_checks::HierarchicalLevel* hpool_ptr = dynamic_cast<mc_convergence_checks::HierarchicalLevel * > (&(*pool_rms_));
588  utility::vector1< core::Size > address(hpool_ptr->nlevels(), 0 );
589  utility::vector1< core::Real > rms_to_cluster(hpool_ptr->nlevels(), 0.0);
590  if( save_loops_only_ && loops.num_loop() > 0 ) {
591  for( loops::Loops::const_iterator itr = loops.begin(); itr != loops.end(); itr++ ) {
592  looponly = core::pose::Pose( pose, itr->start(), itr->stop() );
593  }
594  hpool_ptr->evaluate( looponly, cluster_center, rms_to_cluster, address );
595  }else {
596  hpool_ptr->evaluate( pose, cluster_center, rms_to_cluster, address );
597  }
598  mc_convergence_checks::HierarchicalLevelOP level_n = hpool_ptr;
599  bool above_threshold = false;
600  for( core::Size ii = 1; ii <= rms_to_cluster.size(); ii++ ) {
601  tr.Debug << "level " << ii <<
602  "radius: " << level_n->radius() <<
603  " best-rmsd: " << rms_to_cluster[ ii ] <<
604  " best-cluster: " << cluster_center[ ii ] <<
605  " best-address: " << address[ ii ] << std::endl;
606  if( rms_to_cluster[ ii ] > level_n->radius() ) {
607  above_threshold = true;
608  new_level_start = ii;
609  }
610  level_n = (level_n->next_level());
611  }
612 
613  if( above_threshold ){
614  tr << "NEW STRUCTURE ALERT" << std::endl;
615  for( core::Size ii = 1; ii <= address.size(); ii++ ) {
616  tr << address[ ii ] << " ";
617  }
618  tr << std::endl;
619  std::string newtag = "new-structure-tag";
620  if( save_loops_only_ && loops.num_loop() > 0 ){
621  hpool_ptr->add_new( looponly, newtag, address, true, new_level_start );
622  } else {
623  hpool_ptr->add_new( pose, newtag, address, true, new_level_start );
624  }
625  }
626  } else { //use hierarchy and use MPI-synching
627 #ifdef USEMPI
628  mc_convergence_checks::MPIHPool_RMSD* hpool_ptr = dynamic_cast<mc_convergence_checks::MPIHPool_RMSD * > (&(*pool_rms_));
629  runtime_assert( hpool_ptr != 0 );
630  tr.Debug << "about to call hierarchical mpi eval-and-add" << std::endl;
631  if( save_loops_only_ && loops.num_loop() > 0 ){
632  for( loops::Loops::const_iterator itr = loops.begin(); itr != loops.end(); itr++ ) {
633  looponly = core::pose::Pose( pose, itr->start(), itr->stop() );
634  }
635  hpool_ptr->evaluate_and_add( looponly, cluster_center, rms_to_cluster);
636  } else {
637  hpool_ptr->evaluate_and_add( pose, cluster_center, rms_to_cluster );
638  }
639  //tr << "before scoring" << std::endl;
640  //(*sfxn_)(pose);
641  //tr << "after scoring" << std::endl;
642  tr << "after MPIHPool-eval: " << cluster_center << " " << rms_to_cluster << std::endl;
643 #endif
644  }
645  } else{ //use MPIPool
646  if( save_loops_only_ && loops.num_loop() > 0 ){
647  for( loops::Loops::const_iterator itr = loops.begin(); itr != loops.end(); itr++ ) {
648  looponly = core::pose::Pose( pose, itr->start(), itr->stop() );
649  tr << "looponly pose has " << looponly.total_residue() << " should be containing segment: " << itr->start() << " " << itr->stop() << " " << " from ref: " << pose.total_residue() << std::endl;
650  }
651  tr << "check: looponly pose has " << looponly.total_residue() << std::endl;
652  pool_rms_->evaluate_and_add( looponly, cluster_center, rms_to_cluster, transition_threshold_ );
653  } else {
654  pool_rms_->evaluate_and_add( pose, cluster_center, rms_to_cluster, transition_threshold_ );
655  }
656  }
657  //pool_rms_->evaluate( pose, cluster_center, rms_to_cluster);
658  runtime_assert( pose.total_residue() > 0 );
659  dump_decoy_or_score( traj_sc, pose, i_trial, jobname, loops, true /*not just score*/ );
660 
661  if ( !output_only_cluster_transition_ ) {
662  PROF_START( basic::MPICANONICALSAMPLING );
663  //evaluates cluster and writes transition
664  rms_to_start = core::scoring::CA_rmsd( init, pose );
665  transition_file << i_trial << " "
666  << F(width,precision,mc_->temperature()) << " "
667  << F(width,precision,(*sfxn_)( pose )) << " "
668  << F(width,precision,rge.calculate_rg_score( pose )) << " "
669  << cluster_center << " "
670  << get_ABGEO_string( pose, loops ) << " " //add in on-the-fly ABGEO assignment to save time
671  << F(width,precision,rms_to_cluster) << " "
672  << F(width,precision,rms_to_start) << " "
673  << std::endl;
674  PROF_STOP( basic::MPICANONICALSAMPLING );
675  } else {// output_only_cluster_transition_
676  //check if transition occurs
677  if ( current_cluster_center.compare("") == 0 ) {
678  //first cluster seen
679  current_cluster_center = cluster_center;
680  } else if (current_cluster_center.compare( cluster_center ) != 0 ) { //new cluster
681  PROF_START( basic::MPICANONICALSAMPLING );
682  rms_to_start = core::scoring::CA_rmsd( init, pose );
683  transition_file << i_trial << " "
684  << i_trial-current_cluster_first_seen << " "
685  << F(width,precision,mc_->temperature()) << " "
686  << F(width,precision,(*sfxn_)( pose )) << " "
687  << F(width,precision,rge.calculate_rg_score( pose )) << " "
688  << cluster_center << " "
689  << get_ABGEO_string( pose, loops ) << " " //add in on-the-fly ABGEO assignment to save time
690  << F(width,precision,rms_to_cluster) << " "
691  << F(width,precision,rms_to_start) << " "
692  << std::endl;
693  current_cluster_center = cluster_center;
694  current_cluster_first_seen = i_trial;
695  PROF_STOP( basic::MPICANONICALSAMPLING );
696  }
697  }
698  } //output occured
699  } //for loop over trials
700  //DEBUG OUTPUT
701 
702  /**
703 #ifdef USEMPI
704  int rank = 0;
705  MPI_Comm_rank( MPI_COMM_WORLD, (int*) (&rank) );
706  std::ofstream debug_cl_cnters;
707  std::ostringstream q;
708  q << rank;
709  debug_cl_cnters.open((q.str() + ".debug_cl_centers.txt").c_str());
710  for(core::Size itr = 1; itr <= pool_rms_->size(); itr++){
711  std::string tag = pool_rms_->get_tag(itr);
712  debug_cl_cnters << tag << std::endl;
713  }
714 #endif
715  **/
716  //DEBUG OUTPUT
717 
718 } //apply
719 
720 
722 CanonicalSamplingMover::get_name() const {
723  return "CanonicalSamplingMover";
724 }
725 
726 
727 } //moves
728 } //protocols
729