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::ObjectsAttributeTable,
 
  100                               public internal::ParticleAttributeTable,
 
  101                               public internal::ParticlesAttributeTable,
 
  102                               public internal::SparseStringAttributeTable,
 
  103                               public internal::SparseIntAttributeTable,
 
  104                               public internal::SparseFloatAttributeTable,
 
  105                               public internal::SparseParticleAttributeTable
 
  108   typedef std::set<ModelObject *> Edges;
 
  111   IMP_NAMED_TUPLE_5(NodeInfo, 
NodeInfos, Edges, inputs, Edges, input_outputs,
 
  112                     Edges, outputs, Edges, readers, Edges, writers, );
 
  113   typedef boost::unordered_map<const ModelObject *, NodeInfo> 
DependencyGraph;
 
  114   DependencyGraph dependency_graph_;
 
  115   boost::unordered_set<const ModelObject *> no_dependencies_;
 
  116   boost::unordered_map<const ModelObject *, ScoreStatesTemp>
 
  117       required_score_states_;
 
  120   boost::unordered_map<FloatKey, FloatRange> ranges_;
 
  126   internal::KeyVector<ModelKey, PointerMember<Object> > model_data_;
 
  128 #if !defined(IMP_DOXYGEN) 
  131     std::map<uint32_t, Model*> map_;
 
  132     internal::IDGenerator id_gen_;
 
  135     uint32_t add_new_model(
Model *m);
 
  136     void add_model_with_id(
Model *m, uint32_t 
id);
 
  137     void remove_model(
Model *m);
 
  138     Model *
get(uint32_t id) 
const;
 
  141   static ModelMap model_map_;
 
  146   void do_clear_required_score_states(
ModelObject *mo);
 
  147   void do_check_required_score_states(
const ModelObject *mo) 
const;
 
  148   void do_check_update_order(
const ScoreState *ss) 
const;
 
  149   void do_check_inputs_and_outputs(
const ModelObject *mo) 
const;
 
  150   void do_check_readers_and_writers(
const ModelObject *mo) 
const;
 
  151   void do_check_not_in_readers_and_writers(
const ModelObject *mo) 
const;
 
  155   unsigned age_counter_;
 
  159   unsigned dependencies_age_;
 
  161   unsigned removed_particles_attributes_age_;
 
  164   bool dependencies_saved_;
 
  165   unsigned saved_dependencies_age_;
 
  168   std::vector<ModelObject *> mos_added_since_save_, mos_removed_since_save_;
 
  172   internal::MovedParticlesRestraintCache moved_particles_restraint_cache_;
 
  174   internal::MovedParticlesParticleCache moved_particles_particle_cache_;
 
  176   unsigned moved_particles_cache_age_;
 
  178   void register_unique_id();
 
  180   friend class cereal::access;
 
  182   template<
class Archive> 
void serialize(Archive &ar,
 
  183                                          std::uint32_t 
const version) {
 
  184     ar(cereal::base_class<Object>(
this));
 
  188     if (std::is_base_of<cereal::detail::InputArchiveBase, Archive>::value) {
 
  189       register_unique_id();
 
  191     ar(cereal::base_class<internal::FloatAttributeTable>(
this),
 
  192        cereal::base_class<internal::StringAttributeTable>(
this),
 
  193        cereal::base_class<internal::IntAttributeTable>(
this),
 
  194        cereal::base_class<internal::IntsAttributeTable>(
this),
 
  195        cereal::base_class<internal::FloatsAttributeTable>(
this),
 
  196        cereal::base_class<internal::ParticleAttributeTable>(
this),
 
  197        cereal::base_class<internal::ParticlesAttributeTable>(
this),
 
  198        cereal::base_class<internal::SparseStringAttributeTable>(
this),
 
  199        cereal::base_class<internal::SparseIntAttributeTable>(
this),
 
  200        cereal::base_class<internal::SparseFloatAttributeTable>(
this),
 
  201        cereal::base_class<internal::SparseParticleAttributeTable>(
this));
 
  203     if (std::is_base_of<cereal::detail::InputArchiveBase, Archive>::value) {
 
  205       free_particles_.clear();
 
  207       particle_index_.clear();
 
  215       for (
auto pi : to_free) {
 
  219       size_t count = particle_index_.size();
 
  221       for (
size_t i = 0; i < count; ++i) {
 
  233     ar(cereal::base_class<internal::ObjectAttributeTable>(
this),
 
  234        cereal::base_class<internal::ObjectsAttributeTable>(
this),
 
  235        cereal::base_class<internal::WeakObjectAttributeTable>(
this),
 
  236        model_data_, mutable_access_score_states());
 
  238     if (std::is_base_of<cereal::detail::InputArchiveBase, Archive>::value) {
 
  241       trigger_age_.clear();
 
  242       dependencies_age_ = 0;
 
  243       removed_particles_attributes_age_ = 0;
 
  244       saved_dependencies_age_ = 0;
 
  245       dependencies_saved_ = 
false;
 
  246       moved_particles_cache_age_ = 0;
 
  251   void increase_age() {
 
  253     if (age_counter_ == 0) {
 
  258   template <
class MOType, 
class MOVector>
 
  259   void do_get_dependent(
ModelObject *mo, MOVector &ret) {
 
  260     const auto &node = dependency_graph_.find(mo);
 
  262                        "Object " << mo->get_name()
 
  263                                  << 
" does not have dependencies.");
 
  265                        "Node not in dependency_graph.");
 
  266     MOType *r = 
dynamic_cast<MOType *
>(mo);
 
  270     for (
ModelObject *cur : node->second.get_outputs()) {
 
  271       do_get_dependent<MOType, MOVector>(cur, ret);
 
  273     for (
ModelObject *cur : node->second.get_readers()) {
 
  274       do_get_dependent<MOType, MOVector>(cur, ret);
 
  278 #if !defined(IMP_DOXYGEN) && !defined(SWIG) 
  285   internal::Stage cur_stage_;
 
  288   const std::set<Restraint *> &get_dependent_restraints(
ParticleIndex pi) {
 
  289     return moved_particles_restraint_cache_.get_dependent_restraints(pi);
 
  294     return moved_particles_particle_cache_.get_dependent_particles(pi);
 
  299   bool do_get_has_dependencies(
const ModelObject *mo)
 const {
 
  300     return no_dependencies_.find(mo) == no_dependencies_.end();
 
  302   void do_set_has_dependencies(
const ModelObject *mo, 
bool tf);
 
  303   void do_set_has_all_dependencies(
bool tf);
 
  305   void validate_computed_derivatives()
 const {}
 
  306   void set_has_all_dependencies(
bool tf);
 
  307   bool get_has_all_dependencies() 
const;
 
  308   void check_dependency_invariants() 
const;
 
  309   void check_dependency_invariants(
const ModelObject *mo) 
const;
 
  316   internal::Stage get_stage()
 const { 
return cur_stage_; }
 
  318   static void do_remove_score_state(
ScoreState *obj);
 
  321   bool do_get_has_required_score_states(
const ModelObject *mo) 
const;
 
  322   void do_set_has_required_score_states(
ModelObject *mo, 
bool tf);
 
  326                     "Doesn't have score states");
 
  327     return required_score_states_.find(mo)->second;
 
  334   Model(std::string name = 
"Model %1%");
 
  337 #if !defined(SWIG) && !defined(IMP_DOXYGEN) 
  338   IMP_MODEL_IMPORT(internal::FloatAttributeTable);
 
  339   IMP_MODEL_IMPORT(internal::StringAttributeTable);
 
  340   IMP_MODEL_IMPORT(internal::IntAttributeTable);
 
  341   IMP_MODEL_IMPORT(internal::ObjectAttributeTable);
 
  342   IMP_MODEL_IMPORT(internal::WeakObjectAttributeTable);
 
  343   IMP_MODEL_IMPORT(internal::IntsAttributeTable);
 
  344   IMP_MODEL_IMPORT(internal::FloatsAttributeTable);
 
  345   IMP_MODEL_IMPORT(internal::ObjectsAttributeTable);
 
  346   IMP_MODEL_IMPORT(internal::ParticleAttributeTable);
 
  347   IMP_MODEL_IMPORT(internal::ParticlesAttributeTable);
 
  348   IMP_MODEL_SPARSE_IMPORT(internal::SparseStringAttributeTable);
 
  349   IMP_MODEL_SPARSE_IMPORT(internal::SparseIntAttributeTable);
 
  350   IMP_MODEL_SPARSE_IMPORT(internal::SparseFloatAttributeTable);
 
  351   IMP_MODEL_SPARSE_IMPORT(internal::SparseParticleAttributeTable);
 
  365 #if !defined(IMP_DOXYGEN) 
  387                   do_remove_score_state(obj));
 
  412   void add_attribute(TypeKey attribute_key, 
ParticleIndex particle, Type value);
 
  416   void remove_attribute(TypeKey attribute_key, 
ParticleIndex particle);
 
  419   bool get_has_attribute(TypeKey attribute_key, 
ParticleIndex particle) 
const;
 
  423   void set_attribute(TypeKey attribute_key, 
ParticleIndex particle, Type value);
 
  427   Type get_attribute(TypeKey attribute_key, 
ParticleIndex particle);
 
  440   void add_cache_attribute(TypeKey attribute_key, 
ParticleIndex particle,
 
  445   void set_is_optimized(TypeKey attribute_key, 
ParticleIndex particle,
 
  451 #define IMP_MODEL_ATTRIBUTE_METHODS(Type, Value)                            \ 
  452   void add_attribute(Type##Key attribute_key, ParticleIndex particle,       \ 
  454   void remove_attribute(Type##Key attribute_key, ParticleIndex particle);   \ 
  455   bool get_has_attribute(Type##Key attribute_key,                           \ 
  456                          ParticleIndex particle) const;                     \ 
  457   void set_attribute(Type##Key attribute_key, ParticleIndex particle,       \ 
  459   Value get_attribute(Type##Key attribute_key, ParticleIndex particle);     \ 
  460   void add_cache_attribute(Type##Key attribute_key, ParticleIndex particle, \ 
  463 #define IMP_MODEL_SPARSE_ATTRIBUTE_METHODS(Type, Value)                     \ 
  464   void add_attribute(Type##Key attribute_key, ParticleIndex particle,       \ 
  466   void remove_attribute(Type##Key attribute_key, ParticleIndex particle);   \ 
  467   bool get_has_attribute(Type##Key attribute_key,                           \ 
  468                          ParticleIndex particle) const;                     \ 
  469   void set_attribute(Type##Key attribute_key, ParticleIndex particle,       \ 
  471   Value get_attribute(Type##Key attribute_key, ParticleIndex particle) 
  474   IMP_MODEL_ATTRIBUTE_METHODS(
Int, 
Int);
 
  476   IMP_MODEL_ATTRIBUTE_METHODS(
Ints, 
Ints);
 
  481   IMP_MODEL_ATTRIBUTE_METHODS(WeakObject, 
Object *);
 
  482   IMP_MODEL_SPARSE_ATTRIBUTE_METHODS(SparseString, 
String);
 
  483   IMP_MODEL_SPARSE_ATTRIBUTE_METHODS(SparseInt, 
Int);
 
  484   IMP_MODEL_SPARSE_ATTRIBUTE_METHODS(SparseFloat, 
Float);
 
  485   IMP_MODEL_SPARSE_ATTRIBUTE_METHODS(SparseParticleIndex, 
ParticleIndex);
 
  494     return particle_index_[p];
 
  499     if (particle_index_.size() <= get_as_unsigned_int(p)) 
return false;
 
  500     return particle_index_[p];
 
  527   bool get_has_data(
ModelKey mk) 
const;
 
  565     if (trigger_age_.size() > tk.get_index()) {
 
  566       return trigger_age_[tk.get_index()];
 
  574     if (tk.get_index() >= trigger_age_.size()) {
 
  575       trigger_age_.resize(tk.get_index() + 1, 0);
 
  577     trigger_age_[tk.get_index()] = age_counter_;
 
  592     return removed_particles_attributes_age_;
 
  598     dependencies_saved_ = 
true;
 
  599     saved_dependencies_age_ = dependencies_age_;
 
  601       mos_added_since_save_.clear();
 
  602       mos_removed_since_save_.clear();
 
  621     if (dependencies_saved_) {
 
  622       dependencies_saved_ = 
false;
 
  623       dependencies_age_ = saved_dependencies_age_;
 
  626         std::sort(mos_added_since_save_.begin(), mos_added_since_save_.end());
 
  627         std::sort(mos_removed_since_save_.begin(),
 
  628                   mos_removed_since_save_.end());
 
  630                            "ModelObjects added do not match those removed");
 
  651     return model_map_.get(
id);
 
  657 #if !defined(IMP_DOXYGEN) 
  662 IMPKERNEL_END_NAMESPACE
 
  664 CEREAL_SPECIALIZE_FOR_ALL_ARCHIVES(
 
  665             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.