9 #ifndef IMPKERNEL_MODEL_H
10 #define IMPKERNEL_MODEL_H
12 #include <IMP/kernel_config.h>
22 #include "internal/AttributeTable.h"
23 #include "internal/attribute_tables.h"
24 #include "internal/moved_particles_cache.h"
25 #include "internal/KeyVector.h"
28 #include <IMP/internal/IDGenerator.h>
29 #include <boost/unordered_map.hpp>
30 #include <boost/unordered_set.hpp>
32 #include <boost/iterator/transform_iterator.hpp>
33 #include <boost/iterator/filter_iterator.hpp>
34 #include <cereal/access.hpp>
35 #include <cereal/types/polymorphic.hpp>
39 IMPKERNEL_BEGIN_NAMESPACE
45 #if !defined(SWIG) && !defined(IMP_DOXYGEN)
52 COMPUTING_DEPENDENCIES
59 #if !defined(SWIG) && !defined(IMP_DOXYGEN)
61 inline std::ostream &operator<<(
62 std::ostream &out,
const std::set<ModelObject *> &) {
63 out <<
"(set of ModelObject)";
87 #if !defined(SWIG) && !defined(IMP_DOXYGEN)
89 public internal::Masks,
92 public internal::FloatAttributeTable,
93 public internal::StringAttributeTable,
94 public internal::IntAttributeTable,
95 public internal::ObjectAttributeTable,
96 public internal::WeakObjectAttributeTable,
97 public internal::IntsAttributeTable,
98 public internal::FloatsAttributeTable,
99 public internal::Vector3DAttributeTable,
100 public internal::Vector4DAttributeTable,
101 public internal::ObjectsAttributeTable,
102 public internal::ParticleAttributeTable,
103 public internal::ParticlesAttributeTable,
104 public internal::SparseStringAttributeTable,
105 public internal::SparseIntAttributeTable,
106 public internal::SparseFloatAttributeTable,
107 public internal::SparseParticleAttributeTable,
108 public internal::Vector3DDerivAttributeTable,
109 public internal::Vector4DDerivAttributeTable
112 typedef std::set<ModelObject *> Edges;
115 IMP_NAMED_TUPLE_5(NodeInfo,
NodeInfos, Edges, inputs, Edges, input_outputs,
116 Edges, outputs, Edges, readers, Edges, writers, );
117 typedef boost::unordered_map<const ModelObject *, NodeInfo>
DependencyGraph;
118 DependencyGraph dependency_graph_;
119 boost::unordered_set<const ModelObject *> no_dependencies_;
120 boost::unordered_map<const ModelObject *, ScoreStatesTemp>
121 required_score_states_;
124 boost::unordered_map<FloatKey, FloatRange> ranges_;
130 internal::KeyVector<ModelKey, PointerMember<Object> > model_data_;
132 #if !defined(IMP_DOXYGEN)
135 std::map<uint32_t, Model*> map_;
136 internal::IDGenerator id_gen_;
139 uint32_t add_new_model(
Model *m);
140 void add_model_with_id(
Model *m, uint32_t
id);
141 void remove_model(
Model *m);
142 Model *
get(uint32_t id)
const;
145 static ModelMap model_map_;
150 void do_clear_required_score_states(
ModelObject *mo);
151 void do_check_required_score_states(
const ModelObject *mo)
const;
152 void do_check_update_order(
const ScoreState *ss)
const;
153 void do_check_inputs_and_outputs(
const ModelObject *mo)
const;
154 void do_check_readers_and_writers(
const ModelObject *mo)
const;
155 void do_check_not_in_readers_and_writers(
const ModelObject *mo)
const;
159 unsigned age_counter_;
163 unsigned dependencies_age_;
165 unsigned removed_particles_attributes_age_;
168 bool dependencies_saved_;
169 unsigned saved_dependencies_age_;
172 std::vector<ModelObject *> mos_added_since_save_, mos_removed_since_save_;
176 internal::MovedParticlesRestraintCache moved_particles_restraint_cache_;
178 internal::MovedParticlesParticleCache moved_particles_particle_cache_;
180 unsigned moved_particles_cache_age_;
182 void register_unique_id();
184 friend class cereal::access;
186 template<
class Archive>
void serialize(Archive &ar,
187 std::uint32_t
const version) {
188 ar(cereal::base_class<Object>(
this));
192 if (std::is_base_of<cereal::detail::InputArchiveBase, Archive>::value) {
193 register_unique_id();
195 ar(cereal::base_class<internal::FloatAttributeTable>(
this),
196 cereal::base_class<internal::StringAttributeTable>(
this),
197 cereal::base_class<internal::IntAttributeTable>(
this),
198 cereal::base_class<internal::IntsAttributeTable>(
this),
199 cereal::base_class<internal::FloatsAttributeTable>(
this),
200 cereal::base_class<internal::Vector3DAttributeTable>(
this),
201 cereal::base_class<internal::ParticleAttributeTable>(
this),
202 cereal::base_class<internal::ParticlesAttributeTable>(
this),
203 cereal::base_class<internal::SparseStringAttributeTable>(
this),
204 cereal::base_class<internal::SparseIntAttributeTable>(
this),
205 cereal::base_class<internal::SparseFloatAttributeTable>(
this),
206 cereal::base_class<internal::SparseParticleAttributeTable>(
this),
207 cereal::base_class<internal::Vector3DDerivAttributeTable>(
this),
208 cereal::base_class<internal::Vector4DAttributeTable>(
this),
209 cereal::base_class<internal::Vector4DDerivAttributeTable>(
this));
211 if (std::is_base_of<cereal::detail::InputArchiveBase, Archive>::value) {
213 free_particles_.clear();
215 particle_index_.clear();
223 for (
auto pi : to_free) {
227 size_t count = particle_index_.size();
229 for (
size_t i = 0; i < count; ++i) {
241 ar(cereal::base_class<internal::ObjectAttributeTable>(
this),
242 cereal::base_class<internal::ObjectsAttributeTable>(
this),
243 cereal::base_class<internal::WeakObjectAttributeTable>(
this),
244 model_data_, mutable_access_score_states());
246 if (std::is_base_of<cereal::detail::InputArchiveBase, Archive>::value) {
249 trigger_age_.clear();
250 dependencies_age_ = 0;
251 removed_particles_attributes_age_ = 0;
252 saved_dependencies_age_ = 0;
253 dependencies_saved_ =
false;
254 moved_particles_cache_age_ = 0;
259 void increase_age() {
261 if (age_counter_ == 0) {
266 template <
class MOType,
class MOVector>
267 void do_get_dependent(
ModelObject *mo, MOVector &ret) {
268 const auto &node = dependency_graph_.find(mo);
270 "Object " << mo->get_name()
271 <<
" does not have dependencies.");
273 "Node not in dependency_graph.");
274 MOType *r =
dynamic_cast<MOType *
>(mo);
278 for (
ModelObject *cur : node->second.get_outputs()) {
279 do_get_dependent<MOType, MOVector>(cur, ret);
281 for (
ModelObject *cur : node->second.get_readers()) {
282 do_get_dependent<MOType, MOVector>(cur, ret);
286 #if !defined(IMP_DOXYGEN) && !defined(SWIG)
293 internal::Stage cur_stage_;
296 const std::set<Restraint *> &get_dependent_restraints(
ParticleIndex pi) {
297 return moved_particles_restraint_cache_.get_dependent_restraints(pi);
302 return moved_particles_particle_cache_.get_dependent_particles(pi);
307 bool do_get_has_dependencies(
const ModelObject *mo)
const {
308 return no_dependencies_.find(mo) == no_dependencies_.end();
310 void do_set_has_dependencies(
const ModelObject *mo,
bool tf);
311 void do_set_has_all_dependencies(
bool tf);
313 void validate_computed_derivatives()
const {}
314 void set_has_all_dependencies(
bool tf);
315 bool get_has_all_dependencies()
const;
316 void check_dependency_invariants()
const;
317 void check_dependency_invariants(
const ModelObject *mo)
const;
324 internal::Stage get_stage()
const {
return cur_stage_; }
326 static void do_remove_score_state(
ScoreState *obj);
329 bool do_get_has_required_score_states(
const ModelObject *mo)
const;
330 void do_set_has_required_score_states(
ModelObject *mo,
bool tf);
334 "Doesn't have score states");
335 return required_score_states_.find(mo)->second;
342 Model(std::string name =
"Model %1%");
345 #if !defined(SWIG) && !defined(IMP_DOXYGEN)
346 IMP_MODEL_DERIV_IMPORT(internal::FloatAttributeTable);
347 IMP_MODEL_IMPORT(internal::StringAttributeTable);
348 IMP_MODEL_IMPORT(internal::IntAttributeTable);
349 IMP_MODEL_IMPORT(internal::ObjectAttributeTable);
350 IMP_MODEL_IMPORT(internal::WeakObjectAttributeTable);
351 IMP_MODEL_IMPORT(internal::IntsAttributeTable);
352 IMP_MODEL_IMPORT(internal::FloatsAttributeTable);
353 IMP_MODEL_IMPORT(internal::Vector3DAttributeTable);
354 IMP_MODEL_IMPORT(internal::Vector4DAttributeTable);
355 IMP_MODEL_IMPORT(internal::ObjectsAttributeTable);
356 IMP_MODEL_IMPORT(internal::ParticleAttributeTable);
357 IMP_MODEL_IMPORT(internal::ParticlesAttributeTable);
358 IMP_MODEL_SPARSE_IMPORT(internal::SparseStringAttributeTable);
359 IMP_MODEL_SPARSE_IMPORT(internal::SparseIntAttributeTable);
360 IMP_MODEL_SPARSE_IMPORT(internal::SparseFloatAttributeTable);
361 IMP_MODEL_SPARSE_IMPORT(internal::SparseParticleAttributeTable);
362 IMP_MODEL_DERIV_IMPORT(internal::Vector3DDerivAttributeTable);
363 IMP_MODEL_DERIV_IMPORT(internal::Vector4DDerivAttributeTable);
365 void zero_derivatives() {
366 internal::FloatAttributeTable::zero_derivatives();
367 internal::Vector3DDerivAttributeTable::zero_derivatives();
368 internal::Vector4DDerivAttributeTable::zero_derivatives();
384 #if !defined(IMP_DOXYGEN)
406 do_remove_score_state(obj));
441 void add_attribute(TypeKey attribute_key,
ParticleIndex particle, Type value);
445 void remove_attribute(TypeKey attribute_key,
ParticleIndex particle);
448 bool get_has_attribute(TypeKey attribute_key,
ParticleIndex particle)
const;
452 void set_attribute(TypeKey attribute_key,
ParticleIndex particle, Type value);
456 Type get_attribute(TypeKey attribute_key,
ParticleIndex particle);
469 void add_cache_attribute(TypeKey attribute_key,
ParticleIndex particle,
474 void set_is_optimized(TypeKey attribute_key,
ParticleIndex particle,
480 #define IMP_MODEL_ATTRIBUTE_METHODS(Type, Value) \
481 void add_attribute(Type##Key attribute_key, ParticleIndex particle, \
483 void remove_attribute(Type##Key attribute_key, ParticleIndex particle); \
484 bool get_has_attribute(Type##Key attribute_key, \
485 ParticleIndex particle) const; \
486 void set_attribute(Type##Key attribute_key, ParticleIndex particle, \
488 Value get_attribute(Type##Key attribute_key, ParticleIndex particle); \
489 void add_cache_attribute(Type##Key attribute_key, ParticleIndex particle, \
492 #define IMP_MODEL_DERIV_ATTRIBUTE_METHODS(Type, Value) \
493 IMP_MODEL_ATTRIBUTE_METHODS(Type, Value); \
494 void add_to_derivative(Type##Key attribute_key, ParticleIndex particle, \
495 const Value &v, const DerivativeAccumulator &da); \
496 void set_is_optimized(Type##Key, ParticleIndex, bool)
498 #define IMP_MODEL_SPARSE_ATTRIBUTE_METHODS(Type, Value) \
499 void add_attribute(Type##Key attribute_key, ParticleIndex particle, \
501 void remove_attribute(Type##Key attribute_key, ParticleIndex particle); \
502 bool get_has_attribute(Type##Key attribute_key, \
503 ParticleIndex particle) const; \
504 void set_attribute(Type##Key attribute_key, ParticleIndex particle, \
506 Value get_attribute(Type##Key attribute_key, ParticleIndex particle)
509 IMP_MODEL_ATTRIBUTE_METHODS(
Int,
Int);
513 IMP_MODEL_DERIV_ATTRIBUTE_METHODS(Vector3DDeriv,
IMP::Vector3D);
514 IMP_MODEL_DERIV_ATTRIBUTE_METHODS(Vector4DDeriv,
IMP::Vector4D);
515 IMP_MODEL_ATTRIBUTE_METHODS(
Ints,
Ints);
520 IMP_MODEL_ATTRIBUTE_METHODS(WeakObject,
Object *);
521 IMP_MODEL_SPARSE_ATTRIBUTE_METHODS(SparseString,
String);
522 IMP_MODEL_SPARSE_ATTRIBUTE_METHODS(SparseInt,
Int);
523 IMP_MODEL_SPARSE_ATTRIBUTE_METHODS(SparseFloat,
Float);
524 IMP_MODEL_SPARSE_ATTRIBUTE_METHODS(SparseParticleIndex,
ParticleIndex);
533 return particle_index_[p];
538 if (particle_index_.size() <= get_as_unsigned_int(p))
return false;
539 return particle_index_[p];
566 bool get_has_data(
ModelKey mk)
const;
604 if (trigger_age_.size() > tk.get_index()) {
605 return trigger_age_[tk.get_index()];
613 if (tk.get_index() >= trigger_age_.size()) {
614 trigger_age_.resize(tk.get_index() + 1, 0);
616 trigger_age_[tk.get_index()] = age_counter_;
631 return removed_particles_attributes_age_;
637 dependencies_saved_ =
true;
638 saved_dependencies_age_ = dependencies_age_;
640 mos_added_since_save_.clear();
641 mos_removed_since_save_.clear();
660 if (dependencies_saved_) {
661 dependencies_saved_ =
false;
662 dependencies_age_ = saved_dependencies_age_;
665 std::sort(mos_added_since_save_.begin(), mos_added_since_save_.end());
666 std::sort(mos_removed_since_save_.begin(),
667 mos_removed_since_save_.end());
669 "ModelObjects added do not match those removed");
690 return model_map_.get(
id);
696 #if !defined(IMP_DOXYGEN)
701 IMPKERNEL_END_NAMESPACE
703 CEREAL_SPECIALIZE_FOR_ALL_ARCHIVES(
704 IMP::Model, cereal::specialization::member_serialize);
Particle * get_particle(ParticleIndex p) const
Get the particle from an index.
#define IMP_IF_CHECK(level)
Execute the code block if a certain level checks are on.
Used to hold a set of related restraints.
boost::graph DependencyGraph
Directed graph on the interactions between the various objects in the model.
The base class for undecorators.
#define IMP_OBJECT_METHODS(Name)
Define the basic things needed by any Object.
void restore_dependencies()
Restore ModelObject dependencies to previous restore point.
Index< ParticleIndexTag > ParticleIndex
void add_particle(RMF::FileHandle fh, Particle *hs)
Macros to help in defining tuple classes.
virtual void clear_caches()
unsigned get_dependencies_updated()
Get the model age when ModelObject dependencies were last changed, or 0.
A more IMP-like version of the std::vector.
unsigned get_particles_size() const
Get an upper bound on the number of particles in the Model.
unsigned get_age()
Get the current 'model time'.
bool get_has_particle(ParticleIndex p) const
Check whether a given particle index exists.
Macros to define containers of objects.
unsigned get_trigger_last_updated(TriggerKey tk)
Get the time when the given trigger was last updated, or 0.
#define IMP_INTERNAL_CHECK(expr, message)
An assertion to check for internal errors in IMP. An IMP::ErrorException will be thrown.
Class for storing model, its restraints, constraints, and particles.
Base class for objects in a Model that depend on other objects.
virtual void do_destroy()
Common base class for heavy weight IMP objects.
ParticleIndexes get_particle_indexes(ParticlesTemp const &particles)
ScoreStates maintain invariants in the Model.
static Model * get_by_unique_id(uint32_t id)
Return the Model with the given unique ID.
uint32_t get_unique_id() const
Get the unique ID of this Model.
Implements a vector tied to a particular index of type Index<Tag>.
unsigned get_removed_particles_attributes_age()
Get the model age when particles or attributes were last removed, or 0.
Base class for objects in a Model that depend on other objects.
Classes to handle individual model particles. (Note that implementation of inline functions is in int...
A nullptr-initialized pointer to an IMP Object.
void save_dependencies()
Mark a 'restore point' for ModelObject dependencies.
A shared base class to help in debugging and things.
Represents a scoring function on the model.
double Float
Basic floating-point value (could be float, double...)
Class to handle individual particles of a Model object.
bool get_has_dependencies() const
Return whether this object has dependencies computed.
#define IMP_USAGE_CHECK(expr, message)
A runtime test for incorrect usage of a class or method.
Abstract base class for all restraints.
int Int
Basic integer value.
void set_trigger_updated(TriggerKey tk)
Update the given trigger.
std::string String
Basic string value.
Class for adding derivatives from restraints to the model.