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