IMP logo
IMP Reference Guide  develop.45c11de31d,2024/03/27
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-2022 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 override;
129  virtual void load_particle_state(unsigned int, Particle *) const
130  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 override {
151  IMP_USAGE_CHECK(i < states_.size(), "Out of range");
152  return states_[i];
153  }
154  unsigned int get_nearest_state(
155  const algebra::VectorKD &v) const override {
156  return nn_->get_nearest_neighbors(v, 1)[0];
157  }
158  virtual unsigned int get_number_of_particle_states() const override;
159  virtual void load_particle_state(unsigned int, Particle *) const
160  override;
162 };
163 
164 /** Store a set of states which explicitly define the
165  transformation coordinates of the particle in question.
166 */
167 class IMPDOMINOEXPORT RigidBodyStates : public ParticleStates {
169  double scale_;
171 
172  public:
173  RigidBodyStates(const algebra::ReferenceFrame3Ds &states, double scale = 1);
174  algebra::ReferenceFrame3D get_reference_frame(unsigned int i) const {
175  IMP_USAGE_CHECK(i < states_.size(), "Out of range");
176  return states_[i];
177  }
178  algebra::VectorKD get_embedding(unsigned int i) const override;
179  unsigned int get_nearest_state(const algebra::VectorKD &v) const override;
180  virtual unsigned int get_number_of_particle_states() const override;
181  virtual void load_particle_state(unsigned int, Particle *) const
182  override;
184 };
185 
186 /** Store a set of states which explicitly define the
187  internal transformation of a rigid member
188 */
189 class IMPDOMINOEXPORT NestedRigidBodyStates : public ParticleStates {
190  algebra::Transformation3Ds states_; // states of a nested rigid body
191  double scale_;
193 
194  public:
195  /**
196  \param[in] states states of a rigid member with respect to its parent
197  \param[in] scale an estimate of the radius of the rigid bodies used.
198  Unfortunately, this is hard to determine automatically in the right
199  place.
200  */
202  double scale = 100);
203  algebra::Transformation3D get_transformation(unsigned int i) const {
204  IMP_USAGE_CHECK(i < states_.size(), "Out of range");
205  return states_[i];
206  }
207  algebra::VectorKD get_embedding(unsigned int i) const override;
208  unsigned int get_nearest_state(const algebra::VectorKD &v) const override;
209  virtual unsigned int get_number_of_particle_states() const override;
210  virtual void load_particle_state(unsigned int, Particle *) const
211  override;
213 };
214 
215 /** Combine two particle states together. They must both have the same
216  number of states.
217 */
218 class IMPDOMINOEXPORT CompoundStates : public ParticleStates {
220 
221  public:
223  : ParticleStates("CompoundStates %1%"), a_(a), b_(b) {}
224  virtual unsigned int get_number_of_particle_states() const override;
225  virtual void load_particle_state(unsigned int, Particle *) const
226  override;
228 };
229 
230 /** Load particle states for a set of particles based on the state
231  index of a single particle, This can be used to implement compound
232  objects (like rigid bodies), where state i of the particle being
233  sampled causes a set of representation balls to be moved to
234  certain locations.
235 */
236 class IMPDOMINOEXPORT RecursiveStates : public ParticleStates {
237  Subset s_;
238  Assignments ss_;
241 
242  public:
243  RecursiveStates(Particle *p, Subset s, const Assignments &ss,
244  ParticleStatesTable *pst);
245  virtual unsigned int get_number_of_particle_states() const override;
246  virtual void load_particle_state(unsigned int, Particle *) const
247  override;
249 };
250 
251 /** Permute the states of a particle. This might be useful when
252  trying to sample from a too large set of Assignments. However,
253  it will break many filters, so use with care.
254 */
255 class IMPDOMINOEXPORT PermutationStates : public ParticleStates {
257  IMP::Vector<int> permutation_;
258 
259  public:
261  /** Return the index of the ith state in the inner ParticleState
262  object.*/
263  unsigned int get_inner_state(unsigned int i) const {
264  IMP_CHECK_OBJECT(this);
265  IMP_USAGE_CHECK(i < permutation_.size(), "Out of range inner state");
266  unsigned int cur = permutation_[i];
267  IMP_INTERNAL_CHECK(cur < inner_->get_number_of_particle_states(),
268  "Out of range state returned. This is perplexing.");
269  return cur;
270  }
271  virtual unsigned int get_number_of_particle_states() const override;
272  virtual void load_particle_state(unsigned int, Particle *) const
273  override;
275 };
276 
277 #ifndef IMP_DOXYGEN
278 inline unsigned int PermutationStates::get_number_of_particle_states() const {
279  return inner_->get_number_of_particle_states();
280 }
281 inline void PermutationStates::load_particle_state(unsigned int i,
282  Particle *p) const {
283  return inner_->load_particle_state(get_inner_state(i), p);
284 }
285 #endif
286 
287 /** Accept either particles, decorators or ParticleStatesTable
288  as an input to define a list of particle.*/
290 #ifndef SWIG
291  public ParticlesTemp,
292  public InputAdaptor
293 #else
294  public InputAdaptor
295 #endif
296  {
297  public:
299  : ParticlesTemp(pst->get_particles()) {}
301  : ParticlesTemp(ps.begin(), ps.end()) {}
302 };
303 
304 IMPDOMINO_END_NAMESPACE
305 
306 #endif /* IMPDOMINO_PARTICLE_STATES_H */
unsigned int get_nearest_state(const algebra::VectorKD &v) const override
Return the state closest to a given embedding.
unsigned int get_inner_state(unsigned int i) const
Simple 3D transformation class.
A container for Singletons.
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
algebra::VectorKD get_embedding(unsigned int i) const override
Return an embedding of the state.
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
Convenience class to accept multiple input types.
Common base class for heavy weight IMP objects.
Definition: Object.h:111
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:143
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:408
Simple 3D vector class.
Class to handle individual particles of a Model object.
Definition: Particle.h:43
#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:424
virtual unsigned int get_nearest_state(const algebra::VectorKD &v) const
Return the state closest to a given embedding.