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
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
00180 for (unsigned int i = 0; i < n; ++i) {
00181 sum[i] = h1[i] + h2[i];
00182 diff[i] = h1[i] - h2[i];
00183
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 }