RooBinnedPdf.cc

Go to the documentation of this file.
00001 /*****************************************************************************
00002 * Project: BaBar detector at the SLAC PEP-II B-factory
00003 * Package: RooRarFit
00004  *    File: $Id: RooBinnedPdf.cc,v 1.5 2011/06/16 13:18:48 fwilson Exp $
00005  * Authors:                                                                  *
00006  *    Aaron Roodman, Stanford Linear Accelerator Center, Stanford University *
00007  *    Adapted by Wouter                                                      *
00008  *                                                                           *
00009  * Copyright (C) 2005-2012, Stanford University. All rights reserved.        *
00010  *           
00011  * Redistribution and use in source and binary forms,                        *
00012  * with or without modification, are permitted according to the terms        *
00013  * listed in LICENSE (http://roofit.sourceforge.net/license.txt)             *
00014  *****************************************************************************/
00015 
00016 // -- CLASS DESCRIPTION [PDF] --
00017 // This is an implentation of the Binned PDF function for RooRarFit
00018 //
00020 //
00021 // BEGIN_HTML
00022 // This is an implentation of the Binned PDF function for RooRarFit
00023 //
00024 // END_HTML
00025 //
00026 
00027 // This is a reimplementation of the
00028 // RooModels/RooParametricStepFunction. In the RooModels implementation
00029 // the coefficient of bin n represents the density in bin n. In this
00030 // implementation, the coefficient for bin n is the integral of the
00031 // pdf in bin 'n', divided by the integral over bins [n,N]. The
00032 // advantage of this approach is that as long as each coefficient is
00033 // limited to values [0,1], there will never be a problem with the
00034 // normalization.
00035 //
00036 // Analytical expressions for calculating each bin integral for a given set of
00037 // parameters:
00038 //    b1 = N p1
00039 //    b2 = N p2 (1-p1)
00040 //    b3 = N p3 (1-p1) (1-p2)
00041 //    b4 = N p4 (1-p1) (1-p2) (1-p3)
00042 //    ... 
00043 //
00044 // An example of usage is:
00045 //
00046 // Int_t nbins(10);
00047 // TArrayD limits(nbins+1);
00048 // limits[0] = 0.0; //etc...
00049 // RooArgList* list = new RooArgList("list");
00050 // RooRealVar* binHeight0 = new RooRealVar("binHeight0","bin 0 Value",0.1,0.0,1.0);
00051 // list->add(binHeight0); // up to binHeight8, ie. 9 parameters
00052 //
00053 // RooBinnedPdf  aPdf = ("aPdf","PSF",*x,*list,limits);
00054 //
00055 
00056 #include "RooRarFit/rarVersion.hh"
00057 #include "RooRarFit/RooBinnedPdf.hh"
00058 
00059 #include "RooFitCore/RooAbsReal.hh"
00060 #include "RooFitCore/RooRealVar.hh"
00061 #include "RooFitCore/RooArgList.hh"
00062 
00063 ClassImp(RooBinnedPdf);
00064 
00065 RooBinnedPdf::RooBinnedPdf(const char* name, const char* title, 
00066                              RooAbsReal& x, const RooArgList& coefList, const TArrayD& limits) :
00067   RooAbsPdf(name, title),
00068   _x("x", "Dependent", this, x),
00069   _coefList("coefList","List of coefficients",this),
00070   _nBins(limits.GetSize()-1)
00071 {
00072   // Check lowest order
00073   if (_nBins<0) {
00074     cout << "RooBinnedPdf::ctor(" << GetName() 
00075          << ") WARNING: nBins must be >=0, setting value to 0" << endl ;
00076     _nBins=0 ;
00077   }
00078 
00079   TIterator* coefIter = coefList.createIterator() ;
00080   RooAbsArg* coef ;
00081   while(coef = (RooAbsArg*)coefIter->Next()) {
00082     if (!dynamic_cast<RooAbsReal*>(coef)) {
00083       cout << "RooBinnedPdf::ctor(" << GetName() << ") ERROR: coefficient " << coef->GetName() 
00084            << " is not of type RooAbsReal" << endl ;
00085       assert(0) ;
00086     }
00087     _coefList.add(*coef) ;
00088   }
00089   delete coefIter ;
00090 
00091   // Bin limits  
00092   limits.Copy(_limits);
00093 }
00094 
00095 
00096 RooBinnedPdf::RooBinnedPdf(const RooBinnedPdf& other, const char* name) :
00097   RooAbsPdf(other, name), 
00098   _x("x", this, other._x), 
00099   _coefList("coefList",this,other._coefList),
00100   _nBins(other._nBins)
00101 {
00102   // Copy constructor
00103   (other._limits).Copy(_limits);
00104 }
00105 
00106 
00107 
00108 RooBinnedPdf::~RooBinnedPdf()
00109 {
00110 }
00111 
00112 
00113 Int_t RooBinnedPdf::getAnalyticalIntegral(RooArgSet& allVars, RooArgSet& analVars, const char* /* rangeName */) const 
00114 {
00115   if (matchArgs(allVars, analVars, _x)) return 1;
00116   return 0;
00117 }
00118 
00119 
00120 
00121 Double_t RooBinnedPdf::analyticalIntegral(Int_t code, const char* rangeName) const 
00122 {
00123   assert(code==1) ;
00124 
00125   // Old method:
00126 //   Double_t sum(1.0) ;
00127 //   return sum;  
00128 
00129   Double_t integral(0.0); Double_t width(0.0);
00130   Double_t average(0.0); 
00131   Double_t min(_x.min(rangeName)); Double_t max(_x.max(rangeName));
00132   Int_t first(0); Int_t last(_nBins-1);
00133   
00134   if (min >= _limits[0] && max <= _limits[_nBins]){
00135 
00136     // Get first and last bin
00137     int i=0 ;
00138     for (i=0; i<_nBins && min>=_limits[i];++i){;}
00139     first = i-1; if(first < 0) first = 0;
00140     for (i=0; i<_nBins && max>=_limits[i];++i){;}
00141     last = i-1; if(last > _nBins-1) last = _nBins-1;
00142 
00143     if(first != last) {
00144       width = _limits[first+1] - _limits[first];
00145       average = _limits[first] + (width/2.0);
00146       width = _limits[first+1] - min;
00147       integral += (width * localEval(average));
00148       //      integral += (width * static_cast<RooRealVar*>(_coefList.at(first))->getVal());
00149       
00150       width = _limits[last+1] - _limits[last];
00151       average = _limits[last] + (width/2.0);
00152       width = max - _limits[last];
00153       integral += (width * localEval(average));
00154       //      integral += (width * static_cast<RooRealVar*>(_coefList.at(last))->getVal());
00155       
00156       for(i=first+1; i < last; i++) {
00157         width = _limits[i+1] - _limits[i];
00158         average = _limits[i] + (width/2.0);
00159         integral += (width * localEval(average));
00160         //      integral += (width * static_cast<RooRealVar*>(_coefList.at(i))->getVal());
00161       }
00162     }
00163     else {
00164       width = _limits[first+1] - _limits[first];
00165       average = _limits[first] + (width/2.0);
00166       width = max - min;
00167       integral += (width * localEval(average));
00168       //      integral += (width * static_cast<RooRealVar*>(_coefList.at(first))->getVal());
00169     }
00170   }
00171   return integral;
00172 }
00173 
00174 
00175 Double_t RooBinnedPdf::evaluate() const 
00176 {
00177   const Double_t xval = _x;
00178   return localEval(xval);
00179 }
00180 
00181 Double_t RooBinnedPdf::localEval(const Double_t xval) const
00182 {
00183   Double_t value(0);
00184   if (xval >= _limits[0] && xval < _limits[_nBins]){
00185     double sum(0),binval(0);
00186     int i=0 ;
00187     for (i=0; i<_nBins-1 && xval>=_limits[i];++i) {
00188       binval = (1-sum)*static_cast<RooRealVar*>(_coefList.at(i))->getVal() ;
00189       //binval = static_cast<RooRealVar*>(_coefList.at(i))->getVal() ;
00190       sum    += binval ;
00191     }
00192     if( xval>=_limits[_nBins-1] ) { // the last bin
00193       binval = 1-sum ;
00194       i = _nBins ;
00195     }
00196     double binwidth = _limits[i] - _limits[i-1];
00197     value = binval/binwidth ;
00198     if (value<=0){
00199       cout << "RooBinnedPdf: sum of values gt 1.0 -- beware!!" 
00200            << value << " " << binval << " " << sum << " " << i << " " << xval << endl;
00201       value = 0.000001;
00202     }
00203   }
00204   return value;
00205 }
00206 
00207 
00208 Int_t RooBinnedPdf::getnBins(){
00209   return _nBins;
00210 }
00211 
00212 Double_t* RooBinnedPdf::getLimits(){
00213   Double_t* limoutput = _limits.GetArray();
00214   return limoutput;
00215 }
00216 
00217 
00218 
00219 

Generated on 30 Oct 2013 for RooRarFit by  doxygen 1.4.7