CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC2_patch1/src/JetMETCorrections/InterpolationTables/interface/BoxNDScanner.h

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