RooProdGenContext.cxx

Go to the documentation of this file.
00001 /*****************************************************************************
00002  * Project: RooFit                                                           *
00003  * Package: RooFitCore                                                       *
00004  * @(#)root/roofitcore:$Id: RooProdGenContext.cxx 36222 2010-10-09 18:27:06Z 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 // RooProdGenContext is an efficient implementation of the generator context
00021 // specific for RooProdPdf PDFs. The sim-context owns a list of
00022 // component generator contexts that are used to generate the dependents
00023 // for each component PDF sequentially. 
00024 // END_HTML
00025 //
00026 
00027 #include "RooFit.h"
00028 #include "Riostream.h"
00029 #include "RooMsgService.h"
00030 
00031 #include "RooProdGenContext.h"
00032 #include "RooProdGenContext.h"
00033 #include "RooProdPdf.h"
00034 #include "RooDataSet.h"
00035 #include "RooRealVar.h"
00036 #include "RooGlobalFunc.h"
00037 
00038 
00039 
00040 ClassImp(RooProdGenContext)
00041 ;
00042   
00043 
00044 //_____________________________________________________________________________
00045 RooProdGenContext::RooProdGenContext(const RooProdPdf &model, const RooArgSet &vars, 
00046                                      const RooDataSet *prototype, const RooArgSet* auxProto, Bool_t verbose) :
00047   RooAbsGenContext(model,vars,prototype,auxProto,verbose), _uniIter(0), _pdf(&model)
00048 {
00049 
00050   // Constructor of optimization generator context for RooProdPdf objects
00051 
00052   //Build an array of generator contexts for each product component PDF
00053   cxcoutI(Generation) << "RooProdGenContext::ctor() setting up event special generator context for product p.d.f. " << model.GetName() 
00054                         << " for generation of observable(s) " << vars ;
00055   if (prototype) ccxcoutI(Generation) << " with prototype data for " << *prototype->get() ;
00056   if (auxProto && auxProto->getSize()>0)  ccxcoutI(Generation) << " with auxiliary prototypes " << *auxProto ;
00057   ccxcoutI(Generation) << endl ;
00058 
00059   // Make full list of dependents (generated & proto)
00060   RooArgSet deps(vars) ;
00061   if (prototype) {
00062     RooArgSet* protoDeps = model.getObservables(*prototype->get()) ;
00063     deps.remove(*protoDeps,kTRUE,kTRUE) ;
00064     delete protoDeps ;
00065   }
00066 
00067   // Factorize product in irreducible terms
00068   RooLinkedList termList,depsList,impDepList,crossDepList,intList ;
00069   model.factorizeProduct(deps,RooArgSet(),termList,depsList,impDepList,crossDepList,intList) ;
00070   TIterator* termIter = termList.MakeIterator() ;
00071   TIterator* normIter = depsList.MakeIterator() ;
00072   TIterator* impIter = impDepList.MakeIterator() ;
00073   
00074   if (dologD(Generation)) {
00075     cxcoutD(Generation) << "RooProdGenContext::ctor() factorizing product expression in irriducible terms " ;    
00076     while(RooArgSet* t=(RooArgSet*)termIter->Next()) {
00077       ccxcoutD(Generation) << *t ;
00078     }
00079     ccxcoutD(Generation) << endl ;
00080   }
00081 
00082   RooArgSet genDeps ;
00083   // First add terms that do not import observables
00084   
00085   Bool_t anyAction = kTRUE ;
00086   Bool_t go=kTRUE ; 
00087   while(go) {
00088 
00089     RooAbsPdf* pdf ;
00090     RooArgSet* term ;
00091     RooArgSet* impDeps ;
00092     RooArgSet* termDeps ;
00093 
00094     termIter->Reset() ;
00095     impIter->Reset() ;
00096     normIter->Reset() ;
00097 
00098     Bool_t anyPrevAction=anyAction ;
00099     anyAction=kFALSE ;
00100 
00101     if (termList.GetSize()==0) {
00102       break ;
00103     }
00104 
00105     while((term=(RooArgSet*)termIter->Next())) {
00106 
00107       impDeps = (RooArgSet*)impIter->Next() ;
00108       termDeps = (RooArgSet*)normIter->Next() ;
00109       if (impDeps==0 || termDeps==0) {
00110         break ;
00111       }
00112 
00113       cxcoutD(Generation) << "RooProdGenContext::ctor() analyzing product term " << *term << " with observable(s) " << *termDeps ;
00114       if (impDeps->getSize()>0) {
00115         ccxcoutD(Generation) << " which has dependence of external observable(s) " << *impDeps << " that to be generated first by other terms" ;
00116       }
00117       ccxcoutD(Generation) << endl ;
00118 
00119       // Add this term if we have no imported dependents, or imported dependents are already generated
00120       RooArgSet neededDeps(*impDeps) ;
00121       neededDeps.remove(genDeps,kTRUE,kTRUE) ;
00122 
00123       if (neededDeps.getSize()>0) {
00124         if (!anyPrevAction) {
00125           cxcoutD(Generation) << "RooProdGenContext::ctor() no convergence in single term analysis loop, terminating loop and process remainder of terms as single unit " << endl ;
00126           go=kFALSE ;
00127           break ;
00128         }
00129         cxcoutD(Generation) << "RooProdGenContext::ctor() skipping this term for now because it needs imported dependents that are not generated yet" << endl ; 
00130         continue ;
00131       }
00132 
00133       // Check if this component has any dependents that need to be generated
00134       // e.g. it can happen that there are none if all dependents of this component are prototyped
00135       if (termDeps->getSize()==0) {
00136         cxcoutD(Generation) << "RooProdGenContext::ctor() term has no observables requested to be generated, removing it" << endl ;
00137         termList.Remove(term) ;
00138         depsList.Remove(termDeps) ;
00139         impDepList.Remove(impDeps) ;
00140         delete term ;
00141         delete termDeps ;
00142         delete impDeps ;
00143         anyAction=kTRUE ;
00144         continue ;
00145       }
00146 
00147       TIterator* pdfIter = term->createIterator() ;      
00148       if (term->getSize()==1) {
00149         // Simple term
00150         
00151         pdf = (RooAbsPdf*) pdfIter->Next() ;
00152         RooArgSet* pdfDep = pdf->getObservables(termDeps) ;
00153         if (pdfDep->getSize()>0) {
00154           coutI(Generation) << "RooProdGenContext::ctor() creating subcontext for generation of observables " << *pdfDep << " from model " << pdf->GetName() << endl ;
00155           RooArgSet* auxProto2 = pdf->getObservables(impDeps) ;
00156           RooAbsGenContext* cx = pdf->genContext(*pdfDep,prototype,auxProto2,verbose) ;
00157           delete auxProto2 ;
00158           _gcList.Add(cx) ;
00159         } 
00160 
00161 //      cout << "adding following dependents to list of generated observables: " ; pdfDep->Print("1") ;
00162         genDeps.add(*pdfDep) ;
00163 
00164         delete pdfDep ;
00165         
00166       } else {
00167         
00168         // Composite term
00169         if (termDeps->getSize()>0) {
00170           const char* name = model.makeRGPPName("PRODGEN_",*term,RooArgSet(),RooArgSet(),0) ;      
00171           
00172           // Construct auxiliary PDF expressing product of composite terms, 
00173           // following Conditional component specification of input model
00174           RooLinkedList cmdList ;
00175           RooLinkedList pdfSetList ;
00176           pdfIter->Reset() ;
00177           RooArgSet fullPdfSet ;
00178           while((pdf=(RooAbsPdf*)pdfIter->Next())) {
00179 
00180             RooArgSet* pdfnset = model.findPdfNSet(*pdf) ;
00181             RooArgSet* pdfSet = new RooArgSet(*pdf) ;
00182             pdfSetList.Add(pdfSet) ;
00183 
00184             if (pdfnset && pdfnset->getSize()>0) {
00185               // This PDF requires a Conditional() construction
00186               cmdList.Add(RooFit::Conditional(*pdfSet,*pdfnset).Clone()) ;
00187 //            cout << "Conditional " << pdf->GetName() << " " ; pdfnset->Print("1") ;
00188             } else {
00189               fullPdfSet.add(*pdfSet) ;
00190             }
00191             
00192           }
00193           RooProdPdf* multiPdf = new RooProdPdf(name,name,fullPdfSet,cmdList) ;
00194           cmdList.Delete() ;
00195           pdfSetList.Delete() ;
00196 
00197           multiPdf->useDefaultGen(kTRUE) ;
00198           _ownedMultiProds.addOwned(*multiPdf) ;
00199           
00200           coutI(Generation) << "RooProdGenContext()::ctor creating subcontext for generation of observables " << *termDeps 
00201                               << "for irriducuble composite term using sub-product object " << multiPdf->GetName() ;
00202           RooAbsGenContext* cx = multiPdf->genContext(*termDeps,prototype,auxProto,verbose) ;
00203           _gcList.Add(cx) ;
00204 
00205           genDeps.add(*termDeps) ;
00206 
00207         }
00208       }
00209       
00210       delete pdfIter ;
00211 
00212 //        cout << "added generator for this term, removing from list" << endl ;
00213 
00214       termList.Remove(term) ;
00215       depsList.Remove(termDeps) ;
00216       impDepList.Remove(impDeps) ;
00217       delete term ;
00218       delete termDeps ;
00219       delete impDeps ;
00220       anyAction=kTRUE ;
00221     }
00222   }
00223 
00224   // Check if there are any left over terms that cannot be generated 
00225   // separately due to cross dependency of observables
00226   if (termList.GetSize()>0) {
00227 
00228     cxcoutD(Generation) << "RooProdGenContext::ctor() there are left-over terms that need to be generated separately" << endl ;
00229  
00230     RooAbsPdf* pdf ;
00231     RooArgSet* term ;
00232 
00233     // Concatenate remaining terms
00234     termIter->Reset() ;
00235     normIter->Reset() ;
00236     RooArgSet trailerTerm ;
00237     RooArgSet trailerTermDeps ;
00238     while((term=(RooArgSet*)termIter->Next())) {
00239       RooArgSet* termDeps = (RooArgSet*)normIter->Next() ;
00240       trailerTerm.add(*term) ;
00241       trailerTermDeps.add(*termDeps) ;
00242     }
00243 
00244     const char* name = model.makeRGPPName("PRODGEN_",trailerTerm,RooArgSet(),RooArgSet(),0) ;      
00245       
00246     // Construct auxiliary PDF expressing product of composite terms, 
00247     // following Partial/Full component specification of input model
00248     RooLinkedList cmdList ;
00249     RooLinkedList pdfSetList ;
00250     RooArgSet fullPdfSet ;
00251 
00252     TIterator* pdfIter = trailerTerm.createIterator() ;
00253     while((pdf=(RooAbsPdf*)pdfIter->Next())) {
00254         
00255       RooArgSet* pdfnset = model.findPdfNSet(*pdf) ;
00256       RooArgSet* pdfSet = new RooArgSet(*pdf) ;
00257       pdfSetList.Add(pdfSet) ;
00258       
00259       if (pdfnset && pdfnset->getSize()>0) {
00260         // This PDF requires a Conditional() construction
00261           cmdList.Add(RooFit::Conditional(*pdfSet,*pdfnset).Clone()) ;
00262       } else {
00263         fullPdfSet.add(*pdfSet) ;
00264       }
00265       
00266     }
00267 //     cmdList.Print("v") ;
00268     RooProdPdf* multiPdf = new RooProdPdf(name,name,fullPdfSet,cmdList) ;
00269     cmdList.Delete() ;
00270     pdfSetList.Delete() ;
00271     
00272     multiPdf->useDefaultGen(kTRUE) ;
00273     _ownedMultiProds.addOwned(*multiPdf) ;
00274     
00275     cxcoutD(Generation) << "RooProdGenContext(" << model.GetName() << "): creating context for irreducible composite trailer term " 
00276          << multiPdf->GetName() << " that generates observables " << trailerTermDeps << endl ;
00277     RooAbsGenContext* cx = multiPdf->genContext(trailerTermDeps,prototype,auxProto,verbose) ;
00278     _gcList.Add(cx) ;    
00279   }
00280 
00281   // Now check if the are observables in vars that are not generated by any of the above p.d.f.s
00282   // If not, generate uniform distributions for these using a special context
00283   _uniObs.add(vars) ;
00284   _uniObs.remove(genDeps,kTRUE,kTRUE) ;
00285   if (_uniObs.getSize()>0) {
00286     _uniIter = _uniObs.createIterator() ;
00287     coutI(Generation) << "RooProdGenContext(" << model.GetName() << "): generating uniform distribution for non-dependent observable(s) " << _uniObs << endl ;
00288   }
00289 
00290 
00291   delete termIter ;
00292   delete impIter ;
00293   delete normIter ;
00294 
00295   _gcIter = _gcList.MakeIterator() ;
00296 
00297 
00298   // We own contents of lists filled by factorizeProduct() 
00299   termList.Delete() ;
00300   depsList.Delete() ;
00301   impDepList.Delete() ;
00302   crossDepList.Delete() ;
00303   intList.Delete() ;
00304 
00305 }
00306 
00307 
00308 
00309 //_____________________________________________________________________________
00310 RooProdGenContext::~RooProdGenContext()
00311 {
00312   // Destructor. Delete all owned subgenerator contexts
00313 
00314   delete _gcIter ;
00315   delete _uniIter ;
00316   _gcList.Delete() ;  
00317 }
00318 
00319 
00320 //_____________________________________________________________________________
00321 void RooProdGenContext::attach(const RooArgSet& args) 
00322 {
00323   // Attach generator to given event buffer
00324 
00325   //Forward initGenerator call to all components
00326   RooAbsGenContext* gc ;
00327   _gcIter->Reset() ;
00328   while((gc=(RooAbsGenContext*)_gcIter->Next())){
00329     gc->attach(args) ;
00330   }
00331 }
00332 
00333 
00334 //_____________________________________________________________________________
00335 void RooProdGenContext::initGenerator(const RooArgSet &theEvent)
00336 {
00337   // One-time initialization of generator context, forward to component generators
00338 
00339   // Forward initGenerator call to all components
00340   RooAbsGenContext* gc ;
00341   _gcIter->Reset() ;
00342   while((gc=(RooAbsGenContext*)_gcIter->Next())){
00343     gc->initGenerator(theEvent) ;
00344   }
00345 }
00346 
00347 
00348 
00349 //_____________________________________________________________________________
00350 void RooProdGenContext::generateEvent(RooArgSet &theEvent, Int_t remaining)
00351 {
00352   // Generate a single event of the product by generating the components
00353   // of the products sequentially. The subcontext have been order such
00354   // that all conditional dependencies are correctly taken into account
00355   // when processed in sequential order
00356 
00357   // Loop over the component generators
00358   TList compData ;
00359   RooAbsGenContext* gc ;
00360   _gcIter->Reset() ;
00361 
00362   while((gc=(RooAbsGenContext*)_gcIter->Next())) {
00363 
00364     // Generate component 
00365     gc->generateEvent(theEvent,remaining) ;
00366   }
00367 
00368   // Generate uniform variables (non-dependents)  
00369   if (_uniIter) {
00370     _uniIter->Reset() ;
00371     RooAbsArg* uniVar ;
00372     while((uniVar=(RooAbsArg*)_uniIter->Next())) {
00373       RooAbsLValue* arglv = dynamic_cast<RooAbsLValue*>(uniVar) ;
00374       if (arglv) {
00375         arglv->randomize() ;
00376       }
00377     }
00378     theEvent = _uniObs ;
00379   }  
00380 
00381 }
00382 
00383 
00384 
00385 //_____________________________________________________________________________
00386 void RooProdGenContext::setProtoDataOrder(Int_t* lut)
00387 {
00388   // Set the traversal order of the prototype dataset by the
00389   // given lookup table
00390 
00391   // Forward call to component generators
00392   RooAbsGenContext::setProtoDataOrder(lut) ;
00393   _gcIter->Reset() ;
00394   RooAbsGenContext* gc ;
00395   while((gc=(RooAbsGenContext*)_gcIter->Next())) {
00396     gc->setProtoDataOrder(lut) ;
00397   }
00398 }
00399 
00400 
00401 
00402 //_____________________________________________________________________________
00403 void RooProdGenContext::printMultiline(ostream &os, Int_t content, Bool_t verbose, TString indent) const 
00404 {
00405   // Detailed printing interface
00406 
00407   RooAbsGenContext::printMultiline(os,content,verbose,indent) ;
00408   os << indent << "--- RooProdGenContext ---" << endl ;
00409   os << indent << "Using PDF ";
00410   _pdf->printStream(os,kName|kArgs|kClassName,kSingleLine,indent);
00411   os << indent << "List of component generators" << endl ;
00412 
00413   TString indent2(indent) ;
00414   indent2.Append("    ") ;
00415   RooAbsGenContext* gc ;
00416   _gcIter->Reset() ;
00417   while((gc=(RooAbsGenContext*)_gcIter->Next())) {
00418     gc->printMultiline(os,content,verbose,indent2) ;
00419   }  
00420 }

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