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