IMP  2.0.1
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() {
48  return false;
49  }
50 #endif
51  bool get_has_index(const ExtendedGridIndexD<D>& ) const {
52  return true;
53  }
54  IMP_SHOWABLE_INLINE(UnboundedGridRangeD, out << "UnboundedStorageD" << D);
55 #ifndef SWIG
56 #ifndef IMP_DOXYGEN
57  typedef internal::GridIndexIterator<ExtendedGridIndexD<D>,
58  internal::AllItHelp<ExtendedGridIndexD<D>,
60  > >
61  ExtendedIndexIterator;
62 #else
63  class ExtendedIndexIterator;
64 #endif
65  ExtendedIndexIterator
66  extended_indexes_begin(const ExtendedGridIndexD<D>& lb,
67  const ExtendedGridIndexD<D>& ub) const {
68  ExtendedGridIndexD<D> eub=ub.get_uniform_offset(1);
69  IMP_INTERNAL_CHECK(internal::get_is_non_empty(lb, eub),
70  "empty range");
71  return ExtendedIndexIterator(lb, eub);
72  }
73  ExtendedIndexIterator
74  extended_indexes_end(const ExtendedGridIndexD<D>&,
75  const ExtendedGridIndexD<D>&) const {
76  return ExtendedIndexIterator();
77  }
78 #endif
80  get_extended_indexes(const ExtendedGridIndexD<D>& lb,
81  const ExtendedGridIndexD<D>& ub) const {
83  (extended_indexes_begin(lb, ub),
84  extended_indexes_end(lb, ub));
85  }
86 };
87 
88 
89 
90 #ifndef IMP_DOXYGEN
91 typedef UnboundedGridRangeD<1> UnboundedGridRange1D;
92 typedef UnboundedGridRangeD<2> UnboundedGridRange2D;
93 typedef UnboundedGridRangeD<3> UnboundedGridRange3D;
94 typedef UnboundedGridRangeD<4> UnboundedGridRange4D;
95 typedef UnboundedGridRangeD<5> UnboundedGridRange5D;
96 typedef UnboundedGridRangeD<6> UnboundedGridRange6D;
97 typedef UnboundedGridRangeD<-1> UnboundedGridRangeKD;
98 typedef base::Vector<UnboundedGridRange1D> UnboundedGridRange1Ds;
99 typedef base::Vector<UnboundedGridRange2D> UnboundedGridRange2Ds;
100 typedef base::Vector<UnboundedGridRange3D> UnboundedGridRange3Ds;
101 typedef base::Vector<UnboundedGridRange4D> UnboundedGridRange4Ds;
102 typedef base::Vector<UnboundedGridRange5D> UnboundedGridRange5Ds;
103 typedef base::Vector<UnboundedGridRange6D> UnboundedGridRange6Ds;
104 typedef base::Vector<UnboundedGridRangeKD> UnboundedGridRangeKDs;
105 #endif
106 
107 
108 
109 
110 
111 
112 
113 
114 /** This is a base class for storage types which refer to a bounded number
115  of cells.
116 */
117 template <int D>
120 
121  void set_number_of_voxels(Ints bds) {
122  IMP_USAGE_CHECK(D==-1
123  || static_cast<int>(bds.size()) ==D,
124  "Wrong number of dimensions");
125  d_=ExtendedGridIndexD<D>(bds);
126  }
127  public:
128  typedef GridIndexD<D> Index;
130 #ifndef IMP_DOXYGEN
131  static bool get_is_bounded() {
132  return true;
133  }
134 #endif
136  }
137  explicit BoundedGridRangeD(const Ints &counts) {
138  set_number_of_voxels(counts);
139  }
140  //! Return the number of voxels in a certain direction
141  unsigned int get_number_of_voxels(unsigned int i) const {
142  IMP_INTERNAL_CHECK(D==-1 || i < static_cast<unsigned int>(D),
143  "Only D: "<< i);
144  return d_[i];
145  }
146  unsigned int get_number_of_voxels() const {
147  int ret=d_[0];
148  for (unsigned int i=1; i< d_.get_dimension(); ++i) {
149  ret*=d_[i];
150  }
151  return ret;
152  }
153  //! Get the past-end voxel
155  return d_;
156  }
157 
158  IMP_SHOWABLE_INLINE(BoundedGridRangeD, out << "BoundedStorageD" << D);
159 
160  /** \name All Index iterators
161  The value type is a GridIndexD;
162  @{
163  */
164 #ifndef SWIG
165 #ifdef IMP_DOXYGEN
166  class AllIndexIterator;
167 #else
168  typedef internal::GridIndexIterator<ExtendedGridIndexD<D>,
169  internal::AllItHelp<ExtendedGridIndexD<D>,
170  GridIndexD<D> > >
171  AllIndexIterator;
172 #endif
173  AllIndexIterator all_indexes_begin() const {
174  return indexes_begin(ExtendedGridIndexD<D>(Ints(d_.get_dimension(), 0)),
175  d_);
176  }
177  AllIndexIterator all_indexes_end() const {
178  return indexes_end(ExtendedGridIndexD<D>(Ints(d_.get_dimension(), 0)),
179  d_);
180  }
181 #endif
182  base::Vector<GridIndexD<D> > get_all_indexes() const {
183  base::Vector<GridIndexD<D> > ret(all_indexes_begin(),
184  all_indexes_end());
185  return ret;
186  }
187  /** @} */
188 
189 
190 
191  /** \name Index Iterators
192 
193  Iterate through a range of actual indexes. The value
194  type for the iterator is an GridIndexD<D>.
195 
196  The range is defined by a pair of indexes. It includes
197  all indexes in the axis aligned box defined by lb
198  as the lower corner and the second as the ub. That is, if
199  lb is \f$(l_x, l_y, l_z)\f$ and ub is \f$(u_x, u_y, u_z)\f$,
200  then the range includes all
201  indexes \f$(i_x, i_y, i_z)\f$ such that \f$l_x \leq i_x \leq u_x\f$,
202  \f$l_y \leq i_y \leq u_y\f$
203  and \f$l_z \leq i_z \leq u_z\f$.
204 
205  @{
206  */
207 #ifndef SWIG
208 #ifndef IMP_DOXYGEN
209  typedef internal::GridIndexIterator<ExtendedGridIndexD<D>,
210  internal::AllItHelp<ExtendedGridIndexD<D>,
211  GridIndexD<D> > >
212  IndexIterator;
213  typedef internal::GridIndexIterator<ExtendedGridIndexD<D>,
214  internal::AllItHelp<ExtendedGridIndexD<D>,
215  ExtendedGridIndexD<D>
216  > >
217  ExtendedIndexIterator;
218 #else
219  class IndexIterator;
220  class ExtendedIndexIterator;
221 #endif
222  IndexIterator indexes_begin(const ExtendedGridIndexD<D>& lb,
223  const ExtendedGridIndexD<D>& ub) const {
224  ExtendedGridIndexD<D> eub=ub.get_uniform_offset(1);
225  std::pair<ExtendedGridIndexD<D>, ExtendedGridIndexD<D> > bp
226  = internal::intersect<ExtendedGridIndexD<D> >(lb,eub, d_);
227  if (bp.first== bp.second) {
228  return IndexIterator();
229  } else {
230  IMP_INTERNAL_CHECK(internal::get_is_non_empty(bp.first,
231  bp.second),
232  "empty range");
233  return IndexIterator(bp.first, bp.second);
234  }
235  }
236  IndexIterator indexes_end(const ExtendedGridIndexD<D>&,
237  const ExtendedGridIndexD<D>&) const {
238  //IMP_INTERNAL_CHECK(lb <= ub, "empty range");
239  return IndexIterator();
240  }
241  ExtendedIndexIterator
242  extended_indexes_begin(const ExtendedGridIndexD<D>& lb,
243  const ExtendedGridIndexD<D>& ub) const {
244  ExtendedGridIndexD<D> eub=ub.get_uniform_offset(1);
245  return ExtendedIndexIterator(lb, eub);
246  }
247  ExtendedIndexIterator
248  extended_indexes_end(const ExtendedGridIndexD<D>&,
249  const ExtendedGridIndexD<D>&) const {
250  //IMP_INTERNAL_CHECK(lb <= ub, "empty range");
251  return ExtendedIndexIterator();
252  }
253 #endif
254 
255  base::Vector<GridIndexD<D> >
256  get_indexes(const ExtendedGridIndexD<D>& lb,
257  const ExtendedGridIndexD<D>& ub) const {
258  return base::Vector<GridIndexD<D> >(indexes_begin(lb, ub),
259  indexes_end(lb, ub));
260  }
261  base::Vector<ExtendedGridIndexD<D> >
262  get_extended_indexes(const ExtendedGridIndexD<D>& lb,
263  const ExtendedGridIndexD<D>& ub) const {
264  return base::Vector<ExtendedGridIndexD<D> >
265  (extended_indexes_begin(lb, ub),
266  extended_indexes_end(lb, ub));
267  }
268  /* @} */
269 
270  //! Convert a ExtendedIndex into a real Index if possible
271  /** The passed index must be part of the grid
272  */
274  IMP_USAGE_CHECK(get_has_index(v), "Passed index not in grid "
275  << v);
276  return GridIndexD<D>(v.begin(), v.end());
277  }
278  //! Return true if the ExtendedIndex is also a normal index value
279  bool get_has_index(const ExtendedGridIndexD<D>& v) const {
280  for (unsigned int i=0; i< d_.get_dimension(); ++i) {
281  if (v[i] < 0
282  || v[i] >= static_cast<int>(get_number_of_voxels(i))) {
283  return false;
284  }
285  }
286  return true;
287  }
288  //! Return the ExtendedGridIndexD of all zeros
290  return ExtendedGridIndexD<D>(Ints(d_.get_dimension(), 0));
291  }
292  //! Return the index of the maximumal cell
294  ExtendedGridIndexD<D> ret=d_;
295  for (unsigned int i=0; i< ret.get_dimension(); ++i) {
296  --ret.access_data().get_data()[i];
297  }
298  return ret;
299  }
300 };
301 
302 
303 
304 #ifndef IMP_DOXYGEN
305 typedef BoundedGridRangeD<1> BoundedGridRange1D;
306 typedef BoundedGridRangeD<2> BoundedGridRange2D;
307 typedef BoundedGridRangeD<3> BoundedGridRange3D;
308 typedef BoundedGridRangeD<4> BoundedGridRange4D;
309 typedef BoundedGridRangeD<5> BoundedGridRange5D;
310 typedef BoundedGridRangeD<6> BoundedGridRange6D;
311 typedef BoundedGridRangeD<-1> BoundedGridRangeKD;
312 typedef base::Vector<BoundedGridRange1D> BoundedGridRange1Ds;
313 typedef base::Vector<BoundedGridRange2D> BoundedGridRange2Ds;
314 typedef base::Vector<BoundedGridRange3D> BoundedGridRange3Ds;
315 typedef base::Vector<BoundedGridRange4D> BoundedGridRange4Ds;
316 typedef base::Vector<BoundedGridRange5D> BoundedGridRange5Ds;
317 typedef base::Vector<BoundedGridRange6D> BoundedGridRange6Ds;
318 typedef base::Vector<BoundedGridRangeKD> BoundedGridRangeKDs;
319 #endif
320 
321 IMPALGEBRA_END_NAMESPACE
322 
323 
324 #endif /* IMPALGEBRA_GRID_RANGES_H */