rivet is hosted by Hepforge, IPPP Durham
BinnedHistogram.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #include "Rivet/Tools/BinnedHistogram.hh"
00003 #include "Rivet/Tools/RivetBoost.hh"
00004 #include "Rivet/Tools/RivetYODA.hh"
00005 #include "Rivet/Analysis.hh"
00006 
00007 namespace Rivet {
00008 
00009 
00010   template<typename T>
00011   const BinnedHistogram<T>& BinnedHistogram<T>::addHistogram(const T& binMin,
00012                                                              const T& binMax,
00013                                                              Histo1DPtr histo){
00014     if (binMin > binMax) {
00015       throw Error
00016         ("Cannot add a binned histogram where the lower bin edge is above the upper edge");
00017     }
00018     _histosByUpperBound[binMax] = histo;
00019     _histosByLowerBound[binMin] = histo;
00020     bool found = false;
00021     foreach (Histo1DPtr hist, _histos) {
00022       if (hist == histo) {
00023         found = true;
00024         break;
00025       }
00026     }
00027 
00028     if (!found){
00029       _histos.push_back(histo);
00030       _binWidths[histo]=binMax-binMin;
00031     }
00032 
00033     return *this;
00034   }
00035 
00036 
00037 
00038   template<typename T>
00039   Histo1DPtr BinnedHistogram<T>::fill(const T& bin,
00040                                                      const T& val,
00041                                                      double weight) {
00042 
00043     typename map<T, Histo1DPtr>::iterator histIt =
00044       _histosByUpperBound.upper_bound(bin);
00045     //check that the bin is not out of range
00046     if (histIt == _histosByUpperBound.end()) {
00047       return Histo1DPtr();
00048     }
00049 
00050     Histo1DPtr histo = histIt->second;
00051     histIt = _histosByLowerBound.lower_bound(bin);
00052 
00053     // No need to check going beyond the upper bound if we already passed above
00054     // (given that upper bound > lower bound is checked)
00055     // Check it is not before the start of the map
00056     if (histIt == _histosByLowerBound.begin()) {
00057       return Histo1DPtr();
00058     }
00059     // By-lower-bound actually gives us the iterator one above the nearest element,
00060     // so decrement it. This is safe because we already checked we're not at the start!
00061     --histIt;
00062 
00063     if (histo != histIt->second) {
00064       return Histo1DPtr();
00065     }
00066 
00067     histo->fill(val, weight);
00068 
00069     return histo;
00070   }
00071 
00072 
00073   template<typename T>
00074   void BinnedHistogram<T>::scale(const T& scale, Analysis* ana) {
00075     foreach (Histo1DPtr hist, getHistograms()) {
00076       ana->scale(hist, scale/_binWidths[hist]);
00077     }
00078   }
00079 
00080 
00081 
00082   // Template declarations for the compiler.
00083   template class BinnedHistogram<double>;
00084   template class BinnedHistogram<int>;
00085   template class BinnedHistogram<float>;
00086 
00087 
00088 }