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