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