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>
25 IMPALGEBRA_BEGIN_NAMESPACE
75 template <
int D,
class Storage,
77 class Value,
class EmbeddingT = DefaultEmbeddingD<D> >
85 GetVoxel(
This *home) : home_(home) {}
86 typedef Value &result_type;
88 result_type operator()(argument_type i)
const {
90 return home_->operator[](i);
94 struct ConstGetVoxel {
96 ConstGetVoxel(
const This *home) : home_(home) {}
97 typedef const Value &result_type;
99 result_type operator()(argument_type i)
const {
101 return home_->operator[](i);
107 for (
unsigned int i = 0; i < ret.get_dimension(); ++i) {
116 for (
unsigned int i = 0; i < ds.size(); ++i) {
118 "Number of voxels cannot be 0 on dimension: " << i);
120 double d = bside / ds[i];
121 double cd = std::ceil(d);
122 dd[i] = std::max<int>(1,
static_cast<int>(cd));
128 typedef EmbeddingT Embedding;
133 Value default_value = Value())
134 : Storage(counts, default_value),
135 Embedding(bb.get_corner(0), get_sides(counts, bb)) {
142 const Value &default_value = Value())
143 : Storage(get_ns(
Floats(bb.get_dimension(), side), bb), default_value),
147 Storage::get_is_bounded(),
148 "This grid constructor can only be used with bounded grids.");
151 GridD(
const Storage &storage,
const Embedding &embed)
152 : Storage(storage), Embedding(embed) {}
156 const Value &default_value = Value())
157 : Storage(default_value),
168 Storage::get_has_index(Embedding::get_extended_index(i)),
169 return Storage::operator[](
get_index(Embedding::get_extended_index(i))));
176 using Storage::__getitem__;
177 using Storage::__setitem__;
178 using Storage::operator[];
183 "add_voxel() only works on sparse grids.");
185 return Storage::add_voxel(ei, vt);
187 #if !defined(IMP_DOXYGEN) && !defined(SWIG)
188 Value &get_voxel_always(
const VectorD<D> &pt) {
189 ExtendedGridIndexD<D> ei = Embedding::get_extended_index(pt);
190 return Storage::get_voxel_always(ei);
192 const Value &get_value_always(
const VectorD<D> &pt)
const {
193 ExtendedGridIndexD<D> ei = Embedding::get_extended_index(pt);
194 return Storage::get_value_always(ei);
198 using Storage::get_has_index;
200 using Storage::add_voxel;
202 bool get_has_index(
const ExtendedGridIndexD<D> &i)
const;
203 GridIndexD<D>
get_index(
const ExtendedGridIndexD<D> &i)
const;
204 GridIndexD<D> add_voxel(
const ExtendedGridIndexD<D> &i,
const Value &vt);
211 using Embedding::get_extended_index;
233 Floats nuc(bb3.get_dimension());
234 for (
unsigned int i = 0; i < bb3.get_dimension(); ++i) {
237 nuc[i] = side / Storage::get_number_of_voxels(i);
239 Embedding::set_unit_cell(
VectorD<D>(nuc.begin(), nuc.end()));
252 Storage::get_is_dense(),
"get_nearest_index "
253 <<
"only works on dense grids.");
257 ExtendedGridIndexD<D> get_nearest_extended_index(
const VectorD<D> &pt)
const {
259 Storage::get_is_bounded(),
"get_nearest_index "
260 <<
"only works on bounded grids.");
261 ExtendedGridIndexD<D> ei = Embedding::get_extended_index(pt);
262 for (
unsigned int i = 0; i < pt.get_dimension(); ++i) {
263 ei.access_data().get_data()[i] = std::max(0, ei[i]);
264 ei.access_data().get_data()[i] =
265 std::min<int>(Storage::get_number_of_voxels(i) - 1, ei[i]);
281 class VoxelConstIterator;
283 typedef boost::transform_iterator<GetVoxel, typename Storage::IndexIterator>
285 typedef boost::transform_iterator<
286 ConstGetVoxel,
typename Storage::IndexIterator> VoxelConstIterator;
288 VoxelIterator voxels_begin(
const BoundingBoxD<D> &bb) {
289 return VoxelIterator(indexes_begin(bb), GetVoxel(
this));
291 VoxelIterator voxels_end(
const BoundingBoxD<D> &bb) {
294 return VoxelIterator(indexes_end(bb), GetVoxel(
this));
297 VoxelConstIterator voxels_begin(
const BoundingBoxD<D> &bb)
const {
298 return VoxelConstIterator(indexes_begin(bb), ConstGetVoxel(
this));
300 VoxelConstIterator voxels_end(
const BoundingBoxD<D> &bb)
const {
301 return VoxelConstIterator(indexes_end(bb), ConstGetVoxel(
this));
303 using Storage::indexes_begin;
304 using Storage::indexes_end;
305 typename Storage::IndexIterator indexes_begin(
306 const BoundingBoxD<D> &bb)
const {
307 ExtendedGridIndexD<3> lb = get_extended_index(bb.get_corner(0));
308 ExtendedGridIndexD<3> ub = get_extended_index(bb.get_corner(1));
309 return Storage::indexes_begin(lb, ub);
311 typename Storage::IndexIterator indexes_end(
const BoundingBoxD<D> &)
const {
314 return Storage::indexes_end(ExtendedGridIndexD<3>(),
315 ExtendedGridIndexD<3>());
326 template <
class Functor>
327 Functor apply(
const Functor &f)
const {
328 return Storage::apply(*
this, f);
333 template <
int D,
class Storage,
335 class Value,
class Embedding>
337 const GridD<D, Storage, Value, Embedding> &g) {
338 return g.get_bounding_box();
341 IMPALGEBRA_END_NAMESPACE
GridD()
An empty, undefined grid.
const VectorD< D > & get_corner(unsigned int i) const
For 0 return lower corner and 1 upper corner.
GridD(double side, const VectorD< D > &origin, const Value &default_value=Value())
Ints get_index(const kernel::ParticlesTemp &particles, const Subset &subset, const Subsets &excluded)
A class to represent a voxel grid.
A class to represent a voxel grid.
Represent a real cell in a grid (one within the bounding box)
GridD(double side, const BoundingBoxD< D > &bb, const Value &default_value=Value())
An index in an infinite grid on space.
A voxel grid in d-dimensional space space.
#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)
void set_bounding_box(const BoundingBoxD< D > &bb3)
Change the bounding box but not the grid or contents.
A Cartesian vector in D-dimensions.
ExtendedGridIndexD< D > get_extended_index(const GridIndexD< D > &index) const
Convert an index back to an extended index.
A bounding box in D dimensions.
A class for storing lists of IMP items.
An axis-aligned bounding box.
GridD(const Ints counts, const BoundingBoxD< D > &bb, Value default_value=Value())
#define IMP_BRACKET(Value, Index, bounds_check_expr, expr)
Declare an efficient stl-compatible map.
BoundingBoxD< D > get_bounding_box(const BoundingBoxD< D > &g)