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
 
Base class for geometric types. 
 
#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 for 1, the upper corner. 
 
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. 
 
GridD(const VectorD< D > &sides, const BoundingBoxD< D > &bb, const Value &default_value=Value())
 
#define IMP_BRACKET(Value, Index, bounds_check_expr, expr)
Implement operator[] and at() for C++, and getitem for Python. 
 
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 a simple primitive-like type. 
 
Base class for geometric types. 
 
A Cartesian vector in D-dimensions. 
 
Ints get_index(const ParticlesTemp &particles, const Subset &subset, const Subsets &excluded)
 
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. 
 
ParticleIndexes get_indexes(const ParticlesTemp &ps)
Get the indexes from a list of particles. 
 
GridD()
An empty, undefined grid. 
 
Macros to help with objects that can be printed to a stream.