18 #include <numeric/random/random.hh>
24 #include <utility/tag/Tag.hh>
27 #include <basic/Tracer.hh>
35 #include <utility/vector1.hh>
36 #include <utility/vector0.hh>
37 #include <utility/string_util.hh>
40 #include <boost/foreach.hpp>
41 #define foreach BOOST_FOREACH
50 #include <basic/options/option.hh>
51 #include <basic/options/keys/OptionKeys.hh>
52 #include <basic/options/keys/packing.OptionKeys.gen.hh>
56 #include <utility/mpi_util.hh>
59 #include <basic/options/keys/out.OptionKeys.gen.hh>
60 #include <basic/options/keys/run.OptionKeys.gen.hh>
64 namespace design_opt {
66 static basic::Tracer
TR(
"protocols.design_opt.PointMutationCalculator" );
67 static numeric::random::RandomGenerator
RG( 54 );
69 using namespace chemical;
76 task_factory_( NULL ),
113 for(
Size isamp = 1; isamp <= sample_types.size(); ++isamp ){
115 TR <<
"WARNING: the sample type, " <<
sample_types_[ isamp ] <<
", is not defined. Use \'high\' or \'low\'." << std::endl;
116 runtime_assert(
false );
137 filters.push_back( filter );
139 sample_types.push_back( sample_type );
151 for(
Size isamp = 1; isamp <= sample_types.size(); ++isamp ){
153 TR <<
"WARNING: the sample type, " <<
sample_types_[ isamp ] <<
", is not defined. Use \'high\' or \'low\'." << std::endl;
154 runtime_assert(
false );
286 using namespace basic::options;
287 using namespace basic::options::OptionKeys;
289 if ( option[ run::shuffle ]() ) {
290 return option[ out::shuffle_nstruct ]();
292 return option[ out::nstruct ]();
303 using namespace core::pack::task;
304 using namespace core::pack::task::operation;
305 using namespace core::chemical;
308 vector1< bool > allowed_aas;
311 allowed_aas[ target_aa ] =
true;
318 repack_around_op->repack_shell( repack_shell_ );
319 repack_around_op->allow_design(
true );
320 repack_around_op->include_residue( resi );
321 mut_res->push_back( repack_around_op );
323 PackerTaskOP mutate_residue = mut_res->create_task_and_apply_taskoperations( pose );
324 mutate_residue->initialize_from_command_line().or_include_current(
true );
325 mutate_residue->nonconst_residue_task( resi ).restrict_absent_canonical_aas( allowed_aas );
326 TR<<
"Mutating residue "<<pose.
residue( resi ).
name3()<<resi<<
" to ";
331 mutate_residue->request_symmetrize_by_union();
340 utility_exit_with_message(
"Cannot currently use PointMutationCalculator (GreedyOptMutation/ParetoOptMutation) with rtmin on a symmetric pose!");
343 rtmin->apply( pose );
344 TR<<
"Finished rtmin"<<std::endl;
346 TR<<pose.
residue( resi ).
name3()<<
". Now relaxing..."<<std::endl;
348 if( relax_mover() ) {
349 relax_mover()->apply( pose );
357 AA const & target_aa,
360 using namespace core::pack::task;
361 using namespace core::pack::task::operation;
362 using namespace core::chemical;
365 vector1< bool > allowed_aas;
368 allowed_aas[ target_aa ] =
true;
375 repack_around_op->repack_shell( repack_shell_ );
376 repack_around_op->allow_design(
true );
377 repack_around_op->include_residue( resi );
381 restrict_to_aa_op->keep_aas( allowed_aas );
386 mut_res->push_back( repack_around_op );
387 mut_res->push_back( restrict_to_aa_op );
388 mut_res->push_back( init_from_cmd_op );
389 mut_res->push_back( incl_curr_op );
390 TR <<
"Mutation " << pose.
residue( resi ).
name1() <<
"_" << resi;
393 green_packer->set_task_factory( mut_res );
394 green_packer->apply( pose );
397 relax_mover()->apply( pose );
409 for(
Size ifilt = 1; ifilt <= filters_.size(); ++ifilt ){
411 bool this_filter_pass( ( filters_[ ifilt ] )->apply( pose ) );
412 filter_pass = filter_pass && this_filter_pass;
414 Real const flip_sign( sample_types_[ ifilt ] ==
"high" ? -1 : 1 );
415 Real const val( flip_sign * ( filters_[ ifilt ] )->report_sm( pose ) );
417 TR<<
" :: Filter " << ifilt;
418 if( !this_filter_pass ) TR <<
" fail, ";
419 else TR <<
" pass, ";
420 TR <<
" value "<< val <<
" ::";
421 vals.push_back( val );
434 using namespace core::chemical;
439 bool new_pos(
true );
440 for(
Size iseq = 1; iseq <= seqpos_aa_vals_vec.size(); ++iseq ){
441 if( seqpos == seqpos_aa_vals_vec[ iseq ].first ){
443 bool replaced(
false );
445 for(
core::Size iaa = 1; iaa <= seqpos_aa_vals_vec[ iseq ].second.size(); ++iaa ){
448 seqpos_aa_vals_vec[ iseq ].second[ iaa ].second = vals;
453 if( replaced )
break;
454 seqpos_aa_vals_vec[ iseq ].second.push_back( aa_vals_pair );
475 calc_point_mut_filters( pose, seqpos_aa_vals_vec );
478 seqpos_aa_vals != seqpos_aa_vals_vec.end(); ++seqpos_aa_vals ){
479 Size seqpos( seqpos_aa_vals->first );
481 assert( !seqpos_aa_vals->second.empty() );
484 aa_vals != seqpos_aa_vals->second.end(); ++aa_vals ){
486 assert( !aa_vals->second.empty() );
487 aa_val.push_back( pair< AA, Real >( aa_vals->first, aa_vals->second[ 1 ] ) );
489 seqpos_aa_val_vec.push_back(
pair<
Size, vector1< pair< AA, Real > > >( seqpos, aa_val ) );
496 vector1<
pair<
Size, vector1<
pair<
AA, vector1< Real > > > > > & seqpos_aa_vals_vec
499 using namespace core::pack::task;
500 using namespace core::pack::task::operation;
501 using namespace core::chemical;
505 seqpos_aa_vals_vec.clear();
508 PackerTaskOP tmptask = task_factory_->create_task_and_apply_taskoperations( start_pose );
510 tmptask->request_symmetrize_by_union();
515 vector1< core::Size > being_designed;
517 being_designed.clear();
524 if( task->residue_task( resi ).being_designed() && start_pose.
residue(resi).
is_protein() ){
525 being_designed.push_back( resi );
526 group_ids.push_back( 0 );
528 group_ids.push_back( 1 );
531 if( being_designed.empty() ) {
532 TR.Warning <<
"WARNING: No residues are listed as designable." << std::endl;
538 bool use_precomp_rot_pair_nrgs(
true );
539 if( basic::options::option[ basic::options::OptionKeys::packing::linmem_ig ].user() ){
540 TR <<
"Note: you are using linmem_ig in your options: " <<
541 "packing will be slower because GreedyOpt can't use GreenPacker precomputed rotamer pair energies" << std::endl;
542 use_precomp_rot_pair_nrgs =
false;
545 TR <<
"Note: you are using symmetry: " <<
546 "packing will be slower because GreedyOpt can't use GreenPacker precomputed rotamer pair energies" << std::endl;
547 use_precomp_rot_pair_nrgs =
false;
551 user_defined_group_discriminator->set_group_ids( group_ids );
553 green_packer->set_group_discriminator( user_defined_group_discriminator );
554 green_packer->set_scorefunction( *scorefxn() );
555 green_packer->set_reference_round_task_factory( task_factory() );
558 int mpi_rank( 0 ), mpi_nprocs( 1 ), mpi_rank_low( 0 );
560 MPI_Comm_rank(MPI_COMM_WORLD, &
mpi_rank);
561 MPI_Comm_size(MPI_COMM_WORLD, &mpi_nprocs);
565 TR <<
"Detected jd2::MPIWorkPoolJobDistributor... excluding proc 0 from calculations" << std::endl;
568 if( get_nstruct() < mpi_nprocs - mpi_rank_low ) utility_exit_with_message(
569 "You must specify nstruct >= " + utility::to_string( mpi_nprocs - mpi_rank_low ) +
570 " when using " + utility::to_string( mpi_nprocs ) +
" processors for MPI PointMutationCalculator" +
571 " when called from rosetta_scripts or any other app using jd2::MPIWorkPoolJobDistributor!" );
577 TR <<
"Detected jd2::MPIFileBufJobDistributor... excluding procs 0-" << ( mpi_rank_low - 1 ) <<
" from calculations" << std::endl;
579 if( get_nstruct() < mpi_nprocs - mpi_rank_low ) utility_exit_with_message(
580 "You must specify nstruct >= " + utility::to_string( mpi_nprocs - mpi_rank_low ) +
581 " when using " + utility::to_string( mpi_nprocs ) +
" processors for MPI PointMutationCalculator" +
582 " when called from rosetta_scripts or any other app using jd2::MPIFileBufJobDistributor!" );
612 vector1< pair< Size, AA > > all_muts;
613 for(
Size iresi = 1; iresi <= being_designed.size(); ++iresi ){
614 Size const resi( being_designed[ iresi ] );
616 typedef std::list< ResidueTypeCOP > ResidueTypeCOPList;
617 ResidueTypeCOPList
const & allowed( task->residue_task( resi ).allowed_residue_types() );
618 vector1< AA > allow_temp;
620 if(std::find(allow_temp.begin(),allow_temp.end(),t->aa())!=allow_temp.end())
continue;
621 allow_temp.push_back( t->aa() );
624 foreach(
AA const target_aa, allow_temp ){
625 all_muts.push_back( pair< Size, AA >( resi, target_aa ) );
629 vector1< pair< Size, AA > > my_muts( all_muts );
635 for(
Size imut = 1; imut <= all_muts.size(); ++imut ){
637 Size this_mpi_rank( ( imut - 1 ) % ( mpi_nprocs - mpi_rank_low ) + mpi_rank_low );
639 my_muts.push_back( all_muts[ imut ] );
648 for(
Size imut = 1; imut <= my_muts.size(); ++imut ){
649 Size seqpos( my_muts[ imut ].first );
650 AA target_aa( my_muts[ imut ].second );
656 vector1< Real > vals;
657 if( use_precomp_rot_pair_nrgs ) mutate_and_relax( pose, seqpos, target_aa, green_packer );
658 else mutate_and_relax( pose, seqpos, target_aa );
660 eval_filters( pose, filter_pass, vals );
663 if( !filter_pass )
continue;
664 assert( !vals.empty() );
667 std::stringstream fname;
669 TR<<
"Saving pose "<<fname.str() << std::endl;
682 utility::send_integer_to_node( mpi_rank_low, seqpos_aa_vals_vec.size() );
683 for(
Size iseq = 1; iseq <= seqpos_aa_vals_vec.size(); ++iseq ){
684 utility::send_integer_to_node( mpi_rank_low, seqpos_aa_vals_vec[ iseq ].first );
686 utility::send_integer_to_node( mpi_rank_low, aa_pairs.size() );
687 for(
core::Size iaa = 1; iaa <= aa_pairs.size(); ++iaa ){
691 for(
Size ival = 1; ival <= ( filters() ).
size(); ++ival ){
692 utility::send_double_to_node( mpi_rank_low, aa_pairs[ iaa ].second[ ival ] );
698 else if(
mpi_rank == mpi_rank_low ){
699 for(
Size iproc = mpi_rank_low + 1; iproc < mpi_nprocs; ++iproc ){
702 Size n_seqpos( utility::receive_integer_from_node( iproc ) );
703 for(
Size imut = 1; imut <= n_seqpos; ++imut ){
704 Size seqpos( utility::receive_integer_from_node( iproc ) );
706 Size n_aas( utility::receive_integer_from_node( iproc ) );
707 for(
Size iaa = 1; iaa <= n_aas; ++iaa ){
708 char aa_char( utility::receive_char_from_node( iproc ) );
710 vector1< Real > vals( ( filters() ).
size(), 0. );
711 for(
Size ival = 1; ival <= vals.size(); ++ival ){
712 vals[ ival ] = utility::receive_double_from_node( iproc );
724 for(
Size iproc = mpi_rank_low + 1; iproc < mpi_nprocs; ++iproc ){
725 utility::send_integer_to_node( iproc, seqpos_aa_vals_vec.size() );
726 for(
Size iseq = 1; iseq <= seqpos_aa_vals_vec.size(); ++iseq ){
727 utility::send_integer_to_node( iproc, seqpos_aa_vals_vec[ iseq ].first );
729 utility::send_integer_to_node( iproc, aa_pairs.size() );
730 for(
core::Size iaa = 1; iaa <= aa_pairs.size(); ++iaa ){
733 for(
Size ival = 1; ival <= ( filters() ).
size(); ++ival ){
734 utility::send_double_to_node( iproc, aa_pairs[ iaa ].second[ ival ] );
743 Size n_seqpos( utility::receive_integer_from_node( mpi_rank_low ) );
744 for(
Size imut = 1; imut <= n_seqpos; ++imut ){
745 Size seqpos( utility::receive_integer_from_node( mpi_rank_low ) );
747 Size n_aas( utility::receive_integer_from_node( mpi_rank_low ) );
748 for(
Size iaa = 1; iaa <= n_aas; ++iaa ){
749 char aa_char( utility::receive_char_from_node( mpi_rank_low ) );
752 vector1< Real > vals( ( filters() ).
size(), 0. );
753 for(
Size ival = 1; ival <= vals.size(); ++ival ){
754 vals[ ival ] = utility::receive_double_from_node( mpi_rank_low );