2 #include <protocols/moves/SidechainMover.hh>
3 #include <protocols/moves/SidechainMover.fwd.hh>
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>
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>
48 #include <basic/Tracer.hh>
49 #include <basic/prof.hh>
52 #include <ObjexxFCL/format.hh>
53 #include <ObjexxFCL/Fmath.hh>
63 OPT_1GRP_KEY(Boolean, sampling,output_only_cluster_transitions)
65 OPT_2GRP_KEY(File, sampling, out, new_structures )
81 static basic::Tracer
tr(
"protocols.moves.CanonicalSamplingMover");
86 using namespace protocols::moves;
87 using namespace basic::options;
88 using namespace basic::options::OptionKeys;
89 using namespace core::pack::task;
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 );
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);
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 );
121 CanonicalSamplingMover::CanonicalSamplingMover():
122 Mover(
"CanonicalSamplingMover"),
127 interval_posedump_(100),
128 interval_transitiondump_(100),
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)
137 set_defaults_from_cmdline();
140 CanonicalSamplingMover::CanonicalSamplingMover(
145 Mover(
"CanonicalSamplingMover"),
146 mc_(
new MonteCarlo( *sfxn, basic::options::option[ basic::options::OptionKeys::sampling::mc_kt ]() ) ),
150 interval_posedump_(1000),
151 interval_transitiondump_(100),
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)
160 set_defaults_from_cmdline();
161 runtime_assert( sfxn );
164 void CanonicalSamplingMover::set_defaults_from_cmdline() {
165 using namespace basic::options;
166 using namespace basic::options::OptionKeys;
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 ]();
183 CanonicalSamplingMover::add_mover(
187 randmove_->add_mover( m, probability);
192 CanonicalSamplingMover::periodic_range(
197 using namespace ObjexxFCL;
199 return ( ( a >= halfx || a < -halfx ) ? mod( mod( a, x ) + ( x + halfx ), x ) - halfx : a );
208 for(
core::Size ii = itr->start(); ii <= itr->stop(); ii++ ){
212 periodic_range( phi , 360.0 );
213 periodic_range( psi , 360.0 );
214 periodic_range( omega, 360.0 );
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";
222 position_assignment=
"E";
225 if ( -125 < psi && psi <= 50 ) {
226 position_assignment=
"A";
228 position_assignment=
"B";
231 ABGEO_assignment = ABGEO_assignment + position_assignment;
233 ABGEO_assignment = ABGEO_assignment +
",";
235 return ABGEO_assignment;
238 void CanonicalSamplingMover::ntrials(
int ntrials) {ntrials_ = ntrials;}
240 void CanonicalSamplingMover::set_temp(
core::Real temperature) {
242 temperature_ = temperature;
245 void CanonicalSamplingMover::set_interval_pose_dump(
int p_interval){ interval_posedump_=p_interval;}
247 void CanonicalSamplingMover::set_interval_data_dump(
int d_interval){ interval_transitiondump_=d_interval;}
251 void CanonicalSamplingMover::detailed_balance(
bool truefalse) {detailed_balance_ = truefalse;}
254 void CanonicalSamplingMover::use_MPI_sync_pools(
bool truefalse) {MPI_synchronize_pools_ = truefalse;}
256 void CanonicalSamplingMover::use_MPI_bcast(
bool truefalse) {MPI_bcast_ = truefalse;}
258 void CanonicalSamplingMover::use_hierarchical_clustering(
bool truefalse) {use_hierarchical_clustering_ = truefalse;}
265 void CanonicalSamplingMover::output_only_cluster_transitions(
bool truefalse){
266 output_only_cluster_transition_ = truefalse;
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++){
277 core::Real const CA_dist = ( CA_i - CA_j ).length();
278 if( CA_dist < CA_cutoff ){
301 utility::file::PathName output_path = basic::options::option[ basic::options::OptionKeys::out::path::path ];
303 output_path.name() +
"/" +
305 ObjexxFCL::lead_zero_string_of( job_id % nr_dirs, 4 ) +
"/"
307 utility::file::create_directory_recursive( dir_name );
311 void CanonicalSamplingMover::dump_decoy_or_score(
321 PROF_START( basic::CANONICALMOVER_WRITE_TO_FILE );
329 using namespace ObjexxFCL;
331 core::Size itrial_100 = i_trial / interval_posedump_ / 100;
332 core::Size rest100 = ( i_trial / interval_posedump_ ) % 100;
335 core::Size score_dump100 = ( i_trial / interval_transitiondump_ ) % interval_posedump_;
338 score_dump_str=
"."+lead_zero_string_of( score_dump100, 3 );
350 + lead_zero_string_of( itrial_100, 8 ) +
"."
351 + lead_zero_string_of( rest100_10, 1 ) +
"."
352 + lead_zero_string_of( rest100_rest10, 1)
356 && loop_to_dump.num_loop() > 0 ) {
359 for( loops::Loops::const_iterator itr = loop_to_dump.begin(); itr != loop_to_dump.end(); itr++ ) {
361 ss->fill_struct(looponly, decoy_tag);
366 ss->fill_struct(pose, decoy_tag);
368 ss->add_energy(
"itrial", i_trial );
369 if ( i_trial == 0 ) {
370 ss->print_header( os );
373 tr.Debug <<
"about to write to silent file" << std::endl;
375 PROF_STOP( basic::CANONICALMOVER_WRITE_TO_FILE );
379 CanonicalSamplingMover::apply(
Pose & pose){
380 using namespace ObjexxFCL::fmt;
381 using namespace basic::options;
382 using namespace basic::options::OptionKeys;
384 tr.Debug <<
"starting on pose with name: " << (pose.
pdb_info())->name() << std::endl;
387 utility_exit_with_message(
"did you forget -in:file:silent ? Need to start CanonicalSamplingMover with a valid pose" );
392 PROF_START( basic::MPICANONICALSAMPLING );
395 runtime_assert( pool_rms_ );
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 );
405 if( option[ constraints::cst_file ].user() ) {
412 MPI_Comm_size( MPI_COMM_WORLD, (
int* )( &n_nodes ) );
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() );
418 mpi_pool_rms->set_transition_threshold( transition_threshold_ );
420 mpi_pool_rms->set_reserve_size( n_nodes );
421 pool_rms_ = mpi_pool_rms;
423 utility_exit_with_message(
"cast to MPIBPool_RMSD failed! fatal error!");
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() );
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 );
434 pool_rms_ = mpi_pool_rms;
436 utility_exit_with_message(
"cast to MPIPool_RMSD failed! fatal error!");
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() );
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;
449 utility_exit_with_message(
"cast to MPIPool_RMSD failed! fatal error!");
467 core::Size nr_dirs( nr_jobs / option[ sampling::max_files_per_dir ]() + 1 );
470 std::ofstream transition_file;
472 transition_file.open( transition_filename.c_str() );
479 std::ofstream traj_file( traj_filename.c_str() );
480 std::ofstream traj_sc( traj_scorefile.c_str() );
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 ];
490 if( ramp_temperature_ ){
491 mc_ =
new MonteCarlo( *sfxn_, starting_temp );
508 if ( !output_only_cluster_transition_ ) {
509 transition_file <<
"I_TRIAL SCORE RG CLUSTER RMS_TO_CLUSTER RMS_TO_START" << std::endl;
511 transition_file <<
"I_TRIAL STEPS_SINCE_TRANSITON SCORE RG CLUSTER RMS_TO_CLUSTER RMS_TO_START" << std::endl;
514 runtime_assert( mc_ );
525 Size current_cluster_first_seen( 0 );
527 if( constrain_structure ){
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;
536 randmove_->apply( pose );
537 tr.Debug <<
"finished applying move" << std::endl;
540 if ( detailed_balance_ ) {
541 proposal_density_ratio = randmove_->last_proposal_density_ratio();
543 tr.Debug <<
"got proposal density ratio: " << proposal_density_ratio << std::endl;
545 mc_->boltzmann( pose, randmove_->type(), proposal_density_ratio );
546 tr.Debug <<
"applied boltzmann criterion" << std::endl;
551 if( ramp_temperature_ &&
552 mc_->temperature() < ending_temp &&
553 ( i_trial % interval_inc_temp ) == 0 ){
555 if( constrain_structure ){
559 mc_->set_temperature( mc_->temperature() + 0.1 );
561 if( ramp_temperature_ &&
562 constrain_structure &&
564 (i_trial % (interval_inc_temp/10) == 0)
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 );
580 if ( (i_trial % interval_transitiondump_) == 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_));
590 if( save_loops_only_ && loops.num_loop() > 0 ) {
591 for( loops::Loops::const_iterator itr = loops.begin(); itr != loops.end(); itr++ ) {
594 hpool_ptr->evaluate( looponly, cluster_center, rms_to_cluster, address );
596 hpool_ptr->evaluate( pose, cluster_center, rms_to_cluster, address );
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;
610 level_n = (level_n->next_level());
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 ] <<
" ";
620 if( save_loops_only_ && loops.num_loop() > 0 ){
621 hpool_ptr->add_new( looponly, newtag, address,
true, new_level_start );
623 hpool_ptr->add_new( pose, newtag, address,
true, new_level_start );
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++ ) {
635 hpool_ptr->evaluate_and_add( looponly, cluster_center, rms_to_cluster);
637 hpool_ptr->evaluate_and_add( pose, cluster_center, rms_to_cluster );
642 tr <<
"after MPIHPool-eval: " << cluster_center <<
" " << rms_to_cluster << std::endl;
646 if( save_loops_only_ && loops.num_loop() > 0 ){
647 for( loops::Loops::const_iterator itr = loops.begin(); itr != loops.end(); itr++ ) {
649 tr <<
"looponly pose has " << looponly.
total_residue() <<
" should be containing segment: " << itr->start() <<
" " << itr->stop() <<
" " <<
" from ref: " << pose.
total_residue() << std::endl;
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_ );
654 pool_rms_->evaluate_and_add( pose, cluster_center, rms_to_cluster, transition_threshold_ );
659 dump_decoy_or_score( traj_sc, pose, i_trial, jobname, loops,
true );
661 if ( !output_only_cluster_transition_ ) {
662 PROF_START( basic::MPICANONICALSAMPLING );
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 ) <<
" "
671 << F(width,precision,rms_to_cluster) <<
" "
672 << F(width,precision,rms_to_start) <<
" "
674 PROF_STOP( basic::MPICANONICALSAMPLING );
677 if ( current_cluster_center.compare(
"") == 0 ) {
679 current_cluster_center = cluster_center;
680 }
else if (current_cluster_center.compare( cluster_center ) != 0 ) {
681 PROF_START( basic::MPICANONICALSAMPLING );
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 ) <<
" "
690 << F(width,precision,rms_to_cluster) <<
" "
691 << F(width,precision,rms_to_start) <<
" "
693 current_cluster_center = cluster_center;
694 current_cluster_first_seen = i_trial;
695 PROF_STOP( basic::MPICANONICALSAMPLING );
722 CanonicalSamplingMover::get_name()
const {
723 return "CanonicalSamplingMover";