// RooAbsGenContext is the abstract base class for generator contexts of 
// RooAbsPdf objects. A generator context is an object that controls
// the generation of events from a given p.d.f in one or more sessions.
// This class defines the common interface for all such contexts and organizes
// storage of common components, such as the observables definition, the 
// prototype data etc..
// END_HTML
#include "RooFit.h"
#include "TClass.h"
#include "RooAbsGenContext.h"
#include "RooAbsGenContext.h"
#include "RooAbsPdf.h"
#include "RooDataSet.h"
#include "RooMsgService.h"
#include "Riostream.h"
ClassImp(RooAbsGenContext)
;
RooAbsGenContext::RooAbsGenContext(const RooAbsPdf& model, const RooArgSet &vars,
				   const RooDataSet *prototype, const RooArgSet* auxProto, Bool_t verbose) :
  TNamed(model), 
  _prototype(prototype), 
  _theEvent(0), 
  _isValid(kTRUE),
  _verbose(verbose),
  _protoOrder(0) 
{
  
  
  if (model.recursiveCheckObservables(&vars)) {
    coutE(Generation) << "RooAbsGenContext::ctor: Error in PDF dependents" << endl ;
    _isValid = kFALSE ;
    return ;
  }
  
  _theEvent= (RooArgSet*)vars.snapshot(kFALSE);
  
  _nextProtoIndex= 0;
  if(0 != _prototype) {
    TIterator *protoIterator= _prototype->get()->createIterator();
    const RooAbsArg *proto = 0;
    while((proto= (const RooAbsArg*)protoIterator->Next())) {
      
      if(!_theEvent->contains(*proto)) {
	_protoVars.add(*proto);
	_theEvent->addClone(*proto);
      }
    }
    delete protoIterator;
  }
  
  if (auxProto) {
    _protoVars.add(*auxProto) ;
    _theEvent->addClone(*auxProto) ; 
  }
  
  _extendMode = model.extendMode() ;
  if (model.canBeExtended()) {
    _expectedEvents= (Int_t)(model.expectedEvents(_theEvent) + 0.5);
  } else {
    _expectedEvents= 0 ;
  }
}
RooAbsGenContext::~RooAbsGenContext()
{
  
  if(0 != _theEvent) delete _theEvent;
  if (_protoOrder) delete[] _protoOrder ;
}
void RooAbsGenContext::attach(const RooArgSet& ) 
{
  
}
RooDataSet *RooAbsGenContext::generate(Int_t nEvents) 
{
  
  
  
  
  
  
  
  
  
  if(!isValid()) {
    coutE(Generation) << ClassName() << "::" << GetName() << ": context is not valid" << endl;
    return 0;
  }
  
  if(nEvents <= 0) {
    if(_prototype) {
      nEvents= (Int_t)_prototype->numEntries();
    }
    else {
      if (_extendMode == RooAbsPdf::CanNotBeExtended) {
	coutE(Generation) << ClassName() << "::" << GetName()
	     << ":generate: PDF not extendable: cannot calculate expected number of events" << endl;
	return 0;	
      }
      nEvents= _expectedEvents;
    }
    if(nEvents <= 0) {
      coutE(Generation) << ClassName() << "::" << GetName()
			<< ":generate: cannot calculate expected number of events" << endl;
      return 0;
    }
    coutI(Generation) << ClassName() << "::" << GetName() << ":generate: will generate "
		      << nEvents << " events" << endl;
  }
  
  
  if(_prototype) {
    const RooArgSet *vars= _prototype->get();
    TIterator *iterator= _protoVars.createIterator();
    const RooAbsArg *arg = 0;
    Bool_t ok(kTRUE);
    while((arg= (const RooAbsArg*)iterator->Next())) {
      if(vars->contains(*arg)) continue;
      coutE(InputArguments) << ClassName() << "::" << GetName() << ":generate: prototype dataset is missing \""
			    << arg->GetName() << "\"" << endl;
      
      
    }
    delete iterator;
    if(!ok) return 0;
  }
  if (_verbose) Print("v") ;
  
  TString name(GetName()),title(GetTitle());
  name.Append("Data");
  title.Prepend("Generated From ");
  RooDataSet *data= new RooDataSet(name.Data(), title.Data(), *_theEvent);
  
  initGenerator(*_theEvent);
  
  for(Int_t evt= 0; evt < nEvents; evt++) {
    
    if(0 != _prototype) {
      if(_nextProtoIndex >= _prototype->numEntries()) _nextProtoIndex= 0;
      Int_t actualProtoIdx = _protoOrder ? _protoOrder[_nextProtoIndex] : _nextProtoIndex ;
      const RooArgSet *subEvent= _prototype->get(actualProtoIdx);
      _nextProtoIndex++;
      if(0 != subEvent) {
	*_theEvent= *subEvent;
      }
      else {
	coutE(Generation) << ClassName() << "::" << GetName() << ":generate: cannot load event "
			  << actualProtoIdx << " from prototype dataset" << endl;
	return 0;
      }
    }
    
    generateEvent(*_theEvent, nEvents - evt);
    data->add(*_theEvent);
  }
  
  return data;
}
void RooAbsGenContext::initGenerator(const RooArgSet&) 
{
  
  
}
void RooAbsGenContext::printName(ostream& os) const 
{
  
  os << GetName() ;
}
void RooAbsGenContext::printTitle(ostream& os) const 
{
  
  os << GetTitle() ;
}
void RooAbsGenContext::printClassName(ostream& os) const 
{
  
  os << IsA()->GetName() ;
}
void RooAbsGenContext::printArgs(ostream& os) const 
{
  
  os << "[ " ;    
  TIterator* iter = _theEvent->createIterator() ;
  RooAbsArg* arg ;
  Bool_t first(kTRUE) ;
  while((arg=(RooAbsArg*)iter->Next())) {
    if (first) {
      first=kFALSE ;
    } else {
      os << "," ;
    }
    os << arg->GetName() ;
  }    
  os << "]" ;
  delete iter ;
}
void RooAbsGenContext::printMultiline(ostream &, Int_t , Bool_t , TString ) const
{
  
}
void RooAbsGenContext::setProtoDataOrder(Int_t* lut)
{
  
  
  
  
  
  if (_protoOrder) {
    delete[] _protoOrder ;
    _protoOrder = 0 ;
  }
  
  
  if (lut && _prototype) {
    Int_t n = _prototype->numEntries() ;
    _protoOrder = new Int_t[n] ;
    Int_t i ;
    for (i=0 ; i<n ; i++) {
      _protoOrder[i] = lut[i] ;
    }
  }
}
Int_t RooAbsGenContext::defaultPrintContents(Option_t* ) const 
{
  
  return kName|kClassName|kValue ;
}
RooPrintable::StyleOption RooAbsGenContext::defaultPrintStyle(Option_t* opt) const 
{
  
  if (opt && TString(opt).Contains("v")) {
    return kVerbose ;
  } 
  return kStandard ;
}
Last change: Wed Jun 25 08:31:35 2008
Last generated: 2008-06-25 08:31
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.