#include "RooFit.h"
#include "RooGenContext.h"
#include "RooGenContext.h"
#include "RooAbsPdf.h"
#include "RooDataSet.h"
#include "RooRealIntegral.h"
#include "RooAcceptReject.h"
#include "RooRealVar.h"
#include "RooDataHist.h"
#include "RooErrorHandler.h"
#include "TString.h"
#include "TIterator.h"
ClassImp(RooGenContext)
  ;
RooGenContext::RooGenContext(const RooAbsPdf &model, const RooArgSet &vars,
			     const RooDataSet *prototype, const RooArgSet* auxProto,
			     Bool_t verbose, const RooArgSet* forceDirect) :  
  RooAbsGenContext(model,vars,prototype,auxProto,verbose),
  _cloneSet(0), _pdfClone(0), _acceptRejectFunc(0), _generator(0),
  _maxVar(0), _uniIter(0), _updateFMaxPerEvent(0) 
{
  
  
  
  
  
  
  
  RooArgSet nodes(model,model.GetName());
  _cloneSet= (RooArgSet*) nodes.snapshot(kTRUE);
  if (!_cloneSet) {
    cout << "RooGenContext::RooGenContext(" << GetName() << ") Couldn't deep-clone PDF, abort," << endl ;
    RooErrorHandler::softAbort() ;
  }
  
  _pdfClone = (RooAbsPdf*)_cloneSet->find(model.GetName());
  
  if (prototype&&_pdfClone->dependsOn(*prototype->get())) {
    RooArgSet fullNormSet(vars) ;
    fullNormSet.add(*prototype->get()) ;
    _pdfClone->fixAddCoefNormalization(fullNormSet) ;
  }
      
  
  _isValid= kTRUE;
  TIterator *iterator= vars.createIterator();
  TIterator *servers= _pdfClone->serverIterator();
  const RooAbsArg *tmp = 0;
  const RooAbsArg *arg = 0;
  while((_isValid && (tmp= (const RooAbsArg*)iterator->Next()))) {
    
    if(tmp->isDerived()) {
      cout << ClassName() << "::" << GetName() << ": cannot generate values for derived \""
	   << tmp->GetName() << "\"" << endl;
      _isValid= kFALSE;
      continue;
    }
    
    arg= (const RooAbsArg*)_cloneSet->find(tmp->GetName());
    if(0 == arg) {
      cout << ClassName() << "::" << GetName() << ":WARNING: model does not depend on \""
	   << tmp->GetName() << "\" which will have uniform distribution" << endl;
      _uniformVars.add(*tmp);
    }
    else {
      
      
      const RooAbsArg *direct= arg ;
      if (forceDirect==0 || !forceDirect->find(direct->GetName())) {
	if (!_pdfClone->isDirectGenSafe(*arg)) {
	  
	  direct=0 ;
	}
      }
      
      
      
      if(direct) { 
	_directVars.add(*arg);
      } else {
	_otherVars.add(*arg);
      }
    }
  }
  delete servers;
  delete iterator;
  if(!isValid()) {
    cout << ClassName() << "::" << GetName() << ": constructor failed with errors" << endl;
    return;
  }
  
  
  Bool_t staticInitOK = !_pdfClone->dependsOn(_protoVars) ;
  
  
  RooArgSet generatedVars;
  _code= _pdfClone->getGenerator(_directVars,generatedVars,staticInitOK);
  
  _directVars.remove(generatedVars);
  _otherVars.add(_directVars);
  
  _directVars.removeAll();
  _directVars.add(generatedVars);
  
  RooArgSet *depList= _pdfClone->getObservables(_theEvent);
  depList->remove(_otherVars);
  TString nname(_pdfClone->GetName()) ;
  nname.Append("Reduced") ;
  TString ntitle(_pdfClone->GetTitle()) ;
  ntitle.Append(" (Accept/Reject)") ;
  if (_protoVars.getSize()==0) {
    
    
    if(depList->getSize()==0) {
      
      
      
      Int_t maxFindCode = _pdfClone->getMaxVal(_otherVars) ;
      if (maxFindCode != 0) {
	if (verbose) {
	  cout << "RooGenContext::ctor(" << model.GetName() 
	       << ") PDF supports maximum finding, initial sampling phase skipped" << endl ;
	}
	Double_t maxVal = _pdfClone->maxVal(maxFindCode) / _pdfClone->getNorm(_theEvent) ;
	_maxVar = new RooRealVar("funcMax","function maximum",maxVal) ;
      }
    } 
    _pdfClone->getVal(&vars) ; 
    _acceptRejectFunc= new RooRealIntegral(nname,ntitle,*_pdfClone,*depList,&vars);
  } else {
    
    depList->remove(_protoVars,kTRUE,kTRUE) ;
    _acceptRejectFunc= (RooRealIntegral*) _pdfClone->createIntegral(*depList,vars) ;
    
    if (_directVars.getSize()==0)  {
      
      Int_t maxFindCode = _pdfClone->getMaxVal(_otherVars) ;
      if (maxFindCode != 0) {
	
	if (verbose) {
	  cout << "RooGenContext::ctor(" << model.GetName() 
	       << ") PDF supports maximum finding, initial sampling phase skipped" << endl ;
	}
	_maxVar = new RooRealVar("funcMax","function maximum",1) ;
	_updateFMaxPerEvent = maxFindCode ;
      }
    }
    
    if (!_maxVar) {
      
      RooArgSet otherAndProto(_otherVars) ;
      
      RooArgSet* protoDeps = model.getObservables(_protoVars) ;
      otherAndProto.add(*protoDeps) ;
      delete protoDeps ;
      
      if (_otherVars.getSize()>0) {      
	
	RooAcceptReject maxFinder(*_acceptRejectFunc,otherAndProto,0,_verbose) ;
	Double_t max = maxFinder.getFuncMax() ;
	_maxVar = new RooRealVar("funcMax","function maximum",max) ;
      }
    }
      
  }
  _generator= new RooAcceptReject(*_acceptRejectFunc,_otherVars,_maxVar,_verbose);
  delete depList;
  _otherVars.add(_uniformVars);
}
RooGenContext::~RooGenContext() 
{
  
  
  delete _cloneSet;
  
  delete _generator;
  delete _acceptRejectFunc;
  if (_maxVar) delete _maxVar ;
  if (_uniIter) delete _uniIter ;
}
void RooGenContext::initGenerator(const RooArgSet &theEvent) {
  
  _pdfClone->recursiveRedirectServers(theEvent,kFALSE);
  _acceptRejectFunc->recursiveRedirectServers(theEvent,kFALSE) ; 
  
  _generator->attachParameters(theEvent) ;
  
  _pdfClone->resetErrorCounters();
  
  if (_directVars.getSize()>0) {
    _pdfClone->initGenerator(_code) ;
  }
  
  if (_uniformVars.getSize()>0) {
    _uniIter = _uniformVars.createIterator() ;
  }
}
void RooGenContext::generateEvent(RooArgSet &theEvent, Int_t remaining) {
  
  if(_otherVars.getSize() > 0) {
    
    if (_updateFMaxPerEvent!=0) {
      _maxVar->setVal(_pdfClone->maxVal(_updateFMaxPerEvent)/_pdfClone->getNorm(_otherVars)) ;
    }
    const RooArgSet *subEvent= _generator->generateEvent(remaining);
    if(0 == subEvent) {
      cout << ClassName() << "::" << GetName() << ":generate: accept/reject generator failed." << endl;
      return;
    }
    theEvent= *subEvent;
  }
  
  
  if(_directVars.getSize() > 0) {
    _pdfClone->generateEvent(_code);
  }
  
  if (_uniIter) {
    _uniIter->Reset() ;
    RooAbsArg* uniVar ;
    while((uniVar=(RooAbsArg*)_uniIter->Next())) {
      RooAbsLValue* arglv = dynamic_cast<RooAbsLValue*>(uniVar) ;
      if (!arglv) {
	cout << "RooGenContext::generateEvent(" << GetName() << ") ERROR: uniform variable " 
	     << uniVar->GetName() << " is not an lvalue" << endl ;
	RooErrorHandler::softAbort() ;
      }
      arglv->randomize() ;
    }
    theEvent = _uniformVars ;
  }
}
void RooGenContext::printToStream(ostream &os, PrintOption opt, TString indent) const
{
  RooAbsGenContext::printToStream(os,opt,indent);
  if(opt >= Standard) {
    PrintOption less= lessVerbose(opt);
    TString deeper(indent);
    indent.Append("  ");
    os << indent << "Using PDF ";
    _pdfClone->printToStream(os,less,deeper);
    if(opt >= Verbose) {
      os << indent << "Use PDF generator for ";
      _directVars.printToStream(os,less,deeper);
      os << indent << "Use accept/reject for ";
      _otherVars.printToStream(os,less,deeper);
    }
  }
}
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.