RooGenProdProj.cxx

Go to the documentation of this file.
00001 /*****************************************************************************
00002  * Project: RooFit                                                           *
00003  * Package: RooFitCore                                                       *
00004  * @(#)root/roofitcore:$Id: RooGenProdProj.cxx 34064 2010-06-22 15:05:19Z 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 //
00021 // RooGenProdProj is an auxiliary class for RooProdPdf that calculates
00022 // a general normalized projection of a product of non-factorizing PDFs, e.g.
00023 //
00024 //            Int ( P1 * P2 * ....) dx
00025 //  P_x_xy = -------------------------------
00026 //            Int (P1 * P2 * ... ) dx dy
00027 //
00028 // Partial integrals that factorize that can be calculated are calculated
00029 // analytically. Remaining non-factorizing observables are integrated numerically.
00030 // END_HTML
00031 //
00032 
00033 
00034 #include "RooFit.h"
00035 
00036 #include "Riostream.h"
00037 #include "Riostream.h"
00038 #include <math.h>
00039 
00040 #include "RooGenProdProj.h"
00041 #include "RooAbsReal.h"
00042 #include "RooAbsPdf.h"
00043 #include "RooErrorHandler.h"
00044 #include "RooProduct.h"
00045 
00046 ClassImp(RooGenProdProj)
00047 ;
00048 
00049 
00050 //_____________________________________________________________________________
00051 RooGenProdProj::RooGenProdProj()
00052 {
00053   // Default constructor
00054 }
00055 
00056 
00057 //_____________________________________________________________________________
00058 RooGenProdProj::RooGenProdProj(const char *name, const char *title, const RooArgSet& _prodSet, const RooArgSet& _intSet, 
00059                                const RooArgSet& _normSet, const char* isetRangeName, const char* normRangeName, Bool_t doFactorize) :
00060   RooAbsReal(name, title),
00061   _compSetOwnedN(0), 
00062   _compSetOwnedD(0),
00063   _compSetN("compSetN","Set of integral components owned by numerator",this,kFALSE),
00064   _compSetD("compSetD","Set of integral components owned by denominator",this,kFALSE),
00065   _intList("intList","List of integrals",this,kTRUE),
00066   _haveD(kFALSE)
00067 {
00068   // Constructor for a normalization projection of the product of p.d.f.s _prodSet
00069   // integrated over _intSet in range isetRangeName while normalized over _normSet
00070 
00071   // Create owners of components created in ctor
00072   _compSetOwnedN = new RooArgSet ;
00073   _compSetOwnedD = new RooArgSet ;
00074 
00075   RooAbsReal* numerator = makeIntegral("numerator",_prodSet,_intSet,*_compSetOwnedN,isetRangeName,doFactorize) ;
00076   RooAbsReal* denominator = makeIntegral("denominator",_prodSet,_normSet,*_compSetOwnedD,normRangeName,doFactorize) ;
00077 
00078 //   cout << "RooGenProdPdf::ctor(" << GetName() << ") numerator = " << numerator->GetName() << endl ;
00079 //   numerator->printComponentTree() ;
00080 //   cout << "RooGenProdPdf::ctor(" << GetName() << ") denominator = " << denominator->GetName() << endl ;
00081 //   denominator->printComponentTree() ;
00082 
00083   // Copy all components in (non-owning) set proxy
00084   _compSetN.add(*_compSetOwnedN) ;
00085   _compSetD.add(*_compSetOwnedD) ;
00086   
00087   _intList.add(*numerator) ;
00088   if (denominator) {
00089     _intList.add(*denominator) ;
00090     _haveD = kTRUE ;
00091   }
00092 }
00093 
00094 
00095 
00096 //_____________________________________________________________________________
00097 RooGenProdProj::RooGenProdProj(const RooGenProdProj& other, const char* name) :
00098   RooAbsReal(other, name), 
00099   _compSetOwnedN(0), 
00100   _compSetOwnedD(0),
00101   _compSetN("compSetN","Set of integral components owned by numerator",this),
00102   _compSetD("compSetD","Set of integral components owned by denominator",this),
00103   _intList("intList","List of integrals",this)
00104 {
00105   // Copy constructor
00106 
00107   // Explicitly remove all server links at this point
00108   TIterator* iter = serverIterator() ;
00109   RooAbsArg* server ;
00110   while((server=(RooAbsArg*)iter->Next())) {
00111     removeServer(*server,kTRUE) ;
00112   }
00113   delete iter ;
00114 
00115   // Copy constructor
00116   _compSetOwnedN = (RooArgSet*) other._compSetN.snapshot() ;
00117   _compSetN.add(*_compSetOwnedN) ;
00118 
00119   _compSetOwnedD = (RooArgSet*) other._compSetD.snapshot() ;
00120   _compSetD.add(*_compSetOwnedD) ;
00121 
00122   RooAbsArg* arg ;
00123   TIterator* nIter = _compSetOwnedN->createIterator() ;  
00124   while((arg=(RooAbsArg*)nIter->Next())) {
00125 //     cout << "ownedN elem " << arg->GetName() << "(" << arg << ")" << endl ;
00126     arg->setOperMode(_operMode) ;
00127   }
00128   delete nIter ;
00129   TIterator* dIter = _compSetOwnedD->createIterator() ;
00130   while((arg=(RooAbsArg*)dIter->Next())) {
00131 //     cout << "ownedD elem " << arg->GetName() << "(" << arg << ")" << endl ;
00132     arg->setOperMode(_operMode) ;
00133   }
00134   delete dIter ;
00135 
00136   // Fill _intList
00137   _haveD = other._haveD ;
00138   _intList.add(*_compSetN.find(other._intList.at(0)->GetName())) ;
00139   if (other._haveD) {
00140     _intList.add(*_compSetD.find(other._intList.at(1)->GetName())) ;
00141   }
00142 }
00143 
00144 
00145 
00146 //_____________________________________________________________________________
00147 RooGenProdProj::~RooGenProdProj()
00148 {
00149   // Destructor
00150 
00151   if (_compSetOwnedN) delete _compSetOwnedN ;
00152   if (_compSetOwnedD) delete _compSetOwnedD ;
00153 }
00154 
00155 
00156 
00157 //_____________________________________________________________________________
00158 RooAbsReal* RooGenProdProj::makeIntegral(const char* name, const RooArgSet& compSet, const RooArgSet& intSet, 
00159                                          RooArgSet& saveSet, const char* isetRangeName, Bool_t doFactorize) 
00160 {
00161   // Utility function to create integral over observables intSet in range isetRangeName over product of p.d.fs in compSet.
00162   // The integration is factorized into components as much as possible and done analytically as far as possible.
00163   // All component object needed to represent product integral are added as owned members to saveSet.
00164   // The return value is a RooAbsReal object representing the requested integral
00165 
00166   RooArgSet anaIntSet, numIntSet ;
00167 
00168   // First determine subset of observables in intSet that are factorizable
00169   TIterator* compIter = compSet.createIterator() ;
00170   TIterator* intIter = intSet.createIterator() ;
00171   RooAbsPdf* pdf ;
00172   RooAbsArg* arg ;
00173   while((arg=(RooAbsArg*)intIter->Next())) {
00174     Int_t count(0) ;
00175     compIter->Reset() ;
00176     while((pdf=(RooAbsPdf*)compIter->Next())) {
00177       if (pdf->dependsOn(*arg)) count++ ;
00178     }
00179 
00180     if (count==0) {
00181     } else if (count==1) {
00182       anaIntSet.add(*arg) ;
00183     } else {
00184     }    
00185   }
00186 
00187   // Determine which of the factorizable integrals can be done analytically
00188   RooArgSet prodSet ;
00189   numIntSet.add(intSet) ;
00190   
00191   compIter->Reset() ;
00192   while((pdf=(RooAbsPdf*)compIter->Next())) {
00193     if (doFactorize && pdf->dependsOn(anaIntSet)) {
00194       RooArgSet anaSet ;
00195       Int_t code = pdf->getAnalyticalIntegralWN(anaIntSet,anaSet,0,isetRangeName) ;
00196       if (code!=0) {
00197         // Analytical integral, create integral object
00198         RooAbsReal* pai = pdf->createIntegral(anaSet,isetRangeName) ;
00199         pai->setOperMode(_operMode) ;
00200         
00201         // Add to integral to product
00202         prodSet.add(*pai) ;
00203         
00204         // Remove analytically integratable observables from numeric integration list
00205         numIntSet.remove(anaSet) ;
00206         
00207         // Declare ownership of integral
00208         saveSet.addOwned(*pai) ;
00209       } else {
00210         // Analytic integration of factorizable observable not possible, add straight pdf to product
00211         prodSet.add(*pdf) ;
00212       }      
00213     } else {
00214       // Non-factorizable observables, add straight pdf to product
00215       prodSet.add(*pdf) ;
00216     }
00217   }
00218 
00219   //cout << "RooGenProdProj::makeIntegral(" << GetName() << ") prodset = " << prodSet << endl ;
00220 
00221   // Create product of (partial) analytical integrals
00222   TString prodName ;
00223   if (isetRangeName) {
00224     prodName = Form("%s_%s_Range[%s]",GetName(),name,isetRangeName) ;
00225   } else {
00226     prodName = Form("%s_%s",GetName(),name) ;
00227   }
00228   RooProduct* prod = new RooProduct(prodName,"product",prodSet) ;
00229   prod->setOperMode(_operMode) ;
00230 
00231   // Declare owndership of product
00232   saveSet.addOwned(*prod) ;
00233 
00234   // Create integral performing remaining numeric integration over (partial) analytic product
00235   RooAbsReal* ret = prod->createIntegral(numIntSet,isetRangeName) ;
00236 //   cout << "verbose print of integral object" << endl ;
00237 //   ret->Print("v") ;
00238   ret->setOperMode(_operMode) ;
00239   saveSet.addOwned(*ret) ;
00240 
00241   delete compIter ;
00242   delete intIter ;
00243 
00244   // Caller owners returned master integral object
00245   return ret ;
00246 }
00247 
00248 
00249 
00250 //_____________________________________________________________________________
00251 Double_t RooGenProdProj::evaluate() const 
00252 {  
00253   // Calculate and return value of normalization projection
00254 
00255   Double_t nom = ((RooAbsReal*)_intList.at(0))->getVal() ;
00256 
00257   if (!_haveD) return nom ;
00258 
00259   Double_t den = ((RooAbsReal*)_intList.at(1))->getVal() ;
00260 
00261   //cout << "RooGenProdProj::eval(" << GetName() << ") nom = " << nom << " den = " << den << endl ;
00262 
00263   return nom / den ;
00264 }
00265 
00266 
00267 
00268 //_____________________________________________________________________________
00269 void RooGenProdProj::operModeHook() 
00270 {
00271   // Intercept cache mode operation changes and propagate them to the components
00272 
00273   // WVE use cache manager here!
00274 
00275   RooAbsArg* arg ;
00276   TIterator* nIter = _compSetOwnedN->createIterator() ;  
00277   while((arg=(RooAbsArg*)nIter->Next())) {
00278     arg->setOperMode(_operMode) ;
00279   }
00280   delete nIter ;
00281 
00282   TIterator* dIter = _compSetOwnedD->createIterator() ;
00283   while((arg=(RooAbsArg*)dIter->Next())) {
00284     arg->setOperMode(_operMode) ;
00285   }
00286   delete dIter ;
00287 
00288   _intList.at(0)->setOperMode(_operMode) ;
00289   if (_haveD) _intList.at(1)->setOperMode(Auto) ; // Denominator always stays in Auto mode (normalization integral)
00290 }
00291 
00292 
00293 
00294 
00295 
00296 
00297 

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