Go to the documentation of this file.00001 #ifndef NPSTAT_BOXNDSCANNER_HH_
00002 #define NPSTAT_BOXNDSCANNER_HH_
00003
00015 #include "JetMETCorrections/InterpolationTables/interface/BoxND.h"
00016
00017 namespace npstat {
00037 template <typename Numeric>
00038 class BoxNDScanner
00039 {
00040 public:
00042
00046 inline BoxNDScanner(const BoxND<Numeric>& box,
00047 const std::vector<unsigned>& shape)
00048 : box_(box), state_(0UL)
00049 {initialize(shape.empty() ? static_cast<unsigned*>(0) :
00050 &shape[0], shape.size());}
00051
00052 inline BoxNDScanner(const BoxND<Numeric>& box,
00053 const unsigned* shape, const unsigned lenShape)
00054 : box_(box), state_(0UL) {initialize(shape, lenShape);}
00056
00058 inline unsigned dim() const {return box_.dim();}
00059
00061 inline unsigned long state() const {return state_;}
00062
00064 inline unsigned long maxState() const {return maxState_;}
00065
00067 inline bool isValid() const {return state_ < maxState_;}
00068
00070 void getCoords(Numeric* x, unsigned nx) const;
00071
00073 void getIndex(unsigned* index, unsigned indexBufferLen) const;
00074
00076 inline void reset() {state_ = 0UL;}
00077
00079 inline BoxNDScanner& operator++()
00080 {if (state_ < maxState_) ++state_; return *this;}
00081
00083 inline void operator++(int) {if (state_ < maxState_) ++state_;}
00084
00086 inline void setState(const unsigned long state)
00087 {state_ = state <= maxState_ ? state : maxState_;}
00088
00089 private:
00090 BoxNDScanner();
00091
00092 void initialize(const unsigned* shape, unsigned lenShape);
00093
00094 BoxND<Numeric> box_;
00095 std::vector<unsigned long> strides_;
00096 std::vector<double> bw_;
00097 unsigned long state_;
00098 unsigned long maxState_;
00099 };
00100 }
00101
00102 #include <cassert>
00103 #include "JetMETCorrections/InterpolationTables/interface/NpstatException.h"
00104
00105 namespace npstat {
00106 template <typename Numeric>
00107 void BoxNDScanner<Numeric>::initialize(const unsigned* shape,
00108 const unsigned dim)
00109 {
00110 if (!(dim && box_.dim() == dim)) throw npstat::NpstatInvalidArgument(
00111 "In npstat::BoxNDScanner::initialize: incompatible scan shape");
00112 assert(shape);
00113 for (unsigned j=0; j<dim; ++j)
00114 if (!shape[j]) throw npstat::NpstatInvalidArgument(
00115 "In npstat::BoxNDScanner::initialize: "
00116 "number of scans must be positive in each dimension");
00117
00118 strides_.resize(dim);
00119 strides_[dim - 1] = 1UL;
00120 for (unsigned j=dim - 1; j>0; --j)
00121 strides_[j - 1] = strides_[j]*shape[j];
00122 maxState_ = strides_[0]*shape[0];
00123
00124 bw_.reserve(dim);
00125 for (unsigned j=0; j<dim; ++j)
00126 bw_.push_back(box_[j].length()*1.0/shape[j]);
00127 }
00128
00129 template <typename Numeric>
00130 void BoxNDScanner<Numeric>::getCoords(Numeric* x, const unsigned nx) const
00131 {
00132 const unsigned dim = strides_.size();
00133 if (nx < dim) throw npstat::NpstatInvalidArgument(
00134 "In npstat::BoxNDScanner::getCoords: "
00135 "insufficient length of the output buffer");
00136 if (state_ >= maxState_) throw npstat::NpstatRuntimeError(
00137 "In npstat::BoxNDScanner::getCoords: invalid scanner state");
00138 assert(x);
00139
00140 unsigned long l = state_;
00141 for (unsigned i=0; i<dim; ++i)
00142 {
00143 unsigned long idx = l / strides_[i];
00144 x[i] = box_[i].min() + (idx + 0.5)*bw_[i];
00145 l -= (idx * strides_[i]);
00146 }
00147 }
00148
00149 template <typename Numeric>
00150 void BoxNDScanner<Numeric>::getIndex(unsigned* ix, const unsigned nx) const
00151 {
00152 const unsigned dim = strides_.size();
00153 if (nx < dim) throw npstat::NpstatInvalidArgument(
00154 "In npstat::BoxNDScanner::getIndex: "
00155 "insufficient length of the output buffer");
00156 if (state_ >= maxState_) throw npstat::NpstatRuntimeError(
00157 "In npstat::BoxNDScanner::getIndex: invalid scanner state");
00158 assert(ix);
00159
00160 unsigned long l = state_;
00161 for (unsigned i=0; i<dim; ++i)
00162 {
00163 unsigned long idx = l / strides_[i];
00164 ix[i] = static_cast<unsigned>(idx);
00165 l -= (idx * strides_[i]);
00166 }
00167 }
00168 }
00169
00170
00171 #endif // NPSTAT_BOXNDSCANNER_HH_
00172