RooHistFunc.cxx

Go to the documentation of this file.
00001 /*****************************************************************************
00002  * Project: RooFit                                                           *
00003  * Package: RooFitCore                                                       *
00004  * @(#)root/roofit:$Id: RooHistFunc.cxx 25209 2008-08-22 13:08:40Z wouter $
00005  * Authors:                                                                  *
00006  *   WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu       *
00007  *   DK, David Kirkby,    UC Irvine,         dkirkby@uci.edu                 *
00008  *                                                                           *
00009  * Copyright (c) 2000-2005, Regents of the University of California          *
00010  *                          and Stanford University. All rights reserved.    *
00011  *                                                                           *
00012  * Redistribution and use in source and binary forms,                        *
00013  * with or without modification, are permitted according to the terms        *
00014  * listed in LICENSE (http://roofit.sourceforge.net/license.txt)             *
00015  *****************************************************************************/
00016 
00017 //////////////////////////////////////////////////////////////////////////////
00018 //
00019 // BEGIN_HTML
00020 // RooHistFunc implements a real-valued function sampled from a 
00021 // multidimensional histogram. The histogram can have an arbitrary number of real or 
00022 // discrete dimensions and may have negative values
00023 // END_HTML
00024 //
00025 
00026 #include "RooFit.h"
00027 #include "Riostream.h"
00028 
00029 #include "RooHistFunc.h"
00030 #include "RooDataHist.h"
00031 #include "RooMsgService.h"
00032 #include "RooRealVar.h"
00033 #include "RooCategory.h"
00034 
00035 
00036 
00037 ClassImp(RooHistFunc)
00038 ;
00039 
00040 
00041 
00042 //_____________________________________________________________________________
00043 RooHistFunc::RooHistFunc() : _dataHist(0), _totVolume(0)
00044 {
00045   // Default constructor
00046 }
00047 
00048 
00049 //_____________________________________________________________________________
00050 RooHistFunc::RooHistFunc(const char *name, const char *title, const RooArgSet& vars, 
00051                        const RooDataHist& dhist, Int_t intOrder) :
00052   RooAbsReal(name,title), 
00053   _depList("depList","List of dependents",this),
00054   _dataHist((RooDataHist*)&dhist), 
00055   _codeReg(10),
00056   _intOrder(intOrder),
00057   _cdfBoundaries(kFALSE),
00058   _totVolume(0),
00059   _unitNorm(kFALSE)
00060 {
00061   // Constructor from a RooDataHist. The variable listed in 'vars' control the dimensionality of the
00062   // function. Any additional dimensions present in 'dhist' will be projected out. RooDataHist dimensions
00063   // can be either real or discrete. See RooDataHist::RooDataHist for details on the binning.
00064   // RooHistFunc neither owns or clone 'dhist' and the user must ensure the input histogram exists
00065   // for the entire life span of this function.
00066 
00067   _depList.add(vars) ;
00068 
00069   // Verify that vars and dhist.get() have identical contents
00070   const RooArgSet* dvars = dhist.get() ;
00071   if (vars.getSize()!=dvars->getSize()) {
00072     coutE(InputArguments) << "RooHistFunc::ctor(" << GetName() 
00073                           << ") ERROR variable list and RooDataHist must contain the same variables." << endl ;
00074     assert(0) ;
00075   }
00076   TIterator* iter = vars.createIterator() ;
00077   RooAbsArg* arg ;
00078   while((arg=(RooAbsArg*)iter->Next())) {
00079     if (!dvars->find(arg->GetName())) {
00080       coutE(InputArguments) << "RooHistFunc::ctor(" << GetName() 
00081                             << ") ERROR variable list and RooDataHist must contain the same variables." << endl ;
00082       assert(0) ;
00083     }
00084   }
00085   delete iter ;
00086 }
00087 
00088 
00089 
00090 //_____________________________________________________________________________
00091 RooHistFunc::RooHistFunc(const RooHistFunc& other, const char* name) :
00092   RooAbsReal(other,name), 
00093   _depList("depList",this,other._depList),
00094   _dataHist(other._dataHist),
00095   _codeReg(other._codeReg),
00096   _intOrder(other._intOrder),
00097   _cdfBoundaries(other._cdfBoundaries),
00098   _totVolume(other._totVolume),
00099   _unitNorm(other._unitNorm)
00100 {
00101   // Copy constructor
00102 }
00103 
00104 
00105 
00106 //_____________________________________________________________________________
00107 Double_t RooHistFunc::evaluate() const
00108 {
00109   // Return the current value: The value of the bin enclosing the current coordinates
00110   // of the dependents, normalized by the histograms contents. Interpolation
00111   // is applied if the RooHistFunc is configured to do that
00112 
00113   Double_t ret =  _dataHist->weight(_depList,_intOrder,kFALSE,_cdfBoundaries) ;  
00114   return ret ;
00115 }
00116 
00117 
00118 //_____________________________________________________________________________
00119 Double_t RooHistFunc::totVolume() const
00120 {
00121   // Return the total volume spanned by the observables of the RooDataHist
00122 
00123   // Return previously calculated value, if any
00124   if (_totVolume>0) {
00125     return _totVolume ;
00126   }
00127   _totVolume = 1. ;
00128   TIterator* iter = _depList.createIterator() ;
00129   RooAbsArg* arg ;
00130   while((arg=(RooAbsArg*)iter->Next())) {
00131     RooRealVar* real = dynamic_cast<RooRealVar*>(arg) ;
00132     if (real) {
00133       _totVolume *= (real->getMax()-real->getMin()) ;
00134     } else {
00135       RooCategory* cat = dynamic_cast<RooCategory*>(arg) ;
00136       if (cat) {
00137         _totVolume *= cat->numTypes() ;
00138       }
00139     }
00140   }
00141   delete iter ;
00142   return _totVolume ;
00143 }
00144 
00145 
00146 
00147 //_____________________________________________________________________________
00148 Int_t RooHistFunc::getAnalyticalIntegral(RooArgSet& allVars, RooArgSet& analVars, const char* rangeName) const 
00149 {
00150   // Determine integration scenario. If no interpolation is used,
00151   // RooHistFunc can perform all integrals over its dependents
00152   // analytically via partial or complete summation of the input
00153   // histogram. If interpolation is used, only the integral
00154   // over all RooHistPdf observables is implemented.
00155 
00156 
00157   // Only analytical integrals over the full range are defined
00158   if (rangeName!=0) {
00159     return 0 ;
00160   }
00161 
00162   // Simplest scenario, integrate over all dependents
00163   RooAbsCollection *allVarsCommon = allVars.selectCommon(_depList) ;  
00164   Bool_t intAllObs = (allVarsCommon->getSize()==_depList.getSize()) ;
00165   if (intAllObs && matchArgs(allVars,analVars,_depList)) {
00166     return 1000 ;
00167   }
00168 
00169   // Disable partial analytical integrals if interpolation is used
00170   if (_intOrder>0) {
00171     return 0 ;
00172   }
00173 
00174   // Find subset of _depList that integration is requested over
00175   RooArgSet* allVarsSel = (RooArgSet*) allVars.selectCommon(_depList) ;
00176   if (allVarsSel->getSize()==0) {
00177     delete allVarsSel ;
00178     return 0 ;
00179   }
00180 
00181   // Partial integration scenarios.
00182   // Build unique code from bit mask of integrated variables in depList
00183   Int_t code(0),n(0) ;
00184   TIterator* iter = _depList.createIterator() ;
00185   RooAbsArg* arg ;
00186   while((arg=(RooAbsArg*)iter->Next())) {
00187     if (allVars.find(arg->GetName())) code |= (1<<n) ;
00188     n++ ;
00189   }
00190   delete iter ;
00191   analVars.add(*allVarsSel) ;
00192 
00193   return code ;
00194 
00195 }
00196 
00197 
00198 
00199 //_____________________________________________________________________________
00200 Double_t RooHistFunc::analyticalIntegral(Int_t code, const char* /*rangeName*/) const 
00201 {
00202   // Return integral identified by 'code'. The actual integration
00203   // is deferred to RooDataHist::sum() which implements partial
00204   // or complete summation over the histograms contents
00205 
00206   // WVE needs adaptation for rangeName feature
00207 
00208   // Simplest scenario, integration over all dependents
00209   if (code==1000) {
00210     return _dataHist->sum(kTRUE) ;
00211   }
00212 
00213   // Partial integration scenario, retrieve set of variables, calculate partial sum
00214 
00215   RooArgSet intSet ;
00216   TIterator* iter = _depList.createIterator() ;
00217   RooAbsArg* arg ;
00218   Int_t n(0) ;
00219   while((arg=(RooAbsArg*)iter->Next())) {
00220     if (code & (1<<n)) {
00221       intSet.add(*arg) ;
00222     }
00223     n++ ;
00224   }
00225   delete iter ;
00226 
00227   Double_t ret =  _dataHist->sum(intSet,_depList,kTRUE) ;
00228   return ret ;
00229 }
00230 
00231 
00232 
00233 //_____________________________________________________________________________
00234 list<Double_t>* RooHistFunc::plotSamplingHint(RooAbsRealLValue& obs, Double_t xlo, Double_t xhi) const
00235 {
00236   // Return sampling hint for making curves of (projections) of this function
00237   // as the recursive division strategy of RooCurve cannot deal efficiently
00238   // with the vertical lines that occur in a non-interpolated histogram
00239 
00240   // No hints are required when interpolation is used
00241   if (_intOrder>0) {
00242     return 0 ;
00243   }
00244 
00245   // Check that observable is in dataset, if not no hint is generated
00246   RooAbsLValue* lvarg = dynamic_cast<RooAbsLValue*>(_dataHist->get()->find(obs.GetName())) ;
00247   if (!lvarg) {
00248     return 0 ;
00249   }
00250 
00251   // Retrieve position of all bin boundaries
00252   const RooAbsBinning* binning = lvarg->getBinningPtr(0) ;
00253   Double_t* boundaries = binning->array() ;
00254 
00255   list<Double_t>* hint = new list<Double_t> ;
00256 
00257   // Widen range slighty
00258   xlo = xlo - 0.01*(xhi-xlo) ;
00259   xhi = xhi + 0.01*(xhi-xlo) ;
00260 
00261   Double_t delta = (xhi-xlo)*1e-8 ;
00262  
00263   // Construct array with pairs of points positioned epsilon to the left and
00264   // right of the bin boundaries
00265   for (Int_t i=0 ; i<binning->numBoundaries() ; i++) {
00266     if (boundaries[i]>=xlo && boundaries[i]<=xhi) {
00267       hint->push_back(boundaries[i]-delta) ;
00268       hint->push_back(boundaries[i]+delta) ;
00269     }
00270   }
00271 
00272   return hint ;
00273 }
00274 
00275 

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