IMP  2.1.1
The Integrative Modeling Platform
assignment_containers.h
Go to the documentation of this file.
1 /**
2  * \file IMP/domino/assignment_containers.h
3  * \brief A beyesian infererence-based sampler.
4  *
5  * Copyright 2007-2013 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef IMPDOMINO_ASSIGNMENT_CONTAINERS_H
10 #define IMPDOMINO_ASSIGNMENT_CONTAINERS_H
11 
12 #include <IMP/domino/domino_config.h>
13 #include "Assignment.h"
14 #include "Order.h"
15 #include "subset_scores.h"
16 #include <IMP/base/map.h>
18 #if IMP_DOMINO_HAS_RMF
19 #include <RMF/HDF5/Group.h>
20 #include <RMF/HDF5/File.h>
21 #endif
22 #include <boost/shared_array.hpp>
23 #include <algorithm>
24 #include <IMP/base/hash.h>
25 #include <IMP/base/Vector.h>
26 
27 #include <queue>
28 #include <cstdio>
29 
30 #ifdef _MSC_VER
31 #include <io.h>
32 #endif
33 
34 IMPDOMINO_BEGIN_NAMESPACE
35 
36 /** The base class for containers of assignments. Assignments are stored
37  in these rather than as Assignments to help increase efficiency as
38  well as provide flexibility as to how and where they are stored.
39 */
40 class IMPDOMINOEXPORT AssignmentContainer : public IMP::base::Object {
41  public:
42  AssignmentContainer(std::string name = "AssignmentsContainer %1%");
43  virtual unsigned int get_number_of_assignments() const = 0;
44  virtual Assignment get_assignment(unsigned int i) const = 0;
45  virtual Assignments get_assignments(IntRange ir) const = 0;
46  virtual Assignments get_assignments() const = 0;
47  virtual void add_assignment(const Assignment &a) = 0;
48  virtual void add_assignments(const Assignments &as) = 0;
49  //! Get all the assignments for the ith particle
50  virtual Ints get_particle_assignments(unsigned int i) const = 0;
51 
52  virtual ~AssignmentContainer();
53 };
54 
56 
57 /** Store a set of assignments in a somewhat more compact form in memory
58  than the ListAssignmentContainer.
59  */
60 class IMPDOMINOEXPORT PackedAssignmentContainer : public AssignmentContainer {
61  // store all as one vector
62  Ints d_;
63  int width_;
64 
65  public:
66  PackedAssignmentContainer(std::string name =
67  "PackedAssignmentsContainer %1%");
68  virtual unsigned int get_number_of_assignments() const IMP_OVERRIDE;
69  virtual Assignment get_assignment(unsigned int i) const IMP_OVERRIDE;
70  virtual void add_assignment(const Assignment &a) IMP_OVERRIDE;
73 };
74 
75 #ifndef IMP_DOXYGEN
76 
77 inline unsigned int PackedAssignmentContainer::get_number_of_assignments()
78  const {
79  if (width_ == -1) return 0;
80  return d_.size() / width_;
81 }
82 
83 inline Assignment PackedAssignmentContainer::get_assignment(
84  unsigned int i) const {
85  IMP_USAGE_CHECK(i < get_number_of_assignments(),
86  "Invalid assignment requested: " << i);
87  IMP_USAGE_CHECK(width_ > 0, "Uninitualized PackedAssignmentContainer.");
88  return Assignment(d_.begin() + i * width_, d_.begin() + (i + 1) * width_);
89 }
90 
91 inline void PackedAssignmentContainer::add_assignment(const Assignment &a) {
93  if (width_ == -1) {
94  width_ = a.size();
95  }
96  IMP_USAGE_CHECK(static_cast<int>(a.size()) == width_,
97  "Sizes don't match " << width_ << " vs " << a.size());
99  for (unsigned int i = 0; i < get_number_of_assignments(); ++i) {
100  IMP_INTERNAL_CHECK(get_assignment(i) != a, "Assignment "
101  << a << " already here.");
102  }
103  }
104  d_.insert(d_.end(), a.begin(), a.end());
105 }
106 #endif
107 
108 /** Simple storage of a set of Assignments. Prefer PackedAssignmentContainer,
109  I think.
110  */
111 class IMPDOMINOEXPORT ListAssignmentContainer : public AssignmentContainer {
112  // store all as one vector
113  Assignments d_;
114 
115  public:
116  ListAssignmentContainer(std::string name = "ListAssignmentsContainer %1%");
117  virtual unsigned int get_number_of_assignments() const IMP_OVERRIDE;
118  virtual Assignment get_assignment(unsigned int i) const IMP_OVERRIDE;
119  virtual void add_assignment(const Assignment &a) IMP_OVERRIDE;
122 };
123 
124 #ifndef IMP_DOXYGEN
125 inline unsigned int ListAssignmentContainer::get_number_of_assignments() const {
126  return d_.size();
127 }
128 
129 inline Assignment ListAssignmentContainer::get_assignment(
130  unsigned int i) const {
131  return d_[i];
132 }
133 
134 inline void ListAssignmentContainer::add_assignment(const Assignment &a) {
135  d_.push_back(a);
136 }
137 #endif
138 
139 /** Store a list of k assignments chosen from all of the ones added to this
140  table. The states are chosen uniformly.
141 
142  This doesn't seem very useful
143  */
144 class IMPDOMINOEXPORT SampleAssignmentContainer : public AssignmentContainer {
145  // store all as one vector
146  Ints d_;
147  int width_;
148  unsigned int k_;
149  unsigned int i_;
150  boost::uniform_real<double> select_;
151  boost::uniform_int<> place_;
152 
153  public:
154  SampleAssignmentContainer(unsigned int k,
155  std::string name =
156  "SampleAssignmentsContainer %1%");
157  virtual unsigned int get_number_of_assignments() const IMP_OVERRIDE;
158  virtual Assignment get_assignment(unsigned int i) const IMP_OVERRIDE;
159  virtual void add_assignment(const Assignment &a) IMP_OVERRIDE;
162 };
163 
164 #ifndef IMP_DOXYGEN
165 inline unsigned int SampleAssignmentContainer::get_number_of_assignments()
166  const {
167  return d_.size() / width_;
168 }
169 
170 inline Assignment SampleAssignmentContainer::get_assignment(
171  unsigned int i) const {
172  return Assignment(d_.begin() + i * width_, d_.begin() + (i + 1) * width_);
173 }
174 #endif
175 
176 #if IMP_DOMINO_HAS_RMF || defined(IMP_DOXYGEN)
177 /** Store the assignments in an HDF5DataSet. Make sure to delete this
178  container before trying to read from the same data set (unless
179  you pass the data set explicitly, in which case it may be OK).
180 
181  The format on disk should
182  not, yet, be considered stable.
183  */
184 class IMPDOMINOEXPORT WriteHDF5AssignmentContainer
185  : public AssignmentContainer {
186  RMF::HDF5::IndexDataSet2D ds_;
187  Order order_;
188  Ints cache_;
189  unsigned int max_cache_;
190  void flush();
191  virtual void do_destroy() IMP_OVERRIDE { flush(); }
192 
193  public:
194  WriteHDF5AssignmentContainer(RMF::HDF5::Group parent, const Subset &s,
195  const kernel::ParticlesTemp &all_particles,
196  std::string name);
197 
198  WriteHDF5AssignmentContainer(RMF::HDF5::IndexDataSet2D dataset,
199  const Subset &s,
200  const kernel::ParticlesTemp &all_particles,
201  std::string name);
202  void set_cache_size(unsigned int words);
203  virtual unsigned int get_number_of_assignments() const IMP_OVERRIDE;
204  virtual Assignment get_assignment(unsigned int i) const IMP_OVERRIDE;
205  virtual void add_assignment(const Assignment &a) IMP_OVERRIDE;
208 };
209 
210 /** Store the assignments in an HDF5DataSet. The format on disk should not,
211  yet, be considered stable.
212  */
213 class IMPDOMINOEXPORT ReadHDF5AssignmentContainer : public AssignmentContainer {
214  RMF::HDF5::IndexConstDataSet2D ds_;
215  Order order_;
216  Ints cache_;
217  unsigned int max_cache_;
218  void flush();
219 
220  public:
221 
222  ReadHDF5AssignmentContainer(RMF::HDF5::IndexConstDataSet2D dataset,
223  const Subset &s,
224  const kernel::ParticlesTemp &all_particles,
225  std::string name);
226  void set_cache_size(unsigned int words);
227  virtual unsigned int get_number_of_assignments() const IMP_OVERRIDE;
228  virtual Assignment get_assignment(unsigned int i) const IMP_OVERRIDE;
229  virtual void add_assignment(const Assignment &a) IMP_OVERRIDE;
232 };
233 #endif
234 
235 /** Store the assignments on disk as binary data. Use a ReadAssignmentContainer
236  to read them back. The resulting file is not guaranteed to work on any
237  platform other than the one it was created on and the format may change.
238  */
239 class IMPDOMINOEXPORT WriteAssignmentContainer : public AssignmentContainer {
240  int f_;
241  Order order_;
242  Ints cache_;
243  unsigned int max_cache_;
244  int number_;
245  void flush();
246 
247  virtual void do_destroy() IMP_OVERRIDE {
248  flush();
249 #ifdef _MSC_VER
250  _close(f_);
251 #else
252  close(f_);
253 #endif
254  }
255 
256  public:
257  WriteAssignmentContainer(std::string out_file, const Subset &s,
258  const kernel::ParticlesTemp &all_particles,
259  std::string name);
260  void set_cache_size(unsigned int words);
261  virtual unsigned int get_number_of_assignments() const IMP_OVERRIDE;
262  virtual Assignment get_assignment(unsigned int i) const IMP_OVERRIDE;
263  virtual void add_assignment(const Assignment &a) IMP_OVERRIDE;
266 };
267 
268 /** Read the assignments from binary data on disk. Use a
269  WriteAssignmentContainer to write them. Make sure to destroy the
270  WriteAssignmentContainer before trying to read from the file.
271  */
272 class IMPDOMINOEXPORT ReadAssignmentContainer : public AssignmentContainer {
273  int f_;
274  Order order_;
275  mutable Ints cache_;
276  unsigned int max_cache_;
277  mutable int offset_;
278  int size_;
279  virtual void do_destroy() IMP_OVERRIDE {
280 #ifdef _MSC_VER
281  _close(f_);
282 #else
283  close(f_);
284 #endif
285  }
286 
287  public:
288  ReadAssignmentContainer(std::string out_file, const Subset &s,
289  const kernel::ParticlesTemp &all_particles,
290  std::string name);
291  void set_cache_size(unsigned int words);
292  virtual unsigned int get_number_of_assignments() const IMP_OVERRIDE;
293  virtual Assignment get_assignment(unsigned int i) const IMP_OVERRIDE;
294  virtual void add_assignment(const Assignment &a) IMP_OVERRIDE;
297 };
298 
299 /** Expose a range [begin, end) of an inner assignement container to
300  consumers. One cannot add assignments to this container.
301  */
302 class IMPDOMINOEXPORT RangeViewAssignmentContainer
303  : public AssignmentContainer {
305  int begin_, end_;
306 
307  public:
308  RangeViewAssignmentContainer(AssignmentContainer *inner, unsigned int begin,
309  unsigned int end);
310  virtual unsigned int get_number_of_assignments() const IMP_OVERRIDE;
311  virtual Assignment get_assignment(unsigned int i) const IMP_OVERRIDE;
312  virtual void add_assignment(const Assignment &a) IMP_OVERRIDE;
315 };
316 
317 /** Store a set of k top scoring assignemnts
318  */
319 class IMPDOMINOEXPORT HeapAssignmentContainer : public AssignmentContainer {
320  typedef std::pair<Assignment, double> AP;
321  struct GreaterSecond {
322  bool operator()(const AP &a, const AP &b) { return a.second < b.second; }
323  };
324  typedef base::Vector<AP> C;
325  C d_;
326  Subset subset_;
327  Slices slices_;
328  kernel::Restraints rs_;
329  unsigned int k_; // max number of assignments (heap size)
330  base::Pointer<RestraintCache> rssf_; // to score candidate assignments
331  public:
332  HeapAssignmentContainer(Subset subset, unsigned int k, RestraintCache *rssf,
333  std::string name = "HeapAssignmentsContainer %1%");
334  virtual unsigned int get_number_of_assignments() const IMP_OVERRIDE;
335  virtual Assignment get_assignment(unsigned int i) const IMP_OVERRIDE;
336  virtual void add_assignment(const Assignment &a) IMP_OVERRIDE;
339 };
340 
341 /** This is a wrapper for an AssignmentContainer that throws a ValueException
342  if more than a certain number of states are added.*/
343 class IMPDOMINOEXPORT CappedAssignmentContainer : public AssignmentContainer {
344  typedef AssignmentContainer P;
346  unsigned int max_;
347  void check_number() const;
348 
349  public:
350  CappedAssignmentContainer(AssignmentContainer *contained, int max_states,
351  std::string name);
352  virtual unsigned int get_number_of_assignments() const IMP_OVERRIDE;
353  virtual Assignment get_assignment(unsigned int i) const IMP_OVERRIDE;
354  virtual void add_assignment(const Assignment &a) IMP_OVERRIDE;
357 };
358 
359 IMPDOMINO_END_NAMESPACE
360 
361 #endif /* IMPDOMINO_ASSIGNMENT_CONTAINERS_H */
A beyesian infererence-based sampler.
Store a persistent ordering for a subset based on the list.
Definition: Order.h:29
A smart pointer to a reference counted object.
Definition: base/Pointer.h:87
Represent a subset of the particles being optimized.
Definition: Subset.h:33
Cluster sets of points.
#define IMP_USAGE_CHECK(expr, message)
A runtime test for incorrect usage of a class or method.
#define IMP_INTERNAL_CHECK(expr, message)
An assertion to check for internal errors in IMP. An IMP::ErrorException will be thrown.
#define IMP_ASSIGNMENT_CONTAINER_METHODS(Name)
A class for storing lists of IMP items.
#define IMP_IF_CHECK(level)
Execute the code block if a certain level checks are on.
#define IMP_OBJECT_METHODS(Name)
Define the basic things needed by any Object.
A beyesian infererence-based sampler.
IO support.
Common base class for heavy weight IMP objects.
#define IMP_OBJECT_LOG
Set the log level to the object&#39;s log level.
#define IMP_OBJECTS(Name, PluralName)
Define the types for storing sets of objects.
Store a configuration of a subset.
Definition: Assignment.h:32
virtual void do_destroy()
A beyesian infererence-based sampler.
Declare an efficient stl-compatible map.