IMP  2.0.1
The Integrative Modeling Platform
bond_decorators.h
Go to the documentation of this file.
1 /**
2  * \file IMP/atom/bond_decorators.h \brief Contains decorators for a bond
3  *
4  * Copyright 2007-2013 IMP Inventors. All rights reserved.
5  *
6  */
7 
8 #ifndef IMPATOM_BOND_DECORATORS_H
9 #define IMPATOM_BOND_DECORATORS_H
10 
11 #include <IMP/atom/atom_config.h>
12 #include <IMP/core/internal/graph_base.h>
13 #include "internal/bond_helpers.h"
16 #include <IMP/Particle.h>
17 #include <IMP/Model.h>
18 #include <IMP/Decorator.h>
19 #include <IMP/core/XYZ.h>
20 
21 #include <IMP/internal/IndexingIterator.h>
22 IMPATOM_BEGIN_NAMESPACE
23 
24 class Bond;
25 class Bonded;
26 
27 /** \defgroup bond Creating and restraining bonds
28  A set of classes and functions for manipulating bonds.
29  */
30 
31 //! A decorator for wrapping a particle representing a molecular bond
32 /**
33  As with Atom, the types of bonds will eventually be run-time
34  expandible.
35 
36  \ingroup bond
37  \see Bonded
38  \see IMP::atom::get_internal_bonds()
39  */
40 class IMPATOMEXPORT Bond: public Decorator
41 {
42  friend class Bonded;
43 public:
45 
46  //! Return true if the particle is a bond.
47  static bool particle_is_instance(Particle *p) {
48  return IMP::core::internal::graph_is_edge(p,
49  internal::get_bond_data().graph_);
50  }
51 
52  //! The types a bond can have right now
53  enum Type {UNKNOWN=-1,
54  NONBIOLOGICAL, SINGLE=1, DOUBLE=2, TRIPLE=3, HYDROGEN,
55  SALT, PEPTIDE,
56  AMIDE, AROMATIC
57  };
58 
59  //! Get the atom i of the bond
60  /** \param[in] i 0 or 1
61  \return Bonded for the atom in question
62  */
63  Bonded get_bonded(unsigned int i) const ;
64 
66  internal::get_bond_data().type_, Int, Int,
67  UNKNOWN);
68 
70  internal::get_bond_data().order_,
71  Int, Int, 1);
72 
74  internal::get_bond_data().length_, Float,
75  Float, -1);
76  IMP_DECORATOR_GET_SET_OPT(stiffness,
77  internal::get_bond_data().stiffness_,
78  Float,
79  Float, -1);
80 
81  static FloatKey get_length_key() {
82  return internal::get_bond_data().length_;
83  }
84 };
85 
86 
87 
88 //! A decorator for a particle which has bonds.
89 /** \ingroup bond
90  \see Bond
91  */
92 class IMPATOMEXPORT Bonded: public Decorator
93 {
94  struct GetBond {
95  typedef Bond result_type;
96  Particle* d_;
97  GetBond():d_(nullptr){}
98  GetBond(Particle* d): d_(d){}
99  Bond operator()(unsigned int i) const;
100  bool operator==(const GetBond &o) const {
101  return d_== o.d_;
102  }
103  };
104  struct GetBonded {
105  typedef Bonded result_type;
106  Particle* d_;
107  GetBonded():d_(nullptr){}
108  GetBonded(Particle* d): d_(d){}
109  Bonded operator()(unsigned int i) const;
110  bool operator==(const GetBonded &o) const {
111  return d_== o.d_;
112  }
113  };
114 public:
116  //! return true if it is a bonded particle
117  static bool particle_is_instance(Particle *p) {
118  return IMP::core::internal::graph_is_node(p,
119  internal::get_bond_data().graph_);
120  }
121 
122  static Bonded setup_particle(Particle *p) {
123  graph_initialize_node(p, internal::get_bond_data().graph_);
124  return Bonded(p);
125  }
126 
127  /** */
128  unsigned int get_number_of_bonds() const {
129  return graph_get_number_of_edges(get_particle(),
130  internal::get_bond_data().graph_);
131  }
132 
133  //! moving towards particle indexes
135  return graph_get_edges(get_particle(),
136  internal::get_bond_data().graph_);
137  }
138 
139 
140  //! Get a Bond of the ith bond
141  /** \return decorator of the ith child, or throw an exception if there
142  is no such bond
143  */
144  Bond get_bond(unsigned int i) const {
145  Particle *p= graph_get_edge(get_particle(), i,
146  internal::get_bond_data().graph_);
147  return Bond(p);
148  }
149 
150  //! Get a Bonded of the ith bonded particle
151  /** \return decorator of the ith child, or throw an exception if there
152  is no such bond
153 
154  \note I don't entirely like having this here as it duplicates
155  functionality available otherwise, however it is such a fundamental
156  operation and kind of a pain to write. It also means that we
157  could later pull the edge endpoints into the vertex if
158  desired.
159  */
160  Bonded get_bonded(unsigned int i) const {
161  Particle *p= graph_get_edge(get_particle(), i,
162  internal::get_bond_data().graph_);
163  Bond bd(p);
164  if (bd.get_bonded(0) == *this) return bd.get_bonded(1);
165  else return bd.get_bonded(0);
166  }
167 
168  /** @name Iterate through the bonds
169  @{
170  */
171 #ifdef IMP_DOXYGEN
172  class BondIterator;
173 #else
174  typedef IMP::internal::IndexingIterator<GetBond> BondIterator;
175 #endif
176 #ifndef SWIG
177  BondIterator bonds_begin() const {
178  return BondIterator(GetBond(get_particle()), 0);
179  }
180  BondIterator bonds_end() const {
181  return BondIterator(GetBond(get_particle()), get_number_of_bonds());
182  }
183 #endif
184  /** @} */
185  /** @name Iterate through the bondeds
186  @{
187  */
188 #ifdef IMP_DOXYGEN
189  class BondedIterator;
190 #else
191  typedef IMP::internal::IndexingIterator<GetBonded> BondedIterator;
192 #endif
193 #ifndef SWIG
194  BondedIterator bondeds_begin() const {
195  return BondedIterator(GetBonded(get_particle()), 0);
196  }
197  BondedIterator bondeds_end() const {
198  return BondedIterator(GetBonded(get_particle()), get_number_of_bonds());
199  }
200 #endif
201  /** @} */
202 };
203 
204 IMP_DECORATORS(Bonded,Bondeds, ParticlesTemp);
205 IMP_DECORATORS(Bond,Bonds, ParticlesTemp);
206 
207 
208 inline Bonded Bond::get_bonded(unsigned int i) const
209 {
210  Particle *p= graph_get_node(get_particle(), i,
211  internal::get_bond_data().graph_);
212  return Bonded(p);
213 }
214 
215 #ifndef IMP_DOXYGEN
216 inline Bond Bonded::GetBond::operator()(unsigned int i)
217  const {
218  return Bonded(d_).get_bond(i);
219 }
220 inline Bonded Bonded::GetBonded::operator()(unsigned int i)
221  const {
222  return Bonded(d_).get_bonded(i);
223 }
224 #endif
225 
226 
227 //! Connect the two wrapped particles by a bond.
228 /** \param[in] a The first Particle as a Bonded
229  \param[in] b The second Particle as a Bonded
230  \param[in] t The type to use for the bond
231  \return Bond of the bond Particle.
232 
233  \ingroup bond
234  \relatesalso Bond
235  \relatesalso Bonded
236  */
237 IMPATOMEXPORT
238 Bond create_bond(Bonded a, Bonded b, Int t);
239 
240 
241 //! Connect the two wrapped particles by a custom bond.
242 /** \param[in] a The first Particle as a Bonded
243  \param[in] b The second Particle as a Bonded
244  \param[in] length The length of the bond.
245  \param[in] stiffness The stiffness of the bond.
246  \return Bond of the bond Particle.
247 
248  \ingroup bond
249  \relatesalso Bond
250  \relatesalso Bonded
251  */
252 IMPATOMEXPORT
254  Float length, Float stiffness=-1) {
255  IMP_INTERNAL_CHECK(length>=0, "Length must be positive");
256  Bond bd=create_bond(a,b, Bond::NONBIOLOGICAL);
257  bd.set_length(length);
258  bd.get_particle()->set_name(std::string("bond ")+
259  a.get_particle()->get_name()
260  + " and " + b.get_particle()->get_name());
261  if (stiffness >=0) bd.set_stiffness(stiffness);
262  return bd;
263 }
264 
265 
266 //! Connect the two wrapped particles by a custom bond.
267 /** Create a bond by copying the information from the othr bond
268 
269  \ingroup bond
270  \relatesalso Bond
271  \relatesalso Bonded
272  */
273 IMPATOMEXPORT
275  Bond o) {
276  Bond bd=create_bond(a,b, o.get_type());
277  if (o.get_length() > 0) bd.set_length(o.get_length());
278  bd.get_particle()->set_name(std::string("bond ")+
279  a.get_particle()->get_name()
280  + " and " + b.get_particle()->get_name());
281  if (o.get_stiffness() >=0) bd.set_stiffness(o.get_stiffness());
282  return bd;
283 }
284 
285 //! Destroy the bond connecting to particles.
286 /** \param[in] b The bond.
287  \ingroup bond
288  \relatesalso Bond
289  \relatesalso Bonded
290  */
291 IMPATOMEXPORT
292 void destroy_bond(Bond b);
293 
294 //! Get the bond between two particles.
295 /** Bond() is returned if the particles are not bonded.
296  \ingroup bond
297  \relatesalso Bond
298  \relatesalso Bonded
299  */
300 IMPATOMEXPORT
301 Bond get_bond(Bonded a, Bonded b);
302 
303 
304 
305 
306 /** \class BondGeometry
307  \brief Display an Bond particle as a segment.
308 
309  \class BondsGeometry
310  \brief Display an IMP::SingletonContainer of Bond particles
311  as segments.
312 */
313 IMP_PARTICLE_GEOMETRY(Bond, Bond,{
314  atom::Bonded ep0= d.get_bonded(0);
315  core::XYZ epi0(ep0.get_particle());
316  atom::Bonded ep1= d.get_bonded(1);
317  core::XYZ epi1(ep1.get_particle());
318  algebra::Segment3D s(epi0.get_coordinates(),
319  epi1.get_coordinates());
321  ret.push_back(g);
322  });
323 
324 IMPATOM_END_NAMESPACE
325 
326 #endif /* IMPATOM_BOND_DECORATORS_H */