IMP logo
IMP Reference Guide  2.22.0
The Integrative Modeling Platform
subset_scores.h
Go to the documentation of this file.
1 /**
2  * \file IMP/domino/subset_scores.h
3  * \brief A Bayesian inference-based sampler.
4  *
5  * Copyright 2007-2022 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef IMPDOMINO_SUBSET_SCORES_H
10 #define IMPDOMINO_SUBSET_SCORES_H
11 
12 #include "particle_states.h"
13 #include "Assignment.h"
14 #include "Subset.h"
15 #include "Slice.h"
16 #include "utility.h"
17 #include <IMP/log.h>
18 #include <IMP/Object.h>
19 #include <IMP/cache.h>
20 #include <IMP/Restraint.h>
21 #include <IMP/log.h>
22 #include <boost/unordered_map.hpp>
23 
24 #ifdef IMP_DOMINO_USE_IMP_RMF
25 # include <RMF/config.h>
26 # if RMF_HAS_DEPRECATED_BACKENDS
27 # include <RMF/HDF5/Group.h>
28 # endif
29 #endif
30 
31 
32 IMPDOMINO_BEGIN_NAMESPACE
33 
34 /** Implement a cache for restraint scores as well as management of restraints
35  for domino.
36 
37  The cache size passed to the constructor is the maximum number of scores
38  that will be saved. A least-recently-used eviction policy is used when
39  that number is exceeded.
40 */
41 class IMPDOMINOEXPORT RestraintCache : public Object {
42  IMP_NAMED_TUPLE_2(Key, Keys, WeakPointer<Restraint>, restraint,
43  Assignment, assignment, );
44  IMP_NAMED_TUPLE_3(RestraintData, RestraintDatas,
45  PointerMember<ScoringFunction>, scoring_function,
46  Subset, subset, double, max, );
47  IMP_NAMED_TUPLE_2(RestraintSetData, RestraintSetDatas, Slice, slice,
48  WeakPointer<Restraint>, restraint, );
49  IMP_NAMED_TUPLE_2(SetData, SetDatas, RestraintSetDatas, members, double,
50  max, );
51 
52 #ifndef IMP_DOXYGEN
53  class Generator {
54  typedef boost::unordered_map<Restraint *, RestraintData> RMap;
55  RMap rmap_;
56  typedef boost::unordered_map<Restraint *, SetData> SMap;
57  SMap sets_;
59 
60  public:
61  Generator(ParticleStatesTable *pst) : pst_(pst) {}
62  typedef double result_type;
63  typedef Key argument_type;
64  template <class Cache>
65  result_type operator()(const argument_type &k, const Cache &cache) const {
66  RMap::const_iterator it = rmap_.find(k.get_restraint());
67  if (it != rmap_.end()) {
68  Subset s = rmap_.find(k.get_restraint())->second.get_subset();
69  load_particle_states(s, k.get_assignment(), pst_);
70  double e;
71  {
72  SetLogState sls(SILENT);
73  e = it->second.get_scoring_function()->evaluate_if_below(
74  false, it->second.get_max());
75  }
76  IMP_LOG_TERSE("Restraint " << Showable(k.get_restraint())
77  << " evaluated to " << e << " on "
78  << k.get_assignment() << " vs "
79  << it->second.get_max() << std::endl);
80  // prob can go away with ScoreFunction change
81  if (e > it->second.get_max()) e = std::numeric_limits<double>::max();
82  return e;
83  } else {
84  SMap::const_iterator it = sets_.find(k.get_restraint());
85  IMP_USAGE_CHECK(it != sets_.end(), "Restraint set "
86  << Showable(k.get_restraint())
87  << " not found.");
88  double total = 0;
89  for (unsigned int i = 0; i < it->second.get_members().size(); ++i) {
90  Assignment cur = it->second.get_members()[i].get_slice().get_sliced(
91  k.get_assignment());
92  double score = cache.get(
93  argument_type(it->second.get_members()[i].get_restraint(), cur));
94  total += score * k.get_restraint()->get_weight();
95  if (total >= it->second.get_max()) {
96  break;
97  }
98  }
99  IMP_LOG_TERSE("Restraint " << Showable(k.get_restraint())
100  << " evaluated to " << total << " on "
101  << k.get_assignment() << " with max "
102  << it->second.get_max() << std::endl);
103  if (total >= it->second.get_max()) {
104  return std::numeric_limits<double>::max();
105  } else {
106  return total;
107  }
108  }
109  }
110  void add_to_set(RestraintSet *rs, Restraint *r, Slice slice,
111  double max) {
112  IMP_USAGE_CHECK(!dynamic_cast<RestraintSet *>(r),
113  "don't pass restraint sets here as second arg");
114  sets_[rs].access_members().push_back(RestraintSetData(slice, r));
115  sets_[rs].set_max(max);
116  }
117  void add_restraint(Restraint *e, Subset s, double max) {
118  IMP_USAGE_CHECK(!dynamic_cast<RestraintSet *>(e),
119  "don't pass restraint sets here");
120  if (rmap_.find(e) == rmap_.end()) {
121  rmap_[e] = RestraintData(e->create_scoring_function(1.0, max), s, max);
122  } else {
123  IMP_USAGE_CHECK(rmap_.find(e)->second.get_subset() == s,
124  "Subsets don't match on restraint update");
125  rmap_[e].set_max(std::min(rmap_[e].get_max(), max));
126  }
127  }
128  ParticleStatesTable *get_particle_states_table() const { return pst_; }
129  void show_restraint_information(std::ostream &out) const;
130  };
131 #endif // IMP_DOXYGEN
132 
133  struct ApproximatelyEqual {
134  bool operator()(double a, double b) const {
135  return std::abs(a - b) < .1 * (a + b) + .1;
136  }
137  };
138  typedef boost::unordered_map<Particle *, ParticlesTemp>
139  DepMap;
140  void add_restraint_internal(Restraint *r, unsigned int index,
141  RestraintSet *parent, double max,
142  Subset parent_subset, const DepMap &dependencies);
143  void add_restraint_set_child_internal(Restraint *r,
144  const Subset &cur_subset,
145  RestraintSet *parent,
146  double parent_max,
147  Subset parent_subset);
148  void add_restraint_set_internal(RestraintSet *rs, unsigned int index,
149  const Subset &cur_subset, double cur_max,
150  const DepMap &dependencies);
151  Subset get_subset(Restraint *r, const DepMap &dependencies) const;
152 // otherwise doxygen seems to index this for some reason
153 #ifndef IMP_DOXYGEN
155  Cache cache_;
156 #endif
157  typedef boost::unordered_map<Pointer<Restraint>, Subset>
158  KnownRestraints;
159  KnownRestraints known_restraints_;
160  // assign a unique index to each restraint for use with I/O
161  typedef boost::unordered_map<Pointer<Restraint>, int>
162  RestraintIndex;
163  RestraintIndex restraint_index_;
164  unsigned int next_index_;
165 
166  public:
168  unsigned int size = std::numeric_limits<unsigned int>::max());
169  /** Recursively process the passed restraints (and sets) so all contained
170  restraints and sets that have maximum are known.*/
171  void add_restraints(const RestraintsAdaptor &rs);
172  //! Get the score of a set or restraint
173  /** The returned score will be std::numeric_limits<double>::max()
174  if any of the limits are violated.
175 
176  The assignment passed is the assignment for the particles used by the
177  restraint, not that for some whole subset. See the other get_score()
178  function for a perhaps more useful one.
179  */
180  double get_score(Restraint *r, const Assignment &a) const {
181  set_was_used(true);
182  double s = cache_.get(Key(r, a));
183  return s;
184  }
185  /** Get the score for a restraint given a subset and assignment on
186  that subset.
187  */
188  double get_score(Restraint *r, const Subset &s,
189  const Assignment &a) const;
190 
191  //! Make it so Restraint::get_last_score() returns the score
192  /** This is useful when writing the restraints to disk, as that
193  code often goes off the last score to avoid recomputing the
194  restraints.*/
195  void load_last_score(Restraint *r, const Subset &s,
196  const Assignment &a);
197  /** Return the restraints that should be evaluated for the subset,
198  given the exclusions.*/
200  const Subsets &exclusions) const;
201 
203 
204 #if RMF_HAS_DEPRECATED_BACKENDS || defined(IMP_DOXYGEN)
205  /** This assumes that restraints are always added to the cache
206  in the same order.
207  \param[in] particle_ordering An ordering for the particles.
208  \param[in] restraints Which restraints to write out entries for.
209  You probably want to use get_restraints() to generate this.
210  \param[in] max_entries How many entries to write out at most.
211  \param[in] group Where to put the entries.
212  */
213  void save_cache(const ParticlesTemp &particle_ordering,
214  const RestraintsTemp &restraints,
215  RMF::HDF5::Group group, unsigned int max_entries);
216  void load_cache(const ParticlesTemp &ps, RMF::HDF5::ConstGroup group);
217 #endif
218 
219  //! Return the slice for that restraint given the subset.
220  Slice get_slice(Restraint *r, const Subset &s) const;
221 
222  //! Return the number of entries currently in the cache.
223  unsigned int get_number_of_entries() const { return cache_.size(); }
224 
225  //! Check the entries in the cache.
226  void validate() const;
227 
228  //! Print out information about the known restraints and restraint sets.
229  void show_restraint_information(std::ostream &out = std::cout) const;
230  double get_hit_rate() const { return cache_.get_hit_rate(); }
232 };
233 
234 IMPDOMINO_END_NAMESPACE
235 
236 #endif /* IMPDOMINO_SUBSET_SCORES_H */
Smart pointer to Object-derived classes that does not refcount.
Definition: WeakPointer.h:77
A Bayesian inference-based sampler.
RestraintsTemp get_restraints(const Subset &s, const ParticleStatesTable *pst, const DependencyGraph &dg, RestraintSet *rs)
#define IMP_OBJECT_METHODS(Name)
Define the basic things needed by any Object.
Definition: object_macros.h:25
virtual ScoringFunction * create_scoring_function(double weight=1.0, double max=NO_MAX) const
Create a scoring function with only this restraint.
Represent a subset of the particles being optimized.
Definition: Subset.h:33
#define IMP_LOG_TERSE(expr)
Definition: log_macros.h:72
Object used to hold a set of restraints.
Definition: RestraintSet.h:41
Store a subset of a subset or assignment.
Definition: Slice.h:30
void add_restraint(RMF::FileHandle fh, Restraint *hs)
Do not output any text.
Definition: enums.h:24
Common base class for heavy weight IMP objects.
Definition: Object.h:111
Helper classes for various types of caching.
A class to change and restore log state.
Definition: SetLogState.h:30
Provide a consistent interface for things that take Restraints as arguments.
Definition: Restraint.h:362
Implement a simple least recently used cache.
Definition: cache.h:254
void add_restraints(RMF::FileHandle fh, const Restraints &hs)
A smart pointer to a ref-counted Object that is a class member.
Definition: Pointer.h:143
A Bayesian inference-based sampler.
double get_score(Restraint *r, const Assignment &a) const
Get the score of a set or restraint.
A Bayesian inference-based sampler.
Functions for helping optimize and understand DOMINO-based sampling.
A shared base class to help in debugging and things.
Store a configuration of a subset.
Definition: Assignment.h:35
unsigned int get_number_of_entries() const
Return the number of entries currently in the cache.
#define IMP_USAGE_CHECK(expr, message)
A runtime test for incorrect usage of a class or method.
Definition: check_macros.h:168
Abstract base class for all restraints.
Logging and error reporting support.
void load_particle_states(const Subset &s, const Assignment &ss, const ParticleStatesTable *pst)
Load the appropriate state for each particle in a Subset.
A Bayesian inference-based sampler.
Helper class to aid in output of IMP classes to streams.
Definition: Showable.h:25
void set_was_used(bool tf) const
A restraint is a term in an IMP ScoringFunction.
Definition: Restraint.h:56
Slice get_slice(Subset outer, Subset inner, const Subsets &excluded)
Definition: Slice.h:76