IMP logo
IMP Reference Guide  2.15.0
The Integrative Modeling Platform
particle_states.h
Go to the documentation of this file.
1 /**
2  * \file IMP/domino/particle_states.h
3  * \brief A Bayesian inference-based sampler.
4  *
5  * Copyright 2007-2021 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef IMPDOMINO_PARTICLE_STATES_H
10 #define IMPDOMINO_PARTICLE_STATES_H
11 
12 #include <IMP/domino/domino_config.h>
13 #include "domino_macros.h"
14 #include "Subset.h"
15 #include "Assignment.h"
16 #include <IMP/Sampler.h>
17 #include <IMP/macros.h>
18 #include <IMP/SingletonContainer.h>
20 #include <IMP/algebra/Vector3D.h>
21 #include <IMP/core/rigid_bodies.h>
23 #include <IMP/Pointer.h>
24 #include <IMP/Vector.h>
25 #include <IMP/InputAdaptor.h>
27 #include <boost/unordered_map.hpp>
28 
29 IMPDOMINO_BEGIN_NAMESPACE
30 /** Handle the states for a particular particle (or "class" of
31  particles. For example a state enumerator class could take
32  a bounding box and a number,n, and generate n points in the
33  bounding box. Then the get_number function would return
34  n and update_to_state would modify the particle to have the
35  coordinates for state i.
36  */
37 class IMPDOMINOEXPORT ParticleStates : public IMP::Object {
38  public:
39  ParticleStates(std::string name = "ParticleStates %1%") : Object(name) {}
40  virtual unsigned int get_number_of_particle_states() const = 0;
41  virtual void load_particle_state(unsigned int, Particle *) const = 0;
42  //! Return an embedding of the state
43  /** By default this just returns a 1D vector containing the index.
44  The vector needs to have the same dimension for each value of
45  i.
46  */
47  virtual algebra::VectorKD get_embedding(unsigned int i) const {
48  Floats f(1, i);
49  return algebra::VectorKD(f.begin(), f.end());
50  }
51  //! Return the state closest to a given embedding
52  virtual unsigned int get_nearest_state(const algebra::VectorKD &v) const {
53  IMP_INTERNAL_CHECK(v.get_dimension() == 1,
54  "This is not a defaultly produced"
55  << " embedding.");
56  IMP_INTERNAL_CHECK(v[0] >= 0 && v[0] < get_number_of_particle_states(),
57  "Out of range state found, this is not a default "
58  << "embedding.");
59  return static_cast<unsigned int>(v[0]);
60  }
61  virtual ~ParticleStates();
62 };
63 
65 
66 /** Store the association between particles and the classes
67  which manage their states. I'm not a huge fan of having
68  this class, but I haven't thought of a better way to store
69  the information that is easily exposed to Python
70  and gets to all the right places. It is initialized internally
71  in the DominoSampler.
72  */
73 class IMPDOMINOEXPORT ParticleStatesTable : public IMP::Object {
74  typedef boost::unordered_map<Particle *,
76  Map enumerators_;
77  friend class DominoSampler;
78 
79  public:
80  ParticleStatesTable() : Object("ParticleStatesTable%1%") {}
81  // implementation methods use this to get the enumerator
82  ParticleStates *get_particle_states(Particle *p) const {
83  IMP_USAGE_CHECK(enumerators_.find(p) != enumerators_.end(),
84  "I don't know about particle " << p->get_name());
85  return enumerators_.find(p)->second;
86  }
87  bool get_has_particle(Particle *p) const {
88  return enumerators_.find(p) != enumerators_.end();
89  }
91  ParticlesTemp ret;
92  ret.reserve(enumerators_.size());
93  for (Map::const_iterator it = enumerators_.begin();
94  it != enumerators_.end(); ++it) {
95  ret.push_back(it->first);
96  }
97  std::sort(ret.begin(), ret.end());
98  return ret;
99  }
100  //! Return the subset corresponding to all the particles
101  Subset get_subset() const { return Subset(get_particles()); }
102  /** One can set the states more than once. If you do that, be
103  careful.
104  */
106  IMP_USAGE_CHECK(e->get_number_of_particle_states() > 0,
107  "Cannot have 0 states for a particle: \"" << p->get_name()
108  << "\"\n");
109  enumerators_[p] = e;
110  }
112 };
113 
115 
116 /** Store the state index in the particle. The particle must
117  already have the attribute in question.
118 */
119 class IMPDOMINOEXPORT IndexStates : public ParticleStates {
120  unsigned int n_;
121  IntKey k_;
122 
123  public:
124  /** n is the number of states and k is the attribute key
125  to use.*/
126  IndexStates(unsigned int n, IntKey k = IntKey("state"))
127  : ParticleStates("IndexStates %1%"), n_(n), k_(k) {}
128  virtual unsigned int get_number_of_particle_states() const IMP_OVERRIDE;
129  virtual void load_particle_state(unsigned int, Particle *) const
130  IMP_OVERRIDE;
132 };
133 
134 /** Store a set of states which explicitly define the XYZ coordinates of
135  the particle in question.
136 */
137 class IMPDOMINOEXPORT XYZStates : public ParticleStates {
138  algebra::Vector3Ds states_;
140 
141  public:
142  XYZStates(const algebra::Vector3Ds &states)
143  : ParticleStates("XYZStates %1%"),
144  states_(states),
145  nn_(new algebra::NearestNeighbor3D(states)) {}
146  algebra::Vector3D get_vector(unsigned int i) const {
147  IMP_USAGE_CHECK(i < states_.size(), "Out of range");
148  return states_[i];
149  }
150  algebra::VectorKD get_embedding(unsigned int i) const {
151  IMP_USAGE_CHECK(i < states_.size(), "Out of range");
152  return states_[i];
153  }
154  unsigned int get_nearest_state(const algebra::VectorKD &v) const {
155  return nn_->get_nearest_neighbors(v, 1)[0];
156  }
157  virtual unsigned int get_number_of_particle_states() const IMP_OVERRIDE;
158  virtual void load_particle_state(unsigned int, Particle *) const
159  IMP_OVERRIDE;
161 };
162 
163 /** Store a set of states which explicitly define the
164  transformation coordinates of the particle in question.
165 */
166 class IMPDOMINOEXPORT RigidBodyStates : public ParticleStates {
168  double scale_;
170 
171  public:
172  RigidBodyStates(const algebra::ReferenceFrame3Ds &states, double scale = 1);
173  algebra::ReferenceFrame3D get_reference_frame(unsigned int i) const {
174  IMP_USAGE_CHECK(i < states_.size(), "Out of range");
175  return states_[i];
176  }
177  algebra::VectorKD get_embedding(unsigned int i) const;
178  unsigned int get_nearest_state(const algebra::VectorKD &v) const;
179  virtual unsigned int get_number_of_particle_states() const IMP_OVERRIDE;
180  virtual void load_particle_state(unsigned int, Particle *) const
181  IMP_OVERRIDE;
183 };
184 
185 /** Store a set of states which explicitly define the
186  internal transformation of a rigid member
187 */
188 class IMPDOMINOEXPORT NestedRigidBodyStates : public ParticleStates {
189  algebra::Transformation3Ds states_; // states of a nested rigid body
190  double scale_;
192 
193  public:
194  /**
195  \param[in] states states of a rigid member with respect to its parent
196  \param[in] scale an estimate of the radius of the rigid bodies used.
197  Unfortunately, this is hard to determine automatically in the right
198  place.
199  */
201  double scale = 100);
202  algebra::Transformation3D get_transformation(unsigned int i) const {
203  IMP_USAGE_CHECK(i < states_.size(), "Out of range");
204  return states_[i];
205  }
206  algebra::VectorKD get_embedding(unsigned int i) const;
207  unsigned int get_nearest_state(const algebra::VectorKD &v) const;
208  virtual unsigned int get_number_of_particle_states() const IMP_OVERRIDE;
209  virtual void load_particle_state(unsigned int, Particle *) const
210  IMP_OVERRIDE;
212 };
213 
214 /** Combine two particle states together. They must both have the same
215  number of states.
216 */
217 class IMPDOMINOEXPORT CompoundStates : public ParticleStates {
219 
220  public:
221  CompoundStates(ParticleStates *a, ParticleStates *b)
222  : ParticleStates("CompoundStates %1%"), a_(a), b_(b) {}
223  virtual unsigned int get_number_of_particle_states() const IMP_OVERRIDE;
224  virtual void load_particle_state(unsigned int, Particle *) const
225  IMP_OVERRIDE;
227 };
228 
229 /** Load particle states for a set of particles based on the state
230  index of a single particle, This can be used to implement compound
231  objects (like rigid bodies), where state i of the particle being
232  sampled causes a set of representation balls to be moved to
233  certain locations.
234 */
235 class IMPDOMINOEXPORT RecursiveStates : public ParticleStates {
236  Subset s_;
237  Assignments ss_;
240 
241  public:
242  RecursiveStates(Particle *p, Subset s, const Assignments &ss,
243  ParticleStatesTable *pst);
244  virtual unsigned int get_number_of_particle_states() const IMP_OVERRIDE;
245  virtual void load_particle_state(unsigned int, Particle *) const
246  IMP_OVERRIDE;
248 };
249 
250 /** Permute the states of a particle. This might be useful when
251  trying to sample from a too large set of Assignments. However,
252  it will break many filters, so use with care.
253 */
254 class IMPDOMINOEXPORT PermutationStates : public ParticleStates {
256  IMP::Vector<int> permutation_;
257 
258  public:
259  PermutationStates(ParticleStates *inner);
260  /** Return the index of the ith state in the inner ParticleState
261  object.*/
262  unsigned int get_inner_state(unsigned int i) const {
263  IMP_CHECK_OBJECT(this);
264  IMP_USAGE_CHECK(i < permutation_.size(), "Out of range inner state");
265  unsigned int cur = permutation_[i];
266  IMP_INTERNAL_CHECK(cur < inner_->get_number_of_particle_states(),
267  "Out of range state returned. This is perplexing.");
268  return cur;
269  }
270  virtual unsigned int get_number_of_particle_states() const IMP_OVERRIDE;
271  virtual void load_particle_state(unsigned int, Particle *) const
272  IMP_OVERRIDE;
274 };
275 
276 #ifndef IMP_DOXYGEN
277 inline unsigned int PermutationStates::get_number_of_particle_states() const {
278  return inner_->get_number_of_particle_states();
279 }
280 inline void PermutationStates::load_particle_state(unsigned int i,
281  Particle *p) const {
282  return inner_->load_particle_state(get_inner_state(i), p);
283 }
284 #endif
285 
286 /** Accept either particles, decorators or ParticleStatesTable
287  as an input to define a list of particle.*/
289 #ifndef SWIG
290  public ParticlesTemp,
291  public InputAdaptor
292 #else
293  public InputAdaptor
294 #endif
295  {
296  public:
298  : ParticlesTemp(pst->get_particles()) {}
300  : ParticlesTemp(ps.begin(), ps.end()) {}
301 };
302 
303 IMPDOMINO_END_NAMESPACE
304 
305 #endif /* IMPDOMINO_PARTICLE_STATES_H */
unsigned int get_inner_state(unsigned int i) const
Simple 3D transformation class.
A container for Singletons.
unsigned int get_nearest_state(const algebra::VectorKD &v) const
Return the state closest to a given embedding.
Store a list of ParticleIndexes.
A Bayesian inference-based sampler.
#define IMP_CHECK_OBJECT(obj)
Perform some basic validity checks on the object for memory debugging.
Definition: check_macros.h:277
#define IMP_OBJECT_METHODS(Name)
Define the basic things needed by any Object.
Definition: object_macros.h:25
Sample best solutions using Domino.
Definition: DominoSampler.h:32
ParticlesTemp get_particles(Model *m, const ParticleIndexes &ps)
Get the particles from a list of indexes.
Represent a subset of the particles being optimized.
Definition: Subset.h:33
Various general useful macros for IMP.
A reference frame in 3D.
#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
algebra::VectorKD get_embedding(unsigned int i) const
Return an embedding of the state.
Convenience class to accept multiple input types.
Common base class for heavy weight IMP objects.
Definition: Object.h:106
virtual algebra::VectorKD get_embedding(unsigned int i) const
Return an embedding of the state.
functionality for defining rigid bodies
Base class for all samplers.
Various important macros for implementing decorators.
A smart pointer to a ref-counted Object that is a class member.
Definition: Pointer.h:146
Key< 1 > IntKey
The type used to identify int attributes in the Particles.
Definition: base_types.h:36
IndexStates(unsigned int n, IntKey k=IntKey("state"))
A class for storing lists of IMP items.
A Bayesian inference-based sampler.
#define IMP_OBJECTS(Name, PluralName)
Define the types for storing lists of object pointers.
Definition: object_macros.h:44
A nullptr-initialized pointer to an IMP Object.
Object(std::string name)
Construct an object with the given name.
VectorD< 3 > Vector3D
Definition: VectorD.h:421
Simple 3D vector class.
Class to handle individual particles of a Model object.
Definition: Particle.h:41
#define IMP_USAGE_CHECK(expr, message)
A runtime test for incorrect usage of a class or method.
Definition: check_macros.h:168
Functions to search over vectors.
A reference frame in 3D.
Convenience class to accept multiple input types.
Definition: InputAdaptor.h:25
void set_particle_states(Particle *p, ParticleStates *e)
Subset get_subset() const
Return the subset corresponding to all the particles.
VectorD<-1 > VectorKD
Definition: VectorD.h:437
#define IMP_OVERRIDE
Cause a compile error if this method does not override a parent method.
virtual unsigned int get_nearest_state(const algebra::VectorKD &v) const
Return the state closest to a given embedding.