IMP logo
IMP Reference Guide  develop.cb6747d2d1,2024/03/28
The Integrative Modeling Platform
grid_ranges.h
Go to the documentation of this file.
1 /**
2  * \file IMP/algebra/grid_ranges.h \brief A class to represent a voxel grid.
3  *
4  * Copyright 2007-2022 IMP Inventors. All rights reserved.
5  *
6  */
7 
8 #ifndef IMPALGEBRA_GRID_RANGES_H
9 #define IMPALGEBRA_GRID_RANGES_H
10 
11 #include <IMP/algebra/algebra_config.h>
12 
13 #include <IMP/types.h>
14 #include <IMP/bracket_macros.h>
15 #include "grid_indexes.h"
16 #include "Vector3D.h"
17 #include "BoundingBoxD.h"
18 #include <boost/iterator/transform_iterator.hpp>
19 #include <cereal/access.hpp>
20 #include <IMP/Vector.h>
21 
22 #include <limits>
23 
24 IMPALGEBRA_BEGIN_NAMESPACE
25 
26 /** The base for storing a grid on all of space (in 3D).
27  */
28 template <int D>
30  friend class cereal::access;
31 
32  template<class Archive> void serialize(Archive &ar) {}
33 
34  public:
35  typedef GridIndexD<D> Index;
38 #ifndef IMP_DOXYGEN
39  // for swig
40  UnboundedGridRangeD(const Ints&) {
41  IMP_USAGE_CHECK(false, "The method/constructor cannot be used"
42  << " with unbounded storage.");
43  }
44  void set_number_of_voxels(Ints) {
45  IMP_USAGE_CHECK(false, "The method/constructor cannot be used"
46  << " with unbounded storage.");
47  }
48  unsigned int get_number_of_voxels(int) const {
49  return std::numeric_limits<int>::max();
50  }
51  static bool get_is_bounded() { return false; }
52 #endif
53  bool get_has_index(const ExtendedGridIndexD<D>&) const { return true; }
54  IMP_SHOWABLE_INLINE(UnboundedGridRangeD, out << "UnboundedStorageD" << D);
55 #ifndef SWIG
56 #ifndef IMP_DOXYGEN
57  typedef internal::GridIndexIterator<
59  internal::AllItHelp<ExtendedGridIndexD<D>, ExtendedGridIndexD<D> > >
60  ExtendedIndexIterator;
61 #else
62  class ExtendedIndexIterator;
63 #endif
64  ExtendedIndexIterator extended_indexes_begin(
65  const ExtendedGridIndexD<D>& lb, const ExtendedGridIndexD<D>& ub) const {
66  ExtendedGridIndexD<D> eub = ub.get_uniform_offset(1);
67  IMP_INTERNAL_CHECK(internal::get_is_non_empty(lb, eub), "empty range");
68  return ExtendedIndexIterator(lb, eub);
69  }
70  ExtendedIndexIterator extended_indexes_end(
71  const ExtendedGridIndexD<D>&, const ExtendedGridIndexD<D>&) const {
72  return ExtendedIndexIterator();
73  }
74 #endif
75  Vector<ExtendedGridIndexD<D> > get_extended_indexes(
76  const ExtendedGridIndexD<D>& lb, const ExtendedGridIndexD<D>& ub) const {
77  return Vector<ExtendedGridIndexD<D> >(extended_indexes_begin(lb, ub),
78  extended_indexes_end(lb, ub));
79  }
80 };
81 
82 #ifndef IMP_DOXYGEN
83 typedef UnboundedGridRangeD<1> UnboundedGridRange1D;
84 typedef UnboundedGridRangeD<2> UnboundedGridRange2D;
85 typedef UnboundedGridRangeD<3> UnboundedGridRange3D;
86 typedef UnboundedGridRangeD<4> UnboundedGridRange4D;
87 typedef UnboundedGridRangeD<5> UnboundedGridRange5D;
88 typedef UnboundedGridRangeD<6> UnboundedGridRange6D;
89 typedef UnboundedGridRangeD<-1> UnboundedGridRangeKD;
90 typedef Vector<UnboundedGridRange1D> UnboundedGridRange1Ds;
91 typedef Vector<UnboundedGridRange2D> UnboundedGridRange2Ds;
92 typedef Vector<UnboundedGridRange3D> UnboundedGridRange3Ds;
93 typedef Vector<UnboundedGridRange4D> UnboundedGridRange4Ds;
94 typedef Vector<UnboundedGridRange5D> UnboundedGridRange5Ds;
95 typedef Vector<UnboundedGridRange6D> UnboundedGridRange6Ds;
96 typedef Vector<UnboundedGridRangeKD> UnboundedGridRangeKDs;
97 #endif
98 
99 /** This is a base class for storage types which refer to a bounded number
100  of cells.
101 */
102 template <int D>
105 
106  friend class cereal::access;
107 
108  template<class Archive> void serialize(Archive &ar) {
109  ar(d_);
110  }
111 
112  void set_number_of_voxels(Ints bds) {
113  IMP_USAGE_CHECK(D == -1 || static_cast<int>(bds.size()) == D,
114  "Wrong number of dimensions");
115  d_ = ExtendedGridIndexD<D>(bds.begin(), bds.end());
116  }
117 
118  public:
119  typedef GridIndexD<D> Index;
121 #ifndef IMP_DOXYGEN
122  static bool get_is_bounded() { return true; }
123 #endif
124  BoundedGridRangeD() {}
125  explicit BoundedGridRangeD(const Ints& counts) {
126  set_number_of_voxels(counts);
127  }
128  //! Return the number of voxels in a certain direction
129  unsigned int get_number_of_voxels(unsigned int i) const {
130  IMP_INTERNAL_CHECK(D == -1 || i < static_cast<unsigned int>(D),
131  "Only D: " << i);
132  return d_[i];
133  }
134  unsigned int get_number_of_voxels() const {
135  int ret = d_[0];
136  for (unsigned int i = 1; i < d_.get_dimension(); ++i) {
137  ret *= d_[i];
138  }
139  return ret;
140  }
141  //! Get the past-end voxel
142  ExtendedGridIndexD<D> get_end_index() const { return d_; }
143 
144  IMP_SHOWABLE_INLINE(BoundedGridRangeD, out << "BoundedStorageD" << D);
145 
146 /** \name All Index iterators
147  The value type is a GridIndexD;
148  @{
149 */
150 #ifndef SWIG
151 #ifdef IMP_DOXYGEN
152  class AllIndexIterator;
153 #else
154  typedef internal::GridIndexIterator<
156  internal::AllItHelp<ExtendedGridIndexD<D>, GridIndexD<D> > >
157  AllIndexIterator;
158 #endif
159  AllIndexIterator all_indexes_begin() const {
160  return indexes_begin(
162  d_.get_dimension(), 0),
163  d_);
164  }
165  AllIndexIterator all_indexes_end() const { return indexes_end(d_, d_); }
166 #endif
167  Vector<GridIndexD<D> > get_all_indexes() const {
168  Vector<GridIndexD<D> > ret(all_indexes_begin(), all_indexes_end());
169  return ret;
170  }
171 /** @} */
172 
173 /** \name Index Iterators
174 
175  Iterate through a range of actual indexes. The value
176  type for the iterator is an GridIndexD<D>.
177 
178  The range is defined by a pair of indexes. It includes
179  all indexes in the axis aligned box defined by lb
180  as the lower corner and the second as the ub. That is, if
181  lb is \f$(l_x, l_y, l_z)\f$ and ub is \f$(u_x, u_y, u_z)\f$,
182  then the range includes all
183  indexes \f$(i_x, i_y, i_z)\f$ such that \f$l_x \leq i_x \leq u_x\f$,
184  \f$l_y \leq i_y \leq u_y\f$
185  and \f$l_z \leq i_z \leq u_z\f$.
186 
187  @{
188  */
189 #ifndef SWIG
190 #ifndef IMP_DOXYGEN
191  typedef internal::GridIndexIterator<
192  ExtendedGridIndexD<D>,
193  internal::AllItHelp<ExtendedGridIndexD<D>, GridIndexD<D> > >
194  IndexIterator;
195  typedef internal::GridIndexIterator<
196  ExtendedGridIndexD<D>,
197  internal::AllItHelp<ExtendedGridIndexD<D>, ExtendedGridIndexD<D> > >
198  ExtendedIndexIterator;
199 #else
200  class IndexIterator;
201  class ExtendedIndexIterator;
202 #endif
203  IndexIterator indexes_begin(const ExtendedGridIndexD<D>& lb,
204  const ExtendedGridIndexD<D>& ub) const {
205  ExtendedGridIndexD<D> eub = ub.get_uniform_offset(1);
206  std::pair<ExtendedGridIndexD<D>, ExtendedGridIndexD<D> > bp =
207  internal::intersect<ExtendedGridIndexD<D> >(lb, eub, d_);
208  if (bp.first == bp.second) {
209  return IndexIterator();
210  } else {
211  IMP_INTERNAL_CHECK(internal::get_is_non_empty(bp.first, bp.second),
212  "empty range");
213  return IndexIterator(bp.first, bp.second);
214  }
215  }
216  IndexIterator indexes_end(const ExtendedGridIndexD<D>&,
217  const ExtendedGridIndexD<D>&) const {
218  // IMP_INTERNAL_CHECK(lb <= ub, "empty range");
219  return IndexIterator();
220  }
221  ExtendedIndexIterator extended_indexes_begin(
222  const ExtendedGridIndexD<D>& lb, const ExtendedGridIndexD<D>& ub) const {
223  ExtendedGridIndexD<D> eub = ub.get_uniform_offset(1);
224  return ExtendedIndexIterator(lb, eub);
225  }
226  ExtendedIndexIterator extended_indexes_end(
227  const ExtendedGridIndexD<D>&, const ExtendedGridIndexD<D>&) const {
228  // IMP_INTERNAL_CHECK(lb <= ub, "empty range");
229  return ExtendedIndexIterator();
230  }
231 #endif
232 
233  Vector<GridIndexD<D> > get_indexes(
234  const ExtendedGridIndexD<D>& lb, const ExtendedGridIndexD<D>& ub) const {
235  return Vector<GridIndexD<D> >(indexes_begin(lb, ub),
236  indexes_end(lb, ub));
237  }
238  Vector<ExtendedGridIndexD<D> > get_extended_indexes(
239  const ExtendedGridIndexD<D>& lb, const ExtendedGridIndexD<D>& ub) const {
240  return Vector<ExtendedGridIndexD<D> >(extended_indexes_begin(lb, ub),
241  extended_indexes_end(lb, ub));
242  }
243  /* @} */
244 
245  //! Convert a ExtendedIndex into a real Index if possible
246  /** The passed index must be part of the grid
247  */
249  IMP_USAGE_CHECK(get_has_index(v), "Passed index not in grid " << v);
250  return GridIndexD<D>(v.begin(), v.end());
251  }
252  //! Return true if the ExtendedIndex is also a normal index value
253  bool get_has_index(const ExtendedGridIndexD<D>& v) const {
254  for (unsigned int i = 0; i < d_.get_dimension(); ++i) {
255  if (v[i] < 0 || v[i] >= static_cast<int>(get_number_of_voxels(i))) {
256  return false;
257  }
258  }
259  return true;
260  }
261  //! Return the ExtendedGridIndexD of all zeros
263  ExtendedGridIndexD<D> ret(d_);
264  for (unsigned int i = 0; i < ret.get_dimension(); ++i) {
265  ret.access_data().get_data()[i] = 0;
266  }
267  return ret;
268  }
269  //! Return the index of the maximal cell
271  ExtendedGridIndexD<D> ret = d_;
272  for (unsigned int i = 0; i < ret.get_dimension(); ++i) {
273  --ret.access_data().get_data()[i];
274  }
275  return ret;
276  }
277 };
278 
279 #ifndef IMP_DOXYGEN
280 typedef BoundedGridRangeD<1> BoundedGridRange1D;
281 typedef BoundedGridRangeD<2> BoundedGridRange2D;
282 typedef BoundedGridRangeD<3> BoundedGridRange3D;
283 typedef BoundedGridRangeD<4> BoundedGridRange4D;
284 typedef BoundedGridRangeD<5> BoundedGridRange5D;
285 typedef BoundedGridRangeD<6> BoundedGridRange6D;
286 typedef BoundedGridRangeD<-1> BoundedGridRangeKD;
287 typedef Vector<BoundedGridRange1D> BoundedGridRange1Ds;
288 typedef Vector<BoundedGridRange2D> BoundedGridRange2Ds;
289 typedef Vector<BoundedGridRange3D> BoundedGridRange3Ds;
290 typedef Vector<BoundedGridRange4D> BoundedGridRange4Ds;
291 typedef Vector<BoundedGridRange5D> BoundedGridRange5Ds;
292 typedef Vector<BoundedGridRange6D> BoundedGridRange6Ds;
293 typedef Vector<BoundedGridRangeKD> BoundedGridRangeKDs;
294 #endif
295 
296 IMPALGEBRA_END_NAMESPACE
297 
298 #endif /* IMPALGEBRA_GRID_RANGES_H */
GridIndexD< D > get_index(const ExtendedGridIndexD< D > &v) const
Convert a ExtendedIndex into a real Index if possible.
Definition: grid_ranges.h:248
ExtendedGridIndexD< D > get_end_index() const
Get the past-end voxel.
Definition: grid_ranges.h:142
Basic types used by IMP.
ExtendedGridIndexD< D > get_maximum_extended_index() const
Return the index of the maximal cell.
Definition: grid_ranges.h:270
#define IMP_SHOWABLE_INLINE(Name, how_to_show)
Declare the methods needed by an object that can be printed.
A class to represent a voxel grid.
Represent a real cell in a grid (one within the bounding box)
Definition: grid_indexes.h:170
An index in an infinite grid on space.
Definition: grid_indexes.h:31
unsigned int get_number_of_voxels(unsigned int i) const
Return the number of voxels in a certain direction.
Definition: grid_ranges.h:129
#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
Macros to handle array indexing.
ExtendedGridIndexD< D > get_minimum_extended_index() const
Return the ExtendedGridIndexD of all zeros.
Definition: grid_ranges.h:262
bool get_has_index(const ExtendedGridIndexD< D > &v) const
Return true if the ExtendedIndex is also a normal index value.
Definition: grid_ranges.h:253
A bounding box in D dimensions.
A class for storing lists of IMP items.
Simple 3D vector class.
#define IMP_USAGE_CHECK(expr, message)
A runtime test for incorrect usage of a class or method.
Definition: check_macros.h:168
ParticleIndexes get_indexes(const ParticlesTemp &ps)
Get the indexes from a list of particles.