IMP logo
IMP Reference Guide  2.20.1
The Integrative Modeling Platform
Particle.h
Go to the documentation of this file.
1 /**
2  * \file IMP/Particle.h
3  * \brief Classes to handle individual model particles.
4  * (Note that implementation of inline functions is in internal)
5  *
6  * Copyright 2007-2023 IMP Inventors. All rights reserved.
7  *
8  */
9 
10 #ifndef IMPKERNEL_PARTICLE_H
11 #define IMPKERNEL_PARTICLE_H
12 
13 #include <IMP/kernel_config.h>
14 #include "base_types.h"
15 #include "DerivativeAccumulator.h"
16 #include "Model.h"
17 #include "ModelObject.h"
18 #include "particle_index.h"
19 #include "Key.h"
20 #include "internal/AttributeTable.h"
21 #include <IMP/Object.h>
22 #include <IMP/utility.h>
23 #include <IMP/Pointer.h>
24 #include <IMP/check_macros.h>
25 #include <utility>
26 #include <cereal/access.hpp>
27 #include <cereal/types/base_class.hpp>
28 
29 IMPKERNEL_BEGIN_NAMESPACE
30 
31 //class Model;
32 class Changed;
33 class SaveOptimizeds;
34 
35 //! Class to handle individual particles of a Model object.
36 /** A particle is a lightweight object that serves as a place holder for the
37  particle index in a given Model object. The Model object itself stores
38  the particle attributes of various types:
39  Float, Int, String, Object, and WeakObject, and any data concerning the
40  optimization of these particles by Optimizer and Simulator classes.
41 
42 */
43 class IMPKERNELEXPORT Particle : public ModelObject {
44  private:
45 // doxygen produces funny docs for these things
46 #ifndef IMP_DOXYGEN
47  friend class Model;
48 #endif
49  ParticleIndex id_;
51 
52  public:
53  //! Construct a particle and add it to the Model
54  Particle(Model *m, std::string name);
55 
56  //! Construct a particle and add it to the Model
57  Particle(Model *m);
58 
59 #ifndef IMP_DOXYGEN
60  Particle() {}
61 
62 #define IMP_KERNEL_PARTICLE_ATTRIBUTE_TYPE_DECL(UCName, lcname, Value) \
63  inline void add_attribute(UCName##Key name, Value initial_value); \
64  inline void remove_attribute(UCName##Key name); \
65  inline bool has_attribute(UCName##Key name) const; \
66  inline Value get_value(UCName##Key name) const; \
67  inline void set_value(UCName##Key name, Value value); \
68  inline void add_cache_attribute(UCName##Key name, Value value); \
69  inline UCName##Keys get_##lcname##_keys() const
70 
71  IMP_KERNEL_PARTICLE_ATTRIBUTE_TYPE_DECL(Float, float, Float);
72  IMP_KERNEL_PARTICLE_ATTRIBUTE_TYPE_DECL(Floats, floats, Floats);
73  IMP_KERNEL_PARTICLE_ATTRIBUTE_TYPE_DECL(Int, int, Int);
74  IMP_KERNEL_PARTICLE_ATTRIBUTE_TYPE_DECL(Ints, ints, Ints);
75  IMP_KERNEL_PARTICLE_ATTRIBUTE_TYPE_DECL(String, string, String);
76  IMP_KERNEL_PARTICLE_ATTRIBUTE_TYPE_DECL(Object, object, Object *);
77  IMP_KERNEL_PARTICLE_ATTRIBUTE_TYPE_DECL(WeakObject, weak_object, Object *);
78 
79 #define IMP_KERNEL_SPARSE_PARTICLE_ATTRIBUTE_TYPE_DECL(UCName, lcname, Value) \
80  inline void add_attribute(UCName##Key name, Value initial_value); \
81  inline void remove_attribute(UCName##Key name); \
82  inline bool has_attribute(UCName##Key name) const; \
83  inline Value get_value(UCName##Key name) const; \
84  inline void set_value(UCName##Key name, Value value)
85 
86  IMP_KERNEL_SPARSE_PARTICLE_ATTRIBUTE_TYPE_DECL(SparseString, string, String);
87  IMP_KERNEL_SPARSE_PARTICLE_ATTRIBUTE_TYPE_DECL(SparseInt, int, Int);
88  IMP_KERNEL_SPARSE_PARTICLE_ATTRIBUTE_TYPE_DECL(SparseFloat, float, Float);
89  IMP_KERNEL_SPARSE_PARTICLE_ATTRIBUTE_TYPE_DECL(SparseParticleIndex,
90  particle_index, ParticleIndex);
91 
92  /** @name Float Attributes
93  Float attributes can be optimized, meaning an Optimizer class is
94  allowed to change their value in order to improve the score.
95  As a result, there are a number of specialized methods to manipulate
96  the value of float attributes.
97 
98  All distances are assumed to be in angstroms
99  and derivatives in kcal/mol/angstrom. This is not enforced.
100  */
101  /*@{*/
102  /** add attribute name to the attributes table of this particle
103 
104  @param name attribute key
105  @param initial_value initial value for the attribute
106  @param optimized whether to flag this attribute as optimized
107  */
108  void add_attribute(FloatKey name, const Float initial_value, bool optimized);
109 
110  /** Adds value to the derivatives table of the
111  specified particle attribute
112 
113  @param key the attribute key whose derivative is updated
114  @param value the derivative value to be added
115  @param da a derivative accumulator for reweighting derivatives
116  */
117  void add_to_derivative(FloatKey key, Float value,
118  const DerivativeAccumulator &da);
119 
120  void set_is_optimized(FloatKey k, bool tf);
121 
122  //! returns true if key k is marked by model as optimized
123  inline bool get_is_optimized(FloatKey k) const;
124 
125  //! returns the derivative of the specified particle attribute
126  inline Float get_derivative(FloatKey k) const;
127  /** @} */
128 
129  /** \name Particle attributes
130  @{
131  */
132  void add_attribute(ParticleIndexKey k, Particle *v);
133  bool has_attribute(ParticleIndexKey k);
134  void set_value(ParticleIndexKey k, Particle *v);
135  inline Particle *get_value(ParticleIndexKey k) const;
136  void remove_attribute(ParticleIndexKey k);
137  ParticleIndexKeys get_particle_keys() const;
138  /** @} */
139 
140  //! Print out all the attributes
141  void show(std::ostream &out = std::cout) const;
142 
143  //! Get whether the particle is active.
144  /** Restraints referencing the particle are only evaluated for 'active'
145  particles.
146  \return true it the particle is active.
147  */
148  bool get_is_active() const;
149 #endif
150 
151  //! returns the particle index of this particle in its model
152  ParticleIndex get_index() const;
153 
154 #if !defined(IMP_DOXYGEN)
155  void clear_caches() override;
156 #endif
157  protected:
158  virtual ModelObjectsTemp do_get_inputs() const override final {
159  return ModelObjectsTemp();
160  }
161  virtual ModelObjectsTemp do_get_outputs() const override final {
162  return ModelObjectsTemp();
163  }
164 
165  private:
166  friend class cereal::access;
167  template<class Archive> void serialize(Archive &ar) {
168  ar(cereal::base_class<ModelObject>(this), id_);
169  }
170 };
171 
172 // for swig
173 class Decorator;
174 
175 /** An adaptor that enable to implicitly pass particles to other
176  functions or constructors by passing either the particle itself
177  (in Python), a decorator to the particle, or a raw/smart IMP
178  pointer to the particle (in C++)
179 */
180 class IMPKERNELEXPORT ParticleAdaptor : public InputAdaptor {
181  Model *m_;
182  ParticleIndex pi_;
183 
184  public:
185  ParticleAdaptor() : m_(nullptr), pi_() {}
186  //! convert p to itself
187  ParticleAdaptor(Particle *p) : m_(p->get_model()), pi_(p->get_index()) {}
188  //! convert d to the particle it decorates
189  ParticleAdaptor(const Decorator &d);
190 #ifndef SWIG
192  : m_(p->get_model()), pi_(p->get_index()) {}
193  ParticleAdaptor(IMP::WeakPointer<Particle> p)
194  : m_(p->get_model()), pi_(p->get_index()) {}
195  ParticleAdaptor(IMP::PointerMember<Particle> p)
196  : m_(p->get_model()), pi_(p->get_index()) {}
197 #endif
198  Model *get_model() const { return m_; }
199  ParticleIndex get_particle_index() const { return pi_; }
200 };
201 
202 
203 /****************** Inline methods ***************/
204 
205 #ifndef IMP_DOXYGEN
206 
207 bool Particle::get_is_optimized(FloatKey k) const {
208  IMP_USAGE_CHECK(get_is_active(), "Inactive particle used.");
209  return get_model()->get_is_optimized(k, id_);
210 }
211 
212 Float Particle::get_derivative(FloatKey k) const {
213  IMP_USAGE_CHECK(get_is_active(), "Inactive particle used.");
214  return get_model()->get_derivative(k, id_);
215 }
216 
217 Particle *Particle::get_value(ParticleIndexKey k) const {
218  IMP_USAGE_CHECK(get_is_active(), "Inactive particle used.");
219  return get_model()->get_particle(get_model()->get_attribute(k, id_));
220 }
221 
222 #define IMP_PARTICLE_ATTRIBUTE_TYPE_DEF(UCName, lcname, Value) \
223  void Particle::add_attribute(UCName##Key name, Value initial_value) { \
224  IMP_USAGE_CHECK(get_is_active(), "Inactive particle used."); \
225  get_model()->add_attribute(name, id_, initial_value); \
226  } \
227  void Particle::remove_attribute(UCName##Key name) { \
228  IMP_USAGE_CHECK(get_is_active(), "Inactive particle used."); \
229  get_model()->remove_attribute(name, id_); \
230  } \
231  bool Particle::has_attribute(UCName##Key name) const { \
232  IMP_USAGE_CHECK(get_is_active(), "Inactive particle used."); \
233  return get_model()->get_has_attribute(name, id_); \
234  } \
235  Value Particle::get_value(UCName##Key name) const { \
236  IMP_USAGE_CHECK(get_is_active(), "Inactive particle used."); \
237  return get_model()->get_attribute(name, id_); \
238  } \
239  void Particle::set_value(UCName##Key name, Value value) { \
240  IMP_USAGE_CHECK(get_is_active(), "Inactive particle used."); \
241  get_model()->set_attribute(name, id_, value); \
242  } \
243  UCName##Keys Particle::get_##lcname##_keys() const { \
244  IMP_USAGE_CHECK(get_is_active(), "Inactive particle used."); \
245  return get_model()->internal::UCName##AttributeTable::get_attribute_keys( \
246  id_); \
247  } \
248  void Particle::add_cache_attribute(UCName##Key name, Value value) { \
249  IMP_USAGE_CHECK(get_is_active(), "Inactive particle used."); \
250  return get_model()->add_cache_attribute(name, id_, value); \
251  }
252 
253 IMP_PARTICLE_ATTRIBUTE_TYPE_DEF(Float, float, Float);
254 IMP_PARTICLE_ATTRIBUTE_TYPE_DEF(Floats, floats, Floats);
255 IMP_PARTICLE_ATTRIBUTE_TYPE_DEF(Int, int, Int);
256 IMP_PARTICLE_ATTRIBUTE_TYPE_DEF(Ints, ints, Ints);
257 IMP_PARTICLE_ATTRIBUTE_TYPE_DEF(String, string, String);
258 IMP_PARTICLE_ATTRIBUTE_TYPE_DEF(Object, object, Object *);
259 IMP_PARTICLE_ATTRIBUTE_TYPE_DEF(WeakObject, weak_object, Object *);
260 
261 #define IMP_SPARSE_PARTICLE_ATTRIBUTE_TYPE_DEF(UCName, lcname, Value) \
262  void Particle::add_attribute(UCName##Key name, Value initial_value) { \
263  IMP_USAGE_CHECK(get_is_active(), "Inactive particle used."); \
264  get_model()->add_attribute(name, id_, initial_value); \
265  } \
266  void Particle::remove_attribute(UCName##Key name) { \
267  IMP_USAGE_CHECK(get_is_active(), "Inactive particle used."); \
268  get_model()->remove_attribute(name, id_); \
269  } \
270  bool Particle::has_attribute(UCName##Key name) const { \
271  IMP_USAGE_CHECK(get_is_active(), "Inactive particle used."); \
272  return get_model()->get_has_attribute(name, id_); \
273  } \
274  Value Particle::get_value(UCName##Key name) const { \
275  IMP_USAGE_CHECK(get_is_active(), "Inactive particle used."); \
276  return get_model()->get_attribute(name, id_); \
277  } \
278  void Particle::set_value(UCName##Key name, Value value) { \
279  IMP_USAGE_CHECK(get_is_active(), "Inactive particle used."); \
280  get_model()->set_attribute(name, id_, value); \
281  }
282 
283 IMP_SPARSE_PARTICLE_ATTRIBUTE_TYPE_DEF(SparseString, string, String);
284 IMP_SPARSE_PARTICLE_ATTRIBUTE_TYPE_DEF(SparseInt, int, Int);
285 IMP_SPARSE_PARTICLE_ATTRIBUTE_TYPE_DEF(SparseFloat, float, Float);
286 IMP_SPARSE_PARTICLE_ATTRIBUTE_TYPE_DEF(SparseParticleIndex, particle_index,
287  ParticleIndex);
288 
289 #endif // DOXYGEN
290 
291 IMPKERNEL_END_NAMESPACE
292 #endif /* IMPKERNEL_PARTICLE_H */
virtual ModelObjectsTemp do_get_outputs() const overridefinal
Definition: Particle.h:161
Basic types used by IMP.
Key< 0 > FloatKey
The type used to identify float attributes in the Particles.
Definition: base_types.h:32
Smart pointer to Object-derived classes that does not refcount.
Definition: WeakPointer.h:77
Functions and adaptors for dealing with particle indexes.
IMP::Vector< Float > Floats
Standard way to pass a bunch of Float values.
Definition: types.h:46
#define IMP_OBJECT_METHODS(Name)
Define the basic things needed by any Object.
Definition: object_macros.h:25
Class for adding derivatives from restraints to the model.
Storage of a model, its restraints, constraints and particles.
Index< ParticleIndexTag > ParticleIndex
Definition: base_types.h:178
Keys to cache lookup of attribute strings.
virtual void clear_caches()
Definition: Object.h:270
A smart pointer to a reference counted object.
Definition: Pointer.h:87
IMP::Vector< IMP::WeakPointer< ModelObject > > ModelObjectsTemp
Definition: base_types.h:106
Class for storing model, its restraints, constraints, and particles.
Definition: Model.h:86
Base class for objects in a Model that depend on other objects.
Definition: ModelObject.h:28
Key< 3 > ParticleIndexKey
The type used to identify a particle attribute in the Particles.
Definition: base_types.h:44
Ints get_index(const ParticlesTemp &particles, const Subset &subset, const Subsets &excluded)
Common base class for heavy weight IMP objects.
Definition: Object.h:111
A smart pointer to a ref-counted Object that is a class member.
Definition: Pointer.h:143
Various general useful functions for IMP.
Base class for objects in a Model that depend on other objects.
Interface to specialized Particle types (e.g. atoms)
Definition: Decorator.h:119
std::ostream & show(Hierarchy h, std::ostream &out=std::cout)
Print the hierarchy using a given decorator to display each node.
virtual ModelObjectsTemp do_get_inputs() const overridefinal
Definition: Particle.h:158
A nullptr-initialized pointer to an IMP Object.
Helper macros for throwing and handling exceptions.
A shared base class to help in debugging and things.
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
#define IMP_USAGE_CHECK(expr, message)
A runtime test for incorrect usage of a class or method.
Definition: check_macros.h:168
int Int
Basic integer value.
Definition: types.h:34
IMP::Vector< Int > Ints
Standard way to pass a bunch of Int values.
Definition: types.h:48
Convenience class to accept multiple input types.
Definition: InputAdaptor.h:25
std::string String
Basic string value.
Definition: types.h:43
Class for adding derivatives from restraints to the model.
ParticleAdaptor(Particle *p)
convert p to itself
Definition: Particle.h:187