CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC4_patch1/src/PhysicsTools/Utilities/interface/HistoPdf.h

Go to the documentation of this file.
00001 #ifndef PhysicsTools_Utilities_HistoPdf_h
00002 #define PhysicsTools_Utilities_HistoPdf_h
00003 #include <iostream>
00004 #include "TH1.h"
00005 
00006 namespace funct {
00007   class HistoPdf {
00008   public:
00009     template<typename Iterator>
00010     HistoPdf(double xMin, double xMax, 
00011              const Iterator & begin, const Iterator & end) :
00012       xMin_(xMin), xMax_(xMax), delta_(xMax - xMin), binSize_(delta_ / (end - begin)), y_(end - begin) {
00013       double s = 0;
00014       unsigned int i = 0;
00015       for(Iterator it = begin; it != end; ++it)
00016         s += (y_[i++] = *it);
00017       for(std::vector<double>::iterator i = y_.begin(); i != y_.end(); ++i)
00018         *i /= s;
00019     }
00020     HistoPdf() { }
00021     template<typename Iterator>
00022     void init(double xMin, double xMax, 
00023               const Iterator & begin, const Iterator & end) {
00024       xMin_ = xMin;
00025       xMax_ = xMax;
00026       delta_ = xMax - xMin;
00027       unsigned int n = end - begin;
00028       binSize_ = delta_ / n;
00029       y_.resize(n);
00030       double s = 0;
00031       unsigned int i = 0;
00032       for(Iterator it = begin; it != end; ++it)
00033         s += (y_[i++] = *it);
00034       for(std::vector<double>::iterator i = y_.begin(); i != y_.end(); ++i)
00035         *i /= s;
00036     }
00037     double operator()(double x) const {
00038       if (x < xMin_ || x > xMax_) return 0;
00039       double pdf = y_[static_cast<unsigned int>(((x -xMin_)/delta_)*y_.size())] / binSize_;
00040       return pdf;
00041     }
00042     void rebin(unsigned int r) {
00043       if(y_.size() % r != 0) 
00044         throw edm::Exception(edm::errors::Configuration) <<
00045           "HistoPdf: can't rebin histogram of " << y_.size() << " entries by " << r << "\n";
00046       unsigned int n = y_.size() / r;
00047       std::vector<double> y(n, 0);
00048       for(unsigned int i = 0, j = 0; i < n; ++i)
00049         for(unsigned int k = 0; k < r; ++k) 
00050           y[i] += y_[j++];
00051       y_ = y;
00052       binSize_ *= r;
00053     }
00054     void dump() {
00055       std::cout << ">>> range: [" << xMin_ << ", " << xMax_ << "], bin size: " 
00056            << delta_ << "/" << y_.size() << " = " << binSize_ << std::endl;
00057        double s = 0;
00058       for(unsigned int i = 0; i != y_.size(); ++i) {
00059         double x = xMin_ + (0.5 + i)*binSize_;
00060         double y = operator()(x);
00061         std::cout << ">>> pdf(" << x << ") = " << y << std::endl;
00062         s+= y*binSize_;
00063       }
00064      std::cout << ">>>: PDF normalization is " << s << std::endl;
00065     }
00066   private:
00067     double xMin_, xMax_, delta_, binSize_;
00068     std::vector<double> y_;
00069   };
00070 
00071   class RootHistoPdf : public HistoPdf {
00072   public:
00073     explicit RootHistoPdf(const TH1 & histo, double fMin, double fMax) {
00074       unsigned int nBins = histo.GetNbinsX();
00075       std::vector<double> y;      
00076       y.reserve(nBins);
00077       double xMin = histo.GetXaxis()->GetXmin();
00078       double xMax = histo.GetXaxis()->GetXmax();
00079       double deltaX =(xMax - xMin) / nBins;
00080       for(unsigned int i = 0; i != nBins; ++i) {
00081         double x = xMin + (i + .5) * deltaX;
00082         if(x > fMin && x < fMax) {
00083           y.push_back(histo.GetBinContent(i+1));
00084         }
00085       }
00086       init(fMin, fMax, y.begin(), y.end());
00087     }
00088   };
00089 
00090 }
00091 
00092 
00093 #endif