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