IMP logo
IMP Reference Guide  develop.d97d4ead1f,2024/11/21
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_distribution.hpp>
23 #include <boost/random/uniform_real_distribution.hpp>
24 #include <boost/shared_array.hpp>
25 #include <cstdio>
26 #include <queue>
27 
28 #ifdef IMP_DOMINO_USE_IMP_RMF
29 # include <RMF/config.h>
30 # if RMF_HAS_DEPRECATED_BACKENDS
31 # include <RMF/HDF5/Group.h>
32 # include <RMF/HDF5/File.h>
33 # endif
34 #endif
35 
36 #ifdef _MSC_VER
37 #include <io.h>
38 #endif
39 
40 IMPDOMINO_BEGIN_NAMESPACE
41 
42 //! The base class for containers of assignments.
43 /** Assignments are stored in these rather than as Assignments to help
44  increase efficiency as well as provide flexibility as to how and
45  where they are stored.
46 */
47 class IMPDOMINOEXPORT AssignmentContainer : public IMP::Object {
48  public:
49  AssignmentContainer(std::string name = "AssignmentContainer %1%");
50  virtual unsigned int get_number_of_assignments() const = 0;
51  virtual Assignment get_assignment(unsigned int i) const = 0;
52  virtual Assignments get_assignments(IntRange ir) const = 0;
53  virtual Assignments get_assignments() const = 0;
54  virtual void add_assignment(const Assignment &a) = 0;
55  virtual void add_assignments(const Assignments &asgn) = 0;
56  //! Get all the assignments for the ith particle
57  virtual Ints get_particle_assignments(unsigned int i) const = 0;
58 
59  virtual ~AssignmentContainer();
60 };
61 
63 
64 //! Store assignments in a compact form in memory.
65 /** This should use less memory than the ListAssignmentContainer.
66  */
67 class IMPDOMINOEXPORT PackedAssignmentContainer : public AssignmentContainer {
68  // store all as one vector
69  Ints d_;
70  int width_;
71 
72  public:
73  PackedAssignmentContainer(std::string name =
74  "PackedAssignmentContainer %1%");
75  virtual unsigned int get_number_of_assignments() const override;
76  virtual Assignment get_assignment(unsigned int i) const override;
77  virtual void add_assignment(const Assignment &a) override;
80 };
81 
82 #ifndef IMP_DOXYGEN
83 
84 inline unsigned int PackedAssignmentContainer::get_number_of_assignments()
85  const {
86  if (width_ == -1) return 0;
87  return d_.size() / width_;
88 }
89 
90 inline Assignment PackedAssignmentContainer::get_assignment(unsigned int i)
91  const {
92  IMP_USAGE_CHECK(i < get_number_of_assignments(),
93  "Invalid assignment requested: " << i);
94  IMP_USAGE_CHECK(width_ > 0, "Uninitialized PackedAssignmentContainer.");
95  return Assignment(d_.begin() + i * width_, d_.begin() + (i + 1) * width_);
96 }
97 
98 inline void PackedAssignmentContainer::add_assignment(const Assignment &a) {
100  if (width_ == -1) {
101  width_ = a.size();
102  }
103  IMP_USAGE_CHECK(static_cast<int>(a.size()) == width_,
104  "Sizes don't match " << width_ << " vs " << a.size());
106  for (unsigned int i = 0; i < get_number_of_assignments(); ++i) {
107  IMP_INTERNAL_CHECK(get_assignment(i) != a, "Assignment "
108  << a << " already here.");
109  }
110  }
111  d_.insert(d_.end(), a.begin(), a.end());
112 }
113 #endif
114 
115 //! Simple storage of a set of Assignments.
116 /** PackedAssignmentContainer is probably a better class to use in most cases.
117  */
118 class IMPDOMINOEXPORT ListAssignmentContainer : public AssignmentContainer {
119  // store all as one vector
120  Assignments d_;
121 
122  public:
123  ListAssignmentContainer(std::string name = "ListAssignmentContainer %1%");
124  virtual unsigned int get_number_of_assignments() const override;
125  virtual Assignment get_assignment(unsigned int i) const override;
126  virtual void add_assignment(const Assignment &a) override;
129 };
130 
131 #ifndef IMP_DOXYGEN
132 inline unsigned int ListAssignmentContainer::get_number_of_assignments() const {
133  return d_.size();
134 }
135 
136 inline Assignment ListAssignmentContainer::get_assignment(unsigned int i)
137  const {
138  return d_[i];
139 }
140 
141 inline void ListAssignmentContainer::add_assignment(const Assignment &a) {
142  d_.push_back(a);
143 }
144 #endif
145 
146 //! Store a list of k assignments chosen from all those added to this table.
147 /** The states are chosen uniformly.
148  */
149 class IMPDOMINOEXPORT SampleAssignmentContainer : public AssignmentContainer {
150  // store all as one vector
151  Ints d_;
152  int width_;
153  unsigned int k_;
154  unsigned int i_;
155  boost::random::uniform_real_distribution<double> select_;
156  boost::random::uniform_int_distribution<> place_;
157 
158  public:
159  SampleAssignmentContainer(unsigned int k,
160  std::string name =
161  "SampleAssignmentContainer %1%");
162  virtual unsigned int get_number_of_assignments() const override;
163  virtual Assignment get_assignment(unsigned int i) const override;
164  virtual void add_assignment(const Assignment &a) override;
167 };
168 
169 #ifndef IMP_DOXYGEN
170 inline unsigned int SampleAssignmentContainer::get_number_of_assignments()
171  const {
172  return d_.size() / width_;
173 }
174 
175 inline Assignment SampleAssignmentContainer::get_assignment(unsigned int i)
176  const {
177  return Assignment(d_.begin() + i * width_, d_.begin() + (i + 1) * width_);
178 }
179 #endif
180 
181 #if RMF_HAS_DEPRECATED_BACKENDS || defined(IMP_DOXYGEN)
182 //! Store the assignments in an HDF5DataSet.
183 /** Make sure to delete this container before trying to read from the
184  same data set (unless you pass the data set explicitly, in which
185  case it may be OK).
186 
187  The format on disk should not, yet, be considered stable.
188  */
189 class IMPDOMINOEXPORT WriteHDF5AssignmentContainer
190  : public AssignmentContainer {
191  RMF::HDF5::IndexDataSet2D ds_;
192  Order order_;
193  Ints cache_;
194  unsigned int max_cache_;
195  void flush();
196  virtual void do_destroy() override { flush(); }
197 
198  public:
199  WriteHDF5AssignmentContainer(RMF::HDF5::Group parent, const Subset &s,
200  const ParticlesTemp &all_particles,
201  std::string name);
202 
203  WriteHDF5AssignmentContainer(RMF::HDF5::IndexDataSet2D dataset,
204  const Subset &s,
205  const ParticlesTemp &all_particles,
206  std::string name);
207  void set_cache_size(unsigned int words);
208  virtual unsigned int get_number_of_assignments() const override;
209  virtual Assignment get_assignment(unsigned int i) const override;
210  virtual void add_assignment(const Assignment &a) override;
213 };
214 
215 //! Store the assignments in an HDF5DataSet.
216 /** The format on disk should not, yet, be considered stable.
217  */
218 class IMPDOMINOEXPORT ReadHDF5AssignmentContainer : public AssignmentContainer {
219  RMF::HDF5::IndexConstDataSet2D ds_;
220  Order order_;
221  Ints cache_;
222  unsigned int max_cache_;
223  void flush();
224 
225  public:
226  ReadHDF5AssignmentContainer(RMF::HDF5::IndexConstDataSet2D dataset,
227  const Subset &s,
228  const ParticlesTemp &all_particles,
229  std::string name);
230  void set_cache_size(unsigned int words);
231  virtual unsigned int get_number_of_assignments() const override;
232  virtual Assignment get_assignment(unsigned int i) const override;
233  virtual void add_assignment(const Assignment &a) override;
236 };
237 #endif
238 
239 //! Store the assignments on disk as binary data.
240 /** Use a ReadAssignmentContainer to read them back. The resulting file is
241  not guaranteed to work on any platform other than the one it was created
242  on and the format may change.
243  */
244 class IMPDOMINOEXPORT WriteAssignmentContainer : public AssignmentContainer {
245  int f_;
246  Order order_;
247  Ints cache_;
248  unsigned int max_cache_;
249  int number_;
250  void flush();
251 
252  virtual void do_destroy() override {
253  flush();
254 #ifdef _MSC_VER
255  _close(f_);
256 #else
257  close(f_);
258 #endif
259  }
260 
261  public:
262  WriteAssignmentContainer(std::string out_file, const Subset &s,
263  const ParticlesTemp &all_particles,
264  std::string name);
265  void set_cache_size(unsigned int words);
266  virtual unsigned int get_number_of_assignments() const override;
267  virtual Assignment get_assignment(unsigned int i) const override;
268  virtual void add_assignment(const Assignment &a) override;
271 };
272 
273 //! Read the assignments from binary data on disk.
274 /** Use a WriteAssignmentContainer to write them. Make sure to destroy the
275  WriteAssignmentContainer before trying to read from the file.
276  */
277 class IMPDOMINOEXPORT ReadAssignmentContainer : public AssignmentContainer {
278  int f_;
279  Order order_;
280  mutable Ints cache_;
281  unsigned int max_cache_;
282  mutable int offset_;
283  int size_;
284  virtual void do_destroy() override {
285 #ifdef _MSC_VER
286  _close(f_);
287 #else
288  close(f_);
289 #endif
290  }
291 
292  public:
293  ReadAssignmentContainer(std::string out_file, const Subset &s,
294  const ParticlesTemp &all_particles,
295  std::string name);
296  void set_cache_size(unsigned int words);
297  virtual unsigned int get_number_of_assignments() const override;
298  virtual Assignment get_assignment(unsigned int i) const override;
299  virtual void add_assignment(const Assignment &a) override;
302 };
303 
304 //! Expose a range [begin, end) of an inner assignment container to consumers.
305 /** One cannot add assignments to this container.
306  */
307 class IMPDOMINOEXPORT RangeViewAssignmentContainer
308  : public AssignmentContainer {
310  int begin_, end_;
311 
312  public:
313  RangeViewAssignmentContainer(AssignmentContainer *inner, unsigned int begin,
314  unsigned int end);
315  virtual unsigned int get_number_of_assignments() const override;
316  virtual Assignment get_assignment(unsigned int i) const override;
317  virtual void add_assignment(const Assignment &a) override;
320 };
321 
322 //! Store a set of k top scoring assignments
323 class IMPDOMINOEXPORT HeapAssignmentContainer : public AssignmentContainer {
324  typedef std::pair<Assignment, double> AP;
325  struct GreaterSecond {
326  bool operator()(const AP &a, const AP &b) { return a.second < b.second; }
327  };
328  typedef Vector<AP> C;
329  C d_;
330  Subset subset_;
331  Slices slices_;
332  Restraints rs_;
333  unsigned int k_; // max number of assignments (heap size)
334  Pointer<RestraintCache> rssf_; // to score candidate assignments
335  public:
336  HeapAssignmentContainer(Subset subset, unsigned int k, RestraintCache *rssf,
337  std::string name = "HeapAssignmentContainer %1%");
338  virtual unsigned int get_number_of_assignments() const override;
339  virtual Assignment get_assignment(unsigned int i) const override;
340  virtual void add_assignment(const Assignment &a) override;
343 };
344 
345 //! Store no more than a max number of states.
346 /** This is a wrapper for an AssignmentContainer that throws a ValueException
347  if more than a certain number of states are added.
348  */
349 class IMPDOMINOEXPORT CappedAssignmentContainer : public AssignmentContainer {
350  typedef AssignmentContainer P;
351  Pointer<AssignmentContainer> contained_;
352  unsigned int max_;
353  void check_number() const;
354 
355  public:
356  CappedAssignmentContainer(AssignmentContainer *contained, int max_states,
357  std::string name);
358  virtual unsigned int get_number_of_assignments() const override;
359  virtual Assignment get_assignment(unsigned int i) const override;
360  virtual void add_assignment(const Assignment &a) override;
363 };
364 
365 IMPDOMINO_END_NAMESPACE
366 
367 #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.