Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
HBondSet.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 core/scoring/hbonds/HBondSet.hh
11 /// @brief Hydrogen bond set class implementation
12 /// @author Andrew Leaver-Fay (aleaverfay@gmail.com)
13 
14 // Unit Headers
16 
17 
18 // Package headers
22 #include <core/scoring/Energies.hh>
23 // AUTO-REMOVED #include <core/scoring/EnergyGraph.hh>
25 
26 // Project headers
27 #include <core/pose/Pose.hh>
29 #include <core/id/AtomID.hh>
30 #include <core/pose/PDBInfo.hh>
31 
32 #include <basic/Tracer.hh>
33 
34 // Utility headers
35 //#include <utility/exit.hh>
36 // #include <utility/pointer/access_ptr.hh>
37 #include <utility/pointer/owning_ptr.hh>
38 #include <utility/pointer/ReferenceCount.hh>
39 
40 #include <numeric/xyzVector.hh>
41 #include <numeric/xyz.functions.hh>
42 #include <numeric/conversions.hh>
43 
44 // ObjexxFCL headers
45 #include <ObjexxFCL/format.hh>
46 
47 // C++
48 #include <map> // what is the right header for std::pair ?
49 
50 // option key includes
51 // AUTO-REMOVED #include <utility/options/keys/BooleanOptionKey.hh>
52 
53 #include <utility/vector1.hh>
54 
55 
56 
57 
58 //#include <set>
59 
60 namespace core {
61 namespace scoring {
62 namespace hbonds {
63 
64 /// @details Auto-generated virtual destructor
66 
67 using namespace ObjexxFCL::fmt;
68 
69 static basic::Tracer t("core.scoring.hbonds.HBondSet");
70 
72  Size const dhatm,
73  bool const dhatm_is_protein_backbone,
74  bool const dres_is_protein,
75  bool const dres_is_dna,
76  bool const dhatm_is_backbone,
77  Size const dres,
78  Size const aatm,
79  bool const aatm_is_protein_backbone,
80  bool const ares_is_protein,
81  bool const ares_is_dna,
82  bool const aatm_is_backbone,
83  Size const ares,
84  HBEvalTuple const hbe_tuple,
85  Real const energy_in, // unweighted
86  Real const weight_in,
87  HBondDerivs const & derivs_in
88 ):
89  don_hatm_( dhatm ),
90  don_hatm_is_protein_backbone_( dhatm_is_protein_backbone ),
91  don_res_is_protein_( dres_is_protein ),
92  don_res_is_dna_( dres_is_dna ),
93  don_hatm_is_backbone_( dhatm_is_backbone ),
94  don_res_( dres ),
95  acc_atm_( aatm ),
96  acc_atm_is_protein_backbone_( aatm_is_protein_backbone ),
97  acc_res_is_protein_( ares_is_protein ),
98  acc_res_is_dna_( ares_is_dna ),
99  acc_atm_is_backbone_( aatm_is_backbone ),
100  acc_res_( ares ),
101  eval_tuple_( hbe_tuple ),
102  energy_( energy_in ),
103  weight_( weight_in ),
104  derivs_( derivs_in )
105 {}
106 
107 ///
108 Size
110 {
111  return don_res_;
112 }
113 
114 ///
115 Size
117 {
118  return don_hatm_;
119 }
120 
121 /// needed for silly allow logic
122 bool
124 {
126 }
127 
128 bool
130 {
131  return don_res_is_protein_;
132 }
133 
134 bool
136 {
137  return don_res_is_dna_;
138 }
139 
140 /// needed for silly allow logic
141 bool
143 {
144  return don_hatm_is_backbone_;
145 }
146 
147 ///
148 Size
150 {
151  return acc_res_;
152 }
153 
154 ///
155 Size
157 {
158  return acc_atm_;
159 }
160 
161 /// needed for silly allow logic
162 bool
164 {
166 }
167 
168 bool
170 {
171  return acc_res_is_protein_;
172 }
173 
174 bool
176 {
177  return acc_res_is_dna_;
178 }
179 
180 /// needed for silly allow logic
181 bool
183 {
184  return acc_atm_is_backbone_;
185 }
186 
187 /// NOTE: this is unweighted energy, see weight() for the weight
188 Real
190 {
191  return energy_;
192 }
193 
194 ///
195 Real
197 {
198  return weight_;
199 }
200 
201 
202 HBondDerivs const &
204 {
205  return derivs_;
206 }
207 
208 ///
211 {
212  return eval_tuple_.eval_type();
213 }
214 
215 ///
216 HBEvalTuple const &
218 {
219  return eval_tuple_;
220 }
221 
222 
223 ///
224 bool
225 HBond::atom_is_donorH( id::AtomID const & atom ) const
226 {
227  return ( atom.rsd() == don_res_ && atom.atomno() == don_hatm_ );
228 }
229 
230 
231 ///
232 bool
233 HBond::atom_is_acceptor( id::AtomID const & atom ) const
234 {
235  return ( atom.rsd() == acc_res_ && atom.atomno() == acc_atm_ );
236 }
237 
238 ///////////////////////////////////////////////////////////////////////////////
239 bool
241 {
242  return ( a->energy() * a->weight() < b->energy() * b->weight() );
243 }
244 
245 ///
246 void
247 HBond::show( std::ostream & out ) const
248 {
249  out << eval_tuple_.eval_type() << " ";
250  out << "don: ";
251  out << (don_res_is_protein_ ? "protein " : "");
252  out << (don_hatm_is_protein_backbone_ ? "backbone " : "");
253  out << (don_res_is_dna_ ? "dna " : "");
254  out << don_res_ << " ";
255  out << don_hatm_ << " ";
256  out << "acc: ";
257  out << (acc_res_is_protein_ ? "protein " : "");
258  out << (acc_atm_is_backbone_ ? "backbone " : "");
259  out << (acc_res_is_dna_ ? "dna " : "");
260  out << acc_res_ << " ";
261  out << acc_atm_ << " ";
262  out << energy_ << " ";
263  out << weight_ << std::endl;
264  //out << deriv_ << std::endl;
265 }
266 
267 void
269  pose::Pose const & pose,
270  bool print_header,
271  std::ostream & out
272 ) const {
273 
274  if(print_header){
275  out
276  << "#Dch Dn Dres Da Ach An Ares Aa length AHDang BAHang BAtor weight energy"
277  << std::endl;
278  }
279 
280  char const don_pdb_chain(pose.pdb_info()->chain(don_res()));
281  Size const don_pdb_number(pose.pdb_info()->number(don_res()));
282  char const don_pdb_icode(pose.pdb_info()->icode(don_res()));
283  Size const don_atomno(pose.residue(don_res()).atom_base(don_hatm()));
284  std::string const don_res_name(pose.residue(don_res()).type().name3());
285  std::string const don_atom_name(pose.residue(don_res()).atom_name(don_atomno));
286 
287  Size const acc_pdb_chain(pose.pdb_info()->chain(acc_res()));
288  Size const acc_pdb_number(pose.pdb_info()->number(acc_res()));
289  char const acc_pdb_icode(pose.pdb_info()->icode(acc_res()));
290  Size const base_atomno(pose.residue(acc_res()).atom_base(acc_atm()));
291  Size const bbase_atomno(pose.residue(acc_res()).atom_base(base_atomno));
292  std::string const acc_res_name(pose.residue(acc_res()).type().name3());
293  std::string const acc_atom_name(pose.residue(acc_res()).atom_name(acc_atm()));
294 
295  PointPosition const Dxyz(pose.residue(don_res()).xyz(don_atomno));
296  PointPosition const Hxyz(pose.residue(don_res()).xyz(don_hatm()));
297  PointPosition const Axyz(pose.residue(acc_res()).xyz(acc_atm()));
298  PointPosition const Bxyz(pose.residue(acc_res()).xyz(base_atomno));
299  PointPosition const BBxyz(pose.residue(acc_res()).xyz(bbase_atomno));
300 
301  Real const HAdist(Hxyz.distance(Axyz));
302  Real const AHDangle(numeric::angle_degrees(Axyz, Hxyz, Dxyz));
303  Real const BAHangle(numeric::angle_degrees(Bxyz, Axyz, Hxyz));
304  Real const BAtorsion(dihedral_degrees(BBxyz, Bxyz, Axyz, Hxyz));
305 
306  // In the pdb format, a residue is uniquely identified by
307  // the chain, the residue number and the insertion code
308  out
309  << "#"
310 
311  // donor site
312  << A(1, don_pdb_chain) << I(5, don_pdb_number) << A(1, don_pdb_icode)
313  << I(4, don_res_name) << I(5, don_atom_name)
314 
315  // acceptor site
316  << A(1, acc_pdb_chain) << I(5, acc_pdb_number) << A(1, acc_pdb_icode)
317  << I(4, acc_res_name) << I(5, acc_atom_name)
318 
319  // bond geometry:
320  << F(6, 2, HAdist)
321 
322  // These angles are go from [0, 180] in degrees
323  << F(7, 1, AHDangle) << F(7, 1, BAHangle)
324 
325  // The axis of rotation is around the base-acceptor bond and the
326  // zero angle in the plane of the base of the base of the
327  // acceptor. [-180, 180] in degrees.
328  << F(7, 1, BAtorsion)
329 
330  // The hbond score function weight and energy
331  << F(7, 3, weight()) << F(7, 3, energy()) << std::endl;
332 }
333 
334 
335 
336 std::ostream &
337 operator<< ( std::ostream & out, const HBond & hbond ){
338  hbond.show( out );
339  return out;
340 }
341 
342 ///
343 bool
344 operator==(HBond const & a, HBond const & b)
345 {
346  return (
351  a.don_res_ == b.don_res_ &&
352  a.acc_atm_ == b.acc_atm_ &&
357  a.acc_res_ == b.acc_res_ &&
358  a.eval_tuple_ == b.eval_tuple_ &&
359  a.energy_ == b.energy_ &&
360  a.weight_ == b.weight_ ); /*&&
361  a.deriv_.first[0] == b.deriv_.first[0] &&
362  a.deriv_.first[1] == b.deriv_.first[1] &&
363  a.deriv_.first[2] == b.deriv_.first[2] &&
364  a.deriv_.second[0] == b.deriv_.second[0] &&
365  a.deriv_.second[1] == b.deriv_.second[1] &&
366  a.deriv_.second[2] == b.deriv_.second[2] );*/
367 }
368 
369 
370 
371 
372 
373 
375  options_( new HBondOptions() ),
376  atom_map_init_( false )
377 {}
378 
380 
381 HBondSet::HBondSet( Size const nres ):
382  options_( new HBondOptions() ),
383  atom_map_init_( false )
384 {
386 }
387 
388 
389 // Note that the following constructors are duplicated to prevent
390 // automatic casting. Since owning-ptr is castible to Size and the
391 // above constructor takes a Size, automatic casting would
392 // ambiguous.
394  options_( new HBondOptions( opts ) ),
395  atom_map_init_( false )
396 {}
397 
398 HBondSet::HBondSet( HBondOptions const & opts, Size const nres):
399  options_( new HBondOptions( opts ) ),
400  atom_map_init_( false )
401 {
403 }
404 
405 ///@brief convenience constructor. If you need more controlled
406 ///construction please use one of the other constructors
407 ///
408 /// The pose must be non-const because the neighbor graph may need to
409 /// be initialized.
411  pose::Pose & pose ) :
412  options_(new HBondOptions()),
413  atom_map_init_(false)
414 {
416  setup_for_residue_pair_energies(pose, false);
417 }
418 
419 ///@brief convenience constructor. If you need more controlled
420 ///construction please use one of the other constructors
421 ///
422 /// The pose must be non-const because the neighbor graph may need to
423 /// be initialized.
425  HBondOptions const & opts,
426  pose::Pose & pose) :
427  options_( new HBondOptions(opts)),
428  atom_map_init_(false)
429 {
431  setup_for_residue_pair_energies(pose, false);
432 }
433 
434 
435 /// copy ctor
437  basic::datacache::CacheableData(),
438  options_( new HBondOptions( *src.options_ ))
439 {
440  for ( Size i=1; i<= src.hbonds_.size(); ++i ) {
441  hbonds_.push_back( new HBond( *src.hbonds_[i] ) );
442  }
445  nbrs_ = src.nbrs_;
446  // set this flag since we still have to setup the atommap
447  atom_map_init_ = false;
448 }
449 
450 /// copy ctor
452  basic::datacache::CacheableData(),
453  options_( new HBondOptions( *src.options_ ))
454 {
455 
456  bool exclude=false;
457  for ( Size i=1; i<= src.nhbonds(); ++i ) {
458  HBond const & hbond(src.hbond(i));
459  int const dres = hbond.don_res();
460  int const ares = hbond.acc_res();
461  exclude = false;
462  for ( Size k = 1; k <= exclude_list.size(); k ++ ){
463  if( exclude_list[k] == (core::Size)dres ){ exclude = true; break; };
464  if( exclude_list[k] == (core::Size)ares ){ exclude = true; break; };
465  }
466  if( exclude ) continue;
467 
468  hbonds_.push_back( new HBond( *src.hbonds_[i] ) );
469  }
472  nbrs_ = src.nbrs_;
473  // set this flag since we still have to setup the atommap
474  atom_map_init_ = false;
475 }
476 
477 /// copy ctor
479  basic::datacache::CacheableData(),
480  options_( new HBondOptions( *src.options_ ))
481 {
482 
483  //bool exclude=false;
484  for ( Size i=1; i<= src.nhbonds(); ++i ) {
485  HBond const & hbond(src.hbond(i));
486  if(residue_mask[hbond.don_res()] & residue_mask[hbond.acc_res()]){
487  hbonds_.push_back( new HBond( *src.hbonds_[i] ) );
488  }
489  }
492  nbrs_ = src.nbrs_;
493  // set this flag since we still have to setup the atommap
494  atom_map_init_ = false;
495 }
496 
497 
498 
499 /// copy ctor
501  HBondSet const & src,
502  Size seqpos
503 ):
504  basic::datacache::CacheableData(),
505  options_( new HBondOptions( *src.options_ ))
506 {
507  for ( Size i=1; i<= src.nhbonds(); ++i ) {
508  HBond const & hbond(src.hbond(i));
509  if (hbond.don_res() == seqpos || hbond.acc_res() == seqpos ){
510  hbonds_.push_back( new HBond( *src.hbonds_[i] ));
511  }
512  }
515  nbrs_ = src.nbrs_;
516  // set this flag since we still have to setup the atommap
517  atom_map_init_ = false;
518 }
519 
520 
521 /// @brief clone this object
522 basic::datacache::CacheableDataOP
524 {
525  return new HBondSet( *this );
526 }
527 
528 /// \brief Number of hbonds
529 Size
531 {
532  return hbonds_.size();
533 }
534 
535 
536 // for accessing the nbrs, allows hacky non-tenA_nbr count
537 int
538 HBondSet::nbrs( Size const seqpos ) const
539 {
540  return nbrs_[ seqpos ];
541 }
542 
543 void
544 HBondSet::set_nbrs( Size const seqpos, Size value )
545 {
546  nbrs_[ seqpos ] = value;
547 }
548 
549 
550 /// \brief Access hbond
551 HBond const &
552 HBondSet::hbond( Size const number ) const
553 {
554  return *(hbonds_[ number ]);
555 }
556 
557 ///////////////////////////////////////////////////////////////////////////////
558 /// \brief Add a new hbond to the list
559 /// updates the "hbchk" array as necessary
560 void
562  Size const dhatm,
563  conformation::Residue const & don_rsd,
564  Size const aatm,
565  conformation::Residue const & acc_rsd,
566  HBEvalTuple const & hbe_tuple,
567  Real const energy,
568  Real const weight,
569  HBondDerivs const & derivs
570 ){
571  atom_map_init_ = false;
572 
573  // note that the derivative may not have been evaluated
574  bool const dhatm_is_protein_backbone
575  ( don_rsd.is_protein() && don_rsd.atom_is_backbone( dhatm ) );
576  bool const aatm_is_protein_backbone
577  ( acc_rsd.is_protein() && acc_rsd.atom_is_backbone( aatm ) );
578 
579  bool const dhatm_is_backbone
580  ( don_rsd.atom_is_backbone( dhatm ) );
581  bool const aatm_is_backbone
582  ( acc_rsd.atom_is_backbone( aatm ) );
583 
584  Size const don_pos( don_rsd.seqpos() );
585  Size const acc_pos( acc_rsd.seqpos() );
586 
587  hbonds_.push_back( new HBond(
588  dhatm, dhatm_is_protein_backbone, don_rsd.is_protein(), don_rsd.is_DNA(),
589  dhatm_is_backbone, don_pos,
590  aatm , aatm_is_protein_backbone, acc_rsd.is_protein(),
591  acc_rsd.is_DNA(), aatm_is_backbone, acc_pos,
592  hbe_tuple, energy, weight, derivs ) );
593 
594  // update hbcheck
595  // note: these dimension checks could be removed completely & replaced by pose-aware dimensioning
596  if ( options_->bb_donor_acceptor_check() /* actually we could save a LOT of computation if we implement the removal of bb_donor_acceptor_check correctly... */ ){
597  if ( dhatm_is_protein_backbone || aatm_is_protein_backbone ) {
598  Size const max_pos( std::max( acc_pos, don_pos ) );
599  if ( max_pos > backbone_backbone_donor_.size() ||
600  max_pos > backbone_backbone_acceptor_.size() ) {
601  // this could be more efficient if we require specifying nres ahead of time
602  // Specify nres in setup_for_residue_pair_energy
604  }
605  if ( dhatm_is_protein_backbone && aatm_is_protein_backbone ) {
606  backbone_backbone_donor_ [ don_pos ] = true;
607  backbone_backbone_acceptor_[ acc_pos ] = true;
608  }
609  }
610  }
611 }
612 
613 /// \brief Is this hbond allowed under the bb-bb exclusion scheme?
614 bool
615 HBondSet::allow_hbond( Size const index ) const
616 {
617  return allow_hbond( *hbonds_[ index ] );
618 }
619 
620 bool
621 HBondSet::allow_hbond( HBond const & hbond ) const
622 {
623  // donor is backbone atom already making bb-bb hbond
624  // acceptor is sidechain
625  if ( hbond.don_hatm_is_protein_backbone() &&
626  !hbond.acc_atm_is_protein_backbone() &&
627  backbone_backbone_donor_[ hbond.don_res() ] ) return false;
628 
629  if ( hbond.acc_atm_is_protein_backbone() &&
630  !hbond.don_hatm_is_protein_backbone() &&
631  backbone_backbone_acceptor_[ hbond.acc_res() ] ) return false;
632 
633  return true;
634 }
635 
636 /// @brief is the backbone bone acceptor group in a bb/bb hydrogen bond?
637 bool
639 {
640  return backbone_backbone_acceptor_[ residue ];
641 }
642 
643 /// @brief is the backbone bone donor group in a bb/bb hydrogen bond?
644 bool
646 {
647  return backbone_backbone_donor_[ residue ];
648 }
649 
650 /// \brief Get a vector of all the hbonds involving this atom
652 HBondSet::atom_hbonds( AtomID const & atom ) const
653 {
654  setup_atom_map();
655  HBondAtomMap::const_iterator iter( atom_map_.find( atom ) );
656  if ( iter == atom_map_.end() ) {
657  return empty_list_of_hbonds_;
658  } else return iter->second;
659 }
660 
661 /// \brief Delete all the data
662 void
664 {
665  atom_map_init_ = false;
666  hbonds_.clear();
667  backbone_backbone_donor_.clear();
669  nbrs_.clear();
670 }
671 
672 /*
673 /// @details Leave the backbone_backbone_donor_ and backbone_backbone_acceptor_ arrays
674 /// intact
675 void
676 HBondSet::clear_hbonds()
677 {
678  hbonds_.clear();
679 }
680 */
681 
682 /// \brief Resize bb info arrays
683 void
685 {
686  backbone_backbone_donor_.resize( new_dimension, false );
687  backbone_backbone_acceptor_.resize( new_dimension, false );
688 }
689 
690 void
694 }
695 
696 void
698 {
699  std::sort( hbonds_.begin(), hbonds_.end(), HBond::hbond_energy_comparer );
700 }
701 
702 ///////////////////////////////////////////////////////////////////////////////
703 /// \brief Setup the mapping from atoms to hbonds
704 void
705 HBondSet::setup_atom_map() const // lazy updating
706 {
707  if ( atom_map_init_ ) return;
708  atom_map_init_ = true;
709  for ( Size i=1; i<= hbonds_.size(); ++i ) {
710  if ( !allow_hbond(i) ) continue;
711  HBond const & hb( hbond(i) );
712  AtomID const don_atom( hb.don_hatm(), hb.don_res() );
713  AtomID const acc_atom( hb.acc_atm() , hb.acc_res() );
714  for ( Size r=1; r<= 2; ++r ) {
715  AtomID const & atom( r == 1 ? don_atom : acc_atom );
716  HBondAtomMap::iterator iter( atom_map_.find( atom ) );
717  if ( iter == atom_map_.end() ) {
718  atom_map_.insert
719  ( std::make_pair( atom, utility::vector1< HBondCOP >() ));
720  iter = atom_map_.find( atom );
721  } // atom not already present
722  iter->second.push_back( &hb );
723  } // repeat for donor and acceptor
724  } // i=1.nhbonds
725 }
726 
727 ///
728 void
730  pose::Pose const & pose,
731  bool const calculate_derivative /*= false*/,
732  bool const backbone_only /*= true*/
733 )
734 {
735 
736  // now fill the hbond set with only bb-bb hbonds
737  // in the process we fill the arrays that keep track of which protein bb groups are making a
738  // bb-bb hbond
739  //
740  // sc-bb hbonds with these groups are disallowed
741  //
742 
743  HBondSet hbond_set(*this);
744  fill_hbond_set(pose, calculate_derivative, *this,
745  false, backbone_only, backbone_only, backbone_only);
746 
747  // stash the nbr info
748  TenANeighborGraph const & tenA_neighbor_graph
749  ( pose.energies().tenA_neighbor_graph() );
750 
751  nbrs_.resize( pose.total_residue() );
752  for ( Size i=1; i<= pose.total_residue(); ++i ) {
753  //nbrs_[i] = tenA_neighbor_graph.get_node(i)->num_neighbors_counting_self();
754 
755  { // hacky thing here until we update to current svn
756  nbrs_[i] = 1;
758  ir = tenA_neighbor_graph.get_node( i )->const_edge_list_begin(),
759  ire = tenA_neighbor_graph.get_node( i )->const_edge_list_end();
760  ir != ire; ++ir ) {
761  Size const neighbor_id( (*ir)->get_other_ind( i ) );
762  // Don't include VRTs in neighbor count
763  if ( pose.residue( neighbor_id ).aa() == core::chemical::aa_vrt ) continue;
764  chemical::ResidueType const & nbr_rsd( pose.residue_type( neighbor_id ) );
765  if ( nbr_rsd.is_protein() ) {
766  nbrs_[i] += 1;
767  } else if ( nbr_rsd.is_DNA() ) {
768  nbrs_[i] += 1;
769 // nbrs_[i] += 3;
770  } else {
771  nbrs_[i] += 1;
772  }
773  }
774 // std::cout << "nbrdiff: old= " << tenA_neighbor_graph.get_node(i)->num_neighbors_counting_self() << " new= " <<
775 // nbrs_[i] << std::endl;
776  }
777  }
778 
779  // ensure full size for the the HbondSet bb_acc/bb_don arrays
780  // the bb arrays ought to be resized once at the beginning of this function
781  // and not resized to 0 for later push_back operations.... such a waste.
783 
784  // this is a bug:
785  //std::fill( backbone_backbone_donor_.begin(), backbone_backbone_donor_.end(), false );
786  //std::fill( backbone_backbone_acceptor_.begin(), backbone_backbone_acceptor_.end(), false );
787 
788 }
789 
790 HBondOptions const &
792  return *options_;
793 }
794 
795 /// @breif set the hbond options for this hbond set; clears all hbonds already stored
797 {
798  clear();
799  options_ = new HBondOptions( options ); // make a copy of the input to guarantee its integrity
800 }
801 
802 std::ostream &
803 operator<< ( std::ostream & out, const HBondSet & hbond_set ){
804  hbond_set.show( out );
805  return out;
806 }
807 
808 void
810  std::ostream & out/*=std::cout*/
811 ) const {
812  for ( core::Size i=1; i<=nhbonds(); ++i ){
813  out << hbond(i);
814  }
815 }
816 
817 ///
818 bool
819 operator==(HBondSet const & a, HBondSet const & b)
820 {
821  if(a.options_ != b.options_) return false;
822 
823  if(a.atom_map_ != b.atom_map_) return false;
824  if(a.atom_map_init_ != b.atom_map_init_) return false;
825 
826  if(a.backbone_backbone_donor_.size() != b.backbone_backbone_donor_.size()) return false;
827  for(Size i=1; i<=a.backbone_backbone_donor_.size(); ++i){
828  if (a.backbone_backbone_donor_[i] != b.backbone_backbone_donor_[i]) return false;
829  }
830 
831  if(a.backbone_backbone_acceptor_.size() != b.backbone_backbone_acceptor_.size()) return false;
832  for(Size i=1; i<=a.backbone_backbone_donor_.size(); ++i){
833  if (a.backbone_backbone_acceptor_[i] != b.backbone_backbone_acceptor_[i]) return false;
834  }
835 
836  if(a.nhbonds() != b.nhbonds()) {
837  t << "HBondSets not equal!" << std::endl;
838  t << a << std::endl << b << std::endl;
839  return false;
840  }
841 
842  for(Size i=1; i<=a.nhbonds(); ++i){
843  if (!(a.hbond(i) == b.hbond(i))) return false;
844  }
845 
846  return true;
847 }
848 
849 ///@detail Optionally print a header, and then a row for each hydrogen bond in the set using the iterprable version of the hbond show format formatted for easy parsing by R, Excel, etc.
850 void
852  pose::Pose const & pose,
853  bool print_header/*=true*/,
854  std::ostream & out/*=std::cout*/
855 ) const {
856 
857  for (Size i=1; i<= nhbonds(); ++i ) {
858  hbond(i).show(pose, i==1 && print_header, out);
859  }
860 
861 }
862 
863 
864 ///@detail Optionally print a header, and then a row for each hydrogen
865 ///bond in the set using the iterprable version of the hbond show
866 ///format formatted for easy parsing by R, Excel, etc.
867 void
869  pose::Pose const & pose,
870  Size const residue_number,
871  bool const print_header /*=true*/,
872  std::ostream & out /*=std::cout*/
873 ) const {
874 
875  bool first_found(true);
876  for (Size i=1; i<=nhbonds(); ++i ) {
877  if((hbond(i).don_res() == residue_number)
878  || (hbond(i).acc_res() == residue_number)){
879 
880  hbond(i).show(pose, print_header && first_found, out);
881  first_found = false;
882  }
883  }
884 
885 }
886 
887 
888 
889 
891 
892 }
893 }
894 }