IMP  2.0.1
The Integrative Modeling Platform
subset_filters.h
Go to the documentation of this file.
1 /**
2  * \file IMP/domino/subset_filters.h
3  * \brief A beyesian infererence-based sampler.
4  *
5  * Copyright 2007-2013 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef IMPDOMINO_SUBSET_FILTERS_H
10 #define IMPDOMINO_SUBSET_FILTERS_H
11 
12 #include <IMP/domino/domino_config.h>
13 #include "particle_states.h"
14 #include "Assignment.h"
15 #include "particle_states.h"
16 #include "Subset.h"
17 #include "domino_macros.h"
18 #include "subset_scores.h"
19 #include <IMP/Object.h>
20 #include <IMP/Pointer.h>
21 #include <IMP/base/map.h>
22 #include <IMP/Configuration.h>
23 #include <IMP/Model.h>
24 #include <IMP/macros.h>
25 #include <boost/dynamic_bitset.hpp>
28 
29 #include <boost/pending/disjoint_sets.hpp>
30 
31 
32 
33 IMPDOMINO_BEGIN_NAMESPACE
34 
35 /** An instance of this type is created by the
36  SubsetFilterTable::get_subset_filter method(). It's job
37  is to reject some of the Assignments correspinding to the
38  Subset it was created with. It has one
39  method of interest, get_is_ok() which true if the state
40  passes the filter.
41 
42  The passed Assignment has the particles ordered in the
43  same order as they were in the Subset that was passed to the
44  table in order to create the filter.
45 */
46 class IMPDOMINOEXPORT SubsetFilter: public IMP::base::Object {
47 public:
48  SubsetFilter(std::string name="SubsetFilter%1%");
49  //! Return true if the given state passes this filter for the Subset
50  //! it was created with
51  virtual bool get_is_ok(const Assignment& state) const=0;
52 
53  //! Return a next possible acceptable state for the particle in pos
54  /** The default implementation returns the current value +1. This method
55  needs to make sure it does not skip any valid states.
56 
57  The method can assume \c !get_is_ok(state) and that the state
58  minus pos is ok.
59  */
60  virtual int get_next_state(int pos, const Assignment& state) const {
61  return state[pos]+1;
62  }
63 
64  virtual ~SubsetFilter();
65 };
66 
68 
69 
70 /** A SubsetFilterTable class which produces SubsetFilter objects upon
71  demand. When the get_subset_filter() method is called, it is passed
72  the Subset that is to be filtered. It is also passed subsets of
73  that Subset which have previously been filtered (and so don't need
74  to be checked again).
75 
76  For example, if the passed set is {a,b,c} and the prior_subsets
77  are {a,b} and {b,c}, then only properties than involve a and c need
78  to be checked, as ones involve a and b and b and c have already been
79  checked previously.
80 */
81 class IMPDOMINOEXPORT SubsetFilterTable: public IMP::base::Object {
82  public:
83  SubsetFilterTable(std::string name="SubsetFilterTable%1%"): Object(name){}
84  /** Return a SubsetFilter which acts on the Subset s, given that all
85  the prior_subsets have already been filtered. This should return
86  nullptr if there is no filtering to be done.
87  */
88  virtual SubsetFilter* get_subset_filter(const Subset &s,
89  const Subsets &prior_subsets) const=0;
90 
91  //! The strength is a rough metric of how this filter restricts the subset
92  /** It is still kind of nebulous, but as a rough guide, it should be
93  the fraction of the states that are eliminated by the filter.
94  */
95  virtual double get_strength(const Subset &s,
96  const Subsets &prior_subsets) const=0;
97 
98  virtual ~SubsetFilterTable();
99 };
100 
102 
103 
104 
105 
106 //! Filter a configuration of the subset using the Model thresholds
107 /** This filter table creates filters using the maximum scores
108  set in the Model for various restraints.
109  */
110 class IMPDOMINOEXPORT RestraintScoreSubsetFilterTable:
111  public SubsetFilterTable {
112  OwnerPointer<RestraintCache> cache_;
113  mutable Restraints rs_;
114 public:
116 #ifndef IMP_DOXYGEN
118  ParticleStatesTable *pst);
119 #endif
120  /** Create the RestraintCache internally with unbounded size.*/
121  RestraintScoreSubsetFilterTable(RestraintsTemp rs,
122  ParticleStatesTable *pst);
124 };
125 
128 
129 
130 
131 //! Filter a configuration of the subset using the Model thresholds
132 /** Filter based on an allowed number of failures for the restraints
133  in a list passed.
134  */
136  public SubsetFilterTable {
137  OwnerPointer<RestraintCache> rc_;
138  Restraints rs_;
139  int max_violated_;
140  RestraintsTemp get_restraints(const Subset &s,
141  const Subsets &excluded) const;
142  public:
143  MinimumRestraintScoreSubsetFilterTable(const RestraintsTemp &rs,
144  RestraintCache *rc,
145  int max_number_allowed_violations);
146  int get_maximum_number_of_violated_restraints() const {
147  return max_violated_;}
149 };
150 
153 
154 
155 /** \brief A base class
156 
157  A number of filters work on disjoint sets of the input particles.
158  These can be specified in several different ways
159  - implicitly via having the same ParticleStates objects
160  - as a list of particle equivalencies
161  - as a list of disjoint sets of equivalent particles
162  */
163 class IMPDOMINOEXPORT DisjointSetsSubsetFilterTable:
164  public SubsetFilterTable {
165  Pointer<ParticleStatesTable> pst_;
166  ParticlesTemp elements_;
167  boost::vector_property_map<int> parent_, rank_;
168  mutable boost::disjoint_sets<boost::vector_property_map<int>,
169  boost::vector_property_map<int> > disjoint_sets_;
171  mutable base::Vector<ParticlesTemp> sets_;
172  mutable IMP::base::map<const Particle *, int> set_indexes_;
173 
174  int get_index(Particle *p);
175 
176  void build_sets() const;
177 protected:
178  unsigned int get_number_of_sets() const {
179  build_sets();
180  return sets_.size();
181  }
182  ParticlesTemp get_set(unsigned int i) const {
183  return sets_[i];
184  }
186  std::string name);
187  DisjointSetsSubsetFilterTable(std::string name);
188  IMP_INTERNAL_METHOD(void,
189  get_indexes, (const Subset &s,
190  const Subsets &excluded,
191  base::Vector<Ints> &ret,
192  int lb,
193  Ints &used), const, );
195  get_index_in_set,
196  (Particle *p), const, {
197  if (set_indexes_.find(p)== set_indexes_.end()) {
198  return -1;
199  } else {
200  return set_indexes_.find(p)->second;
201  }
202  });
203  public:
204  void add_set(const ParticlesTemp &ps);
205  void add_pair(const ParticlePair &pp);
206 };
207 
208 #if !defined(SWIG) && !defined(IMP_DOXYGEN)
209 inline DisjointSetsSubsetFilterTable
210 ::DisjointSetsSubsetFilterTable(ParticleStatesTable *pst,
211  std::string name):
212  SubsetFilterTable(name),
213  pst_(pst),
214  disjoint_sets_(rank_, parent_){}
215 inline DisjointSetsSubsetFilterTable
216 ::DisjointSetsSubsetFilterTable(std::string name):
217  SubsetFilterTable(name),
218  disjoint_sets_(rank_, parent_){}
219 #endif
220 
221 
222 /** \brief Do not allow two particles to be in the same state.
223 
224  If a ParticleStatesTable is passed, then two particles cannot
225  be in the same state if they have the same ParticleStates,
226  otherwise, if a ParticlePairs is passed then pairs found in the
227  list are not allowed to have the same state index.
228  */
230 
231 /** \brief Do not allow two particles to be in the same state.
232 
233  If a ParticleStatesTable is passed, then two particles must
234  be in the same state if they have the same ParticleStates,
235  otherwise, if a ParticlePairs is passed then pairs found in the
236  list must have the same state index.
237  */
239 
240 
241 /** \brief Define sets of equivalent particles
242 
243  Particles in an equivalency set are assumed to be equivalent under
244  exchange. Given that, one should only generate each of the equivalent
245  conformations once. More specifically, given equivalent particles
246  p0 and p1, if p0 is given state s0 and p1 is given state s1, then
247  p1 will never be given state s0 when p0 is given the state s1.
248 */
250 
251 /** \brief Define sets of equivalent and exclusive particles
252 
253  This is equivalent to having both an EquivalenceSubsetFilterTable
254  and an ExclusionSubsetFilterTable on the same particles, but faster.
255 */
256 IMP_DISJOINT_SUBSET_FILTER_TABLE_DECL(EquivalenceAndExclusion);
257 
258 
259 
260 
261 
262 /** \brief Maintain an explicit list of what states each particle
263  is allowed to have.
264 
265  This filter maintains a list for each particle storing whether
266  that particle is allowed to be in a certain state or not.
267  */
268 class IMPDOMINOEXPORT ListSubsetFilterTable:
269  public SubsetFilterTable {
270  public:
271 #if !defined(IMP_DOXYGEN) && !defined(SWIG)
274  Pointer<ParticleStatesTable> pst_;
275  mutable double num_ok_, num_test_;
276  int get_index(Particle*p) const;
277  void load_indexes(const Subset &s,
278  Ints &indexes) const;
279  void mask_allowed_states(Particle *p, const boost::dynamic_bitset<> &bs);
280 #endif
281  public:
283  double get_ok_rate() const {
284  return num_ok_/num_test_;
285  }
286  unsigned int get_number_of_particle_states(Particle *p) const {
287  int i= get_index(p);
288  if (i==-1) {
289  return pst_->get_particle_states(p)->get_number_of_particle_states();
290  }
291  IMP_USAGE_CHECK(i>=0, "Particle " << p->get_name()
292  << " is unknown. It probably is not in the "
293  << " ParticleStatesTable. Boom.");
294  return states_[i].size();
295  }
296  void set_allowed_states(Particle *p, const Ints &states);
298 };
299 
302 
303 
304 
305 /** For provided pairs of particles, on all them to be in certain
306  explicitly lists pairs of states. That is, if the particle
307  pair (p0, p1) is added, with the list [(0,1), (3,4)], then
308  (p0, p1) can only be in (0,1) or (3,4). Note, this class
309  assumes that the single particles are handled appropriately.
310  That is, that something else is restricting p0 to only 0 or 3.
311 */
312 class IMPDOMINOEXPORT PairListSubsetFilterTable:
313  public SubsetFilterTable {
315  void fill(const Subset &s,
316  const Subsets &e,
317  IntPairs& indexes,
318  base::Vector<IntPairs>& allowed) const;
319  public:
321  void set_allowed_states(ParticlePair p, const IntPairs &states);
323 };
324 
327 
328 
329 /** Randomly reject some of the states. The purpose of this is
330  to try to generate a sampling of the total states when there
331  are a very large number of acceptable states.
332 */
333 class IMPDOMINOEXPORT ProbabilisticSubsetFilterTable:
334  public SubsetFilterTable {
335  double p_;
336  bool leaves_only_;
337  public:
338  /** param[in] p Allow states to pass with probability p
339  param[in] leaves_only If true, only filter the leaves of
340  the merge tree.
341  */
343  bool leaves_only=false);
345 };
346 
348 
349 IMPDOMINO_END_NAMESPACE
350 
351 
352 #endif /* IMPDOMINO_SUBSET_FILTERS_H */