IMP  2.0.1
The Integrative Modeling Platform
XYZR.h
Go to the documentation of this file.
1 /**
2  * \file IMP/core/XYZR.h
3  * \brief Decorator for a sphere-like particle.
4  *
5  * Copyright 2007-2013 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef IMPCORE_XYZ_R_H
10 #define IMPCORE_XYZ_R_H
11 
12 #include "XYZ.h"
13 #include <IMP/algebra/Sphere3D.h>
17 #include <limits>
18 
19 IMPCORE_BEGIN_NAMESPACE
20 
21 //! A decorator for a particle with x,y,z coordinates and a radius.
22 /** \ingroup decorators
23 
24  A simple example illustrating some of the functionality.
25  \pythonexample{XYZR_Decorator}
26  */
27 class IMPCOREEXPORT XYZR:
28  public XYZ
29 {
30 public:
32 
33  /** Create a decorator using radius_key to store the FloatKey.
34  \param[in] p The particle to wrap.
35  */
37  if (!XYZ::particle_is_instance(p)) {
39  }
40  p->add_attribute(get_radius_key(), 0, false);
41  return XYZR(p);
42  }
43 
44 
45  /** Create a decorator using radius_key to store the FloatKey.
46  The particle should already be an XYZ particle.
47  \param[in] p The particle to wrap.
48  \param[in] radius The radius to set initially
49  */
51  Float radius) {
52  p->add_attribute(get_radius_key(), radius, false);
53  return XYZR(p);
54  }
55 
56  /** Create a decorator using radius_key to store the FloatKey.
57  \param[in] p The particle to wrap.
58  \param[in] s The sphere to use to set the position and radius
59  */
61  // See XYZ::setup_particle before you change this
62  const algebra::Sphere3D s) {
63  XYZ::setup_particle(p, s.get_center());
64  p->add_attribute(get_radius_key(), s.get_radius(), false);
65  return XYZR(p);
66  }
67 
68  /** Add the coordinates and radius from the sphere to the particle.
69  */
71  // See XYZ::setup_particle before you change this
72  const algebra::Sphere3D s) {
73  XYZ::setup_particle(m, pi, s.get_center());
74  m->add_attribute(get_radius_key(), pi, s.get_radius(), false);
75  return XYZR(m, pi);
76  }
77 
78  //! Check if the particle has the required attributes
79  static bool particle_is_instance(Particle *p) {
80  return p->has_attribute(get_radius_key());
81  }
82  double get_radius() const {
83  return get_sphere().get_radius();
84  }
85  void set_radius(double r) const {
86  get_model()->get_sphere(get_particle_index())[3]=r;
87  }
88 
89 
90  //! Return a sphere object
91  const algebra::Sphere3D& get_sphere() const {
92  return get_model()->get_sphere(get_particle_index());
93  }
94 
95  //! Set the attributes from a sphere
96  void set_sphere(const algebra::Sphere3D &s) {
97  get_model()->get_sphere(get_particle_index())=s;
98  }
99  //! Get the default radius key.
101  return IMP::internal::xyzr_keys[3];
102  }
103  void add_to_radius_derivative(double v,
105  get_particle()->add_to_derivative(get_radius_key(), v, d);
106  }
107 };
108 
109 IMP_DECORATORS(XYZR,XYZRs, XYZs);
110 
111 //! Compute the distance between a pair of particles
112 /** \relatesalso XYZR
113  */
114 inline double get_distance(XYZR a, XYZR b) {
116 }
117 
118 //! Set the coordinates and radius of the first to enclose the list
119 /** \param[in] v The vector of XYZ or XYZR particles to enclose
120  \param[out] b The one whose values should be set
121  \param[in] slack An amount to add to the radius.
122  Any particle which does not have the attribute b.get_radius()
123  is assumed to have a radius of 0.
124 
125  \note This function produces tighter bounds if the \ref cgal "CGAL"
126  library is available.
127  \ingroup CGAL
128  \relatesalso XYZR
129  */
130 IMPCOREEXPORT void set_enclosing_sphere(XYZR b,
131  const XYZs &v,
132  double slack=0);
133 
134 //! Set the radius of the first to enclose the list
135 /** \param[in] v The vector of XYZ or XYZR particles to enclose
136  \param[out] b The one whose radius should be set
137  Any particle which does not have the attribute b.get_radius()
138  is assumed to have a radius of 0.
139 
140  \relatesalso XYZR
141  */
142 IMPCOREEXPORT void set_enclosing_radius(XYZR b,
143  const XYZs &v);
144 
145 //! Get a sphere enclosing the set of XYZRs
146 /** \param[in] v The one whose radius should be set
147  Any particle which does not have the attribute b.get_radius()
148  is assumed to have a radius of 0.
149 
150  \relatesalso XYZR
151  */
152 IMPCOREEXPORT algebra::Sphere3D get_enclosing_sphere(const XYZs& v);
153 
154 //! Create a set of particles with random coordinates
155 /** This function is mostly to be used to keep demo code brief.
156  \param[in] m The model to add them to.
157  \param[in] num The number of particles to create.
158  \param[in] radius The radius to give them.
159  \param[in] box_side The particles have coordinates from -box_side
160  to box_side.
161  \relatesalso XYZR
162 
163  The particles coordinates are optimized.
164  */
165 IMPCOREEXPORT XYZRs create_xyzr_particles(Model *m,
166  unsigned int num,
167  Float radius,
168  Float box_side=10);
169 
170 /** \genericgeometry */
172  return d.get_sphere();
173 }
174 
175 /** \genericgeometry */
176 inline void set_sphere_d_geometry(XYZR d, const algebra::Sphere3D &v) {
177  d.set_sphere(v);
178 }
179 
180 
181 
182 /** \class XYZRGeometry
183  \brief Display an IMP::core::XYZR particle as a ball.
184 
185  \class XYZRsGeometry
186  \brief Display an IMP::SingletonContainer of IMP::core::XYZR particles
187  as balls.
188 */
189 IMP_PARTICLE_GEOMETRY(XYZR, core::XYZR,
190  {
191  display::SphereGeometry *g= new display::SphereGeometry(d.get_sphere());
192  ret.push_back(g);
193  });
194 
195 
196 
197 
198 IMP_PARTICLE_GEOMETRY(XYZDerivative, core::XYZ, {
199  algebra::Segment3D s(d.get_coordinates(),
200  d.get_coordinates()+d.get_derivatives());
202  ret.push_back(g);
203  });
204 
205 
206 /** \class EdgePairGeometry
207  \brief Display an IMP::atom::Bond particle as a segment.
208 
209  \class EdgePairsGeometry
210  \brief Display an IMP::SingletonContainer of IMP::atom::Bond particles
211  as segments.
212 */
213 IMP_PARTICLE_PAIR_GEOMETRY(EdgePair, core::XYZ, {
214  ret.push_back(
215  new display::SegmentGeometry(algebra::Segment3D(d0.get_coordinates(),
216  d1.get_coordinates())));
217  });
218 
219 IMPCORE_END_NAMESPACE
220 
221 #ifndef SWIG
222 // swig doesn't like having the overloads in different namespaces
223 // it will do the conversion implicitly anyway
224 IMPKERNEL_BEGIN_NAMESPACE
225 /** \genericgeometry */
227  return core::XYZR(p).get_sphere();
228 }
229 
230 /** \genericgeometry */
232  core::XYZR(p).set_sphere(v);
233 }
234 
235 /** \genericgeometry */
236 inline const algebra::BoundingBoxD<3>
238  return get_bounding_box(core::XYZR(p).get_sphere());
239 }
240 IMPKERNEL_END_NAMESPACE
241 #endif
242 
243 #endif /* IMPCORE_XYZ_R_H */