53 #include <basic/MetricValue.hh>
71 #include <basic/options/keys/packstat.OptionKeys.gen.hh>
75 #include <utility/tag/Tag.hh>
79 #include <ObjexxFCL/FArray1D.hh>
80 #include <ObjexxFCL/FArray2D.hh>
82 #include <basic/Tracer.hh>
84 #include <utility/file/FileName.hh>
85 #include <utility/string_util.hh>
93 #include <utility/vector0.hh>
94 #include <utility/vector1.hh>
97 #include <utility/excn/Exceptions.hh>
101 using basic::Warning;
103 static basic::Tracer
TR(
"protocols.analysis.InterfaceAnalyzerMover");
104 static basic::Tracer
TRinterface(
"protocols.analysis.InterfaceAnalyzerMover.interface_selection");
105 static basic::Tracer
TRhbonds(
"protocols.analysis.InterfaceAnalyzerMover.missing_hbonds");
111 if(tracer)
return ost;
118 using namespace protocols::moves;
134 return "InterfaceAnalyzerMover";
144 bool compute_packstat,
150 interface_jump_(interface_jump),
156 compute_packstat_(compute_packstat),
157 compute_interface_sc_(true),
158 compute_separated_sasa_(true),
159 compute_interface_energy_(true),
160 calc_hbond_sasaE_(true),
161 compute_interface_delta_hbond_unsat_(true),
162 skip_reporting_(false),
163 multichain_constructor_(false),
164 pack_input_(pack_input),
165 pack_separated_(pack_separated),
166 use_jobname_(use_jobname),
168 use_centroid_(false),
171 interface_delta_sasa_(0),
173 per_residue_energy_(0),
175 separated_interface_energy_(0),
176 crossterm_interface_energy_(0),
177 separated_interface_energy_ratio_(0),
178 crossterm_interface_energy_ratio_(0),
179 interface_packstat_(0),
182 delta_unsat_hbond_counter_(0),
205 std::set<int> fixed_chains,
208 bool compute_packstat,
215 fixed_chains_(fixed_chains),
225 compute_packstat_(compute_packstat),
226 compute_interface_sc_(true),
227 compute_separated_sasa_(true),
228 compute_interface_energy_(true),
229 calc_hbond_sasaE_(true),
230 compute_interface_delta_hbond_unsat_(true),
231 skip_reporting_(false),
232 multichain_constructor_(true),
233 pack_input_(pack_input),
234 pack_separated_(pack_separated),
235 use_jobname_(use_jobname),
237 use_centroid_(false),
240 interface_delta_sasa_(0),
242 per_residue_energy_(0),
244 separated_interface_energy_(0),
245 crossterm_interface_energy_(0),
246 separated_interface_energy_ratio_(0),
247 crossterm_interface_energy_ratio_(0),
248 interface_packstat_(0),
251 delta_unsat_hbond_counter_(0),
330 using namespace core;
332 utility_exit_with_message_status(
"InterfaceAnalyzerMover: pose has only one chain, aborting analysis \n", 1 );
353 TR<<
"WARNING: more than 2 chains present w/o using the right constructor! Values might be over the wrong jump." << std::endl;
418 return "InterfaceAnalyzerMover";
451 TR <<
"Making an interface set with default calculator." << std::endl;
452 basic::MetricValue< std::set< core::Size > > mv_interface_set;
463 std::set<int> & fixed_chains){
464 using namespace core;
467 if(fixed_chains.empty())
468 utility_exit_with_message_status(
"Can't find fixed chains. Exiting...\n", 1 );
473 for(
Size ii = 1; ii<= numchains; ++ii){
479 Size anchor_chain (1);
480 for(
Size ii = 1; ii<= numchains; ++ii){
481 if ( !fixed_chains.count( ii ) ){
492 bool previous_mobile (
false);
493 for(
Size ii=1; ii<= numchains; ++ii){
494 foldtree.add_edge(
Edge(chain_starts[ii], chain_ends[ii], kinematics::Edge::PEPTIDE) );
495 if (ii != anchor_chain) {
496 if ( fixed_chains.count(ii) && previous_mobile ){
497 foldtree.add_edge(
Edge(chain_starts[ii], chain_ends[*(fixed_chains.begin())], this_jump) );
499 else if ( fixed_chains.count(ii) ){
500 foldtree.add_edge(
Edge(chain_starts[ii], chain_ends[anchor_chain], this_jump) );
501 mobile_jump = this_jump;
502 previous_mobile=
true;
504 else foldtree.add_edge(
Edge(chain_starts[ii], chain_ends[anchor_chain], this_jump) );
509 foldtree.reorder(chain_starts[anchor_chain]);
520 std::set<int> & fixed_chains){
521 using namespace core;
522 using namespace utility;
523 std::set<Size> fixed_side_residues, other_side_residues;
524 std::set<core::Size> fixed_chain_nums ;
525 std::set<core::Size> other_chain_nums;
529 if( fixed_chains.count( pose.
chain( ii ) ) ){
530 fixed_side_residues.insert( ii );
531 fixed_chain_nums.insert( pose.
chain( ii ) );
534 other_side_residues.insert( ii );
535 other_chain_nums.insert( pose.
chain( ii ) );
545 std::pair< std::set<Size>, std::set<Size> > side_pairs;
546 side_pairs.first = fixed_side_residues;
547 side_pairs.second = other_side_residues;
549 interface_deffinition_vector.push_back( side_pairs );
556 basic::MetricValue< std::set<Size> > mv_interface_set;
568 using namespace core;
571 TR <<
"NULL scorefunction. Initialize from cmd line." << std::endl;
572 using namespace core::scoring;
579 translate->step_size( 1000.0 );
580 translate->apply( separated_pose );
581 (*sf_)(separated_pose);
584 return separated_pose;
592 using namespace core;
593 basic::MetricValue< core::Real > mv_complex_sasa;
594 basic::MetricValue< core::Real > mv_separated_sasa;
596 complexed_pose.
metric(
Sasa_,
"total_sasa", mv_complex_sasa);
597 separated_pose.
metric(
Sasa_,
"total_sasa", mv_separated_sasa);
598 Real const total_sasa_value (mv_complex_sasa.value());
599 Real const separated_sasa_value ( mv_separated_sasa.value() );
608 core::Real probe_radius = basic::options::option[basic::options::OptionKeys::pose_metrics::sasa_calculator_probe_radius];
610 complexed_residue_hsasa, probe_radius,
613 separated_residue_hsasa, probe_radius,
632 basic::MetricValue< core::Real > mv_delta_total;
638 basic::MetricValue<Size> mv_size;
650 for(
core::Size i(ch1_begin_num); i<= ch1_end_num; ++i) {
656 for(
core::Size i(ch2_begin_num); i<= ch2_end_num; ++i) {
668 using namespace basic::options;
669 using namespace basic::options::OptionKeys;
670 using namespace protocols::moves;
688 repacker->apply(complexed_pose);
689 complex_score = (*sf_)(complexed_pose);
694 repacker->apply( separated_pose );
695 separated_score = (*sf_)(separated_pose) ;
701 ddG_ = complex_score - separated_score;
760 current_job->add_string_real_pair(
"cen_dG",
centroid_dG_ );
763 current_job->add_string_real_pair(
"side1_score",
side1_score_ );
764 current_job->add_string_real_pair(
"side2_score",
side2_score_ );
765 current_job->add_string_real_pair(
"nres_all",
nres_ );
770 current_job->add_string_real_pair(
"sc_value",
sc_value_);
780 TR <<
"Computing interface packstats." << std::endl;
795 interface_pack_score_sum += interface_pack_scores[*it];
812 TR <<
"Computing delta unsat polar residues..." << std::endl;
821 basic::MetricValue< utility::vector1< core::Size > > mv_complexed_unsat_res;
822 basic::MetricValue< utility::vector1< core::Size > > mv_separated_unsat_res;
823 basic::MetricValue< core::id::AtomID_Map< bool > > mv_complexed_unsat_map;
824 basic::MetricValue< core::id::AtomID_Map< bool > > mv_separated_unsat_map;
844 for(
core::Size i=1 ; i <= res.natoms(); ++i ){
850 bool unsat_complex(complexed_unsat_map.has(atid) && complexed_unsat_map(atid) );
851 bool unsat_separated(separated_unsat_map.has(atid) && separated_unsat_map(atid) );
853 if( unsat_complex && !unsat_separated ) {
855 delta_unsat_hbond_atid_vector.push_back(atid);
856 ++delta_unsat_hbond_counter;
877 std::ostringstream interface_oss;
881 std::ostringstream interface_sele;
882 interface_sele << std::endl;
891 pymol_interface <<
"pymol-style selection for interface res \n"
894 bool first_sel_complete(
false );
896 char chain_char, chain_char_last(
'z');
897 for( std::set< core::Size >::const_iterator it(interface_set.begin()),
end(interface_set.end());
900 resnum = pose.
pdb_info()->number(*it);
901 chain_char = pose.
pdb_info()->chain(*it);
903 if( !first_sel_complete ) {
904 interface_sele <<
"cmd.select(\"/" << pymol_obj_for_interface_sel <<
"//" << chain_char <<
"/"
905 << resnum <<
"\")" << std::endl;
906 pymol_interface <<
"/" << posename_base_ <<
"//" << chain_char <<
"/" << resnum <<
"+" ;
907 first_sel_complete =
true;
909 else if (chain_char != chain_char_last){
910 interface_sele <<
"cmd.select(\"sele + /" << pymol_obj_for_interface_sel <<
"//" << chain_char <<
"/"
911 << resnum <<
"\")" << std::endl;
912 pymol_interface <<
" + "<<
"/" << posename_base_ <<
"//" << chain_char <<
"/" << resnum <<
"+";
915 interface_sele <<
"cmd.select(\"sele + /" << pymol_obj_for_interface_sel <<
"//" << chain_char <<
"/"
916 << resnum <<
"\")" << std::endl;
917 pymol_interface << resnum <<
"+";
919 chain_char_last = chain_char;
922 pymol_interface << std::endl;
923 interface_sele <<
"cmd.create(\"" << posename_base_ <<
"_interface_sel\", \"sele\")" << std::endl;
927 current_job->add_string( interface_oss.str() );
939 std::ostringstream results_oss, unsathbond_oss;
942 results <<
"Residues missing H-bonds:" << std::endl;
943 results <<
"Residue \t Chain \t Atom " << std::endl;
944 bool first_sel_complete(
false );
945 std::ostringstream missingHbond;
946 missingHbond << std::endl;
949 unsathbond <<
"pymol-style selection for unstat hbond res \n"
953 char chain_char, chain_char_last (
'z');
955 for(
core::Size i(1); i <= delta_unsat_hbond_atid_vector.size(); i++ ) {
957 resnum = pose.
pdb_info()->number(
id.rsd());
958 chain_char = pose.
pdb_info()->chain(
id.rsd() );
962 for (
unsigned int j = 0; j < atomname.length(); j++) {
963 if (atomname[j] !=
' ') { temp += atomname[j]; }
967 results << resnum <<
" \t " << chain_char <<
" \t "<< atomname << std::endl;
969 if( !first_sel_complete ) {
970 missingHbond <<
"cmd.select(\"/" << posename_base_ <<
"//" << chain_char <<
"/" << resnum <<
"/" << atomname <<
"\")"<< std::endl;
971 unsathbond <<
"/" << posename_base_ <<
"//" << chain_char <<
"/" << resnum <<
"+" ;
972 first_sel_complete =
true;
974 else if (chain_char != chain_char_last){
975 missingHbond <<
"cmd.select(\"sele + /" << posename_base_ <<
"//" << chain_char <<
"/" << resnum <<
"/" << atomname <<
"\")"<< std::endl;
976 unsathbond <<
" + "<<
"/" << posename_base_ <<
"//" << chain_char <<
"/" << resnum <<
"+";
979 missingHbond <<
"cmd.select(\"sele + /" << posename_base_ <<
"//" << chain_char <<
"/" << resnum <<
"/" << atomname <<
"\")"<< std::endl;
980 unsathbond << resnum <<
"+";
982 chain_char_last = chain_char;
984 unsathbond << std::endl;
986 missingHbond <<
"cmd.create(\"" << posename_base_ <<
"_unsat_hbond\", \"sele\")" << std::endl;
987 missingHbond <<
"cmd.show(\"spheres\", \"" << posename_base_ <<
"_unsat_hbond\")" << std::endl;
992 current_job->add_string( results_oss.str() );
993 current_job->add_string( unsathbond_oss.str() );
1003 std::ostringstream pymol_packing;
1004 pymol_packing << std::endl;
1007 pymol_packing <<
"cmd.create(\"" << pymol_object_fullpose_pack <<
"\", \"" <<
posename_base_ <<
"\")" << std::endl;
1012 char chain_char = pose.
pdb_info()->chain(i);
1014 if ( interface_pack_scores[i] >= 0.75 ) { color = 2; }
1015 else if ( interface_pack_scores[i] >= 0.50 ) { color = 16; }
1016 else if ( interface_pack_scores[i] >= 0.25 ) { color = 12; }
1017 else if ( interface_pack_scores[i] > 0.00 ) { color = 4; }
1018 else { color = 24; }
1020 pymol_packing <<
"cmd.select(\"/" << pymol_object_fullpose_pack <<
"//" << chain_char <<
"/" << resnum <<
"\")" << std::endl;
1021 pymol_packing <<
"cmd.color(" << color <<
", \"sele\")" << std::endl;
1033 using namespace core::pose::metrics;
1034 using namespace protocols::toolbox::pose_metric_calculators;
1036 std::ostringstream interface_jump_cast;
1038 std::string const ijump(interface_jump_cast.str());
1044 Sasa_ =
"Sasa_" + ijump;
1045 if( CalculatorFactory::Instance().check_calculator_exists(
Sasa_ ) ){
1046 Warning() <<
"In InterfaceAnalyzerMover, calculator " <<
Sasa_
1047 <<
" already exists, this is hopefully correct for your purposes" << std::endl;
1055 <<
" already exists, this is hopefully correct for your purposes" << std::endl;
1063 <<
" already exists, this is hopefully correct for your purposes" << std::endl;
1071 <<
" already exists, this is hopefully correct for your purposes" << std::endl;
1077 if( CalculatorFactory::Instance().check_calculator_exists(
NumberHBonds_ ) ){
1078 Warning() <<
"In InterfaceAnalyzerMover, calculator " <<
NumberHBonds_
1079 <<
" already exists, this is hopefully correct for your purposes" << std::endl;
1087 <<
" already exists, this is hopefully correct for your purposes" << std::endl;
1099 using namespace core::pose::metrics;
1100 using namespace protocols::toolbox::pose_metric_calculators;
1104 <<
" already exists, this is hopefully correct for your purposes" << std::endl;
1112 using namespace core::scoring;
1113 using namespace core;
1128 using namespace core::scoring::hbonds;
1129 using namespace core;
1130 using namespace core::chemical;
1142 atom_subset.
clear();
1147 atom_subset[ ii ][ jj ] =
true;
1181 new_sf->set_energy_method_options( energymethodoptions );
1191 hbond_set.setup_for_residue_pair_energies(pose,
false,
false);
1194 Real n_crosschain_hbonds( 0 );
1198 for(
Size ii=1; ii <= hbond_set.nhbonds(); ++ii){
1205 if( pose.
chain( don_resnum ) != pose.
chain( acc_resnum )){
1210 TR <<
"Found Hbond between chains: "<< pose.
chain( don_resnum ) <<
" and " << pose.
chain( acc_resnum ) <<std::endl;
1212 n_crosschain_hbonds += 1;
1257 if ( pose.
chain( hbond.don_res() ) != pose.
chain( hbond.acc_res() ) ) {
1258 n_crosschain_hbonds += 1;
1324 TR <<
"Computing Shape Complementarity Score..." << std::endl;
1325 TR <<
"Upstream chain(s) numbers: ";
1332 TR <<
"Downstream chain(s) numbers: ";
1349 using namespace core;
1353 using namespace core::pack::task;
1354 using namespace core::pack::task::operation;
1355 using namespace protocols::toolbox::task_operations;
1359 utility::vector1_bool packable(copy_complex.
total_residue(),
false);
1365 task->nonconst_residue_task( *it ).restrict_absent_canonical_aas(allowed_aa);
1366 packable[ *it ] =
true;
1368 task->restrict_to_residues(packable);
1371 TR<<
"GLY Packer Task: " << *(task) << std::endl;
1376 packrot_mover->apply ( copy_complex );
1377 packrot_mover->apply( copy_separate );
1378 gly_dG_ = (*sf_) ( copy_complex ) - (*
sf_) ( copy_separate ) ;
1395 TR <<
"Centroid score of complex: " << (*scorefxn) ( copy_complex ) << std::endl;
1396 TR <<
"Centroid score of separated: " << (*scorefxn) ( copy_separated ) << std::endl;
1398 centroid_dG_ = (*scorefxn) ( copy_complex ) - (*scorefxn ) ( copy_separated ) ;
1404 using namespace core::pack::task;
1405 using namespace core::pack::task::operation;
1406 using namespace protocols::toolbox::task_operations;
1419 calculators_used.push_back( multichain_strings );
1423 calculators_used.push_back( chain_strings );
1440 if ( tag->getName() !=
"InterfaceAnalyzerMover" ) {
1455 if (tag->hasOption(
"jump") && tag->hasOption(
"fixedchains"))
1457 throw utility::excn::EXCN_RosettaScriptsOption(
"Jump and fixedchains are mutually exclusive. Use either jump or fixedchains");
1459 if (tag->hasOption(
"fixedchains"))
1466 TR <<
"Fixed chains are: " ;
1467 for(
core::Size j = 1; j <= fixed_chains_string.size(); ++j){
1468 char this_chain (fixed_chains_string[ j ][0]);
1470 if (pose.
pdb_info()->chain( i ) == this_chain){
1475 TR << this_chain <<
", ";
1477 TR <<
"these will be moved together." << std::endl;