IMP logo
IMP Reference Guide  develop.b708a66810,2021/08/02
The Integrative Modeling Platform
grid_indexes.h
Go to the documentation of this file.
1 /**
2  * \file IMP/algebra/grid_indexes.h \brief A class to represent a voxel grid.
3  *
4  * Copyright 2007-2021 IMP Inventors. All rights reserved.
5  *
6  */
7 
8 #ifndef IMPALGEBRA_GRID_INDEXES_H
9 #define IMPALGEBRA_GRID_INDEXES_H
10 
11 #include <IMP/algebra/algebra_config.h>
12 #include <IMP/bracket_macros.h>
13 #include "internal/vector.h"
14 #include "internal/grid_internal.h"
15 #include <IMP/types.h>
16 #include <IMP/Value.h>
17 #include <IMP/exception.h>
18 // for swig wrappers
19 #include <IMP/internal/range.h>
20 
21 IMPALGEBRA_BEGIN_NAMESPACE
22 
23 //! An index in an infinite grid on space
24 /* The index entries can be positive or negative and do not need to correspond
25  directly to cells in the grid. They get mapped on to actual grid cells
26  by various functions.
27  \see Grid3D
28 */
29 template <int D>
30 class ExtendedGridIndexD : public Value {
31  internal::VectorData<int, D, true> data_;
32  int compare(const ExtendedGridIndexD<D>& o) const {
33  if (D == -1) {
34  if (data_.get_dimension() == 0 && o.data_.get_dimension() == 0) {
35  return 0;
36  } else if (data_.get_dimension() == 0) {
37  return -1;
38  } else if (o.data_.get_dimension() == 0) {
39  return 1;
40  }
41  } else {
42  IMP_USAGE_CHECK(get_dimension() == o.get_dimension(),
43  "Dimensions don't match");
44  }
45  return internal::lexicographical_compare(begin(), end(), o.begin(),
46  o.end());
47  }
48 
49  public:
50 #if !defined(IMP_DOXYGEN) && !defined(SWIG)
51  struct Uninitialized {};
52  ExtendedGridIndexD(Uninitialized, int dim) : data_(dim) {}
53  struct Filled {};
54  ExtendedGridIndexD(Filled, int dim, int value) : data_(dim) {
55  std::fill(data_.get_data(), data_.get_data() + dim, value);
56  }
57  const internal::VectorData<int, D, true>& get_data() const { return data_; }
58  internal::VectorData<int, D, true>& access_data() { return data_; }
59 #endif
60 //! Create a grid cell from three arbitrary indexes
61 /** \note Only use this from Python. */
62 #ifndef SWIG
63  IMP_DEPRECATED_ATTRIBUTE
64 #endif
65  explicit ExtendedGridIndexD(Ints vals) {
66  data_.set_coordinates(vals.begin(), vals.end());
67  }
68 #ifndef SWIG
69  template <class It>
70  ExtendedGridIndexD(It b, It e) {
71  data_.set_coordinates(b, e);
72  }
73 #endif
74  ExtendedGridIndexD(int x) {
75  IMP_USAGE_CHECK(D == 1, "Can only use explicit constructor in 1D");
76  int v[] = {x};
77  data_.set_coordinates(v, v + 1);
78  }
79  ExtendedGridIndexD(int x, int y) {
80  IMP_USAGE_CHECK(D == 2, "Can only use explicit constructor in 2D");
81  int v[] = {x, y};
82  data_.set_coordinates(v, v + 2);
83  }
84  ExtendedGridIndexD(int x, int y, int z) {
85  IMP_USAGE_CHECK(D == 3, "Can only use explicit constructor in 3D");
86  int v[] = {x, y, z};
87  data_.set_coordinates(v, v + 3);
88  }
89  ExtendedGridIndexD(int i, int j, int k, int l) {
90  IMP_USAGE_CHECK(D == 4, "Can only use explicit constructor in 4D");
91  int v[] = {i, j, k, l};
92  data_.set_coordinates(v, v + 4);
93  }
94  ExtendedGridIndexD(int i, int j, int k, int l, int m) {
95  IMP_USAGE_CHECK(D == 5, "Can only use explicit constructor in 5D");
96  int v[] = {i, j, k, l, m};
97  data_.set_coordinates(v, v + 5);
98  }
99  ExtendedGridIndexD(int i, int j, int k, int l, int m, int n) {
100  IMP_USAGE_CHECK(D == 6, "Can only use explicit constructor in 6D");
101  int v[] = {i, j, k, l, m, n};
102  data_.set_coordinates(v, v + 6);
103  }
104  ExtendedGridIndexD() {}
105  unsigned int get_dimension() const { return data_.get_dimension(); }
106  IMP_COMPARISONS(ExtendedGridIndexD);
107  //! Get the ith component (i=0,1,2)
108  IMP_BRACKET(int, unsigned int, i < get_dimension(),
109  IMP_USAGE_CHECK(!data_.get_is_null(),
110  "Using uninitialized grid index");
111  return data_.get_data()[i]);
112  IMP_SHOWABLE_INLINE(ExtendedGridIndexD, {
113  out << "(";
114  for (unsigned int i = 0; i < get_dimension(); ++i) {
115  out << operator[](i);
116  if (i != get_dimension() - 1) out << ", ";
117  }
118  out << ")";
119  });
120 
121 #ifndef SWIG
122  typedef const int* iterator;
123  iterator begin() const { return data_.get_data(); }
124  iterator end() const { return data_.get_data() + get_dimension(); }
125 #endif
126 #ifndef IMP_DOXYGEN
127  unsigned int __len__() const { return get_dimension(); }
128 #endif
129  IMP_HASHABLE_INLINE(ExtendedGridIndexD,
130  return boost::hash_range(begin(), end()));
131  ExtendedGridIndexD<D> get_uniform_offset(int ii) const {
132  ExtendedGridIndexD<D> ret(typename ExtendedGridIndexD<D>::Filled(),
133  get_dimension(), 0);
134  for (unsigned int i = 0; i < get_dimension(); ++i) {
135  ret.access_data().get_data()[i] = operator[](i) + ii;
136  }
137  // std::cout << "Offset " << *this << " to get " << ret << std::endl;
138  return ret;
139  }
140  ExtendedGridIndexD<D> get_offset(int i, int j, int k) const {
141  IMP_USAGE_CHECK(D == 3, "Only for 3D");
142  int v[] = {operator[](0) + i, operator[](1) + j, operator[](2) + k};
143  ExtendedGridIndexD<D> ret(v, v + 3);
144  return ret;
145  }
146 };
147 
148 #if !defined(SWIG) && !defined(IMP_DOXYGEN)
149 template <int D>
150 inline std::size_t hash_value(const ExtendedGridIndexD<D>& ind) {
151  return ind.__hash__();
152 }
153 #endif
154 
155 //! Represent a real cell in a grid (one within the bounding box)
156 /* These indexes represent an actual cell in the grid.
157  They can only be constructed by the grid (since only it knows what
158  are the actual cells).
159  \see Grid3D
160 */
161 template <int D>
162 class GridIndexD : public Value {
163  internal::VectorData<int, D, true> data_;
164  int compare(const GridIndexD<D>& o) const {
165  if (D == -1) {
166  if (data_.get_dimension() == 0 && o.data_.get_dimension() == 0) {
167  return 0;
168  } else if (data_.get_dimension() == 0) {
169  return -1;
170  } else if (o.data_.get_dimension() == 0) {
171  return 1;
172  }
173  } else {
174  IMP_USAGE_CHECK(get_dimension() == o.get_dimension(),
175  "Dimensions don't match");
176  }
177  return internal::lexicographical_compare(begin(), end(), o.begin(),
178  o.end());
179  }
180 
181  public:
182 #if !defined(IMP_DOXYGEN) && !defined(SWIG)
183  const internal::VectorData<int, D, true>& get_data() const { return data_; }
184  internal::VectorData<int, D, true>& access_data() { return data_; }
185  struct Uninitialized {};
186  GridIndexD(Uninitialized, int dim) : data_(dim) {}
187  struct Filled {};
188  GridIndexD(Filled, int dim, int value) : data_(dim) {
189  std::fill(data_.get_data(), data_.get_data() + dim, value);
190  }
191 #endif
192  GridIndexD() {}
193  GridIndexD(int x) {
194  IMP_USAGE_CHECK(D == 1, "Can only use explicit constructor in 1D");
195  int v[] = {x};
196  data_.set_coordinates(v, v + 1);
197  }
198  GridIndexD(int x, int y) {
199  IMP_USAGE_CHECK(D == 2, "Can only use explicit constructor in 2D");
200  int v[] = {x, y};
201  data_.set_coordinates(v, v + 2);
202  }
203  GridIndexD(int x, int y, int z) {
204  IMP_USAGE_CHECK(D == 3, "Can only use explicit constructor in 3D");
205  int v[] = {x, y, z};
206  data_.set_coordinates(v, v + 3);
207  }
208  GridIndexD(int i, int j, int k, int l) {
209  IMP_USAGE_CHECK(D == 4, "Can only use explicit constructor in 4D");
210  int v[] = {i, j, k, l};
211  data_.set_coordinates(v, v + 4);
212  }
213  GridIndexD(int i, int j, int k, int l, int m) {
214  IMP_USAGE_CHECK(D == 5, "Can only use explicit constructor in 5D");
215  int v[] = {i, j, k, l, m};
216  data_.set_coordinates(v, v + 5);
217  }
218  GridIndexD(int i, int j, int k, int l, int m, int n) {
219  IMP_USAGE_CHECK(D == 6, "Can only use explicit constructor in 6D");
220  int v[] = {i, j, k, l, m, n};
221  data_.set_coordinates(v, v + 6);
222  }
223  unsigned int get_dimension() const { return data_.get_dimension(); }
224 
225 #ifndef IMP_DOXYGEN
226  //! Get the ith component (i=0,1,2)
227  IMP_CONST_BRACKET(int, unsigned int, i < get_dimension(),
228  IMP_USAGE_CHECK(!data_.get_is_null(),
229  "Using uninitialized grid index");
230  return data_.get_data()[i]);
232  out << "(";
233  for (unsigned int i = 0; i < get_dimension(); ++i) {
234  out << operator[](i);
235  if (i != get_dimension() - 1) out << ", ";
236  }
237  out << ")";
238  });
239 #ifndef SWIG
240  typedef const int* iterator;
241  iterator begin() const { return data_.get_data(); }
242  iterator end() const { return data_.get_data() + get_dimension(); }
243 /** \note Only use this from Python. */
244 #ifndef SWIG
245  IMP_DEPRECATED_ATTRIBUTE
246 #endif
247  explicit GridIndexD(Ints vals) {
248  data_.set_coordinates(vals.begin(), vals.end());
249  }
250  template <class It>
251  GridIndexD(It b, It e) {
252  data_.set_coordinates(b, e);
253  }
254 #endif
255  unsigned int __len__() const { return get_dimension(); }
256 #endif
258  IMP_HASHABLE_INLINE(GridIndexD, return boost::hash_range(begin(), end()));
259 };
260 
261 #if !defined(SWIG) && !defined(IMP_DOXYGEN)
262 template <int D>
263 inline std::size_t hash_value(const GridIndexD<D>& ind) {
264  return ind.__hash__();
265 }
266 #endif
267 
268 #if !defined(IMP_DOXYGEN)
269 typedef GridIndexD<1> GridIndex1D;
270 typedef ExtendedGridIndexD<1> ExtendedGridIndex1D;
271 typedef Vector<GridIndex1D> GridIndex1Ds;
272 typedef Vector<ExtendedGridIndex1D> ExtendedGridIndex1Ds;
273 
274 typedef GridIndexD<2> GridIndex2D;
275 typedef ExtendedGridIndexD<2> ExtendedGridIndex2D;
276 typedef Vector<GridIndex2D> GridIndex2Ds;
277 typedef Vector<ExtendedGridIndex2D> ExtendedGridIndex2Ds;
278 
279 typedef GridIndexD<3> GridIndex3D;
280 typedef ExtendedGridIndexD<3> ExtendedGridIndex3D;
281 typedef Vector<GridIndex3D> GridIndex3Ds;
282 typedef Vector<ExtendedGridIndex3D> ExtendedGridIndex3Ds;
283 
284 typedef GridIndexD<4> GridIndex4D;
285 typedef ExtendedGridIndexD<4> ExtendedGridIndex4D;
286 typedef Vector<GridIndex4D> GridIndex4Ds;
287 typedef Vector<ExtendedGridIndex4D> ExtendedGridIndex4Ds;
288 
289 typedef GridIndexD<5> GridIndex5D;
290 typedef ExtendedGridIndexD<5> ExtendedGridIndex5D;
291 typedef Vector<GridIndex5D> GridIndex5Ds;
292 typedef Vector<ExtendedGridIndex5D> ExtendedGridIndex5Ds;
293 
294 typedef GridIndexD<6> GridIndex6D;
295 typedef ExtendedGridIndexD<6> ExtendedGridIndex6D;
296 typedef Vector<GridIndex6D> GridIndex6Ds;
297 typedef Vector<ExtendedGridIndex6D> ExtendedGridIndex6Ds;
298 
299 typedef GridIndexD<-1> GridIndexKD;
300 typedef ExtendedGridIndexD<-1> ExtendedGridIndexKD;
301 typedef Vector<GridIndexKD> GridIndexKDs;
302 typedef Vector<ExtendedGridIndexKD> ExtendedGridIndexKDs;
303 #endif
304 
305 IMPALGEBRA_END_NAMESPACE
306 
307 #endif /* IMPALGEBRA_GRID_INDEXES_H */
ExtendedGridIndexD(Ints vals)
Create a grid cell from three arbitrary indexes.
Definition: grid_indexes.h:65
Basic types used by IMP.
#define IMP_SHOWABLE_INLINE(Name, how_to_show)
Declare the methods needed by an object that can be printed.
#define IMP_CONST_BRACKET(Value, Index, bounds_check_expr, expr)
Implement operator[] and at() for C++, and getitem for Python.
Represent a real cell in a grid (one within the bounding box)
Definition: grid_indexes.h:162
#define IMP_HASHABLE_INLINE(name, hashret)
Definition: hash_macros.h:18
An index in an infinite grid on space.
Definition: grid_indexes.h:30
#define IMP_BRACKET(Value, Index, bounds_check_expr, expr)
Implement operator[] and at() for C++, and getitem for Python.
#define IMP_COMPARISONS(Name)
Implement comparison in a class using a compare function.
Exception definitions and assertions.
Macros to handle array indexing.
Base class for a simple primitive-like type.
Definition: Value.h:23
int compare(const VectorD< D > &a, const VectorD< D > &b)
lexicographic comparison of two vectors
Definition: VectorD.h:179
Base class for a simple primitive-like type.
#define IMP_USAGE_CHECK(expr, message)
A runtime test for incorrect usage of a class or method.
Definition: check_macros.h:168