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