RooNumRunningInt.cxx

Go to the documentation of this file.
00001  /***************************************************************************** 
00002   * Project: RooFit                                                           * 
00003   *                                                                           * 
00004   * Copyright (c) 2000-2005, Regents of the University of California          * 
00005   *                          and Stanford University. All rights reserved.    * 
00006   *                                                                           * 
00007   * Redistribution and use in source and binary forms,                        * 
00008   * with or without modification, are permitted according to the terms        * 
00009   * listed in LICENSE (http://roofit.sourceforge.net/license.txt)             * 
00010   *****************************************************************************/ 
00011 
00012 //////////////////////////////////////////////////////////////////////////////
00013 //
00014 // BEGIN_HTML
00015 // Class RooNumRunningInt is an implementation of RooAbsCachedReal that represents a running integral
00016 // <pre>
00017 // RI(f(x)) = Int[x_lo,x] f(x') dx'
00018 // </pre>
00019 // that is calculated internally with a numeric technique: The input function
00020 // is first sampled into a histogram, which is then numerically integrated.
00021 // The output function is an interpolated version of the integrated histogram.
00022 // The sampling density is controlled by the binning named "cache" in the observable x.
00023 // The shape of the p.d.f is always calculated for the entire domain in x and
00024 // cached in a histogram. The cache histogram is automatically recalculated
00025 // when any of the parameters of the input p.d.f. has changed.
00026 // END_HTML
00027 //
00028 
00029 #include "Riostream.h" 
00030 
00031 #include "RooAbsPdf.h"
00032 #include "RooNumRunningInt.h" 
00033 #include "RooAbsReal.h" 
00034 #include "RooMsgService.h"
00035 #include "RooDataHist.h"
00036 #include "RooHistPdf.h"
00037 #include "RooRealVar.h"
00038 
00039 ClassImp(RooNumRunningInt) 
00040   ;
00041 
00042 
00043 
00044 //_____________________________________________________________________________
00045 RooNumRunningInt::RooNumRunningInt(const char *name, const char *title, RooAbsReal& _func, RooRealVar& _x, const char* bname) :
00046    RooAbsCachedReal(name,title), 
00047    func("func","func",this,_func),
00048    x("x","x",this,_x),
00049    _binningName(bname?bname:"cache")
00050  { 
00051    // Construct running integral of function '_func' over x_print from
00052    // the lower bound on _x to the present value of _x using a numeric
00053    // sampling technique. The sampling frequency is controlled by the
00054    // binning named 'bname' and a default second order interpolation
00055    // is applied to smooth the histogram-based c.d.f.
00056 
00057    setInterpolationOrder(2) ;
00058  } 
00059 
00060 
00061 
00062 
00063 //_____________________________________________________________________________
00064 RooNumRunningInt::RooNumRunningInt(const RooNumRunningInt& other, const char* name) :  
00065    RooAbsCachedReal(other,name), 
00066    func("func",this,other.func),
00067    x("x",this,other.x),
00068    _binningName(other._binningName)
00069  { 
00070    // Copy constructor
00071  } 
00072 
00073 
00074 
00075 //_____________________________________________________________________________
00076 RooNumRunningInt::~RooNumRunningInt() 
00077 {
00078   // Destructor
00079 }
00080 
00081 
00082 //_____________________________________________________________________________
00083 const char* RooNumRunningInt::inputBaseName() const 
00084 {
00085   // Return unique name for RooAbsCachedPdf cache components
00086   // constructed from input function name
00087 
00088   static string ret ;
00089   ret = func.arg().GetName() ;
00090   ret += "_NUMRUNINT" ;
00091   return ret.c_str() ;
00092 } ;
00093 
00094 
00095 
00096 //_____________________________________________________________________________
00097 RooNumRunningInt::RICacheElem::RICacheElem(const RooNumRunningInt& self, const RooArgSet* nset) : 
00098   FuncCacheElem(self,nset), _self(&const_cast<RooNumRunningInt&>(self))
00099 {
00100   // Construct RunningIntegral CacheElement
00101   
00102   // Instantiate temp arrays
00103   _ax = new Double_t[hist()->numEntries()] ;
00104   _ay = new Double_t[hist()->numEntries()] ;
00105 
00106   // Copy X values from histo  
00107   _xx = (RooRealVar*) hist()->get()->find(self.x.arg().GetName()) ;
00108   for (int i=0 ; i<hist()->numEntries() ; i++) {
00109     hist()->get(i) ;
00110     _ax[i] = _xx->getVal() ;
00111     _ay[i] = -1 ;
00112   }
00113 
00114 }
00115 
00116 
00117 //_____________________________________________________________________________
00118 RooNumRunningInt::RICacheElem::~RICacheElem() 
00119 {
00120   // Destructor
00121 
00122   // Delete temp arrays 
00123   delete[] _ax ;
00124   delete[] _ay ;    
00125 }
00126 
00127 
00128 //_____________________________________________________________________________
00129 RooArgList RooNumRunningInt::RICacheElem::containedArgs(Action action) 
00130 {
00131   // Return all RooAbsArg components contained in cache element
00132 
00133   RooArgList ret ;
00134   ret.add(FuncCacheElem::containedArgs(action)) ;
00135   ret.add(*_self) ;
00136   ret.add(*_xx) ;
00137   return ret ;  
00138 }
00139 
00140 
00141 
00142 //_____________________________________________________________________________
00143 void RooNumRunningInt::RICacheElem::calculate(Bool_t cdfmode) 
00144 {
00145   // Calculate the numeric running integral and store
00146   // the result in the cache histogram provided
00147   // by RooAbsCachedPdf
00148 
00149   // Update contents of histogram
00150   Int_t nbins = hist()->numEntries() ;
00151   
00152   Double_t xsave = _self->x ;
00153 
00154   Int_t lastHi=0 ;
00155   Int_t nInitRange=32 ;
00156   for (int i=1 ; i<=nInitRange ; i++) {
00157     Int_t hi = (i*nbins)/nInitRange -1 ;
00158     Int_t lo = lastHi ;
00159     addRange(lo,hi,nbins) ;
00160     lastHi=hi ;
00161   }
00162 
00163   // Perform numeric integration
00164   for (int i=1 ; i<nbins ; i++) {
00165     _ay[i] += _ay[i-1] ;
00166   }
00167  
00168   // Normalize and transfer to cache histogram
00169   Double_t binv = (_self->x.max()-_self->x.min())/nbins ;
00170   for (int i=0 ; i<nbins ; i++) {
00171     hist()->get(i) ;
00172     if (cdfmode) {
00173       hist()->set(_ay[i]/_ay[nbins-1]) ;
00174     } else {
00175       hist()->set(_ay[i]*binv) ;
00176     }
00177   }
00178 
00179   if (cdfmode) {
00180     func()->setCdfBoundaries(kTRUE) ;
00181   }
00182   _self->x = xsave ;
00183 }
00184 
00185 
00186 
00187 //_____________________________________________________________________________
00188 void RooNumRunningInt::RICacheElem::addRange(Int_t ixlo, Int_t ixhi, Int_t nbins) 
00189 {
00190   // Fill all empty histogram bins in the range [ixlo,ixhi] where nbins is the
00191   // total number of histogram bins. This method samples the mid-point of the
00192   // range and if the mid-point value is within small tolerance of the interpolated
00193   // mid-point value fills all remaining elements through linear interpolation.
00194   // If the tolerance is exceeded, the algorithm is recursed on the two subranges
00195   // [xlo,xmid] and [xmid,xhi]
00196 
00197   // Add first and last point, if not there already
00198   if (_ay[ixlo]<0) {
00199     addPoint(ixlo) ;
00200   }
00201   if (_ay[ixhi]<0) {
00202     addPoint(ixhi) ;
00203   }
00204 
00205   // Terminate here if there is no gap
00206   if (ixhi-ixlo==1) {
00207     return ;
00208   }
00209 
00210   // If gap size is one, simply fill gap and return
00211   if (ixhi-ixlo==2) {
00212     addPoint(ixlo+1) ;
00213     return ;
00214   }
00215 
00216   // Add mid-point
00217   Int_t ixmid = (ixlo+ixhi)/2 ;
00218   addPoint(ixmid) ;
00219   
00220   // Calculate difference of mid-point w.r.t interpolated value
00221   Double_t yInt = _ay[ixlo] + (_ay[ixhi]-_ay[ixlo])*(ixmid-ixlo)/(ixhi-ixlo) ;
00222   
00223   // If relative deviation is greater than tolerance divide and iterate
00224   if (fabs(yInt-_ay[ixmid])*(_ax[nbins-1]-_ax[0])>1e-6) {    
00225     addRange(ixlo,ixmid,nbins) ;
00226     addRange(ixmid,ixhi,nbins) ;
00227   } else {
00228     for (Int_t j=ixlo+1 ; j<ixmid ; j++) { 
00229       _ay[j] = _ay[ixlo] + (_ay[ixmid]-_ay[ixlo])*(j-ixlo)/(ixmid-ixlo) ; 
00230     }
00231     for (Int_t j=ixmid+1 ; j<ixhi ; j++) { 
00232       _ay[j] = _ay[ixmid] + (_ay[ixhi]-_ay[ixmid])*(j-ixmid)/(ixhi-ixmid) ; 
00233     }
00234   }
00235 
00236 }
00237 
00238 
00239 //_____________________________________________________________________________
00240 void RooNumRunningInt::RICacheElem::addPoint(Int_t ix)
00241 {
00242   // Sample function at bin ix
00243 
00244   hist()->get(ix) ;
00245   _self->x = _xx->getVal() ;
00246   _ay[ix] = _self->func.arg().getVal(*_xx) ;
00247 
00248 }
00249 
00250 
00251 
00252 //_____________________________________________________________________________
00253 void RooNumRunningInt::fillCacheObject(RooAbsCachedReal::FuncCacheElem& cache) const 
00254 {
00255   // Fill the cache object by calling its calculate() method
00256   RICacheElem& riCache = static_cast<RICacheElem&>(cache) ;
00257   riCache.calculate(kFALSE) ;
00258 }
00259 
00260 
00261 
00262 //_____________________________________________________________________________
00263 RooArgSet* RooNumRunningInt::actualObservables(const RooArgSet& /*nset*/) const 
00264 {
00265   // Return observable in nset to be cached by RooAbsCachedPdf
00266   // this is always the x observable that is integrated
00267 
00268   RooArgSet* ret = new RooArgSet ;
00269   ret->add(x.arg()) ;
00270   return ret ;
00271 }
00272 
00273 
00274 
00275 //_____________________________________________________________________________
00276 RooArgSet* RooNumRunningInt::actualParameters(const RooArgSet& /*nset*/) const 
00277 {
00278   // Return the parameters of the cache created by RooAbsCachedPdf.
00279   // These are always the input functions parameter, but never the
00280   // integrated variable x.
00281 
00282   RooArgSet* ret = func.arg().getParameters(RooArgSet()) ;
00283   ret->remove(x.arg(),kTRUE,kTRUE) ;
00284   return ret ;
00285 }
00286 
00287 
00288 //_____________________________________________________________________________
00289 RooAbsCachedReal::FuncCacheElem* RooNumRunningInt::createCache(const RooArgSet* nset) const 
00290 {
00291   // Create custom cache element for running integral calculations
00292 
00293   return new RICacheElem(*const_cast<RooNumRunningInt*>(this),nset) ; 
00294 }
00295 
00296 
00297 //_____________________________________________________________________________
00298 Double_t RooNumRunningInt::evaluate() const 
00299 {
00300   // Dummy function that is never called
00301 
00302   cout << "RooNumRunningInt::evaluate(" << GetName() << ")" << endl ;
00303   return 0 ;
00304 }
00305 
00306 

Generated on Tue Jul 5 15:06:53 2011 for ROOT_528-00b_version by  doxygen 1.5.1