IMP logo
IMP Reference Guide  develop.7cb8855c60,2024/10/04
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-2022 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  \brief 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  expandable.
35 
36  \ingroup bond
37  \see Bonded
38  \see IMP::atom::get_internal_bonds()
39  */
40 class IMPATOMEXPORT Bond : public Decorator {
41  friend class Bonded;
42 
43  public:
45 
46  static bool get_is_setup(Model *m, ParticleIndex pi) {
47  return IMP::core::internal::graph_is_edge(m->get_particle(pi),
48  internal::get_bond_data().graph_);
49  }
50 
51  //! The types a bond can have right now
52  enum Type {
53  UNKNOWN = -1,
54  NONBIOLOGICAL,
55  SINGLE = 1,
56  DOUBLE = 2,
57  TRIPLE = 3,
58  HYDROGEN,
59  SALT,
60  PEPTIDE,
61  AMIDE,
62  AROMATIC
63  };
64 
65  //! Get the atom i of the bond
66  /** \param[in] i 0 or 1
67  \return Bonded for the atom in question
68  */
69  Bonded get_bonded(unsigned int i) const;
70 
71  IMP_DECORATOR_GET_SET_OPT(type, internal::get_bond_data().type_, Int, Int,
72  UNKNOWN);
73 
74  IMP_DECORATOR_GET_SET_OPT(order, internal::get_bond_data().order_, Int, Int,
75  1);
76 
77  IMP_DECORATOR_GET_SET_OPT(length, internal::get_bond_data().length_, Float,
78  Float, -1);
79  IMP_DECORATOR_GET_SET_OPT(stiffness, internal::get_bond_data().stiffness_,
80  Float, Float, -1);
81 
82  static FloatKey get_length_key() { return internal::get_bond_data().length_; }
83 };
84 
85 //! A decorator for a particle which has bonds.
86 /** \ingroup bond
87  \see Bond
88  */
89 class IMPATOMEXPORT Bonded : public Decorator {
90  struct GetBond {
91  typedef Bond result_type;
92  Particle *d_;
93  GetBond() : d_(nullptr) {}
94  GetBond(Particle *d) : d_(d) {}
95  Bond operator()(unsigned int i) const;
96  bool operator==(const GetBond &o) const { return d_ == o.d_; }
97  };
98  struct GetBonded {
99  typedef Bonded result_type;
100  Particle *d_;
101  GetBonded() : d_(nullptr) {}
102  GetBonded(Particle *d) : d_(d) {}
103  Bonded operator()(unsigned int i) const;
104  bool operator==(const GetBonded &o) const { return d_ == o.d_; }
105  };
106  static void do_setup_particle(Model *m, ParticleIndex pi) {
107  graph_initialize_node(m->get_particle(pi),
108  internal::get_bond_data().graph_);
109  }
110 
111  public:
114 
115  static bool get_is_setup(Model *m, ParticleIndex pi) {
116  return IMP::core::internal::graph_is_node(m->get_particle(pi),
117  internal::get_bond_data().graph_);
118  }
119 
120  /** */
121  unsigned int get_number_of_bonds() const {
122  return graph_get_number_of_edges(get_particle(),
123  internal::get_bond_data().graph_);
124  }
125 
126  ParticleIndexes get_bond_indexes() const {
127  return graph_get_edges(get_particle(), internal::get_bond_data().graph_);
128  }
129 
130  //! Get a Bond of the ith bond
131  /** \return decorator of the ith child, or throw an exception if there
132  is no such bond
133  */
134  Bond get_bond(unsigned int i) const {
135  Particle *p =
136  graph_get_edge(get_particle(), i, internal::get_bond_data().graph_);
137  return Bond(p);
138  }
139 
140  //! Get a Bonded of the ith bonded particle
141  /** \return decorator of the ith child, or throw an exception if there
142  is no such bond
143 
144  \note I don't entirely like having this here as it duplicates
145  functionality available otherwise, however it is such a fundamental
146  operation and kind of a pain to write. It also means that we
147  could later pull the edge endpoints into the vertex if
148  desired.
149  */
150  Bonded get_bonded(unsigned int i) const {
151  Particle *p =
152  graph_get_edge(get_particle(), i, internal::get_bond_data().graph_);
153  Bond bd(p);
154  if (bd.get_bonded(0) == *this)
155  return bd.get_bonded(1);
156  else
157  return bd.get_bonded(0);
158  }
159 
160 /** @name Iterate through the bonds
161  @{
162 */
163 #ifdef IMP_DOXYGEN
164  class BondIterator;
165 #else
166  typedef IMP::internal::IndexingIterator<GetBond> BondIterator;
167 #endif
168 #ifndef SWIG
169  BondIterator bonds_begin() const {
170  return BondIterator(GetBond(get_particle()), 0);
171  }
172  BondIterator bonds_end() const {
173  return BondIterator(GetBond(get_particle()), get_number_of_bonds());
174  }
175 #endif
176 /** @} */
177 /** @name Iterate through the bondeds
178  @{
179 */
180 #ifdef IMP_DOXYGEN
181  class BondedIterator;
182 #else
183  typedef IMP::internal::IndexingIterator<GetBonded> BondedIterator;
184 #endif
185 #ifndef SWIG
186  BondedIterator bondeds_begin() const {
187  return BondedIterator(GetBonded(get_particle()), 0);
188  }
189  BondedIterator bondeds_end() const {
190  return BondedIterator(GetBonded(get_particle()), get_number_of_bonds());
191  }
192 #endif
193  /** @} */
194 };
195 
196 IMP_DECORATORS(Bonded, Bondeds, ParticlesTemp);
197 IMP_DECORATORS(Bond, Bonds, ParticlesTemp);
198 
199 inline Bonded Bond::get_bonded(unsigned int i) const {
200  Particle *p =
201  graph_get_node(get_particle(), i, internal::get_bond_data().graph_);
202  return Bonded(p);
203 }
204 
205 #ifndef IMP_DOXYGEN
206 inline Bond Bonded::GetBond::operator()(unsigned int i) const {
207  return Bonded(d_).get_bond(i);
208 }
209 inline Bonded Bonded::GetBonded::operator()(unsigned int i) const {
210  return Bonded(d_).get_bonded(i);
211 }
212 #endif
213 
214 //! Connect the two wrapped particles by a bond.
215 /** \param[in] a The first Particle as a Bonded
216  \param[in] b The second Particle as a Bonded
217  \param[in] t The type to use for the bond
218  \return Bond of the bond Particle.
219 
220  \ingroup bond
221  \see Bond
222  \see Bonded
223  */
224 IMPATOMEXPORT Bond create_bond(Bonded a, Bonded b, Int t);
225 
226 //! Connect the two wrapped particles by a custom bond.
227 /** \param[in] a The first Particle as a Bonded
228  \param[in] b The second Particle as a Bonded
229  \param[in] length The length of the bond.
230  \param[in] stiffness The stiffness of the bond.
231  \return Bond of the bond Particle.
232 
233  \ingroup bond
234  \see Bond
235  \see Bonded
236  */
237 IMPATOMEXPORT inline Bond create_custom_bond(Bonded a, Bonded b, Float length,
238  Float stiffness = -1) {
239  IMP_INTERNAL_CHECK(length >= 0, "Length must be positive");
240  Bond bd = create_bond(a, b, Bond::NONBIOLOGICAL);
241  bd.set_length(length);
242  bd.get_particle()->set_name(std::string("bond ") +
243  a.get_particle()->get_name() + " and " +
244  b.get_particle()->get_name());
245  if (stiffness >= 0) bd.set_stiffness(stiffness);
246  return bd;
247 }
248 
249 //! Connect the two wrapped particles by a custom bond.
250 /** Create a bond by copying the information from the other bond
251 
252  \ingroup bond
253  \see Bond
254  \see Bonded
255  */
256 IMPATOMEXPORT inline Bond create_bond(Bonded a, Bonded b, Bond o) {
257  Bond bd = create_bond(a, b, o.get_type());
258  if (o.get_length() > 0) bd.set_length(o.get_length());
259  bd.get_particle()->set_name(std::string("bond ") +
260  a.get_particle()->get_name() + " and " +
261  b.get_particle()->get_name());
262  if (o.get_stiffness() >= 0) bd.set_stiffness(o.get_stiffness());
263  return bd;
264 }
265 
266 //! Destroy the bond connecting two particles.
267 /** \param[in] b The bond.
268  \ingroup bond
269  \see Bond
270  \see Bonded
271  */
272 IMPATOMEXPORT void destroy_bond(Bond b);
273 
274 //! Get the bond between two particles.
275 /** Bond() is returned if the particles are not bonded.
276  \ingroup bond
277  \see Bond
278  \see Bonded
279  */
280 IMPATOMEXPORT Bond get_bond(Bonded a, Bonded b);
281 
282 /** \class BondGeometry
283  \brief Display a Bond particle as a segment.
284 
285  \class BondsGeometry
286  \brief Display an IMP::SingletonContainer of Bond particles
287  as segments.
288 */
289 IMP_PARTICLE_GEOMETRY(Bond, Bond, {
290  atom::Bonded ep0 = d.get_bonded(0);
291  core::XYZ epi0(ep0.get_particle());
292  atom::Bonded ep1 = d.get_bonded(1);
293  core::XYZ epi1(ep1.get_particle());
294  algebra::Segment3D s(epi0.get_coordinates(), epi1.get_coordinates());
296  ret.push_back(g);
297 });
298 
299 IMPATOM_END_NAMESPACE
300 
301 #endif /* IMPATOM_BOND_DECORATORS_H */
Particle * get_particle(ParticleIndex p) const
Get the particle from an index.
Definition: Model.h:489
The base class for decorators.
Int get_type() const
The base class for geometry.
A decorator for a particle which has bonds.
#define IMP_DECORATOR_GET_SET_OPT(name, AttributeKey, Type, ReturnType, default_value)
Define methods for getting and setting an optional simple field.
Storage of a model, its restraints, constraints and particles.
Float get_stiffness() const
Type
The types a bond can have right now.
Bond get_bond(unsigned int i) const
Get a Bond of the ith bond.
void destroy_bond(Bond b)
Destroy the bond connecting two particles.
Simple XYZ decorator.
Bond create_bond(Bonded a, Bonded b, Bond o)
Connect the two wrapped particles by a custom bond.
#define IMP_INTERNAL_CHECK(expr, message)
An assertion to check for internal errors in IMP. An IMP::ErrorException will be thrown.
Definition: check_macros.h:139
Bond create_custom_bond(Bonded a, Bonded b, Float length, Float stiffness=-1)
Connect the two wrapped particles by a custom bond.
Class for storing model, its restraints, constraints, and particles.
Definition: Model.h:86
Implement geometry for the basic shapes from IMP.algebra.
void set_stiffness(Float t)
A decorator for wrapping a particle representing a molecular bond.
Represent an XYZR particle with a sphere.
A decorator for a particle with x,y,z coordinates.
Definition: XYZ.h:30
Bonded get_bonded(unsigned int i) const
Get the atom i of the bond.
#define IMP_DECORATOR_SETUP_0(Name)
Particle * get_particle() const
Returns the particle decorated by this decorator.
Definition: Decorator.h:194
Interface to specialized Particle types (e.g. atoms)
Definition: Decorator.h:119
Classes to handle individual model particles. (Note that implementation of inline functions is in int...
Simple implementation of segments in 3D.
Definition: Segment3D.h:25
#define IMP_DECORATOR_METHODS(Name, Parent)
double Float
Basic floating-point value (could be float, double...)
Definition: types.h:19
Class to handle individual particles of a Model object.
Definition: Particle.h:43
Bond get_bond(Bonded a, Bonded b)
Get the bond between two particles.
#define IMP_DECORATORS(Name, PluralName, Parent)
Define the types for storing sets of decorators.
int Int
Basic integer value.
Definition: types.h:34
Bonded get_bonded(unsigned int i) const
Get a Bonded of the ith bonded particle.
void set_length(Float t)
Float get_length() const