CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/FastSimulation/Utilities/src/SimpleHistogramGenerator.cc

Go to the documentation of this file.
00001 #include "FastSimulation/Utilities/interface/SimpleHistogramGenerator.h"
00002 #include "FastSimulation/Utilities/interface/RandomEngine.h"
00003 
00004 #include <cmath>
00005 #include "TH1.h"
00006 // #include <iostream>
00007 
00008 SimpleHistogramGenerator::SimpleHistogramGenerator(TH1 * histo, const RandomEngine* engine) :
00009   random(engine), 
00010   myHisto(histo),
00011   theXaxis(histo->GetXaxis()),
00012   nBins(theXaxis->GetNbins()),
00013   xMin(theXaxis->GetXmin()),
00014   xMax(theXaxis->GetXmax()),
00015   binWidth((xMax-xMin)/(float)nBins)
00016 {
00017   integral.push_back(0.);
00018   for ( int i=1; i<=nBins; ++i )
00019     integral.push_back(integral[i-1]+histo->GetBinContent(i));
00020   integral.push_back(integral[nBins]);
00021   nEntries = integral[nBins+1];
00022   for ( int i=1; i<=nBins; ++i )
00023     integral[i] /= nEntries;
00024 
00025 }
00026 
00027 
00028 double 
00029 SimpleHistogramGenerator::generate() const {
00030 
00031   // return a random number distributed according the histogram bin contents.
00032   // NB Only valid for 1-d histograms, with fixed bin width.
00033 
00034    double r1 = random->flatShoot();
00035    int ibin = binarySearch(nBins,integral,r1);
00036    double x = xMin + (double)(ibin) * binWidth;
00037    if (r1 > integral[ibin]) x +=
00038       binWidth*(r1-integral[ibin])/(integral[ibin+1] - integral[ibin]);
00039    return x;
00040 
00041 }
00042 
00043 int 
00044 SimpleHistogramGenerator::binarySearch(const int& n, 
00045                                        const std::vector<double>& array, 
00046                                        const double& value) const
00047 {
00048    // Binary search in an array of n values to locate value.
00049    //
00050    // Array is supposed  to be sorted prior to this call.
00051    // If match is found, function returns position of element.
00052    // If no match found, function gives nearest element smaller than value.
00053 
00054    int nabove, nbelow, middle;
00055    nabove = n+1;
00056    nbelow = 0;
00057    while(nabove-nbelow > 1) {
00058       middle = (nabove+nbelow)/2;
00059       if (value == array[middle-1]) return middle-1;
00060       if (value  < array[middle-1]) nabove = middle;
00061       else                          nbelow = middle;
00062    }
00063    return nbelow-1;
00064 }