RooSimGenContext.cxx

Go to the documentation of this file.
00001 /*****************************************************************************
00002  * Project: RooFit                                                           *
00003  * Package: RooFitCore                                                       *
00004  * @(#)root/roofitcore:$Id: RooSimGenContext.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 // RooSimGenContext is an efficient implementation of the generator context
00021 // specific for RooSimultaneous PDFs when generating more than one of the
00022 // component pdfs.
00023 // END_HTML
00024 //
00025 
00026 #include "RooFit.h"
00027 #include "Riostream.h"
00028 
00029 #include "RooSimGenContext.h"
00030 #include "RooSimultaneous.h"
00031 #include "RooRealProxy.h"
00032 #include "RooDataSet.h"
00033 #include "Roo1DTable.h"
00034 #include "RooCategory.h"
00035 #include "RooMsgService.h"
00036 #include "RooRandom.h"
00037 
00038 #include <string>
00039 
00040 ClassImp(RooSimGenContext)
00041 ;
00042   
00043 
00044 //_____________________________________________________________________________
00045 RooSimGenContext::RooSimGenContext(const RooSimultaneous &model, const RooArgSet &vars, 
00046                                    const RooDataSet *prototype, const RooArgSet* auxProto, Bool_t verbose) :
00047   RooAbsGenContext(model,vars,prototype,auxProto,verbose), _pdf(&model)
00048 {
00049   // Constructor of specialized generator context for RooSimultaneous p.d.f.s. This
00050   // context creates a dedicated context for each component p.d.f.s and delegates
00051   // generation of events to the appropriate component generator context
00052 
00053   // Determine if we are requested to generate the index category
00054   RooAbsCategory *idxCat = (RooAbsCategory*) model._indexCat.absArg() ;
00055   RooArgSet pdfVars(vars) ;
00056 
00057   RooArgSet allPdfVars(pdfVars) ;
00058   if (prototype) allPdfVars.add(*prototype->get(),kTRUE) ;
00059 
00060   if (!idxCat->isDerived()) {
00061     pdfVars.remove(*idxCat,kTRUE,kTRUE) ;
00062     Bool_t doGenIdx = allPdfVars.find(idxCat->GetName())?kTRUE:kFALSE ;
00063 
00064     if (!doGenIdx) {
00065       oocoutE(_pdf,Generation) << "RooSimGenContext::ctor(" << GetName() << ") ERROR: This context must"
00066                                << " generate the index category" << endl ;
00067       _isValid = kFALSE ;
00068       _numPdf = 0 ;
00069       _haveIdxProto = kFALSE ;
00070       return ;
00071     }
00072   } else {
00073     TIterator* sIter = idxCat->serverIterator() ;
00074     RooAbsArg* server ;
00075     Bool_t anyServer(kFALSE), allServers(kTRUE) ;
00076     while((server=(RooAbsArg*)sIter->Next())) {
00077       if (vars.find(server->GetName())) {
00078         anyServer=kTRUE ;
00079         pdfVars.remove(*server,kTRUE,kTRUE) ;
00080       } else {
00081         allServers=kFALSE ;
00082       }
00083     }
00084     delete sIter ;    
00085 
00086     if (anyServer && !allServers) {
00087       oocoutE(_pdf,Generation) << "RooSimGenContext::ctor(" << GetName() << ") ERROR: This context must"
00088                                << " generate all components of a derived index category" << endl ;
00089       _isValid = kFALSE ;
00090       _numPdf = 0 ;
00091       _haveIdxProto = kFALSE ;
00092       return ;
00093     }
00094   }
00095 
00096   // We must either have the prototype or extended likelihood to determined
00097   // the relative fractions of the components
00098   _haveIdxProto = prototype ? kTRUE : kFALSE ;
00099   _idxCatName = idxCat->GetName() ;
00100   if (!_haveIdxProto && !model.canBeExtended()) {
00101     oocoutE(_pdf,Generation) << "RooSimGenContext::ctor(" << GetName() << ") ERROR: Need either extended mode"
00102                              << " or prototype data to calculate number of events per category" << endl ;
00103     _isValid = kFALSE ;
00104     _numPdf = 0 ;
00105     return ;
00106   }
00107 
00108   // Initialize fraction threshold array (used only in extended mode)
00109   _numPdf = model._pdfProxyList.GetSize() ;
00110   _fracThresh = new Double_t[_numPdf+1] ;
00111   _fracThresh[0] = 0 ;
00112   
00113   // Generate index category and all registered PDFS
00114   TIterator* iter = model._pdfProxyList.MakeIterator() ;
00115   RooRealProxy* proxy ;
00116   RooAbsPdf* pdf ;
00117   Int_t i(1) ;
00118   while((proxy=(RooRealProxy*)iter->Next())) {
00119     pdf=(RooAbsPdf*)proxy->absArg() ;
00120 
00121     // Create generator context for this PDF
00122     RooAbsGenContext* cx = pdf->genContext(pdfVars,prototype,auxProto,verbose) ;
00123 
00124     // Name the context after the associated state and add to list
00125     cx->SetName(proxy->name()) ;
00126     _gcList.Add(cx) ;
00127 
00128     // Fill fraction threshold array
00129     _fracThresh[i] = _fracThresh[i-1] + (_haveIdxProto?0:pdf->expectedEvents(&allPdfVars)) ;
00130     i++ ;
00131   }   
00132   delete iter ;
00133     
00134   // Normalize fraction threshold array
00135   if (!_haveIdxProto) {
00136     for(i=0 ; i<_numPdf ; i++) 
00137       _fracThresh[i] /= _fracThresh[_numPdf] ;
00138   }
00139   
00140 
00141   // Clone the index category
00142   _idxCatSet = (RooArgSet*) RooArgSet(model._indexCat.arg()).snapshot(kTRUE) ;
00143   if (!_idxCatSet) {
00144     oocoutE(_pdf,Generation) << "RooSimGenContext::RooSimGenContext(" << GetName() << ") Couldn't deep-clone index category, abort," << endl ;
00145     throw std::string("RooSimGenContext::RooSimGenContext() Couldn't deep-clone index category, abort") ;
00146   }
00147   
00148   _idxCat = (RooAbsCategoryLValue*) _idxCatSet->find(model._indexCat.arg().GetName()) ;
00149 }
00150 
00151 
00152 
00153 //_____________________________________________________________________________
00154 RooSimGenContext::~RooSimGenContext()
00155 {
00156   // Destructor. Delete all owned subgenerator contexts
00157 
00158   delete[] _fracThresh ;
00159   delete _idxCatSet ;
00160   _gcList.Delete() ;
00161 }
00162 
00163 
00164 
00165 //_____________________________________________________________________________
00166 void RooSimGenContext::attach(const RooArgSet& args) 
00167 {
00168   // Attach the index category clone to the given event buffer
00169 
00170   if (_idxCat->isDerived()) {
00171     _idxCat->recursiveRedirectServers(args,kTRUE) ;
00172   }
00173 
00174   // Forward initGenerator call to all components
00175   RooAbsGenContext* gc ;
00176   TIterator* iter = _gcList.MakeIterator() ;
00177   while((gc=(RooAbsGenContext*)iter->Next())){
00178     gc->attach(args) ;
00179   }
00180   delete iter;
00181   
00182 }
00183 
00184 
00185 //_____________________________________________________________________________
00186 void RooSimGenContext::initGenerator(const RooArgSet &theEvent)
00187 {
00188   // Perform one-time initialization of generator context
00189 
00190   // Attach the index category clone to the event
00191   if (_idxCat->isDerived()) {
00192     _idxCat->recursiveRedirectServers(theEvent,kTRUE) ;
00193   } else {
00194     _idxCat = (RooAbsCategoryLValue*) theEvent.find(_idxCat->GetName()) ;
00195   }
00196 
00197   // Forward initGenerator call to all components
00198   RooAbsGenContext* gc ;
00199   TIterator* iter = _gcList.MakeIterator() ;
00200   while((gc=(RooAbsGenContext*)iter->Next())){
00201     gc->initGenerator(theEvent) ;
00202   }
00203   delete iter;
00204 
00205 }
00206 
00207 
00208 
00209 //_____________________________________________________________________________
00210 void RooSimGenContext::generateEvent(RooArgSet &theEvent, Int_t remaining)
00211 {
00212   // Generate event appropriate for current index state. 
00213   // The index state is taken either from the prototype
00214   // or is generated from the fraction threshold table.
00215 
00216   if (_haveIdxProto) {
00217 
00218     // Lookup pdf from selected prototype index state
00219     const char* label = _idxCat->getLabel() ;
00220     RooAbsGenContext* cx = (RooAbsGenContext*)_gcList.FindObject(label) ;
00221     if (cx) {      
00222       cx->generateEvent(theEvent,remaining) ;
00223     } else {
00224       oocoutW(_pdf,Generation) << "RooSimGenContext::generateEvent: WARNING, no PDF to generate event of type " << label << endl ;
00225     }    
00226 
00227   
00228   } else {
00229 
00230     // Throw a random number and select PDF from fraction threshold table
00231     Double_t rand = RooRandom::uniform() ;
00232     Int_t i=0 ;
00233     for (i=0 ; i<_numPdf ; i++) {
00234       if (rand>_fracThresh[i] && rand<_fracThresh[i+1]) {
00235         RooAbsGenContext* gen= ((RooAbsGenContext*)_gcList.At(i)) ;
00236         gen->generateEvent(theEvent,remaining) ;
00237         _idxCat->setLabel(gen->GetName()) ;
00238         return ;
00239       }
00240     }
00241 
00242   }
00243 }
00244 
00245 
00246 //_____________________________________________________________________________
00247 void RooSimGenContext::setProtoDataOrder(Int_t* lut)
00248 {
00249   // Set the traversal order of the prototype data to that in the
00250   // given lookup table. This information is passed to all
00251   // component generator contexts
00252 
00253   RooAbsGenContext::setProtoDataOrder(lut) ;
00254 
00255   TIterator* iter = _gcList.MakeIterator() ;
00256   RooAbsGenContext* gc ;
00257   while((gc=(RooAbsGenContext*)iter->Next())) {
00258     gc->setProtoDataOrder(lut) ;
00259   }
00260   delete iter ;
00261 }
00262 
00263 
00264 //_____________________________________________________________________________
00265 void RooSimGenContext::printMultiline(ostream &os, Int_t content, Bool_t verbose, TString indent) const 
00266 {
00267   // Detailed printing interface
00268 
00269   RooAbsGenContext::printMultiline(os,content,verbose,indent) ;
00270   os << indent << "--- RooSimGenContext ---" << endl ;
00271   os << indent << "Using PDF ";
00272   _pdf->printStream(os,kName|kArgs|kClassName,kSingleLine,indent);
00273   os << indent << "List of component generators" << endl ;
00274 
00275   TString indent2(indent) ;
00276   indent2.Append("    ") ;
00277 
00278   TIterator* iter = _gcList.MakeIterator() ;
00279   RooAbsGenContext* gc ;
00280   while((gc=(RooAbsGenContext*)iter->Next())) {
00281     gc->printMultiline(os,content,verbose,indent2);
00282   }
00283   delete iter ;
00284 }

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