CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/HiggsAnalysis/CombinedLimit/src/FastTemplate.cc

Go to the documentation of this file.
00001 #include "../interface/FastTemplate.h"
00002 
00003 #include <cmath>
00004 #include <cstdlib>
00005 #include <cstdio>
00006 #include <algorithm>
00007 
00008 FastTemplate::T FastTemplate::Integral() const {
00009     T total = 0;
00010     for (unsigned int i = 0; i < size_; ++i) total += values_[i];
00011     return total;
00012 }
00013 
00014 void FastTemplate::Scale(T factor) {
00015     for (unsigned int i = 0; i < size_; ++i) values_[i] *= factor;
00016 }
00017 
00018 void FastTemplate::Clear() {
00019     for (unsigned int i = 0; i < size_; ++i) values_[i] = T(0.);
00020 }
00021 
00022 void FastTemplate::CopyValues(const FastTemplate &other) {
00023     memcpy(values_, other.values_, size_*sizeof(T));
00024 }
00025 
00026 void FastTemplate::CopyValues(const TH1 &other) {
00027      for (unsigned int i = 0; i < size_; ++i) values_[i] = other.GetBinContent(i+1);
00028 }
00029 
00030 void FastTemplate::CopyValues(const TH2 &other) {
00031     for (unsigned int i = 0, ix = 1, nx = other.GetNbinsX(), ny = other.GetNbinsY(); ix <= nx; ++ix) {
00032         for (unsigned int iy = 1; iy <= ny; ++iy, ++i) {
00033             values_[i] = other.GetBinContent(ix,iy);
00034             //printf("FastTemplate::CopyValues from %s: (ix,iy) = (%d/%d,%d/%d), i = %d/%d, val = %.5f\n", other.GetName(), ix, nx, iy, ny,  i, size_, values_[i]);
00035         }
00036     }
00037 }
00038 
00039 void FastTemplate::Dump() const {
00040     printf("--- dumping template with %d bins (@%p) ---\n", size_+1, (void*)values_);
00041     for (unsigned int i = 0; i < size_; ++i) printf(" bin %3d: yval = %9.5f\n", i, values_[i]);
00042     printf("\n"); 
00043 }
00044 
00045 FastHisto::FastHisto(const TH1 &hist) :
00046     FastTemplate(hist),
00047     binEdges_(new T[size_+1]),
00048     binWidths_(new T[size_])
00049 {
00050     for (unsigned int i = 0; i < size_; ++i) {
00051         binEdges_[i] = hist.GetBinLowEdge(i+1);
00052         binWidths_[i] = hist.GetBinWidth(i+1);
00053     }
00054     binEdges_[size_] = hist.GetBinLowEdge(size_+1);
00055 }
00056 
00057 FastHisto::FastHisto(const FastHisto &other) :
00058     FastTemplate(other),
00059     binEdges_(size_ ? new T[size_+1] : 0),
00060     binWidths_(size_ ? new T[size_] : 0)
00061 {
00062     if (size_) {
00063         memcpy(binEdges_,  other.binEdges_, (size_+1)*sizeof(T));
00064         memcpy(binWidths_, other.binWidths_, size_*sizeof(T));
00065     }
00066 }
00067 
00068 FastHisto::T FastHisto::GetAt(const T &x) const {
00069     T *match = std::lower_bound(binEdges_, binEdges_+size_+1, x);
00070     if (match == binEdges_ || match == binEdges_+size_+1) return T(0.0);
00071     return values_[match - binEdges_ - 1];
00072 }
00073 
00074 FastHisto::T FastHisto::IntegralWidth() const {
00075     double total = 0;
00076     for (unsigned int i = 0; i < size_; ++i) total += values_[i] * binWidths_[i];
00077     return total;
00078 }
00079 
00080 void FastHisto::Dump() const {
00081     printf("--- dumping histo template with %d bins in range %.2f - %.2f (@%p)---\n", size_+1, binEdges_[0], binEdges_[size_], (void*)values_);
00082     for (unsigned int i = 0; i < size_; ++i) {
00083         printf(" bin %3d, x = %6.2f: yval = %9.5f, width = %6.3f\n", 
00084                     i, 0.5*(binEdges_[i]+binEdges_[i+1]), values_[i], binWidths_[i]);
00085     }
00086     printf("\n"); 
00087 }
00088 
00089 FastHisto2D::FastHisto2D(const TH2 &hist, bool normXonly) :
00090     FastTemplate(hist),
00091     binX_(hist.GetNbinsX()), binY_(hist.GetNbinsY()),
00092     binEdgesX_(new T[binX_+1]),
00093     binEdgesY_(new T[binY_+1]),
00094     binWidths_(new T[size_])
00095 {
00096     TAxis *ax = hist.GetXaxis(), *ay = hist.GetYaxis();
00097     for (unsigned int ix = 0; ix < binX_; ++ix) {
00098         binEdgesX_[ix] = ax->GetBinLowEdge(ix+1);
00099     }
00100     binEdgesX_[binX_] = ax->GetBinLowEdge(binX_+1);
00101     for (unsigned int iy = 0; iy < binY_; ++iy) {
00102         binEdgesY_[iy] = ay->GetBinLowEdge(iy+1);
00103     }
00104     binEdgesY_[binY_] = ay->GetBinLowEdge(binY_+1);
00105     for (unsigned int ix = 1, i = 0; ix <= binX_; ++ix) {
00106         for (unsigned int iy = 1; iy <= binY_; ++iy, ++i) {
00107             binWidths_[i] = (normXonly ? 1 : ax->GetBinWidth(ix))*ay->GetBinWidth(iy);
00108         }
00109     }
00110 }
00111 
00112 FastHisto2D::FastHisto2D(const FastHisto2D &other) :
00113     FastTemplate(other),
00114     binX_(other.binX_), binY_(other.binY_),
00115     binEdgesX_(binX_ ? new T[binX_+1] : 0),
00116     binEdgesY_(binX_ ? new T[binY_+1] : 0),
00117     binWidths_(binX_ ? new T[size_] : 0)
00118 {
00119     if (binX_) {
00120         memcpy(binEdgesX_, other.binEdgesX_, (binX_+1)*sizeof(T));
00121         memcpy(binEdgesY_, other.binEdgesY_, (binY_+1)*sizeof(T));
00122         memcpy(binWidths_, other.binWidths_, size_*sizeof(T));
00123     }
00124 }
00125 
00126 FastHisto2D::T FastHisto2D::GetAt(const T &x, const T &y) const {
00127     T *matchx = std::lower_bound(binEdgesX_, binEdgesX_+binX_+1, x);
00128     int ix = (matchx - binEdgesX_ - 1);
00129     if (ix < 0 || unsigned(ix) >= binX_) return T(0.0);
00130     T *matchy = std::lower_bound(binEdgesY_, binEdgesY_+binY_+1, y);
00131     int iy = (matchy - binEdgesY_ - 1);
00132     if (iy < 0 || unsigned(iy) >= binY_) return T(0.0);
00133     return values_[ix * binY_ + iy];
00134 }
00135 
00136 FastHisto2D::T FastHisto2D::IntegralWidth() const {
00137     double total = 0;
00138     for (unsigned int i = 0; i < size_; ++i) total += values_[i] * binWidths_[i];
00139     return total;
00140 }
00141 
00142 void FastHisto2D::NormalizeXSlices() {
00143     for (unsigned int ix = 0, offs = 0; ix < binX_; ++ix, offs += binY_) {
00144        T *values = & values_[offs], *widths = & binWidths_[offs];
00145        double total = 0;
00146        for (unsigned int i = 0; i < binY_; ++i) total += values[i] * widths[i];
00147        if (total > 0) {
00148             total = T(1.0)/total;
00149             for (unsigned int i = 0; i < binY_; ++i) values[i] *= total;
00150        } 
00151     }
00152 }
00153 
00154 void FastHisto2D::Dump() const {
00155     printf("--- dumping histo template with %d x %d bins (@%p)---\n", binX_, binY_, (void*)values_);
00156     for (unsigned int i = 0; i < size_; ++i) {
00157         printf(" bin %3d, x = %6.2f, y = %6.2f: yval = %9.5f, width = %6.3f\n", 
00158                     i, 0.5*(binEdgesX_[i/binY_]+binEdgesX_[i/binY_+1]), 
00159                        0.5*(binEdgesY_[i%binY_]+binEdgesY_[(i%binY_)+1]),
00160                      values_[i], binWidths_[i]);
00161     }
00162     printf("\n"); 
00163 }
00164 
00165 
00166 namespace { 
00168     void subtract(FastTemplate::T * __restrict__ out, unsigned int n, FastTemplate::T  const * __restrict__ ref) {
00169         for (unsigned int i = 0; i < n; ++i) out[i] -= ref[i];
00170     }
00171     void logratio(FastTemplate::T * __restrict__ out, unsigned int n, FastTemplate::T  const * __restrict__ ref) {
00172         for (unsigned int i = 0; i < n; ++i) {
00173             out[i] = (out[i] > 0 && ref[i] > 0) ? std::log(out[i]/ref[i]) : 0;
00174         }
00175     }
00176     void sumdiff(FastTemplate::T * __restrict__ sum, FastTemplate::T * __restrict__ diff, 
00177                  unsigned int n, 
00178                  const FastTemplate::T  * __restrict__ h1, const FastTemplate::T  * __restrict__ h2) {
00179         //printf("sumdiff(sum = %p, diff = %p, n = %d, h1 = %p, h2 = %p\n", (void*)sum, (void*)diff, n, (void*)h1, (void*)h2);
00180         for (unsigned int i = 0; i < n; ++i) {
00181             sum[i]  = h1[i] + h2[i];
00182             diff[i] = h1[i] - h2[i];
00183             //printf("%3d: sum = %.6f, diff = %.6f, h1 = %.6f, h2 = %.6f\n", i, sum[i], diff[i], h1[i], h2[i]);
00184         }
00185     }
00186     void meld(FastTemplate::T * __restrict__ out, unsigned int n, FastTemplate::T  const * __restrict__ diff, FastTemplate::T  const * __restrict__ sum, FastTemplate::T x, FastTemplate::T y) {
00187         for (unsigned int i = 0; i < n; ++i) {
00188             out[i] += x*(diff[i] + y*sum[i]);
00189         }
00190     }
00191 }
00192 
00193 void FastTemplate::Subtract(const FastTemplate & ref) {
00194     subtract(values_, size_, &ref[0]);
00195 }
00196 void FastTemplate::LogRatio(const FastTemplate & ref) {
00197     logratio(values_, size_, &ref[0]);
00198 }
00199 void FastTemplate::SumDiff(const FastTemplate & h1, const FastTemplate & h2, 
00200                            FastTemplate & sum, FastTemplate & diff) {
00201     sumdiff(&sum[0], &diff[0], h1.size_, &h1[0], &h2[0]);
00202 }
00203 
00204 void FastTemplate::Meld(const FastTemplate & diff, const FastTemplate & sum, T x, T y) {
00205     meld(values_, size_, &diff[0], &sum[0], x, y);
00206 }
00207 
00208 void FastTemplate::Log() {
00209     for (unsigned int i = 0; i < size_; ++i) {
00210         values_[i] = values_[i] > 0 ? std::log(values_[i]) : T(-999);
00211     }
00212 }
00213 
00214 void FastTemplate::Exp() {
00215     for (unsigned int i = 0; i < size_; ++i) {
00216         values_[i] = std::exp(values_[i]);
00217     }
00218 }
00219 
00220 void FastTemplate::CropUnderflows(T minimum) {
00221     for (unsigned int i = 0; i < size_; ++i) {
00222         if (values_[i] < minimum) values_[i] = minimum;
00223     }
00224 }