Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
design_utils.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 devel/protein_interface_design/design_utils.cc
11 /// @brief various utilities for interface design.
12 /// @author Sarel Fleishman (sarelf@u.washington.edu)
13 
14 // Project Headers
16 #include <core/pose/Pose.hh>
17 #include <core/scoring/Energies.hh>
18 
22 // AUTO-REMOVED #include <core/kinematics/tree/Atom.hh>
23 
24 #include <core/chemical/AA.hh>
25 #include <core/types.hh>
28 // AUTO-REMOVED #include <core/conformation/symmetry/util.hh>
29 
42 
44 #include <basic/Tracer.hh>
45 
46 // Utility Headers
47 #include <utility/vector1.hh>
48 
49 // Unit Headers
52 
53 #include <ObjexxFCL/format.hh>
54 
55 // C++ headers
56 #include <map>
57 
59 #include <utility/vector0.hh>
60 #include <boost/lexical_cast.hpp>
61 
62 // option key includes
63 
64 
65 
66 using ObjexxFCL::fmt::A;
67 using ObjexxFCL::fmt::I;
68 using ObjexxFCL::fmt::F;
69 using namespace core;
70 using namespace core::scoring;
71 
72 static basic::Tracer TR( "protocols.protein_interface_design.design_utils" );
73 
74 using namespace protocols::protein_interface_design;
75 using namespace core;
76 
77 typedef core::Real Real;
78 typedef core::Size Size;
80 
81 // it is assumed that the pose is scored prior to calling this function
84 {
85  using namespace core::scoring;
86 
87  typedef utility::vector1<ScoreType> ScoreTypeVec;
88 
89  ScoreTypeVec score_types;
90  EnergyMap weights = pose.energies().weights();
91  for( core::Size i = 1; i <= n_score_types; ++i ) {
92  ScoreType const st = ScoreType( i );
93  if( weights[ st ] != 0 ) score_types.push_back( st );
94  }
95 
96  core::Real residue_total( 0.0 );
97  for(ScoreTypeVec::const_iterator it=score_types.begin(); it!=score_types.end(); ++it ) {
98  residue_total+=(weights[*it] * pose.energies().residue_total_energies( resid )[ *it ]);
99  }
100  return( residue_total);
101 }
102 
103 void
104 ReportSequenceDifferences::calculate( pose::Pose const & pose1_in, pose::Pose const & pose2_in )
105 {
106  using namespace core::scoring;
107 
108  core::pose::Pose pose1( pose1_in );
109  core::pose::Pose pose2( pose2_in );
110 
111  ScoreFunctionOP scorefxn1 = scorefxn_;
112  ScoreFunctionOP scorefxn2 = scorefxn_;
113  (*scorefxn1)(pose1);
114  (*scorefxn2)(pose2);
115 
116  /// Now handled automatically. scorefxn1->accumulate_residue_total_energies( pose1 );
117  /// Now handled automatically. scorefxn2->accumulate_residue_total_energies( pose2 );
118 
119  // core::scoring::EnergyMap weights1 = pose1.energies().weights(); // Unused variable causes a warning.
120  // core::scoring::EnergyMap weights2 = pose2.energies().weights(); // Unused variable causes a warning.
121 
122  runtime_assert( pose1.total_residue() == pose2.total_residue() );
123  for( core::Size i = 1; i <= pose1.total_residue(); ++i ) {
124  if( !pose1.residue(i).is_protein() ) continue;
125  core::Size const restype1( pose1.residue(i).aa() );
126  core::Size const restype2( pose2.residue(i).aa() );
127 
128  if( restype1 != restype2 ) {
129  res_energy1_.insert( std::make_pair( i, sum_total_residue_energy( pose1, i ) ));
130  res_energy2_.insert( std::make_pair( i, sum_total_residue_energy( pose2, i ) ));
131 
132  res_name1_.insert( std::make_pair( i, pose1.residue(i).name3() ));
133  res_name2_.insert( std::make_pair( i, pose2.residue(i).name3() ));
134  }
135  }
136 }
137 
138 void
139 ReportSequenceDifferences::report( std::ostream & out ) const
140 {
141  std::map< Size, core::Real >::const_iterator it_energy1=res_energy1_.begin();
142  std::map< Size, core::Real >::const_iterator it_energy2=res_energy2_.begin();
143  std::map< Size, std::string >::const_iterator it_name1=res_name1_.begin();
144  std::map< Size, std::string >::const_iterator it_name2=res_name2_.begin();
145 
146  if( it_energy1 == res_energy1_.end() ) {
147  out<<"No changes\n";
148  return;
149  }
150  else { out <<res_energy1_.size()<<" changes:\n"; }
151 
152  while( it_energy1!=res_energy1_.end() ) {
153  TR<<it_name1->second<<it_name1->first<<" "<<it_energy1->second<<'\t'<<
154  it_name2->second<<it_name2->first<<" "<<it_energy2->second<<std::endl;
155  ++it_energy1; ++it_energy2; ++it_name1; ++it_name2;
156  }
157 }
158 
160 ddG_cycles( pose::Pose const & pose, core::scoring::ScoreFunctionOP scorefxn, core::Size const cycles )
161 {
162  pose::Pose temp_pose = pose;
163  protocols::simple_moves::ddG ddg( scorefxn );
164  core::Real ddG_val( 0.0 );
165  for( core::Size i = 1; i<=cycles; ++i ) {
166  ddg.calculate( temp_pose );
167  ddG_val += ddg.sum_ddG();
168  temp_pose = pose; // reset the pose
169  }
170  ddG_val = ddG_val / cycles;
171  return( ddG_val );
172 }
173 
174 void
175 point_mutation( pose::Pose & pose, core::scoring::ScoreFunctionCOP scorefxn, core::Size const seqpos, core::Size const mutation )
176 {
178  allowed_aas[ mutation ] = true;
179 
181  for( core::Size i=1; i<=pose.total_residue(); ++i ) {
182  if( i == seqpos )
183  task->nonconst_residue_task(i).restrict_absent_canonical_aas( allowed_aas );
184  else
185  task->nonconst_residue_task(i).prevent_repacking();
186  }
187  pack::pack_rotamers( pose, *scorefxn, task );
188 }
189 
190 void
191 Revert::apply( pose::Pose & pose_wt, pose::Pose & pose_des ) const
192 {
193  using namespace core::scoring;
194 
195  pose::Pose const saved_des = pose_des;
196 
197  ScoreFunctionOP scorefxn_wt = scorefxn_;
198  ScoreFunctionOP scorefxn_des = scorefxn_;
199 
200  TR<<"Averaging all ddg calculations over "<<ddg_cycles_<<" iterations\n";
201  core::Real const ddG_des_val( ddG_cycles( pose_des, scorefxn_des, ddg_cycles_));
202  TR<<"average ddG for design: "<<ddG_des_val<<'\n';
203 
204  (*scorefxn_wt)(pose_wt);
205  (*scorefxn_des)(pose_des);
206 
207  ReportSequenceDifferences seq_diff( scorefxn_ );
208  seq_diff.calculate( pose_wt, pose_des );
209  typedef std::map< core::Size, core::Real> EnMap;
210  EnMap const *energy_map2( seq_diff.get_res_energy( 2 ));
211 // now substitute each w/t sidechain on pose_des and measure ddg. if ddg doesn't change, apply it
212  std::vector< int > revert_positions;
213  std::vector< int > ala_positions;
214  core::Size count_changes_orig( 0 ), count_changes_revert( 0 );
215  std::string ignored_resids( "select resi " );
216  std::string done_resids( "select resi " );
217  bool first_pass_ignored( true ), first_pass_done( true );
218  for( EnMap::const_iterator it2 = energy_map2->begin(); it2!=energy_map2->end(); ++it2 ) {
219  using boost::lexical_cast;
220  using std::string;
221  core::Size const seqpos( it2->first );
222 
223  TR<<pose_des.residue(seqpos).name3()<<seqpos<<"->"<<pose_wt.residue(seqpos).name3()<<" ";
224  pose_des.copy_segment( 1, pose_wt, seqpos, seqpos );
225  core::Real const ddG_revert_val( ddG_cycles( pose_des, scorefxn_des, ddg_cycles_ ));
226  TR<<"ddG change "<<ddG_revert_val-ddG_des_val<<". ";
227  pose_des = saved_des;
228  if( ddG_revert_val <= ddG_des_val + ddg_tolerance_ ) {
229  TR<<" Done.\n";
230  if( first_pass_done )
231  first_pass_done = false;
232  else
233  done_resids += "+";
234  done_resids += lexical_cast< string >( seqpos );
235  revert_positions.push_back( seqpos );
236  ++count_changes_orig;
237  }
238  else {
239  TR<<" Ignored.\n";
240  ++count_changes_revert; ++count_changes_orig;
241  if( first_pass_ignored )
242  first_pass_ignored = false;
243  else
244  ignored_resids += "+";
245  ignored_resids += lexical_cast< string >( seqpos );
246 
247  if( it2->second > 0 ) {
248  TR<<"but the total energy for "<<pose_des.residue(seqpos).name3()<<seqpos<<" is "<<it2->second<<" testing an Ala substitution\n";
249  TR<<"mutation "<<pose_des.residue(seqpos).name3()<<seqpos<<"->ALA has ddG ";
250  point_mutation( pose_des, scorefxn_des, seqpos, chemical::aa_ala );
251  core::Real const ddG_ala( ddG_cycles( pose_des, scorefxn_des, ddg_cycles_ ));
252  TR << ddG_ala<<" and will be ";
253  if( ddG_ala <= ddG_des_val ) {
254  TR<<"kept\n";
255  ala_positions.push_back( seqpos );
256  }
257  else { TR<<"ignored\n"; }
258  }
259  }
260  }
261  pose_des = saved_des;
262  for( std::vector<int>::const_iterator it_rev=revert_positions.begin(); it_rev!=revert_positions.end(); ++it_rev ) {
263  point_mutation( pose_des, scorefxn_des, *it_rev, pose_wt.residue( *it_rev ).aa() );
264  }
265  for( std::vector<int>::const_iterator it_ala=ala_positions.begin(); it_ala!=ala_positions.end(); ++it_ala ) {
266  point_mutation( pose_des, scorefxn_des, *it_ala, chemical::aa_ala );
267  }
268  core::Real const ddG_all_changes( ddG_cycles( pose_des, scorefxn_des, ddg_cycles_ ));
269  TR<<"Starting ddG "<<ddG_des_val<<" final ddG "<< ddG_all_changes<<"\n";
270  TR<<"Sequences changes in design: "<<count_changes_orig<<". Sequence changes in reversion: "<<count_changes_revert<<'\n';
271  TR<<"Ignored residues: \n"<<ignored_resids<<'\n';
272  TR<<"Done residues: \n"<<done_resids<<'\n';
273  TR.flush();
274 }
275 
276 
277 ///////////////////////////////
278 FavorNativeResidue::FavorNativeResidue( core::pose::Pose & pose, core::Real const native_residue_bonus )
279 {
280  core::Size const nres( pose.total_residue() );
281  for( core::Size i = 1; i <= nres; ++i ) {
282  native_residue_bonus_.push_back( native_residue_bonus );
283  }
284  add_residue_constraints( pose );
285 }
286 
287 ////////////////////////////
288 FavorNativeResidue::FavorNativeResidue( core::pose::Pose & pose, utility::vector1<core::Real> const native_residue_bonus )
289 {
290  core::Size const nres( pose.total_residue() );
291  for( core::Size i = 1; i <= nres; ++i ) {
292  native_residue_bonus_.push_back( native_residue_bonus[i] );
293  }
294  add_residue_constraints( pose );
295 }
296 
297 
298 ///////////////////////////////////////////////////////////////////////////////////////////////
299 void
300 FavorNativeResidue::add_residue_constraints( core::pose::Pose & pose ) const {
301  using namespace core::id;
302  using namespace core::conformation;
303  using namespace core::scoring::constraints;
304 
305  core::Size const nres( pose.total_residue() );
306  for ( core::Size i=1; i<= nres; ++i ) {
307  pose.add_constraint( new ResidueTypeConstraint( pose, i, native_residue_bonus_[ i ]) );
308  }
309 
310 }
311 
312 ///////////////////////////////
313 FavorNonNativeResidue::FavorNonNativeResidue( Pose & pose, core::Real const non_native_residue_bonus )
314 {
315  core::Size const nres( pose.total_residue() );
316  for( core::Size i = 1; i <= nres; ++i ) {
317  non_native_residue_bonus_.push_back( non_native_residue_bonus );
318  }
319  add_residue_constraints( pose );
320 }
321 
322 ////////////////////////////
323 FavorNonNativeResidue::FavorNonNativeResidue( Pose & pose, utility::vector1<core::Real> const non_native_residue_bonus )
324 {
325  core::Size const nres( pose.total_residue() );
326  for( core::Size i = 1; i <= nres; ++i ) {
327  non_native_residue_bonus_.push_back( non_native_residue_bonus[i] );
328  }
329  add_residue_constraints( pose );
330 }
331 
332 
333 ///////////////////////////////////////////////////////////////////////////////////////////////
334 void
335 FavorNonNativeResidue::add_residue_constraints( pose::Pose & pose ) const {
336  using namespace core::id;
337  using namespace core::conformation;
338  using namespace core::scoring::constraints;
339 
340  core::Size const nres( pose.total_residue() );
341  for ( core::Size i=1; i<= nres; ++i ) {
342  pose.add_constraint( new NonResidueTypeConstraint( pose, i, non_native_residue_bonus_[ i ]) );
343  }
344 
345 }
346 
347 
348 
349 /// @detailed minimize the interface between two partners. If target_residues is defined
350 /// the fold_tree for minimization is set up between the central residue in the target residues and the nearest residue on the partner.
351 /// if simultaneous minimization is true, then all dofs are minimized at once.
352 void
354 pose::Pose & pose,
356 utility::vector1< bool > const min_bb,
357 utility::vector1< bool > const min_sc,
358 utility::vector1< bool > const min_rb,
359 bool const optimize_foldtree,
360 utility::vector1< core::Size > const target_residues,
361 bool const simultaneous_minimization/* = false */ )
362 {
363  using namespace optimization;
364 
365  runtime_assert( min_rb.size() == pose.num_jump() );
366 
367  core::Size const nres( pose.total_residue() );
368  runtime_assert( min_bb.size() == nres );
369  runtime_assert( min_sc.size() == nres );
370  runtime_assert( min_rb.size() == pose.num_jump() );
371 
372  pose.update_residue_neighbors(); // o/w fails assertion `graph_state_ == GOOD`
373  kinematics::FoldTree const saved_ft( pose.fold_tree() );
374 
375  if( optimize_foldtree && target_residues.size() > 0 ) { //setup new fold_tree for better numerical behaviour between the residue at the centre of target_residues and the nearest residue on the partner
376  core::Real min_mean_dist=10000;
377  core::Size central_residue( *target_residues.begin() );
378  for( utility::vector1<core::Size>::const_iterator res_it1=target_residues.begin(); res_it1!=target_residues.end(); ++res_it1 ){
379  runtime_assert( *res_it1 <= pose.total_residue() );
380 
381  core::conformation::Residue const res1( pose.residue(*res_it1) );
382  core::Real mean_distance( 0.0 );
383  for( utility::vector1<core::Size>::const_iterator res_it2=res_it1+1; res_it2!=target_residues.end(); ++res_it2 ){
384  core::conformation::Residue const res2( pose.residue(*res_it2) );
385 
386  mean_distance += res1.xyz( res1.nbr_atom() ).distance( res2.xyz( res2.nbr_atom() ) ) ;
387  }
388  if( mean_distance<=min_mean_dist ) {
389  central_residue = *res_it1;
390  min_mean_dist = mean_distance;
391  }
392  }
393  bool const central_res_in_chain1( central_residue < pose.conformation().chain_begin( 2 ) );
394  core::Size const begin( central_res_in_chain1 ? pose.conformation().chain_begin( 2 ) : pose.conformation().chain_begin( 1 ) );
395  core::Size const end ( central_res_in_chain1 ? pose.conformation().chain_end( 2 ) : pose.conformation().chain_end( 1 ) );
396 
397  core::Real min_dist(10000);
398  core::Size nearest_res( 0 );
399  core::conformation::Residue const res_central( pose.residue( central_residue ) );
400  for( core::Size res=begin; res<=end; ++res ) {
401  core::conformation::Residue const res2( pose.residue(res) );
402  core::Real const distance( res_central.xyz( res_central.nbr_atom() ).distance( res2.xyz( res2.nbr_atom() ) ) );
403  if( distance<=min_dist ) {
404  min_dist = distance;
405  nearest_res = res;
406  }
407  }
408  runtime_assert( nearest_res );
409 
410  kinematics::FoldTree new_ft;
411 
412  core::Size const rb_jump( 1 );
413  core::Size const jump_pos1( central_res_in_chain1 ? central_residue : nearest_res );
414  core::Size const jump_pos2( central_res_in_chain1 ? nearest_res : central_residue );
415  new_ft.clear();
416  new_ft.add_edge( jump_pos1, jump_pos2, rb_jump );
417  new_ft.add_edge( 1, jump_pos1, kinematics::Edge::PEPTIDE );
418  new_ft.add_edge( jump_pos1, pose.conformation().chain_end( 1 ), kinematics::Edge::PEPTIDE );
419  new_ft.add_edge( pose.conformation().chain_begin( 2 ), jump_pos2, kinematics::Edge::PEPTIDE );
420  new_ft.add_edge( jump_pos2, pose.total_residue(), kinematics::Edge::PEPTIDE );
421  new_ft.reorder( 1 );
422 
423  TR<<"setting fold_tree for minimization between "<<jump_pos1<<" and "<<jump_pos2<<"\n";
424  pose.fold_tree( new_ft );
425  } //setup new foldtree
426  else
427  TR<<"Fold tree not optimized in minimize interface.\n"<<pose.fold_tree()<<std::endl;
428 
430  mm.set_bb( false );
431  TR<<"minimizing sc of residues: ";
432  for( core::Size i=1; i<=pose.total_residue(); ++i ) {
433  if ( !pose.residue(i).is_protein() ) continue;
434  mm.set_chi( i, min_sc[ i ] );
435  if( min_sc[ i ] )
436  TR<<i<<' ';
437  }
438  TR<<'\n';
439  if( !simultaneous_minimization )
440  AtomTreeMinimizer().run( pose, mm, *scorefxn,
441  MinimizerOptions( "dfpmin_armijo_nonmonotone", 0.01, true/*nblist*/, false/*deriv_check*/ ) );
442 
443  for( core::Size rb_jump=1; rb_jump<=pose.num_jump(); ++rb_jump )
444  mm.set_jump( rb_jump, min_rb[ rb_jump ] );
445  if( !simultaneous_minimization && std::find( min_rb.begin(), min_rb.end(), true ) != min_rb.end() ){
446  TR<<"minimizing rigid body orientation\n";
447  AtomTreeMinimizer().run( pose, mm, *scorefxn,
448  MinimizerOptions( "dfpmin_armijo_nonmonotone", 0.01, true/*nblist*/, false/*deriv_check*/ ) );
449  }
450 
451  if( !simultaneous_minimization )
452  TR<<"minimizing bb of residues (and sc of the previous subset): ";
453  for( core::Size i=1; i<=pose.total_residue(); ++i ) {
454  if ( !pose.residue(i).is_protein() ) continue;
455  mm.set_bb( i, min_bb[ i ] );
456  mm.set_chi( i, min_sc[ i ] );
457  if( min_bb[ i ] )
458  TR<<i<<' ';
459  }
460  TR<<"\nAnd now minimizing all dofs together\n";
461  AtomTreeMinimizer().run( pose, mm, *scorefxn,
462  MinimizerOptions( "dfpmin_armijo_nonmonotone", 0.01, true/*nblist*/, false/*deriv_check*/ ) );
463 
464  if( 0/* target_residues.size() > 0*/ ) //reset fold_tree
465  pose.fold_tree( saved_ft );
466  TR.flush();
467 }
468 
469 void
471 pose::Pose & pose,
473 utility::vector1< bool > const min_bb,
474 utility::vector1< bool > const min_sc,
475 utility::vector1< bool > const min_rb,
476 //bool const optimize_foldtree,
477 //utility::vector1< core::Size > const target_residues,
478 bool const simultaneous_minimization/* = false */ )
479 {
480  using namespace optimization;
481  using namespace conformation::symmetry;
482 
483  runtime_assert( core::pose::symmetry::is_symmetric( pose ) );
484  pose.update_residue_neighbors(); // o/w fails assertion `graph_state_ == GOOD`
485 
487  mm.set_bb( false );
488  TR<<"minimizing sc of residues: ";
489  for( core::Size i=1; i<=pose.total_residue(); ++i ) {
490  if ( !pose.residue(i).is_protein() ) continue;
491  mm.set_chi( i, min_sc[ i ] );
492  if( min_sc[ i ] )
493  TR<<i<<' ';
494  }
495  TR<<'\n';
497 
498  if( !simultaneous_minimization )
499  optimization::symmetry::SymAtomTreeMinimizer().run( pose, mm, *scorefxn,
500  MinimizerOptions( "dfpmin_armijo_nonmonotone", 0.01, true/*nblist*/, false/*deriv_check*/ ) );
501 
502  mm.set_jump( true );
504 
505  if ( min_rb.size() > 0 ) {
506  TR<<"minimizing rigid body orientation\n";
507  TR<<"By default all dofs in the symmetry input are used!!!Should change?\n";
508  optimization::symmetry::SymAtomTreeMinimizer().run( pose, mm, *scorefxn,
509  MinimizerOptions( "dfpmin_armijo_nonmonotone", 0.01, true/*nblist*/, false/*deriv_check*/ ) );
510  }
511 
512  if( !simultaneous_minimization )
513  TR<<"minimizing bb of residues (and sc of the previous subset): ";
514  for( core::Size i=1; i<=pose.total_residue(); ++i ) {
515  if ( !pose.residue(i).is_protein() ) continue;
516  mm.set_bb( i, min_bb[ i ] );
517  mm.set_chi( i, min_sc[ i ] );
518  if( min_bb[ i ] )
519  TR<<i<<' ';
520  }
521  TR<<"\nAnd now minimizing all dofs together\n";
523  optimization::symmetry::SymAtomTreeMinimizer().run( pose, mm, *scorefxn,
524  MinimizerOptions( "dfpmin_armijo_nonmonotone", 0.01, true/*nblist*/, false/*deriv_check*/ ) );
525  TR.flush();
526 }
527 
528 std::list< core::Size >
530  Pose const & in_pose, core::Size const target_residue, std::set< core::Size > const & binders,
531  bool const bb, bool const sc, core::Real const energy_thres, bool const bb_bb )
532 {
533 
534  using namespace core::scoring::hbonds;
535 
536  std::list< core::Size > hbonded_list;
538  Pose pose( in_pose );
539  (*scorefxn)(pose);
540 
541  HBondSet background_hbond_set;
542  background_hbond_set.setup_for_residue_pair_energies( pose, false/*calculate_derivative*/, true/*backbone_only*/ );
543  HBondDatabaseCOP hb_database( HBondDatabase::get_database( background_hbond_set.hbond_options().params_database_tag()));
544 
545  if( bb_bb ){
546  TR << "decomposing bb hydrogen bond terms" << std::endl;
547  core::scoring::methods::EnergyMethodOptionsOP energy_options(new core::scoring::methods::EnergyMethodOptions(scorefxn->energy_method_options()));
548  energy_options->hbond_options().decompose_bb_hb_into_pair_energies(true);
549  scorefxn->set_energy_method_options(*energy_options);
550  }
551 
552  EnergyMap hbond_emap;
553  core::conformation::Residue const resi( pose.residue( target_residue ));
554  core::Real const distance_cutoff( 20.0 );
555  for ( std::set< core::Size >::const_iterator binder_it=binders.begin(); binder_it!=binders.end(); ++binder_it ) {
556  core::conformation::Residue const resj( pose.residue(*binder_it) );
557 
558  core::Real const distance( resi.xyz( resi.nbr_atom() ).distance( resj.xyz( resj.nbr_atom() ) ) );
559  if ( distance > distance_cutoff ) continue;
560 
561  HBondSet pair_hbond_set(2);
563  *hb_database,
564  resi, resj, background_hbond_set.nbrs(resi.seqpos()), background_hbond_set.nbrs(resj.seqpos()),
565  false /*calculate_derivative*/,
566  !bb, !sc, !sc, !sc, pair_hbond_set);
568  *hb_database,
569  resj, resi, background_hbond_set.nbrs(resj.seqpos()), background_hbond_set.nbrs(resi.seqpos()),
570  false /*calculate_derivative*/,
571  !bb, !sc, !sc, !sc, pair_hbond_set);
572 
573  hbond_emap.zero();
574  get_hbond_energies( pair_hbond_set, hbond_emap );
575  // The hbond_energies should be controlled by dotting hbond_emap
576  // with the weights file used, but this cannot be done without
577  // effecting hbond_energy_threshold_ which is calibrated for
578  // unweighted hbond energies. Since STANDARD_WTS + SCORE12_PATCH
579  // is hard coded, use this instead:
580 // hbond_emap[ hbond_sr_bb_sc ] = 0;
581 // hbond_emap[ hbond_lr_bb_sc ] = 0;
582 
583  core::Real total_hbond_energy( hbond_emap.sum() );
584 
585 
586  // all of the bb / sc energies are lumped together
587  // but it can be controlled whether bb - bb are included or not
588 
589  // counting the number of hbonds between the two residues
590  if( total_hbond_energy <= energy_thres ) {
591  using namespace core::conformation;
592  for( core::Size i=1; i<=pair_hbond_set.nhbonds(); ++i ){
593  using namespace core::scoring::hbonds;
594  HBond const & hb( pair_hbond_set.hbond( i ) );
595 
596  if( !bb && ( hb.don_hatm_is_protein_backbone() && hb.acc_atm_is_protein_backbone() ) ) continue;
597  if( !sc && ( !hb.don_hatm_is_protein_backbone() || !hb.acc_atm_is_protein_backbone() ) ) continue;
598 
599  core::Size const don_res_i( hb.don_res() ), acc_res_i( hb.acc_res() );
600  Residue const & don_rsd( pose.residue( don_res_i ) ),
601  acc_rsd( pose.residue( acc_res_i ) );
602  if( (don_rsd.seqpos() == *binder_it && acc_rsd.seqpos() == target_residue) ||
603  ( don_rsd.seqpos() == target_residue && acc_rsd.seqpos() == *binder_it ) ){
604  hbonded_list.push_back( *binder_it );
605  core::Size const width( 10 );
606  TR << I( width, target_residue )
607  << I( width, *binder_it )
608  << A( width, resi.name1() )
609  << A( width, resj.name1() )
610  << F( width, 3, hbond_emap[ hbond_sr_bb ] )
611  << F( width, 3, hbond_emap[ hbond_lr_bb ] )
612  << F( width, 3, hbond_emap[ hbond_sc ] )
613  << F( width, 3, hbond_emap[ hbond_bb_sc ] )
614  << F( width, 3, distance ) << "\n";
615  }//correct residues
616  }//hbond num
617  }// if energy passes threshold
618  } // residue j
619  TR.flush();
620  return( hbonded_list );
621 }
622