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) {
118 Ints dd(bb.get_dimension());
119 for (
unsigned int i = 0; i < bb.get_dimension(); ++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)) {
151 const Value &default_value = Value())
152 :
Storage(get_ns(
Floats(bb.get_dimension(), side), bb), default_value),
156 Storage::get_is_bounded(),
157 "This grid constructor can only be used with bounded grids.");
166 const Value &default_value = Value())
167 :
Storage(get_ns(sides.get_coordinates(), bb), default_value),
170 Storage::get_is_bounded(),
171 "This grid constructor can only be used with bounded grids.");
185 const Value &default_value = Value())
195 const Value &default_value = Value())
212 Storage::get_has_index(Embedding::get_extended_index(i)),
213 return Storage::operator[](
get_index(Embedding::get_extended_index(i))));
220 using Storage::__getitem__;
221 using Storage::__setitem__;
222 using Storage::operator[];
227 "add_voxel() only works on sparse grids.");
229 return Storage::add_voxel(ei, vt);
231 #if !defined(IMP_DOXYGEN) && !defined(SWIG)
232 Value &get_voxel_always(
const VectorD<D> &pt) {
233 ExtendedGridIndexD<D> ei = Embedding::get_extended_index(pt);
234 return Storage::get_voxel_always(ei);
236 const Value &get_value_always(
const VectorD<D> &pt)
const {
237 ExtendedGridIndexD<D> ei = Embedding::get_extended_index(pt);
238 return Storage::get_value_always(ei);
242 using Storage::get_has_index;
244 using Storage::add_voxel;
251 using Embedding::get_extended_index;
257 return get_bounding_box(min) + get_bounding_box(max);
260 using Embedding::get_bounding_box;
262 BoundingBoxD<D> get_bounding_box(
const ExtendedGridIndexD<D> &i)
const;
263 BoundingBoxD<D> get_bounding_box(
const GridIndexD<D> &i)
const;
271 Floats nuc(bb3.get_dimension());
272 for (
unsigned int i = 0; i < bb3.get_dimension(); ++i) {
275 nuc[i] = side / Storage::get_number_of_voxels(i);
277 Embedding::set_unit_cell(
VectorD<D>(nuc.begin(), nuc.end()));
290 Storage::get_is_dense(),
"get_nearest_index "
291 <<
"only works on dense grids.");
295 ExtendedGridIndexD<D> get_nearest_extended_index(
const VectorD<D> &pt)
const {
297 Storage::get_is_bounded(),
"get_nearest_index "
298 <<
"only works on bounded grids.");
299 ExtendedGridIndexD<D> ei = Embedding::get_extended_index(pt);
300 for (
unsigned int i = 0; i < pt.get_dimension(); ++i) {
301 ei.access_data().get_data()[i] = std::max(0, ei[i]);
302 ei.access_data().get_data()[i] =
303 std::min<int>(Storage::get_number_of_voxels(i) - 1, ei[i]);
319 class VoxelConstIterator;
321 typedef boost::transform_iterator<GetVoxel, typename Storage::IndexIterator>
323 typedef boost::transform_iterator<
324 ConstGetVoxel,
typename Storage::IndexIterator> VoxelConstIterator;
326 VoxelIterator voxels_begin(
const BoundingBoxD<D> &bb) {
327 return VoxelIterator(indexes_begin(bb), GetVoxel(
this));
329 VoxelIterator voxels_end(
const BoundingBoxD<D> &bb) {
332 return VoxelIterator(indexes_end(bb), GetVoxel(
this));
335 VoxelConstIterator voxels_begin(
const BoundingBoxD<D> &bb)
const {
336 return VoxelConstIterator(indexes_begin(bb), ConstGetVoxel(
this));
338 VoxelConstIterator voxels_end(
const BoundingBoxD<D> &bb)
const {
339 return VoxelConstIterator(indexes_end(bb), ConstGetVoxel(
this));
341 using Storage::indexes_begin;
342 using Storage::indexes_end;
343 typename Storage::IndexIterator indexes_begin(
const BoundingBoxD<D> &bb)
345 ExtendedGridIndexD<D> lb = get_extended_index(bb.get_corner(0));
346 ExtendedGridIndexD<D> ub = get_extended_index(bb.get_corner(1));
347 return Storage::indexes_begin(lb, ub);
349 typename Storage::IndexIterator indexes_end(
const BoundingBoxD<D> &)
const {
352 return Storage::indexes_end(ExtendedGridIndexD<D>(),
353 ExtendedGridIndexD<D>());
356 typedef internal::GridIndexIterator<
357 ExtendedGridIndexD<D>,
358 internal::AllItHelp<ExtendedGridIndexD<D>, ExtendedGridIndexD<D> > >
359 ExtendedIndexIterator;
360 ExtendedIndexIterator extended_indexes_begin(
const BoundingBoxD<D> &bb)
362 ExtendedGridIndexD<D> lb = get_extended_index(bb.get_corner(0));
363 ExtendedGridIndexD<D> ub = get_extended_index(bb.get_corner(1));
364 ExtendedGridIndexD<D> eub = ub.get_offset(1, 1, 1);
365 return ExtendedIndexIterator(lb, eub);
367 ExtendedIndexIterator extended_indexes_end(
const BoundingBoxD<D> &)
const {
370 return ExtendedIndexIterator();
373 typedef boost::iterator_range<typename Storage::IndexIterator> Indexes;
374 Indexes
get_indexes(
const BoundingBoxD<D> &bb)
const {
375 return Indexes(indexes_begin(bb), indexes_end(bb));
377 typedef boost::iterator_range<typename Storage::AllIndexIterator> AllIndexes;
378 AllIndexes get_all_indexes()
const {
379 return AllIndexes(Storage::all_indexes_begin(), Storage::all_indexes_end());
381 using Storage::get_extended_indexes;
382 typedef boost::iterator_range<ExtendedIndexIterator> ExtendedIndexes;
383 ExtendedIndexes get_extended_indexes(
const BoundingBoxD<D> &bb)
const {
384 return ExtendedIndexes(extended_indexes_begin(bb),
385 extended_indexes_end(bb));
396 template <
class Functor>
397 Functor apply(
const Functor &f)
const {
398 return Storage::apply(*
this, f);
403 template <
int D,
class Storage,
405 class Value,
class Embedding>
407 const GridD<D, Storage, Value, Embedding> &g) {
408 return g.get_bounding_box();
411 IMPALGEBRA_END_NAMESPACE
ParticleIndexes get_indexes(const ParticlesTemp &ps)
#define IMP_SHOWABLE_INLINE(Name, how_to_show)
Declare the methods needed by an object that can be printed.
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())
GridD(const VectorD< D > &sides, 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.
GridD(const VectorD< D > &sides, const BoundingBoxD< D > &bb, const Value &default_value=Value())
#define IMP_BRACKET(Value, Index, bounds_check_expr, expr)
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)
Base class for geometric types.
A Cartesian vector in D-dimensions.
GridD(double side, const BoundingBoxD< D > &bb, const Value &default_value=Value())
BoundingBoxD< 3 > get_bounding_box(const Cone3D &g)
A bounding box in D dimensions.
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())
A class for storing lists of IMP items.
void set_bounding_box(const BoundingBoxD< D > &bb3)
Change the bounding box but not the grid or contents.
An axis-aligned bounding box.
#define IMP_USAGE_CHECK(expr, message)
A runtime test for incorrect usage of a class or method.
GridD()
An empty, undefined grid.
Various general useful macros for IMP.