// RooSimGenContext is an efficient implementation of the generator context
// specific for RooSimultaneous PDFs when generating more than one of the
// component pdfs.
// END_HTML
#include "RooFit.h"
#include "Riostream.h"
#include "RooSimGenContext.h"
#include "RooSimultaneous.h"
#include "RooRealProxy.h"
#include "RooDataSet.h"
#include "Roo1DTable.h"
#include "RooCategory.h"
#include "RooMsgService.h"
#include "RooRandom.h"
ClassImp(RooSimGenContext)
;
RooSimGenContext::RooSimGenContext(const RooSimultaneous &model, const RooArgSet &vars,
const RooDataSet *prototype, const RooArgSet* auxProto, Bool_t verbose) :
RooAbsGenContext(model,vars,prototype,auxProto,verbose), _pdf(&model)
{
RooAbsCategory *idxCat = (RooAbsCategory*) model._indexCat.absArg() ;
RooArgSet pdfVars(vars) ;
RooArgSet allPdfVars(pdfVars) ;
if (prototype) allPdfVars.add(*prototype->get(),kTRUE) ;
if (!idxCat->isDerived()) {
pdfVars.remove(*idxCat,kTRUE,kTRUE) ;
Bool_t doGenIdx = allPdfVars.find(idxCat->GetName())?kTRUE:kFALSE ;
if (!doGenIdx) {
oocoutE(_pdf,Generation) << "RooSimGenContext::ctor(" << GetName() << ") ERROR: This context must"
<< " generate the index category" << endl ;
_isValid = kFALSE ;
return ;
}
} else {
TIterator* sIter = idxCat->serverIterator() ;
RooAbsArg* server ;
Bool_t anyServer(kFALSE), allServers(kTRUE) ;
while((server=(RooAbsArg*)sIter->Next())) {
if (vars.find(server->GetName())) {
anyServer=kTRUE ;
pdfVars.remove(*server,kTRUE,kTRUE) ;
} else {
allServers=kFALSE ;
}
}
delete sIter ;
if (anyServer && !allServers) {
oocoutE(_pdf,Generation) << "RooSimGenContext::ctor(" << GetName() << ") ERROR: This context must"
<< " generate all components of a derived index category" << endl ;
_isValid = kFALSE ;
return ;
}
}
_haveIdxProto = prototype ? kTRUE : kFALSE ;
_idxCatName = idxCat->GetName() ;
if (!_haveIdxProto && !model.canBeExtended()) {
oocoutE(_pdf,Generation) << "RooSimGenContext::ctor(" << GetName() << ") ERROR: Need either extended mode"
<< " or prototype data to calculate number of events per category" << endl ;
_isValid = kFALSE ;
return ;
}
_numPdf = model._pdfProxyList.GetSize() ;
_fracThresh = new Double_t[_numPdf+1] ;
_fracThresh[0] = 0 ;
TIterator* iter = model._pdfProxyList.MakeIterator() ;
RooRealProxy* proxy ;
RooAbsPdf* pdf ;
Int_t i(1) ;
while((proxy=(RooRealProxy*)iter->Next())) {
pdf=(RooAbsPdf*)proxy->absArg() ;
RooAbsGenContext* cx = pdf->genContext(pdfVars,prototype,auxProto,verbose) ;
cx->SetName(proxy->name()) ;
_gcList.Add(cx) ;
_fracThresh[i] = _fracThresh[i-1] + (_haveIdxProto?0:pdf->expectedEvents(&allPdfVars)) ;
i++ ;
}
delete iter ;
if (!_haveIdxProto) {
for(i=0 ; i<_numPdf ; i++)
_fracThresh[i] /= _fracThresh[_numPdf] ;
}
_idxCatSet = (RooArgSet*) RooArgSet(model._indexCat.arg()).snapshot(kTRUE) ;
if (!_idxCatSet) {
oocoutE(_pdf,Generation) << "RooSimGenContext::RooSimGenContext(" << GetName() << ") Couldn't deep-clone index category, abort," << endl ;
RooErrorHandler::softAbort() ;
}
_idxCat = (RooAbsCategoryLValue*) _idxCatSet->find(model._indexCat.arg().GetName()) ;
}
RooSimGenContext::~RooSimGenContext()
{
delete[] _fracThresh ;
delete _idxCatSet ;
_gcList.Delete() ;
}
void RooSimGenContext::attach(const RooArgSet& args)
{
if (_idxCat->isDerived()) {
_idxCat->recursiveRedirectServers(args,kTRUE) ;
}
RooAbsGenContext* gc ;
TIterator* iter = _gcList.MakeIterator() ;
while((gc=(RooAbsGenContext*)iter->Next())){
gc->attach(args) ;
}
delete iter;
}
void RooSimGenContext::initGenerator(const RooArgSet &theEvent)
{
if (_idxCat->isDerived()) {
_idxCat->recursiveRedirectServers(theEvent,kTRUE) ;
} else {
_idxCat = (RooAbsCategoryLValue*) theEvent.find(_idxCat->GetName()) ;
}
RooAbsGenContext* gc ;
TIterator* iter = _gcList.MakeIterator() ;
while((gc=(RooAbsGenContext*)iter->Next())){
gc->initGenerator(theEvent) ;
}
delete iter;
}
void RooSimGenContext::generateEvent(RooArgSet &theEvent, Int_t remaining)
{
if (_haveIdxProto) {
const char* label = _idxCat->getLabel() ;
RooAbsGenContext* cx = (RooAbsGenContext*)_gcList.FindObject(label) ;
if (cx) {
cx->generateEvent(theEvent,remaining) ;
} else {
oocoutW(_pdf,Generation) << "RooSimGenContext::generateEvent: WARNING, no PDF to generate event of type " << label << endl ;
}
} else {
Double_t rand = RooRandom::uniform() ;
Int_t i=0 ;
for (i=0 ; i<_numPdf ; i++) {
if (rand>_fracThresh[i] && rand<_fracThresh[i+1]) {
RooAbsGenContext* gen= ((RooAbsGenContext*)_gcList.At(i)) ;
gen->generateEvent(theEvent,remaining) ;
_idxCat->setLabel(gen->GetName()) ;
return ;
}
}
}
}
void RooSimGenContext::setProtoDataOrder(Int_t* lut)
{
RooAbsGenContext::setProtoDataOrder(lut) ;
TIterator* iter = _gcList.MakeIterator() ;
RooAbsGenContext* gc ;
while((gc=(RooAbsGenContext*)iter->Next())) {
gc->setProtoDataOrder(lut) ;
}
delete iter ;
}
void RooSimGenContext::printMultiline(ostream &os, Int_t content, Bool_t verbose, TString indent) const
{
RooAbsGenContext::printMultiline(os,content,verbose,indent) ;
os << indent << "--- RooSimGenContext ---" << endl ;
os << indent << "Using PDF ";
_pdf->printStream(os,kName|kArgs|kClassName,kSingleLine,indent);
os << indent << "List of component generators" << endl ;
TString indent2(indent) ;
indent2.Append(" ") ;
TIterator* iter = _gcList.MakeIterator() ;
RooAbsGenContext* gc ;
while((gc=(RooAbsGenContext*)iter->Next())) {
gc->printMultiline(os,content,verbose,indent2);
}
delete iter ;
}
Last change: Wed Jun 25 08:34:12 2008
Last generated: 2008-06-25 08:34
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.