8 #ifndef IMPALGEBRA_GRID_D_H
9 #define IMPALGEBRA_GRID_D_H
11 #include <IMP/algebra/algebra_config.h>
19 #include <boost/iterator/transform_iterator.hpp>
22 #include <boost/range/iterator_range.hpp>
26 IMPALGEBRA_BEGIN_NAMESPACE
76 template <
int D,
class StorageT,
78 class Value,
class EmbeddingT = DefaultEmbeddingD<D> >
88 GetVoxel(
This *home) : home_(home) {}
89 typedef Value &result_type;
91 result_type operator()(argument_type i)
const {
93 return home_->operator[](i);
97 struct ConstGetVoxel {
99 ConstGetVoxel(
const This *home) : home_(home) {}
100 typedef const Value &result_type;
102 result_type operator()(argument_type i)
const {
104 return home_->operator[](i);
110 for (
unsigned int i = 0; i < ret.get_dimension(); ++i) {
119 for (
unsigned int i = 0; i < ds.size(); ++i) {
121 "Number of voxels cannot be 0 on dimension: " << i);
123 double d = bside / ds[i];
124 double cd = std::ceil(d);
125 dd[i] = std::max<int>(1,
static_cast<int>(cd));
131 typedef StorageT Storage;
132 typedef EmbeddingT Embedding;
139 Value default_value = Value())
140 :
Storage(counts, default_value),
141 Embedding(bb.get_corner(0), get_sides(counts, bb)) {
150 const Value &default_value = Value())
151 :
Storage(get_ns(
Floats(bb.get_dimension(), side), bb), default_value),
155 Storage::get_is_bounded(),
156 "This grid constructor can only be used with bounded grids.");
169 const Value &default_value = Value())
185 Storage::get_has_index(Embedding::get_extended_index(i)),
186 return Storage::operator[](
get_index(Embedding::get_extended_index(i))));
193 using Storage::__getitem__;
194 using Storage::__setitem__;
195 using Storage::operator[];
200 "add_voxel() only works on sparse grids.");
202 return Storage::add_voxel(ei, vt);
204 #if !defined(IMP_DOXYGEN) && !defined(SWIG)
205 Value &get_voxel_always(
const VectorD<D> &pt) {
206 ExtendedGridIndexD<D> ei = Embedding::get_extended_index(pt);
207 return Storage::get_voxel_always(ei);
209 const Value &get_value_always(
const VectorD<D> &pt)
const {
210 ExtendedGridIndexD<D> ei = Embedding::get_extended_index(pt);
211 return Storage::get_value_always(ei);
215 using Storage::get_has_index;
217 using Storage::add_voxel;
224 using Embedding::get_extended_index;
233 using Embedding::get_bounding_box;
235 BoundingBoxD<D> get_bounding_box(
const ExtendedGridIndexD<D> &i)
const;
236 BoundingBoxD<D> get_bounding_box(
const GridIndexD<D> &i)
const;
244 Floats nuc(bb3.get_dimension());
245 for (
unsigned int i = 0; i < bb3.get_dimension(); ++i) {
248 nuc[i] = side / Storage::get_number_of_voxels(i);
250 Embedding::set_unit_cell(
VectorD<D>(nuc.begin(), nuc.end()));
263 Storage::get_is_dense(),
"get_nearest_index "
264 <<
"only works on dense grids.");
268 ExtendedGridIndexD<D> get_nearest_extended_index(
const VectorD<D> &pt)
const {
270 Storage::get_is_bounded(),
"get_nearest_index "
271 <<
"only works on bounded grids.");
272 ExtendedGridIndexD<D> ei = Embedding::get_extended_index(pt);
273 for (
unsigned int i = 0; i < pt.get_dimension(); ++i) {
274 ei.access_data().get_data()[i] = std::max(0, ei[i]);
275 ei.access_data().get_data()[i] =
276 std::min<int>(Storage::get_number_of_voxels(i) - 1, ei[i]);
292 class VoxelConstIterator;
294 typedef boost::transform_iterator<GetVoxel, typename Storage::IndexIterator>
296 typedef boost::transform_iterator<
297 ConstGetVoxel,
typename Storage::IndexIterator> VoxelConstIterator;
299 VoxelIterator voxels_begin(
const BoundingBoxD<D> &bb) {
300 return VoxelIterator(indexes_begin(bb), GetVoxel(
this));
302 VoxelIterator voxels_end(
const BoundingBoxD<D> &bb) {
305 return VoxelIterator(indexes_end(bb), GetVoxel(
this));
308 VoxelConstIterator voxels_begin(
const BoundingBoxD<D> &bb)
const {
309 return VoxelConstIterator(indexes_begin(bb), ConstGetVoxel(
this));
311 VoxelConstIterator voxels_end(
const BoundingBoxD<D> &bb)
const {
312 return VoxelConstIterator(indexes_end(bb), ConstGetVoxel(
this));
314 using Storage::indexes_begin;
315 using Storage::indexes_end;
316 typename Storage::IndexIterator indexes_begin(
const BoundingBoxD<D> &bb)
318 ExtendedGridIndexD<D> lb = get_extended_index(bb.get_corner(0));
319 ExtendedGridIndexD<D> ub = get_extended_index(bb.get_corner(1));
320 return Storage::indexes_begin(lb, ub);
322 typename Storage::IndexIterator indexes_end(
const BoundingBoxD<D> &)
const {
325 return Storage::indexes_end(ExtendedGridIndexD<D>(),
326 ExtendedGridIndexD<D>());
329 typedef internal::GridIndexIterator<
330 ExtendedGridIndexD<D>,
331 internal::AllItHelp<ExtendedGridIndexD<D>, ExtendedGridIndexD<D> > >
332 ExtendedIndexIterator;
333 ExtendedIndexIterator extended_indexes_begin(
const BoundingBoxD<D> &bb)
335 ExtendedGridIndexD<D> lb = get_extended_index(bb.get_corner(0));
336 ExtendedGridIndexD<D> ub = get_extended_index(bb.get_corner(1));
337 ExtendedGridIndexD<D> eub = ub.get_offset(1, 1, 1);
338 return ExtendedIndexIterator(lb, eub);
340 ExtendedIndexIterator extended_indexes_end(
const BoundingBoxD<D> &)
const {
343 return ExtendedIndexIterator();
346 typedef boost::iterator_range<typename Storage::IndexIterator> Indexes;
347 Indexes
get_indexes(
const BoundingBoxD<D> &bb)
const {
348 return Indexes(indexes_begin(bb), indexes_end(bb));
350 typedef boost::iterator_range<typename Storage::AllIndexIterator> AllIndexes;
351 AllIndexes get_all_indexes()
const {
352 return AllIndexes(Storage::all_indexes_begin(), Storage::all_indexes_end());
354 using Storage::get_extended_indexes;
355 typedef boost::iterator_range<ExtendedIndexIterator> ExtendedIndexes;
356 ExtendedIndexes get_extended_indexes(
const BoundingBoxD<D> &bb)
const {
357 return ExtendedIndexes(extended_indexes_begin(bb),
358 extended_indexes_end(bb));
369 template <
class Functor>
370 Functor apply(
const Functor &f)
const {
371 return Storage::apply(*
this, f);
376 template <
int D,
class Storage,
378 class Value,
class Embedding>
380 const GridD<D, Storage, Value, Embedding> &g) {
381 return g.get_bounding_box();
384 IMPALGEBRA_END_NAMESPACE
ParticleIndexes get_indexes(const ParticlesTemp &ps)
const VectorD< D > & get_corner(unsigned int i) const
For 0 return lower corner and 1 upper corner.
Ints get_index(const kernel::ParticlesTemp &particles, const Subset &subset, const Subsets &excluded)
A class to represent a voxel grid.
GridD(double side, const VectorD< D > &origin, const Value &default_value=Value())
A class to represent a voxel grid.
Represent a real cell in a grid (one within the bounding box)
An index in an infinite grid on space.
A voxel grid in d-dimensional space space.
#define IMP_SHOWABLE_INLINE(Name, how_to_show)
Declare the methods needed by an object that can be printed.
#define IMP_USAGE_CHECK(expr, message)
A runtime test for incorrect usage of a class or method.
VectorD< D > get_ones_vector_kd(unsigned int Di, double v=1)
Return a vector of ones (or another constant)
GridD(const Storage &storage, const Embedding &embed)
A Cartesian vector in D-dimensions.
GridD(double side, const BoundingBoxD< D > &bb, const Value &default_value=Value())
A bounding box in D dimensions.
A class for storing lists of IMP items.
ExtendedGridIndexD< D > get_extended_index(const GridIndexD< D > &index) const
Convert an index back to an extended index.
GridD(const Ints counts, const BoundingBoxD< D > &bb, Value default_value=Value())
void set_bounding_box(const BoundingBoxD< D > &bb3)
Change the bounding box but not the grid or contents.
An axis-aligned bounding box.
Various general useful macros for IMP.
#define IMP_BRACKET(Value, Index, bounds_check_expr, expr)
GridD()
An empty, undefined grid.
BoundingBoxD< D > get_bounding_box(const BoundingBoxD< D > &g)