IMP  2.0.0
The Integrative Modeling Platform
XYZ.h
Go to the documentation of this file.
1 /**
2  * \file IMP/core/XYZ.h \brief Simple xyz decorator.
3  *
4  * Copyright 2007-2013 IMP Inventors. All rights reserved.
5  *
6  */
7 
8 #ifndef IMPCORE_XY_Z_H
9 #define IMPCORE_XY_Z_H
10 
11 #include <IMP/core/core_config.h>
12 #include <IMP/decorator_macros.h>
13 #include "internal/dihedral_helpers.h"
14 
15 #include <IMP/Decorator.h>
16 #include <IMP/algebra/Vector3D.h>
18 #include <vector>
19 #include <limits>
20 
21 IMPCORE_BEGIN_NAMESPACE
22 
23 //! A a decorator for a particle with x,y,z coordinates.
24 /** \inlineimage{xyz.png, 50} Using the decorator one can
25  get and set coordinates and modify derivatives.
26 
27  \ingroup helper
28  \ingroup decorators
29  \pythonexample{XYZ_Decorator}
30  \see XYZR
31  */
32 class IMPCOREEXPORT XYZ: public Decorator
33 {
34  public:
35 
36  static FloatKey get_coordinate_key(unsigned int i) {
37  IMP_USAGE_CHECK(i <3, "Out of range coordinate");
38  return IMP::internal::xyzr_keys[i];
39  }
40 
42 
43  /** Create a decorator with the passed coordinates. */
44  static XYZ setup_particle(Model *m,
45  ParticleIndex pi,
46  // This method and the next one need to take a vector (not a ref)
47  // as otherwise, you can pass the vector from one and use it to
48  // create another. But this would resize the vector and so invalidate
49  // the passed reference. Ick.
50  const algebra::Vector3D v=
51  algebra::Vector3D(0,0,0)) {
52  m->add_attribute(get_coordinate_key(0),pi,v[0]);
53  m->add_attribute(get_coordinate_key(1),pi,v[1]);
54  m->add_attribute(get_coordinate_key(2),pi,v[2]);
55  return XYZ(m, pi);
56  }
57 
58  static XYZ setup_particle(Particle *p,
59  // See setup_particle, above, before touching this
60  const algebra::Vector3D v=
61  algebra::Vector3D(0,0,0)) {
62  return setup_particle(p->get_model(),
63  p->get_index(),
64  v);
65  }
66 
67  IMP_DECORATOR_GET_SET(x, get_coordinate_key(0), Float, Float);
68  IMP_DECORATOR_GET_SET(y, get_coordinate_key(1), Float, Float);
69  IMP_DECORATOR_GET_SET(z, get_coordinate_key(2), Float, Float);
70  //! set the ith coordinate
71  void set_coordinate(unsigned int i, Float v) {
72  get_model()->get_sphere(get_particle_index())[i]=v;
73  }
74  //! set all coordinates from a vector
76  get_model()->get_sphere(get_particle_index())[0]=v[0];
77  get_model()->get_sphere(get_particle_index())[1]=v[1];
78  get_model()->get_sphere(get_particle_index())[2]=v[2];
79  }
80 
81  //! Get the ith coordinate
82  Float get_coordinate(int i) const {
83  return get_model()->get_sphere(get_particle_index())[i];
84  }
85  //! Get the ith coordinate derivative
86  Float get_derivative(int i) const {
87  return get_derivatives()[i];
88  }
89  //! Add something to the derivative of the ith coordinate
90  void add_to_derivative(int i, Float v,
92  get_particle()->add_to_derivative(get_coordinate_key(i), v, d);
93  }
94  //! Add something to the derivative of the coordinates
95  void add_to_derivatives(const algebra::Vector3D& v,
97  get_model()->add_to_coordinate_derivatives(get_particle_index(),
98  v, d);
99  }
100  //! Get whether the coordinates are optimized
101  /** \return true only if all of them are optimized.
102  */
104  return get_particle()->get_is_optimized(get_coordinate_key(0))
105  && get_particle()->get_is_optimized(get_coordinate_key(1))
106  && get_particle()->get_is_optimized(get_coordinate_key(2));
107  }
108  //! Set whether the coordinates are optimized
109  void set_coordinates_are_optimized(bool tf) const {
110  get_particle()->set_is_optimized(get_coordinate_key(0), tf);
111  get_particle()->set_is_optimized(get_coordinate_key(1), tf);
112  get_particle()->set_is_optimized(get_coordinate_key(2), tf);
113  }
114 
115  //! Get the vector from this particle to another
117  return b.get_coordinates()-get_coordinates();;
118  }
119 
120  //! Convert it to a vector.
121  /** Somewhat suspect based on wanting a Point/Vector differentiation
122  but we don't have points */
124  return get_model()->get_sphere(get_particle_index()).get_center();
125  }
126 
127  //! Get the vector of derivatives.
128  /** Somewhat suspect based on wanting a Point/Vector differentiation
129  but we don't have points */
131  return get_model()->get_coordinate_derivatives(get_particle_index());
132  }
133 
134  static bool particle_is_instance(Particle *p) {
135  IMP_USAGE_CHECK((p->has_attribute(get_coordinate_key(2))
136  && p->has_attribute(get_coordinate_key(0))
137  && p->has_attribute(get_coordinate_key(1)))
138  || (!p->has_attribute(get_coordinate_key(2))
139  && !p->has_attribute(get_coordinate_key(0))
140  && !p->has_attribute(get_coordinate_key(1))),
141  "Particle expected to either have all of x,y,z or none.");
142  return p->has_attribute(get_coordinate_key(2));
143  }
144 
145  static bool particle_is_instance(Model *m, ParticleIndex pi) {
146  return m->get_has_attribute(get_coordinate_key(2), pi);
147  }
148 
149  //! Get a vector containing the keys for x,y,z
150  /** This is quite handy for initializing movers and things.
151  */
152  static const FloatKeys& get_xyz_keys();
153 };
154 
155 //! Compute the distance between a pair of particles
156 /** \ingroup helper
157  \relatesalso XYZ
158  */
159 inline double get_distance(XYZ a, XYZ b) {
161 }
162 
163 //! Compute the dihedral angle (in radians) between the four particles
164 /** \ingroup helper
165  \relatesalso XYZ
166  */
167 inline double get_dihedral(XYZ a, XYZ b, XYZ c, XYZ d) {
168  return internal::dihedral(a, b, c, d, nullptr, nullptr, nullptr, nullptr);
169 }
170 
171 //! Apply a transformation to the particle
172 /** \relatesalso XYZ
173  \relatesalso algebra::Transformation3D
174 */
175 IMPCOREEXPORT void transform(XYZ a, const algebra::Transformation3D &tr);
176 
177 /** \genericgeometry */
179  return d.get_coordinates();
180 }
181 /** \genericgeometry */
182 inline void set_vector_d_geometry(XYZ d, const algebra::Vector3D &v) {
183  d.set_coordinates(v);
184 }
185 
186 IMP_DECORATORS(XYZ,XYZs, ParticlesTemp);
187 
188 
189 IMPCORE_END_NAMESPACE
190 
191 
192 #ifndef SWIG
193 // use koenig lookup
194 // swig doesn't like having the overloads in different namespaces
195 // it will do the conversion implicitly anyway
196 IMPKERNEL_BEGIN_NAMESPACE
197 /** \genericgeometry */
199  return core::XYZ(p).get_coordinates();
200 }
201 /** \genericgeometry */
204 }
205 
206 IMPKERNEL_END_NAMESPACE
207 #endif
208 
209 #endif /* IMPCORE_XY_Z_H */