Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
InterfaceAnalyzerMover.cc
Go to the documentation of this file.
1 // -*- mode:c++;tab-width:2;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t -*-
2 // vi: set ts=2 noet:
3 //
4 // (c) Copyright Rosetta Commons Member Institutions.
5 // (c) This file is part of the Rosetta software suite and is made available under license.
6 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
7 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
8 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
9 
10 /// @file /protocols/analysis/InterfaceAnalyzerMover.cc
11 /// @brief InterfaceAnalyzerMover implementation - class for in-depth interface quality analysis
12 /// @author Steven Lewis, Bryan Der, Ben Stranges
13 
14 // Unit Headers
17 
18 // Project Headers
21 
25 #include <core/scoring/Energies.hh>
27 // AUTO-REMOVED #include <core/scoring/hbonds/hbonds.hh>
30 #include <core/scoring/sasa.hh>
32 //#include <core/scoring/Energies.hh>
33 //#include <core/scoring/EnergyMap.hh>
34 // AUTO-REMOVED #include <core/chemical/ChemicalManager.hh> //for centroid switch
35 
36 // AUTO-REMOVED #include <core/chemical/AtomTypeSet.hh>
37 // AUTO-REMOVED #include <core/chemical/AtomType.hh>
39 
40 #include <core/pose/Pose.hh>
41 #include <core/pose/PDBInfo.hh>
42 
46 
48 #include <protocols/jd2/Job.hh>
50 
52 
53 #include <basic/MetricValue.hh>
55 // AUTO-REMOVED #include <protocols/simple_moves/MutateResidue.hh>
64 
66 // AUTO-REMOVED #include <protocols/analysis/PackStatMover.hh>
68 // AUTO-REMOVED #include <basic/options/keys/run.OptionKeys.gen.hh>
69 // AUTO-REMOVED #include <basic/options/keys/in.OptionKeys.gen.hh>
70 // AUTO-REMOVED #include <basic/options/keys/packing.OptionKeys.gen.hh>
71 #include <basic/options/keys/packstat.OptionKeys.gen.hh>
72 
73 // AUTO-REMOVED #include <protocols/moves/DataMap.hh>
75 #include <utility/tag/Tag.hh>
76 
77 
78 // Utility Headers
79 #include <ObjexxFCL/FArray1D.hh> //necessary for fold tree tricks
80 #include <ObjexxFCL/FArray2D.hh>
81 #include <core/types.hh>
82 #include <basic/Tracer.hh>
83 //#include <utility/exit.hh>
84 #include <utility/file/FileName.hh>
85 #include <utility/string_util.hh>
86 
87 // C++ Headers
88 #include <sstream>
89 #include <set>
90 #include <string>
91 
93 #include <utility/vector0.hh>
94 #include <utility/vector1.hh>
95 
96 //Auto Headers
97 #include <utility/excn/Exceptions.hh>
99 using basic::T;
100 using basic::Error;
101 using basic::Warning;
102 
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");
106 
107 
108 
109 ///stupid helper function needed because ternary operator does not allow variable return types
110 std::ostream & which_ostream( std::ostream & ost, std::ostream & oss, bool const tracer){
111  if(tracer) return ost;
112  return oss;
113 }
114 
115 namespace protocols{
116 namespace analysis{
117 
118 using namespace protocols::moves;
119 
122 {
124 }
125 
128  return new InterfaceAnalyzerMover();
129 }
130 
133 {
134  return "InterfaceAnalyzerMover";
135 }
136 
137 ///////////////////////////////////////////////////////////////////////////////////////////////////////////
138 //////////////////////////InterfaceAnalyzerMover///////////////////////////////////////////////////////////
139 ///////////////////////////////////////////////////////////////////////////////////////////////////////////
141  core::Size interface_jump,
142  bool const tracer,
144  bool compute_packstat,
145  bool pack_input,
146  bool pack_separated,
147  bool use_jobname
148 ) :
149  Mover(),
150  interface_jump_(interface_jump),
151  sf_(sf),
152  chain1_(0),
153  chain2_(0),
154  tracer_(tracer),
155  calcs_ready_(false),
156  compute_packstat_(compute_packstat),
157  compute_interface_sc_(true), //would prefer a default of false
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),
167  use_resfile_(false),
168  use_centroid_(false),
169  ddG_(0),
170  total_sasa_(0),
171  interface_delta_sasa_(0),
172  n_interface_res_(0),
173  per_residue_energy_(0),
174  complex_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),
180  gly_dG_(0),
181  centroid_dG_(0),
182  delta_unsat_hbond_counter_(0),
183  //pymol_sel_interface_,
184  //pymol_sel_hbond_unsat_,
185  //pymol_sel_packing_,
186  side1_score_(0),
187  side2_score_(0),
188  nres_(0),
189  side1_nres_(0),
190  side2_nres_(0),
191  //hbond_exposure_ratio_(0),
192  //total_hb_sasa_(0),
193  total_hb_E_(0),
194  sc_value_(0.0),
195  task_(0)//,
196 {
197  protocols::moves::Mover::type( "InterfaceAnalyzer" );
198  upstream_chains_.insert(0);
199  downstream_chains_.insert(0);
200 }
201 
202 //Alternate constructor for multichain poses
203 //Takes a set of ints for the chain nums
205  std::set<int> fixed_chains,
206  bool const tracer,
208  bool compute_packstat,
209  bool pack_input,
210  bool pack_separated,
211  bool use_jobname
212 ) :
213  Mover(),
214  interface_jump_(0),
215  fixed_chains_(fixed_chains),
216  sf_(sf),
217  //posename_,
218  //posename_base_,
219  chain1_(0),
220  chain2_(0),
221  //chain1_char_;
222  //chain2_char_;
223  tracer_(tracer),
224  calcs_ready_(false),
225  compute_packstat_(compute_packstat),
226  compute_interface_sc_(true), //would prefer a default of false
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),
236  use_resfile_(false),
237  use_centroid_(false),
238  ddG_(0),
239  total_sasa_(0),
240  interface_delta_sasa_(0),
241  n_interface_res_(0),
242  per_residue_energy_(0),
243  complex_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),
249  gly_dG_(0),
250  centroid_dG_(0),
251  delta_unsat_hbond_counter_(0),
252  //pymol_sel_interface_,
253  //pymol_sel_hbond_unsat_,
254  //pymol_sel_packing_,
255  side1_score_(0),
256  side2_score_(0),
257  nres_(0),
258  side1_nres_(0),
259  side2_nres_(0),
260  //hbond_exposure_ratio_(0),
261  //total_hb_sasa_(0),
262  total_hb_E_(0),
263  sc_value_(0.0),
264  //interface_set_,
265  //chain_groups_,
266  task_(0)//,
267  //Sasa_,
268  //InterfaceNeighborDefinition_,
269  //InterfaceSasaDefinition_,
270  //InterfaceDeltaEnergetics_,
271  //NumberHBonds_,
272  //BuriedUnsatisfiedPolars_,
273  //InterGroupNeighborsCalculator_,
274 {
275  protocols::moves::Mover::type( "InterfaceAnalyzer" );
276  upstream_chains_.insert(0);
277  downstream_chains_.insert(0);
278 }
279 
280 
282 
283 core::Real InterfaceAnalyzerMover::get_interface_ddG() const {return ddG_; } //previous functionality: redundant with get_separated_interface_energy, but supports other protocols
284 
285 ///@details getters
308 //core::Real InterfaceAnalyzerMover::get_interface_Hbond_sasa() {return total_hb_sasa_; }
309 //core::Real InterfaceAnalyzerMover::get_Hbond_exposure_ratio() {return hbond_exposure_ratio_; }
311 
314 
315 ///@details setters
316 void InterfaceAnalyzerMover::set_use_resfile(bool const use_resfile) {use_resfile_ = use_resfile;}
317 void InterfaceAnalyzerMover::set_use_centroid_dG(bool const use_centroid) {use_centroid_ = use_centroid;}
318 void InterfaceAnalyzerMover::set_compute_packstat(bool const compute_packstat) {compute_packstat_ = compute_packstat;}
319 void InterfaceAnalyzerMover::set_pack_input(bool const pack_input) {pack_input_ = pack_input;}
320 void InterfaceAnalyzerMover::set_interface_jump(core::Size const interface_jump) {interface_jump_ = interface_jump;}
322 //void InterfaceAnalyzerMover::set_calcs_ready(bool const calcs_ready) {calcs_ready_ = calcs_ready;}
323 void InterfaceAnalyzerMover::set_use_jobname(bool const use_jobname) {use_jobname_ = use_jobname;}
324 void InterfaceAnalyzerMover::set_pack_separated(bool const pack_separated) {pack_separated_ = pack_separated;}
325 
326 
327 ///@details InterfaceAnalyzerMover computes various interface statistics and makes them available through getters
329 {
330  using namespace core;
331  if( pose.conformation().num_chains() < 2 ){
332  utility_exit_with_message_status( "InterfaceAnalyzerMover: pose has only one chain, aborting analysis \n", 1 );
333  //remaining code works for actual interfaces
334  }
335  //check for multichain poses
336  else if(pose.conformation().num_chains() > 2){
338  //fix the foldtree to reflect the fixed chains we want
339  core::Size newjump;
340  std::set< int > fixedchains( get_fixed_chains() );
341  newjump = reorder_foldtree_find_jump( pose, fixedchains );
342  interface_jump_ = newjump ;
343  set_pose_info( pose );
344  //need calculators to register here if not already around
345  //make_multichain_interface_set(pose, fixedchains);
346  if(!calcs_ready_){
348  calcs_ready_ = true;
349  }
350  }
351  //if multi chains with wrong constructor, work but print a warming
352  else{
353  TR<< "WARNING: more than 2 chains present w/o using the right constructor! Values might be over the wrong jump." << std::endl;
354  //sets up the pose for calculations
355  set_pose_info( pose );
356  //register calculators here if need be
357  if(!calcs_ready_){
359  calcs_ready_ = true;
360  }
361  }
362  }//end if greater than 2 chains
363 
364  //if only 2 chains
365  else {
366  //sets up the pose for calculations
367  set_pose_info( pose );
368  //register calculators here if need be
369  if(!calcs_ready_){
371  calcs_ready_ = true;
372  }
373  }// end if only two chains
374 
375  //setup an interface set
376  if(interface_set_.empty()) //should always be empty at this point
377  make_interface_set(pose);
378  //set up the packer task for later
379  setup_task(pose);
380  //init compexed and separated pose objects
381  core::pose::Pose complexed_pose( pose );
382  core::pose::Pose separated_pose( make_separated_pose( complexed_pose ) );
383  //actual computation here
384  if(compute_separated_sasa_) compute_separated_sasa( complexed_pose, separated_pose );
385  if(compute_interface_energy_) compute_interface_energy( complexed_pose, separated_pose );
386  //mut_to_gly(complexed_pose, separated_pose ); this didn't help
387  if(use_centroid_) calc_centroid_dG( complexed_pose, separated_pose );
388  if(calc_hbond_sasaE_) calc_hbond_sasaE( complexed_pose ); //get hbond E at interface
389  if( compute_packstat_) compute_interface_packstat( complexed_pose );
390  //find the change in interface hbonds
392  //find the shape complementarity stats for the interface
394 
395  if( !skip_reporting_ ){
396  //always will fill a selection option to get the pymol selection
398 
399  //report to tracer or job all this cool stuff we calculated
400  report_data();
401  }
402 
403  //why on earth are we deleting this set? Nobody can use it if we delete it... SML 11/2/12
404  // //get the interface set again setup some output and clear it.
405  // if( ! (interface_set_.empty()) ){
406  // //TR << "Total interface residues for " << posename_base_ << ": " << interface_set_.size() << std::endl;
407  // //clear any old values before return
408  // interface_set_.clear();
409  // //set_interface_set( interface_set_ );
410  // }
411 
412 
413  return;
414 }//end apply
415 
418  return "InterfaceAnalyzerMover";
419 }
420 
421 ///@details sets up the pose information such as the name and chain ids
423  if( use_jobname_ ){
426  }
427  else {
428  posename_ = pose.pdb_info()->name();
429  posename_base_ = posename_.base();
430  }
431 
434  chain1_char_ = pose.pdb_info()->chain(pose.conformation().chain_end(chain1_));
435  chain2_char_ = pose.pdb_info()->chain(pose.conformation().chain_end(chain2_));
436  //set here_ will be later replaced by multichain constructor if need be
437  upstream_chains_.clear();
438  downstream_chains_.clear();
439  upstream_chains_.insert(chain1_);
440  downstream_chains_.insert( chain2_);
441 }
442 
443 ///@details makes the interface sets for either constructor
444 //always will make a new interface set, make sure this is what you want
448  }
449  //std::set< core::Size > interface_set ( get_interface_set() );
450  else {
451  TR << "Making an interface set with default calculator." << std::endl;
452  basic::MetricValue< std::set< core::Size > > mv_interface_set;
453  pose.metric(InterfaceNeighborDefinition_, "interface_residues", mv_interface_set);
454  interface_set_ = mv_interface_set.value();
455  //set_interface_set( interface_set_ );
456  }
457  if ( interface_set_.empty() )
458  TR << "NO INTERFACE FOR: " << posename_base_ << std::endl;
459 }
460 
461 ///@details reorder the fold tree to allow multichain interfaces to be evaluated returns the new chain for the jump
463  std::set<int> & fixed_chains){
464  using namespace core;
466  core::Size mobile_jump(1); //setup, will be changed later
467  if(fixed_chains.empty())
468  utility_exit_with_message_status( "Can't find fixed chains. Exiting...\n", 1 );
469  //now get info about chains
470  Size numchains ( pose.conformation().num_chains() );
471  utility::vector1<Size> chain_starts;
472  utility::vector1<Size> chain_ends;
473  for(Size ii = 1; ii<= numchains; ++ii){
474  chain_starts.push_back( pose.conformation().chain_begin( ii ) );
475  chain_ends.push_back( pose.conformation().chain_end( ii ) );
476  }
477 
478  //find a non mobile chain
479  Size anchor_chain (1); //switch later if needed
480  for(Size ii = 1; ii<= numchains; ++ii){
481  if ( !fixed_chains.count( ii ) ){
482  anchor_chain = ii;
483  break;
484  }
485  }
486 
487  //now build our fold tree
488  //this will move the mobile chains together
489  kinematics::FoldTree foldtree (pose.fold_tree());
490  Size this_jump(1);
491  foldtree.clear();
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 ){ //not in the first mobile chain
497  foldtree.add_edge( Edge(chain_starts[ii], chain_ends[*(fixed_chains.begin())], this_jump) );
498  }
499  else if ( fixed_chains.count(ii) ){ //ie in the first mobile chain
500  foldtree.add_edge( Edge(chain_starts[ii], chain_ends[anchor_chain], this_jump) );
501  mobile_jump = this_jump; //sets this jump to be the new mobile one
502  previous_mobile=true;
503  }
504  else foldtree.add_edge( Edge(chain_starts[ii], chain_ends[anchor_chain], this_jump) );
505  ++this_jump;
506  }
507  }
508  //now set all the new values!
509  foldtree.reorder(chain_starts[anchor_chain]);
510  pose.fold_tree(foldtree);
511  //TR << "Remade foldtree:\n"<< foldtree << std::endl;
512 
513  return mobile_jump;
514 
515 }//end reorder foldtree
516 
517 // sets the interface set for a multichain pose
518 // uses everything in the fixed chains as one side, everything else is the other side
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;
526  //itterate over all residues determine what part of the interface they are
527  //also select what chain(s) are upstream and downstream of the interface
528  for( Size ii = 1; ii<= pose.total_residue(); ++ii){
529  if( fixed_chains.count( pose.chain( ii ) ) ){
530  fixed_side_residues.insert( ii );
531  fixed_chain_nums.insert( pose.chain( ii ) );
532  }
533  else{
534  other_side_residues.insert( ii );
535  other_chain_nums.insert( pose.chain( ii ) );
536  }
537  }
538  //now assign the correct chains
539  upstream_chains_ = fixed_chain_nums;
540  downstream_chains_= other_chain_nums;
541  //debugging
542  //TR << "Fixed residues: " << fixed_side_residues.size() << " Other side residues: " << other_side_residues.size() << std::endl;
543 
544  //prep a vector of a pair of these residue sets for Steven's calculator
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;
548  InterfaceAnalyzerMover::group_set interface_deffinition_vector;
549  interface_deffinition_vector.push_back( side_pairs );
550  chain_groups_ = interface_deffinition_vector ;
551 
552  //get calculator for multichain poses
554 
555  //std::set<Size> multichain_interface;
556  basic::MetricValue< std::set<Size> > mv_interface_set;
557  pose.metric( InterGroupNeighborsCalculator_, "neighbors", mv_interface_set);
558  //set_interface_set( mv_interface_set.value() );
559  interface_set_ = mv_interface_set.value();
560  //debugging
561  //TR << "Interface set residues total: " << interface_set_.size() << std::endl;
562 
563 }//end make_multichain_interface_set
564 
565 
566 ///@details makes the complexed and separated poses for the mover
568  using namespace core;
569 
570  if(!sf_) {
571  TR << "NULL scorefunction. Initialize from cmd line." << std::endl;
572  using namespace core::scoring;
573  sf_ = getScoreFunction();
574  }
575  (*sf_)(pose); //shits, giggles, and segfault prevention
576  //complexed_pose_ = pose;
577  pose::Pose separated_pose( pose );
579  translate->step_size( 1000.0 );
580  translate->apply( separated_pose );
581  (*sf_)(separated_pose);
582  //debugging step to make sure the jump is right
583  //separated_pose_.dump_pdb("IAM_test.pdb");
584  return separated_pose;
585 }
586 
587 
588 ///@details computes the SASA by finding difference between complex and separated SASA
589 /// also does the same thing for hydrophobic/polar SASA
591  core::pose::Pose & separated_pose){
592  using namespace core;
593  basic::MetricValue< core::Real > mv_complex_sasa;
594  basic::MetricValue< core::Real > mv_separated_sasa;
595 
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() );
600  total_sasa_ = total_sasa_value ;
601  interface_delta_sasa_ = separated_sasa_value - total_sasa_value ;
602 
603  //need to get the hydrophobic sasa at the interface, only need to subtract them
604  utility::vector1< core::Real > complexed_residue_sasa( complexed_pose.total_residue(), 0.0 );
605  utility::vector1< core::Real > separated_residue_sasa( separated_pose.total_residue(), 0.0 );
606  utility::vector1< core::Real > complexed_residue_hsasa( complexed_pose.total_residue(), 0.0 ); // hydrophobic SASA only
607  utility::vector1< core::Real > separated_residue_hsasa( separated_pose.total_residue(), 0.0 ); // hydrophobic SASA only
608  core::Real probe_radius = basic::options::option[basic::options::OptionKeys::pose_metrics::sasa_calculator_probe_radius];
609  core::Real complexed_hSASA = core::scoring::calc_per_res_hydrophobic_sasa( complexed_pose, complexed_residue_sasa,
610  complexed_residue_hsasa, probe_radius,
611  false /*no n_acccess_radii*/ );
612  core::Real separated_hSASA = core::scoring::calc_per_res_hydrophobic_sasa( separated_pose, separated_residue_sasa,
613  separated_residue_hsasa, probe_radius,
614  false /*no n_acccess_radii*/ );
615 
616  //Now assume anything that isn't hydrophobic is polar
617  interface_hsasa_ = separated_hSASA - complexed_hSASA;
619  return;
620 }
621 
622 
623 ///@details computes the interface energy of the interface
625  core::pose::Pose & separated_pose )
626 {
627  //separated interface energy and ratio
628  score_separated_chains(complexed_pose, separated_pose); //sets separated_interface_energy_
630  calc_per_residue_energy( complexed_pose ); //find avg residue E at interface
631  //crossterm interface energy and ratio
632  basic::MetricValue< core::Real > mv_delta_total;
633  complexed_pose.metric(InterfaceDeltaEnergetics_, "weighted_total", mv_delta_total);
634  crossterm_interface_energy_ = mv_delta_total.value() ;
636 
637  // Get the first and last resnum of each chain, using name_of_InterfaceNeighborDefinitionCalculator_
638  basic::MetricValue<Size> mv_size;
639  separated_pose.metric(InterfaceNeighborDefinition_,"first_chain_first_resnum",mv_size);
640  core::Size ch1_begin_num = mv_size.value();
641  separated_pose.metric(InterfaceNeighborDefinition_,"first_chain_last_resnum",mv_size);
642  core::Size ch1_end_num = mv_size.value();
643  separated_pose.metric(InterfaceNeighborDefinition_,"second_chain_first_resnum",mv_size);
644  core::Size ch2_begin_num = mv_size.value();
645  separated_pose.metric(InterfaceNeighborDefinition_,"second_chain_last_resnum",mv_size);
646  core::Size ch2_end_num = mv_size.value();
647 
648  side1_score_ = 0;
649  side1_nres_ = ch1_end_num - ch1_begin_num+1;
650  for( core::Size i(ch1_begin_num); i<= ch1_end_num; ++i) {
651  side1_score_ += separated_pose.energies().residue_total_energy(i);
652  }
653 
654  side2_score_ = 0;
655  side2_nres_ = ch2_end_num - ch2_begin_num+1;
656  for( core::Size i(ch2_begin_num); i<= ch2_end_num; ++i) {
657  side2_score_ += separated_pose.energies().residue_total_energy(i);
658  }
659 
660  nres_ = complexed_pose.total_residue();
661 
662  return;
663 }
664 ///@details actual function to separate the chains based on the chosen jump and score
666  core::pose::Pose & separated_pose ){
667  //using namespace core::pack::task;
668  using namespace basic::options;
669  using namespace basic::options::OptionKeys;
670  using namespace protocols::moves;
671 
672  //core::pose::Pose copy(pose);
673  //PackerTaskOP const task( get_packer_task() );
674  //we know there is a score function from above
675  core::Real complex_score( (*sf_)(complexed_pose) );
676  core::Real separated_score( (*sf_)(separated_pose) );
677  complex_energy_ = complex_score ;
678 
679  // TR<< "Initial complex_score: " << complex_score << " sep_score: "
680  // << separated_score << std::endl;
681 
682  //setup mover to pack interface
683  //core::Size ndruns = option[packing::ndruns];
685 
686  //do we pack the complex?
687  if ( pack_input_ ){
688  repacker->apply(complexed_pose);
689  complex_score = (*sf_)(complexed_pose);
690  complex_energy_ = complex_score ;
691  }
692  //do we pack the separated pose
693  if (pack_separated_){
694  repacker->apply( separated_pose );
695  separated_score = (*sf_)(separated_pose) ;
696  }
697  //debugging step to make sure the jump is right
698  //copy.dump_pdb("IAM_test.pdb");
699  // TR<< "Post Packing complex_score: " << complex_score << " sep_score: "
700  // << separated_score << std::endl;
701  ddG_ = complex_score - separated_score;
702  separated_interface_energy_ = ddG_ ; //these are the same thing
703 }
704 
705 ///@details reports all the cool stuff we calculate to tracer output OR puts it into the job object.
707  //make output
709  //std::string const posename(protocols::jd2::JobDistributor::get_instance()->job_outputter()->output_name( current_job ) );
710  //std::ostringstream results_oss;
711  //std::ostream & results = which_ostream(T(posename_base_), results_oss, tracer_); //easy swap between tracer/job output
712 
713  //std::ostringstream interface_sele, missingHbond;
714 
715  //set up what data is reported in a string stream
716  //report to job
717  if (tracer_){
718  //TR<<"Debugging print interface info:" << std::endl;
719  T(posename_base_) << "TOTAL SASA: " << total_sasa_ << std::endl;
720  T(posename_base_) << "NUMBER OF RESIDUES: " << n_interface_res_ << std::endl;
721  T(posename_base_) << "AVG RESIDUE ENERGY: " << per_residue_energy_ << std::endl;
722  T(posename_base_) << "INTERFACE DELTA SASA: " << interface_delta_sasa_ << std::endl;
723  T(posename_base_) << "INTERFACE HYDROPHOBIC SASA: " << interface_hsasa_ << std::endl;
724  T(posename_base_) << "INTERFACE POLAR SASA: " << interface_polar_sasa_ << std::endl;
725  T(posename_base_) << "CROSS-INTERFACE ENERGY SUMS: " << crossterm_interface_energy_ << std::endl;
726  T(posename_base_) << "SEPARATED INTERFACE ENERGY DIFFERENCE: " << separated_interface_energy_ << std::endl;
727  T(posename_base_) << "INTERFACE DELTA SASA/CROSS-INTERFACE ENERGY: " << crossterm_interface_energy_ratio_ << std::endl;
728  T(posename_base_) << "INTERFACE DELTA SASA/SEPARATED INTERFACE ENERGY: " << separated_interface_energy_ratio_ << std::endl;
729  T(posename_base_) << "DELTA UNSTAT HBONDS: " << delta_unsat_hbond_counter_ << std::endl;
730  //T(posename_base_) << "ALL Gly INTERFACE ENERGY: " << gly_dG_ << std::endl; does not help
731  if(use_centroid_)
732  T(posename_base_) << "CENTORID dG: " << centroid_dG_ << std::endl;
733  //T(posename_base_) << "AVG HBOND EXPOSURE RATIO: " << hbond_exposure_ratio_ << std::endl; does not help
734  //T(posename_base_) << "HBOND SASA / INTERFACE dSASA: " << total_hb_sasa_ / interface_delta_sasa_ << std::endl;
735  T(posename_base_) << "HBOND ENERGY: " << total_hb_E_ << std::endl;
736  T(posename_base_) << "HBOND ENERGY/ SEPARATED INTERFACE ENERGY: " << total_hb_E_ / separated_interface_energy_ << std::endl;
737  if (compute_packstat_)
738  T(posename_base_) << "INTERFACE PACK STAT: " << interface_packstat_ << std::endl;
740  T(posename_base_) << "SHAPE COMPLEMENTARITY VALUE: " << sc_value_ << std::endl;
741  //results << pymol_sel_interface_;
742  // results << pymol_sel_hbond_unsat_;
743  //if(compute_packstat_)
744  // results << pymol_sel_packing_;
745 
746  }
747  //or report to job
748  else{
749  current_job->add_string_real_pair("dSASA_int", interface_delta_sasa_);
750  current_job->add_string_real_pair("dSASA_polar", interface_polar_sasa_);
751  current_job->add_string_real_pair("dSASA_hphobic", interface_hsasa_);
752  current_job->add_string_real_pair("dG_separated", separated_interface_energy_);
753  current_job->add_string_real_pair("dG_separated/dSASAx100", separated_interface_energy_ratio_*100.0 );//purpose of 1000 is to move decimal point to make more significant digits appear in fixed-precision scorefile (0.022 is only 2 digits, 2.234 is more useful)
754  current_job->add_string_real_pair("delta_unsatHbonds", delta_unsat_hbond_counter_ );
755  current_job->add_string_real_pair("packstat", interface_packstat_ );
756  current_job->add_string_real_pair("dG_cross", crossterm_interface_energy_ );
757  current_job->add_string_real_pair("dG_cross/dSASAx100", crossterm_interface_energy_ratio_*100.0);//as above
758  //current_job->add_string_real_pair("AllGly_dG", gly_dG_ ); does not help
759  if(use_centroid_)
760  current_job->add_string_real_pair("cen_dG", centroid_dG_ );
761  current_job->add_string_real_pair("nres_int", n_interface_res_ );
762  current_job->add_string_real_pair("per_residue_energy_int", per_residue_energy_ );
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_ );
766  current_job->add_string_real_pair("side1_normalized", (side1_score_/(core::Real(side1_nres_))) );
767  current_job->add_string_real_pair("side2_normalized", (side2_score_/(core::Real(side2_nres_))) );
768  current_job->add_string_real_pair("complex_normalized", complex_energy_/(core::Real(nres_)) );
769  current_job->add_string_real_pair("hbond_E_fraction", total_hb_E_/separated_interface_energy_);
770  current_job->add_string_real_pair("sc_value", sc_value_);
771 
772  }
773 
774 }
775 
776 ///@details Averaged packstat of interface residues only
778 {
779 
780  TR << "Computing interface packstats." << std::endl;
781  //check if there is already an interface set, if so use it, if not, make own
782  //will make own using the basic calculator
783  //std::set< core::Size > interface_set ( get_interface_set() );
784  if( interface_set_.empty() )
785  make_interface_set( pose );
786 
787  //calculates the packstat scores for the interface set
788  utility::vector1< core::Real > interface_pack_scores;
789  core::Real interface_pack_score_sum (0.0);
790  core::Size interface_num_res (0);
791  interface_pack_scores = core::scoring::packstat::compute_residue_packing_scores( pose, basic::options::option[ basic::options::OptionKeys::packstat::oversample ]() );
792 
793  for( std::set< Size >::const_iterator it( interface_set_.begin() ), end( interface_set_.end());
794  it != end; ++it){
795  interface_pack_score_sum += interface_pack_scores[*it];
796  ++interface_num_res;
797  }
798  //fills the selection for pymol output, doesn't print anything here
799  print_pymol_selection_of_packing( pose, interface_pack_scores );
800  interface_packstat_ = interface_pack_score_sum / interface_num_res ;
801 }
802 
803 ///@details If a polar atom at the interface is also "buried unsat" in the monomer, we don't count this one
805  core::pose::Pose & separated_pose)
806 {
807 
808  //already should be an interface set but check anyway
809  if(interface_set_.empty() )
810  make_interface_set(complexed_pose);
811  //do the calculations
812  TR << "Computing delta unsat polar residues..." << std::endl;
813 
814 
815  //core::pose::Pose complexed_pose_(pose);
816  //core::pose::Pose separated_pose_(pose);
817  //protocols::rigid::RigidBodyTransMoverOP translate( new protocols::rigid::RigidBodyTransMover( separated_pose_, interface_jump_ ) );
818  //translate->step_size( 1000.0 );
819  //translate->apply( separated_pose_ );
820 
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;
825 
826  complexed_pose.metric(BuriedUnsatisfiedPolars_, "residue_bur_unsat_polars", mv_complexed_unsat_res);
827  separated_pose.metric(BuriedUnsatisfiedPolars_, "residue_bur_unsat_polars", mv_separated_unsat_res);
828  utility::vector1< core::Size > const complexed_unsat_res(mv_complexed_unsat_res.value());
829  utility::vector1< core::Size > const separated_unsat_res(mv_separated_unsat_res.value());
830 
831  complexed_pose.metric(BuriedUnsatisfiedPolars_, "atom_bur_unsat", mv_complexed_unsat_map);
832  separated_pose.metric(BuriedUnsatisfiedPolars_, "atom_bur_unsat", mv_separated_unsat_map);
833  core::id::AtomID_Map< bool > const complexed_unsat_map(mv_complexed_unsat_map.value());
834  core::id::AtomID_Map< bool > const separated_unsat_map(mv_separated_unsat_map.value());
835 
836  //loop over the interface set and figure out what's burried/unsat
837  core::Size delta_unsat_hbond_counter( 0 );
838  utility::vector1< core::id::AtomID > delta_unsat_hbond_atid_vector;
839  for( std::set< core::Size >::const_iterator it(interface_set_.begin()), end(interface_set_.end());
840  it != end; ++it){
841  //TR << "UnsatHbond res " << *it << std::endl;
842  //iterate over all its atoms, check if they're in the map of missing, and print their string name
843  core::chemical::ResidueType const & res(complexed_pose.residue_type(*it));
844  for( core::Size i=1 ; i <= res.natoms(); ++i ){
845  core::id::AtomID const atid(i, *it);
846 
847  //TR << "UnsatHbond atom " << i << std::endl;
848 
849  //if atom is buried unsat in complexed pose but not separated pose, count it as delta unsat
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) );
852 
853  if( unsat_complex && !unsat_separated ) {
854  //results << " " << res.atom_name(i) ;
855  delta_unsat_hbond_atid_vector.push_back(atid);
856  ++delta_unsat_hbond_counter;
857  }
858  }//end for each atom
859  }//end loop of interface_set_
860 
861  delta_unsat_hbond_counter_ = delta_unsat_hbond_counter ; //sets the total
862  //print_pymol_selection_of_interface_residues( pose, interface_set_);
863  //calculated here but need to call get the selection to output it
864  print_pymol_selection_of_hbond_unsat( complexed_pose, delta_unsat_hbond_atid_vector );
865 
866  return;
867 }
868 
869 
870 ///@details prints tracer output of pymol selction of interface residues, also builds a pymol selection that can be used from a file.
871 void InterfaceAnalyzerMover::print_pymol_selection_of_interface_residues( core::pose::Pose const & pose, std::set< core::Size > const interface_set )
872 {
873 
874  //make output
876  //for tracer or job output
877  std::ostringstream interface_oss;
878  std::ostream & pymol_interface = which_ostream(TRinterface, interface_oss, tracer_);
879 
880  //setup naming of pymol objects
881  std::ostringstream interface_sele;
882  interface_sele << std::endl;
883  std::string pymol_obj_for_interface_sel;
884  if( compute_packstat_ ) {
885  pymol_obj_for_interface_sel = posename_base_ + "_fullpose_pack";
886  }
887  else {
888  pymol_obj_for_interface_sel = posename_base_;
889  }
890  //setup the tracer output
891  pymol_interface << "pymol-style selection for interface res \n"
892  << "select " << posename_base_ << "_interface, ";
893  //itterate through the interface set and build the selection syntaxt
894  bool first_sel_complete( false );
895  core::Size resnum;
896  char chain_char, chain_char_last('z');
897  for( std::set< core::Size >::const_iterator it(interface_set.begin()), end(interface_set.end());
898  it != end; ++it){
899  //sets the current values
900  resnum = pose.pdb_info()->number(*it);
901  chain_char = pose.pdb_info()->chain(*it);
902  //special print if the first time through
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;
908  }
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 << "+";
913  }
914  else {
915  interface_sele << "cmd.select(\"sele + /" << pymol_obj_for_interface_sel << "//" << chain_char << "/"
916  << resnum << "\")" << std::endl;
917  pymol_interface << resnum << "+";
918  }
919  chain_char_last = chain_char;
920  } //end itterate over interface
921  //finish up
922  pymol_interface << std::endl;
923  interface_sele << "cmd.create(\"" << posename_base_ << "_interface_sel\", \"sele\")" << std::endl;
924  pymol_sel_interface_ = interface_sele.str() ;
925  //job output if wanted
926  if(!tracer_)
927  current_job->add_string( interface_oss.str() );
928  return;
929 
930 }//end
931 
932 
933 ///@details This function reports a few things: a pymol sytle selection of the unstat atoms and reports to the tracer or job what these atoms are. The app InterfaceAnalyzer gets the multi-line string to write a file or print the selection. Unsat hbonds to be shown as Spheres
935 {
936  //make output
938  //for tracer or job output
939  std::ostringstream results_oss, unsathbond_oss;
940  std::ostream & results = which_ostream(T(posename_base_), results_oss, tracer_); //easy swap between tracer/job output
941  std::ostream & unsathbond = which_ostream(TRhbonds, unsathbond_oss, tracer_);
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; // for pymol selection
946  missingHbond << std::endl;
947 
948  //setup the tracer output
949  unsathbond << "pymol-style selection for unstat hbond res \n"
950  << "select " << posename_base_ << "_unsat, ";
951  //setup for looping over all unstat hbonds
952  core::Size resnum;
953  char chain_char, chain_char_last ('z');
954  std::string atomname ;
955  for( core::Size i(1); i <= delta_unsat_hbond_atid_vector.size(); i++ ) {
956  core::id::AtomID const id ( delta_unsat_hbond_atid_vector[ i ] );
957  resnum = pose.pdb_info()->number(id.rsd());
958  chain_char = pose.pdb_info()->chain( id.rsd() );
959  atomname = pose.residue(id.rsd()).atom_name(id.atomno());
960  //get rid of whitespace in the atomname
961  std::string temp;
962  for (unsigned int j = 0; j < atomname.length(); j++) {
963  if (atomname[j] != ' ') { temp += atomname[j]; }
964  }
965  atomname = temp;
966  //do the tracer/job output
967  results << resnum << " \t " << chain_char << " \t "<< atomname << std::endl;
968  //now setup pymol output
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;
973  }
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 << "+";
977  }
978  else {
979  missingHbond << "cmd.select(\"sele + /" << posename_base_ << "//" << chain_char << "/" << resnum << "/" << atomname << "\")"<< std::endl;
980  unsathbond << resnum << "+";
981  }
982  chain_char_last = chain_char;
983  } //end itterate over all unsat AtomIDs
984  unsathbond << std::endl;
985  //finalize output
986  missingHbond << "cmd.create(\"" << posename_base_ << "_unsat_hbond\", \"sele\")" << std::endl;
987  missingHbond << "cmd.show(\"spheres\", \"" << posename_base_ << "_unsat_hbond\")" << std::endl;
988  pymol_sel_hbond_unsat_ = missingHbond.str() ;
989 
990  //if we're not doing tracer output report this stuff to the job
991  if(!tracer_){
992  current_job->add_string( results_oss.str() );
993  current_job->add_string( unsathbond_oss.str() );
994  }
995 
996  return;
997 }
998 
999 
1000 ///@details This function doesn't do the printing itself. The app InterfaceAnalyzer gets the multi-line string to write a file or print the selection
1001 ///@details From best packing to worse packing, colors go as Blue, Purple, Pink, Red
1003  std::ostringstream pymol_packing;
1004  pymol_packing << std::endl;
1005 
1006  std::string pymol_object_fullpose_pack = posename_base_ + "_fullpose_pack";
1007  pymol_packing << "cmd.create(\"" << pymol_object_fullpose_pack << "\", \"" << posename_base_ << "\")" << std::endl;
1008 
1009  ///////////////////////////////////////////// WHOLE POSE COLOR BY PACKING /////////////////////
1010  for( core::Size i(1); i <= pose.total_residue(); i++ ) {
1011  core::Size resnum = pose.pdb_info()->number(i);
1012  char chain_char = pose.pdb_info()->chain(i);
1013  core::Size color;
1014  if ( interface_pack_scores[i] >= 0.75 ) { color = 2; } //blue
1015  else if ( interface_pack_scores[i] >= 0.50 ) { color = 16; } //purple
1016  else if ( interface_pack_scores[i] >= 0.25 ) { color = 12; } //pink
1017  else if ( interface_pack_scores[i] > 0.00 ) { color = 4; } //red
1018  else { color = 24; } //gray, something went wrong
1019 
1020  pymol_packing << "cmd.select(\"/" << pymol_object_fullpose_pack << "//" << chain_char << "/" << resnum << "\")" << std::endl;
1021  pymol_packing << "cmd.color(" << color << ", \"sele\")" << std::endl;
1022  }
1023 
1024  pymol_sel_packing_ = pymol_packing.str() ;
1025 
1026  return;
1027 }
1028 
1029 
1030 ///@detail Only want to register the calculators once, thus the 'if' statement in apply
1032 {
1033  using namespace core::pose::metrics;
1034  using namespace protocols::toolbox::pose_metric_calculators;
1035  //determine name
1036  std::ostringstream interface_jump_cast;
1037  interface_jump_cast << interface_jump_;
1038  std::string const ijump(interface_jump_cast.str());
1039 
1040 
1041  //TR << "Running register_calculators" << std::endl;
1042 
1043  //this sucks but I can't figure out a way to iterate...
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;
1048  } else {
1049  CalculatorFactory::Instance().register_calculator( Sasa_, new core::pose::metrics::simple_calculators::SasaCalculator);
1050  }
1051 
1052  InterfaceNeighborDefinition_ = "InterfaceNeighborDefinition_" + ijump;
1053  if( CalculatorFactory::Instance().check_calculator_exists( InterfaceNeighborDefinition_ ) ){
1054  Warning() << "In InterfaceAnalyzerMover, calculator " << InterfaceNeighborDefinition_
1055  << " already exists, this is hopefully correct for your purposes" << std::endl;
1056  } else {
1058  }
1059 
1060  InterfaceSasaDefinition_ = "InterfaceSasaDefinition_" + ijump;
1061  if( CalculatorFactory::Instance().check_calculator_exists( InterfaceSasaDefinition_ ) ){
1062  Warning() << "In InterfaceAnalyzerMover, calculator " << InterfaceSasaDefinition_
1063  << " already exists, this is hopefully correct for your purposes" << std::endl;
1064  } else {
1066  }
1067 
1068  InterfaceDeltaEnergetics_ = "InterfaceDeltaEnergetics_" + ijump;
1069  if( CalculatorFactory::Instance().check_calculator_exists( InterfaceDeltaEnergetics_ ) ){
1070  Warning() << "In InterfaceAnalyzerMover, calculator " << InterfaceDeltaEnergetics_
1071  << " already exists, this is hopefully correct for your purposes" << std::endl;
1072  } else {
1074  }
1075 
1076  NumberHBonds_ = "NumberHBonds_" + ijump;
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;
1080  } else {
1081  CalculatorFactory::Instance().register_calculator( NumberHBonds_, new NumberHBondsCalculator);
1082  }
1083 
1084  BuriedUnsatisfiedPolars_ = "BuriedUnsatisfiedPolars_" + ijump;
1085  if( CalculatorFactory::Instance().check_calculator_exists( BuriedUnsatisfiedPolars_ ) ){
1086  Warning() << "In InterfaceAnalyzerMover, calculator " << BuriedUnsatisfiedPolars_
1087  << " already exists, this is hopefully correct for your purposes" << std::endl;
1088  } else {
1089  CalculatorFactory::Instance().register_calculator( BuriedUnsatisfiedPolars_, new BuriedUnsatisfiedPolarsCalculator(Sasa_, NumberHBonds_));
1090  }
1091 
1092 
1093 
1094  return;
1095 }//register_calculators
1096 
1097 ///@detail register calculator for multichain poses
1099  using namespace core::pose::metrics;
1100  using namespace protocols::toolbox::pose_metric_calculators;
1101  InterGroupNeighborsCalculator_ = "InterGroupNeighborsCalculator_" + posename_base_ ;
1102  if( CalculatorFactory::Instance().check_calculator_exists( InterGroupNeighborsCalculator_ ) ){
1103  Warning() << "In InterfaceAnalyzerMover, calculator " << InterGroupNeighborsCalculator_
1104  << " already exists, this is hopefully correct for your purposes" << std::endl;
1105  } else {
1106  CalculatorFactory::Instance().register_calculator( InterGroupNeighborsCalculator_, new InterGroupNeighborsCalculator(chain_groups_, basic::options::option[basic::options::OptionKeys::pose_metrics::inter_group_neighbors_cutoff] ) );
1107  }
1108 }
1109 
1110 ///@details calculate the average energy per residue in the interface
1112  using namespace core::scoring;
1113  using namespace core;
1114  //using namespace core::scoring::Energies;
1115  //pose.update_residue_neighbors();
1116  (*sf_) (pose); //shits, giggles, and segfault prevention
1117  //itterate over all residues calc total energy for each then take avg
1118  core::Real total= 0.0;
1119  for( std::set< core::Size >::const_iterator it(interface_set_.begin()), end(interface_set_.end());
1120  it != end; ++it){
1121  total+=pose.energies().residue_total_energies( *it )[ ScoreType( total_score ) ];
1122  }
1123  per_residue_energy_ = ( total / interface_set_.size() );
1125 }
1126 ///@details calculate the hbond energy and dampen it by exposure
1128  using namespace core::scoring::hbonds;
1129  using namespace core;
1130  using namespace core::chemical;
1131  (*sf_) (pose); //shits, giggles, and segfault prevention
1132  //calculate the per atom sasa
1133  // an atomID map is needed for the calc_per_atom_sasa method; it stores the actual calculated sasa for every atom
1134  //core::id::AtomID_Map< core::Real > atom_sasa;
1135  //core::pose::initialize_atomid_map( atom_sasa, pose, (core::Real)0.0 ); // initialize to 0.0 for "not computed"
1136 
1137  //utility::vector1< Real > rsd_sasa( pose.total_residue(), 0.0 );
1138  //core::Real probe_radius = basic::options::option[basic::options::OptionKeys::pose_metrics::sasa_calculator_probe_radius];
1139 
1140  // create an atom_subset mask such that only the heavy atoms will have their sasa computed (ignore H's to make it faster)
1141  core::id::AtomID_Map< bool > atom_subset;
1142  atom_subset.clear();
1143  atom_subset.resize( pose.n_residue() );
1144  for ( Size ii=1; ii <= pose.n_residue(); ++ii ) {
1145  atom_subset.resize( ii, pose.residue_type(ii).natoms(), false );
1146  for ( Size jj = 1; jj <= pose.residue_type(ii).nheavyatoms(); ++jj ) {
1147  atom_subset[ ii ][ jj ] = true;
1148  }
1149  }
1150  //now actually calculate the SASA for heavy atoms only
1151  // core::Real total_sasa = 0.0;
1152  // total_sasa = core::scoring::calc_per_atom_sasa( pose, atom_sasa, rsd_sasa, probe_radius, false /* no big polar H */, atom_subset );
1153  // //some tracer output to make sure things work
1154  // for ( core::Size ii=1; ii <= pose.total_residue(); ++ii ) {
1155  // core::conformation::Residue const & rsd = pose.residue( ii );
1156  // TR << "residue " << rsd.name3() << pose.pdb_info()->number(ii) << " atom_sasas: [ ";
1157  // for ( Size at=1; at <= rsd.nheavyatoms(); ++at ) {
1158  // core::id::AtomID atid( at, ii );
1159  // TR << utility::trim( rsd.atom_name( at ) ) << ":" << atom_sasa[ atid ] << ", ";
1160  // }
1161  // TR << "], total residue SASA: " << rsd_sasa[ ii ] << std::endl;
1162  // }
1163 
1164  //setup a vector of the sasa radii
1165  //Real const four_pi = 4.0f * Real( numeric::constants::d::pi );
1166  //AtomTypeSet const & atom_type_set = * ChemicalManager::get_instance()->atom_type_set( FA_STANDARD );
1167  //utility::vector1< Real > radii( atom_type_set.n_atomtypes(), 0.0 );
1168  //core::Size SASA_RADIUS_INDEX = atom_type_set.extra_parameter_index( "SASA_RADIUS" );
1169 
1170  // TR << "radii: [ ";
1171  // for ( core::Size ii=1; ii <= atom_type_set.n_atomtypes(); ++ii ) {
1172  // radii[ ii ] = atom_type_set[ ii ].extra_parameter( SASA_RADIUS_INDEX );
1173  // TR << radii[ ii ] << ", ";
1174  // }
1175  // TR << "]" << std::endl;
1176 
1177  //EM options for bb-bb hbond output
1179  scoring::methods::EnergyMethodOptions energymethodoptions( new_sf->energy_method_options() );
1180  energymethodoptions.hbond_options().decompose_bb_hb_into_pair_energies(true);
1181  new_sf->set_energy_method_options( energymethodoptions );
1182 
1183  //make an HbondSet
1184  //figure out energy statistics
1186  pose.update_residue_neighbors();
1187  //fill_hbond_set( pose,
1188  // false /*calc_deriv*/,
1189  // hbond_set,
1190  // false /*bb only*/ );
1191  hbond_set.setup_for_residue_pair_energies(pose, false, false);
1192 
1193  //itterate through all hbonds and figure out which ones are bb-bb betas
1194  Real n_crosschain_hbonds( 0 );
1195  //Real total_ratios( 0 );
1196  //total_hb_sasa_ = 0 ;
1197  total_hb_E_ = 0;
1198  for(Size ii=1; ii <= hbond_set.nhbonds(); ++ii){
1199  core::scoring::hbonds::HBond hbond ( hbond_set.hbond(ii) );
1200  Size don_resnum = hbond.don_res(); Size acc_resnum = hbond.acc_res();
1201  //need to take special consideration for multichain constructor
1203  //TR<< "Do multichain hbonds eval..." << std::endl;
1204  //if they are different chains
1205  if( pose.chain( don_resnum ) != pose.chain( acc_resnum )){
1206  //if the acceptor or donor is in a fixed chain
1207  if ( fixed_chains_.count( pose.chain( don_resnum ) ) || fixed_chains_.count( pose.chain( acc_resnum ) ) ){
1208  //if the acceptor and donor are not both fixed chains
1209  if ( fixed_chains_.count( pose.chain( don_resnum ) ) != fixed_chains_.count( pose.chain( acc_resnum ) ) ){
1210  TR << "Found Hbond between chains: "<< pose.chain( don_resnum ) << " and " << pose.chain( acc_resnum ) <<std::endl;
1211  //now copy the same stuff as for the normal case:
1212  n_crosschain_hbonds += 1;
1213  //TR << "Hbond number: "<< ii << " is between chains." << std::endl;
1214  //now look at atoms involved
1215  // Size hatm = hbond.don_hatm() ;
1216  // conformation::Residue don_rsd = pose.residue( don_resnum );
1217  // conformation::Residue acc_rsd = pose.residue( acc_resnum );
1218  // Size don_atm = don_rsd.atom_base( hatm );
1219  // //Size don_atm = hbond.don_hatm() ;
1220  // Size acc_atm = hbond.acc_atm();
1221 
1222  // //Make AtomIDs
1223  // core::id::AtomID don_atid( don_atm, don_resnum );
1224  // core::id::AtomID acc_atid( acc_atm, acc_resnum );
1225  // Real acc_SASA( atom_sasa[ acc_atid ] );
1226  // Real don_SASA( atom_sasa[ don_atid ] );
1227  // Real hbond_SASA ( acc_SASA + don_SASA );
1228 
1229  // //now find possible sasa
1230  // Real const don_rad = radii[ don_rsd.atom(don_atm).type() ] + probe_radius;
1231  // Real const acc_rad = radii[ acc_rsd.atom(acc_atm).type() ] + probe_radius;
1232  // Real const possible_sasa( four_pi * (don_rad*don_rad + acc_rad*acc_rad ) );
1233 
1234  // //Adujust Hbond energy
1235  // Real adjust_weight( 2 );
1236  // Real sasa_ratio( hbond_SASA / possible_sasa );
1237  // Real const adjustment = (1 - adjust_weight * sasa_ratio);
1238  // //Real const new_Hbond_E = adjustment * hbond.energy();
1239 
1240  // //Print some stuff to make sure
1241  // const std::string & don_atomname = don_rsd.atom_name( don_atm );
1242  // const std::string & acc_atomname = acc_rsd.atom_name( acc_atm );
1243  // // TR << "Donor Res: " << don_rsd.name3() << pose.pdb_info()->number( don_resnum ) << " Donor Atm: " << don_atid << " (" << don_atomname << ")"
1244  // // << " Acc Res: " << acc_rsd.name3() << pose.pdb_info()->number( acc_resnum ) << " Acc Atm: " << acc_atid << " (" << acc_atomname << ")"
1245  // // << " Hbond_SASA: " << hbond_SASA << " Possible SASA: " << possible_sasa << " SASA ratio: " << sasa_ratio
1246  // // << " Initial HBond E: " << hbond.energy() << " Adjusted: "<< new_Hbond_E
1247  // // << std::endl ;
1248  // //add up the ratios and total hbond sasa
1249  // total_ratios += sasa_ratio;
1250  // total_hb_sasa_ += hbond_SASA;
1251  total_hb_E_ += hbond.energy();
1252  }
1253  }
1254  }//end if different chains
1255  }
1256  else { //not multichain constructor
1257  if ( pose.chain( hbond.don_res() ) != pose.chain( hbond.acc_res() ) ) {
1258  n_crosschain_hbonds += 1;
1259  // //TR << "Hbond number: "<< ii << " is between chains." << std::endl;
1260  // //now look at atoms involved
1261  // Size hatm = hbond.don_hatm() ;
1262  // conformation::Residue don_rsd = pose.residue( don_resnum );
1263  // conformation::Residue acc_rsd = pose.residue( acc_resnum );
1264  // Size don_atm = don_rsd.atom_base( hatm );
1265  // //Size don_atm = hbond.don_hatm() ;
1266  // Size acc_atm = hbond.acc_atm();
1267 
1268  // //Make AtomIDs
1269  // core::id::AtomID don_atid( don_atm, don_resnum );
1270  // core::id::AtomID acc_atid( acc_atm, acc_resnum );
1271  // Real acc_SASA( atom_sasa[ acc_atid ] );
1272  // Real don_SASA( atom_sasa[ don_atid ] );
1273  // Real hbond_SASA ( acc_SASA + don_SASA );
1274 
1275  // //now find possible sasa
1276  // Real const don_rad = radii[ don_rsd.atom(don_atm).type() ] + probe_radius;
1277  // Real const acc_rad = radii[ acc_rsd.atom(acc_atm).type() ] + probe_radius;
1278  // Real const possible_sasa( four_pi * (don_rad*don_rad + acc_rad*acc_rad ) );
1279 
1280  // //Adujust Hbond energy
1281  // Real adjust_weight( 2 );
1282  // Real sasa_ratio( hbond_SASA / possible_sasa );
1283  // Real const adjustment = (1 - adjust_weight * sasa_ratio);
1284  // Real const new_Hbond_E = adjustment * hbond.energy();
1285 
1286  // // //Print some stuff to make sure
1287  // // const std::string & don_atomname = don_rsd.atom_name( don_atm );
1288  // // const std::string & acc_atomname = acc_rsd.atom_name( acc_atm );
1289  // // // TR << "Donor Res: " << don_rsd.name3() << pose.pdb_info()->number( don_resnum ) << " Donor Atm: " << don_atid << " (" << don_atomname << ")"
1290  // // // << " Acc Res: " << acc_rsd.name3() << pose.pdb_info()->number( acc_resnum ) << " Acc Atm: " << acc_atid << " (" << acc_atomname << ")"
1291  // // // << " Hbond_SASA: " << hbond_SASA << " Possible SASA: " << possible_sasa << " SASA ratio: " << sasa_ratio
1292  // // // << " Initial HBond E: " << hbond.energy() << " Adjusted: "<< new_Hbond_E
1293  // // // << std::endl ;
1294  // // //add up the ratios and total hbond sasa
1295  // total_ratios += sasa_ratio;
1296  // total_hb_sasa_ += hbond_SASA;
1297  total_hb_E_ += hbond.energy();
1298  } //end if chains not equal
1299  } //end if not multichain
1300  }//end loop over all hbonds
1301  //get the avg exposure of the hbonds
1302  //hbond_exposure_ratio_ = total_ratios / n_crosschain_hbonds;
1303 }//end function def
1304 
1305 // //helper function for above to calculate hbond stats based on an hbond input
1306 // void hbond_info_calculate( core::scoring::hbonds::HBond hbond ){
1307 // //does nothing for now, figure out later
1308 // }
1309 
1310 void
1312 
1314  // Split PDB into two surfaces
1315  for(core::Size i = 1; i <= complexed_pose.n_residue(); i++) {
1316  if(upstream_chains_.count( complexed_pose.chain( i ) ) )
1317  sc_calc.AddResidue(0, complexed_pose.residue(i));
1318  else if(downstream_chains_.count( complexed_pose.chain( i ) ) )
1319  sc_calc.AddResidue(1, complexed_pose.residue(i));
1320  else
1321  continue;
1322  }
1323  //now calculate and print results
1324  TR << "Computing Shape Complementarity Score..." << std::endl;
1325  TR << "Upstream chain(s) numbers: ";
1326  for( std::set< core::Size >::const_iterator it(upstream_chains_.begin()), end(upstream_chains_.end());
1327  it != end; ++it){
1328  TR << *it << ", ";
1329  }
1330  TR << std::endl;
1331 
1332  TR << "Downstream chain(s) numbers: ";
1333  for( std::set< core::Size >::const_iterator it(downstream_chains_.begin()), end(downstream_chains_.end());
1334  it != end; ++it){
1335  TR << *it << ", ";
1336  }
1337  TR << std::endl;
1338 
1339  //actual calculate function
1340  sc_calc.Calc();
1341  core::scoring::sc::RESULTS const results = sc_calc.GetResults();
1342  sc_value_ = results.sc;
1343 
1344 }//end compute_interface_sc
1345 
1346 
1347 ///@details Mutate all residues to GlY rescore complex energy and separated energy
1349  using namespace core;
1350  //need a copy of the pose to avoid screwing up the good one
1351  pose::Pose copy_complex( complex_pose );
1352  pose::Pose copy_separate( separated_pose );
1353  using namespace core::pack::task;
1354  using namespace core::pack::task::operation;
1355  using namespace protocols::toolbox::task_operations;
1356 
1357  //setupt task info
1359  utility::vector1_bool packable(copy_complex.total_residue(), false); //false = nobody is packable
1360  utility::vector1< bool > allowed_aa( chemical::num_canonical_aas, false ); //no allowed residues
1361  allowed_aa[ core::chemical::aa_from_oneletter_code( 'G' ) ] = true; //allow gly only
1362  //allow all interface residues to be mutated to Gly
1363  for( std::set< core::Size >::const_iterator it(interface_set_.begin()), end(interface_set_.end());
1364  it != end; ++it){
1365  task->nonconst_residue_task( *it ).restrict_absent_canonical_aas(allowed_aa);
1366  packable[ *it ] = true;
1367  }
1368  task->restrict_to_residues(packable); //prevents non interface res from changing
1369 
1370 #ifndef NDEBUG
1371  TR<< "GLY Packer Task: " << *(task) << std::endl;
1372 #endif
1373 
1374  //apply mutations
1376  packrot_mover->apply ( copy_complex );
1377  packrot_mover->apply( copy_separate );
1378  gly_dG_ = (*sf_) ( copy_complex ) - (*sf_) ( copy_separate ) ;
1379 }
1380 
1381 ///@details
1383  if(!use_centroid_){
1384  centroid_dG_ = 0;
1385  return;
1386  }
1387  core::pose::Pose copy_complex( complex_pose );
1388  core::pose::Pose copy_separated( separated_pose );
1391  // use score3 but turn of RG
1393  scorefxn->set_weight( core::scoring::rg, 0.0 );
1394  //Debugging:
1395  TR << "Centroid score of complex: " << (*scorefxn) ( copy_complex ) << std::endl;
1396  TR << "Centroid score of separated: " << (*scorefxn) ( copy_separated ) << std::endl;
1397 
1398  centroid_dG_ = (*scorefxn) ( copy_complex ) - (*scorefxn ) ( copy_separated ) ;
1399 }
1400 
1401 
1402 ///@details sets up the packer task for the interface
1404  using namespace core::pack::task;
1405  using namespace core::pack::task::operation;
1406  using namespace protocols::toolbox::task_operations;
1407  //set up the task to match this calculation
1408  //set up a packer task
1409  TaskFactoryOP tf = new TaskFactory();
1410  tf->push_back( new InitializeFromCommandline() );
1411  //force include current to prevent wonky results
1412  tf->push_back( new IncludeCurrent() );
1413  tf->push_back( new RestrictToRepacking() );
1414  if( use_resfile_ ) tf->push_back( new ReadResfile() );
1415  //use the same logic for calculators to restrict to the interface
1417  if(multichain_constructor_){ //different calculator for different constructor
1418  std::pair< std::string, std::string> multichain_strings ( InterGroupNeighborsCalculator_, "neighbors" );
1419  calculators_used.push_back( multichain_strings );
1420  }
1421  else{ //if not multichain constructor
1422  std::pair< std::string, std::string> chain_strings ( InterfaceNeighborDefinition_, "interface_residues" );
1423  calculators_used.push_back( chain_strings );
1424  }
1425  tf->push_back( new RestrictByCalculatorsOperation( calculators_used ) );
1426  core::pack::task::PackerTaskOP task( tf->create_task_and_apply_taskoperations( pose ) );
1427  task_ = task ;
1428 }
1429 
1430 ///@brief parse XML (specifically in the context of the parser/scripting scheme)
1431 void
1433  TagPtr const tag,
1434  DataMap & datamap,
1435  Filters_map const &,
1436  Movers_map const &,
1437  Pose const & pose
1438 )
1439 {
1440  if ( tag->getName() != "InterfaceAnalyzerMover" ) {
1441  //TR(t_warning) << " received incompatible Tag " << tag << std::endl;
1442  // assert(false);
1443  // return;
1444  }
1446 
1447  set_pack_separated(tag->getOption<bool>("pack_separated", false));
1448  set_use_resfile(tag->getOption<bool>("resfile", false ) );
1449  set_compute_packstat(tag->getOption<bool> ("packstat", false));
1450  set_compute_interface_sc(tag->getOption<bool> ("interface_sc", false));
1451  set_pack_input(tag->getOption<bool> ("pack_input", false));
1452  set_tracer(tag->getOption("tracer", false));
1453  set_use_jobname(tag->getOption("use_jobname", false));
1454 
1455  if (tag->hasOption("jump") && tag->hasOption("fixedchains"))
1456  {
1457  throw utility::excn::EXCN_RosettaScriptsOption("Jump and fixedchains are mutually exclusive. Use either jump or fixedchains");
1458  }
1459  if (tag->hasOption("fixedchains"))
1460  {
1461  set_interface_jump(0);
1462  std::string chains_string = tag->getOption<std::string>("fixedchains");
1463  utility::vector1<std::string> fixed_chains_string = utility::string_split(chains_string,',');
1464  //parse the fixed chains to figure out pose chain nums
1465  //std::set< int > fixed_chains_ ; //This is a set of the CHAIN IDs, not residue ids
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]);
1469  for (core::Size i = 1; i<=pose.total_residue(); ++i){
1470  if (pose.pdb_info()->chain( i ) == this_chain){
1471  fixed_chains_.insert( pose.chain(i) );
1472  break; //once we know something about the chain we can skip - we just need the chain id
1473  }
1474  }
1475  TR << this_chain << ", ";
1476  }
1477  TR << "these will be moved together." << std::endl;
1478 
1479  multichain_constructor_ = true;
1480  //fixed_chains_(fixed_chains)
1481  }
1482  else
1483  {
1484  set_interface_jump(tag->getOption("jump", 1));
1485  }
1486  // tracer_(false), //output to tracer
1487  // calcs_ready_(false), //calculators are not ready
1488  // use_jobname_(false), //use the pose name
1489 }
1490 
1491 ///@brief required in the context of the parser/scripting scheme
1494 {
1495  return new InterfaceAnalyzerMover;
1496 }
1497 
1498 ///@brief required in the context of the parser/scripting scheme
1501 {
1502  return new InterfaceAnalyzerMover( *this );
1503 }
1504 
1505 
1506 }//analysis
1507 }//protocols