Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
hbonds.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
11 /// @brief
12 /// @author
13 
14 
15 // Unit headers
17 
18 // Package headers
25 
26 // // Project headers
28 #include <core/graph/Graph.hh>
29 #include <core/pose/Pose.hh>
30 #include <core/scoring/Energies.hh>
36 #include <basic/Tracer.hh>
38 #include <ObjexxFCL/format.hh>
39 
40 //pba membrane specific hbond
44 // AUTO-REMOVED #include <core/scoring/MembraneTopology.hh>
45 // AUTO-REMOVED #include <basic/options/option.hh>
46 // AUTO-REMOVED #include <basic/options/keys/membrane.OptionKeys.gen.hh>
47 
48 #include <utility/vector1.hh>
49 #include <basic/options/keys/OptionKeys.hh>
50 
51 // Boost Headers
52 #include <boost/foreach.hpp>
53 #define foreach BOOST_FOREACH
54 
55 
56 //#include <core/scoring/Energies.hh>
57 
58 // // Numeric headers
59 // #include <numeric/numeric.functions.hh>
60 
61 using namespace ObjexxFCL;
62 //pba
63 using namespace basic::options;
64 using namespace OptionKeys;
65 
66 namespace core {
67 namespace scoring {
68 namespace hbonds {
69 
70 static basic::Tracer tr("core.scoring.hbonds.hbonds");
71 
72 /**
73  This routine fills an hbond-set with hbonds. All hbonds are included,
74  even ones which might be excluded later based on the backbone-hbond
75  exclusion.
76 
77  WARNING WARNING WARNING
78  The pose must have an update energies object, eg it must be scored.
79  WARNING WARNING WARNING
80 **/
81 
82 ///////////////////////////////////////////////////
83 void
85  pose::Pose const & pose,
86  bool const calculate_derivative,
87  HBondSet & hbond_set)
88 {
89 
90  HBondDatabase const & database( * HBondDatabase::get_database(hbond_set.hbond_options().params_database_tag()));
91 
92 
93  for ( Size res1 = 1; res1 <= pose.total_residue(); ++res1 ) {
94  conformation::Residue const & rsd1( pose.residue( res1 ) );
95 
96  if(rsd1.is_RNA()==false) continue;
97 
98  identify_intra_res_hbonds( database, rsd1, calculate_derivative, hbond_set);
99 
100  }
101 
102 }
103 ///////////////////////////////////////////////////
104 
105 void
107  pose::Pose const & pose,
108  bool const calculate_derivative,
109  HBondSet & hbond_set,
110  bool const exclude_bb /* default false */,
111  bool const exclude_bsc /* default false */,
112  bool const exclude_scb /* default false */,
113  bool const exclude_sc /* default false */
114 )
115 {
116  assert( pose.energies().residue_neighbors_updated() );
117 
118  // clear old data
119  hbond_set.clear();
120  HBondDatabase const & database( * HBondDatabase::get_database(hbond_set.hbond_options().params_database_tag()));
121 
122  // need to know which residues are neighbors
123  // and what the neighbor-numbers are for each residue since some of the
124  // weights are environment-dependent.
125  EnergyGraph const & energy_graph( pose.energies().energy_graph() );
126  TenANeighborGraph const & tenA_neighbor_graph( pose.energies().tenA_neighbor_graph() );
127 
128  // loop over all nbr-pairs
129  for ( Size res1 = 1; res1 <= pose.total_residue(); ++res1 ) {
130  int const nb1 = tenA_neighbor_graph.get_node( res1 )->num_neighbors_counting_self_static();
131  conformation::Residue const & rsd1( pose.residue( res1 ) );
132 
134  iru = energy_graph.get_node(res1)->const_upper_edge_list_begin(),
135  irue = energy_graph.get_node(res1)->const_upper_edge_list_end();
136  iru != irue; ++iru ) {
137 
138  int const res2( (*iru)->get_second_node_ind() );
139 
140  conformation::Residue const & rsd2( pose.residue( res2 ) );
141  if ( hbond_set.hbond_options().exclude_DNA_DNA() && rsd1.is_DNA() && rsd2.is_DNA() ) continue;
142 
143  int const nb2 = tenA_neighbor_graph.get_node( res2 )->num_neighbors_counting_self_static();
144 
145  //pba membrane specific hbond
146  if ( hbond_set.hbond_options().Mbhbond() ) {
148  database,
149  rsd1, rsd2, nb1, nb2, calculate_derivative,
150  exclude_bb, exclude_bsc, exclude_scb, exclude_sc, hbond_set, pose);
151 
153  database,
154  rsd2, rsd1, nb2, nb1, calculate_derivative,
155  exclude_bb, exclude_bsc, exclude_scb, exclude_sc, hbond_set, pose);
156  } else {
158  database,
159  rsd1, rsd2, nb1, nb2, calculate_derivative,
160  exclude_bb, exclude_bsc, exclude_scb, exclude_sc, hbond_set);
161 
163  database,
164  rsd2, rsd1, nb2, nb1, calculate_derivative,
165  exclude_bb, exclude_bsc, exclude_scb, exclude_sc, hbond_set);
166 
167  }
168  } // nbrs of res1
169  if(!hbond_set.hbond_options().exclude_self_hbonds() && hbond_set.hbond_options().exclude_DNA_DNA() && rsd1.is_DNA() ){
170  //pba membrane specific hbond
171  if ( hbond_set.hbond_options().Mbhbond() ) {
173  database,
174  rsd1, rsd1, nb1, nb1, calculate_derivative,
175  exclude_bb, exclude_bsc, exclude_scb, exclude_sc, hbond_set, pose);
176  } else {
178  database,
179  rsd1, rsd1, nb1, nb1, calculate_derivative,
180  exclude_bb, exclude_bsc, exclude_scb, exclude_sc, hbond_set);
181  }
182  }
183  } // res1
184 
185 
186  if(hbond_set.hbond_options().include_intra_res_RNA()){ //Note that we are neglecting exclude_bsc and exclude_scb options here!
187  fill_intra_res_hbond_set(pose, calculate_derivative, hbond_set);
188  }
189 
190 }
191 
192 ///////////////////////////////////////////////////
193 
194 void
196  core::pose::Pose const & pose,
197  Real const AHdist_threshold,
198  HBondSet & hbond_set
199 ) {
200 
201  hbond_set.clear();
202  HBondDatabase const & database( * HBondDatabase::get_database(hbond_set.hbond_options().params_database_tag()));
203 
204  // need to know which residues are neighbors
205  // and what the neighbor-numbers are for each residue since some of the
206  // weights are environment-dependent.
207  EnergyGraph const & energy_graph( pose.energies().energy_graph() );
208  TenANeighborGraph const & tenA_neighbor_graph( pose.energies().tenA_neighbor_graph() );
209 
210  // loop over all nbr-pairs
211  for ( Size acc_rsd_num = 1; acc_rsd_num <= pose.total_residue(); ++acc_rsd_num ) {
212  core::conformation::Residue const & acc_rsd( pose.residue( acc_rsd_num ) );
213  int const n_acc_nbrs = tenA_neighbor_graph.get_node( acc_rsd_num )->num_neighbors_counting_self_static();
214 
216  iru = energy_graph.get_node(acc_rsd_num)->const_upper_edge_list_begin(),
217  irue = energy_graph.get_node(acc_rsd_num)->const_upper_edge_list_end();
218  iru != irue; ++iru ) {
219  int const don_rsd_num( (*iru)->get_second_node_ind() );
220  core::conformation::Residue const & don_rsd(pose.residue(don_rsd_num));
221  int const n_don_nbrs = tenA_neighbor_graph.get_node(don_rsd_num)->num_neighbors_counting_self_static();
222 
223  if (hbond_set.hbond_options().exclude_DNA_DNA() &&
224  acc_rsd.is_DNA() && don_rsd.is_DNA() ) continue;
225 
226  foreach(Size const hatm, don_rsd.Hpos_polar()){
227  Size const datm(don_rsd.atom_base(hatm));
228  Vector const & hatm_xyz(don_rsd.atom(hatm).xyz());
229  Vector const & datm_xyz(don_rsd.atom(datm).xyz());
230 
231  foreach(Size const aatm, acc_rsd.accpt_pos()){
232  if(hatm_xyz.distance( acc_rsd.xyz( aatm )) > AHdist_threshold) continue;
233 
234  HBEvalTuple hbe_type(datm, don_rsd, aatm, acc_rsd);
235  int const base ( acc_rsd.atom_base( aatm ) );
236  int const base2( acc_rsd.abase2( aatm ) );
237 
238  Real unweighted_energy( 0.0 );
239  hb_energy_deriv(database, hbond_set.hbond_options(),
240  hbe_type, datm_xyz, hatm_xyz,
241  acc_rsd.atom(aatm ).xyz(),
242  acc_rsd.atom(base ).xyz(),
243  acc_rsd.atom(base2).xyz(),
244  unweighted_energy, false, DUMMY_DERIVS);
245 
246  Real environmental_weight
247  (!hbond_set.hbond_options().use_hb_env_dep() ? 1 :
248  get_environment_dependent_weight(hbe_type, n_don_nbrs, n_acc_nbrs, hbond_set.hbond_options()));
249 
250  hbond_set.append_hbond(
251  hatm, don_rsd, aatm, acc_rsd, hbe_type, unweighted_energy, environmental_weight, DUMMY_DERIVS );
252  }
253  }
254  }
255  }
256 
257 }
258 
259 
260 
261 /// @brief Get the f1 and f2 contributions from all hbonds involving this atom
262 /*void
263 get_atom_hbond_derivative(
264  id::AtomID const & atom,
265  HBondSet const & hbond_set,
266  EnergyMap const & weights,
267  Vector & f1,
268  Vector & f2
269 ){
270  f1 = Vector(0.0);
271  f2 = Vector(0.0);
272 
273  utility::vector1< HBondCOP > const & hbonds
274  ( hbond_set.atom_hbonds( atom ) );
275 
276  for ( Size i=1; i<= hbonds.size(); ++i ) {
277  HBond const & hbond( *hbonds[ i ] );
278  Real sign_factor( 0.0 );
279  if ( hbond.atom_is_donorH( atom ) ) sign_factor = 1.0;
280  else {
281  assert( hbond.atom_is_acceptor( atom ) );
282  sign_factor = -1;
283  }
284  // get the appropriate type of hbond weight
285  Real const weight(sign_factor * hbond.weight() * hb_eval_type_weight(hbond.eval_type(), weights));
286  f1 += weight * hbond.deriv().first;
287  f2 += weight * hbond.deriv().second;
288 
289  }
290 }*/
291 
292 
293 /// @details identify_hbonds_1way is overloaded to either add HBond objects to
294 /// an HBondSet or to accumulate energy into a EnergyMap
295 /// object. This is done for performance reasons. The allocation of
296 /// the temporary HBondSet on the heap causes a substatial slow down.
297 void
299  HBondDatabase const & database,
300  conformation::Residue const & don_rsd,
301  conformation::Residue const & acc_rsd,
302  Size const don_nb,
303  Size const acc_nb,
304  bool const evaluate_derivative,
305  bool const exclude_bb, /* exclude if acc=bb and don=bb */
306  bool const exclude_bsc, /* exclude if acc=bb and don=sc */
307  bool const exclude_scb, /* exclude if acc=sc and don=bb */
308  bool const exclude_sc, /* exclude if acc=sc and don=sc */
309  // output
310  HBondSet & hbond_set
311 )
312 {
313  assert( don_rsd.seqpos() != acc_rsd.seqpos() );
314 
315  // <f1,f2> -- derivative vectors
316  //std::pair< Vector, Vector > deriv( Vector(0.0), Vector(0.0 ) );
317  HBondDerivs derivs;
318 
319  for ( chemical::AtomIndices::const_iterator
320  hnum = don_rsd.Hpos_polar().begin(), hnume = don_rsd.Hpos_polar().end();
321  hnum != hnume; ++hnum ) {
322  Size const hatm( *hnum );
323  Size const datm(don_rsd.atom_base(hatm));
324  bool datm_is_bb = don_rsd.atom_is_backbone(datm);
325 
326  if (datm_is_bb){
327  if (exclude_bb && exclude_scb) continue;
328  } else {
329  if (exclude_sc && exclude_bsc) continue;
330  }
331  Vector const & hatm_xyz(don_rsd.atom(hatm).xyz());
332  Vector const & datm_xyz(don_rsd.atom(datm).xyz());
333 
334  for ( chemical::AtomIndices::const_iterator
335  anum = acc_rsd.accpt_pos().begin(), anume = acc_rsd.accpt_pos().end();
336  anum != anume; ++anum ) {
337  Size const aatm( *anum );
338  if (acc_rsd.atom_is_backbone(aatm)){
339  if (datm_is_bb){
340  if (exclude_bb) continue;
341  } else {
342  if (exclude_bsc) continue;
343  }
344  } else {
345  if (datm_is_bb){
346  if (exclude_scb) continue;
347  } else {
348  if (exclude_sc) continue;
349  }
350  }
351 
352  // rough filter for existance of hydrogen bond
353  if ( hatm_xyz.distance_squared( acc_rsd.xyz( aatm ) ) > MAX_R2 ) continue;
354 
355  Real unweighted_energy( 0.0 );
356 
357  HBEvalTuple hbe_type( datm, don_rsd, aatm, acc_rsd);
358 
359  int const base ( acc_rsd.atom_base( aatm ) );
360  int const base2( acc_rsd.abase2( aatm ) );
361  assert( base2 > 0 && base != base2 );
362 
363 
364  hb_energy_deriv( database, hbond_set.hbond_options(),
365  hbe_type, datm_xyz, hatm_xyz,
366  acc_rsd.atom(aatm ).xyz(),
367  acc_rsd.atom(base ).xyz(),
368  acc_rsd.atom(base2).xyz(),
369  unweighted_energy, evaluate_derivative, derivs);
370 
371  if (unweighted_energy >= MAX_HB_ENERGY) continue;
372 
373  Real environmental_weight
374  (!hbond_set.hbond_options().use_hb_env_dep() ? 1 :
375  get_environment_dependent_weight(hbe_type, don_nb, acc_nb, hbond_set.hbond_options()));
376 
377  //////
378  // now we have identified a hbond -> append it into the hbond_set
379  hbond_set.append_hbond( hatm, don_rsd, aatm, acc_rsd,
380  hbe_type, unweighted_energy, environmental_weight, derivs );
381 
382  //////
383 
384  } // loop over acceptors
385  } // loop over donors
386 }
387 
388 void
390  HBondDatabase const & database,
391  conformation::Residue const & don_rsd,
392  conformation::Residue const & acc_rsd,
393  Size const don_nb,
394  Size const acc_nb,
395  bool const evaluate_derivative,
396  bool const exclude_bb, /* exclude if acc=bb and don=bb */
397  bool const exclude_bsc, /* exclude if acc=bb and don=sc */
398  bool const exclude_scb, /* exclude if acc=sc and don=bb */
399  bool const exclude_sc, /* exclude if acc=sc and don=sc */
400  HBondOptions const & options,
401  // output
402  EnergyMap & emap
403 )
404 {
405  assert( don_rsd.seqpos() != acc_rsd.seqpos() );
406 
407  // <f1,f2> -- derivative vectors
408  //std::pair< Vector, Vector > deriv( Vector(0.0), Vector(0.0 ) );
409  HBondDerivs derivs;
410 
411  for ( chemical::AtomIndices::const_iterator
412  hnum = don_rsd.Hpos_polar().begin(), hnume = don_rsd.Hpos_polar().end();
413  hnum != hnume; ++hnum ) {
414  Size const hatm( *hnum );
415  Size const datm(don_rsd.atom_base(hatm));
416  bool datm_is_bb = don_rsd.atom_is_backbone(datm);
417 
418  if (datm_is_bb){
419  if (exclude_bb && exclude_scb) continue;
420  } else {
421  if (exclude_sc && exclude_bsc) continue;
422  }
423  Vector const & hatm_xyz(don_rsd.atom(hatm).xyz());
424  Vector const & datm_xyz(don_rsd.atom(datm).xyz());
425 
426  for ( chemical::AtomIndices::const_iterator
427  anum = acc_rsd.accpt_pos().begin(), anume = acc_rsd.accpt_pos().end();
428  anum != anume; ++anum ) {
429  Size const aatm( *anum );
430  if (acc_rsd.atom_is_backbone(aatm)){
431  if (datm_is_bb){
432  if (exclude_bb) continue;
433  } else {
434  if (exclude_bsc) continue;
435  }
436  } else {
437  if (datm_is_bb){
438  if (exclude_scb) continue;
439  } else {
440  if (exclude_sc) continue;
441  }
442  }
443 
444  // rough filter for existance of hydrogen bond
445  if ( hatm_xyz.distance_squared( acc_rsd.xyz( aatm ) ) > MAX_R2 ) continue;
446 
447  Real unweighted_energy( 0.0 );
448 
449  HBEvalTuple hbe_type( datm, don_rsd, aatm, acc_rsd);
450 
451  int const base ( acc_rsd.atom_base( aatm ) );
452  int const base2( acc_rsd.abase2( aatm ) );
453  assert( base2 > 0 && base != base2 );
454 
455  hb_energy_deriv( database, options, hbe_type, datm_xyz, hatm_xyz,
456  acc_rsd.atom(aatm ).xyz(),
457  acc_rsd.atom(base ).xyz(),
458  acc_rsd.atom(base2).xyz(),
459  unweighted_energy, evaluate_derivative, derivs);
460 
461  if (unweighted_energy >= MAX_HB_ENERGY) continue;
462 
463  Real environmental_weight
464  (!options.use_hb_env_dep() ? 1 :
465  get_environment_dependent_weight(hbe_type, don_nb, acc_nb, options));
466 
467  ////////
468  // now we have identified an hbond -> accumulate its energy
469 
470  Real hbE = unweighted_energy /*raw energy*/ * environmental_weight /*env-dep-wt*/;
471  switch(get_hbond_weight_type(hbe_type.eval_type())){
472  case hbw_NONE:
473  case hbw_SR_BB:
474  emap[hbond_sr_bb] += hbE; break;
475  case hbw_LR_BB:
476  emap[hbond_lr_bb] += hbE; break;
477  case hbw_SR_BB_SC:
478  //Note this is double counting if both hbond_bb_sc and hbond_sr_bb_sc have nonzero weight!
479  emap[hbond_bb_sc] += hbE;
480  emap[hbond_sr_bb_sc] += hbE; break;
481  case hbw_LR_BB_SC:
482  //Note this is double counting if both hbond_bb_sc and hbond_sr_bb_sc have nonzero weight!
483  emap[hbond_bb_sc] += hbE;
484  emap[hbond_lr_bb_sc] += hbE; break;
485  case hbw_SC:
486  emap[hbond_sc] += hbE; break;
487  default:
488  tr << "Warning: energy from unexpected HB type ignored "
489  << hbe_type.eval_type() << std::endl;
490  runtime_assert(false);
491  break;
492  }
493  /////////
494 
495  } // loop over acceptors
496  } // loop over donors
497 }
498 
499 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
500 
501 void
503  HBondDatabase const & database,
504  conformation::Residue const & rsd,
505  bool const evaluate_derivative,
506  HBondSet & hbond_set
507 )
508 {
509 
510  if(rsd.is_RNA()==false) return;
511 
512  if(hbond_set.hbond_options().include_intra_res_RNA()==false) return;
513 
514  // <f1,f2> -- derivative vectors
515  //std::pair< Vector, Vector > deriv( Vector(0.0), Vector(0.0 ) );
516  HBondDerivs derivs;
517 
518  //Assume use_hb_env_dep==False!
519  //Right now RNA specific. Include only hydrogen bonds between the base and the phosphate. June 22, 2011 Parin S.
520  //Since there is no DONOR on the phosphate, this means that datm needs to be on the base and the aatm is on the phosphate
521 
522  for ( chemical::AtomIndices::const_iterator anum = rsd.accpt_pos().begin(), anume = rsd.accpt_pos().end(); anum != anume; ++anum ) {
523 
524  Size const aatm( *anum );
525  int const base ( rsd.atom_base( aatm ) ); //"base" does not refer to RNA base here!
526  int const base2( rsd.abase2( aatm ) );
527  assert( base2 > 0 && base != base2 );
528 
529  if( rsd.RNA_type().atom_is_phosphate(aatm)==false) continue;
530 
531  if( rsd.is_virtual(aatm) ) continue; //Is this necessary?
532 
533  for ( chemical::AtomIndices::const_iterator hnum = rsd.Hpos_polar().begin(), hnume = rsd.Hpos_polar().end(); hnum != hnume; ++hnum ) {
534  Size const hatm( *hnum );
535  Size const datm(rsd.atom_base(hatm));
536 
537  if( rsd.RNA_type().is_RNA_base_atom( datm )==false ) continue;
538 
539  if( rsd.path_distance( aatm, datm ) < 4) utility_exit_with_message("rsd.path_distance(aatm, datm) < 4"); //consistency check
540 
541  if(rsd.is_virtual(hatm) ) continue; //Is this necessary?
542  if(rsd.is_virtual(datm) ) continue; //Is this necessary?
543 
544  Vector const & hatm_xyz( rsd.atom(hatm).xyz());
545  Vector const & datm_xyz( rsd.atom(datm).xyz());
546 
547  // rough filter for existance of hydrogen bond
548  if ( hatm_xyz.distance_squared( rsd.xyz( aatm ) ) > MAX_R2 ) continue;
549 
550  Real unweighted_energy( 0.0 );
551 
552  HBEvalTuple hbe_type( datm, rsd, aatm, rsd);
553 
554  hb_energy_deriv( database, hbond_set.hbond_options(),
555  hbe_type, datm_xyz, hatm_xyz,
556  rsd.atom(aatm ).xyz(),
557  rsd.atom(base ).xyz(),
558  rsd.atom(base2).xyz(),
559  unweighted_energy, evaluate_derivative, derivs);
560 
561  if (unweighted_energy >= MAX_HB_ENERGY) continue;
562 
563  Real environmental_weight=1;
564 
565  // now we have identified a hbond -> upt it into the hbond_set//////
566  hbond_set.append_hbond( hatm, rsd, aatm, rsd, hbe_type, unweighted_energy, environmental_weight, derivs );
567  ///
568 
569  } // loop over donors
570  } // loop over acceptors
571 }
572 
573 
574 
575 void
577  HBondDatabase const & database,
578  conformation::Residue const & rsd,
579  bool const evaluate_derivative,
580  HBondOptions const & options,
581  EnergyMap & emap){
582 
583  if(rsd.is_RNA()==false) return;
584 
585  if(options.include_intra_res_RNA()==false) return;
586 
587  // <f1,f2> -- derivative vectors
588  //std::pair< Vector, Vector > deriv( Vector(0.0), Vector(0.0 ) );
589  HBondDerivs derivs;
590 
591  //Assume use_hb_env_dep==False!
592  //Right now RNA specific. Include only hydrogen bonds between the base and the phosphate. June 22, 2011 Parin S.
593  //Since there is no DONOR on the phosphate, this means that datm needs to be on the base and the aatm is on the phosphate
594 
595  for ( chemical::AtomIndices::const_iterator anum = rsd.accpt_pos().begin(), anume = rsd.accpt_pos().end(); anum != anume; ++anum ) {
596 
597  Size const aatm( *anum );
598  int const base ( rsd.atom_base( aatm ) ); //"base" does not refer to RNA base here!
599  int const base2( rsd.abase2( aatm ) );
600  assert( base2 > 0 && base != base2 );
601 
602  if( rsd.RNA_type().atom_is_phosphate(aatm)==false) continue;
603 
604  if( rsd.is_virtual(aatm) ) continue; //Is this necessary?
605 
606  for ( chemical::AtomIndices::const_iterator hnum = rsd.Hpos_polar().begin(), hnume = rsd.Hpos_polar().end(); hnum != hnume; ++hnum ) {
607  Size const hatm( *hnum );
608  Size const datm(rsd.atom_base(hatm));
609 
610  if( rsd.RNA_type().is_RNA_base_atom( datm )==false ) continue;
611 
612  if( rsd.path_distance( aatm, datm ) < 4) utility_exit_with_message("rsd.path_distance(aatm, datm) < 4"); //consistency check
613 
614  if(rsd.is_virtual(hatm) ) continue; //Is this necessary?
615  if(rsd.is_virtual(datm) ) continue; //Is this necessary?
616 
617  Vector const & hatm_xyz( rsd.atom(hatm).xyz());
618  Vector const & datm_xyz( rsd.atom(datm).xyz());
619 
620  // rough filter for existance of hydrogen bond
621  if ( hatm_xyz.distance_squared( rsd.xyz( aatm ) ) > MAX_R2 ) continue;
622 
623  Real unweighted_energy( 0.0 );
624 
625  HBEvalTuple hbe_type( datm, rsd, aatm, rsd);
626 
627  hb_energy_deriv( database, options,
628  hbe_type, datm_xyz, hatm_xyz,
629  rsd.atom(aatm ).xyz(),
630  rsd.atom(base ).xyz(),
631  rsd.atom(base2).xyz(),
632  unweighted_energy, evaluate_derivative, derivs);
633 
634  if (unweighted_energy >= MAX_HB_ENERGY) continue;
635 
636  Real environmental_weight=1;
637 
638  Real hbE = unweighted_energy * environmental_weight;
639 
640  emap[hbond_intra] += hbE;
641 
642  } // loop over donors
643  } // loop over acceptors
644 }
645 
646 
647 void
649  HBondDatabase const & database,
650  conformation::Residue const & don_rsd,
651  conformation::Residue const & acc_rsd,
652  Size const don_nb,
653  Size const acc_nb,
654  bool const evaluate_derivative,
655  bool const exclude_bb, /* exclude if acc=bb and don=bb */
656  bool const exclude_bsc, /* exclude if acc=bb and don=sc */
657  bool const exclude_scb, /* exclude if acc=sc and don=bb */
658  bool const exclude_sc, /* exclude if acc=sc and don=sc */
659  // output
660  HBondSet & hbond_set,
661  pose::Pose const & pose
662 ){
663  assert( don_rsd.seqpos() != acc_rsd.seqpos() );
664 
665  //pbadebug
666  //std::cout << "entered in identify_hbonds_1way_membrane() " << std::endl;
667 
668  // <f1,f2> -- derivative vectors
669  //std::pair< Vector, Vector > deriv( Vector(0.0), Vector(0.0 ) );
670  HBondDerivs derivs;
671 
672  for ( chemical::AtomIndices::const_iterator
673  hnum = don_rsd.Hpos_polar().begin(), hnume = don_rsd.Hpos_polar().end();
674  hnum != hnume; ++hnum ) {
675  Size const hatm( *hnum );
676  Size const datm(don_rsd.atom_base(hatm));
677  bool datm_is_bb = don_rsd.atom_is_backbone(datm);
678 
679  if (datm_is_bb){
680  if (exclude_bb && exclude_scb) continue;
681  } else {
682  if (exclude_sc && exclude_bsc) continue;
683  }
684  Vector const & hatm_xyz(don_rsd.atom(hatm).xyz());
685  Vector const & datm_xyz(don_rsd.atom(datm).xyz());
686 
687  for ( chemical::AtomIndices::const_iterator
688  anum = acc_rsd.accpt_pos().begin(), anume = acc_rsd.accpt_pos().end();
689  anum != anume; ++anum ) {
690  Size const aatm( *anum );
691  if (acc_rsd.atom_is_backbone(aatm)){
692  if (datm_is_bb){
693  if (exclude_bb) continue;
694  } else {
695  if (exclude_bsc) continue;
696  }
697  } else {
698  if (datm_is_bb){
699  if (exclude_scb) continue;
700  } else {
701  if (exclude_sc) continue;
702  }
703  }
704 
705  // rough filter for existance of hydrogen bond
706  if ( hatm_xyz.distance_squared( acc_rsd.xyz( aatm ) ) > MAX_R2 ) continue;
707 
708  Real unweighted_energy( 0.0 );
709 
710  HBEvalTuple hbe_type( datm, don_rsd, aatm, acc_rsd);
711 
712  int const base ( acc_rsd.atom_base( aatm ) );
713  int const base2( acc_rsd.abase2( aatm ) );
714  assert( base2 > 0 && base != base2 );
715 
716 
717  hb_energy_deriv( database, hbond_set.hbond_options(),
718  hbe_type, datm_xyz, hatm_xyz,
719  acc_rsd.atom(aatm ).xyz(),
720  acc_rsd.atom(base ).xyz(),
721  acc_rsd.atom(base2).xyz(),
722  unweighted_energy, evaluate_derivative, derivs);
723 
724  if (unweighted_energy >= MAX_HB_ENERGY) continue;
725 
726  //pba membrane depth dependent correction to the environmental_weight
727  Real environmental_weight(
728  get_membrane_depth_dependent_weight(pose, don_nb, acc_nb, hatm_xyz,
729  acc_rsd.atom(aatm ).xyz()));
730 
731  //////
732  // now we have identified a hbond -> put it into the hbond_set
733 
734  hbond_set.append_hbond( hatm, don_rsd, aatm, acc_rsd,
735  hbe_type, unweighted_energy, environmental_weight, derivs );
736 
737  //////
738 
739  } // loop over acceptors
740  } // loop over donors
741 }
742 
743 void
745  HBondDatabase const & database,
746  conformation::Residue const & don_rsd,
747  conformation::Residue const & acc_rsd,
748  Size const don_nb,
749  Size const acc_nb,
750  bool const evaluate_derivative,
751  bool const exclude_bb, /* exclude if acc=bb and don=bb */
752  bool const exclude_bsc, /* exclude if acc=bb and don=sc */
753  bool const exclude_scb, /* exclude if acc=sc and don=bb */
754  bool const exclude_sc, /* exclude if acc=sc and don=sc */
755  HBondOptions const & options,
756  // output
757  EnergyMap & emap,
758  pose::Pose const & pose
759 )
760 {
761  assert( don_rsd.seqpos() != acc_rsd.seqpos() );
762 
763  // <f1,f2> -- derivative vectors
764  //std::pair< Vector, Vector > deriv( Vector(0.0), Vector(0.0 ) );
765  HBondDerivs derivs;
766 
767  for ( chemical::AtomIndices::const_iterator
768  hnum = don_rsd.Hpos_polar().begin(), hnume = don_rsd.Hpos_polar().end();
769  hnum != hnume; ++hnum ) {
770  Size const hatm( *hnum );
771  Size const datm(don_rsd.atom_base(hatm));
772  bool datm_is_bb = don_rsd.atom_is_backbone(datm);
773 
774  if (datm_is_bb){
775  if (exclude_bb && exclude_scb) continue;
776  } else {
777  if (exclude_sc && exclude_bsc) continue;
778  }
779  Vector const & hatm_xyz(don_rsd.atom(hatm).xyz());
780  Vector const & datm_xyz(don_rsd.atom(datm).xyz());
781 
782  for ( chemical::AtomIndices::const_iterator
783  anum = acc_rsd.accpt_pos().begin(), anume = acc_rsd.accpt_pos().end();
784  anum != anume; ++anum ) {
785  Size const aatm( *anum );
786  if (acc_rsd.atom_is_backbone(aatm)){
787  if (datm_is_bb){
788  if (exclude_bb) continue;
789  } else {
790  if (exclude_bsc) continue;
791  }
792  } else {
793  if (datm_is_bb){
794  if (exclude_scb) continue;
795  } else {
796  if (exclude_sc) continue;
797  }
798  }
799 
800  // rough filter for existance of hydrogen bond
801  if ( hatm_xyz.distance_squared( acc_rsd.xyz( aatm ) ) > MAX_R2 ) continue;
802 
803  Real unweighted_energy( 0.0 );
804 
805  HBEvalTuple hbe_type( datm, don_rsd, aatm, acc_rsd);
806 
807  int const base ( acc_rsd.atom_base( aatm ) );
808  int const base2( acc_rsd.abase2( aatm ) );
809  assert( base2 > 0 && base != base2 );
810 
811  hb_energy_deriv( database, options,
812  hbe_type, datm_xyz, hatm_xyz,
813  acc_rsd.atom(aatm ).xyz(),
814  acc_rsd.atom(base ).xyz(),
815  acc_rsd.atom(base2).xyz(),
816  unweighted_energy, evaluate_derivative, derivs);
817 
818  if (unweighted_energy >= MAX_HB_ENERGY) continue;
819 
820  //pba membrane depth dependent weight
821 
822  Real environmental_weight(
823  get_membrane_depth_dependent_weight(pose, don_nb, acc_nb, hatm_xyz,
824  acc_rsd.atom(aatm ).xyz()));
825 
826  ////////
827  // now we have identified an hbond -> accumulate its energy
828 
829  Real hbE = unweighted_energy /*raw energy*/ * environmental_weight /*env-dep-wt*/;
830  switch(get_hbond_weight_type(hbe_type.eval_type())){
831  case hbw_NONE:
832  case hbw_SR_BB:
833  emap[hbond_sr_bb] += hbE; break;
834  case hbw_LR_BB:
835  emap[hbond_lr_bb] += hbE; break;
836  case hbw_SR_BB_SC:
837  //Note this is double counting if both hbond_bb_sc and hbond_sr_bb_sc have nonzero weight!
838  emap[hbond_bb_sc] += hbE;
839  emap[hbond_sr_bb_sc] += hbE; break;
840  case hbw_LR_BB_SC:
841  //Note this is double counting if both hbond_bb_sc and hbond_sr_bb_sc have nonzero weight!
842  emap[hbond_bb_sc] += hbE;
843  emap[hbond_lr_bb_sc] += hbE; break;
844  case hbw_SC:
845  emap[hbond_sc] += hbE; break;
846  default:
847  tr << "Warning: energy from unexpected HB type ignored "
848  << hbe_type.eval_type() << std::endl;
849  runtime_assert(false);
850  break;
851  }
852  /////////
853 
854  } // loop over acceptors
855  } // loop over donors
856 }
857 
858 
859 
860 //mjo this should be the only way to assign hbond energies. If you
861 //feel the need to collect the energies from some of the bonds,
862 //consider filtering the hbond set instead. Don't assign energies for
863 //"special cases" with other functions, add cases to the HBEvalType
864 //instead.
865 
866 void
868  HBondSet const & hbond_set,
869  EnergyMap & emap
870 )
871 {
872  for (Size i = 1; i <= hbond_set.nhbonds(); ++i){
873  if (!hbond_set.allow_hbond(i)) continue;
874 
875  HBond const & hbond(hbond_set.hbond(i));
876  HBEvalType const hbe_type = hbond.eval_type();
877 
878  Real hbE = hbond.energy() /*raw energy*/ * hbond.weight() /*env-dep-wt*/;
879 
880  switch(get_hbond_weight_type(hbe_type)){
881  case hbw_NONE:
882  case hbw_SR_BB:
883  emap[hbond_sr_bb] += hbE; break;
884  case hbw_LR_BB:
885  emap[hbond_lr_bb] += hbE; break;
886  case hbw_SR_BB_SC:
887  //Note this is double counting if both hbond_bb_sc and hbond_sr_bb_sc have nonzero weight!
888  emap[hbond_bb_sc] += hbE;
889  emap[hbond_sr_bb_sc] += hbE; break;
890  case hbw_LR_BB_SC:
891  //Note this is double counting if both hbond_bb_sc and hbond_sr_bb_sc have nonzero weight!
892  emap[hbond_bb_sc] += hbE;
893  emap[hbond_lr_bb_sc] += hbE; break;
894  case hbw_SC:
895  emap[hbond_sc] += hbE; break;
896  default:
897  tr << "Warning: energy from unexpected HB type ignored "
898  << hbond << std::endl;
899  runtime_assert(false);
900  break;
901  }
902  }
903 }
904 
905 // this overloads get_hbond_energies to take an EnergyMap because
906 // EnergyMap and EnergyMap cannot be substituted efficiently
907 /*
908 void
909 get_hbond_energies(
910  HBondSet const & hbond_set,
911  EnergyMap & emap)
912 {
913  for (Size i = 1; i <= hbond_set.nhbonds(); ++i){
914  if (!hbond_set.allow_hbond(i)) continue;
915 
916  HBond const & hbond(hbond_set.hbond(i));
917  HBEvalType const hbe_type = hbond.eval_type();
918  // raw energy * env-dep-wt
919  Real hbE = hbond.energy() * hbond.weight();
920 
921  switch(get_hbond_weight_type(hbe_type)){
922  case hbw_NONE:
923  case hbw_SR_BB:
924  emap[hbond_sr_bb] += hbE; break;
925  case hbw_LR_BB:
926  emap[hbond_lr_bb] += hbE; break;
927  case hbw_SR_BB_SC:
928  //Note this is double counting if both hbond_bb_sc and hbond_sr_bb_sc have nonzero weight!
929  emap[hbond_bb_sc] += hbE;
930  emap[hbond_sr_bb_sc] += hbE; break;
931  case hbw_LR_BB_SC:
932  //Note this is double counting if both hbond_bb_sc and hbond_sr_bb_sc have nonzero weight!
933  emap[hbond_bb_sc] += hbE;
934  emap[hbond_lr_bb_sc] += hbE; break;
935  case hbw_SC:
936  emap[hbond_sc] += hbE; break;
937  default:
938  tr << "Warning: energy from unexpected HB type ignored "
939  << hbond << std::endl;
940  runtime_assert(false);
941  break;
942  }
943  }
944 }
945 */
946 
947 Real
949  HBEvalType const & hbe_type,
950  EnergyMap const & emap,
951  bool const intra_res /*false*/)
952 {
953  Real weight(0.0);
954 
955  if(intra_res){
956 
957  weight= emap[hbond_intra];
958 
959  }else{
960 
961  switch(get_hbond_weight_type(hbe_type)){
962  case hbw_NONE:
963  case hbw_SR_BB:
964  weight += emap[hbond_sr_bb]; break;
965  case hbw_LR_BB:
966  weight += emap[hbond_lr_bb]; break;
967  case hbw_SR_BB_SC:
968  //Note this is double counting if both hbond_bb_sc and hbond_sr_bb_sc have nonzero weight!
969  weight += emap[hbond_bb_sc];
970  weight += emap[hbond_sr_bb_sc]; break;
971  case hbw_LR_BB_SC:
972  //Note this is double counting if both hbond_bb_sc and hbond_sr_bb_sc have nonzero weight!
973  weight += emap[hbond_bb_sc];
974  weight += emap[hbond_lr_bb_sc]; break;
975  case hbw_SC:
976  weight += emap[hbond_sc]; break;
977  default:
978  tr << "Warning: Unexpected HBondWeightType " << get_hbond_weight_type(hbe_type) << std::endl;
979  runtime_assert(false);
980  break;
981  }
982  }
983 
984  return weight;
985 }
986 
987 
988 ///////////////////////////////////////////////////////////////////////////////
989 ///////////////////////////////////////////////////////////////////////////////
990 // functions for environment-dependent weighting
991 ///////////////////////////////////////////////////////////////////////////////
992 ///////////////////////////////////////////////////////////////////////////////
993 
994 ////////////////////////
995 // lin jiang's approach:
996 
997 //JSS note: this is half of the weight from one atom;
998 // the burial weight is the sum from donor and acceptor.
999 inline core::Real
1000 burial_weight(int const nb)
1001 {
1002  if ( nb < 7 ) return 0.1;
1003  if ( nb > 24 ) return 0.5;
1004  return (nb-2.75)*(0.5/21.25);
1005 }
1006 
1007 core::Real
1008 hb_env_dep_burial_lin(int const nb1, int const nb2)
1009 {
1010  return (burial_weight(nb1) + burial_weight(nb2));
1011 }
1012 
1013 ////////////////////////////
1014 // tanja kortemme's approach
1015 
1016 void
1018 {
1019  burial( 1, 1 ) = 0.2 ; burial( 1, 2 ) = 0.2 ; burial( 1, 3 ) = 0.55;
1020  burial( 2, 1 ) = 0.2 ; burial( 2, 2 ) = 0.55; burial( 2, 3 ) = 1.0 ;
1021  burial( 3, 1 ) = 0.55; burial( 3, 2 ) = 1.0 ; burial( 3, 3 ) = 1.0 ;
1022 }
1023 
1024 inline int
1026  int const neighbors,
1027  int const threshold_1,
1028  int const threshold_3
1029 )
1030 {
1031  //tk get burial measure, three possible classes:
1032  //tk 1: exposed, 2: intermediate, 3:buried
1033  if ( neighbors > threshold_1 ) {
1034  if ( neighbors >= threshold_3 ) return 3;
1035  else return 2;
1036  }
1037  else return 1;
1038 }
1039 
1040 core::Real
1041 hb_env_dep_burial_tk(int const nb1, int const nb2)
1042 {
1043  //tk assign weight based on CB neighbors of two interacting residues
1044 
1045  // local
1046  int const exposed_threshold = { 10 };
1047  int const buried_threshold = { 20 };
1048 
1049  static FArray2D_double const burial3class_weight
1051 
1052  return burial3class_weight(
1053  get_burial_3( nb1, exposed_threshold, buried_threshold ),
1054  get_burial_3( nb2, exposed_threshold, buried_threshold ) );
1055 }
1056 
1057 ///////////////////////////////////////////////////////////////////////////////
1058 Real
1060  HBEvalTuple const & hbe_type,
1061  int const don_nb,
1062  int const acc_nb,
1063  HBondOptions const & options
1064 )
1065 {
1066  Real weight( 1.0 );
1067  // mjo why is this only applied to side chains!!!!
1068  if ( hbe_is_SC_type(hbe_type.eval_type()) ) {
1069  if ( options.smooth_hb_env_dep() ) {
1070  weight = hb_env_dep_burial_lin( acc_nb, don_nb );
1071  } else {
1072  weight = hb_env_dep_burial_tk( acc_nb, don_nb );
1073  }
1074  }
1075  // std::cout << "HB_ENV_WEIGHT: " << weight << std::endl;
1076  return weight;
1077 }
1078 
1079 ///////////////////////////////////////////////////////////////////////////////
1080 Real
1082  pose::Pose const & pose,
1083  int const don_nb,
1084  int const acc_nb,
1085  Vector const & Hxyz, // proton
1086  Vector const & Axyz // acceptor
1087 )
1088 {
1089  Real wat_weight(1.0), memb_weight(1.0), total_weight(1.0);
1090 
1091  // water phase smooth_hb_env_dep
1092  wat_weight = hb_env_dep_burial_lin( acc_nb, don_nb );
1093 
1094  // membrane phase dependent weight
1095  Vector const normal(MembraneEmbed_from_pose( pose ).normal());
1096  Vector const center(MembraneEmbed_from_pose( pose ).center());
1097  Real const thickness(Membrane_FAEmbed_from_pose( pose ).thickness());
1098  Real const steepness(Membrane_FAEmbed_from_pose( pose ).steepness());
1099 
1100  // Hdonor depth
1101  Real fa_depth_H = dot(Hxyz-center, normal);
1102  Real internal_product = std::abs(fa_depth_H);
1103  Real z = internal_product;
1104  z /= thickness;
1105  Real zn = std::pow( z, steepness );
1106  Real fa_proj_H = zn/(1 + zn);
1107 
1108  // Acc depth
1109  Real fa_depth_A = dot(Axyz-center, normal);
1110  internal_product = std::abs(fa_depth_A);
1111  z = internal_product;
1112  z /= thickness;
1113  zn = std::pow( z, steepness );
1114  Real fa_proj_A = zn/(1 + zn);
1115 
1116  Real fa_proj_AH = 0.5*(fa_proj_H+fa_proj_A);
1117  total_weight = fa_proj_AH * wat_weight + (1-fa_proj_AH) * memb_weight;
1118 
1119  //pbadebug
1120  //std::cout << "tot " << total_weight << " wat " << wat_weight << " memb " << memb_weight << " proj "
1121  //<< fa_proj_AH << std::endl;
1122 
1123  return total_weight;
1124 }
1125 ///////////////////////////////////////////////////////////////////////////////
1126 Real
1128  Vector const & normal,
1129  Vector const & center,
1130  Real const & thickness,
1131  Real const & steepness,
1132  int const don_nb,
1133  int const acc_nb,
1134  Vector const & Hxyz, // proton
1135  Vector const & Axyz // acceptor
1136 )
1137 {
1138  Real wat_weight(1.0), memb_weight(1.0), total_weight(1.0);
1139 
1140  // water phase smooth_hb_env_dep
1141  wat_weight = hb_env_dep_burial_lin( acc_nb, don_nb );
1142 
1143  // membrane phase dependent weight
1144  // Hdonor depth
1145  Real fa_depth_H = dot(Hxyz-center, normal);
1146  Real internal_product = std::abs(fa_depth_H);
1147  Real z = internal_product;
1148  z /= thickness;
1149  Real zn = std::pow( z, steepness );
1150  Real fa_proj_H = zn/(1 + zn);
1151 
1152  // Acc depth
1153  Real fa_depth_A = dot(Axyz-center, normal);
1154  internal_product = std::abs(fa_depth_A);
1155  z = internal_product;
1156  z /= thickness;
1157  zn = std::pow( z, steepness );
1158  Real fa_proj_A = zn/(1 + zn);
1159 
1160  Real fa_proj_AH = 0.5*(fa_proj_H+fa_proj_A);
1161  total_weight = fa_proj_AH * wat_weight + (1-fa_proj_AH) * memb_weight;
1162 
1163  //pbadebug
1164  //std::cout << "tot " << total_weight << " wat " << wat_weight << " memb " << memb_weight << " proj "
1165  //<< fa_proj_AH << std::endl;
1166 
1167  return total_weight;
1168 }
1169 ///////////////////////////////////////////////////////////////////////////////
1170 
1171 bool
1173 {
1174  return ( scorefxn.has_nonzero_weight( hbond_lr_bb ) ||
1175  scorefxn.has_nonzero_weight( hbond_sr_bb ) ||
1176  scorefxn.has_nonzero_weight( hbond_bb_sc ) ||
1177  scorefxn.has_nonzero_weight( hbond_sr_bb_sc ) ||
1178  scorefxn.has_nonzero_weight( hbond_lr_bb_sc ) ||
1179  scorefxn.has_nonzero_weight( hbond_sc ) );
1180 }
1181 
1182 } // hbonds
1183 } // scoring
1184 } // core