/*****************************************************************************
* Project: RooFit *
* Package: RooFitCore *
* File: $Id: RooAbsGenContext.cc,v 1.21 2005/06/20 15:44:44 wverkerke Exp $
* 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) *
*****************************************************************************/
// -- CLASS DESCRIPTION [AUX] --
// RooAbsGenContext is the abstract base class for generator contexts.
#include "RooFit.h"
#include "RooAbsGenContext.h"
#include "RooAbsGenContext.h"
#include "RooAbsPdf.h"
#include "RooDataSet.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)
{
// Constructor
// Check PDF dependents
if (model.recursiveCheckObservables(&vars)) {
cout << "RooAbsGenContext::ctor: Error in PDF dependents" << endl ;
_isValid = kFALSE ;
return ;
}
// Make a snapshot of the generated variables that we can overwrite.
_theEvent= (RooArgSet*)vars.snapshot(kFALSE);
// Analyze the prototype dataset, if one is specified
_nextProtoIndex= 0;
if(0 != _prototype) {
TIterator *protoIterator= _prototype->get()->createIterator();
const RooAbsArg *proto = 0;
while((proto= (const RooAbsArg*)protoIterator->Next())) {
// is this variable being generated or taken from the prototype?
if(!_theEvent->contains(*proto)) {
_protoVars.add(*proto);
_theEvent->addClone(*proto);
}
}
delete protoIterator;
}
// Add auxiliary protovars to _protoVars, if provided
if (auxProto) {
_protoVars.add(*auxProto) ;
}
// Remember the default number of events to generate when no prototype dataset is provided.
_extendMode = model.extendMode() ;
if (model.canBeExtended()) {
_expectedEvents= (Int_t)(model.expectedEvents(_theEvent) + 0.5);
} else {
_expectedEvents= 0 ;
}
}
RooAbsGenContext::~RooAbsGenContext()
{
// Destructor
if(0 != _theEvent) delete _theEvent;
if (_protoOrder) delete[] _protoOrder ;
}
RooDataSet *RooAbsGenContext::generate(Int_t nEvents) {
// Generate the specified number of events with nEvents>0 and
// and return a dataset containing the generated events. With nEvents<=0,
// generate the number of events in the prototype dataset, if available,
// or else the expected number of events, if non-zero. The returned
// dataset belongs to the caller. Return zero in case of an error.
// Generation of individual events is delegated to a virtual generateEvent()
// method. A virtual initGenerator() method is also called just before the
// first call to generateEvent().
if(!isValid()) {
cout << ClassName() << "::" << GetName() << ": context is not valid" << endl;
return 0;
}
// Calculate the expected number of events if necessary
if(nEvents <= 0) {
if(_prototype) {
nEvents= (Int_t)_prototype->numEntries();
}
else {
if (_extendMode == RooAbsPdf::CanNotBeExtended) {
cout << ClassName() << "::" << GetName()
<< ":generate: PDF not extendable: cannot calculate expected number of events" << endl;
return 0;
}
nEvents= _expectedEvents;
}
if(nEvents <= 0) {
cout << ClassName() << "::" << GetName()
<< ":generate: cannot calculate expected number of events" << endl;
return 0;
}
else if(_verbose) {
cout << ClassName() << "::" << GetName() << ":generate: will generate "
<< nEvents << " events" << endl;
}
}
// check that any prototype dataset still defines the variables we need
// (this is necessary since we never make a private clone, for efficiency)
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;
cout << ClassName() << "::" << GetName() << ":generate: prototype dataset is missing \""
<< arg->GetName() << "\"" << endl;
// WVE disable this for the moment
// ok= kFALSE;
}
delete iterator;
if(!ok) return 0;
}
if (_verbose) Print("v") ;
// create a new dataset
TString name(GetName()),title(GetTitle());
name.Append("Data");
title.Prepend("Generated From ");
RooDataSet *data= new RooDataSet(name.Data(), title.Data(), *_theEvent);
// Perform any subclass implementation-specific initialization
initGenerator(*_theEvent);
// Loop over the events to generate
for(Int_t evt= 0; evt < nEvents; evt++) {
// first, load values from the prototype dataset, if one was provided
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 {
cout << ClassName() << "::" << GetName() << ":generate: cannot load event "
<< actualProtoIdx << " from prototype dataset" << endl;
return 0;
}
}
// delegate the generation of the rest of this event to our subclass implementation
generateEvent(*_theEvent, nEvents - evt);
data->add(*_theEvent);
}
return data;
}
void RooAbsGenContext::initGenerator(const RooArgSet&) {
// The base class provides a do-nothing default implementation.
}
void RooAbsGenContext::printToStream(ostream &os, PrintOption opt, TString indent) const
{
oneLinePrint(os,*this);
if(opt >= Standard) {
PrintOption less= lessVerbose(opt);
TString deeper(indent);
indent.Append(" ");
os << indent << " Generator of ";
_theEvent->printToStream(os,less,deeper);
os << indent << " Prototype variables are ";
_protoVars.printToStream(os,less,deeper);
}
}
void RooAbsGenContext::setProtoDataOrder(Int_t* lut)
{
// Delete any previous lookup table
if (_protoOrder) {
delete[] _protoOrder ;
_protoOrder = 0 ;
}
// Copy new lookup table if provided and needed
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] ;
}
}
}
ROOT page - Class index - Class Hierarchy - Top of the page
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.