ROOT logo
/*****************************************************************************
 * Project: RooFit                                                           *
 * Package: RooFitCore                                                       *
 * @(#)root/roofitcore:$Id: RooSimGenContext.cxx 24285 2008-06-16 15:05:15Z wouter $
 * Authors:                                                                  *
 *   WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu       *
 *   DK, David Kirkby,    UC Irvine,         dkirkby@uci.edu                 *
 *                                                                           *
 * Copyright (c) 2000-2005, Regents of the University of California          *
 *                          and Stanford University. All rights reserved.    *
 *                                                                           *
 * Redistribution and use in source and binary forms,                        *
 * with or without modification, are permitted according to the terms        *
 * listed in LICENSE (http://roofit.sourceforge.net/license.txt)             *
 *****************************************************************************/

//////////////////////////////////////////////////////////////////////////////
//
// BEGIN_HTML
// 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)
{
  // Constructor of specialized generator context for RooSimultaneous p.d.f.s. This
  // context creates a dedicated context for each component p.d.f.s and delegates
  // generation of events to the appropriate component generator context

  // Determine if we are requested to generate the index category
  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 ;
    }
  }

  // We must either have the prototype or extended likelihood to determined
  // the relative fractions of the components
  _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 ;
  }

  // Initialize fraction threshold array (used only in extended mode)
  _numPdf = model._pdfProxyList.GetSize() ;
  _fracThresh = new Double_t[_numPdf+1] ;
  _fracThresh[0] = 0 ;
  
  // Generate index category and all registered PDFS
  TIterator* iter = model._pdfProxyList.MakeIterator() ;
  RooRealProxy* proxy ;
  RooAbsPdf* pdf ;
  Int_t i(1) ;
  while((proxy=(RooRealProxy*)iter->Next())) {
    pdf=(RooAbsPdf*)proxy->absArg() ;

    // Create generator context for this PDF
    RooAbsGenContext* cx = pdf->genContext(pdfVars,prototype,auxProto,verbose) ;

    // Name the context after the associated state and add to list
    cx->SetName(proxy->name()) ;
    _gcList.Add(cx) ;

    // Fill fraction threshold array
    _fracThresh[i] = _fracThresh[i-1] + (_haveIdxProto?0:pdf->expectedEvents(&allPdfVars)) ;
    i++ ;
  }   
  delete iter ;
    
  // Normalize fraction threshold array
  if (!_haveIdxProto) {
    for(i=0 ; i<_numPdf ; i++) 
      _fracThresh[i] /= _fracThresh[_numPdf] ;
  }
  

  // Clone the index category
  _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()
{
  // Destructor. Delete all owned subgenerator contexts

  delete[] _fracThresh ;
  delete _idxCatSet ;
  _gcList.Delete() ;
}



//_____________________________________________________________________________
void RooSimGenContext::attach(const RooArgSet& args) 
{
  // Attach the index category clone to the given event buffer

  if (_idxCat->isDerived()) {
    _idxCat->recursiveRedirectServers(args,kTRUE) ;
  }

  // Forward initGenerator call to all components
  RooAbsGenContext* gc ;
  TIterator* iter = _gcList.MakeIterator() ;
  while((gc=(RooAbsGenContext*)iter->Next())){
    gc->attach(args) ;
  }
  delete iter;
  
}


//_____________________________________________________________________________
void RooSimGenContext::initGenerator(const RooArgSet &theEvent)
{
  // Perform one-time initialization of generator context

  // Attach the index category clone to the event
  if (_idxCat->isDerived()) {
    _idxCat->recursiveRedirectServers(theEvent,kTRUE) ;
  } else {
    _idxCat = (RooAbsCategoryLValue*) theEvent.find(_idxCat->GetName()) ;
  }

  // Forward initGenerator call to all components
  RooAbsGenContext* gc ;
  TIterator* iter = _gcList.MakeIterator() ;
  while((gc=(RooAbsGenContext*)iter->Next())){
    gc->initGenerator(theEvent) ;
  }
  delete iter;

}



//_____________________________________________________________________________
void RooSimGenContext::generateEvent(RooArgSet &theEvent, Int_t remaining)
{
  // Generate event appropriate for current index state. 
  // The index state is taken either from the prototype
  // or is generated from the fraction threshold table.

  if (_haveIdxProto) {

    // Lookup pdf from selected prototype index state
    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 {

    // Throw a random number and select PDF from fraction threshold table
    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)
{
  // Set the traversal order of the prototype data to that in the
  // given lookup table. This information is passed to all
  // component generator contexts

  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 
{
  // Detailed printing interface

  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 ;
}
 RooSimGenContext.cxx:1
 RooSimGenContext.cxx:2
 RooSimGenContext.cxx:3
 RooSimGenContext.cxx:4
 RooSimGenContext.cxx:5
 RooSimGenContext.cxx:6
 RooSimGenContext.cxx:7
 RooSimGenContext.cxx:8
 RooSimGenContext.cxx:9
 RooSimGenContext.cxx:10
 RooSimGenContext.cxx:11
 RooSimGenContext.cxx:12
 RooSimGenContext.cxx:13
 RooSimGenContext.cxx:14
 RooSimGenContext.cxx:15
 RooSimGenContext.cxx:16
 RooSimGenContext.cxx:17
 RooSimGenContext.cxx:18
 RooSimGenContext.cxx:19
 RooSimGenContext.cxx:20
 RooSimGenContext.cxx:21
 RooSimGenContext.cxx:22
 RooSimGenContext.cxx:23
 RooSimGenContext.cxx:24
 RooSimGenContext.cxx:25
 RooSimGenContext.cxx:26
 RooSimGenContext.cxx:27
 RooSimGenContext.cxx:28
 RooSimGenContext.cxx:29
 RooSimGenContext.cxx:30
 RooSimGenContext.cxx:31
 RooSimGenContext.cxx:32
 RooSimGenContext.cxx:33
 RooSimGenContext.cxx:34
 RooSimGenContext.cxx:35
 RooSimGenContext.cxx:36
 RooSimGenContext.cxx:37
 RooSimGenContext.cxx:38
 RooSimGenContext.cxx:39
 RooSimGenContext.cxx:40
 RooSimGenContext.cxx:41
 RooSimGenContext.cxx:42
 RooSimGenContext.cxx:43
 RooSimGenContext.cxx:44
 RooSimGenContext.cxx:45
 RooSimGenContext.cxx:46
 RooSimGenContext.cxx:47
 RooSimGenContext.cxx:48
 RooSimGenContext.cxx:49
 RooSimGenContext.cxx:50
 RooSimGenContext.cxx:51
 RooSimGenContext.cxx:52
 RooSimGenContext.cxx:53
 RooSimGenContext.cxx:54
 RooSimGenContext.cxx:55
 RooSimGenContext.cxx:56
 RooSimGenContext.cxx:57
 RooSimGenContext.cxx:58
 RooSimGenContext.cxx:59
 RooSimGenContext.cxx:60
 RooSimGenContext.cxx:61
 RooSimGenContext.cxx:62
 RooSimGenContext.cxx:63
 RooSimGenContext.cxx:64
 RooSimGenContext.cxx:65
 RooSimGenContext.cxx:66
 RooSimGenContext.cxx:67
 RooSimGenContext.cxx:68
 RooSimGenContext.cxx:69
 RooSimGenContext.cxx:70
 RooSimGenContext.cxx:71
 RooSimGenContext.cxx:72
 RooSimGenContext.cxx:73
 RooSimGenContext.cxx:74
 RooSimGenContext.cxx:75
 RooSimGenContext.cxx:76
 RooSimGenContext.cxx:77
 RooSimGenContext.cxx:78
 RooSimGenContext.cxx:79
 RooSimGenContext.cxx:80
 RooSimGenContext.cxx:81
 RooSimGenContext.cxx:82
 RooSimGenContext.cxx:83
 RooSimGenContext.cxx:84
 RooSimGenContext.cxx:85
 RooSimGenContext.cxx:86
 RooSimGenContext.cxx:87
 RooSimGenContext.cxx:88
 RooSimGenContext.cxx:89
 RooSimGenContext.cxx:90
 RooSimGenContext.cxx:91
 RooSimGenContext.cxx:92
 RooSimGenContext.cxx:93
 RooSimGenContext.cxx:94
 RooSimGenContext.cxx:95
 RooSimGenContext.cxx:96
 RooSimGenContext.cxx:97
 RooSimGenContext.cxx:98
 RooSimGenContext.cxx:99
 RooSimGenContext.cxx:100
 RooSimGenContext.cxx:101
 RooSimGenContext.cxx:102
 RooSimGenContext.cxx:103
 RooSimGenContext.cxx:104
 RooSimGenContext.cxx:105
 RooSimGenContext.cxx:106
 RooSimGenContext.cxx:107
 RooSimGenContext.cxx:108
 RooSimGenContext.cxx:109
 RooSimGenContext.cxx:110
 RooSimGenContext.cxx:111
 RooSimGenContext.cxx:112
 RooSimGenContext.cxx:113
 RooSimGenContext.cxx:114
 RooSimGenContext.cxx:115
 RooSimGenContext.cxx:116
 RooSimGenContext.cxx:117
 RooSimGenContext.cxx:118
 RooSimGenContext.cxx:119
 RooSimGenContext.cxx:120
 RooSimGenContext.cxx:121
 RooSimGenContext.cxx:122
 RooSimGenContext.cxx:123
 RooSimGenContext.cxx:124
 RooSimGenContext.cxx:125
 RooSimGenContext.cxx:126
 RooSimGenContext.cxx:127
 RooSimGenContext.cxx:128
 RooSimGenContext.cxx:129
 RooSimGenContext.cxx:130
 RooSimGenContext.cxx:131
 RooSimGenContext.cxx:132
 RooSimGenContext.cxx:133
 RooSimGenContext.cxx:134
 RooSimGenContext.cxx:135
 RooSimGenContext.cxx:136
 RooSimGenContext.cxx:137
 RooSimGenContext.cxx:138
 RooSimGenContext.cxx:139
 RooSimGenContext.cxx:140
 RooSimGenContext.cxx:141
 RooSimGenContext.cxx:142
 RooSimGenContext.cxx:143
 RooSimGenContext.cxx:144
 RooSimGenContext.cxx:145
 RooSimGenContext.cxx:146
 RooSimGenContext.cxx:147
 RooSimGenContext.cxx:148
 RooSimGenContext.cxx:149
 RooSimGenContext.cxx:150
 RooSimGenContext.cxx:151
 RooSimGenContext.cxx:152
 RooSimGenContext.cxx:153
 RooSimGenContext.cxx:154
 RooSimGenContext.cxx:155
 RooSimGenContext.cxx:156
 RooSimGenContext.cxx:157
 RooSimGenContext.cxx:158
 RooSimGenContext.cxx:159
 RooSimGenContext.cxx:160
 RooSimGenContext.cxx:161
 RooSimGenContext.cxx:162
 RooSimGenContext.cxx:163
 RooSimGenContext.cxx:164
 RooSimGenContext.cxx:165
 RooSimGenContext.cxx:166
 RooSimGenContext.cxx:167
 RooSimGenContext.cxx:168
 RooSimGenContext.cxx:169
 RooSimGenContext.cxx:170
 RooSimGenContext.cxx:171
 RooSimGenContext.cxx:172
 RooSimGenContext.cxx:173
 RooSimGenContext.cxx:174
 RooSimGenContext.cxx:175
 RooSimGenContext.cxx:176
 RooSimGenContext.cxx:177
 RooSimGenContext.cxx:178
 RooSimGenContext.cxx:179
 RooSimGenContext.cxx:180
 RooSimGenContext.cxx:181
 RooSimGenContext.cxx:182
 RooSimGenContext.cxx:183
 RooSimGenContext.cxx:184
 RooSimGenContext.cxx:185
 RooSimGenContext.cxx:186
 RooSimGenContext.cxx:187
 RooSimGenContext.cxx:188
 RooSimGenContext.cxx:189
 RooSimGenContext.cxx:190
 RooSimGenContext.cxx:191
 RooSimGenContext.cxx:192
 RooSimGenContext.cxx:193
 RooSimGenContext.cxx:194
 RooSimGenContext.cxx:195
 RooSimGenContext.cxx:196
 RooSimGenContext.cxx:197
 RooSimGenContext.cxx:198
 RooSimGenContext.cxx:199
 RooSimGenContext.cxx:200
 RooSimGenContext.cxx:201
 RooSimGenContext.cxx:202
 RooSimGenContext.cxx:203
 RooSimGenContext.cxx:204
 RooSimGenContext.cxx:205
 RooSimGenContext.cxx:206
 RooSimGenContext.cxx:207
 RooSimGenContext.cxx:208
 RooSimGenContext.cxx:209
 RooSimGenContext.cxx:210
 RooSimGenContext.cxx:211
 RooSimGenContext.cxx:212
 RooSimGenContext.cxx:213
 RooSimGenContext.cxx:214
 RooSimGenContext.cxx:215
 RooSimGenContext.cxx:216
 RooSimGenContext.cxx:217
 RooSimGenContext.cxx:218
 RooSimGenContext.cxx:219
 RooSimGenContext.cxx:220
 RooSimGenContext.cxx:221
 RooSimGenContext.cxx:222
 RooSimGenContext.cxx:223
 RooSimGenContext.cxx:224
 RooSimGenContext.cxx:225
 RooSimGenContext.cxx:226
 RooSimGenContext.cxx:227
 RooSimGenContext.cxx:228
 RooSimGenContext.cxx:229
 RooSimGenContext.cxx:230
 RooSimGenContext.cxx:231
 RooSimGenContext.cxx:232
 RooSimGenContext.cxx:233
 RooSimGenContext.cxx:234
 RooSimGenContext.cxx:235
 RooSimGenContext.cxx:236
 RooSimGenContext.cxx:237
 RooSimGenContext.cxx:238
 RooSimGenContext.cxx:239
 RooSimGenContext.cxx:240
 RooSimGenContext.cxx:241
 RooSimGenContext.cxx:242
 RooSimGenContext.cxx:243
 RooSimGenContext.cxx:244
 RooSimGenContext.cxx:245
 RooSimGenContext.cxx:246
 RooSimGenContext.cxx:247
 RooSimGenContext.cxx:248
 RooSimGenContext.cxx:249
 RooSimGenContext.cxx:250
 RooSimGenContext.cxx:251
 RooSimGenContext.cxx:252
 RooSimGenContext.cxx:253
 RooSimGenContext.cxx:254
 RooSimGenContext.cxx:255
 RooSimGenContext.cxx:256
 RooSimGenContext.cxx:257
 RooSimGenContext.cxx:258
 RooSimGenContext.cxx:259
 RooSimGenContext.cxx:260
 RooSimGenContext.cxx:261
 RooSimGenContext.cxx:262
 RooSimGenContext.cxx:263
 RooSimGenContext.cxx:264
 RooSimGenContext.cxx:265
 RooSimGenContext.cxx:266
 RooSimGenContext.cxx:267
 RooSimGenContext.cxx:268
 RooSimGenContext.cxx:269
 RooSimGenContext.cxx:270
 RooSimGenContext.cxx:271
 RooSimGenContext.cxx:272
 RooSimGenContext.cxx:273
 RooSimGenContext.cxx:274
 RooSimGenContext.cxx:275
 RooSimGenContext.cxx:276
 RooSimGenContext.cxx:277
 RooSimGenContext.cxx:278
 RooSimGenContext.cxx:279